diff --git a/.docker/apache-default.conf b/.docker/apache-default.conf new file mode 100644 index 0000000..58471f4 --- /dev/null +++ b/.docker/apache-default.conf @@ -0,0 +1,63 @@ +LoadModule remoteip_module modules/mod_remoteip.so +LoadModule rewrite_module modules/mod_rewrite.so + +ServerTokens Prod +LogLevel warn + +# Filter out AWS health check access logs +SetEnvIf Request_Method "^GET$" METHOD_GET=1 +SetEnvIf User-Agent "^Amazon-Route53-Health-Check-Service" HEALTH_CHECK_UA=1 +SetEnvIf User-Agent "^ELB-HealthChecker" HEALTH_CHECK_UA=1 +SetEnvIf Request_URI "^/ping$" HEALTH_CHECK_URI=1 +SetEnvIf Request_URI "^/user/login$" HEALTH_CHECK_URI=1 +# Filter out internal dummy connections: https://cwiki.apache.org/confluence/display/HTTPD/InternalDummyConnection +SetEnvIf Remote_Addr "127\.0\.0\.1" LOOPBACK=1 +SetEnvIf Remote_Addr "::1" LOOPBACK=1 + + +# Also listening on port 8000 so that local environments can reference themselves (e.g. PDF printing) +Listen 8000 + + ServerName ${ADDRESS} + DocumentRoot /var/www/html/web + RemoteIPHeader X-Forwarded-For + RemoteIPInternalProxy 10.0.0.0/16 + ServerSignature Off + Header set Strict-Transport-Security "max-age=31536000; includeSubdomains; preload" + Header set X-XSS-Protection "1; mode=block" + Header set X-Content-Type-Options nosniff + Header unset x-generator + + + AllowOverride All + Require all granted + SetEnvIf X-Forwarded-Proto "^https$" HTTPS + php_value upload_max_filesize 512M + php_value post_max_size 512M + php_value memory_limit 512M + php_value max_execution_time 60 + php_flag display_errors Off + Require all granted + SetEnvIf X-Forwarded-Proto "^https$" HTTPS + AddType application/manifest+json webmanifest + Redirect 403 "/core/install.php" + + + + Order deny,allow + Deny from all + + + SetEnv SIMPLESAMLPHP_CONFIG_DIR /var/www/html/simplesamlphp_config/config + Alias /simplesaml /var/www/html/simplesamlphp/www + + Require all granted + SetEnvIf X-Forwarded-Proto "^https$" HTTPS + + + +ErrorLog /dev/stdout +# Skip logging AWS health check requests (user agent, HTTP method and URI check) or apache internal dummy connections (loopback) +CustomLog /dev/stdout combined "expr=!((-n reqenv('HEALTH_CHECK_UA') && -n reqenv('HEALTH_CHECK_URI') && -n reqenv('METHOD_GET')) || -n reqenv('LOOPBACK'))" + +# vim: syntax=apache ts=4 sw=4 sts=4 sr noet diff --git a/.docker/docker-php-ext-xdebug.ini b/.docker/docker-php-ext-xdebug.ini new file mode 100644 index 0000000..b1a97bf --- /dev/null +++ b/.docker/docker-php-ext-xdebug.ini @@ -0,0 +1,11 @@ +[xdebug] +zend_extension = xdebug.so +xdebug.default_enable=1 +xdebug.mode = debug +xdebug.client_port=9003 +xdebug.start_with_request=yes +; no need for remote host +xdebug.discover_client_host = 1 +xdebug.client_host = host.docker.internal +xdebug.idekey=IDEA_DEBUG +xdebug.output_dir=/mnt/files/ diff --git a/.docker/entrypoint-dev.sh b/.docker/entrypoint-dev.sh new file mode 100755 index 0000000..981bb63 --- /dev/null +++ b/.docker/entrypoint-dev.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +if [ "${ENABLE_XDEBUG}" = true ]; then + echo "Enabling xdebug..." + cp /dev-tools/docker-php-ext-xdebug.ini /etc/php7/conf.d/docker-php-ext-xdebug.ini +else + echo "Disabling xdebug..." + rm /etc/php7/conf.d/docker-php-ext-xdebug.ini 2>&1 > /dev/null +fi + +echo "Starting httpd..." +httpd -DFOREGROUND diff --git a/.docker/php.ini b/.docker/php.ini new file mode 100644 index 0000000..a71f7f2 --- /dev/null +++ b/.docker/php.ini @@ -0,0 +1,5 @@ +[PHP] +expose_php = Off +memory_limit = 512M +upload_max_filesize = 256M + diff --git a/.docker/php.opcache.ini b/.docker/php.opcache.ini new file mode 100644 index 0000000..a0e3712 --- /dev/null +++ b/.docker/php.opcache.ini @@ -0,0 +1,11 @@ +[opcache] +opcache.enable=1 +; 0 means it will check on every request +; 0 is irrelevant if opcache.validate_timestamps=0 which is desirable in production +opcache.revalidate_freq=0 +opcache.validate_timestamps=${PHP_OPCACHE_VALIDATE_TIMESTAMPS} +opcache.max_accelerated_files=10000 +opcache.memory_consumption=192 +opcache.max_wasted_percentage=10 +opcache.interned_strings_buffer=16 + diff --git a/.docker/unit.conf.json b/.docker/unit.conf.json new file mode 100644 index 0000000..c2547f9 --- /dev/null +++ b/.docker/unit.conf.json @@ -0,0 +1,148 @@ +{ + "listeners": { + "*:80": { + "pass": "routes" + } + }, + + "routes": [ + { + "match": { + "uri": [ + "!*/.well-known/*", + "/vendor/*", + "/core/profiles/demo_umami/modules/demo_umami_content/default_content/*", + "*.engine", + "*.inc", + "*.install", + "*.make", + "*.module", + "*.po", + "*.profile", + "*.sh", + "*.theme", + "*.tpl", + "*.twig", + "*.xtmpl", + "*.yml", + "*/.*", + "*/Entries*", + "*/Repository", + "*/Root", + "*/Tag", + "*/Template", + "*/composer.json", + "*/composer.lock", + "*/web.config", + "*sql", + "*.bak", + "*.orig", + "*.save", + "*.swo", + "*.swp", + "*~" + ] + }, + + "action": { + "return": 404 + } + }, + { + "match": { + "uri": [ + "/core/authorize.php", + "/core/core.api.php", + "/core/globals.api.php", + "/core/install.php", + "/core/modules/statistics/statistics.php", + "/core/modules/system/tests/http.php*", + "/core/modules/system/tests/https.php*", + "/core/rebuild.php", + "/update.php" + ] + }, + + "action": { + "pass": "applications/drupal/direct" + } + }, + { + "match": { + "uri": [ + "!/index.php*", + "*.php" + ] + }, + + "action": { + "return": 404 + } + }, + { + "match": { + "uri": [ + "/simplesaml" + ] + }, + + "action": { + "pass": "applications/simplesaml" + } + }, + { + "action": { + "share": "/app/web/", + "fallback": { + "pass": "applications/drupal/index" + } + } + } + ], + + "applications": { + "drupal": { + "type": "php", + "processes": { + "max": 10, + "spare": 5, + "idle_timeout": 20 + }, + "limits": { + "timeout": 30, + "requests": 1000 + }, + "options": { + "file": "/etc/php7/php.ini", + "admin": { + "memory_limit": "512M", + "variables_order": "EGPCS", + "expose_php": "0" + }, + "user": { + "display_errors": "0" + } + }, + "targets": { + "direct": { + "root": "/app/web/" + }, + + "index": { + "root": "/app/web/", + "script": "index.php" + } + } + }, + + "simplesaml": { + "type": "php", + "root": "/app/simplesamlphp/www", + "script": "index.php", + "environment": { + "SIMPLESAMLPHP_CONFIG_DIR": "/app/simplesamlphp_config/config" + } + } + } +} + diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..1cb0630 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,25 @@ +.env +.env.example +.ssh +.tugboat +.git/ +.gitignore +.gitattributes +.travis.yml +.editorconfig +Makefile +*.md +admin_api/lambda_functions/ +admin_api/cloud_formation_templates/ +behat.yml +drush/ +features/ +Dockerfile +docker/ +docker.mk +scripts/ +postman/ +readme/ +docker-compose* +docker-sync* +*.sql diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..686c443 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,17 @@ +# Drupal editor configuration normalization +# @see http://editorconfig.org/ + +# This is the top-most .editorconfig file; do not search in parent directories. +root = true + +# All files. +[*] +end_of_line = LF +indent_style = space +indent_size = 2 +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[composer.{json,lock}] +indent_size = 4 diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..4b2dabf --- /dev/null +++ b/.env.example @@ -0,0 +1,125 @@ +### Documentation available at https://wodby.com/docs/stacks/drupal/local +### Changelog can be found at https://github.com/wodby/docker4drupal/releases +### Images tags format explained at https://github.com/wodby/docker4drupal#images-tags + +### PROJECT SETTINGS + +PROJECT_NAME=PERLS +PROJECT_BASE_URL=perls.localhost +### Possible values are 'dev' and 'prod' +PROJECT_ENV=dev + +# Add an additional url this tenant can be accessed on +# ADDITIONAL_TRUSTED_HOST='www.perls.local' + +DB_NAME=drupal_perls +DB_USER=drupal +DB_PASSWORD=drupal +DB_ROOT_PASSWORD=password +DB_HOST=mariadb +DB_DRIVER=mysql +DB_HOST_PORT=3306 + +LRS_HOST="" +LRS_USERNAME="" +LRS_PASSWORD="" + +# This value should match with name of webserver container name. +WEB_CONTAINER=PERLS_nginx + +SMTP_USERNAME="" +SMTP_PASSWORD="" +SMTP_HOST="mailhog" +SMTP_PORT="1025" +SMTP_FROM="perls@dev.local" + +### SSO Configuration +# Can be anything, but must be unique for the identity provider. +SIMPLESAML_AUTH_SOURCE="perls" +# Where uploaded IdP metadata is stored; must be an absolute path. +SIMPLESAML_CONFIG_DIR="/var/www/html/private/saml_config" +# The name of the Service Provider metadata file downloaded from the web interface. +SIMPLESAML_SSO_SP_METADATA_FILE="saml_sp_metadata.xml" +# The Host configured to use SSO. Sites with multiple urls will redirect to +# this url when user tries to login with with saml. +# SIMPLESAML_HOST='perls.localhost:8000' + +TUGBOAT_TOKEN="" +TUGBOAT_REPO_ID="" + +### --- MARIADB ---- + +MARIADB_TAG=10.3-3.4.11 + +### --- VANILLA DRUPAL ---- + +DRUPAL_TAG=8-4.13.6 + +### --- PHP ---- + +# Linux (uid 1000 gid 1000) + +PHP_TAG=7.4-dev-4.24.0 + + +# macOS (uid 501 gid 20) + +#PHP_TAG=7.3-dev-macos-4.12.12 +#PHP_TAG=7.2-dev-macos-4.12.12 +#PHP_TAG=7.1-dev-macos-4.12.12 +#PHP_TAG=5.6-dev-macos-4.12.12 + +### --- NGINX ---- + +NGINX_TAG=1.17-5.5.0 + +NGINX_VHOST_PRESET=drupal8-perls + +### --- SOLR --- + +SOLR_CONFIG_SET="search_api_solr_4.1.6" + +SOLR_TAG=8-4.14.1 + +### --- ELASTICSEARCH --- + +ELASTICSEARCH_TAG=7-4.3.1 + +### --- KIBANA --- + +KIBANA_TAG=7-4.3.1 + +### --- REDIS --- + +REDIS_TAG=4-3.0.8 + +### --- NODE --- + +NODE_TAG=12-0.17.0 + +### --- VARNISH --- + +VARNISH_TAG=6.0-4.2.9 + +### --- POSTGRESQL ---- + +POSTGRES_TAG=11-1.6.3 + +### OTHERS + +ADMINER_TAG=4-3.5.12 +APACHE_TAG=2.4-4.0.7 +ATHENAPDF_TAG=2.10.0 +DRUPAL_NODE_TAG=1.0-2.0.0 +MEMCACHED_TAG=1-2.2.6 +OPENSMTPD_TAG=6.0-1.4.2 +RSYSLOG_TAG=latest +WEBGRIND_TAG=1.5-1.9.12 +XHPROF_TAG=1.3.12 + +### PUSH Notifications +FIREBASE_SERVER_KEY="" +FIREBASE_SENDER_ID="" +### Unsplash media +UNSPLASH_APP_NAME="" +UNSPLASH_ACCESS_KEY="" diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..a37894e --- /dev/null +++ b/.gitattributes @@ -0,0 +1,61 @@ +# Drupal git normalization +# @see https://www.kernel.org/pub/software/scm/git/docs/gitattributes.html +# @see https://www.drupal.org/node/1542048 + +# Normally these settings would be done with macro attributes for improved +# readability and easier maintenance. However macros can only be defined at the +# repository root directory. Drupal avoids making any assumptions about where it +# is installed. + +# Define text file attributes. +# - Treat them as text. +# - Ensure no CRLF line-endings, neither on checkout nor on checkin. +# - Detect whitespace errors. +# - Exposed by default in `git diff --color` on the CLI. +# - Validate with `git diff --check`. +# - Deny applying with `git apply --whitespace=error-all`. +# - Fix automatically with `git apply --whitespace=fix`. + +*.config text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.css text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.dist text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.engine text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php +*.html text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=html +*.inc text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php +*.install text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php +*.js text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.json text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.lock text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.map text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.md text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.module text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php +*.php text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php +*.po text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.profile text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php +*.script text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.sh text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php +*.sql text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.svg text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.theme text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php +*.twig text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.txt text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.xml text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.yml text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 + +# Define binary file attributes. +# - Do not treat them as text. +# - Include binary diff in patches instead of "binary files differ." +*.eot -text diff +*.exe -text diff +*.gif -text diff +*.gz -text diff +*.ico -text diff +*.jpeg -text diff +*.jpg -text diff +*.otf -text diff +*.phar -text diff +*.png -text diff +*.svgz -text diff +*.ttf -text diff +*.woff -text diff +*.woff2 -text diff diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d66a10d --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.env +db_backup.sql +/files/ +/private/ +/simplesamlphp/ +/vendor/ \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..5a3b11b --- /dev/null +++ b/.travis.yml @@ -0,0 +1,43 @@ +language: php +dist: trusty +sudo: false + +php: + - 7.0 + - 7.1 + - 7.2 + - 7.3 + +env: + global: + - SIMPLETEST_DB=sqlite://tmp/site.sqlite + - SIMPLETEST_BASE_URL="http://127.0.0.1:8080" + matrix: + - RELEASE=stable COMPOSER_CHANNEL=stable + - RELEASE=dev COMPOSER_CHANNEL=stable + - RELEASE=stable COMPOSER_CHANNEL=snapshot + +before_install: + - echo 'sendmail_path = /bin/true' >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini + - phpenv config-rm xdebug.ini + - composer --verbose self-update --$COMPOSER_CHANNEL + - composer --version + +install: + - composer --verbose validate + - composer --verbose install + +script: + - if [[ $RELEASE = dev ]]; then composer --verbose remove --no-update drupal/console; fi; + - if [[ $RELEASE = dev ]]; then composer --verbose require --no-update drupal/core:8.8.x-dev webflo/drupal-core-require-dev:8.8.x-dev; fi; + - if [[ $RELEASE = dev ]]; then composer --verbose update; fi; + - cd $TRAVIS_BUILD_DIR/web + - ./../vendor/bin/drush site-install --verbose --yes --db-url=sqlite://tmp/site.sqlite + - ./../vendor/bin/drush runserver $SIMPLETEST_BASE_URL & + - until curl -s $SIMPLETEST_BASE_URL; do true; done > /dev/null + # Skip core/tests/Drupal/Tests/ComposerIntegrationTest.php because web/ has no composer.json + # Ignore PageCache group temporarily, @see https://www.drupal.org/node/2770673 + # Ignore Setup group temporarily, @see https://www.drupal.org/node/2962157 + - ./../vendor/bin/phpunit -c core --testsuite unit --exclude-group Composer,DependencyInjection,PageCache,Setup + - ./../vendor/bin/drush + - if [[ $RELEASE = stable ]]; then ./../vendor/bin/drupal; fi; diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..ebfc64c --- /dev/null +++ b/Dockerfile @@ -0,0 +1,65 @@ +ARG ALPINE_VERSION=3.14 + +# for template build +FROM alpine:${ALPINE_VERSION} as template-build +ARG ALPINE_VERSION + +RUN apk add --no-cache nodejs npm python3 + +WORKDIR /theme +COPY web/themes/custom/perls /theme + +RUN npm rebuild node-sass && npm install +RUN ./node_modules/.bin/gulp build-theme + +# for production usage +FROM alpine:${ALPINE_VERSION} as prod +ARG ALPINE_VERSION +ARG version + +ENV PHP_OPCACHE_VALIDATE_TIMESTAMPS 0 +ENV APP_PATH /var/www/html + +RUN apk add --no-cache \ + apache2 php7 php7-apache2 \ + php7-gd php7-zip php7-dom php7-tokenizer php7-pdo_mysql php7-pdo_sqlite php7-session php7-xml \ + php7-exif php7-xmlwriter php7-xmlreader php7-ctype php7-simplexml php7-opcache php7-soap php7-sodium \ + bash patch git composer wget php7-pecl-redis shadow + +RUN usermod -u 1000 apache && groupmod -g 1000 apache + +COPY .docker/php.ini /etc/php7/conf.d/99_php.ini +COPY .docker/php.opcache.ini /etc/php7/conf.d/99_opcache.ini +COPY .docker/apache-default.conf /etc/apache2/conf.d/default.conf +RUN chown -R apache:apache /tmp + +WORKDIR $APP_PATH + +COPY --chown=root:apache . $APP_PATH + +ENV VERSION=${version} + +RUN composer install --no-dev --no-cache + +ENV PATH $PATH:$APP_PATH/vendor/drush/drush +COPY --from=template-build --chown=root:apache /theme $APP_PATH/web/themes/custom/perls + +EXPOSE 80 + +CMD httpd -DFOREGROUND + +# for development usage +FROM prod as dev + +ENV PHP_OPCACHE_VALIDATE_TIMESTAMPS 1 + +RUN apk add --no-cache tini openssh-client mariadb-client nodejs npm rsync php7-pecl-xdebug $PHPIZE_DEPS + +RUN composer install --no-cache + +RUN mkdir /dev-tools +COPY .docker/docker-php-ext-xdebug.ini /dev-tools/docker-php-ext-xdebug.ini +COPY .docker/entrypoint-dev.sh /entrypoint-dev.sh + +ENTRYPOINT ["/sbin/tini", "--"] +CMD ["/entrypoint-dev.sh"] diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..0449465 --- /dev/null +++ b/Makefile @@ -0,0 +1,9 @@ +include docker.mk + +.PHONY: test + +DRUPAL_VER ?= 8 +PHP_VER ?= 7.2 + +test: + cd ./tests/$(DRUPAL_VER) && PHP_VER=$(PHP_VER) ./run.sh diff --git a/README.md b/README.md new file mode 100644 index 0000000..b41d475 --- /dev/null +++ b/README.md @@ -0,0 +1,157 @@ +# PERLS Web Application + +The PERLS Web application contains the Learner web app, CMS, and a REST interface to drive data to and from the mobile application. The system is built on Drupal 9 and uses Docker containers to run services for easy configuration and deployment. + +Ensure all the requirements are met and follow the install instructions to get started. + +## Installation + +There are a few ways to deploy PERLS, but the simplest way would be to just use Docker and configure a non-root user. + +### Local Deployment TL;DR + +Assuming you are on an Ubuntu 20+ machine with Docker and Docker-Compose installed: + +- Download the [Starter Content](https://github.com/adlnet/perls/releases/download/v3.0.0/starter-content.zip) +- `git clone https://github.com/adlnet/perls` +- `cd perls` +- From the Starter Content, add the `files` folder and `db_backup.sql` to the project root +- `cp .env.example .env` and configure your `.env` file (see below) +- `./scripts/build.sh -l -n` +- `docker exec PERLS_php ./scripts/styles.sh` + +Once everything's up, the default login is just: +``` +username: admin@example.com +password: password +``` + +and it should be accessible at `perls.localhost:8000`. + + +## Development Environment + +Standing up a development environment is a bit more involved and requires things to be installed locally on your machine. + +### Requirements + +* [Docker](https://www.docker.com/) +* [Composer](https://getcomposer.org) +* [PHP CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer#installation) +* Port 8000 (development) or port 80 (production) and 3306 must be available + +### Building the Development Environment +The fastest way to set up your development environment is to have a starter database (i.e. synced from a staging environment). + +After completion, you can reach your local environment at: +http://perls.localhost:8000 + +#### Option A: With a Starter Database (db_backup.sql) +Your working directory must contain a `db_backup.sql` file. + +``` bash +./scripts/build.sh -l -n +``` + +#### Option B: Without a Starter Database +You can still run the build script without a starter database. In this instance, Drupal will attempt to build the site from scratch and then save the database to `db_backup.sql` (to save time on future builds). **This will take a long time.** + +``` bash +./scripts/build.sh -l +``` + +#### Option C: From a Staging Environment +You can also define a `stage` drush site alias and build your local development environment from an existing remote environment. + +See the drush documentation on [creating a site alias](https://www.drush.org/latest/site-aliases/). With the site alias defined, you can execute: + +``` bash +./scripts/build.sh +``` + +#### Tip +If your staging environment requires an SSH key, you can place that in `.ssh`. + +## Environment Variables +The development environment is built by default when using the given `.env` and build script. +If these have been modified, ensure the environment variable `PROJECT_ENV` is set to `dev`. +This allows certain modules and configurations to be installed which improve quality of life when developing. + +* `PROJECT_ENV` +* `DB_HOST` - Database host name. Default value is `mariadb` +* `DB_NAME` - Database name. Default value: `drupal_perls`. +* `DB_PASSWORD` - Database password. Default value is `drupal`. +* `DB_HOST_PORT` - Database port. Default value is `3306`. +* `DB_USER` - Databse user. Default value is `drupal`. +* `DB_DRIVER` - Database user. Default value is `mysql`. +* `SMTP_HOST` - SMTP server host name. Default value is `mailhog`. +* `SMTP_PORT` - SMTP server port. Default value is `1025`. +* `SMTP_FROM` - Sender email address. Default value is `perls@dev.local`. + +There are some service what you can configure from .env file. +* `LRS_HOST` - Host name of the LRS server +* `LRS_USERNAME` - Account name +* `LRS_PASSWORD` - Password of LRS account +* `FIREBASE_SERVER_KEY` - Server key for firebase service, which sends out push notifications. +* `FIREBASE_SENDER_ID` - Served ID of firebase. +* `UNSPLASH_APP_NAME` - Account name of unsplash free image service. +* `UNSPLASH_ACCESS_KEY` - Access key of unsplash service. + +SSO +* `SIMPLESAML_AUTH_SOURCE` - This key will store the authentication source config +* `SIMPLESAML_CONFIG_DIR` - Where uploaded IdP metadata is stored +* `SIMPLESAML_SSO_SP_METADATA_FILE` - Mame of the Service Provider metadata file downloaded from the web interface + + +## Debuggging +### Rebuilding styles + +``` bash +docker exec PERLS_php ./scripts/styles.sh +``` + +### Using xdebug +Xdebug can be enabled by setting the `ENABLE_XDEBUG` environment variable to `true` on the PHP container in `docker-compose.yml` and restarting the stack. + +### Troubleshooting + +See [Troubleshooting](./readme/troubleshooting.md) + +## Testing + +This project has behat feature tests. They are best run from inside the PHP docker container. +This can be achieved by running: + +``` bash +./scripts/test.sh +``` + +## Guidelines + +### Coding standards + +Code should be readible, portable, and standardize. Since the web application is based on Drupal, +all custom code should be placed in the appropriate locations (either theme/custom or modules/custom). +Changes should not be made to Drupal Core so other releases of Drupal can be easily updated. + +The code should follow [Drupal's coding standards](https://www.drupal.org/node/318) which can be enforced with +PHPCodeSniffer. + +A good place to start writing a custom module in order to change/update functionality of Drupal, +follow the Drupal documentation [Creating custom modules](https://www.drupal.org/docs/creating-custom-modules). +It contains a code skeleton, naming standards, and other information to get started. + +When developing, follow the [contribution guidelines](#contribution-guidelines) and +[Drupal's guidelines](https://www.drupal.org/docs/develop). + +### Maintenance + +See [Maintenance](./readme/maintenance.md) + +### Security + +See [Security](./readme/security.md) + +------- +Created by Float. +For more information, contact them at diff --git a/acknowledgements.md b/acknowledgements.md new file mode 100644 index 0000000..7a02f69 --- /dev/null +++ b/acknowledgements.md @@ -0,0 +1,354 @@ +# Acknowledgements +## docker4drupal + +The MIT License (MIT) +Copyright (c) 2016 Wodby, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +## Drupal + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + {description} + Copyright (C) {year} {fullname} + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + {signature of Ty Coon}, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/admin_api/cloud_formation_templates/PERLS-lambda-gateway.yml b/admin_api/cloud_formation_templates/PERLS-lambda-gateway.yml new file mode 100644 index 0000000..b0cc9c4 --- /dev/null +++ b/admin_api/cloud_formation_templates/PERLS-lambda-gateway.yml @@ -0,0 +1,852 @@ +AWSTemplateFormatVersion: 2010-09-09 +Parameters: + AdminUUID: + Description: Admin UUID of the LRS + Type: String + Role: + Description: IAM Role for the funcitons to use + Type: String + BaseStack: + Description: Base Stack to pull info from + Type: String + FunctionsBucket: + Description: S3 Bucket name to pull the functions from + Type: String + CodeBucket: + Description: Bucket to access CMS Versions + Type: String + LRSAdminURL: + Description: Url of the LRS admin api + Type: String + LRSBaseURL: + Description: Base url of the LRS + Type: String + LRSAPIKey: + Description: API key for the admin functions of the lrs + Type: String + CMSBaseURL: + Description: base url for cms + Type: String + Default: usalearning.net + Project: + Description: Project for tenant cloudformation script + Type: String + Default: perls + SNSTopic: + Description: SNS topic to send alerts and notifications + Type: String + FIREBASEKEY: + Description: Key for sending push notifications + Type: String + FIREBASEID: + Description: ID for sending push notifications + Type: String + SecurityGroup: + Description: Security Group ID to use for Lambda functions + Type: String + +Resources: + EFSSolrAP: + Type: 'AWS::EFS::AccessPoint' + Properties: + FileSystemId: + Fn::ImportValue: + !Sub ${BaseStack}-EFS + PosixUser: + Uid: "8983" + Gid: "8983" + SecondaryGids: + - "1000" + RootDirectory: + CreationInfo: + OwnerGid: "1000" + OwnerUid: "1000" + Permissions: "0755" + Path: / + + EFSFilesAP: + Type: 'AWS::EFS::AccessPoint' + Properties: + FileSystemId: + Fn::ImportValue: + !Sub ${BaseStack}-EFS + PosixUser: + Uid: "1000" + Gid: "1000" + RootDirectory: + Path: / + + RootAP: + Type: 'AWS::EFS::AccessPoint' + Properties: + FileSystemId: + Fn::ImportValue: + !Sub ${BaseStack}-EFS + PosixUser: + Uid: "1000" + Gid: "1000" + RootDirectory: + CreationInfo: + OwnerGid: "1000" + OwnerUid: "1000" + Permissions: "0755" + Path: / + + AdminFunction: + Type: AWS::Lambda::Function + Properties: + FunctionName: admin_function + Handler: admin_container.lambda_handler + Role: !Sub ${Role} + Code: + S3Bucket: !Sub ${FunctionsBucket} + S3Key: functions/admin_container.zip + Runtime: python3.8 + Timeout: 600 + Environment: + Variables: + base_stack: !Sub ${BaseStack} + VpcConfig: + SecurityGroupIds: + - + !Sub ${SecurityGroup} + SubnetIds: + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet1 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet2 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet3 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet4 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet5 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet6 + + ConfigExportFunction: + Type: AWS::Lambda::Function + Properties: + FunctionName: config_export + Handler: config_export.lambda_handler + Role: !Sub ${Role} + Code: + S3Bucket: !Sub ${FunctionsBucket} + S3Key: functions/config_export.zip + Runtime: python3.8 + Timeout: 600 + Environment: + Variables: + base_stack: !Sub ${BaseStack} + VpcConfig: + SecurityGroupIds: + - + !Sub ${SecurityGroup} + SubnetIds: + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet1 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet2 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet3 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet4 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet5 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet6 + + CreateSolrFSFunction: + Type: AWS::Lambda::Function + Properties: + FunctionName: create_solr_fs + Handler: create_solr_fs.lambda_handler + Role: !Sub ${Role} + Code: + S3Bucket: !Sub ${FunctionsBucket} + S3Key: functions/create_solr_fs.zip + Runtime: python3.8 + Timeout: 180 + Environment: + Variables: + base_stack: !Sub ${BaseStack} + FileSystemConfigs: + - + Arn: !GetAtt EFSSolrAP.Arn + LocalMountPath: /mnt/efs + VpcConfig: + SecurityGroupIds: + - + !Sub ${SecurityGroup} + SubnetIds: + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet1 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet2 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet3 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet4 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet5 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet6 + + CreateFilesDirectoriesFunction: + Type: AWS::Lambda::Function + Properties: + FunctionName: create_files_directories + Handler: create_files_directories.lambda_handler + Role: !Sub ${Role} + Code: + S3Bucket: !Sub ${FunctionsBucket} + S3Key: functions/create_files_directories.zip + Runtime: python3.8 + Timeout: 600 + Environment: + Variables: + base_stack: !Sub ${BaseStack} + FileSystemConfigs: + - + Arn: !GetAtt EFSFilesAP.Arn + LocalMountPath: /mnt/efs + VpcConfig: + SecurityGroupIds: + - + !Sub ${SecurityGroup} + SubnetIds: + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet1 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet2 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet3 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet4 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet5 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet6 + + CronFunction: + Type: AWS::Lambda::Function + Properties: + FunctionName: cron_function + Handler: cron.lambda_handler + Role: !Sub ${Role} + Code: + S3Bucket: !Sub ${FunctionsBucket} + S3Key: functions/cron.zip + Runtime: python3.8 + Timeout: 60 + VpcConfig: + SecurityGroupIds: + - + !Sub ${SecurityGroup} + SubnetIds: + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet1 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet2 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet3 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet4 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet5 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet6 + + InvokeDeleteFunction: + Type: AWS::Lambda::Function + Properties: + FunctionName: invoke_delete + Handler: invoke_delete.lambda_handler + Role: !Sub ${Role} + Code: + S3Bucket: !Sub ${FunctionsBucket} + S3Key: functions/invoke_delete.zip + Runtime: python3.8 + Timeout: 30 + VpcConfig: + SecurityGroupIds: + - + !Sub ${SecurityGroup} + SubnetIds: + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet1 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet2 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet3 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet4 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet5 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet6 + + DeleteTenantFunction: + Type: AWS::Lambda::Function + Properties: + FunctionName: delete_tenant + Handler: delete_tenant.lambda_handler + Role: !Sub ${Role} + Code: + S3Bucket: !Sub ${FunctionsBucket} + S3Key: functions/delete_tenant.zip + Environment: + Variables: + lrs_url: !Sub ${LRSAdminURL} + lrs_api_key: !Sub ${LRSAPIKey} + FileSystemConfigs: + - + Arn: !GetAtt RootAP.Arn + LocalMountPath: /mnt/efs + Runtime: python3.8 + Timeout: 600 + VpcConfig: + SecurityGroupIds: + - + !Sub ${SecurityGroup} + SubnetIds: + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet1 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet2 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet3 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet4 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet5 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet6 + + GetVersionsFunction: + Type: AWS::Lambda::Function + Properties: + FunctionName: get_versions + Handler: get_versions.lambda_handler + Role: !Sub ${Role} + Code: + S3Bucket: !Sub ${FunctionsBucket} + S3Key: functions/get_versions.zip + Environment: + Variables: + s3_bucket: !Sub ${CodeBucket} + lrs_api_key: !Sub ${LRSAPIKey} + Runtime: python3.8 + Timeout: 60 + VpcConfig: + SecurityGroupIds: + - + !Sub ${SecurityGroup} + SubnetIds: + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet1 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet2 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet3 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet4 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet5 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet6 + + CreateDBFunction: + Type: AWS::Lambda::Function + Properties: + FunctionName: create_db + Handler: create_db.lambda_handler + Role: !Sub ${Role} + Code: + S3Bucket: !Sub ${FunctionsBucket} + S3Key: functions/create_db.zip + FileSystemConfigs: + - + Arn: !GetAtt RootAP.Arn + LocalMountPath: /mnt/efs + MemorySize: 512 + Runtime: python3.8 + Timeout: 300 + VpcConfig: + SecurityGroupIds: + - + !Sub ${SecurityGroup} + SubnetIds: + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet1 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet2 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet3 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet4 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet5 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet6 + + CreateLRSFunction: + Type: AWS::Lambda::Function + Properties: + FunctionName: create_lrs + Handler: create_lrs.lambda_handler + Role: !Sub ${Role} + Code: + S3Bucket: !Sub ${FunctionsBucket} + S3Key: functions/create_lrs.zip + Environment: + Variables: + lrs_base_url: !Sub ${LRSBaseURL} + lrs_api_key: !Sub ${LRSAPIKey} + admin_uuid: !Sub ${AdminUUID} + Runtime: python3.8 + Timeout: 180 + VpcConfig: + SecurityGroupIds: + - + !Sub ${SecurityGroup} + SubnetIds: + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet1 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet2 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet3 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet4 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet5 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet6 + + CreatePasswordFunction: + Type: AWS::Lambda::Function + Properties: + FunctionName: create_passwords + Handler: create_passwords.lambda_handler + Role: !Sub ${Role} + Code: + S3Bucket: !Sub ${FunctionsBucket} + S3Key: functions/create_passwords.zip + Environment: + Variables: + s3_bucket: !Sub ${CodeBucket} + base_stack: !Sub ${BaseStack} + Runtime: python3.8 + Timeout: 180 + VpcConfig: + SecurityGroupIds: + - + !Sub ${SecurityGroup} + SubnetIds: + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet1 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet2 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet3 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet4 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet5 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet6 + + CreateStackFunction: + Type: AWS::Lambda::Function + Properties: + FunctionName: create_stack + Handler: create_stack.lambda_handler + Role: !Sub ${Role} + Code: + S3Bucket: !Sub ${FunctionsBucket} + S3Key: functions/create_stack.zip + Environment: + Variables: + s3_bucket: !Sub ${CodeBucket} + base_stack: !Sub ${BaseStack} + cms_base_url: !Sub ${CMSBaseURL} + lrs_base_url: !Sub ${LRSBaseURL} + project: !Sub ${Project} + snstopic: !Sub ${SNSTopic} + firebase_key: !Sub ${FIREBASEKEY} + firebase_id: !Sub ${FIREBASEID} + FileSystemConfigs: + - + Arn: !GetAtt RootAP.Arn + LocalMountPath: /mnt/efs + Runtime: python3.8 + Timeout: 600 + VpcConfig: + SecurityGroupIds: + - + !Sub ${SecurityGroup} + SubnetIds: + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet1 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet2 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet3 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet4 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet5 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet6 + + TenantStatusFunction: + Type: AWS::Lambda::Function + Properties: + FunctionName: tenant_status + Handler: tenant_status.lambda_handler + Role: !Sub ${Role} + Code: + S3Bucket: !Sub ${FunctionsBucket} + S3Key: functions/tenant_status.zip + Runtime: python3.8 + Timeout: 30 + VpcConfig: + SecurityGroupIds: + - + !Sub ${SecurityGroup} + SubnetIds: + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet1 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet2 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet3 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet4 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet5 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet6 + + TenantStatusListFunction: + Type: AWS::Lambda::Function + Properties: + FunctionName: tenant_status_list + Handler: tenant_list.lambda_handler + Role: !Sub ${Role} + Code: + S3Bucket: !Sub ${FunctionsBucket} + S3Key: functions/tenant_list.zip + Runtime: python3.8 + Timeout: 30 + VpcConfig: + SecurityGroupIds: + - + !Sub ${SecurityGroup} + SubnetIds: + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet1 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet2 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet3 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet4 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet5 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet6 + + UpdateFunction: + Type: AWS::Lambda::Function + Properties: + FunctionName: update + Handler: update.lambda_handler + Role: !Sub ${Role} + Code: + S3Bucket: !Sub ${FunctionsBucket} + S3Key: functions/update.zip + Environment: + Variables: + s3_bucket: !Sub ${CodeBucket} + Runtime: python3.8 + Timeout: 30 + VpcConfig: + SecurityGroupIds: + - + !Sub ${SecurityGroup} + SubnetIds: + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet1 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet2 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet3 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet4 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet5 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet6 + + UpdateStackFunction: + Type: AWS::Lambda::Function + Properties: + FunctionName: update_stack + Handler: update_stack.lambda_handler + Role: !Sub ${Role} + Code: + S3Bucket: !Sub ${FunctionsBucket} + S3Key: functions/update_stack.zip + Environment: + Variables: + s3_bucket: !Sub ${CodeBucket} + Runtime: python3.8 + Timeout: 600 + VpcConfig: + SecurityGroupIds: + - + !Sub ${SecurityGroup} + SubnetIds: + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet1 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet2 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet3 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet4 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet5 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet6 + + apiGateway: + Type: AWS::ApiGateway::RestApi + DependsOn: [AdminFunction, ConfigExportFunction, CreateSolrFSFunction, CronFunction, InvokeDeleteFunction, DeleteTenantFunction, GetVersionsFunction, CreateDBFunction, CreateLRSFunction, CreatePasswordFunction, CreateStackFunction, TenantStatusFunction, TenantStatusListFunction, UpdateFunction, UpdateStackFunction] + Properties: + Description: API for managing tenants + EndpointConfiguration: + Types: + - REGIONAL + Name: tenant-api + + CreateTenantResource: + Type: 'AWS::ApiGateway::Resource' + Properties: + RestApiId: !Ref apiGateway + ParentId: !GetAtt + - apiGateway + - RootResourceId + PathPart: tenant + + TenantResource: + Type: 'AWS::ApiGateway::Resource' + Properties: + RestApiId: !Ref apiGateway + ParentId: !Ref CreateTenantResource + PathPart: '{tenant}' + + TenantListResource: + Type: 'AWS::ApiGateway::Resource' + Properties: + RestApiId: !Ref apiGateway + ParentId: !GetAtt + - apiGateway + - RootResourceId + PathPart: tenant-list + + VersionsResource: + Type: 'AWS::ApiGateway::Resource' + Properties: + RestApiId: !Ref apiGateway + ParentId: !GetAtt + - apiGateway + - RootResourceId + PathPart: versions + + CreateTenantMethod: + Type: AWS::ApiGateway::Method + Properties: + ApiKeyRequired: true + AuthorizationType: NONE + HttpMethod: POST + Integration: + IntegrationHttpMethod: POST + Type: AWS_PROXY + Uri: !Sub + - arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${lambdaArn}/invocations + - lambdaArn: !GetAtt CreatePasswordFunction.Arn + ResourceId: !Ref CreateTenantResource + RestApiId: !Ref apiGateway + + DeleteTenantMethod: + Type: AWS::ApiGateway::Method + Properties: + ApiKeyRequired: true + AuthorizationType: NONE + HttpMethod: DELETE + Integration: + IntegrationHttpMethod: POST + Type: AWS_PROXY + Uri: !Sub + - arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${lambdaArn}/invocations + - lambdaArn: !GetAtt InvokeDeleteFunction.Arn + ResourceId: !Ref TenantResource + RestApiId: !Ref apiGateway + + UpdateTenantMethod: + Type: AWS::ApiGateway::Method + Properties: + ApiKeyRequired: true + AuthorizationType: NONE + HttpMethod: PATCH + Integration: + IntegrationHttpMethod: POST + Type: AWS_PROXY + Uri: !Sub + - arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${lambdaArn}/invocations + - lambdaArn: !GetAtt UpdateFunction.Arn + ResourceId: !Ref TenantResource + RestApiId: !Ref apiGateway + + GetTenantStatusMethod: + Type: AWS::ApiGateway::Method + Properties: + ApiKeyRequired: true + AuthorizationType: NONE + HttpMethod: GET + Integration: + IntegrationHttpMethod: POST + Type: AWS_PROXY + Uri: !Sub + - arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${lambdaArn}/invocations + - lambdaArn: !GetAtt TenantStatusFunction.Arn + ResourceId: !Ref TenantResource + RestApiId: !Ref apiGateway + + GetVersionsMethod: + Type: AWS::ApiGateway::Method + Properties: + ApiKeyRequired: true + AuthorizationType: NONE + HttpMethod: GET + Integration: + IntegrationHttpMethod: POST + Type: AWS_PROXY + Uri: !Sub + - arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${lambdaArn}/invocations + - lambdaArn: !GetAtt GetVersionsFunction.Arn + ResourceId: !Ref VersionsResource + RestApiId: !Ref apiGateway + + TenantListMethod: + Type: AWS::ApiGateway::Method + Properties: + ApiKeyRequired: true + AuthorizationType: NONE + HttpMethod: GET + Integration: + IntegrationHttpMethod: POST + Type: AWS_PROXY + Uri: !Sub + - arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${lambdaArn}/invocations + - lambdaArn: !GetAtt TenantStatusListFunction.Arn + ResourceId: !Ref TenantListResource + RestApiId: !Ref apiGateway + + apiGatewayDeployment: + Type: AWS::ApiGateway::Deployment + DependsOn: [GetVersionsMethod, CreateTenantMethod, TenantListMethod, GetTenantStatusMethod, UpdateTenantMethod, DeleteTenantMethod] + Properties: + RestApiId: !Ref apiGateway + StageName: api + + apiKey: + Type: AWS::ApiGateway::ApiKey + DependsOn: apiGatewayDeployment + Properties: + Name: AdminAPIKey + Description: Admin API Key + Enabled: 'true' + StageKeys: + - RestApiId: !Ref apiGateway + StageName: api + + usagePlan: + Type: AWS::ApiGateway::UsagePlan + DependsOn: apiGatewayDeployment + Properties: + ApiStages: + - ApiId: !Ref apiGateway + Stage: api + Description: Tenant API usage plan + Quota: + Limit: 100 + Period: MONTH + Throttle: + BurstLimit: 1 + RateLimit: 1 + UsagePlanName: tenant_api_usage_plan + + usagePlanKey: + Type: AWS::ApiGateway::UsagePlanKey + Properties: + KeyId: !Ref apiKey + KeyType: API_KEY + UsagePlanId: !Ref usagePlan + + CreateTenantInvoke: + Type: AWS::Lambda::Permission + Properties: + FunctionName: !GetAtt CreatePasswordFunction.Arn + Action: lambda:InvokeFunction + Principal: apigateway.amazonaws.com + SourceArn: !Sub arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${apiGateway}/*/POST/tenant + + TenantStatusInvoke: + Type: AWS::Lambda::Permission + Properties: + FunctionName: !GetAtt TenantStatusFunction.Arn + Action: lambda:InvokeFunction + Principal: apigateway.amazonaws.com + SourceArn: !Sub arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${apiGateway}/*/GET/tenant/{tenant} + + DeleteTenantApiGatewayInvoke: + Type: AWS::Lambda::Permission + Properties: + Action: lambda:InvokeFunction + FunctionName: !GetAtt InvokeDeleteFunction.Arn + Principal: apigateway.amazonaws.com + SourceArn: !Sub arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${apiGateway}/*/DELETE/tenant/{tenant} + + UpdateTenantApiGatewayInvoke: + Type: AWS::Lambda::Permission + Properties: + Action: lambda:InvokeFunction + FunctionName: !GetAtt UpdateFunction.Arn + Principal: apigateway.amazonaws.com + SourceArn: !Sub arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${apiGateway}/*/PATCH/tenant/{tenant} + + GetVersionsApiGatewayInvoke: + Type: AWS::Lambda::Permission + Properties: + Action: lambda:InvokeFunction + FunctionName: !GetAtt GetVersionsFunction.Arn + Principal: apigateway.amazonaws.com + SourceArn: !Sub arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${apiGateway}/*/GET/versions + + TenantListApiGatewayInvoke: + Type: AWS::Lambda::Permission + Properties: + Action: lambda:InvokeFunction + FunctionName: !GetAtt TenantStatusListFunction.Arn + Principal: apigateway.amazonaws.com + SourceArn: !Sub arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${apiGateway}/*/GET/tenant-list + +Outputs: + CronFunction: + Value: !GetAtt CronFunction.Arn + Export: + Name: !Sub "${AWS::StackName}-CronFunction" diff --git a/admin_api/config_export.sh b/admin_api/config_export.sh new file mode 100644 index 0000000..d6df58c --- /dev/null +++ b/admin_api/config_export.sh @@ -0,0 +1,4 @@ +#!/bin/bash +drush config-split:export ignored_config -y +# This trigger a warning if the tenant_overrides isn't active. +drush config-split:export tenant_overrides -y diff --git a/admin_api/create_cms.sh b/admin_api/create_cms.sh new file mode 100755 index 0000000..be2b110 --- /dev/null +++ b/admin_api/create_cms.sh @@ -0,0 +1,47 @@ +#!/bin/bash +while [[ $# -gt 0 ]]; do + case $1 in + -u|--cms_username) + CMS_USERNAME="$2" + shift + shift + ;; + -e|--email) + EMAIL="$2" + shift + shift + ;; + -n|--full_name) + FULL_NAME="$2" + shift + shift + ;; + -c|--cron_key) + CRON_KEY="$2" + shift + shift + ;; + -*|--*) + echo "Unknown option $1" + echo "Necessary options:" + echo "-u|--cms_username" + echo "-e|--email" + echo "-n|--full_name" + echo "-c|--cron_key" + exit 1 + ;; + esac +done + +if [ -z "$CMS_USERNAME" ]; then echo "User is empty; -u must be specified."; exit -1; fi +if [ -z "$EMAIL" ]; then echo "Email is empty; -e must be specified."; exit -1; fi +if [ -z "$FULL_NAME" ]; then echo "Full name is empty; -n must be specified."; exit -1; fi +if [ -z "$CRON_KEY" ]; then echo "Cron key is empty; -c must be specified."; exit -1; fi + +drush status +drush deploy +drush user:create ${CMS_USERNAME} --mail="${EMAIL}" +drush user-add-role "perls_system_admin" ${CMS_USERNAME} +drush perls:update-user-field ${EMAIL} --field=field_name --value="${FULL_NAME}" +drush state-set system.cron_key $CRON_KEY +drush uli --mail=${EMAIL} diff --git a/admin_api/lambda_functions/.pylintrc b/admin_api/lambda_functions/.pylintrc new file mode 100644 index 0000000..256c406 --- /dev/null +++ b/admin_api/lambda_functions/.pylintrc @@ -0,0 +1,566 @@ +[MASTER] + +# A comma-separated list of package or module names from where C extensions may +# be loaded. Extensions are loading into the active Python interpreter and may +# run arbitrary code. +extension-pkg-allow-list= + +# A comma-separated list of package or module names from where C extensions may +# be loaded. Extensions are loading into the active Python interpreter and may +# run arbitrary code. (This is an alternative name to extension-pkg-allow-list +# for backward compatibility.) +extension-pkg-whitelist= + +# Return non-zero exit code if any of these messages/categories are detected, +# even if score is above --fail-under value. Syntax same as enable. Messages +# specified are enabled, while categories only check already-enabled messages. +fail-on= + +# Specify a score threshold to be exceeded before program exits with error. +fail-under=10.0 + +# Files or directories to be skipped. They should be base names, not paths. +ignore=CVS + +# Add files or directories matching the regex patterns to the ignore-list. The +# regex matches against paths and can be in Posix or Windows format. +ignore-paths= + +# Files or directories matching the regex patterns are skipped. The regex +# matches against base names, not paths. +ignore-patterns= + +# Python code to execute, usually for sys.path manipulation such as +# pygtk.require(). +#init-hook= + +# Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the +# number of processors available to use. +jobs=1 + +# Control the amount of potential inferred values when inferring a single +# object. This can help the performance when dealing with large functions or +# complex, nested conditions. +limit-inference-results=100 + +# List of plugins (as comma separated values of python module names) to load, +# usually to register additional checkers. +load-plugins= + +# Pickle collected data for later comparisons. +persistent=yes + +# Minimum Python version to use for version dependent checks. Will default to +# the version used to run pylint. +py-version=3.8 + +# When enabled, pylint would attempt to guess common misconfiguration and emit +# user-friendly hints instead of false-positive error messages. +suggestion-mode=yes + +# Allow loading of arbitrary C extensions. Extensions are imported into the +# active Python interpreter and may run arbitrary code. +unsafe-load-any-extension=no + + +[MESSAGES CONTROL] + +# Only show warnings with the listed confidence levels. Leave empty to show +# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED. +confidence= + +# Disable the message, report, category or checker with the given id(s). You +# can either give multiple identifiers separated by comma (,) or put this +# option multiple times (only on the command line, not in the configuration +# file where it should appear only once). You can also use "--disable=all" to +# disable everything first and then reenable specific checks. For example, if +# you want to run only the similarities checker, you can use "--disable=all +# --enable=similarities". If you want to run only the classes checker, but have +# no Warning level messages displayed, use "--disable=all --enable=classes +# --disable=W". +disable=raw-checker-failed, + bad-inline-option, + locally-disabled, + file-ignored, + suppressed-message, + useless-suppression, + deprecated-pragma, + use-symbolic-message-instead + +# Enable the message, report, category or checker with the given id(s). You can +# either give multiple identifier separated by comma (,) or put this option +# multiple time (only on the command line, not in the configuration file where +# it should appear only once). See also the "--disable" option for examples. +enable=c-extension-no-member + + +[REPORTS] + +# Python expression which should return a score less than or equal to 10. You +# have access to the variables 'error', 'warning', 'refactor', and 'convention' +# which contain the number of messages in each category, as well as 'statement' +# which is the total number of statements analyzed. This score is used by the +# global evaluation report (RP0004). +evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) + +# Template used to display messages. This is a python new-style format string +# used to format the message information. See doc for all details. +#msg-template= + +# Set the output format. Available formats are text, parseable, colorized, json +# and msvs (visual studio). You can also give a reporter class, e.g. +# mypackage.mymodule.MyReporterClass. +output-format=text + +# Tells whether to display a full report or only the messages. +reports=no + +# Activate the evaluation score. +score=yes + + +[REFACTORING] + +# Maximum number of nested blocks for function / method body +max-nested-blocks=5 + +# Complete name of functions that never returns. When checking for +# inconsistent-return-statements if a never returning function is called then +# it will be considered as an explicit return statement and no message will be +# printed. +never-returning-functions=sys.exit,argparse.parse_error + + +[LOGGING] + +# The type of string formatting that logging methods do. `old` means using % +# formatting, `new` is for `{}` formatting. +logging-format-style=old + +# Logging modules to check that the string format arguments are in logging +# function parameter format. +logging-modules=logging + + +[SPELLING] + +# Limits count of emitted suggestions for spelling mistakes. +max-spelling-suggestions=4 + +# Spelling dictionary name. Available dictionaries: none. To make it work, +# install the 'python-enchant' package. +spelling-dict= + +# List of comma separated words that should be considered directives if they +# appear and the beginning of a comment and should not be checked. +spelling-ignore-comment-directives=fmt: on,fmt: off,noqa:,noqa,nosec,isort:skip,mypy: + +# List of comma separated words that should not be checked. +spelling-ignore-words= + +# A path to a file that contains the private dictionary; one word per line. +spelling-private-dict-file= + +# Tells whether to store unknown words to the private dictionary (see the +# --spelling-private-dict-file option) instead of raising a message. +spelling-store-unknown-words=no + + +[MISCELLANEOUS] + +# List of note tags to take in consideration, separated by a comma. +notes=XXX,FIXME + +# Regular expression of note tags to take in consideration. +#notes-rgx= + + +[TYPECHECK] + +# List of decorators that produce context managers, such as +# contextlib.contextmanager. Add to this list to register other decorators that +# produce valid context managers. +contextmanager-decorators=contextlib.contextmanager + +# List of members which are set dynamically and missed by pylint inference +# system, and so shouldn't trigger E1101 when accessed. Python regular +# expressions are accepted. +generated-members= + +# Tells whether missing members accessed in mixin class should be ignored. A +# class is considered mixin if its name matches the mixin-class-rgx option. +ignore-mixin-members=yes + +# Tells whether to warn about missing members when the owner of the attribute +# is inferred to be None. +ignore-none=yes + +# This flag controls whether pylint should warn about no-member and similar +# checks whenever an opaque object is returned when inferring. The inference +# can return multiple potential results while evaluating a Python object, but +# some branches might not be evaluated, which results in partial inference. In +# that case, it might be useful to still emit no-member and other checks for +# the rest of the inferred objects. +ignore-on-opaque-inference=yes + +# List of class names for which member attributes should not be checked (useful +# for classes with dynamically set attributes). This supports the use of +# qualified names. +ignored-classes=optparse.Values,thread._local,_thread._local + +# List of module names for which member attributes should not be checked +# (useful for modules/projects where namespaces are manipulated during runtime +# and thus existing member attributes cannot be deduced by static analysis). It +# supports qualified module names, as well as Unix pattern matching. +ignored-modules= + +# Show a hint with possible names when a member name was not found. The aspect +# of finding the hint is based on edit distance. +missing-member-hint=yes + +# The minimum edit distance a name should have in order to be considered a +# similar match for a missing member name. +missing-member-hint-distance=1 + +# The total number of similar names that should be taken in consideration when +# showing a hint for a missing member. +missing-member-max-choices=1 + +# Regex pattern to define which classes are considered mixins ignore-mixin- +# members is set to 'yes' +mixin-class-rgx=.*[Mm]ixin + +# List of decorators that change the signature of a decorated function. +signature-mutators= + + +[VARIABLES] + +# List of additional names supposed to be defined in builtins. Remember that +# you should avoid defining new builtins when possible. +additional-builtins= + +# Tells whether unused global variables should be treated as a violation. +allow-global-unused-variables=yes + +# List of names allowed to shadow builtins +allowed-redefined-builtins= + +# List of strings which can identify a callback function by name. A callback +# name must start or end with one of those strings. +callbacks=cb_, + _cb + +# A regular expression matching the name of dummy variables (i.e. expected to +# not be used). +dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_ + +# Argument names that match this expression will be ignored. Default to name +# with leading underscore. +ignored-argument-names=_.*|^ignored_|^unused_|context + +# Tells whether we should check for unused import in __init__ files. +init-import=no + +# List of qualified module names which can have objects that can redefine +# builtins. +redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io + + +[FORMAT] + +# Expected format of line ending, e.g. empty (any line ending), LF or CRLF. +expected-line-ending-format= + +# Regexp for a line that is allowed to be longer than the limit. +ignore-long-lines=^\s*(# )??$ + +# Number of spaces of indent required inside a hanging or continued line. +indent-after-paren=4 + +# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 +# tab). +indent-string=' ' + +# Maximum number of characters on a single line. +max-line-length=100 + +# Maximum number of lines in a module. +max-module-lines=1000 + +# Allow the body of a class to be on the same line as the declaration if body +# contains single statement. +single-line-class-stmt=no + +# Allow the body of an if to be on the same line as the test if there is no +# else. +single-line-if-stmt=no + + +[SIMILARITIES] + +# Comments are removed from the similarity computation +ignore-comments=yes + +# Docstrings are removed from the similarity computation +ignore-docstrings=yes + +# Imports are removed from the similarity computation +ignore-imports=no + +# Signatures are removed from the similarity computation +ignore-signatures=no + +# Minimum lines number of a similarity. +min-similarity-lines=4 + + +[BASIC] + +# Naming style matching correct argument names. +argument-naming-style=snake_case + +# Regular expression matching correct argument names. Overrides argument- +# naming-style. +#argument-rgx= + +# Naming style matching correct attribute names. +attr-naming-style=snake_case + +# Regular expression matching correct attribute names. Overrides attr-naming- +# style. +#attr-rgx= + +# Bad variable names which should always be refused, separated by a comma. +bad-names=foo, + bar, + baz, + toto, + tutu, + tata + +# Bad variable names regexes, separated by a comma. If names match any regex, +# they will always be refused +bad-names-rgxs= + +# Naming style matching correct class attribute names. +class-attribute-naming-style=any + +# Regular expression matching correct class attribute names. Overrides class- +# attribute-naming-style. +#class-attribute-rgx= + +# Naming style matching correct class constant names. +class-const-naming-style=UPPER_CASE + +# Regular expression matching correct class constant names. Overrides class- +# const-naming-style. +#class-const-rgx= + +# Naming style matching correct class names. +class-naming-style=PascalCase + +# Regular expression matching correct class names. Overrides class-naming- +# style. +#class-rgx= + +# Naming style matching correct constant names. +const-naming-style=UPPER_CASE + +# Regular expression matching correct constant names. Overrides const-naming- +# style. +#const-rgx= + +# Minimum line length for functions/classes that require docstrings, shorter +# ones are exempt. +docstring-min-length=-1 + +# Naming style matching correct function names. +function-naming-style=snake_case + +# Regular expression matching correct function names. Overrides function- +# naming-style. +#function-rgx= + +# Good variable names which should always be accepted, separated by a comma. +good-names=i, + j, + k, + ex, + Run, + _ + +# Good variable names regexes, separated by a comma. If names match any regex, +# they will always be accepted +good-names-rgxs= + +# Include a hint for the correct naming format with invalid-name. +include-naming-hint=no + +# Naming style matching correct inline iteration names. +inlinevar-naming-style=any + +# Regular expression matching correct inline iteration names. Overrides +# inlinevar-naming-style. +#inlinevar-rgx= + +# Naming style matching correct method names. +method-naming-style=snake_case + +# Regular expression matching correct method names. Overrides method-naming- +# style. +#method-rgx= + +# Naming style matching correct module names. +module-naming-style=snake_case + +# Regular expression matching correct module names. Overrides module-naming- +# style. +#module-rgx= + +# Colon-delimited sets of names that determine each other's naming style when +# the name regexes allow several styles. +name-group= + +# Regular expression which should only match function or class names that do +# not require a docstring. +no-docstring-rgx=^_ + +# List of decorators that produce properties, such as abc.abstractproperty. Add +# to this list to register other decorators that produce valid properties. +# These decorators are taken in consideration only for invalid-name. +property-classes=abc.abstractproperty + +# Naming style matching correct variable names. +variable-naming-style=snake_case + +# Regular expression matching correct variable names. Overrides variable- +# naming-style. +#variable-rgx= + + +[STRING] + +# This flag controls whether inconsistent-quotes generates a warning when the +# character used as a quote delimiter is used inconsistently within a module. +check-quote-consistency=no + +# This flag controls whether the implicit-str-concat should generate a warning +# on implicit string concatenation in sequences defined over several lines. +check-str-concat-over-line-jumps=no + + +[IMPORTS] + +# List of modules that can be imported at any level, not just the top level +# one. +allow-any-import-level= + +# Allow wildcard imports from modules that define __all__. +allow-wildcard-with-all=no + +# Analyse import fallback blocks. This can be used to support both Python 2 and +# 3 compatible code, which means that the block might have code that exists +# only in one or another interpreter, leading to false positives when analysed. +analyse-fallback-blocks=no + +# Deprecated modules which should not be used, separated by a comma. +deprecated-modules= + +# Output a graph (.gv or any supported image format) of external dependencies +# to the given file (report RP0402 must not be disabled). +ext-import-graph= + +# Output a graph (.gv or any supported image format) of all (i.e. internal and +# external) dependencies to the given file (report RP0402 must not be +# disabled). +import-graph= + +# Output a graph (.gv or any supported image format) of internal dependencies +# to the given file (report RP0402 must not be disabled). +int-import-graph= + +# Force import order to recognize a module as part of the standard +# compatibility libraries. +known-standard-library= + +# Force import order to recognize a module as part of a third party library. +known-third-party=enchant + +# Couples of modules and preferred modules, separated by a comma. +preferred-modules= + + +[CLASSES] + +# Warn about protected attribute access inside special methods +check-protected-access-in-special-methods=no + +# List of method names used to declare (i.e. assign) instance attributes. +defining-attr-methods=__init__, + __new__, + setUp, + __post_init__ + +# List of member names, which should be excluded from the protected access +# warning. +exclude-protected=_asdict, + _fields, + _replace, + _source, + _make + +# List of valid names for the first argument in a class method. +valid-classmethod-first-arg=cls + +# List of valid names for the first argument in a metaclass class method. +valid-metaclass-classmethod-first-arg=cls + + +[DESIGN] + +# List of regular expressions of class ancestor names to ignore when counting +# public methods (see R0903) +exclude-too-few-public-methods= + +# List of qualified class names to ignore when counting class parents (see +# R0901) +ignored-parents= + +# Maximum number of arguments for function / method. +max-args=5 + +# Maximum number of attributes for a class (see R0902). +max-attributes=7 + +# Maximum number of boolean expressions in an if statement (see R0916). +max-bool-expr=5 + +# Maximum number of branch for function / method body. +max-branches=12 + +# Maximum number of locals for function / method body. +max-locals=50 + +# Maximum number of parents for a class (see R0901). +max-parents=7 + +# Maximum number of public methods for a class (see R0904). +max-public-methods=20 + +# Maximum number of return / yield for function / method body. +max-returns=6 + +# Maximum number of statements in function / method body. +max-statements=100 + +# Minimum number of public methods for a class (see R0903). +min-public-methods=2 + + +[EXCEPTIONS] + +# Exceptions that will emit a warning when being caught. Defaults to +# "BaseException, Exception". +overgeneral-exceptions=BaseException, + Exception diff --git a/admin_api/lambda_functions/admin_container.py b/admin_api/lambda_functions/admin_container.py new file mode 100644 index 0000000..d9dd3a6 --- /dev/null +++ b/admin_api/lambda_functions/admin_container.py @@ -0,0 +1,88 @@ +def lambda_handler(event, context): + import boto3 + import time + import json + from decouple import config + + print("Starting Admin container") + session = boto3.Session() + cf_client = session.client('cloudformation') + ecs_client = session.client('ecs') + secrets_client = session.client('secretsmanager') + base_stack = config('base_stack') + tenant_info = event['body'] + tenant_data = json.loads(tenant_info) + tenant = tenant_data['TENANT'].lower() + task_definition = tenant + '-php-admin-task' + method = event['httpMethod'] + + ###check if tenant exists + try: + response = cf_client.describe_stack_resources(StackName=tenant) + except: + raise Exception('Tenant '+ tenant +' does not exist.') + else: + print("Updating Tenant " + tenant) + + ### Wait until the CF stack has finished created/updated + stack_status_complete = 'stack_create_complete' if method == 'POST' else 'stack_update_complete' + try: + waiter = cf_client.get_waiter(stack_status_complete) + waiter.wait(StackName=tenant) + except boto3.exceptions.ClientError as ex: + error_message = ex.response['Error']['Message'] + if error_message == 'No updates are to be performed.': + print("No changes") + else: + raise + + cron_key_secret = secrets_client.get_secret_value(SecretId=tenant + "_cron_key") + cron_key = cron_key_secret['SecretString'] + base_stack_info = cf_client.describe_stacks(StackName=base_stack) + outputs = base_stack_info['Stacks'][0]['Outputs'] + subnets=[] + for output in outputs: + if 'PrivateSubnet' in output['OutputKey']: + subnets.append(output['OutputValue']) + if 'ECSCluster' in output['OutputKey']: + ecs_cluster = output['OutputValue'] + if 'SGECS' in output['OutputKey']: + ecs_security_group = output['OutputValue'] + command = [ + "drush", "deploy" + ] + if method == 'POST': + email = tenant_data['EMAIL'] + cms_username = tenant + "_admin" + full_name = tenant_data['FULL_NAME'] + command = ["sh", "/var/www/html/admin_api/create_cms.sh", + "-u", cms_username, + "-e", email, + "-n", full_name, + "-c", cron_key] + + ecs_client.run_task( + cluster=ecs_cluster, + launchType='FARGATE', + taskDefinition=task_definition, + count=1, + platformVersion='1.4.0', + networkConfiguration={ + 'awsvpcConfiguration': { + 'subnets': subnets, + 'securityGroups': [ + ecs_security_group, + ], + 'assignPublicIp': 'ENABLED' + } + }, + overrides={'containerOverrides': [ + { + 'name': tenant + '-php', + 'command': command + } + ] + } + ) + + return { 'statusCode': 200 } diff --git a/admin_api/lambda_functions/create/create_db.py b/admin_api/lambda_functions/create/create_db.py new file mode 100644 index 0000000..9106a54 --- /dev/null +++ b/admin_api/lambda_functions/create/create_db.py @@ -0,0 +1,68 @@ +def lambda_handler(event, context): + import mysql.connector + import boto3 + import json + import re + from mysql.connector.errors import OperationalError, ProgrammingError + + print("Starting db load") + session = boto3.Session() + secrets_client = session.client('secretsmanager') + version = event['VERSION'] + tenant = event['TENANT'].lower() + brand = event['BRAND'] + db_password_secret = secrets_client.get_secret_value(SecretId=tenant + '_db_password') + db_password = db_password_secret['SecretString'] + db_name = tenant + "_" + brand + access_hosts = "10.0.0.0/255.255.0.0" + rds_secret = secrets_client.get_secret_value(SecretId='rds_admin_login') + rds_info = json.loads(rds_secret['SecretString']) + rds_user = rds_info['username'] + rds_password = rds_info['password'] + rds_host = rds_info['host'] + + sql_file = "/mnt/efs/version/" + version + "/starter/CMS-Database.sql" + + ###create mysql user and db for tenant + mydb = mysql.connector.connect( + host=rds_host, + user=rds_user, + password=rds_password + ) + mycursor = mydb.cursor() + create_mysql_user = "CREATE USER %s@%s IDENTIFIED BY %s" + mycursor.execute(create_mysql_user, (tenant, access_hosts, db_password)) + mycursor.execute("CREATE DATABASE {}".format(db_name)) + grant = "GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, CREATE TEMPORARY TABLES ON {}.* TO %s@%s" + mycursor.execute(grant.format(db_name), (tenant, access_hosts)) + mycursor.execute("Flush Privileges") + mycursor.close() + mydb.close() + + ###import db + tenantdb = mysql.connector.connect( + host=rds_host, + user=rds_user, + password=rds_password, + database=db_name + ) + cursor = tenantdb.cursor() + + statement = "" + for line in open(sql_file, "r"): + if re.match(r'--', line): # ignore sql comment lines + continue + if not re.search(r';$', line): # keep appending lines that don't end in ';' + statement = statement + line + else: # when you get a line ending in ';' then exec statement and reset for next statement + statement = statement + line + try: + cursor.execute(statement) + except (OperationalError, ProgrammingError) as e: + print("[WARN] MySQLError during execute statement Args: '{}'".format(str(e.args))) + statement = "" + tenantdb.commit() + tenantdb.close() + print('Database version ' + version + ' has sucessfully been loaded for ' + tenant) + return { "statusCode": 200 } + diff --git a/admin_api/lambda_functions/create/create_files_directories.py b/admin_api/lambda_functions/create/create_files_directories.py new file mode 100644 index 0000000..bab5d3b --- /dev/null +++ b/admin_api/lambda_functions/create/create_files_directories.py @@ -0,0 +1,36 @@ +"""Copies public starter files +Uses a different method in order to ensure the correct +user is mounted to /efs +""" + +import json +import os +import shutil +def lambda_handler(event, context): + """ + Parameters + ---------- + event: dict, required + API Gateway Lambda Proxy Input Format + + Returns + ------ + API Gateway Lambda Proxy Output Format: dict + """ + + print("Start to copy files process") + tenant_info = event['body'] + tenant_data = json.loads(tenant_info) + version = tenant_data['VERSION'] + tenant = tenant_data['TENANT'].lower() + + print("Create directories") + destination = f"/mnt/efs/{tenant}" + os.mkdir(f'{destination}/private') + + print("Copying public files.") + files_source = f'/mnt/efs/version/{version}/starter/public' + files_dest = f'{destination}/public' + shutil.copytree(files_source, files_dest) + + return {'message': 'Files sucessfully copied'} diff --git a/admin_api/lambda_functions/create/create_lrs.py b/admin_api/lambda_functions/create/create_lrs.py new file mode 100644 index 0000000..08bd40e --- /dev/null +++ b/admin_api/lambda_functions/create/create_lrs.py @@ -0,0 +1,105 @@ +"""Provides handler for creating an LRS via Veracity API +""" +import boto3 +import requests + + +def lambda_handler(event, context): + """Provides handler for creating an LRS via Veracity API + + Parameters + ---------- + event: dict, required + API Gateway Lambda Proxy Input Format + + Returns + ------ + API Gateway Lambda Proxy Output Format: dict + """ + + ## Lambda doesn't understand from XXX import YYY at a global + ## level from what I can tell. Allow from XXX import YYY + from datetime import date # pylint: disable=import-outside-toplevel + from decouple import config # pylint: disable=import-outside-toplevel + + print("Starting creation of the lrs") + toc_date = date.today().strftime("%m/%d/%y") + session = boto3.Session() + secrets_client = session.client('secretsmanager') + lrs_api_key = config('lrs_api_key') + tenant = event['TENANT'].lower() + email = event['EMAIL'] + admin_uuid = config('admin_uuid') + lrs_base_url = config('lrs_base_url') + lrs_user_url = f'{lrs_base_url}admin/api/user' + lrs_lrs_url = f'{lrs_base_url}admin/api/lrs' + lrs_key_url = f'{lrs_base_url}api/{tenant}/xapi-access-keys' + user_password_secret = secrets_client.get_secret_value( + SecretId=f"{tenant}_user_password") + user_password = user_password_secret['SecretString'] + lrs_key_password_secret = secrets_client.get_secret_value( + SecretId=f"{tenant}_lrs_key_password") + lrs_key_password = lrs_key_password_secret['SecretString'] + try: + # TODO: Create Forwarder if they have an LRS already. + + ### Check for existing user + search_query = f'{{"email": "{email}"}}' + lrs_user_response = requests.get(f'{lrs_user_url}?search={search_query}', + headers={"x-veracity-api-key": lrs_api_key}) + lrs_user_info = lrs_user_response.json() + + ### Create a new user if one doesn't exist + if not lrs_user_info: + lrs_create_user_json = { + "username": email, + "email": email, + "publicAccount": True, + "password": user_password, + "acceptsTOS": toc_date, + "verifiedEmail": True + } + lrs_user_response = requests.post(lrs_user_url, + json=lrs_create_user_json, headers={"x-veracity-api-key": lrs_api_key}) + lrs_user_info = lrs_user_response.json() + else: + ## Select first one in array + lrs_user_info = lrs_user_info[0] + + ### Create LRS for Tenant + ### with given user + user_uuid = lrs_user_info['uuid'] + lrs_create_json = { + "owner": admin_uuid, + "lrsName": tenant, + "active": True, + "strict": False, + "compatibilityLevel": 0, + "verboseLogs": True, + "permissions": { + user_uuid: ["lrs.edit", "lrs.**.edit", + "lrs.view", "lrs.**.view"] + } + } + requests.post(lrs_lrs_url, + json=lrs_create_json, headers={"x-veracity-api-key": lrs_api_key}) + + ### Create API Key for LRS + lrs_create_key_json = { + "name": tenant, + "read": True, + "write": True, + "jwt": False, + "enabled": True, + "advancedQueries": True, + "limitedRead": False, + "username": tenant, + "password": lrs_key_password + } + requests.post(lrs_key_url, json=lrs_create_key_json, + headers={"x-veracity-api-key": lrs_api_key}) + except Exception as ex: + print(f'An exception occurred: {ex}') + raise + + return {"message": f'The LRS has been successfully created for tenant {tenant}.'} diff --git a/admin_api/lambda_functions/create/create_passwords.py b/admin_api/lambda_functions/create/create_passwords.py new file mode 100644 index 0000000..993b70d --- /dev/null +++ b/admin_api/lambda_functions/create/create_passwords.py @@ -0,0 +1,102 @@ +def lambda_handler(event, context): + import json + import boto3 + import string + import random + import re + from decouple import config + + print("Starting password creation function") + session = boto3.Session() + lambda_client = session.client('lambda') + secrets_client = session.client('secretsmanager') + cf_client = session.client('cloudformation') + s3_client = session.client('s3') + tenant_info = event['body'] + tenant_data = json.loads(tenant_info) + version = tenant_data['VERSION'] + tenant = tenant_data['TENANT'].lower() + email = tenant_data['EMAIL'] + smtp_password = tenant_data['SMTPPASSWORD'] + base_stack = config('base_stack') + s3_bucket = config('s3_bucket') + tenant_reg = '^[a-zA-Z0-9]+$' + email_reg = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b' + + if re.match(tenant_reg, tenant) and len(tenant) <= 50: + print("Valid tenant name") + else: + return { "statusCode": 400, + "body": "Invalid tenant name" + } + + if re.match(email_reg, email) and len(email) <= 75: + print("Valid email address") + else: + return { "statusCode": 400, + "body": "Invalid email address" + } + + ###check if version is available + version_check = s3_client.list_objects_v2(Bucket=s3_bucket,Prefix=version) + + if version_check['KeyCount'] == 0 : + return { "statusCode": 404, + "body": "CMS Version not available" + } + else: + print("Version " + version + " of the cms exists.") + + ###check if tenant exists + try: + tenant_response = cf_client.describe_stack_resources(StackName=tenant) + except: + print("Tenant does not exist. Creating tenant " + tenant) + else: + return { "statusCode": 400, + "body": "Tenant already exists." + } + + ###check if base stack exists + try: + base_stack_response = cf_client.describe_stack_resources(StackName=base_stack) + except: + raise Exception("The base stack " + base_stack + " does not exist") + + db_password = ''.join(random.choices(string.ascii_uppercase + string.ascii_lowercase + string.digits, k=20)) + secrets_client.create_secret(Name=tenant + "_db_password",SecretString=db_password) + + user_password = ''.join(random.choices(string.ascii_uppercase + string.ascii_lowercase + string.digits, k=20)) + secrets_client.create_secret(Name=tenant + "_user_password", SecretString=user_password) + + lrs_key_password = ''.join(random.choices(string.ascii_uppercase + string.ascii_lowercase + string.digits, k=20)) + secrets_client.create_secret(Name=tenant + "_lrs_key_password",SecretString=lrs_key_password) + + cron_key = ''.join(random.choices(string.ascii_lowercase + string.digits, k=20)) + secrets_client.create_secret(Name=tenant + "_cron_key",SecretString=cron_key) + + secrets_client.create_secret(Name=tenant + "_smtp_password", SecretString=smtp_password) + db_response = lambda_client.invoke( + FunctionName='create_db', + InvocationType='Event', + LogType='Tail', + Payload=tenant_info + ) + print(db_response) + + lrs_response = lambda_client.invoke( + FunctionName='create_lrs', + InvocationType='Event', + LogType='Tail', + Payload=tenant_info + ) + print(lrs_response) + + cf_response = lambda_client.invoke( + FunctionName='create_stack', + InvocationType='Event', + LogType='Tail', + Payload=json.dumps(event) + ) + print(cf_response) + return { 'statusCode': 200 } diff --git a/admin_api/lambda_functions/create/create_solr_fs.py b/admin_api/lambda_functions/create/create_solr_fs.py new file mode 100644 index 0000000..4f62cc6 --- /dev/null +++ b/admin_api/lambda_functions/create/create_solr_fs.py @@ -0,0 +1,19 @@ +def lambda_handler(event, context): + import tarfile + import json + + print("Starting solr fs creation") + tenant_info = event['body'] + tenant_data = json.loads(tenant_info) + version = tenant_data['VERSION'] + tenant = tenant_data['TENANT'].lower() + + print("Copying solr config and index.") + + solr_src="/mnt/efs/version/" + version + "/starter/solr.tar.gz" + dest= "/mnt/efs/" + tenant + "/solr" + my_tar = tarfile.open(solr_src) + my_tar.extractall(dest) + my_tar.close() + + return {'statusCode': 200} \ No newline at end of file diff --git a/admin_api/lambda_functions/create/create_stack.py b/admin_api/lambda_functions/create/create_stack.py new file mode 100644 index 0000000..fbb9ac6 --- /dev/null +++ b/admin_api/lambda_functions/create/create_stack.py @@ -0,0 +1,209 @@ +""" +Triggers jobs to create tenant and dependencies +""" + +import os +import json +import boto3 +def lambda_handler(event, context): + """ + Parameters + ---------- + event: dict, required + API Gateway Lambda Proxy Input Format + + Returns + ------ + API Gateway Lambda Proxy Output Format: dict + """ + + from decouple import config # pylint: disable=import-outside-toplevel + + print("Starting stack creation") + session = boto3.Session() + cf_client = session.client('cloudformation') + secrets_client = session.client('secretsmanager') + elb_client = session.client('elbv2') + lambda_client = session.client('lambda') + tenant_data = json.loads(event['body']) + version = tenant_data['VERSION'] + tenant = tenant_data['TENANT'].lower() + smtp_username = tenant_data['SMTPUSERNAME'] + smtp_host = tenant_data['SMTPHOST'] + smtp_from = tenant_data['SMTPFROM'] + smtp_port = tenant_data['SMTPPORT'] + smtp_protocol = tenant_data.get('SMTPPROTOCOL') or 'tls' + brand = tenant_data['BRAND'] + + #set vars for later use + s3_bucket = config('s3_bucket') + project = config('project') + snstopic = config('snstopic') + base_stack = config('base_stack') + cms_base_url = config('cms_base_url') + lrs_base_url = config('lrs_base_url') + firebase_key= config('firebase_key') + firebase_id = config('firebase_id') + + template_url = f'https://{s3_bucket}.s3.amazonaws.com/{version}/code/scripts/tenant.yml' + lrs_host = f'{lrs_base_url}{tenant}/xapi/' + + address = f'{tenant}.perls.{cms_base_url}' + listener_name = 'PERLSAppLBListener443' + + ### Get info from secrets manager + db_password_secret = secrets_client.get_secret_value( + SecretId=f'{tenant}_db_password') + lrs_key_password_secret = secrets_client.get_secret_value( + SecretId=f'{tenant}_lrs_key_password') + smtp_password_secret = secrets_client.get_secret_value( + SecretId=f'{tenant}_smtp_password') + + print("Copying starter content.") + dirs=os.listdir('/mnt/efs/') + print(dirs) + dest = f"/mnt/efs/{tenant}" + os.mkdir(dest) + os.mkdir(dest + "/solr") + + # Run Lambda function to expand public/private files with efs ap where + # POSIX uid and gid set to 1000 so solr can access the dir + lambda_response = lambda_client.invoke( + FunctionName='create_files_directories', + InvocationType='Event', + LogType='Tail', + Payload=json.dumps(event) + ) + + # Run Lambda function to expand solr files with efs ap where + # POSIX uid and gid set to 8983 so solr can access the dir + print(lambda_response) + lambda_response = lambda_client.invoke( + FunctionName='create_solr_fs', + InvocationType='Event', + LogType='Tail', + Payload=json.dumps(event) + ) + print(lambda_response) + + #Get LB Listener and next priority number info + app_listener_info = cf_client.describe_stack_resource( + StackName=base_stack, LogicalResourceId=listener_name) + #TODO: Change listerner name for PERLS stack + app_listener_arn = app_listener_info['StackResourceDetail']['PhysicalResourceId'] + listener_rules = elb_client.describe_rules(ListenerArn=app_listener_arn) + rules = listener_rules['Rules'] + priority_int = 0 + for rule in rules: + try: + rule_priority = int(rule['Priority']) + if rule_priority > priority_int: + priority_int = int(rule['Priority']) + except (TypeError, NameError, KeyError, ValueError) as ex: + print(f'An exception occurred setting rules: {ex}') + break + + priority_int += 1 + priority = str(priority_int) + + ### Create Cloudformation tenant stack + stack_creation_response = cf_client.create_stack( + StackName=tenant, + TemplateURL=template_url, + Parameters=[ + { + 'ParameterKey': 'TENANT', + 'ParameterValue': tenant, + }, + { + 'ParameterKey': 'VERSION', + 'ParameterValue': version, + }, + { + 'ParameterKey': 'DBPASSWORDARN', + 'ParameterValue': db_password_secret['ARN'], + }, + { + 'ParameterKey': 'SMTPPASSWORDARN', + 'ParameterValue': smtp_password_secret['ARN'], + }, + { + 'ParameterKey': 'PRIORITY', + 'ParameterValue': priority, + }, + { + 'ParameterKey': 'LRSHOST', + 'ParameterValue': lrs_host, + }, + { + 'ParameterKey': 'LRSPASSWORDARN', + 'ParameterValue': lrs_key_password_secret['ARN'], + }, + { + 'ParameterKey': 'SMTPUSERNAME', + 'ParameterValue': smtp_username, + }, + { + 'ParameterKey': 'SMTPHOST', + 'ParameterValue': smtp_host, + }, + { + 'ParameterKey': 'SMTPFROM', + 'ParameterValue': smtp_from, + }, + { + 'ParameterKey': 'SMTPPROTOCOL', + 'ParameterValue': smtp_protocol, + }, + { + 'ParameterKey': 'SMTPPORT', + 'ParameterValue': smtp_port, + }, + { + 'ParameterKey': 'BaseStack', + 'ParameterValue': base_stack, + }, + { + 'ParameterKey': 'SNSTopic', + 'ParameterValue': snstopic, + }, + { + 'ParameterKey': 'Project', + 'ParameterValue': project, + }, + { + 'ParameterKey': 'BRAND', + 'ParameterValue': brand, + }, + { + 'ParameterKey': 'ADDRESS', + 'ParameterValue': address, + }, + { + 'ParameterKey': 'FIREBASEKEY', + 'ParameterValue': firebase_key, + }, + { + 'ParameterKey': 'FIREBASEID', + 'ParameterValue': firebase_id, + } + ], + Capabilities=[ + 'CAPABILITY_NAMED_IAM' + ], + Tags=[ + { + 'Key': 'Tenant', + 'Value': tenant + }, + ] + ) + print(stack_creation_response) + lambda_response = lambda_client.invoke( + FunctionName='admin_function', + InvocationType='Event', + LogType='Tail', + Payload=json.dumps(event) + ) + print(lambda_response) + return {'message': 'Stack creation successful'} diff --git a/admin_api/lambda_functions/cron.py b/admin_api/lambda_functions/cron.py new file mode 100644 index 0000000..3d37907 --- /dev/null +++ b/admin_api/lambda_functions/cron.py @@ -0,0 +1,23 @@ +def lambda_handler(event, context): + import requests + import boto3 + + session = boto3.Session() + secrets_client = session.client('secretsmanager') + cf_client = session.client('cloudformation') + tenant = event['tenant'] + cron_key_secret = secrets_client.get_secret_value(SecretId=tenant + "_cron_key") + cron_key = cron_key_secret['SecretString'] + + tenant_stack_info = cf_client.describe_stacks(StackName=tenant) + env_vars = tenant_stack_info['Stacks'][0]['Parameters'] + for var in env_vars: + if var['ParameterKey'] == 'ADDRESS': + address = var['ParameterValue'] + full_address = "https://" + address + "/cron/" + cron_key + cron_response = requests.get(full_address) + try: + cron_response.raise_for_status() + except requests.exceptions.HTTPError as e: + return "Error: " + str(e) + return diff --git a/admin_api/lambda_functions/delete/delete_tenant.py b/admin_api/lambda_functions/delete/delete_tenant.py new file mode 100644 index 0000000..7e2698f --- /dev/null +++ b/admin_api/lambda_functions/delete/delete_tenant.py @@ -0,0 +1,63 @@ +def lambda_handler(event, context): + import shutil + import requests + import boto3 + import json + from decouple import config + import mysql.connector + + session = boto3.Session() + cf_client = session.client('cloudformation') + secrets_client = session.client('secretsmanager') + rds_secret = secrets_client.get_secret_value(SecretId='rds_admin_login') + rds_info = json.loads(rds_secret['SecretString']) + rds_user = rds_info['username'] + rds_password = rds_info['password'] + rds_host = rds_info['host'] + lrs_api_key = config('lrs_api_key') + lrs_url = config('lrs_url') + path_parameters = event['pathParameters'] + tenant = path_parameters['tenant'].lower() + + get_lrs = requests.get(lrs_url + 'lrs?limit=0', headers = {"Content-Type": "application/json", "x-veracity-api-key": lrs_api_key }) + lrs_info = get_lrs.json() + for lrs in lrs_info: + if lrs['lrsName'] == tenant: + lrs_id = lrs['_id'] + requests.delete(lrs_url + 'lrs/' + lrs_id, headers = {"Content-Type": "application/json", "x-veracity-api-key": lrs_api_key }) + + stack = cf_client.describe_stacks(StackName=tenant) + + secrets_client.delete_secret(SecretId=tenant + "_db_password") + secrets_client.delete_secret(SecretId=tenant + "_user_password") + secrets_client.delete_secret(SecretId=tenant + "_lrs_key_password") + secrets_client.delete_secret(SecretId=tenant + "_cron_key") + secrets_client.delete_secret(SecretId=tenant + "_smtp_password") + + # Remove files in EFS + if(not (tenant and not tenant.isspace())): + print('Tenant is empty. Please remove files from EFS.') + else: + dest = "/mnt/efs/" + tenant + shutil.rmtree(dest) + + parameters = stack['Stacks'][0]['Parameters'] + for parameter in parameters: + if 'BRAND' in parameter['ParameterKey']: + brand = parameter['ParameterValue'] + db_name = tenant + "_" + brand + + cf_client.delete_stack(StackName=tenant) + + mydb = mysql.connector.connect( + host=rds_host, + user=rds_user, + password=rds_password + ) + mycursor = mydb.cursor() + mycursor.execute("DROP DATABASE {}".format(db_name)) + mycursor.execute("DROP USER {}@'10.0.0.0/255.255.0.0'".format(tenant)) + mycursor.close() + mydb.close() + + return { "statusCode": 200 } diff --git a/admin_api/lambda_functions/delete/invoke_delete.py b/admin_api/lambda_functions/delete/invoke_delete.py new file mode 100644 index 0000000..041b596 --- /dev/null +++ b/admin_api/lambda_functions/delete/invoke_delete.py @@ -0,0 +1,26 @@ +def lambda_handler(event, context): + import boto3 + import json + + session = boto3.Session() + cf_client = session.client('cloudformation') + lambda_client = session.client('lambda') + path_parameters = event['pathParameters'] + tenant = path_parameters['tenant'].lower() + + ###check if tenant exists + try: + cf_client.describe_stack_resources(StackName=tenant) + except: + return { + "statusCode": 404, + "body": "Tenant does not exist" + } + us_response = lambda_client.invoke( + FunctionName='delete_tenant', + InvocationType='Event', + LogType='Tail', + Payload=json.dumps(event) + ) + print(us_response) + return { 'statusCode': 200 } diff --git a/admin_api/lambda_functions/requirements.txt b/admin_api/lambda_functions/requirements.txt new file mode 100644 index 0000000..fb4d91d --- /dev/null +++ b/admin_api/lambda_functions/requirements.txt @@ -0,0 +1,5 @@ +python-decouple +boto3 +requests +mysql-connector-python +regex diff --git a/admin_api/lambda_functions/status/get_versions.py b/admin_api/lambda_functions/status/get_versions.py new file mode 100644 index 0000000..2a2923f --- /dev/null +++ b/admin_api/lambda_functions/status/get_versions.py @@ -0,0 +1,19 @@ +def lambda_handler(event, context): + + from decouple import config + import json + import boto3 + + session = boto3.Session() + s3_client = session.client('s3') + s3_bucket = config('s3_bucket') + versions = s3_client.list_objects_v2(Bucket=s3_bucket, Delimiter='/')['CommonPrefixes'] + version_list=[] + for v in versions: + version = v.get('Prefix') + version_list.append(version.strip('/')) + response = {"versions": version_list} + return { + "statusCode": 200, + "body": json.dumps(response) + } \ No newline at end of file diff --git a/admin_api/lambda_functions/status/tenant_list.py b/admin_api/lambda_functions/status/tenant_list.py new file mode 100644 index 0000000..96a8bf4 --- /dev/null +++ b/admin_api/lambda_functions/status/tenant_list.py @@ -0,0 +1,32 @@ +def lambda_handler(event, context): + import boto3 + import json + from dateutil.tz import tzutc + + session = boto3.Session() + cf_client = session.client('cloudformation') + stacks = cf_client.describe_stacks()['Stacks'] + response = [] + for stack in stacks: + try: + if stack['Tags'][0]['Key'] == 'Tenant': + tenant = stack['Tags'][0]['Value'] + stack_status = stack['StackStatus'] + except: + continue + parameters = stack['Parameters'] + for parameter in parameters: + if 'VERSION' in parameter['ParameterKey']: + version = parameter['ParameterValue'] + + tenant_status = { + "name": tenant, + "status": stack_status, + "version": version + } + response.append(tenant_status) + response_body={"tenants": response} + return { + "statusCode": 200, + "body": json.dumps(response_body) + } \ No newline at end of file diff --git a/admin_api/lambda_functions/status/tenant_status.py b/admin_api/lambda_functions/status/tenant_status.py new file mode 100644 index 0000000..1fcdc6d --- /dev/null +++ b/admin_api/lambda_functions/status/tenant_status.py @@ -0,0 +1,32 @@ +def lambda_handler(event, context): + import boto3 + import json + from decouple import config + from dateutil.tz import tzutc + + session = boto3.Session() + cf_client = session.client('cloudformation') + pathParameters = event['pathParameters'] + tenant = pathParameters['tenant'].lower() + try: + stack = cf_client.describe_stacks(StackName=tenant) + except: + raise Exception("The tenant " + tenant + " does not exist.") + + parameters = stack['Stacks'][0]['Parameters'] + for parameter in parameters: + if 'VERSION' in parameter['ParameterKey']: + version = parameter['ParameterValue'] + + stack_status = stack['Stacks'][0]['StackStatus'] + + response_body = { + "name": tenant, + "status": stack_status, + "version": version + } + + return { + "statusCode": 200, + "body": json.dumps(response_body) + } diff --git a/admin_api/lambda_functions/update/config_export.py b/admin_api/lambda_functions/update/config_export.py new file mode 100644 index 0000000..4be34d4 --- /dev/null +++ b/admin_api/lambda_functions/update/config_export.py @@ -0,0 +1,48 @@ +def lambda_handler(event, context): + import boto3 + from decouple import config + + print("Starting Admin container") + session = boto3.Session() + cf_client = session.client('cloudformation') + ecs_client = session.client('ecs') + tenant = event['tenant'].lower() + base_stack = config('base_stack') + base_stack_info = cf_client.describe_stacks(StackName=base_stack) + task_definition = tenant + '-php-admin-task' + + outputs = base_stack_info['Stacks'][0]['Outputs'] + subnets=[] + for output in outputs: + if 'PrivateSubnet' in output['OutputKey']: + subnets.append(output['OutputValue']) + if 'ECSCluster' in output['OutputKey']: + ecs_cluster = output['OutputValue'] + if 'SGECS' in output['OutputKey']: + ecs_security_group = output['OutputValue'] + + ecs_client.run_task( + cluster=ecs_cluster, + launchType='FARGATE', + taskDefinition=task_definition, + count=1, + platformVersion='1.4.0', + networkConfiguration={ + 'awsvpcConfiguration': { + 'subnets': subnets, + 'securityGroups': [ + ecs_security_group, + ], + 'assignPublicIp': 'ENABLED' + } + }, + overrides={ 'containerOverrides': [ + { + 'name': tenant + '-php', + 'command': [ + "sh", "/var/www/html/admin_api/config_export.sh", tenant + ] + } + ] + } + ) diff --git a/admin_api/lambda_functions/update/update.py b/admin_api/lambda_functions/update/update.py new file mode 100644 index 0000000..6ee6cfb --- /dev/null +++ b/admin_api/lambda_functions/update/update.py @@ -0,0 +1,41 @@ +def lambda_handler(event, context): + import boto3 + import json + from decouple import config + + tenant_info = json.loads(event['body']) + session = boto3.Session() + s3_client = session.client('s3') + s3_bucket = config('s3_bucket') + version = tenant_info['VERSION'] + cf_client = session.client('cloudformation') + lambda_client = session.client('lambda') + pathParameters = event['pathParameters'] + tenant = pathParameters['tenant'].lower() + + ###check if version is available + version_check = s3_client.list_objects_v2(Bucket=s3_bucket,Prefix=version) + + if version_check['KeyCount'] == 0 : + return { "statusCode": 400, + "body": "Version does not exist" + } + else: + print("Version " + version + " of the cms exists.") + + ###check if tenant exists + try: + tenant_response = cf_client.describe_stack_resources(StackName=tenant) + print("Tenant exists. Updating tenant " + tenant + " to version " + version ) + except: + return { "statusCode": 404, + "body": "Tenant does not exist" + } + us_response = lambda_client.invoke( + FunctionName='update_stack', + InvocationType='Event', + LogType='Tail', + Payload=json.dumps(event) + ) + print(us_response) + return {'statusCode': 200} \ No newline at end of file diff --git a/admin_api/lambda_functions/update/update_stack.py b/admin_api/lambda_functions/update/update_stack.py new file mode 100644 index 0000000..3f551dd --- /dev/null +++ b/admin_api/lambda_functions/update/update_stack.py @@ -0,0 +1,135 @@ +def lambda_handler(event, context): + import boto3 + import json + from decouple import config + + session = boto3.Session() + cf_client = session.client('cloudformation') + lambda_client = session.client('lambda') + tenant_info = event['body'] + tenant_data = json.loads(tenant_info) + path_parameters = event['pathParameters'] + tenant = path_parameters['tenant'].lower() + tenant_data['TENANT'] = tenant + event['body'] = json.dumps(tenant_data) + s3_bucket = config('s3_bucket') + version = tenant_data['VERSION'] + template_url = 'https://' + s3_bucket + '.s3.amazonaws.com/' + version + '/code/scripts/tenant.yml' + ce_payload = {"tenant": tenant} + + ce_response = lambda_client.invoke( + FunctionName='config_export', + InvocationType='RequestResponse', + LogType='Tail', + Payload=json.dumps(ce_payload) + ) + print(ce_response) + stack_update_response = cf_client.update_stack( + StackName=tenant, + TemplateURL=template_url, + Parameters=[ + { + 'ParameterKey': 'TENANT', + 'ParameterValue': tenant + }, + { + 'ParameterKey': 'VERSION', + 'ParameterValue': version + }, + { + 'ParameterKey': 'DBPASSWORDARN', + 'UsePreviousValue': True + }, + { + 'ParameterKey': 'SMTPPASSWORDARN', + 'UsePreviousValue': True + }, + { + 'ParameterKey': 'PRIORITY', + 'UsePreviousValue': True + }, + { + 'ParameterKey': 'LRSHOST', + 'UsePreviousValue': True + }, + { + 'ParameterKey': 'LRSPASSWORDARN', + 'UsePreviousValue': True + }, + { + 'ParameterKey': 'SMTPUSERNAME', + 'UsePreviousValue': True + }, + { + 'ParameterKey': 'SMTPHOST', + 'UsePreviousValue': True + }, + { + 'ParameterKey': 'SMTPFROM', + 'UsePreviousValue': True + }, + { + 'ParameterKey': 'SMTPPORT', + 'UsePreviousValue': True + }, + { + 'ParameterKey': 'SMTPPROTOCOL', + 'UsePreviousValue': True + }, + { + 'ParameterKey': 'BaseStack', + 'UsePreviousValue': True + }, + { + 'ParameterKey': 'SNSTopic', + 'UsePreviousValue': True + }, + { + 'ParameterKey': 'Project', + 'UsePreviousValue': True + }, + { + 'ParameterKey': 'BRAND', + 'UsePreviousValue': True + }, + { + 'ParameterKey': 'ADDRESS', + 'UsePreviousValue': True + }, + { + 'ParameterKey': 'FIREBASEKEY', + 'UsePreviousValue': True + }, + { + 'ParameterKey': 'FIREBASEID', + 'UsePreviousValue': True + }, + { + 'ParameterKey': 'ALTHost', + 'UsePreviousValue': True + }, + { + 'ParameterKey': 'SIMPLESAMLHOST', + 'UsePreviousValue': True + } + ], + Capabilities=[ + 'CAPABILITY_NAMED_IAM' + ], + Tags=[ + { + 'Key': 'Tenant', + 'Value': tenant + }, + ] + ) + print(stack_update_response) + admin_response = lambda_client.invoke( + FunctionName='admin_function', + InvocationType='Event', + LogType='Tail', + Payload=json.dumps(event) + ) + + print(admin_response) + return {'statusCode': 200} diff --git a/behat.yml b/behat.yml new file mode 100644 index 0000000..d660ed7 --- /dev/null +++ b/behat.yml @@ -0,0 +1,63 @@ +default: + suites: + default: + contexts: + - '\FeatureContext' + - '\IntegratedExperts\BehatScreenshotExtension\Context\ScreenshotContext' + - '\Drupal\DrupalExtension\Context\MinkContext' + - '\Drupal\DrupalExtension\Context\MessageContext' + - '\NuvoleWeb\Drupal\DrupalExtension\Context\DrupalContext' + - '\NuvoleWeb\Drupal\DrupalExtension\Context\VisibilityContext' + - '\PerlsDrupalContentContext' + - '\PerlsDrupalContext' + gherkin: + cache: ~ + extensions: + DMore\ChromeExtension\Behat\ServiceContainer\ChromeExtension: ~ + Drupal\MinkExtension: + goutte: ~ + base_url: "http://localhost" + default_session: "goutte" + browser_name: "chrome" + javascript_session: "browserChrome" + files_path: "%paths.base%" + sessions: + javascript: + chrome: +# api_url: "http://PERLS_chrome:9222" + socket_timeout: 60000 + default: + goutte: ~ + browserChrome: + chrome: +# api_url: "http://PERLS_chrome:9222" + socket_timeout: 60000 + NuvoleWeb\Drupal\DrupalExtension: + drupal: + drupal_root: "%paths.base%/web/" + api_driver: "drupal" + blackbox: ~ + region_map: + header: ".content-header" + content: ".region-content" + text: + log_in: "Sign in" + log_out: "Log out" + username_field: "Email" + IntegratedExperts\BehatScreenshotExtension: + dir: "%paths.base%/artifacts/screenshots" + fail: true + purge: true +tugboat: + extensions: + Drupal\MinkExtension: + base_url: "http://localhost" + sessions: + javascript: + chrome: + api_url: "http://localhost:9222" + browserChrome: + chrome: + api_url: "http://localhost:9222" + IntegratedExperts\BehatScreenshotExtension: + dir: "%paths.base%/web/artifacts/screenshots" diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..31eb67d --- /dev/null +++ b/composer.json @@ -0,0 +1,438 @@ +{ + "name": "drupal-composer/drupal-project", + "description": "Project template for Drupal 8 projects with composer", + "type": "project", + "license": "GPL-2.0-or-later", + "authors": [ + { + "name": "", + "role": "" + } + ], + "repositories": [ + { + "type": "package", + "package": { + "name": "jquery/icheck", + "version": "1.0.2 ", + "type": "drupal-library", + "extra": { + "installer-name": "jquery.icheck" + }, + "dist": { + "url": "https://github.com/dargullin/icheck/zipball/refs/heads/1.0.2", + "type": "zip" + } + } + }, + { + "type": "composer", + "url": "https://packages.drupal.org/8" + }, + { + "type": "composer", + "url": "https://asset-packagist.org" + }, + { + "type": "package", + "package": { + "name": "ckeditor/tabletoolstoolbar", + "version": "0.0.1", + "type": "drupal-library", + "dist": { + "url": "https://download.ckeditor.com/tabletoolstoolbar/releases/tabletoolstoolbar_0.0.1.zip", + "type": "zip" + } + } + }, + { + "type": "package", + "package": { + "name": "jameswilson/filename_transliteration", + "version": "1.0", + "type": "drupal-module", + "source": { + "url": "https://github.com/jameswilson/filename_transliteration.git", + "type": "git", + "reference": "1.0.x" + } + } + } + ], + "require": { + "php": ">=7.0", + "behat/mink-selenium2-driver": "dev-master as 1.3.x-dev", + "bex/behat-screenshot": "^1.2", + "bower-asset/isotope": "^3.0", + "ckeditor/tabletoolstoolbar": "^0.0.1", + "composer/installers": "^1.2", + "cweagans/composer-patches": "^1.6.5", + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", + "dmore/behat-chrome-extension": "^1.3", + "doctrine/lexer": "^1.0", + "drupal/achievements": "dev-2.x", + "drupal/admin_toolbar": "^3.0", + "drupal/adminimal_theme": "^1.5", + "drupal/administerusersbyrole": "^3.0@beta", + "drupal/allowed_formats": "^1.1", + "drupal/audiofield": "^1.11", + "drupal/autocomplete_deluxe": "^2.0", + "drupal/autosave_form": "^1.3", + "drupal/backward_compatibility": "^1.0", + "drupal/block_exclude_pages": "^2.0", + "drupal/block_field": "^1.0@RC", + "drupal/business_rules": "^2.0@beta", + "drupal/cer": "^4.0@alpha", + "drupal/ckeditor_tabletoolstoolbar": "^1.0", + "drupal/coder": "^8.3", + "drupal/config_filter": "^2.2", + "drupal/config_ignore": "^2.2", + "drupal/config_split": "^2.0", + "drupal/console": "^1.0.2", + "drupal/core": "9.3.3 as 8.9.99", + "drupal/core-composer-scaffold": "^9.2", + "drupal/core-dev": "^9.2", + "drupal/core-project-message": "^9.2", + "drupal/core-recommended": "^9.2.9", + "drupal/csv_serialization": "^2.0", + "drupal/ctools": "^3.7", + "drupal/date_recur": "^3.0", + "drupal/date_recur_modular": "^3.0", + "drupal/default_content": "^2.0@alpha", + "drupal/description_field": "1.x-dev", + "drupal/devel": "^4.0", + "drupal/dis": "^1.0", + "drupal/disable_messages": "^2.0", + "drupal/drupal-extension": "^4.1", + "drupal/email_registration": "^1.0@RC", + "drupal/entity_browser": "^2.6", + "drupal/entity_clone": "^1.0@beta", + "drupal/entity_normalization": "^1.0", + "drupal/entity_print": "^2.1", + "drupal/entitygroupfield": "^1.0@alpha", + "drupal/exif_orientation": "^1.0", + "drupal/field_group": "^3.1", + "drupal/field_permissions": "^1.1", + "drupal/filefield_paths": "^1.0@beta", + "drupal/firebase": "^3.0", + "drupal/flag": "4.x-dev#d1671b83", + "drupal/form_mode_manager": "^2.0", + "drupal/formatter_suite": "^1.3", + "drupal/formtips": "^1.3", + "drupal/go_back_history": "^1.0", + "drupal/group": "^1.4", + "drupal/header_formatter": "^1.0", + "drupal/hook_event_dispatcher": "^2.5", + "drupal/inline_entity_form": "^1.0@RC", + "drupal/jquery_ui_effects": "^1.1", + "drupal/jsonapi_extras": "^3.19", + "drupal/layout_builder_tabs": "^1.0@beta", + "drupal/log_stdout": "^2.0", + "drupal/maxlength": "^2.0@RC", + "drupal/media_entity_browser": "^2.0", + "drupal/monolog": "^2", + "drupal/multivalue_form_element": "^1.0@beta", + "drupal/node_title_help_text": "^1.2", + "drupal/page_manager": "^4.0@beta", + "drupal/paragraphs": "^1.8", + "drupal/pathauto": "^1.8", + "drupal/pdb_vue": "^1.0@alpha", + "drupal/queue_ui": "^2.1", + "drupal/r4032login": "^2.1", + "drupal/recreate_block_content": "2.x-dev", + "drupal/redirect": "^1.5", + "drupal/redis": "^1.5", + "drupal/require_on_publish": "^1.6", + "drupal/responsive_favicons": "^1.5", + "drupal/rest_export_nested": "^1.0", + "drupal/restui": "^1.20", + "drupal/rules": "3.x-dev@dev", + "drupal/rules_send_big_email": "^1.4", + "drupal/save_edit": "^1.3", + "drupal/scheduler": "^1.4", + "drupal/scheduler_content_moderation_integration": "^1.3", + "drupal/search_api": "^1.20", + "drupal/search_api_autocomplete": "^1.5", + "drupal/search_api_solr": "^4.2", + "drupal/select2": "^1.13", + "drupal/simple_block": "^1.3", + "drupal/simple_multistep": "^1.0@dev", + "drupal/simple_oauth": "^5.2.0", + "drupal/simplesamlphp_auth": "^3.2", + "drupal/smtp": "^1.0", + "drupal/stage_file_proxy": "^1.0", + "drupal/statistics_counter": "^1.0", + "drupal/switches": "1.x-dev", + "drupal/textimage": "^4.1", + "drupal/time_field": "^2.0", + "drupal/twig_tweak": "^3.1", + "drupal/username_enumeration_prevention": "^1.2", + "drupal/video_embed_brightcove": "^1.0@alpha", + "drupal/video_embed_field": "^2.1", + "drupal/video_embed_google_drive": "^1.2", + "drupal/video_embed_kaltura": "^1.2", + "drupal/views_add_button": "^2.0", + "drupal/views_autocomplete_filters": "^1.2", + "drupal/views_block_filter_block": "^1.0", + "drupal/views_bulk_operations": "^4.0", + "drupal/views_custom_cache_tag": "^1.1", + "drupal/views_field_formatter": "^1.10", + "drupal/webform": "^6.0", + "drupal/webform_views": "^5.0@alpha", + "drush/drush": "^10.6", + "james-heinrich/getid3": "v2.0.0-beta4", + "jameswilson/filename_transliteration": "^1.0", + "jquery/icheck": "1.0.2", + "npm-asset/clamp-js": "^0.7.0", + "npm-asset/select2": "^4.0", + "npm-asset/slick-carousel": "^1.8", + "npm-asset/sticky-js": "^1.3", + "nuvoleweb/drupal-behat": "^1.1", + "oomphinc/composer-installers-extender": "^2.0", + "simplesamlphp/simplesamlphp": "^1.19", + "vlucas/phpdotenv": "^2.4", + "webflo/drupal-finder": "^1.0.0", + "webmozart/path-util": "^2.3", + "wikimedia/composer-merge-plugin": "^2.0", + "zaporylie/composer-drupal-optimizations": "^1.0" + }, + "require-dev": { + "drupal/twig_vardumper": "^3.0", + "integratedexperts/behat-screenshot": "^0.7.3", + "mglaman/drupal-check": "^1.1" + }, + "conflict": { + "drupal/drupal": "*" + }, + "minimum-stability": "dev", + "prefer-stable": true, + "config": { + "sort-packages": true, + "discard-changes": true, + "allow-plugins": { + "cweagans/composer-patches": true, + "composer/installers": true, + "drupal/core-composer-scaffold": true, + "drupal/core-project-message": true, + "wikimedia/composer-merge-plugin": true, + "zaporylie/composer-drupal-optimizations": true, + "dealerdirect/phpcodesniffer-composer-installer": true, + "drupal/console-extend-plugin": true, + "simplesamlphp/composer-module-installer": true, + "oomphinc/composer-installers-extender": true + } + }, + "autoload": { + "classmap": [ + "composer/ScriptHandler.php" + ], + "files": [ + "load.environment.php" + ] + }, + "scripts": { + "pre-install-cmd": [ + "DrupalProject\\composer\\ScriptHandler::checkComposerVersion" + ], + "pre-update-cmd": [ + "DrupalProject\\composer\\ScriptHandler::checkComposerVersion" + ], + "post-install-cmd": [ + "DrupalProject\\composer\\ScriptHandler::createRequiredFiles", + "php -r \"symlink('vendor/simplesamlphp/simplesamlphp', 'simplesamlphp');\"", + "cp -R simplesamlphp_config/* simplesamlphp" + ], + "post-update-cmd": [ + "DrupalProject\\composer\\ScriptHandler::createRequiredFiles" + ] + }, + "extra": { + "composer-exit-on-patch-failure": true, + "merge-plugin": { + "include": [ + "web/modules/contrib/webform/composer.libraries.json" + ], + "ignore-duplicates": true + }, + "patchLevel": { + "drupal/core": "-p2" + }, + "installer-types": [ + "npm-asset", + "bower-asset" + ], + "installer-paths": { + "web/core": [ + "type:drupal-core" + ], + "web/libraries/{$name}": [ + "type:drupal-library", + "type:npm-asset", + "type:bower-asset" + ], + "web/modules/contrib/{$name}": [ + "type:drupal-module" + ], + "web/profiles/contrib/{$name}": [ + "type:drupal-profile" + ], + "web/themes/contrib/{$name}": [ + "type:drupal-theme" + ], + "drush/Commands/{$name}": [ + "type:drupal-drush" + ], + "simplesamlphp": [ + "vendor/simplesamlphp" + ] + }, + "patches": { + "drupal/achievements": { + "Fixed image upload bug": "https://www.drupal.org/files/issues/2020-11-05/3180872-image-upload-1.patch", + "Fix form in D9": "https://www.drupal.org/files/issues/2020-11-14/achievements-D9_form_fix-0.diff" + }, + "drupal/autocomplete_deluxe": { + "Client JS execution": "./patches/autocomplete_deluxe/js_execution.patch" + }, + "drupal/core": { + "Plugin ID menu_link_content was not found in _menu_link_content_update_path_alias() when does not yet exist": "https://www.drupal.org/files/issues/2019-08-04/menu_link_content_check_definition-3072557-1.patch", + "2982729 - REST views: pagination information and total count result": "https://www.drupal.org/files/issues/2021-08-04/2982729-add-option-to-add-pager-information-to-rest-export-45_0.patch", + "2974925 - Default 'rid' value for Change User Roles causes an illegal error": "https://www.drupal.org/files/issues/2018-05-24/2974925-default-rid-config-causes-illegal-error.patch", + "2986958 - Allow negate user role in block visibility settings": "https://www.drupal.org/files/issues/2018-07-19/enable-block-visibility-user-role-negation-2986958-2.patch", + "3041463 - Support Entity UUID (and other properties) in the generic Entity Argument Validator": "https://www.drupal.org/files/issues/2021-03-13/support_uuid_views_arguement_validator-3041463-19.patch", + "1819538 - More link disappears when time-based views cache is enabled": "https://www.drupal.org/files/issues/2021-03-10/1819538-65.patch", + "2463753 - Do not bypass route access with 'link to any page' permissions": "https://www.drupal.org/files/issues/2021-09-15/2463753-87_0.patch", + "3015152 - Allow to set settings to layout builder components": "https://www.drupal.org/files/issues/2021-12-13/3015152-tps-9.3.x-128.patch", + "2700667 - Undefined index: #type in drupal_process_states()": "https://www.drupal.org/files/issues/2021-05-12/2700667-133a.patch", + "1650930 - Prevents deadlock after cache clear": "https://www.drupal.org/files/issues/2021-03-23/1650930-109.patch", + "2935999 - Removed field UI dependncy from Layout builder": "./patches/core/2935999-remove_field_ui_dependency_layout_builder-9.3.x.patch", + "2264739 - Allow multiple field widgets to not use tabledrag": "https://www.drupal.org/files/issues/2021-12-02/2264739-116-9.3.x.patch", + "2329937 - Allow definition objects to provide options": "https://www.drupal.org/files/issues/2021-12-18/2329937-75.options-provider.patch", + "3021671 - Node revisions tab have 'Current Version' on every Page": "https://www.drupal.org/files/issues/2022-01-15/3021671-16-determine_current_revision.patch", + "2681953 - Allow exposed form to preserve URL query parameters": "https://www.drupal.org/files/issues/2020-10-23/2681953-25.patch" + }, + "drupal/ctools": { + "2475595 - Views exposed filters missing autosubmit option": "https://www.drupal.org/files/issues/2475595-ctools-autocomplete-fix-47.patch" + }, + "drupal/description_field": { + "Drupal 9 compatibility": "https://www.drupal.org/files/issues/2020-05-23/description_field.1.x-dev.rector.patch" + }, + "drupal/entity_browser": { + "Auto open cause ajax infinite loop": "https://www.drupal.org/files/issues/entity_browser-auto_open_once-2857339-2.patch", + "3123876 - Entity display plugin 'Rendered Entity' should only add cache key if the entity is render cached": "https://www.drupal.org/files/issues/2020-09-23/rendered-entity-cache-keys-tags-3123876-6.patch", + "3038050 - Entity browser does not edit latest version": "https://www.drupal.org/files/issues/2019-03-06/entity_browser-content_moderation-3038050-2.patch", + "3104901 - Entity Browser used in a entity referenced field of a layout builder custom block is not working": "https://www.drupal.org/files/issues/2020-03-25/3104901.patch" + }, + "drupal/entity_clone": { + "3112577 - Cloning child references to nodes has potential to cause memory resource issues": "https://www.drupal.org/files/issues/2020-02-10/entity_clone-child-node-system-drain-3112577-1.patch" + }, + "drupal/cer": { + "3200122 - Delete hook throws Drupal\\Core\\Entity\\EntityStorageException: Update existing 'node' entity while changing the ID is not supported": "https://www.drupal.org/files/issues/2021-02-24/delete-hook-added-in-dev-causes-test-failures.patch" + }, + "drupal/flag": { + "3229964 - TypeError: Argument 5 passed to Drupal\\Core\\Template\\TwigExtension::__construct()": "https://www.drupal.org/files/issues/2021-08-26/flag-TypeError-3229964-2.patch" + }, + "drupal/filefield_paths": { + "2718783 - Call to undefined method BaseFieldDefinition::getThirdPartySettings()": "https://www.drupal.org/files/issues/2021-03-18/call_to_undefined-2718783-45.patch" + }, + "drupal/form_mode_manager": { + "Field UI disabled": "./patches/form_mode_manager/form-ui-disable-D9-compatible.patch" + }, + "drupal/formatter_suite": { + "3162381 - Allow 0 decimal": "https://www.drupal.org/files/issues/2020-07-30/3162381-allow-0-decimal-1.patch" + }, + "drupal/switches": { + "0001 - Fixes Deprecation": "./patches/switches/0001-Fixes-Deprecation.patch", + "0002 - Fixes Issue When Saving Switch": "./patches/switches/0002-Fix-Issue-When-Saving-Switch.patch", + "0003 - Fixes Conditional Logic": "./patches/switches/0003-Fixes-Conditional-Logic.patch", + "3238790 - Error message An illegal choice...": "https://www.drupal.org/files/issues/2021-09-24/switches-illegal_choice_has_been_detected-3238790-5.patch" + }, + "drupal/group": { + "2942657 - /views/ajax?_wrapper_format=drupal_ajax HTTP/1.1 - HTTP/1.1 403 Forbidden": "https://www.drupal.org/files/issues/2019-06-27/group_route_ajax_route-2942657-18.patch", + "3161707 - hook_query_TAG_alter does not handle empty MetaData.": "https://www.drupal.org/files/issues/2020-07-27/group__3161707__handle_empty_metadata__2.patch", + "2876696 - Add support for 'view own unpublished entity' permission": "https://git.drupalcode.org/project/group/-/merge_requests/9.patch" + }, + "drupal/entity_normalization": { + "3160617 - Add access check to field item list": "https://www.drupal.org/files/issues/2020-07-23/add-access-check-field-item-list-3160617-3.patch" + }, + "drupal/layout_builder_tabs": { + "3150894 - Users error in log when in Layout tab": "https://www.drupal.org/files/issues/2020-07-27/layout_builder_tabs-user_errors-3150894-5.patch" + }, + "drupal/media_entity_browser": { + "2939543 - Improving JS behavior to comply with field cardinality": "https://www.drupal.org/files/issues/2019-06-25/media_entity_browser-ported-file-browser-cadinality-support-2939543-17.patch" + }, + "drupal/paragraphs": { + "2901390 - Integrity constraint violation: 1048 Column 'langcode' cannot be null": "https://www.drupal.org/files/issues/2019-07-10/paragraphs-set_langcode_widgets-2901390-29.patch" + }, + "drupal/r4032login": { + "Drupal 9 fixes": "./patches/r4032login/drupal-9-fix.patch" + }, + "drupal/save_edit": { + "3026200 - Inherit all submit handlers from save": "https://www.drupal.org/files/issues/2019-10-28/inline_entity_forms_not_saving-3026200-12.patch" + }, + "drupal/simple_oauth": { + "Avoid access token revoke on user update": "https://www.drupal.org/files/issues/2019-04-15/simple_oauth-auth-revoke-2946882-34.patch", + "Better error messages:": "https://www.drupal.org/files/issues/2020-05-29/simple_oauth2_error_message_hint.patch", + "3082984 - Reduce logging severity/don't log expired tokens/401s": "https://www.drupal.org/files/issues/2021-08-11/reduce-reporting-severtiy-3082984-8_2.patch" + }, + "drupal/stage_file_proxy": { + "3175045 - Error retrieving images from styles that use ConvertImageEffect": "https://www.drupal.org/files/issues/2021-11-16/3175045-03.patch", + "2833845 - styleOriginalPath() finds wrong path when using a Convert effect": "https://www.drupal.org/files/issues/2020-10-30/stage_file_proxy-2833845-convert-image-style-16.patch" + }, + "drupal/statistics_counter": { + "2693019 - Use state instead of config for cron timestamp": "https://www.drupal.org/files/issues/2018-08-14/statistics_counter-2693019-4.patch", + "2861191 - Fixed hook_disable for Drupal 8": "https://www.drupal.org/files/issues/statistics_counter-hook-0.patch", + "2860205 - Replace deprecated uses": "https://www.drupal.org/files/issues/statistics_counter-replace_deprecated_uses-2860205-2.patch", + "2905572 - Fixed php error on node sub-pages": "./patches/statistics_counter/php_error_in_updateStatistics-2905572-5.patch", + "Drupal 9 compatibility patch": "./patches/statistics_counter/d9-compatibility.patch" + }, + "drupal/simplesamlphp_auth": { + "3120326 - Disable default SAML authentication if local login is enabled": "https://www.drupal.org/files/issues/2020-03-17/disable-default-saml-login-3120326-1.patch", + "3186552 - Preserve URL parameters on authentication": "https://www.drupal.org/files/issues/2020-12-04/3186552-2.patch" + }, + "drupal/token": { + "3047568 - Consistent tokens support across all entities and fields": "https://www.drupal.org/files/issues/2020-09-21/token-consistent-entity-and-field-support-3047568-12.patch" + }, + "drupal/video_embed_kaltura": { + "3212315 - Invalid url string cause undefined index error": "https://www.drupal.org/files/issues/2021-05-05/3212315-validate-url-1_0.patch" + }, + "drupal/views_bulk_operations": { + "3216584 - Unable to cancel a user account if it has more then 10 content": "https://www.drupal.org/files/issues/2021-06-03/3216584-unable-cancel-user-account-10-content-8_1.patch" + }, + "drupal/page_manager": { + "3201744 - Change block configuration to use SubFormState and other inline block changes.": "https://www.drupal.org/files/issues/2021-08-05/3201744-4.patch" + }, + "float/recommender": { + "Moved getScoreEntity method to base class": "./patches/recommender/move-getScoreEntity-function-1.1.1.patch" + }, + "drupal/block_field": { + "Fix the block field widget issue.": "./patches/block_field/fix_empty_block_issue_widget.patch" + }, + "drupal/rules": { + "2664280 - Select lists in action & condition configuration forms": "https://www.drupal.org/files/issues/2021-09-20/2664280-89.select-lists.patch", + "3161036 - CurrentPathContext inadvertently bubbles up 'route' cache context": "https://www.drupal.org/files/issues/2021-01-02/rules-3161036-6-v1.patch" + }, + "drupal/multivalue_form_element": { + "3200306 - Add support for non-orderable multivalue form elements": "./patches/multivalue_form_element/3200306-disable-multifield-ordering.patch" + }, + "drupal/scheduler": { + "3238643: Route \"view.scheduler_scheduled_content.overview\" does not exist": "https://www.drupal.org/files/issues/2021-10-14/because_of_changes_to_scheduler.links_.task_.yml-3238643-1.patch" + }, + "drupal/business_rules": { + "3200711: cannot add an action to a condition": "https://www.drupal.org/files/issues/2021-05-15/cannot_add_action-3200711-29.patch" + } + }, + "drupal-scaffold": { + "initial": { + ".editorconfig": "../.editorconfig", + ".gitattributes": "../.gitattributes" + }, + "locations": { + "web-root": "./web" + }, + "file-mapping": { + "[web-root]/sites/development.services.yml": false + } + } + } +} \ No newline at end of file diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..a305355 --- /dev/null +++ b/composer.lock @@ -0,0 +1,24759 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "89400fadf2bc7a1f0b534546183b3549", + "packages": [ + { + "name": "alchemy/zippy", + "version": "0.4.9", + "source": { + "type": "git", + "url": "https://github.com/alchemy-fr/Zippy.git", + "reference": "59fbeefb9a249122867ef25e53addfcce31850d7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/alchemy-fr/Zippy/zipball/59fbeefb9a249122867ef25e53addfcce31850d7", + "reference": "59fbeefb9a249122867ef25e53addfcce31850d7", + "shasum": "" + }, + "require": { + "doctrine/collections": "~1.0", + "php": ">=5.5", + "symfony/filesystem": "^2.0.5 || ^3.0 || ^4.0", + "symfony/polyfill-mbstring": "^1.3", + "symfony/process": "^2.1 || ^3.0 || ^4.0" + }, + "require-dev": { + "ext-zip": "*", + "guzzle/guzzle": "~3.0", + "guzzlehttp/guzzle": "^6.0", + "phpunit/phpunit": "^4.0 || ^5.0", + "symfony/finder": "^2.0.5 || ^3.0 || ^4.0" + }, + "suggest": { + "ext-zip": "To use the ZipExtensionAdapter", + "guzzle/guzzle": "To use the GuzzleTeleporter with Guzzle 3", + "guzzlehttp/guzzle": "To use the GuzzleTeleporter with Guzzle 6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.4.x-dev" + } + }, + "autoload": { + "psr-4": { + "Alchemy\\Zippy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Alchemy", + "email": "dev.team@alchemy.fr", + "homepage": "http://www.alchemy.fr/" + } + ], + "description": "Zippy, the archive manager companion", + "keywords": [ + "bzip", + "compression", + "tar", + "zip" + ], + "support": { + "issues": "https://github.com/alchemy-fr/Zippy/issues", + "source": "https://github.com/alchemy-fr/Zippy/tree/master" + }, + "time": "2018-02-22T13:58:36+00:00" + }, + { + "name": "algolia/places", + "version": "1.19.0", + "dist": { + "type": "tar", + "url": "https://registry.npmjs.org/places.js/-/places.js-1.19.0.tgz" + }, + "type": "drupal-library", + "extra": { + "installer-name": "algolia.places" + } + }, + { + "name": "asm89/stack-cors", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/asm89/stack-cors.git", + "reference": "b9c31def6a83f84b4d4a40d35996d375755f0e08" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/asm89/stack-cors/zipball/b9c31def6a83f84b4d4a40d35996d375755f0e08", + "reference": "b9c31def6a83f84b4d4a40d35996d375755f0e08", + "shasum": "" + }, + "require": { + "php": ">=5.5.9", + "symfony/http-foundation": "~2.7|~3.0|~4.0|~5.0", + "symfony/http-kernel": "~2.7|~3.0|~4.0|~5.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.0 || ^4.8.10", + "squizlabs/php_codesniffer": "^2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "psr-4": { + "Asm89\\Stack\\": "src/Asm89/Stack/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Alexander", + "email": "iam.asm89@gmail.com" + } + ], + "description": "Cross-origin resource sharing library and stack middleware", + "homepage": "https://github.com/asm89/stack-cors", + "keywords": [ + "cors", + "stack" + ], + "support": { + "issues": "https://github.com/asm89/stack-cors/issues", + "source": "https://github.com/asm89/stack-cors/tree/1.3.0" + }, + "time": "2019-12-24T22:41:47+00:00" + }, + { + "name": "behat/behat", + "version": "v3.5.0", + "source": { + "type": "git", + "url": "https://github.com/Behat/Behat.git", + "reference": "e4bce688be0c2029dc1700e46058d86428c63cab" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Behat/Behat/zipball/e4bce688be0c2029dc1700e46058d86428c63cab", + "reference": "e4bce688be0c2029dc1700e46058d86428c63cab", + "shasum": "" + }, + "require": { + "behat/gherkin": "^4.5.1", + "behat/transliterator": "^1.2", + "container-interop/container-interop": "^1.2", + "ext-mbstring": "*", + "php": ">=5.3.3", + "psr/container": "^1.0", + "symfony/class-loader": "~2.1||~3.0", + "symfony/config": "~2.3||~3.0||~4.0", + "symfony/console": "~2.7.40||^2.8.33||~3.3.15||^3.4.3||^4.0.3", + "symfony/dependency-injection": "~2.1||~3.0||~4.0", + "symfony/event-dispatcher": "~2.1||~3.0||~4.0", + "symfony/translation": "~2.3||~3.0||~4.0", + "symfony/yaml": "~2.1||~3.0||~4.0" + }, + "require-dev": { + "herrera-io/box": "~1.6.1", + "phpunit/phpunit": "^4.8.36|^6.3", + "symfony/process": "~2.5|~3.0|~4.0" + }, + "bin": [ + "bin/behat" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.5.x-dev" + } + }, + "autoload": { + "psr-0": { + "Behat\\Behat": "src/", + "Behat\\Testwork": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + } + ], + "description": "Scenario-oriented BDD framework for PHP 5.3", + "homepage": "http://behat.org/", + "keywords": [ + "Agile", + "BDD", + "ScenarioBDD", + "Scrum", + "StoryBDD", + "User story", + "business", + "development", + "documentation", + "examples", + "symfony", + "testing" + ], + "support": { + "issues": "https://github.com/Behat/Behat/issues", + "source": "https://github.com/Behat/Behat/tree/master" + }, + "time": "2018-08-10T18:56:51+00:00" + }, + { + "name": "behat/gherkin", + "version": "v4.9.0", + "source": { + "type": "git", + "url": "https://github.com/Behat/Gherkin.git", + "reference": "0bc8d1e30e96183e4f36db9dc79caead300beff4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Behat/Gherkin/zipball/0bc8d1e30e96183e4f36db9dc79caead300beff4", + "reference": "0bc8d1e30e96183e4f36db9dc79caead300beff4", + "shasum": "" + }, + "require": { + "php": "~7.2|~8.0" + }, + "require-dev": { + "cucumber/cucumber": "dev-gherkin-22.0.0", + "phpunit/phpunit": "~8|~9", + "symfony/yaml": "~3|~4|~5" + }, + "suggest": { + "symfony/yaml": "If you want to parse features, represented in YAML files" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.x-dev" + } + }, + "autoload": { + "psr-0": { + "Behat\\Gherkin": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + } + ], + "description": "Gherkin DSL parser for PHP", + "homepage": "http://behat.org/", + "keywords": [ + "BDD", + "Behat", + "Cucumber", + "DSL", + "gherkin", + "parser" + ], + "support": { + "issues": "https://github.com/Behat/Gherkin/issues", + "source": "https://github.com/Behat/Gherkin/tree/v4.9.0" + }, + "time": "2021-10-12T13:05:09+00:00" + }, + { + "name": "behat/mink", + "version": "v1.9.0", + "source": { + "type": "git", + "url": "https://github.com/minkphp/Mink.git", + "reference": "e35f4695de8800fc776af34ebf665ad58ebdd996" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/minkphp/Mink/zipball/e35f4695de8800fc776af34ebf665ad58ebdd996", + "reference": "e35f4695de8800fc776af34ebf665ad58ebdd996", + "shasum": "" + }, + "require": { + "php": ">=5.4", + "symfony/css-selector": "^2.7|^3.0|^4.0|^5.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5 || ^9.5", + "symfony/debug": "^2.7|^3.0|^4.0|^5.0", + "symfony/phpunit-bridge": "^3.4.38 || ^4.4 || ^5.0.5", + "yoast/phpunit-polyfills": "^1.0" + }, + "suggest": { + "behat/mink-browserkit-driver": "extremely fast headless driver for Symfony\\Kernel-based apps (Sf2, Silex)", + "behat/mink-goutte-driver": "fast headless driver for any app without JS emulation", + "behat/mink-selenium2-driver": "slow, but JS-enabled driver for any app (requires Selenium2)", + "behat/mink-zombie-driver": "fast and JS-enabled headless driver for any app (requires node.js)", + "dmore/chrome-mink-driver": "fast and JS-enabled driver for any app (requires chromium or google chrome)" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Behat\\Mink\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + } + ], + "description": "Browser controller/emulator abstraction for PHP", + "homepage": "https://mink.behat.org/", + "keywords": [ + "browser", + "testing", + "web" + ], + "support": { + "issues": "https://github.com/minkphp/Mink/issues", + "source": "https://github.com/minkphp/Mink/tree/v1.9.0" + }, + "time": "2021-10-11T11:58:47+00:00" + }, + { + "name": "behat/mink-extension", + "version": "2.3.1", + "source": { + "type": "git", + "url": "https://github.com/Behat/MinkExtension.git", + "reference": "80f7849ba53867181b7e412df9210e12fba50177" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Behat/MinkExtension/zipball/80f7849ba53867181b7e412df9210e12fba50177", + "reference": "80f7849ba53867181b7e412df9210e12fba50177", + "shasum": "" + }, + "require": { + "behat/behat": "^3.0.5", + "behat/mink": "^1.5", + "php": ">=5.3.2", + "symfony/config": "^2.7|^3.0|^4.0" + }, + "require-dev": { + "behat/mink-goutte-driver": "^1.1", + "phpspec/phpspec": "^2.0" + }, + "type": "behat-extension", + "extra": { + "branch-alias": { + "dev-master": "2.1.x-dev" + } + }, + "autoload": { + "psr-0": { + "Behat\\MinkExtension": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christophe Coevoet", + "email": "stof@notk.org" + }, + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com" + } + ], + "description": "Mink extension for Behat", + "homepage": "http://extensions.behat.org/mink", + "keywords": [ + "browser", + "gui", + "test", + "web" + ], + "support": { + "issues": "https://github.com/Behat/MinkExtension/issues", + "source": "https://github.com/Behat/MinkExtension/tree/master" + }, + "time": "2018-02-06T15:36:30+00:00" + }, + { + "name": "behat/mink-goutte-driver", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/minkphp/MinkGoutteDriver.git", + "reference": "8139f520f417c81bf9d2f9a171fff400f6adc9ea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/minkphp/MinkGoutteDriver/zipball/8139f520f417c81bf9d2f9a171fff400f6adc9ea", + "reference": "8139f520f417c81bf9d2f9a171fff400f6adc9ea", + "shasum": "" + }, + "require": { + "behat/mink-browserkit-driver": "~1.2@dev", + "fabpot/goutte": "~1.0.4|~2.0|~3.1", + "php": ">=5.4" + }, + "require-dev": { + "mink/driver-testsuite": "dev-master" + }, + "type": "mink-driver", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Behat\\Mink\\Driver\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + } + ], + "description": "Goutte driver for Mink framework", + "homepage": "https://mink.behat.org/", + "keywords": [ + "browser", + "goutte", + "headless", + "testing" + ], + "support": { + "issues": "https://github.com/minkphp/MinkGoutteDriver/issues", + "source": "https://github.com/minkphp/MinkGoutteDriver/tree/v1.3.0" + }, + "time": "2021-10-12T11:35:46+00:00" + }, + { + "name": "behat/mink-selenium2-driver", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/minkphp/MinkSelenium2Driver.git", + "reference": "9db0068849d6365e58ecd100aa2ce58b02697bb4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/minkphp/MinkSelenium2Driver/zipball/9db0068849d6365e58ecd100aa2ce58b02697bb4", + "reference": "9db0068849d6365e58ecd100aa2ce58b02697bb4", + "shasum": "" + }, + "require": { + "behat/mink": "^1.9@dev", + "ext-json": "*", + "instaclick/php-webdriver": "^1.4", + "php": ">=7.2" + }, + "require-dev": { + "mink/driver-testsuite": "dev-master", + "phpunit/phpunit": "^8.5.22 || ^9.5.11", + "symfony/error-handler": "^4.4 || ^5.0" + }, + "default-branch": true, + "type": "mink-driver", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Behat\\Mink\\Driver\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Pete Otaqui", + "email": "pete@otaqui.com", + "homepage": "https://github.com/pete-otaqui" + }, + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + } + ], + "description": "Selenium2 (WebDriver) driver for Mink framework", + "homepage": "https://mink.behat.org/", + "keywords": [ + "ajax", + "browser", + "javascript", + "selenium", + "testing", + "webdriver" + ], + "support": { + "issues": "https://github.com/minkphp/MinkSelenium2Driver/issues", + "source": "https://github.com/minkphp/MinkSelenium2Driver/tree/master" + }, + "time": "2022-01-19T20:36:53+00:00" + }, + { + "name": "behat/transliterator", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/Behat/Transliterator.git", + "reference": "3c4ec1d77c3d05caa1f0bf8fb3aae4845005c7fc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Behat/Transliterator/zipball/3c4ec1d77c3d05caa1f0bf8fb3aae4845005c7fc", + "reference": "3c4ec1d77c3d05caa1f0bf8fb3aae4845005c7fc", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "chuyskywalker/rolling-curl": "^3.1", + "php-yaoi/php-yaoi": "^1.0", + "phpunit/phpunit": "^4.8.36|^6.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "psr-4": { + "Behat\\Transliterator\\": "src/Behat/Transliterator" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Artistic-1.0" + ], + "description": "String transliterator", + "keywords": [ + "i18n", + "slug", + "transliterator" + ], + "support": { + "issues": "https://github.com/Behat/Transliterator/issues", + "source": "https://github.com/Behat/Transliterator/tree/v1.3.0" + }, + "time": "2020-01-14T16:39:13+00:00" + }, + { + "name": "bex/behat-extension-driver-locator", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/tkotosz/behat-extension-driver-locator.git", + "reference": "af9fb11f5f3cc220ee2c08071ee9d50f11048b86" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/tkotosz/behat-extension-driver-locator/zipball/af9fb11f5f3cc220ee2c08071ee9d50f11048b86", + "reference": "af9fb11f5f3cc220ee2c08071ee9d50f11048b86", + "shasum": "" + }, + "require": { + "behat/behat": "^3.0.0", + "php": ">=5.4" + }, + "require-dev": { + "phpspec/phpspec": "2.4.0-alpha2" + }, + "type": "library", + "autoload": { + "psr-0": { + "": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Tibor Kotosz", + "email": "kotosy@gmail.com", + "homepage": "https://github.com/tkotosz", + "role": "Developer" + } + ], + "description": "Driver locator tool for behat extensions", + "homepage": "https://github.com/tkotosz/behat-extension-driver-locator", + "keywords": [ + "BDD", + "Behat", + "TDD" + ], + "support": { + "issues": "https://github.com/tkotosz/behat-extension-driver-locator/issues", + "source": "https://github.com/tkotosz/behat-extension-driver-locator/tree/master" + }, + "time": "2015-12-17T13:26:09+00:00" + }, + { + "name": "bex/behat-screenshot", + "version": "1.2.9", + "source": { + "type": "git", + "url": "https://github.com/elvetemedve/behat-screenshot.git", + "reference": "618a857169ebf80eb9f4dd56ed42efaebb2de9b6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/elvetemedve/behat-screenshot/zipball/618a857169ebf80eb9f4dd56ed42efaebb2de9b6", + "reference": "618a857169ebf80eb9f4dd56ed42efaebb2de9b6", + "shasum": "" + }, + "require": { + "behat/behat": "^3.0.0 <3.6", + "behat/mink-extension": "^2.0.0", + "bex/behat-extension-driver-locator": "^1.0.2", + "php": ">=5.4", + "symfony/filesystem": "^2.7|^3.0|^4.0", + "symfony/finder": "^2.7|^3.0|^4.0" + }, + "require-dev": { + "behat/mink-selenium2-driver": "^1.3.0", + "bex/behat-screenshot-image-driver-dummy": "^1.0", + "bex/behat-test-runner": "^1.2.2", + "jakoch/phantomjs-installer": "^2.1.1-p07", + "phpspec/phpspec": "^2.5" + }, + "suggest": { + "bex/behat-screenshot-image-driver-img42": "Allows to upload the screenshot to img42.com", + "bex/behat-screenshot-image-driver-unsee": "Allows to upload the screenshot to unsee.cc", + "bex/behat-screenshot-image-driver-uploadpie": "Allows to upload the screenshot to uploadpie.com" + }, + "type": "library", + "autoload": { + "psr-0": { + "Bex\\Behat\\ScreenshotExtension\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Tibor Kotosz", + "email": "kotosy@gmail.com", + "homepage": "https://github.com/tkotosz", + "role": "Developer" + }, + { + "name": "Geza Buza", + "email": "bghome@gmail.com", + "homepage": "https://twitter.com/medve540", + "role": "Developer" + } + ], + "description": "Extension for behat to help debug failing scenarios", + "homepage": "https://github.com/elvetemedve/behat-screenshot", + "keywords": [ + "BDD", + "Behat", + "TDD", + "behat-screenshot" + ], + "support": { + "issues": "https://github.com/elvetemedve/behat-screenshot/issues", + "source": "https://github.com/elvetemedve/behat-screenshot/tree/master" + }, + "time": "2020-04-07T13:22:51+00:00" + }, + { + "name": "bower-asset/desandro-matches-selector", + "version": "v2.0.2", + "source": { + "type": "git", + "url": "git@github.com:desandro/matches-selector.git", + "reference": "42ee1cbab7469454d140bdab04d2ceed9c68b85e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/desandro/matches-selector/zipball/42ee1cbab7469454d140bdab04d2ceed9c68b85e", + "reference": "42ee1cbab7469454d140bdab04d2ceed9c68b85e" + }, + "type": "bower-asset", + "license": [ + "MIT" + ] + }, + { + "name": "bower-asset/ev-emitter", + "version": "v1.1.1", + "source": { + "type": "git", + "url": "https://github.com/metafizzy/ev-emitter.git", + "reference": "1baa3a03d8e07f665b0eb797661fcc2b0d2a5736" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/metafizzy/ev-emitter/zipball/1baa3a03d8e07f665b0eb797661fcc2b0d2a5736", + "reference": "1baa3a03d8e07f665b0eb797661fcc2b0d2a5736" + }, + "type": "bower-asset", + "license": [ + "MIT" + ] + }, + { + "name": "bower-asset/fizzy-ui-utils", + "version": "v2.0.7", + "source": { + "type": "git", + "url": "git@github.com:metafizzy/fizzy-ui-utils.git", + "reference": "72feb9fc3d6de25696291941121bb3ec2db8221e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/metafizzy/fizzy-ui-utils/zipball/72feb9fc3d6de25696291941121bb3ec2db8221e", + "reference": "72feb9fc3d6de25696291941121bb3ec2db8221e" + }, + "require": { + "bower-asset/desandro-matches-selector": ">=2.0.0,<3.0.0" + }, + "type": "bower-asset", + "license": [ + "MIT" + ] + }, + { + "name": "bower-asset/get-size", + "version": "v2.0.3", + "source": { + "type": "git", + "url": "git@github.com:desandro/get-size.git", + "reference": "6879e7f15b4b6e19ca392b6955edfa8d4aa6f787" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/desandro/get-size/zipball/6879e7f15b4b6e19ca392b6955edfa8d4aa6f787", + "reference": "6879e7f15b4b6e19ca392b6955edfa8d4aa6f787" + }, + "type": "bower-asset", + "license": [ + "MIT" + ] + }, + { + "name": "bower-asset/isotope", + "version": "v3.0.6", + "source": { + "type": "git", + "url": "git@github.com:metafizzy/isotope.git", + "reference": "ad008079ec0bc6387d2781b98cfd5c80a9fc0b40" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/metafizzy/isotope/zipball/ad008079ec0bc6387d2781b98cfd5c80a9fc0b40", + "reference": "ad008079ec0bc6387d2781b98cfd5c80a9fc0b40" + }, + "require": { + "bower-asset/desandro-matches-selector": ">=2.0.0,<3.0.0", + "bower-asset/fizzy-ui-utils": ">=2.0.4,<3.0.0", + "bower-asset/get-size": ">=2.0.0,<3.0.0", + "bower-asset/masonry-layout": ">=4.1.0,<5.0.0", + "bower-asset/outlayer": ">=2.1.0,<3.0.0" + }, + "type": "bower-asset", + "license": [ + "GPL-3.0" + ] + }, + { + "name": "bower-asset/masonry-layout", + "version": "v4.2.2", + "source": { + "type": "git", + "url": "git@github.com:desandro/masonry.git", + "reference": "3b0883cf4a4a046896719b9cf282ea74be7ffecd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/desandro/masonry/zipball/3b0883cf4a4a046896719b9cf282ea74be7ffecd", + "reference": "3b0883cf4a4a046896719b9cf282ea74be7ffecd" + }, + "require": { + "bower-asset/get-size": ">=2.0.2,<3.0.0", + "bower-asset/outlayer": ">=2.1.0,<3.0.0" + }, + "type": "bower-asset", + "license": [ + "MIT" + ] + }, + { + "name": "bower-asset/outlayer", + "version": "v2.1.1", + "source": { + "type": "git", + "url": "https://github.com/metafizzy/outlayer.git", + "reference": "bf31c5748bf84fcc2c553d1199a6ecaf0ebd9878" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/metafizzy/outlayer/zipball/bf31c5748bf84fcc2c553d1199a6ecaf0ebd9878", + "reference": "bf31c5748bf84fcc2c553d1199a6ecaf0ebd9878" + }, + "require": { + "bower-asset/ev-emitter": ">=1.0.0,<2.0.0", + "bower-asset/fizzy-ui-utils": ">=2.0.0,<3.0.0", + "bower-asset/get-size": ">=2.0.2,<3.0.0" + }, + "type": "bower-asset", + "license": [ + "MIT" + ] + }, + { + "name": "chi-teck/drupal-code-generator", + "version": "1.33.1", + "source": { + "type": "git", + "url": "https://github.com/Chi-teck/drupal-code-generator.git", + "reference": "5f814e980b6f9cf1ca8c74cc9385c3d81090d388" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Chi-teck/drupal-code-generator/zipball/5f814e980b6f9cf1ca8c74cc9385c3d81090d388", + "reference": "5f814e980b6f9cf1ca8c74cc9385c3d81090d388", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": ">=5.5.9", + "symfony/console": "^3.4 || ^4.0", + "symfony/filesystem": "^2.7 || ^3.4 || ^4.0", + "twig/twig": "^1.41 || ^2.12" + }, + "conflict": { + "drush/drush": "< 10.3.2" + }, + "bin": [ + "bin/dcg" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "files": [ + "src/bootstrap.php" + ], + "psr-4": { + "DrupalCodeGenerator\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0-or-later" + ], + "description": "Drupal code generator", + "support": { + "issues": "https://github.com/Chi-teck/drupal-code-generator/issues", + "source": "https://github.com/Chi-teck/drupal-code-generator/tree/1.33.1" + }, + "time": "2020-12-05T05:59:11+00:00" + }, + { + "name": "choices/choices", + "version": "9.0.1", + "dist": { + "type": "zip", + "url": "https://github.com/jshjohnson/Choices/archive/v9.0.1.zip" + }, + "type": "drupal-library", + "extra": { + "installer-name": "choices" + } + }, + { + "name": "ckeditor/autogrow", + "version": "4.17.1", + "dist": { + "type": "zip", + "url": "https://download.ckeditor.com/autogrow/releases/autogrow_4.17.1.zip" + }, + "type": "drupal-library", + "extra": { + "installer-name": "ckeditor.autogrow" + } + }, + { + "name": "ckeditor/codemirror", + "version": "v1.17.12", + "dist": { + "type": "zip", + "url": "https://github.com/w8tcha/CKEditor-CodeMirror-Plugin/releases/download/v1.17.12/CKEditor-CodeMirror-Plugin.zip" + }, + "type": "drupal-library", + "extra": { + "installer-name": "ckeditor.codemirror" + } + }, + { + "name": "ckeditor/fakeobjects", + "version": "4.17.1", + "dist": { + "type": "zip", + "url": "https://download.ckeditor.com/fakeobjects/releases/fakeobjects_4.17.1.zip" + }, + "type": "drupal-library", + "extra": { + "installer-name": "ckeditor.fakeobjects" + } + }, + { + "name": "ckeditor/image", + "version": "4.17.1", + "dist": { + "type": "zip", + "url": "https://download.ckeditor.com/image/releases/image_4.17.1.zip" + }, + "type": "drupal-library", + "extra": { + "installer-name": "ckeditor.image" + } + }, + { + "name": "ckeditor/link", + "version": "4.17.1", + "dist": { + "type": "zip", + "url": "https://download.ckeditor.com/link/releases/link_4.17.1.zip" + }, + "type": "drupal-library", + "extra": { + "installer-name": "ckeditor.link" + } + }, + { + "name": "ckeditor/tabletoolstoolbar", + "version": "0.0.1", + "dist": { + "type": "zip", + "url": "https://download.ckeditor.com/tabletoolstoolbar/releases/tabletoolstoolbar_0.0.1.zip" + }, + "type": "drupal-library" + }, + { + "name": "codemirror/codemirror", + "version": "5.61.1", + "dist": { + "type": "zip", + "url": "https://github.com/components/codemirror/archive/5.61.1.zip" + }, + "type": "drupal-library", + "extra": { + "installer-name": "codemirror" + } + }, + { + "name": "composer/ca-bundle", + "version": "1.3.1", + "source": { + "type": "git", + "url": "https://github.com/composer/ca-bundle.git", + "reference": "4c679186f2aca4ab6a0f1b0b9cf9252decb44d0b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/4c679186f2aca4ab6a0f1b0b9cf9252decb44d0b", + "reference": "4c679186f2aca4ab6a0f1b0b9cf9252decb44d0b", + "shasum": "" + }, + "require": { + "ext-openssl": "*", + "ext-pcre": "*", + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.55", + "psr/log": "^1.0", + "symfony/phpunit-bridge": "^4.2 || ^5", + "symfony/process": "^2.5 || ^3.0 || ^4.0 || ^5.0 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\CaBundle\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle.", + "keywords": [ + "cabundle", + "cacert", + "certificate", + "ssl", + "tls" + ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/ca-bundle/issues", + "source": "https://github.com/composer/ca-bundle/tree/1.3.1" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2021-10-28T20:44:15+00:00" + }, + { + "name": "composer/composer", + "version": "2.2.4", + "source": { + "type": "git", + "url": "https://github.com/composer/composer.git", + "reference": "8a5ad75194f901e3b39ece4bbd22cbdabc79ae8f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/composer/zipball/8a5ad75194f901e3b39ece4bbd22cbdabc79ae8f", + "reference": "8a5ad75194f901e3b39ece4bbd22cbdabc79ae8f", + "shasum": "" + }, + "require": { + "composer/ca-bundle": "^1.0", + "composer/metadata-minifier": "^1.0", + "composer/pcre": "^1.0", + "composer/semver": "^3.0", + "composer/spdx-licenses": "^1.2", + "composer/xdebug-handler": "^2.0", + "justinrainbow/json-schema": "^5.2.11", + "php": "^5.3.2 || ^7.0 || ^8.0", + "psr/log": "^1.0 || ^2.0", + "react/promise": "^1.2 || ^2.7", + "seld/jsonlint": "^1.4", + "seld/phar-utils": "^1.0", + "symfony/console": "^2.8.52 || ^3.4.35 || ^4.4 || ^5.0", + "symfony/filesystem": "^2.8.52 || ^3.4.35 || ^4.4 || ^5.0 || ^6.0", + "symfony/finder": "^2.8.52 || ^3.4.35 || ^4.4 || ^5.0 || ^6.0", + "symfony/process": "^2.8.52 || ^3.4.35 || ^4.4 || ^5.0 || ^6.0" + }, + "require-dev": { + "phpspec/prophecy": "^1.10", + "symfony/phpunit-bridge": "^4.2 || ^5.0 || ^6.0" + }, + "suggest": { + "ext-openssl": "Enabling the openssl extension allows you to access https URLs for repositories and packages", + "ext-zip": "Enabling the zip extension allows you to unzip archives", + "ext-zlib": "Allow gzip compression of HTTP requests" + }, + "bin": [ + "bin/composer" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.2-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\": "src/Composer" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "https://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "https://seld.be" + } + ], + "description": "Composer helps you declare, manage and install dependencies of PHP projects. It ensures you have the right stack everywhere.", + "homepage": "https://getcomposer.org/", + "keywords": [ + "autoload", + "dependency", + "package" + ], + "support": { + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/composer/issues", + "source": "https://github.com/composer/composer/tree/2.2.4" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2022-01-08T11:30:42+00:00" + }, + { + "name": "composer/installers", + "version": "v1.12.0", + "source": { + "type": "git", + "url": "https://github.com/composer/installers.git", + "reference": "d20a64ed3c94748397ff5973488761b22f6d3f19" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/installers/zipball/d20a64ed3c94748397ff5973488761b22f6d3f19", + "reference": "d20a64ed3c94748397ff5973488761b22f6d3f19", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0 || ^2.0" + }, + "replace": { + "roundcube/plugin-installer": "*", + "shama/baton": "*" + }, + "require-dev": { + "composer/composer": "1.6.* || ^2.0", + "composer/semver": "^1 || ^3", + "phpstan/phpstan": "^0.12.55", + "phpstan/phpstan-phpunit": "^0.12.16", + "symfony/phpunit-bridge": "^4.2 || ^5", + "symfony/process": "^2.3" + }, + "type": "composer-plugin", + "extra": { + "class": "Composer\\Installers\\Plugin", + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Installers\\": "src/Composer/Installers" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kyle Robinson Young", + "email": "kyle@dontkry.com", + "homepage": "https://github.com/shama" + } + ], + "description": "A multi-framework Composer library installer", + "homepage": "https://composer.github.io/installers/", + "keywords": [ + "Craft", + "Dolibarr", + "Eliasis", + "Hurad", + "ImageCMS", + "Kanboard", + "Lan Management System", + "MODX Evo", + "MantisBT", + "Mautic", + "Maya", + "OXID", + "Plentymarkets", + "Porto", + "RadPHP", + "SMF", + "Starbug", + "Thelia", + "Whmcs", + "WolfCMS", + "agl", + "aimeos", + "annotatecms", + "attogram", + "bitrix", + "cakephp", + "chef", + "cockpit", + "codeigniter", + "concrete5", + "croogo", + "dokuwiki", + "drupal", + "eZ Platform", + "elgg", + "expressionengine", + "fuelphp", + "grav", + "installer", + "itop", + "joomla", + "known", + "kohana", + "laravel", + "lavalite", + "lithium", + "magento", + "majima", + "mako", + "mediawiki", + "miaoxing", + "modulework", + "modx", + "moodle", + "osclass", + "pantheon", + "phpbb", + "piwik", + "ppi", + "processwire", + "puppet", + "pxcms", + "reindex", + "roundcube", + "shopware", + "silverstripe", + "sydes", + "sylius", + "symfony", + "tastyigniter", + "typo3", + "wordpress", + "yawik", + "zend", + "zikula" + ], + "support": { + "issues": "https://github.com/composer/installers/issues", + "source": "https://github.com/composer/installers/tree/v1.12.0" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2021-09-13T08:19:44+00:00" + }, + { + "name": "composer/metadata-minifier", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/composer/metadata-minifier.git", + "reference": "c549d23829536f0d0e984aaabbf02af91f443207" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/metadata-minifier/zipball/c549d23829536f0d0e984aaabbf02af91f443207", + "reference": "c549d23829536f0d0e984aaabbf02af91f443207", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "composer/composer": "^2", + "phpstan/phpstan": "^0.12.55", + "symfony/phpunit-bridge": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\MetadataMinifier\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Small utility library that handles metadata minification and expansion.", + "keywords": [ + "composer", + "compression" + ], + "support": { + "issues": "https://github.com/composer/metadata-minifier/issues", + "source": "https://github.com/composer/metadata-minifier/tree/1.0.0" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2021-04-07T13:37:33+00:00" + }, + { + "name": "composer/pcre", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/composer/pcre.git", + "reference": "3d322d715c43a1ac36c7fe215fa59336265500f2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/pcre/zipball/3d322d715c43a1ac36c7fe215fa59336265500f2", + "reference": "3d322d715c43a1ac36c7fe215fa59336265500f2", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/phpunit-bridge": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Pcre\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", + "keywords": [ + "PCRE", + "preg", + "regex", + "regular expression" + ], + "support": { + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/1.0.0" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2021-12-06T15:17:27+00:00" + }, + { + "name": "composer/semver", + "version": "3.2.6", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "83e511e247de329283478496f7a1e114c9517506" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/83e511e247de329283478496f7a1e114c9517506", + "reference": "83e511e247de329283478496f7a1e114c9517506", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.54", + "symfony/phpunit-bridge": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/3.2.6" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2021-10-25T11:34:17+00:00" + }, + { + "name": "composer/spdx-licenses", + "version": "1.5.6", + "source": { + "type": "git", + "url": "https://github.com/composer/spdx-licenses.git", + "reference": "a30d487169d799745ca7280bc90fdfa693536901" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/a30d487169d799745ca7280bc90fdfa693536901", + "reference": "a30d487169d799745ca7280bc90fdfa693536901", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.55", + "symfony/phpunit-bridge": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Spdx\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "SPDX licenses list and validation library.", + "keywords": [ + "license", + "spdx", + "validator" + ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/spdx-licenses/issues", + "source": "https://github.com/composer/spdx-licenses/tree/1.5.6" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2021-11-18T10:14:14+00:00" + }, + { + "name": "composer/xdebug-handler", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "0c1a3925ec58a4ec98e992b9c7d171e9e184be0a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/0c1a3925ec58a4ec98e992b9c7d171e9e184be0a", + "reference": "0c1a3925ec58a4ec98e992b9c7d171e9e184be0a", + "shasum": "" + }, + "require": { + "composer/pcre": "^1", + "php": "^5.3.2 || ^7.0 || ^8.0", + "psr/log": "^1 || ^2 || ^3" + }, + "require-dev": { + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/phpunit-bridge": "^4.2 || ^5.0 || ^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without Xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/xdebug-handler/issues", + "source": "https://github.com/composer/xdebug-handler/tree/2.0.4" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2022-01-04T17:06:45+00:00" + }, + { + "name": "consolidation/annotated-command", + "version": "4.4.0", + "source": { + "type": "git", + "url": "https://github.com/consolidation/annotated-command.git", + "reference": "308f6ac178566a1ce9aa90ed908dac90a2c1e707" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/annotated-command/zipball/308f6ac178566a1ce9aa90ed908dac90a2c1e707", + "reference": "308f6ac178566a1ce9aa90ed908dac90a2c1e707", + "shasum": "" + }, + "require": { + "consolidation/output-formatters": "^4.1.1", + "php": ">=7.1.3", + "psr/log": "^1|^2", + "symfony/console": "^4.4.8|~5.1.0", + "symfony/event-dispatcher": "^4.4.8|^5", + "symfony/finder": "^4.4.8|^5" + }, + "require-dev": { + "phpunit/phpunit": "^7.5.20 || ^8 || ^9", + "squizlabs/php_codesniffer": "^3", + "yoast/phpunit-polyfills": "^0.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.x-dev" + } + }, + "autoload": { + "psr-4": { + "Consolidation\\AnnotatedCommand\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + } + ], + "description": "Initialize Symfony Console commands from annotated command class methods.", + "support": { + "issues": "https://github.com/consolidation/annotated-command/issues", + "source": "https://github.com/consolidation/annotated-command/tree/4.4.0" + }, + "time": "2021-09-30T01:08:15+00:00" + }, + { + "name": "consolidation/config", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/consolidation/config.git", + "reference": "cac1279bae7efb5c7fb2ca4c3ba4b8eb741a96c1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/config/zipball/cac1279bae7efb5c7fb2ca4c3ba4b8eb741a96c1", + "reference": "cac1279bae7efb5c7fb2ca4c3ba4b8eb741a96c1", + "shasum": "" + }, + "require": { + "dflydev/dot-access-data": "^1.1.0", + "grasmash/expander": "^1", + "php": ">=5.4.0" + }, + "require-dev": { + "g1a/composer-test-scenarios": "^3", + "php-coveralls/php-coveralls": "^1", + "phpunit/phpunit": "^5", + "squizlabs/php_codesniffer": "2.*", + "symfony/console": "^2.5|^3|^4", + "symfony/yaml": "^2.8.11|^3|^4" + }, + "suggest": { + "symfony/yaml": "Required to use Consolidation\\Config\\Loader\\YamlConfigLoader" + }, + "type": "library", + "extra": { + "scenarios": { + "symfony4": { + "require-dev": { + "symfony/console": "^4.0" + }, + "config": { + "platform": { + "php": "7.1.3" + } + } + }, + "symfony2": { + "require-dev": { + "symfony/console": "^2.8", + "symfony/event-dispatcher": "^2.8", + "phpunit/phpunit": "^4.8.36" + }, + "remove": [ + "php-coveralls/php-coveralls" + ], + "config": { + "platform": { + "php": "5.4.8" + } + } + } + }, + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Consolidation\\Config\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + } + ], + "description": "Provide configuration services for a commandline tool.", + "support": { + "issues": "https://github.com/consolidation/config/issues", + "source": "https://github.com/consolidation/config/tree/master" + }, + "time": "2019-03-03T19:37:04+00:00" + }, + { + "name": "consolidation/filter-via-dot-access-data", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/consolidation/filter-via-dot-access-data.git", + "reference": "a53e96c6b9f7f042f5e085bf911f3493cea823c6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/filter-via-dot-access-data/zipball/a53e96c6b9f7f042f5e085bf911f3493cea823c6", + "reference": "a53e96c6b9f7f042f5e085bf911f3493cea823c6", + "shasum": "" + }, + "require": { + "dflydev/dot-access-data": "^1.1.0", + "php": ">=5.5.0" + }, + "require-dev": { + "consolidation/robo": "^1.2.3", + "g1a/composer-test-scenarios": "^3", + "knplabs/github-api": "^2.7", + "php-coveralls/php-coveralls": "^1", + "php-http/guzzle6-adapter": "^1.1", + "phpunit/phpunit": "^5", + "squizlabs/php_codesniffer": "^2.8", + "symfony/console": "^2.8|^3|^4" + }, + "type": "library", + "extra": { + "scenarios": { + "phpunit5": { + "require-dev": { + "phpunit/phpunit": "^5.7.27" + }, + "remove": [ + "php-coveralls/php-coveralls" + ], + "config": { + "platform": { + "php": "5.6.33" + } + } + } + }, + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Consolidation\\Filter\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + } + ], + "description": "This project uses dflydev/dot-access-data to provide simple output filtering for applications built with annotated-command / Robo.", + "support": { + "source": "https://github.com/consolidation/filter-via-dot-access-data/tree/1.0.0" + }, + "time": "2019-01-18T06:05:07+00:00" + }, + { + "name": "consolidation/log", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/consolidation/log.git", + "reference": "82a2aaaa621a7b976e50a745a8d249d5085ee2b1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/log/zipball/82a2aaaa621a7b976e50a745a8d249d5085ee2b1", + "reference": "82a2aaaa621a7b976e50a745a8d249d5085ee2b1", + "shasum": "" + }, + "require": { + "php": ">=7.1.3", + "psr/log": "^1.0", + "symfony/console": "^4|^5" + }, + "require-dev": { + "phpunit/phpunit": ">=7.5.20", + "squizlabs/php_codesniffer": "^3", + "yoast/phpunit-polyfills": "^0.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Consolidation\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + } + ], + "description": "Improved Psr-3 / Psr\\Log logger based on Symfony Console components.", + "support": { + "issues": "https://github.com/consolidation/log/issues", + "source": "https://github.com/consolidation/log/tree/2.0.2" + }, + "time": "2020-12-10T16:26:23+00:00" + }, + { + "name": "consolidation/output-formatters", + "version": "4.1.2", + "source": { + "type": "git", + "url": "https://github.com/consolidation/output-formatters.git", + "reference": "5821e6ae076bf690058a4de6c94dce97398a69c9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/output-formatters/zipball/5821e6ae076bf690058a4de6c94dce97398a69c9", + "reference": "5821e6ae076bf690058a4de6c94dce97398a69c9", + "shasum": "" + }, + "require": { + "dflydev/dot-access-data": "^1.1.0", + "php": ">=7.1.3", + "symfony/console": "^4|^5", + "symfony/finder": "^4|^5" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.4.2", + "phpunit/phpunit": ">=7", + "squizlabs/php_codesniffer": "^3", + "symfony/var-dumper": "^4", + "symfony/yaml": "^4", + "yoast/phpunit-polyfills": "^0.2.0" + }, + "suggest": { + "symfony/var-dumper": "For using the var_dump formatter" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.x-dev" + } + }, + "autoload": { + "psr-4": { + "Consolidation\\OutputFormatters\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + } + ], + "description": "Format text by applying transformations provided by plug-in formatters.", + "support": { + "issues": "https://github.com/consolidation/output-formatters/issues", + "source": "https://github.com/consolidation/output-formatters/tree/4.1.2" + }, + "time": "2020-12-12T19:04:59+00:00" + }, + { + "name": "consolidation/robo", + "version": "3.0.6", + "source": { + "type": "git", + "url": "https://github.com/consolidation/Robo.git", + "reference": "36dce2965a67abe5cf91f2bc36d2582a64a11258" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/Robo/zipball/36dce2965a67abe5cf91f2bc36d2582a64a11258", + "reference": "36dce2965a67abe5cf91f2bc36d2582a64a11258", + "shasum": "" + }, + "require": { + "consolidation/annotated-command": "^4.3", + "consolidation/config": "^1.2.1|^2.0.1", + "consolidation/log": "^1.1.1|^2.0.2", + "consolidation/output-formatters": "^4.1.2", + "consolidation/self-update": "^2.0", + "league/container": "^3.3.1", + "php": ">=7.1.3", + "symfony/console": "^4.4.19 || ^5", + "symfony/event-dispatcher": "^4.4.19 || ^5", + "symfony/filesystem": "^4.4.9 || ^5", + "symfony/finder": "^4.4.9 || ^5", + "symfony/process": "^4.4.9 || ^5", + "symfony/yaml": "^4.4 || ^5" + }, + "conflict": { + "codegyre/robo": "*" + }, + "require-dev": { + "natxet/cssmin": "3.0.4", + "patchwork/jsqueeze": "^2", + "pear/archive_tar": "^1.4.4", + "phpunit/phpunit": "^7.5.20 | ^8", + "squizlabs/php_codesniffer": "^3.6", + "yoast/phpunit-polyfills": "^0.2.0" + }, + "suggest": { + "natxet/cssmin": "For minifying CSS files in taskMinify", + "patchwork/jsqueeze": "For minifying JS files in taskMinify", + "pear/archive_tar": "Allows tar archives to be created and extracted in taskPack and taskExtract, respectively.", + "totten/lurkerlite": "For monitoring filesystem changes in taskWatch" + }, + "bin": [ + "robo" + ], + "type": "library", + "extra": { + "scenarios": { + "symfony4": { + "require": { + "symfony/console": "^4.4.11", + "symfony/event-dispatcher": "^4.4.11", + "symfony/filesystem": "^4.4.11", + "symfony/finder": "^4.4.11", + "symfony/process": "^4.4.11", + "phpunit/phpunit": "^6", + "nikic/php-parser": "^2" + }, + "remove": [ + "codeception/phpunit-wrapper" + ], + "config": { + "platform": { + "php": "7.1.3" + } + } + } + }, + "branch-alias": { + "dev-master": "2.x-dev", + "dev-main": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Robo\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Davert", + "email": "davert.php@resend.cc" + } + ], + "description": "Modern task runner", + "support": { + "issues": "https://github.com/consolidation/Robo/issues", + "source": "https://github.com/consolidation/Robo/tree/3.0.6" + }, + "time": "2021-10-05T23:56:45+00:00" + }, + { + "name": "consolidation/self-update", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/consolidation/self-update.git", + "reference": "7d6877f8006c51069e1469a9c57b1435640f74b7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/self-update/zipball/7d6877f8006c51069e1469a9c57b1435640f74b7", + "reference": "7d6877f8006c51069e1469a9c57b1435640f74b7", + "shasum": "" + }, + "require": { + "composer/semver": "^3.2", + "php": ">=5.5.0", + "symfony/console": "^2.8|^3|^4|^5", + "symfony/filesystem": "^2.5|^3|^4|^5" + }, + "bin": [ + "scripts/release" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "SelfUpdate\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Alexander Menk", + "email": "menk@mestrona.net" + }, + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + } + ], + "description": "Provides a self:update command for Symfony Console applications.", + "support": { + "issues": "https://github.com/consolidation/self-update/issues", + "source": "https://github.com/consolidation/self-update/tree/2.0.0" + }, + "time": "2021-10-05T23:29:47+00:00" + }, + { + "name": "consolidation/site-alias", + "version": "3.1.1", + "source": { + "type": "git", + "url": "https://github.com/consolidation/site-alias.git", + "reference": "e824b57253d9174f4a500f87e6d0e1e497c2a50a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/site-alias/zipball/e824b57253d9174f4a500f87e6d0e1e497c2a50a", + "reference": "e824b57253d9174f4a500f87e6d0e1e497c2a50a", + "shasum": "" + }, + "require": { + "consolidation/config": "^1.2.1|^2", + "php": ">=5.5.0", + "symfony/finder": "~2.3|^3|^4.4|^5" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.4.2", + "phpunit/phpunit": ">=7", + "squizlabs/php_codesniffer": "^3", + "symfony/var-dumper": "^4", + "yoast/phpunit-polyfills": "^0.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Consolidation\\SiteAlias\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + }, + { + "name": "Moshe Weitzman", + "email": "weitzman@tejasa.com" + } + ], + "description": "Manage alias records for local and remote sites.", + "support": { + "issues": "https://github.com/consolidation/site-alias/issues", + "source": "https://github.com/consolidation/site-alias/tree/3.1.1" + }, + "time": "2021-09-21T00:30:48+00:00" + }, + { + "name": "consolidation/site-process", + "version": "4.1.0", + "source": { + "type": "git", + "url": "https://github.com/consolidation/site-process.git", + "reference": "ef57711d7049f7606ce936ded16ad93f1ad7f02c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/site-process/zipball/ef57711d7049f7606ce936ded16ad93f1ad7f02c", + "reference": "ef57711d7049f7606ce936ded16ad93f1ad7f02c", + "shasum": "" + }, + "require": { + "consolidation/config": "^1.2.1|^2", + "consolidation/site-alias": "^3", + "php": ">=7.1.3", + "symfony/console": "^2.8.52|^3|^4.4|^5", + "symfony/process": "^4.3.4" + }, + "require-dev": { + "phpunit/phpunit": "^7.5.20|^8.5.14", + "squizlabs/php_codesniffer": "^3", + "yoast/phpunit-polyfills": "^0.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.x-dev" + } + }, + "autoload": { + "psr-4": { + "Consolidation\\SiteProcess\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + }, + { + "name": "Moshe Weitzman", + "email": "weitzman@tejasa.com" + } + ], + "description": "A thin wrapper around the Symfony Process Component that allows applications to use the Site Alias library to specify the target for a remote call.", + "support": { + "issues": "https://github.com/consolidation/site-process/issues", + "source": "https://github.com/consolidation/site-process/tree/4.1.0" + }, + "time": "2021-02-21T02:53:33+00:00" + }, + { + "name": "container-interop/container-interop", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/container-interop/container-interop.git", + "reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/container-interop/container-interop/zipball/79cbf1341c22ec75643d841642dd5d6acd83bdb8", + "reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8", + "shasum": "" + }, + "require": { + "psr/container": "^1.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Interop\\Container\\": "src/Interop/Container/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Promoting the interoperability of container objects (DIC, SL, etc.)", + "homepage": "https://github.com/container-interop/container-interop", + "support": { + "issues": "https://github.com/container-interop/container-interop/issues", + "source": "https://github.com/container-interop/container-interop/tree/master" + }, + "abandoned": "psr/container", + "time": "2017-02-14T19:40:03+00:00" + }, + { + "name": "cweagans/composer-patches", + "version": "1.7.1", + "source": { + "type": "git", + "url": "https://github.com/cweagans/composer-patches.git", + "reference": "9888dcc74993c030b75f3dd548bb5e20cdbd740c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/cweagans/composer-patches/zipball/9888dcc74993c030b75f3dd548bb5e20cdbd740c", + "reference": "9888dcc74993c030b75f3dd548bb5e20cdbd740c", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0 || ^2.0", + "php": ">=5.3.0" + }, + "require-dev": { + "composer/composer": "~1.0 || ~2.0", + "phpunit/phpunit": "~4.6" + }, + "type": "composer-plugin", + "extra": { + "class": "cweagans\\Composer\\Patches" + }, + "autoload": { + "psr-4": { + "cweagans\\Composer\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Cameron Eagans", + "email": "me@cweagans.net" + } + ], + "description": "Provides a way to patch Composer packages.", + "support": { + "issues": "https://github.com/cweagans/composer-patches/issues", + "source": "https://github.com/cweagans/composer-patches/tree/1.7.1" + }, + "time": "2021-06-08T15:12:46+00:00" + }, + { + "name": "dealerdirect/phpcodesniffer-composer-installer", + "version": "v0.7.1", + "source": { + "type": "git", + "url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git", + "reference": "fe390591e0241955f22eb9ba327d137e501c771c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/fe390591e0241955f22eb9ba327d137e501c771c", + "reference": "fe390591e0241955f22eb9ba327d137e501c771c", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0 || ^2.0", + "php": ">=5.3", + "squizlabs/php_codesniffer": "^2.0 || ^3.0 || ^4.0" + }, + "require-dev": { + "composer/composer": "*", + "phpcompatibility/php-compatibility": "^9.0", + "sensiolabs/security-checker": "^4.1.0" + }, + "type": "composer-plugin", + "extra": { + "class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" + }, + "autoload": { + "psr-4": { + "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Franck Nijhof", + "email": "franck.nijhof@dealerdirect.com", + "homepage": "http://www.frenck.nl", + "role": "Developer / IT Manager" + } + ], + "description": "PHP_CodeSniffer Standards Composer Installer Plugin", + "homepage": "http://www.dealerdirect.com", + "keywords": [ + "PHPCodeSniffer", + "PHP_CodeSniffer", + "code quality", + "codesniffer", + "composer", + "installer", + "phpcs", + "plugin", + "qa", + "quality", + "standard", + "standards", + "style guide", + "stylecheck", + "tests" + ], + "support": { + "issues": "https://github.com/dealerdirect/phpcodesniffer-composer-installer/issues", + "source": "https://github.com/dealerdirect/phpcodesniffer-composer-installer" + }, + "time": "2020-12-07T18:04:37+00:00" + }, + { + "name": "defuse/php-encryption", + "version": "v2.3.1", + "source": { + "type": "git", + "url": "https://github.com/defuse/php-encryption.git", + "reference": "77880488b9954b7884c25555c2a0ea9e7053f9d2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/defuse/php-encryption/zipball/77880488b9954b7884c25555c2a0ea9e7053f9d2", + "reference": "77880488b9954b7884c25555c2a0ea9e7053f9d2", + "shasum": "" + }, + "require": { + "ext-openssl": "*", + "paragonie/random_compat": ">= 2", + "php": ">=5.6.0" + }, + "require-dev": { + "phpunit/phpunit": "^4|^5|^6|^7|^8|^9" + }, + "bin": [ + "bin/generate-defuse-key" + ], + "type": "library", + "autoload": { + "psr-4": { + "Defuse\\Crypto\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Hornby", + "email": "taylor@defuse.ca", + "homepage": "https://defuse.ca/" + }, + { + "name": "Scott Arciszewski", + "email": "info@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "Secure PHP Encryption Library", + "keywords": [ + "aes", + "authenticated encryption", + "cipher", + "crypto", + "cryptography", + "encrypt", + "encryption", + "openssl", + "security", + "symmetric key cryptography" + ], + "support": { + "issues": "https://github.com/defuse/php-encryption/issues", + "source": "https://github.com/defuse/php-encryption/tree/v2.3.1" + }, + "time": "2021-04-09T23:57:26+00:00" + }, + { + "name": "dflydev/dot-access-configuration", + "version": "v1.0.3", + "source": { + "type": "git", + "url": "https://github.com/dflydev/dflydev-dot-access-configuration.git", + "reference": "2e6eb0c8b8830b26bb23defcfc38d4276508fc49" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dflydev/dflydev-dot-access-configuration/zipball/2e6eb0c8b8830b26bb23defcfc38d4276508fc49", + "reference": "2e6eb0c8b8830b26bb23defcfc38d4276508fc49", + "shasum": "" + }, + "require": { + "dflydev/dot-access-data": "1.*", + "dflydev/placeholder-resolver": "1.*", + "php": ">=5.3.2" + }, + "require-dev": { + "symfony/yaml": "~2.1" + }, + "suggest": { + "symfony/yaml": "Required for using the YAML Configuration Builders" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-0": { + "Dflydev\\DotAccessConfiguration": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dragonfly Development Inc.", + "email": "info@dflydev.com", + "homepage": "http://dflydev.com" + }, + { + "name": "Beau Simensen", + "email": "beau@dflydev.com", + "homepage": "http://beausimensen.com" + } + ], + "description": "Given a deep data structure representing a configuration, access configuration by dot notation.", + "homepage": "https://github.com/dflydev/dflydev-dot-access-configuration", + "keywords": [ + "config", + "configuration" + ], + "support": { + "issues": "https://github.com/dflydev/dflydev-dot-access-configuration/issues", + "source": "https://github.com/dflydev/dflydev-dot-access-configuration/tree/master" + }, + "time": "2018-09-08T23:00:17+00:00" + }, + { + "name": "dflydev/dot-access-data", + "version": "v1.1.0", + "source": { + "type": "git", + "url": "https://github.com/dflydev/dflydev-dot-access-data.git", + "reference": "3fbd874921ab2c041e899d044585a2ab9795df8a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/3fbd874921ab2c041e899d044585a2ab9795df8a", + "reference": "3fbd874921ab2c041e899d044585a2ab9795df8a", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-0": { + "Dflydev\\DotAccessData": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dragonfly Development Inc.", + "email": "info@dflydev.com", + "homepage": "http://dflydev.com" + }, + { + "name": "Beau Simensen", + "email": "beau@dflydev.com", + "homepage": "http://beausimensen.com" + }, + { + "name": "Carlos Frutos", + "email": "carlos@kiwing.it", + "homepage": "https://github.com/cfrutos" + } + ], + "description": "Given a deep data structure, access data by dot notation.", + "homepage": "https://github.com/dflydev/dflydev-dot-access-data", + "keywords": [ + "access", + "data", + "dot", + "notation" + ], + "support": { + "issues": "https://github.com/dflydev/dflydev-dot-access-data/issues", + "source": "https://github.com/dflydev/dflydev-dot-access-data/tree/master" + }, + "time": "2017-01-20T21:14:22+00:00" + }, + { + "name": "dflydev/placeholder-resolver", + "version": "v1.0.2", + "source": { + "type": "git", + "url": "https://github.com/dflydev/dflydev-placeholder-resolver.git", + "reference": "c498d0cae91b1bb36cc7d60906dab8e62bb7c356" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dflydev/dflydev-placeholder-resolver/zipball/c498d0cae91b1bb36cc7d60906dab8e62bb7c356", + "reference": "c498d0cae91b1bb36cc7d60906dab8e62bb7c356", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-0": { + "Dflydev\\PlaceholderResolver": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dragonfly Development Inc.", + "email": "info@dflydev.com", + "homepage": "http://dflydev.com" + }, + { + "name": "Beau Simensen", + "email": "beau@dflydev.com", + "homepage": "http://beausimensen.com" + } + ], + "description": "Given a data source representing key => value pairs, resolve placeholders like ${foo.bar} to the value associated with the 'foo.bar' key in the data source.", + "homepage": "https://github.com/dflydev/dflydev-placeholder-resolver", + "keywords": [ + "placeholder", + "resolver" + ], + "support": { + "issues": "https://github.com/dflydev/dflydev-placeholder-resolver/issues", + "source": "https://github.com/dflydev/dflydev-placeholder-resolver/tree/v1.0.2" + }, + "time": "2012-10-28T21:08:28+00:00" + }, + { + "name": "dmore/behat-chrome-extension", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://gitlab.com/DMore/behat-chrome-extension.git", + "reference": "6279986ef85ac179f055460502e9b11c3784146c" + }, + "dist": { + "type": "zip", + "url": "https://gitlab.com/api/v4/projects/DMore%2Fbehat-chrome-extension/repository/archive.zip?sha=6279986ef85ac179f055460502e9b11c3784146c", + "reference": "6279986ef85ac179f055460502e9b11c3784146c", + "shasum": "" + }, + "require": { + "behat/behat": "^3.0.4", + "behat/mink-extension": "^2.0", + "dmore/chrome-mink-driver": "^2.4.1", + "php": ">=5.6" + }, + "require-dev": { + "phpunit/phpunit": "^5.7" + }, + "type": "library", + "autoload": { + "psr-4": { + "DMore\\ChromeExtension\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dorian More", + "email": "doriancmore@gmail.com" + } + ], + "description": "Behat extension for controlling chrome without selenium", + "keywords": [ + "Behat", + "chrome", + "driver", + "headless" + ], + "time": "2019-03-30T08:57:34+00:00" + }, + { + "name": "dmore/chrome-mink-driver", + "version": "2.8.0", + "source": { + "type": "git", + "url": "https://gitlab.com/DMore/chrome-mink-driver.git", + "reference": "f85c8f86ca2e9000119c310577a6942683f7e280" + }, + "dist": { + "type": "zip", + "url": "https://gitlab.com/api/v4/projects/DMore%2Fchrome-mink-driver/repository/archive.zip?sha=f85c8f86ca2e9000119c310577a6942683f7e280", + "reference": "f85c8f86ca2e9000119c310577a6942683f7e280", + "shasum": "" + }, + "require": { + "behat/mink": "^1.7", + "ext-curl": "*", + "ext-json": "*", + "ext-mbstring": "*", + "textalk/websocket": "^1.2.0" + }, + "require-dev": { + "mink/driver-testsuite": "dev-master", + "phpunit/phpunit": "^5.0.0", + "squizlabs/php_codesniffer": "^3.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "DMore\\ChromeDriver\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dorian More", + "email": "doriancmore@gmail.com" + } + ], + "description": "Mink driver for controlling chrome without selenium", + "support": { + "issues": "https://gitlab.com/api/v4/projects/3255077/issues" + }, + "time": "2021-04-25T06:49:32+00:00" + }, + { + "name": "doctrine/annotations", + "version": "1.13.2", + "source": { + "type": "git", + "url": "https://github.com/doctrine/annotations.git", + "reference": "5b668aef16090008790395c02c893b1ba13f7e08" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/5b668aef16090008790395c02c893b1ba13f7e08", + "reference": "5b668aef16090008790395c02c893b1ba13f7e08", + "shasum": "" + }, + "require": { + "doctrine/lexer": "1.*", + "ext-tokenizer": "*", + "php": "^7.1 || ^8.0", + "psr/cache": "^1 || ^2 || ^3" + }, + "require-dev": { + "doctrine/cache": "^1.11 || ^2.0", + "doctrine/coding-standard": "^6.0 || ^8.1", + "phpstan/phpstan": "^0.12.20", + "phpunit/phpunit": "^7.5 || ^8.0 || ^9.1.5", + "symfony/cache": "^4.4 || ^5.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Docblock Annotations Parser", + "homepage": "https://www.doctrine-project.org/projects/annotations.html", + "keywords": [ + "annotations", + "docblock", + "parser" + ], + "support": { + "issues": "https://github.com/doctrine/annotations/issues", + "source": "https://github.com/doctrine/annotations/tree/1.13.2" + }, + "time": "2021-08-05T19:00:23+00:00" + }, + { + "name": "doctrine/cache", + "version": "1.12.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/cache.git", + "reference": "4cf401d14df219fa6f38b671f5493449151c9ad8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/cache/zipball/4cf401d14df219fa6f38b671f5493449151c9ad8", + "reference": "4cf401d14df219fa6f38b671f5493449151c9ad8", + "shasum": "" + }, + "require": { + "php": "~7.1 || ^8.0" + }, + "conflict": { + "doctrine/common": ">2.2,<2.4" + }, + "require-dev": { + "alcaeus/mongo-php-adapter": "^1.1", + "cache/integration-tests": "dev-master", + "doctrine/coding-standard": "^8.0", + "mongodb/mongodb": "^1.1", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0", + "predis/predis": "~1.0", + "psr/cache": "^1.0 || ^2.0 || ^3.0", + "symfony/cache": "^4.4 || ^5.2 || ^6.0@dev", + "symfony/var-exporter": "^4.4 || ^5.2 || ^6.0@dev" + }, + "suggest": { + "alcaeus/mongo-php-adapter": "Required to use legacy MongoDB driver" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Cache library is a popular cache implementation that supports many different drivers such as redis, memcache, apc, mongodb and others.", + "homepage": "https://www.doctrine-project.org/projects/cache.html", + "keywords": [ + "abstraction", + "apcu", + "cache", + "caching", + "couchdb", + "memcached", + "php", + "redis", + "xcache" + ], + "support": { + "issues": "https://github.com/doctrine/cache/issues", + "source": "https://github.com/doctrine/cache/tree/1.12.1" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fcache", + "type": "tidelift" + } + ], + "time": "2021-07-17T14:39:21+00:00" + }, + { + "name": "doctrine/collections", + "version": "1.6.8", + "source": { + "type": "git", + "url": "https://github.com/doctrine/collections.git", + "reference": "1958a744696c6bb3bb0d28db2611dc11610e78af" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/collections/zipball/1958a744696c6bb3bb0d28db2611dc11610e78af", + "reference": "1958a744696c6bb3bb0d28db2611dc11610e78af", + "shasum": "" + }, + "require": { + "php": "^7.1.3 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9.0", + "phpstan/phpstan": "^0.12", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.1.5", + "vimeo/psalm": "^4.2.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Collections\\": "lib/Doctrine/Common/Collections" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Collections library that adds additional functionality on top of PHP arrays.", + "homepage": "https://www.doctrine-project.org/projects/collections.html", + "keywords": [ + "array", + "collections", + "iterators", + "php" + ], + "support": { + "issues": "https://github.com/doctrine/collections/issues", + "source": "https://github.com/doctrine/collections/tree/1.6.8" + }, + "time": "2021-08-10T18:51:53+00:00" + }, + { + "name": "doctrine/common", + "version": "2.13.3", + "source": { + "type": "git", + "url": "https://github.com/doctrine/common.git", + "reference": "f3812c026e557892c34ef37f6ab808a6b567da7f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/common/zipball/f3812c026e557892c34ef37f6ab808a6b567da7f", + "reference": "f3812c026e557892c34ef37f6ab808a6b567da7f", + "shasum": "" + }, + "require": { + "doctrine/annotations": "^1.0", + "doctrine/cache": "^1.0", + "doctrine/collections": "^1.0", + "doctrine/event-manager": "^1.0", + "doctrine/inflector": "^1.0", + "doctrine/lexer": "^1.0", + "doctrine/persistence": "^1.3.3", + "doctrine/reflection": "^1.0", + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^1.0", + "phpstan/phpstan": "^0.11", + "phpstan/phpstan-phpunit": "^0.11", + "phpunit/phpunit": "^7.0", + "squizlabs/php_codesniffer": "^3.0", + "symfony/phpunit-bridge": "^4.0.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.11.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\": "lib/Doctrine/Common" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + }, + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" + } + ], + "description": "PHP Doctrine Common project is a library that provides additional functionality that other Doctrine projects depend on such as better reflection support, persistence interfaces, proxies, event system and much more.", + "homepage": "https://www.doctrine-project.org/projects/common.html", + "keywords": [ + "common", + "doctrine", + "php" + ], + "support": { + "issues": "https://github.com/doctrine/common/issues", + "source": "https://github.com/doctrine/common/tree/2.13.x" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fcommon", + "type": "tidelift" + } + ], + "time": "2020-06-05T16:46:05+00:00" + }, + { + "name": "doctrine/event-manager", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/event-manager.git", + "reference": "41370af6a30faa9dc0368c4a6814d596e81aba7f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/event-manager/zipball/41370af6a30faa9dc0368c4a6814d596e81aba7f", + "reference": "41370af6a30faa9dc0368c4a6814d596e81aba7f", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/common": "<2.9@dev" + }, + "require-dev": { + "doctrine/coding-standard": "^6.0", + "phpunit/phpunit": "^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\": "lib/Doctrine/Common" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + }, + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" + } + ], + "description": "The Doctrine Event Manager is a simple PHP event system that was built to be used with the various Doctrine projects.", + "homepage": "https://www.doctrine-project.org/projects/event-manager.html", + "keywords": [ + "event", + "event dispatcher", + "event manager", + "event system", + "events" + ], + "support": { + "issues": "https://github.com/doctrine/event-manager/issues", + "source": "https://github.com/doctrine/event-manager/tree/1.1.x" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fevent-manager", + "type": "tidelift" + } + ], + "time": "2020-05-29T18:28:51+00:00" + }, + { + "name": "doctrine/inflector", + "version": "1.4.4", + "source": { + "type": "git", + "url": "https://github.com/doctrine/inflector.git", + "reference": "4bd5c1cdfcd00e9e2d8c484f79150f67e5d355d9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/4bd5c1cdfcd00e9e2d8c484f79150f67e5d355d9", + "reference": "4bd5c1cdfcd00e9e2d8c484f79150f67e5d355d9", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^8.0", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-phpunit": "^0.12", + "phpstan/phpstan-strict-rules": "^0.12", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\Inflector\\": "lib/Doctrine/Common/Inflector", + "Doctrine\\Inflector\\": "lib/Doctrine/Inflector" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Inflector is a small library that can perform string manipulations with regard to upper/lowercase and singular/plural forms of words.", + "homepage": "https://www.doctrine-project.org/projects/inflector.html", + "keywords": [ + "inflection", + "inflector", + "lowercase", + "manipulation", + "php", + "plural", + "singular", + "strings", + "uppercase", + "words" + ], + "support": { + "issues": "https://github.com/doctrine/inflector/issues", + "source": "https://github.com/doctrine/inflector/tree/1.4.4" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finflector", + "type": "tidelift" + } + ], + "time": "2021-04-16T17:34:40+00:00" + }, + { + "name": "doctrine/instantiator", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b", + "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^8.0", + "ext-pdo": "*", + "ext-phar": "*", + "phpbench/phpbench": "^0.13 || 1.0.0-alpha2", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-phpunit": "^0.12", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "https://ocramius.github.io/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", + "keywords": [ + "constructor", + "instantiate" + ], + "support": { + "issues": "https://github.com/doctrine/instantiator/issues", + "source": "https://github.com/doctrine/instantiator/tree/1.4.0" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", + "type": "tidelift" + } + ], + "time": "2020-11-10T18:47:58+00:00" + }, + { + "name": "doctrine/lexer", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "e864bbf5904cb8f5bb334f99209b48018522f042" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/e864bbf5904cb8f5bb334f99209b48018522f042", + "reference": "e864bbf5904cb8f5bb334f99209b48018522f042", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^6.0", + "phpstan/phpstan": "^0.11.8", + "phpunit/phpunit": "^8.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "https://www.doctrine-project.org/projects/lexer.html", + "keywords": [ + "annotations", + "docblock", + "lexer", + "parser", + "php" + ], + "support": { + "issues": "https://github.com/doctrine/lexer/issues", + "source": "https://github.com/doctrine/lexer/tree/1.2.1" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer", + "type": "tidelift" + } + ], + "time": "2020-05-25T17:44:05+00:00" + }, + { + "name": "doctrine/persistence", + "version": "1.3.8", + "source": { + "type": "git", + "url": "https://github.com/doctrine/persistence.git", + "reference": "7a6eac9fb6f61bba91328f15aa7547f4806ca288" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/persistence/zipball/7a6eac9fb6f61bba91328f15aa7547f4806ca288", + "reference": "7a6eac9fb6f61bba91328f15aa7547f4806ca288", + "shasum": "" + }, + "require": { + "doctrine/annotations": "^1.0", + "doctrine/cache": "^1.0", + "doctrine/collections": "^1.0", + "doctrine/event-manager": "^1.0", + "doctrine/reflection": "^1.2", + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/common": "<2.10@dev" + }, + "require-dev": { + "doctrine/coding-standard": "^6.0", + "phpstan/phpstan": "^0.11", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0", + "vimeo/psalm": "^3.11" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\": "lib/Doctrine/Common", + "Doctrine\\Persistence\\": "lib/Doctrine/Persistence" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + }, + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" + } + ], + "description": "The Doctrine Persistence project is a set of shared interfaces and functionality that the different Doctrine object mappers share.", + "homepage": "https://doctrine-project.org/projects/persistence.html", + "keywords": [ + "mapper", + "object", + "odm", + "orm", + "persistence" + ], + "support": { + "issues": "https://github.com/doctrine/persistence/issues", + "source": "https://github.com/doctrine/persistence/tree/1.3.x" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fpersistence", + "type": "tidelift" + } + ], + "time": "2020-06-20T12:56:16+00:00" + }, + { + "name": "doctrine/reflection", + "version": "1.2.2", + "source": { + "type": "git", + "url": "https://github.com/doctrine/reflection.git", + "reference": "fa587178be682efe90d005e3a322590d6ebb59a5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/reflection/zipball/fa587178be682efe90d005e3a322590d6ebb59a5", + "reference": "fa587178be682efe90d005e3a322590d6ebb59a5", + "shasum": "" + }, + "require": { + "doctrine/annotations": "^1.0", + "ext-tokenizer": "*", + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/common": "<2.9" + }, + "require-dev": { + "doctrine/coding-standard": "^6.0 || ^8.2.0", + "doctrine/common": "^2.10", + "phpstan/phpstan": "^0.11.0 || ^0.12.20", + "phpstan/phpstan-phpunit": "^0.11.0 || ^0.12.16", + "phpunit/phpunit": "^7.5 || ^9.1.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\": "lib/Doctrine/Common" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + }, + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" + } + ], + "description": "The Doctrine Reflection project is a simple library used by the various Doctrine projects which adds some additional functionality on top of the reflection functionality that comes with PHP. It allows you to get the reflection information about classes, methods and properties statically.", + "homepage": "https://www.doctrine-project.org/projects/reflection.html", + "keywords": [ + "reflection", + "static" + ], + "support": { + "issues": "https://github.com/doctrine/reflection/issues", + "source": "https://github.com/doctrine/reflection/tree/1.2.2" + }, + "abandoned": "roave/better-reflection", + "time": "2020-10-27T21:46:55+00:00" + }, + { + "name": "dompdf/dompdf", + "version": "v1.1.0", + "source": { + "type": "git", + "url": "https://github.com/dompdf/dompdf.git", + "reference": "aa594c1cdbcdab04977fdd0fff669a017fb50ef4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dompdf/dompdf/zipball/aa594c1cdbcdab04977fdd0fff669a017fb50ef4", + "reference": "aa594c1cdbcdab04977fdd0fff669a017fb50ef4", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-mbstring": "*", + "phenx/php-font-lib": "^0.5.2", + "phenx/php-svg-lib": "^0.3.3", + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "mockery/mockery": "^1.3", + "phpunit/phpunit": "^7.5 || ^8 || ^9", + "squizlabs/php_codesniffer": "^3.5" + }, + "suggest": { + "ext-gd": "Needed to process images", + "ext-gmagick": "Improves image processing performance", + "ext-imagick": "Improves image processing performance", + "ext-zlib": "Needed for pdf stream compression" + }, + "type": "library", + "autoload": { + "psr-4": { + "Dompdf\\": "src/" + }, + "classmap": [ + "lib/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-2.1" + ], + "authors": [ + { + "name": "Fabien Ménager", + "email": "fabien.menager@gmail.com" + }, + { + "name": "Brian Sweeney", + "email": "eclecticgeek@gmail.com" + }, + { + "name": "Gabriel Bull", + "email": "me@gabrielbull.com" + } + ], + "description": "DOMPDF is a CSS 2.1 compliant HTML to PDF converter", + "homepage": "https://github.com/dompdf/dompdf", + "support": { + "issues": "https://github.com/dompdf/dompdf/issues", + "source": "https://github.com/dompdf/dompdf/tree/v1.1.0" + }, + "time": "2021-11-16T18:39:01+00:00" + }, + { + "name": "drupal/achievements", + "version": "dev-2.x", + "source": { + "type": "git", + "url": "https://git.drupalcode.org/project/achievements.git", + "reference": "d7e74cd7c821fc3f896cd0fe96ff5a9cd193d26f" + }, + "require": { + "drupal/core": "^8 || ^9", + "drupal/jquery_ui_effects": "^1.1" + }, + "type": "drupal-module", + "extra": { + "branch-alias": { + "dev-2.x": "2.x-dev" + }, + "drupal": { + "version": "2.x-dev", + "datestamp": "1599959801", + "security-coverage": { + "status": "not-covered", + "message": "Dev releases are not covered by Drupal security advisories." + } + } + }, + "notification-url": "https://packages.drupal.org/8/downloads", + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "Matthew Grasmick", + "homepage": "https://www.drupal.org/u/grasmash" + }, + { + "name": "grasmash", + "homepage": "https://www.drupal.org/user/455714" + }, + { + "name": "jhedstrom", + "homepage": "https://www.drupal.org/user/208732" + } + ], + "description": "The Achievements module offers the ability to create achievements and badges.", + "homepage": "https://drupal.org/project/achievements", + "support": { + "source": "https://cgit.drupalcode.org/achievements", + "issues": "https://drupal.org/project/issues/achievements" + } + }, + { + "name": "drupal/admin_toolbar", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://git.drupalcode.org/project/admin_toolbar.git", + "reference": "3.0.3" + }, + "dist": { + "type": "zip", + "url": "https://ftp.drupal.org/files/projects/admin_toolbar-3.0.3.zip", + "reference": "3.0.3", + "shasum": "ce735c931c0bd6da79bd8e45ca459d61015bbe44" + }, + "require": { + "drupal/core": "^8.8.0 || ^9.0" + }, + "require-dev": { + "drupal/admin_toolbar_tools": "*" + }, + "type": "drupal-module", + "extra": { + "drupal": { + "version": "3.0.3", + "datestamp": "1632322497", + "security-coverage": { + "status": "covered", + "message": "Covered by Drupal's security advisory policy" + } + } + }, + "notification-url": "https://packages.drupal.org/8/downloads", + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "Wilfrid Roze (eme)", + "homepage": "https://www.drupal.org/u/eme", + "role": "Maintainer" + }, + { + "name": "Romain Jarraud (romainj)", + "homepage": "https://www.drupal.org/u/romainj", + "role": "Maintainer" + }, + { + "name": "Adrian Cid Almaguer (adriancid)", + "homepage": "https://www.drupal.org/u/adriancid", + "email": "adriancid@gmail.com", + "role": "Maintainer" + }, + { + "name": "Mohamed Anis Taktak (matio89)", + "homepage": "https://www.drupal.org/u/matio89", + "role": "Maintainer" + }, + { + "name": "fethi.krout", + "homepage": "https://www.drupal.org/user/3206765" + }, + { + "name": "matio89", + "homepage": "https://www.drupal.org/user/2320090" + }, + { + "name": "romainj", + "homepage": "https://www.drupal.org/user/370706" + } + ], + "description": "Provides a drop-down menu interface to the core Drupal Toolbar.", + "homepage": "http://drupal.org/project/admin_toolbar", + "keywords": [ + "Drupal", + "Toolbar" + ], + "support": { + "source": "https://git.drupalcode.org/project/admin_toolbar", + "issues": "https://www.drupal.org/project/issues/admin_toolbar" + } + }, + { + "name": "drupal/adminimal_theme", + "version": "1.6.0", + "source": { + "type": "git", + "url": "https://git.drupalcode.org/project/adminimal_theme.git", + "reference": "8.x-1.6" + }, + "dist": { + "type": "zip", + "url": "https://ftp.drupal.org/files/projects/adminimal_theme-8.x-1.6.zip", + "reference": "8.x-1.6", + "shasum": "89132d0853388afe8dfd11fb83c69a48d8c13413" + }, + "require": { + "drupal/core": "^8.8 || ^9" + }, + "type": "drupal-theme", + "extra": { + "drupal": { + "version": "8.x-1.6", + "datestamp": "1602006937", + "security-coverage": { + "status": "covered", + "message": "Covered by Drupal's security advisory policy" + } + } + }, + "notification-url": "https://packages.drupal.org/8/downloads", + "license": [ + "GPL-2.0+" + ], + "authors": [ + { + "name": "ANDiTKO", + "homepage": "https://www.drupal.org/user/1428124" + }, + { + "name": "andrey.troeglazov", + "homepage": "https://www.drupal.org/user/3145389" + }, + { + "name": "realityloop", + "homepage": "https://www.drupal.org/user/139189" + } + ], + "description": "Drupal administration theme with modern minimalist design.", + "homepage": "https://www.drupal.org/project/adminimal_theme", + "support": { + "source": "https://git.drupalcode.org/project/adminimal_theme", + "issues": "https://www.drupal.org/project/issues/adminimal_theme" + } + }, + { + "name": "drupal/administerusersbyrole", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://git.drupalcode.org/project/administerusersbyrole.git", + "reference": "8.x-3.0" + }, + "dist": { + "type": "zip", + "url": "https://ftp.drupal.org/files/projects/administerusersbyrole-8.x-3.0.zip", + "reference": "8.x-3.0", + "shasum": "decf16981abe616f675812c040db2b52332f0a66" + }, + "require": { + "drupal/core": "^8 || ^9" + }, + "type": "drupal-module", + "extra": { + "drupal": { + "version": "8.x-3.0", + "datestamp": "1586962918", + "security-coverage": { + "status": "covered", + "message": "Covered by Drupal's security advisory policy" + } + } + }, + "notification-url": "https://packages.drupal.org/8/downloads", + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "AdamPS", + "homepage": "https://www.drupal.org/user/2650563" + }, + { + "name": "mrfelton", + "homepage": "https://www.drupal.org/user/305669" + }, + { + "name": "smokris", + "homepage": "https://www.drupal.org/user/161913" + } + ], + "description": "Allows site builders to set up fine-grained permissions for allowing \"sub-admin\" users to edit and delete other users.", + "homepage": "https://www.drupal.org/project/administerusersbyrole", + "support": { + "source": "https://git.drupalcode.org/project/administerusersbyrole" + } + }, + { + "name": "drupal/allowed_formats", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://git.drupalcode.org/project/allowed_formats.git", + "reference": "8.x-1.3" + }, + "dist": { + "type": "zip", + "url": "https://ftp.drupal.org/files/projects/allowed_formats-8.x-1.3.zip", + "reference": "8.x-1.3", + "shasum": "4c3c036d7b41428d6e22b61f1219de0ab012feec" + }, + "require": { + "drupal/core": "^8.7.7 || ^9" + }, + "type": "drupal-module", + "extra": { + "drupal": { + "version": "8.x-1.3", + "datestamp": "1592909219", + "security-coverage": { + "status": "covered", + "message": "Covered by Drupal's security advisory policy" + } + } + }, + "notification-url": "https://packages.drupal.org/8/downloads", + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "floretan", + "homepage": "https://www.drupal.org/user/66163" + }, + { + "name": "nord102", + "homepage": "https://www.drupal.org/user/3471419" + } + ], + "description": "Limit which text formats are available for each field instance.", + "homepage": "https://www.drupal.org/project/allowed_formats", + "support": { + "source": "https://git.drupalcode.org/project/allowed_formats" + } + }, + { + "name": "drupal/audiofield", + "version": "1.11.0", + "source": { + "type": "git", + "url": "https://git.drupalcode.org/project/audiofield.git", + "reference": "8.x-1.11" + }, + "dist": { + "type": "zip", + "url": "https://ftp.drupal.org/files/projects/audiofield-8.x-1.11.zip", + "reference": "8.x-1.11", + "shasum": "b677d0b178f16baffec8b52bb0c05a06384daf67" + }, + "require": { + "drupal/core": "^8 || ^9" + }, + "type": "drupal-module", + "extra": { + "drupal": { + "version": "8.x-1.11", + "datestamp": "1630089337", + "security-coverage": { + "status": "covered", + "message": "Covered by Drupal's security advisory policy" + } + }, + "drush": { + "services": { + "drush.services.yml": "^9" + } + } + }, + "notification-url": "https://packages.drupal.org/8/downloads", + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "Daniel Moberly", + "homepage": "https://www.drupal.org/u/danielmoberly", + "role": "Maintainer" + }, + { + "name": "josipsaric", + "homepage": "https://www.drupal.org/user/3063287" + }, + { + "name": "tamerzg", + "homepage": "https://www.drupal.org/user/464564" + } + ], + "description": "AudioField Module", + "homepage": "https://www.drupal.org/project/audiofield", + "support": { + "source": "https://git.drupalcode.org/project/audiofield", + "issues": "https://www.drupal.org/project/issues/audiofield" + } + }, + { + "name": "drupal/autocomplete_deluxe", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://git.drupalcode.org/project/autocomplete_deluxe.git", + "reference": "2.0.1" + }, + "dist": { + "type": "zip", + "url": "https://ftp.drupal.org/files/projects/autocomplete_deluxe-2.0.1.zip", + "reference": "2.0.1", + "shasum": "244d3a1992da6ec126220bab22a933f9f6780d78" + }, + "require": { + "drupal/core": "^8 || ^9" + }, + "type": "drupal-module", + "extra": { + "drupal": { + "version": "2.0.1", + "datestamp": "1630177423", + "security-coverage": { + "status": "covered", + "message": "Covered by Drupal's security advisory policy" + } + } + }, + "notification-url": "https://packages.drupal.org/8/downloads", + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "Vardot", + "homepage": "https://www.drupal.org/vardot", + "role": "Maintenance for D8 and D9 versions" + }, + { + "name": "Mediacurrent", + "homepage": "https://www.drupal.org/mediacurrent", + "role": "Supporting organization" + }, + { + "name": "edwardchiapet", + "homepage": "https://www.drupal.org/user/2354784" + }, + { + "name": "klausi", + "homepage": "https://www.drupal.org/user/262198" + }, + { + "name": "mpriscella", + "homepage": "https://www.drupal.org/user/2354820" + }, + { + "name": "sepgil", + "homepage": "https://www.drupal.org/user/512828" + } + ], + "description": "Enhanced autocomplete using Jquery UI autocomplete.", + "homepage": "https://www.drupal.org/project/autocomplete_deluxe", + "support": { + "source": "http://cgit.drupalcode.org/autocomplete_deluxe", + "issues": "https://www.drupal.org/project/issues/autocomplete_deluxe" + } + }, + { + "name": "drupal/autosave_form", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://git.drupalcode.org/project/autosave_form.git", + "reference": "8.x-1.3" + }, + "dist": { + "type": "zip", + "url": "https://ftp.drupal.org/files/projects/autosave_form-8.x-1.3.zip", + "reference": "8.x-1.3", + "shasum": "5a7d07baf6952e7ac00a580ed96f7effffe72c8f" + }, + "require": { + "drupal/core": "^8 || ^9" + }, + "type": "drupal-module", + "extra": { + "drupal": { + "version": "8.x-1.3", + "datestamp": "1635343527", + "security-coverage": { + "status": "covered", + "message": "Covered by Drupal's security advisory policy" + } + } + }, + "notification-url": "https://packages.drupal.org/8/downloads", + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "hchonov", + "homepage": "https://www.drupal.org/user/2901211" + } + ], + "description": "Adds autosave feature on forms.", + "homepage": "https://www.drupal.org/project/autosave_form", + "support": { + "source": "https://git.drupalcode.org/project/autosave_form" + } + }, + { + "name": "drupal/backward_compatibility", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://git.drupalcode.org/project/backward_compatibility.git", + "reference": "1.0.0" + }, + "dist": { + "type": "zip", + "url": "https://ftp.drupal.org/files/projects/backward_compatibility-1.0.0.zip", + "reference": "1.0.0", + "shasum": "b0f728e6d9f31b227b99628456971dfdb2f129bf" + }, + "require": { + "drupal/core": "^8 || ^9" + }, + "type": "drupal-module", + "extra": { + "drupal": { + "version": "1.0.0", + "datestamp": "1600375481", + "security-coverage": { + "status": "not-covered", + "message": "Project has not opted into security advisory coverage!" + } + } + }, + "notification-url": "https://packages.drupal.org/8/downloads", + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "DamienMcKenna", + "homepage": "https://www.drupal.org/user/108450" + }, + { + "name": "Greg Boggs", + "homepage": "https://www.drupal.org/user/153069" + } + ], + "description": "Backward Compatibility for Drupal 9 with previous versions of Drupal.", + "homepage": "https://www.drupal.org/project/backward_compatibility", + "support": { + "source": "http://cgit.drupalcode.org/backward_compatibility", + "issues": "https://www.drupal.org/project/issues/backward_compatibility" + } + }, + { + "name": "drupal/block_exclude_pages", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://git.drupalcode.org/project/block_exclude_pages.git", + "reference": "2.0.0" + }, + "dist": { + "type": "zip", + "url": "https://ftp.drupal.org/files/projects/block_exclude_pages-2.0.0.zip", + "reference": "2.0.0", + "shasum": "b9eecc6b37507212f249e472a57308d26dcd468a" + }, + "require": { + "drupal/core": "^8.8 || ^9" + }, + "type": "drupal-module", + "extra": { + "drupal": { + "version": "2.0.0", + "datestamp": "1594830387", + "security-coverage": { + "status": "covered", + "message": "Covered by Drupal's security advisory policy" + } + } + }, + "notification-url": "https://packages.drupal.org/8/downloads", + "license": [ + "GPL-2.0+" + ], + "authors": [ + { + "name": "jcontreras", + "homepage": "https://www.drupal.org/user/2422356" + } + ], + "description": "adds an exclude pages field for blocks", + "homepage": "https://www.drupal.org/project/block_exclude_pages", + "keywords": [ + "Drupal" + ], + "support": { + "source": "http://cgit.drupalcode.org/block_exclude_pages", + "issues": "https://www.drupal.org/project/issues/block_exclude_pages" + } + }, + { + "name": "drupal/block_field", + "version": "1.0.0-rc2", + "source": { + "type": "git", + "url": "https://git.drupalcode.org/project/block_field.git", + "reference": "8.x-1.0-rc2" + }, + "dist": { + "type": "zip", + "url": "https://ftp.drupal.org/files/projects/block_field-8.x-1.0-rc2.zip", + "reference": "8.x-1.0-rc2", + "shasum": "44472f8e89c319af884b25ac0a66337329a9b309" + }, + "require": { + "drupal/core": "^8.7.7 || ^9" + }, + "type": "drupal-module", + "extra": { + "drupal": { + "version": "8.x-1.0-rc2", + "datestamp": "1621950813", + "security-coverage": { + "status": "not-covered", + "message": "RC releases are not covered by Drupal security advisories." + } + } + }, + "notification-url": "https://packages.drupal.org/8/downloads", + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "Berdir", + "homepage": "https://www.drupal.org/user/214652" + }, + { + "name": "acbramley", + "homepage": "https://www.drupal.org/user/1036766" + }, + { + "name": "fenstrat", + "homepage": "https://www.drupal.org/user/362649" + }, + { + "name": "jrockowitz", + "homepage": "https://www.drupal.org/user/371407" + }, + { + "name": "michaellander", + "homepage": "https://www.drupal.org/user/636494" + }, + { + "name": "paulocs", + "homepage": "https://www.drupal.org/user/3640109" + } + ], + "description": "Provides a field that allows a content entity to create and configure custom block instances.", + "homepage": "https://www.drupal.org/project/block_field", + "support": { + "source": "https://git.drupalcode.org/project/block_field" + } + }, + { + "name": "drupal/business_rules", + "version": "2.0.0-beta1", + "source": { + "type": "git", + "url": "https://git.drupalcode.org/project/business_rules.git", + "reference": "2.0.0-beta1" + }, + "dist": { + "type": "zip", + "url": "https://ftp.drupal.org/files/projects/business_rules-2.0.0-beta1.zip", + "reference": "2.0.0-beta1", + "shasum": "3e50c68364a0e780117ab55f7cff064b5526afe3" + }, + "require": { + "drupal/core": "^8 || ^9", + "drupal/dbug": "*" + }, + "require-dev": { + "drupal/group": "*", + "drupal/paragraphs": "*", + "drupal/sms": "*" + }, + "type": "drupal-module", + "extra": { + "drupal": { + "version": "2.0.0-beta1", + "datestamp": "1615910333", + "security-coverage": { + "status": "not-covered", + "message": "Beta releases are not covered by Drupal security advisories." + } + } + }, + "notification-url": "https://packages.drupal.org/8/downloads", + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "C.E.A", + "homepage": "https://www.drupal.org/user/3189629" + }, + { + "name": "colan", + "homepage": "https://www.drupal.org/user/58704" + }, + { + "name": "pratik_kamble", + "homepage": "https://www.drupal.org/user/3204909" + }, + { + "name": "rohit-rajput-sahab", + "homepage": "https://www.drupal.org/user/2036406" + }, + { + "name": "yuriseki", + "homepage": "https://www.drupal.org/user/1523064" + } + ], + "description": "Business Rules", + "homepage": "https://www.drupal.org/project/business_rules", + "support": { + "source": "https://git.drupalcode.org/project/business_rules" + } + }, + { + "name": "drupal/cer", + "version": "4.0.0-alpha3", + "source": { + "type": "git", + "url": "https://git.drupalcode.org/project/cer.git", + "reference": "8.x-4.0-alpha3" + }, + "dist": { + "type": "zip", + "url": "https://ftp.drupal.org/files/projects/cer-8.x-4.0-alpha3.zip", + "reference": "8.x-4.0-alpha3", + "shasum": "3c508e842a2c17235e4c9909ab64ef1aeb9d3ebe" + }, + "require": { + "drupal/core": "^8 || ^9" + }, + "type": "drupal-module", + "extra": { + "drupal": { + "version": "8.x-4.0-alpha3", + "datestamp": "1620240213", + "security-coverage": { + "status": "not-covered", + "message": "Project has not opted into security advisory coverage!" + } + } + }, + "notification-url": "https://packages.drupal.org/8/downloads", + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "bmcclure", + "homepage": "https://www.drupal.org/user/278485" + }, + { + "name": "chertzog", + "homepage": "https://www.drupal.org/user/806366" + }, + { + "name": "gcb", + "homepage": "https://www.drupal.org/user/1682976" + }, + { + "name": "gregcube", + "homepage": "https://www.drupal.org/user/336930" + }, + { + "name": "jrglasgow", + "homepage": "https://www.drupal.org/user/36590" + }, + { + "name": "phenaproxima", + "homepage": "https://www.drupal.org/user/205645" + } + ], + "description": "Allows user to create two-way references between entities.", + "homepage": "https://www.drupal.org/project/cer", + "support": { + "source": "https://git.drupalcode.org/project/cer" + } + }, + { + "name": "drupal/ckeditor_tabletoolstoolbar", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://git.drupalcode.org/project/ckeditor_tabletoolstoolbar.git", + "reference": "8.x-1.0" + }, + "dist": { + "type": "zip", + "url": "https://ftp.drupal.org/files/projects/ckeditor_tabletoolstoolbar-8.x-1.0.zip", + "reference": "8.x-1.0", + "shasum": "03c2c952e73d9f2010f46352b1495123727d370f" + }, + "require": { + "drupal/core": "^8" + }, + "type": "drupal-module", + "extra": { + "drupal": { + "version": "8.x-1.0", + "datestamp": "1503931144", + "security-coverage": { + "status": "covered", + "message": "Covered by Drupal's security advisory policy" + } + } + }, + "notification-url": "https://packages.drupal.org/8/downloads", + "license": [ + "GPL-2.0+" + ], + "authors": [ + { + "name": "Oleksandr Milkovskyi (a.milkovsky)", + "homepage": "https://www.drupal.org/u/amilkovsky", + "role": "Maintainer" + }, + { + "name": "pcambra", + "homepage": "https://www.drupal.org/user/122101" + } + ], + "description": "Integrates the CKEditor \"Table Tools Toolbar\" plugin.", + "homepage": "http://drupal.org/project/ckeditor_tabletoolstoolbar", + "keywords": [ + "Drupal" + ], + "support": { + "source": "http://cgit.drupalcode.org/ckeditor_tabletoolstoolbar", + "issues": "http://drupal.org/project/issues/ckeditor_tabletoolstoolbar" + } + }, + { + "name": "drupal/coder", + "version": "8.3.13", + "source": { + "type": "git", + "url": "https://git.drupalcode.org/project/coder.git", + "reference": "d3286d571b19633cc296d438c36b9aed195de43c" + }, + "require": { + "ext-mbstring": "*", + "php": ">=7.0.8", + "sirbrillig/phpcs-variable-analysis": "^2.10", + "squizlabs/php_codesniffer": "^3.5.6", + "symfony/yaml": ">=2.0.5" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.63", + "phpunit/phpunit": "^6.0 || ^7.0" + }, + "type": "phpcodesniffer-standard", + "autoload": { + "psr-4": { + "Drupal\\": "coder_sniffer/Drupal/", + "DrupalPractice\\": "coder_sniffer/DrupalPractice/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0-or-later" + ], + "description": "Coder is a library to review Drupal code.", + "homepage": "https://www.drupal.org/project/coder", + "keywords": [ + "code review", + "phpcs", + "standards" + ], + "support": { + "issues": "https://www.drupal.org/project/issues/coder", + "source": "https://www.drupal.org/project/coder" + }, + "time": "2021-02-06T10:44:32+00:00" + }, + { + "name": "drupal/config_filter", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://git.drupalcode.org/project/config_filter.git", + "reference": "8.x-2.2" + }, + "dist": { + "type": "zip", + "url": "https://ftp.drupal.org/files/projects/config_filter-8.x-2.2.zip", + "reference": "8.x-2.2", + "shasum": "dc6bc8107255066507cfc1d6766e664c3673cda0" + }, + "require": { + "drupal/core": "^8.8 || ^9" + }, + "conflict": { + "drush/drush": "<10" + }, + "suggest": { + "drupal/config_split": "Split site configuration for different environments." + }, + "type": "drupal-module", + "extra": { + "drupal": { + "version": "8.x-2.2", + "datestamp": "1601934694", + "security-coverage": { + "status": "covered", + "message": "Covered by Drupal's security advisory policy" + } + } + }, + "notification-url": "https://packages.drupal.org/8/downloads", + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "Fabian Bircher", + "homepage": "https://www.drupal.org/u/bircher", + "email": "opensource@fabianbircher.com", + "role": "Maintainer" + }, + { + "name": "Nuvole Web", + "homepage": "http://nuvole.org", + "email": "info@nuvole.org", + "role": "Maintainer" + }, + { + "name": "pescetti", + "homepage": "https://www.drupal.org/user/436244" + } + ], + "description": "Config Filter allows other modules to interact with a ConfigStorage through filter plugins.", + "homepage": "https://www.drupal.org/project/config_filter", + "keywords": [ + "Drupal", + "configuration", + "configuration management" + ], + "support": { + "source": "https://git.drupalcode.org/project/config_filter", + "issues": "https://www.drupal.org/project/issues/config_filter", + "slack": "https://drupal.slack.com/archives/C45342CDD" + } + }, + { + "name": "drupal/config_ignore", + "version": "2.3.0", + "source": { + "type": "git", + "url": "https://git.drupalcode.org/project/config_ignore.git", + "reference": "8.x-2.3" + }, + "dist": { + "type": "zip", + "url": "https://ftp.drupal.org/files/projects/config_ignore-8.x-2.3.zip", + "reference": "8.x-2.3", + "shasum": "2e1f07a455275fb6637909921a8915646601fc00" + }, + "require": { + "drupal/config_filter": "^1 || ^2", + "drupal/core": "^8 || ^9" + }, + "type": "drupal-module", + "extra": { + "drupal": { + "version": "8.x-2.3", + "datestamp": "1608306489", + "security-coverage": { + "status": "covered", + "message": "Covered by Drupal's security advisory policy" + } + } + }, + "notification-url": "https://packages.drupal.org/8/downloads", + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "Tommy Lynge Jørgensen", + "homepage": "https://www.drupal.org/u/tlyngej", + "email": "tlyngej@gmail.com", + "role": "Maintainer" + }, + { + "name": "Fabian Bircher", + "homepage": "https://www.drupal.org/u/bircher", + "role": "Maintainer" + }, + { + "name": "tlyngej", + "homepage": "https://www.drupal.org/user/413139" + } + ], + "description": "Ignore certain configuration during import.", + "homepage": "http://drupal.org/project/config_ignore", + "support": { + "source": "https://git.drupalcode.org/project/config_ignore", + "issues": "http://drupal.org/project/config_ignore", + "irc": "irc://irc.freenode.org/drupal-contribute" + } + }, + { + "name": "drupal/config_split", + "version": "2.0.0-beta5", + "source": { + "type": "git", + "url": "https://git.drupalcode.org/project/config_split.git", + "reference": "2.0.0-beta5" + }, + "dist": { + "type": "zip", + "url": "https://ftp.drupal.org/files/projects/config_split-2.0.0-beta5.zip", + "reference": "2.0.0-beta5", + "shasum": "b5cf4ee3d7af1ba38883bebead12678214a98f1e" + }, + "require": { + "drupal/core": "^8.8 || ^9" + }, + "conflict": { + "drush/drush": "<10" + }, + "require-dev": { + "drupal/config_filter": "^1||^2" + }, + "suggest": { + "drupal/chosen": "Chosen uses the Chosen jQuery plugin to make the (?:[^"]|\\")*)"$/ + */ + public function selectTheRecentlyAddedSuperUserOption($select) { + $name = ""; + if ($this->userManager->hasUsers()) { + foreach ($this->userManager->getUsers() as $user) { + if ($user->role == 'superuser') { + $name = $user->name; + } + } + } + $this->getSession()->getPage()->selectFieldOption($select, $name); + } + + /** + * @Given I am logged in as the recently created user with the :role role + */ + public function iAmLoggedInAsTheRecentlyCreatedUserWithTheRole($role) { + if ($this->userManager->hasUsers()) { + foreach ($this->userManager->getUsers() as $user) { + // Every user who exists is authenticated so we don't need to check. + if (in_array($role, [ + 'authenticated', + 'authenticated user', + ]) || $user->role === $role) { + $this->login($user); + return; + } + } + } + } + + /** + * @Given I save a screenshot to :arg1 + */ + public function iSaveAScreenshotTo($arg1) { + $image_data = $this->getSession()->getDriver()->getScreenshot(); + $file_and_path = $this->getMinkParameter('files_path') . '/artifacts/screenshots/' . $arg1; + file_put_contents($file_and_path, $image_data); + } + + /** + * @Given I fill in wysiwyg on field :locator with :value + */ + public function iFillInWysiwygOnFieldWith($value, $locator) { + $el = $this->getSession()->getPage()->findField($locator); + + if (empty($el)) { + throw new ExpectationException('Could not find WYSIWYG with locator: ' . $locator, $this->getSession()); + } + + $fieldId = $el->getAttribute('id'); + + if (empty($fieldId)) { + throw new \Exception('Could not find an id for field with locator: ' . $locator); + } + + $this->getSession() + ->executeScript("CKEDITOR.instances[\"$fieldId\"].setData(\"$value\");"); + } + + /** + * @Given I choose :arg1 after entering :arg2 in the autocomplete :arg3 + */ + public function iChooseAfterEnteringInTheAutocomplete($popup, $text, $field) { + $session = $this->getSession(); + $element = $session->getPage()->findField($field); + if (empty($element)) { + throw new ElementNotFoundException($session, NULL, 'named', $field); + } + $element->setValue($text); + $element->focus(); + $this->iWaitForAjaxToFinish(); + $available_autocompletes = $this->getSession()->getPage()->findAll('css', 'ul.ui-autocomplete[id^=ui-id]'); + if (empty($available_autocompletes)) { + throw new ElementNotFoundException('Could not find the autocomplete popup box'); + } + // It's possible for multiple autocompletes to be on the page at once, + // but it shouldn't be possible for multiple to be visible/open at once. + foreach ($available_autocompletes as $autocomplete) { + if ($autocomplete->isVisible()) { + $matches = $autocomplete->findAll('xpath', "//li/a"); + if (empty($matches)) { + throw new \Exception(t('Could not find the select box')); + } + foreach ($matches as $match) { + if ($match->getText() == $popup) { + $match->click(); + return; + } + } + } + } + throw new \Exception('Could not find the autocomplete popup box'); + } + + /** + * @Given I choose :arg1 after entering :arg2 in the _chosen_ field with id :arg3 + */ + public function iChooseAfterEnteringInTheChosenFieldWithId($popup, $text, $field) { + $session = $this->getSession(); + $element = $session->getPage()->findField($field); + if (empty($element)) { + throw new ElementNotFoundException($session, NULL, 'named', $field); + } + $element->focus(); + $element->setValue($text); + $this->getSession()->wait(3000); + $field_replace = str_replace("-", "_", $field); + $matches = $this->getSession()->getPage()->findAll('xpath', '//div[@id="' . $field_replace . '_chosen"]/div/ul/li'); + if (empty($matches)) { + throw new \Exception('Could not find the select box'); + } + foreach ($matches as $match) { + if ($match->getText() == $popup) { + $match->click(); + return; + } + } + throw new \Exception('Could not find the select box'); + } + + /** + * @Then I select :arg1 from field :arg2 + */ + public function iSelectFromField($value, $locator) { + $session = $this->getSession(); + $field = $session->getPage()->findField($locator); + if (NULL === $field) { + throw new ElementNotFoundException($this->getSession(), 'form field', 'id|name|label|value', $locator); + } + $field->selectOption($value); + } + + /** + * @Given the default theme is :arg1 + * @When I set the default theme to :arg1 + */ + public function setDefaultTheme($theme) { + $config = \Drupal::service('config.factory')->getEditable('system.theme'); + $config->set('default', $theme)->save(); + } + + /** + * @Given I wait for the batch job to finish + */ + public function iWaitForTheBatchJobToFinish() { + $this->getSession()->wait(180000, '!document.getElementById("updateprogress")'); + } + + /** + * @Given I select all rows in the table + */ + public function iSelectAllRowsInTable() { + $this->getSession()->getPage()->find('css', 'th.select-all .form-checkbox')->click(); + } + +} diff --git a/features/core-functionality.feature b/features/core-functionality.feature new file mode 100644 index 0000000..9fd79c8 --- /dev/null +++ b/features/core-functionality.feature @@ -0,0 +1,27 @@ +@test @core_functionality +Feature: Test all core functionality of the site which doesn't belong to other category. + + Background: + Given "category" terms: + | name | + | eLearning | + + Given the following content: + """ + title: Test article + type: learn_article + langcode: en + moderation_state: published + field_topic: eLearning + field_body: + - + type: text + field_paragraph_body: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec et ex risus. + """ + + @api @javascript @search_api + Scenario: Make sure that authenticated users can use the search page + Given I am logged in with email address as a user with the "authenticated user" role + And I am on "/search?text=Test article" + Then the "body" element should contain "class=\"c-view__content\"" + Then I should not see "Undefined index" diff --git a/features/first-test.feature b/features/first-test.feature new file mode 100755 index 0000000..81003b5 --- /dev/null +++ b/features/first-test.feature @@ -0,0 +1,8 @@ +@core_functionality +Feature: Test account menu links + +@javascript @api +Scenario: Make sure that anonymous users see the account menu + Given I am not logged in + And I am on "/" + Then I should see the link "Create Account" diff --git a/features/homepage.feature b/features/homepage.feature new file mode 100644 index 0000000..298f0f6 --- /dev/null +++ b/features/homepage.feature @@ -0,0 +1,23 @@ +@core_functionality +Feature: Verify the home page experience is correct. + + @javascript @api + Scenario: Learner gets recommendations page as the homepage + Given I am logged in with email address as a user with the "authenticated user" role + When I go to the homepage + Then the "body" element should contain "perls-learner" + Then the url should match "/start" + + @javascript @api + Scenario: Content manager gets dashboard page as the homepage + Given I am logged in with email address as a user with the "Content Manager" role + When I go to the homepage + Then the "body" element should contain "perls-content-manager" + And I should see "Dashboard" + + @javascript @api + Scenario: Anonymous user gets appropriate user/login page. + Given I am on "/user/logout" + And I go to the homepage + Then I should be on "/user/login?destination=/home" + And I should not see "Page not found" diff --git a/features/learner_feedback.feature b/features/learner_feedback.feature new file mode 100644 index 0000000..3f770ee --- /dev/null +++ b/features/learner_feedback.feature @@ -0,0 +1,43 @@ +@core_functionality +Feature: Test Learner Feedback form + + @api @javascript + Scenario: Verify Feedback block is present for Content + Given "category" terms: + | name | + | eLearning | + Given the following content: + """ + title: Test learn article + type: learn_article + langcode: en + field_topic: eLearning + moderation_state: published + field_body: + - + type: text + field_paragraph_body: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec et ex risus. + """ + And the following content: + """ + title: Test course + type: course + langcode: en + field_topic: eLearning + field_learning_content: Test learn article + """ + And I am logged in with email address as a user with the "authenticated user" role + # Navigate to Course + When I am visiting the "course" content "Test course" + # Feedback block should be visible, not broken and contain feedback form field + Then I should see "Was this relevant to you?" + And I should not see "This block is broken or missing" + And I should see an ".relevant-content-rate" element + And should see an ".js-form-item-feedback" element + # Test the Form + When I fill in "content_relevant" with "1" + And I wait 2 seconds + And I fill in "feedback" with "Test Feedback" + And I press "Submit" + And I wait 10 seconds + Then should see an ".webform-confirmation" element diff --git a/features/learner_menu.feature b/features/learner_menu.feature new file mode 100644 index 0000000..2e70d0b --- /dev/null +++ b/features/learner_menu.feature @@ -0,0 +1,11 @@ +@core_functionality +Feature: Test Learner menus + + @api @javascript + Scenario: Verify Bookmarks menu exists under Me and redirects to the Bookmarks Page + Given I am logged in with email address as a user with the "authenticated user" role + When I click the element ".c-menu__item--me" + Then I should see an ".c-menu__item--bookmarks" element + # Redirects to Bookmarks page + When I click the element ".c-menu__item--bookmarks" + And I should see an ".l-page--bookmarks" element diff --git a/features/learner_views.feature b/features/learner_views.feature new file mode 100644 index 0000000..e9930ad --- /dev/null +++ b/features/learner_views.feature @@ -0,0 +1,55 @@ +@core_functionality +Feature: Test Learner views + + Background: + Given "category" terms: + | name | + | eLearning | + + Given the following content: + """ + title: Test learn article + type: learn_article + langcode: en + field_topic: eLearning + moderation_state: published + field_body: + - + type: text + field_paragraph_body: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec et ex risus. + """ + + Given users: + | name | mail | roles | + | testlearner36@test.com | testlearner36@test.com | | + | testsysadmin@test.com | testsysadmin@test.com | sysadmin | + + @api @javascript + Scenario: Verify bookmarking functionality, page display and filter + Given I am logged in as the recently created user with the "authenticated" role + When I am on "/bookmarks" + Then I should see "You haven’t bookmarked anything yet" + And I am at "/user/logout" + Given I am logged in as "testsysadmin@test.com" + And I am at "/admin/people" + And I click the element ".username" + And I click "State" + And I click "Bookmarked" + # Bookmark a known item + When I select "- Any -" from "edit-flagged" + And I fill in "edit-title" with "Test learn article" + And I click the element "#edit-submit-administrate-user-flags" + And I select all rows in the table + And I select "Bookmark" from "edit-action" + And I press "Apply to selected items" + And I wait for the batch job to finish + Then I should see "Action processing results: Bookmark added (1)" + # Verify that the learner sees the bookmarked items + And I am at "/user/logout" + Given I am logged in as the recently created user with the "authenticated" role + And I am on "/user" + When I am on "/bookmarks" + And the ".views-exposed-form" element should contain "form-item-title" + When I fill in "edit-title" with "Test learn article" + And press "Apply" + Then the ".c-view__content" element should contain "Test learn article" diff --git a/features/learner_views_core.feature b/features/learner_views_core.feature new file mode 100644 index 0000000..4dd6fe7 --- /dev/null +++ b/features/learner_views_core.feature @@ -0,0 +1,12 @@ +@core_functionality +Feature: Test Learner views - Core Functionality + + @api @javascript + Scenario: Verify bookmarked node shows up + Given I am logged in with email address as a user with the "authenticated user" role + When I am on "/discover" + And I click the element ".o-flag--bookmark" + And I wait 10 seconds + Then I should see an ".o-flag--bookmark.is-active" element + When I am on "/bookmarks" + Then I should see an "article" element diff --git a/features/search.feature b/features/search.feature new file mode 100644 index 0000000..b33705b --- /dev/null +++ b/features/search.feature @@ -0,0 +1,42 @@ +@core_functionality @search_api +Feature: Test regarding search + + Background: + Given "category" terms: + | name | + | eLearning | + + Given the following content: + """ + title: Test article + type: learn_article + langcode: en + field_topic: eLearning + moderation_state: published + field_body: + - + type: text + field_paragraph_body: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec et ex risus. + """ + + @api @javascript @test + Scenario: Make sure search bar works + Given I am logged in with email address as a user with the "authenticated" role + And I am on "/bookmarks" + And I click the element ".c-search-block__toggle" + And I fill in "search_api_fulltext" with "Test article" + And I click the element ".c-search-block .button" + And I wait 10 seconds + Then should see an ".c-node" element + + @api @javascript + Scenario: Make sure that user see the proper message when the search result is empty. + + Given I am logged in with email address as a user with the "authenticated" role + And I am on "/bookmarks" + And I click the element ".c-search-block__toggle" + And I fill in "search_api_fulltext" with "xyz" + And I click the element ".c-search-block .button" + And I wait 10 seconds + Then should see "There are no results found!" + diff --git a/features/test-content-access.feature b/features/test-content-access.feature new file mode 100644 index 0000000..81628cb --- /dev/null +++ b/features/test-content-access.feature @@ -0,0 +1,66 @@ +@core_functionality +Feature: Test proper access handling if a test content is part of a course content. + + Background: + Given "category" terms: + | name | + | eLearning | + Given the following content: + """ + title: Test publishing quiz + type: quiz + langcode: en + field_topic: eLearning + """ + And the following content: + """ + title: Test publishing test + type: test + langcode: en + field_quiz: Test publishing quiz + field_pass_mark: 85 + """ + And the following content: + """ + title: Test publishing course + type: course + langcode: en + field_topic: eLearning + field_learning_content: Test publishing test + """ + + @javascript @api + Scenario: I create a new course + When I am logged in with email address as a user with the "authenticated user" role + And I am visiting the "course" content "Test publishing course" + Then I should see the text "Test publishing course" + + @javascript @api + Scenario: An learner doesn't have access to content and test if content is unpublished. + Given I am logged in with email address as a user with the "Content Manager" role + When I edit the "course" content "Test publishing course" + Then I uncheck the box "Published" + When I submit the content form + Then I should see the text "has been updated" + Then I am logged in with email address as a user with the "authenticated user" role + And I am visiting the "course" content "Test publishing course" + And I should get an access denied error + Then I am visiting the "test" content "Test publishing test" + And I should get an access denied error + + @javascript @api + Scenario: An learner have access to course but he doesn't have access to unpublished test. + Given I am logged in with email address as a user with the "Content Manager" role + When I edit the "test" content "Test publishing test" + Then I uncheck the box "Published" + When I submit the content form + Then I should see the text "has been updated" + Then I am logged in with email address as a user with the "authenticated user" role + And I am visiting the "course" content "Test publishing course" + And I should see the text "Test publishing course" + Then I am visiting the "test" content "Test publishing test" + And I should get an access denied error + + + + diff --git a/features/theme-switcher.feature b/features/theme-switcher.feature new file mode 100644 index 0000000..274ef4d --- /dev/null +++ b/features/theme-switcher.feature @@ -0,0 +1,51 @@ +@core_functionality +Feature: Test theme switcher functionality + + Background: + Given "category" terms: + | name | + | eLearning | + Given the following content: + """ + title: Test learn article + type: learn_article + langcode: en + field_topic: eLearning + moderation_state: published + field_body: + - + type: text + field_paragraph_body: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec et ex risus. + """ + + @api @javascript + Scenario: As an authenticated user I use learner theme as default. + Given I am logged in with email address as a user with the "authenticated user" role + When I go to the homepage + Then the "body" element should contain "perls-learner" + When I am at "/user" + Then the "body" element should contain "perls-learner" + + @api @javascript + Scenario: As a content manager user I use content manager theme on specific path. + Given I am logged in with email address as a user with the "Content Manager" role + When I am at "/manage-content/course" + Then the "body" element should contain "perls-content-manager" + And I am visiting the "learn_article" content "Test learn article" + Then the "body" element should contain "perls-learner" + Then I click "Edit" + Then the "body" element should contain "perls-content-manager" + When I am at "/manage/courses-and-content-library/topics" + Then the "body" element should contain "perls-content-manager" + + @api @javascript + Scenario: As an administrator user I use admin theme on admin paths. + Given I am logged in with email address as a user with the "Sysadmin" role + When I am at "/manage-content/course" + Then the "body" element should contain "perls-content-manager" + And I am visiting the "learn_article" content "Test learn article" + Then the "body" element should contain "perls-learner" + When I am at "/admin" + Then the "body" element should contain "adminimal-theme" + + diff --git a/load.environment.php b/load.environment.php new file mode 100644 index 0000000..769343f --- /dev/null +++ b/load.environment.php @@ -0,0 +1,20 @@ +load(); +} +catch (InvalidPathException $e) { + // Do nothing. Production environments rarely use .env files. +} diff --git a/patches/autocomplete_deluxe/js_execution.patch b/patches/autocomplete_deluxe/js_execution.patch new file mode 100644 index 0000000..3a03131 --- /dev/null +++ b/patches/autocomplete_deluxe/js_execution.patch @@ -0,0 +1,24 @@ +diff --git a/assets/js/autocomplete_deluxe.js b/assets/js/autocomplete_deluxe.js +index 6171c61..7b8543b 100755 +--- a/assets/js/autocomplete_deluxe.js ++++ b/assets/js/autocomplete_deluxe.js +@@ -382,9 +382,7 @@ + } + + this.value = item.value; +- this.element = $( +- '' + item.label + "" +- ); ++ this.element = $('').text(item.label); + this.widget = widget; + this.item = item; + const self = this; +@@ -478,7 +476,7 @@ + ? value.substr(1, value.length - 2) + : value; + let itemInit = { +- label: Drupal.checkPlain(label), ++ label: label, + value: value + }; + let item = new Drupal.autocomplete_deluxe.MultipleWidget.Item( diff --git a/patches/block_field/fix_empty_block_issue_widget.patch b/patches/block_field/fix_empty_block_issue_widget.patch new file mode 100644 index 0000000..4d4c711 --- /dev/null +++ b/patches/block_field/fix_empty_block_issue_widget.patch @@ -0,0 +1,20 @@ +diff --git a/src/Plugin/Field/FieldWidget/BlockFieldWidget.php b/src/Plugin/Field/FieldWidget/BlockFieldWidget.php +index 933135e..82c658c 100644 +--- a/src/Plugin/Field/FieldWidget/BlockFieldWidget.php ++++ b/src/Plugin/Field/FieldWidget/BlockFieldWidget.php +@@ -211,9 +211,12 @@ class BlockFieldWidget extends WidgetBase implements ContainerFactoryPluginInter + + // Set the label #value to the default block instance's label. + $plugin_id = $trigger_element['#value']; +- /** @var \Drupal\Core\Block\BlockPluginInterface $block_instance */ +- if ($block_instance = $this->blockManager->createInstance($plugin_id)) { +- $settings_element['label']['#value'] = $block_instance->label(); ++ $settings_element['label']['#value'] = ''; ++ if (!empty($plugin_id)) { ++ /** @var \Drupal\Core\Block\BlockPluginInterface $block_instance */ ++ if ($block_instance = $this->blockManager->createInstance($plugin_id)) { ++ $settings_element['label']['#value'] = $block_instance->label(); ++ } + } + + return $settings_element; diff --git a/patches/core/2935999-remove_field_ui_dependency_layout_builder-9.3.x.patch b/patches/core/2935999-remove_field_ui_dependency_layout_builder-9.3.x.patch new file mode 100644 index 0000000..8635245 --- /dev/null +++ b/patches/core/2935999-remove_field_ui_dependency_layout_builder-9.3.x.patch @@ -0,0 +1,1616 @@ +From fc4e0982444f07b8b88f047b8969d890cb62b6d9 Mon Sep 17 00:00:00 2001 +From: Tim Plunkett +Date: Mon, 29 Jun 2020 12:28:20 -0400 +Subject: [PATCH 1/7] First attempt + +--- + .../layout_builder/layout_builder.info.yml | 2 - + .../SectionStorage/DefaultsSectionStorage.php | 9 +-- + .../Functional/LayoutBuilderAccessTest.php | 1 + + .../LayoutBuilderSectionStorageTest.php | 1 + + .../src/Functional/LayoutBuilderTest.php | 1 + + .../LayoutBuilderThemeSuggestionsTest.php | 11 +-- + .../LayoutBuilderTranslationTest.php | 23 ++---- + .../Functional/Rest/LayoutRestTestBase.php | 15 ++-- + .../FunctionalJavascript/AjaxBlockTest.php | 30 ++++---- + .../FunctionalJavascript/BlockFilterTest.php | 23 +++--- + .../BlockFormMessagesTest.php | 19 +++-- + .../ContentPreviewToggleTest.php | 13 ++-- + .../ContextualLinksTest.php | 16 ++--- + .../InlineBlockPrivateFilesTest.php | 20 ++---- + .../FunctionalJavascript/InlineBlockTest.php | 70 ++++++++++--------- + .../ItemLayoutFieldBlockTest.php | 13 ++-- + .../LayoutBuilderDisableInteractionsTest.php | 1 + + .../LayoutBuilderNestedFormUiTest.php | 17 ++--- + .../LayoutBuilderToolbarTest.php | 1 + + .../LayoutBuilderUiTest.php | 4 ++ + .../MoveBlockFormTest.php | 32 ++++----- + .../TestMultiWidthLayoutsTest.php | 24 +++---- + .../Functional/LayoutBuilderQuickEditTest.php | 11 ++- + .../LayoutBuilderQuickEditTest.php | 1 + + 24 files changed, 159 insertions(+), 199 deletions(-) + +diff --git a/core/modules/layout_builder/layout_builder.info.yml b/core/modules/layout_builder/layout_builder.info.yml +index ccf4e273d69..0a6e43ea3b2 100644 +--- a/core/modules/layout_builder/layout_builder.info.yml ++++ b/core/modules/layout_builder/layout_builder.info.yml +@@ -6,7 +6,5 @@ version: VERSION + dependencies: + - drupal:layout_discovery + - drupal:contextual +- # @todo Discuss removing in https://www.drupal.org/project/drupal/issues/2935999. +- - drupal:field_ui + # @todo Discuss removing in https://www.drupal.org/project/drupal/issues/3003610. + - drupal:block +diff --git a/core/modules/layout_builder/src/Plugin/SectionStorage/DefaultsSectionStorage.php b/core/modules/layout_builder/src/Plugin/SectionStorage/DefaultsSectionStorage.php +index dc0f35707b4..355677a9406 100644 +--- a/core/modules/layout_builder/src/Plugin/SectionStorage/DefaultsSectionStorage.php ++++ b/core/modules/layout_builder/src/Plugin/SectionStorage/DefaultsSectionStorage.php +@@ -14,7 +14,6 @@ + use Drupal\Core\Plugin\Context\EntityContext; + use Drupal\Core\Session\AccountInterface; + use Drupal\Core\Url; +-use Drupal\field_ui\FieldUI; + use Drupal\layout_builder\DefaultsSectionStorageInterface; + use Drupal\layout_builder\Entity\SampleEntityGeneratorInterface; + use Symfony\Component\DependencyInjection\ContainerInterface; +@@ -136,9 +135,11 @@ public function getLayoutBuilderUrl($rel = 'view') { + protected function getRouteParameters() { + $display = $this->getDisplay(); + $entity_type = $this->entityTypeManager->getDefinition($display->getTargetEntityTypeId()); +- $route_parameters = FieldUI::getRouteBundleParameter($entity_type, $display->getTargetBundle()); +- $route_parameters['view_mode_name'] = $display->getMode(); +- return $route_parameters; ++ $bundle_parameter_key = $entity_type->getBundleEntityType() ?: 'bundle'; ++ return [ ++ $bundle_parameter_key => $display->getTargetBundle(), ++ 'view_mode_name' => $display->getMode(), ++ ]; + } + + /** +diff --git a/core/modules/layout_builder/tests/src/Functional/LayoutBuilderAccessTest.php b/core/modules/layout_builder/tests/src/Functional/LayoutBuilderAccessTest.php +index dcf482eb8c3..fee21994c8c 100644 +--- a/core/modules/layout_builder/tests/src/Functional/LayoutBuilderAccessTest.php ++++ b/core/modules/layout_builder/tests/src/Functional/LayoutBuilderAccessTest.php +@@ -18,6 +18,7 @@ class LayoutBuilderAccessTest extends BrowserTestBase { + protected static $modules = [ + 'layout_builder', + 'block_test', ++ 'field_ui', + 'node', + 'user', + ]; +diff --git a/core/modules/layout_builder/tests/src/Functional/LayoutBuilderSectionStorageTest.php b/core/modules/layout_builder/tests/src/Functional/LayoutBuilderSectionStorageTest.php +index a008b63f9bb..a30d65dcf81 100644 +--- a/core/modules/layout_builder/tests/src/Functional/LayoutBuilderSectionStorageTest.php ++++ b/core/modules/layout_builder/tests/src/Functional/LayoutBuilderSectionStorageTest.php +@@ -16,6 +16,7 @@ class LayoutBuilderSectionStorageTest extends BrowserTestBase { + */ + protected static $modules = [ + 'layout_builder', ++ 'field_ui', + 'node', + 'layout_builder_test', + ]; +diff --git a/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTest.php b/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTest.php +index d4314d7ecbb..5afb950064b 100644 +--- a/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTest.php ++++ b/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTest.php +@@ -19,6 +19,7 @@ class LayoutBuilderTest extends BrowserTestBase { + * {@inheritdoc} + */ + protected static $modules = [ ++ 'field_ui', + 'views', + 'layout_builder', + 'layout_builder_views_test', +diff --git a/core/modules/layout_builder/tests/src/Functional/LayoutBuilderThemeSuggestionsTest.php b/core/modules/layout_builder/tests/src/Functional/LayoutBuilderThemeSuggestionsTest.php +index 3c140db949f..16469f50de7 100644 +--- a/core/modules/layout_builder/tests/src/Functional/LayoutBuilderThemeSuggestionsTest.php ++++ b/core/modules/layout_builder/tests/src/Functional/LayoutBuilderThemeSuggestionsTest.php +@@ -2,6 +2,7 @@ + + namespace Drupal\Tests\layout_builder\Functional; + ++use Drupal\layout_builder\Entity\LayoutBuilderEntityViewDisplay; + use Drupal\Tests\BrowserTestBase; + + /** +@@ -35,6 +36,10 @@ protected function setUp(): void { + 'type' => 'bundle_with_section_field', + 'name' => 'Bundle with section field', + ]); ++ LayoutBuilderEntityViewDisplay::load('node.bundle_with_section_field.default') ++ ->enableLayoutBuilder() ++ ->setOverridable() ++ ->save(); + $this->createNode([ + 'type' => 'bundle_with_section_field', + 'title' => 'A node title', +@@ -47,11 +52,7 @@ protected function setUp(): void { + + $this->drupalLogin($this->drupalCreateUser([ + 'configure any layout', +- 'administer node display', + ])); +- +- $this->drupalGet('admin/structure/types/manage/bundle_with_section_field/display/default'); +- $this->submitForm(['layout[enabled]' => TRUE], 'Save'); + } + + /** +@@ -61,7 +62,7 @@ public function testLayoutListSuggestion() { + $page = $this->getSession()->getPage(); + $assert_session = $this->assertSession(); + +- $this->drupalGet('admin/structure/types/manage/bundle_with_section_field/display/default/layout'); ++ $this->drupalGet('node/1/layout'); + $page->clickLink('Add section'); + $assert_session->pageTextContains('layout_builder_theme_suggestions_test_preprocess_item_list__layouts'); + } +diff --git a/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTranslationTest.php b/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTranslationTest.php +index a4873d5d7b6..df882876866 100644 +--- a/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTranslationTest.php ++++ b/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTranslationTest.php +@@ -2,6 +2,7 @@ + + namespace Drupal\Tests\layout_builder\Functional; + ++use Drupal\layout_builder\Entity\LayoutBuilderEntityViewDisplay; + use Drupal\Tests\content_translation\Functional\ContentTranslationTestBase; + use Drupal\Core\Entity\Entity\EntityViewDisplay; + use Drupal\Core\Url; +@@ -122,15 +123,6 @@ public function testLayoutOverrideBeforeTranslation() { + $assert_session->pageTextContains('Access denied'); + } + +- /** +- * {@inheritdoc} +- */ +- protected function getAdministratorPermissions() { +- $permissions = parent::getAdministratorPermissions(); +- $permissions[] = 'administer entity_test_mul display'; +- return $permissions; +- } +- + /** + * {@inheritdoc} + */ +@@ -148,13 +140,6 @@ protected function getTranslatorPermissions() { + protected function setUpEntities() { + $this->drupalLogin($this->administrator); + +- $field_ui_prefix = 'entity_test_mul/structure/entity_test_mul'; +- // Allow overrides for the layout. +- $this->drupalGet("{$field_ui_prefix}/display/default"); +- $this->submitForm(['layout[enabled]' => TRUE], 'Save'); +- $this->drupalGet("{$field_ui_prefix}/display/default"); +- $this->submitForm(['layout[allow_custom]' => TRUE], 'Save'); +- + // @todo The Layout Builder UI relies on local tasks; fix in + // https://www.drupal.org/project/drupal/issues/2917777. + $this->drupalPlaceBlock('local_tasks_block'); +@@ -179,7 +164,11 @@ protected function setUpViewDisplay() { + 'bundle' => $this->bundle, + 'mode' => 'default', + 'status' => TRUE, +- ])->setComponent($this->fieldName, ['type' => 'string'])->save(); ++ ]) ++ ->setComponent($this->fieldName, ['type' => 'string']) ++ ->enableLayoutBuilder() ++ ->setOverridable() ++ ->save(); + } + + /** +diff --git a/core/modules/layout_builder/tests/src/Functional/Rest/LayoutRestTestBase.php b/core/modules/layout_builder/tests/src/Functional/Rest/LayoutRestTestBase.php +index 37708448368..7198ad9b4d3 100644 +--- a/core/modules/layout_builder/tests/src/Functional/Rest/LayoutRestTestBase.php ++++ b/core/modules/layout_builder/tests/src/Functional/Rest/LayoutRestTestBase.php +@@ -4,6 +4,7 @@ + + use Drupal\Component\Utility\NestedArray; + use Drupal\Core\Url; ++use Drupal\layout_builder\Entity\LayoutBuilderEntityViewDisplay; + use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait; + use Drupal\Tests\rest\Functional\ResourceTestBase; + use GuzzleHttp\RequestOptions; +@@ -48,24 +49,18 @@ public function setUp() { + $assert_session = $this->assertSession(); + + $this->createContentType(['type' => 'bundle_with_section_field']); ++ LayoutBuilderEntityViewDisplay::load('node.bundle_with_section_field.default') ++ ->enableLayoutBuilder() ++ ->setOverridable() ++ ->save(); + + $this->drupalLogin($this->drupalCreateUser([ + 'configure any layout', +- 'administer node display', +- 'administer display modes', + 'bypass node access', + 'create bundle_with_section_field content', + 'edit any bundle_with_section_field content', + ])); + $page = $this->getSession()->getPage(); +- $field_ui_prefix = 'admin/structure/types/manage/bundle_with_section_field/display'; +- +- // Enable Layout Builder for the default view modes, and overrides. +- $this->drupalGet("$field_ui_prefix/default"); +- $page->checkField('layout[enabled]'); +- $page->pressButton('Save'); +- $page->checkField('layout[allow_custom]'); +- $page->pressButton('Save'); + + // Create a node. + $this->node = $this->createNode([ +diff --git a/core/modules/layout_builder/tests/src/FunctionalJavascript/AjaxBlockTest.php b/core/modules/layout_builder/tests/src/FunctionalJavascript/AjaxBlockTest.php +index 5fbf7ac022e..d596dc500c1 100644 +--- a/core/modules/layout_builder/tests/src/FunctionalJavascript/AjaxBlockTest.php ++++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/AjaxBlockTest.php +@@ -3,6 +3,7 @@ + namespace Drupal\Tests\layout_builder\FunctionalJavascript; + + use Drupal\FunctionalJavascriptTests\WebDriverTestBase; ++use Drupal\layout_builder\Entity\LayoutBuilderEntityViewDisplay; + + /** + * Ajax blocks tests. +@@ -33,14 +34,19 @@ class AjaxBlockTest extends WebDriverTestBase { + */ + protected function setUp(): void { + parent::setUp(); +- $user = $this->drupalCreateUser([ ++ ++ // @todo The Layout Builder UI relies on local tasks; fix in ++ // https://www.drupal.org/project/drupal/issues/2917777. ++ $this->drupalPlaceBlock('local_tasks_block'); ++ ++ $this->drupalLogin($this->drupalCreateUser([ + 'configure any layout', +- 'administer node display', +- 'administer node fields', +- ]); +- $user->save(); +- $this->drupalLogin($user); ++ ])); + $this->createContentType(['type' => 'bundle_with_section_field']); ++ LayoutBuilderEntityViewDisplay::load('node.bundle_with_section_field.default') ++ ->enableLayoutBuilder() ++ ->setOverridable() ++ ->save(); + } + + /** +@@ -49,8 +55,9 @@ protected function setUp(): void { + public function testAddAjaxBlock() { + $assert_session = $this->assertSession(); + $page = $this->getSession()->getPage(); ++ + // Start by creating a node. +- $node = $this->createNode([ ++ $this->createNode([ + 'type' => 'bundle_with_section_field', + 'body' => [ + [ +@@ -58,18 +65,13 @@ public function testAddAjaxBlock() { + ], + ], + ]); +- $node->save(); ++ + $this->drupalGet('node/1'); + $assert_session->pageTextContains('The node body'); + $assert_session->pageTextNotContains('Every word is like an unnecessary stain on silence and nothingness.'); +- $field_ui_prefix = 'admin/structure/types/manage/bundle_with_section_field'; + + // From the manage display page, go to manage the layout. +- $this->drupalGet("{$field_ui_prefix}/display/default"); +- $this->submitForm(['layout[enabled]' => TRUE], 'Save'); +- $assert_session->linkExists('Manage layout'); +- $this->clickLink('Manage layout'); +- $assert_session->addressEquals("$field_ui_prefix/display/default/layout"); ++ $this->clickLink('Layout'); + // The body field is present. + $assert_session->elementExists('css', '.field--name-body'); + +diff --git a/core/modules/layout_builder/tests/src/FunctionalJavascript/BlockFilterTest.php b/core/modules/layout_builder/tests/src/FunctionalJavascript/BlockFilterTest.php +index d4402a79658..4474947a7ec 100644 +--- a/core/modules/layout_builder/tests/src/FunctionalJavascript/BlockFilterTest.php ++++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/BlockFilterTest.php +@@ -4,6 +4,7 @@ + + use Behat\Mink\Element\NodeElement; + use Drupal\FunctionalJavascriptTests\WebDriverTestBase; ++use Drupal\layout_builder\Entity\LayoutBuilderEntityViewDisplay; + + /** + * Tests the JavaScript functionality of the block add filter. +@@ -33,13 +34,16 @@ class BlockFilterTest extends WebDriverTestBase { + */ + protected function setUp(): void { + parent::setUp(); +- $user = $this->drupalCreateUser([ ++ ++ $this->drupalLogin($this->drupalCreateUser([ + 'configure any layout', +- 'administer node display', +- 'administer node fields', +- ]); +- $this->drupalLogin($user); ++ ])); + $this->createContentType(['type' => 'bundle_with_section_field']); ++ LayoutBuilderEntityViewDisplay::load('node.bundle_with_section_field.default') ++ ->enableLayoutBuilder() ++ ->setOverridable() ++ ->save(); ++ $this->createNode(['type' => 'bundle_with_section_field']); + } + + /** +@@ -50,15 +54,8 @@ public function testBlockFilter() { + $session = $this->getSession(); + $page = $session->getPage(); + +- // From the manage display page, go to manage the layout. +- $field_ui_prefix = 'admin/structure/types/manage/bundle_with_section_field'; +- $this->drupalGet("{$field_ui_prefix}/display/default"); +- $this->submitForm(['layout[enabled]' => TRUE], 'Save'); +- $assert_session->linkExists('Manage layout'); +- $this->clickLink('Manage layout'); +- $assert_session->addressEquals("$field_ui_prefix/display/default/layout"); +- + // Open the block listing. ++ $this->drupalGet('node/1/layout'); + $assert_session->linkExists('Add block'); + $this->clickLink('Add block'); + $assert_session->assertWaitOnAjaxRequest(); +diff --git a/core/modules/layout_builder/tests/src/FunctionalJavascript/BlockFormMessagesTest.php b/core/modules/layout_builder/tests/src/FunctionalJavascript/BlockFormMessagesTest.php +index 54e7e4e9b43..5e8dbcb3b17 100644 +--- a/core/modules/layout_builder/tests/src/FunctionalJavascript/BlockFormMessagesTest.php ++++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/BlockFormMessagesTest.php +@@ -3,6 +3,7 @@ + namespace Drupal\Tests\layout_builder\FunctionalJavascript; + + use Drupal\FunctionalJavascriptTests\WebDriverTestBase; ++use Drupal\layout_builder\Entity\LayoutBuilderEntityViewDisplay; + use Drupal\Tests\contextual\FunctionalJavascript\ContextualLinkClickTrait; + + /** +@@ -35,6 +36,11 @@ class BlockFormMessagesTest extends WebDriverTestBase { + protected function setUp(): void { + parent::setUp(); + $this->createContentType(['type' => 'bundle_with_section_field']); ++ LayoutBuilderEntityViewDisplay::load('node.bundle_with_section_field.default') ++ ->enableLayoutBuilder() ++ ->setOverridable() ++ ->save(); ++ $this->createNode(['type' => 'bundle_with_section_field']); + } + + /** +@@ -50,15 +56,8 @@ public function testValidationMessage() { + $this->drupalLogin($this->drupalCreateUser([ + 'access contextual links', + 'configure any layout', +- 'administer node display', +- 'administer node fields', + ])); +- $field_ui_prefix = 'admin/structure/types/manage/bundle_with_section_field'; +- // Enable layout builder. +- $this->drupalGet($field_ui_prefix . '/display/default'); +- $this->submitForm(['layout[enabled]' => TRUE], 'Save'); +- $page->findLink('Manage layout')->click(); +- $assert_session->addressEquals($field_ui_prefix . '/display/default/layout'); ++ $this->drupalGet('node/1/layout'); + $page->findLink('Add block')->click(); + $this->assertNotEmpty($assert_session->waitForElementVisible('css', '#drupal-off-canvas .block-categories')); + $page->findLink('Powered by Drupal')->click(); +@@ -75,10 +74,10 @@ public function testValidationMessage() { + $assert_session->assertWaitOnAjaxRequest(); + $this->drupalGet($this->getUrl()); + $page->findButton('Save layout')->click(); +- $this->assertNotEmpty($assert_session->waitForElement('css', 'div:contains("The layout has been saved")')); ++ $this->assertNotEmpty($assert_session->waitForElement('css', 'div:contains("The layout override has been saved")')); + + // Ensure that message are displayed when configuring an existing block. +- $this->drupalGet($field_ui_prefix . '/display/default/layout'); ++ $this->drupalGet('node/1/layout'); + $assert_session->assertWaitOnAjaxRequest(); + $this->clickContextualLink($block_css_locator, 'Configure', TRUE); + $this->assertNotEmpty($assert_session->waitForElementVisible('css', '#drupal-off-canvas [name="settings[label]"]')); +diff --git a/core/modules/layout_builder/tests/src/FunctionalJavascript/ContentPreviewToggleTest.php b/core/modules/layout_builder/tests/src/FunctionalJavascript/ContentPreviewToggleTest.php +index 0d472adc821..0505aae3c3a 100644 +--- a/core/modules/layout_builder/tests/src/FunctionalJavascript/ContentPreviewToggleTest.php ++++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/ContentPreviewToggleTest.php +@@ -3,6 +3,7 @@ + namespace Drupal\Tests\layout_builder\FunctionalJavascript; + + use Drupal\FunctionalJavascriptTests\WebDriverTestBase; ++use Drupal\layout_builder\Entity\LayoutBuilderEntityViewDisplay; + use Drupal\Tests\contextual\FunctionalJavascript\ContextualLinkClickTrait; + + /** +@@ -37,11 +38,13 @@ protected function setUp(): void { + parent::setUp(); + + $this->createContentType(['type' => 'bundle_for_this_particular_test']); ++ LayoutBuilderEntityViewDisplay::load('node.bundle_for_this_particular_test.default') ++ ->enableLayoutBuilder() ++ ->setOverridable() ++ ->save(); + + $this->drupalLogin($this->drupalCreateUser([ + 'configure any layout', +- 'administer node display', +- 'administer node fields', + 'access contextual links', + ])); + } +@@ -56,12 +59,6 @@ public function testContentPreviewToggle() { + $body_field_placeholder_label = '"Body" field'; + $content_preview_body_text = 'I should only be visible if content preview is enabled.'; + +- $this->drupalGet('admin/structure/types/manage/bundle_for_this_particular_test/display/default'); +- $this->submitForm([ +- 'layout[enabled]' => TRUE, +- 'layout[allow_custom]' => TRUE, +- ], 'Save'); +- + $this->createNode([ + 'type' => 'bundle_for_this_particular_test', + 'body' => [ +diff --git a/core/modules/layout_builder/tests/src/FunctionalJavascript/ContextualLinksTest.php b/core/modules/layout_builder/tests/src/FunctionalJavascript/ContextualLinksTest.php +index 94872332337..3e7b91c108b 100644 +--- a/core/modules/layout_builder/tests/src/FunctionalJavascript/ContextualLinksTest.php ++++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/ContextualLinksTest.php +@@ -3,6 +3,7 @@ + namespace Drupal\Tests\layout_builder\FunctionalJavascript; + + use Drupal\FunctionalJavascriptTests\WebDriverTestBase; ++use Drupal\layout_builder\Entity\LayoutBuilderEntityViewDisplay; + use Drupal\Tests\system\Functional\Cache\AssertPageCacheContextsAndTagsTrait; + + /** +@@ -41,8 +42,6 @@ protected function setUp(): void { + + $user = $this->drupalCreateUser([ + 'configure any layout', +- 'administer node display', +- 'administer node fields', + 'access contextual links', + 'administer nodes', + 'bypass node access', +@@ -51,6 +50,10 @@ protected function setUp(): void { + $user->save(); + $this->drupalLogin($user); + $this->createContentType(['type' => 'bundle_with_section_field']); ++ LayoutBuilderEntityViewDisplay::load('node.bundle_with_section_field.default') ++ ->enableLayoutBuilder() ++ ->setOverridable() ++ ->save(); + + $this->createNode([ + 'type' => 'bundle_with_section_field', +@@ -68,15 +71,6 @@ protected function setUp(): void { + public function testContextualLinks() { + $page = $this->getSession()->getPage(); + +- $field_ui_prefix = 'admin/structure/types/manage/bundle_with_section_field'; +- +- // Enable Layout Builder and overrides. +- $this->drupalGet("{$field_ui_prefix}/display/default"); +- $this->submitForm([ +- 'layout[enabled]' => TRUE, +- 'layout[allow_custom]' => TRUE, +- ], 'Save'); +- + $this->drupalGet('node/1/layout'); + + // Add a block that includes an entity contextual link. +diff --git a/core/modules/layout_builder/tests/src/FunctionalJavascript/InlineBlockPrivateFilesTest.php b/core/modules/layout_builder/tests/src/FunctionalJavascript/InlineBlockPrivateFilesTest.php +index 5727e9b8a40..032b5cb9959 100644 +--- a/core/modules/layout_builder/tests/src/FunctionalJavascript/InlineBlockPrivateFilesTest.php ++++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/InlineBlockPrivateFilesTest.php +@@ -4,6 +4,7 @@ + + use Drupal\file\Entity\File; + use Drupal\file\FileInterface; ++use Drupal\layout_builder\Entity\LayoutBuilderEntityViewDisplay; + use Drupal\node\Entity\Node; + use Drupal\node\Entity\NodeType; + use Drupal\Tests\file\Functional\FileFieldCreationTrait; +@@ -62,21 +63,10 @@ protected function setUp(): void { + */ + public function testPrivateFiles() { + $assert_session = $this->assertSession(); +- $this->drupalLogin($this->drupalCreateUser([ +- 'access contextual links', +- 'configure any layout', +- 'administer node display', +- 'administer node fields', +- 'create and edit custom blocks', +- ])); +- +- // Enable layout builder and overrides. +- $this->drupalGet(static::FIELD_UI_PREFIX . '/display/default'); +- $this->submitForm([ +- 'layout[enabled]' => TRUE, +- 'layout[allow_custom]' => TRUE, +- ], 'Save'); +- $this->drupalLogout(); ++ LayoutBuilderEntityViewDisplay::load('node.bundle_with_section_field.default') ++ ->enableLayoutBuilder() ++ ->setOverridable() ++ ->save(); + + // Log in as user you can only configure layouts and access content. + $this->drupalLogin($this->drupalCreateUser([ +diff --git a/core/modules/layout_builder/tests/src/FunctionalJavascript/InlineBlockTest.php b/core/modules/layout_builder/tests/src/FunctionalJavascript/InlineBlockTest.php +index 773ad3a396a..b5c4dab47f0 100644 +--- a/core/modules/layout_builder/tests/src/FunctionalJavascript/InlineBlockTest.php ++++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/InlineBlockTest.php +@@ -17,6 +17,13 @@ class InlineBlockTest extends InlineBlockTestBase { + */ + protected $defaultTheme = 'classy'; + ++ /** ++ * {@inheritdoc} ++ */ ++ protected static $modules = [ ++ 'field_ui', ++ ]; ++ + /** + * Tests adding and editing of inline blocks. + */ +@@ -32,11 +39,12 @@ public function testInlineBlocks() { + 'create and edit custom blocks', + ])); + +- // Enable layout builder. +- $this->drupalGet(static::FIELD_UI_PREFIX . '/display/default'); +- $this->submitForm(['layout[enabled]' => TRUE], 'Save'); +- $this->clickLink('Manage layout'); +- $assert_session->addressEquals(static::FIELD_UI_PREFIX . '/display/default/layout'); ++ LayoutBuilderEntityViewDisplay::load('node.bundle_with_section_field.default') ++ ->enableLayoutBuilder() ++ ->setOverridable() ++ ->save(); ++ ++ $this->drupalGet(static::FIELD_UI_PREFIX . '/display/default/layout'); + // Add a basic block with the body field set. + $this->addInlineBlockToLayout('Block title', 'The DEFAULT block body'); + $this->assertSaveLayout(); +@@ -46,9 +54,6 @@ public function testInlineBlocks() { + $this->drupalGet('node/2'); + $assert_session->pageTextContains('The DEFAULT block body'); + +- // Enable overrides. +- $this->drupalGet(static::FIELD_UI_PREFIX . '/display/default'); +- $this->submitForm(['layout[allow_custom]' => TRUE], 'Save'); + $this->drupalGet('node/1/layout'); + + // Confirm the block can be edited. +@@ -116,11 +121,10 @@ public function testNoLayoutSave($operation, $no_save_button_text, $confirm_butt + $page = $this->getSession()->getPage(); + $this->assertEmpty($this->blockStorage->loadMultiple(), 'No entity blocks exist'); + // Enable layout builder and overrides. +- $this->drupalGet(static::FIELD_UI_PREFIX . '/display/default'); +- $this->submitForm([ +- 'layout[enabled]' => TRUE, +- 'layout[allow_custom]' => TRUE, +- ], 'Save'); ++ LayoutBuilderEntityViewDisplay::load('node.bundle_with_section_field.default') ++ ->enableLayoutBuilder() ++ ->setOverridable() ++ ->save(); + + $this->drupalGet('node/1/layout'); + $this->addInlineBlockToLayout('Block title', 'The block body'); +@@ -208,8 +212,10 @@ public function testInlineBlocksRevisioning() { + 'create and edit custom blocks', + ])); + // Enable layout builder and overrides. +- $this->drupalGet(static::FIELD_UI_PREFIX . '/display/default'); +- $this->submitForm(['layout[enabled]' => TRUE, 'layout[allow_custom]' => TRUE], 'Save'); ++ LayoutBuilderEntityViewDisplay::load('node.bundle_with_section_field.default') ++ ->enableLayoutBuilder() ++ ->setOverridable() ++ ->save(); + $this->drupalGet('node/1/layout'); + + // Add an inline block. +@@ -368,12 +374,12 @@ public function testDeletion() { + $page = $this->getSession()->getPage(); + + // Enable layout builder. +- $this->drupalGet(static::FIELD_UI_PREFIX . '/display/default'); +- $this->submitForm(['layout[enabled]' => TRUE], 'Save'); ++ LayoutBuilderEntityViewDisplay::load('node.bundle_with_section_field.default') ++ ->enableLayoutBuilder() ++ ->setOverridable() ++ ->save(); + // Add a block to default layout. +- $this->drupalGet(static::FIELD_UI_PREFIX . '/display/default'); +- $this->clickLink('Manage layout'); +- $assert_session->addressEquals(static::FIELD_UI_PREFIX . '/display/default/layout'); ++ $this->drupalGet(static::FIELD_UI_PREFIX . '/display/default/layout'); + $this->addInlineBlockToLayout('Block title', 'The DEFAULT block body'); + $this->assertSaveLayout(); + +@@ -386,10 +392,6 @@ public function testDeletion() { + $this->drupalGet('node/2'); + $assert_session->pageTextContains('The DEFAULT block body'); + +- // Enable overrides. +- $this->drupalGet(static::FIELD_UI_PREFIX . '/display/default'); +- $this->submitForm(['layout[allow_custom]' => TRUE], 'Save'); +- + // Ensure we have 2 copies of the block in node overrides. + $this->drupalGet('node/1/layout'); + $this->assertSaveLayout(); +@@ -400,9 +402,7 @@ public function testDeletion() { + $node_2_block_id = $this->getLatestBlockEntityId(); + $this->assertCount(3, $this->blockStorage->loadMultiple()); + +- $this->drupalGet(static::FIELD_UI_PREFIX . '/display/default'); +- $this->clickLink('Manage layout'); +- $assert_session->addressEquals(static::FIELD_UI_PREFIX . '/display/default/layout'); ++ $this->drupalGet(static::FIELD_UI_PREFIX . '/display/default/layout'); + + $this->assertNotEmpty($this->blockStorage->load($default_block_id)); + $this->assertNotEmpty($usage->getUsage($default_block_id)); +@@ -437,9 +437,7 @@ public function testDeletion() { + $this->assertCount(1, $this->blockStorage->loadMultiple()); + + // Add another block to the default. +- $this->drupalGet(static::FIELD_UI_PREFIX . '/display/default'); +- $this->clickLink('Manage layout'); +- $assert_session->addressEquals(static::FIELD_UI_PREFIX . '/display/default/layout'); ++ $this->drupalGet(static::FIELD_UI_PREFIX . '/display/default/layout'); + $this->addInlineBlockToLayout('Title 2', 'Body 2'); + $this->assertSaveLayout(); + $cron->run(); +@@ -489,8 +487,10 @@ public function testAccess() { + $assert_session = $this->assertSession(); + + // Enable layout builder and overrides. +- $this->drupalGet(static::FIELD_UI_PREFIX . '/display/default'); +- $this->submitForm(['layout[enabled]' => TRUE, 'layout[allow_custom]' => TRUE], 'Save'); ++ LayoutBuilderEntityViewDisplay::load('node.bundle_with_section_field.default') ++ ->enableLayoutBuilder() ++ ->setOverridable() ++ ->save(); + + // Ensure we have 2 copies of the block in node overrides. + $this->drupalGet('node/1/layout'); +@@ -539,8 +539,10 @@ public function testAddWorkFlow() { + ])); + + // Enable layout builder and overrides. +- $this->drupalGet(static::FIELD_UI_PREFIX . '/display/default'); +- $this->submitForm(['layout[enabled]' => TRUE, 'layout[allow_custom]' => TRUE], 'Save'); ++ LayoutBuilderEntityViewDisplay::load('node.bundle_with_section_field.default') ++ ->enableLayoutBuilder() ++ ->setOverridable() ++ ->save(); + + $layout_default_path = 'admin/structure/types/manage/bundle_with_section_field/display/default/layout'; + $this->drupalGet($layout_default_path); +diff --git a/core/modules/layout_builder/tests/src/FunctionalJavascript/ItemLayoutFieldBlockTest.php b/core/modules/layout_builder/tests/src/FunctionalJavascript/ItemLayoutFieldBlockTest.php +index 726cc31a2d4..eba608cdc18 100644 +--- a/core/modules/layout_builder/tests/src/FunctionalJavascript/ItemLayoutFieldBlockTest.php ++++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/ItemLayoutFieldBlockTest.php +@@ -3,6 +3,7 @@ + namespace Drupal\Tests\layout_builder\FunctionalJavascript; + + use Drupal\FunctionalJavascriptTests\WebDriverTestBase; ++use Drupal\layout_builder\Entity\LayoutBuilderEntityViewDisplay; + + /** + * Field blocks tests for the override layout. +@@ -32,12 +33,14 @@ protected function setUp(): void { + + $this->drupalLogin($this->drupalCreateUser([ + 'configure any layout', +- 'administer node display', +- 'administer node fields', + ])); + + // We need more then one content type for this test. + $this->createContentType(['type' => 'bundle_with_layout_overrides']); ++ LayoutBuilderEntityViewDisplay::load('node.bundle_with_layout_overrides.default') ++ ->enableLayoutBuilder() ++ ->setOverridable() ++ ->save(); + $this->createContentType(['type' => 'filler_bundle']); + } + +@@ -48,12 +51,6 @@ public function testAddAjaxBlock() { + $assert_session = $this->assertSession(); + $page = $this->getSession()->getPage(); + +- // Allow overrides for the layout. +- $this->drupalGet('admin/structure/types/manage/bundle_with_layout_overrides/display/default'); +- $page->checkField('layout[enabled]'); +- $page->checkField('layout[allow_custom]'); +- $page->pressButton('Save'); +- + // Start by creating a node of type with layout overrides. + $node = $this->createNode([ + 'type' => 'bundle_with_layout_overrides', +diff --git a/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderDisableInteractionsTest.php b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderDisableInteractionsTest.php +index e83099c1dbc..6962a9528dd 100644 +--- a/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderDisableInteractionsTest.php ++++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderDisableInteractionsTest.php +@@ -25,6 +25,7 @@ class LayoutBuilderDisableInteractionsTest extends WebDriverTestBase { + protected static $modules = [ + 'block', + 'block_content', ++ 'field_ui', + 'filter', + 'filter_test', + 'layout_builder', +diff --git a/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderNestedFormUiTest.php b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderNestedFormUiTest.php +index aa073f12364..8178918828a 100644 +--- a/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderNestedFormUiTest.php ++++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderNestedFormUiTest.php +@@ -3,6 +3,7 @@ + namespace Drupal\Tests\layout_builder\FunctionalJavascript; + + use Drupal\FunctionalJavascriptTests\WebDriverTestBase; ++use Drupal\layout_builder\Entity\LayoutBuilderEntityViewDisplay; + + /** + * Tests placing blocks containing forms in theLayout Builder UI. +@@ -25,6 +26,7 @@ class LayoutBuilderNestedFormUiTest extends WebDriverTestBase { + */ + protected static $modules = [ + 'block', ++ 'field_ui', + 'node', + 'layout_builder', + 'layout_builder_form_block_test', +@@ -53,6 +55,10 @@ protected function setUp(): void { + 'type' => 'bundle_with_section_field', + 'name' => 'Bundle with section field', + ]); ++ LayoutBuilderEntityViewDisplay::load('node.bundle_with_section_field.default') ++ ->enableLayoutBuilder() ++ ->setOverridable() ++ ->save(); + for ($i = 1; $i <= count(static::FORM_BLOCK_LABELS); $i++) { + $this->createNode([ + 'type' => 'bundle_with_section_field', +@@ -70,11 +76,7 @@ public function testAddingFormBlocksToDefaults() { + 'administer node display', + ])); + +- // From the manage display page, enable Layout Builder. + $field_ui_prefix = 'admin/structure/types/manage/bundle_with_section_field'; +- $this->drupalGet("$field_ui_prefix/display/default"); +- $this->submitForm(['layout[enabled]' => TRUE], 'Save'); +- $this->submitForm(['layout[allow_custom]' => TRUE], 'Save'); + + // Save the entity view display so that it can be reverted to later. + /** @var \Drupal\Core\Config\StorageInterface $active_config_storage */ +@@ -101,15 +103,8 @@ public function testAddingFormBlocksToDefaults() { + public function testAddingFormBlocksToOverrides() { + $this->drupalLogin($this->drupalCreateUser([ + 'configure any layout', +- 'administer node display', + ])); + +- // From the manage display page, enable Layout Builder. +- $field_ui_prefix = 'admin/structure/types/manage/bundle_with_section_field'; +- $this->drupalGet("$field_ui_prefix/display/default"); +- $this->submitForm(['layout[enabled]' => TRUE], 'Save'); +- $this->submitForm(['layout[allow_custom]' => TRUE], 'Save'); +- + $expected_save_message = 'The layout override has been saved.'; + $nid = 1; + foreach (static::FORM_BLOCK_LABELS as $label) { +diff --git a/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderToolbarTest.php b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderToolbarTest.php +index 9cb41a4b420..2af74b31457 100644 +--- a/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderToolbarTest.php ++++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderToolbarTest.php +@@ -17,6 +17,7 @@ class LayoutBuilderToolbarTest extends WebDriverTestBase { + protected static $modules = [ + 'block', + 'node', ++ 'field_ui', + 'layout_builder', + 'node', + 'toolbar', +diff --git a/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderUiTest.php b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderUiTest.php +index 77af692cc51..47aee6c186b 100644 +--- a/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderUiTest.php ++++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderUiTest.php +@@ -22,9 +22,13 @@ class LayoutBuilderUiTest extends WebDriverTestBase { + */ + const FIELD_UI_PREFIX = 'admin/structure/types/manage/bundle_with_section_field'; + ++ /** ++ * {@inheritdoc} ++ */ + protected static $modules = [ + 'layout_builder', + 'block', ++ 'field_ui', + 'node', + 'block_content', + 'contextual', +diff --git a/core/modules/layout_builder/tests/src/FunctionalJavascript/MoveBlockFormTest.php b/core/modules/layout_builder/tests/src/FunctionalJavascript/MoveBlockFormTest.php +index f7b302e7355..6eb6576304a 100644 +--- a/core/modules/layout_builder/tests/src/FunctionalJavascript/MoveBlockFormTest.php ++++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/MoveBlockFormTest.php +@@ -3,6 +3,7 @@ + namespace Drupal\Tests\layout_builder\FunctionalJavascript; + + use Drupal\FunctionalJavascriptTests\WebDriverTestBase; ++use Drupal\layout_builder\Entity\LayoutBuilderEntityViewDisplay; + use Drupal\Tests\contextual\FunctionalJavascript\ContextualLinkClickTrait; + + /** +@@ -14,13 +15,6 @@ class MoveBlockFormTest extends WebDriverTestBase { + + use ContextualLinkClickTrait; + +- /** +- * Path prefix for the field UI for the test bundle. +- * +- * @var string +- */ +- const FIELD_UI_PREFIX = 'admin/structure/types/manage/bundle_with_section_field'; +- + /** + * {@inheritdoc} + */ +@@ -44,21 +38,25 @@ protected function setUp(): void { + $page = $this->getSession()->getPage(); + $assert_session = $this->assertSession(); + ++ // @todo The Layout Builder UI relies on local tasks; fix in ++ // https://www.drupal.org/project/drupal/issues/2917777. ++ $this->drupalPlaceBlock('local_tasks_block'); ++ + $this->createContentType(['type' => 'bundle_with_section_field']); ++ LayoutBuilderEntityViewDisplay::load('node.bundle_with_section_field.default') ++ ->enableLayoutBuilder() ++ ->setOverridable() ++ ->save(); ++ $this->createNode([ ++ 'type' => 'bundle_with_section_field', ++ ]); + + $this->drupalLogin($this->drupalCreateUser([ + 'configure any layout', +- 'administer node display', +- 'administer node fields', + 'access contextual links', + ])); + +- // Enable layout builder. +- $this->drupalGet(static::FIELD_UI_PREFIX . '/display/default'); +- $this->submitForm(['layout[enabled]' => TRUE], 'Save'); +- $page->clickLink('Manage layout'); +- $assert_session->addressEquals(static::FIELD_UI_PREFIX . '/display/default/layout'); +- ++ $this->drupalGet('node/1/layout'); + $expected_block_order = [ + '.block-extra-field-blocknodebundle-with-section-fieldlinks', + '.block-field-blocknodebundle-with-section-fieldbody', +@@ -108,7 +106,7 @@ public function testMoveBlock() { + ]; + $this->assertRegionBlocksOrder(1, 'content', $expected_block_order); + $page->pressButton('Save layout'); +- $page->clickLink('Manage layout'); ++ $page->clickLink('Layout'); + $this->assertRegionBlocksOrder(1, 'content', $expected_block_order); + + // Move the body block into the first region above existing block. +@@ -126,7 +124,7 @@ public function testMoveBlock() { + // Ensure the body block is no longer in the content region. + $this->assertRegionBlocksOrder(1, 'content', ['.block-extra-field-blocknodebundle-with-section-fieldlinks']); + $page->pressButton('Save layout'); +- $page->clickLink('Manage layout'); ++ $page->clickLink('Layout'); + $this->assertRegionBlocksOrder(0, 'first', $expected_block_order); + + // Move into the second region that has no existing blocks. +diff --git a/core/modules/layout_builder/tests/src/FunctionalJavascript/TestMultiWidthLayoutsTest.php b/core/modules/layout_builder/tests/src/FunctionalJavascript/TestMultiWidthLayoutsTest.php +index 9ec01e7cb0d..6ada06020ec 100644 +--- a/core/modules/layout_builder/tests/src/FunctionalJavascript/TestMultiWidthLayoutsTest.php ++++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/TestMultiWidthLayoutsTest.php +@@ -3,6 +3,7 @@ + namespace Drupal\Tests\layout_builder\FunctionalJavascript; + + use Drupal\FunctionalJavascriptTests\WebDriverTestBase; ++use Drupal\layout_builder\Entity\LayoutBuilderEntityViewDisplay; + + /** + * Test the multi-width layout plugins. +@@ -12,12 +13,8 @@ + class TestMultiWidthLayoutsTest extends WebDriverTestBase { + + /** +- * Path prefix for the field UI for the test bundle. +- * +- * @var string ++ * {@inheritdoc} + */ +- const FIELD_UI_PREFIX = 'admin/structure/types/manage/bundle_with_section_field'; +- + protected static $modules = [ + 'layout_builder', + 'block', +@@ -36,11 +33,16 @@ protected function setUp(): void { + parent::setUp(); + + $this->createContentType(['type' => 'bundle_with_section_field']); ++ LayoutBuilderEntityViewDisplay::load('node.bundle_with_section_field.default') ++ ->enableLayoutBuilder() ++ ->setOverridable() ++ ->save(); + ++ $this->createNode([ ++ 'type' => 'bundle_with_section_field', ++ ]); + $this->drupalLogin($this->drupalCreateUser([ + 'configure any layout', +- 'administer node display', +- 'administer node fields', + ])); + } + +@@ -51,13 +53,7 @@ public function testWidthChange() { + $assert_session = $this->assertSession(); + $page = $this->getSession()->getPage(); + +- // Enable layout builder. +- $this->drupalGet(static::FIELD_UI_PREFIX . '/display/default'); +- $this->submitForm(['layout[enabled]' => TRUE], 'Save'); +- +- $this->clickLink('Manage layout'); +- $assert_session->addressEquals(static::FIELD_UI_PREFIX . '/display/default/layout'); +- ++ $this->drupalGet('node/1/layout'); + $width_options = [ + [ + 'label' => 'Two column', +diff --git a/core/modules/quickedit/tests/src/Functional/LayoutBuilderQuickEditTest.php b/core/modules/quickedit/tests/src/Functional/LayoutBuilderQuickEditTest.php +index e9be41eb804..3c46248158e 100644 +--- a/core/modules/quickedit/tests/src/Functional/LayoutBuilderQuickEditTest.php ++++ b/core/modules/quickedit/tests/src/Functional/LayoutBuilderQuickEditTest.php +@@ -2,6 +2,7 @@ + + namespace Drupal\Tests\quickedit\Functional; + ++use Drupal\layout_builder\Entity\LayoutBuilderEntityViewDisplay; + use Drupal\Tests\BrowserTestBase; + + /** +@@ -39,6 +40,10 @@ protected function setUp(): void { + $this->createNode([ + 'type' => 'bundle_with_section_field', + ]); ++ LayoutBuilderEntityViewDisplay::load('node.bundle_with_section_field.default') ++ ->enableLayoutBuilder() ++ ->setOverridable() ++ ->save(); + } + + /** +@@ -49,15 +54,9 @@ public function testPlaceFieldBlockFromDifferentEntityType() { + + $this->drupalLogin($this->drupalCreateUser([ + 'configure any layout', +- 'administer node display', + 'access in-place editing', + ])); + +- // From the manage display page, go to manage the layout. +- $this->drupalGet('admin/structure/types/manage/bundle_with_section_field/display/default'); +- $this->submitForm(['layout[enabled]' => TRUE], 'Save'); +- $this->submitForm(['layout[allow_custom]' => TRUE], 'Save'); +- + // Place a field block for a user entity field. + $this->drupalGet('node/1/layout'); + $page->clickLink('Add block'); +diff --git a/core/modules/quickedit/tests/src/FunctionalJavascript/LayoutBuilderQuickEditTest.php b/core/modules/quickedit/tests/src/FunctionalJavascript/LayoutBuilderQuickEditTest.php +index 05744d77eaf..6fc6b401bec 100644 +--- a/core/modules/quickedit/tests/src/FunctionalJavascript/LayoutBuilderQuickEditTest.php ++++ b/core/modules/quickedit/tests/src/FunctionalJavascript/LayoutBuilderQuickEditTest.php +@@ -25,6 +25,7 @@ class LayoutBuilderQuickEditTest extends QuickEditJavascriptTestBase { + protected static $modules = [ + 'node', + 'layout_builder', ++ 'field_ui', + ]; + + /** +-- +GitLab + + +From 9a4130c7fa32e22cb7ee189b30fc45b3f6dbabc8 Mon Sep 17 00:00:00 2001 +From: Tim Plunkett +Date: Mon, 29 Jun 2020 13:45:23 -0400 +Subject: [PATCH 2/7] improvements + +--- + .../FunctionalJavascript/InlineBlockTest.php | 76 ++++++++++++------- + .../LayoutBuilderNestedFormUiTest.php | 16 ++-- + .../Theme/ClaroLayoutBuilderTest.php | 1 + + .../Theme/SevenLayoutBuilderTest.php | 1 + + 4 files changed, 60 insertions(+), 34 deletions(-) + +diff --git a/core/modules/layout_builder/tests/src/FunctionalJavascript/InlineBlockTest.php b/core/modules/layout_builder/tests/src/FunctionalJavascript/InlineBlockTest.php +index b5c4dab47f0..91d585b5ecf 100644 +--- a/core/modules/layout_builder/tests/src/FunctionalJavascript/InlineBlockTest.php ++++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/InlineBlockTest.php +@@ -39,12 +39,14 @@ public function testInlineBlocks() { + 'create and edit custom blocks', + ])); + +- LayoutBuilderEntityViewDisplay::load('node.bundle_with_section_field.default') +- ->enableLayoutBuilder() +- ->setOverridable() +- ->save(); +- +- $this->drupalGet(static::FIELD_UI_PREFIX . '/display/default/layout'); ++ // Enable layout builder. ++ $this->drupalPostForm( ++ static::FIELD_UI_PREFIX . '/display/default', ++ ['layout[enabled]' => TRUE], ++ 'Save' ++ ); ++ $this->clickLink('Manage layout'); ++ $assert_session->addressEquals(static::FIELD_UI_PREFIX . '/display/default/layout'); + // Add a basic block with the body field set. + $this->addInlineBlockToLayout('Block title', 'The DEFAULT block body'); + $this->assertSaveLayout(); +@@ -54,6 +56,8 @@ public function testInlineBlocks() { + $this->drupalGet('node/2'); + $assert_session->pageTextContains('The DEFAULT block body'); + ++ // Enable overrides. ++ $this->drupalPostForm(static::FIELD_UI_PREFIX . '/display/default', ['layout[allow_custom]' => TRUE], 'Save'); + $this->drupalGet('node/1/layout'); + + // Confirm the block can be edited. +@@ -121,10 +125,11 @@ public function testNoLayoutSave($operation, $no_save_button_text, $confirm_butt + $page = $this->getSession()->getPage(); + $this->assertEmpty($this->blockStorage->loadMultiple(), 'No entity blocks exist'); + // Enable layout builder and overrides. +- LayoutBuilderEntityViewDisplay::load('node.bundle_with_section_field.default') +- ->enableLayoutBuilder() +- ->setOverridable() +- ->save(); ++ $this->drupalPostForm( ++ static::FIELD_UI_PREFIX . '/display/default', ++ ['layout[enabled]' => TRUE, 'layout[allow_custom]' => TRUE], ++ 'Save' ++ ); + + $this->drupalGet('node/1/layout'); + $this->addInlineBlockToLayout('Block title', 'The block body'); +@@ -212,10 +217,11 @@ public function testInlineBlocksRevisioning() { + 'create and edit custom blocks', + ])); + // Enable layout builder and overrides. +- LayoutBuilderEntityViewDisplay::load('node.bundle_with_section_field.default') +- ->enableLayoutBuilder() +- ->setOverridable() +- ->save(); ++ $this->drupalPostForm( ++ static::FIELD_UI_PREFIX . '/display/default', ++ ['layout[enabled]' => TRUE, 'layout[allow_custom]' => TRUE], ++ 'Save' ++ ); + $this->drupalGet('node/1/layout'); + + // Add an inline block. +@@ -374,12 +380,15 @@ public function testDeletion() { + $page = $this->getSession()->getPage(); + + // Enable layout builder. +- LayoutBuilderEntityViewDisplay::load('node.bundle_with_section_field.default') +- ->enableLayoutBuilder() +- ->setOverridable() +- ->save(); ++ $this->drupalPostForm( ++ static::FIELD_UI_PREFIX . '/display/default', ++ ['layout[enabled]' => TRUE], ++ 'Save' ++ ); + // Add a block to default layout. +- $this->drupalGet(static::FIELD_UI_PREFIX . '/display/default/layout'); ++ $this->drupalGet(static::FIELD_UI_PREFIX . '/display/default'); ++ $this->clickLink('Manage layout'); ++ $assert_session->addressEquals(static::FIELD_UI_PREFIX . '/display/default/layout'); + $this->addInlineBlockToLayout('Block title', 'The DEFAULT block body'); + $this->assertSaveLayout(); + +@@ -392,6 +401,9 @@ public function testDeletion() { + $this->drupalGet('node/2'); + $assert_session->pageTextContains('The DEFAULT block body'); + ++ // Enable overrides. ++ $this->drupalPostForm(static::FIELD_UI_PREFIX . '/display/default', ['layout[allow_custom]' => TRUE], 'Save'); ++ + // Ensure we have 2 copies of the block in node overrides. + $this->drupalGet('node/1/layout'); + $this->assertSaveLayout(); +@@ -402,7 +414,9 @@ public function testDeletion() { + $node_2_block_id = $this->getLatestBlockEntityId(); + $this->assertCount(3, $this->blockStorage->loadMultiple()); + +- $this->drupalGet(static::FIELD_UI_PREFIX . '/display/default/layout'); ++ $this->drupalGet(static::FIELD_UI_PREFIX . '/display/default'); ++ $this->clickLink('Manage layout'); ++ $assert_session->addressEquals(static::FIELD_UI_PREFIX . '/display/default/layout'); + + $this->assertNotEmpty($this->blockStorage->load($default_block_id)); + $this->assertNotEmpty($usage->getUsage($default_block_id)); +@@ -437,7 +451,9 @@ public function testDeletion() { + $this->assertCount(1, $this->blockStorage->loadMultiple()); + + // Add another block to the default. +- $this->drupalGet(static::FIELD_UI_PREFIX . '/display/default/layout'); ++ $this->drupalGet(static::FIELD_UI_PREFIX . '/display/default'); ++ $this->clickLink('Manage layout'); ++ $assert_session->addressEquals(static::FIELD_UI_PREFIX . '/display/default/layout'); + $this->addInlineBlockToLayout('Title 2', 'Body 2'); + $this->assertSaveLayout(); + $cron->run(); +@@ -487,10 +503,11 @@ public function testAccess() { + $assert_session = $this->assertSession(); + + // Enable layout builder and overrides. +- LayoutBuilderEntityViewDisplay::load('node.bundle_with_section_field.default') +- ->enableLayoutBuilder() +- ->setOverridable() +- ->save(); ++ $this->drupalPostForm( ++ static::FIELD_UI_PREFIX . '/display/default', ++ ['layout[enabled]' => TRUE, 'layout[allow_custom]' => TRUE], ++ 'Save' ++ ); + + // Ensure we have 2 copies of the block in node overrides. + $this->drupalGet('node/1/layout'); +@@ -539,10 +556,11 @@ public function testAddWorkFlow() { + ])); + + // Enable layout builder and overrides. +- LayoutBuilderEntityViewDisplay::load('node.bundle_with_section_field.default') +- ->enableLayoutBuilder() +- ->setOverridable() +- ->save(); ++ $this->drupalPostForm( ++ static::FIELD_UI_PREFIX . '/display/default', ++ ['layout[enabled]' => TRUE, 'layout[allow_custom]' => TRUE], ++ 'Save' ++ ); + + $layout_default_path = 'admin/structure/types/manage/bundle_with_section_field/display/default/layout'; + $this->drupalGet($layout_default_path); +diff --git a/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderNestedFormUiTest.php b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderNestedFormUiTest.php +index 8178918828a..9ebd4792570 100644 +--- a/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderNestedFormUiTest.php ++++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderNestedFormUiTest.php +@@ -3,7 +3,6 @@ + namespace Drupal\Tests\layout_builder\FunctionalJavascript; + + use Drupal\FunctionalJavascriptTests\WebDriverTestBase; +-use Drupal\layout_builder\Entity\LayoutBuilderEntityViewDisplay; + + /** + * Tests placing blocks containing forms in theLayout Builder UI. +@@ -55,10 +54,6 @@ protected function setUp(): void { + 'type' => 'bundle_with_section_field', + 'name' => 'Bundle with section field', + ]); +- LayoutBuilderEntityViewDisplay::load('node.bundle_with_section_field.default') +- ->enableLayoutBuilder() +- ->setOverridable() +- ->save(); + for ($i = 1; $i <= count(static::FORM_BLOCK_LABELS); $i++) { + $this->createNode([ + 'type' => 'bundle_with_section_field', +@@ -76,7 +71,11 @@ public function testAddingFormBlocksToDefaults() { + 'administer node display', + ])); + ++ // From the manage display page, enable Layout Builder. + $field_ui_prefix = 'admin/structure/types/manage/bundle_with_section_field'; ++ $this->drupalGet("$field_ui_prefix/display/default"); ++ $this->drupalPostForm(NULL, ['layout[enabled]' => TRUE], 'Save'); ++ $this->drupalPostForm(NULL, ['layout[allow_custom]' => TRUE], 'Save'); + + // Save the entity view display so that it can be reverted to later. + /** @var \Drupal\Core\Config\StorageInterface $active_config_storage */ +@@ -103,8 +102,15 @@ public function testAddingFormBlocksToDefaults() { + public function testAddingFormBlocksToOverrides() { + $this->drupalLogin($this->drupalCreateUser([ + 'configure any layout', ++ 'administer node display', + ])); + ++ // From the manage display page, enable Layout Builder. ++ $field_ui_prefix = 'admin/structure/types/manage/bundle_with_section_field'; ++ $this->drupalGet("$field_ui_prefix/display/default"); ++ $this->drupalPostForm(NULL, ['layout[enabled]' => TRUE], 'Save'); ++ $this->drupalPostForm(NULL, ['layout[allow_custom]' => TRUE], 'Save'); ++ + $expected_save_message = 'The layout override has been saved.'; + $nid = 1; + foreach (static::FORM_BLOCK_LABELS as $label) { +diff --git a/core/tests/Drupal/FunctionalTests/Theme/ClaroLayoutBuilderTest.php b/core/tests/Drupal/FunctionalTests/Theme/ClaroLayoutBuilderTest.php +index c2569bcff87..c20e08b44ec 100644 +--- a/core/tests/Drupal/FunctionalTests/Theme/ClaroLayoutBuilderTest.php ++++ b/core/tests/Drupal/FunctionalTests/Theme/ClaroLayoutBuilderTest.php +@@ -24,6 +24,7 @@ class ClaroLayoutBuilderTest extends BrowserTestBase { + 'layout_builder', + 'layout_builder_views_test', + 'layout_test', ++ 'field_ui', + 'block', + 'block_test', + 'node', +diff --git a/core/tests/Drupal/FunctionalTests/Theme/SevenLayoutBuilderTest.php b/core/tests/Drupal/FunctionalTests/Theme/SevenLayoutBuilderTest.php +index 4fd04e89be3..f738f125614 100644 +--- a/core/tests/Drupal/FunctionalTests/Theme/SevenLayoutBuilderTest.php ++++ b/core/tests/Drupal/FunctionalTests/Theme/SevenLayoutBuilderTest.php +@@ -24,6 +24,7 @@ class SevenLayoutBuilderTest extends BrowserTestBase { + 'layout_builder', + 'layout_builder_views_test', + 'layout_test', ++ 'field_ui', + 'block', + 'block_test', + 'node', +-- +GitLab + + +From 0d53ef9de4d4e31d221ce0d8b98c64eff860d2bb Mon Sep 17 00:00:00 2001 +From: Tim Plunkett +Date: Mon, 24 May 2021 10:42:38 -0400 +Subject: [PATCH 3/7] Fix regressions + +--- + .../FunctionalJavascript/InlineBlockTest.php | 51 +++++++------------ + .../LayoutBuilderNestedFormUiTest.php | 8 +-- + 2 files changed, 23 insertions(+), 36 deletions(-) + +diff --git a/core/modules/layout_builder/tests/src/FunctionalJavascript/InlineBlockTest.php b/core/modules/layout_builder/tests/src/FunctionalJavascript/InlineBlockTest.php +index 91d585b5ecf..867cb1abae9 100644 +--- a/core/modules/layout_builder/tests/src/FunctionalJavascript/InlineBlockTest.php ++++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/InlineBlockTest.php +@@ -40,11 +40,8 @@ public function testInlineBlocks() { + ])); + + // Enable layout builder. +- $this->drupalPostForm( +- static::FIELD_UI_PREFIX . '/display/default', +- ['layout[enabled]' => TRUE], +- 'Save' +- ); ++ $this->drupalGet(static::FIELD_UI_PREFIX . '/display/default'); ++ $this->submitForm(['layout[enabled]' => TRUE], 'Save'); + $this->clickLink('Manage layout'); + $assert_session->addressEquals(static::FIELD_UI_PREFIX . '/display/default/layout'); + // Add a basic block with the body field set. +@@ -57,7 +54,8 @@ public function testInlineBlocks() { + $assert_session->pageTextContains('The DEFAULT block body'); + + // Enable overrides. +- $this->drupalPostForm(static::FIELD_UI_PREFIX . '/display/default', ['layout[allow_custom]' => TRUE], 'Save'); ++ $this->drupalGet(static::FIELD_UI_PREFIX . '/display/default'); ++ $this->submitForm(['layout[allow_custom]' => TRUE], 'Save'); + $this->drupalGet('node/1/layout'); + + // Confirm the block can be edited. +@@ -125,11 +123,11 @@ public function testNoLayoutSave($operation, $no_save_button_text, $confirm_butt + $page = $this->getSession()->getPage(); + $this->assertEmpty($this->blockStorage->loadMultiple(), 'No entity blocks exist'); + // Enable layout builder and overrides. +- $this->drupalPostForm( +- static::FIELD_UI_PREFIX . '/display/default', +- ['layout[enabled]' => TRUE, 'layout[allow_custom]' => TRUE], +- 'Save' +- ); ++ $this->drupalGet(static::FIELD_UI_PREFIX . '/display/default'); ++ $this->submitForm([ ++ 'layout[enabled]' => TRUE, ++ 'layout[allow_custom]' => TRUE, ++ ], 'Save'); + + $this->drupalGet('node/1/layout'); + $this->addInlineBlockToLayout('Block title', 'The block body'); +@@ -217,11 +215,8 @@ public function testInlineBlocksRevisioning() { + 'create and edit custom blocks', + ])); + // Enable layout builder and overrides. +- $this->drupalPostForm( +- static::FIELD_UI_PREFIX . '/display/default', +- ['layout[enabled]' => TRUE, 'layout[allow_custom]' => TRUE], +- 'Save' +- ); ++ $this->drupalGet(static::FIELD_UI_PREFIX . '/display/default'); ++ $this->submitForm(['layout[enabled]' => TRUE, 'layout[allow_custom]' => TRUE], 'Save'); + $this->drupalGet('node/1/layout'); + + // Add an inline block. +@@ -380,11 +375,8 @@ public function testDeletion() { + $page = $this->getSession()->getPage(); + + // Enable layout builder. +- $this->drupalPostForm( +- static::FIELD_UI_PREFIX . '/display/default', +- ['layout[enabled]' => TRUE], +- 'Save' +- ); ++ $this->drupalGet(static::FIELD_UI_PREFIX . '/display/default'); ++ $this->submitForm(['layout[enabled]' => TRUE], 'Save'); + // Add a block to default layout. + $this->drupalGet(static::FIELD_UI_PREFIX . '/display/default'); + $this->clickLink('Manage layout'); +@@ -402,7 +394,8 @@ public function testDeletion() { + $assert_session->pageTextContains('The DEFAULT block body'); + + // Enable overrides. +- $this->drupalPostForm(static::FIELD_UI_PREFIX . '/display/default', ['layout[allow_custom]' => TRUE], 'Save'); ++ $this->drupalGet(static::FIELD_UI_PREFIX . '/display/default'); ++ $this->submitForm(['layout[allow_custom]' => TRUE], 'Save'); + + // Ensure we have 2 copies of the block in node overrides. + $this->drupalGet('node/1/layout'); +@@ -503,11 +496,8 @@ public function testAccess() { + $assert_session = $this->assertSession(); + + // Enable layout builder and overrides. +- $this->drupalPostForm( +- static::FIELD_UI_PREFIX . '/display/default', +- ['layout[enabled]' => TRUE, 'layout[allow_custom]' => TRUE], +- 'Save' +- ); ++ $this->drupalGet(static::FIELD_UI_PREFIX . '/display/default'); ++ $this->submitForm(['layout[enabled]' => TRUE, 'layout[allow_custom]' => TRUE], 'Save'); + + // Ensure we have 2 copies of the block in node overrides. + $this->drupalGet('node/1/layout'); +@@ -556,11 +546,8 @@ public function testAddWorkFlow() { + ])); + + // Enable layout builder and overrides. +- $this->drupalPostForm( +- static::FIELD_UI_PREFIX . '/display/default', +- ['layout[enabled]' => TRUE, 'layout[allow_custom]' => TRUE], +- 'Save' +- ); ++ $this->drupalGet(static::FIELD_UI_PREFIX . '/display/default'); ++ $this->submitForm(['layout[enabled]' => TRUE, 'layout[allow_custom]' => TRUE], 'Save'); + + $layout_default_path = 'admin/structure/types/manage/bundle_with_section_field/display/default/layout'; + $this->drupalGet($layout_default_path); +diff --git a/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderNestedFormUiTest.php b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderNestedFormUiTest.php +index 9ebd4792570..82efebb9ea5 100644 +--- a/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderNestedFormUiTest.php ++++ b/core/modules/layout_builder/tests/src/FunctionalJavascript/LayoutBuilderNestedFormUiTest.php +@@ -74,8 +74,8 @@ public function testAddingFormBlocksToDefaults() { + // From the manage display page, enable Layout Builder. + $field_ui_prefix = 'admin/structure/types/manage/bundle_with_section_field'; + $this->drupalGet("$field_ui_prefix/display/default"); +- $this->drupalPostForm(NULL, ['layout[enabled]' => TRUE], 'Save'); +- $this->drupalPostForm(NULL, ['layout[allow_custom]' => TRUE], 'Save'); ++ $this->submitForm(['layout[enabled]' => TRUE], 'Save'); ++ $this->submitForm(['layout[allow_custom]' => TRUE], 'Save'); + + // Save the entity view display so that it can be reverted to later. + /** @var \Drupal\Core\Config\StorageInterface $active_config_storage */ +@@ -108,8 +108,8 @@ public function testAddingFormBlocksToOverrides() { + // From the manage display page, enable Layout Builder. + $field_ui_prefix = 'admin/structure/types/manage/bundle_with_section_field'; + $this->drupalGet("$field_ui_prefix/display/default"); +- $this->drupalPostForm(NULL, ['layout[enabled]' => TRUE], 'Save'); +- $this->drupalPostForm(NULL, ['layout[allow_custom]' => TRUE], 'Save'); ++ $this->submitForm(['layout[enabled]' => TRUE], 'Save'); ++ $this->submitForm(['layout[allow_custom]' => TRUE], 'Save'); + + $expected_save_message = 'The layout override has been saved.'; + $nid = 1; +-- +GitLab + + +From 129279109e02d380efdf1a506c10613c69b0f25b Mon Sep 17 00:00:00 2001 +From: Tim Plunkett +Date: Mon, 24 May 2021 10:45:20 -0400 +Subject: [PATCH 4/7] Fix LayoutBuilderPrepareLayoutTest + +--- + .../tests/src/Functional/LayoutBuilderPrepareLayoutTest.php | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/core/modules/layout_builder/tests/src/Functional/LayoutBuilderPrepareLayoutTest.php b/core/modules/layout_builder/tests/src/Functional/LayoutBuilderPrepareLayoutTest.php +index e991d909e48..903ebfcff46 100644 +--- a/core/modules/layout_builder/tests/src/Functional/LayoutBuilderPrepareLayoutTest.php ++++ b/core/modules/layout_builder/tests/src/Functional/LayoutBuilderPrepareLayoutTest.php +@@ -16,6 +16,7 @@ class LayoutBuilderPrepareLayoutTest extends BrowserTestBase { + * {@inheritdoc} + */ + protected static $modules = [ ++ 'field_ui', + 'layout_builder', + 'node', + 'layout_builder_element_test', +-- +GitLab + + +From 47f412f950fc8d366a70470253fa8cdbd7fc0cec Mon Sep 17 00:00:00 2001 +From: Tim Plunkett +Date: Mon, 24 May 2021 11:49:07 -0400 +Subject: [PATCH 5/7] Remove leftover use statement + +--- + .../tests/src/Functional/LayoutBuilderTranslationTest.php | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTranslationTest.php b/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTranslationTest.php +index df882876866..4b5999d9030 100644 +--- a/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTranslationTest.php ++++ b/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTranslationTest.php +@@ -2,7 +2,6 @@ + + namespace Drupal\Tests\layout_builder\Functional; + +-use Drupal\layout_builder\Entity\LayoutBuilderEntityViewDisplay; + use Drupal\Tests\content_translation\Functional\ContentTranslationTestBase; + use Drupal\Core\Entity\Entity\EntityViewDisplay; + use Drupal\Core\Url; +-- +GitLab + + +From ad7243ebea8522744a043089bc5cd5558d75ac94 Mon Sep 17 00:00:00 2001 +From: Tim Plunkett +Date: Fri, 17 Sep 2021 10:17:31 -0400 +Subject: [PATCH 6/7] Do not provide Field UI-based routes if Field UI isn't + installed. + +--- + .../src/Plugin/SectionStorage/DefaultsSectionStorage.php | 4 ++++ + .../layout_builder/tests/src/Functional/LayoutBuilderTest.php | 4 +++- + 2 files changed, 7 insertions(+), 1 deletion(-) + +diff --git a/core/modules/layout_builder/src/Plugin/SectionStorage/DefaultsSectionStorage.php b/core/modules/layout_builder/src/Plugin/SectionStorage/DefaultsSectionStorage.php +index 355677a9406..4c5d6f103b8 100644 +--- a/core/modules/layout_builder/src/Plugin/SectionStorage/DefaultsSectionStorage.php ++++ b/core/modules/layout_builder/src/Plugin/SectionStorage/DefaultsSectionStorage.php +@@ -146,6 +146,10 @@ protected function getRouteParameters() { + * {@inheritdoc} + */ + public function buildRoutes(RouteCollection $collection) { ++ if (!\Drupal::moduleHandler()->moduleExists('field_ui')) { ++ return; ++ } ++ + foreach ($this->getEntityTypes() as $entity_type_id => $entity_type) { + // Try to get the route from the current collection. + if (!$entity_route = $collection->get($entity_type->get('field_ui_base_route'))) { +diff --git a/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTest.php b/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTest.php +index 5afb950064b..e36ef89d062 100644 +--- a/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTest.php ++++ b/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTest.php +@@ -109,7 +109,9 @@ public function testOverridesWithoutDefaultsAccess() { + $assert_session = $this->assertSession(); + $page = $this->getSession()->getPage(); + +- $this->drupalLogin($this->drupalCreateUser(['configure any layout'])); ++ // @todo In https://www.drupal.org/node/540008 switch this to logging in as ++ // a user with the 'configure any layout' permission. ++ $this->drupalLogin($this->rootUser); + + LayoutBuilderEntityViewDisplay::load('node.bundle_with_section_field.default') + ->enableLayoutBuilder() +-- +GitLab + + +From a2dc384989d12bf6ff24d6a52380638b123e4c30 Mon Sep 17 00:00:00 2001 +From: Tim Plunkett +Date: Fri, 17 Sep 2021 11:14:51 -0400 +Subject: [PATCH 7/7] Fix test coverage + +--- + .../src/Functional/LayoutBuilderTest.php | 22 +++++++++++++++++++ + .../src/Unit/DefaultsSectionStorageTest.php | 22 +++++++++++++++++++ + 2 files changed, 44 insertions(+) + +diff --git a/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTest.php b/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTest.php +index e36ef89d062..0581071ca17 100644 +--- a/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTest.php ++++ b/core/modules/layout_builder/tests/src/Functional/LayoutBuilderTest.php +@@ -109,6 +109,28 @@ public function testOverridesWithoutDefaultsAccess() { + $assert_session = $this->assertSession(); + $page = $this->getSession()->getPage(); + ++ $this->drupalLogin($this->drupalCreateUser(['configure any layout'])); ++ ++ LayoutBuilderEntityViewDisplay::load('node.bundle_with_section_field.default') ++ ->enableLayoutBuilder() ++ ->setOverridable() ++ ->save(); ++ ++ $this->drupalGet('node/1'); ++ $page->clickLink('Layout'); ++ $assert_session->elementTextContains('css', '.layout-builder__message.layout-builder__message--overrides', 'You are editing the layout for this Bundle with section field content item.'); ++ $assert_session->linkNotExists('Edit the template for all Bundle with section field content items instead.'); ++ } ++ ++ /** ++ * Tests Layout Builder overrides without Field UI installed. ++ */ ++ public function testOverridesWithoutFieldUi() { ++ $this->container->get('module_installer')->uninstall(['field_ui']); ++ ++ $assert_session = $this->assertSession(); ++ $page = $this->getSession()->getPage(); ++ + // @todo In https://www.drupal.org/node/540008 switch this to logging in as + // a user with the 'configure any layout' permission. + $this->drupalLogin($this->rootUser); +diff --git a/core/modules/layout_builder/tests/src/Unit/DefaultsSectionStorageTest.php b/core/modules/layout_builder/tests/src/Unit/DefaultsSectionStorageTest.php +index 11aff3d47f8..162935d5b17 100644 +--- a/core/modules/layout_builder/tests/src/Unit/DefaultsSectionStorageTest.php ++++ b/core/modules/layout_builder/tests/src/Unit/DefaultsSectionStorageTest.php +@@ -9,6 +9,7 @@ + use Drupal\Core\Entity\EntityTypeInterface; + use Drupal\Core\Entity\EntityTypeManagerInterface; + use Drupal\Core\Entity\FieldableEntityInterface; ++use Drupal\Core\Extension\ModuleHandlerInterface; + use Drupal\Core\Plugin\Context\ContextDefinition; + use Drupal\Core\Plugin\Context\ContextInterface; + use Drupal\Core\Plugin\Context\EntityContextDefinition; +@@ -220,6 +221,12 @@ public function testExtractEntityFromRouteCreate() { + * @covers \Drupal\layout_builder\Routing\LayoutBuilderRoutesTrait::buildLayoutRoutes + */ + public function testBuildRoutes() { ++ $module_handler = $this->prophesize(ModuleHandlerInterface::class); ++ $module_handler->moduleExists('field_ui')->willReturn(TRUE); ++ $container = new ContainerBuilder(); ++ $container->set('module_handler', $module_handler->reveal()); ++ \Drupal::setContainer($container); ++ + $entity_types = []; + + $not_fieldable = $this->prophesize(EntityTypeInterface::class); +@@ -405,4 +412,19 @@ public function testBuildRoutes() { + $this->assertSame(array_keys($expected), array_keys($collection->all())); + } + ++ /** ++ * @covers ::buildRoutes ++ */ ++ public function testBuildRoutesNoFieldUi() { ++ $module_handler = $this->prophesize(ModuleHandlerInterface::class); ++ $module_handler->moduleExists('field_ui')->willReturn(FALSE); ++ $container = new ContainerBuilder(); ++ $container->set('module_handler', $module_handler->reveal()); ++ \Drupal::setContainer($container); ++ ++ $collection = new RouteCollection(); ++ $this->plugin->buildRoutes($collection); ++ $this->assertEmpty($collection->all()); ++ } ++ + } +-- +GitLab + diff --git a/patches/core/password-reset-form-1521996-d9-1-11.patch b/patches/core/password-reset-form-1521996-d9-1-11.patch new file mode 100644 index 0000000..8de1201 --- /dev/null +++ b/patches/core/password-reset-form-1521996-d9-1-11.patch @@ -0,0 +1,338 @@ +diff --git a/core/modules/user/src/Form/UserPasswordForm.php b/core/modules/user/src/Form/UserPasswordForm.php +index 9796581..a8fc6db 100644 +--- a/core/modules/user/src/Form/UserPasswordForm.php ++++ b/core/modules/user/src/Form/UserPasswordForm.php +@@ -2,12 +2,15 @@ + + namespace Drupal\user\Form; + ++use Drupal\Component\Utility\EmailValidatorInterface; + use Drupal\Core\Config\ConfigFactory; ++use Drupal\Core\Field\BaseFieldDefinition; + use Drupal\Core\Flood\FloodInterface; + use Drupal\Core\Form\FormBase; + use Drupal\Core\Form\FormStateInterface; + use Drupal\Core\Language\LanguageManagerInterface; + use Drupal\Core\Render\Element\Email; ++use Drupal\Core\TypedData\TypedDataManagerInterface; + use Drupal\user\UserInterface; + use Drupal\user\UserStorageInterface; + use Symfony\Component\DependencyInjection\ContainerInterface; +@@ -43,6 +46,20 @@ class UserPasswordForm extends FormBase { + protected $flood; + + /** ++ * The typed data manager. ++ * ++ * @var \Drupal\Core\TypedData\TypedDataManagerInterface ++ */ ++ protected $typedDataManager; ++ ++ /** ++ * The email validator service. ++ * ++ * @var \Drupal\Component\Utility\EmailValidatorInterface ++ */ ++ protected $emailValidator; ++ ++ /** + * Constructs a UserPasswordForm object. + * + * @param \Drupal\user\UserStorageInterface $user_storage +@@ -53,12 +70,26 @@ class UserPasswordForm extends FormBase { + * The config factory. + * @param \Drupal\Core\Flood\FloodInterface $flood + * The flood service. ++ * @param \Drupal\Core\TypedData\TypedDataManagerInterface $typed_data_manager ++ * The typed data manager. ++ * @param \Drupal\Component\Utility\EmailValidatorInterface $email_validator ++ * The email validator service. + */ +- public function __construct(UserStorageInterface $user_storage, LanguageManagerInterface $language_manager, ConfigFactory $config_factory, FloodInterface $flood) { ++ public function __construct(UserStorageInterface $user_storage, LanguageManagerInterface $language_manager, ConfigFactory $config_factory, FloodInterface $flood, TypedDataManagerInterface $typed_data_manager = NULL, EmailValidatorInterface $email_validator = NULL) { + $this->userStorage = $user_storage; + $this->languageManager = $language_manager; + $this->configFactory = $config_factory; + $this->flood = $flood; ++ if (is_null($typed_data_manager)) { ++ @trigger_error('Calling ' . __METHOD__ . ' without the $typed_data_manager argument is deprecated in drupal:9.2.0 and will be required in drupal:10.0.0. See https://www.drupal.org/node/3189310', E_USER_DEPRECATED); ++ $typed_data_manager = \Drupal::typedDataManager(); ++ } ++ $this->typedDataManager = $typed_data_manager; ++ if (is_null($email_validator)) { ++ @trigger_error('Calling ' . __METHOD__ . ' without the $email_validator argument is deprecated in drupal:9.2.0 and will be required in drupal:10.0.0. See https://www.drupal.org/node/3189310', E_USER_DEPRECATED); ++ $email_validator = \Drupal::service('email.validator'); ++ } ++ $this->emailValidator = $email_validator; + } + + /** +@@ -69,7 +100,9 @@ public static function create(ContainerInterface $container) { + $container->get('entity_type.manager')->getStorage('user'), + $container->get('language_manager'), + $container->get('config.factory'), +- $container->get('flood') ++ $container->get('flood'), ++ $container->get('typed_data_manager'), ++ $container->get('email.validator') + ); + } + +@@ -133,7 +166,20 @@ public function validateForm(array &$form, FormStateInterface $form_state) { + return; + } + $this->flood->register('user.password_request_ip', $flood_config->get('ip_window')); ++ // First, see if the input is possibly valid as a username. + $name = trim($form_state->getValue('name')); ++ $definition = BaseFieldDefinition::create('string') ++ ->addConstraint('UserName', []); ++ $data = $this->typedDataManager->create($definition); ++ $data->setValue($name); ++ $violations = $data->validate(); ++ // Usernames have a maximum length shorter than email addresses. Only print ++ // this error if the input is not valid as a username or email address. ++ if ($violations->count() > 0 && !$this->emailValidator->isValid($name)) { ++ $form_state->setErrorByName('name', $this->t("The username or email address is invalid.")); ++ return; ++ } ++ + // Try to load by email. + $users = $this->userStorage->loadByProperties(['mail' => $name]); + if (empty($users)) { +@@ -141,26 +187,17 @@ public function validateForm(array &$form, FormStateInterface $form_state) { + $users = $this->userStorage->loadByProperties(['name' => $name]); + } + $account = reset($users); +- if ($account && $account->id()) { +- // Blocked accounts cannot request a new password. +- if (!$account->isActive()) { +- $form_state->setErrorByName('name', $this->t('%name is blocked or has not been activated yet.', ['%name' => $name])); +- } +- else { +- // Register flood events based on the uid only, so they apply for any +- // IP address. This allows them to be cleared on successful reset (from +- // any IP). +- $identifier = $account->id(); +- if (!$this->flood->isAllowed('user.password_request_user', $flood_config->get('user_limit'), $flood_config->get('user_window'), $identifier)) { +- $form_state->setErrorByName('name', $this->t('Too many password recovery requests for this account. It is temporarily blocked. Try again later or contact the site administrator.')); +- return; +- } +- $this->flood->register('user.password_request_user', $flood_config->get('user_window'), $identifier); +- $form_state->setValueForElement(['#parents' => ['account']], $account); ++ // Blocked accounts cannot request a new password. ++ if ($account && $account->id() && $account->isActive()) { ++ // Register flood events based on the uid only, so they apply for any ++ // IP address. This allows them to be cleared on successful reset (from ++ // any IP). ++ $identifier = $account->id(); ++ if (!$this->flood->isAllowed('user.password_request_user', $flood_config->get('user_limit'), $flood_config->get('user_window'), $identifier)) { ++ return; + } +- } +- else { +- $form_state->setErrorByName('name', $this->t('%name is not recognized as a username or an email address.', ['%name' => $name])); ++ $this->flood->register('user.password_request_user', $flood_config->get('user_window'), $identifier); ++ $form_state->setValueForElement(['#parents' => ['account']], $account); + } + } + +@@ -169,12 +206,29 @@ public function validateForm(array &$form, FormStateInterface $form_state) { + */ + public function submitForm(array &$form, FormStateInterface $form_state) { + $account = $form_state->getValue('account'); +- // Mail one time login URL and instructions using current language. +- $mail = _user_mail_notify('password_reset', $account); +- if (!empty($mail)) { +- $this->logger('user')->notice('Password reset instructions mailed to %name at %email.', ['%name' => $account->getAccountName(), '%email' => $account->getEmail()]); +- $this->messenger()->addStatus($this->t('Further instructions have been sent to your email address.')); ++ if ($account) { ++ // Mail one time login URL and instructions using current language. ++ $mail = _user_mail_notify('password_reset', $account); ++ if (!empty($mail)) { ++ $this->logger('user') ++ ->notice('Password reset instructions mailed to %name at %email.', [ ++ '%name' => $account->getAccountName(), ++ '%email' => $account->getEmail(), ++ ]); ++ } ++ } ++ else { ++ $this->logger('user') ++ ->notice('Password reset form was submitted with an unknown or inactive account: %name.', [ ++ '%name' => $form_state->getValue('name'), ++ ]); + } ++ // Make sure the status text is displayed even if no email was sent. This ++ // message is deliberately the same as the success message for privacy. ++ $this->messenger() ++ ->addStatus($this->t('If %identifier is a valid account, an email will be sent with instructions to reset your password.', [ ++ '%identifier' => $form_state->getValue('name'), ++ ])); + + $form_state->setRedirect(''); + } +diff --git a/core/modules/user/tests/src/Functional/UserPasswordResetTest.php b/core/modules/user/tests/src/Functional/UserPasswordResetTest.php +index 92e874b..c1be12d 100644 +--- a/core/modules/user/tests/src/Functional/UserPasswordResetTest.php ++++ b/core/modules/user/tests/src/Functional/UserPasswordResetTest.php +@@ -9,6 +9,7 @@ + use Drupal\language\Entity\ConfigurableLanguage; + use Drupal\Tests\BrowserTestBase; + use Drupal\user\Entity\User; ++use Drupal\user\UserInterface; + + /** + * Ensure that password reset methods work as expected. +@@ -87,11 +88,28 @@ public function testUserPasswordReset() { + $this->drupalGet(Url::fromRoute('user.reset.form', ['uid' => $this->account->id()])); + $this->assertSession()->statusCodeEquals(403); + ++ // Try to reset the password for a completely invalid username. ++ $this->drupalGet('user/password'); ++ $long_name = $this->randomMachineName(UserInterface::USERNAME_MAX_LENGTH + 10); ++ $edit = ['name' => $long_name]; ++ $this->submitForm($edit, 'Submit'); ++ $this->assertCount(0, $this->drupalGetMails(['id' => 'user_password_reset']), 'No e-mail was sent when requesting a password for an invalid user name.'); ++ $this->assertSession()->pageTextContains("The username or email address is invalid."); ++ + // Try to reset the password for an invalid account. + $this->drupalGet('user/password'); +- $edit = ['name' => $this->randomMachineName()]; ++ $random_name = $this->randomMachineName(); ++ $edit = ['name' => $random_name]; ++ $this->submitForm($edit, 'Submit'); ++ $this->assertNoValidPasswordReset($random_name); ++ // Try to reset the password for a valid email address longer than ++ // UserInterface::USERNAME_MAX_LENGTH (invalid username, valid email). ++ // This should pass validation and print the generic message. ++ $this->drupalGet('user/password'); ++ $long_name = $this->randomMachineName(UserInterface::USERNAME_MAX_LENGTH) . '@example.com'; ++ $edit = ['name' => $long_name]; + $this->submitForm($edit, 'Submit'); +- $this->assertNoValidPasswordReset($edit['name']); ++ $this->assertNoValidPasswordReset($long_name); + + // Reset the password by username via the password reset page. + $this->drupalGet('user/password'); +@@ -175,7 +193,6 @@ public function testUserPasswordReset() { + $before = count($this->drupalGetMails(['id' => 'user_password_reset'])); + $edit = ['name' => $blocked_account->getAccountName()]; + $this->submitForm($edit, 'Submit'); +- $this->assertRaw(t('%name is blocked or has not been activated yet.', ['%name' => $blocked_account->getAccountName()])); + $this->assertCount($before, $this->drupalGetMails(['id' => 'user_password_reset']), 'No email was sent when requesting password reset for a blocked account'); + + // Verify a password reset link is invalidated when the user's email address changes. +@@ -380,18 +397,22 @@ public function testUserResetPasswordUserFloodControl() { + + $edit = ['name' => $this->account->getAccountName()]; + ++ // Count email messages before to compare with after. ++ $before = count($this->drupalGetMails(['id' => 'user_password_reset'])); ++ + // Try 3 requests that should not trigger flood control. + for ($i = 0; $i < 3; $i++) { + $this->drupalGet('user/password'); + $this->submitForm($edit, 'Submit'); + $this->assertValidPasswordReset($edit['name']); +- $this->assertNoPasswordUserFlood(); + } + ++ // Ensure 3 emails were sent. ++ $this->assertCount($before + 3, $this->drupalGetMails(['id' => 'user_password_reset']), '3 emails sent without triggering flood control.'); ++ + // The next request should trigger flood control. + $this->drupalGet('user/password'); + $this->submitForm($edit, 'Submit'); +- $this->assertPasswordUserFlood(); + } + + /** +@@ -405,10 +426,11 @@ public function testUserResetPasswordIpFloodControl() { + // Try 3 requests that should not trigger flood control. + for ($i = 0; $i < 3; $i++) { + $this->drupalGet('user/password'); +- $edit = ['name' => $this->randomMachineName()]; ++ $random_name = $this->randomMachineName(); ++ $edit = ['name' => $random_name]; + $this->submitForm($edit, 'Submit'); + // Because we're testing with a random name, the password reset will not be valid. +- $this->assertNoValidPasswordReset($edit['name']); ++ $this->assertNoValidPasswordReset($random_name); + $this->assertNoPasswordIpFlood(); + } + +@@ -429,14 +451,19 @@ public function testUserResetPasswordUserFloodControlIsCleared() { + + $edit = ['name' => $this->account->getAccountName()]; + ++ // Count email messages before to compare with after. ++ $before = count($this->drupalGetMails(['id' => 'user_password_reset'])); ++ + // Try 3 requests that should not trigger flood control. + for ($i = 0; $i < 3; $i++) { + $this->drupalGet('user/password'); + $this->submitForm($edit, 'Submit'); + $this->assertValidPasswordReset($edit['name']); +- $this->assertNoPasswordUserFlood(); + } + ++ // Ensure 3 emails were sent. ++ $this->assertCount($before + 3, $this->drupalGetMails(['id' => 'user_password_reset']), '3 emails sent without triggering flood control.'); ++ + // Use the last password reset URL which was generated. + $reset_url = $this->getResetURL(); + $this->drupalGet($reset_url . '/login'); +@@ -449,15 +476,16 @@ public function testUserResetPasswordUserFloodControlIsCleared() { + $this->drupalGet('user/password'); + $this->submitForm($edit, 'Submit'); + $this->assertValidPasswordReset($edit['name']); +- $this->assertNoPasswordUserFlood(); ++ ++ // Ensure another email was sent. ++ $this->assertCount($before + 4, $this->drupalGetMails(['id' => 'user_password_reset']), 'Another email was sent after clearing flood control.'); + } + + /** + * Helper function to make assertions about a valid password reset. + */ + public function assertValidPasswordReset($name) { +- // Make sure the error text is not displayed and email sent. +- $this->assertNoText("Sorry, $name is not recognized as a username or an e-mail address."); ++ $this->assertSession()->pageTextContains("If $name is a valid account, an email will be sent with instructions to reset your password."); + $this->assertMail('to', $this->account->getEmail(), 'Password e-mail sent to user.'); + $subject = t('Replacement login information for @username at @site', ['@username' => $this->account->getAccountName(), '@site' => \Drupal::config('system.site')->get('name')]); + $this->assertMail('subject', $subject, 'Password reset e-mail subject is correct.'); +@@ -465,28 +493,17 @@ public function assertValidPasswordReset($name) { + + /** + * Helper function to make assertions about an invalid password reset. ++ * ++ * @param string $name + */ + public function assertNoValidPasswordReset($name) { +- // Make sure the error text is displayed and no email sent. +- $this->assertSession()->pageTextContains($name . ' is not recognized as a username or an email address.'); ++ // This message is the same as the valid reset for privacy reasons. ++ $this->assertSession()->pageTextContains("If $name is a valid account, an email will be sent with instructions to reset your password."); ++ // The difference is that no email is sent. + $this->assertCount(0, $this->drupalGetMails(['id' => 'user_password_reset']), 'No e-mail was sent when requesting a password for an invalid account.'); + } + + /** +- * Makes assertions about a password reset triggering user flood control. +- */ +- public function assertPasswordUserFlood() { +- $this->assertSession()->pageTextContains('Too many password recovery requests for this account. It is temporarily blocked. Try again later or contact the site administrator.'); +- } +- +- /** +- * Makes assertions about a password reset not triggering user flood control. +- */ +- public function assertNoPasswordUserFlood() { +- $this->assertNoText('Too many password recovery requests for this account. It is temporarily blocked. Try again later or contact the site administrator.'); +- } +- +- /** + * Makes assertions about a password reset triggering IP flood control. + */ + public function assertPasswordIpFlood() { diff --git a/patches/form_mode_manager/form-ui-disable-D9-compatible.patch b/patches/form_mode_manager/form-ui-disable-D9-compatible.patch new file mode 100644 index 0000000..81e91ed --- /dev/null +++ b/patches/form_mode_manager/form-ui-disable-D9-compatible.patch @@ -0,0 +1,26 @@ +diff --git a/src/FormModeManagerPermissions.php b/src/FormModeManagerPermissions.php +index 0a2ccdc..e67a99b 100644 +--- a/src/FormModeManagerPermissions.php ++++ b/src/FormModeManagerPermissions.php +@@ -115,12 +115,19 @@ class FormModeManagerPermissions implements ContainerInjectionInterface { + if ($form_mode_loaded instanceof EntityFormMode) { + $placeholders = array_merge($entity_placeholder, [ + '%form_mode_label' => $form_mode_loaded->label(), +- ':url' => $form_mode_loaded->toUrl()->toString(), + ]); + ++ if (\Drupal::service('module_handler')->moduleExists('field_ui')) { ++ $title = 'Use %form_mode_label form mode with %type_id entity'; ++ $placeholders[':url'] = $form_mode_loaded->toUrl()->toString(); ++ } ++ else { ++ $title = 'Use %form_mode_label form mode with %type_id entity'; ++ } ++ + $perms_per_mode += [ + "use {$form_mode_loaded->id()} form mode" => [ +- 'title' => $this->t('Use %form_mode_label form mode with %type_id entity', $placeholders), ++ 'title' => $this->t($title, $placeholders), + 'description' => [ + '#prefix' => '', + '#markup' => $this->t('This permission control access of %type_id entity with %form_mode_label form mode.', $placeholders), diff --git a/patches/multivalue_form_element/3200306-disable-multifield-ordering.patch b/patches/multivalue_form_element/3200306-disable-multifield-ordering.patch new file mode 100644 index 0000000..a8dc6f4 --- /dev/null +++ b/patches/multivalue_form_element/3200306-disable-multifield-ordering.patch @@ -0,0 +1,20 @@ +diff --git a/src/Element/MultiValue.php b/src/Element/MultiValue.php +index a21de24..10b59d0 100644 +--- a/src/Element/MultiValue.php ++++ b/src/Element/MultiValue.php +@@ -140,6 +140,7 @@ class MultiValue extends FormElement { + $class = get_class($this); + return [ + '#input' => TRUE, ++ '#orderable' => TRUE, + '#theme' => 'field_multiple_value_form', + '#cardinality_multiple' => TRUE, + '#description' => NULL, +@@ -174,6 +175,7 @@ class MultiValue extends FormElement { + $cardinality = $element['#cardinality']; + + $element['#tree'] = TRUE; ++ $element['#theme'] = $element['#orderable'] ? 'field_multiple_value_form' : 'field_multiple_value_without_order_form'; + $element['#field_name'] = $element_name; + + $element_state = static::getElementState($parents, $element_name, $form_state); diff --git a/patches/pdb/drupal9-ready.patch b/patches/pdb/drupal9-ready.patch new file mode 100644 index 0000000..4be8d24 --- /dev/null +++ b/patches/pdb/drupal9-ready.patch @@ -0,0 +1,22 @@ +diff --git a/src/Plugin/Derivative/PdbBlockDeriver.php b/src/Plugin/Derivative/PdbBlockDeriver.php +index 62e8bca..5c8dfd7 100644 +--- a/src/Plugin/Derivative/PdbBlockDeriver.php ++++ b/src/Plugin/Derivative/PdbBlockDeriver.php +@@ -3,7 +3,7 @@ + namespace Drupal\pdb\Plugin\Derivative; + + use Drupal\Component\Plugin\Derivative\DeriverBase; +-use Drupal\Core\Plugin\Context\ContextDefinition; ++use Drupal\Core\Plugin\Context\EntityContextDefinition; + use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface; + use Drupal\pdb\ComponentDiscoveryInterface; + use Symfony\Component\DependencyInjection\ContainerInterface; +@@ -72,7 +72,7 @@ class PdbBlockDeriver extends DeriverBase implements ContainerDeriverInterface { + $contexts_definitions = []; + if (isset($contexts['entity'])) { + // @todo Check entity type exists and fail! +- $contexts_definitions['entity'] = new ContextDefinition('entity:' . $contexts['entity']); ++ $contexts_definitions['entity'] = new EntityContextDefinition('entity:' . $contexts['entity']); + } + // @todo Dynamically handle unknown context definitions + return $contexts_definitions; diff --git a/patches/r4032login/drupal-9-fix.patch b/patches/r4032login/drupal-9-fix.patch new file mode 100644 index 0000000..46e5cb8 --- /dev/null +++ b/patches/r4032login/drupal-9-fix.patch @@ -0,0 +1,123 @@ +diff --git a/r4032login.services.yml b/r4032login.services.yml +index 3b2db73..7e2bc86 100644 +--- a/r4032login.services.yml ++++ b/r4032login.services.yml +@@ -1,6 +1,6 @@ + services: + r4032login.subscriber: + class: Drupal\r4032login\EventSubscriber\R4032LoginSubscriber +- arguments: ['@config.factory', '@current_user', '@path.matcher', '@event_dispatcher', '@messenger'] ++ arguments: ['@config.factory', '@current_user', '@request_stack', '@path.matcher', '@event_dispatcher', '@messenger'] + tags: + - { name: event_subscriber } +diff --git a/src/EventSubscriber/R4032LoginSubscriber.php b/src/EventSubscriber/R4032LoginSubscriber.php +index 99e69a3..f135f9c 100644 +--- a/src/EventSubscriber/R4032LoginSubscriber.php ++++ b/src/EventSubscriber/R4032LoginSubscriber.php +@@ -15,6 +15,7 @@ use Drupal\Core\Session\AccountInterface; + use Drupal\Core\Url; + use Drupal\r4032login\Event\RedirectEvent; + use Symfony\Component\EventDispatcher\EventDispatcherInterface; ++use Symfony\Component\HttpFoundation\RequestStack; + use Drupal\Component\Utility\Xss; + use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; + +@@ -37,6 +38,13 @@ class R4032LoginSubscriber extends HttpExceptionSubscriberBase { + */ + protected $currentUser; + ++ /** ++ * The request stack service. ++ * ++ * @var \Symfony\Component\HttpFoundation\RequestStack ++ */ ++ protected $requestStack; ++ + /** + * The path matcher. + * +@@ -65,6 +73,8 @@ class R4032LoginSubscriber extends HttpExceptionSubscriberBase { + * The configuration factory. + * @param \Drupal\Core\Session\AccountInterface $current_user + * The current user. ++ * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack ++ * The request stack service. + * @param \Drupal\Core\Path\PathMatcherInterface $path_matcher + * The path matcher. + * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher +@@ -72,9 +82,10 @@ class R4032LoginSubscriber extends HttpExceptionSubscriberBase { + * @param \Drupal\Core\Messenger\MessengerInterface $messenger + * The messenger service. + */ +- public function __construct(ConfigFactoryInterface $config_factory, AccountInterface $current_user, PathMatcherInterface $path_matcher, EventDispatcherInterface $event_dispatcher, MessengerInterface $messenger) { ++ public function __construct(ConfigFactoryInterface $config_factory, AccountInterface $current_user, RequestStack $request_stack, PathMatcherInterface $path_matcher, EventDispatcherInterface $event_dispatcher, MessengerInterface $messenger) { + $this->configFactory = $config_factory; + $this->currentUser = $current_user; ++ $this->requestStack = $request_stack; + $this->pathMatcher = $path_matcher; + $this->eventDispatcher = $event_dispatcher; + $this->messenger = $messenger; +diff --git a/tests/src/Unit/R4032LoginSubscriberTest.php b/tests/src/Unit/R4032LoginSubscriberTest.php +index 7e5bc66..6b1ff8e 100644 +--- a/tests/src/Unit/R4032LoginSubscriberTest.php ++++ b/tests/src/Unit/R4032LoginSubscriberTest.php +@@ -8,6 +8,7 @@ namespace Drupal\Tests\r4032login\Unit { + use Drupal\Tests\UnitTestCase; + use Symfony\Component\EventDispatcher\EventDispatcher; + use Symfony\Component\HttpFoundation\Request; ++ use Symfony\Component\HttpFoundation\RequestStack; + use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; + use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; + use Symfony\Component\HttpKernel\HttpKernelInterface; +@@ -40,6 +41,13 @@ namespace Drupal\Tests\r4032login\Unit { + */ + protected $currentUser; + ++ /** ++ * The mocked request stack service. ++ * ++ * @var \Symfony\Component\HttpFoundation\RequestStack|\PHPUnit_Framework_MockObject_MockObject ++ */ ++ protected $requestStack; ++ + /** + * The path matcher. + * +@@ -100,6 +108,10 @@ namespace Drupal\Tests\r4032login\Unit { + ]); + + $this->currentUser = $this->createMock('Drupal\Core\Session\AccountInterface'); ++ ++ $this->requestStack = new RequestStack(); ++ $this->requestStack->push(new Request()); ++ + $this->pathMatcher = $this->createMock('\Drupal\Core\Path\PathMatcherInterface'); + $this->eventDispatcher = $this->createMock('\Symfony\Component\EventDispatcher\EventDispatcherInterface'); + $this->messenger = $this->createMock('\Drupal\Core\Messenger\MessengerInterface'); +@@ -123,7 +135,7 @@ namespace Drupal\Tests\r4032login\Unit { + * @covers ::__construct + */ + public function testConstruct() { +- $r4032login = new R4032LoginSubscriber($this->configFactory, $this->currentUser, $this->pathMatcher, $this->eventDispatcher, $this->messenger); ++ $r4032login = new R4032LoginSubscriber($this->configFactory, $this->currentUser, $this->requestStack, $this->pathMatcher, $this->eventDispatcher, $this->messenger); + $this->assertInstanceOf('\Drupal\r4032login\EventSubscriber\R4032LoginSubscriber', $r4032login); + } + +@@ -158,7 +170,7 @@ namespace Drupal\Tests\r4032login\Unit { + ->method('isAnonymous') + ->willReturn(TRUE); + +- $r4032login = new R4032LoginSubscriber($config, $this->currentUser, $this->pathMatcher, $this->eventDispatcher, $this->messenger); ++ $r4032login = new R4032LoginSubscriber($config, $this->currentUser, $this->requestStack, $this->pathMatcher, $this->eventDispatcher, $this->messenger); + $event = new GetResponseForExceptionEvent($this->kernel, $request, HttpKernelInterface::MASTER_REQUEST, new AccessDeniedHttpException()); + $dispatcher = new EventDispatcher(); + $dispatcher->addListener(KernelEvents::EXCEPTION, [ +@@ -205,7 +217,7 @@ namespace Drupal\Tests\r4032login\Unit { + ->method('isAuthenticated') + ->willReturn(TRUE); + +- $r4032login = new R4032LoginSubscriber($config, $this->currentUser, $this->pathMatcher, $this->eventDispatcher, $this->messenger); ++ $r4032login = new R4032LoginSubscriber($config, $this->currentUser, $this->requestStack, $this->pathMatcher, $this->eventDispatcher, $this->messenger); + $event = new GetResponseForExceptionEvent($this->kernel, $request, HttpKernelInterface::MASTER_REQUEST, new AccessDeniedHttpException()); + $dispatcher = new EventDispatcher(); + $dispatcher->addListener(KernelEvents::EXCEPTION, [ diff --git a/patches/recommender/move-getScoreEntity-function-1.1.1.patch b/patches/recommender/move-getScoreEntity-function-1.1.1.patch new file mode 100644 index 0000000..54554fb --- /dev/null +++ b/patches/recommender/move-getScoreEntity-function-1.1.1.patch @@ -0,0 +1,109 @@ +diff --git a/src/Plugin/Recommendations/PadResultsRecommendationEnginePlugin.php b/src/Plugin/Recommendations/PadResultsRecommendationEnginePlugin.php +index a602f7c..0ff1677 100644 +--- a/src/Plugin/Recommendations/PadResultsRecommendationEnginePlugin.php ++++ b/src/Plugin/Recommendations/PadResultsRecommendationEnginePlugin.php +@@ -135,32 +135,6 @@ class PadResultsRecommendationEnginePlugin extends RecommendationEnginePluginBas + } + + /** +- * Get Previously Stored score entities. +- */ +- protected function getScoreEntity($user_id, $node_id) { +- $entity = $this->entityTypeManager +- ->getStorage('recommendation_plugin_score') +- ->loadByProperties( +- [ +- 'user_id' => $user_id, +- 'nid' => $node_id, +- 'plugin_id' => $this->getPluginId(), +- 'status' => RecommendationPluginScore::STATUS_PROCESSING, +- ] +- ); +- +- if (!empty($entity)) { +- $entity = reset($entity); +- $entity->setStatus(RecommendationPluginScore::STATUS_READY); +- $entity->save(); +- return $entity; +- } +- else { +- return FALSE; +- } +- } +- +- /** + * Calculate Score. + * + * Since this is the random recommendation engine it simply +diff --git a/src/Plugin/Recommendations/TrendingContentRecommendationEnginePlugin.php b/src/Plugin/Recommendations/TrendingContentRecommendationEnginePlugin.php +index c098359..52dbedd 100644 +--- a/src/Plugin/Recommendations/TrendingContentRecommendationEnginePlugin.php ++++ b/src/Plugin/Recommendations/TrendingContentRecommendationEnginePlugin.php +@@ -152,30 +152,6 @@ class TrendingContentRecommendationEnginePlugin extends RecommendationEnginePlug + return 1 / $position; + } + +- /** +- * Get Previously Stored score entities. +- */ +- protected function getScoreEntity($user_id, $node_id) { +- $entity = $this->entityTypeManager +- ->getStorage('recommendation_plugin_score') +- ->loadByProperties( +- [ +- 'user_id' => $user_id, +- 'nid' => $node_id, +- 'plugin_id' => $this->getPluginId(), +- 'status' => RecommendationPluginScore::STATUS_PROCESSING, +- ] +- ); + +- if (!empty($entity)) { +- $entity = reset($entity); +- $entity->setStatus(RecommendationPluginScore::STATUS_READY); +- $entity->save(); +- return $entity; +- } +- else { +- return FALSE; +- } +- } + + } +diff --git a/src/RecommendationEnginePluginBase.php b/src/RecommendationEnginePluginBase.php +index b908e0f..578d0d7 100644 +--- a/src/RecommendationEnginePluginBase.php ++++ b/src/RecommendationEnginePluginBase.php +@@ -349,4 +349,32 @@ abstract class RecommendationEnginePluginBase extends PluginBase implements Reco + return $entity; + } + ++ ++ /** ++ * Get Previously Stored score entities. ++ */ ++ protected function getScoreEntity($user_id, $node_id) { ++ $entity = $this->entityTypeManager ++ ->getStorage('recommendation_plugin_score') ++ ->loadByProperties( ++ [ ++ 'user_id' => $user_id, ++ 'nid' => $node_id, ++ 'plugin_id' => $this->getPluginId(), ++ 'status' => RecommendationPluginScore::STATUS_PROCESSING, ++ ] ++ ); ++ ++ if (!empty($entity)) { ++ $entity = reset($entity); ++ $entity->setStatus(RecommendationPluginScore::STATUS_READY); ++ $entity->save(); ++ return $entity; ++ } ++ else { ++ return FALSE; ++ } ++ } ++ ++ + } diff --git a/patches/responsive_favicons/drupal-9-remove-deprecated.patch b/patches/responsive_favicons/drupal-9-remove-deprecated.patch new file mode 100644 index 0000000..9ae43ec --- /dev/null +++ b/patches/responsive_favicons/drupal-9-remove-deprecated.patch @@ -0,0 +1,288 @@ +diff --git a/responsive_favicons.install b/responsive_favicons.install +index 6b970c9..14ff05f 100644 +--- a/responsive_favicons.install ++++ b/responsive_favicons.install +@@ -54,7 +54,7 @@ function responsive_favicons_uninstall() { + // Remove favicon files + $config = \Drupal::config('responsive_favicons.settings'); + if (!empty($config->get('path'))) { +- file_unmanaged_delete_recursive('public://' . $config->get('path')); ++ \Drupal::service('file_system')->deleteRecursive('public://' . $config->get('path')); + } + } + +diff --git a/src/Form/ResponsiveFaviconsAdmin.php b/src/Form/ResponsiveFaviconsAdmin.php +index d1c3e76..2e5d5bd 100644 +--- a/src/Form/ResponsiveFaviconsAdmin.php ++++ b/src/Form/ResponsiveFaviconsAdmin.php +@@ -2,9 +2,15 @@ + + namespace Drupal\responsive_favicons\Form; + ++use Drupal\Core\File\Exception\FileException; ++use Drupal\Core\File\Exception\FileWriteException; + use Drupal\Core\Form\ConfigFormBase; + use Drupal\Core\Form\FormStateInterface; ++use Drupal\Core\Messenger\MessengerTrait; + use Drupal\Core\Site\Settings; ++use Drupal\Core\File\FileSystemInterface; ++use Drupal\Core\StringTranslation\StringTranslationTrait; ++use Symfony\Component\DependencyInjection\ContainerInterface; + + /** + * Class ResponsiveFaviconsAdmin. +@@ -13,6 +19,25 @@ use Drupal\Core\Site\Settings; + */ + class ResponsiveFaviconsAdmin extends ConfigFormBase { + ++ use MessengerTrait; ++ use StringTranslationTrait; ++ ++ /** ++ * The file system service. ++ * ++ * @var \Drupal\Core\File\FileSystemInterface ++ */ ++ protected $fileSystem; ++ ++ /** ++ * {@inheritdoc} ++ */ ++ public static function create(ContainerInterface $container) { ++ $instance = parent::create($container); ++ $instance->fileSystem = $container->get('file_system'); ++ return $instance; ++ } ++ + /** + * {@inheritdoc} + */ +@@ -64,13 +89,6 @@ class ResponsiveFaviconsAdmin extends ConfigFormBase { + } + + /** +- * {@inheritdoc} +- */ +- public function validateForm(array &$form, FormStateInterface $form_state) { +- parent::validateForm($form, $form_state); +- } +- +- /** + * {@inheritdoc} + */ + public function submitForm(array &$form, FormStateInterface $form_state) { +@@ -85,7 +103,7 @@ class ResponsiveFaviconsAdmin extends ConfigFormBase { + // Remove trailing slash on responsive_favicons_path. + $config->set('path', rtrim($form_state->getValue('path'))); + +- // Checkbox ++ // Checkbox. + $config->set('remove_default', $form_state->getValue('remove_default')); + + // Attempt the upload and extraction of the zip file. This code is largely +@@ -94,11 +112,10 @@ class ResponsiveFaviconsAdmin extends ConfigFormBase { + // @see UpdateManagerInstall->submitForm(). + $local_cache = NULL; + if (!empty($_FILES['files']['name']['upload'])) { +- $validators = array('file_validate_extensions' => array(archiver_get_extensions())); +- $field = 'upload'; +- if (!($finfo = file_save_upload('upload', $validators, NULL, 0, FILE_EXISTS_REPLACE))) { ++ $validators = ['file_validate_extensions' => ['zip']]; ++ if (!($finfo = file_save_upload('upload', $validators, NULL, 0, FileSystemInterface::EXISTS_REPLACE))) { + // Failed to upload the file. file_save_upload() calls +- // drupal_set_message() on failure. ++ // \Drupal\Core\Messenger\MessengerInterface::addError() on failure. + return; + } + $local_cache = $finfo->getFileUri(); +@@ -111,56 +128,71 @@ class ResponsiveFaviconsAdmin extends ConfigFormBase { + $archive = $this->archiveExtract($local_cache, $directory); + } + catch (\Exception $e) { +- \Drupal::messenger()->addStatus($e->getMessage(), 'error'); ++ $this->messenger()->addStatus($e->getMessage(), 'error'); + return; + } + + $files = $archive->listContents(); + if (!$files) { +- $form_state->setError($field, t('Provided archive contains no files.')); ++ $form_state->setError($field, $this->t('Provided archive contains no files.')); + return; + } + + $destination = 'public://' . $config->get('path'); +- file_prepare_directory($destination, FILE_CREATE_DIRECTORY); ++ $this->fileSystem->prepareDirectory($destination, FileSystemInterface::CREATE_DIRECTORY); + + // Copy the files to the correct location. + $success_count = 0; + foreach ($files as $file) { +- $success = file_unmanaged_copy($directory . '/' . $file, $destination, FILE_EXISTS_REPLACE); ++ // Handle exceptions when copy does not happen correctly. ++ try { ++ $success = $this->fileSystem->copy($directory . '/' . $file, $destination, FileSystemInterface::EXISTS_REPLACE); ++ } ++ catch (FileException $e) { ++ $success = FALSE; ++ } + $uri = $destination . '/' . $file; + if ($success) { + $success_count++; +- +- // Rewrite the paths of the JSON files. +- if (preg_match('/\.json$/', $file)) { +- $file_contents = file_get_contents(\Drupal::service('file_system')->realpath($uri)); +- $find = preg_quote('"\/android-chrome', '/'); +- $replace = '"' . str_replace('/', '\/', _responsive_favicons_normalise_path('/android-chrome')); +- $file_contents = preg_replace('/' . $find . '/', $replace, $file_contents); +- file_unmanaged_save_data($file_contents, $uri, FILE_EXISTS_REPLACE); ++ // Handle exceptions when file contents are not saved correctly into ++ // destination. ++ try { ++ // Rewrite the paths of the JSON files. ++ if (preg_match('/\.json$/', $file)) { ++ $file_contents = file_get_contents($this->fileSystem->realpath($uri)); ++ $find = preg_quote('"\/android-chrome', '/'); ++ $replace = '"' . str_replace('/', '\/', _responsive_favicons_normalise_path('/android-chrome')); ++ $file_contents = preg_replace('/' . $find . '/', $replace, $file_contents); ++ $this->fileSystem->saveData($file_contents, $uri, FileSystemInterface::EXISTS_REPLACE); ++ } ++ // Rewrite the paths of the XML files. ++ elseif (preg_match('/\.xml$/', $file)) { ++ $file_contents = file_get_contents($this->fileSystem->realpath($uri)); ++ $find = preg_quote('"/mstile', '/'); ++ $replace = '"' . _responsive_favicons_normalise_path('/mstile'); ++ $file_contents = preg_replace('/' . $find . '/', $replace, $file_contents); ++ $this->fileSystem->saveData($file_contents, $uri, FileSystemInterface::EXISTS_REPLACE); ++ } ++ // Rewrite the paths of the WEBMANIFEST files. ++ elseif (preg_match('/\.webmanifest$/', $file)) { ++ $file_contents = file_get_contents($this->fileSystem->realpath($uri)); ++ $find = preg_quote('"/android-chrome', '/'); ++ $replace = '"' . _responsive_favicons_normalise_path('/android-chrome'); ++ $file_contents = preg_replace('/' . $find . '/', $replace, $file_contents); ++ $this->fileSystem->saveData($file_contents, $uri, FileSystemInterface::EXISTS_REPLACE); ++ } + } +- // Rewrite the paths of the XML files. +- else if (preg_match('/\.xml$/', $file)) { +- $file_contents = file_get_contents(\Drupal::service('file_system')->realpath($uri)); +- $find = preg_quote('"/mstile', '/'); +- $replace = '"' . _responsive_favicons_normalise_path('/mstile'); +- $file_contents = preg_replace('/' . $find . '/', $replace, $file_contents); +- file_unmanaged_save_data($file_contents, $uri, FILE_EXISTS_REPLACE); ++ catch (FileWriteException $e) { ++ $this->messenger()->addError($this->t('The file could not be created.')); + } +- // Rewrite the paths of the WEBMANIFEST files. +- else if (preg_match('/\.webmanifest$/', $file)) { +- $file_contents = file_get_contents(\Drupal::service('file_system')->realpath($uri)); +- $find = preg_quote('"/android-chrome', '/'); +- $replace = '"' . _responsive_favicons_normalise_path('/android-chrome'); +- $file_contents = preg_replace('/' . $find . '/', $replace, $file_contents); +- file_unmanaged_save_data($file_contents, $uri, FILE_EXISTS_REPLACE); ++ catch (FileException $e) { ++ $this->messenger()->addError($e->getMessage()); + } + } + } + + if ($success_count > 0) { +- \Drupal::messenger()->addStatus(\Drupal::translation()->formatPlural($success_count, 'Uploaded 1 favicon file successfully.', 'Uploaded @count favicon files successfully.')); ++ $this->messenger()->addStatus($this->formatPlural($success_count, 'Uploaded 1 favicon file successfully.', 'Uploaded @count favicon files successfully.')); + } + } + +@@ -173,7 +205,7 @@ class ResponsiveFaviconsAdmin extends ConfigFormBase { + /** + * Returns a short unique identifier for this Drupal installation. + * +- * @return ++ * @return string + * An eight character string uniquely identifying this Drupal installation. + */ + private function uniqueIdentifier() { +@@ -185,14 +217,13 @@ class ResponsiveFaviconsAdmin extends ConfigFormBase { + } + + /** +- * Returns the directory where responsive favicons archive files should be +- * extracted. ++ * Gets the directory where responsive favicons zip files should be extracted. + * +- * @param $create ++ * @param bool $create + * (optional) Whether to attempt to create the directory if it does not + * already exist. Defaults to TRUE. + * +- * @return ++ * @return string + * The full path to the temporary directory where responsive favicons fil + * archives should be extracted. + */ +@@ -215,22 +246,23 @@ class ResponsiveFaviconsAdmin extends ConfigFormBase { + * @param string $directory + * The directory you wish to extract the archive into. + * +- * @return Archiver ++ * @return \Drupal\Core\Archiver\ArchiverInterface + * The Archiver object used to extract the archive. + * + * @throws \Exception + */ + private function archiveExtract($file, $directory) { +- $archiver = archiver_get_archiver($file); ++ $archiver = \Drupal::service('plugin.manager.archiver')->getInstance(['filepath' => $file]); + if (!$archiver) { +- throw new \Exception(t('Cannot extract %file, not a valid archive.', array('%file' => $file))); ++ throw new \Exception($this->t('Cannot extract %file, not a valid archive.', ['%file' => $file])); + } + + if (file_exists($directory)) { +- file_unmanaged_delete_recursive($directory); ++ $this->fileSystem->deleteRecursive($directory); + } + + $archiver->extract($directory); + return $archiver; + } ++ + } +diff --git a/src/Routing/DefaultFavicons.php b/src/Routing/DefaultFavicons.php +index f77a459..5c848e9 100644 +--- a/src/Routing/DefaultFavicons.php ++++ b/src/Routing/DefaultFavicons.php +@@ -29,11 +29,11 @@ class DefaultFavicons { + // List of icons to redirect. + // Note, in order for these to work alter the fast404 pattern to allow these + // requests to hit Drupal. Please see the README for more information. +- $icons = array( ++ $icons = [ + '/apple-touch-icon.png', + '/apple-touch-icon-precomposed.png', + '/browserconfig.xml', +- ); ++ ]; + // Try to avoid clashing with the favicon module. + if (!$moduleHandler->moduleExists('favicon')) { + $icons[] = '/favicon.ico'; +@@ -43,14 +43,14 @@ class DefaultFavicons { + // Path to attach this route to: + $icon, + // Route defaults: +- array( ++ [ + '_controller' => '\Drupal\responsive_favicons\Controller\GetFile::deliver', + '_title' => '' +- ), ++ ], + // Route requirements: +- array( ++ [ + '_access' => 'TRUE', +- ) ++ ] + ); + // Add the route under a unique key. + $key = preg_replace("/[^A-Za-z]/", '', $icon); diff --git a/patches/statistics_counter/d9-compatibility.patch b/patches/statistics_counter/d9-compatibility.patch new file mode 100644 index 0000000..fd1c9b2 --- /dev/null +++ b/patches/statistics_counter/d9-compatibility.patch @@ -0,0 +1,33 @@ +diff --git a/statistics_counter.info.yml b/statistics_counter.info.yml +index ebe2843..591416b 100644 +--- a/statistics_counter.info.yml ++++ b/statistics_counter.info.yml +@@ -6,6 +6,7 @@ package: 'Statistics' + # core: 8.x + dependencies: + - statistics ++core_version_requirement: ^8 || ^9 + + # Information added by Drupal.org packaging script on 2015-10-18 + version: '8.x-1.0-beta2' +diff --git a/statistics_counter.install b/statistics_counter.install +index ed8facd..93390e1 100644 +--- a/statistics_counter.install ++++ b/statistics_counter.install +@@ -51,7 +51,7 @@ function statistics_counter_install() { + } catch (\Exception $e) { + $transaction->rollback(); + watchdog_exception('php', $e); +- drupal_set_message(t('Cannot create new fields'), 'error'); ++ \Drupal::messenger()->addError(t('Cannot create new fields')); + } + } + +@@ -73,6 +73,6 @@ function statistics_counter_uninstall() { + } catch (\Exception $e) { + $transaction->rollback(); + watchdog_exception('php', $e); +- drupal_set_message(t('Cannot drop fields'), 'error'); ++ \Drupal::messenger()->addError(t('Cannot drop fields')); + } + } diff --git a/patches/statistics_counter/php_error_in_updateStatistics-2905572-5.patch b/patches/statistics_counter/php_error_in_updateStatistics-2905572-5.patch new file mode 100644 index 0000000..17fdf51 --- /dev/null +++ b/patches/statistics_counter/php_error_in_updateStatistics-2905572-5.patch @@ -0,0 +1,21 @@ +diff --git a/src/EventSubscriber/StatisticsCounterSubscriber.php b/src/EventSubscriber/StatisticsCounterSubscriber.php +index 9b1c8b4..4fa86d4 100644 +--- a/src/EventSubscriber/StatisticsCounterSubscriber.php ++++ b/src/EventSubscriber/StatisticsCounterSubscriber.php +@@ -7,6 +7,7 @@ use Symfony\Component\EventDispatcher\Event; + use Symfony\Component\EventDispatcher\EventSubscriberInterface; + use Symfony\Component\HttpKernel\KernelEvents; + use Drupal\Core\Database\Database; ++use Drupal\node\NodeInterface; + + /** + * Subscribe to KernelEvents::TERMINATE events to recalculate nodes statistics. +@@ -30,7 +31,7 @@ class StatisticsCounterSubscriber implements EventSubscriberInterface { + $node = \Drupal::request()->attributes->get('node'); + $views = \Drupal::config('statistics.settings')->get('count_content_views'); + +- if ($node && ($event->getResponse() instanceof HtmlResponse) && $views) { ++ if (($node instanceof NodeInterface) && ($event->getResponse() instanceof HtmlResponse) && $views) { + // Support statistics filter. + if (\Drupal::moduleHandler()->moduleExists('statistics_filter') && statistics_filter_do_filter()) { + return; diff --git a/patches/switches/0001-Fixes-Deprecation.patch b/patches/switches/0001-Fixes-Deprecation.patch new file mode 100644 index 0000000..873725e --- /dev/null +++ b/patches/switches/0001-Fixes-Deprecation.patch @@ -0,0 +1,26 @@ +diff --git a/src/TwigExtension/SwitchExtension.php b/src/TwigExtension/SwitchExtension.php +index 12452f1..9e15d01 100644 +--- a/src/TwigExtension/SwitchExtension.php ++++ b/src/TwigExtension/SwitchExtension.php +@@ -46,7 +46,7 @@ class SwitchExtension extends \Twig_Extension { + */ + public function getFunctions() { + return [ +- 'switch_is_active' => new \Twig_Function_Function([$this, 'isSwitchActive']), ++ 'switch_is_active' => new \Twig\TwigFunction('switch_is_active', [$this, 'isSwitchActive']), + ]; + } + +diff --git a/switches.services.yml b/switches.services.yml +index 46bc5fa..dcb68a0 100644 +--- a/switches.services.yml ++++ b/switches.services.yml +@@ -2,7 +2,7 @@ services: + switches.manager: + class: Drupal\switches\SwitchManager + arguments: +- - '@entity.manager' ++ - '@entity_type.manager' + - '@logger.channel.switches' + logger.channel.switches: + parent: logger.channel_base diff --git a/patches/switches/0002-Fix-Issue-When-Saving-Switch.patch b/patches/switches/0002-Fix-Issue-When-Saving-Switch.patch new file mode 100644 index 0000000..5e42527 --- /dev/null +++ b/patches/switches/0002-Fix-Issue-When-Saving-Switch.patch @@ -0,0 +1,16 @@ +diff --git a/src/Form/SwitchForm.php b/src/Form/SwitchForm.php +index e31e6d5..3b0438a 100644 +--- a/src/Form/SwitchForm.php ++++ b/src/Form/SwitchForm.php +@@ -159,6 +159,11 @@ class SwitchForm extends EntityForm { + * The current state of the form. + */ + protected function submitActivationConditions(array $form, FormStateInterface $form_state) { ++ if ($this->entity->getActivationMethod() === 'manual') { ++ $this->entity->setManualActivationStatus($form['manualActivationStatus']['#value']); ++ return; ++ } ++ + // Extract the enabled conditions tab from the front of the list. + $enabled_conditions = $form_state->getValue([ + 'activation_conditions', diff --git a/patches/switches/0003-Fixes-Conditional-Logic.patch b/patches/switches/0003-Fixes-Conditional-Logic.patch new file mode 100644 index 0000000..dbfd5fe --- /dev/null +++ b/patches/switches/0003-Fixes-Conditional-Logic.patch @@ -0,0 +1,239 @@ +diff --git a/src/Entity/SwitchEntity.php b/src/Entity/SwitchEntity.php +index b8775d7..29127ee 100644 +--- a/src/Entity/SwitchEntity.php ++++ b/src/Entity/SwitchEntity.php +@@ -6,6 +6,9 @@ use Drupal\Core\Condition\ConditionPluginCollection; + use Drupal\Core\Config\ConfigValueException; + use Drupal\Core\Config\Entity\ConfigEntityBase; + use Drupal\Core\Entity\EntityWithPluginCollectionInterface; ++use Drupal\Core\Plugin\ContextAwarePluginInterface; ++use Drupal\Core\Plugin\Context\ContextHandlerInterface; ++use Drupal\Core\Plugin\Context\ContextRepositoryInterface; + + /** + * Defines the Switch entity. +@@ -117,6 +120,30 @@ class SwitchEntity extends ConfigEntityBase implements SwitchInterface, EntityWi + */ + protected $conditionPluginManager; + ++ /** ++ * The context repository service. ++ * ++ * @var \Drupal\Core\Plugin\Context\ContextRepositoryInterface ++ */ ++ protected $contextRepository; ++ ++ /** ++ * The context repository service. ++ * ++ * @var \Drupal\Core\Plugin\Context\ContextHandlerInterface; ++ */ ++ protected $contextHandler; ++ ++ /** ++ * {@inheritdoc} ++ */ ++ public function __construct(array $values, $entity_type) { ++ parent::__construct($values, $entity_type); ++ $this->conditionPluginManager = \Drupal::service('plugin.manager.condition'); ++ $this->contextRepository = \Drupal::service('context.repository'); ++ $this->contextHandler = \Drupal::service('context.handler'); ++ } ++ + /** + * {@inheritdoc} + */ +@@ -157,12 +184,17 @@ class SwitchEntity extends ConfigEntityBase implements SwitchInterface, EntityWi + * @todo Allow configuration of and/or logic. + */ + public function getConditionActivationStatus() { +- // Evaluate all configured activation conditions. +- foreach ($this->getActivationConditions() as $condition_plugin) { +- $condition_value = $condition_plugin->evaluate(); +- +- // Since we're using AND logic we can stop when we encounter any condition +- // evaluating as FALSE. ++ foreach ($this->getActivationConditions() as $condition_id => $condition) { ++ if ($condition instanceof ContextAwarePluginInterface) { ++ try { ++ $contexts = $this->contextRepository->getRuntimeContexts(array_values($condition->getContextMapping())); ++ $this->contextHandler->applyContextMapping($condition, $contexts); ++ } ++ catch (\Exception $e) { ++ continue; ++ } ++ } ++ $condition_value = $condition->evaluate(); + if (!$condition_value) { + return FALSE; + } +@@ -207,7 +239,7 @@ class SwitchEntity extends ConfigEntityBase implements SwitchInterface, EntityWi + public function getActivationConditions() { + if (!isset($this->activationConditionsCollection)) { + $this->activationConditionsCollection = new ConditionPluginCollection($this +- ->conditionPluginManager(), $this->get('activationConditions')); ++ ->conditionPluginManager, $this->get('activationConditions')); + } + + return $this->activationConditionsCollection; +@@ -249,19 +281,4 @@ class SwitchEntity extends ConfigEntityBase implements SwitchInterface, EntityWi + } + } + +- /** +- * Gets the condition plugin manager. +- * +- * @return \Drupal\Core\Executable\ExecutableManagerInterface +- * The condition plugin manager. +- * +- * @todo Figure out how to load this through DI. +- */ +- protected function conditionPluginManager() { +- if (!isset($this->conditionPluginManager)) { +- $this->conditionPluginManager = \Drupal::service('plugin.manager.condition'); +- } +- return $this->conditionPluginManager; +- } +- + } +diff --git a/src/Form/SwitchForm.php b/src/Form/SwitchForm.php +index fe221bd..168cfc1 100644 +--- a/src/Form/SwitchForm.php ++++ b/src/Form/SwitchForm.php +@@ -9,45 +9,55 @@ use Drupal\Core\Form\SubformState; + use Drupal\Core\Plugin\Context\ContextRepositoryInterface; + use Drupal\Core\Plugin\ContextAwarePluginInterface; + use Symfony\Component\DependencyInjection\ContainerInterface; ++use Drupal\Core\Language\LanguageManagerInterface; ++use Drupal\Core\Executable\ExecutableManagerInterface; + + /** + * Class SwitchForm. + */ + class SwitchForm extends EntityForm { + +- /** +- * The entity being used by this form. ++ /** ++ * The switch entity. + * +- * @var \Drupal\switches\Entity\SwitchEntity ++ * @var \Drupal\switch\SwitchInterface + */ + protected $entity; + + /** +- * The Condition plugin manager service. ++ * The condition plugin manager. + * + * @var \Drupal\Core\Condition\ConditionManager + */ + protected $conditionManager; + + /** +- * The Context Repository service. ++ * The context repository service. + * + * @var \Drupal\Core\Plugin\Context\ContextRepositoryInterface + */ + protected $contextRepository; + + /** +- * SwitchForm constructor. ++ * The language manager service. + * +- * @param \Drupal\Core\Condition\ConditionManager $condition_manager +- * The Condition plugin manager service. ++ * @var \Drupal\Core\Language\LanguageManagerInterface ++ */ ++ protected $language; ++ ++ /** ++ * Constructs a SwitchForm object. ++ * @param \Drupal\Core\Executable\ExecutableManagerInterface $manager ++ * The ConditionManager for building the visibility UI. + * @param \Drupal\Core\Plugin\Context\ContextRepositoryInterface $context_repository +- * The Context Repository service. ++ * The lazy context repository service. ++ * @param \Drupal\Core\Language\LanguageManagerInterface $language ++ * The language manager. + */ +- public function __construct(ConditionManager $condition_manager, +- ContextRepositoryInterface $context_repository) { +- $this->conditionManager = $condition_manager; ++ public function __construct(ExecutableManagerInterface $manager, ContextRepositoryInterface $context_repository, LanguageManagerInterface $language) { ++ $this->conditionManager = $manager; + $this->contextRepository = $context_repository; ++ $this->language = $language; + } + + /** +@@ -56,7 +66,8 @@ class SwitchForm extends EntityForm { + public static function create(ContainerInterface $container) { + return new static( + $container->get('plugin.manager.condition'), +- $container->get('context.repository') ++ $container->get('context.repository'), ++ $container->get('language_manager') + ); + } + +@@ -266,6 +277,14 @@ class SwitchForm extends EntityForm { + + // Build and embed the plugin form for each condition plugin. + foreach ($available_conditions as $condition_id => $definition) { ++ // Don't display the current theme condition. ++ if ($condition_id == 'current_theme') { ++ continue; ++ } ++ // Don't display the language condition until we have multiple languages. ++ if ($condition_id == 'language' && !$this->language->isMultilingual()) { ++ continue; ++ } + /** @var \Drupal\Core\Condition\ConditionInterface $condition */ + $instance_config = isset($condition_config[$condition_id]) ? $condition_config[$condition_id] : []; + $condition = $this->conditionManager->createInstance($condition_id, $instance_config); +@@ -274,8 +293,7 @@ class SwitchForm extends EntityForm { + // Build the form section for this condition. + $condition_form = $condition->buildConfigurationForm([], $form_state); + $condition_form['#type'] = 'details'; +- $condition_form['#title'] = $condition +- ->getPluginDefinition()['label']; ++ $condition_form['#title'] = $condition->getPluginDefinition()['label']; + $condition_form['#group'] = 'activation_condition_tabs'; + $form[$condition_id] = $condition_form; + +@@ -288,6 +306,30 @@ class SwitchForm extends EntityForm { + ]; + } + ++ if (isset($form['node_type'])) { ++ $form['node_type']['negate']['#type'] = 'value'; ++ $form['node_type']['negate']['#title_display'] = 'invisible'; ++ $form['node_type']['negate']['#value'] = $form['node_type']['negate']['#default_value']; ++ } ++ if (isset($form['user_role'])) { ++ unset($form['user_role']['roles']['#description']); ++ $form['user_role']['negate']['#type'] = 'value'; ++ $form['user_role']['negate']['#value'] = $form['user_role']['negate']['#default_value']; ++ } ++ if (isset($form['request_path'])) { ++ $form['request_path']['negate']['#type'] = 'radios'; ++ $form['request_path']['negate']['#default_value'] = (int) $form['request_path']['negate']['#default_value']; ++ $form['request_path']['negate']['#title_display'] = 'invisible'; ++ $form['request_path']['negate']['#options'] = [ ++ $this->t('Show for the listed pages'), ++ $this->t('Hide for the listed pages'), ++ ]; ++ } ++ if (isset($form['language'])) { ++ $form['language']['negate']['#type'] = 'value'; ++ $form['language']['negate']['#value'] = $form['language']['negate']['#default_value']; ++ } ++ + return $form; + } + +-- +2.26.2 + diff --git a/patches/time_field/d9_time_field.patch b/patches/time_field/d9_time_field.patch new file mode 100644 index 0000000..f66d182 --- /dev/null +++ b/patches/time_field/d9_time_field.patch @@ -0,0 +1,13 @@ +diff --git a/time_field.info.yml b/time_field.info.yml +index 130c992..3938cd0 100644 +--- a/time_field.info.yml ++++ b/time_field.info.yml +@@ -1,7 +1,7 @@ + name: 'Time Field' + type: module + description: 'Provides "Time Field" and "Time Range Field".' +-core: 8.x ++core_version_requirement: ^8 || ^9 + package: 'Field types' + dependencies: + - drupal:datetime diff --git a/phpunit.local.xml b/phpunit.local.xml new file mode 100644 index 0000000..331403e --- /dev/null +++ b/phpunit.local.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + ./web/core/tests/TestSuites/UnitTestSuite.php + + + ./web/core/TestSuites/KernelTestSuite.php + + + ./web/core/TestSuites/FunctionalTestSuite.php + + + ./web/core/TestSuites/FunctionalJavascriptTestSuite.php + + + + + + + + + + + + + ./web/core/includes + ./web/core/lib + ./web/core/modules + ./web/modules + ./web/sites + + */tests/* + + + diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..624e798 --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + ./web/core/tests/TestSuites/UnitTestSuite.php + + + ./web/core/TestSuites/KernelTestSuite.php + + + ./web/core/TestSuites/FunctionalTestSuite.php + + + ./web/core/TestSuites/FunctionalJavascriptTestSuite.php + + + + + + + + + + + + + ./web/core/includes + ./web/core/lib + ./web/core/modules + ./web/modules + ./web/sites + + + */tests/* + + + + diff --git a/postman/PERLS.postman_collection.json b/postman/PERLS.postman_collection.json new file mode 100755 index 0000000..98c81cd --- /dev/null +++ b/postman/PERLS.postman_collection.json @@ -0,0 +1,5229 @@ +{ + "info": { + "_postman_id": "0dec7a7d-a41b-4e42-856f-4d3b989ba208", + "name": "PERLS", + "description": "A collection of items to test PERLS Rest API", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" + }, + "item": [ + { + "name": "Learner State APIs", + "item": [ + { + "name": "Bookmark state", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/state/bookmark", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "state", + "bookmark" + ] + }, + "description": "Retrieve a list of bookmarked content IDs (but not the content itself). This request can be paged by adding the `page` query param (e.g. `?page=1`)." + }, + "response": [ + { + "name": "Bookmark state", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/state/bookmark", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "state", + "bookmark" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Date", + "value": "Wed, 01 Sep 2021 20:50:44 GMT" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Content-Length", + "value": "433" + }, + { + "key": "Connection", + "value": "keep-alive" + }, + { + "key": "Set-Cookie", + "value": "AWSALB=oy1zdngzakw5DngzgEiR3eaTe/14FapUKuAQ8PorIX8ngr17n3DW4oQeIZuoc8Qw5xVhveyVEL3wjSc0qk5IyCa5rEdlgpT7DooCYuW98ejljTNN/J841jhCUaJ9; Expires=Wed, 08 Sep 2021 20:50:44 GMT; Path=/" + }, + { + "key": "Set-Cookie", + "value": "AWSALBCORS=oy1zdngzakw5DngzgEiR3eaTe/14FapUKuAQ8PorIX8ngr17n3DW4oQeIZuoc8Qw5xVhveyVEL3wjSc0qk5IyCa5rEdlgpT7DooCYuW98ejljTNN/J841jhCUaJ9; Expires=Wed, 08 Sep 2021 20:50:44 GMT; Path=/; SameSite=None; Secure" + }, + { + "key": "Server", + "value": "Apache" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "Cache-Control", + "value": "must-revalidate, no-cache, private" + }, + { + "key": "X-Drupal-Dynamic-Cache", + "value": "MISS" + }, + { + "key": "X-UA-Compatible", + "value": "IE=edge" + }, + { + "key": "Content-language", + "value": "en" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "Permissions-Policy", + "value": "interest-cohort=()" + }, + { + "key": "Expires", + "value": "Sun, 19 Nov 1978 05:00:00 GMT" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubdomains; preload" + }, + { + "key": "X-XSS-Protection", + "value": "1; mode=block" + } + ], + "cookie": [], + "body": "{\n \"rows\": [\n {\n \"id\": \"d7c325bc-5332-416a-ad3b-179399a68adf\",\n \"type\": \"bookmark\",\n \"nid\": \"1022\",\n \"created\": \"2021-09-01T20:48:09+0000\"\n },\n {\n \"id\": \"a70e9514-0f54-4a3a-84e5-0e1e19c8b5c3\",\n \"type\": \"bookmark\",\n \"nid\": \"1019\",\n \"created\": \"2021-09-01T20:48:08+0000\"\n },\n {\n \"id\": \"feb3a943-95ee-4899-8b23-2888a95cc352\",\n \"type\": \"bookmark\",\n \"nid\": \"353\",\n \"created\": \"2020-12-08T19:53:52+0000\"\n }\n ],\n \"pager\": {\n \"current_page\": 0,\n \"total_items\": \"3\",\n \"total_pages\": 1,\n \"items_per_page\": 100\n }\n}" + } + ] + }, + { + "name": "Following state", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/state/following", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "state", + "following" + ] + }, + "description": "Retrieve a list of followed tag IDs (but not the tag itself). This request can be paged by adding the `page` query param (e.g. `?page=1`)." + }, + "response": [] + }, + { + "name": "Completed state", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/state/completed", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "state", + "completed" + ] + }, + "description": "Retrieve a list of completed content IDs (but not the content itself). This request can be paged by adding the `page` query param (e.g. `?page=1`)." + }, + "response": [] + }, + { + "name": "Recommendation state", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/state/recommendation", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "state", + "recommendation" + ] + }, + "description": "Retrieve a list of recommended content IDs (but not the content itself). This request can be paged by adding the `page` query param (e.g. `?page=1`)." + }, + "response": [ + { + "name": "Recommendation state", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/state/recommendation", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "state", + "recommendation" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Date", + "value": "Wed, 01 Sep 2021 20:51:18 GMT" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Content-Length", + "value": "5802" + }, + { + "key": "Connection", + "value": "keep-alive" + }, + { + "key": "Set-Cookie", + "value": "AWSALB=BLT0DeRaND0Q5SoAVI6cVfohB9TfG6Y6rOf72aiBbEKYS0+Rpv4kHfG9ehFHEEp7oFoIORIoIJ72+vR0t6Va+JehB+qkFoXDGwO9avny5Ak40is+bvlnsJ3r+M28; Expires=Wed, 08 Sep 2021 20:51:17 GMT; Path=/" + }, + { + "key": "Set-Cookie", + "value": "AWSALBCORS=BLT0DeRaND0Q5SoAVI6cVfohB9TfG6Y6rOf72aiBbEKYS0+Rpv4kHfG9ehFHEEp7oFoIORIoIJ72+vR0t6Va+JehB+qkFoXDGwO9avny5Ak40is+bvlnsJ3r+M28; Expires=Wed, 08 Sep 2021 20:51:17 GMT; Path=/; SameSite=None; Secure" + }, + { + "key": "Server", + "value": "Apache" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "Cache-Control", + "value": "must-revalidate, no-cache, private" + }, + { + "key": "X-Drupal-Dynamic-Cache", + "value": "MISS" + }, + { + "key": "X-UA-Compatible", + "value": "IE=edge" + }, + { + "key": "Content-language", + "value": "en" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "Permissions-Policy", + "value": "interest-cohort=()" + }, + { + "key": "Expires", + "value": "Sun, 19 Nov 1978 05:00:00 GMT" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubdomains; preload" + }, + { + "key": "X-XSS-Protection", + "value": "1; mode=block" + } + ], + "cookie": [], + "body": "{\n \"rows\": [\n {\n \"id\": \"832b1747-7529-4c83-b111-4d57ca49d557\",\n \"type\": \"recommendation\",\n \"nid\": \"1021\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is popular and new.\",\n \"score\": 1.53835\n },\n {\n \"id\": \"e90e1a12-c09a-4623-b657-3d5131dcdf73\",\n \"type\": \"recommendation\",\n \"nid\": \"825\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is something you might want to explore and popular.\",\n \"score\": 0.284358\n },\n {\n \"id\": \"bde13382-a1fa-4f76-aa8e-adb4162bf04f\",\n \"type\": \"recommendation\",\n \"nid\": \"1019\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is new and popular.\",\n \"score\": 1.09042\n },\n {\n \"id\": \"ef42b12c-c06f-4979-bb62-34ffc442f643\",\n \"type\": \"recommendation\",\n \"nid\": \"586\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is something you might want to explore.\",\n \"score\": 0.146\n },\n {\n \"id\": \"1ee80e4c-764c-49ec-b8d6-b4deb4519f0d\",\n \"type\": \"recommendation\",\n \"nid\": \"1022\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is new and popular.\",\n \"score\": 1.15145\n },\n {\n \"id\": \"4c6a98f1-5116-48da-9da5-956e29f8532c\",\n \"type\": \"recommendation\",\n \"nid\": \"974\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is something you might want to explore and popular.\",\n \"score\": 0.44994\n },\n {\n \"id\": \"b57aed87-cccc-410c-bcea-4b9ebc843d7e\",\n \"type\": \"recommendation\",\n \"nid\": \"1018\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is new and popular.\",\n \"score\": 0.789458\n },\n {\n \"id\": \"c26f4422-0332-43e4-9969-47ef9ca7aca7\",\n \"type\": \"recommendation\",\n \"nid\": \"481\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is something you might want to explore.\",\n \"score\": 0.229\n },\n {\n \"id\": \"048f14c9-c64d-4bfb-bfb5-317b984f21ba\",\n \"type\": \"recommendation\",\n \"nid\": \"994\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is popular and new.\",\n \"score\": 0.324806\n },\n {\n \"id\": \"43748792-ca6b-4a87-8464-0e72405e06bf\",\n \"type\": \"recommendation\",\n \"nid\": \"988\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is something you might want to explore and new.\",\n \"score\": 0.19433\n },\n {\n \"id\": \"8a93604b-4bd4-4302-a631-cb5c23883980\",\n \"type\": \"recommendation\",\n \"nid\": \"1023\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is new and popular.\",\n \"score\": 0.96746\n },\n {\n \"id\": \"68306692-86fc-4bbd-8848-ca542e827e09\",\n \"type\": \"recommendation\",\n \"nid\": \"887\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is something you might want to explore and new.\",\n \"score\": 0.222191\n },\n {\n \"id\": \"591dc840-eeab-4f7d-a2c4-16c04c6518ad\",\n \"type\": \"recommendation\",\n \"nid\": \"967\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is something you might want to explore and new.\",\n \"score\": 0.163326\n },\n {\n \"id\": \"99447d00-54ad-4e0e-9ece-4c7401109d10\",\n \"type\": \"recommendation\",\n \"nid\": \"1007\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is something you might want to explore and new.\",\n \"score\": 0.359303\n },\n {\n \"id\": \"5e541b2f-e5a0-44f0-8448-cf87877a9093\",\n \"type\": \"recommendation\",\n \"nid\": \"621\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is something you might want to explore.\",\n \"score\": 0.162\n },\n {\n \"id\": \"1b2200ea-f82f-4ef7-991e-838588d6f5fa\",\n \"type\": \"recommendation\",\n \"nid\": \"969\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is something you might want to explore and popular.\",\n \"score\": 0.274199\n },\n {\n \"id\": \"c90751a1-e3b6-4b2a-bf54-8d021bdc0b19\",\n \"type\": \"recommendation\",\n \"nid\": \"876\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is something you might want to explore and new.\",\n \"score\": 0.256879\n },\n {\n \"id\": \"3101934a-3a94-4901-99bf-8c19d8dfe104\",\n \"type\": \"recommendation\",\n \"nid\": \"609\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is something you might want to explore.\",\n \"score\": 0.24\n },\n {\n \"id\": \"a39f62d3-3fff-40c0-b5ff-b60c2e2342e9\",\n \"type\": \"recommendation\",\n \"nid\": \"561\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is something you might want to explore.\",\n \"score\": 0.108\n },\n {\n \"id\": \"c21383c1-2bdf-42d4-a2d7-70dbbe7fe85f\",\n \"type\": \"recommendation\",\n \"nid\": \"965\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is something you might want to explore and new.\",\n \"score\": 0.152307\n },\n {\n \"id\": \"f7f48800-1db3-47e0-98b1-e0056db49e2f\",\n \"type\": \"recommendation\",\n \"nid\": \"587\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is something you might want to explore.\",\n \"score\": 0.155\n },\n {\n \"id\": \"1a327662-675d-4e53-b9e5-b3596040f0da\",\n \"type\": \"recommendation\",\n \"nid\": \"987\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is something you might want to explore and new.\",\n \"score\": 0.179326\n },\n {\n \"id\": \"7dffbf27-ee83-4161-9ba5-f0388d9d3067\",\n \"type\": \"recommendation\",\n \"nid\": \"662\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is something you might want to explore.\",\n \"score\": 0.122\n },\n {\n \"id\": \"ab73fe26-fcb9-46d1-ad9f-272e5589c599\",\n \"type\": \"recommendation\",\n \"nid\": \"977\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is something you might want to explore and new.\",\n \"score\": 0.206362\n },\n {\n \"id\": \"9921d600-5bd2-43a8-b40b-6054522e13bb\",\n \"type\": \"recommendation\",\n \"nid\": \"982\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is something you might want to explore and new.\",\n \"score\": 0.175258\n },\n {\n \"id\": \"63da64a7-ae3f-449c-9c9c-63a2b9830b60\",\n \"type\": \"recommendation\",\n \"nid\": \"676\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is something you might want to explore.\",\n \"score\": 0.231\n }\n ],\n \"pager\": {\n \"current_page\": 0,\n \"total_items\": \"26\",\n \"total_pages\": 1,\n \"items_per_page\": 100\n }\n}" + } + ] + }, + { + "name": "All states", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/state/all", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "state", + "all" + ] + }, + "description": "Retrieve a full list the current user's content state. This request can be paged by adding the `page` query param (e.g. `?page=1`)." + }, + "response": [ + { + "name": "All states", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/state/all", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "state", + "all" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Date", + "value": "Wed, 01 Sep 2021 20:51:29 GMT" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Content-Length", + "value": "6143" + }, + { + "key": "Connection", + "value": "keep-alive" + }, + { + "key": "Set-Cookie", + "value": "AWSALB=BCkH9UA+JCb/nVPCKpgHjxhGAWxsrP30vuNM41kZrk3A/t1OY5GcHK4hmu3PhfIlWgE5HvfBjgcmcVvlcYfK5ErM9EMTyixCA+Yliou3z158JmSCIpjX9j+9PGL9; Expires=Wed, 08 Sep 2021 20:51:28 GMT; Path=/" + }, + { + "key": "Set-Cookie", + "value": "AWSALBCORS=BCkH9UA+JCb/nVPCKpgHjxhGAWxsrP30vuNM41kZrk3A/t1OY5GcHK4hmu3PhfIlWgE5HvfBjgcmcVvlcYfK5ErM9EMTyixCA+Yliou3z158JmSCIpjX9j+9PGL9; Expires=Wed, 08 Sep 2021 20:51:28 GMT; Path=/; SameSite=None; Secure" + }, + { + "key": "Server", + "value": "Apache" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "Cache-Control", + "value": "must-revalidate, no-cache, private" + }, + { + "key": "X-Drupal-Dynamic-Cache", + "value": "MISS" + }, + { + "key": "X-UA-Compatible", + "value": "IE=edge" + }, + { + "key": "Content-language", + "value": "en" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "Permissions-Policy", + "value": "interest-cohort=()" + }, + { + "key": "Expires", + "value": "Sun, 19 Nov 1978 05:00:00 GMT" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubdomains; preload" + }, + { + "key": "X-XSS-Protection", + "value": "1; mode=block" + } + ], + "cookie": [], + "body": "{\n \"rows\": [\n {\n \"id\": \"d7c325bc-5332-416a-ad3b-179399a68adf\",\n \"type\": \"bookmark\",\n \"nid\": \"1022\",\n \"created\": \"2021-09-01T20:48:09+0000\"\n },\n {\n \"id\": \"a70e9514-0f54-4a3a-84e5-0e1e19c8b5c3\",\n \"type\": \"bookmark\",\n \"nid\": \"1019\",\n \"created\": \"2021-09-01T20:48:08+0000\"\n },\n {\n \"id\": \"63da64a7-ae3f-449c-9c9c-63a2b9830b60\",\n \"type\": \"recommendation\",\n \"nid\": \"676\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is something you might want to explore.\",\n \"score\": 0.231\n },\n {\n \"id\": \"832b1747-7529-4c83-b111-4d57ca49d557\",\n \"type\": \"recommendation\",\n \"nid\": \"1021\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is popular and new.\",\n \"score\": 1.53835\n },\n {\n \"id\": \"e90e1a12-c09a-4623-b657-3d5131dcdf73\",\n \"type\": \"recommendation\",\n \"nid\": \"825\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is something you might want to explore and popular.\",\n \"score\": 0.284358\n },\n {\n \"id\": \"bde13382-a1fa-4f76-aa8e-adb4162bf04f\",\n \"type\": \"recommendation\",\n \"nid\": \"1019\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is new and popular.\",\n \"score\": 1.09042\n },\n {\n \"id\": \"ef42b12c-c06f-4979-bb62-34ffc442f643\",\n \"type\": \"recommendation\",\n \"nid\": \"586\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is something you might want to explore.\",\n \"score\": 0.146\n },\n {\n \"id\": \"1ee80e4c-764c-49ec-b8d6-b4deb4519f0d\",\n \"type\": \"recommendation\",\n \"nid\": \"1022\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is new and popular.\",\n \"score\": 1.15145\n },\n {\n \"id\": \"4c6a98f1-5116-48da-9da5-956e29f8532c\",\n \"type\": \"recommendation\",\n \"nid\": \"974\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is something you might want to explore and popular.\",\n \"score\": 0.44994\n },\n {\n \"id\": \"b57aed87-cccc-410c-bcea-4b9ebc843d7e\",\n \"type\": \"recommendation\",\n \"nid\": \"1018\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is new and popular.\",\n \"score\": 0.789458\n },\n {\n \"id\": \"c26f4422-0332-43e4-9969-47ef9ca7aca7\",\n \"type\": \"recommendation\",\n \"nid\": \"481\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is something you might want to explore.\",\n \"score\": 0.229\n },\n {\n \"id\": \"048f14c9-c64d-4bfb-bfb5-317b984f21ba\",\n \"type\": \"recommendation\",\n \"nid\": \"994\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is popular and new.\",\n \"score\": 0.324806\n },\n {\n \"id\": \"43748792-ca6b-4a87-8464-0e72405e06bf\",\n \"type\": \"recommendation\",\n \"nid\": \"988\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is something you might want to explore and new.\",\n \"score\": 0.19433\n },\n {\n \"id\": \"8a93604b-4bd4-4302-a631-cb5c23883980\",\n \"type\": \"recommendation\",\n \"nid\": \"1023\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is new and popular.\",\n \"score\": 0.96746\n },\n {\n \"id\": \"68306692-86fc-4bbd-8848-ca542e827e09\",\n \"type\": \"recommendation\",\n \"nid\": \"887\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is something you might want to explore and new.\",\n \"score\": 0.222191\n },\n {\n \"id\": \"591dc840-eeab-4f7d-a2c4-16c04c6518ad\",\n \"type\": \"recommendation\",\n \"nid\": \"967\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is something you might want to explore and new.\",\n \"score\": 0.163326\n },\n {\n \"id\": \"99447d00-54ad-4e0e-9ece-4c7401109d10\",\n \"type\": \"recommendation\",\n \"nid\": \"1007\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is something you might want to explore and new.\",\n \"score\": 0.359303\n },\n {\n \"id\": \"5e541b2f-e5a0-44f0-8448-cf87877a9093\",\n \"type\": \"recommendation\",\n \"nid\": \"621\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is something you might want to explore.\",\n \"score\": 0.162\n },\n {\n \"id\": \"1b2200ea-f82f-4ef7-991e-838588d6f5fa\",\n \"type\": \"recommendation\",\n \"nid\": \"969\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is something you might want to explore and popular.\",\n \"score\": 0.274199\n },\n {\n \"id\": \"c90751a1-e3b6-4b2a-bf54-8d021bdc0b19\",\n \"type\": \"recommendation\",\n \"nid\": \"876\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is something you might want to explore and new.\",\n \"score\": 0.256879\n },\n {\n \"id\": \"3101934a-3a94-4901-99bf-8c19d8dfe104\",\n \"type\": \"recommendation\",\n \"nid\": \"609\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is something you might want to explore.\",\n \"score\": 0.24\n },\n {\n \"id\": \"a39f62d3-3fff-40c0-b5ff-b60c2e2342e9\",\n \"type\": \"recommendation\",\n \"nid\": \"561\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is something you might want to explore.\",\n \"score\": 0.108\n },\n {\n \"id\": \"c21383c1-2bdf-42d4-a2d7-70dbbe7fe85f\",\n \"type\": \"recommendation\",\n \"nid\": \"965\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is something you might want to explore and new.\",\n \"score\": 0.152307\n },\n {\n \"id\": \"f7f48800-1db3-47e0-98b1-e0056db49e2f\",\n \"type\": \"recommendation\",\n \"nid\": \"587\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is something you might want to explore.\",\n \"score\": 0.155\n },\n {\n \"id\": \"1a327662-675d-4e53-b9e5-b3596040f0da\",\n \"type\": \"recommendation\",\n \"nid\": \"987\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is something you might want to explore and new.\",\n \"score\": 0.179326\n },\n {\n \"id\": \"7dffbf27-ee83-4161-9ba5-f0388d9d3067\",\n \"type\": \"recommendation\",\n \"nid\": \"662\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is something you might want to explore.\",\n \"score\": 0.122\n },\n {\n \"id\": \"ab73fe26-fcb9-46d1-ad9f-272e5589c599\",\n \"type\": \"recommendation\",\n \"nid\": \"977\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is something you might want to explore and new.\",\n \"score\": 0.206362\n },\n {\n \"id\": \"9921d600-5bd2-43a8-b40b-6054522e13bb\",\n \"type\": \"recommendation\",\n \"nid\": \"982\",\n \"created\": \"2021-08-27T18:40:01+0000\",\n \"reason\": \"We picked this for you because it is something you might want to explore and new.\",\n \"score\": 0.175258\n },\n {\n \"id\": \"feb3a943-95ee-4899-8b23-2888a95cc352\",\n \"type\": \"bookmark\",\n \"nid\": \"353\",\n \"created\": \"2020-12-08T19:53:52+0000\"\n }\n ],\n \"pager\": {\n \"current_page\": 0,\n \"total_items\": \"29\",\n \"total_pages\": 1,\n \"items_per_page\": 100\n }\n}" + } + ] + }, + { + "name": "All states, page 2", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/state/all?page=1", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "state", + "all" + ], + "query": [ + { + "key": "page", + "value": "1" + } + ] + }, + "description": "Retrieve a full list the current user's content state. This request can be paged by adding the `page` query param (e.g. `?page=1`)." + }, + "response": [ + { + "name": "All states, page 2", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/state/all?page=1", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "state", + "all" + ], + "query": [ + { + "key": "page", + "value": "1" + } + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Date", + "value": "Wed, 01 Sep 2021 20:51:39 GMT" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Content-Length", + "value": "94" + }, + { + "key": "Connection", + "value": "keep-alive" + }, + { + "key": "Set-Cookie", + "value": "AWSALB=OGq7w4z1iN0xBhMuB92ZvpGip8OW6Y7+GryQKEsvTFQvl6YoybnuvuSRxZl+GI2rUygHmNUps+9UU8pooxpRq5VDJ+N5efuK1rLarQBmAH/sIaBrJ8oNVQP6s12X; Expires=Wed, 08 Sep 2021 20:51:39 GMT; Path=/" + }, + { + "key": "Set-Cookie", + "value": "AWSALBCORS=OGq7w4z1iN0xBhMuB92ZvpGip8OW6Y7+GryQKEsvTFQvl6YoybnuvuSRxZl+GI2rUygHmNUps+9UU8pooxpRq5VDJ+N5efuK1rLarQBmAH/sIaBrJ8oNVQP6s12X; Expires=Wed, 08 Sep 2021 20:51:39 GMT; Path=/; SameSite=None; Secure" + }, + { + "key": "Server", + "value": "Apache" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "Cache-Control", + "value": "must-revalidate, no-cache, private" + }, + { + "key": "X-Drupal-Dynamic-Cache", + "value": "MISS" + }, + { + "key": "X-UA-Compatible", + "value": "IE=edge" + }, + { + "key": "Content-language", + "value": "en" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "Permissions-Policy", + "value": "interest-cohort=()" + }, + { + "key": "Expires", + "value": "Sun, 19 Nov 1978 05:00:00 GMT" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubdomains; preload" + }, + { + "key": "X-XSS-Protection", + "value": "1; mode=block" + } + ], + "cookie": [], + "body": "{\n \"rows\": [],\n \"pager\": {\n \"current_page\": 0,\n \"total_items\": \"29\",\n \"total_pages\": 1,\n \"items_per_page\": 100\n }\n}" + } + ] + }, + { + "name": "All states for corpus item", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/state/all?id=95", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "state", + "all" + ], + "query": [ + { + "key": "id", + "value": "95" + } + ] + }, + "description": "The current learner states of a specified corpus item.
\nUsing `nid` as the parameter here will limit items returned to nodes.
\nUsing `tid` as the parameter here will limit items returned to taxonomy terms.
\nUsing `id` as the parameter will return any entity that matches that id regardless of entity type." + }, + "response": [] + }, + { + "name": "All states for multiple corpus items", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/state/all?nid=179|124|125", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "state", + "all" + ], + "query": [ + { + "key": "nid", + "value": "179|124|125" + } + ] + }, + "description": "The current learner states of multiple corpus items with their nid separated by a pipe.
\nUsing `nid` as the parameter here will limit items returned to nodes.
\nUsing `tid` as the parameter here will limit items returned to taxonomy terms.
\nUsing `id` as the parameter will return any entity that matches that id regardless of entity type.\nAdding `entity_type` parameter can be used with `id` to get entities of a certain type." + }, + "response": [] + } + ], + "description": "These APIs retrieve the current learner's state (i.e. the list of content items they have bookmarked, completed, recommended, etc.).", + "event": [ + { + "listen": "prerequest", + "script": { + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ] + }, + { + "name": "Groups", + "item": [ + { + "name": "Groups for current user", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var jsonData = JSON.parse(responseBody);", + "var [group] = jsonData.rows;", + "postman.setEnvironmentVariable(\"group_id\", group.gid);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "url": { + "raw": "{{server}}/{{base_url}}/groups", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "groups" + ] + }, + "description": "Retrieves the groups where the current user has an active membership.\n\n### Paging\nThis endpoint allows for paging with the `page` query parameter. Paging uses a 0-based index. For example, to request the second page, add `page=1` to the query parameters." + }, + "response": [ + { + "name": "Groups for current user", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/groups", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "groups" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Cache-Control", + "value": "must-revalidate, no-cache, private" + }, + { + "key": "Content-Encoding", + "value": "gzip" + }, + { + "key": "Content-Language", + "value": "en" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Sun, 11 Apr 2021 17:40:25 GMT" + }, + { + "key": "Expires", + "value": "Sun, 19 Nov 1978 05:00:00 GMT" + }, + { + "key": "Server", + "value": "nginx" + }, + { + "key": "Vary", + "value": "Accept-Encoding" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Drupal-Cache-Contexts", + "value": "languages:language_interface request_format theme url user.group_permissions user.permissions" + }, + { + "key": "X-Drupal-Cache-Max-Age", + "value": "-1 (Permanent)" + }, + { + "key": "X-Drupal-Cache-Tags", + "value": "config:views.view.group_index group:15 group_content:240 group_content_list group_list http_response page_manager_route_name:view.group_index.rest_export_1" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "X-Generator", + "value": "Drupal 9 (https://www.drupal.org)" + }, + { + "key": "X-Ua-Compatible", + "value": "IE=edge" + }, + { + "key": "X-Xss-Protection", + "value": "1; mode=block" + }, + { + "key": "Content-Length", + "value": "407" + } + ], + "cookie": [], + "body": "{\n \"rows\": [\n {\n \"id\": \"c3dde2de-5f71-4614-bccb-ba6ac5274469\",\n \"gid\": 15,\n \"url\": \"/group/15\",\n \"name\": \"Health and Well-being\",\n \"changed\": \"2021-04-11T17:37:57+0000\",\n \"description\": \"Share tips for staying healthy--physically and emotionally.\",\n \"image\": {\n \"UUID\": \"d407196f-ba95-4ecf-ab5a-5c6cae919295\",\n \"name\": \"fitness_1.jpg\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2021-03/fitness_1.jpg?itok=ALlRLkGJ\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2021-03/fitness_1.jpg\"\n },\n \"visibility\": \"public\"\n }\n ],\n \"pager\": {\n \"current_page\": 0,\n \"total_items\": \"1\",\n \"total_pages\": 1,\n \"items_per_page\": 50\n }\n}" + } + ] + }, + { + "name": "Get membership info", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "url": { + "raw": "{{server}}/group/{{group_id}}/membership", + "host": [ + "{{server}}" + ], + "path": [ + "group", + "{{group_id}}", + "membership" + ], + "query": [ + { + "key": "", + "value": null, + "disabled": true + } + ] + }, + "description": "Retrieves the current user's membership record from the specified group.\n\n### Response\n|Property|Description|\n|--------|-----------|\n|id |UUID for the membership entity.|\n|url |Canonical URL for the entity; not currently used for anything meaningful.|\n|name |The name of the membership record; this will almost always be the learner's name.|\n|created |The date the user joined the group.|\n|status |`open` - The user can leave the group.
`locked` - The user cannot leave the group.|\n|group |The group the user belongs to.|\n|user |The user record.|\n\n\n### Response codes\n`404` - either the group does not exist **or** the user is not a member of the group; the response message will disambiguate why the membership record could not be found" + }, + "response": [ + { + "name": "Example response", + "originalRequest": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "url": { + "raw": "{{server}}/group/{{group_id}}/membership", + "host": [ + "{{server}}" + ], + "path": [ + "group", + "{{group_id}}", + "membership" + ], + "query": [ + { + "key": "", + "value": null, + "disabled": true + } + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Cache-Control", + "value": "must-revalidate, no-cache, private" + }, + { + "key": "Content-Encoding", + "value": "gzip" + }, + { + "key": "Content-Language", + "value": "en" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Sun, 11 Apr 2021 18:18:43 GMT" + }, + { + "key": "Expires", + "value": "Sun, 19 Nov 1978 05:00:00 GMT" + }, + { + "key": "Server", + "value": "nginx" + }, + { + "key": "Vary", + "value": "Accept-Encoding" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Drupal-Cache-Contexts", + "value": "languages:language_interface user" + }, + { + "key": "X-Drupal-Cache-Max-Age", + "value": "-1 (Permanent)" + }, + { + "key": "X-Drupal-Cache-Tags", + "value": "config:rest.resource.membership_resource group_content:240 http_response page_manager_route_name:rest.membership_resource.GET" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "X-Generator", + "value": "Drupal 9 (https://www.drupal.org)" + }, + { + "key": "X-Ua-Compatible", + "value": "IE=edge" + }, + { + "key": "X-Xss-Protection", + "value": "1; mode=block" + }, + { + "key": "Content-Length", + "value": "665" + } + ], + "cookie": [], + "body": "{\n \"id\": \"4deb0203-64b8-4687-8a17-72b647110e38\",\n \"url\": \"/group/15/content/240\",\n \"name\": \"Learner\",\n \"created\": \"2021-04-09T14:11:40+0000\",\n \"status\": \"open\",\n \"group\": {\n \"id\": \"c3dde2de-5f71-4614-bccb-ba6ac5274469\",\n \"gid\": 15,\n \"url\": \"/group/15\",\n \"name\": \"Health and Well-being\",\n \"changed\": \"2021-04-11T17:37:57+0000\",\n \"description\": \"Share tips for staying healthy--physically and emotionally.\",\n \"image\": {\n \"UUID\": \"d407196f-ba95-4ecf-ab5a-5c6cae919295\",\n \"name\": \"fitness_1.jpg\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2021-03/fitness_1.jpg?itok=ALlRLkGJ\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2021-03/fitness_1.jpg\"\n },\n \"visibility\": \"public\"\n },\n \"user\": {\n \"id\": \"b35e0df4-fa31-404a-a528-8de44e96faed\",\n \"url\": \"/user/310\",\n \"name\": \"Learner\",\n \"avatar\": null,\n \"goals\": {\n \"notification_days\": [],\n \"weekly_test_average\": 70,\n \"monthly_course_completions\": 6,\n \"weekly_completions\": 5,\n \"weekly_views\": 10,\n \"notification_time\": null\n },\n \"mail\": \"learner@learner.learner\",\n \"username\": \"learner@learner.learner\",\n \"is_enabled\": true,\n \"roles\": [],\n \"preferred_langcode\": \"en\",\n \"changed\": \"2021-04-11T17:51:32+0000\",\n \"last_access\": \"2021-04-11T18:13:34+0000\",\n \"last_login\": \"2021-04-09T17:16:52+0000\"\n }\n}" + }, + { + "name": "Group does not exist", + "originalRequest": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "url": { + "raw": "{{server}}/group/18/membership", + "host": [ + "{{server}}" + ], + "path": [ + "group", + "18", + "membership" + ], + "query": [ + { + "key": "", + "value": null, + "disabled": true + } + ] + } + }, + "status": "Not Found", + "code": 404, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Cache-Control", + "value": "must-revalidate, no-cache, private" + }, + { + "key": "Content-Encoding", + "value": "gzip" + }, + { + "key": "Content-Language", + "value": "en" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Sun, 11 Apr 2021 18:20:10 GMT" + }, + { + "key": "Expires", + "value": "Sun, 19 Nov 1978 05:00:00 GMT" + }, + { + "key": "Server", + "value": "nginx" + }, + { + "key": "Vary", + "value": "Accept-Encoding" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "X-Generator", + "value": "Drupal 9 (https://www.drupal.org)" + }, + { + "key": "X-Ua-Compatible", + "value": "IE=edge" + }, + { + "key": "Content-Length", + "value": "54" + } + ], + "cookie": [], + "body": "{\n \"message\": \"Unable to find group\"\n}" + } + ] + }, + { + "name": "Get group", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "url": { + "raw": "{{server}}/group/{{group_id}}", + "host": [ + "{{server}}" + ], + "path": [ + "group", + "{{group_id}}" + ], + "query": [ + { + "key": "", + "value": null, + "disabled": true + } + ] + }, + "description": "Retrieves information about a group.\n\n### Response\n| Property | Description |\n|----------|-------------|\n|id |The UUID for the group entity.|\n|gid |A secondary identifier for the group. This ID is used in the canonical URL for the group. But you should always use the `url` field below for generating a group URL.|\n|url |The URL to the group in the web interface.|\n|name |The name of the group.|\n|changed |The date the group was last updated (does not update for changes in content or members, only for changes in group metadata.|\n|description|The group description.|\n|image |An image representing the group.|\n|visibility|`public` - anybody can see the group
`private` - only users in the group can see it. Learner cannot leave private groups.|\n\n### Response codes\n* `200` - the group exists\n* `404` - the group could not be found **or** the user does not have permission to see the group." + }, + "response": [ + { + "name": "Example response", + "originalRequest": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "url": { + "raw": "{{server}}/group/{{group_id}}", + "host": [ + "{{server}}" + ], + "path": [ + "group", + "{{group_id}}" + ], + "query": [ + { + "key": "", + "value": null, + "disabled": true + } + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Cache-Control", + "value": "must-revalidate, no-cache, private" + }, + { + "key": "Content-Encoding", + "value": "gzip" + }, + { + "key": "Content-Language", + "value": "en" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Sun, 11 Apr 2021 18:24:39 GMT" + }, + { + "key": "Expires", + "value": "Sun, 19 Nov 1978 05:00:00 GMT" + }, + { + "key": "Link", + "value": "; rel=\"https://drupal.org/link-relations/add-form\"" + }, + { + "key": "Link", + "value": "; rel=\"https://drupal.org/link-relations/add-page\"" + }, + { + "key": "Link", + "value": "; rel=\"canonical\"" + }, + { + "key": "Link", + "value": "; rel=\"collection\"" + }, + { + "key": "Link", + "value": "; rel=\"edit-form\"" + }, + { + "key": "Link", + "value": "; rel=\"https://drupal.org/link-relations/delete-form\"" + }, + { + "key": "Server", + "value": "nginx" + }, + { + "key": "Vary", + "value": "Accept-Encoding" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Drupal-Cache-Contexts", + "value": "languages:language_interface url.site user.group_permissions" + }, + { + "key": "X-Drupal-Cache-Max-Age", + "value": "-1 (Permanent)" + }, + { + "key": "X-Drupal-Cache-Tags", + "value": "config:rest.resource.entity.group group:15 http_response page_manager_route_name:rest.entity.group.GET" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "X-Generator", + "value": "Drupal 9 (https://www.drupal.org)" + }, + { + "key": "X-Ua-Compatible", + "value": "IE=edge" + }, + { + "key": "X-Xss-Protection", + "value": "1; mode=block" + }, + { + "key": "Content-Length", + "value": "352" + } + ], + "cookie": [], + "body": "{\n \"id\": \"c3dde2de-5f71-4614-bccb-ba6ac5274469\",\n \"gid\": 15,\n \"url\": \"/group/15\",\n \"name\": \"Health and Well-being\",\n \"changed\": \"2021-04-11T17:37:57+0000\",\n \"description\": \"Share tips for staying healthy--physically and emotionally.\",\n \"image\": {\n \"UUID\": \"d407196f-ba95-4ecf-ab5a-5c6cae919295\",\n \"name\": \"fitness_1.jpg\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2021-03/fitness_1.jpg?itok=ALlRLkGJ\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2021-03/fitness_1.jpg\"\n },\n \"visibility\": \"public\"\n}" + } + ] + }, + { + "name": "Open groups", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var jsonData = JSON.parse(responseBody);", + "var [group] = jsonData.rows;", + "postman.setEnvironmentVariable(\"joinable_group_id\", group.gid);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/groups?joinable=1", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "groups" + ], + "query": [ + { + "key": "joinable", + "value": "1" + } + ] + }, + "description": "Retrieve the groups open to the current user to join.\n\n### Paging\nThis endpoint allows for paging with the `page` query parameter. Paging uses a 0-based index. For example, to request the second page, add `page=1` to the query parameters." + }, + "response": [ + { + "name": "Open groups", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/groups?joinable=1", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "groups" + ], + "query": [ + { + "key": "joinable", + "value": "1" + } + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Cache-Control", + "value": "must-revalidate, no-cache, private" + }, + { + "key": "Content-Encoding", + "value": "gzip" + }, + { + "key": "Content-Language", + "value": "en" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Sun, 11 Apr 2021 17:42:55 GMT" + }, + { + "key": "Expires", + "value": "Sun, 19 Nov 1978 05:00:00 GMT" + }, + { + "key": "Server", + "value": "nginx" + }, + { + "key": "Vary", + "value": "Accept-Encoding" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Drupal-Cache-Contexts", + "value": "languages:language_interface request_format theme url user.group_permissions user.permissions" + }, + { + "key": "X-Drupal-Cache-Max-Age", + "value": "-1 (Permanent)" + }, + { + "key": "X-Drupal-Cache-Tags", + "value": "config:views.view.group_index group:17 group_content_list group_list http_response page_manager_route_name:view.group_index.rest_export_1" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "X-Generator", + "value": "Drupal 9 (https://www.drupal.org)" + }, + { + "key": "X-Ua-Compatible", + "value": "IE=edge" + }, + { + "key": "X-Xss-Protection", + "value": "1; mode=block" + }, + { + "key": "Content-Length", + "value": "442" + } + ], + "cookie": [], + "body": "{\n \"rows\": [\n {\n \"id\": \"94975176-f26d-4baa-a9cf-1cf5795656da\",\n \"gid\": 17,\n \"url\": \"/group/17\",\n \"name\": \"Effective Use of Technology\",\n \"changed\": \"2021-04-11T17:38:43+0000\",\n \"description\": \"Tips on how to become more effective with the tools you use everyday.\",\n \"image\": {\n \"UUID\": \"4eb878e5-8320-49d7-86cf-ce45a02e1f2b\",\n \"name\": \"christopher-gower-m_hrflhgabo-unsplash.jpg\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2021-04/christopher-gower-m_hrflhgabo-unsplash.jpg?itok=LGxKSY5E\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2021-04/christopher-gower-m_hrflhgabo-unsplash.jpg\"\n },\n \"visibility\": \"public\"\n }\n ],\n \"pager\": {\n \"current_page\": 0,\n \"total_items\": \"1\",\n \"total_pages\": 1,\n \"items_per_page\": 50\n }\n}" + } + ] + }, + { + "name": "Join group", + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "url": { + "raw": "{{server}}/group/{{joinable_group_id}}/membership", + "host": [ + "{{server}}" + ], + "path": [ + "group", + "{{joinable_group_id}}", + "membership" + ], + "query": [ + { + "key": "", + "value": "", + "disabled": true + } + ] + }, + "description": "Add the current user to a group.\n\nThe response is a membership record containing information about the user's membership (such as the date it was created, the group that was joined, and the membership status.\n\n### Membership status\n* `open` - the user can leave the group whenever they want\n* `locked` - the user may not leave the group\n\n### Response codes\n* `201` - the membership was created\n* `403` - the user is not allowed to join the group\n* `404` - the group was not found; this status code can be returned for a group that does exist, but the current user does not have permission to see it\n* `409` - the user is already a member of the group" + }, + "response": [ + { + "name": "Joined group successfully", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "url": { + "raw": "{{server}}/group/{{joinable_group_id}}/membership", + "host": [ + "{{server}}" + ], + "path": [ + "group", + "{{joinable_group_id}}", + "membership" + ], + "query": [ + { + "key": "", + "value": "", + "disabled": true + } + ] + } + }, + "status": "Created", + "code": 201, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Cache-Control", + "value": "must-revalidate, no-cache, private" + }, + { + "key": "Content-Language", + "value": "en" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Sun, 11 Apr 2021 17:44:48 GMT" + }, + { + "key": "Expires", + "value": "Sun, 19 Nov 1978 05:00:00 GMT" + }, + { + "key": "Server", + "value": "nginx" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "X-Generator", + "value": "Drupal 9 (https://www.drupal.org)" + }, + { + "key": "X-Ua-Compatible", + "value": "IE=edge" + }, + { + "key": "X-Xss-Protection", + "value": "1; mode=block" + }, + { + "key": "Content-Length", + "value": "1298" + } + ], + "cookie": [], + "body": "{\n \"id\": \"6445a20b-4cda-4a5f-9399-d4228556bef1\",\n \"url\": \"/group/17/content/241\",\n \"name\": \"Learner\",\n \"created\": \"2021-04-11T17:44:48+0000\",\n \"status\": \"open\",\n \"group\": {\n \"id\": \"94975176-f26d-4baa-a9cf-1cf5795656da\",\n \"gid\": 17,\n \"url\": \"/group/17\",\n \"name\": \"Effective Use of Technology\",\n \"changed\": \"2021-04-11T17:38:43+0000\",\n \"description\": \"Tips on how to become more effective with the tools you use everyday.\",\n \"image\": {\n \"UUID\": \"4eb878e5-8320-49d7-86cf-ce45a02e1f2b\",\n \"name\": \"christopher-gower-m_hrflhgabo-unsplash.jpg\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2021-04/christopher-gower-m_hrflhgabo-unsplash.jpg?itok=LGxKSY5E\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2021-04/christopher-gower-m_hrflhgabo-unsplash.jpg\"\n },\n \"visibility\": \"public\"\n },\n \"user\": {\n \"id\": \"b35e0df4-fa31-404a-a528-8de44e96faed\",\n \"url\": \"/user/310\",\n \"name\": \"Learner\",\n \"avatar\": null,\n \"goals\": {\n \"notification_days\": [],\n \"weekly_test_average\": 70,\n \"monthly_course_completions\": 6,\n \"weekly_completions\": 5,\n \"weekly_views\": 10,\n \"notification_time\": null\n },\n \"mail\": \"learner@learner.learner\",\n \"username\": \"learner@learner.learner\",\n \"is_enabled\": true,\n \"roles\": [],\n \"preferred_langcode\": \"en\",\n \"changed\": \"2021-04-11T17:44:48+0000\",\n \"last_access\": \"2021-04-11T17:44:38+0000\",\n \"last_login\": \"2021-04-09T17:16:52+0000\"\n }\n}" + }, + { + "name": "User already belongs to group", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + }, + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "url": { + "raw": "{{server}}/group/{{joinable_group_id}}/membership", + "host": [ + "{{server}}" + ], + "path": [ + "group", + "{{joinable_group_id}}", + "membership" + ], + "query": [ + { + "key": "", + "value": "", + "disabled": true + } + ] + } + }, + "status": "Conflict", + "code": 409, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Cache-Control", + "value": "must-revalidate, no-cache, private" + }, + { + "key": "Content-Language", + "value": "en" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Sun, 11 Apr 2021 17:47:57 GMT" + }, + { + "key": "Expires", + "value": "Sun, 19 Nov 1978 05:00:00 GMT" + }, + { + "key": "Server", + "value": "nginx" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "X-Generator", + "value": "Drupal 9 (https://www.drupal.org)" + }, + { + "key": "X-Ua-Compatible", + "value": "IE=edge" + }, + { + "key": "Content-Length", + "value": "69" + } + ], + "cookie": [], + "body": "{\n \"message\": \"You are already a member of Effective Use of Technology\"\n}" + } + ] + }, + { + "name": "Leave group", + "request": { + "method": "DELETE", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "url": { + "raw": "{{server}}/group/{{joinable_group_id}}/membership", + "host": [ + "{{server}}" + ], + "path": [ + "group", + "{{joinable_group_id}}", + "membership" + ], + "query": [ + { + "key": "", + "value": null, + "disabled": true + } + ] + }, + "description": "Leave a group.\n\nThe response body will be empty if the membership record was destroyed successfully (see **Response codes**).\n\n### Response codes\n* `204` - the membership was destroyed\n* `403` - the user is not allowed to leave the group (i.e. if the group is private)\n* `404` - the group was not found **or** the user did not belong to the group; the response message will disambiguate why the user could not leave the group" + }, + "response": [ + { + "name": "User is not in group", + "originalRequest": { + "method": "DELETE", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "url": { + "raw": "{{server}}/group/{{joinable_group_id}}/membership", + "host": [ + "{{server}}" + ], + "path": [ + "group", + "{{joinable_group_id}}", + "membership" + ], + "query": [ + { + "key": "", + "value": null, + "disabled": true + } + ] + } + }, + "status": "Not Found", + "code": 404, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Cache-Control", + "value": "must-revalidate, no-cache, private" + }, + { + "key": "Content-Encoding", + "value": "gzip" + }, + { + "key": "Content-Language", + "value": "en" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Sun, 11 Apr 2021 17:53:43 GMT" + }, + { + "key": "Expires", + "value": "Sun, 19 Nov 1978 05:00:00 GMT" + }, + { + "key": "Server", + "value": "nginx" + }, + { + "key": "Vary", + "value": "Accept-Encoding" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "X-Generator", + "value": "Drupal 9 (https://www.drupal.org)" + }, + { + "key": "X-Ua-Compatible", + "value": "IE=edge" + }, + { + "key": "Content-Length", + "value": "83" + } + ], + "cookie": [], + "body": "{\n \"message\": \"You are not a member of Effective Use of Technology\"\n}" + } + ] + }, + { + "name": "Group topics", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "var groups = JSON.parse(responseBody);", + "var topic = groups[0].content[0].topic;", + "postman.setEnvironmentVariable(\"group_topic_id\", topic.tid);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "url": { + "raw": "{{server}}/{{base_url}}/groups/{{group_id}}/topics", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "groups", + "{{group_id}}", + "topics" + ] + }, + "description": "Retrieves the first 30 topics associated with the group and the 10 most recently updated content items within that topics.\n\n**Note:** This endpoint is currently limited and can only return up to 30 topics (for performance reasons). There is a separate endpoint for searching all group content.\n\n### Response\nFor each topic, the server returns:\n* `name` - the name of the topic\n* `url` - the url for retrieving more than the first 10 items\n* `content` - the 10 most recently updated content items within the topic that belong to the group" + }, + "response": [ + { + "name": "Example response", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/groups/{{group_id}}/topics", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "groups", + "{{group_id}}", + "topics" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Cache-Control", + "value": "must-revalidate, no-cache, private" + }, + { + "key": "Content-Encoding", + "value": "gzip" + }, + { + "key": "Content-Language", + "value": "en" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Sun, 11 Apr 2021 17:54:33 GMT" + }, + { + "key": "Expires", + "value": "Sun, 19 Nov 1978 05:00:00 GMT" + }, + { + "key": "Server", + "value": "nginx" + }, + { + "key": "Vary", + "value": "Accept-Encoding" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Drupal-Cache-Contexts", + "value": "languages:language_content languages:language_interface request_format route.group theme url user.group_permissions user.permissions" + }, + { + "key": "X-Drupal-Cache-Max-Age", + "value": "-1 (Permanent)" + }, + { + "key": "X-Drupal-Cache-Tags", + "value": "config:views.view.group_topics group_content_list group_list http_response node_list page_manager_route_name:view.group_topics.rest_export_nested_1 taxonomy_term_list" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "X-Generator", + "value": "Drupal 9 (https://www.drupal.org)" + }, + { + "key": "X-Ua-Compatible", + "value": "IE=edge" + }, + { + "key": "X-Xss-Protection", + "value": "1; mode=block" + }, + { + "key": "Transfer-Encoding", + "value": "chunked" + } + ], + "cookie": [], + "body": "[\n {\n \"name\": \"Occupational Safety and Health\",\n \"url\": \"/api/groups/15/topics/80\",\n \"content\": [\n {\n \"id\": \"0113f56c-e06b-4d21-b0db-688e74447834\",\n \"nid\": 229,\n \"vid\": 519,\n \"url\": \"/node/229\",\n \"name\": \"Did you know? 40% of Businesses Affected by Disaster Never Reopen. \",\n \"type\": \"tip_card\",\n \"changed\": \"2020-03-18T19:24:07+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": [],\n \"topic\": {\n \"id\": \"fb473dd7-86a8-40a6-8a12-c9c80d46c2fb\",\n \"vid\": 80,\n \"tid\": 80,\n \"url\": \"/taxonomy/term/80\",\n \"name\": \"Occupational Safety and Health\",\n \"type\": \"category\",\n \"changed\": \"2021-02-01T00:30:23+0000\",\n \"description\": \"This topic includes content related to the safety, health, and welfare of people at work The goal of occupational safety and health programs is to foster a safe and healthy work environment.[3] OSH may also protect co-workers, family members, employers, customers, and many others who might be affected by the workplace environment. \"\n },\n \"contents\": [\n \"
\\n
\\n
\\n \\n

The main reason to have an emergency action plan is to do as much as possible to keep your employees safe in case of disaster but a good plan can keep your business safe as well. Up to 40% of businesses affected by a natural or human-caused disaster never reopen. Having procedures in place to deal with disasters can help your business survive this difficult experience.

\\n

 

\\n
\\n \\n
\\n
\\n\\n
\\n\",\n \"
\\n
\\n
\\n \\n
\\\"Closed\\n\\n\\n
\\n \\n
\\n
\\n\\n
\\n\"\n ],\n \"body\": [\n {\n \"id\": \"c548cc2f-d8f0-4a98-88f5-f96ae130d076\",\n \"type\": \"text\",\n \"fields\": [\n {\n \"type\": \"Label\",\n \"attributes\": {\n \"Text\": \"

The main reason to have an emergency action plan is to do as much as possible to keep your employees safe in case of disaster but a good plan can keep your business safe as well. Up to 40% of businesses affected by a natural or human-caused disaster never reopen. Having procedures in place to deal with disasters can help your business survive this difficult experience.

\\r\\n\\r\\n

 

\",\n \"TextType\": \"Html\"\n }\n }\n ]\n },\n {\n \"id\": \"b74d5871-47ad-4d40-baa0-d1f225f18abf\",\n \"type\": \"image\",\n \"fields\": [\n {\n \"type\": \"Image\",\n \"attributes\": {\n \"Source\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/benedikt-geyer-Qq_F_5kS7uo-unsplash.jpg?itok=eIObe6Xf\",\n \"Aspect\": \"AspectFit\"\n }\n }\n ]\n }\n ]\n },\n {\n \"id\": \"09f8e9db-c1e9-47e3-adff-f0cf8132d37e\",\n \"nid\": 227,\n \"vid\": 610,\n \"url\": \"/node/227\",\n \"name\": \"Creating an Emergency Action Plan\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-10T20:56:10+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"f97b1a60-9e2b-45b3-83c9-eb5dc0da85eb\",\n \"name\": \"node_227.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_227.zip\"\n },\n \"tags\": [\n {\n \"id\": \"425e382c-8fc9-4a46-a252-cb6f20bc42eb\",\n \"vid\": 83,\n \"tid\": 83,\n \"url\": \"/taxonomy/term/83\",\n \"name\": \"Leadership\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:33:24+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"fb473dd7-86a8-40a6-8a12-c9c80d46c2fb\",\n \"vid\": 80,\n \"tid\": 80,\n \"url\": \"/taxonomy/term/80\",\n \"name\": \"Occupational Safety and Health\",\n \"type\": \"category\",\n \"changed\": \"2021-02-01T00:30:23+0000\",\n \"description\": \"This topic includes content related to the safety, health, and welfare of people at work The goal of occupational safety and health programs is to foster a safe and healthy work environment.[3] OSH may also protect co-workers, family members, employers, customers, and many others who might be affected by the workplace environment. \"\n },\n \"description\": \"A brief guide to creating an Emergency Action Plan\",\n \"image\": {\n \"UUID\": \"1f445741-9ed9-414f-8a60-68239e502915\",\n \"name\": \"emergency-plan.jpg\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/emergency-plan.jpg?itok=RG84ODJ3\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/emergency-plan.jpg\"\n },\n \"body\": [\n {\n \"id\": 262,\n \"uuid\": \"3c8cf7f3-6494-41aa-8844-60ffb4a8dca4\",\n \"revision_id\": 595,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1583858101,\n \"parent_id\": \"227\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

How to Get Started

\\r\\n\\r\\n

The best time to handle an emergency is before it ever takes place. Before you create your emergency action plan, you'll need to analyze your business and see what potential hazards you face. These can vary depending on the type of business and your location. Some emergency action plans will cover problems dealing with hazardous materials on hand, some will need to deal with issues stemming from older buildings that were built to a lower-standard safety code, and some will need to have strategies in place to prepare for natural disasters more likely in certain areas, such as hurricanes, earthquakes, and tornadoes.

\\r\\n\\r\\n

While many things will be different depending on the type of emergency you are preparing for—what you do during a tornado or earthquake will be much different than what you do during a fire or workplace violence incident, for example—some of the basic preparations will be similar for multiple problems. Always provide steps for getting people to safety, whether that means sheltering or evacuating them, and always have a clear and effective plan for communicating with everyone who could be affected.

\\r\\n\\r\\n

Be sure to investigate not just what hazards you may face and how to stay safe during them, but also what effects they will have afterward. This should reveal such considerations as what lost income and increased expenses could be caused by your business being shut down for various amounts of time, the effect of lost customers, the delay of new business plans, and other effects of a disruption of service. Be as exact as possible in order to get a good idea of what costs you might accrue so you can most accurately plan for a disaster.

\\r\\n\\r\\n

FEMA provides a Business Impact Analysis Worksheet you can distribute to management and any other employees you feel can contribute to your preparations. Download the worksheet here: http://www.ready.gov/sites/default/files/documents/files/BusinessImpactAnalysis_Worksheet.pdf

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

How to Get Started

\\n

The best time to handle an emergency is before it ever takes place. Before you create your emergency action plan, you'll need to analyze your business and see what potential hazards you face. These can vary depending on the type of business and your location. Some emergency action plans will cover problems dealing with hazardous materials on hand, some will need to deal with issues stemming from older buildings that were built to a lower-standard safety code, and some will need to have strategies in place to prepare for natural disasters more likely in certain areas, such as hurricanes, earthquakes, and tornadoes.

\\n

While many things will be different depending on the type of emergency you are preparing for—what you do during a tornado or earthquake will be much different than what you do during a fire or workplace violence incident, for example—some of the basic preparations will be similar for multiple problems. Always provide steps for getting people to safety, whether that means sheltering or evacuating them, and always have a clear and effective plan for communicating with everyone who could be affected.

\\n

Be sure to investigate not just what hazards you may face and how to stay safe during them, but also what effects they will have afterward. This should reveal such considerations as what lost income and increased expenses could be caused by your business being shut down for various amounts of time, the effect of lost customers, the delay of new business plans, and other effects of a disruption of service. Be as exact as possible in order to get a good idea of what costs you might accrue so you can most accurately plan for a disaster.

\\n

FEMA provides a Business Impact Analysis Worksheet you can distribute to management and any other employees you feel can contribute to your preparations. Download the worksheet here: http://www.ready.gov/sites/default/files/documents/files/BusinessImpactAnalysis_Worksheet.pdf

\\n\"\n }\n },\n {\n \"id\": 263,\n \"uuid\": \"ec1ac160-2f77-46ed-ad14-05ae02cb089a\",\n \"revision_id\": 596,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1583858229,\n \"parent_id\": \"227\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

Create Your Emergency Action Plan

\\r\\n\\r\\n

Once you have identified all of the possible threats you may face and the potential effects, you should come up with responses for the hazards. Here are some tips to keep in mind.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

Create Your Emergency Action Plan

\\n

Once you have identified all of the possible threats you may face and the potential effects, you should come up with responses for the hazards. Here are some tips to keep in mind.

\\n\"\n }\n },\n {\n \"id\": 264,\n \"uuid\": \"6c1ea93c-3ef8-45db-a215-5294eba0e717\",\n \"revision_id\": 597,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1583858298,\n \"parent_id\": \"227\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_list_content\": {\n \"value\": \"
    \\r\\n\\t
  • For emergency situations, have an individual in charge of following and getting others to follow the procedures you outline. For larger companies, you may need more than one, in separate departments or as backups, but in this case make sure the hierarchy is clearly laid out. Employees must know this individual is in charge and has authority during an emergency.
  • \\r\\n\\t
  • Ensure the methods for reporting fires and other emergencies are clear, whether it's dialing 911, calling an internal emergency number, pulling a manual fire alarm, or other procedure which may change depending on the type of emergency.
  • \\r\\n\\t
  • Create evacuation policies and paths that are clear and easy to follow.
  • \\r\\n\\t
  • Have procedures in place for employees who must remain during the beginning of an evacuation to take care of greater hazards. This includes employees who must use fire extinguishers, shut down gas lines and/or electrical systems, or safeguard hazardous materials to keep a bad situation from getting worse.
  • \\r\\n\\t
  • Be prepared for the loss of computer hardware, software, and information related to technological disruptions, and find ways to back up and recover it.
  • \\r\\n\\t
  • Note who is able to perform medical care, from first aid to CPR, and make sure they are in the proper positions to do so.
  • \\r\\n\\t
  • Provide clear communication during and immediately after any dangerous incident.
  • \\r\\n
\\r\\n\",\n \"format\": \"list\",\n \"processed\": \"
    \\n
  • For emergency situations, have an individual in charge of following and getting others to follow the procedures you outline. For larger companies, you may need more than one, in separate departments or as backups, but in this case make sure the hierarchy is clearly laid out. Employees must know this individual is in charge and has authority during an emergency.
  • \\n
  • Ensure the methods for reporting fires and other emergencies are clear, whether it's dialing 911, calling an internal emergency number, pulling a manual fire alarm, or other procedure which may change depending on the type of emergency.
  • \\n
  • Create evacuation policies and paths that are clear and easy to follow.
  • \\n
  • Have procedures in place for employees who must remain during the beginning of an evacuation to take care of greater hazards. This includes employees who must use fire extinguishers, shut down gas lines and/or electrical systems, or safeguard hazardous materials to keep a bad situation from getting worse.
  • \\n
  • Be prepared for the loss of computer hardware, software, and information related to technological disruptions, and find ways to back up and recover it.
  • \\n
  • Note who is able to perform medical care, from first aid to CPR, and make sure they are in the proper positions to do so.
  • \\n
  • Provide clear communication during and immediately after any dangerous incident.
  • \\n
\\n\"\n },\n \"field_list_items\": []\n },\n {\n \"id\": 265,\n \"uuid\": \"ce2878bd-402e-4e04-ae93-3aa1ae3ca2d1\",\n \"revision_id\": 598,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1583858383,\n \"parent_id\": \"227\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

OSHA has several resources to help you prepare your emergency action plan.

\\r\\n\\r\\n\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

OSHA has several resources to help you prepare your emergency action plan.

\\n\\n\"\n }\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"960ad1e3-66e0-4388-baa7-62cbf7e87bdb\",\n \"nid\": 226,\n \"vid\": 611,\n \"url\": \"/node/226\",\n \"name\": \"Emergency Action Plan – Why Should You Have One?\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-10T18:53:36+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"6acf8cc1-ae88-411c-86f5-0998666ba4ec\",\n \"name\": \"node_226.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_226.zip\"\n },\n \"tags\": [\n {\n \"id\": \"425e382c-8fc9-4a46-a252-cb6f20bc42eb\",\n \"vid\": 83,\n \"tid\": 83,\n \"url\": \"/taxonomy/term/83\",\n \"name\": \"Leadership\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:33:24+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"fb473dd7-86a8-40a6-8a12-c9c80d46c2fb\",\n \"vid\": 80,\n \"tid\": 80,\n \"url\": \"/taxonomy/term/80\",\n \"name\": \"Occupational Safety and Health\",\n \"type\": \"category\",\n \"changed\": \"2021-02-01T00:30:23+0000\",\n \"description\": \"This topic includes content related to the safety, health, and welfare of people at work The goal of occupational safety and health programs is to foster a safe and healthy work environment.[3] OSH may also protect co-workers, family members, employers, customers, and many others who might be affected by the workplace environment. \"\n },\n \"description\": \"Rationale for why your workplace should have an Emergency Action Plan.\",\n \"image\": {\n \"UUID\": \"b302865b-6e06-44ab-91ce-7229de0490ad\",\n \"name\": \"isravel-raj-YuN8QjfBYUY-unsplash.jpg\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/isravel-raj-YuN8QjfBYUY-unsplash.jpg?itok=c2wu3JnG\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/isravel-raj-YuN8QjfBYUY-unsplash.jpg\"\n },\n \"body\": [\n {\n \"id\": 260,\n \"uuid\": \"3c623628-2b4b-418b-8206-1bb86e31c13a\",\n \"revision_id\": 582,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1583857015,\n \"parent_id\": \"226\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

The main reason to have an emergency action plan is to do as much as possible to keep your employees safe in case of disaster. The confusion of an emergency can make a bad situation worse and put lives at risk. The Federal Emergency Management Agency (FEMA) provides more reasons an emergency action plan is important from a purely business perspective.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

The main reason to have an emergency action plan is to do as much as possible to keep your employees safe in case of disaster. The confusion of an emergency can make a bad situation worse and put lives at risk. The Federal Emergency Management Agency (FEMA) provides more reasons an emergency action plan is important from a purely business perspective.

\\n\"\n }\n },\n {\n \"id\": 261,\n \"uuid\": \"076bcddf-01f7-42b1-9a41-5f9910d0114b\",\n \"revision_id\": 583,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1583856683,\n \"parent_id\": \"226\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_list_content\": {\n \"value\": \"
    \\r\\n\\t
  • Up to 40% of businesses affected by a natural or human-caused disaster never reopen. Having procedures in place to deal with disasters can help your business survive this difficult experience.
  • \\r\\n\\t
  • Customers may not understand the disaster and its effects on your business. They'll still expect products or service on time. If there's a significant delay, they may take their business to a competitor.
  • \\r\\n\\t
  • Even if a disaster does slow or shut down your business, a robust emergency action plan has procedures in place to contact customers and stakeholders quickly to keep them up to date on what has happened. News travels fast and perceptions are often different from reality. Staying on top of the information stream reduces negative perception.
  • \\r\\n\\t
  • Insurance often only provides partial assistance. It does not cover all losses and does not bring back lost customers.
  • \\r\\n\\t
  • Public agencies cannot be expected to provide total relief either. Many disasters can overwhelm their resources, meaning aid may not be immediate even when it is available.
  • \\r\\n\\t
  • Many large businesses are now expecting their suppliers to have preparations in place for emergencies, trying to make sure their own business will not be hurt if something happens to another company on the supply chain. Without a plan in place, your business could be given to a competitor.
  • \\r\\n
\\r\\n\",\n \"format\": \"list\",\n \"processed\": \"
    \\n
  • Up to 40% of businesses affected by a natural or human-caused disaster never reopen. Having procedures in place to deal with disasters can help your business survive this difficult experience.
  • \\n
  • Customers may not understand the disaster and its effects on your business. They'll still expect products or service on time. If there's a significant delay, they may take their business to a competitor.
  • \\n
  • Even if a disaster does slow or shut down your business, a robust emergency action plan has procedures in place to contact customers and stakeholders quickly to keep them up to date on what has happened. News travels fast and perceptions are often different from reality. Staying on top of the information stream reduces negative perception.
  • \\n
  • Insurance often only provides partial assistance. It does not cover all losses and does not bring back lost customers.
  • \\n
  • Public agencies cannot be expected to provide total relief either. Many disasters can overwhelm their resources, meaning aid may not be immediate even when it is available.
  • \\n
  • Many large businesses are now expecting their suppliers to have preparations in place for emergencies, trying to make sure their own business will not be hurt if something happens to another company on the supply chain. Without a plan in place, your business could be given to a competitor.
  • \\n
\\n\"\n },\n \"field_list_items\": []\n }\n ],\n \"discussion_status\": \"hidden\"\n }\n ]\n },\n {\n \"name\": \"Take Precautions: COVID-19\",\n \"url\": \"/api/groups/15/topics/99\",\n \"content\": [\n {\n \"id\": \"5d7dd7d2-7a00-4a9f-a1fc-428ce90cf6e9\",\n \"nid\": 252,\n \"vid\": 632,\n \"url\": \"/node/252\",\n \"name\": \"COVID-19: Don't Panic\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-26T15:25:39+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"83278a03-8995-4e83-bb9c-3e0ce6d3ad95\",\n \"name\": \"node_252.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_252.zip\"\n },\n \"tags\": [\n {\n \"id\": \"801623d6-5b1a-4934-afd2-e55f75f5bafc\",\n \"vid\": 94,\n \"tid\": 94,\n \"url\": \"/taxonomy/term/94\",\n \"name\": \"COVID-19\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:18:22+0000\"\n },\n {\n \"id\": \"eff406f7-0dff-4945-812a-be707a816230\",\n \"vid\": 95,\n \"tid\": 95,\n \"url\": \"/taxonomy/term/95\",\n \"name\": \"Coronavirus\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:45+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"e2d54015-6e0b-43aa-a6b6-bd8abf7e66f6\",\n \"vid\": 99,\n \"tid\": 99,\n \"url\": \"/taxonomy/term/99\",\n \"name\": \"Take Precautions: COVID-19\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:34:44+0000\",\n \"description\": \"The recent coronavirus outbreak is a serious health concern. Do you know how to protect yourself and others from serious illness? Arming yourself with information and strategies will help reduce the spread of disease and enable you to work effectively in the challenging circumstances of an outbreak.\"\n },\n \"description\": \"While the current coronavirus outbreak is a serious health concern, discover why keeping calm and staying properly informed are an important part of managing your response to an outbreak.\",\n \"image\": {\n \"UUID\": \"017d2e6b-ba9e-4e30-9b58-a8a82d30a5d9\",\n \"name\": \"01_dontpanic_preview_image_0.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/01_dontpanic_preview_image_0.png.jpg?itok=3SfGRscG\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/01_dontpanic_preview_image_0.png\"\n },\n \"body\": [\n {\n \"id\": 307,\n \"uuid\": \"f3795f1d-d8e2-42f4-a9f2-839ee9ea63a1\",\n \"revision_id\": 891,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584456088,\n \"parent_id\": \"252\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

While the current coronavirus outbreak is a serious health concern, discover why keeping calm and staying properly informed are an important part of managing your response to an outbreak.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

While the current coronavirus outbreak is a serious health concern, discover why keeping calm and staying properly informed are an important part of managing your response to an outbreak.

\\n\"\n }\n },\n {\n \"id\": 308,\n \"uuid\": \"0f6508ca-5139-4a69-8148-55134a59a357\",\n \"revision_id\": 892,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584456088,\n \"parent_id\": \"252\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_video\": \"https://youtu.be/hLDjZ8631Qc\"\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"258982dd-b38d-4a8e-98d2-9ab04f395b21\",\n \"nid\": 253,\n \"vid\": 604,\n \"url\": \"/node/253\",\n \"name\": \"COVID-19: Limit Contagion\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-26T15:25:18+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"ac84d99a-86c2-41f0-8ed1-95b3046abcc0\",\n \"name\": \"node_253.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_253.zip\"\n },\n \"tags\": [\n {\n \"id\": \"801623d6-5b1a-4934-afd2-e55f75f5bafc\",\n \"vid\": 94,\n \"tid\": 94,\n \"url\": \"/taxonomy/term/94\",\n \"name\": \"COVID-19\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:18:22+0000\"\n },\n {\n \"id\": \"eff406f7-0dff-4945-812a-be707a816230\",\n \"vid\": 95,\n \"tid\": 95,\n \"url\": \"/taxonomy/term/95\",\n \"name\": \"Coronavirus\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:45+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"e2d54015-6e0b-43aa-a6b6-bd8abf7e66f6\",\n \"vid\": 99,\n \"tid\": 99,\n \"url\": \"/taxonomy/term/99\",\n \"name\": \"Take Precautions: COVID-19\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:34:44+0000\",\n \"description\": \"The recent coronavirus outbreak is a serious health concern. Do you know how to protect yourself and others from serious illness? Arming yourself with information and strategies will help reduce the spread of disease and enable you to work effectively in the challenging circumstances of an outbreak.\"\n },\n \"description\": \"The best way to avoid catching any virus is to avoid being exposed to that virus in the first place. Learn some expert-recommended strategies to reduce your chances of becoming ill and of infecting others.\",\n \"image\": {\n \"UUID\": \"208859b6-2b45-484e-8e21-f5285c888379\",\n \"name\": \"02_limit_contagion_preview_image_0.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/02_limit_contagion_preview_image_0.png.jpg?itok=b1DYtoSP\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/02_limit_contagion_preview_image_0.png\"\n },\n \"body\": [\n {\n \"id\": 309,\n \"uuid\": \"fbaa1d75-7b7e-44c8-9e30-f0eabc41e7e9\",\n \"revision_id\": 889,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584457096,\n \"parent_id\": \"253\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

The best way to avoid catching any virus is to avoid being exposed to that virus in the first place. Learn some expert-recommended strategies to reduce your chances of becoming ill and of infecting others.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

The best way to avoid catching any virus is to avoid being exposed to that virus in the first place. Learn some expert-recommended strategies to reduce your chances of becoming ill and of infecting others.

\\n\"\n }\n },\n {\n \"id\": 310,\n \"uuid\": \"a22733ae-1e8b-4e1b-9521-7eb6f8218480\",\n \"revision_id\": 890,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584457096,\n \"parent_id\": \"253\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_video\": \"https://youtu.be/YaxyOuRaPzY\"\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"3947b0c3-e992-4930-89f4-56181045269d\",\n \"nid\": 254,\n \"vid\": 605,\n \"url\": \"/node/254\",\n \"name\": \"COVID-19: Manage Social Symptoms\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-26T15:24:52+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"85bd4579-cd04-4120-ad22-07a9ee9b7071\",\n \"name\": \"node_254.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_254.zip\"\n },\n \"tags\": [\n {\n \"id\": \"801623d6-5b1a-4934-afd2-e55f75f5bafc\",\n \"vid\": 94,\n \"tid\": 94,\n \"url\": \"/taxonomy/term/94\",\n \"name\": \"COVID-19\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:18:22+0000\"\n },\n {\n \"id\": \"eff406f7-0dff-4945-812a-be707a816230\",\n \"vid\": 95,\n \"tid\": 95,\n \"url\": \"/taxonomy/term/95\",\n \"name\": \"Coronavirus\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:45+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"e2d54015-6e0b-43aa-a6b6-bd8abf7e66f6\",\n \"vid\": 99,\n \"tid\": 99,\n \"url\": \"/taxonomy/term/99\",\n \"name\": \"Take Precautions: COVID-19\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:34:44+0000\",\n \"description\": \"The recent coronavirus outbreak is a serious health concern. Do you know how to protect yourself and others from serious illness? Arming yourself with information and strategies will help reduce the spread of disease and enable you to work effectively in the challenging circumstances of an outbreak.\"\n },\n \"description\": \"Misinformation and fear can lead to xenophobia and hostility during an outbreak. While it’s normal to be concerned about preventing illness, use these strategies to ensure that your concern is focused on fighting the disease itself.\",\n \"image\": {\n \"UUID\": \"18dbdfd2-0551-4eb2-9d15-d70b24564f45\",\n \"name\": \"03_manage_social_symptoms_preview_image_0.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/03_manage_social_symptoms_preview_image_0.png.jpg?itok=US_PLy25\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/03_manage_social_symptoms_preview_image_0.png\"\n },\n \"body\": [\n {\n \"id\": 311,\n \"uuid\": \"16452dc7-da79-4d2e-b17e-66044e556e8f\",\n \"revision_id\": 887,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584457478,\n \"parent_id\": \"254\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

Misinformation and fear can lead to xenophobia and hostility during an outbreak. While it’s normal to be concerned about preventing illness, use these strategies to ensure that your concern is focused on fighting the disease itself.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

Misinformation and fear can lead to xenophobia and hostility during an outbreak. While it’s normal to be concerned about preventing illness, use these strategies to ensure that your concern is focused on fighting the disease itself.

\\n\"\n }\n },\n {\n \"id\": 312,\n \"uuid\": \"57b12ed2-ced1-49a2-9249-a4fd88d6740d\",\n \"revision_id\": 888,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584457486,\n \"parent_id\": \"254\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_video\": \"https://youtu.be/2Gg8clhfyAE\"\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"1b2fee1e-fb4c-4237-83e4-383002922b92\",\n \"nid\": 255,\n \"vid\": 633,\n \"url\": \"/node/255\",\n \"name\": \"COVID-19: Get a Flu Shot\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-26T15:24:30+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"d7140275-9264-4769-bc7f-cf754598e7f7\",\n \"name\": \"node_255.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_255.zip\"\n },\n \"tags\": [\n {\n \"id\": \"801623d6-5b1a-4934-afd2-e55f75f5bafc\",\n \"vid\": 94,\n \"tid\": 94,\n \"url\": \"/taxonomy/term/94\",\n \"name\": \"COVID-19\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:18:22+0000\"\n },\n {\n \"id\": \"eff406f7-0dff-4945-812a-be707a816230\",\n \"vid\": 95,\n \"tid\": 95,\n \"url\": \"/taxonomy/term/95\",\n \"name\": \"Coronavirus\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:45+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"e2d54015-6e0b-43aa-a6b6-bd8abf7e66f6\",\n \"vid\": 99,\n \"tid\": 99,\n \"url\": \"/taxonomy/term/99\",\n \"name\": \"Take Precautions: COVID-19\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:34:44+0000\",\n \"description\": \"The recent coronavirus outbreak is a serious health concern. Do you know how to protect yourself and others from serious illness? Arming yourself with information and strategies will help reduce the spread of disease and enable you to work effectively in the challenging circumstances of an outbreak.\"\n },\n \"description\": \"There isn’t a vaccine readily available for coronavirus. Learn why getting an annual flu shot can still help protect you and those around you during the coronavirus outbreak.\",\n \"image\": {\n \"UUID\": \"428d0f8a-3511-45a8-a24b-4e334babddcb\",\n \"name\": \"04_get_flu_shot_preview_image_1.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/04_get_flu_shot_preview_image_1.png.jpg?itok=rZLjaHrn\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/04_get_flu_shot_preview_image_1.png\"\n },\n \"body\": [\n {\n \"id\": 313,\n \"uuid\": \"f44e2157-6bb7-4d8a-9853-c78a4d4b4702\",\n \"revision_id\": 885,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584458472,\n \"parent_id\": \"255\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

There isn’t a vaccine readily available for coronavirus. Learn why getting an annual flu shot can still help protect you and those around you during the coronavirus outbreak.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

There isn’t a vaccine readily available for coronavirus. Learn why getting an annual flu shot can still help protect you and those around you during the coronavirus outbreak.

\\n\"\n }\n },\n {\n \"id\": 314,\n \"uuid\": \"43eec42d-3d6c-4445-9eed-139342bbb9b0\",\n \"revision_id\": 886,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584458485,\n \"parent_id\": \"255\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_video\": \"https://youtu.be/lSyPts0lr1E\"\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"3f18f2a0-2f3c-4114-94cf-1222d389f877\",\n \"nid\": 256,\n \"vid\": 606,\n \"url\": \"/node/256\",\n \"name\": \"COVID-19: Manage the Timeline of Infection\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-26T15:24:04+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"f2ae69e5-f95f-4119-abba-53fd85a30014\",\n \"name\": \"node_256.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_256.zip\"\n },\n \"tags\": [\n {\n \"id\": \"801623d6-5b1a-4934-afd2-e55f75f5bafc\",\n \"vid\": 94,\n \"tid\": 94,\n \"url\": \"/taxonomy/term/94\",\n \"name\": \"COVID-19\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:18:22+0000\"\n },\n {\n \"id\": \"eff406f7-0dff-4945-812a-be707a816230\",\n \"vid\": 95,\n \"tid\": 95,\n \"url\": \"/taxonomy/term/95\",\n \"name\": \"Coronavirus\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:45+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"e2d54015-6e0b-43aa-a6b6-bd8abf7e66f6\",\n \"vid\": 99,\n \"tid\": 99,\n \"url\": \"/taxonomy/term/99\",\n \"name\": \"Take Precautions: COVID-19\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:34:44+0000\",\n \"description\": \"The recent coronavirus outbreak is a serious health concern. Do you know how to protect yourself and others from serious illness? Arming yourself with information and strategies will help reduce the spread of disease and enable you to work effectively in the challenging circumstances of an outbreak.\"\n },\n \"description\": \"Sick people can often spread illness before they show symptoms. Learn the main ways viruses are spread and what you should do if you become ill to avoid infecting others.\",\n \"image\": {\n \"UUID\": \"0c1fd93c-30c0-4297-acb7-3aec3e61bcf3\",\n \"name\": \"05_manage_timeline_infection_preview_image_0.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/05_manage_timeline_infection_preview_image_0.png.jpg?itok=zslh7Ueq\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/05_manage_timeline_infection_preview_image_0.png\"\n },\n \"body\": [\n {\n \"id\": 315,\n \"uuid\": \"70acb4e6-ba50-407c-beb0-c18eee07ce2e\",\n \"revision_id\": 883,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584458626,\n \"parent_id\": \"256\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

Sick people can often spread illness before they show symptoms. Learn the main ways viruses are spread and what you should do if you become ill to avoid infecting others.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

Sick people can often spread illness before they show symptoms. Learn the main ways viruses are spread and what you should do if you become ill to avoid infecting others.

\\n\"\n }\n },\n {\n \"id\": 316,\n \"uuid\": \"e2b4276b-9997-4b89-a450-33a3cea014ab\",\n \"revision_id\": 884,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584458626,\n \"parent_id\": \"256\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_video\": \"https://youtu.be/szvRf458bC8\"\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"2cf688b8-5f12-4d0a-b777-6b56eb323983\",\n \"nid\": 257,\n \"vid\": 607,\n \"url\": \"/node/257\",\n \"name\": \"COVID-19: Prepare to Isolate\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-26T15:23:31+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"812cf891-c59b-46cf-b168-ab7b115118de\",\n \"name\": \"node_257.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_257.zip\"\n },\n \"tags\": [\n {\n \"id\": \"801623d6-5b1a-4934-afd2-e55f75f5bafc\",\n \"vid\": 94,\n \"tid\": 94,\n \"url\": \"/taxonomy/term/94\",\n \"name\": \"COVID-19\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:18:22+0000\"\n },\n {\n \"id\": \"eff406f7-0dff-4945-812a-be707a816230\",\n \"vid\": 95,\n \"tid\": 95,\n \"url\": \"/taxonomy/term/95\",\n \"name\": \"Coronavirus\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:45+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"e2d54015-6e0b-43aa-a6b6-bd8abf7e66f6\",\n \"vid\": 99,\n \"tid\": 99,\n \"url\": \"/taxonomy/term/99\",\n \"name\": \"Take Precautions: COVID-19\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:34:44+0000\",\n \"description\": \"The recent coronavirus outbreak is a serious health concern. Do you know how to protect yourself and others from serious illness? Arming yourself with information and strategies will help reduce the spread of disease and enable you to work effectively in the challenging circumstances of an outbreak.\"\n },\n \"description\": \"Discover what proactive steps you can take to be prepared in the event that you or someone in your household gets sick.\",\n \"image\": {\n \"UUID\": \"6b2c984f-7043-476f-bc7c-e221882a4f84\",\n \"name\": \"06_prepare_to_isolate_preview_image_0.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/06_prepare_to_isolate_preview_image_0.png.jpg?itok=H7necaWh\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/06_prepare_to_isolate_preview_image_0.png\"\n },\n \"body\": [\n {\n \"id\": 317,\n \"uuid\": \"3afe06d1-6012-45ad-9e96-0b69f7aefe77\",\n \"revision_id\": 881,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584458917,\n \"parent_id\": \"257\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

Discover what proactive steps you can take to be prepared in the event that you or someone in your household gets sick.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

Discover what proactive steps you can take to be prepared in the event that you or someone in your household gets sick.

\\n\"\n }\n },\n {\n \"id\": 318,\n \"uuid\": \"57438bfd-6e92-45f6-a1e9-8b061fa7acdf\",\n \"revision_id\": 882,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584458917,\n \"parent_id\": \"257\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_video\": \"https://youtu.be/fo9BXZJDjMY\"\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"ccbbc825-2188-45e0-9ec7-5bc1567f2b95\",\n \"nid\": 258,\n \"vid\": 609,\n \"url\": \"/node/258\",\n \"name\": \"COVID-19: Work Virtually\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-26T15:23:07+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"d50da248-7850-43bf-8444-324748aec4e1\",\n \"name\": \"node_258.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_258.zip\"\n },\n \"tags\": [\n {\n \"id\": \"801623d6-5b1a-4934-afd2-e55f75f5bafc\",\n \"vid\": 94,\n \"tid\": 94,\n \"url\": \"/taxonomy/term/94\",\n \"name\": \"COVID-19\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:18:22+0000\"\n },\n {\n \"id\": \"eff406f7-0dff-4945-812a-be707a816230\",\n \"vid\": 95,\n \"tid\": 95,\n \"url\": \"/taxonomy/term/95\",\n \"name\": \"Coronavirus\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:45+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"e2d54015-6e0b-43aa-a6b6-bd8abf7e66f6\",\n \"vid\": 99,\n \"tid\": 99,\n \"url\": \"/taxonomy/term/99\",\n \"name\": \"Take Precautions: COVID-19\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:34:44+0000\",\n \"description\": \"The recent coronavirus outbreak is a serious health concern. Do you know how to protect yourself and others from serious illness? Arming yourself with information and strategies will help reduce the spread of disease and enable you to work effectively in the challenging circumstances of an outbreak.\"\n },\n \"description\": \"You may need to work virtually during an outbreak, which can be difficult if this isn’t normal for your workplace. Learn strategies to communicate effectively with your team and maintain a high quality of work when you work virtually.\",\n \"image\": {\n \"UUID\": \"d20490ca-60fa-48c3-b2be-6de2751e438b\",\n \"name\": \"07_work_virtually_preview_image_0.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/07_work_virtually_preview_image_0.png.jpg?itok=i97BI50p\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/07_work_virtually_preview_image_0.png\"\n },\n \"body\": [\n {\n \"id\": 319,\n \"uuid\": \"1f5b5d3f-dd49-4ce5-aada-2c7a5a1d0b3d\",\n \"revision_id\": 879,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584459356,\n \"parent_id\": \"258\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

You may need to work virtually during an outbreak, which can be difficult if this isn’t normal for your workplace. Learn strategies to communicate effectively with your team and maintain a high quality of work when you work virtually.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

You may need to work virtually during an outbreak, which can be difficult if this isn’t normal for your workplace. Learn strategies to communicate effectively with your team and maintain a high quality of work when you work virtually.

\\n\"\n }\n },\n {\n \"id\": 320,\n \"uuid\": \"39e5fada-8827-4ba5-b0d5-674d280cf993\",\n \"revision_id\": 880,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584459420,\n \"parent_id\": \"258\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_video\": \"https://youtu.be/UEPFhQGcSek\"\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"800ce9a7-7066-4195-87bb-1eecc9bfac3f\",\n \"nid\": 259,\n \"vid\": 631,\n \"url\": \"/node/259\",\n \"name\": \"COVID-19: Conclusion\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-26T15:22:41+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"5158b8d2-eaee-413e-84d9-8cab8de01704\",\n \"name\": \"node_259.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_259.zip\"\n },\n \"tags\": [\n {\n \"id\": \"801623d6-5b1a-4934-afd2-e55f75f5bafc\",\n \"vid\": 94,\n \"tid\": 94,\n \"url\": \"/taxonomy/term/94\",\n \"name\": \"COVID-19\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:18:22+0000\"\n },\n {\n \"id\": \"eff406f7-0dff-4945-812a-be707a816230\",\n \"vid\": 95,\n \"tid\": 95,\n \"url\": \"/taxonomy/term/95\",\n \"name\": \"Coronavirus\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:45+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"e2d54015-6e0b-43aa-a6b6-bd8abf7e66f6\",\n \"vid\": 99,\n \"tid\": 99,\n \"url\": \"/taxonomy/term/99\",\n \"name\": \"Take Precautions: COVID-19\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:34:44+0000\",\n \"description\": \"The recent coronavirus outbreak is a serious health concern. Do you know how to protect yourself and others from serious illness? Arming yourself with information and strategies will help reduce the spread of disease and enable you to work effectively in the challenging circumstances of an outbreak.\"\n },\n \"description\": \"Stay informed, take proper precautions, and keep washing your hands. Thanks for joining us here at Eleventure®. Higher learning. At work.\",\n \"image\": {\n \"UUID\": \"e40ae7b4-dd96-47c4-9213-5c92fe3f44dd\",\n \"name\": \"08_conclusion_preview_image_0.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/08_conclusion_preview_image_0.png.jpg?itok=Q9H3obzu\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/08_conclusion_preview_image_0.png\"\n },\n \"body\": [\n {\n \"id\": 321,\n \"uuid\": \"e0c4c1f2-2fcd-421a-b1b8-cbbea203b114\",\n \"revision_id\": 877,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584460058,\n \"parent_id\": \"259\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

Stay informed, take proper precautions, and keep washing your hands. Thanks for joining us here at Eleventure. Higher learning. At work.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

Stay informed, take proper precautions, and keep washing your hands. Thanks for joining us here at Eleventure. Higher learning. At work.

\\n\"\n }\n },\n {\n \"id\": 322,\n \"uuid\": \"0c54afab-f847-4181-831b-dbc0ea5a500b\",\n \"revision_id\": 878,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584460058,\n \"parent_id\": \"259\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_video\": \"https://youtu.be/mEYCQsBloEA\"\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"d8d056ea-ad88-4955-8a5d-a4e18be78233\",\n \"nid\": 271,\n \"vid\": 608,\n \"url\": \"/node/271\",\n \"name\": \"COVID-19: Prepare to Work Virtually\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-26T15:21:44+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"9cb9259d-b937-49b0-8233-933e3fb43a90\",\n \"name\": \"node_271.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_271.zip\"\n },\n \"tags\": [\n {\n \"id\": \"801623d6-5b1a-4934-afd2-e55f75f5bafc\",\n \"vid\": 94,\n \"tid\": 94,\n \"url\": \"/taxonomy/term/94\",\n \"name\": \"COVID-19\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:18:22+0000\"\n },\n {\n \"id\": \"eff406f7-0dff-4945-812a-be707a816230\",\n \"vid\": 95,\n \"tid\": 95,\n \"url\": \"/taxonomy/term/95\",\n \"name\": \"Coronavirus\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:45+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"e2d54015-6e0b-43aa-a6b6-bd8abf7e66f6\",\n \"vid\": 99,\n \"tid\": 99,\n \"url\": \"/taxonomy/term/99\",\n \"name\": \"Take Precautions: COVID-19\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:34:44+0000\",\n \"description\": \"The recent coronavirus outbreak is a serious health concern. Do you know how to protect yourself and others from serious illness? Arming yourself with information and strategies will help reduce the spread of disease and enable you to work effectively in the challenging circumstances of an outbreak.\"\n },\n \"description\": \"During a disease outbreak, you may need to work from home (although not every job allows for this\\r\\ndegree of flexibility). If you do not ordinarily work remotely, ensure that you are prepared with all the\\r\\ntools you need and that you have a plan to help you be as productive as you would be at work.\",\n \"image\": {\n \"UUID\": \"e98de4da-ed4a-4d0a-b22f-5176b441eaa6\",\n \"name\": \"09_prepare_to_work_from_home_preview_image.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/09_prepare_to_work_from_home_preview_image.png.jpg?itok=FQ2SYuG_\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/09_prepare_to_work_from_home_preview_image.png\"\n },\n \"body\": [\n {\n \"id\": 345,\n \"uuid\": \"94c77451-3435-4e0b-b127-495acd4cf815\",\n \"revision_id\": 875,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584542670,\n \"parent_id\": \"271\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

During a disease outbreak, you may need to work from home (although not every job allows for this degree of flexibility). If you do not ordinarily work remotely, ensure that you are prepared with all the tools you need and that you have a plan to help you be as productive as you would be at work.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

During a disease outbreak, you may need to work from home (although not every job allows for this degree of flexibility). If you do not ordinarily work remotely, ensure that you are prepared with all the tools you need and that you have a plan to help you be as productive as you would be at work.

\\n\"\n }\n },\n {\n \"id\": 346,\n \"uuid\": \"2b01dbc7-5fc5-4a59-8ec5-92a51f5d4813\",\n \"revision_id\": 876,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584542734,\n \"parent_id\": \"271\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_document\": {\n \"target_id\": 238,\n \"display\": true,\n \"description\": \"\"\n }\n }\n ],\n \"discussion_status\": \"hidden\"\n }\n ]\n },\n {\n \"name\": \"Virtual Team\",\n \"url\": \"/api/groups/15/topics/100\",\n \"content\": [\n {\n \"id\": \"9fecf981-8d5e-45d8-a499-8528be027418\",\n \"nid\": 275,\n \"vid\": 622,\n \"url\": \"/node/275\",\n \"name\": \"Lead Your Virtual Team: Lead Successful Meetings\",\n \"type\": \"learn_article\",\n \"changed\": \"2021-01-21T00:26:56+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"ab179d6d-aa5e-4d0e-b4a4-5926f69f0cd8\",\n \"name\": \"node_275.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_275.zip\"\n },\n \"tags\": [\n {\n \"id\": \"2e03cfc6-7b44-4853-a629-1283b7b6b5cd\",\n \"vid\": 93,\n \"tid\": 93,\n \"url\": \"/taxonomy/term/93\",\n \"name\": \"SLGO\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-16T19:38:00+0000\"\n },\n {\n \"id\": \"81d34d52-d62b-4769-9ab4-3f07897372c5\",\n \"vid\": 97,\n \"tid\": 97,\n \"url\": \"/taxonomy/term/97\",\n \"name\": \"Work from Home\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:24+0000\"\n },\n {\n \"id\": \"a2cfcf08-21e8-4d9e-a0a2-e4ce0ff9f58b\",\n \"vid\": 96,\n \"tid\": 96,\n \"url\": \"/taxonomy/term/96\",\n \"name\": \"Working Remotely\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:32+0000\"\n },\n {\n \"id\": \"f49d9d61-21ba-472d-9100-3e83beeacf33\",\n \"vid\": 98,\n \"tid\": 98,\n \"url\": \"/taxonomy/term/98\",\n \"name\": \"Virtual Team\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:03+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"39299858-9ea2-4e61-bf1e-7c7a8a91bdc9\",\n \"vid\": 100,\n \"tid\": 100,\n \"url\": \"/taxonomy/term/100\",\n \"name\": \"Virtual Team\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:18:16+0000\",\n \"description\": \"These days everything’s moving online… even your team. Are you ready? Knowing how to identify the dynamics of your team, communicate clearly with everyone & foster trust will give you the basic skills you need as a manager to bridge the distance & form your virtual team. \"\n },\n \"description\": \"Virtual meetings have a special set of challenges. To start, they often involve more advance planning\\r\\nand preparation. You’ll need to accommodate time schedules and time zones. To keep meetings on\\r\\ntrack, you’ll want to plan and send agendas beforehand.\",\n \"image\": {\n \"UUID\": \"6a5a47c3-7ab4-4906-abc4-1606fb139e10\",\n \"name\": \"Lead-successful_meetings_preview_image.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/Lead-successful_meetings_preview_image.png.jpg?itok=CQ4zVc1q\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/Lead-successful_meetings_preview_image.png\"\n },\n \"body\": [\n {\n \"id\": 352,\n \"uuid\": \"274a885f-9f82-4cd7-ab06-5adb5a03584d\",\n \"revision_id\": 928,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584547416,\n \"parent_id\": \"275\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

Virtual meetings have a special set of challenges. To start, they often involve more advance planning and preparation. You’ll need to accommodate time schedules and time zones. To keep meetings on track, you’ll want to plan and send agendas beforehand. 

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

Virtual meetings have a special set of challenges. To start, they often involve more advance planning and preparation. You’ll need to accommodate time schedules and time zones. To keep meetings on track, you’ll want to plan and send agendas beforehand. 

\\n\"\n }\n },\n {\n \"id\": 353,\n \"uuid\": \"4442ab52-62ae-46d4-b9aa-4995f2489975\",\n \"revision_id\": 929,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584547533,\n \"parent_id\": \"275\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_document\": {\n \"target_id\": 246,\n \"display\": true,\n \"description\": \"\"\n }\n }\n ],\n \"discussion_status\": \"open\"\n },\n {\n \"id\": \"ba541590-ac32-4021-b005-001e87b824e4\",\n \"nid\": 273,\n \"vid\": 617,\n \"url\": \"/node/273\",\n \"name\": \"Form Your Virtual Team: Identify the Environment\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-06-11T20:03:11+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"f0860bf7-9d40-4b01-a227-2a1ffa396380\",\n \"name\": \"node_273.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_273.zip\"\n },\n \"tags\": [\n {\n \"id\": \"2e03cfc6-7b44-4853-a629-1283b7b6b5cd\",\n \"vid\": 93,\n \"tid\": 93,\n \"url\": \"/taxonomy/term/93\",\n \"name\": \"SLGO\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-16T19:38:00+0000\"\n },\n {\n \"id\": \"a2cfcf08-21e8-4d9e-a0a2-e4ce0ff9f58b\",\n \"vid\": 96,\n \"tid\": 96,\n \"url\": \"/taxonomy/term/96\",\n \"name\": \"Working Remotely\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:32+0000\"\n },\n {\n \"id\": \"81d34d52-d62b-4769-9ab4-3f07897372c5\",\n \"vid\": 97,\n \"tid\": 97,\n \"url\": \"/taxonomy/term/97\",\n \"name\": \"Work from Home\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:24+0000\"\n },\n {\n \"id\": \"f49d9d61-21ba-472d-9100-3e83beeacf33\",\n \"vid\": 98,\n \"tid\": 98,\n \"url\": \"/taxonomy/term/98\",\n \"name\": \"Virtual Team\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:03+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"39299858-9ea2-4e61-bf1e-7c7a8a91bdc9\",\n \"vid\": 100,\n \"tid\": 100,\n \"url\": \"/taxonomy/term/100\",\n \"name\": \"Virtual Team\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:18:16+0000\",\n \"description\": \"These days everything’s moving online… even your team. Are you ready? Knowing how to identify the dynamics of your team, communicate clearly with everyone & foster trust will give you the basic skills you need as a manager to bridge the distance & form your virtual team. \"\n },\n \"description\": \"Take the time to consider the environment surrounding your virtual team. Where are members\\r\\nphysically located? What time differences and cultural boundaries will impact how you will work? Use\\r\\nthis checklist to determine these critical environmental factors.\",\n \"image\": {\n \"UUID\": \"f6bdfdc9-31c5-46e3-b43a-8f073cb9ae87\",\n \"name\": \"identify_environment_preview_image_0.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/identify_environment_preview_image_0.png.jpg?itok=jkvYy0gv\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/identify_environment_preview_image_0.png\"\n },\n \"body\": [\n {\n \"id\": 348,\n \"uuid\": \"3b023d03-b180-49fe-98ad-809051659fb3\",\n \"revision_id\": 789,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584544601,\n \"parent_id\": \"273\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": true,\n \"field_paragraph_body\": {\n \"value\": \"

 

\\r\\n\\r\\n

 Take the time to consider the environment surrounding your virtual team. Where are members physically located? What time differences and cultural boundaries will impact how you will work? Use this checklist to determine these critical environmental factors. 

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

 

\\n

 Take the time to consider the environment surrounding your virtual team. Where are members physically located? What time differences and cultural boundaries will impact how you will work? Use this checklist to determine these critical environmental factors. 

\\n\"\n }\n },\n {\n \"id\": 349,\n \"uuid\": \"7a0cbe76-7dcd-4317-8c48-f7039ab09d8d\",\n \"revision_id\": 790,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584544651,\n \"parent_id\": \"273\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": true,\n \"field_document\": {\n \"target_id\": 242,\n \"display\": true,\n \"description\": \"\"\n }\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"6f4b9aa4-f025-4a9e-9d65-e3f021feb478\",\n \"nid\": 274,\n \"vid\": 618,\n \"url\": \"/node/274\",\n \"name\": \"Form Your Virtual Team: Identify Your Team's Virtual Environment\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-06-11T20:03:11+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"e04b2083-3567-46df-b6dc-444113f21a3a\",\n \"name\": \"node_274.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_274.zip\"\n },\n \"tags\": [\n {\n \"id\": \"2e03cfc6-7b44-4853-a629-1283b7b6b5cd\",\n \"vid\": 93,\n \"tid\": 93,\n \"url\": \"/taxonomy/term/93\",\n \"name\": \"SLGO\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-16T19:38:00+0000\"\n },\n {\n \"id\": \"81d34d52-d62b-4769-9ab4-3f07897372c5\",\n \"vid\": 97,\n \"tid\": 97,\n \"url\": \"/taxonomy/term/97\",\n \"name\": \"Work from Home\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:24+0000\"\n },\n {\n \"id\": \"a2cfcf08-21e8-4d9e-a0a2-e4ce0ff9f58b\",\n \"vid\": 96,\n \"tid\": 96,\n \"url\": \"/taxonomy/term/96\",\n \"name\": \"Working Remotely\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:32+0000\"\n },\n {\n \"id\": \"f49d9d61-21ba-472d-9100-3e83beeacf33\",\n \"vid\": 98,\n \"tid\": 98,\n \"url\": \"/taxonomy/term/98\",\n \"name\": \"Virtual Team\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:03+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"39299858-9ea2-4e61-bf1e-7c7a8a91bdc9\",\n \"vid\": 100,\n \"tid\": 100,\n \"url\": \"/taxonomy/term/100\",\n \"name\": \"Virtual Team\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:18:16+0000\",\n \"description\": \"These days everything’s moving online… even your team. Are you ready? Knowing how to identify the dynamics of your team, communicate clearly with everyone & foster trust will give you the basic skills you need as a manager to bridge the distance & form your virtual team. \"\n },\n \"description\": \"Where your team members are located matters and it makes a difference in how you craft your\\r\\nmanagement strategy. Consider how the three factors of physical location, time difference, and\\r\\ncultural boundaries impact and shape your team’s environment.\",\n \"image\": {\n \"UUID\": \"f5280391-910e-49c4-aee1-2f3e4b82f99c\",\n \"name\": \"identify_Virtual_environment_preview_image.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/identify_Virtual_environment_preview_image.png.jpg?itok=hqJ4i49c\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/identify_Virtual_environment_preview_image.png\"\n },\n \"body\": [\n {\n \"id\": 350,\n \"uuid\": \"ea0bb7dd-1d34-4013-9fa0-901fb1235bce\",\n \"revision_id\": 791,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584545130,\n \"parent_id\": \"274\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": true,\n \"field_paragraph_body\": {\n \"value\": \"

Where your team members are located matters and it makes a difference in how you craft your management strategy. Consider how the three factors of physical location, time difference, and cultural boundaries impact and shape your team’s environment. 

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

Where your team members are located matters and it makes a difference in how you craft your management strategy. Consider how the three factors of physical location, time difference, and cultural boundaries impact and shape your team’s environment. 

\\n\"\n }\n },\n {\n \"id\": 351,\n \"uuid\": \"31b890db-9c89-4e72-8426-e45bbedcde59\",\n \"revision_id\": 792,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584545184,\n \"parent_id\": \"274\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": true,\n \"field_document\": {\n \"target_id\": 244,\n \"display\": true,\n \"description\": \"\"\n }\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"c2e5e16a-6354-4fcb-b82d-74915c561f9f\",\n \"nid\": 260,\n \"vid\": 619,\n \"url\": \"/node/260\",\n \"name\": \"Form Your Virtual Team: Set Your Team Up for Success\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-18T14:25:40+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"d839c9cc-0a69-4b3e-be8d-7641b71f4470\",\n \"name\": \"node_260.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_260.zip\"\n },\n \"tags\": [\n {\n \"id\": \"2e03cfc6-7b44-4853-a629-1283b7b6b5cd\",\n \"vid\": 93,\n \"tid\": 93,\n \"url\": \"/taxonomy/term/93\",\n \"name\": \"SLGO\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-16T19:38:00+0000\"\n },\n {\n \"id\": \"a2cfcf08-21e8-4d9e-a0a2-e4ce0ff9f58b\",\n \"vid\": 96,\n \"tid\": 96,\n \"url\": \"/taxonomy/term/96\",\n \"name\": \"Working Remotely\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:32+0000\"\n },\n {\n \"id\": \"81d34d52-d62b-4769-9ab4-3f07897372c5\",\n \"vid\": 97,\n \"tid\": 97,\n \"url\": \"/taxonomy/term/97\",\n \"name\": \"Work from Home\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:24+0000\"\n },\n {\n \"id\": \"f49d9d61-21ba-472d-9100-3e83beeacf33\",\n \"vid\": 98,\n \"tid\": 98,\n \"url\": \"/taxonomy/term/98\",\n \"name\": \"Virtual Team\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:03+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"39299858-9ea2-4e61-bf1e-7c7a8a91bdc9\",\n \"vid\": 100,\n \"tid\": 100,\n \"url\": \"/taxonomy/term/100\",\n \"name\": \"Virtual Team\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:18:16+0000\",\n \"description\": \"These days everything’s moving online… even your team. Are you ready? Knowing how to identify the dynamics of your team, communicate clearly with everyone & foster trust will give you the basic skills you need as a manager to bridge the distance & form your virtual team. \"\n },\n \"description\": \"Whether your organization is going global or you’re bringing on remote hires, there are a few things you’ll need to do consistently to form an effective virtual team.\",\n \"image\": {\n \"UUID\": \"c692dd57-f6b4-413b-999c-5264b30577e7\",\n \"name\": \"set_your_team_up_success_preview_image_1.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/set_your_team_up_success_preview_image_1.png.jpg?itok=PNY3KUjH\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/set_your_team_up_success_preview_image_1.png\"\n },\n \"body\": [\n {\n \"id\": 323,\n \"uuid\": \"c47ec5f4-b866-47ac-954a-a3e5c2263396\",\n \"revision_id\": 782,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584460394,\n \"parent_id\": \"260\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

Whether your organization is going global or you’re bringing on remote hires, there are a few things you’ll need to do consistently to form an effective virtual team.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

Whether your organization is going global or you’re bringing on remote hires, there are a few things you’ll need to do consistently to form an effective virtual team.

\\n\"\n }\n },\n {\n \"id\": 324,\n \"uuid\": \"b4de99e0-864b-4a5d-a754-71a169f982d3\",\n \"revision_id\": 783,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584460394,\n \"parent_id\": \"260\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_video\": \"https://youtu.be/3t6v6bE_l8w\"\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"cbdb4d52-68a3-4c9c-9177-d37d0c973232\",\n \"nid\": 261,\n \"vid\": 615,\n \"url\": \"/node/261\",\n \"name\": \"Form Your Virtual Team: Consider Your Team\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-18T14:25:13+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"93dab80a-0f9c-433c-b644-a296da18ddcc\",\n \"name\": \"node_261.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_261.zip\"\n },\n \"tags\": [\n {\n \"id\": \"81d34d52-d62b-4769-9ab4-3f07897372c5\",\n \"vid\": 97,\n \"tid\": 97,\n \"url\": \"/taxonomy/term/97\",\n \"name\": \"Work from Home\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:24+0000\"\n },\n {\n \"id\": \"a2cfcf08-21e8-4d9e-a0a2-e4ce0ff9f58b\",\n \"vid\": 96,\n \"tid\": 96,\n \"url\": \"/taxonomy/term/96\",\n \"name\": \"Working Remotely\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:32+0000\"\n },\n {\n \"id\": \"f49d9d61-21ba-472d-9100-3e83beeacf33\",\n \"vid\": 98,\n \"tid\": 98,\n \"url\": \"/taxonomy/term/98\",\n \"name\": \"Virtual Team\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:03+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"39299858-9ea2-4e61-bf1e-7c7a8a91bdc9\",\n \"vid\": 100,\n \"tid\": 100,\n \"url\": \"/taxonomy/term/100\",\n \"name\": \"Virtual Team\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:18:16+0000\",\n \"description\": \"These days everything’s moving online… even your team. Are you ready? Knowing how to identify the dynamics of your team, communicate clearly with everyone & foster trust will give you the basic skills you need as a manager to bridge the distance & form your virtual team. \"\n },\n \"description\": \"The environment surrounding your team matters to your management strategy. Consider how physical location, time difference, & cultural norms will affect how you & your team interact.\",\n \"image\": {\n \"UUID\": \"cb63ccec-5701-4b4f-a0b9-b81e4374fb94\",\n \"name\": \"consider_your_team_preview_image_0.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/consider_your_team_preview_image_0.png.jpg?itok=7aW_sFhv\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/consider_your_team_preview_image_0.png\"\n },\n \"body\": [\n {\n \"id\": 325,\n \"uuid\": \"58703df8-651c-43d4-a755-db04e29a4178\",\n \"revision_id\": 780,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584460911,\n \"parent_id\": \"261\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

The environment surrounding your team matters to your management strategy. Consider how physical location, time difference, & cultural norms will affect how you & your team interact.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

The environment surrounding your team matters to your management strategy. Consider how physical location, time difference, & cultural norms will affect how you & your team interact.

\\n\"\n }\n },\n {\n \"id\": 326,\n \"uuid\": \"96692ce2-69f6-43d6-ba95-532bfc8ff24a\",\n \"revision_id\": 781,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584461035,\n \"parent_id\": \"261\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_video\": \"https://youtu.be/DedwabN7a_g\"\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"f833653e-4077-472f-8f52-5b76227a4d71\",\n \"nid\": 262,\n \"vid\": 614,\n \"url\": \"/node/262\",\n \"name\": \"Form Your Virtual Team: Communicate With Clarity\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-18T14:24:44+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"a66dc7ac-b204-49ec-bcc4-9baa0c8eda10\",\n \"name\": \"node_262.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_262.zip\"\n },\n \"tags\": [\n {\n \"id\": \"2e03cfc6-7b44-4853-a629-1283b7b6b5cd\",\n \"vid\": 93,\n \"tid\": 93,\n \"url\": \"/taxonomy/term/93\",\n \"name\": \"SLGO\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-16T19:38:00+0000\"\n },\n {\n \"id\": \"81d34d52-d62b-4769-9ab4-3f07897372c5\",\n \"vid\": 97,\n \"tid\": 97,\n \"url\": \"/taxonomy/term/97\",\n \"name\": \"Work from Home\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:24+0000\"\n },\n {\n \"id\": \"f49d9d61-21ba-472d-9100-3e83beeacf33\",\n \"vid\": 98,\n \"tid\": 98,\n \"url\": \"/taxonomy/term/98\",\n \"name\": \"Virtual Team\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:03+0000\"\n },\n {\n \"id\": \"a2cfcf08-21e8-4d9e-a0a2-e4ce0ff9f58b\",\n \"vid\": 96,\n \"tid\": 96,\n \"url\": \"/taxonomy/term/96\",\n \"name\": \"Working Remotely\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:32+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"39299858-9ea2-4e61-bf1e-7c7a8a91bdc9\",\n \"vid\": 100,\n \"tid\": 100,\n \"url\": \"/taxonomy/term/100\",\n \"name\": \"Virtual Team\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:18:16+0000\",\n \"description\": \"These days everything’s moving online… even your team. Are you ready? Knowing how to identify the dynamics of your team, communicate clearly with everyone & foster trust will give you the basic skills you need as a manager to bridge the distance & form your virtual team. \"\n },\n \"description\": \"Extra, open & honest communication is needed to keep a virtual team running smoothly. Learn how clearly defined roles & designated responsibilities will keep things on track. \",\n \"image\": {\n \"UUID\": \"666bb1f7-76d5-4215-bedd-434b5e46c815\",\n \"name\": \"communicate_with_clarity_0.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/communicate_with_clarity_0.png.jpg?itok=dTn2qagE\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/communicate_with_clarity_0.png\"\n },\n \"body\": [\n {\n \"id\": 327,\n \"uuid\": \"d1fb45ad-c4aa-4c86-b700-08858787ad10\",\n \"revision_id\": 778,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584461685,\n \"parent_id\": \"262\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

Extra, open & honest communication is needed to keep a virtual team running smoothly. Learn how clearly defined roles & designated responsibilities will keep things on track. 

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

Extra, open & honest communication is needed to keep a virtual team running smoothly. Learn how clearly defined roles & designated responsibilities will keep things on track. 

\\n\"\n }\n },\n {\n \"id\": 328,\n \"uuid\": \"0d95682d-1112-4b05-adba-c57ad4d614ad\",\n \"revision_id\": 779,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584461716,\n \"parent_id\": \"262\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_video\": \"https://youtu.be/57nUlH8cFj0\"\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"77505e29-789c-4355-9b17-961b20a5176e\",\n \"nid\": 263,\n \"vid\": 616,\n \"url\": \"/node/263\",\n \"name\": \"Form Your Virtual Team: Foster Trust\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-18T14:22:25+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"885d627c-bfe2-4893-b510-bd909b10c240\",\n \"name\": \"node_263.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_263.zip\"\n },\n \"tags\": [\n {\n \"id\": \"2e03cfc6-7b44-4853-a629-1283b7b6b5cd\",\n \"vid\": 93,\n \"tid\": 93,\n \"url\": \"/taxonomy/term/93\",\n \"name\": \"SLGO\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-16T19:38:00+0000\"\n },\n {\n \"id\": \"81d34d52-d62b-4769-9ab4-3f07897372c5\",\n \"vid\": 97,\n \"tid\": 97,\n \"url\": \"/taxonomy/term/97\",\n \"name\": \"Work from Home\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:24+0000\"\n },\n {\n \"id\": \"a2cfcf08-21e8-4d9e-a0a2-e4ce0ff9f58b\",\n \"vid\": 96,\n \"tid\": 96,\n \"url\": \"/taxonomy/term/96\",\n \"name\": \"Working Remotely\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:32+0000\"\n },\n {\n \"id\": \"f49d9d61-21ba-472d-9100-3e83beeacf33\",\n \"vid\": 98,\n \"tid\": 98,\n \"url\": \"/taxonomy/term/98\",\n \"name\": \"Virtual Team\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:03+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"39299858-9ea2-4e61-bf1e-7c7a8a91bdc9\",\n \"vid\": 100,\n \"tid\": 100,\n \"url\": \"/taxonomy/term/100\",\n \"name\": \"Virtual Team\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:18:16+0000\",\n \"description\": \"These days everything’s moving online… even your team. Are you ready? Knowing how to identify the dynamics of your team, communicate clearly with everyone & foster trust will give you the basic skills you need as a manager to bridge the distance & form your virtual team. \"\n },\n \"description\": \"Trust is critical for all teams, but how do you foster trust when people are separated? Discover how to build rapport, either in person or online, to help your virtual team members learn to trust one another.\",\n \"image\": {\n \"UUID\": \"22367a71-754b-4c28-abf1-a18e2c1071f1\",\n \"name\": \"Foster_Trust_preview_image_0.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/Foster_Trust_preview_image_0.png.jpg?itok=_I_MQOeM\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/Foster_Trust_preview_image_0.png\"\n },\n \"body\": [\n {\n \"id\": 329,\n \"uuid\": \"0d73664a-7988-4779-85c0-0472acefa741\",\n \"revision_id\": 776,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584462530,\n \"parent_id\": \"263\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

Trust is critical for all teams, but how do you foster trust when people are separated? Discover how to build rapport, either in person or online, to help your virtual team members learn to trust one another.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

Trust is critical for all teams, but how do you foster trust when people are separated? Discover how to build rapport, either in person or online, to help your virtual team members learn to trust one another.

\\n\"\n }\n },\n {\n \"id\": 330,\n \"uuid\": \"fc078590-0aac-47b5-a43b-964a2e80f646\",\n \"revision_id\": 777,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584462565,\n \"parent_id\": \"263\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_video\": \"https://youtu.be/S2mTBXE54pQ\"\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"af9ac669-8e56-42c9-abca-4d83ca10cd5c\",\n \"nid\": 264,\n \"vid\": 613,\n \"url\": \"/node/264\",\n \"name\": \"Form Your Virtual Team: Bridge the Distance\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-18T14:21:52+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"b1dca302-5c13-470c-af91-26d796a38317\",\n \"name\": \"node_264.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_264.zip\"\n },\n \"tags\": [\n {\n \"id\": \"2e03cfc6-7b44-4853-a629-1283b7b6b5cd\",\n \"vid\": 93,\n \"tid\": 93,\n \"url\": \"/taxonomy/term/93\",\n \"name\": \"SLGO\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-16T19:38:00+0000\"\n },\n {\n \"id\": \"81d34d52-d62b-4769-9ab4-3f07897372c5\",\n \"vid\": 97,\n \"tid\": 97,\n \"url\": \"/taxonomy/term/97\",\n \"name\": \"Work from Home\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:24+0000\"\n },\n {\n \"id\": \"a2cfcf08-21e8-4d9e-a0a2-e4ce0ff9f58b\",\n \"vid\": 96,\n \"tid\": 96,\n \"url\": \"/taxonomy/term/96\",\n \"name\": \"Working Remotely\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:32+0000\"\n },\n {\n \"id\": \"f49d9d61-21ba-472d-9100-3e83beeacf33\",\n \"vid\": 98,\n \"tid\": 98,\n \"url\": \"/taxonomy/term/98\",\n \"name\": \"Virtual Team\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:03+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"39299858-9ea2-4e61-bf1e-7c7a8a91bdc9\",\n \"vid\": 100,\n \"tid\": 100,\n \"url\": \"/taxonomy/term/100\",\n \"name\": \"Virtual Team\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:18:16+0000\",\n \"description\": \"These days everything’s moving online… even your team. Are you ready? Knowing how to identify the dynamics of your team, communicate clearly with everyone & foster trust will give you the basic skills you need as a manager to bridge the distance & form your virtual team. \"\n },\n \"description\": \"Getting everyone on the same page on a virtual team means being through & specific with your communication details. Find out how to select the right technological tools & use agreed upon terms to make communication easier.\",\n \"image\": {\n \"UUID\": \"7080cb95-17b5-4ad1-a071-4251472476b3\",\n \"name\": \"Bridge_the_Distance_preview_image_0.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/Bridge_the_Distance_preview_image_0.png.jpg?itok=bfB5hsew\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/Bridge_the_Distance_preview_image_0.png\"\n },\n \"body\": [\n {\n \"id\": 331,\n \"uuid\": \"6bc0db84-d9fa-4475-9ae7-210629be5f2b\",\n \"revision_id\": 774,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584463759,\n \"parent_id\": \"264\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

Getting everyone on the same page on a virtual team means being through & specific with your communication details. Find out how to select the right technological tools & use agreed upon terms to make communication easier.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

Getting everyone on the same page on a virtual team means being through & specific with your communication details. Find out how to select the right technological tools & use agreed upon terms to make communication easier.

\\n\"\n }\n },\n {\n \"id\": 332,\n \"uuid\": \"61441c5c-b2ff-4c5c-9bc5-ae6a1a3d223a\",\n \"revision_id\": 775,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584463801,\n \"parent_id\": \"264\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_video\": \"https://youtu.be/ROfJ_tqUqN4\"\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"37608fae-33d6-4adc-bba3-2586494a51c8\",\n \"nid\": 265,\n \"vid\": 612,\n \"url\": \"/node/265\",\n \"name\": \"Form Your Virtual Team: 1 More Thing About Forming Your Virtual Team\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-18T14:21:22+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"9d604b51-3c10-4bef-b11d-d85d83c05e4b\",\n \"name\": \"node_265.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_265.zip\"\n },\n \"tags\": [\n {\n \"id\": \"2e03cfc6-7b44-4853-a629-1283b7b6b5cd\",\n \"vid\": 93,\n \"tid\": 93,\n \"url\": \"/taxonomy/term/93\",\n \"name\": \"SLGO\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-16T19:38:00+0000\"\n },\n {\n \"id\": \"a2cfcf08-21e8-4d9e-a0a2-e4ce0ff9f58b\",\n \"vid\": 96,\n \"tid\": 96,\n \"url\": \"/taxonomy/term/96\",\n \"name\": \"Working Remotely\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:32+0000\"\n },\n {\n \"id\": \"81d34d52-d62b-4769-9ab4-3f07897372c5\",\n \"vid\": 97,\n \"tid\": 97,\n \"url\": \"/taxonomy/term/97\",\n \"name\": \"Work from Home\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:24+0000\"\n },\n {\n \"id\": \"f49d9d61-21ba-472d-9100-3e83beeacf33\",\n \"vid\": 98,\n \"tid\": 98,\n \"url\": \"/taxonomy/term/98\",\n \"name\": \"Virtual Team\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:03+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"39299858-9ea2-4e61-bf1e-7c7a8a91bdc9\",\n \"vid\": 100,\n \"tid\": 100,\n \"url\": \"/taxonomy/term/100\",\n \"name\": \"Virtual Team\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:18:16+0000\",\n \"description\": \"These days everything’s moving online… even your team. Are you ready? Knowing how to identify the dynamics of your team, communicate clearly with everyone & foster trust will give you the basic skills you need as a manager to bridge the distance & form your virtual team. \"\n },\n \"description\": \"Consider this final piece of advice on how to keep team members engaged through casual communication channels as you work to form your virtual team.\",\n \"image\": {\n \"UUID\": \"c718ad5c-9a8c-41ed-afe5-467d26815103\",\n \"name\": \"1_more_thing_preview_image_0.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/1_more_thing_preview_image_0.png.jpg?itok=A08X2K9C\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/1_more_thing_preview_image_0.png\"\n },\n \"body\": [\n {\n \"id\": 333,\n \"uuid\": \"0ff6b931-3c9f-47ac-b3b9-139d64a411ea\",\n \"revision_id\": 772,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584464025,\n \"parent_id\": \"265\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

Consider this final piece of advice on how to keep team members engaged through casual communication channels as you work to form your virtual team.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

Consider this final piece of advice on how to keep team members engaged through casual communication channels as you work to form your virtual team.

\\n\"\n }\n },\n {\n \"id\": 344,\n \"uuid\": \"95b168e1-6637-4293-a887-3e66bb12a83f\",\n \"revision_id\": 773,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584477383,\n \"parent_id\": \"265\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_video\": \"https://youtu.be/j3N1ryenxxM\"\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"702a6935-4985-48e8-98f5-395e99d906f9\",\n \"nid\": 266,\n \"vid\": 625,\n \"url\": \"/node/266\",\n \"name\": \"Lead Your Virtual Team: Why It Matters\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-18T14:20:55+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"4f26f94d-6ef0-4fb5-a18b-1be35712e28a\",\n \"name\": \"node_266.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_266.zip\"\n },\n \"tags\": [\n {\n \"id\": \"2e03cfc6-7b44-4853-a629-1283b7b6b5cd\",\n \"vid\": 93,\n \"tid\": 93,\n \"url\": \"/taxonomy/term/93\",\n \"name\": \"SLGO\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-16T19:38:00+0000\"\n },\n {\n \"id\": \"425e382c-8fc9-4a46-a252-cb6f20bc42eb\",\n \"vid\": 83,\n \"tid\": 83,\n \"url\": \"/taxonomy/term/83\",\n \"name\": \"Leadership\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:33:24+0000\"\n },\n {\n \"id\": \"f49d9d61-21ba-472d-9100-3e83beeacf33\",\n \"vid\": 98,\n \"tid\": 98,\n \"url\": \"/taxonomy/term/98\",\n \"name\": \"Virtual Team\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:03+0000\"\n },\n {\n \"id\": \"a2cfcf08-21e8-4d9e-a0a2-e4ce0ff9f58b\",\n \"vid\": 96,\n \"tid\": 96,\n \"url\": \"/taxonomy/term/96\",\n \"name\": \"Working Remotely\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:32+0000\"\n },\n {\n \"id\": \"81d34d52-d62b-4769-9ab4-3f07897372c5\",\n \"vid\": 97,\n \"tid\": 97,\n \"url\": \"/taxonomy/term/97\",\n \"name\": \"Work from Home\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:24+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"39299858-9ea2-4e61-bf1e-7c7a8a91bdc9\",\n \"vid\": 100,\n \"tid\": 100,\n \"url\": \"/taxonomy/term/100\",\n \"name\": \"Virtual Team\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:18:16+0000\",\n \"description\": \"These days everything’s moving online… even your team. Are you ready? Knowing how to identify the dynamics of your team, communicate clearly with everyone & foster trust will give you the basic skills you need as a manager to bridge the distance & form your virtual team. \"\n },\n \"description\": \"What’s your role as the leader of a virtual team? It starts with your ability to communicate clearly and effectively. \",\n \"image\": {\n \"UUID\": \"048b3aff-90c1-4eb0-94cc-6b23151a5a35\",\n \"name\": \"Why_it_Matters_preview_image.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/Why_it_Matters_preview_image.png.jpg?itok=pACP8Kp3\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/Why_it_Matters_preview_image.png\"\n },\n \"body\": [\n {\n \"id\": 334,\n \"uuid\": \"479119a7-51a4-45a9-9f49-440ab82a70f4\",\n \"revision_id\": 770,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584464549,\n \"parent_id\": \"266\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

What’s your role as the leader of a virtual team? It starts with your ability to communicate clearly and effectively.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

What’s your role as the leader of a virtual team? It starts with your ability to communicate clearly and effectively.

\\n\"\n }\n },\n {\n \"id\": 335,\n \"uuid\": \"c11782c2-785f-42b3-b417-15e56e53a8cf\",\n \"revision_id\": 771,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584464599,\n \"parent_id\": \"266\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_video\": \"https://youtu.be/0EuMpK5Ln3w\"\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"84ae2ee5-f845-4eda-9567-6f4b0fecaf45\",\n \"nid\": 267,\n \"vid\": 623,\n \"url\": \"/node/267\",\n \"name\": \"Lead Your Virtual Team: Lead Virtual Meetings\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-18T14:20:33+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"f733e365-341d-4d89-b7b9-94434cb537fc\",\n \"name\": \"node_267.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_267.zip\"\n },\n \"tags\": [\n {\n \"id\": \"2e03cfc6-7b44-4853-a629-1283b7b6b5cd\",\n \"vid\": 93,\n \"tid\": 93,\n \"url\": \"/taxonomy/term/93\",\n \"name\": \"SLGO\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-16T19:38:00+0000\"\n },\n {\n \"id\": \"425e382c-8fc9-4a46-a252-cb6f20bc42eb\",\n \"vid\": 83,\n \"tid\": 83,\n \"url\": \"/taxonomy/term/83\",\n \"name\": \"Leadership\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:33:24+0000\"\n },\n {\n \"id\": \"81d34d52-d62b-4769-9ab4-3f07897372c5\",\n \"vid\": 97,\n \"tid\": 97,\n \"url\": \"/taxonomy/term/97\",\n \"name\": \"Work from Home\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:24+0000\"\n },\n {\n \"id\": \"a2cfcf08-21e8-4d9e-a0a2-e4ce0ff9f58b\",\n \"vid\": 96,\n \"tid\": 96,\n \"url\": \"/taxonomy/term/96\",\n \"name\": \"Working Remotely\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:32+0000\"\n },\n {\n \"id\": \"f49d9d61-21ba-472d-9100-3e83beeacf33\",\n \"vid\": 98,\n \"tid\": 98,\n \"url\": \"/taxonomy/term/98\",\n \"name\": \"Virtual Team\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:03+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"39299858-9ea2-4e61-bf1e-7c7a8a91bdc9\",\n \"vid\": 100,\n \"tid\": 100,\n \"url\": \"/taxonomy/term/100\",\n \"name\": \"Virtual Team\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:18:16+0000\",\n \"description\": \"These days everything’s moving online… even your team. Are you ready? Knowing how to identify the dynamics of your team, communicate clearly with everyone & foster trust will give you the basic skills you need as a manager to bridge the distance & form your virtual team. \"\n },\n \"description\": \"Leading a good meeting is hard. Leading a good virtual meeting is even harder. Find out what you can do to make your virtual meetings successful from day one.\",\n \"image\": {\n \"UUID\": \"8986ca42-294e-4930-adcf-f1d700cf136b\",\n \"name\": \"Lead_Virtual_Meetings_preview_image_0.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/Lead_Virtual_Meetings_preview_image_0.png.jpg?itok=0ddqbQxz\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/Lead_Virtual_Meetings_preview_image_0.png\"\n },\n \"body\": [\n {\n \"id\": 336,\n \"uuid\": \"0c762c9b-00a1-4ce6-9fe4-a896ca5111ce\",\n \"revision_id\": 768,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584464927,\n \"parent_id\": \"267\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

Leading a good meeting is hard. Leading a good virtual meeting is even harder. Find out what you can do to make your virtual meetings successful from day one.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

Leading a good meeting is hard. Leading a good virtual meeting is even harder. Find out what you can do to make your virtual meetings successful from day one.

\\n\"\n }\n },\n {\n \"id\": 337,\n \"uuid\": \"cf92fa5f-9637-4c30-9b35-494187aab765\",\n \"revision_id\": 769,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584464946,\n \"parent_id\": \"267\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_video\": \"https://youtu.be/F75fyBbUT3w\"\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"5011f7fc-0130-41df-8c69-a9dd1f610352\",\n \"nid\": 268,\n \"vid\": 624,\n \"url\": \"/node/268\",\n \"name\": \"Lead Your Virtual Team: Resolve Conflict\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-18T14:19:26+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"aea57abf-0f2d-4ca1-9913-2a814b97cb1e\",\n \"name\": \"node_268.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_268.zip\"\n },\n \"tags\": [\n {\n \"id\": \"2e03cfc6-7b44-4853-a629-1283b7b6b5cd\",\n \"vid\": 93,\n \"tid\": 93,\n \"url\": \"/taxonomy/term/93\",\n \"name\": \"SLGO\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-16T19:38:00+0000\"\n },\n {\n \"id\": \"425e382c-8fc9-4a46-a252-cb6f20bc42eb\",\n \"vid\": 83,\n \"tid\": 83,\n \"url\": \"/taxonomy/term/83\",\n \"name\": \"Leadership\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:33:24+0000\"\n },\n {\n \"id\": \"81d34d52-d62b-4769-9ab4-3f07897372c5\",\n \"vid\": 97,\n \"tid\": 97,\n \"url\": \"/taxonomy/term/97\",\n \"name\": \"Work from Home\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:24+0000\"\n },\n {\n \"id\": \"a2cfcf08-21e8-4d9e-a0a2-e4ce0ff9f58b\",\n \"vid\": 96,\n \"tid\": 96,\n \"url\": \"/taxonomy/term/96\",\n \"name\": \"Working Remotely\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:32+0000\"\n },\n {\n \"id\": \"f49d9d61-21ba-472d-9100-3e83beeacf33\",\n \"vid\": 98,\n \"tid\": 98,\n \"url\": \"/taxonomy/term/98\",\n \"name\": \"Virtual Team\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:03+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"39299858-9ea2-4e61-bf1e-7c7a8a91bdc9\",\n \"vid\": 100,\n \"tid\": 100,\n \"url\": \"/taxonomy/term/100\",\n \"name\": \"Virtual Team\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:18:16+0000\",\n \"description\": \"These days everything’s moving online… even your team. Are you ready? Knowing how to identify the dynamics of your team, communicate clearly with everyone & foster trust will give you the basic skills you need as a manager to bridge the distance & form your virtual team. \"\n },\n \"description\": \"Conflict happens. Learn how to diffuse tension and manage situations appropriately with the three C’s of conflict management.\",\n \"image\": {\n \"UUID\": \"5caac0f2-76e0-4a3a-b185-78ecbee21999\",\n \"name\": \"Resolve_Conficlt_preview_image_0.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/Resolve_Conficlt_preview_image_0.png.jpg?itok=kOQiZ5MQ\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/Resolve_Conficlt_preview_image_0.png\"\n },\n \"body\": [\n {\n \"id\": 338,\n \"uuid\": \"31bf6c91-bab3-4b63-bec9-f7588efe5821\",\n \"revision_id\": 766,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584470034,\n \"parent_id\": \"268\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

Conflict happens. Learn how to diffuse tension and manage situations appropriately with the three C’s of conflict management.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

Conflict happens. Learn how to diffuse tension and manage situations appropriately with the three C’s of conflict management.

\\n\"\n }\n },\n {\n \"id\": 339,\n \"uuid\": \"6054a9cb-7711-47df-a508-8a9bcc4e2511\",\n \"revision_id\": 767,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584470066,\n \"parent_id\": \"268\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_video\": \"https://youtu.be/nD5AZ4YfGdU\"\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"cf03a63b-ef79-4f84-8ab6-8b5a1b7e31cc\",\n \"nid\": 269,\n \"vid\": 621,\n \"url\": \"/node/269\",\n \"name\": \"Lead Your Virtual Team: Coach to Foster Results\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-18T14:18:57+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"1b5c613f-abd4-40bf-a799-ad42a55cae03\",\n \"name\": \"node_269.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_269.zip\"\n },\n \"tags\": [\n {\n \"id\": \"2e03cfc6-7b44-4853-a629-1283b7b6b5cd\",\n \"vid\": 93,\n \"tid\": 93,\n \"url\": \"/taxonomy/term/93\",\n \"name\": \"SLGO\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-16T19:38:00+0000\"\n },\n {\n \"id\": \"425e382c-8fc9-4a46-a252-cb6f20bc42eb\",\n \"vid\": 83,\n \"tid\": 83,\n \"url\": \"/taxonomy/term/83\",\n \"name\": \"Leadership\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:33:24+0000\"\n },\n {\n \"id\": \"81d34d52-d62b-4769-9ab4-3f07897372c5\",\n \"vid\": 97,\n \"tid\": 97,\n \"url\": \"/taxonomy/term/97\",\n \"name\": \"Work from Home\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:24+0000\"\n },\n {\n \"id\": \"a2cfcf08-21e8-4d9e-a0a2-e4ce0ff9f58b\",\n \"vid\": 96,\n \"tid\": 96,\n \"url\": \"/taxonomy/term/96\",\n \"name\": \"Working Remotely\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:32+0000\"\n },\n {\n \"id\": \"f49d9d61-21ba-472d-9100-3e83beeacf33\",\n \"vid\": 98,\n \"tid\": 98,\n \"url\": \"/taxonomy/term/98\",\n \"name\": \"Virtual Team\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:03+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"39299858-9ea2-4e61-bf1e-7c7a8a91bdc9\",\n \"vid\": 100,\n \"tid\": 100,\n \"url\": \"/taxonomy/term/100\",\n \"name\": \"Virtual Team\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:18:16+0000\",\n \"description\": \"These days everything’s moving online… even your team. Are you ready? Knowing how to identify the dynamics of your team, communicate clearly with everyone & foster trust will give you the basic skills you need as a manager to bridge the distance & form your virtual team. \"\n },\n \"description\": \"Move beyond simply managing your virtual team to coaching them and building relationships that foster results.\",\n \"image\": {\n \"UUID\": \"5fc32613-18ef-4139-b7f8-ffd57f3b67a5\",\n \"name\": \"coach_to_foster_results_preview_image_0.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/coach_to_foster_results_preview_image_0.png.jpg?itok=mass3BVi\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/coach_to_foster_results_preview_image_0.png\"\n },\n \"body\": [\n {\n \"id\": 340,\n \"uuid\": \"3ed21f98-710f-4b97-bf66-b3bff58885d9\",\n \"revision_id\": 764,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584470254,\n \"parent_id\": \"269\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

Move beyond simply managing your virtual team to coaching them and building relationships that foster results.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

Move beyond simply managing your virtual team to coaching them and building relationships that foster results.

\\n\"\n }\n },\n {\n \"id\": 341,\n \"uuid\": \"2b37375f-a622-4d5f-9f5b-e15472cdc368\",\n \"revision_id\": 765,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584470287,\n \"parent_id\": \"269\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_video\": \"https://youtu.be/AA0jZb77l8k\"\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"26fdfcfe-0a44-4ff9-b33c-20c7764d5257\",\n \"nid\": 270,\n \"vid\": 620,\n \"url\": \"/node/270\",\n \"name\": \"Lead Your Virtual Team: 1 More Thing About Leading Virtual Teams\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-18T14:18:34+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"1dd15635-75e1-486a-acd1-1b252845f1a0\",\n \"name\": \"node_270.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_270.zip\"\n },\n \"tags\": [\n {\n \"id\": \"2e03cfc6-7b44-4853-a629-1283b7b6b5cd\",\n \"vid\": 93,\n \"tid\": 93,\n \"url\": \"/taxonomy/term/93\",\n \"name\": \"SLGO\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-16T19:38:00+0000\"\n },\n {\n \"id\": \"81d34d52-d62b-4769-9ab4-3f07897372c5\",\n \"vid\": 97,\n \"tid\": 97,\n \"url\": \"/taxonomy/term/97\",\n \"name\": \"Work from Home\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:24+0000\"\n },\n {\n \"id\": \"a2cfcf08-21e8-4d9e-a0a2-e4ce0ff9f58b\",\n \"vid\": 96,\n \"tid\": 96,\n \"url\": \"/taxonomy/term/96\",\n \"name\": \"Working Remotely\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:32+0000\"\n },\n {\n \"id\": \"425e382c-8fc9-4a46-a252-cb6f20bc42eb\",\n \"vid\": 83,\n \"tid\": 83,\n \"url\": \"/taxonomy/term/83\",\n \"name\": \"Leadership\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:33:24+0000\"\n },\n {\n \"id\": \"f49d9d61-21ba-472d-9100-3e83beeacf33\",\n \"vid\": 98,\n \"tid\": 98,\n \"url\": \"/taxonomy/term/98\",\n \"name\": \"Virtual Team\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:03+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"39299858-9ea2-4e61-bf1e-7c7a8a91bdc9\",\n \"vid\": 100,\n \"tid\": 100,\n \"url\": \"/taxonomy/term/100\",\n \"name\": \"Virtual Team\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:18:16+0000\",\n \"description\": \"These days everything’s moving online… even your team. Are you ready? Knowing how to identify the dynamics of your team, communicate clearly with everyone & foster trust will give you the basic skills you need as a manager to bridge the distance & form your virtual team. \"\n },\n \"description\": \"Consider this final piece of advice about body language as you lead your virtual team.\",\n \"image\": {\n \"UUID\": \"61e3f2da-31ee-4c87-b38b-56958a98b1c7\",\n \"name\": \"1-More-Thing-About-Leading-Virtual-Teams_0.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/1-More-Thing-About-Leading-Virtual-Teams_0.png.jpg?itok=D8wPQWiK\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/1-More-Thing-About-Leading-Virtual-Teams_0.png\"\n },\n \"body\": [\n {\n \"id\": 342,\n \"uuid\": \"41ff541e-c7a6-47bf-b0a9-a7f0e2140f7e\",\n \"revision_id\": 762,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584470745,\n \"parent_id\": \"270\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

Consider this final piece of advice about body language as you lead your virtual team.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

Consider this final piece of advice about body language as you lead your virtual team.

\\n\"\n }\n },\n {\n \"id\": 343,\n \"uuid\": \"23dab46e-3412-4276-8014-8ada1cfd04fa\",\n \"revision_id\": 763,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584470766,\n \"parent_id\": \"270\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_video\": \"https://youtu.be/2xauNxFOzG0\"\n }\n ],\n \"discussion_status\": \"hidden\"\n }\n ]\n },\n {\n \"name\": \"Welcome to SLGO\",\n \"url\": \"/api/groups/15/topics/92\",\n \"content\": [\n {\n \"id\": \"da68041d-6ffa-4c53-968b-08b98829c0c2\",\n \"nid\": 251,\n \"vid\": 626,\n \"url\": \"/node/251\",\n \"name\": \"Welcome to SLGO!\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-20T20:02:39+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"853b82f6-0946-4267-bae8-1597fa8e7586\",\n \"name\": \"node_251.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_251.zip\"\n },\n \"tags\": [\n {\n \"id\": \"2e03cfc6-7b44-4853-a629-1283b7b6b5cd\",\n \"vid\": 93,\n \"tid\": 93,\n \"url\": \"/taxonomy/term/93\",\n \"name\": \"SLGO\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-16T19:38:00+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"7db21c39-78c9-48a6-a78d-ecbd7ab49b4b\",\n \"vid\": 92,\n \"tid\": 92,\n \"url\": \"/taxonomy/term/92\",\n \"name\": \"Welcome to SLGO\",\n \"type\": \"category\",\n \"changed\": \"2020-03-16T19:29:47+0000\",\n \"description\": null\n },\n \"description\": \"With SLGO you can easily connect with your team and stay on top of your learning anytime, anywhere. In this lesson, you will learn how to stay connected, find and organize the content relevant to you, and take advantage of pre-loaded content on working remotely.\",\n \"image\": {\n \"UUID\": \"8b68f317-73cb-4bc4-989d-4f54ce827669\",\n \"name\": \"SLgo_LearningObject_App.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/SLgo_LearningObject_App.png.jpg?itok=Vqpd89xU\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/SLgo_LearningObject_App.png\"\n },\n \"body\": [\n {\n \"id\": 305,\n \"uuid\": \"13d24610-77a0-435f-acf4-b47154f9598f\",\n \"revision_id\": 867,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584387127,\n \"parent_id\": \"251\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": true,\n \"field_paragraph_body\": {\n \"value\": \"

Connecting people. SLGO helps you learn when and where you want to and be able to pick up anywhere at any time. Your admin can deliver relevant content to you remotely and review your progress. This means you can stay connected and keep your knowledge up to date from the comfort of your home.

\\r\\n\\r\\n

Enhancing Productivity.  Effective learning can help to solve problems and accelerate performance. SLGO has learning content for all levels from exploring to studying, to sharpening. You can browse topics or join groups to find content tailored to you. We also have free courses from TorranceLearning.

\\r\\n\\r\\n

Giving you results. SLGO uses a powerful recommendation engine to give you content that reinforces what you are learning and bring similar lessons to your attention. As you complete courses and interact with flashcards, quizzes, and tip cards, you will receive meaningful feedback. 

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

Connecting people. SLGO helps you learn when and where you want to and be able to pick up anywhere at any time. Your admin can deliver relevant content to you remotely and review your progress. This means you can stay connected and keep your knowledge up to date from the comfort of your home.

\\n

Enhancing Productivity.  Effective learning can help to solve problems and accelerate performance. SLGO has learning content for all levels from exploring to studying, to sharpening. You can browse topics or join groups to find content tailored to you. We also have free courses from TorranceLearning.

\\n

Giving you results. SLGO uses a powerful recommendation engine to give you content that reinforces what you are learning and bring similar lessons to your attention. As you complete courses and interact with flashcards, quizzes, and tip cards, you will receive meaningful feedback. 

\\n\"\n }\n },\n {\n \"id\": 306,\n \"uuid\": \"17eb2457-7f3a-4680-a8e7-c1cd7c3bc65b\",\n \"revision_id\": 868,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584387421,\n \"parent_id\": \"251\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_size\": \"h4\",\n \"field_title\": \"Resources\"\n }\n ],\n \"discussion_status\": \"hidden\"\n }\n ]\n }\n]" + } + ] + }, + { + "name": "Group topic contents", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "url": { + "raw": "{{server}}/{{base_url}}/groups/{{group_id}}/topics/{{group_topic_id}}", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "groups", + "{{group_id}}", + "topics", + "{{group_topic_id}}" + ] + }, + "description": "Retrieves content belonging to the group within the specified topic.\n\n### Query parameters\n* `title` - filter the response to content with a title containing the provided value\n* `page` - retrieve a specific page\n\n### Paging\nThis endpoint allows for paging with the `page` query parameter. Paging uses a 0-based index. For example, to request the second page, add `page=1` to the query parameters." + }, + "response": [ + { + "name": "Example response", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/groups/{{group_id}}/topics/{{group_topic_id}}", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "groups", + "{{group_id}}", + "topics", + "{{group_topic_id}}" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Cache-Control", + "value": "must-revalidate, no-cache, private" + }, + { + "key": "Content-Encoding", + "value": "gzip" + }, + { + "key": "Content-Language", + "value": "en" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Sun, 11 Apr 2021 18:01:42 GMT" + }, + { + "key": "Expires", + "value": "Sun, 19 Nov 1978 05:00:00 GMT" + }, + { + "key": "Server", + "value": "nginx" + }, + { + "key": "Vary", + "value": "Accept-Encoding" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Drupal-Cache-Contexts", + "value": "languages:language_content languages:language_interface request_format route theme url user.group_permissions user.node_grants:view user.permissions" + }, + { + "key": "X-Drupal-Cache-Max-Age", + "value": "-1 (Permanent)" + }, + { + "key": "X-Drupal-Cache-Tags", + "value": "config:views.view.group_content_by_topic group:15 group_content:187 group_content:188 group_content:189 group_content_list group_content_list:plugin:group_node:course group_content_list:plugin:group_node:flash_card group_content_list:plugin:group_node:learn_article group_content_list:plugin:group_node:learn_file group_content_list:plugin:group_node:learn_link group_content_list:plugin:group_node:learn_package group_content_list:plugin:group_node:podcast group_content_list:plugin:group_node:podcast_episode group_content_list:plugin:group_node:quiz group_content_list:plugin:group_node:test group_content_list:plugin:group_node:tip_card group_list http_response node:226 node:227 node:229 node_list page_manager_route_name:view.group_content_by_topic.rest_export_1 taxonomy_term:80 taxonomy_term_list" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "X-Generator", + "value": "Drupal 9 (https://www.drupal.org)" + }, + { + "key": "X-Ua-Compatible", + "value": "IE=edge" + }, + { + "key": "X-Xss-Protection", + "value": "1; mode=block" + }, + { + "key": "Transfer-Encoding", + "value": "chunked" + } + ], + "cookie": [], + "body": "{\n \"rows\": [\n {\n \"id\": \"0113f56c-e06b-4d21-b0db-688e74447834\",\n \"nid\": 229,\n \"vid\": 519,\n \"url\": \"/node/229\",\n \"name\": \"Did you know? 40% of Businesses Affected by Disaster Never Reopen. \",\n \"type\": \"tip_card\",\n \"changed\": \"2020-03-18T19:24:07+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": [],\n \"topic\": {\n \"id\": \"fb473dd7-86a8-40a6-8a12-c9c80d46c2fb\",\n \"vid\": 80,\n \"tid\": 80,\n \"url\": \"/taxonomy/term/80\",\n \"name\": \"Occupational Safety and Health\",\n \"type\": \"category\",\n \"changed\": \"2021-02-01T00:30:23+0000\",\n \"description\": \"This topic includes content related to the safety, health, and welfare of people at work The goal of occupational safety and health programs is to foster a safe and healthy work environment.[3] OSH may also protect co-workers, family members, employers, customers, and many others who might be affected by the workplace environment. \"\n },\n \"contents\": [\n \"
\\n
\\n
\\n \\n

The main reason to have an emergency action plan is to do as much as possible to keep your employees safe in case of disaster but a good plan can keep your business safe as well. Up to 40% of businesses affected by a natural or human-caused disaster never reopen. Having procedures in place to deal with disasters can help your business survive this difficult experience.

\\n

 

\\n
\\n \\n
\\n
\\n\\n
\\n\",\n \"
\\n
\\n
\\n \\n
\\\"Closed\\n\\n\\n
\\n \\n
\\n
\\n\\n
\\n\"\n ],\n \"body\": [\n {\n \"id\": \"c548cc2f-d8f0-4a98-88f5-f96ae130d076\",\n \"type\": \"text\",\n \"fields\": [\n {\n \"type\": \"Label\",\n \"attributes\": {\n \"Text\": \"

The main reason to have an emergency action plan is to do as much as possible to keep your employees safe in case of disaster but a good plan can keep your business safe as well. Up to 40% of businesses affected by a natural or human-caused disaster never reopen. Having procedures in place to deal with disasters can help your business survive this difficult experience.

\\r\\n\\r\\n

 

\",\n \"TextType\": \"Html\"\n }\n }\n ]\n },\n {\n \"id\": \"b74d5871-47ad-4d40-baa0-d1f225f18abf\",\n \"type\": \"image\",\n \"fields\": [\n {\n \"type\": \"Image\",\n \"attributes\": {\n \"Source\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/benedikt-geyer-Qq_F_5kS7uo-unsplash.jpg?itok=eIObe6Xf\",\n \"Aspect\": \"AspectFit\"\n }\n }\n ]\n }\n ]\n },\n {\n \"id\": \"09f8e9db-c1e9-47e3-adff-f0cf8132d37e\",\n \"nid\": 227,\n \"vid\": 610,\n \"url\": \"/node/227\",\n \"name\": \"Creating an Emergency Action Plan\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-10T20:56:10+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"f97b1a60-9e2b-45b3-83c9-eb5dc0da85eb\",\n \"name\": \"node_227.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_227.zip\"\n },\n \"tags\": [\n {\n \"id\": \"425e382c-8fc9-4a46-a252-cb6f20bc42eb\",\n \"vid\": 83,\n \"tid\": 83,\n \"url\": \"/taxonomy/term/83\",\n \"name\": \"Leadership\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:33:24+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"fb473dd7-86a8-40a6-8a12-c9c80d46c2fb\",\n \"vid\": 80,\n \"tid\": 80,\n \"url\": \"/taxonomy/term/80\",\n \"name\": \"Occupational Safety and Health\",\n \"type\": \"category\",\n \"changed\": \"2021-02-01T00:30:23+0000\",\n \"description\": \"This topic includes content related to the safety, health, and welfare of people at work The goal of occupational safety and health programs is to foster a safe and healthy work environment.[3] OSH may also protect co-workers, family members, employers, customers, and many others who might be affected by the workplace environment. \"\n },\n \"description\": \"A brief guide to creating an Emergency Action Plan\",\n \"image\": {\n \"UUID\": \"1f445741-9ed9-414f-8a60-68239e502915\",\n \"name\": \"emergency-plan.jpg\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/emergency-plan.jpg?itok=RG84ODJ3\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/emergency-plan.jpg\"\n },\n \"body\": [\n {\n \"id\": 262,\n \"uuid\": \"3c8cf7f3-6494-41aa-8844-60ffb4a8dca4\",\n \"revision_id\": 595,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1583858101,\n \"parent_id\": \"227\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

How to Get Started

\\r\\n\\r\\n

The best time to handle an emergency is before it ever takes place. Before you create your emergency action plan, you'll need to analyze your business and see what potential hazards you face. These can vary depending on the type of business and your location. Some emergency action plans will cover problems dealing with hazardous materials on hand, some will need to deal with issues stemming from older buildings that were built to a lower-standard safety code, and some will need to have strategies in place to prepare for natural disasters more likely in certain areas, such as hurricanes, earthquakes, and tornadoes.

\\r\\n\\r\\n

While many things will be different depending on the type of emergency you are preparing for—what you do during a tornado or earthquake will be much different than what you do during a fire or workplace violence incident, for example—some of the basic preparations will be similar for multiple problems. Always provide steps for getting people to safety, whether that means sheltering or evacuating them, and always have a clear and effective plan for communicating with everyone who could be affected.

\\r\\n\\r\\n

Be sure to investigate not just what hazards you may face and how to stay safe during them, but also what effects they will have afterward. This should reveal such considerations as what lost income and increased expenses could be caused by your business being shut down for various amounts of time, the effect of lost customers, the delay of new business plans, and other effects of a disruption of service. Be as exact as possible in order to get a good idea of what costs you might accrue so you can most accurately plan for a disaster.

\\r\\n\\r\\n

FEMA provides a Business Impact Analysis Worksheet you can distribute to management and any other employees you feel can contribute to your preparations. Download the worksheet here: http://www.ready.gov/sites/default/files/documents/files/BusinessImpactAnalysis_Worksheet.pdf

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

How to Get Started

\\n

The best time to handle an emergency is before it ever takes place. Before you create your emergency action plan, you'll need to analyze your business and see what potential hazards you face. These can vary depending on the type of business and your location. Some emergency action plans will cover problems dealing with hazardous materials on hand, some will need to deal with issues stemming from older buildings that were built to a lower-standard safety code, and some will need to have strategies in place to prepare for natural disasters more likely in certain areas, such as hurricanes, earthquakes, and tornadoes.

\\n

While many things will be different depending on the type of emergency you are preparing for—what you do during a tornado or earthquake will be much different than what you do during a fire or workplace violence incident, for example—some of the basic preparations will be similar for multiple problems. Always provide steps for getting people to safety, whether that means sheltering or evacuating them, and always have a clear and effective plan for communicating with everyone who could be affected.

\\n

Be sure to investigate not just what hazards you may face and how to stay safe during them, but also what effects they will have afterward. This should reveal such considerations as what lost income and increased expenses could be caused by your business being shut down for various amounts of time, the effect of lost customers, the delay of new business plans, and other effects of a disruption of service. Be as exact as possible in order to get a good idea of what costs you might accrue so you can most accurately plan for a disaster.

\\n

FEMA provides a Business Impact Analysis Worksheet you can distribute to management and any other employees you feel can contribute to your preparations. Download the worksheet here: http://www.ready.gov/sites/default/files/documents/files/BusinessImpactAnalysis_Worksheet.pdf

\\n\"\n }\n },\n {\n \"id\": 263,\n \"uuid\": \"ec1ac160-2f77-46ed-ad14-05ae02cb089a\",\n \"revision_id\": 596,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1583858229,\n \"parent_id\": \"227\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

Create Your Emergency Action Plan

\\r\\n\\r\\n

Once you have identified all of the possible threats you may face and the potential effects, you should come up with responses for the hazards. Here are some tips to keep in mind.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

Create Your Emergency Action Plan

\\n

Once you have identified all of the possible threats you may face and the potential effects, you should come up with responses for the hazards. Here are some tips to keep in mind.

\\n\"\n }\n },\n {\n \"id\": 264,\n \"uuid\": \"6c1ea93c-3ef8-45db-a215-5294eba0e717\",\n \"revision_id\": 597,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1583858298,\n \"parent_id\": \"227\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_list_content\": {\n \"value\": \"
    \\r\\n\\t
  • For emergency situations, have an individual in charge of following and getting others to follow the procedures you outline. For larger companies, you may need more than one, in separate departments or as backups, but in this case make sure the hierarchy is clearly laid out. Employees must know this individual is in charge and has authority during an emergency.
  • \\r\\n\\t
  • Ensure the methods for reporting fires and other emergencies are clear, whether it's dialing 911, calling an internal emergency number, pulling a manual fire alarm, or other procedure which may change depending on the type of emergency.
  • \\r\\n\\t
  • Create evacuation policies and paths that are clear and easy to follow.
  • \\r\\n\\t
  • Have procedures in place for employees who must remain during the beginning of an evacuation to take care of greater hazards. This includes employees who must use fire extinguishers, shut down gas lines and/or electrical systems, or safeguard hazardous materials to keep a bad situation from getting worse.
  • \\r\\n\\t
  • Be prepared for the loss of computer hardware, software, and information related to technological disruptions, and find ways to back up and recover it.
  • \\r\\n\\t
  • Note who is able to perform medical care, from first aid to CPR, and make sure they are in the proper positions to do so.
  • \\r\\n\\t
  • Provide clear communication during and immediately after any dangerous incident.
  • \\r\\n
\\r\\n\",\n \"format\": \"list\",\n \"processed\": \"
    \\n
  • For emergency situations, have an individual in charge of following and getting others to follow the procedures you outline. For larger companies, you may need more than one, in separate departments or as backups, but in this case make sure the hierarchy is clearly laid out. Employees must know this individual is in charge and has authority during an emergency.
  • \\n
  • Ensure the methods for reporting fires and other emergencies are clear, whether it's dialing 911, calling an internal emergency number, pulling a manual fire alarm, or other procedure which may change depending on the type of emergency.
  • \\n
  • Create evacuation policies and paths that are clear and easy to follow.
  • \\n
  • Have procedures in place for employees who must remain during the beginning of an evacuation to take care of greater hazards. This includes employees who must use fire extinguishers, shut down gas lines and/or electrical systems, or safeguard hazardous materials to keep a bad situation from getting worse.
  • \\n
  • Be prepared for the loss of computer hardware, software, and information related to technological disruptions, and find ways to back up and recover it.
  • \\n
  • Note who is able to perform medical care, from first aid to CPR, and make sure they are in the proper positions to do so.
  • \\n
  • Provide clear communication during and immediately after any dangerous incident.
  • \\n
\\n\"\n },\n \"field_list_items\": []\n },\n {\n \"id\": 265,\n \"uuid\": \"ce2878bd-402e-4e04-ae93-3aa1ae3ca2d1\",\n \"revision_id\": 598,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1583858383,\n \"parent_id\": \"227\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

OSHA has several resources to help you prepare your emergency action plan.

\\r\\n\\r\\n\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

OSHA has several resources to help you prepare your emergency action plan.

\\n\\n\"\n }\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"960ad1e3-66e0-4388-baa7-62cbf7e87bdb\",\n \"nid\": 226,\n \"vid\": 611,\n \"url\": \"/node/226\",\n \"name\": \"Emergency Action Plan – Why Should You Have One?\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-10T18:53:36+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"6acf8cc1-ae88-411c-86f5-0998666ba4ec\",\n \"name\": \"node_226.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_226.zip\"\n },\n \"tags\": [\n {\n \"id\": \"425e382c-8fc9-4a46-a252-cb6f20bc42eb\",\n \"vid\": 83,\n \"tid\": 83,\n \"url\": \"/taxonomy/term/83\",\n \"name\": \"Leadership\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:33:24+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"fb473dd7-86a8-40a6-8a12-c9c80d46c2fb\",\n \"vid\": 80,\n \"tid\": 80,\n \"url\": \"/taxonomy/term/80\",\n \"name\": \"Occupational Safety and Health\",\n \"type\": \"category\",\n \"changed\": \"2021-02-01T00:30:23+0000\",\n \"description\": \"This topic includes content related to the safety, health, and welfare of people at work The goal of occupational safety and health programs is to foster a safe and healthy work environment.[3] OSH may also protect co-workers, family members, employers, customers, and many others who might be affected by the workplace environment. \"\n },\n \"description\": \"Rationale for why your workplace should have an Emergency Action Plan.\",\n \"image\": {\n \"UUID\": \"b302865b-6e06-44ab-91ce-7229de0490ad\",\n \"name\": \"isravel-raj-YuN8QjfBYUY-unsplash.jpg\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/isravel-raj-YuN8QjfBYUY-unsplash.jpg?itok=c2wu3JnG\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/isravel-raj-YuN8QjfBYUY-unsplash.jpg\"\n },\n \"body\": [\n {\n \"id\": 260,\n \"uuid\": \"3c623628-2b4b-418b-8206-1bb86e31c13a\",\n \"revision_id\": 582,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1583857015,\n \"parent_id\": \"226\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

The main reason to have an emergency action plan is to do as much as possible to keep your employees safe in case of disaster. The confusion of an emergency can make a bad situation worse and put lives at risk. The Federal Emergency Management Agency (FEMA) provides more reasons an emergency action plan is important from a purely business perspective.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

The main reason to have an emergency action plan is to do as much as possible to keep your employees safe in case of disaster. The confusion of an emergency can make a bad situation worse and put lives at risk. The Federal Emergency Management Agency (FEMA) provides more reasons an emergency action plan is important from a purely business perspective.

\\n\"\n }\n },\n {\n \"id\": 261,\n \"uuid\": \"076bcddf-01f7-42b1-9a41-5f9910d0114b\",\n \"revision_id\": 583,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1583856683,\n \"parent_id\": \"226\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_list_content\": {\n \"value\": \"
    \\r\\n\\t
  • Up to 40% of businesses affected by a natural or human-caused disaster never reopen. Having procedures in place to deal with disasters can help your business survive this difficult experience.
  • \\r\\n\\t
  • Customers may not understand the disaster and its effects on your business. They'll still expect products or service on time. If there's a significant delay, they may take their business to a competitor.
  • \\r\\n\\t
  • Even if a disaster does slow or shut down your business, a robust emergency action plan has procedures in place to contact customers and stakeholders quickly to keep them up to date on what has happened. News travels fast and perceptions are often different from reality. Staying on top of the information stream reduces negative perception.
  • \\r\\n\\t
  • Insurance often only provides partial assistance. It does not cover all losses and does not bring back lost customers.
  • \\r\\n\\t
  • Public agencies cannot be expected to provide total relief either. Many disasters can overwhelm their resources, meaning aid may not be immediate even when it is available.
  • \\r\\n\\t
  • Many large businesses are now expecting their suppliers to have preparations in place for emergencies, trying to make sure their own business will not be hurt if something happens to another company on the supply chain. Without a plan in place, your business could be given to a competitor.
  • \\r\\n
\\r\\n\",\n \"format\": \"list\",\n \"processed\": \"
    \\n
  • Up to 40% of businesses affected by a natural or human-caused disaster never reopen. Having procedures in place to deal with disasters can help your business survive this difficult experience.
  • \\n
  • Customers may not understand the disaster and its effects on your business. They'll still expect products or service on time. If there's a significant delay, they may take their business to a competitor.
  • \\n
  • Even if a disaster does slow or shut down your business, a robust emergency action plan has procedures in place to contact customers and stakeholders quickly to keep them up to date on what has happened. News travels fast and perceptions are often different from reality. Staying on top of the information stream reduces negative perception.
  • \\n
  • Insurance often only provides partial assistance. It does not cover all losses and does not bring back lost customers.
  • \\n
  • Public agencies cannot be expected to provide total relief either. Many disasters can overwhelm their resources, meaning aid may not be immediate even when it is available.
  • \\n
  • Many large businesses are now expecting their suppliers to have preparations in place for emergencies, trying to make sure their own business will not be hurt if something happens to another company on the supply chain. Without a plan in place, your business could be given to a competitor.
  • \\n
\\n\"\n },\n \"field_list_items\": []\n }\n ],\n \"discussion_status\": \"hidden\"\n }\n ],\n \"pager\": {\n \"current_page\": 0,\n \"total_items\": \"3\",\n \"total_pages\": 1,\n \"items_per_page\": 50\n }\n}" + }, + { + "name": "Get second page of results", + "originalRequest": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "url": { + "raw": "{{server}}/{{base_url}}/groups/{{group_id}}/topics/{{group_topic_id}}?page=1", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "groups", + "{{group_id}}", + "topics", + "{{group_topic_id}}" + ], + "query": [ + { + "key": "page", + "value": "1" + } + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Cache-Control", + "value": "must-revalidate, no-cache, private" + }, + { + "key": "Content-Encoding", + "value": "gzip" + }, + { + "key": "Content-Language", + "value": "en" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Sun, 11 Apr 2021 18:05:54 GMT" + }, + { + "key": "Expires", + "value": "Sun, 19 Nov 1978 05:00:00 GMT" + }, + { + "key": "Server", + "value": "nginx" + }, + { + "key": "Vary", + "value": "Accept-Encoding" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Drupal-Cache-Contexts", + "value": "languages:language_content languages:language_interface request_format route theme url user.group_permissions user.node_grants:view user.permissions" + }, + { + "key": "X-Drupal-Cache-Max-Age", + "value": "-1 (Permanent)" + }, + { + "key": "X-Drupal-Cache-Tags", + "value": "config:views.view.group_content_by_topic group:15 group_content:189 group_content_list group_content_list:plugin:group_node:course group_content_list:plugin:group_node:flash_card group_content_list:plugin:group_node:learn_article group_content_list:plugin:group_node:learn_file group_content_list:plugin:group_node:learn_link group_content_list:plugin:group_node:learn_package group_content_list:plugin:group_node:podcast group_content_list:plugin:group_node:podcast_episode group_content_list:plugin:group_node:quiz group_content_list:plugin:group_node:test group_content_list:plugin:group_node:tip_card group_list http_response node:226 node_list page_manager_route_name:view.group_content_by_topic.rest_export_1 taxonomy_term:80 taxonomy_term_list" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "X-Generator", + "value": "Drupal 9 (https://www.drupal.org)" + }, + { + "key": "X-Ua-Compatible", + "value": "IE=edge" + }, + { + "key": "X-Xss-Protection", + "value": "1; mode=block" + }, + { + "key": "Transfer-Encoding", + "value": "chunked" + } + ], + "cookie": [], + "body": "{\n \"rows\": [\n {\n \"id\": \"960ad1e3-66e0-4388-baa7-62cbf7e87bdb\",\n \"nid\": 226,\n \"vid\": 611,\n \"url\": \"/node/226\",\n \"name\": \"Emergency Action Plan – Why Should You Have One?\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-10T18:53:36+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"6acf8cc1-ae88-411c-86f5-0998666ba4ec\",\n \"name\": \"node_226.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_226.zip\"\n },\n \"tags\": [\n {\n \"id\": \"425e382c-8fc9-4a46-a252-cb6f20bc42eb\",\n \"vid\": 83,\n \"tid\": 83,\n \"url\": \"/taxonomy/term/83\",\n \"name\": \"Leadership\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:33:24+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"fb473dd7-86a8-40a6-8a12-c9c80d46c2fb\",\n \"vid\": 80,\n \"tid\": 80,\n \"url\": \"/taxonomy/term/80\",\n \"name\": \"Occupational Safety and Health\",\n \"type\": \"category\",\n \"changed\": \"2021-02-01T00:30:23+0000\",\n \"description\": \"This topic includes content related to the safety, health, and welfare of people at work The goal of occupational safety and health programs is to foster a safe and healthy work environment.[3] OSH may also protect co-workers, family members, employers, customers, and many others who might be affected by the workplace environment. \"\n },\n \"description\": \"Rationale for why your workplace should have an Emergency Action Plan.\",\n \"image\": {\n \"UUID\": \"b302865b-6e06-44ab-91ce-7229de0490ad\",\n \"name\": \"isravel-raj-YuN8QjfBYUY-unsplash.jpg\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/isravel-raj-YuN8QjfBYUY-unsplash.jpg?itok=c2wu3JnG\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/isravel-raj-YuN8QjfBYUY-unsplash.jpg\"\n },\n \"body\": [\n {\n \"id\": 260,\n \"uuid\": \"3c623628-2b4b-418b-8206-1bb86e31c13a\",\n \"revision_id\": 582,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1583857015,\n \"parent_id\": \"226\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

The main reason to have an emergency action plan is to do as much as possible to keep your employees safe in case of disaster. The confusion of an emergency can make a bad situation worse and put lives at risk. The Federal Emergency Management Agency (FEMA) provides more reasons an emergency action plan is important from a purely business perspective.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

The main reason to have an emergency action plan is to do as much as possible to keep your employees safe in case of disaster. The confusion of an emergency can make a bad situation worse and put lives at risk. The Federal Emergency Management Agency (FEMA) provides more reasons an emergency action plan is important from a purely business perspective.

\\n\"\n }\n },\n {\n \"id\": 261,\n \"uuid\": \"076bcddf-01f7-42b1-9a41-5f9910d0114b\",\n \"revision_id\": 583,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1583856683,\n \"parent_id\": \"226\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_list_content\": {\n \"value\": \"
    \\r\\n\\t
  • Up to 40% of businesses affected by a natural or human-caused disaster never reopen. Having procedures in place to deal with disasters can help your business survive this difficult experience.
  • \\r\\n\\t
  • Customers may not understand the disaster and its effects on your business. They'll still expect products or service on time. If there's a significant delay, they may take their business to a competitor.
  • \\r\\n\\t
  • Even if a disaster does slow or shut down your business, a robust emergency action plan has procedures in place to contact customers and stakeholders quickly to keep them up to date on what has happened. News travels fast and perceptions are often different from reality. Staying on top of the information stream reduces negative perception.
  • \\r\\n\\t
  • Insurance often only provides partial assistance. It does not cover all losses and does not bring back lost customers.
  • \\r\\n\\t
  • Public agencies cannot be expected to provide total relief either. Many disasters can overwhelm their resources, meaning aid may not be immediate even when it is available.
  • \\r\\n\\t
  • Many large businesses are now expecting their suppliers to have preparations in place for emergencies, trying to make sure their own business will not be hurt if something happens to another company on the supply chain. Without a plan in place, your business could be given to a competitor.
  • \\r\\n
\\r\\n\",\n \"format\": \"list\",\n \"processed\": \"
    \\n
  • Up to 40% of businesses affected by a natural or human-caused disaster never reopen. Having procedures in place to deal with disasters can help your business survive this difficult experience.
  • \\n
  • Customers may not understand the disaster and its effects on your business. They'll still expect products or service on time. If there's a significant delay, they may take their business to a competitor.
  • \\n
  • Even if a disaster does slow or shut down your business, a robust emergency action plan has procedures in place to contact customers and stakeholders quickly to keep them up to date on what has happened. News travels fast and perceptions are often different from reality. Staying on top of the information stream reduces negative perception.
  • \\n
  • Insurance often only provides partial assistance. It does not cover all losses and does not bring back lost customers.
  • \\n
  • Public agencies cannot be expected to provide total relief either. Many disasters can overwhelm their resources, meaning aid may not be immediate even when it is available.
  • \\n
  • Many large businesses are now expecting their suppliers to have preparations in place for emergencies, trying to make sure their own business will not be hurt if something happens to another company on the supply chain. Without a plan in place, your business could be given to a competitor.
  • \\n
\\n\"\n },\n \"field_list_items\": []\n }\n ],\n \"discussion_status\": \"hidden\"\n }\n ],\n \"pager\": {\n \"current_page\": 1,\n \"total_items\": \"3\",\n \"total_pages\": 2,\n \"items_per_page\": 2\n }\n}" + }, + { + "name": "Search group topic by title", + "originalRequest": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "url": { + "raw": "{{server}}/{{base_url}}/groups/{{group_id}}/topics/{{group_topic_id}}?title=business", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "groups", + "{{group_id}}", + "topics", + "{{group_topic_id}}" + ], + "query": [ + { + "key": "title", + "value": "business" + } + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Cache-Control", + "value": "must-revalidate, no-cache, private" + }, + { + "key": "Content-Encoding", + "value": "gzip" + }, + { + "key": "Content-Language", + "value": "en" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Sun, 11 Apr 2021 18:09:42 GMT" + }, + { + "key": "Expires", + "value": "Sun, 19 Nov 1978 05:00:00 GMT" + }, + { + "key": "Server", + "value": "nginx" + }, + { + "key": "Vary", + "value": "Accept-Encoding" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Drupal-Cache-Contexts", + "value": "languages:language_content languages:language_interface request_format route theme url user.group_permissions user.node_grants:view user.permissions" + }, + { + "key": "X-Drupal-Cache-Max-Age", + "value": "-1 (Permanent)" + }, + { + "key": "X-Drupal-Cache-Tags", + "value": "config:views.view.group_content_by_topic group:15 group_content:188 group_content_list group_content_list:plugin:group_node:course group_content_list:plugin:group_node:flash_card group_content_list:plugin:group_node:learn_article group_content_list:plugin:group_node:learn_file group_content_list:plugin:group_node:learn_link group_content_list:plugin:group_node:learn_package group_content_list:plugin:group_node:podcast group_content_list:plugin:group_node:podcast_episode group_content_list:plugin:group_node:quiz group_content_list:plugin:group_node:test group_content_list:plugin:group_node:tip_card group_list http_response node:229 node_list page_manager_route_name:view.group_content_by_topic.rest_export_1 taxonomy_term:80 taxonomy_term_list" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "X-Generator", + "value": "Drupal 9 (https://www.drupal.org)" + }, + { + "key": "X-Ua-Compatible", + "value": "IE=edge" + }, + { + "key": "X-Xss-Protection", + "value": "1; mode=block" + }, + { + "key": "Content-Length", + "value": "1400" + } + ], + "cookie": [], + "body": "{\n \"rows\": [\n {\n \"id\": \"0113f56c-e06b-4d21-b0db-688e74447834\",\n \"nid\": 229,\n \"vid\": 519,\n \"url\": \"/node/229\",\n \"name\": \"Did you know? 40% of Businesses Affected by Disaster Never Reopen. \",\n \"type\": \"tip_card\",\n \"changed\": \"2020-03-18T19:24:07+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": [],\n \"topic\": {\n \"id\": \"fb473dd7-86a8-40a6-8a12-c9c80d46c2fb\",\n \"vid\": 80,\n \"tid\": 80,\n \"url\": \"/taxonomy/term/80\",\n \"name\": \"Occupational Safety and Health\",\n \"type\": \"category\",\n \"changed\": \"2021-02-01T00:30:23+0000\",\n \"description\": \"This topic includes content related to the safety, health, and welfare of people at work The goal of occupational safety and health programs is to foster a safe and healthy work environment.[3] OSH may also protect co-workers, family members, employers, customers, and many others who might be affected by the workplace environment. \"\n },\n \"contents\": [\n \"
\\n
\\n
\\n \\n

The main reason to have an emergency action plan is to do as much as possible to keep your employees safe in case of disaster but a good plan can keep your business safe as well. Up to 40% of businesses affected by a natural or human-caused disaster never reopen. Having procedures in place to deal with disasters can help your business survive this difficult experience.

\\n

 

\\n
\\n \\n
\\n
\\n\\n
\\n\",\n \"
\\n
\\n
\\n \\n
\\\"Closed\\n\\n\\n
\\n \\n
\\n
\\n\\n
\\n\"\n ],\n \"body\": [\n {\n \"id\": \"c548cc2f-d8f0-4a98-88f5-f96ae130d076\",\n \"type\": \"text\",\n \"fields\": [\n {\n \"type\": \"Label\",\n \"attributes\": {\n \"Text\": \"

The main reason to have an emergency action plan is to do as much as possible to keep your employees safe in case of disaster but a good plan can keep your business safe as well. Up to 40% of businesses affected by a natural or human-caused disaster never reopen. Having procedures in place to deal with disasters can help your business survive this difficult experience.

\\r\\n\\r\\n

 

\",\n \"TextType\": \"Html\"\n }\n }\n ]\n },\n {\n \"id\": \"b74d5871-47ad-4d40-baa0-d1f225f18abf\",\n \"type\": \"image\",\n \"fields\": [\n {\n \"type\": \"Image\",\n \"attributes\": {\n \"Source\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/benedikt-geyer-Qq_F_5kS7uo-unsplash.jpg?itok=eIObe6Xf\",\n \"Aspect\": \"AspectFit\"\n }\n }\n ]\n }\n ]\n }\n ],\n \"pager\": {\n \"current_page\": 0,\n \"total_items\": \"1\",\n \"total_pages\": 1,\n \"items_per_page\": 2\n }\n}" + } + ] + }, + { + "name": "All group content", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "url": { + "raw": "{{server}}/{{base_url}}/groups/{{group_id}}/contents", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "groups", + "{{group_id}}", + "contents" + ] + }, + "description": "Retrieve all group content, sorted by title.\n\n### Query Parameters\n* `title` - filter the response to content with a title containing the provided value\n* `type` - filter the response to a specific type of content\n* `page` - retrieve a specific page\n\n### Content types\nThe following values are accepted in the `type` query parameter:\n* `learn_article`\n* `learn_link`\n* `learn_package`\n* `learn_file`\n* `course`\n* `flash_card`\n* `tip_card`\n\n### Paging\nThis endpoint allows for paging with the `page` query parameter. Paging uses a 0-based index. For example, to request the second page, add `page=1` to the query parameters." + }, + "response": [ + { + "name": "Example response", + "originalRequest": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "url": { + "raw": "{{server}}/{{base_url}}/groups/{{group_id}}/contents", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "groups", + "{{group_id}}", + "contents" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Cache-Control", + "value": "must-revalidate, no-cache, private" + }, + { + "key": "Content-Encoding", + "value": "gzip" + }, + { + "key": "Content-Language", + "value": "en" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Sun, 11 Apr 2021 18:10:40 GMT" + }, + { + "key": "Expires", + "value": "Sun, 19 Nov 1978 05:00:00 GMT" + }, + { + "key": "Server", + "value": "nginx" + }, + { + "key": "Vary", + "value": "Accept-Encoding" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Drupal-Cache-Contexts", + "value": "languages:language_content languages:language_interface request_format theme url user.group_permissions user.node_grants:view user.permissions" + }, + { + "key": "X-Drupal-Cache-Max-Age", + "value": "-1 (Permanent)" + }, + { + "key": "X-Drupal-Cache-Tags", + "value": "config:views.view.group_content group:15 group_content:176 group_content:177 group_content:180 group_content:181 group_content:182 group_content:183 group_content:184 group_content:185 group_content:186 group_content:187 group_content:188 group_content:189 group_content:190 group_content:191 group_content:192 group_content:193 group_content:194 group_content:195 group_content:196 group_content:197 group_content:198 group_content:199 group_content:200 group_content:201 group_content:202 group_content:203 group_content:204 group_content_list group_content_list:plugin:group_node:course group_content_list:plugin:group_node:flash_card group_content_list:plugin:group_node:learn_article group_content_list:plugin:group_node:learn_file group_content_list:plugin:group_node:learn_link group_content_list:plugin:group_node:learn_package group_content_list:plugin:group_node:podcast group_content_list:plugin:group_node:podcast_episode group_content_list:plugin:group_node:quiz group_content_list:plugin:group_node:test group_content_list:plugin:group_node:tip_card group_list http_response node:226 node:227 node:229 node:251 node:252 node:253 node:254 node:255 node:256 node:257 node:258 node:259 node:260 node:261 node:262 node:263 node:264 node:265 node:266 node:267 node:268 node:269 node:270 node:271 node:273 node:274 node:275 node_list page_manager_route_name:view.group_content.rest_export_1" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "X-Generator", + "value": "Drupal 9 (https://www.drupal.org)" + }, + { + "key": "X-Ua-Compatible", + "value": "IE=edge" + }, + { + "key": "X-Xss-Protection", + "value": "1; mode=block" + }, + { + "key": "Transfer-Encoding", + "value": "chunked" + } + ], + "cookie": [], + "body": "{\n \"rows\": [\n {\n \"id\": \"800ce9a7-7066-4195-87bb-1eecc9bfac3f\",\n \"nid\": 259,\n \"vid\": 631,\n \"url\": \"/node/259\",\n \"name\": \"COVID-19: Conclusion\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-26T15:22:41+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"5158b8d2-eaee-413e-84d9-8cab8de01704\",\n \"name\": \"node_259.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_259.zip\"\n },\n \"tags\": [\n {\n \"id\": \"801623d6-5b1a-4934-afd2-e55f75f5bafc\",\n \"vid\": 94,\n \"tid\": 94,\n \"url\": \"/taxonomy/term/94\",\n \"name\": \"COVID-19\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:18:22+0000\"\n },\n {\n \"id\": \"eff406f7-0dff-4945-812a-be707a816230\",\n \"vid\": 95,\n \"tid\": 95,\n \"url\": \"/taxonomy/term/95\",\n \"name\": \"Coronavirus\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:45+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"e2d54015-6e0b-43aa-a6b6-bd8abf7e66f6\",\n \"vid\": 99,\n \"tid\": 99,\n \"url\": \"/taxonomy/term/99\",\n \"name\": \"Take Precautions: COVID-19\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:34:44+0000\",\n \"description\": \"The recent coronavirus outbreak is a serious health concern. Do you know how to protect yourself and others from serious illness? Arming yourself with information and strategies will help reduce the spread of disease and enable you to work effectively in the challenging circumstances of an outbreak.\"\n },\n \"description\": \"Stay informed, take proper precautions, and keep washing your hands. Thanks for joining us here at Eleventure®. Higher learning. At work.\",\n \"image\": {\n \"UUID\": \"e40ae7b4-dd96-47c4-9213-5c92fe3f44dd\",\n \"name\": \"08_conclusion_preview_image_0.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/08_conclusion_preview_image_0.png.jpg?itok=Q9H3obzu\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/08_conclusion_preview_image_0.png\"\n },\n \"body\": [\n {\n \"id\": 321,\n \"uuid\": \"e0c4c1f2-2fcd-421a-b1b8-cbbea203b114\",\n \"revision_id\": 877,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584460058,\n \"parent_id\": \"259\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

Stay informed, take proper precautions, and keep washing your hands. Thanks for joining us here at Eleventure. Higher learning. At work.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

Stay informed, take proper precautions, and keep washing your hands. Thanks for joining us here at Eleventure. Higher learning. At work.

\\n\"\n }\n },\n {\n \"id\": 322,\n \"uuid\": \"0c54afab-f847-4181-831b-dbc0ea5a500b\",\n \"revision_id\": 878,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584460058,\n \"parent_id\": \"259\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_video\": \"https://youtu.be/mEYCQsBloEA\"\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"5d7dd7d2-7a00-4a9f-a1fc-428ce90cf6e9\",\n \"nid\": 252,\n \"vid\": 632,\n \"url\": \"/node/252\",\n \"name\": \"COVID-19: Don't Panic\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-26T15:25:39+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"83278a03-8995-4e83-bb9c-3e0ce6d3ad95\",\n \"name\": \"node_252.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_252.zip\"\n },\n \"tags\": [\n {\n \"id\": \"801623d6-5b1a-4934-afd2-e55f75f5bafc\",\n \"vid\": 94,\n \"tid\": 94,\n \"url\": \"/taxonomy/term/94\",\n \"name\": \"COVID-19\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:18:22+0000\"\n },\n {\n \"id\": \"eff406f7-0dff-4945-812a-be707a816230\",\n \"vid\": 95,\n \"tid\": 95,\n \"url\": \"/taxonomy/term/95\",\n \"name\": \"Coronavirus\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:45+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"e2d54015-6e0b-43aa-a6b6-bd8abf7e66f6\",\n \"vid\": 99,\n \"tid\": 99,\n \"url\": \"/taxonomy/term/99\",\n \"name\": \"Take Precautions: COVID-19\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:34:44+0000\",\n \"description\": \"The recent coronavirus outbreak is a serious health concern. Do you know how to protect yourself and others from serious illness? Arming yourself with information and strategies will help reduce the spread of disease and enable you to work effectively in the challenging circumstances of an outbreak.\"\n },\n \"description\": \"While the current coronavirus outbreak is a serious health concern, discover why keeping calm and staying properly informed are an important part of managing your response to an outbreak.\",\n \"image\": {\n \"UUID\": \"017d2e6b-ba9e-4e30-9b58-a8a82d30a5d9\",\n \"name\": \"01_dontpanic_preview_image_0.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/01_dontpanic_preview_image_0.png.jpg?itok=3SfGRscG\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/01_dontpanic_preview_image_0.png\"\n },\n \"body\": [\n {\n \"id\": 307,\n \"uuid\": \"f3795f1d-d8e2-42f4-a9f2-839ee9ea63a1\",\n \"revision_id\": 891,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584456088,\n \"parent_id\": \"252\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

While the current coronavirus outbreak is a serious health concern, discover why keeping calm and staying properly informed are an important part of managing your response to an outbreak.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

While the current coronavirus outbreak is a serious health concern, discover why keeping calm and staying properly informed are an important part of managing your response to an outbreak.

\\n\"\n }\n },\n {\n \"id\": 308,\n \"uuid\": \"0f6508ca-5139-4a69-8148-55134a59a357\",\n \"revision_id\": 892,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584456088,\n \"parent_id\": \"252\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_video\": \"https://youtu.be/hLDjZ8631Qc\"\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"1b2fee1e-fb4c-4237-83e4-383002922b92\",\n \"nid\": 255,\n \"vid\": 633,\n \"url\": \"/node/255\",\n \"name\": \"COVID-19: Get a Flu Shot\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-26T15:24:30+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"d7140275-9264-4769-bc7f-cf754598e7f7\",\n \"name\": \"node_255.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_255.zip\"\n },\n \"tags\": [\n {\n \"id\": \"801623d6-5b1a-4934-afd2-e55f75f5bafc\",\n \"vid\": 94,\n \"tid\": 94,\n \"url\": \"/taxonomy/term/94\",\n \"name\": \"COVID-19\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:18:22+0000\"\n },\n {\n \"id\": \"eff406f7-0dff-4945-812a-be707a816230\",\n \"vid\": 95,\n \"tid\": 95,\n \"url\": \"/taxonomy/term/95\",\n \"name\": \"Coronavirus\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:45+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"e2d54015-6e0b-43aa-a6b6-bd8abf7e66f6\",\n \"vid\": 99,\n \"tid\": 99,\n \"url\": \"/taxonomy/term/99\",\n \"name\": \"Take Precautions: COVID-19\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:34:44+0000\",\n \"description\": \"The recent coronavirus outbreak is a serious health concern. Do you know how to protect yourself and others from serious illness? Arming yourself with information and strategies will help reduce the spread of disease and enable you to work effectively in the challenging circumstances of an outbreak.\"\n },\n \"description\": \"There isn’t a vaccine readily available for coronavirus. Learn why getting an annual flu shot can still help protect you and those around you during the coronavirus outbreak.\",\n \"image\": {\n \"UUID\": \"428d0f8a-3511-45a8-a24b-4e334babddcb\",\n \"name\": \"04_get_flu_shot_preview_image_1.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/04_get_flu_shot_preview_image_1.png.jpg?itok=rZLjaHrn\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/04_get_flu_shot_preview_image_1.png\"\n },\n \"body\": [\n {\n \"id\": 313,\n \"uuid\": \"f44e2157-6bb7-4d8a-9853-c78a4d4b4702\",\n \"revision_id\": 885,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584458472,\n \"parent_id\": \"255\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

There isn’t a vaccine readily available for coronavirus. Learn why getting an annual flu shot can still help protect you and those around you during the coronavirus outbreak.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

There isn’t a vaccine readily available for coronavirus. Learn why getting an annual flu shot can still help protect you and those around you during the coronavirus outbreak.

\\n\"\n }\n },\n {\n \"id\": 314,\n \"uuid\": \"43eec42d-3d6c-4445-9eed-139342bbb9b0\",\n \"revision_id\": 886,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584458485,\n \"parent_id\": \"255\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_video\": \"https://youtu.be/lSyPts0lr1E\"\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"258982dd-b38d-4a8e-98d2-9ab04f395b21\",\n \"nid\": 253,\n \"vid\": 604,\n \"url\": \"/node/253\",\n \"name\": \"COVID-19: Limit Contagion\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-26T15:25:18+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"ac84d99a-86c2-41f0-8ed1-95b3046abcc0\",\n \"name\": \"node_253.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_253.zip\"\n },\n \"tags\": [\n {\n \"id\": \"801623d6-5b1a-4934-afd2-e55f75f5bafc\",\n \"vid\": 94,\n \"tid\": 94,\n \"url\": \"/taxonomy/term/94\",\n \"name\": \"COVID-19\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:18:22+0000\"\n },\n {\n \"id\": \"eff406f7-0dff-4945-812a-be707a816230\",\n \"vid\": 95,\n \"tid\": 95,\n \"url\": \"/taxonomy/term/95\",\n \"name\": \"Coronavirus\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:45+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"e2d54015-6e0b-43aa-a6b6-bd8abf7e66f6\",\n \"vid\": 99,\n \"tid\": 99,\n \"url\": \"/taxonomy/term/99\",\n \"name\": \"Take Precautions: COVID-19\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:34:44+0000\",\n \"description\": \"The recent coronavirus outbreak is a serious health concern. Do you know how to protect yourself and others from serious illness? Arming yourself with information and strategies will help reduce the spread of disease and enable you to work effectively in the challenging circumstances of an outbreak.\"\n },\n \"description\": \"The best way to avoid catching any virus is to avoid being exposed to that virus in the first place. Learn some expert-recommended strategies to reduce your chances of becoming ill and of infecting others.\",\n \"image\": {\n \"UUID\": \"208859b6-2b45-484e-8e21-f5285c888379\",\n \"name\": \"02_limit_contagion_preview_image_0.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/02_limit_contagion_preview_image_0.png.jpg?itok=b1DYtoSP\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/02_limit_contagion_preview_image_0.png\"\n },\n \"body\": [\n {\n \"id\": 309,\n \"uuid\": \"fbaa1d75-7b7e-44c8-9e30-f0eabc41e7e9\",\n \"revision_id\": 889,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584457096,\n \"parent_id\": \"253\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

The best way to avoid catching any virus is to avoid being exposed to that virus in the first place. Learn some expert-recommended strategies to reduce your chances of becoming ill and of infecting others.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

The best way to avoid catching any virus is to avoid being exposed to that virus in the first place. Learn some expert-recommended strategies to reduce your chances of becoming ill and of infecting others.

\\n\"\n }\n },\n {\n \"id\": 310,\n \"uuid\": \"a22733ae-1e8b-4e1b-9521-7eb6f8218480\",\n \"revision_id\": 890,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584457096,\n \"parent_id\": \"253\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_video\": \"https://youtu.be/YaxyOuRaPzY\"\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"3947b0c3-e992-4930-89f4-56181045269d\",\n \"nid\": 254,\n \"vid\": 605,\n \"url\": \"/node/254\",\n \"name\": \"COVID-19: Manage Social Symptoms\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-26T15:24:52+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"85bd4579-cd04-4120-ad22-07a9ee9b7071\",\n \"name\": \"node_254.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_254.zip\"\n },\n \"tags\": [\n {\n \"id\": \"801623d6-5b1a-4934-afd2-e55f75f5bafc\",\n \"vid\": 94,\n \"tid\": 94,\n \"url\": \"/taxonomy/term/94\",\n \"name\": \"COVID-19\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:18:22+0000\"\n },\n {\n \"id\": \"eff406f7-0dff-4945-812a-be707a816230\",\n \"vid\": 95,\n \"tid\": 95,\n \"url\": \"/taxonomy/term/95\",\n \"name\": \"Coronavirus\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:45+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"e2d54015-6e0b-43aa-a6b6-bd8abf7e66f6\",\n \"vid\": 99,\n \"tid\": 99,\n \"url\": \"/taxonomy/term/99\",\n \"name\": \"Take Precautions: COVID-19\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:34:44+0000\",\n \"description\": \"The recent coronavirus outbreak is a serious health concern. Do you know how to protect yourself and others from serious illness? Arming yourself with information and strategies will help reduce the spread of disease and enable you to work effectively in the challenging circumstances of an outbreak.\"\n },\n \"description\": \"Misinformation and fear can lead to xenophobia and hostility during an outbreak. While it’s normal to be concerned about preventing illness, use these strategies to ensure that your concern is focused on fighting the disease itself.\",\n \"image\": {\n \"UUID\": \"18dbdfd2-0551-4eb2-9d15-d70b24564f45\",\n \"name\": \"03_manage_social_symptoms_preview_image_0.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/03_manage_social_symptoms_preview_image_0.png.jpg?itok=US_PLy25\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/03_manage_social_symptoms_preview_image_0.png\"\n },\n \"body\": [\n {\n \"id\": 311,\n \"uuid\": \"16452dc7-da79-4d2e-b17e-66044e556e8f\",\n \"revision_id\": 887,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584457478,\n \"parent_id\": \"254\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

Misinformation and fear can lead to xenophobia and hostility during an outbreak. While it’s normal to be concerned about preventing illness, use these strategies to ensure that your concern is focused on fighting the disease itself.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

Misinformation and fear can lead to xenophobia and hostility during an outbreak. While it’s normal to be concerned about preventing illness, use these strategies to ensure that your concern is focused on fighting the disease itself.

\\n\"\n }\n },\n {\n \"id\": 312,\n \"uuid\": \"57b12ed2-ced1-49a2-9249-a4fd88d6740d\",\n \"revision_id\": 888,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584457486,\n \"parent_id\": \"254\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_video\": \"https://youtu.be/2Gg8clhfyAE\"\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"3f18f2a0-2f3c-4114-94cf-1222d389f877\",\n \"nid\": 256,\n \"vid\": 606,\n \"url\": \"/node/256\",\n \"name\": \"COVID-19: Manage the Timeline of Infection\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-26T15:24:04+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"f2ae69e5-f95f-4119-abba-53fd85a30014\",\n \"name\": \"node_256.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_256.zip\"\n },\n \"tags\": [\n {\n \"id\": \"801623d6-5b1a-4934-afd2-e55f75f5bafc\",\n \"vid\": 94,\n \"tid\": 94,\n \"url\": \"/taxonomy/term/94\",\n \"name\": \"COVID-19\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:18:22+0000\"\n },\n {\n \"id\": \"eff406f7-0dff-4945-812a-be707a816230\",\n \"vid\": 95,\n \"tid\": 95,\n \"url\": \"/taxonomy/term/95\",\n \"name\": \"Coronavirus\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:45+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"e2d54015-6e0b-43aa-a6b6-bd8abf7e66f6\",\n \"vid\": 99,\n \"tid\": 99,\n \"url\": \"/taxonomy/term/99\",\n \"name\": \"Take Precautions: COVID-19\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:34:44+0000\",\n \"description\": \"The recent coronavirus outbreak is a serious health concern. Do you know how to protect yourself and others from serious illness? Arming yourself with information and strategies will help reduce the spread of disease and enable you to work effectively in the challenging circumstances of an outbreak.\"\n },\n \"description\": \"Sick people can often spread illness before they show symptoms. Learn the main ways viruses are spread and what you should do if you become ill to avoid infecting others.\",\n \"image\": {\n \"UUID\": \"0c1fd93c-30c0-4297-acb7-3aec3e61bcf3\",\n \"name\": \"05_manage_timeline_infection_preview_image_0.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/05_manage_timeline_infection_preview_image_0.png.jpg?itok=zslh7Ueq\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/05_manage_timeline_infection_preview_image_0.png\"\n },\n \"body\": [\n {\n \"id\": 315,\n \"uuid\": \"70acb4e6-ba50-407c-beb0-c18eee07ce2e\",\n \"revision_id\": 883,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584458626,\n \"parent_id\": \"256\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

Sick people can often spread illness before they show symptoms. Learn the main ways viruses are spread and what you should do if you become ill to avoid infecting others.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

Sick people can often spread illness before they show symptoms. Learn the main ways viruses are spread and what you should do if you become ill to avoid infecting others.

\\n\"\n }\n },\n {\n \"id\": 316,\n \"uuid\": \"e2b4276b-9997-4b89-a450-33a3cea014ab\",\n \"revision_id\": 884,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584458626,\n \"parent_id\": \"256\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_video\": \"https://youtu.be/szvRf458bC8\"\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"2cf688b8-5f12-4d0a-b777-6b56eb323983\",\n \"nid\": 257,\n \"vid\": 607,\n \"url\": \"/node/257\",\n \"name\": \"COVID-19: Prepare to Isolate\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-26T15:23:31+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"812cf891-c59b-46cf-b168-ab7b115118de\",\n \"name\": \"node_257.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_257.zip\"\n },\n \"tags\": [\n {\n \"id\": \"801623d6-5b1a-4934-afd2-e55f75f5bafc\",\n \"vid\": 94,\n \"tid\": 94,\n \"url\": \"/taxonomy/term/94\",\n \"name\": \"COVID-19\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:18:22+0000\"\n },\n {\n \"id\": \"eff406f7-0dff-4945-812a-be707a816230\",\n \"vid\": 95,\n \"tid\": 95,\n \"url\": \"/taxonomy/term/95\",\n \"name\": \"Coronavirus\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:45+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"e2d54015-6e0b-43aa-a6b6-bd8abf7e66f6\",\n \"vid\": 99,\n \"tid\": 99,\n \"url\": \"/taxonomy/term/99\",\n \"name\": \"Take Precautions: COVID-19\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:34:44+0000\",\n \"description\": \"The recent coronavirus outbreak is a serious health concern. Do you know how to protect yourself and others from serious illness? Arming yourself with information and strategies will help reduce the spread of disease and enable you to work effectively in the challenging circumstances of an outbreak.\"\n },\n \"description\": \"Discover what proactive steps you can take to be prepared in the event that you or someone in your household gets sick.\",\n \"image\": {\n \"UUID\": \"6b2c984f-7043-476f-bc7c-e221882a4f84\",\n \"name\": \"06_prepare_to_isolate_preview_image_0.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/06_prepare_to_isolate_preview_image_0.png.jpg?itok=H7necaWh\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/06_prepare_to_isolate_preview_image_0.png\"\n },\n \"body\": [\n {\n \"id\": 317,\n \"uuid\": \"3afe06d1-6012-45ad-9e96-0b69f7aefe77\",\n \"revision_id\": 881,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584458917,\n \"parent_id\": \"257\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

Discover what proactive steps you can take to be prepared in the event that you or someone in your household gets sick.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

Discover what proactive steps you can take to be prepared in the event that you or someone in your household gets sick.

\\n\"\n }\n },\n {\n \"id\": 318,\n \"uuid\": \"57438bfd-6e92-45f6-a1e9-8b061fa7acdf\",\n \"revision_id\": 882,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584458917,\n \"parent_id\": \"257\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_video\": \"https://youtu.be/fo9BXZJDjMY\"\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"d8d056ea-ad88-4955-8a5d-a4e18be78233\",\n \"nid\": 271,\n \"vid\": 608,\n \"url\": \"/node/271\",\n \"name\": \"COVID-19: Prepare to Work Virtually\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-26T15:21:44+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"9cb9259d-b937-49b0-8233-933e3fb43a90\",\n \"name\": \"node_271.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_271.zip\"\n },\n \"tags\": [\n {\n \"id\": \"801623d6-5b1a-4934-afd2-e55f75f5bafc\",\n \"vid\": 94,\n \"tid\": 94,\n \"url\": \"/taxonomy/term/94\",\n \"name\": \"COVID-19\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:18:22+0000\"\n },\n {\n \"id\": \"eff406f7-0dff-4945-812a-be707a816230\",\n \"vid\": 95,\n \"tid\": 95,\n \"url\": \"/taxonomy/term/95\",\n \"name\": \"Coronavirus\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:45+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"e2d54015-6e0b-43aa-a6b6-bd8abf7e66f6\",\n \"vid\": 99,\n \"tid\": 99,\n \"url\": \"/taxonomy/term/99\",\n \"name\": \"Take Precautions: COVID-19\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:34:44+0000\",\n \"description\": \"The recent coronavirus outbreak is a serious health concern. Do you know how to protect yourself and others from serious illness? Arming yourself with information and strategies will help reduce the spread of disease and enable you to work effectively in the challenging circumstances of an outbreak.\"\n },\n \"description\": \"During a disease outbreak, you may need to work from home (although not every job allows for this\\r\\ndegree of flexibility). If you do not ordinarily work remotely, ensure that you are prepared with all the\\r\\ntools you need and that you have a plan to help you be as productive as you would be at work.\",\n \"image\": {\n \"UUID\": \"e98de4da-ed4a-4d0a-b22f-5176b441eaa6\",\n \"name\": \"09_prepare_to_work_from_home_preview_image.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/09_prepare_to_work_from_home_preview_image.png.jpg?itok=FQ2SYuG_\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/09_prepare_to_work_from_home_preview_image.png\"\n },\n \"body\": [\n {\n \"id\": 345,\n \"uuid\": \"94c77451-3435-4e0b-b127-495acd4cf815\",\n \"revision_id\": 875,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584542670,\n \"parent_id\": \"271\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

During a disease outbreak, you may need to work from home (although not every job allows for this degree of flexibility). If you do not ordinarily work remotely, ensure that you are prepared with all the tools you need and that you have a plan to help you be as productive as you would be at work.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

During a disease outbreak, you may need to work from home (although not every job allows for this degree of flexibility). If you do not ordinarily work remotely, ensure that you are prepared with all the tools you need and that you have a plan to help you be as productive as you would be at work.

\\n\"\n }\n },\n {\n \"id\": 346,\n \"uuid\": \"2b01dbc7-5fc5-4a59-8ec5-92a51f5d4813\",\n \"revision_id\": 876,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584542734,\n \"parent_id\": \"271\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_document\": {\n \"target_id\": 238,\n \"display\": true,\n \"description\": \"\"\n }\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"ccbbc825-2188-45e0-9ec7-5bc1567f2b95\",\n \"nid\": 258,\n \"vid\": 609,\n \"url\": \"/node/258\",\n \"name\": \"COVID-19: Work Virtually\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-26T15:23:07+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"d50da248-7850-43bf-8444-324748aec4e1\",\n \"name\": \"node_258.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_258.zip\"\n },\n \"tags\": [\n {\n \"id\": \"801623d6-5b1a-4934-afd2-e55f75f5bafc\",\n \"vid\": 94,\n \"tid\": 94,\n \"url\": \"/taxonomy/term/94\",\n \"name\": \"COVID-19\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:18:22+0000\"\n },\n {\n \"id\": \"eff406f7-0dff-4945-812a-be707a816230\",\n \"vid\": 95,\n \"tid\": 95,\n \"url\": \"/taxonomy/term/95\",\n \"name\": \"Coronavirus\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:45+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"e2d54015-6e0b-43aa-a6b6-bd8abf7e66f6\",\n \"vid\": 99,\n \"tid\": 99,\n \"url\": \"/taxonomy/term/99\",\n \"name\": \"Take Precautions: COVID-19\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:34:44+0000\",\n \"description\": \"The recent coronavirus outbreak is a serious health concern. Do you know how to protect yourself and others from serious illness? Arming yourself with information and strategies will help reduce the spread of disease and enable you to work effectively in the challenging circumstances of an outbreak.\"\n },\n \"description\": \"You may need to work virtually during an outbreak, which can be difficult if this isn’t normal for your workplace. Learn strategies to communicate effectively with your team and maintain a high quality of work when you work virtually.\",\n \"image\": {\n \"UUID\": \"d20490ca-60fa-48c3-b2be-6de2751e438b\",\n \"name\": \"07_work_virtually_preview_image_0.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/07_work_virtually_preview_image_0.png.jpg?itok=i97BI50p\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/07_work_virtually_preview_image_0.png\"\n },\n \"body\": [\n {\n \"id\": 319,\n \"uuid\": \"1f5b5d3f-dd49-4ce5-aada-2c7a5a1d0b3d\",\n \"revision_id\": 879,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584459356,\n \"parent_id\": \"258\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

You may need to work virtually during an outbreak, which can be difficult if this isn’t normal for your workplace. Learn strategies to communicate effectively with your team and maintain a high quality of work when you work virtually.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

You may need to work virtually during an outbreak, which can be difficult if this isn’t normal for your workplace. Learn strategies to communicate effectively with your team and maintain a high quality of work when you work virtually.

\\n\"\n }\n },\n {\n \"id\": 320,\n \"uuid\": \"39e5fada-8827-4ba5-b0d5-674d280cf993\",\n \"revision_id\": 880,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584459420,\n \"parent_id\": \"258\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_video\": \"https://youtu.be/UEPFhQGcSek\"\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"09f8e9db-c1e9-47e3-adff-f0cf8132d37e\",\n \"nid\": 227,\n \"vid\": 610,\n \"url\": \"/node/227\",\n \"name\": \"Creating an Emergency Action Plan\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-10T20:56:10+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"f97b1a60-9e2b-45b3-83c9-eb5dc0da85eb\",\n \"name\": \"node_227.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_227.zip\"\n },\n \"tags\": [\n {\n \"id\": \"425e382c-8fc9-4a46-a252-cb6f20bc42eb\",\n \"vid\": 83,\n \"tid\": 83,\n \"url\": \"/taxonomy/term/83\",\n \"name\": \"Leadership\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:33:24+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"fb473dd7-86a8-40a6-8a12-c9c80d46c2fb\",\n \"vid\": 80,\n \"tid\": 80,\n \"url\": \"/taxonomy/term/80\",\n \"name\": \"Occupational Safety and Health\",\n \"type\": \"category\",\n \"changed\": \"2021-02-01T00:30:23+0000\",\n \"description\": \"This topic includes content related to the safety, health, and welfare of people at work The goal of occupational safety and health programs is to foster a safe and healthy work environment.[3] OSH may also protect co-workers, family members, employers, customers, and many others who might be affected by the workplace environment. \"\n },\n \"description\": \"A brief guide to creating an Emergency Action Plan\",\n \"image\": {\n \"UUID\": \"1f445741-9ed9-414f-8a60-68239e502915\",\n \"name\": \"emergency-plan.jpg\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/emergency-plan.jpg?itok=RG84ODJ3\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/emergency-plan.jpg\"\n },\n \"body\": [\n {\n \"id\": 262,\n \"uuid\": \"3c8cf7f3-6494-41aa-8844-60ffb4a8dca4\",\n \"revision_id\": 595,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1583858101,\n \"parent_id\": \"227\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

How to Get Started

\\r\\n\\r\\n

The best time to handle an emergency is before it ever takes place. Before you create your emergency action plan, you'll need to analyze your business and see what potential hazards you face. These can vary depending on the type of business and your location. Some emergency action plans will cover problems dealing with hazardous materials on hand, some will need to deal with issues stemming from older buildings that were built to a lower-standard safety code, and some will need to have strategies in place to prepare for natural disasters more likely in certain areas, such as hurricanes, earthquakes, and tornadoes.

\\r\\n\\r\\n

While many things will be different depending on the type of emergency you are preparing for—what you do during a tornado or earthquake will be much different than what you do during a fire or workplace violence incident, for example—some of the basic preparations will be similar for multiple problems. Always provide steps for getting people to safety, whether that means sheltering or evacuating them, and always have a clear and effective plan for communicating with everyone who could be affected.

\\r\\n\\r\\n

Be sure to investigate not just what hazards you may face and how to stay safe during them, but also what effects they will have afterward. This should reveal such considerations as what lost income and increased expenses could be caused by your business being shut down for various amounts of time, the effect of lost customers, the delay of new business plans, and other effects of a disruption of service. Be as exact as possible in order to get a good idea of what costs you might accrue so you can most accurately plan for a disaster.

\\r\\n\\r\\n

FEMA provides a Business Impact Analysis Worksheet you can distribute to management and any other employees you feel can contribute to your preparations. Download the worksheet here: http://www.ready.gov/sites/default/files/documents/files/BusinessImpactAnalysis_Worksheet.pdf

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

How to Get Started

\\n

The best time to handle an emergency is before it ever takes place. Before you create your emergency action plan, you'll need to analyze your business and see what potential hazards you face. These can vary depending on the type of business and your location. Some emergency action plans will cover problems dealing with hazardous materials on hand, some will need to deal with issues stemming from older buildings that were built to a lower-standard safety code, and some will need to have strategies in place to prepare for natural disasters more likely in certain areas, such as hurricanes, earthquakes, and tornadoes.

\\n

While many things will be different depending on the type of emergency you are preparing for—what you do during a tornado or earthquake will be much different than what you do during a fire or workplace violence incident, for example—some of the basic preparations will be similar for multiple problems. Always provide steps for getting people to safety, whether that means sheltering or evacuating them, and always have a clear and effective plan for communicating with everyone who could be affected.

\\n

Be sure to investigate not just what hazards you may face and how to stay safe during them, but also what effects they will have afterward. This should reveal such considerations as what lost income and increased expenses could be caused by your business being shut down for various amounts of time, the effect of lost customers, the delay of new business plans, and other effects of a disruption of service. Be as exact as possible in order to get a good idea of what costs you might accrue so you can most accurately plan for a disaster.

\\n

FEMA provides a Business Impact Analysis Worksheet you can distribute to management and any other employees you feel can contribute to your preparations. Download the worksheet here: http://www.ready.gov/sites/default/files/documents/files/BusinessImpactAnalysis_Worksheet.pdf

\\n\"\n }\n },\n {\n \"id\": 263,\n \"uuid\": \"ec1ac160-2f77-46ed-ad14-05ae02cb089a\",\n \"revision_id\": 596,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1583858229,\n \"parent_id\": \"227\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

Create Your Emergency Action Plan

\\r\\n\\r\\n

Once you have identified all of the possible threats you may face and the potential effects, you should come up with responses for the hazards. Here are some tips to keep in mind.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

Create Your Emergency Action Plan

\\n

Once you have identified all of the possible threats you may face and the potential effects, you should come up with responses for the hazards. Here are some tips to keep in mind.

\\n\"\n }\n },\n {\n \"id\": 264,\n \"uuid\": \"6c1ea93c-3ef8-45db-a215-5294eba0e717\",\n \"revision_id\": 597,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1583858298,\n \"parent_id\": \"227\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_list_content\": {\n \"value\": \"
    \\r\\n\\t
  • For emergency situations, have an individual in charge of following and getting others to follow the procedures you outline. For larger companies, you may need more than one, in separate departments or as backups, but in this case make sure the hierarchy is clearly laid out. Employees must know this individual is in charge and has authority during an emergency.
  • \\r\\n\\t
  • Ensure the methods for reporting fires and other emergencies are clear, whether it's dialing 911, calling an internal emergency number, pulling a manual fire alarm, or other procedure which may change depending on the type of emergency.
  • \\r\\n\\t
  • Create evacuation policies and paths that are clear and easy to follow.
  • \\r\\n\\t
  • Have procedures in place for employees who must remain during the beginning of an evacuation to take care of greater hazards. This includes employees who must use fire extinguishers, shut down gas lines and/or electrical systems, or safeguard hazardous materials to keep a bad situation from getting worse.
  • \\r\\n\\t
  • Be prepared for the loss of computer hardware, software, and information related to technological disruptions, and find ways to back up and recover it.
  • \\r\\n\\t
  • Note who is able to perform medical care, from first aid to CPR, and make sure they are in the proper positions to do so.
  • \\r\\n\\t
  • Provide clear communication during and immediately after any dangerous incident.
  • \\r\\n
\\r\\n\",\n \"format\": \"list\",\n \"processed\": \"
    \\n
  • For emergency situations, have an individual in charge of following and getting others to follow the procedures you outline. For larger companies, you may need more than one, in separate departments or as backups, but in this case make sure the hierarchy is clearly laid out. Employees must know this individual is in charge and has authority during an emergency.
  • \\n
  • Ensure the methods for reporting fires and other emergencies are clear, whether it's dialing 911, calling an internal emergency number, pulling a manual fire alarm, or other procedure which may change depending on the type of emergency.
  • \\n
  • Create evacuation policies and paths that are clear and easy to follow.
  • \\n
  • Have procedures in place for employees who must remain during the beginning of an evacuation to take care of greater hazards. This includes employees who must use fire extinguishers, shut down gas lines and/or electrical systems, or safeguard hazardous materials to keep a bad situation from getting worse.
  • \\n
  • Be prepared for the loss of computer hardware, software, and information related to technological disruptions, and find ways to back up and recover it.
  • \\n
  • Note who is able to perform medical care, from first aid to CPR, and make sure they are in the proper positions to do so.
  • \\n
  • Provide clear communication during and immediately after any dangerous incident.
  • \\n
\\n\"\n },\n \"field_list_items\": []\n },\n {\n \"id\": 265,\n \"uuid\": \"ce2878bd-402e-4e04-ae93-3aa1ae3ca2d1\",\n \"revision_id\": 598,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1583858383,\n \"parent_id\": \"227\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

OSHA has several resources to help you prepare your emergency action plan.

\\r\\n\\r\\n\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

OSHA has several resources to help you prepare your emergency action plan.

\\n\\n\"\n }\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"0113f56c-e06b-4d21-b0db-688e74447834\",\n \"nid\": 229,\n \"vid\": 519,\n \"url\": \"/node/229\",\n \"name\": \"Did you know? 40% of Businesses Affected by Disaster Never Reopen. \",\n \"type\": \"tip_card\",\n \"changed\": \"2020-03-18T19:24:07+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": [],\n \"topic\": {\n \"id\": \"fb473dd7-86a8-40a6-8a12-c9c80d46c2fb\",\n \"vid\": 80,\n \"tid\": 80,\n \"url\": \"/taxonomy/term/80\",\n \"name\": \"Occupational Safety and Health\",\n \"type\": \"category\",\n \"changed\": \"2021-02-01T00:30:23+0000\",\n \"description\": \"This topic includes content related to the safety, health, and welfare of people at work The goal of occupational safety and health programs is to foster a safe and healthy work environment.[3] OSH may also protect co-workers, family members, employers, customers, and many others who might be affected by the workplace environment. \"\n },\n \"contents\": [\n \"
\\n
\\n
\\n \\n

The main reason to have an emergency action plan is to do as much as possible to keep your employees safe in case of disaster but a good plan can keep your business safe as well. Up to 40% of businesses affected by a natural or human-caused disaster never reopen. Having procedures in place to deal with disasters can help your business survive this difficult experience.

\\n

 

\\n
\\n \\n
\\n
\\n\\n
\\n\",\n \"
\\n
\\n
\\n \\n
\\\"Closed\\n\\n\\n
\\n \\n
\\n
\\n\\n
\\n\"\n ],\n \"body\": [\n {\n \"id\": \"c548cc2f-d8f0-4a98-88f5-f96ae130d076\",\n \"type\": \"text\",\n \"fields\": [\n {\n \"type\": \"Label\",\n \"attributes\": {\n \"Text\": \"

The main reason to have an emergency action plan is to do as much as possible to keep your employees safe in case of disaster but a good plan can keep your business safe as well. Up to 40% of businesses affected by a natural or human-caused disaster never reopen. Having procedures in place to deal with disasters can help your business survive this difficult experience.

\\r\\n\\r\\n

 

\",\n \"TextType\": \"Html\"\n }\n }\n ]\n },\n {\n \"id\": \"b74d5871-47ad-4d40-baa0-d1f225f18abf\",\n \"type\": \"image\",\n \"fields\": [\n {\n \"type\": \"Image\",\n \"attributes\": {\n \"Source\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/benedikt-geyer-Qq_F_5kS7uo-unsplash.jpg?itok=eIObe6Xf\",\n \"Aspect\": \"AspectFit\"\n }\n }\n ]\n }\n ]\n },\n {\n \"id\": \"960ad1e3-66e0-4388-baa7-62cbf7e87bdb\",\n \"nid\": 226,\n \"vid\": 611,\n \"url\": \"/node/226\",\n \"name\": \"Emergency Action Plan – Why Should You Have One?\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-10T18:53:36+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"6acf8cc1-ae88-411c-86f5-0998666ba4ec\",\n \"name\": \"node_226.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_226.zip\"\n },\n \"tags\": [\n {\n \"id\": \"425e382c-8fc9-4a46-a252-cb6f20bc42eb\",\n \"vid\": 83,\n \"tid\": 83,\n \"url\": \"/taxonomy/term/83\",\n \"name\": \"Leadership\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:33:24+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"fb473dd7-86a8-40a6-8a12-c9c80d46c2fb\",\n \"vid\": 80,\n \"tid\": 80,\n \"url\": \"/taxonomy/term/80\",\n \"name\": \"Occupational Safety and Health\",\n \"type\": \"category\",\n \"changed\": \"2021-02-01T00:30:23+0000\",\n \"description\": \"This topic includes content related to the safety, health, and welfare of people at work The goal of occupational safety and health programs is to foster a safe and healthy work environment.[3] OSH may also protect co-workers, family members, employers, customers, and many others who might be affected by the workplace environment. \"\n },\n \"description\": \"Rationale for why your workplace should have an Emergency Action Plan.\",\n \"image\": {\n \"UUID\": \"b302865b-6e06-44ab-91ce-7229de0490ad\",\n \"name\": \"isravel-raj-YuN8QjfBYUY-unsplash.jpg\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/isravel-raj-YuN8QjfBYUY-unsplash.jpg?itok=c2wu3JnG\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/isravel-raj-YuN8QjfBYUY-unsplash.jpg\"\n },\n \"body\": [\n {\n \"id\": 260,\n \"uuid\": \"3c623628-2b4b-418b-8206-1bb86e31c13a\",\n \"revision_id\": 582,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1583857015,\n \"parent_id\": \"226\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

The main reason to have an emergency action plan is to do as much as possible to keep your employees safe in case of disaster. The confusion of an emergency can make a bad situation worse and put lives at risk. The Federal Emergency Management Agency (FEMA) provides more reasons an emergency action plan is important from a purely business perspective.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

The main reason to have an emergency action plan is to do as much as possible to keep your employees safe in case of disaster. The confusion of an emergency can make a bad situation worse and put lives at risk. The Federal Emergency Management Agency (FEMA) provides more reasons an emergency action plan is important from a purely business perspective.

\\n\"\n }\n },\n {\n \"id\": 261,\n \"uuid\": \"076bcddf-01f7-42b1-9a41-5f9910d0114b\",\n \"revision_id\": 583,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1583856683,\n \"parent_id\": \"226\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_list_content\": {\n \"value\": \"
    \\r\\n\\t
  • Up to 40% of businesses affected by a natural or human-caused disaster never reopen. Having procedures in place to deal with disasters can help your business survive this difficult experience.
  • \\r\\n\\t
  • Customers may not understand the disaster and its effects on your business. They'll still expect products or service on time. If there's a significant delay, they may take their business to a competitor.
  • \\r\\n\\t
  • Even if a disaster does slow or shut down your business, a robust emergency action plan has procedures in place to contact customers and stakeholders quickly to keep them up to date on what has happened. News travels fast and perceptions are often different from reality. Staying on top of the information stream reduces negative perception.
  • \\r\\n\\t
  • Insurance often only provides partial assistance. It does not cover all losses and does not bring back lost customers.
  • \\r\\n\\t
  • Public agencies cannot be expected to provide total relief either. Many disasters can overwhelm their resources, meaning aid may not be immediate even when it is available.
  • \\r\\n\\t
  • Many large businesses are now expecting their suppliers to have preparations in place for emergencies, trying to make sure their own business will not be hurt if something happens to another company on the supply chain. Without a plan in place, your business could be given to a competitor.
  • \\r\\n
\\r\\n\",\n \"format\": \"list\",\n \"processed\": \"
    \\n
  • Up to 40% of businesses affected by a natural or human-caused disaster never reopen. Having procedures in place to deal with disasters can help your business survive this difficult experience.
  • \\n
  • Customers may not understand the disaster and its effects on your business. They'll still expect products or service on time. If there's a significant delay, they may take their business to a competitor.
  • \\n
  • Even if a disaster does slow or shut down your business, a robust emergency action plan has procedures in place to contact customers and stakeholders quickly to keep them up to date on what has happened. News travels fast and perceptions are often different from reality. Staying on top of the information stream reduces negative perception.
  • \\n
  • Insurance often only provides partial assistance. It does not cover all losses and does not bring back lost customers.
  • \\n
  • Public agencies cannot be expected to provide total relief either. Many disasters can overwhelm their resources, meaning aid may not be immediate even when it is available.
  • \\n
  • Many large businesses are now expecting their suppliers to have preparations in place for emergencies, trying to make sure their own business will not be hurt if something happens to another company on the supply chain. Without a plan in place, your business could be given to a competitor.
  • \\n
\\n\"\n },\n \"field_list_items\": []\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"37608fae-33d6-4adc-bba3-2586494a51c8\",\n \"nid\": 265,\n \"vid\": 612,\n \"url\": \"/node/265\",\n \"name\": \"Form Your Virtual Team: 1 More Thing About Forming Your Virtual Team\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-18T14:21:22+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"9d604b51-3c10-4bef-b11d-d85d83c05e4b\",\n \"name\": \"node_265.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_265.zip\"\n },\n \"tags\": [\n {\n \"id\": \"2e03cfc6-7b44-4853-a629-1283b7b6b5cd\",\n \"vid\": 93,\n \"tid\": 93,\n \"url\": \"/taxonomy/term/93\",\n \"name\": \"SLGO\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-16T19:38:00+0000\"\n },\n {\n \"id\": \"a2cfcf08-21e8-4d9e-a0a2-e4ce0ff9f58b\",\n \"vid\": 96,\n \"tid\": 96,\n \"url\": \"/taxonomy/term/96\",\n \"name\": \"Working Remotely\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:32+0000\"\n },\n {\n \"id\": \"81d34d52-d62b-4769-9ab4-3f07897372c5\",\n \"vid\": 97,\n \"tid\": 97,\n \"url\": \"/taxonomy/term/97\",\n \"name\": \"Work from Home\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:24+0000\"\n },\n {\n \"id\": \"f49d9d61-21ba-472d-9100-3e83beeacf33\",\n \"vid\": 98,\n \"tid\": 98,\n \"url\": \"/taxonomy/term/98\",\n \"name\": \"Virtual Team\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:03+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"39299858-9ea2-4e61-bf1e-7c7a8a91bdc9\",\n \"vid\": 100,\n \"tid\": 100,\n \"url\": \"/taxonomy/term/100\",\n \"name\": \"Virtual Team\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:18:16+0000\",\n \"description\": \"These days everything’s moving online… even your team. Are you ready? Knowing how to identify the dynamics of your team, communicate clearly with everyone & foster trust will give you the basic skills you need as a manager to bridge the distance & form your virtual team. \"\n },\n \"description\": \"Consider this final piece of advice on how to keep team members engaged through casual communication channels as you work to form your virtual team.\",\n \"image\": {\n \"UUID\": \"c718ad5c-9a8c-41ed-afe5-467d26815103\",\n \"name\": \"1_more_thing_preview_image_0.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/1_more_thing_preview_image_0.png.jpg?itok=A08X2K9C\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/1_more_thing_preview_image_0.png\"\n },\n \"body\": [\n {\n \"id\": 333,\n \"uuid\": \"0ff6b931-3c9f-47ac-b3b9-139d64a411ea\",\n \"revision_id\": 772,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584464025,\n \"parent_id\": \"265\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

Consider this final piece of advice on how to keep team members engaged through casual communication channels as you work to form your virtual team.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

Consider this final piece of advice on how to keep team members engaged through casual communication channels as you work to form your virtual team.

\\n\"\n }\n },\n {\n \"id\": 344,\n \"uuid\": \"95b168e1-6637-4293-a887-3e66bb12a83f\",\n \"revision_id\": 773,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584477383,\n \"parent_id\": \"265\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_video\": \"https://youtu.be/j3N1ryenxxM\"\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"af9ac669-8e56-42c9-abca-4d83ca10cd5c\",\n \"nid\": 264,\n \"vid\": 613,\n \"url\": \"/node/264\",\n \"name\": \"Form Your Virtual Team: Bridge the Distance\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-18T14:21:52+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"b1dca302-5c13-470c-af91-26d796a38317\",\n \"name\": \"node_264.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_264.zip\"\n },\n \"tags\": [\n {\n \"id\": \"2e03cfc6-7b44-4853-a629-1283b7b6b5cd\",\n \"vid\": 93,\n \"tid\": 93,\n \"url\": \"/taxonomy/term/93\",\n \"name\": \"SLGO\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-16T19:38:00+0000\"\n },\n {\n \"id\": \"81d34d52-d62b-4769-9ab4-3f07897372c5\",\n \"vid\": 97,\n \"tid\": 97,\n \"url\": \"/taxonomy/term/97\",\n \"name\": \"Work from Home\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:24+0000\"\n },\n {\n \"id\": \"a2cfcf08-21e8-4d9e-a0a2-e4ce0ff9f58b\",\n \"vid\": 96,\n \"tid\": 96,\n \"url\": \"/taxonomy/term/96\",\n \"name\": \"Working Remotely\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:32+0000\"\n },\n {\n \"id\": \"f49d9d61-21ba-472d-9100-3e83beeacf33\",\n \"vid\": 98,\n \"tid\": 98,\n \"url\": \"/taxonomy/term/98\",\n \"name\": \"Virtual Team\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:03+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"39299858-9ea2-4e61-bf1e-7c7a8a91bdc9\",\n \"vid\": 100,\n \"tid\": 100,\n \"url\": \"/taxonomy/term/100\",\n \"name\": \"Virtual Team\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:18:16+0000\",\n \"description\": \"These days everything’s moving online… even your team. Are you ready? Knowing how to identify the dynamics of your team, communicate clearly with everyone & foster trust will give you the basic skills you need as a manager to bridge the distance & form your virtual team. \"\n },\n \"description\": \"Getting everyone on the same page on a virtual team means being through & specific with your communication details. Find out how to select the right technological tools & use agreed upon terms to make communication easier.\",\n \"image\": {\n \"UUID\": \"7080cb95-17b5-4ad1-a071-4251472476b3\",\n \"name\": \"Bridge_the_Distance_preview_image_0.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/Bridge_the_Distance_preview_image_0.png.jpg?itok=bfB5hsew\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/Bridge_the_Distance_preview_image_0.png\"\n },\n \"body\": [\n {\n \"id\": 331,\n \"uuid\": \"6bc0db84-d9fa-4475-9ae7-210629be5f2b\",\n \"revision_id\": 774,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584463759,\n \"parent_id\": \"264\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

Getting everyone on the same page on a virtual team means being through & specific with your communication details. Find out how to select the right technological tools & use agreed upon terms to make communication easier.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

Getting everyone on the same page on a virtual team means being through & specific with your communication details. Find out how to select the right technological tools & use agreed upon terms to make communication easier.

\\n\"\n }\n },\n {\n \"id\": 332,\n \"uuid\": \"61441c5c-b2ff-4c5c-9bc5-ae6a1a3d223a\",\n \"revision_id\": 775,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584463801,\n \"parent_id\": \"264\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_video\": \"https://youtu.be/ROfJ_tqUqN4\"\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"f833653e-4077-472f-8f52-5b76227a4d71\",\n \"nid\": 262,\n \"vid\": 614,\n \"url\": \"/node/262\",\n \"name\": \"Form Your Virtual Team: Communicate With Clarity\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-18T14:24:44+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"a66dc7ac-b204-49ec-bcc4-9baa0c8eda10\",\n \"name\": \"node_262.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_262.zip\"\n },\n \"tags\": [\n {\n \"id\": \"2e03cfc6-7b44-4853-a629-1283b7b6b5cd\",\n \"vid\": 93,\n \"tid\": 93,\n \"url\": \"/taxonomy/term/93\",\n \"name\": \"SLGO\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-16T19:38:00+0000\"\n },\n {\n \"id\": \"81d34d52-d62b-4769-9ab4-3f07897372c5\",\n \"vid\": 97,\n \"tid\": 97,\n \"url\": \"/taxonomy/term/97\",\n \"name\": \"Work from Home\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:24+0000\"\n },\n {\n \"id\": \"f49d9d61-21ba-472d-9100-3e83beeacf33\",\n \"vid\": 98,\n \"tid\": 98,\n \"url\": \"/taxonomy/term/98\",\n \"name\": \"Virtual Team\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:03+0000\"\n },\n {\n \"id\": \"a2cfcf08-21e8-4d9e-a0a2-e4ce0ff9f58b\",\n \"vid\": 96,\n \"tid\": 96,\n \"url\": \"/taxonomy/term/96\",\n \"name\": \"Working Remotely\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:32+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"39299858-9ea2-4e61-bf1e-7c7a8a91bdc9\",\n \"vid\": 100,\n \"tid\": 100,\n \"url\": \"/taxonomy/term/100\",\n \"name\": \"Virtual Team\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:18:16+0000\",\n \"description\": \"These days everything’s moving online… even your team. Are you ready? Knowing how to identify the dynamics of your team, communicate clearly with everyone & foster trust will give you the basic skills you need as a manager to bridge the distance & form your virtual team. \"\n },\n \"description\": \"Extra, open & honest communication is needed to keep a virtual team running smoothly. Learn how clearly defined roles & designated responsibilities will keep things on track. \",\n \"image\": {\n \"UUID\": \"666bb1f7-76d5-4215-bedd-434b5e46c815\",\n \"name\": \"communicate_with_clarity_0.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/communicate_with_clarity_0.png.jpg?itok=dTn2qagE\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/communicate_with_clarity_0.png\"\n },\n \"body\": [\n {\n \"id\": 327,\n \"uuid\": \"d1fb45ad-c4aa-4c86-b700-08858787ad10\",\n \"revision_id\": 778,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584461685,\n \"parent_id\": \"262\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

Extra, open & honest communication is needed to keep a virtual team running smoothly. Learn how clearly defined roles & designated responsibilities will keep things on track. 

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

Extra, open & honest communication is needed to keep a virtual team running smoothly. Learn how clearly defined roles & designated responsibilities will keep things on track. 

\\n\"\n }\n },\n {\n \"id\": 328,\n \"uuid\": \"0d95682d-1112-4b05-adba-c57ad4d614ad\",\n \"revision_id\": 779,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584461716,\n \"parent_id\": \"262\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_video\": \"https://youtu.be/57nUlH8cFj0\"\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"cbdb4d52-68a3-4c9c-9177-d37d0c973232\",\n \"nid\": 261,\n \"vid\": 615,\n \"url\": \"/node/261\",\n \"name\": \"Form Your Virtual Team: Consider Your Team\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-18T14:25:13+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"93dab80a-0f9c-433c-b644-a296da18ddcc\",\n \"name\": \"node_261.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_261.zip\"\n },\n \"tags\": [\n {\n \"id\": \"81d34d52-d62b-4769-9ab4-3f07897372c5\",\n \"vid\": 97,\n \"tid\": 97,\n \"url\": \"/taxonomy/term/97\",\n \"name\": \"Work from Home\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:24+0000\"\n },\n {\n \"id\": \"a2cfcf08-21e8-4d9e-a0a2-e4ce0ff9f58b\",\n \"vid\": 96,\n \"tid\": 96,\n \"url\": \"/taxonomy/term/96\",\n \"name\": \"Working Remotely\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:32+0000\"\n },\n {\n \"id\": \"f49d9d61-21ba-472d-9100-3e83beeacf33\",\n \"vid\": 98,\n \"tid\": 98,\n \"url\": \"/taxonomy/term/98\",\n \"name\": \"Virtual Team\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:03+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"39299858-9ea2-4e61-bf1e-7c7a8a91bdc9\",\n \"vid\": 100,\n \"tid\": 100,\n \"url\": \"/taxonomy/term/100\",\n \"name\": \"Virtual Team\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:18:16+0000\",\n \"description\": \"These days everything’s moving online… even your team. Are you ready? Knowing how to identify the dynamics of your team, communicate clearly with everyone & foster trust will give you the basic skills you need as a manager to bridge the distance & form your virtual team. \"\n },\n \"description\": \"The environment surrounding your team matters to your management strategy. Consider how physical location, time difference, & cultural norms will affect how you & your team interact.\",\n \"image\": {\n \"UUID\": \"cb63ccec-5701-4b4f-a0b9-b81e4374fb94\",\n \"name\": \"consider_your_team_preview_image_0.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/consider_your_team_preview_image_0.png.jpg?itok=7aW_sFhv\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/consider_your_team_preview_image_0.png\"\n },\n \"body\": [\n {\n \"id\": 325,\n \"uuid\": \"58703df8-651c-43d4-a755-db04e29a4178\",\n \"revision_id\": 780,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584460911,\n \"parent_id\": \"261\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

The environment surrounding your team matters to your management strategy. Consider how physical location, time difference, & cultural norms will affect how you & your team interact.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

The environment surrounding your team matters to your management strategy. Consider how physical location, time difference, & cultural norms will affect how you & your team interact.

\\n\"\n }\n },\n {\n \"id\": 326,\n \"uuid\": \"96692ce2-69f6-43d6-ba95-532bfc8ff24a\",\n \"revision_id\": 781,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584461035,\n \"parent_id\": \"261\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_video\": \"https://youtu.be/DedwabN7a_g\"\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"77505e29-789c-4355-9b17-961b20a5176e\",\n \"nid\": 263,\n \"vid\": 616,\n \"url\": \"/node/263\",\n \"name\": \"Form Your Virtual Team: Foster Trust\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-18T14:22:25+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"885d627c-bfe2-4893-b510-bd909b10c240\",\n \"name\": \"node_263.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_263.zip\"\n },\n \"tags\": [\n {\n \"id\": \"2e03cfc6-7b44-4853-a629-1283b7b6b5cd\",\n \"vid\": 93,\n \"tid\": 93,\n \"url\": \"/taxonomy/term/93\",\n \"name\": \"SLGO\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-16T19:38:00+0000\"\n },\n {\n \"id\": \"81d34d52-d62b-4769-9ab4-3f07897372c5\",\n \"vid\": 97,\n \"tid\": 97,\n \"url\": \"/taxonomy/term/97\",\n \"name\": \"Work from Home\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:24+0000\"\n },\n {\n \"id\": \"a2cfcf08-21e8-4d9e-a0a2-e4ce0ff9f58b\",\n \"vid\": 96,\n \"tid\": 96,\n \"url\": \"/taxonomy/term/96\",\n \"name\": \"Working Remotely\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:32+0000\"\n },\n {\n \"id\": \"f49d9d61-21ba-472d-9100-3e83beeacf33\",\n \"vid\": 98,\n \"tid\": 98,\n \"url\": \"/taxonomy/term/98\",\n \"name\": \"Virtual Team\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:03+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"39299858-9ea2-4e61-bf1e-7c7a8a91bdc9\",\n \"vid\": 100,\n \"tid\": 100,\n \"url\": \"/taxonomy/term/100\",\n \"name\": \"Virtual Team\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:18:16+0000\",\n \"description\": \"These days everything’s moving online… even your team. Are you ready? Knowing how to identify the dynamics of your team, communicate clearly with everyone & foster trust will give you the basic skills you need as a manager to bridge the distance & form your virtual team. \"\n },\n \"description\": \"Trust is critical for all teams, but how do you foster trust when people are separated? Discover how to build rapport, either in person or online, to help your virtual team members learn to trust one another.\",\n \"image\": {\n \"UUID\": \"22367a71-754b-4c28-abf1-a18e2c1071f1\",\n \"name\": \"Foster_Trust_preview_image_0.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/Foster_Trust_preview_image_0.png.jpg?itok=_I_MQOeM\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/Foster_Trust_preview_image_0.png\"\n },\n \"body\": [\n {\n \"id\": 329,\n \"uuid\": \"0d73664a-7988-4779-85c0-0472acefa741\",\n \"revision_id\": 776,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584462530,\n \"parent_id\": \"263\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

Trust is critical for all teams, but how do you foster trust when people are separated? Discover how to build rapport, either in person or online, to help your virtual team members learn to trust one another.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

Trust is critical for all teams, but how do you foster trust when people are separated? Discover how to build rapport, either in person or online, to help your virtual team members learn to trust one another.

\\n\"\n }\n },\n {\n \"id\": 330,\n \"uuid\": \"fc078590-0aac-47b5-a43b-964a2e80f646\",\n \"revision_id\": 777,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584462565,\n \"parent_id\": \"263\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_video\": \"https://youtu.be/S2mTBXE54pQ\"\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"ba541590-ac32-4021-b005-001e87b824e4\",\n \"nid\": 273,\n \"vid\": 617,\n \"url\": \"/node/273\",\n \"name\": \"Form Your Virtual Team: Identify the Environment\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-06-11T20:03:11+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"f0860bf7-9d40-4b01-a227-2a1ffa396380\",\n \"name\": \"node_273.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_273.zip\"\n },\n \"tags\": [\n {\n \"id\": \"2e03cfc6-7b44-4853-a629-1283b7b6b5cd\",\n \"vid\": 93,\n \"tid\": 93,\n \"url\": \"/taxonomy/term/93\",\n \"name\": \"SLGO\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-16T19:38:00+0000\"\n },\n {\n \"id\": \"a2cfcf08-21e8-4d9e-a0a2-e4ce0ff9f58b\",\n \"vid\": 96,\n \"tid\": 96,\n \"url\": \"/taxonomy/term/96\",\n \"name\": \"Working Remotely\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:32+0000\"\n },\n {\n \"id\": \"81d34d52-d62b-4769-9ab4-3f07897372c5\",\n \"vid\": 97,\n \"tid\": 97,\n \"url\": \"/taxonomy/term/97\",\n \"name\": \"Work from Home\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:24+0000\"\n },\n {\n \"id\": \"f49d9d61-21ba-472d-9100-3e83beeacf33\",\n \"vid\": 98,\n \"tid\": 98,\n \"url\": \"/taxonomy/term/98\",\n \"name\": \"Virtual Team\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:03+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"39299858-9ea2-4e61-bf1e-7c7a8a91bdc9\",\n \"vid\": 100,\n \"tid\": 100,\n \"url\": \"/taxonomy/term/100\",\n \"name\": \"Virtual Team\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:18:16+0000\",\n \"description\": \"These days everything’s moving online… even your team. Are you ready? Knowing how to identify the dynamics of your team, communicate clearly with everyone & foster trust will give you the basic skills you need as a manager to bridge the distance & form your virtual team. \"\n },\n \"description\": \"Take the time to consider the environment surrounding your virtual team. Where are members\\r\\nphysically located? What time differences and cultural boundaries will impact how you will work? Use\\r\\nthis checklist to determine these critical environmental factors.\",\n \"image\": {\n \"UUID\": \"f6bdfdc9-31c5-46e3-b43a-8f073cb9ae87\",\n \"name\": \"identify_environment_preview_image_0.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/identify_environment_preview_image_0.png.jpg?itok=jkvYy0gv\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/identify_environment_preview_image_0.png\"\n },\n \"body\": [\n {\n \"id\": 348,\n \"uuid\": \"3b023d03-b180-49fe-98ad-809051659fb3\",\n \"revision_id\": 789,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584544601,\n \"parent_id\": \"273\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": true,\n \"field_paragraph_body\": {\n \"value\": \"

 

\\r\\n\\r\\n

 Take the time to consider the environment surrounding your virtual team. Where are members physically located? What time differences and cultural boundaries will impact how you will work? Use this checklist to determine these critical environmental factors. 

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

 

\\n

 Take the time to consider the environment surrounding your virtual team. Where are members physically located? What time differences and cultural boundaries will impact how you will work? Use this checklist to determine these critical environmental factors. 

\\n\"\n }\n },\n {\n \"id\": 349,\n \"uuid\": \"7a0cbe76-7dcd-4317-8c48-f7039ab09d8d\",\n \"revision_id\": 790,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584544651,\n \"parent_id\": \"273\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": true,\n \"field_document\": {\n \"target_id\": 242,\n \"display\": true,\n \"description\": \"\"\n }\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"6f4b9aa4-f025-4a9e-9d65-e3f021feb478\",\n \"nid\": 274,\n \"vid\": 618,\n \"url\": \"/node/274\",\n \"name\": \"Form Your Virtual Team: Identify Your Team's Virtual Environment\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-06-11T20:03:11+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"e04b2083-3567-46df-b6dc-444113f21a3a\",\n \"name\": \"node_274.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_274.zip\"\n },\n \"tags\": [\n {\n \"id\": \"2e03cfc6-7b44-4853-a629-1283b7b6b5cd\",\n \"vid\": 93,\n \"tid\": 93,\n \"url\": \"/taxonomy/term/93\",\n \"name\": \"SLGO\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-16T19:38:00+0000\"\n },\n {\n \"id\": \"81d34d52-d62b-4769-9ab4-3f07897372c5\",\n \"vid\": 97,\n \"tid\": 97,\n \"url\": \"/taxonomy/term/97\",\n \"name\": \"Work from Home\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:24+0000\"\n },\n {\n \"id\": \"a2cfcf08-21e8-4d9e-a0a2-e4ce0ff9f58b\",\n \"vid\": 96,\n \"tid\": 96,\n \"url\": \"/taxonomy/term/96\",\n \"name\": \"Working Remotely\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:32+0000\"\n },\n {\n \"id\": \"f49d9d61-21ba-472d-9100-3e83beeacf33\",\n \"vid\": 98,\n \"tid\": 98,\n \"url\": \"/taxonomy/term/98\",\n \"name\": \"Virtual Team\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:03+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"39299858-9ea2-4e61-bf1e-7c7a8a91bdc9\",\n \"vid\": 100,\n \"tid\": 100,\n \"url\": \"/taxonomy/term/100\",\n \"name\": \"Virtual Team\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:18:16+0000\",\n \"description\": \"These days everything’s moving online… even your team. Are you ready? Knowing how to identify the dynamics of your team, communicate clearly with everyone & foster trust will give you the basic skills you need as a manager to bridge the distance & form your virtual team. \"\n },\n \"description\": \"Where your team members are located matters and it makes a difference in how you craft your\\r\\nmanagement strategy. Consider how the three factors of physical location, time difference, and\\r\\ncultural boundaries impact and shape your team’s environment.\",\n \"image\": {\n \"UUID\": \"f5280391-910e-49c4-aee1-2f3e4b82f99c\",\n \"name\": \"identify_Virtual_environment_preview_image.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/identify_Virtual_environment_preview_image.png.jpg?itok=hqJ4i49c\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/identify_Virtual_environment_preview_image.png\"\n },\n \"body\": [\n {\n \"id\": 350,\n \"uuid\": \"ea0bb7dd-1d34-4013-9fa0-901fb1235bce\",\n \"revision_id\": 791,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584545130,\n \"parent_id\": \"274\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": true,\n \"field_paragraph_body\": {\n \"value\": \"

Where your team members are located matters and it makes a difference in how you craft your management strategy. Consider how the three factors of physical location, time difference, and cultural boundaries impact and shape your team’s environment. 

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

Where your team members are located matters and it makes a difference in how you craft your management strategy. Consider how the three factors of physical location, time difference, and cultural boundaries impact and shape your team’s environment. 

\\n\"\n }\n },\n {\n \"id\": 351,\n \"uuid\": \"31b890db-9c89-4e72-8426-e45bbedcde59\",\n \"revision_id\": 792,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584545184,\n \"parent_id\": \"274\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": true,\n \"field_document\": {\n \"target_id\": 244,\n \"display\": true,\n \"description\": \"\"\n }\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"c2e5e16a-6354-4fcb-b82d-74915c561f9f\",\n \"nid\": 260,\n \"vid\": 619,\n \"url\": \"/node/260\",\n \"name\": \"Form Your Virtual Team: Set Your Team Up for Success\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-18T14:25:40+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"d839c9cc-0a69-4b3e-be8d-7641b71f4470\",\n \"name\": \"node_260.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_260.zip\"\n },\n \"tags\": [\n {\n \"id\": \"2e03cfc6-7b44-4853-a629-1283b7b6b5cd\",\n \"vid\": 93,\n \"tid\": 93,\n \"url\": \"/taxonomy/term/93\",\n \"name\": \"SLGO\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-16T19:38:00+0000\"\n },\n {\n \"id\": \"a2cfcf08-21e8-4d9e-a0a2-e4ce0ff9f58b\",\n \"vid\": 96,\n \"tid\": 96,\n \"url\": \"/taxonomy/term/96\",\n \"name\": \"Working Remotely\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:32+0000\"\n },\n {\n \"id\": \"81d34d52-d62b-4769-9ab4-3f07897372c5\",\n \"vid\": 97,\n \"tid\": 97,\n \"url\": \"/taxonomy/term/97\",\n \"name\": \"Work from Home\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:24+0000\"\n },\n {\n \"id\": \"f49d9d61-21ba-472d-9100-3e83beeacf33\",\n \"vid\": 98,\n \"tid\": 98,\n \"url\": \"/taxonomy/term/98\",\n \"name\": \"Virtual Team\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:03+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"39299858-9ea2-4e61-bf1e-7c7a8a91bdc9\",\n \"vid\": 100,\n \"tid\": 100,\n \"url\": \"/taxonomy/term/100\",\n \"name\": \"Virtual Team\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:18:16+0000\",\n \"description\": \"These days everything’s moving online… even your team. Are you ready? Knowing how to identify the dynamics of your team, communicate clearly with everyone & foster trust will give you the basic skills you need as a manager to bridge the distance & form your virtual team. \"\n },\n \"description\": \"Whether your organization is going global or you’re bringing on remote hires, there are a few things you’ll need to do consistently to form an effective virtual team.\",\n \"image\": {\n \"UUID\": \"c692dd57-f6b4-413b-999c-5264b30577e7\",\n \"name\": \"set_your_team_up_success_preview_image_1.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/set_your_team_up_success_preview_image_1.png.jpg?itok=PNY3KUjH\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/set_your_team_up_success_preview_image_1.png\"\n },\n \"body\": [\n {\n \"id\": 323,\n \"uuid\": \"c47ec5f4-b866-47ac-954a-a3e5c2263396\",\n \"revision_id\": 782,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584460394,\n \"parent_id\": \"260\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

Whether your organization is going global or you’re bringing on remote hires, there are a few things you’ll need to do consistently to form an effective virtual team.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

Whether your organization is going global or you’re bringing on remote hires, there are a few things you’ll need to do consistently to form an effective virtual team.

\\n\"\n }\n },\n {\n \"id\": 324,\n \"uuid\": \"b4de99e0-864b-4a5d-a754-71a169f982d3\",\n \"revision_id\": 783,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584460394,\n \"parent_id\": \"260\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_video\": \"https://youtu.be/3t6v6bE_l8w\"\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"26fdfcfe-0a44-4ff9-b33c-20c7764d5257\",\n \"nid\": 270,\n \"vid\": 620,\n \"url\": \"/node/270\",\n \"name\": \"Lead Your Virtual Team: 1 More Thing About Leading Virtual Teams\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-18T14:18:34+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"1dd15635-75e1-486a-acd1-1b252845f1a0\",\n \"name\": \"node_270.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_270.zip\"\n },\n \"tags\": [\n {\n \"id\": \"2e03cfc6-7b44-4853-a629-1283b7b6b5cd\",\n \"vid\": 93,\n \"tid\": 93,\n \"url\": \"/taxonomy/term/93\",\n \"name\": \"SLGO\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-16T19:38:00+0000\"\n },\n {\n \"id\": \"81d34d52-d62b-4769-9ab4-3f07897372c5\",\n \"vid\": 97,\n \"tid\": 97,\n \"url\": \"/taxonomy/term/97\",\n \"name\": \"Work from Home\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:24+0000\"\n },\n {\n \"id\": \"a2cfcf08-21e8-4d9e-a0a2-e4ce0ff9f58b\",\n \"vid\": 96,\n \"tid\": 96,\n \"url\": \"/taxonomy/term/96\",\n \"name\": \"Working Remotely\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:32+0000\"\n },\n {\n \"id\": \"425e382c-8fc9-4a46-a252-cb6f20bc42eb\",\n \"vid\": 83,\n \"tid\": 83,\n \"url\": \"/taxonomy/term/83\",\n \"name\": \"Leadership\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:33:24+0000\"\n },\n {\n \"id\": \"f49d9d61-21ba-472d-9100-3e83beeacf33\",\n \"vid\": 98,\n \"tid\": 98,\n \"url\": \"/taxonomy/term/98\",\n \"name\": \"Virtual Team\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:03+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"39299858-9ea2-4e61-bf1e-7c7a8a91bdc9\",\n \"vid\": 100,\n \"tid\": 100,\n \"url\": \"/taxonomy/term/100\",\n \"name\": \"Virtual Team\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:18:16+0000\",\n \"description\": \"These days everything’s moving online… even your team. Are you ready? Knowing how to identify the dynamics of your team, communicate clearly with everyone & foster trust will give you the basic skills you need as a manager to bridge the distance & form your virtual team. \"\n },\n \"description\": \"Consider this final piece of advice about body language as you lead your virtual team.\",\n \"image\": {\n \"UUID\": \"61e3f2da-31ee-4c87-b38b-56958a98b1c7\",\n \"name\": \"1-More-Thing-About-Leading-Virtual-Teams_0.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/1-More-Thing-About-Leading-Virtual-Teams_0.png.jpg?itok=D8wPQWiK\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/1-More-Thing-About-Leading-Virtual-Teams_0.png\"\n },\n \"body\": [\n {\n \"id\": 342,\n \"uuid\": \"41ff541e-c7a6-47bf-b0a9-a7f0e2140f7e\",\n \"revision_id\": 762,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584470745,\n \"parent_id\": \"270\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

Consider this final piece of advice about body language as you lead your virtual team.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

Consider this final piece of advice about body language as you lead your virtual team.

\\n\"\n }\n },\n {\n \"id\": 343,\n \"uuid\": \"23dab46e-3412-4276-8014-8ada1cfd04fa\",\n \"revision_id\": 763,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584470766,\n \"parent_id\": \"270\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_video\": \"https://youtu.be/2xauNxFOzG0\"\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"cf03a63b-ef79-4f84-8ab6-8b5a1b7e31cc\",\n \"nid\": 269,\n \"vid\": 621,\n \"url\": \"/node/269\",\n \"name\": \"Lead Your Virtual Team: Coach to Foster Results\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-18T14:18:57+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"1b5c613f-abd4-40bf-a799-ad42a55cae03\",\n \"name\": \"node_269.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_269.zip\"\n },\n \"tags\": [\n {\n \"id\": \"2e03cfc6-7b44-4853-a629-1283b7b6b5cd\",\n \"vid\": 93,\n \"tid\": 93,\n \"url\": \"/taxonomy/term/93\",\n \"name\": \"SLGO\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-16T19:38:00+0000\"\n },\n {\n \"id\": \"425e382c-8fc9-4a46-a252-cb6f20bc42eb\",\n \"vid\": 83,\n \"tid\": 83,\n \"url\": \"/taxonomy/term/83\",\n \"name\": \"Leadership\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:33:24+0000\"\n },\n {\n \"id\": \"81d34d52-d62b-4769-9ab4-3f07897372c5\",\n \"vid\": 97,\n \"tid\": 97,\n \"url\": \"/taxonomy/term/97\",\n \"name\": \"Work from Home\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:24+0000\"\n },\n {\n \"id\": \"a2cfcf08-21e8-4d9e-a0a2-e4ce0ff9f58b\",\n \"vid\": 96,\n \"tid\": 96,\n \"url\": \"/taxonomy/term/96\",\n \"name\": \"Working Remotely\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:32+0000\"\n },\n {\n \"id\": \"f49d9d61-21ba-472d-9100-3e83beeacf33\",\n \"vid\": 98,\n \"tid\": 98,\n \"url\": \"/taxonomy/term/98\",\n \"name\": \"Virtual Team\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:03+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"39299858-9ea2-4e61-bf1e-7c7a8a91bdc9\",\n \"vid\": 100,\n \"tid\": 100,\n \"url\": \"/taxonomy/term/100\",\n \"name\": \"Virtual Team\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:18:16+0000\",\n \"description\": \"These days everything’s moving online… even your team. Are you ready? Knowing how to identify the dynamics of your team, communicate clearly with everyone & foster trust will give you the basic skills you need as a manager to bridge the distance & form your virtual team. \"\n },\n \"description\": \"Move beyond simply managing your virtual team to coaching them and building relationships that foster results.\",\n \"image\": {\n \"UUID\": \"5fc32613-18ef-4139-b7f8-ffd57f3b67a5\",\n \"name\": \"coach_to_foster_results_preview_image_0.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/coach_to_foster_results_preview_image_0.png.jpg?itok=mass3BVi\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/coach_to_foster_results_preview_image_0.png\"\n },\n \"body\": [\n {\n \"id\": 340,\n \"uuid\": \"3ed21f98-710f-4b97-bf66-b3bff58885d9\",\n \"revision_id\": 764,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584470254,\n \"parent_id\": \"269\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

Move beyond simply managing your virtual team to coaching them and building relationships that foster results.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

Move beyond simply managing your virtual team to coaching them and building relationships that foster results.

\\n\"\n }\n },\n {\n \"id\": 341,\n \"uuid\": \"2b37375f-a622-4d5f-9f5b-e15472cdc368\",\n \"revision_id\": 765,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584470287,\n \"parent_id\": \"269\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_video\": \"https://youtu.be/AA0jZb77l8k\"\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"9fecf981-8d5e-45d8-a499-8528be027418\",\n \"nid\": 275,\n \"vid\": 622,\n \"url\": \"/node/275\",\n \"name\": \"Lead Your Virtual Team: Lead Successful Meetings\",\n \"type\": \"learn_article\",\n \"changed\": \"2021-01-21T00:26:56+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"ab179d6d-aa5e-4d0e-b4a4-5926f69f0cd8\",\n \"name\": \"node_275.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_275.zip\"\n },\n \"tags\": [\n {\n \"id\": \"2e03cfc6-7b44-4853-a629-1283b7b6b5cd\",\n \"vid\": 93,\n \"tid\": 93,\n \"url\": \"/taxonomy/term/93\",\n \"name\": \"SLGO\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-16T19:38:00+0000\"\n },\n {\n \"id\": \"81d34d52-d62b-4769-9ab4-3f07897372c5\",\n \"vid\": 97,\n \"tid\": 97,\n \"url\": \"/taxonomy/term/97\",\n \"name\": \"Work from Home\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:24+0000\"\n },\n {\n \"id\": \"a2cfcf08-21e8-4d9e-a0a2-e4ce0ff9f58b\",\n \"vid\": 96,\n \"tid\": 96,\n \"url\": \"/taxonomy/term/96\",\n \"name\": \"Working Remotely\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:32+0000\"\n },\n {\n \"id\": \"f49d9d61-21ba-472d-9100-3e83beeacf33\",\n \"vid\": 98,\n \"tid\": 98,\n \"url\": \"/taxonomy/term/98\",\n \"name\": \"Virtual Team\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:03+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"39299858-9ea2-4e61-bf1e-7c7a8a91bdc9\",\n \"vid\": 100,\n \"tid\": 100,\n \"url\": \"/taxonomy/term/100\",\n \"name\": \"Virtual Team\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:18:16+0000\",\n \"description\": \"These days everything’s moving online… even your team. Are you ready? Knowing how to identify the dynamics of your team, communicate clearly with everyone & foster trust will give you the basic skills you need as a manager to bridge the distance & form your virtual team. \"\n },\n \"description\": \"Virtual meetings have a special set of challenges. To start, they often involve more advance planning\\r\\nand preparation. You’ll need to accommodate time schedules and time zones. To keep meetings on\\r\\ntrack, you’ll want to plan and send agendas beforehand.\",\n \"image\": {\n \"UUID\": \"6a5a47c3-7ab4-4906-abc4-1606fb139e10\",\n \"name\": \"Lead-successful_meetings_preview_image.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/Lead-successful_meetings_preview_image.png.jpg?itok=CQ4zVc1q\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/Lead-successful_meetings_preview_image.png\"\n },\n \"body\": [\n {\n \"id\": 352,\n \"uuid\": \"274a885f-9f82-4cd7-ab06-5adb5a03584d\",\n \"revision_id\": 928,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584547416,\n \"parent_id\": \"275\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

Virtual meetings have a special set of challenges. To start, they often involve more advance planning and preparation. You’ll need to accommodate time schedules and time zones. To keep meetings on track, you’ll want to plan and send agendas beforehand. 

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

Virtual meetings have a special set of challenges. To start, they often involve more advance planning and preparation. You’ll need to accommodate time schedules and time zones. To keep meetings on track, you’ll want to plan and send agendas beforehand. 

\\n\"\n }\n },\n {\n \"id\": 353,\n \"uuid\": \"4442ab52-62ae-46d4-b9aa-4995f2489975\",\n \"revision_id\": 929,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584547533,\n \"parent_id\": \"275\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_document\": {\n \"target_id\": 246,\n \"display\": true,\n \"description\": \"\"\n }\n }\n ],\n \"discussion_status\": \"open\"\n },\n {\n \"id\": \"84ae2ee5-f845-4eda-9567-6f4b0fecaf45\",\n \"nid\": 267,\n \"vid\": 623,\n \"url\": \"/node/267\",\n \"name\": \"Lead Your Virtual Team: Lead Virtual Meetings\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-18T14:20:33+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"f733e365-341d-4d89-b7b9-94434cb537fc\",\n \"name\": \"node_267.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_267.zip\"\n },\n \"tags\": [\n {\n \"id\": \"2e03cfc6-7b44-4853-a629-1283b7b6b5cd\",\n \"vid\": 93,\n \"tid\": 93,\n \"url\": \"/taxonomy/term/93\",\n \"name\": \"SLGO\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-16T19:38:00+0000\"\n },\n {\n \"id\": \"425e382c-8fc9-4a46-a252-cb6f20bc42eb\",\n \"vid\": 83,\n \"tid\": 83,\n \"url\": \"/taxonomy/term/83\",\n \"name\": \"Leadership\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:33:24+0000\"\n },\n {\n \"id\": \"81d34d52-d62b-4769-9ab4-3f07897372c5\",\n \"vid\": 97,\n \"tid\": 97,\n \"url\": \"/taxonomy/term/97\",\n \"name\": \"Work from Home\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:24+0000\"\n },\n {\n \"id\": \"a2cfcf08-21e8-4d9e-a0a2-e4ce0ff9f58b\",\n \"vid\": 96,\n \"tid\": 96,\n \"url\": \"/taxonomy/term/96\",\n \"name\": \"Working Remotely\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:32+0000\"\n },\n {\n \"id\": \"f49d9d61-21ba-472d-9100-3e83beeacf33\",\n \"vid\": 98,\n \"tid\": 98,\n \"url\": \"/taxonomy/term/98\",\n \"name\": \"Virtual Team\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:03+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"39299858-9ea2-4e61-bf1e-7c7a8a91bdc9\",\n \"vid\": 100,\n \"tid\": 100,\n \"url\": \"/taxonomy/term/100\",\n \"name\": \"Virtual Team\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:18:16+0000\",\n \"description\": \"These days everything’s moving online… even your team. Are you ready? Knowing how to identify the dynamics of your team, communicate clearly with everyone & foster trust will give you the basic skills you need as a manager to bridge the distance & form your virtual team. \"\n },\n \"description\": \"Leading a good meeting is hard. Leading a good virtual meeting is even harder. Find out what you can do to make your virtual meetings successful from day one.\",\n \"image\": {\n \"UUID\": \"8986ca42-294e-4930-adcf-f1d700cf136b\",\n \"name\": \"Lead_Virtual_Meetings_preview_image_0.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/Lead_Virtual_Meetings_preview_image_0.png.jpg?itok=0ddqbQxz\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/Lead_Virtual_Meetings_preview_image_0.png\"\n },\n \"body\": [\n {\n \"id\": 336,\n \"uuid\": \"0c762c9b-00a1-4ce6-9fe4-a896ca5111ce\",\n \"revision_id\": 768,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584464927,\n \"parent_id\": \"267\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

Leading a good meeting is hard. Leading a good virtual meeting is even harder. Find out what you can do to make your virtual meetings successful from day one.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

Leading a good meeting is hard. Leading a good virtual meeting is even harder. Find out what you can do to make your virtual meetings successful from day one.

\\n\"\n }\n },\n {\n \"id\": 337,\n \"uuid\": \"cf92fa5f-9637-4c30-9b35-494187aab765\",\n \"revision_id\": 769,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584464946,\n \"parent_id\": \"267\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_video\": \"https://youtu.be/F75fyBbUT3w\"\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"5011f7fc-0130-41df-8c69-a9dd1f610352\",\n \"nid\": 268,\n \"vid\": 624,\n \"url\": \"/node/268\",\n \"name\": \"Lead Your Virtual Team: Resolve Conflict\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-18T14:19:26+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"aea57abf-0f2d-4ca1-9913-2a814b97cb1e\",\n \"name\": \"node_268.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_268.zip\"\n },\n \"tags\": [\n {\n \"id\": \"2e03cfc6-7b44-4853-a629-1283b7b6b5cd\",\n \"vid\": 93,\n \"tid\": 93,\n \"url\": \"/taxonomy/term/93\",\n \"name\": \"SLGO\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-16T19:38:00+0000\"\n },\n {\n \"id\": \"425e382c-8fc9-4a46-a252-cb6f20bc42eb\",\n \"vid\": 83,\n \"tid\": 83,\n \"url\": \"/taxonomy/term/83\",\n \"name\": \"Leadership\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:33:24+0000\"\n },\n {\n \"id\": \"81d34d52-d62b-4769-9ab4-3f07897372c5\",\n \"vid\": 97,\n \"tid\": 97,\n \"url\": \"/taxonomy/term/97\",\n \"name\": \"Work from Home\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:24+0000\"\n },\n {\n \"id\": \"a2cfcf08-21e8-4d9e-a0a2-e4ce0ff9f58b\",\n \"vid\": 96,\n \"tid\": 96,\n \"url\": \"/taxonomy/term/96\",\n \"name\": \"Working Remotely\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:32+0000\"\n },\n {\n \"id\": \"f49d9d61-21ba-472d-9100-3e83beeacf33\",\n \"vid\": 98,\n \"tid\": 98,\n \"url\": \"/taxonomy/term/98\",\n \"name\": \"Virtual Team\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:03+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"39299858-9ea2-4e61-bf1e-7c7a8a91bdc9\",\n \"vid\": 100,\n \"tid\": 100,\n \"url\": \"/taxonomy/term/100\",\n \"name\": \"Virtual Team\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:18:16+0000\",\n \"description\": \"These days everything’s moving online… even your team. Are you ready? Knowing how to identify the dynamics of your team, communicate clearly with everyone & foster trust will give you the basic skills you need as a manager to bridge the distance & form your virtual team. \"\n },\n \"description\": \"Conflict happens. Learn how to diffuse tension and manage situations appropriately with the three C’s of conflict management.\",\n \"image\": {\n \"UUID\": \"5caac0f2-76e0-4a3a-b185-78ecbee21999\",\n \"name\": \"Resolve_Conficlt_preview_image_0.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/Resolve_Conficlt_preview_image_0.png.jpg?itok=kOQiZ5MQ\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/Resolve_Conficlt_preview_image_0.png\"\n },\n \"body\": [\n {\n \"id\": 338,\n \"uuid\": \"31bf6c91-bab3-4b63-bec9-f7588efe5821\",\n \"revision_id\": 766,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584470034,\n \"parent_id\": \"268\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

Conflict happens. Learn how to diffuse tension and manage situations appropriately with the three C’s of conflict management.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

Conflict happens. Learn how to diffuse tension and manage situations appropriately with the three C’s of conflict management.

\\n\"\n }\n },\n {\n \"id\": 339,\n \"uuid\": \"6054a9cb-7711-47df-a508-8a9bcc4e2511\",\n \"revision_id\": 767,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584470066,\n \"parent_id\": \"268\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_video\": \"https://youtu.be/nD5AZ4YfGdU\"\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"702a6935-4985-48e8-98f5-395e99d906f9\",\n \"nid\": 266,\n \"vid\": 625,\n \"url\": \"/node/266\",\n \"name\": \"Lead Your Virtual Team: Why It Matters\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-18T14:20:55+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"4f26f94d-6ef0-4fb5-a18b-1be35712e28a\",\n \"name\": \"node_266.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_266.zip\"\n },\n \"tags\": [\n {\n \"id\": \"2e03cfc6-7b44-4853-a629-1283b7b6b5cd\",\n \"vid\": 93,\n \"tid\": 93,\n \"url\": \"/taxonomy/term/93\",\n \"name\": \"SLGO\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-16T19:38:00+0000\"\n },\n {\n \"id\": \"425e382c-8fc9-4a46-a252-cb6f20bc42eb\",\n \"vid\": 83,\n \"tid\": 83,\n \"url\": \"/taxonomy/term/83\",\n \"name\": \"Leadership\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:33:24+0000\"\n },\n {\n \"id\": \"f49d9d61-21ba-472d-9100-3e83beeacf33\",\n \"vid\": 98,\n \"tid\": 98,\n \"url\": \"/taxonomy/term/98\",\n \"name\": \"Virtual Team\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:03+0000\"\n },\n {\n \"id\": \"a2cfcf08-21e8-4d9e-a0a2-e4ce0ff9f58b\",\n \"vid\": 96,\n \"tid\": 96,\n \"url\": \"/taxonomy/term/96\",\n \"name\": \"Working Remotely\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:32+0000\"\n },\n {\n \"id\": \"81d34d52-d62b-4769-9ab4-3f07897372c5\",\n \"vid\": 97,\n \"tid\": 97,\n \"url\": \"/taxonomy/term/97\",\n \"name\": \"Work from Home\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:24+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"39299858-9ea2-4e61-bf1e-7c7a8a91bdc9\",\n \"vid\": 100,\n \"tid\": 100,\n \"url\": \"/taxonomy/term/100\",\n \"name\": \"Virtual Team\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:18:16+0000\",\n \"description\": \"These days everything’s moving online… even your team. Are you ready? Knowing how to identify the dynamics of your team, communicate clearly with everyone & foster trust will give you the basic skills you need as a manager to bridge the distance & form your virtual team. \"\n },\n \"description\": \"What’s your role as the leader of a virtual team? It starts with your ability to communicate clearly and effectively. \",\n \"image\": {\n \"UUID\": \"048b3aff-90c1-4eb0-94cc-6b23151a5a35\",\n \"name\": \"Why_it_Matters_preview_image.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/Why_it_Matters_preview_image.png.jpg?itok=pACP8Kp3\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/Why_it_Matters_preview_image.png\"\n },\n \"body\": [\n {\n \"id\": 334,\n \"uuid\": \"479119a7-51a4-45a9-9f49-440ab82a70f4\",\n \"revision_id\": 770,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584464549,\n \"parent_id\": \"266\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

What’s your role as the leader of a virtual team? It starts with your ability to communicate clearly and effectively.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

What’s your role as the leader of a virtual team? It starts with your ability to communicate clearly and effectively.

\\n\"\n }\n },\n {\n \"id\": 335,\n \"uuid\": \"c11782c2-785f-42b3-b417-15e56e53a8cf\",\n \"revision_id\": 771,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584464599,\n \"parent_id\": \"266\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_video\": \"https://youtu.be/0EuMpK5Ln3w\"\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"da68041d-6ffa-4c53-968b-08b98829c0c2\",\n \"nid\": 251,\n \"vid\": 626,\n \"url\": \"/node/251\",\n \"name\": \"Welcome to SLGO!\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-20T20:02:39+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"853b82f6-0946-4267-bae8-1597fa8e7586\",\n \"name\": \"node_251.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_251.zip\"\n },\n \"tags\": [\n {\n \"id\": \"2e03cfc6-7b44-4853-a629-1283b7b6b5cd\",\n \"vid\": 93,\n \"tid\": 93,\n \"url\": \"/taxonomy/term/93\",\n \"name\": \"SLGO\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-16T19:38:00+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"7db21c39-78c9-48a6-a78d-ecbd7ab49b4b\",\n \"vid\": 92,\n \"tid\": 92,\n \"url\": \"/taxonomy/term/92\",\n \"name\": \"Welcome to SLGO\",\n \"type\": \"category\",\n \"changed\": \"2020-03-16T19:29:47+0000\",\n \"description\": null\n },\n \"description\": \"With SLGO you can easily connect with your team and stay on top of your learning anytime, anywhere. In this lesson, you will learn how to stay connected, find and organize the content relevant to you, and take advantage of pre-loaded content on working remotely.\",\n \"image\": {\n \"UUID\": \"8b68f317-73cb-4bc4-989d-4f54ce827669\",\n \"name\": \"SLgo_LearningObject_App.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/SLgo_LearningObject_App.png.jpg?itok=Vqpd89xU\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/SLgo_LearningObject_App.png\"\n },\n \"body\": [\n {\n \"id\": 305,\n \"uuid\": \"13d24610-77a0-435f-acf4-b47154f9598f\",\n \"revision_id\": 867,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584387127,\n \"parent_id\": \"251\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": true,\n \"field_paragraph_body\": {\n \"value\": \"

Connecting people. SLGO helps you learn when and where you want to and be able to pick up anywhere at any time. Your admin can deliver relevant content to you remotely and review your progress. This means you can stay connected and keep your knowledge up to date from the comfort of your home.

\\r\\n\\r\\n

Enhancing Productivity.  Effective learning can help to solve problems and accelerate performance. SLGO has learning content for all levels from exploring to studying, to sharpening. You can browse topics or join groups to find content tailored to you. We also have free courses from TorranceLearning.

\\r\\n\\r\\n

Giving you results. SLGO uses a powerful recommendation engine to give you content that reinforces what you are learning and bring similar lessons to your attention. As you complete courses and interact with flashcards, quizzes, and tip cards, you will receive meaningful feedback. 

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

Connecting people. SLGO helps you learn when and where you want to and be able to pick up anywhere at any time. Your admin can deliver relevant content to you remotely and review your progress. This means you can stay connected and keep your knowledge up to date from the comfort of your home.

\\n

Enhancing Productivity.  Effective learning can help to solve problems and accelerate performance. SLGO has learning content for all levels from exploring to studying, to sharpening. You can browse topics or join groups to find content tailored to you. We also have free courses from TorranceLearning.

\\n

Giving you results. SLGO uses a powerful recommendation engine to give you content that reinforces what you are learning and bring similar lessons to your attention. As you complete courses and interact with flashcards, quizzes, and tip cards, you will receive meaningful feedback. 

\\n\"\n }\n },\n {\n \"id\": 306,\n \"uuid\": \"17eb2457-7f3a-4680-a8e7-c1cd7c3bc65b\",\n \"revision_id\": 868,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584387421,\n \"parent_id\": \"251\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_size\": \"h4\",\n \"field_title\": \"Resources\"\n }\n ],\n \"discussion_status\": \"hidden\"\n }\n ],\n \"pager\": {\n \"current_page\": 0,\n \"total_items\": \"27\",\n \"total_pages\": 1,\n \"items_per_page\": 50\n }\n}" + }, + { + "name": "Search group content by title", + "originalRequest": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "url": { + "raw": "{{server}}/{{base_url}}/groups/{{group_id}}/contents?title=work", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "groups", + "{{group_id}}", + "contents" + ], + "query": [ + { + "key": "title", + "value": "work" + } + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Cache-Control", + "value": "must-revalidate, no-cache, private" + }, + { + "key": "Content-Encoding", + "value": "gzip" + }, + { + "key": "Content-Language", + "value": "en" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Sun, 11 Apr 2021 18:13:48 GMT" + }, + { + "key": "Expires", + "value": "Sun, 19 Nov 1978 05:00:00 GMT" + }, + { + "key": "Server", + "value": "nginx" + }, + { + "key": "Vary", + "value": "Accept-Encoding" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Drupal-Cache-Contexts", + "value": "languages:language_content languages:language_interface request_format theme url user.group_permissions user.node_grants:view user.permissions" + }, + { + "key": "X-Drupal-Cache-Max-Age", + "value": "-1 (Permanent)" + }, + { + "key": "X-Drupal-Cache-Tags", + "value": "config:views.view.group_content group:15 group_content:185 group_content:186 group_content_list group_content_list:plugin:group_node:course group_content_list:plugin:group_node:flash_card group_content_list:plugin:group_node:learn_article group_content_list:plugin:group_node:learn_file group_content_list:plugin:group_node:learn_link group_content_list:plugin:group_node:learn_package group_content_list:plugin:group_node:podcast group_content_list:plugin:group_node:podcast_episode group_content_list:plugin:group_node:quiz group_content_list:plugin:group_node:test group_content_list:plugin:group_node:tip_card group_list http_response node:258 node:271 node_list page_manager_route_name:view.group_content.rest_export_1" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "X-Generator", + "value": "Drupal 9 (https://www.drupal.org)" + }, + { + "key": "X-Ua-Compatible", + "value": "IE=edge" + }, + { + "key": "X-Xss-Protection", + "value": "1; mode=block" + }, + { + "key": "Content-Length", + "value": "1900" + } + ], + "cookie": [], + "body": "{\n \"rows\": [\n {\n \"id\": \"d8d056ea-ad88-4955-8a5d-a4e18be78233\",\n \"nid\": 271,\n \"vid\": 608,\n \"url\": \"/node/271\",\n \"name\": \"COVID-19: Prepare to Work Virtually\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-26T15:21:44+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"9cb9259d-b937-49b0-8233-933e3fb43a90\",\n \"name\": \"node_271.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_271.zip\"\n },\n \"tags\": [\n {\n \"id\": \"801623d6-5b1a-4934-afd2-e55f75f5bafc\",\n \"vid\": 94,\n \"tid\": 94,\n \"url\": \"/taxonomy/term/94\",\n \"name\": \"COVID-19\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:18:22+0000\"\n },\n {\n \"id\": \"eff406f7-0dff-4945-812a-be707a816230\",\n \"vid\": 95,\n \"tid\": 95,\n \"url\": \"/taxonomy/term/95\",\n \"name\": \"Coronavirus\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:45+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"e2d54015-6e0b-43aa-a6b6-bd8abf7e66f6\",\n \"vid\": 99,\n \"tid\": 99,\n \"url\": \"/taxonomy/term/99\",\n \"name\": \"Take Precautions: COVID-19\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:34:44+0000\",\n \"description\": \"The recent coronavirus outbreak is a serious health concern. Do you know how to protect yourself and others from serious illness? Arming yourself with information and strategies will help reduce the spread of disease and enable you to work effectively in the challenging circumstances of an outbreak.\"\n },\n \"description\": \"During a disease outbreak, you may need to work from home (although not every job allows for this\\r\\ndegree of flexibility). If you do not ordinarily work remotely, ensure that you are prepared with all the\\r\\ntools you need and that you have a plan to help you be as productive as you would be at work.\",\n \"image\": {\n \"UUID\": \"e98de4da-ed4a-4d0a-b22f-5176b441eaa6\",\n \"name\": \"09_prepare_to_work_from_home_preview_image.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/09_prepare_to_work_from_home_preview_image.png.jpg?itok=FQ2SYuG_\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/09_prepare_to_work_from_home_preview_image.png\"\n },\n \"body\": [\n {\n \"id\": 345,\n \"uuid\": \"94c77451-3435-4e0b-b127-495acd4cf815\",\n \"revision_id\": 875,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584542670,\n \"parent_id\": \"271\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

During a disease outbreak, you may need to work from home (although not every job allows for this degree of flexibility). If you do not ordinarily work remotely, ensure that you are prepared with all the tools you need and that you have a plan to help you be as productive as you would be at work.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

During a disease outbreak, you may need to work from home (although not every job allows for this degree of flexibility). If you do not ordinarily work remotely, ensure that you are prepared with all the tools you need and that you have a plan to help you be as productive as you would be at work.

\\n\"\n }\n },\n {\n \"id\": 346,\n \"uuid\": \"2b01dbc7-5fc5-4a59-8ec5-92a51f5d4813\",\n \"revision_id\": 876,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584542734,\n \"parent_id\": \"271\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_document\": {\n \"target_id\": 238,\n \"display\": true,\n \"description\": \"\"\n }\n }\n ],\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"ccbbc825-2188-45e0-9ec7-5bc1567f2b95\",\n \"nid\": 258,\n \"vid\": 609,\n \"url\": \"/node/258\",\n \"name\": \"COVID-19: Work Virtually\",\n \"type\": \"learn_article\",\n \"changed\": \"2020-03-26T15:23:07+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"d50da248-7850-43bf-8444-324748aec4e1\",\n \"name\": \"node_258.zip\",\n \"url\": \"http://perls.localhost:8000/system/files/offline_page/node_258.zip\"\n },\n \"tags\": [\n {\n \"id\": \"801623d6-5b1a-4934-afd2-e55f75f5bafc\",\n \"vid\": 94,\n \"tid\": 94,\n \"url\": \"/taxonomy/term/94\",\n \"name\": \"COVID-19\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:18:22+0000\"\n },\n {\n \"id\": \"eff406f7-0dff-4945-812a-be707a816230\",\n \"vid\": 95,\n \"tid\": 95,\n \"url\": \"/taxonomy/term/95\",\n \"name\": \"Coronavirus\",\n \"type\": \"tags\",\n \"changed\": \"2020-03-26T15:32:45+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"e2d54015-6e0b-43aa-a6b6-bd8abf7e66f6\",\n \"vid\": 99,\n \"tid\": 99,\n \"url\": \"/taxonomy/term/99\",\n \"name\": \"Take Precautions: COVID-19\",\n \"type\": \"category\",\n \"changed\": \"2020-03-18T14:34:44+0000\",\n \"description\": \"The recent coronavirus outbreak is a serious health concern. Do you know how to protect yourself and others from serious illness? Arming yourself with information and strategies will help reduce the spread of disease and enable you to work effectively in the challenging circumstances of an outbreak.\"\n },\n \"description\": \"You may need to work virtually during an outbreak, which can be difficult if this isn’t normal for your workplace. Learn strategies to communicate effectively with your team and maintain a high quality of work when you work virtually.\",\n \"image\": {\n \"UUID\": \"d20490ca-60fa-48c3-b2be-6de2751e438b\",\n \"name\": \"07_work_virtually_preview_image_0.png\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/07_work_virtually_preview_image_0.png.jpg?itok=i97BI50p\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/2020-03/07_work_virtually_preview_image_0.png\"\n },\n \"body\": [\n {\n \"id\": 319,\n \"uuid\": \"1f5b5d3f-dd49-4ce5-aada-2c7a5a1d0b3d\",\n \"revision_id\": 879,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584459356,\n \"parent_id\": \"258\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_paragraph_body\": {\n \"value\": \"

You may need to work virtually during an outbreak, which can be difficult if this isn’t normal for your workplace. Learn strategies to communicate effectively with your team and maintain a high quality of work when you work virtually.

\\r\\n\",\n \"format\": \"inline_styling\",\n \"processed\": \"

You may need to work virtually during an outbreak, which can be difficult if this isn’t normal for your workplace. Learn strategies to communicate effectively with your team and maintain a high quality of work when you work virtually.

\\n\"\n }\n },\n {\n \"id\": 320,\n \"uuid\": \"39e5fada-8827-4ba5-b0d5-674d280cf993\",\n \"revision_id\": 880,\n \"langcode\": \"en\",\n \"type\": null,\n \"status\": true,\n \"created\": 1584459420,\n \"parent_id\": \"258\",\n \"parent_type\": \"node\",\n \"parent_field_name\": \"field_body\",\n \"behavior_settings\": [],\n \"default_langcode\": true,\n \"revision_translation_affected\": false,\n \"field_video\": \"https://youtu.be/UEPFhQGcSek\"\n }\n ],\n \"discussion_status\": \"hidden\"\n }\n ],\n \"pager\": {\n \"current_page\": 0,\n \"total_items\": \"2\",\n \"total_pages\": 1,\n \"items_per_page\": 50\n }\n}" + }, + { + "name": "Search group content by type", + "originalRequest": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "url": { + "raw": "{{server}}/{{base_url}}/groups/{{group_id}}/contents?type=tip_card", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "groups", + "{{group_id}}", + "contents" + ], + "query": [ + { + "key": "type", + "value": "tip_card" + } + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Cache-Control", + "value": "must-revalidate, no-cache, private" + }, + { + "key": "Content-Encoding", + "value": "gzip" + }, + { + "key": "Content-Language", + "value": "en" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Sun, 11 Apr 2021 18:15:27 GMT" + }, + { + "key": "Expires", + "value": "Sun, 19 Nov 1978 05:00:00 GMT" + }, + { + "key": "Server", + "value": "nginx" + }, + { + "key": "Vary", + "value": "Accept-Encoding" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Drupal-Cache-Contexts", + "value": "languages:language_content languages:language_interface request_format theme url user.group_permissions user.node_grants:view user.permissions" + }, + { + "key": "X-Drupal-Cache-Max-Age", + "value": "-1 (Permanent)" + }, + { + "key": "X-Drupal-Cache-Tags", + "value": "config:views.view.group_content group:15 group_content:188 group_content_list group_content_list:plugin:group_node:course group_content_list:plugin:group_node:flash_card group_content_list:plugin:group_node:learn_article group_content_list:plugin:group_node:learn_file group_content_list:plugin:group_node:learn_link group_content_list:plugin:group_node:learn_package group_content_list:plugin:group_node:podcast group_content_list:plugin:group_node:podcast_episode group_content_list:plugin:group_node:quiz group_content_list:plugin:group_node:test group_content_list:plugin:group_node:tip_card group_list http_response node:229 node_list page_manager_route_name:view.group_content.rest_export_1" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "X-Generator", + "value": "Drupal 9 (https://www.drupal.org)" + }, + { + "key": "X-Ua-Compatible", + "value": "IE=edge" + }, + { + "key": "X-Xss-Protection", + "value": "1; mode=block" + }, + { + "key": "Content-Length", + "value": "1401" + } + ], + "cookie": [], + "body": "{\n \"rows\": [\n {\n \"id\": \"0113f56c-e06b-4d21-b0db-688e74447834\",\n \"nid\": 229,\n \"vid\": 519,\n \"url\": \"/node/229\",\n \"name\": \"Did you know? 40% of Businesses Affected by Disaster Never Reopen. \",\n \"type\": \"tip_card\",\n \"changed\": \"2020-03-18T19:24:07+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": [],\n \"topic\": {\n \"id\": \"fb473dd7-86a8-40a6-8a12-c9c80d46c2fb\",\n \"vid\": 80,\n \"tid\": 80,\n \"url\": \"/taxonomy/term/80\",\n \"name\": \"Occupational Safety and Health\",\n \"type\": \"category\",\n \"changed\": \"2021-02-01T00:30:23+0000\",\n \"description\": \"This topic includes content related to the safety, health, and welfare of people at work The goal of occupational safety and health programs is to foster a safe and healthy work environment.[3] OSH may also protect co-workers, family members, employers, customers, and many others who might be affected by the workplace environment. \"\n },\n \"contents\": [\n \"
\\n
\\n
\\n \\n

The main reason to have an emergency action plan is to do as much as possible to keep your employees safe in case of disaster but a good plan can keep your business safe as well. Up to 40% of businesses affected by a natural or human-caused disaster never reopen. Having procedures in place to deal with disasters can help your business survive this difficult experience.

\\n

 

\\n
\\n \\n
\\n
\\n\\n
\\n\",\n \"
\\n
\\n
\\n \\n
\\\"Closed\\n\\n\\n
\\n \\n
\\n
\\n\\n
\\n\"\n ],\n \"body\": [\n {\n \"id\": \"c548cc2f-d8f0-4a98-88f5-f96ae130d076\",\n \"type\": \"text\",\n \"fields\": [\n {\n \"type\": \"Label\",\n \"attributes\": {\n \"Text\": \"

The main reason to have an emergency action plan is to do as much as possible to keep your employees safe in case of disaster but a good plan can keep your business safe as well. Up to 40% of businesses affected by a natural or human-caused disaster never reopen. Having procedures in place to deal with disasters can help your business survive this difficult experience.

\\r\\n\\r\\n

 

\",\n \"TextType\": \"Html\"\n }\n }\n ]\n },\n {\n \"id\": \"b74d5871-47ad-4d40-baa0-d1f225f18abf\",\n \"type\": \"image\",\n \"fields\": [\n {\n \"type\": \"Image\",\n \"attributes\": {\n \"Source\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/benedikt-geyer-Qq_F_5kS7uo-unsplash.jpg?itok=eIObe6Xf\",\n \"Aspect\": \"AspectFit\"\n }\n }\n ]\n }\n ]\n }\n ],\n \"pager\": {\n \"current_page\": 0,\n \"total_items\": \"1\",\n \"total_pages\": 1,\n \"items_per_page\": 50\n }\n}" + } + ] + } + ], + "description": "Retrieve information about groups." + }, + { + "name": "JSON:API", + "item": [ + { + "name": "Courses", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/jsonapi/node/course", + "host": [ + "{{server}}" + ], + "path": [ + "jsonapi", + "node", + "course" + ] + } + }, + "response": [] + }, + { + "name": "File", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/jsonapi/file/file", + "host": [ + "{{server}}" + ], + "path": [ + "jsonapi", + "file", + "file" + ] + } + }, + "response": [] + }, + { + "name": "Media Image", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/jsonapi/media/image", + "host": [ + "{{server}}" + ], + "path": [ + "jsonapi", + "media", + "image" + ] + } + }, + "response": [] + }, + { + "name": "Event", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/jsonapi/node/event", + "host": [ + "{{server}}" + ], + "path": [ + "jsonapi", + "node", + "event" + ] + } + }, + "response": [] + }, + { + "name": "Flash Card", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/jsonapi/node/flash_card", + "host": [ + "{{server}}" + ], + "path": [ + "jsonapi", + "node", + "flash_card" + ] + } + }, + "response": [] + }, + { + "name": "Article", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/jsonapi/node/learn_article", + "host": [ + "{{server}}" + ], + "path": [ + "jsonapi", + "node", + "learn_article" + ] + } + }, + "response": [] + }, + { + "name": "Document", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/jsonapi/node/learn_file", + "host": [ + "{{server}}" + ], + "path": [ + "jsonapi", + "node", + "learn_file" + ] + } + }, + "response": [] + }, + { + "name": "Web Link", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/jsonapi/node/learn_link", + "host": [ + "{{server}}" + ], + "path": [ + "jsonapi", + "node", + "learn_link" + ] + } + }, + "response": [] + }, + { + "name": "eLearning Package", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/jsonapi/node/learn_package", + "host": [ + "{{server}}" + ], + "path": [ + "jsonapi", + "node", + "learn_package" + ] + } + }, + "response": [] + }, + { + "name": "Podcast", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/jsonapi/node/podcast", + "host": [ + "{{server}}" + ], + "path": [ + "jsonapi", + "node", + "podcast" + ] + } + }, + "response": [] + }, + { + "name": "Podcast Episode", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/jsonapi/node/podcast_episode", + "host": [ + "{{server}}" + ], + "path": [ + "jsonapi", + "node", + "podcast_episode" + ] + } + }, + "response": [] + }, + { + "name": "Quiz", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/jsonapi/node/quiz", + "host": [ + "{{server}}" + ], + "path": [ + "jsonapi", + "node", + "quiz" + ] + } + }, + "response": [] + }, + { + "name": "Test", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/jsonapi/node/test", + "host": [ + "{{server}}" + ], + "path": [ + "jsonapi", + "node", + "test" + ] + } + }, + "response": [] + }, + { + "name": "Tip", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/jsonapi/node/tip_card", + "host": [ + "{{server}}" + ], + "path": [ + "jsonapi", + "node", + "tip_card" + ] + } + }, + "response": [] + }, + { + "name": "Taxonomy Category", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/jsonapi/taxonomy_term/category", + "host": [ + "{{server}}" + ], + "path": [ + "jsonapi", + "taxonomy_term", + "category" + ] + } + }, + "response": [] + }, + { + "name": "Taxonomy Difficulty", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/jsonapi/taxonomy_term/difficulty", + "host": [ + "{{server}}" + ], + "path": [ + "jsonapi", + "taxonomy_term", + "difficulty" + ] + } + }, + "response": [] + }, + { + "name": "Taxonomy Tags", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/jsonapi/taxonomy_term/tags", + "host": [ + "{{server}}" + ], + "path": [ + "jsonapi", + "taxonomy_term", + "tags" + ] + } + }, + "response": [] + } + ] + }, + { + "name": "Publishing APIs", + "item": [ + { + "name": "Create Web link", + "protocolProfileBehavior": { + "disabledSystemHeaders": { + "accept": true + } + }, + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"name\": \"New weblink with group image and group\",\n \"feature_image\": \"https://upload.wikimedia.org/wikipedia/commons/thumb/a/a4/Anatomy_of_a_Sunset-2.jpg/440px-Anatomy_of_a_Sunset-2.jpg\",\n \"type\": \"learn_link\",\n \"url\": \"http://example.com\",\n \"topic\": \"What is PERLS\",\n \"tags\": [\n \"AppOnboarding\",\n \"Content Managers\",\n \"New tag\"\n ],\n \"difficulty\": \"Intermediate\",\n \"description\": \"Text in the description.\",\n \"is_sticky\": true,\n \"link_type\": \"custom\",\n \"is_promoted\": true,\n \"published\": true,\n \"groups\": [\n \"New group\",\n \"Content Managers\"\n ]\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{server}}/node", + "host": [ + "{{server}}" + ], + "path": [ + "node" + ] + }, + "description": "Add new Web link content\n\nThe response is a new web link node record\n\n### Link destination(link\\_type)\n\nThis decides whether the URL is stored under\n\n* `web` - a http/https URL for web content.\n* `custom` - URL for native content/asset with scheme prefix.\n \n\n### Response codes\n\n* `201` - The web link was created\n* `403` - The user is not allowed to create web link content\n* `422` - Un-processable Entity: The mandatory fields Title(name)/ Topic(topic) is empty or missing" + }, + "response": [ + { + "name": "Create Web link successfully", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"name\": \"New weblink with group image and group\",\n \"feature_image\": \"https://upload.wikimedia.org/wikipedia/commons/thumb/a/a4/Anatomy_of_a_Sunset-2.jpg/440px-Anatomy_of_a_Sunset-2.jpg\",\n \"type\": \"learn_link\",\n \"url\": \"http://example.com\",\n \"topic\": \"What is PERLS\",\n \"tags\": [\n \"AppOnboarding\",\n \"Content Managers\",\n \"New tag\"\n ],\n \"difficulty\": \"Intermediate\",\n \"description\": \"Text in the description.\",\n \"is_sticky\": true,\n \"link_type\": \"custom\",\n \"is_promoted\": true,\n \"published\": true,\n \"groups\": [\n \"New group\",\n \"Content Managers\"\n ]\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{server}}/node", + "host": [ + "{{server}}" + ], + "path": [ + "node" + ] + } + }, + "status": "Created", + "code": 201, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Date", + "value": "Thu, 16 Dec 2021 15:57:41 GMT" + }, + { + "key": "Server", + "value": "Apache" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "Set-Cookie", + "value": "SESS5f17f36b17be2854884ad86bf6359d6a=n8TP7v4tThz-zFsa9laqY2QOkHafFfYISVu4UK4gtUos9GD0; expires=Sat, 08-Jan-2022 19:31:09 GMT; Max-Age=2000000; path=/; domain=.perls.localhost; HttpOnly" + }, + { + "key": "Location", + "value": "http://perls.localhost:8000/node/560" + }, + { + "key": "Cache-Control", + "value": "must-revalidate, no-cache, private" + }, + { + "key": "X-UA-Compatible", + "value": "IE=edge" + }, + { + "key": "Content-language", + "value": "en" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "Permissions-Policy", + "value": "interest-cohort=()" + }, + { + "key": "Expires", + "value": "Sun, 19 Nov 1978 05:00:00 GMT" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubdomains; preload" + }, + { + "key": "X-XSS-Protection", + "value": "1; mode=block" + }, + { + "key": "Content-Length", + "value": "1444" + }, + { + "key": "Keep-Alive", + "value": "timeout=5, max=99" + }, + { + "key": "Connection", + "value": "Keep-Alive" + }, + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"id\": \"0b988c17-b5b5-4625-bde2-8df82e43eed9\",\n \"nid\": 637,\n \"vid\": 995,\n \"url\": \"http://example.com\",\n \"name\": \"New weblink with group image and group\",\n \"type\": \"learn_link\",\n \"changed\": \"2021-12-16T15:57:41+0000\",\n \"is_promoted\": true,\n \"is_sticky\": true,\n \"file\": null,\n \"tags\": [\n {\n \"id\": \"40e0f1df-d0e1-42da-8633-82d45824cd87\",\n \"vid\": 118,\n \"tid\": 118,\n \"url\": \"/taxonomy/term/118\",\n \"name\": \"AppOnboarding\",\n \"type\": \"tags\",\n \"changed\": \"2021-03-18T16:55:42+0000\"\n },\n {\n \"id\": \"75bf7268-dbab-4aed-baf6-05f7677c927f\",\n \"vid\": 119,\n \"tid\": 119,\n \"url\": \"/taxonomy/term/119\",\n \"name\": \"Content Managers\",\n \"type\": \"tags\",\n \"changed\": \"2021-04-14T15:43:03+0000\"\n },\n {\n \"id\": \"4b12b931-2d20-4278-bba1-29b59680bf52\",\n \"vid\": 124,\n \"tid\": 124,\n \"url\": \"/taxonomy/term/124\",\n \"name\": \"New tag\",\n \"type\": \"tags\",\n \"changed\": \"2021-11-22T04:08:50+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"48894a0c-84ea-4052-b7fa-def32478a00d\",\n \"vid\": 116,\n \"tid\": 116,\n \"url\": \"/taxonomy/term/116\",\n \"name\": \"What is PERLS\",\n \"type\": \"category\",\n \"changed\": \"2021-08-27T17:02:17+0000\"\n },\n \"description\": \"Text in the description.\",\n \"image\": {\n \"UUID\": \"caef2a7a-1023-4334-8237-7e68d73195b7\",\n \"filename\": \"440px-anatomy_of_a_sunset-2_25.jpg\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/440px-anatomy_of_a_sunset-2_25.jpg?itok=CPgxYW6o\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/440px-anatomy_of_a_sunset-2_25.jpg\"\n }\n}" + }, + { + "name": "Topic should not be null", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"name\": \"New weblink\",\n \"type\": \"learn_link\",\n \"url\": \"http://example.com\",\n \"tags\": [\"AppOnboarding\", \"Content Managers\", \"New tag\"],\n \"description\": \"Text in the description updated\",\n \"is_sticky\": true,\n \"link_type\": \"web\",\n \"is_promoted\": true,\n \"published\": true\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{server}}/node", + "host": [ + "{{server}}" + ], + "path": [ + "node" + ] + } + }, + "status": "Unprocessable Entity", + "code": 422, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Date", + "value": "Wed, 01 Dec 2021 14:23:56 GMT" + }, + { + "key": "Server", + "value": "Apache" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "Set-Cookie", + "value": "SESS5f17f36b17be2854884ad86bf6359d6a=qAxxCkWqYqG3CoC%2CNVcz%2CBBZ7PuwSKgq1DNepJJlfJfOydI3; expires=Fri, 24-Dec-2021 17:57:21 GMT; Max-Age=2000000; path=/; domain=.perls.localhost; HttpOnly" + }, + { + "key": "Cache-Control", + "value": "must-revalidate, no-cache, private" + }, + { + "key": "X-UA-Compatible", + "value": "IE=edge" + }, + { + "key": "Content-language", + "value": "en" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "Permissions-Policy", + "value": "interest-cohort=()" + }, + { + "key": "Expires", + "value": "Sun, 19 Nov 1978 05:00:00 GMT" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubdomains; preload" + }, + { + "key": "X-XSS-Protection", + "value": "1; mode=block" + }, + { + "key": "Content-Length", + "value": "101" + }, + { + "key": "Keep-Alive", + "value": "timeout=5, max=100" + }, + { + "key": "Connection", + "value": "Keep-Alive" + }, + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"message\": \"Unprocessable Entity: validation failed.\\nfield_topic: This value should not be null.\\n\"\n}" + }, + { + "name": "Title should not be null", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"name\": \"New weblink\",\n \"type\": \"learn_link\",\n \"url\": \"http://example.com\",\n \"topic\": \"What is PERLS\",\n \"tags\": [\"AppOnboarding\", \"Content Managers\", \"New tag\"],\n \"description\": \"Text in the description updated\",\n \"is_sticky\": true,\n \"link_type\": \"web\",\n \"is_promoted\": true,\n \"published\": true\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{server}}/node", + "host": [ + "{{server}}" + ], + "path": [ + "node" + ] + } + }, + "status": "Unprocessable Entity", + "code": 422, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Date", + "value": "Wed, 01 Dec 2021 16:51:18 GMT" + }, + { + "key": "Server", + "value": "Apache" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "Set-Cookie", + "value": "SESS5f17f36b17be2854884ad86bf6359d6a=F7tHhQn7hCmfE3AKk4zLoLwORmb%2CwK%2CGmn0gxLWhPfzmreOa; expires=Fri, 24-Dec-2021 20:24:43 GMT; Max-Age=2000000; path=/; domain=.perls.localhost; HttpOnly" + }, + { + "key": "Cache-Control", + "value": "must-revalidate, no-cache, private" + }, + { + "key": "X-UA-Compatible", + "value": "IE=edge" + }, + { + "key": "Content-language", + "value": "en" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "Permissions-Policy", + "value": "interest-cohort=()" + }, + { + "key": "Expires", + "value": "Sun, 19 Nov 1978 05:00:00 GMT" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubdomains; preload" + }, + { + "key": "X-XSS-Protection", + "value": "1; mode=block" + }, + { + "key": "Content-Length", + "value": "95" + }, + { + "key": "Keep-Alive", + "value": "timeout=5, max=100" + }, + { + "key": "Connection", + "value": "Keep-Alive" + }, + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"message\": \"Unprocessable Entity: validation failed.\\ntitle: This value should not be null.\\n\"\n}" + } + ] + }, + { + "name": "Get Web link content", + "protocolProfileBehavior": { + "disabledSystemHeaders": { + "accept": true + }, + "disableBodyPruning": true + }, + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{server}}/node/462", + "host": [ + "{{server}}" + ], + "path": [ + "node", + "462" + ] + }, + "description": "Creates new Web link content" + }, + "response": [] + }, + { + "name": "Update Web link", + "protocolProfileBehavior": { + "disabledSystemHeaders": { + "accept": true + } + }, + "request": { + "method": "PATCH", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"name\": \"Updated weblink \",\n \"feature_image\": \"https://upload.wikimedia.org/wikipedia/commons/thumb/a/a4/Anatomy_of_a_Sunset-2.jpg/440px-Anatomy_of_a_Sunset-2.jpg\",\n \"type\": \"learn_link\",\n \"url\": \"http://example.com\",\n \"topic\": \"What is PERLS\",\n \"tags\": [\n \"AppOnboarding\",\n \"Content Managers\",\n \"New tag\"\n ],\n \"difficulty\": \"Intermediate\",\n \"description\": \"Text in the description.\",\n \"is_sticky\": true,\n \"link_type\": \"custom\",\n \"is_promoted\": true,\n \"published\": true,\n \"groups\": [\n \"New group\",\n \"Content Managers\"\n ]\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{server}}/node/{{node-id}}", + "host": [ + "{{server}}" + ], + "path": [ + "node", + "{{node-id}}" + ] + }, + "description": "Creates new Web link content" + }, + "response": [ + { + "name": "Update Web link", + "originalRequest": { + "method": "PATCH", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"name\": \"Updated weblink \",\n \"feature_image\": \"https://upload.wikimedia.org/wikipedia/commons/thumb/a/a4/Anatomy_of_a_Sunset-2.jpg/440px-Anatomy_of_a_Sunset-2.jpg\",\n \"type\": \"learn_link\",\n \"url\": \"http://example.com\",\n \"topic\": \"What is PERLS\",\n \"tags\": [\n \"AppOnboarding\",\n \"Content Managers\",\n \"New tag\"\n ],\n \"difficulty\": \"Intermediate\",\n \"description\": \"Text in the description.\",\n \"is_sticky\": true,\n \"link_type\": \"custom\",\n \"is_promoted\": true,\n \"published\": true,\n \"groups\": [\n \"New group\",\n \"Content Managers\"\n ]\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{server}}/node/560", + "host": [ + "{{server}}" + ], + "path": [ + "node", + "560" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Date", + "value": "Thu, 16 Dec 2021 15:59:09 GMT" + }, + { + "key": "Server", + "value": "Apache" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "Set-Cookie", + "value": "SESS5f17f36b17be2854884ad86bf6359d6a=Hk%2CK2chV4ZDOGftyU4%2Cozs2Y6BmT5hYZK%2CYO2Tu5K7hzU0sI; expires=Sat, 08-Jan-2022 19:32:44 GMT; Max-Age=2000000; path=/; domain=.perls.localhost; HttpOnly" + }, + { + "key": "Cache-Control", + "value": "must-revalidate, no-cache, private" + }, + { + "key": "X-UA-Compatible", + "value": "IE=edge" + }, + { + "key": "Content-language", + "value": "en" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "Permissions-Policy", + "value": "interest-cohort=()" + }, + { + "key": "Expires", + "value": "Sun, 19 Nov 1978 05:00:00 GMT" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubdomains; preload" + }, + { + "key": "X-XSS-Protection", + "value": "1; mode=block" + }, + { + "key": "Content-Length", + "value": "1313" + }, + { + "key": "Keep-Alive", + "value": "timeout=5, max=99" + }, + { + "key": "Connection", + "value": "Keep-Alive" + }, + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"id\": \"a8a9b939-b68b-445b-b384-e3ef3e113eea\",\n \"nid\": 560,\n \"vid\": 939,\n \"url\": \"http://example.com\",\n \"name\": \"Updated weblink \",\n \"type\": \"learn_link\",\n \"changed\": \"2021-12-16T15:59:09+0000\",\n \"is_promoted\": true,\n \"is_sticky\": true,\n \"file\": null,\n \"tags\": [\n {\n \"id\": \"40e0f1df-d0e1-42da-8633-82d45824cd87\",\n \"vid\": 118,\n \"tid\": 118,\n \"url\": \"/taxonomy/term/118\",\n \"name\": \"AppOnboarding\",\n \"type\": \"tags\",\n \"changed\": \"2021-03-18T16:55:42+0000\"\n },\n {\n \"id\": \"75bf7268-dbab-4aed-baf6-05f7677c927f\",\n \"vid\": 119,\n \"tid\": 119,\n \"url\": \"/taxonomy/term/119\",\n \"name\": \"Content Managers\",\n \"type\": \"tags\",\n \"changed\": \"2021-04-14T15:43:03+0000\"\n },\n {\n \"id\": \"4b12b931-2d20-4278-bba1-29b59680bf52\",\n \"vid\": 124,\n \"tid\": 124,\n \"url\": \"/taxonomy/term/124\",\n \"name\": \"New tag\",\n \"type\": \"tags\",\n \"changed\": \"2021-11-22T04:08:50+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"48894a0c-84ea-4052-b7fa-def32478a00d\",\n \"vid\": 116,\n \"tid\": 116,\n \"url\": \"/taxonomy/term/116\",\n \"name\": \"What is PERLS\",\n \"type\": \"category\",\n \"changed\": \"2021-08-27T17:02:17+0000\"\n },\n \"description\": \"Text in the description.\",\n \"image\": {\n \"UUID\": \"9c7a98bd-d061-402f-87a9-cc07b3e991d0\",\n \"filename\": \"440px-anatomy_of_a_sunset-2_27.jpg\",\n \"url\": \"http://perls.localhost:8000/sites/default/files/styles/large/public/440px-anatomy_of_a_sunset-2_27.jpg?itok=RULncaon\",\n \"original_url\": \"http://perls.localhost:8000/sites/default/files/440px-anatomy_of_a_sunset-2_27.jpg\"\n }\n}" + } + ] + } + ] + }, + { + "name": "Auth Revoke (Refresh token)", + "protocolProfileBehavior": { + "disabledSystemHeaders": {}, + "followAuthorizationHeader": true + }, + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "token", + "value": "{{refresh_token}}", + "type": "text" + }, + { + "key": "client_id", + "value": "{{client_id}}", + "type": "text" + }, + { + "key": "client_secret", + "value": "{{client_secret}}", + "type": "text" + }, + { + "key": "token_type_hint", + "value": "refresh_token", + "type": "text" + } + ], + "options": { + "raw": { + "language": "text" + } + } + }, + "url": { + "raw": "{{server}}/oauth/revoke?XDEBUG_SESSION_START=PHPSTORM", + "host": [ + "{{server}}" + ], + "path": [ + "oauth", + "revoke" + ], + "query": [ + { + "key": "XDEBUG_SESSION_START", + "value": "PHPSTORM" + } + ] + }, + "description": "Revokes access and refresh tokens." + }, + "response": [] + }, + { + "name": "Auth Revoke (Access token)", + "protocolProfileBehavior": { + "disabledSystemHeaders": {}, + "followAuthorizationHeader": true + }, + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "formdata", + "formdata": [ + { + "key": "token", + "value": "{{access_token}}", + "type": "text" + }, + { + "key": "client_id", + "value": "{{client_id}}", + "type": "text" + }, + { + "key": "client_secret", + "value": "{{client_secret}}", + "type": "text" + }, + { + "key": "token_type_hint", + "value": "access_token", + "type": "text" + } + ], + "options": { + "raw": { + "language": "text" + } + } + }, + "url": { + "raw": "{{server}}/oauth/revoke?XDEBUG_SESSION_START=PHPSTORM", + "host": [ + "{{server}}" + ], + "path": [ + "oauth", + "revoke" + ], + "query": [ + { + "key": "XDEBUG_SESSION_START", + "value": "PHPSTORM" + } + ] + }, + "description": "Revokes access and refresh tokens." + }, + "response": [] + }, + { + "name": "Debug", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/oauth/debug", + "host": [ + "{{server}}" + ], + "path": [ + "oauth", + "debug" + ] + }, + "description": "Default endpoint for testing auth" + }, + "response": [] + }, + { + "name": "Current User", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/user/me", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "user", + "me" + ] + }, + "description": "Gets information about the currently authenticated user" + }, + "response": [ + { + "name": "Current User", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/user/me", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "user", + "me" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Date", + "value": "Wed, 01 Sep 2021 20:50:22 GMT" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Content-Length", + "value": "492" + }, + { + "key": "Connection", + "value": "keep-alive" + }, + { + "key": "Set-Cookie", + "value": "AWSALB=u2JdtlPzDUxE94i94BMfFV6+RKoIngrnxv5ZZlJiVzO1gDAvD4F206cUpEquDG4M1g4YSFfTl6Ul1wWBctGBFOrKW24WosTHtAg9NBb6cR3Lx4mVt39inCg4LuIY; Expires=Wed, 08 Sep 2021 20:50:22 GMT; Path=/" + }, + { + "key": "Set-Cookie", + "value": "AWSALBCORS=u2JdtlPzDUxE94i94BMfFV6+RKoIngrnxv5ZZlJiVzO1gDAvD4F206cUpEquDG4M1g4YSFfTl6Ul1wWBctGBFOrKW24WosTHtAg9NBb6cR3Lx4mVt39inCg4LuIY; Expires=Wed, 08 Sep 2021 20:50:22 GMT; Path=/; SameSite=None; Secure" + }, + { + "key": "Server", + "value": "Apache" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "Cache-Control", + "value": "must-revalidate, no-cache, private" + }, + { + "key": "X-Drupal-Dynamic-Cache", + "value": "MISS" + }, + { + "key": "X-UA-Compatible", + "value": "IE=edge" + }, + { + "key": "Content-language", + "value": "en" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "Permissions-Policy", + "value": "interest-cohort=()" + }, + { + "key": "Expires", + "value": "Sun, 19 Nov 1978 05:00:00 GMT" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubdomains; preload" + }, + { + "key": "X-XSS-Protection", + "value": "1; mode=block" + } + ], + "cookie": [], + "body": "{\n \"id\": \"2455a7ba-4935-4a0c-a34b-67b595915a37\",\n \"url\": \"/user/511\",\n \"name\": \"John Doe\",\n \"avatar\": null,\n \"goals\": {\n \"notification_days\": [],\n \"weekly_test_average\": 70,\n \"monthly_course_completions\": 6,\n \"weekly_completions\": 5,\n \"weekly_views\": 10,\n \"notification_time\": null\n },\n \"mail\": \"jdoe@example.com\",\n \"username\": \"jdoe@example.com\",\n \"is_enabled\": true,\n \"roles\": [],\n \"preferred_langcode\": \"en\",\n \"changed\": \"2021-08-27T18:32:26+0000\",\n \"last_access\": \"2021-09-01T20:49:15+0000\",\n \"last_login\": \"2021-09-01T20:48:04+0000\"\n}" + } + ] + }, + { + "name": "Stats", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/stats", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "stats" + ] + }, + "description": "Gets the current user's stats" + }, + "response": [ + { + "name": "Stats", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/stats", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "stats" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Date", + "value": "Wed, 01 Sep 2021 20:46:37 GMT" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Content-Length", + "value": "216" + }, + { + "key": "Connection", + "value": "keep-alive" + }, + { + "key": "Set-Cookie", + "value": "AWSALB=e2SuelsrERYA7LCcUdbLsx6Fo6n+7awQjQSki5j4QTtauce36DVow1jyl0UzvZRzhmZ31Oz4WALwYmXfCI6M36z87CFNJPjIpiqb9c9vJDshJcgnLA6QDo6QNuNu; Expires=Wed, 08 Sep 2021 20:46:37 GMT; Path=/" + }, + { + "key": "Set-Cookie", + "value": "AWSALBCORS=e2SuelsrERYA7LCcUdbLsx6Fo6n+7awQjQSki5j4QTtauce36DVow1jyl0UzvZRzhmZ31Oz4WALwYmXfCI6M36z87CFNJPjIpiqb9c9vJDshJcgnLA6QDo6QNuNu; Expires=Wed, 08 Sep 2021 20:46:37 GMT; Path=/; SameSite=None; Secure" + }, + { + "key": "Set-Cookie", + "value": "SimpleSAMLSessionID=3b6a2593b45aa74dd3680754691f2d2a; path=/; secure; HttpOnly" + }, + { + "key": "Server", + "value": "Apache" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "Cache-Control", + "value": "must-revalidate, no-cache, private" + }, + { + "key": "X-Drupal-Dynamic-Cache", + "value": "UNCACHEABLE" + }, + { + "key": "X-UA-Compatible", + "value": "IE=edge" + }, + { + "key": "Content-language", + "value": "en" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "Permissions-Policy", + "value": "interest-cohort=()" + }, + { + "key": "Expires", + "value": "Sun, 19 Nov 1978 05:00:00 GMT" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubdomains; preload" + }, + { + "key": "X-XSS-Protection", + "value": "1; mode=block" + } + ], + "cookie": [], + "body": "{\n \"completed_count_total\": 0,\n \"completed_count_week\": 0,\n \"seen_count_lo_week\": 0,\n \"completed_count_course_total\": 0,\n \"completed_count_course_month\": 0,\n \"seen_count_total\": 0,\n \"bookmarked_count_total\": 1,\n \"result_avg_test_week\": \"0\"\n}" + } + ] + }, + { + "name": "Badges", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/badges", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "badges" + ] + }, + "description": "Gets a list of badges availabe to this user. The response also contains details of which badges have been awarded." + }, + "response": [ + { + "name": "Badges", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/badges", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "badges" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Date", + "value": "Wed, 01 Sep 2021 20:46:49 GMT" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Transfer-Encoding", + "value": "chunked" + }, + { + "key": "Connection", + "value": "keep-alive" + }, + { + "key": "Set-Cookie", + "value": "AWSALB=xBhToj5WWFkAOSb2aDDSfQkP31S59Fe772ZwhCjN8no6qleZXHg0NdgUHSTAITk1oUcypT0JKnRICiLu9PkKPriY6A6Ogz+lJFvTZXFcvtwcXu6SPnlk1R6BCVUk; Expires=Wed, 08 Sep 2021 20:46:48 GMT; Path=/" + }, + { + "key": "Set-Cookie", + "value": "AWSALBCORS=xBhToj5WWFkAOSb2aDDSfQkP31S59Fe772ZwhCjN8no6qleZXHg0NdgUHSTAITk1oUcypT0JKnRICiLu9PkKPriY6A6Ogz+lJFvTZXFcvtwcXu6SPnlk1R6BCVUk; Expires=Wed, 08 Sep 2021 20:46:48 GMT; Path=/; SameSite=None; Secure" + }, + { + "key": "Server", + "value": "Apache" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "Cache-Control", + "value": "must-revalidate, no-cache, private" + }, + { + "key": "X-UA-Compatible", + "value": "IE=edge" + }, + { + "key": "Content-language", + "value": "en" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "Permissions-Policy", + "value": "interest-cohort=()" + }, + { + "key": "Expires", + "value": "Sun, 19 Nov 1978 05:00:00 GMT" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubdomains; preload" + }, + { + "key": "X-XSS-Protection", + "value": "1; mode=block" + } + ], + "cookie": [], + "body": "[\n {\n \"id\": \"authored_first_article\",\n \"uuid\": \"122e06e6-9a11-42f8-862b-b7eba5918636\",\n \"label\": \"First Article Sent for Review\",\n \"description\": \"Awarded to any user who creates their first article and submits it for review.\",\n \"type\": \"badge\",\n \"plugin_type\": \"Authored Count\",\n \"secret\": false,\n \"invisible\": false,\n \"locked_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/lockedBadge.png\",\n \"unlocked_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/1_review.png\",\n \"sharable_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/1_review.png\",\n \"unlocked\": 1,\n \"unlocked_timestamp\": \"2021-06-25T21:57:26-0500\",\n \"status_description\": \"Awarded\"\n },\n {\n \"id\": \"bookmark_beast\",\n \"uuid\": \"f7d11ed8-6fbc-4a7e-8027-c9be16123ab4\",\n \"label\": \"Bookmark Beast\",\n \"description\": \"Awarded to any user who bookmarks 30 pieces of content.\",\n \"type\": \"badge\",\n \"plugin_type\": \"Bookmark Count Badge\",\n \"secret\": false,\n \"invisible\": false,\n \"locked_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/lockedBadge.png\",\n \"unlocked_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/bookmarkBeast.png\",\n \"sharable_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/bookmarkBeast.png\",\n \"unlocked\": 0,\n \"unlocked_timestamp\": null,\n \"status_description\": \"Achievement Locked\"\n },\n {\n \"id\": \"bookmark_believer\",\n \"uuid\": \"5b9a69c0-28eb-4430-acfa-96aec6704f9f\",\n \"label\": \"Bookmark Believer\",\n \"description\": \"Awarded to any user who bookmarks a piece of content.\",\n \"type\": \"badge\",\n \"plugin_type\": \"Bookmark Count Badge\",\n \"secret\": false,\n \"invisible\": false,\n \"locked_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/lockedBadge.png\",\n \"unlocked_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/bookmarkBeliever.png\",\n \"sharable_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/bookmarkBeliever.png\",\n \"unlocked\": 1,\n \"unlocked_timestamp\": \"2020-12-08T13:53:52-0600\",\n \"status_description\": \"Awarded\"\n },\n {\n \"id\": \"bookmark_boss\",\n \"uuid\": \"9c42e3c3-a67b-48e4-b1d7-cb315028faf4\",\n \"label\": \"Bookmark Boss\",\n \"description\": \"Awarded to any user who bookmarks 10 pieces of content.\",\n \"type\": \"badge\",\n \"plugin_type\": \"Bookmark Count Badge\",\n \"secret\": false,\n \"invisible\": false,\n \"locked_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/lockedBadge.png\",\n \"unlocked_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/bookmarkBoss.png\",\n \"sharable_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/bookmarkBoss.png\",\n \"unlocked\": 0,\n \"unlocked_timestamp\": null,\n \"status_description\": \"Achievement Locked\"\n },\n {\n \"id\": \"courses_completed_20\",\n \"uuid\": \"d75bd09e-4e88-4a97-b032-504999aa2f74\",\n \"label\": \"Adventurer\",\n \"description\": \"Awarded to any user who completes 20 courses.\",\n \"type\": \"badge\",\n \"plugin_type\": \"Completion Count Badge\",\n \"secret\": false,\n \"invisible\": false,\n \"locked_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/lockedBadge.png\",\n \"unlocked_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/adventurer.png\",\n \"sharable_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/adventurer.png\",\n \"unlocked\": 0,\n \"unlocked_timestamp\": null,\n \"status_description\": \"Achievement Locked\"\n },\n {\n \"id\": \"courses_completed_5\",\n \"uuid\": \"12db47e4-bcc3-4a84-b144-36ffa8c69e3c\",\n \"label\": \"Explorer\",\n \"description\": \"Awarded to any user who completes 5 courses\",\n \"type\": \"badge\",\n \"plugin_type\": \"Completion Count Badge\",\n \"secret\": false,\n \"invisible\": false,\n \"locked_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/lockedBadge.png\",\n \"unlocked_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/explorer.png\",\n \"sharable_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/explorer.png\",\n \"unlocked\": 0,\n \"unlocked_timestamp\": null,\n \"status_description\": \"Achievement Locked\"\n },\n {\n \"id\": \"courses_completed_50\",\n \"uuid\": \"d033cea5-fba8-4420-bab7-6e558e364d1a\",\n \"label\": \"Completionist\",\n \"description\": \"Awarded to any user who completes 50 courses.\",\n \"type\": \"badge\",\n \"plugin_type\": \"Completion Count Badge\",\n \"secret\": false,\n \"invisible\": false,\n \"locked_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/lockedBadge.png\",\n \"unlocked_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/completionist.png\",\n \"sharable_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/completionist.png\",\n \"unlocked\": 0,\n \"unlocked_timestamp\": null,\n \"status_description\": \"Achievement Locked\"\n },\n {\n \"id\": \"daily_streak_1\",\n \"uuid\": \"2662d62d-2420-40f8-af28-f6f82149c800\",\n \"label\": \"Daily Streak 1\",\n \"description\": \"Awarded to any user who achieves a one day streak.\",\n \"type\": \"badge\",\n \"plugin_type\": \"Log in Streak\",\n \"secret\": false,\n \"invisible\": false,\n \"locked_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/lockedBadge.png\",\n \"unlocked_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/1daystreak.png\",\n \"sharable_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/1daystreak.png\",\n \"unlocked\": 0,\n \"unlocked_timestamp\": null,\n \"status_description\": \"Achievement Locked\"\n },\n {\n \"id\": \"daily_streak_10\",\n \"uuid\": \"d10b9af8-9d0a-4766-abcd-f709d1ad9d60\",\n \"label\": \"Daily Streak 10\",\n \"description\": \"Awarded to any user who achieves a 10 day streak.\",\n \"type\": \"badge\",\n \"plugin_type\": \"Log in Streak\",\n \"secret\": false,\n \"invisible\": false,\n \"locked_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/lockedBadge.png\",\n \"unlocked_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/10daystreak.png\",\n \"sharable_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/10daystreak.png\",\n \"unlocked\": 0,\n \"unlocked_timestamp\": null,\n \"status_description\": \"Achievement Locked\"\n },\n {\n \"id\": \"daily_streak_50\",\n \"uuid\": \"7f416aa0-268c-4792-a49f-a2135cd8d718\",\n \"label\": \"Daily Streak 50\",\n \"description\": \"Awarded to any user who achieves a streak of 50.\",\n \"type\": \"badge\",\n \"plugin_type\": \"Log in Streak\",\n \"secret\": false,\n \"invisible\": false,\n \"locked_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/lockedBadge.png\",\n \"unlocked_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/50daystreak.png\",\n \"sharable_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/50daystreak.png\",\n \"unlocked\": 0,\n \"unlocked_timestamp\": null,\n \"status_description\": \"Achievement Locked\"\n },\n {\n \"id\": \"first_authored_completion\",\n \"uuid\": \"dd3ef6c2-a660-46dc-bf5d-5c27b3847672\",\n \"label\": \"First Self-Authored Article Completed\",\n \"description\": \"Awarded to any user when they create an article and another user completes it.\",\n \"type\": \"badge\",\n \"plugin_type\": \"Authored Completed\",\n \"secret\": false,\n \"invisible\": false,\n \"locked_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/lockedBadge.png\",\n \"unlocked_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/1_authored_completed.png\",\n \"sharable_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/1_authored_completed.png\",\n \"unlocked\": 0,\n \"unlocked_timestamp\": null,\n \"status_description\": \"Achievement Locked\"\n },\n {\n \"id\": \"milwaukee_ppe_badge\",\n \"uuid\": \"c97441be-a818-46f8-8ba9-960c8498d393\",\n \"label\": \"Milwaukee PPE Badge\",\n \"description\": \"Badge awarded after completing the Milwaukee PPE badge course\",\n \"type\": \"badge\",\n \"plugin_type\": \"Completion Badge\",\n \"secret\": false,\n \"invisible\": false,\n \"locked_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/defaultLocked.png\",\n \"unlocked_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/ppe-positioning_0.png\",\n \"sharable_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/ppe-positioning_0.png\",\n \"unlocked\": 0,\n \"unlocked_timestamp\": null,\n \"status_description\": \"Achievement Locked\"\n },\n {\n \"id\": \"custom_badge\",\n \"uuid\": \"a75164a2-7468-42eb-b143-76af6ee23dda\",\n \"label\": \"Custom Badge\",\n \"description\": \"\",\n \"type\": \"badge\",\n \"plugin_type\": \"Completion Badge\",\n \"secret\": false,\n \"invisible\": false,\n \"locked_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/defaultLocked.png\",\n \"unlocked_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/custom.png\",\n \"sharable_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/custom.png\",\n \"unlocked\": 0,\n \"unlocked_timestamp\": null,\n \"status_description\": \"Achievement Locked\"\n },\n {\n \"id\": \"published_first_article\",\n \"uuid\": \"9fe35697-3106-404c-b2a5-0fc2d0d65fcc\",\n \"label\": \"First Article Published\",\n \"description\": \"Awarded to any user when their first article is published.\",\n \"type\": \"badge\",\n \"plugin_type\": \"Authored Count\",\n \"secret\": false,\n \"invisible\": false,\n \"locked_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/lockedBadge.png\",\n \"unlocked_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/1_published.png\",\n \"sharable_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/1_published.png\",\n \"unlocked\": 0,\n \"unlocked_timestamp\": null,\n \"status_description\": \"Achievement Locked\"\n },\n {\n \"id\": \"time_streak_15_min\",\n \"uuid\": \"e0afb66d-765a-4da1-9ba7-fd0f8fdacd1d\",\n \"label\": \"Time Streak 15 min\",\n \"description\": \"Awarded to any user who uses the app for 15 minutes.\",\n \"type\": \"badge\",\n \"plugin_type\": \"Time Attack\",\n \"secret\": false,\n \"invisible\": false,\n \"locked_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/lockedBadge.png\",\n \"unlocked_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/15minutes.png\",\n \"sharable_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/15minutes.png\",\n \"unlocked\": 0,\n \"unlocked_timestamp\": null,\n \"status_description\": \"Achievement Locked\"\n },\n {\n \"id\": \"time_streak_5_hour\",\n \"uuid\": \"567837a3-c0fe-4d21-a241-55a09347baab\",\n \"label\": \"Time Streak 5 hour\",\n \"description\": \"Awarded to any user who uses the app for 5 hours.\",\n \"type\": \"badge\",\n \"plugin_type\": \"Time Attack\",\n \"secret\": false,\n \"invisible\": false,\n \"locked_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/lockedBadge.png\",\n \"unlocked_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/5hours.png\",\n \"sharable_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/5hours.png\",\n \"unlocked\": 0,\n \"unlocked_timestamp\": null,\n \"status_description\": \"Achievement Locked\"\n },\n {\n \"id\": \"time_streak_60_min\",\n \"uuid\": \"54c06bfe-28f0-4951-9b58-fdeeb24d2849\",\n \"label\": \"Time Streak 60 min\",\n \"description\": \"Awarded to any user who uses the app for 60 minutes.\",\n \"type\": \"badge\",\n \"plugin_type\": \"Time Attack\",\n \"secret\": false,\n \"invisible\": false,\n \"locked_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/lockedBadge.png\",\n \"unlocked_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/1hour.png\",\n \"sharable_image_url\": \"https://perls.localhost:8000/sites/default/files/badges/1hour.png\",\n \"unlocked\": 0,\n \"unlocked_timestamp\": null,\n \"status_description\": \"Achievement Locked\"\n }\n]" + } + ] + }, + { + "name": "Certificates", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/certificates", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "certificates" + ] + }, + "description": "Gets a list of certifcates a user has earned." + }, + "response": [] + }, + { + "name": "Recommendations", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/recommendations", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "recommendations" + ] + }, + "description": "List of Recommendations for currently logged in user" + }, + "response": [ + { + "name": "Recommendations", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/recommendations", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "recommendations" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Date", + "value": "Wed, 01 Sep 2021 20:47:11 GMT" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Transfer-Encoding", + "value": "chunked" + }, + { + "key": "Connection", + "value": "keep-alive" + }, + { + "key": "Set-Cookie", + "value": "AWSALB=BALGZ9mi4FnVKxQznIItJGG1q6xIC20eLR6JO+riIwKUiRdmKY7dMqH8NHqe+GU8xTLZdOBTmUo0X2suQaR0y8JVcd4v/zgdsRARaSDimtFwkMXnhed9RF9VWVce; Expires=Wed, 08 Sep 2021 20:47:10 GMT; Path=/" + }, + { + "key": "Set-Cookie", + "value": "AWSALBCORS=BALGZ9mi4FnVKxQznIItJGG1q6xIC20eLR6JO+riIwKUiRdmKY7dMqH8NHqe+GU8xTLZdOBTmUo0X2suQaR0y8JVcd4v/zgdsRARaSDimtFwkMXnhed9RF9VWVce; Expires=Wed, 08 Sep 2021 20:47:10 GMT; Path=/; SameSite=None; Secure" + }, + { + "key": "Server", + "value": "Apache" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "Cache-Control", + "value": "must-revalidate, no-cache, private" + }, + { + "key": "X-Drupal-Dynamic-Cache", + "value": "MISS" + }, + { + "key": "X-UA-Compatible", + "value": "IE=edge" + }, + { + "key": "Content-language", + "value": "en" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "Permissions-Policy", + "value": "interest-cohort=()" + }, + { + "key": "Expires", + "value": "Sun, 19 Nov 1978 05:00:00 GMT" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubdomains; preload" + }, + { + "key": "X-XSS-Protection", + "value": "1; mode=block" + } + ], + "cookie": [], + "body": "[\n {\n \"id\": \"a4cf285d-e8da-4d3d-bb5f-a2d9198d1d1c\",\n \"nid\": 1021,\n \"vid\": 2734,\n \"url\": \"/node/1021\",\n \"name\": \"Sprint 17 Demo Meeting\",\n \"type\": \"event\",\n \"changed\": \"2021-08-27T05:22:42+0000\",\n \"is_promoted\": true,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": [\n {\n \"id\": \"7567d087-b32d-4959-8c43-ec9e66f1b7f8\",\n \"vid\": 105,\n \"tid\": 105,\n \"url\": \"/taxonomy/term/105\",\n \"name\": \"test\",\n \"type\": \"tags\",\n \"changed\": \"2020-06-11T20:09:40+0000\"\n }\n ]\n },\n {\n \"id\": \"a055fba8-332a-4933-ae5b-dc301e42ab82\",\n \"nid\": 1022,\n \"vid\": 2741,\n \"url\": \"/node/1022\",\n \"name\": \"Virtual Event\",\n \"type\": \"event\",\n \"changed\": \"2021-08-31T17:41:29+0000\",\n \"is_promoted\": true,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": [\n {\n \"id\": \"ebc14d90-2ad9-4bcb-a7fd-7454efb25d55\",\n \"vid\": 283,\n \"tid\": 283,\n \"url\": \"/taxonomy/term/283\",\n \"name\": \"event\",\n \"type\": \"tags\",\n \"changed\": \"2021-08-27T07:15:27+0000\"\n }\n ]\n },\n {\n \"id\": \"47ffbab9-1bd9-4518-b290-99524efd29ee\",\n \"nid\": 1019,\n \"vid\": 2733,\n \"url\": \"/node/1019\",\n \"name\": \"Testcourse-1\",\n \"type\": \"course\",\n \"changed\": \"2021-08-27T00:07:21+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": [],\n \"topic\": {\n \"id\": \"4a16bc04-dca6-4ed9-9a07-af2e138ca6c0\",\n \"vid\": 213,\n \"tid\": 213,\n \"url\": \"/taxonomy/term/213\",\n \"name\": \"Content Test Suite [CTS]\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"Create a content test suite course on the dev server with example content\"\n },\n \"description\": null,\n \"learning_objects\": [\n {\n \"id\": \"0cf81d2a-b4d3-4a1e-858c-598ff0b5a626\",\n \"nid\": 1020,\n \"vid\": 2731,\n \"url\": \"/node/1020\",\n \"name\": \"Testarticle---\",\n \"type\": \"learn_article\",\n \"changed\": \"2021-08-27T00:04:52+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"530f3550-ead3-4570-8806-f5c6e749de55\",\n \"name\": \"node_1020.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/offline_page/node_1020.zip\"\n },\n \"tags\": [],\n \"topic\": {\n \"id\": \"4a16bc04-dca6-4ed9-9a07-af2e138ca6c0\",\n \"vid\": 213,\n \"tid\": 213,\n \"url\": \"/taxonomy/term/213\",\n \"name\": \"Content Test Suite [CTS]\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"Create a content test suite course on the dev server with example content\"\n },\n \"description\": null,\n \"image\": null,\n \"discussion_status\": \"hidden\"\n }\n ],\n \"image\": null\n },\n {\n \"id\": \"546f2221-5b49-4c81-80e7-64c757ebb922\",\n \"nid\": 1023,\n \"vid\": 2736,\n \"url\": \"/node/1023\",\n \"name\": \"Test Event\",\n \"type\": \"event\",\n \"changed\": \"2021-08-27T16:26:01+0000\",\n \"is_promoted\": true,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": []\n },\n {\n \"id\": \"8202fc01-bf42-4a2e-8800-109aaec7d610\",\n \"nid\": 1018,\n \"vid\": 2726,\n \"url\": \"/node/1018\",\n \"name\": \"NEW COURSE WITHOUT IMAGE\",\n \"type\": \"course\",\n \"changed\": \"2021-08-26T15:59:58+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": [\n {\n \"id\": \"71277fab-7978-4af0-9b41-5aaba5464ca5\",\n \"vid\": 273,\n \"tid\": 273,\n \"url\": \"/taxonomy/term/273\",\n \"name\": \"COURSE1TOBETESTED\",\n \"type\": \"tags\",\n \"changed\": \"2021-07-30T15:05:12+0000\"\n },\n {\n \"id\": \"54db0a3d-4696-4061-bbb6-e8cc905145b5\",\n \"vid\": 215,\n \"tid\": 215,\n \"url\": \"/taxonomy/term/215\",\n \"name\": \"Content Test Suite\",\n \"type\": \"tags\",\n \"changed\": \"2021-04-01T15:54:53+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"54e0ff01-851c-4e7a-9c89-21aa6496c1a9\",\n \"vid\": 246,\n \"tid\": 246,\n \"url\": \"/taxonomy/term/246\",\n \"name\": \"new topic 3\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"new topic 3\"\n },\n \"description\": \"NEW COURSE WITHOUT IMAGE\\r\\n\\r\\nNEW COURSE WITHOUT IMAGE\",\n \"learning_objects\": [\n {\n \"id\": \"8d3d02dc-13e8-416f-ab26-978e00c7d5e9\",\n \"nid\": 1012,\n \"vid\": 2732,\n \"url\": \"/node/1012\",\n \"name\": \"Test article\",\n \"type\": \"learn_article\",\n \"changed\": \"2021-08-27T00:04:52+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"0efcddd1-2030-4c48-a4af-5895e6722572\",\n \"name\": \"node_1012.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/offline_page/node_1012.zip\"\n },\n \"tags\": [],\n \"topic\": {\n \"id\": \"4a16bc04-dca6-4ed9-9a07-af2e138ca6c0\",\n \"vid\": 213,\n \"tid\": 213,\n \"url\": \"/taxonomy/term/213\",\n \"name\": \"Content Test Suite [CTS]\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"Create a content test suite course on the dev server with example content\"\n },\n \"description\": null,\n \"image\": null,\n \"discussion_status\": \"hidden\"\n }\n ],\n \"image\": null\n },\n {\n \"id\": \"f8ab3951-e7f8-4729-9b16-471dbee33239\",\n \"nid\": 974,\n \"vid\": 2702,\n \"url\": \"/node/974\",\n \"name\": \"Article for SL 2671\",\n \"type\": \"learn_article\",\n \"changed\": \"2021-08-18T20:16:59+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"9e40f25a-ef1a-4336-b7c5-6ab813f38fa2\",\n \"name\": \"node_974.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/offline_page/node_974.zip\"\n },\n \"tags\": [],\n \"topic\": {\n \"id\": \"7db21c39-78c9-48a6-a78d-ecbd7ab49b4b\",\n \"vid\": 92,\n \"tid\": 92,\n \"url\": \"/taxonomy/term/92\",\n \"name\": \"Welcome to SLGO\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": null\n },\n \"description\": null,\n \"image\": null,\n \"discussion_status\": \"open\"\n },\n {\n \"id\": \"11f46744-246c-45dc-bcc4-d22d2ee5272b\",\n \"nid\": 1007,\n \"vid\": 2700,\n \"url\": \"/node/1007\",\n \"name\": \"Untagged course containing #carwash article\",\n \"type\": \"course\",\n \"changed\": \"2021-08-18T20:16:05+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": [],\n \"topic\": {\n \"id\": \"2c22f3e4-e44c-4e36-8956-d3ae6b1a9ac8\",\n \"vid\": 104,\n \"tid\": 104,\n \"url\": \"/taxonomy/term/104\",\n \"name\": \"e-learning\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": null\n },\n \"description\": \"This course contains the article tagged with #carwash.\",\n \"learning_objects\": [\n {\n \"id\": \"a8486eba-7ea6-4118-902e-da8e212f74ff\",\n \"nid\": 1006,\n \"vid\": 2701,\n \"url\": \"/node/1006\",\n \"name\": \"Article tagged #carwash\",\n \"type\": \"learn_article\",\n \"changed\": \"2021-08-18T20:16:05+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"265a9098-72c2-40d7-b6d4-f88e7be83a65\",\n \"name\": \"node_1006.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/offline_page/node_1006.zip\"\n },\n \"tags\": [\n {\n \"id\": \"0e53228a-faf8-4eb1-ae49-ece61debe8fd\",\n \"vid\": 275,\n \"tid\": 275,\n \"url\": \"/taxonomy/term/275\",\n \"name\": \"carwash\",\n \"type\": \"tags\",\n \"changed\": \"2021-08-04T19:07:27+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"2589cea9-25b1-4c7c-bd84-51aa61c8294b\",\n \"vid\": 274,\n \"tid\": 274,\n \"url\": \"/taxonomy/term/274\",\n \"name\": \"An empty topic\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"This topic is empty.\"\n },\n \"description\": \"This article is tagged #carwash.\",\n \"image\": null,\n \"discussion_status\": \"hidden\"\n }\n ],\n \"image\": null\n },\n {\n \"id\": \"9e3d6dfc-2933-40fd-a51d-5051112707bf\",\n \"nid\": 994,\n \"vid\": 2670,\n \"url\": \"/node/994\",\n \"name\": \"Certificate course\",\n \"type\": \"course\",\n \"changed\": \"2021-08-12T13:21:49+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": [],\n \"topic\": {\n \"id\": \"2589cea9-25b1-4c7c-bd84-51aa61c8294b\",\n \"vid\": 274,\n \"tid\": 274,\n \"url\": \"/taxonomy/term/274\",\n \"name\": \"An empty topic\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"This topic is empty.\"\n },\n \"description\": null,\n \"learning_objects\": [\n {\n \"id\": \"e8d9da86-f21a-415b-a45a-35e1d44609df\",\n \"nid\": 996,\n \"vid\": 2667,\n \"url\": \"/node/996\",\n \"name\": \"Certificate test\",\n \"type\": \"test\",\n \"changed\": \"2021-08-12T13:20:51+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": [],\n \"questions\": [\n {\n \"id\": \"13c15571-1f77-4e18-82c6-b52094d4ed32\",\n \"nid\": 995,\n \"vid\": 2666,\n \"url\": \"/node/995\",\n \"question\": \"Easy question\",\n \"type\": \"quiz\",\n \"changed\": \"2021-09-01T16:48:26+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": [],\n \"topic\": {\n \"id\": \"2589cea9-25b1-4c7c-bd84-51aa61c8294b\",\n \"vid\": 274,\n \"tid\": 274,\n \"url\": \"/taxonomy/term/274\",\n \"name\": \"An empty topic\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"This topic is empty.\"\n },\n \"options\": [\n {\n \"uuid\": \"7005469b-90fd-4019-bcae-ae6791d230ba\",\n \"answer\": \"Correct\",\n \"rationale\": null,\n \"correct\": true\n },\n {\n \"uuid\": \"95e03132-ccf9-435a-9317-f001fba5f142\",\n \"answer\": \"Incorrect\",\n \"rationale\": null,\n \"correct\": false\n }\n ]\n }\n ],\n \"pass_mark\": 0.5\n }\n ],\n \"image\": {\n \"UUID\": \"4091d5a2-a6df-4bdb-a640-199c670653de\",\n \"filename\": \"ahsan-s-UTO8escGF3M-unsplash.jpg\",\n \"url\": \"https://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/ahsan-s-UTO8escGF3M-unsplash.jpg?itok=ZumCUSxm\",\n \"original_url\": \"https://perls.localhost:8000/sites/default/files/2020-03/ahsan-s-UTO8escGF3M-unsplash.jpg\"\n }\n },\n {\n \"id\": \"c5d65d3b-d681-4047-8915-a66dee1ea741\",\n \"nid\": 825,\n \"vid\": 1990,\n \"url\": \"/node/825\",\n \"name\": \"Testcourse\",\n \"type\": \"course\",\n \"changed\": \"2021-05-21T17:15:32+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": [],\n \"topic\": {\n \"id\": \"4a16bc04-dca6-4ed9-9a07-af2e138ca6c0\",\n \"vid\": 213,\n \"tid\": 213,\n \"url\": \"/taxonomy/term/213\",\n \"name\": \"Content Test Suite [CTS]\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"Create a content test suite course on the dev server with example content\"\n },\n \"description\": \"Testcourse\",\n \"learning_objects\": [],\n \"image\": null\n },\n {\n \"id\": \"254f74df-e99e-4dbe-b1b9-4888dfd55f21\",\n \"nid\": 969,\n \"vid\": 2590,\n \"url\": \"/node/969\",\n \"name\": \"TestPC\",\n \"type\": \"learn_article\",\n \"changed\": \"2021-07-30T20:22:55+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"affeb744-182d-45e0-b798-5d3d503ad1ff\",\n \"name\": \"node_969.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/offline_page/node_969.zip\"\n },\n \"tags\": [],\n \"topic\": {\n \"id\": \"4a16bc04-dca6-4ed9-9a07-af2e138ca6c0\",\n \"vid\": 213,\n \"tid\": 213,\n \"url\": \"/taxonomy/term/213\",\n \"name\": \"Content Test Suite [CTS]\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"Create a content test suite course on the dev server with example content\"\n },\n \"description\": \"TestPC\",\n \"image\": null,\n \"discussion_status\": \"open\"\n },\n {\n \"id\": \"631dee28-d9e9-42a1-a024-7411c4741242\",\n \"nid\": 876,\n \"vid\": 2126,\n \"url\": \"/node/876\",\n \"name\": \"Outlandish Course\",\n \"type\": \"course\",\n \"changed\": \"2021-05-28T20:31:45+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": [\n {\n \"id\": \"04ec7f44-2b9d-4284-9d3e-4deb9bc9bea4\",\n \"vid\": 259,\n \"tid\": 259,\n \"url\": \"/taxonomy/term/259\",\n \"name\": \"outlandish\",\n \"type\": \"tags\",\n \"changed\": \"2021-05-28T20:31:45+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"420d2b42-9b40-43cd-8a81-1d40d7585b74\",\n \"vid\": 245,\n \"tid\": 245,\n \"url\": \"/taxonomy/term/245\",\n \"name\": \"new topic 2\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"new topic 2\"\n },\n \"description\": \"a1234567890\\r\\nb1234567890\\r\\nc1234567890\\r\\nd1234567890\\r\\ne1234567890\\r\\nf1234567890\\r\\ng1234567890\\r\\nh1234567890\\r\\ni1234567890\\r\\nj1234567890\\r\\nk1234567890\\r\\nl1234567890\\r\\nm1234567890\\r\\nn1234567890\\r\\no1234567890\\r\\np1234567890\\r\\nq1234567890\\r\\nr1234567890\\r\\ns1234567890\\r\\nt1234567890\\r\\nu1234567890\\r\\nv1234567890\\r\\nw1234567890\\r\\nx1234567890\\r\\ny1234567890\\r\\nz1234567890\\r\\na1234567890\\r\\nb1234567890\\r\\nc1234567890\\r\\nd1234567890\\r\\ne1234567890\\r\\nf1234567890\\r\\ng1234567890\\r\\nh1234567890\\r\\ni1234567890\\r\\nj1234567890\\r\\nk1234567890\\r\\nl1234567890\\r\\nm1234567890\\r\\nn1234567890\\r\\no123456780\",\n \"learning_objects\": [],\n \"image\": {\n \"UUID\": \"87fd204f-e6db-4d10-b7a2-2beb19668818\",\n \"filename\": \"dog-sunglasses-square_0.jpg\",\n \"url\": \"https://perls.localhost:8000/sites/default/files/styles/large/public/2021-05/dog-sunglasses-square_0.jpg?itok=_9floKCS\",\n \"original_url\": \"https://perls.localhost:8000/sites/default/files/2021-05/dog-sunglasses-square_0.jpg\"\n }\n },\n {\n \"id\": \"0f545c02-61f1-4a48-a3d5-b8a47767c87e\",\n \"nid\": 609,\n \"vid\": 1256,\n \"url\": \"/node/609\",\n \"name\": \"new course\",\n \"type\": \"course\",\n \"changed\": \"2021-03-25T15:20:52+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": [],\n \"topic\": {\n \"id\": \"fb473dd7-86a8-40a6-8a12-c9c80d46c2fb\",\n \"vid\": 80,\n \"tid\": 80,\n \"url\": \"/taxonomy/term/80\",\n \"name\": \"Occupational Safety and Health\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"This topic includes content related to the safety, health, and welfare of people at work The goal of occupational safety and health programs is to foster a safe and healthy work environment.[3] OSH may also protect co-workers, family members, employers, customers, and many others who might be affected by the workplace environment. \"\n },\n \"description\": \"testUse a course to guide your learners through a sequential set of content (including articles, web links, tests, and more). Learners are encouraged to start with the first item in the course and work their way through to gain mastery of the information presented here.\\r\\n\\r\\n\",\n \"learning_objects\": [\n {\n \"id\": \"374b2852-aa0b-4b79-adb5-f7c2ec470b7b\",\n \"nid\": 603,\n \"vid\": 1303,\n \"url\": \"/node/603\",\n \"name\": \"test\",\n \"type\": \"podcast_episode\",\n \"changed\": \"2021-03-29T20:58:24+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"867adcf0-e0f4-490e-a538-4ac761556cf7\",\n \"name\": \"mp3.mp3\",\n \"url\": \"https://perls.localhost:8000/sites/default/files/podcasts/2021-03/test-374b2852-aa0b-4b79-adb5-f7c2ec470b7b/mp3.mp3\",\n \"mimetype\": \"audio/mpeg\"\n },\n \"tags\": [\n {\n \"id\": \"7567d087-b32d-4959-8c43-ec9e66f1b7f8\",\n \"vid\": 105,\n \"tid\": 105,\n \"url\": \"/taxonomy/term/105\",\n \"name\": \"test\",\n \"type\": \"tags\",\n \"changed\": \"2020-06-11T20:09:40+0000\"\n }\n ],\n \"description\": \"test\",\n \"duration\": 29,\n \"release_date\": \"2021-03-25\"\n }\n ],\n \"image\": null\n },\n {\n \"id\": \"a7d950ce-f018-4875-9fb0-d7c27420e42a\",\n \"nid\": 676,\n \"vid\": 1440,\n \"url\": \"/node/676\",\n \"name\": \"Course with 250 1 test\",\n \"type\": \"course\",\n \"changed\": \"2021-04-07T14:45:56+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": [\n {\n \"id\": \"54db0a3d-4696-4061-bbb6-e8cc905145b5\",\n \"vid\": 215,\n \"tid\": 215,\n \"url\": \"/taxonomy/term/215\",\n \"name\": \"Content Test Suite\",\n \"type\": \"tags\",\n \"changed\": \"2021-04-01T15:54:53+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"fb473dd7-86a8-40a6-8a12-c9c80d46c2fb\",\n \"vid\": 80,\n \"tid\": 80,\n \"url\": \"/taxonomy/term/80\",\n \"name\": \"Occupational Safety and Health\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"This topic includes content related to the safety, health, and welfare of people at work The goal of occupational safety and health programs is to foster a safe and healthy work environment.[3] OSH may also protect co-workers, family members, employers, customers, and many others who might be affected by the workplace environment. \"\n },\n \"description\": \"Course with 250 1 test\\r\\nCourse with 250 1 test\",\n \"learning_objects\": [],\n \"image\": null\n },\n {\n \"id\": \"e0cc5cf5-d9ca-477f-8b4e-78e48e90e9af\",\n \"nid\": 481,\n \"vid\": 951,\n \"url\": \"/node/481\",\n \"name\": \"COURSE FOR SWAT TEAM - Cloned - Cloned - Cloned - Cloned - Cloned\",\n \"type\": \"course\",\n \"changed\": \"2021-04-22T03:15:37+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": [\n {\n \"id\": \"eb748509-0c76-4649-a48a-9d2b4c6b5de5\",\n \"vid\": 136,\n \"tid\": 136,\n \"url\": \"/taxonomy/term/136\",\n \"name\": \"PQA\",\n \"type\": \"tags\",\n \"changed\": \"2021-01-26T15:59:36+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"fb473dd7-86a8-40a6-8a12-c9c80d46c2fb\",\n \"vid\": 80,\n \"tid\": 80,\n \"url\": \"/taxonomy/term/80\",\n \"name\": \"Occupational Safety and Health\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"This topic includes content related to the safety, health, and welfare of people at work The goal of occupational safety and health programs is to foster a safe and healthy work environment.[3] OSH may also protect co-workers, family members, employers, customers, and many others who might be affected by the workplace environment. \"\n },\n \"description\": \"Test\",\n \"learning_objects\": [\n {\n \"id\": \"a8b3225b-f438-4a60-952e-441539c7c40f\",\n \"nid\": 431,\n \"vid\": 838,\n \"url\": \"/node/431\",\n \"name\": \"Test\",\n \"type\": \"podcast_episode\",\n \"changed\": \"2021-01-22T16:48:19+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"f5a158f8-caae-4793-90dc-adbad486ce89\",\n \"name\": \"mp3.mp3\",\n \"url\": \"https://perls.localhost:8000/sites/default/files/podcasts/2021-01/mp3.mp3\",\n \"mimetype\": \"audio/mpeg\"\n },\n \"tags\": [\n {\n \"id\": \"c36b1927-1f39-4ddf-b74b-dc5e45c25aad\",\n \"vid\": 132,\n \"tid\": 132,\n \"url\": \"/taxonomy/term/132\",\n \"name\": \"broken\",\n \"type\": \"tags\",\n \"changed\": \"2021-01-20T16:51:57+0000\"\n }\n ],\n \"description\": \"Test\\r\\nTest\\r\\nTest\\r\\nTest\\r\\nTest\",\n \"duration\": 29,\n \"release_date\": \"2021-01-22\"\n },\n {\n \"id\": \"cf1e197a-5f87-40c7-8b50-8c1fe04802c8\",\n \"nid\": 427,\n \"vid\": 1537,\n \"url\": \"/node/427\",\n \"name\": \"Learning object new\",\n \"type\": \"learn_article\",\n \"changed\": \"2021-04-22T03:15:37+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"5c7859e7-50c6-4068-9b99-a86948050067\",\n \"name\": \"node_427.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/offline_page/node_427.zip\"\n },\n \"tags\": [\n {\n \"id\": \"70fd405c-8fe9-415b-afbf-3692625e778f\",\n \"vid\": 111,\n \"tid\": 111,\n \"url\": \"/taxonomy/term/111\",\n \"name\": \"digital learning\",\n \"type\": \"tags\",\n \"changed\": \"2020-07-29T11:30:56+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"fb473dd7-86a8-40a6-8a12-c9c80d46c2fb\",\n \"vid\": 80,\n \"tid\": 80,\n \"url\": \"/taxonomy/term/80\",\n \"name\": \"Occupational Safety and Health\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"This topic includes content related to the safety, health, and welfare of people at work The goal of occupational safety and health programs is to foster a safe and healthy work environment.[3] OSH may also protect co-workers, family members, employers, customers, and many others who might be affected by the workplace environment. \"\n },\n \"description\": \"Test\",\n \"image\": {\n \"UUID\": \"a27c9b66-059c-4f39-8eef-53f9b45137ac\",\n \"filename\": \"armour_0.jpg\",\n \"url\": \"https://perls.localhost:8000/sites/default/files/styles/large/public/2021-01/armour_0.jpg?itok=YhWRMI2t\",\n \"original_url\": \"https://perls.localhost:8000/sites/default/files/2021-01/armour_0.jpg\"\n },\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"50cbd2a8-d377-4943-bb40-3007c4898c6c\",\n \"nid\": 419,\n \"vid\": 817,\n \"url\": \"/node/419\",\n \"name\": \"refactor 2\",\n \"type\": \"podcast_episode\",\n \"changed\": \"2020-12-21T20:29:41+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"17eb5d56-cd9a-48f2-9889-c71db5f188cd\",\n \"name\": \"test_35.mp3\",\n \"url\": \"https://perls.localhost:8000/sites/default/files/podcasts/2020-12/test_35.mp3\",\n \"mimetype\": \"audio/mpeg\"\n },\n \"tags\": [\n {\n \"id\": \"c3c293a8-acb2-4e52-bb4c-7bf45be16495\",\n \"vid\": 109,\n \"tid\": 109,\n \"url\": \"/taxonomy/term/109\",\n \"name\": \"chicken\",\n \"type\": \"tags\",\n \"changed\": \"2020-06-12T18:26:53+0000\"\n }\n ],\n \"description\": null,\n \"duration\": 4,\n \"release_date\": \"2020-12-21\"\n },\n {\n \"id\": \"012d524a-0eb7-4e2e-b8a3-ae41bf39d1cc\",\n \"nid\": 418,\n \"vid\": 815,\n \"url\": \"/node/418\",\n \"name\": \"Refactor test\",\n \"type\": \"podcast_episode\",\n \"changed\": \"2020-12-21T20:27:42+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"9cd498eb-5991-4f16-a1a4-558bbdcf8707\",\n \"name\": \"test_34.mp3\",\n \"url\": \"https://perls.localhost:8000/sites/default/files/podcasts/2020-12/test_34.mp3\",\n \"mimetype\": \"audio/mpeg\"\n },\n \"tags\": [\n {\n \"id\": \"c3c293a8-acb2-4e52-bb4c-7bf45be16495\",\n \"vid\": 109,\n \"tid\": 109,\n \"url\": \"/taxonomy/term/109\",\n \"name\": \"chicken\",\n \"type\": \"tags\",\n \"changed\": \"2020-06-12T18:26:53+0000\"\n }\n ],\n \"description\": null,\n \"duration\": 4,\n \"release_date\": \"2020-12-21\"\n }\n ],\n \"image\": {\n \"UUID\": \"68f8c779-2a63-4aa2-b4e0-c1ffa7cc3ee6\",\n \"filename\": \"army.jpg\",\n \"url\": \"https://perls.localhost:8000/sites/default/files/styles/large/public/2021-01/army.jpg?itok=F1VmuwLG\",\n \"original_url\": \"https://perls.localhost:8000/sites/default/files/2021-01/army.jpg\"\n }\n },\n {\n \"id\": \"fa9f0752-4228-400a-aac9-2a9914ac3b55\",\n \"nid\": 887,\n \"vid\": 2174,\n \"url\": \"/node/887\",\n \"name\": \"Test article 9\",\n \"type\": \"learn_article\",\n \"changed\": \"2021-05-31T10:02:53+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"3e6e68a3-3f1b-4f3b-8e02-1470ac89d3c7\",\n \"name\": \"node_887.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/offline_page/node_887.zip\"\n },\n \"tags\": [],\n \"topic\": {\n \"id\": \"4a16bc04-dca6-4ed9-9a07-af2e138ca6c0\",\n \"vid\": 213,\n \"tid\": 213,\n \"url\": \"/taxonomy/term/213\",\n \"name\": \"Content Test Suite [CTS]\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"Create a content test suite course on the dev server with example content\"\n },\n \"description\": null,\n \"image\": null,\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"ddc03afc-ad8e-4110-aa6c-82c49085775b\",\n \"nid\": 977,\n \"vid\": 2620,\n \"url\": \"/node/977\",\n \"name\": \"Testweblink-41\",\n \"type\": \"learn_link\",\n \"changed\": \"2021-08-06T17:35:24+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": [],\n \"topic\": {\n \"id\": \"4a16bc04-dca6-4ed9-9a07-af2e138ca6c0\",\n \"vid\": 213,\n \"tid\": 213,\n \"url\": \"/taxonomy/term/213\",\n \"name\": \"Content Test Suite [CTS]\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"Create a content test suite course on the dev server with example content\"\n },\n \"description\": null,\n \"image\": {\n \"UUID\": \"baf9a246-a3e2-42f7-8223-ffb482c4cdf4\",\n \"filename\": \"image-1100.jpg\",\n \"url\": \"https://perls.localhost:8000/sites/default/files/styles/large/public/2021-08/image-1100.jpg?itok=1SOz8ZZH\",\n \"original_url\": \"https://perls.localhost:8000/sites/default/files/2021-08/image-1100.jpg\"\n }\n },\n {\n \"id\": \"bc732155-7117-4daf-8bdb-392771d3a30d\",\n \"nid\": 988,\n \"vid\": 2658,\n \"url\": \"https://perls.localhost:8000/system/files/2021-08/xapi_300mb_incompressible/index.html?endpoint=https%3A//perls.localhost:8000/lrs/&auth=none&actor=%7B%22objectType%22%3A%22Agent%22%2C%22name%22%3A%22John%20Doe%22%2C%22account%22%3A%7B%22name%22%3A%222455a7ba-4935-4a0c-a34b-67b595915a37%22%2C%22homePage%22%3A%22https%3A%5C/%5C/perls.localhost:8000%22%7D%7D&activity_id=https%3A//perls.localhost:8000/node/988&activity_platform=PERLS\",\n \"name\": \"xAPI 300MB\",\n \"type\": \"learn_package\",\n \"changed\": \"2021-08-11T15:12:58+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"d63e82dd-318c-4148-a6bf-e18a109ab9f8\",\n \"name\": \"xapi_300mb_incompressible.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/2021-08/xapi_300mb_incompressible.zip\",\n \"mimetype\": \"application/zip\"\n },\n \"tags\": [],\n \"topic\": {\n \"id\": \"2c22f3e4-e44c-4e36-8956-d3ae6b1a9ac8\",\n \"vid\": 104,\n \"tid\": 104,\n \"url\": \"/taxonomy/term/104\",\n \"name\": \"e-learning\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": null\n },\n \"description\": \"This xAPI content is 300 megabytes before and after unzipping.\",\n \"image\": {\n \"UUID\": \"6ce9e52d-257f-4a92-9005-afd3bcdab632\",\n \"filename\": \"photofunia-1628607670.jpg\",\n \"url\": \"https://perls.localhost:8000/sites/default/files/styles/large/public/2021-08/photofunia-1628607670.jpg?itok=tmcAPAxY\",\n \"original_url\": \"https://perls.localhost:8000/sites/default/files/2021-08/photofunia-1628607670.jpg\"\n }\n },\n {\n \"id\": \"a46bc804-7000-4785-a822-e6f156be8ef0\",\n \"nid\": 987,\n \"vid\": 2657,\n \"url\": \"https://perls.localhost:8000/system/files/2021-08/xapi_100mb_incompressible/index.html?endpoint=https%3A//perls.localhost:8000/lrs/&auth=none&actor=%7B%22objectType%22%3A%22Agent%22%2C%22name%22%3A%22John%20Doe%22%2C%22account%22%3A%7B%22name%22%3A%222455a7ba-4935-4a0c-a34b-67b595915a37%22%2C%22homePage%22%3A%22https%3A%5C/%5C/perls.localhost:8000%22%7D%7D&activity_id=https%3A//perls.localhost:8000/node/987&activity_platform=PERLS\",\n \"name\": \"xAPI 100MB\",\n \"type\": \"learn_package\",\n \"changed\": \"2021-08-11T15:11:19+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"31e9e91f-43ad-4109-9ad3-4550d362a4a7\",\n \"name\": \"xapi_100mb_incompressible.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/2021-08/xapi_100mb_incompressible.zip\",\n \"mimetype\": \"application/zip\"\n },\n \"tags\": [],\n \"topic\": {\n \"id\": \"2c22f3e4-e44c-4e36-8956-d3ae6b1a9ac8\",\n \"vid\": 104,\n \"tid\": 104,\n \"url\": \"/taxonomy/term/104\",\n \"name\": \"e-learning\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": null\n },\n \"description\": \"This xAPI content is 100 megabytes before and after unzipping.\",\n \"image\": {\n \"UUID\": \"d029031c-6bfa-45d0-b8f2-cc329112328d\",\n \"filename\": \"photofunia-1628607792.jpg\",\n \"url\": \"https://perls.localhost:8000/sites/default/files/styles/large/public/2021-08/photofunia-1628607792.jpg?itok=Axt__rLK\",\n \"original_url\": \"https://perls.localhost:8000/sites/default/files/2021-08/photofunia-1628607792.jpg\"\n }\n },\n {\n \"id\": \"d013a6ec-659c-4a01-8ed6-5956f8bf9262\",\n \"nid\": 982,\n \"vid\": 2643,\n \"url\": \"/node/982\",\n \"name\": \"Testarticle3601\",\n \"type\": \"learn_article\",\n \"changed\": \"2021-08-10T00:01:48+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"0afd006a-1e8d-480e-a6d6-f1d0a662d903\",\n \"name\": \"node_982.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/offline_page/node_982.zip\"\n },\n \"tags\": [],\n \"topic\": {\n \"id\": \"4a16bc04-dca6-4ed9-9a07-af2e138ca6c0\",\n \"vid\": 213,\n \"tid\": 213,\n \"url\": \"/taxonomy/term/213\",\n \"name\": \"Content Test Suite [CTS]\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"Create a content test suite course on the dev server with example content\"\n },\n \"description\": \"Testarticle3601\",\n \"image\": null,\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"486ffbc9-ad10-4358-a625-708100133d12\",\n \"nid\": 967,\n \"vid\": 2582,\n \"url\": \"/node/967\",\n \"name\": \"NEW CONTENT TO DRAFT STATUS\",\n \"type\": \"learn_article\",\n \"changed\": \"2021-07-30T15:29:36+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"da97e569-d5b7-4e2c-8703-c6d4975cfd68\",\n \"name\": \"node_967.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/offline_page/node_967.zip\"\n },\n \"tags\": [\n {\n \"id\": \"54db0a3d-4696-4061-bbb6-e8cc905145b5\",\n \"vid\": 215,\n \"tid\": 215,\n \"url\": \"/taxonomy/term/215\",\n \"name\": \"Content Test Suite\",\n \"type\": \"tags\",\n \"changed\": \"2021-04-01T15:54:53+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"2c22f3e4-e44c-4e36-8956-d3ae6b1a9ac8\",\n \"vid\": 104,\n \"tid\": 104,\n \"url\": \"/taxonomy/term/104\",\n \"name\": \"e-learning\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": null\n },\n \"description\": \"NEW CONTENT TO DRAFT STATUS\",\n \"image\": null,\n \"discussion_status\": \"hidden\"\n }\n]" + } + ] + }, + { + "name": "Trending", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/trending", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "trending" + ] + }, + "description": "List of content (learning objects, tips, quizzes, and flash cards) that is currently popular" + }, + "response": [ + { + "name": "Trending", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/trending", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "trending" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Date", + "value": "Wed, 01 Sep 2021 20:47:20 GMT" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Transfer-Encoding", + "value": "chunked" + }, + { + "key": "Connection", + "value": "keep-alive" + }, + { + "key": "Set-Cookie", + "value": "AWSALB=caikMsNsCZ0ekYuvk403TSwYeuHdpxOPuQaGDKRYT3NoQ3xIl/KlFwbg0kekiATEbkBPW9OydV2LAKFZKJZwkwH0xEIThqYFXUj+CeYtFpOxeuN7bext0AYyjqEy; Expires=Wed, 08 Sep 2021 20:47:19 GMT; Path=/" + }, + { + "key": "Set-Cookie", + "value": "AWSALBCORS=caikMsNsCZ0ekYuvk403TSwYeuHdpxOPuQaGDKRYT3NoQ3xIl/KlFwbg0kekiATEbkBPW9OydV2LAKFZKJZwkwH0xEIThqYFXUj+CeYtFpOxeuN7bext0AYyjqEy; Expires=Wed, 08 Sep 2021 20:47:19 GMT; Path=/; SameSite=None; Secure" + }, + { + "key": "Server", + "value": "Apache" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "Cache-Control", + "value": "must-revalidate, no-cache, private" + }, + { + "key": "X-Drupal-Dynamic-Cache", + "value": "MISS" + }, + { + "key": "X-UA-Compatible", + "value": "IE=edge" + }, + { + "key": "Content-language", + "value": "en" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "Permissions-Policy", + "value": "interest-cohort=()" + }, + { + "key": "Expires", + "value": "Sun, 19 Nov 1978 05:00:00 GMT" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubdomains; preload" + }, + { + "key": "X-XSS-Protection", + "value": "1; mode=block" + } + ], + "cookie": [], + "body": "[\n {\n \"id\": \"3f52b16b-f05a-440e-9df3-4feedc7b5aed\",\n \"nid\": 1036,\n \"vid\": 2766,\n \"url\": \"/node/1036\",\n \"name\": \"CBTarticle-4487\",\n \"type\": \"learn_article\",\n \"changed\": \"2021-09-01T17:05:06+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"3ec56113-d13f-404f-8472-6ad1d97ff851\",\n \"name\": \"node_1036.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/offline_page/node_1036.zip\"\n },\n \"tags\": [],\n \"topic\": {\n \"id\": \"f8e352ee-1e06-4180-b5f2-3862827b7c24\",\n \"vid\": 285,\n \"tid\": 285,\n \"url\": \"/taxonomy/term/285\",\n \"name\": \"CBTtopic\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"CBTtopic\"\n },\n \"description\": null,\n \"image\": {\n \"UUID\": \"100e5902-51c6-443a-b578-87f27caf22a2\",\n \"filename\": \"image.jpg\",\n \"url\": \"https://perls.localhost:8000/sites/default/files/styles/large/public/2021-08/image.jpg?itok=j0xATO8o\",\n \"original_url\": \"https://perls.localhost:8000/sites/default/files/2021-08/image.jpg\"\n },\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"2e0ab36c-3f81-4927-a101-9399727993db\",\n \"nid\": 1033,\n \"vid\": 2759,\n \"url\": \"/node/1033\",\n \"name\": \"Testdocument-4487\",\n \"type\": \"learn_file\",\n \"changed\": \"2021-09-01T16:46:15+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"ed895493-2811-4aaa-8295-af47c73c9005\",\n \"name\": \"article_0.pdf\",\n \"url\": \"https://perls.localhost:8000/system/files/2021-08/article_0.pdf\",\n \"mimetype\": \"application/pdf\"\n },\n \"tags\": [],\n \"topic\": {\n \"id\": \"f8e352ee-1e06-4180-b5f2-3862827b7c24\",\n \"vid\": 285,\n \"tid\": 285,\n \"url\": \"/taxonomy/term/285\",\n \"name\": \"CBTtopic\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"CBTtopic\"\n },\n \"description\": null,\n \"image\": null\n },\n {\n \"id\": \"62caab85-f05e-440d-863e-ba28d0c7d506\",\n \"nid\": 1037,\n \"vid\": 2767,\n \"url\": \"/node/1037\",\n \"name\": \"VE-1\",\n \"type\": \"event\",\n \"changed\": \"2021-09-01T19:02:25+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": []\n },\n {\n \"id\": \"ad05339c-6fd9-4e2f-a13b-4bdd305009cf\",\n \"nid\": 1034,\n \"vid\": 2754,\n \"url\": \"/node/1034\",\n \"name\": \"Testdocument-4487 - Cloned\",\n \"type\": \"learn_file\",\n \"changed\": \"2021-08-31T19:38:00+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"ed895493-2811-4aaa-8295-af47c73c9005\",\n \"name\": \"article_0.pdf\",\n \"url\": \"https://perls.localhost:8000/system/files/2021-08/article_0.pdf\",\n \"mimetype\": \"application/pdf\"\n },\n \"tags\": [],\n \"topic\": {\n \"id\": \"f8e352ee-1e06-4180-b5f2-3862827b7c24\",\n \"vid\": 285,\n \"tid\": 285,\n \"url\": \"/taxonomy/term/285\",\n \"name\": \"CBTtopic\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"CBTtopic\"\n },\n \"description\": null,\n \"image\": null\n },\n {\n \"id\": \"5a81c15d-9793-47f3-a572-920d1bfba6d7\",\n \"nid\": 1056,\n \"vid\": 2787,\n \"url\": \"/node/1056\",\n \"name\": \"VE-1 - Cloned\",\n \"type\": \"event\",\n \"changed\": \"2021-09-01T20:46:50+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": []\n },\n {\n \"id\": \"a4cf285d-e8da-4d3d-bb5f-a2d9198d1d1c\",\n \"nid\": 1021,\n \"vid\": 2734,\n \"url\": \"/node/1021\",\n \"name\": \"Sprint 17 Demo Meeting\",\n \"type\": \"event\",\n \"changed\": \"2021-08-27T05:22:42+0000\",\n \"is_promoted\": true,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": [\n {\n \"id\": \"7567d087-b32d-4959-8c43-ec9e66f1b7f8\",\n \"vid\": 105,\n \"tid\": 105,\n \"url\": \"/taxonomy/term/105\",\n \"name\": \"test\",\n \"type\": \"tags\",\n \"changed\": \"2020-06-11T20:09:40+0000\"\n }\n ]\n },\n {\n \"id\": \"2d944b81-6c6b-49bb-9686-834fff9d88a3\",\n \"nid\": 1035,\n \"vid\": 2755,\n \"url\": \"/node/1035\",\n \"name\": \"Testdocument-4487 - Cloned\",\n \"type\": \"learn_file\",\n \"changed\": \"2021-08-31T19:56:16+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"ed895493-2811-4aaa-8295-af47c73c9005\",\n \"name\": \"article_0.pdf\",\n \"url\": \"https://perls.localhost:8000/system/files/2021-08/article_0.pdf\",\n \"mimetype\": \"application/pdf\"\n },\n \"tags\": [],\n \"topic\": {\n \"id\": \"f8e352ee-1e06-4180-b5f2-3862827b7c24\",\n \"vid\": 285,\n \"tid\": 285,\n \"url\": \"/taxonomy/term/285\",\n \"name\": \"CBTtopic\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"CBTtopic\"\n },\n \"description\": null,\n \"image\": null\n },\n {\n \"id\": \"18397e31-19bf-4b81-9de0-7d90b3af4a6d\",\n \"nid\": 310,\n \"vid\": 1531,\n \"url\": \"/node/310\",\n \"name\": \"test\",\n \"type\": \"learn_article\",\n \"changed\": \"2021-04-22T03:15:37+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"7788d80a-0267-4d8a-9be9-baadee3472c9\",\n \"name\": \"node_310.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/offline_page/node_310.zip\"\n },\n \"tags\": [\n {\n \"id\": \"c3c293a8-acb2-4e52-bb4c-7bf45be16495\",\n \"vid\": 109,\n \"tid\": 109,\n \"url\": \"/taxonomy/term/109\",\n \"name\": \"chicken\",\n \"type\": \"tags\",\n \"changed\": \"2020-06-12T18:26:53+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"33adf0fd-782f-4146-873d-22b375a929fb\",\n \"vid\": 110,\n \"tid\": 110,\n \"url\": \"/taxonomy/term/110\",\n \"name\": \"Digital literacy\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": null\n },\n \"description\": \"optionally\",\n \"image\": {\n \"UUID\": \"d2b9620e-90bb-44ed-9db6-409b3c46ef8d\",\n \"filename\": \"city-sunny-people-street.jpg\",\n \"url\": \"https://perls.localhost:8000/sites/default/files/styles/large/public/2020-10/city-sunny-people-street.jpg?itok=yFsHjZLG\",\n \"original_url\": \"https://perls.localhost:8000/sites/default/files/2020-10/city-sunny-people-street.jpg\"\n },\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"1843e33e-230f-4d84-9ba2-a937e1fe27c6\",\n \"nid\": 923,\n \"vid\": 2402,\n \"url\": \"/node/923\",\n \"name\": \"TEST\",\n \"type\": \"learn_article\",\n \"changed\": \"2021-07-09T12:26:43+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"94b8b917-098d-4cdf-a8f7-4d22fb3a37a6\",\n \"name\": \"node_923.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/offline_page/node_923.zip\"\n },\n \"tags\": [],\n \"topic\": {\n \"id\": \"40b8344e-f144-4be5-bc57-4322c24ed8c7\",\n \"vid\": 268,\n \"tid\": 268,\n \"url\": \"/taxonomy/term/268\",\n \"name\": \"NEW TOPIC\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"TEST\"\n },\n \"description\": \"TEST\",\n \"image\": null,\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"d2d3e087-14d7-4971-931d-32998551aba6\",\n \"nid\": 447,\n \"vid\": 1539,\n \"url\": \"/node/447\",\n \"name\": \"THIS IS A LENGTH CONTENT\",\n \"type\": \"learn_article\",\n \"changed\": \"2021-04-22T03:15:37+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"2e2d54a0-319d-4435-9702-af46729b3b74\",\n \"name\": \"node_447.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/offline_page/node_447.zip\"\n },\n \"tags\": [\n {\n \"id\": \"cbee504a-f709-4ca4-87c6-fbef7cf50110\",\n \"vid\": 124,\n \"tid\": 124,\n \"url\": \"/taxonomy/term/124\",\n \"name\": \"army\",\n \"type\": \"tags\",\n \"changed\": \"2020-08-27T19:17:36+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"fb473dd7-86a8-40a6-8a12-c9c80d46c2fb\",\n \"vid\": 80,\n \"tid\": 80,\n \"url\": \"/taxonomy/term/80\",\n \"name\": \"Occupational Safety and Health\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"This topic includes content related to the safety, health, and welfare of people at work The goal of occupational safety and health programs is to foster a safe and healthy work environment.[3] OSH may also protect co-workers, family members, employers, customers, and many others who might be affected by the workplace environment. \"\n },\n \"description\": \"An army (from Latin arma \\\"arms, weapons\\\" via Old French armée, \\\"armed\\\" [feminine]), ground \\r\\nAn army (from Latin arma \\\"arms, weapons\\\" via Old French armée, \\\"armed\\\" [feminine]), ground \\r\\nAn army (from Latin arma \\\"arms, weapons\\\" via Old French armée, \\\"armed\\\" [feminine]), ground \",\n \"image\": {\n \"UUID\": \"37a3a4d1-f0ef-4091-8a4b-2cf064ca2263\",\n \"filename\": \"mask.jpg\",\n \"url\": \"https://perls.localhost:8000/sites/default/files/styles/large/public/2021-02/mask.jpg?itok=6OicZPzh\",\n \"original_url\": \"https://perls.localhost:8000/sites/default/files/2021-02/mask.jpg\"\n },\n \"discussion_status\": \"open\"\n },\n {\n \"id\": \"6089dcfd-332e-4bd7-aa95-e014efa07247\",\n \"nid\": 587,\n \"vid\": 2530,\n \"url\": \"/node/587\",\n \"name\": \"John Doe content\",\n \"type\": \"learn_article\",\n \"changed\": \"2021-04-27T17:23:39+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"4afcb227-bc4d-4d80-9c84-db29498c5f2d\",\n \"name\": \"node_587.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/offline_page/node_587.zip\"\n },\n \"tags\": [\n {\n \"id\": \"7567d087-b32d-4959-8c43-ec9e66f1b7f8\",\n \"vid\": 105,\n \"tid\": 105,\n \"url\": \"/taxonomy/term/105\",\n \"name\": \"test\",\n \"type\": \"tags\",\n \"changed\": \"2020-06-11T20:09:40+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"fb473dd7-86a8-40a6-8a12-c9c80d46c2fb\",\n \"vid\": 80,\n \"tid\": 80,\n \"url\": \"/taxonomy/term/80\",\n \"name\": \"Occupational Safety and Health\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"This topic includes content related to the safety, health, and welfare of people at work The goal of occupational safety and health programs is to foster a safe and healthy work environment.[3] OSH may also protect co-workers, family members, employers, customers, and many others who might be affected by the workplace environment. \"\n },\n \"description\": \"An article allows you to build and publish content directly to learners. Try focusing your articles to a single learning objective. You can create many articles under the same topic or course to provide your learners a comprehensive set of content.\\r\\n\\r\\nyou an add more contents. \",\n \"image\": null,\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"5b842811-587f-489a-a1f0-096756cc5c09\",\n \"nid\": 596,\n \"vid\": 2531,\n \"url\": \"/node/596\",\n \"name\": \"Move this to a private group\",\n \"type\": \"learn_article\",\n \"changed\": \"2021-03-25T15:41:43+0000\",\n \"is_promoted\": true,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"142012b4-b193-46b4-9179-91128e50bf64\",\n \"name\": \"node_596.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/offline_page/node_596.zip\"\n },\n \"tags\": [\n {\n \"id\": \"7567d087-b32d-4959-8c43-ec9e66f1b7f8\",\n \"vid\": 105,\n \"tid\": 105,\n \"url\": \"/taxonomy/term/105\",\n \"name\": \"test\",\n \"type\": \"tags\",\n \"changed\": \"2020-06-11T20:09:40+0000\"\n }\n ],\n \"topic\": null,\n \"description\": \"Move this to a private group\",\n \"image\": null,\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"54b86809-6411-47de-94c4-96d3220e4736\",\n \"nid\": 961,\n \"vid\": 2585,\n \"url\": \"/node/961\",\n \"name\": \"new article by user\",\n \"type\": \"learn_article\",\n \"changed\": \"2021-07-30T15:29:36+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"960e7280-233c-4057-bcd6-6a73c20b342c\",\n \"name\": \"node_961.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/offline_page/node_961.zip\"\n },\n \"tags\": [\n {\n \"id\": \"54db0a3d-4696-4061-bbb6-e8cc905145b5\",\n \"vid\": 215,\n \"tid\": 215,\n \"url\": \"/taxonomy/term/215\",\n \"name\": \"Content Test Suite\",\n \"type\": \"tags\",\n \"changed\": \"2021-04-01T15:54:53+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"54e0ff01-851c-4e7a-9c89-21aa6496c1a9\",\n \"vid\": 246,\n \"tid\": 246,\n \"url\": \"/taxonomy/term/246\",\n \"name\": \"new topic 3\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"new topic 3\"\n },\n \"description\": \"new article by user\",\n \"image\": null,\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"4ac4cc1c-62a3-4098-be5b-4884116fac0d\",\n \"nid\": 962,\n \"vid\": 2565,\n \"url\": \"/node/962\",\n \"name\": \"new article by user - Cloned\",\n \"type\": \"learn_article\",\n \"changed\": \"2021-07-30T13:48:33+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"2911ca81-9866-435f-b55b-e4a61eed94ce\",\n \"name\": \"node_962.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/offline_page/node_962.zip\"\n },\n \"tags\": [\n {\n \"id\": \"54db0a3d-4696-4061-bbb6-e8cc905145b5\",\n \"vid\": 215,\n \"tid\": 215,\n \"url\": \"/taxonomy/term/215\",\n \"name\": \"Content Test Suite\",\n \"type\": \"tags\",\n \"changed\": \"2021-04-01T15:54:53+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"54e0ff01-851c-4e7a-9c89-21aa6496c1a9\",\n \"vid\": 246,\n \"tid\": 246,\n \"url\": \"/taxonomy/term/246\",\n \"name\": \"new topic 3\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"new topic 3\"\n },\n \"description\": \"new article by user\",\n \"image\": null,\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"ed159532-272c-4311-876c-efe23e6b08a6\",\n \"nid\": 748,\n \"vid\": 1775,\n \"url\": \"/node/748\",\n \"name\": \"New user created Learning article\",\n \"type\": \"learn_article\",\n \"changed\": \"2021-04-27T15:41:35+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"94e698fb-2548-4120-bda4-1b4457d24bf4\",\n \"name\": \"node_748.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/offline_page/node_748.zip\"\n },\n \"tags\": [\n {\n \"id\": \"54db0a3d-4696-4061-bbb6-e8cc905145b5\",\n \"vid\": 215,\n \"tid\": 215,\n \"url\": \"/taxonomy/term/215\",\n \"name\": \"Content Test Suite\",\n \"type\": \"tags\",\n \"changed\": \"2021-04-01T15:54:53+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"353674e0-3235-43e6-9b57-beb7e7bbf8c8\",\n \"vid\": 247,\n \"tid\": 247,\n \"url\": \"/taxonomy/term/247\",\n \"name\": \"over30topic\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"over30topic\"\n },\n \"description\": \"New user created Learning article\",\n \"image\": null,\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"7070f63b-4815-4455-94c9-b704c7840fb2\",\n \"nid\": 963,\n \"vid\": 2584,\n \"url\": \"/node/963\",\n \"name\": \"new article by user - Cloned\",\n \"type\": \"learn_article\",\n \"changed\": \"2021-07-30T15:29:36+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"82d934d1-29bd-4c23-b1e8-56d4be6b2707\",\n \"name\": \"node_963.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/offline_page/node_963.zip\"\n },\n \"tags\": [\n {\n \"id\": \"54db0a3d-4696-4061-bbb6-e8cc905145b5\",\n \"vid\": 215,\n \"tid\": 215,\n \"url\": \"/taxonomy/term/215\",\n \"name\": \"Content Test Suite\",\n \"type\": \"tags\",\n \"changed\": \"2021-04-01T15:54:53+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"54e0ff01-851c-4e7a-9c89-21aa6496c1a9\",\n \"vid\": 246,\n \"tid\": 246,\n \"url\": \"/taxonomy/term/246\",\n \"name\": \"new topic 3\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"new topic 3\"\n },\n \"description\": \"new article by user\",\n \"image\": null,\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"0fcfe5de-414d-4019-8c33-fc79aa5e2a12\",\n \"nid\": 749,\n \"vid\": 2158,\n \"url\": \"/node/749\",\n \"name\": \"This is a test article from user\",\n \"type\": \"learn_article\",\n \"changed\": \"2021-05-31T10:01:45+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"972af238-3b7f-4626-806c-045d0a07a8ca\",\n \"name\": \"node_749.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/offline_page/node_749.zip\"\n },\n \"tags\": [\n {\n \"id\": \"54db0a3d-4696-4061-bbb6-e8cc905145b5\",\n \"vid\": 215,\n \"tid\": 215,\n \"url\": \"/taxonomy/term/215\",\n \"name\": \"Content Test Suite\",\n \"type\": \"tags\",\n \"changed\": \"2021-04-01T15:54:53+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"b73ca034-aca7-4b2b-8875-e089a87f9e89\",\n \"vid\": 150,\n \"tid\": 150,\n \"url\": \"/taxonomy/term/150\",\n \"name\": \"lesson about the Apache - Cloned\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"oriign apache\\r\\n\"\n },\n \"description\": \"This is a test article from user\",\n \"image\": null,\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"32fd10c0-368b-4cbb-9e28-798c4e734766\",\n \"nid\": 879,\n \"vid\": 2182,\n \"url\": \"/node/879\",\n \"name\": \"Test article 1\",\n \"type\": \"learn_article\",\n \"changed\": \"2021-05-31T10:02:55+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"144b48f7-83e5-472c-97e2-585cc4dbbac4\",\n \"name\": \"node_879.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/offline_page/node_879.zip\"\n },\n \"tags\": [],\n \"topic\": {\n \"id\": \"4a16bc04-dca6-4ed9-9a07-af2e138ca6c0\",\n \"vid\": 213,\n \"tid\": 213,\n \"url\": \"/taxonomy/term/213\",\n \"name\": \"Content Test Suite [CTS]\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"Create a content test suite course on the dev server with example content\"\n },\n \"description\": null,\n \"image\": null,\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"486ffbc9-ad10-4358-a625-708100133d12\",\n \"nid\": 967,\n \"vid\": 2582,\n \"url\": \"/node/967\",\n \"name\": \"NEW CONTENT TO DRAFT STATUS\",\n \"type\": \"learn_article\",\n \"changed\": \"2021-07-30T15:29:36+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"da97e569-d5b7-4e2c-8703-c6d4975cfd68\",\n \"name\": \"node_967.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/offline_page/node_967.zip\"\n },\n \"tags\": [\n {\n \"id\": \"54db0a3d-4696-4061-bbb6-e8cc905145b5\",\n \"vid\": 215,\n \"tid\": 215,\n \"url\": \"/taxonomy/term/215\",\n \"name\": \"Content Test Suite\",\n \"type\": \"tags\",\n \"changed\": \"2021-04-01T15:54:53+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"2c22f3e4-e44c-4e36-8956-d3ae6b1a9ac8\",\n \"vid\": 104,\n \"tid\": 104,\n \"url\": \"/taxonomy/term/104\",\n \"name\": \"e-learning\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": null\n },\n \"description\": \"NEW CONTENT TO DRAFT STATUS\",\n \"image\": null,\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"9dbd5562-93b9-4e1c-962f-00140cc71406\",\n \"nid\": 880,\n \"vid\": 2181,\n \"url\": \"/node/880\",\n \"name\": \"Test article 2\",\n \"type\": \"learn_article\",\n \"changed\": \"2021-05-31T10:02:55+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"69b1a00a-9243-4fe4-b29a-40784461787c\",\n \"name\": \"node_880.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/offline_page/node_880.zip\"\n },\n \"tags\": [],\n \"topic\": {\n \"id\": \"94e4d235-2d88-4530-8133-66ea0ca69455\",\n \"vid\": 258,\n \"tid\": 258,\n \"url\": \"/taxonomy/term/258\",\n \"name\": \"SL-3876 Topic\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"This is a topic that can be used for testing #SL-3876.\"\n },\n \"description\": null,\n \"image\": null,\n \"discussion_status\": \"hidden\"\n }\n]" + } + ] + }, + { + "name": "Recent", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/recent", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "recent" + ] + }, + "description": "List of content (learning objects, tips, quizzes, and flash cards) that was recently updated" + }, + "response": [ + { + "name": "Recent", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/recent", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "recent" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Date", + "value": "Wed, 01 Sep 2021 20:47:28 GMT" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Content-Length", + "value": "6997" + }, + { + "key": "Connection", + "value": "keep-alive" + }, + { + "key": "Set-Cookie", + "value": "AWSALB=X3ugvvO1lPiaIBToBToYbIqQ8VX7sWAR9iAAqu3uVfhtsnPhP6X5YaMjcKVJZX20crRkC6D4y0UJ+XfomwpAzjRkn16eGwhG0N+/1/A/lH45pIGgJ2s2vzwCtreE; Expires=Wed, 08 Sep 2021 20:47:27 GMT; Path=/" + }, + { + "key": "Set-Cookie", + "value": "AWSALBCORS=X3ugvvO1lPiaIBToBToYbIqQ8VX7sWAR9iAAqu3uVfhtsnPhP6X5YaMjcKVJZX20crRkC6D4y0UJ+XfomwpAzjRkn16eGwhG0N+/1/A/lH45pIGgJ2s2vzwCtreE; Expires=Wed, 08 Sep 2021 20:47:27 GMT; Path=/; SameSite=None; Secure" + }, + { + "key": "Server", + "value": "Apache" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "Cache-Control", + "value": "must-revalidate, no-cache, private" + }, + { + "key": "X-Drupal-Dynamic-Cache", + "value": "MISS" + }, + { + "key": "X-UA-Compatible", + "value": "IE=edge" + }, + { + "key": "Content-language", + "value": "en" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "Permissions-Policy", + "value": "interest-cohort=()" + }, + { + "key": "Expires", + "value": "Sun, 19 Nov 1978 05:00:00 GMT" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubdomains; preload" + }, + { + "key": "X-XSS-Protection", + "value": "1; mode=block" + } + ], + "cookie": [], + "body": "[\n {\n \"id\": \"5a81c15d-9793-47f3-a572-920d1bfba6d7\",\n \"nid\": 1056,\n \"vid\": 2787,\n \"url\": \"/node/1056\",\n \"name\": \"VE-1 - Cloned\",\n \"type\": \"event\",\n \"changed\": \"2021-09-01T20:46:50+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": []\n },\n {\n \"id\": \"5e5675c1-623d-4c19-a3e0-33f796e7592e\",\n \"nid\": 1055,\n \"vid\": 2786,\n \"url\": \"/node/1055\",\n \"name\": \"VE-18\",\n \"type\": \"event\",\n \"changed\": \"2021-09-01T20:12:34+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": []\n },\n {\n \"id\": \"1388fbe4-7e3e-48ab-b01b-2244f8da0562\",\n \"nid\": 1054,\n \"vid\": 2785,\n \"url\": \"/node/1054\",\n \"name\": \"VE-17\",\n \"type\": \"event\",\n \"changed\": \"2021-09-01T20:11:18+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": []\n },\n {\n \"id\": \"85498e1f-55f7-456c-a754-afab640f5d8b\",\n \"nid\": 1053,\n \"vid\": 2784,\n \"url\": \"/node/1053\",\n \"name\": \"VE-16\",\n \"type\": \"event\",\n \"changed\": \"2021-09-01T20:10:20+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": []\n },\n {\n \"id\": \"24c95065-c642-4375-bf7d-820c8921ad61\",\n \"nid\": 1050,\n \"vid\": 2781,\n \"url\": \"/node/1050\",\n \"name\": \"VE-13\",\n \"type\": \"event\",\n \"changed\": \"2021-09-01T20:04:47+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": []\n },\n {\n \"id\": \"9b7c63ad-aa56-4482-80cb-bf76866e2e09\",\n \"nid\": 1049,\n \"vid\": 2780,\n \"url\": \"/node/1049\",\n \"name\": \"VE-12\",\n \"type\": \"event\",\n \"changed\": \"2021-09-01T20:03:56+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": []\n },\n {\n \"id\": \"b16d468b-70da-4510-a253-af3d81ffaed0\",\n \"nid\": 1048,\n \"vid\": 2779,\n \"url\": \"/node/1048\",\n \"name\": \"VE-12\",\n \"type\": \"event\",\n \"changed\": \"2021-09-01T20:02:23+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": []\n },\n {\n \"id\": \"ff805ae8-cfb4-44be-945d-ebe70f2bf625\",\n \"nid\": 1047,\n \"vid\": 2778,\n \"url\": \"/node/1047\",\n \"name\": \"VE-11\",\n \"type\": \"event\",\n \"changed\": \"2021-09-01T20:01:05+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": []\n },\n {\n \"id\": \"f5ee3d86-6796-4264-9703-297d0dc804ef\",\n \"nid\": 1046,\n \"vid\": 2777,\n \"url\": \"/node/1046\",\n \"name\": \"VE-10\",\n \"type\": \"event\",\n \"changed\": \"2021-09-01T19:59:52+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": []\n },\n {\n \"id\": \"620d9324-9d78-47ef-bb3c-2b12734624d2\",\n \"nid\": 1045,\n \"vid\": 2776,\n \"url\": \"/node/1045\",\n \"name\": \"VE-9\",\n \"type\": \"event\",\n \"changed\": \"2021-09-01T19:57:44+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": []\n },\n {\n \"id\": \"0ddea4b2-2e39-44fe-9cb8-03cdc99e8c7e\",\n \"nid\": 1044,\n \"vid\": 2775,\n \"url\": \"/node/1044\",\n \"name\": \"VE-8\",\n \"type\": \"event\",\n \"changed\": \"2021-09-01T19:56:03+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": []\n },\n {\n \"id\": \"908f5e8a-4564-43ca-8f42-9296f0dfce9d\",\n \"nid\": 1043,\n \"vid\": 2774,\n \"url\": \"/node/1043\",\n \"name\": \"VE-7\",\n \"type\": \"event\",\n \"changed\": \"2021-09-01T19:53:50+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": []\n },\n {\n \"id\": \"c7993ed9-3996-4537-a251-d5a9742088c7\",\n \"nid\": 1042,\n \"vid\": 2773,\n \"url\": \"/node/1042\",\n \"name\": \"VE-6\",\n \"type\": \"event\",\n \"changed\": \"2021-09-01T19:52:34+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": []\n },\n {\n \"id\": \"d0da438c-0d1d-4fd0-8b25-67d6cab1ed62\",\n \"nid\": 1041,\n \"vid\": 2772,\n \"url\": \"/node/1041\",\n \"name\": \"VE-5\",\n \"type\": \"event\",\n \"changed\": \"2021-09-01T19:51:03+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": []\n },\n {\n \"id\": \"2129b145-b7fc-4dc5-9a13-ac73452fb9c4\",\n \"nid\": 1040,\n \"vid\": 2771,\n \"url\": \"/node/1040\",\n \"name\": \"VE-4\",\n \"type\": \"event\",\n \"changed\": \"2021-09-01T19:49:40+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": []\n },\n {\n \"id\": \"62caab85-f05e-440d-863e-ba28d0c7d506\",\n \"nid\": 1037,\n \"vid\": 2767,\n \"url\": \"/node/1037\",\n \"name\": \"VE-1\",\n \"type\": \"event\",\n \"changed\": \"2021-09-01T19:02:25+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": []\n },\n {\n \"id\": \"3f52b16b-f05a-440e-9df3-4feedc7b5aed\",\n \"nid\": 1036,\n \"vid\": 2766,\n \"url\": \"/node/1036\",\n \"name\": \"CBTarticle-4487\",\n \"type\": \"learn_article\",\n \"changed\": \"2021-09-01T17:05:06+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"3ec56113-d13f-404f-8472-6ad1d97ff851\",\n \"name\": \"node_1036.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/offline_page/node_1036.zip\"\n },\n \"tags\": [],\n \"topic\": {\n \"id\": \"f8e352ee-1e06-4180-b5f2-3862827b7c24\",\n \"vid\": 285,\n \"tid\": 285,\n \"url\": \"/taxonomy/term/285\",\n \"name\": \"CBTtopic\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"CBTtopic\"\n },\n \"description\": null,\n \"image\": {\n \"UUID\": \"100e5902-51c6-443a-b578-87f27caf22a2\",\n \"filename\": \"image.jpg\",\n \"url\": \"https://perls.localhost:8000/sites/default/files/styles/large/public/2021-08/image.jpg?itok=j0xATO8o\",\n \"original_url\": \"https://perls.localhost:8000/sites/default/files/2021-08/image.jpg\"\n },\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"2e0ab36c-3f81-4927-a101-9399727993db\",\n \"nid\": 1033,\n \"vid\": 2759,\n \"url\": \"/node/1033\",\n \"name\": \"Testdocument-4487\",\n \"type\": \"learn_file\",\n \"changed\": \"2021-09-01T16:46:15+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"ed895493-2811-4aaa-8295-af47c73c9005\",\n \"name\": \"article_0.pdf\",\n \"url\": \"https://perls.localhost:8000/system/files/2021-08/article_0.pdf\",\n \"mimetype\": \"application/pdf\"\n },\n \"tags\": [],\n \"topic\": {\n \"id\": \"f8e352ee-1e06-4180-b5f2-3862827b7c24\",\n \"vid\": 285,\n \"tid\": 285,\n \"url\": \"/taxonomy/term/285\",\n \"name\": \"CBTtopic\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"CBTtopic\"\n },\n \"description\": null,\n \"image\": null\n },\n {\n \"id\": \"2d944b81-6c6b-49bb-9686-834fff9d88a3\",\n \"nid\": 1035,\n \"vid\": 2755,\n \"url\": \"/node/1035\",\n \"name\": \"Testdocument-4487 - Cloned\",\n \"type\": \"learn_file\",\n \"changed\": \"2021-08-31T19:56:16+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"ed895493-2811-4aaa-8295-af47c73c9005\",\n \"name\": \"article_0.pdf\",\n \"url\": \"https://perls.localhost:8000/system/files/2021-08/article_0.pdf\",\n \"mimetype\": \"application/pdf\"\n },\n \"tags\": [],\n \"topic\": {\n \"id\": \"f8e352ee-1e06-4180-b5f2-3862827b7c24\",\n \"vid\": 285,\n \"tid\": 285,\n \"url\": \"/taxonomy/term/285\",\n \"name\": \"CBTtopic\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"CBTtopic\"\n },\n \"description\": null,\n \"image\": null\n },\n {\n \"id\": \"ad05339c-6fd9-4e2f-a13b-4bdd305009cf\",\n \"nid\": 1034,\n \"vid\": 2754,\n \"url\": \"/node/1034\",\n \"name\": \"Testdocument-4487 - Cloned\",\n \"type\": \"learn_file\",\n \"changed\": \"2021-08-31T19:38:00+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"ed895493-2811-4aaa-8295-af47c73c9005\",\n \"name\": \"article_0.pdf\",\n \"url\": \"https://perls.localhost:8000/system/files/2021-08/article_0.pdf\",\n \"mimetype\": \"application/pdf\"\n },\n \"tags\": [],\n \"topic\": {\n \"id\": \"f8e352ee-1e06-4180-b5f2-3862827b7c24\",\n \"vid\": 285,\n \"tid\": 285,\n \"url\": \"/taxonomy/term/285\",\n \"name\": \"CBTtopic\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"CBTtopic\"\n },\n \"description\": null,\n \"image\": null\n }\n]" + } + ] + }, + { + "name": "Search", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/search?text=uc", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "search" + ], + "query": [ + { + "key": "text", + "value": "uc" + } + ] + }, + "description": "Request for search results" + }, + "response": [ + { + "name": "Search", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/search?text=uc", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "search" + ], + "query": [ + { + "key": "text", + "value": "uc" + } + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Date", + "value": "Wed, 01 Sep 2021 20:47:36 GMT" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Content-Length", + "value": "1838" + }, + { + "key": "Connection", + "value": "keep-alive" + }, + { + "key": "Set-Cookie", + "value": "AWSALB=Sqv/NESXA33IW9AJSrI2cl9Zh+d1xq/zH5E1ewPRZYjRWFDAFJfvmEPBz18lD1yhlUvzhfc/Q824vyXm9Sjul7vd+Y7k5SEaXiWQehKgnjAwElUrynNxn2cJO1wA; Expires=Wed, 08 Sep 2021 20:47:36 GMT; Path=/" + }, + { + "key": "Set-Cookie", + "value": "AWSALBCORS=Sqv/NESXA33IW9AJSrI2cl9Zh+d1xq/zH5E1ewPRZYjRWFDAFJfvmEPBz18lD1yhlUvzhfc/Q824vyXm9Sjul7vd+Y7k5SEaXiWQehKgnjAwElUrynNxn2cJO1wA; Expires=Wed, 08 Sep 2021 20:47:36 GMT; Path=/; SameSite=None; Secure" + }, + { + "key": "Server", + "value": "Apache" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "Cache-Control", + "value": "must-revalidate, no-cache, private" + }, + { + "key": "X-Drupal-Dynamic-Cache", + "value": "MISS" + }, + { + "key": "X-UA-Compatible", + "value": "IE=edge" + }, + { + "key": "Content-language", + "value": "en" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "Permissions-Policy", + "value": "interest-cohort=()" + }, + { + "key": "Expires", + "value": "Sun, 19 Nov 1978 05:00:00 GMT" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubdomains; preload" + }, + { + "key": "X-XSS-Protection", + "value": "1; mode=block" + } + ], + "cookie": [], + "body": "[\n {\n \"id\": \"5468222a-e5f1-4275-a204-d2d1b30a5569\",\n \"nid\": 377,\n \"vid\": 738,\n \"url\": \"/node/377\",\n \"name\": \"A CLINICAL REVIEW OF MOBILE LEARNING INTEGRATION IN FORMAL EDUCATIONAL CONTEXTS\",\n \"type\": \"course\",\n \"changed\": \"2020-12-14T15:20:04+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": [\n {\n \"id\": \"b74951dc-27a6-4df8-9d03-83ee8cea920f\",\n \"vid\": 107,\n \"tid\": 107,\n \"url\": \"/taxonomy/term/107\",\n \"name\": \"CreatenewTags\",\n \"type\": \"tags\",\n \"changed\": \"2020-06-11T20:11:55+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"c83bf669-87e5-42c1-979a-7c132231759c\",\n \"vid\": 89,\n \"tid\": 89,\n \"url\": \"/taxonomy/term/89\",\n \"name\": \"mLearning\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"Content related to Mobile Learning principles, methods, design, development, and use.\"\n },\n \"description\": \"n army (from Latin arma \\\"arms, weapons\\\" via Old French armée, \\\"armed\\\" [feminine]), ground force or land force is a fighting force that fights primarily on land. In the broadest sense, it is the land-based military branch, service branch or armed service of a nation or state. It may also include aviation assets by possessing an army aviation component. Within a national military force, the word army may also mean a field army.\\r\\nn army (from Latin arma \\\"arms, weapons\\\" via Old French armée\",\n \"learning_objects\": [\n {\n \"id\": \"79d5e384-7800-4eba-aa54-2013be65db2e\",\n \"nid\": 375,\n \"vid\": 732,\n \"url\": \"/node/375\",\n \"name\": \"John Doe Test Episode 2\",\n \"type\": \"podcast_episode\",\n \"changed\": \"2020-12-11T20:34:19+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"a490f888-82ef-46d5-8739-0feabc749241\",\n \"name\": \"file_example_mp3_1mg_4.mp3\",\n \"url\": \"https://perls.localhost:8000/sites/default/files/podcasts/2020-12/file_example_mp3_1mg_4.mp3\",\n \"mimetype\": \"audio/mpeg\"\n },\n \"tags\": [],\n \"description\": null,\n \"duration\": 27,\n \"release_date\": \"2020-12-11\"\n }\n ],\n \"image\": null\n }\n]" + } + ] + }, + { + "name": "Browse", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/browse", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "browse" + ] + }, + "description": "Get relevant content for the current user" + }, + "response": [ + { + "name": "Browse", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/browse", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "browse" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Date", + "value": "Wed, 01 Sep 2021 20:47:50 GMT" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Transfer-Encoding", + "value": "chunked" + }, + { + "key": "Connection", + "value": "keep-alive" + }, + { + "key": "Set-Cookie", + "value": "AWSALB=qr5JUP85TWj6QcmYZskl2PLMV9owvphsi5af8SX6PBOBgnTN+G6huZYiVzq5MjFC+OObVjA2XEnjLW84AAMk75zEIrYjIPVVaeSPmFJIaWkpIqUDEZ287g2J8fqY; Expires=Wed, 08 Sep 2021 20:47:49 GMT; Path=/" + }, + { + "key": "Set-Cookie", + "value": "AWSALBCORS=qr5JUP85TWj6QcmYZskl2PLMV9owvphsi5af8SX6PBOBgnTN+G6huZYiVzq5MjFC+OObVjA2XEnjLW84AAMk75zEIrYjIPVVaeSPmFJIaWkpIqUDEZ287g2J8fqY; Expires=Wed, 08 Sep 2021 20:47:49 GMT; Path=/; SameSite=None; Secure" + }, + { + "key": "Server", + "value": "Apache" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "Cache-Control", + "value": "must-revalidate, no-cache, private" + }, + { + "key": "X-Drupal-Dynamic-Cache", + "value": "MISS" + }, + { + "key": "X-UA-Compatible", + "value": "IE=edge" + }, + { + "key": "Content-language", + "value": "en" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "Permissions-Policy", + "value": "interest-cohort=()" + }, + { + "key": "Expires", + "value": "Sun, 19 Nov 1978 05:00:00 GMT" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubdomains; preload" + }, + { + "key": "X-XSS-Protection", + "value": "1; mode=block" + } + ], + "cookie": [], + "body": "[\n {\n \"name\": \"Digital literacy\",\n \"url\": \"/api/taxonomy/term/110\",\n \"content\": [\n {\n \"id\": \"6087bdf0-b2ea-423c-9641-97a8d1f4faaa\",\n \"nid\": 1011,\n \"vid\": 2706,\n \"url\": \"/node/1011\",\n \"name\": \"Digital_Literacy_Document\",\n \"type\": \"learn_file\",\n \"changed\": \"2021-08-24T19:37:40+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"d3916cb9-5a08-43bf-aa39-a7e84511ff3f\",\n \"name\": \"test_docx.docx\",\n \"url\": \"https://perls.localhost:8000/system/files/2021-08/test_docx.docx\",\n \"mimetype\": \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\"\n },\n \"tags\": [],\n \"topic\": {\n \"id\": \"33adf0fd-782f-4146-873d-22b375a929fb\",\n \"vid\": 110,\n \"tid\": 110,\n \"url\": \"/taxonomy/term/110\",\n \"name\": \"Digital literacy\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": null\n },\n \"description\": null,\n \"image\": {\n \"UUID\": \"e0ac0fb7-8744-4691-9a0d-289e38555037\",\n \"filename\": \"photofunia-1628607749.jpg\",\n \"url\": \"https://perls.localhost:8000/sites/default/files/styles/large/public/2021-08/photofunia-1628607749.jpg?itok=tuXW2J0I\",\n \"original_url\": \"https://perls.localhost:8000/sites/default/files/2021-08/photofunia-1628607749.jpg\"\n }\n },\n {\n \"id\": \"c9470d5b-f8a4-433c-bbca-74546d512699\",\n \"nid\": 1010,\n \"vid\": 2705,\n \"url\": \"/node/1010\",\n \"name\": \"Digital Literacy doc I\",\n \"type\": \"learn_file\",\n \"changed\": \"2021-08-23T19:30:31+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"abe71f6a-515d-4dca-9301-042a280d5a9e\",\n \"name\": \"test_doc.doc\",\n \"url\": \"https://perls.localhost:8000/system/files/2021-08/test_doc.doc\",\n \"mimetype\": \"application/msword\"\n },\n \"tags\": [],\n \"topic\": {\n \"id\": \"33adf0fd-782f-4146-873d-22b375a929fb\",\n \"vid\": 110,\n \"tid\": 110,\n \"url\": \"/taxonomy/term/110\",\n \"name\": \"Digital literacy\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": null\n },\n \"description\": null,\n \"image\": {\n \"UUID\": \"08c4db3c-e3a6-49f7-b423-4782f3eb502e\",\n \"filename\": \"nasa-q1p7bh3shj8-unsplash_0.jpg\",\n \"url\": \"https://perls.localhost:8000/sites/default/files/styles/large/public/2021-03/nasa-q1p7bh3shj8-unsplash_0.jpg?itok=9GAVDBrq\",\n \"original_url\": \"https://perls.localhost:8000/sites/default/files/2021-03/nasa-q1p7bh3shj8-unsplash_0.jpg\"\n }\n },\n {\n \"id\": \"8879cca7-df36-454c-b174-23bccb0cb41d\",\n \"nid\": 940,\n \"vid\": 2511,\n \"url\": \"/node/940\",\n \"name\": \"Secure localhost link\",\n \"type\": \"learn_link\",\n \"changed\": \"2021-07-21T21:12:48+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": [],\n \"topic\": {\n \"id\": \"33adf0fd-782f-4146-873d-22b375a929fb\",\n \"vid\": 110,\n \"tid\": 110,\n \"url\": \"/taxonomy/term/110\",\n \"name\": \"Digital literacy\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": null\n },\n \"description\": \"URL: https://127.0.0.1:54321\",\n \"image\": null\n },\n {\n \"id\": \"63191326-fbb5-461e-ac46-cd18be0a324c\",\n \"nid\": 939,\n \"vid\": 2510,\n \"url\": \"/node/939\",\n \"name\": \"Insecure localhost link\",\n \"type\": \"learn_link\",\n \"changed\": \"2021-07-21T21:11:48+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": [],\n \"topic\": {\n \"id\": \"33adf0fd-782f-4146-873d-22b375a929fb\",\n \"vid\": 110,\n \"tid\": 110,\n \"url\": \"/taxonomy/term/110\",\n \"name\": \"Digital literacy\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": null\n },\n \"description\": \"URL: http://127.0.0.1:54321\",\n \"image\": null\n },\n {\n \"id\": \"95385a39-cf5b-4fda-b4ed-437319124e35\",\n \"nid\": 924,\n \"vid\": 2406,\n \"url\": \"/node/924\",\n \"name\": \"Test\",\n \"type\": \"learn_article\",\n \"changed\": \"2021-07-13T00:32:07+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": [],\n \"topic\": {\n \"id\": \"33adf0fd-782f-4146-873d-22b375a929fb\",\n \"vid\": 110,\n \"tid\": 110,\n \"url\": \"/taxonomy/term/110\",\n \"name\": \"Digital literacy\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": null\n },\n \"description\": null,\n \"image\": null,\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"2e6e3b31-c1b6-4cea-b9a5-cd73c610eee2\",\n \"nid\": 699,\n \"vid\": 2371,\n \"url\": \"/node/699\",\n \"name\": \"Weblink - TEST THE SHARE BUTTON\",\n \"type\": \"learn_link\",\n \"changed\": \"2021-07-08T23:24:56+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": [\n {\n \"id\": \"54db0a3d-4696-4061-bbb6-e8cc905145b5\",\n \"vid\": 215,\n \"tid\": 215,\n \"url\": \"/taxonomy/term/215\",\n \"name\": \"Content Test Suite\",\n \"type\": \"tags\",\n \"changed\": \"2021-04-01T15:54:53+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"33adf0fd-782f-4146-873d-22b375a929fb\",\n \"vid\": 110,\n \"tid\": 110,\n \"url\": \"/taxonomy/term/110\",\n \"name\": \"Digital literacy\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": null\n },\n \"description\": \"Use a web link to direct your learners to content published elsewhere on the web. You can use a course to combine web links with articles to guide your learners to relevant information they need.\\r\\n\\r\\n\\r\\nUse a web link to direct your learners to content published elsewhere on the web. You can use a course to combine web links with articles to guide your learners to relevant information they need.\\r\\n\\r\\n\\r\\nUse a web link to direct your learners to content published elsewhere on the web. You can use a course to combine web links with articles to guide your learners to relevant information they need.\\r\\n\\r\\n\",\n \"image\": {\n \"UUID\": \"b5561bb4-c80a-45aa-be03-537c3fa423ff\",\n \"filename\": \"target.jpg\",\n \"url\": \"https://perls.localhost:8000/sites/default/files/styles/large/public/2021-04/target.jpg?itok=3013FnrV\",\n \"original_url\": \"https://perls.localhost:8000/sites/default/files/2021-04/target.jpg\"\n }\n },\n {\n \"id\": \"35a9365f-60e1-41f8-ab8a-baf9db171e37\",\n \"nid\": 642,\n \"vid\": 2376,\n \"url\": \"https://perls.localhost:8000/system/files/2021-03/example_xapi_content_valid_all/index.html?endpoint=https%3A//perls.localhost:8000/lrs/&auth=none&actor=%7B%22objectType%22%3A%22Agent%22%2C%22name%22%3A%22John%20Doe%22%2C%22account%22%3A%7B%22name%22%3A%222455a7ba-4935-4a0c-a34b-67b595915a37%22%2C%22homePage%22%3A%22https%3A%5C/%5C/perls.localhost:8000%22%7D%7D&activity_id=https%3A//perls.localhost:8000/node/642&activity_platform=PERLS\",\n \"name\": \"e-learning package\",\n \"type\": \"learn_package\",\n \"changed\": \"2021-07-08T23:30:04+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"933a999e-6228-479b-8909-1705559aa398\",\n \"name\": \"example_xapi_content_valid_all.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/2021-03/example_xapi_content_valid_all.zip\",\n \"mimetype\": \"application/zip\"\n },\n \"tags\": [\n {\n \"id\": \"7567d087-b32d-4959-8c43-ec9e66f1b7f8\",\n \"vid\": 105,\n \"tid\": 105,\n \"url\": \"/taxonomy/term/105\",\n \"name\": \"test\",\n \"type\": \"tags\",\n \"changed\": \"2020-06-11T20:09:40+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"33adf0fd-782f-4146-873d-22b375a929fb\",\n \"vid\": 110,\n \"tid\": 110,\n \"url\": \"/taxonomy/term/110\",\n \"name\": \"Digital literacy\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": null\n },\n \"description\": \"If you already have content created in an eLearning authoring tool, you can export that as a Tin Can or xAPI-compliant package and upload it here.\\r\\n\\r\\n\",\n \"image\": null\n },\n {\n \"id\": \"18397e31-19bf-4b81-9de0-7d90b3af4a6d\",\n \"nid\": 310,\n \"vid\": 1531,\n \"url\": \"/node/310\",\n \"name\": \"test\",\n \"type\": \"learn_article\",\n \"changed\": \"2021-04-22T03:15:37+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"7788d80a-0267-4d8a-9be9-baadee3472c9\",\n \"name\": \"node_310.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/offline_page/node_310.zip\"\n },\n \"tags\": [\n {\n \"id\": \"c3c293a8-acb2-4e52-bb4c-7bf45be16495\",\n \"vid\": 109,\n \"tid\": 109,\n \"url\": \"/taxonomy/term/109\",\n \"name\": \"chicken\",\n \"type\": \"tags\",\n \"changed\": \"2020-06-12T18:26:53+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"33adf0fd-782f-4146-873d-22b375a929fb\",\n \"vid\": 110,\n \"tid\": 110,\n \"url\": \"/taxonomy/term/110\",\n \"name\": \"Digital literacy\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": null\n },\n \"description\": \"optionally\",\n \"image\": {\n \"UUID\": \"d2b9620e-90bb-44ed-9db6-409b3c46ef8d\",\n \"filename\": \"city-sunny-people-street.jpg\",\n \"url\": \"https://perls.localhost:8000/sites/default/files/styles/large/public/2020-10/city-sunny-people-street.jpg?itok=yFsHjZLG\",\n \"original_url\": \"https://perls.localhost:8000/sites/default/files/2020-10/city-sunny-people-street.jpg\"\n },\n \"discussion_status\": \"hidden\"\n }\n ]\n },\n {\n \"name\": \"Occupational Safety and Health\",\n \"url\": \"/api/taxonomy/term/80\",\n \"content\": [\n {\n \"id\": \"c7d5cbcc-ca35-4244-b68a-7cdea7edf53e\",\n \"nid\": 701,\n \"vid\": 1484,\n \"url\": \"/node/701\",\n \"name\": \"DOCUMENT- TEST THE SHARE BUTTON\",\n \"type\": \"learn_file\",\n \"changed\": \"2021-04-22T03:15:37+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"cf21366d-728b-4098-b8aa-c8e936bcc00b\",\n \"name\": \"13.03_open_kitchen_press_release.pdf\",\n \"url\": \"https://perls.localhost:8000/system/files/2021-04/13.03_open_kitchen_press_release.pdf\",\n \"mimetype\": \"application/pdf\"\n },\n \"tags\": [\n {\n \"id\": \"54db0a3d-4696-4061-bbb6-e8cc905145b5\",\n \"vid\": 215,\n \"tid\": 215,\n \"url\": \"/taxonomy/term/215\",\n \"name\": \"Content Test Suite\",\n \"type\": \"tags\",\n \"changed\": \"2021-04-01T15:54:53+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"fb473dd7-86a8-40a6-8a12-c9c80d46c2fb\",\n \"vid\": 80,\n \"tid\": 80,\n \"url\": \"/taxonomy/term/80\",\n \"name\": \"Occupational Safety and Health\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"This topic includes content related to the safety, health, and welfare of people at work The goal of occupational safety and health programs is to foster a safe and healthy work environment.[3] OSH may also protect co-workers, family members, employers, customers, and many others who might be affected by the workplace environment. \"\n },\n \"description\": \"Use a document to upload content authored somewhere else. Learners can download and share documents making them useful for quick reference materials.\\r\\n\\r\\n\\r\\nUse a document to upload content authored somewhere else. Learners can download and share documents making them useful for quick reference materials.\\r\\n\\r\\n\",\n \"image\": {\n \"UUID\": \"eeabd32d-94e3-46f5-85ca-00d00f42ce23\",\n \"filename\": \"training.jpg\",\n \"url\": \"https://perls.localhost:8000/sites/default/files/styles/large/public/2021-04/training.jpg?itok=Wbs1SfW6\",\n \"original_url\": \"https://perls.localhost:8000/sites/default/files/2021-04/training.jpg\"\n }\n },\n {\n \"id\": \"a7d950ce-f018-4875-9fb0-d7c27420e42a\",\n \"nid\": 676,\n \"vid\": 1440,\n \"url\": \"/node/676\",\n \"name\": \"Course with 250 1 test\",\n \"type\": \"course\",\n \"changed\": \"2021-04-07T14:45:56+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": [\n {\n \"id\": \"54db0a3d-4696-4061-bbb6-e8cc905145b5\",\n \"vid\": 215,\n \"tid\": 215,\n \"url\": \"/taxonomy/term/215\",\n \"name\": \"Content Test Suite\",\n \"type\": \"tags\",\n \"changed\": \"2021-04-01T15:54:53+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"fb473dd7-86a8-40a6-8a12-c9c80d46c2fb\",\n \"vid\": 80,\n \"tid\": 80,\n \"url\": \"/taxonomy/term/80\",\n \"name\": \"Occupational Safety and Health\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"This topic includes content related to the safety, health, and welfare of people at work The goal of occupational safety and health programs is to foster a safe and healthy work environment.[3] OSH may also protect co-workers, family members, employers, customers, and many others who might be affected by the workplace environment. \"\n },\n \"description\": \"Course with 250 1 test\\r\\nCourse with 250 1 test\",\n \"learning_objects\": [],\n \"image\": null\n },\n {\n \"id\": \"e60e4d7d-187a-4162-bcd4-4fd536b22f26\",\n \"nid\": 662,\n \"vid\": 1417,\n \"url\": \"https://perls.localhost:8000/system/files/2021-04/example_xapi_content_valid_all/index.html?endpoint=https%3A//perls.localhost:8000/lrs/&auth=none&actor=%7B%22objectType%22%3A%22Agent%22%2C%22name%22%3A%22John%20Doe%22%2C%22account%22%3A%7B%22name%22%3A%222455a7ba-4935-4a0c-a34b-67b595915a37%22%2C%22homePage%22%3A%22https%3A%5C/%5C/perls.localhost:8000%22%7D%7D&activity_id=https%3A//perls.localhost:8000/node/662&activity_platform=PERLS\",\n \"name\": \"e-Learning validate all XAPI\",\n \"type\": \"learn_package\",\n \"changed\": \"2021-04-05T15:02:40+0000\",\n \"is_promoted\": true,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"09a735d6-7fe1-4804-89ac-0f59124160df\",\n \"name\": \"example_xapi_content_valid_all.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/2021-04/example_xapi_content_valid_all.zip\",\n \"mimetype\": \"application/zip\"\n },\n \"tags\": [\n {\n \"id\": \"7567d087-b32d-4959-8c43-ec9e66f1b7f8\",\n \"vid\": 105,\n \"tid\": 105,\n \"url\": \"/taxonomy/term/105\",\n \"name\": \"test\",\n \"type\": \"tags\",\n \"changed\": \"2020-06-11T20:09:40+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"fb473dd7-86a8-40a6-8a12-c9c80d46c2fb\",\n \"vid\": 80,\n \"tid\": 80,\n \"url\": \"/taxonomy/term/80\",\n \"name\": \"Occupational Safety and Health\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"This topic includes content related to the safety, health, and welfare of people at work The goal of occupational safety and health programs is to foster a safe and healthy work environment.[3] OSH may also protect co-workers, family members, employers, customers, and many others who might be affected by the workplace environment. \"\n },\n \"description\": \"If you already have content created in an eLearning authoring tool, you can export that as a Tin Can or xAPI-compliant package and upload it here.\\r\\n\\r\\n\",\n \"image\": null\n },\n {\n \"id\": \"0f545c02-61f1-4a48-a3d5-b8a47767c87e\",\n \"nid\": 609,\n \"vid\": 1256,\n \"url\": \"/node/609\",\n \"name\": \"new course\",\n \"type\": \"course\",\n \"changed\": \"2021-03-25T15:20:52+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": [],\n \"topic\": {\n \"id\": \"fb473dd7-86a8-40a6-8a12-c9c80d46c2fb\",\n \"vid\": 80,\n \"tid\": 80,\n \"url\": \"/taxonomy/term/80\",\n \"name\": \"Occupational Safety and Health\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"This topic includes content related to the safety, health, and welfare of people at work The goal of occupational safety and health programs is to foster a safe and healthy work environment.[3] OSH may also protect co-workers, family members, employers, customers, and many others who might be affected by the workplace environment. \"\n },\n \"description\": \"testUse a course to guide your learners through a sequential set of content (including articles, web links, tests, and more). Learners are encouraged to start with the first item in the course and work their way through to gain mastery of the information presented here.\\r\\n\\r\\n\",\n \"learning_objects\": [\n {\n \"id\": \"374b2852-aa0b-4b79-adb5-f7c2ec470b7b\",\n \"nid\": 603,\n \"vid\": 1303,\n \"url\": \"/node/603\",\n \"name\": \"test\",\n \"type\": \"podcast_episode\",\n \"changed\": \"2021-03-29T20:58:24+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"867adcf0-e0f4-490e-a538-4ac761556cf7\",\n \"name\": \"mp3.mp3\",\n \"url\": \"https://perls.localhost:8000/sites/default/files/podcasts/2021-03/test-374b2852-aa0b-4b79-adb5-f7c2ec470b7b/mp3.mp3\",\n \"mimetype\": \"audio/mpeg\"\n },\n \"tags\": [\n {\n \"id\": \"7567d087-b32d-4959-8c43-ec9e66f1b7f8\",\n \"vid\": 105,\n \"tid\": 105,\n \"url\": \"/taxonomy/term/105\",\n \"name\": \"test\",\n \"type\": \"tags\",\n \"changed\": \"2020-06-11T20:09:40+0000\"\n }\n ],\n \"description\": \"test\",\n \"duration\": 29,\n \"release_date\": \"2021-03-25\"\n }\n ],\n \"image\": null\n },\n {\n \"id\": \"6089dcfd-332e-4bd7-aa95-e014efa07247\",\n \"nid\": 587,\n \"vid\": 2530,\n \"url\": \"/node/587\",\n \"name\": \"John Doe content\",\n \"type\": \"learn_article\",\n \"changed\": \"2021-04-27T17:23:39+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"4afcb227-bc4d-4d80-9c84-db29498c5f2d\",\n \"name\": \"node_587.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/offline_page/node_587.zip\"\n },\n \"tags\": [\n {\n \"id\": \"7567d087-b32d-4959-8c43-ec9e66f1b7f8\",\n \"vid\": 105,\n \"tid\": 105,\n \"url\": \"/taxonomy/term/105\",\n \"name\": \"test\",\n \"type\": \"tags\",\n \"changed\": \"2020-06-11T20:09:40+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"fb473dd7-86a8-40a6-8a12-c9c80d46c2fb\",\n \"vid\": 80,\n \"tid\": 80,\n \"url\": \"/taxonomy/term/80\",\n \"name\": \"Occupational Safety and Health\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"This topic includes content related to the safety, health, and welfare of people at work The goal of occupational safety and health programs is to foster a safe and healthy work environment.[3] OSH may also protect co-workers, family members, employers, customers, and many others who might be affected by the workplace environment. \"\n },\n \"description\": \"An article allows you to build and publish content directly to learners. Try focusing your articles to a single learning objective. You can create many articles under the same topic or course to provide your learners a comprehensive set of content.\\r\\n\\r\\nyou an add more contents. \",\n \"image\": null,\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"85b3a4b7-341d-4e3e-bdc6-5260e1e3278a\",\n \"nid\": 573,\n \"vid\": 1155,\n \"url\": \"/node/573\",\n \"name\": \"CERTIFICATE\",\n \"type\": \"course\",\n \"changed\": \"2021-03-15T17:14:23+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": [\n {\n \"id\": \"7567d087-b32d-4959-8c43-ec9e66f1b7f8\",\n \"vid\": 105,\n \"tid\": 105,\n \"url\": \"/taxonomy/term/105\",\n \"name\": \"test\",\n \"type\": \"tags\",\n \"changed\": \"2020-06-11T20:09:40+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"fb473dd7-86a8-40a6-8a12-c9c80d46c2fb\",\n \"vid\": 80,\n \"tid\": 80,\n \"url\": \"/taxonomy/term/80\",\n \"name\": \"Occupational Safety and Health\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"This topic includes content related to the safety, health, and welfare of people at work The goal of occupational safety and health programs is to foster a safe and healthy work environment.[3] OSH may also protect co-workers, family members, employers, customers, and many others who might be affected by the workplace environment. \"\n },\n \"description\": \"test\",\n \"learning_objects\": [\n {\n \"id\": \"51e10b86-7826-497a-bd57-9e95433259b7\",\n \"nid\": 547,\n \"vid\": 1266,\n \"url\": \"/node/547\",\n \"name\": \"New article by authenticated user\",\n \"type\": \"learn_article\",\n \"changed\": \"2021-03-25T15:41:43+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"a6f4ce02-0a98-4d24-b092-63dc3abddee7\",\n \"name\": \"node_547.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/offline_page/node_547.zip\"\n },\n \"tags\": [],\n \"topic\": {\n \"id\": \"fb473dd7-86a8-40a6-8a12-c9c80d46c2fb\",\n \"vid\": 80,\n \"tid\": 80,\n \"url\": \"/taxonomy/term/80\",\n \"name\": \"Occupational Safety and Health\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"This topic includes content related to the safety, health, and welfare of people at work The goal of occupational safety and health programs is to foster a safe and healthy work environment.[3] OSH may also protect co-workers, family members, employers, customers, and many others who might be affected by the workplace environment. \"\n },\n \"description\": \"test\",\n \"image\": null,\n \"discussion_status\": \"hidden\"\n }\n ],\n \"image\": null\n },\n {\n \"id\": \"ad180630-1b9e-49a1-a148-dc13ffef4391\",\n \"nid\": 570,\n \"vid\": 1137,\n \"url\": \"/node/570\",\n \"name\": \"Use a course to - with description\",\n \"type\": \"course\",\n \"changed\": \"2021-04-22T03:15:37+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": [\n {\n \"id\": \"7567d087-b32d-4959-8c43-ec9e66f1b7f8\",\n \"vid\": 105,\n \"tid\": 105,\n \"url\": \"/taxonomy/term/105\",\n \"name\": \"test\",\n \"type\": \"tags\",\n \"changed\": \"2020-06-11T20:09:40+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"fb473dd7-86a8-40a6-8a12-c9c80d46c2fb\",\n \"vid\": 80,\n \"tid\": 80,\n \"url\": \"/taxonomy/term/80\",\n \"name\": \"Occupational Safety and Health\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"This topic includes content related to the safety, health, and welfare of people at work The goal of occupational safety and health programs is to foster a safe and healthy work environment.[3] OSH may also protect co-workers, family members, employers, customers, and many others who might be affected by the workplace environment. \"\n },\n \"description\": \"Use a course to guide your learners through a sequential set of content (including articles, web links, tests, and more). Learners are encouraged to start with the first item in the course and work their way through to gain mastery of the information presented here.\\r\\nUse a course to guide your learners through a sequential set of content (including articles, web links, tests, and more). Learners are encouraged to start with the first item in the course and work their way through to\\r\\n\\r\\n\",\n \"learning_objects\": [],\n \"image\": {\n \"UUID\": \"12925eed-9e32-4da8-9e53-46ea83e65256\",\n \"filename\": \"army_assault.jpg\",\n \"url\": \"https://perls.localhost:8000/sites/default/files/styles/large/public/2021-03/army_assault.jpg?itok=sfLQ48dS\",\n \"original_url\": \"https://perls.localhost:8000/sites/default/files/2021-03/army_assault.jpg\"\n }\n },\n {\n \"id\": \"ad56af79-cbb5-43ca-89c2-d8d1d51371f6\",\n \"nid\": 569,\n \"vid\": 1133,\n \"url\": \"/node/569\",\n \"name\": \"Use a course to guide your learners\",\n \"type\": \"course\",\n \"changed\": \"2021-03-10T21:04:02+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": [\n {\n \"id\": \"7567d087-b32d-4959-8c43-ec9e66f1b7f8\",\n \"vid\": 105,\n \"tid\": 105,\n \"url\": \"/taxonomy/term/105\",\n \"name\": \"test\",\n \"type\": \"tags\",\n \"changed\": \"2020-06-11T20:09:40+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"fb473dd7-86a8-40a6-8a12-c9c80d46c2fb\",\n \"vid\": 80,\n \"tid\": 80,\n \"url\": \"/taxonomy/term/80\",\n \"name\": \"Occupational Safety and Health\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"This topic includes content related to the safety, health, and welfare of people at work The goal of occupational safety and health programs is to foster a safe and healthy work environment.[3] OSH may also protect co-workers, family members, employers, customers, and many others who might be affected by the workplace environment. \"\n },\n \"description\": null,\n \"learning_objects\": [\n {\n \"id\": \"2facb8d1-0be0-4029-aa2c-0681502ee520\",\n \"nid\": 554,\n \"vid\": 1265,\n \"url\": \"/node/554\",\n \"name\": \"Test group permissions\",\n \"type\": \"learn_article\",\n \"changed\": \"2021-03-25T15:41:43+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"66ebacc5-464c-4ed2-adde-054d311272ec\",\n \"name\": \"node_554.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/offline_page/node_554.zip\"\n },\n \"tags\": [],\n \"topic\": {\n \"id\": \"e2d54015-6e0b-43aa-a6b6-bd8abf7e66f6\",\n \"vid\": 99,\n \"tid\": 99,\n \"url\": \"/taxonomy/term/99\",\n \"name\": \"Take Precautions: COVID-19\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"The recent coronavirus outbreak is a serious health concern. Do you know how to protect yourself and others from serious illness? Arming yourself with information and strategies will help reduce the spread of disease and enable you to work effectively in the challenging circumstances of an outbreak.\"\n },\n \"description\": \"asdfasdf\",\n \"image\": null,\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"51e10b86-7826-497a-bd57-9e95433259b7\",\n \"nid\": 547,\n \"vid\": 1266,\n \"url\": \"/node/547\",\n \"name\": \"New article by authenticated user\",\n \"type\": \"learn_article\",\n \"changed\": \"2021-03-25T15:41:43+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"a6f4ce02-0a98-4d24-b092-63dc3abddee7\",\n \"name\": \"node_547.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/offline_page/node_547.zip\"\n },\n \"tags\": [],\n \"topic\": {\n \"id\": \"fb473dd7-86a8-40a6-8a12-c9c80d46c2fb\",\n \"vid\": 80,\n \"tid\": 80,\n \"url\": \"/taxonomy/term/80\",\n \"name\": \"Occupational Safety and Health\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"This topic includes content related to the safety, health, and welfare of people at work The goal of occupational safety and health programs is to foster a safe and healthy work environment.[3] OSH may also protect co-workers, family members, employers, customers, and many others who might be affected by the workplace environment. \"\n },\n \"description\": \"test\",\n \"image\": null,\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"c35890aa-c46f-4e9a-a976-933133fe18b5\",\n \"nid\": 467,\n \"vid\": 1544,\n \"url\": \"/node/467\",\n \"name\": \"Leveraging Focus Groups for 2687\",\n \"type\": \"learn_article\",\n \"changed\": \"2021-04-22T03:15:37+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": [\n {\n \"id\": \"62351975-218e-4076-9470-4bd84200f9b4\",\n \"vid\": 149,\n \"tid\": 149,\n \"url\": \"/taxonomy/term/149\",\n \"name\": \"FPD 215\",\n \"type\": \"tags\",\n \"changed\": \"2021-02-23T14:53:16+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"4719b562-89a3-4e06-b821-03a7b8c5149c\",\n \"vid\": 134,\n \"tid\": 134,\n \"url\": \"/taxonomy/term/134\",\n \"name\": \"lesson about the Apache\",\n \"type\": \"category\",\n \"changed\": \"2021-08-05T06:16:18+0000\",\n \"description\": \"oriign apache\\r\\n\"\n },\n \"description\": \"Focus groups provide the richness and context that enable better decision-making. This article is borrowed from PERLS for testing purposes. Please do not modify this article.\",\n \"image\": {\n \"UUID\": \"35cd61e6-f9f8-42f0-8504-da807aad74ea\",\n \"filename\": \"v9y2hefhbynvxigr.jpg\",\n \"url\": \"https://perls.localhost:8000/sites/default/files/styles/large/public/2021-02/v9y2hefhbynvxigr.jpg?itok=s71HepHn\",\n \"original_url\": \"https://perls.localhost:8000/sites/default/files/2021-02/v9y2hefhbynvxigr.jpg\"\n },\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"96e02d39-2c29-45f0-9c76-42f43a81bbd6\",\n \"nid\": 466,\n \"vid\": 1543,\n \"url\": \"/node/466\",\n \"name\": \"Manual completion article\",\n \"type\": \"learn_article\",\n \"changed\": \"2021-04-22T03:15:37+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"99311a37-2a47-42db-96ea-d3703c9ecd3e\",\n \"name\": \"node_466.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/offline_page/node_466.zip\"\n },\n \"tags\": [\n {\n \"id\": \"7353d6a8-3220-49d2-a212-7f7ccaabe0f9\",\n \"vid\": 146,\n \"tid\": 146,\n \"url\": \"/taxonomy/term/146\",\n \"name\": \"manual\",\n \"type\": \"tags\",\n \"changed\": \"2021-02-22T18:14:41+0000\"\n },\n {\n \"id\": \"d3c98ff7-4440-499a-b1d6-bf1112bf9ee2\",\n \"vid\": 147,\n \"tid\": 147,\n \"url\": \"/taxonomy/term/147\",\n \"name\": \"completion\",\n \"type\": \"tags\",\n \"changed\": \"2021-02-22T18:14:41+0000\"\n },\n {\n \"id\": \"0041cc3f-7e36-49aa-9349-6e5d807b3e83\",\n \"vid\": 148,\n \"tid\": 148,\n \"url\": \"/taxonomy/term/148\",\n \"name\": \"article\",\n \"type\": \"tags\",\n \"changed\": \"2021-02-22T18:14:41+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"fb473dd7-86a8-40a6-8a12-c9c80d46c2fb\",\n \"vid\": 80,\n \"tid\": 80,\n \"url\": \"/taxonomy/term/80\",\n \"name\": \"Occupational Safety and Health\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"This topic includes content related to the safety, health, and welfare of people at work The goal of occupational safety and health programs is to foster a safe and healthy work environment.[3] OSH may also protect co-workers, family members, employers, customers, and many others who might be affected by the workplace environment. \"\n },\n \"description\": \"A simple article with manual completion.\",\n \"image\": {\n \"UUID\": \"deb29c55-4e5c-4632-825d-c14a0320f271\",\n \"filename\": \"covariance.png\",\n \"url\": \"https://perls.localhost:8000/sites/default/files/styles/large/public/2021-02/covariance.png.jpg?itok=FwQMphpp\",\n \"original_url\": \"https://perls.localhost:8000/sites/default/files/2021-02/covariance.png\"\n },\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"3b7223dc-e255-4022-9f89-10a3423d6534\",\n \"nid\": 465,\n \"vid\": 1124,\n \"url\": \"/node/465\",\n \"name\": \"test\",\n \"type\": \"learn_article\",\n \"changed\": \"2021-03-10T19:14:00+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"cf4c49f4-8b61-42d7-8c19-73b5e9572784\",\n \"name\": \"node_465.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/offline_page/node_465.zip\"\n },\n \"tags\": [\n {\n \"id\": \"7567d087-b32d-4959-8c43-ec9e66f1b7f8\",\n \"vid\": 105,\n \"tid\": 105,\n \"url\": \"/taxonomy/term/105\",\n \"name\": \"test\",\n \"type\": \"tags\",\n \"changed\": \"2020-06-11T20:09:40+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"e2d54015-6e0b-43aa-a6b6-bd8abf7e66f6\",\n \"vid\": 99,\n \"tid\": 99,\n \"url\": \"/taxonomy/term/99\",\n \"name\": \"Take Precautions: COVID-19\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"The recent coronavirus outbreak is a serious health concern. Do you know how to protect yourself and others from serious illness? Arming yourself with information and strategies will help reduce the spread of disease and enable you to work effectively in the challenging circumstances of an outbreak.\"\n },\n \"description\": \"test\",\n \"image\": null,\n \"discussion_status\": \"hidden\"\n }\n ],\n \"image\": null\n },\n {\n \"id\": \"ebcfa00b-1404-48e7-be4b-949c10ee1b9f\",\n \"nid\": 567,\n \"vid\": 1108,\n \"url\": \"https://perls.localhost:8000/system/files/2021-03/financial-hurdles-phase-iii-r/index.html?endpoint=https%3A//perls.localhost:8000/lrs/&auth=none&actor=%7B%22objectType%22%3A%22Agent%22%2C%22name%22%3A%22John%20Doe%22%2C%22account%22%3A%7B%22name%22%3A%222455a7ba-4935-4a0c-a34b-67b595915a37%22%2C%22homePage%22%3A%22https%3A%5C/%5C/perls.localhost:8000%22%7D%7D&activity_id=https%3A//perls.localhost:8000/node/567&activity_platform=PERLS\",\n \"name\": \"Learning package -Financial hurdle\",\n \"type\": \"learn_package\",\n \"changed\": \"2021-04-22T03:15:37+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"0c85a7e5-33a8-4bd2-81df-9915f4fe0a1c\",\n \"name\": \"financial-hurdles-phase-iii-r.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/2021-03/financial-hurdles-phase-iii-r.zip\",\n \"mimetype\": \"application/zip\"\n },\n \"tags\": [\n {\n \"id\": \"7567d087-b32d-4959-8c43-ec9e66f1b7f8\",\n \"vid\": 105,\n \"tid\": 105,\n \"url\": \"/taxonomy/term/105\",\n \"name\": \"test\",\n \"type\": \"tags\",\n \"changed\": \"2020-06-11T20:09:40+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"fb473dd7-86a8-40a6-8a12-c9c80d46c2fb\",\n \"vid\": 80,\n \"tid\": 80,\n \"url\": \"/taxonomy/term/80\",\n \"name\": \"Occupational Safety and Health\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"This topic includes content related to the safety, health, and welfare of people at work The goal of occupational safety and health programs is to foster a safe and healthy work environment.[3] OSH may also protect co-workers, family members, employers, customers, and many others who might be affected by the workplace environment. \"\n },\n \"description\": \"Test\",\n \"image\": {\n \"UUID\": \"892b6a73-715b-4b21-beb3-9b6289ae2f09\",\n \"filename\": \"patrol2.jpg\",\n \"url\": \"https://perls.localhost:8000/sites/default/files/styles/large/public/2021-03/patrol2.jpg?itok=xGr010Qc\",\n \"original_url\": \"https://perls.localhost:8000/sites/default/files/2021-03/patrol2.jpg\"\n }\n },\n {\n \"id\": \"d2d3e087-14d7-4971-931d-32998551aba6\",\n \"nid\": 447,\n \"vid\": 1539,\n \"url\": \"/node/447\",\n \"name\": \"THIS IS A LENGTH CONTENT TITLE\",\n \"type\": \"learn_article\",\n \"changed\": \"2021-04-22T03:15:37+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"2e2d54a0-319d-4435-9702-af46729b3b74\",\n \"name\": \"node_447.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/offline_page/node_447.zip\"\n },\n \"tags\": [\n {\n \"id\": \"cbee504a-f709-4ca4-87c6-fbef7cf50110\",\n \"vid\": 124,\n \"tid\": 124,\n \"url\": \"/taxonomy/term/124\",\n \"name\": \"army\",\n \"type\": \"tags\",\n \"changed\": \"2020-08-27T19:17:36+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"fb473dd7-86a8-40a6-8a12-c9c80d46c2fb\",\n \"vid\": 80,\n \"tid\": 80,\n \"url\": \"/taxonomy/term/80\",\n \"name\": \"Occupational Safety and Health\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"This topic includes content related to the safety, health, and welfare of people at work The goal of occupational safety and health programs is to foster a safe and healthy work environment.[3] OSH may also protect co-workers, family members, employers, customers, and many others who might be affected by the workplace environment. \"\n },\n \"description\": \"An army (from Latin arma \\\"arms, weapons\\\" via Old French armée, \\\"armed\\\" [feminine]), ground \\r\\nAn army (from Latin arma \\\"arms, weapons\\\" via Old French armée, \\\"armed\\\" [feminine]), ground \\r\\nAn army (from Latin arma \\\"arms, weapons\\\" via Old French armée, \\\"armed\\\" [feminine]), ground \",\n \"image\": {\n \"UUID\": \"37a3a4d1-f0ef-4091-8a4b-2cf064ca2263\",\n \"filename\": \"mask.jpg\",\n \"url\": \"https://perls.localhost:8000/sites/default/files/styles/large/public/2021-02/mask.jpg?itok=6OicZPzh\",\n \"original_url\": \"https://perls.localhost:8000/sites/default/files/2021-02/mask.jpg\"\n },\n \"discussion_status\": \"open\"\n }\n ]\n },\n {\n \"name\": \"Content Test Suite [CTS]\",\n \"url\": \"/api/taxonomy/term/213\",\n \"content\": [\n {\n \"id\": \"47ffbab9-1bd9-4518-b290-99524efd29ee\",\n \"nid\": 1019,\n \"vid\": 2733,\n \"url\": \"/node/1019\",\n \"name\": \"Testcourse-1\",\n \"type\": \"course\",\n \"changed\": \"2021-08-27T00:07:21+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": [],\n \"topic\": {\n \"id\": \"4a16bc04-dca6-4ed9-9a07-af2e138ca6c0\",\n \"vid\": 213,\n \"tid\": 213,\n \"url\": \"/taxonomy/term/213\",\n \"name\": \"Content Test Suite [CTS]\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"Create a content test suite course on the dev server with example content\"\n },\n \"description\": null,\n \"learning_objects\": [\n {\n \"id\": \"0cf81d2a-b4d3-4a1e-858c-598ff0b5a626\",\n \"nid\": 1020,\n \"vid\": 2731,\n \"url\": \"/node/1020\",\n \"name\": \"Testarticle---\",\n \"type\": \"learn_article\",\n \"changed\": \"2021-08-27T00:04:52+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"530f3550-ead3-4570-8806-f5c6e749de55\",\n \"name\": \"node_1020.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/offline_page/node_1020.zip\"\n },\n \"tags\": [],\n \"topic\": {\n \"id\": \"4a16bc04-dca6-4ed9-9a07-af2e138ca6c0\",\n \"vid\": 213,\n \"tid\": 213,\n \"url\": \"/taxonomy/term/213\",\n \"name\": \"Content Test Suite [CTS]\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"Create a content test suite course on the dev server with example content\"\n },\n \"description\": null,\n \"image\": null,\n \"discussion_status\": \"hidden\"\n }\n ],\n \"image\": null\n },\n {\n \"id\": \"6fd012a6-0828-4502-b1ce-49f026fb5ae1\",\n \"nid\": 1009,\n \"vid\": 2704,\n \"url\": \"/node/1009\",\n \"name\": \"Testtipcard\",\n \"type\": \"tip_card\",\n \"changed\": \"2021-09-01T16:37:24+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": [],\n \"topic\": {\n \"id\": \"4a16bc04-dca6-4ed9-9a07-af2e138ca6c0\",\n \"vid\": 213,\n \"tid\": 213,\n \"url\": \"/taxonomy/term/213\",\n \"name\": \"Content Test Suite [CTS]\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"Create a content test suite course on the dev server with example content\"\n },\n \"contents\": [\n \"
\\n \\n

Testtipcard

\\n
\\n \\n
\\n\"\n ],\n \"body\": [\n {\n \"id\": \"c7e688c5-55d8-4658-9b25-25370f1887c0\",\n \"type\": \"text\",\n \"fields\": [\n {\n \"type\": \"Label\",\n \"attributes\": {\n \"Text\": \"

Testtipcard

\",\n \"TextType\": \"Html\"\n }\n }\n ]\n }\n ]\n },\n {\n \"id\": \"77a8ee56-2853-49ef-b11f-94b67c246d4f\",\n \"nid\": 984,\n \"vid\": 2645,\n \"url\": \"/node/984\",\n \"name\": \"Testflashcard3601\",\n \"type\": \"flash_card\",\n \"changed\": \"2021-08-10T00:08:34+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": [],\n \"topic\": {\n \"id\": \"4a16bc04-dca6-4ed9-9a07-af2e138ca6c0\",\n \"vid\": 213,\n \"tid\": 213,\n \"url\": \"/taxonomy/term/213\",\n \"name\": \"Content Test Suite [CTS]\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"Create a content test suite course on the dev server with example content\"\n },\n \"contents\": [\n \"
\\n \\n

Testflashcard3601

\\n
\\n \\n
\\n\",\n \"
\\n \\n
\\\"denmark,sunset,nautical\\\"\\n\\n
\\n \\n
\\n\"\n ],\n \"back_contents\": [\n \"
\\n \\n

Testflashcard3601

\\n
\\n \\n
\\n\",\n \"
\\n \\n
\\\"bus,iceland,reykyavik\\\"\\n\\n
\\n \\n
\\n\"\n ],\n \"body\": [\n {\n \"id\": \"7d806cd8-3f0d-4b04-aea3-92b9248ffe1d\",\n \"type\": \"text\",\n \"fields\": [\n {\n \"type\": \"Label\",\n \"attributes\": {\n \"Text\": \"

Testflashcard3601

\",\n \"TextType\": \"Html\",\n \"Style\": \"Heading\"\n }\n }\n ]\n },\n {\n \"id\": \"c39668c4-de15-4122-b235-d223dca08ec2\",\n \"type\": \"image\",\n \"fields\": [\n {\n \"type\": \"Image\",\n \"attributes\": {\n \"Source\": \"https://perls.localhost:8000/sites/default/files/styles/large/public/unsplash/ship/photo-1470645792662-dd18394f8c97.jpg?itok=Wk4xhsNJ\",\n \"Aspect\": \"AspectFit\"\n }\n }\n ]\n }\n ],\n \"body_back\": [\n {\n \"id\": \"eaad3399-89f1-47b0-bd23-1d52ae31b50b\",\n \"type\": \"text\",\n \"fields\": [\n {\n \"type\": \"Label\",\n \"attributes\": {\n \"Text\": \"

Testflashcard3601

\",\n \"TextType\": \"Html\"\n }\n }\n ]\n },\n {\n \"id\": \"a61682d1-6b16-48b0-8ecd-b449335cc17b\",\n \"type\": \"image\",\n \"fields\": [\n {\n \"type\": \"Image\",\n \"attributes\": {\n \"Source\": \"https://perls.localhost:8000/sites/default/files/styles/large/public/unsplash/bus/photo-1544620347-c4fd4a3d5957.jpg?itok=n577Sall\",\n \"Aspect\": \"AspectFit\"\n }\n }\n ]\n }\n ]\n },\n {\n \"id\": \"8607b028-b0f0-43b0-8694-aef4bf7c3393\",\n \"nid\": 983,\n \"vid\": 2644,\n \"url\": \"/node/983\",\n \"name\": \"Testtip3601\",\n \"type\": \"tip_card\",\n \"changed\": \"2021-08-10T00:06:17+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": [],\n \"topic\": {\n \"id\": \"4a16bc04-dca6-4ed9-9a07-af2e138ca6c0\",\n \"vid\": 213,\n \"tid\": 213,\n \"url\": \"/taxonomy/term/213\",\n \"name\": \"Content Test Suite [CTS]\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"Create a content test suite course on the dev server with example content\"\n },\n \"contents\": [\n \"
\\n \\n

Testtip3601

\\n
\\n \\n
\\n\",\n \"
\\n \\n
\\\"plane,travel,airplane\\\"\\n\\n
\\n \\n
\\n\"\n ],\n \"body\": [\n {\n \"id\": \"794f18f3-2268-4196-b258-e4bec9bdc96c\",\n \"type\": \"text\",\n \"fields\": [\n {\n \"type\": \"Label\",\n \"attributes\": {\n \"Text\": \"

Testtip3601

\",\n \"TextType\": \"Html\"\n }\n }\n ]\n },\n {\n \"id\": \"a2985d43-650d-4e8c-940c-dcf41bf924c8\",\n \"type\": \"image\",\n \"fields\": [\n {\n \"type\": \"Image\",\n \"attributes\": {\n \"Source\": \"https://perls.localhost:8000/sites/default/files/styles/large/public/unsplash/Plane/photo-1531642765602-5cae8bbbf285.jpg?itok=1EFQwnmv\",\n \"Aspect\": \"AspectFit\"\n }\n }\n ]\n }\n ]\n },\n {\n \"id\": \"d013a6ec-659c-4a01-8ed6-5956f8bf9262\",\n \"nid\": 982,\n \"vid\": 2643,\n \"url\": \"/node/982\",\n \"name\": \"Testarticle3601\",\n \"type\": \"learn_article\",\n \"changed\": \"2021-08-10T00:01:48+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"0afd006a-1e8d-480e-a6d6-f1d0a662d903\",\n \"name\": \"node_982.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/offline_page/node_982.zip\"\n },\n \"tags\": [],\n \"topic\": {\n \"id\": \"4a16bc04-dca6-4ed9-9a07-af2e138ca6c0\",\n \"vid\": 213,\n \"tid\": 213,\n \"url\": \"/taxonomy/term/213\",\n \"name\": \"Content Test Suite [CTS]\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"Create a content test suite course on the dev server with example content\"\n },\n \"description\": \"Testarticle3601\",\n \"image\": null,\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"ddc03afc-ad8e-4110-aa6c-82c49085775b\",\n \"nid\": 977,\n \"vid\": 2620,\n \"url\": \"/node/977\",\n \"name\": \"Testweblink-41\",\n \"type\": \"learn_link\",\n \"changed\": \"2021-08-06T17:35:24+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": [],\n \"topic\": {\n \"id\": \"4a16bc04-dca6-4ed9-9a07-af2e138ca6c0\",\n \"vid\": 213,\n \"tid\": 213,\n \"url\": \"/taxonomy/term/213\",\n \"name\": \"Content Test Suite [CTS]\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"Create a content test suite course on the dev server with example content\"\n },\n \"description\": null,\n \"image\": {\n \"UUID\": \"baf9a246-a3e2-42f7-8223-ffb482c4cdf4\",\n \"filename\": \"image-1100.jpg\",\n \"url\": \"https://perls.localhost:8000/sites/default/files/styles/large/public/2021-08/image-1100.jpg?itok=1SOz8ZZH\",\n \"original_url\": \"https://perls.localhost:8000/sites/default/files/2021-08/image-1100.jpg\"\n }\n },\n {\n \"id\": \"db55eb4d-a5e1-4431-9369-c089be94330c\",\n \"nid\": 973,\n \"vid\": 2617,\n \"url\": \"/node/973\",\n \"name\": \"Testarticle-4204\",\n \"type\": \"learn_article\",\n \"changed\": \"2021-08-05T13:44:19+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"d2b12b9c-90be-4a94-af38-71284ff12551\",\n \"name\": \"node_973.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/offline_page/node_973.zip\"\n },\n \"tags\": [\n {\n \"id\": \"3102d095-55d7-4a74-ae13-7b3fb3185cd5\",\n \"vid\": 276,\n \"tid\": 276,\n \"url\": \"/taxonomy/term/276\",\n \"name\": \"car wash\",\n \"type\": \"tags\",\n \"changed\": \"2021-08-04T19:07:52+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"4a16bc04-dca6-4ed9-9a07-af2e138ca6c0\",\n \"vid\": 213,\n \"tid\": 213,\n \"url\": \"/taxonomy/term/213\",\n \"name\": \"Content Test Suite [CTS]\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"Create a content test suite course on the dev server with example content\"\n },\n \"description\": \"Testarticle-4204\",\n \"image\": {\n \"UUID\": \"9b9a75be-d1a3-4b31-8a78-e12b467417b9\",\n \"filename\": \"SL_BlogPostCover_1.png\",\n \"url\": \"https://perls.localhost:8000/sites/default/files/styles/large/public/2020-03/SL_BlogPostCover_1.png.jpg?itok=lk9AihvE\",\n \"original_url\": \"https://perls.localhost:8000/sites/default/files/2020-03/SL_BlogPostCover_1.png\"\n },\n \"discussion_status\": \"open\"\n },\n {\n \"id\": \"254f74df-e99e-4dbe-b1b9-4888dfd55f21\",\n \"nid\": 969,\n \"vid\": 2590,\n \"url\": \"/node/969\",\n \"name\": \"TestPC\",\n \"type\": \"learn_article\",\n \"changed\": \"2021-07-30T20:22:55+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"affeb744-182d-45e0-b798-5d3d503ad1ff\",\n \"name\": \"node_969.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/offline_page/node_969.zip\"\n },\n \"tags\": [],\n \"topic\": {\n \"id\": \"4a16bc04-dca6-4ed9-9a07-af2e138ca6c0\",\n \"vid\": 213,\n \"tid\": 213,\n \"url\": \"/taxonomy/term/213\",\n \"name\": \"Content Test Suite [CTS]\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"Create a content test suite course on the dev server with example content\"\n },\n \"description\": \"TestPC\",\n \"image\": null,\n \"discussion_status\": \"open\"\n },\n {\n \"id\": \"73858ba3-64b4-44f6-83a5-ea36b00ea068\",\n \"nid\": 946,\n \"vid\": 2517,\n \"url\": \"/node/946\",\n \"name\": \"Testpower\",\n \"type\": \"learn_file\",\n \"changed\": \"2021-07-23T13:52:31+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"a8ffedfb-4858-4db9-97d5-0ec2ff92137b\",\n \"name\": \"testpower.pptx\",\n \"url\": \"https://perls.localhost:8000/system/files/2021-07/testpower.pptx\",\n \"mimetype\": \"application/vnd.openxmlformats-officedocument.presentationml.presentation\"\n },\n \"tags\": [],\n \"topic\": {\n \"id\": \"4a16bc04-dca6-4ed9-9a07-af2e138ca6c0\",\n \"vid\": 213,\n \"tid\": 213,\n \"url\": \"/taxonomy/term/213\",\n \"name\": \"Content Test Suite [CTS]\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"Create a content test suite course on the dev server with example content\"\n },\n \"description\": \"Testpower\",\n \"image\": null\n },\n {\n \"id\": \"47bed617-4d57-4840-896a-6153b0ca9a2a\",\n \"nid\": 945,\n \"vid\": 2516,\n \"url\": \"/node/945\",\n \"name\": \"TestExcel\",\n \"type\": \"learn_file\",\n \"changed\": \"2021-07-23T13:08:11+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"5afeae86-a04d-48ce-874f-3385d5992cdc\",\n \"name\": \"testexcel.xlsx\",\n \"url\": \"https://perls.localhost:8000/system/files/2021-07/testexcel.xlsx\",\n \"mimetype\": \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\"\n },\n \"tags\": [],\n \"topic\": {\n \"id\": \"4a16bc04-dca6-4ed9-9a07-af2e138ca6c0\",\n \"vid\": 213,\n \"tid\": 213,\n \"url\": \"/taxonomy/term/213\",\n \"name\": \"Content Test Suite [CTS]\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"Create a content test suite course on the dev server with example content\"\n },\n \"description\": \"TestExcel\",\n \"image\": null\n }\n ]\n },\n {\n \"name\": \"e-learning\",\n \"url\": \"/api/taxonomy/term/104\",\n \"content\": [\n {\n \"id\": \"11f46744-246c-45dc-bcc4-d22d2ee5272b\",\n \"nid\": 1007,\n \"vid\": 2700,\n \"url\": \"/node/1007\",\n \"name\": \"Untagged course containing #carwash article\",\n \"type\": \"course\",\n \"changed\": \"2021-08-18T20:16:05+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": [],\n \"topic\": {\n \"id\": \"2c22f3e4-e44c-4e36-8956-d3ae6b1a9ac8\",\n \"vid\": 104,\n \"tid\": 104,\n \"url\": \"/taxonomy/term/104\",\n \"name\": \"e-learning\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": null\n },\n \"description\": \"This course contains the article tagged with #carwash.\",\n \"learning_objects\": [\n {\n \"id\": \"a8486eba-7ea6-4118-902e-da8e212f74ff\",\n \"nid\": 1006,\n \"vid\": 2701,\n \"url\": \"/node/1006\",\n \"name\": \"Article tagged #carwash\",\n \"type\": \"learn_article\",\n \"changed\": \"2021-08-18T20:16:05+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"265a9098-72c2-40d7-b6d4-f88e7be83a65\",\n \"name\": \"node_1006.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/offline_page/node_1006.zip\"\n },\n \"tags\": [\n {\n \"id\": \"0e53228a-faf8-4eb1-ae49-ece61debe8fd\",\n \"vid\": 275,\n \"tid\": 275,\n \"url\": \"/taxonomy/term/275\",\n \"name\": \"carwash\",\n \"type\": \"tags\",\n \"changed\": \"2021-08-04T19:07:27+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"2589cea9-25b1-4c7c-bd84-51aa61c8294b\",\n \"vid\": 274,\n \"tid\": 274,\n \"url\": \"/taxonomy/term/274\",\n \"name\": \"An empty topic\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"This topic is empty.\"\n },\n \"description\": \"This article is tagged #carwash.\",\n \"image\": null,\n \"discussion_status\": \"hidden\"\n }\n ],\n \"image\": null\n },\n {\n \"id\": \"16df4272-cba2-40e1-b0ad-32156e4b8fc6\",\n \"nid\": 998,\n \"vid\": 2671,\n \"url\": \"https://perls.localhost:8000/system/files/2021-08/xapi_500mb_incompressible/index.html?endpoint=https%3A//perls.localhost:8000/lrs/&auth=none&actor=%7B%22objectType%22%3A%22Agent%22%2C%22name%22%3A%22John%20Doe%22%2C%22account%22%3A%7B%22name%22%3A%222455a7ba-4935-4a0c-a34b-67b595915a37%22%2C%22homePage%22%3A%22https%3A%5C/%5C/perls.localhost:8000%22%7D%7D&activity_id=https%3A//perls.localhost:8000/node/998&activity_platform=PERLS\",\n \"name\": \"xAPI 500MB\",\n \"type\": \"learn_package\",\n \"changed\": \"2021-08-12T15:27:33+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"6f21b55f-9084-43c5-bc4e-dbdf05faa96a\",\n \"name\": \"xapi_500mb_incompressible.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/2021-08/xapi_500mb_incompressible.zip\",\n \"mimetype\": \"application/zip\"\n },\n \"tags\": [],\n \"topic\": {\n \"id\": \"2c22f3e4-e44c-4e36-8956-d3ae6b1a9ac8\",\n \"vid\": 104,\n \"tid\": 104,\n \"url\": \"/taxonomy/term/104\",\n \"name\": \"e-learning\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": null\n },\n \"description\": \"This xAPI content is 500 megabytes before and after unzipping.\",\n \"image\": {\n \"UUID\": \"4b9a915a-db2b-40a5-9b86-bbe992b61a97\",\n \"filename\": \"photofunia-1628781669.jpg\",\n \"url\": \"https://perls.localhost:8000/sites/default/files/styles/large/public/2021-08/photofunia-1628781669.jpg?itok=r1N0J5k5\",\n \"original_url\": \"https://perls.localhost:8000/sites/default/files/2021-08/photofunia-1628781669.jpg\"\n }\n },\n {\n \"id\": \"bc732155-7117-4daf-8bdb-392771d3a30d\",\n \"nid\": 988,\n \"vid\": 2658,\n \"url\": \"https://perls.localhost:8000/system/files/2021-08/xapi_300mb_incompressible/index.html?endpoint=https%3A//perls.localhost:8000/lrs/&auth=none&actor=%7B%22objectType%22%3A%22Agent%22%2C%22name%22%3A%22John%20Doe%22%2C%22account%22%3A%7B%22name%22%3A%222455a7ba-4935-4a0c-a34b-67b595915a37%22%2C%22homePage%22%3A%22https%3A%5C/%5C/perls.localhost:8000%22%7D%7D&activity_id=https%3A//perls.localhost:8000/node/988&activity_platform=PERLS\",\n \"name\": \"xAPI 300MB\",\n \"type\": \"learn_package\",\n \"changed\": \"2021-08-11T15:12:58+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"d63e82dd-318c-4148-a6bf-e18a109ab9f8\",\n \"name\": \"xapi_300mb_incompressible.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/2021-08/xapi_300mb_incompressible.zip\",\n \"mimetype\": \"application/zip\"\n },\n \"tags\": [],\n \"topic\": {\n \"id\": \"2c22f3e4-e44c-4e36-8956-d3ae6b1a9ac8\",\n \"vid\": 104,\n \"tid\": 104,\n \"url\": \"/taxonomy/term/104\",\n \"name\": \"e-learning\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": null\n },\n \"description\": \"This xAPI content is 300 megabytes before and after unzipping.\",\n \"image\": {\n \"UUID\": \"6ce9e52d-257f-4a92-9005-afd3bcdab632\",\n \"filename\": \"photofunia-1628607670.jpg\",\n \"url\": \"https://perls.localhost:8000/sites/default/files/styles/large/public/2021-08/photofunia-1628607670.jpg?itok=tmcAPAxY\",\n \"original_url\": \"https://perls.localhost:8000/sites/default/files/2021-08/photofunia-1628607670.jpg\"\n }\n },\n {\n \"id\": \"a46bc804-7000-4785-a822-e6f156be8ef0\",\n \"nid\": 987,\n \"vid\": 2657,\n \"url\": \"https://perls.localhost:8000/system/files/2021-08/xapi_100mb_incompressible/index.html?endpoint=https%3A//perls.localhost:8000/lrs/&auth=none&actor=%7B%22objectType%22%3A%22Agent%22%2C%22name%22%3A%22John%20Doe%22%2C%22account%22%3A%7B%22name%22%3A%222455a7ba-4935-4a0c-a34b-67b595915a37%22%2C%22homePage%22%3A%22https%3A%5C/%5C/perls.localhost:8000%22%7D%7D&activity_id=https%3A//perls.localhost:8000/node/987&activity_platform=PERLS\",\n \"name\": \"xAPI 100MB\",\n \"type\": \"learn_package\",\n \"changed\": \"2021-08-11T15:11:19+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"31e9e91f-43ad-4109-9ad3-4550d362a4a7\",\n \"name\": \"xapi_100mb_incompressible.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/2021-08/xapi_100mb_incompressible.zip\",\n \"mimetype\": \"application/zip\"\n },\n \"tags\": [],\n \"topic\": {\n \"id\": \"2c22f3e4-e44c-4e36-8956-d3ae6b1a9ac8\",\n \"vid\": 104,\n \"tid\": 104,\n \"url\": \"/taxonomy/term/104\",\n \"name\": \"e-learning\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": null\n },\n \"description\": \"This xAPI content is 100 megabytes before and after unzipping.\",\n \"image\": {\n \"UUID\": \"d029031c-6bfa-45d0-b8f2-cc329112328d\",\n \"filename\": \"photofunia-1628607792.jpg\",\n \"url\": \"https://perls.localhost:8000/sites/default/files/styles/large/public/2021-08/photofunia-1628607792.jpg?itok=Axt__rLK\",\n \"original_url\": \"https://perls.localhost:8000/sites/default/files/2021-08/photofunia-1628607792.jpg\"\n }\n },\n {\n \"id\": \"f6f3093d-b370-499e-8b35-c28230267648\",\n \"nid\": 986,\n \"vid\": 2656,\n \"url\": \"https://perls.localhost:8000/system/files/2021-08/xapi_50mb_incompressible/index.html?endpoint=https%3A//perls.localhost:8000/lrs/&auth=none&actor=%7B%22objectType%22%3A%22Agent%22%2C%22name%22%3A%22John%20Doe%22%2C%22account%22%3A%7B%22name%22%3A%222455a7ba-4935-4a0c-a34b-67b595915a37%22%2C%22homePage%22%3A%22https%3A%5C/%5C/perls.localhost:8000%22%7D%7D&activity_id=https%3A//perls.localhost:8000/node/986&activity_platform=PERLS\",\n \"name\": \"xAPI 50MB\",\n \"type\": \"learn_package\",\n \"changed\": \"2021-08-11T15:10:38+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"915eaa34-c1cd-42bf-ad55-2f5b3480e9df\",\n \"name\": \"xapi_50mb_incompressible.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/2021-08/xapi_50mb_incompressible.zip\",\n \"mimetype\": \"application/zip\"\n },\n \"tags\": [],\n \"topic\": {\n \"id\": \"2c22f3e4-e44c-4e36-8956-d3ae6b1a9ac8\",\n \"vid\": 104,\n \"tid\": 104,\n \"url\": \"/taxonomy/term/104\",\n \"name\": \"e-learning\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": null\n },\n \"description\": \"This xAPI content is 50 megabytes before and after unzipping.\",\n \"image\": {\n \"UUID\": \"e0ac0fb7-8744-4691-9a0d-289e38555037\",\n \"filename\": \"photofunia-1628607749.jpg\",\n \"url\": \"https://perls.localhost:8000/sites/default/files/styles/large/public/2021-08/photofunia-1628607749.jpg?itok=tuXW2J0I\",\n \"original_url\": \"https://perls.localhost:8000/sites/default/files/2021-08/photofunia-1628607749.jpg\"\n }\n },\n {\n \"id\": \"6f9c4027-6afd-4e33-925b-8a6007a44c39\",\n \"nid\": 976,\n \"vid\": 2612,\n \"url\": \"/node/976\",\n \"name\": \"Article tagged with spaces\",\n \"type\": \"learn_article\",\n \"changed\": \"2021-08-04T19:16:31+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"da3c00dc-092c-453e-a498-ea953004b721\",\n \"name\": \"node_976.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/offline_page/node_976.zip\"\n },\n \"tags\": [\n {\n \"id\": \"3102d095-55d7-4a74-ae13-7b3fb3185cd5\",\n \"vid\": 276,\n \"tid\": 276,\n \"url\": \"/taxonomy/term/276\",\n \"name\": \"car wash\",\n \"type\": \"tags\",\n \"changed\": \"2021-08-04T19:07:52+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"2c22f3e4-e44c-4e36-8956-d3ae6b1a9ac8\",\n \"vid\": 104,\n \"tid\": 104,\n \"url\": \"/taxonomy/term/104\",\n \"name\": \"e-learning\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": null\n },\n \"description\": \"The tag has spaces.\",\n \"image\": null,\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"486ffbc9-ad10-4358-a625-708100133d12\",\n \"nid\": 967,\n \"vid\": 2582,\n \"url\": \"/node/967\",\n \"name\": \"NEW CONTENT TO DRAFT STATUS\",\n \"type\": \"learn_article\",\n \"changed\": \"2021-07-30T15:29:36+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"da97e569-d5b7-4e2c-8703-c6d4975cfd68\",\n \"name\": \"node_967.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/offline_page/node_967.zip\"\n },\n \"tags\": [\n {\n \"id\": \"54db0a3d-4696-4061-bbb6-e8cc905145b5\",\n \"vid\": 215,\n \"tid\": 215,\n \"url\": \"/taxonomy/term/215\",\n \"name\": \"Content Test Suite\",\n \"type\": \"tags\",\n \"changed\": \"2021-04-01T15:54:53+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"2c22f3e4-e44c-4e36-8956-d3ae6b1a9ac8\",\n \"vid\": 104,\n \"tid\": 104,\n \"url\": \"/taxonomy/term/104\",\n \"name\": \"e-learning\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": null\n },\n \"description\": \"NEW CONTENT TO DRAFT STATUS\",\n \"image\": null,\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"b36db13e-cbad-4a54-aa6b-7ee7c0d6d3f2\",\n \"nid\": 966,\n \"vid\": 2583,\n \"url\": \"/node/966\",\n \"name\": \"NEW CONTENT TO DRAFT STATUS\",\n \"type\": \"learn_article\",\n \"changed\": \"2021-07-30T15:29:36+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"71e1687b-a4ae-41b1-956a-dad3ce654e90\",\n \"name\": \"node_966.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/offline_page/node_966.zip\"\n },\n \"tags\": [\n {\n \"id\": \"54db0a3d-4696-4061-bbb6-e8cc905145b5\",\n \"vid\": 215,\n \"tid\": 215,\n \"url\": \"/taxonomy/term/215\",\n \"name\": \"Content Test Suite\",\n \"type\": \"tags\",\n \"changed\": \"2021-04-01T15:54:53+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"2c22f3e4-e44c-4e36-8956-d3ae6b1a9ac8\",\n \"vid\": 104,\n \"tid\": 104,\n \"url\": \"/taxonomy/term/104\",\n \"name\": \"e-learning\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": null\n },\n \"description\": \"NEW CONTENT TO DRAFT STATUS\",\n \"image\": null,\n \"discussion_status\": \"hidden\"\n },\n {\n \"id\": \"1d5a0470-b6f0-4f37-852a-8734442c92b4\",\n \"nid\": 952,\n \"vid\": 2543,\n \"url\": \"/node/952\",\n \"name\": \"Test tip card\",\n \"type\": \"tip_card\",\n \"changed\": \"2021-07-27T14:25:05+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": [\n {\n \"id\": \"ef027507-dd23-496c-a5f1-60455ca0f913\",\n \"vid\": 272,\n \"tid\": 272,\n \"url\": \"/taxonomy/term/272\",\n \"name\": \"soldier\",\n \"type\": \"tags\",\n \"changed\": \"2021-07-27T14:25:05+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"2c22f3e4-e44c-4e36-8956-d3ae6b1a9ac8\",\n \"vid\": 104,\n \"tid\": 104,\n \"url\": \"/taxonomy/term/104\",\n \"name\": \"e-learning\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": null\n },\n \"contents\": [\n \"
\\n \\n

This xAPI content is 100 megabytes before and after unzipping.

\\n \\n

Test the TIP Card

\\n

Test the TIP Card

\\n

 

\\n
\\n \\n
\\n\"\n ],\n \"body\": [\n {\n \"id\": \"a82a4950-0251-4af4-b772-15084609c369\",\n \"type\": \"text\",\n \"fields\": [\n {\n \"type\": \"Label\",\n \"attributes\": {\n \"Text\": \"

Test the TIP Card

\\r\\n\\r\\n

Test the TIP Card

\\r\\n\\r\\n

 

\",\n \"TextType\": \"Html\"\n }\n }\n ]\n }\n ]\n },\n {\n \"id\": \"401e2e50-97ba-4275-bdf9-9da3c95078c7\",\n \"nid\": 415,\n \"vid\": 1173,\n \"url\": \"/node/415\",\n \"name\": \"New web link under CONTENT\",\n \"type\": \"learn_link\",\n \"changed\": \"2021-03-16T15:28:12+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": [\n {\n \"id\": \"cc163d39-95be-46b1-920d-2f50eb8e2897\",\n \"vid\": 130,\n \"tid\": 130,\n \"url\": \"/taxonomy/term/130\",\n \"name\": \"John\",\n \"type\": \"tags\",\n \"changed\": \"2020-12-08T21:05:16+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"c83bf669-87e5-42c1-979a-7c132231759c\",\n \"vid\": 89,\n \"tid\": 89,\n \"url\": \"/taxonomy/term/89\",\n \"name\": \"mLearning\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"Content related to Mobile Learning principles, methods, design, development, and use.\"\n },\n \"description\": \"TEST\",\n \"image\": null\n },\n {\n \"id\": \"5468222a-e5f1-4275-a204-d2d1b30a5569\",\n \"nid\": 377,\n \"vid\": 738,\n \"url\": \"/node/377\",\n \"name\": \"A CLINICAL REVIEW OF MOBILE LEARNING INTEGRATION IN FORMAL EDUCATIONAL CONTEXTS\",\n \"type\": \"course\",\n \"changed\": \"2020-12-14T15:20:04+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": [\n {\n \"id\": \"b74951dc-27a6-4df8-9d03-83ee8cea920f\",\n \"vid\": 107,\n \"tid\": 107,\n \"url\": \"/taxonomy/term/107\",\n \"name\": \"CreatenewTags\",\n \"type\": \"tags\",\n \"changed\": \"2020-06-11T20:11:55+0000\"\n }\n ],\n \"topic\": {\n \"id\": \"c83bf669-87e5-42c1-979a-7c132231759c\",\n \"vid\": 89,\n \"tid\": 89,\n \"url\": \"/taxonomy/term/89\",\n \"name\": \"mLearning\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"Content related to Mobile Learning principles, methods, design, development, and use.\"\n },\n \"description\": \"n army (from Latin arma \\\"arms, weapons\\\" via Old French armée, \\\"armed\\\" [feminine]), ground force or land force is a fighting force that fights primarily on land. In the broadest sense, it is the land-based military branch, service branch or armed service of a nation or state. It may also include aviation assets by possessing an army aviation component. Within a national military force, the word army may also mean a field army.\\r\\nn army (from Latin arma \\\"arms, weapons\\\" via Old French armée\",\n \"learning_objects\": [\n {\n \"id\": \"79d5e384-7800-4eba-aa54-2013be65db2e\",\n \"nid\": 375,\n \"vid\": 732,\n \"url\": \"/node/375\",\n \"name\": \"John Test Episode 2\",\n \"type\": \"podcast_episode\",\n \"changed\": \"2020-12-11T20:34:19+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"a490f888-82ef-46d5-8739-0feabc749241\",\n \"name\": \"file_example_mp3_1mg_4.mp3\",\n \"url\": \"https://perls.localhost:8000/sites/default/files/podcasts/2020-12/file_example_mp3_1mg_4.mp3\",\n \"mimetype\": \"audio/mpeg\"\n },\n \"tags\": [],\n \"description\": null,\n \"duration\": 27,\n \"release_date\": \"2020-12-11\"\n }\n ],\n \"image\": null\n }\n ]\n }\n]" + } + ] + }, + { + "name": "Bookmarks", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/bookmarks", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "bookmarks" + ] + }, + "description": "List of Recommendations for currently logged in user" + }, + "response": [ + { + "name": "Bookmarks", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/bookmarks", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "bookmarks" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Date", + "value": "Wed, 01 Sep 2021 20:48:12 GMT" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Content-Length", + "value": "1679" + }, + { + "key": "Connection", + "value": "keep-alive" + }, + { + "key": "Set-Cookie", + "value": "AWSALB=GbbfW+94C+dDveixpwQCjwbf8iNuW6C1pvAynYMUgtwccRAB6X+pbSyi0iyag9/AYugEYLUH5Mf2Hq46OxJrE0FwnGPW5HTn96xoIE4e3AbAdeEbkqRLwbeRvN/A; Expires=Wed, 08 Sep 2021 20:48:12 GMT; Path=/" + }, + { + "key": "Set-Cookie", + "value": "AWSALBCORS=GbbfW+94C+dDveixpwQCjwbf8iNuW6C1pvAynYMUgtwccRAB6X+pbSyi0iyag9/AYugEYLUH5Mf2Hq46OxJrE0FwnGPW5HTn96xoIE4e3AbAdeEbkqRLwbeRvN/A; Expires=Wed, 08 Sep 2021 20:48:12 GMT; Path=/; SameSite=None; Secure" + }, + { + "key": "Server", + "value": "Apache" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "Cache-Control", + "value": "must-revalidate, no-cache, private" + }, + { + "key": "X-Drupal-Dynamic-Cache", + "value": "MISS" + }, + { + "key": "X-UA-Compatible", + "value": "IE=edge" + }, + { + "key": "Content-language", + "value": "en" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "Permissions-Policy", + "value": "interest-cohort=()" + }, + { + "key": "Expires", + "value": "Sun, 19 Nov 1978 05:00:00 GMT" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubdomains; preload" + }, + { + "key": "X-XSS-Protection", + "value": "1; mode=block" + } + ], + "cookie": [], + "body": "[\n {\n \"id\": \"a055fba8-332a-4933-ae5b-dc301e42ab82\",\n \"nid\": 1022,\n \"vid\": 2741,\n \"url\": \"/node/1022\",\n \"name\": \"Virtual Event\",\n \"type\": \"event\",\n \"changed\": \"2021-08-31T17:41:29+0000\",\n \"is_promoted\": true,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": [\n {\n \"id\": \"ebc14d90-2ad9-4bcb-a7fd-7454efb25d55\",\n \"vid\": 283,\n \"tid\": 283,\n \"url\": \"/taxonomy/term/283\",\n \"name\": \"event\",\n \"type\": \"tags\",\n \"changed\": \"2021-08-27T07:15:27+0000\"\n }\n ]\n },\n {\n \"id\": \"47ffbab9-1bd9-4518-b290-99524efd29ee\",\n \"nid\": 1019,\n \"vid\": 2733,\n \"url\": \"/node/1019\",\n \"name\": \"Testcourse-1\",\n \"type\": \"course\",\n \"changed\": \"2021-08-27T00:07:21+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": [],\n \"topic\": {\n \"id\": \"4a16bc04-dca6-4ed9-9a07-af2e138ca6c0\",\n \"vid\": 213,\n \"tid\": 213,\n \"url\": \"/taxonomy/term/213\",\n \"name\": \"Content Test Suite [CTS]\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"Create a content test suite course on the dev server with example content\"\n },\n \"description\": null,\n \"learning_objects\": [\n {\n \"id\": \"0cf81d2a-b4d3-4a1e-858c-598ff0b5a626\",\n \"nid\": 1020,\n \"vid\": 2731,\n \"url\": \"/node/1020\",\n \"name\": \"Testarticle---\",\n \"type\": \"learn_article\",\n \"changed\": \"2021-08-27T00:04:52+0000\",\n \"is_promoted\": false,\n \"is_sticky\": false,\n \"file\": {\n \"id\": \"530f3550-ead3-4570-8806-f5c6e749de55\",\n \"name\": \"node_1020.zip\",\n \"url\": \"https://perls.localhost:8000/system/files/offline_page/node_1020.zip\"\n },\n \"tags\": [],\n \"topic\": {\n \"id\": \"4a16bc04-dca6-4ed9-9a07-af2e138ca6c0\",\n \"vid\": 213,\n \"tid\": 213,\n \"url\": \"/taxonomy/term/213\",\n \"name\": \"Content Test Suite [CTS]\",\n \"type\": \"category\",\n \"changed\": \"2021-08-31T22:44:06+0000\",\n \"description\": \"Create a content test suite course on the dev server with example content\"\n },\n \"description\": null,\n \"image\": null,\n \"discussion_status\": \"hidden\"\n }\n ],\n \"image\": null\n }\n]" + } + ] + }, + { + "name": "Followed Channels", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/channels", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "channels" + ] + }, + "description": "Get followed content for the current user" + }, + "response": [] + }, + { + "name": "History", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/history", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "history" + ] + }, + "description": "List of History for currently logged in user" + }, + "response": [ + { + "name": "History", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/history", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "history" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Date", + "value": "Wed, 01 Sep 2021 20:48:45 GMT" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Content-Length", + "value": "385" + }, + { + "key": "Connection", + "value": "keep-alive" + }, + { + "key": "Set-Cookie", + "value": "AWSALB=iv3HLD40Em4VSIg7nqVzyhoRmK0qz0H9iuw805KxqI+72QhfCYA+xdO9zjGqJsQ39sHD3wr7EdtW0+lRnWCu7E5jSSk7HzMKWuISZ83LTRcnNz6aAK2gC6D+xDDa; Expires=Wed, 08 Sep 2021 20:48:44 GMT; Path=/" + }, + { + "key": "Set-Cookie", + "value": "AWSALBCORS=iv3HLD40Em4VSIg7nqVzyhoRmK0qz0H9iuw805KxqI+72QhfCYA+xdO9zjGqJsQ39sHD3wr7EdtW0+lRnWCu7E5jSSk7HzMKWuISZ83LTRcnNz6aAK2gC6D+xDDa; Expires=Wed, 08 Sep 2021 20:48:44 GMT; Path=/; SameSite=None; Secure" + }, + { + "key": "Server", + "value": "Apache" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "Cache-Control", + "value": "must-revalidate, no-cache, private" + }, + { + "key": "X-Drupal-Dynamic-Cache", + "value": "UNCACHEABLE" + }, + { + "key": "X-UA-Compatible", + "value": "IE=edge" + }, + { + "key": "Content-language", + "value": "en" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "Permissions-Policy", + "value": "interest-cohort=()" + }, + { + "key": "Expires", + "value": "Sun, 19 Nov 1978 05:00:00 GMT" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubdomains; preload" + }, + { + "key": "X-XSS-Protection", + "value": "1; mode=block" + } + ], + "cookie": [], + "body": "[\n {\n \"id\": \"a055fba8-332a-4933-ae5b-dc301e42ab82\",\n \"nid\": 1022,\n \"vid\": 2741,\n \"url\": \"/node/1022\",\n \"name\": \"Virtual Event\",\n \"type\": \"event\",\n \"changed\": \"2021-08-31T17:41:29+0000\",\n \"is_promoted\": true,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": [\n {\n \"id\": \"ebc14d90-2ad9-4bcb-a7fd-7454efb25d55\",\n \"vid\": 283,\n \"tid\": 283,\n \"url\": \"/taxonomy/term/283\",\n \"name\": \"event\",\n \"type\": \"tags\",\n \"changed\": \"2021-08-27T07:15:27+0000\"\n }\n ]\n }\n]" + } + ] + }, + { + "name": "Feature Switches", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/switches", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "switches" + ] + }, + "description": "List of configuration settings (like feature flags) for currently logged in user" + }, + "response": [ + { + "name": "Feature Switches", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/switches", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "switches" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Date", + "value": "Wed, 01 Sep 2021 20:48:53 GMT" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Content-Length", + "value": "222" + }, + { + "key": "Connection", + "value": "keep-alive" + }, + { + "key": "Set-Cookie", + "value": "AWSALB=rsW9s7uLNtnSb8l8pBmA1QKmIzuOU69tOOxSbkXpQGCn0pkndkmsxge6WY9vSxMxiXkqV7XeJeTOVhDp/ecPg0oQr7Oed4gFhX/40VU2S4r+5h0shTK9NHt8yyLM; Expires=Wed, 08 Sep 2021 20:48:53 GMT; Path=/" + }, + { + "key": "Set-Cookie", + "value": "AWSALBCORS=rsW9s7uLNtnSb8l8pBmA1QKmIzuOU69tOOxSbkXpQGCn0pkndkmsxge6WY9vSxMxiXkqV7XeJeTOVhDp/ecPg0oQr7Oed4gFhX/40VU2S4r+5h0shTK9NHt8yyLM; Expires=Wed, 08 Sep 2021 20:48:53 GMT; Path=/; SameSite=None; Secure" + }, + { + "key": "Server", + "value": "Apache" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "Cache-Control", + "value": "must-revalidate, no-cache, private" + }, + { + "key": "X-Drupal-Dynamic-Cache", + "value": "HIT" + }, + { + "key": "X-UA-Compatible", + "value": "IE=edge" + }, + { + "key": "Content-language", + "value": "en" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "Permissions-Policy", + "value": "interest-cohort=()" + }, + { + "key": "Expires", + "value": "Sun, 19 Nov 1978 05:00:00 GMT" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubdomains; preload" + }, + { + "key": "X-XSS-Protection", + "value": "1; mode=block" + } + ], + "cookie": [], + "body": "{\n \"switches\": {\n \"achievements\": {\n \"status\": true\n },\n \"adaptive_learning\": {\n \"status\": true\n },\n \"new_dashboard\": {\n \"status\": true\n },\n \"offline_support\": {\n \"status\": true\n },\n \"podcast_support\": {\n \"status\": true\n },\n \"user_generated_content\": {\n \"status\": true\n }\n }\n}" + } + ] + }, + { + "name": "Taxonomy", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/taxonomy/term/55", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "taxonomy", + "term", + "55" + ] + }, + "description": "List of nodes in the specified taxonomy term" + }, + "response": [ + { + "name": "Taxonomy", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/taxonomy/term/283", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "taxonomy", + "term", + "283" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Date", + "value": "Wed, 01 Sep 2021 20:49:27 GMT" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Content-Length", + "value": "385" + }, + { + "key": "Connection", + "value": "keep-alive" + }, + { + "key": "Set-Cookie", + "value": "AWSALB=8jTUUzoff5KEbdkRfFJOl4/j9RR9PfLKT7kGO78giYIHABmPfKTad+BnsI204EwDsrYVG+KVKDXxofh9qeX/e6sox0JPI2FA1KP1N+fM6HELnjLoS7jS9JBmH+Au; Expires=Wed, 08 Sep 2021 20:49:27 GMT; Path=/" + }, + { + "key": "Set-Cookie", + "value": "AWSALBCORS=8jTUUzoff5KEbdkRfFJOl4/j9RR9PfLKT7kGO78giYIHABmPfKTad+BnsI204EwDsrYVG+KVKDXxofh9qeX/e6sox0JPI2FA1KP1N+fM6HELnjLoS7jS9JBmH+Au; Expires=Wed, 08 Sep 2021 20:49:27 GMT; Path=/; SameSite=None; Secure" + }, + { + "key": "Server", + "value": "Apache" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "Cache-Control", + "value": "must-revalidate, no-cache, private" + }, + { + "key": "X-Drupal-Dynamic-Cache", + "value": "MISS" + }, + { + "key": "X-UA-Compatible", + "value": "IE=edge" + }, + { + "key": "Content-language", + "value": "en" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "Permissions-Policy", + "value": "interest-cohort=()" + }, + { + "key": "Expires", + "value": "Sun, 19 Nov 1978 05:00:00 GMT" + }, + { + "key": "Strict-Transport-Security", + "value": "max-age=31536000; includeSubdomains; preload" + }, + { + "key": "X-XSS-Protection", + "value": "1; mode=block" + } + ], + "cookie": [], + "body": "[\n {\n \"id\": \"a055fba8-332a-4933-ae5b-dc301e42ab82\",\n \"nid\": 1022,\n \"vid\": 2741,\n \"url\": \"/node/1022\",\n \"name\": \"Virtual Event\",\n \"type\": \"event\",\n \"changed\": \"2021-08-31T17:41:29+0000\",\n \"is_promoted\": true,\n \"is_sticky\": false,\n \"file\": null,\n \"tags\": [\n {\n \"id\": \"ebc14d90-2ad9-4bcb-a7fd-7454efb25d55\",\n \"vid\": 283,\n \"tid\": 283,\n \"url\": \"/taxonomy/term/283\",\n \"name\": \"event\",\n \"type\": \"tags\",\n \"changed\": \"2021-08-27T07:15:27+0000\"\n }\n ]\n }\n]" + } + ] + }, + { + "name": "Taxonomy, page 2", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/taxonomy/term/55?page=1", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "taxonomy", + "term", + "55" + ], + "query": [ + { + "key": "page", + "value": "1" + } + ] + }, + "description": "List of nodes in the specified taxonomy term, second page" + }, + "response": [] + }, + { + "name": "Prompts", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/api/prompts", + "host": [ + "{{server}}" + ], + "path": [ + "api", + "prompts" + ] + } + }, + "response": [] + }, + { + "name": "Current User goals update", + "request": { + "method": "PATCH", + "header": [], + "body": { + "mode": "raw", + "raw": "{\n \"id\": \"be7559d4-48b0-4ed4-af08-b47c52e19bf6\",\n \"goals\": {\n \"notification_days\": [\n \"sunday\",\n \"monday\",\n \"tuesday\"\n ],\n \"weekly_test_average\": \"42%\",\n \"monthly_course_completions\": 5,\n \"weekly_completions\": 2,\n \"weekly_views\": 3,\n \"notification_time\": \"11:32 AM\"\n }\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{server}}/{{base_url}}/user/me", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "user", + "me" + ] + } + }, + "response": [] + }, + { + "name": "Podcasts", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/podcasts", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "podcasts" + ] + } + }, + "response": [] + }, + { + "name": "Podcast Episode", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/podcasts/%uuid/episodes", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "podcasts", + "%uuid", + "episodes" + ] + } + }, + "response": [] + }, + { + "name": "Dashboard", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/dashboard", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "dashboard" + ] + }, + "description": "Retrieve a list of contents of dashboard." + }, + "response": [ + { + "name": "Dashboard", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "{{server}}/{{base_url}}/dashboard", + "host": [ + "{{server}}" + ], + "path": [ + "{{base_url}}", + "dashboard" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Cache-Control", + "value": "must-revalidate, no-cache, private" + }, + { + "key": "Content-Encoding", + "value": "gzip" + }, + { + "key": "Content-Language", + "value": "en" + }, + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Date", + "value": "Wed, 26 May 2021 10:24:02 GMT" + }, + { + "key": "Expires", + "value": "Sun, 19 Nov 1978 05:00:00 GMT" + }, + { + "key": "Server", + "value": "nginx" + }, + { + "key": "Vary", + "value": "Accept-Encoding" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Drupal-Cache-Contexts", + "value": "languages:language_interface user" + }, + { + "key": "X-Drupal-Cache-Max-Age", + "value": "-1 (Permanent)" + }, + { + "key": "X-Drupal-Cache-Tags", + "value": "config:rest.resource.site_dashboard_resource http_response page_manager_route_name:rest.site_dashboard_resource.GET" + }, + { + "key": "X-Drupal-Dynamic-Cache", + "value": "MISS" + }, + { + "key": "X-Frame-Options", + "value": "SAMEORIGIN" + }, + { + "key": "X-Generator", + "value": "Drupal 9 (https://www.drupal.org)" + }, + { + "key": "X-Ua-Compatible", + "value": "IE=edge" + }, + { + "key": "X-Xss-Protection", + "value": "1; mode=block" + }, + { + "key": "Content-Length", + "value": "227" + } + ], + "cookie": [], + "body": "[\n {\n \"layout\": \"layout_onecol\",\n \"blocks\": [\n {\n \"name\": \"My groups\",\n \"entity\": \"group\",\n \"template\": \"chip\",\n \"contents_url\": \"/api/groups\"\n }\n ]\n },\n {\n \"layout\": \"tabs\",\n \"blocks\": [\n {\n \"name\": \"Recommended Content\",\n \"entity\": \"node\",\n \"template\": \"card\",\n \"contents_url\": \"/api/recommendations\"\n },\n {\n \"name\": \"Recent Content\",\n \"entity\": \"node\",\n \"template\": \"tile\",\n \"contents_url\": \"/api/recent\"\n },\n {\n \"name\": \"Trending\",\n \"entity\": \"node\",\n \"template\": \"card\",\n \"contents_url\": \"/api/trending\"\n }\n ]\n },\n {\n \"layout\": \"layout_onecol\",\n \"blocks\": [\n {\n \"name\": \"Recently viewed\",\n \"entity\": \"node\",\n \"template\": \"tile\",\n \"contents_url\": \"/api/history\"\n }\n ]\n }\n]" + } + ] + } + ], + "auth": { + "type": "oauth2", + "oauth2": [ + { + "key": "accessTokenUrl", + "value": "{{server}}/oauth/token", + "type": "string" + }, + { + "key": "redirect_uri", + "value": "https://example.com/auth", + "type": "string" + }, + { + "key": "tokenType", + "value": "Bearer", + "type": "string" + }, + { + "key": "accessToken", + "value": "", + "type": "string" + }, + { + "key": "clientSecret", + "value": "{{client_secret}}", + "type": "string" + }, + { + "key": "clientId", + "value": "{{client_id}}", + "type": "string" + }, + { + "key": "authUrl", + "value": "{{server}}/oauth/authorize", + "type": "string" + }, + { + "key": "useBrowser", + "value": false, + "type": "boolean" + }, + { + "key": "addTokenTo", + "value": "header", + "type": "string" + } + ] + }, + "event": [ + { + "listen": "prerequest", + "script": { + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ] +} \ No newline at end of file diff --git a/readme/maintenance.md b/readme/maintenance.md new file mode 100644 index 0000000..697ae65 --- /dev/null +++ b/readme/maintenance.md @@ -0,0 +1,62 @@ +# Maintenance +The system administrator may perform the several tasks using the web application. Below highlight tasks significant to set up, maintain, and debug the system. All tasks assume the user is logged into the web application and has the proper permission. +## Edit system name +1. Go to Configuration in the top menu. +2. Find the System category and go to Site Information. +3. Edit the Site Name field. +4. Save the changes. + +## Adding System Admin User +1. Go to People in the top menu. +2. Go to Add User +3. Fill out required fields in form +4. Ensure user has role of SysAdmin +5. Save the changes. + +## Removing System Admin User +1. Go to People in the top menu. +2. Find or search for the user +3. Cancel Account and confirm + +## Manually Execute Cron +1. Go to Configuration in the top menu. +2. Find the System category and go to Cron. +3. Run cron + +## Clear System Cache +1. Go to Configuration in the top menu. +2. Find the Development category and go to Performance. +3. Clear all caches + +## Take System Offline for Maintenance +1. Go to Configuration in the top menu. +2. Find the Development category and go to Maintenance mode +3. Check the “Put site into maintenance mode” box to put the site offline +4. Save the changes. + +## Put System Online from Maintenance +1. Go to Configuration in the top menu. +2. Find the Development category and go to Maintenance mode +3. Un-check the “Put site into maintenance mode” box to put the site offline +4. Save the changes. + +## View System Status Report +1. Go to Reports in the top menu. +2. Go to Status report + +## View System Logs +1. Go to Reports in the top menu. +2. Go to Recent log messages + +## Manage Target LRS Endpoints +1. Go to Configuration in the top menu. +2. Find the System category and go to XAPI Content +3. Fill out the required fields +4. Save the changes. + +## Manage Recommendation Plugins +1. Go to Configuration in the top menu. +2. Find the System category and go to Recommendations Engine Configuration +3. Update the required fields +4. Save the changes. + diff --git a/readme/perls_tenants.md b/readme/perls_tenants.md new file mode 100644 index 0000000..98272b9 --- /dev/null +++ b/readme/perls_tenants.md @@ -0,0 +1,18 @@ +#Tenant Deployment Processes + +##New Tenant Deploy +1. SSH in the utility.perls.usalearning.net as the centos. Only administrators with explicitly allowed IP addresses and the centos private key will be able to login. +2. Change directory to /home/centos/perls. "cd /home/centos/perls" +3. Create the tenant.env file based on the scripts/perls_tenants/sample_tenant.env file. +4. Run the command "bash make_tenant.sh". + +##Tenant Update +1. SSH in the utility.perls.usalearning.net as the centos. Only administrators with explicitly allowed IP addresses and the centos private key will be able to login. +2. Change directory in the the tenant's home directory. "cd /var/www/" +3. Update the VERSION variable to the version of the CMS you are upgrading to. +4. Run the command "bash scripts/perls_tenants/bash update_tenant.sh" + +##Tenant Deletion +1. SSH in the utility.perls.usalearning.net as the centos. Only administrators with explicitly allowed IP addresses and the centos private key will be able to login. +2. Change directory to /home/centos/perls. "cd /home/centos/perls" +3. Run the command "bash delete_tenant.sh " diff --git a/readme/security.md b/readme/security.md new file mode 100644 index 0000000..2bcf13f --- /dev/null +++ b/readme/security.md @@ -0,0 +1,11 @@ +# Security + +## Drupal +Drupal has been proven to be reliable and fight against critical internet vulnerabilities. Go here for more information about [Drupal Security](https://www.drupal.org/features/security). + +In general the best way to stay protected is by keeping the system up to date. Drupal has checks on the [Status Report](./maintenance.md#View-System-Status-Report) to ensure you are up to date. + +## REST API +The REST API is necessary for the mobile application to communicate with the web application. It uses oAuth2 to authenticate requests using the [Simple oAuth module](https://www.drupal.org/project/simple_oauth). To be secure, it is necessary the public and private keys this modules uses are not accessible via the web. + +Users request OAuth tokens via the `/login` endpoint. These tokens have an expiration time, which can be set by the System Administrator. The tokens can be revoked manually by the System Administrator. diff --git a/readme/troubleshooting.md b/readme/troubleshooting.md new file mode 100644 index 0000000..9fd9f2c --- /dev/null +++ b/readme/troubleshooting.md @@ -0,0 +1,33 @@ +# Troubleshooting + +## Build script fails + +If the `build.sh` script fails with a database message, running it a second time may work. + +## Drupal Warning - Permissions + +There may be permissions issues running on MacOS; there are slightly different permissions +between the Linux Docker image and MacOS. This can occur after clearing the cache. +If there are permission errors, running +`chmod 777 web/sites/default && mkdir -p web/sites/default/files/php/twig` might help. + +## Drush from host + +For drush to work from the host it needs access to the code base and a +database connection. The code base is already accessable as long as we +are somewhere inside the web/ folder. For drush to see our docker container +datatbase, we need to add a line to our host file: + +If your .env DB_HOST is mariadb, then your host file line would need to look like this: + +On Mac, edit /private/etc/hosts with elevated privileges. + +127.0.0.1 mariadb + +*mariadb matches the docker-compose container for the project database. +Changing DB_HOST in the .env file would require the docker-compose.yml +file to be updated as well. This is not advised. + +If you are having problems running drush locally, you may need to export .env variables. + set -a + source .env diff --git a/scripts/backup_db.sh b/scripts/backup_db.sh new file mode 100755 index 0000000..9e03b96 --- /dev/null +++ b/scripts/backup_db.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +set -e + +echo "== Backing up local database to db_backup.sql..." +echo " Database backup can be skipped with the -n flag" +drush sql:dump > db_backup.sql \ No newline at end of file diff --git a/scripts/build.sh b/scripts/build.sh new file mode 100755 index 0000000..d9d02c7 --- /dev/null +++ b/scripts/build.sh @@ -0,0 +1,129 @@ +#!/bin/bash + +set -e + +backup=true +sync_local='' +force_build=false +code_sniff=false +export target=dev +build_arg='' + +print_usage() { + echo "build.sh Fully build site with docker." + echo " " + echo "build.sh [options]" + echo " " + echo "options:" + echo "-h, --help show brief help" + echo "-n do not backup the database upon successful build" + echo "-l, -f use local db_backup.sql file for database, the existing local db will be wiped out when docker restarts" + echo "-b force rebuild app image (ex. for Dockerfile changes)" + echo "-s run phpcs from vendor directory on this project" +} + +source "${BASH_SOURCE%/*}/git_hooks/copy_hooks.sh" + +while getopts 'nlfbs' flag; do + case "${flag}" in + l) sync_local="-f" ;; + f) sync_local="-f" ;; + n) backup=false ;; + b) force_build=true ;; + s) code_sniff=true ;; + *) print_usage + exit 1 ;; + esac +done + +#Make sure environmental variables are setup +if [[ ! -f .env ]]; then + if [[ -f .env.example ]]; then + echo "No .env file found. Copying .env.example to .env" + cp .env.example .env + fi +fi + +#Make sure settings.local.php exists for new projects +if [[ ! -f web/sites/default/settings.local.php ]]; then + if [[ -f web/sites/default/default.settings.local.php ]]; then + echo "No settings.local.php file found. Copying default.settings.local.php to settings.local.php" + cp web/sites/default/default.settings.local.php web/sites/default/settings.local.php + fi +fi + +# Load environmental variables +set -a +source .env + +# Reset any previously created containers +echo "Cleaning up any previous containers..." +docker network disconnect -f ${PROJECT_NAME}_network chrome || true +docker-compose down -v || true + +docker_compose_files='-f docker-compose.yml' + +if [[ "$force_build" == true ]]; then + build_arg='--build' +fi + +echo "Starting docker using this config: $docker_compose_files" +docker-compose up -d $build_arg + + +# The drupal install might error if the docker containers are not fully ready. +# Giving the docker containers a few extra moments here seems to fix the issue. +sleep 3 + +# Do not allow a build with an out of data lock file +docker exec ${PROJECT_NAME}_php composer validate --no-check-all --no-check-publish && echo "pass" || exit 1 + +# Update dependencies +docker exec ${PROJECT_NAME}_php composer install -n && echo "pass" || exit 1 + +if [[ "$code_sniff" == true ]]; then + # Run code sniffer + echo "== Check code styles with phpcs..." + # Run the sniffer a second time to generate a report only on fail. + docker exec ${PROJECT_NAME}_php vendor/bin/phpcs --standard=Drupal --extensions=php,module,inc,install,test,profile,theme,css,info,txt,md '--ignore=node_modules,bower_components,vendor,*.min.js,*.min.css' web/modules/custom web/themes/custom \ + || docker exec ${PROJECT_NAME}_php vendor/bin/phpcs --report=checkstyle --report-file=checkstyle.xml --standard=Drupal --extensions=php,module,inc,install,test,profile,theme,css,info,txt,md '--ignore=node_modules,bower_components,vendor,*.min.js,*.min.css' web/modules/custom web/themes/custom +fi + +# Set up proper settings file +chmod 755 web/sites/default + +# Add default drupal core to solr server. +cores=$(docker exec -it ${PROJECT_NAME}_solr curl -s "http://localhost:8983/solr/admin/cores?action=STATUS" | { grep -c "instanceDir" || true; }) + +sleep 10 + +if [[ "${cores}" == 0 ]]; then + echo "No solr cores found, creating a drupal core" + docker exec ${PROJECT_NAME}_solr make create core="drupal" -f /usr/local/bin/actions.mk +fi + +# Execute this script from inside docker container. +# This wipes the db, copies db from stage and imports config. +docker exec ${PROJECT_NAME}_php scripts/sync_site.sh $sync_local + +# This is the earliest point that we have a stable DB to backup +if [[ "$backup" == true ]]; then + docker exec ${PROJECT_NAME}_php scripts/backup_db.sh +fi + +# Generate Keys +echo "== Generating Keys..." +if [[ ! -d private ]]; then + mkdir private +fi +cd private +if [[ ! -f private.key ]]; then + openssl genrsa -out private.key 2048 +fi +if [[ ! -f public.key ]]; then + openssl rsa -in private.key -pubout > public.key +fi +chmod 600 private.key && chmod 600 public.key +cd .. + +echo "http://${PROJECT_NAME}.localhost:8000 username: admin@example.com password: password" diff --git a/scripts/generate_content.sh b/scripts/generate_content.sh new file mode 100755 index 0000000..9640cac --- /dev/null +++ b/scripts/generate_content.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash +set -e +drush genu 50; + +echo "Finished generating content."; + +drush sapi-i; \ No newline at end of file diff --git a/scripts/git_hooks/copy_hooks.sh b/scripts/git_hooks/copy_hooks.sh new file mode 100755 index 0000000..0de0087 --- /dev/null +++ b/scripts/git_hooks/copy_hooks.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +#Copy pre-commit git hook +if [[ -d ".git" && -f "scripts/git_hooks/pre-commit" ]]; then + if [[ ! -d ".git/hooks" ]]; then + echo "== .git/hooks directory not found. Creating it ..." + mkdir .git/hooks + fi + echo "== Copying scripts/git_hooks/pre-commit to .git/hooks/pre-commit ..." + cp scripts/git_hooks/pre-commit .git/hooks/pre-commit +fi + diff --git a/scripts/git_hooks/pre-commit b/scripts/git_hooks/pre-commit new file mode 100755 index 0000000..f20221f --- /dev/null +++ b/scripts/git_hooks/pre-commit @@ -0,0 +1,44 @@ +#!/bin/bash +echo "== Running code style checks in git pre-commit hook..." + +vendor/bin/phpcs --standard=Drupal --extensions=php,module,inc,install,test,profile,theme,css,info,txt,md '--ignore=node_modules,bower_components,vendor,*.min.js,*.min.css' web/modules/custom web/themes/custom + +if [[ $? -eq 0 ]] +then + echo "== Code style check passed..." +else + printf "== Code style issues found.\n Try to auto fix errors with:\n vendor/bin/phpcbf --standard=Drupal --extensions=php,module,inc,install,test,profile,theme,css,info,txt,md '--ignore=node_modules,bower_components,vendor,*.min.js,*.min.css' web/modules/custom web/themes/custom" + exit 1 +fi + +scan_deprecations() { + echo "== Running drupal-check to check for Drupal 9 incompatibility..." + + # Paths the scan. + module_path='web/modules/custom' + theme_path='web/themes/custom' + scan_command="./vendor/bin/drupal-check -d --no-progress" + + # Scan modules first for deprecation. + scan_output=$($scan_command $module_path) + + pattern='(\[ERROR\] Found )' + + if [[ $scan_output =~ $pattern ]]; then + echo "$scan_output"; + echo "Use of deprecated code found in '$module_path'. Please run '$scan_command $module_path' and fix the deprecations." + exit 1; + fi + + # Scan themes for deprecation. + scan_output=$($scan_command $theme_path) + + if [[ $scan_output =~ $pattern ]]; then + echo "$scan_output"; + echo "Use of deprecated code found in '$theme_path'. Please run '$scan_command $theme_path' and fix the deprecations." + exit 1; + fi + +} +# TODO: Uncomment this to run deprecations scan after the codebase has deprications fixed +# scan_deprecations diff --git a/scripts/package_functions.sh b/scripts/package_functions.sh new file mode 100644 index 0000000..1330b74 --- /dev/null +++ b/scripts/package_functions.sh @@ -0,0 +1,46 @@ +#!/bin/bash +if [ ! -d "venv/lib/python3.8/site-packages/" ] +then + python3 -m venv venv + source venv/bin/activate + pip3 install -r admin_api/lambda_functions/requirements.txt +fi +mkdir functions +cd venv/lib/python3.8/site-packages/ +zip -r ../../../../functions/lambda_package.zip . +cd ../../../../admin_api/lambda_functions/create/ +cp ../../functions/lambda_package.zip ../../functions/admin_container.zip +cp ../../functions/lambda_package.zip ../../functions/create_db.zip +cp ../../functions/lambda_package.zip ../../functions/create_passwords.zip +cp ../../functions/lambda_package.zip ../../functions/create_stack.zip +cp ../../functions/lambda_package.zip ../../functions/create_lrs.zip +cp ../../functions/lambda_package.zip ../../functions/create_solr_fs.zip +cp ../../functions/lambda_package.zip ../../functions/admin_container.zip +cp ../../functions/lambda_package.zip ../../functions/update_stack.zip +cp ../../functions/lambda_package.zip ../../functions/update.zip +cp ../../functions/lambda_package.zip ../../functions/config_export.zip +cp ../../functions/lambda_package.zip ../../functions/invoke_delete.zip +cp ../../functions/lambda_package.zip ../../functions/delete_tenant.zip +cp ../../functions/lambda_package.zip ../../functions/tenant_status.zip +cp ../../functions/lambda_package.zip ../../functions/tenant_list.zip +cp ../../functions/lambda_package.zip ../../functions/cron.zip +cp ../../functions/lambda_package.zip ../../functions/get_versions.zip +zip -g ../../functions/create_db.zip create_db.py +zip -g ../../functions/create_passwords.zip create_passwords.py +zip -g ../../functions/create_stack.zip create_stack.py +zip -g ../../functions/create_lrs.zip create_lrs.py +zip -g ../../functions/create_solr_fs.zip create_solr_fs.py +cd ../ +zip -g ../functions/admin_container.zip admin_container.py +cd update +zip -g ../../functions/update_stack.zip update_stack.py +zip -g ../../functions/update.zip update.py +zip -g ../../functions/config_export.zip config_export.py +cd ../delete +zip -g ../../functions/delete_tenant.zip delete_tenant.py +cd ../status +zip -g ../../functions/tenant_status.zip tenant_status.py +zip -g ../../functions/tenant_list.zip tenant_list.py +zip -g ../../functions/get_versions.zip get_versions.py +cd ../../ +aws s3 cp functions s3://$1/functions --recursive --profile $2 diff --git a/scripts/perls_tenants/PERLS_tenant.yml b/scripts/perls_tenants/PERLS_tenant.yml new file mode 100644 index 0000000..cae9ea7 --- /dev/null +++ b/scripts/perls_tenants/PERLS_tenant.yml @@ -0,0 +1,527 @@ +AWSTemplateFormatVersion: 2010-09-09 +Description: Used by bash scripts for managing PERLS tenants. +Parameters: + TENANT: + Description: The name of the TENANT + Type: String + DBPASSWORD: + Description: Password for MySQL + Type: String + SMTPPASSWORD: + Description: Password for Email account + Type: String + PRIORITY: + Description: Where to put the listener rule in the LB config + Type: Number + LRSHOST: + Description: Endpoint for TENANT's xapi statements to be sent + Type: String + LRSUSERNAME: + Description: Username for the LRS + Type: String + LRSPASSWORD: + Description: Password for the LRS + Type: String + REDISTASKDEFVER: + Description: Which Task definition to use for Redis + Type: Number + Default: 1 + SMTPUSERNAME: + Description: User for Email account + Type: String + SMTPHOST: + Description: Host for SMTP Connection + Type: String + SMTPFROM: + Description: Email to send from + Type: String + SMTPPORT: + Description: Port for SMTP connection + Type: String + SMTPPROTOCOL: + Description: Protocol for SMTP connections(SSL or TLS) + Type: String + Default: tls + VERSION: + Description: Version of the Container + Type: String + TASKDEFVER: + Description: Which Task definition to use + Type: Number + Default: 1 + SOLRTASKDEFVER: + Description: Which Task definition to use for SOLR + Type: Number + Default: 1 + SIMPLESAMLAUTHSOURCE: + Description: SAML auth source + Type: String + Default: perls + SIMPLESAMLCONFIGDIR: + Description: Directory location of SAML config + Type: String + Default: "/var/www/html/private/saml_config" + ALTHost: + Description: Additional hostname to add to trusted hosts in settings.php + Type: String + Default: '' + SIMPLESAMLHOST: + Description: Base address of the CMS. Only used in conjunction with ALTHost + Type: String + Default: '' + StackName: + Description: Name of the initial environment stack. + Type: String + Default: PERLS + +Resources: + TaskDefinitionPHP: + DependsOn: [EFSPublicAP, EFSPrivateAP, CloudWatchLogGroup] + Type: AWS::ECS::TaskDefinition + Properties: + ContainerDefinitions: + - Name: PERLS-php + Environment: + - Name: DB_DRIVER + Value: mysql + - Name: DB_HOST + Value: + Fn::ImportValue: + !Sub "PERLS-RDS" + - Name: DB_NAME + Value: !Sub ${TENANT}_PERLS + - Name: DB_PORT + Value: 3306 + - Name: DB_USER + Value: perls_user + - Name: DRUPAL_SOLR_HOST + Value: !Sub ${TENANT}.solr.perls.net + - Name: SMTP_USERNAME + Value: !Sub ${SMTPUSERNAME} + - Name: DB_PASSWORD + Value: !Sub ${DBPASSWORD} + - Name: SMTP_PASSWORD + Value: !Sub ${SMTPPASSWORD} + - Name: LRS_HOST + Value: !Sub ${LRSHOST} + - Name: LRS_USERNAME + Value: !Sub ${LRSUSERNAME} + - Name: LRS_PASSWORD + Value: !Sub ${LRSPASSWORD} + - Name: SMTP_FROM + Value: !Sub ${SMTPFROM} + - Name: SMTP_HOST + Value: !Sub ${SMTPHOST} + - Name: SMTP_PORT + Value: !Sub ${SMTPPORT} + - Name: SMTP_PROTOCOL + Value: !Sub ${SMTPPROTOCOL} + - Name: BRAND + Value: PERLS + - Name: SIMPLESAML_AUTH_SOURCE + Value: !Sub ${SIMPLESAMLAUTHSOURCE} + - Name: SIMPLESAML_CONFIG_DIR + Value: !Sub ${SIMPLESAMLCONFIGDIR} + - Name: REDIS_HOST + Value: !Sub ${TENANT}-redis.internalservice + - Name: ADDITIONAL_TRUSTED_HOST + Value: !Sub ${ALTHost} + MountPoints: + - SourceVolume: public + ContainerPath: /var/www/html/web/sites/default/files + - SourceVolume: private + ContainerPath: /var/www/html/private + Image: + Fn::Join: + - '' + - - !Sub ${AWS::AccountId} + - '.dkr.ecr.us-east-1.amazonaws.com/perls:' + - !Sub ${VERSION} + PortMappings: + - containerPort: 80 + LogConfiguration: + LogDriver: awslogs + Options: + awslogs-region: us-east-1 + awslogs-group: !Sub ${TENANT} + awslogs-stream-prefix: php + Cpu: 512 + ExecutionRoleArn: + Fn::ImportValue: PERLS-ECSTaskExecutionRole + Family: !Sub ${TENANT}-php-task + Memory: 1024 + NetworkMode: awsvpc + RequiresCompatibilities: + - FARGATE + Volumes: + - + EFSVolumeConfiguration: + AuthorizationConfig: + AccessPointId: !Ref EFSPublicAP + IAM: DISABLED + FilesystemId: + Fn::ImportValue: "PERLS-EFS" + TransitEncryption: ENABLED + Name: public + - + EFSVolumeConfiguration: + AuthorizationConfig: + AccessPointId: !Ref EFSPrivateAP + IAM: DISABLED + FilesystemId: + Fn::ImportValue: PERLS-EFS + TransitEncryption: ENABLED + Name: private + + TaskDefinitionSOLR: + DependsOn: [EFSSolrAP, CloudWatchLogGroup] + Type: AWS::ECS::TaskDefinition + Properties: + RequiresCompatibilities: + - FARGATE + Cpu: 256 + Memory: 512 + ExecutionRoleArn: + Fn::ImportValue: PERLS-ECSTaskExecutionRole + NetworkMode: awsvpc + ContainerDefinitions: + - Name: PERLS-solr + MountPoints: + - SourceVolume: solr + ContainerPath: /var/solr/data + Image: solr:8 + PortMappings: + - containerPort: 8983 + LogConfiguration: + LogDriver: awslogs + Options: + awslogs-region: us-east-1 + awslogs-group: !Sub ${TENANT} + awslogs-stream-prefix: solr + Volumes: + - + EFSVolumeConfiguration: + AuthorizationConfig: + AccessPointId: !Ref EFSSolrAP + IAM: DISABLED + FilesystemId: + Fn::ImportValue: PERLS-EFS + TransitEncryption: ENABLED + Name: solr + Family: !Sub ${TENANT}-solr-task + + TaskDefinitionRedis: + DependsOn: [EFSSolrAP, CloudWatchRedisLogGroup] + Type: AWS::ECS::TaskDefinition + Properties: + RequiresCompatibilities: + - FARGATE + Cpu: 256 + Memory: 512 + ExecutionRoleArn: + Fn::ImportValue: PERLS-ECSTaskExecutionRole + NetworkMode: awsvpc + ContainerDefinitions: + - Name: !Sub ${TENANT}-redis + Image: redis:6 + PortMappings: + - containerPort: 6379 + LogConfiguration: + LogDriver: awslogs + Options: + awslogs-region: us-east-1 + awslogs-stream-prefix: redis + awslogs-group: !Sub ${TENANT}-redis + Family: !Sub ${TENANT}-redis-task + + ServicePHP: + DependsOn: [ListenerRulePHP, TaskDefinitionPHP] + Type: AWS::ECS::Service + Properties: + PlatformVersion: 1.4.0 + ServiceName: !Sub ${TENANT}-php-svc + Cluster: + Fn::ImportValue: PERLS-ECSCluster + TaskDefinition: !Sub ${TENANT}-php-task:${TASKDEFVER} + NetworkConfiguration: + AwsvpcConfiguration: + AssignPublicIp: ENABLED + SecurityGroups: + - Fn::ImportValue: PERLS-SGECS + Subnets: + - Fn::ImportValue: PERLS-PrivateSubnet1 + - Fn::ImportValue: PERLS-PrivateSubnet2 + - Fn::ImportValue: PERLS-PrivateSubnet3 + - Fn::ImportValue: PERLS-PrivateSubnet4 + - Fn::ImportValue: PERLS-PrivateSubnet5 + - Fn::ImportValue: PERLS-PrivateSubnet6 + + DeploymentConfiguration: + MaximumPercent: 200 + MinimumHealthyPercent: 50 + SchedulingStrategy: REPLICA + DesiredCount: 1 + LaunchType: FARGATE + EnableECSManagedTags: true + HealthCheckGracePeriodSeconds: 30 + LoadBalancers: + - ContainerName: PERLS-php + ContainerPort: 80 + TargetGroupArn: !Ref TargetGroupPHP + Tags: + - Key: TENANT + Value: !Sub ${TENANT} + + ServiceSOLR: + DependsOn: [ListenerRuleSOLR, TaskDefinitionSOLR] + Type: AWS::ECS::Service + Properties: + PlatformVersion: 1.4.0 + ServiceName: !Sub ${TENANT}-solr-svc + Cluster: + Fn::ImportValue: PERLS-ECSCluster + TaskDefinition: !Sub ${TENANT}-solr-task:${SOLRTASKDEFVER} + NetworkConfiguration: + AwsvpcConfiguration: + AssignPublicIp: ENABLED + SecurityGroups: + - Fn::ImportValue: PERLS-SGSolr + Subnets: + - Fn::ImportValue: PERLS-PrivateSubnet1 + - Fn::ImportValue: PERLS-PrivateSubnet2 + - Fn::ImportValue: PERLS-PrivateSubnet3 + - Fn::ImportValue: PERLS-PrivateSubnet4 + - Fn::ImportValue: PERLS-PrivateSubnet5 + - Fn::ImportValue: PERLS-PrivateSubnet6 + DeploymentConfiguration: + MaximumPercent: 200 + MinimumHealthyPercent: 50 + SchedulingStrategy: REPLICA + DesiredCount: 1 + LaunchType: FARGATE + EnableECSManagedTags: true + HealthCheckGracePeriodSeconds: 30 + LoadBalancers: + - ContainerName: PERLS-solr + ContainerPort: 8983 + TargetGroupArn: !Ref TargetGroupSOLR + Tags: + - Key: TENANT + Value: !Sub ${TENANT} + + RedisDiscoveryService: + Type: AWS::ServiceDiscovery::Service + Properties: + Description: Discovery Service for Redis + DnsConfig: + RoutingPolicy: MULTIVALUE + DnsRecords: + - TTL: 60 + Type: A + HealthCheckCustomConfig: + FailureThreshold: 1 + Name: !Sub ${TENANT}-redis + NamespaceId: + Fn::ImportValue: PERLS-ServiceDiscovery + + ServiceRedis: + DependsOn: [ TaskDefinitionRedis, RedisDiscoveryService ] + Type: AWS::ECS::Service + Properties: + PlatformVersion: 1.4.0 + ServiceName: !Sub ${TENANT}-redis-svc + Cluster: + Fn::ImportValue: PERLS-ECSCluster + TaskDefinition: !Sub ${TENANT}-redis-task:${REDISTASKDEFVER} + NetworkConfiguration: + AwsvpcConfiguration: + AssignPublicIp: ENABLED + SecurityGroups: + - Fn::ImportValue: PERLS-SGRedis + Subnets: + - Fn::ImportValue: PERLS-PrivateSubnet1 + - Fn::ImportValue: PERLS-PrivateSubnet2 + - Fn::ImportValue: PERLS-PrivateSubnet3 + - Fn::ImportValue: PERLS-PrivateSubnet4 + - Fn::ImportValue: PERLS-PrivateSubnet5 + - Fn::ImportValue: PERLS-PrivateSubnet6 + DeploymentConfiguration: + MaximumPercent: 200 + MinimumHealthyPercent: 50 + SchedulingStrategy: REPLICA + DesiredCount: 1 + LaunchType: FARGATE + EnableECSManagedTags: true + ServiceRegistries: + - RegistryArn: !GetAtt RedisDiscoveryService.Arn + Tags: + - Key: TENANT + Value: !Sub ${TENANT} + + ListenerRulePHP: + DependsOn: TargetGroupPHP + Type: AWS::ElasticLoadBalancingV2::ListenerRule + Properties: + Actions: + - Type: forward + TargetGroupArn: !Ref TargetGroupPHP + Conditions: + - Field: host-header + HostHeaderConfig: + Values: + - !Sub ${TENANT}.perls.usalearning.net + ListenerArn: + Fn::ImportValue: PERLS-AppLBListener + Priority: !Sub ${PRIORITY} + + ListenerRuleSOLR: + DependsOn: TargetGroupSOLR + Type: AWS::ElasticLoadBalancingV2::ListenerRule + Properties: + Actions: + - Type: forward + TargetGroupArn: !Ref TargetGroupSOLR + Conditions: + - Field: host-header + HostHeaderConfig: + Values: + - !Sub ${TENANT}.solr.perls.net + ListenerArn: + Fn::ImportValue: PERLS-SolrLBListener + Priority: !Sub ${PRIORITY} + + + TargetGroupPHP: + Type: AWS::ElasticLoadBalancingV2::TargetGroup + Properties: + HealthCheckEnabled: true + HealthCheckIntervalSeconds: 45 + HealthCheckPath: /ping + HealthCheckProtocol: HTTP + HealthCheckTimeoutSeconds: 30 + HealthyThresholdCount: 2 + Name: !Sub ${TENANT}-php-tg + Port: 80 + Protocol: HTTP + TargetType: ip + TargetGroupAttributes: + - Key: stickiness.enabled + Value: true + - Key: stickiness.lb_cookie.duration_seconds + Value: 3600 + - Key: deregistration_delay.timeout_seconds + Value: 30 + UnhealthyThresholdCount: 2 + VpcId: + Fn::ImportValue: PERLS-VPCID + + TargetGroupSOLR: + Type: AWS::ElasticLoadBalancingV2::TargetGroup + Properties: + HealthCheckEnabled: true + HealthCheckIntervalSeconds: 45 + HealthCheckPath: /solr/#/ + HealthCheckProtocol: HTTP + HealthCheckTimeoutSeconds: 30 + HealthyThresholdCount: 2 + Name: !Sub ${TENANT}-internal-solr-tg + Port: 8983 + Protocol: HTTP + TargetType: ip + UnhealthyThresholdCount: 2 + VpcId: + Fn::ImportValue: PERLS-VPCID + + EFSPublicAP: + Type: 'AWS::EFS::AccessPoint' + Properties: + FileSystemId: + Fn::ImportValue: PERLS-EFS + PosixUser: + Uid: "1000" + Gid: "1000" + RootDirectory: + CreationInfo: + OwnerGid: "1000" + OwnerUid: "1000" + Permissions: "0755" + Path: !Sub "/${TENANT}/public" + + EFSPrivateAP: + Type: 'AWS::EFS::AccessPoint' + Properties: + FileSystemId: + Fn::ImportValue: PERLS-EFS + PosixUser: + Uid: "1000" + Gid: "1000" + RootDirectory: + CreationInfo: + OwnerGid: "1000" + OwnerUid: "1000" + Permissions: "0755" + Path: !Sub "/${TENANT}/private" + + EFSSolrAP: + Type: 'AWS::EFS::AccessPoint' + Properties: + FileSystemId: + Fn::ImportValue: PERLS-EFS + RootDirectory: + Path: !Sub "/${TENANT}/solr" + + ScalableTarget: + DependsOn: ServicePHP + Type: AWS::ApplicationAutoScaling::ScalableTarget + Properties: + MaxCapacity: 20 + MinCapacity: 1 + RoleARN: + Fn::ImportValue: PERLS-AppAutoScalingRole + ServiceNamespace: ecs + ScalableDimension: ecs:service:DesiredCount + ResourceId: !Sub service/PERLSECSCluster/${TENANT}-php-svc + + ECSCPUAutoscaling: + DependsOn: [ServicePHP, ScalableTarget] + Type: AWS::ApplicationAutoScaling::ScalingPolicy + Properties: + PolicyName: !Sub ${TENANT}-CPU-AutoScaling + PolicyType: TargetTrackingScaling + ResourceId: !Sub service/PERLSECSCluster/${TENANT}-php-svc + ScalableDimension: ecs:service:DesiredCount + ServiceNamespace: ecs + TargetTrackingScalingPolicyConfiguration: + ScaleInCooldown: 300 + ScaleOutCooldown: 120 + TargetValue: 50 + PredefinedMetricSpecification: + PredefinedMetricType: ECSServiceAverageCPUUtilization + + ECSMEMAutoscaling: + DependsOn: [ServicePHP, ScalableTarget] + Type: AWS::ApplicationAutoScaling::ScalingPolicy + Properties: + PolicyName: !Sub ${TENANT}-MEM-AutoScaling + PolicyType: TargetTrackingScaling + ResourceId: !Sub service/PERLSECSCluster/${TENANT}-php-svc + ScalableDimension: ecs:service:DesiredCount + ServiceNamespace: ecs + TargetTrackingScalingPolicyConfiguration: + ScaleInCooldown: 300 + ScaleOutCooldown: 120 + TargetValue: 50 + PredefinedMetricSpecification: + PredefinedMetricType: ECSServiceAverageMemoryUtilization + + CloudWatchLogGroup: + Type: AWS::Logs::LogGroup + Properties: + LogGroupName: !Sub ${TENANT}-php + RetentionInDays: 365 + + CloudWatchRedisLogGroup: + Type: AWS::Logs::LogGroup + Properties: + LogGroupName: !Sub ${TENANT}-redis + RetentionInDays: 365 diff --git a/scripts/perls_tenants/ReadMe.md b/scripts/perls_tenants/ReadMe.md new file mode 100644 index 0000000..7a9f4e9 --- /dev/null +++ b/scripts/perls_tenants/ReadMe.md @@ -0,0 +1,3 @@ +(Legacy) PERLS Tenant Management +----------- +These scripts are for updating/deleting PERLS tenants that were created under the original CloudFormation stack template. New tenants should be created and maintained using the admin API (see admin_api). diff --git a/scripts/perls_tenants/delete_tenant.sh b/scripts/perls_tenants/delete_tenant.sh new file mode 100644 index 0000000..56738c6 --- /dev/null +++ b/scripts/perls_tenants/delete_tenant.sh @@ -0,0 +1,16 @@ +#!/bin/bash +#This file has been copied to the /home/centos/perls directory of the centos user on the utility server +TENANT=$1 +read -p "Type 'delete' if you are sure you want to delete tenant $TENANT: " CONFIRM +if [ "$CONFIRM" = "delete" ]; then + echo "Deleting tenant $TENANT" + TENANT=${TENANT,,} + RDS_HOST=$(aws cloudformation describe-stacks --stack-name PERLS | jq '.Stacks[].Outputs[] | select(.OutputKey=="PERLSRDS") | .OutputValue' -r) + RDS_PWD=$(aws cloudformation describe-stacks --stack-name PERLS | jq '.Stacks[].Parameters[] | select(.ParameterKey=="RDSMasterPassword") | .ParameterValue' -r) + aws cloudformation delete-stack --stack-name ${TENANT} + mysql -h ${RDS_HOST} -u 'perls_user' -p${RDS_PWD} -e "DROP DATABASE ${TENANT}_PERLS;" + sudo rm -rf /efs/${TENANT} + rm -rf /var/www/${TENANT} +else + exit 0 +fi diff --git a/scripts/perls_tenants/sample_tenant.env b/scripts/perls_tenants/sample_tenant.env new file mode 100644 index 0000000..5cea906 --- /dev/null +++ b/scripts/perls_tenants/sample_tenant.env @@ -0,0 +1,29 @@ +# Name of the tenant to be created. This must be alphanumeric. +TENANT="perls" + +#Name of the admin user ie. "John Doe" +NAME="John Doe" + +#Email Address of the admin user. Used for login +ADMIN_EMAIL="john.doe@example.com" + +#Version of the CMS to deploy. Current version is 2.3.0. This must match one the available versions provided by the vendor. +VERSION="3.0.0" + +#If true a LRS will be created for the new tenant at https://lrs.perls.usalearning.net +CREATE_LRS="true" + +#Settings for a CMS that has already been created or exists with another provider. If CREATE_LRS is true, leave the LRS_ variables empty. +#Complete address of xapi endpoint. +LRS_HOST="https://lrs.perls.usalearning.net//xapi/" +#Username for sending xapi statements +LRS_USERNAME="xapi_user" +#Password for sending xapi statements +LRS_PASSWORD="xapi_user_password" + +#SMTP connection info for sending emails from the CMS. +SMTP_HOST="smtp.gmail.com" +SMTP_USERNAME="john.doe@example.com" +SMTP_PASSWORD="notsosecretpassword" +SMTP_FROM="john.doe@example.com" +SMTP_PORT="465" diff --git a/scripts/perls_tenants/update_tenant.sh b/scripts/perls_tenants/update_tenant.sh new file mode 100644 index 0000000..63d122e --- /dev/null +++ b/scripts/perls_tenants/update_tenant.sh @@ -0,0 +1,59 @@ +#!/bin/bash + +TENANT=${TENANT,,} +source /var/www/${TENANT}/tenant.env +export BRAND=PERLS + +TaskDefARN=$(aws ecs describe-services --services ${TENANT}-php-svc --cluster PERLSECSCluster | jq '.services[0].deployments[0].taskDefinition' -r) +SOLRTaskDefARN=$(aws ecs describe-services --services ${TENANT}-solr-svc --cluster PERLSECSCluster | jq '.services[0].deployments[0].taskDefinition' -r) +TASKDEFVER=${TaskDefARN##*:} +TASKDEFVER_new=$(($TASKDEFVER+1)) + +drush config-split:export ignored_config -y +# This trigger a warning if the tenant_overrides isn't active. +drush config-split:export tenant_overrides -y +unlink private +unlink web/sites/default/files +echo "Updating code base" +aws s3 sync s3://perls-repo-pt/${VERSION}/code/ . --delete --quiet --exclude web/sites/default/settings.local.php --exclude tenant.env --exclude tenant.properties + +ln -s /efs/${TENANT}/private/ private +ln -s /efs/${TENANT}/public/ web/sites/default/files + +sudo chown -R $(whoami): /efs/${TENANT}/{private,public} + +drush status +rm -rf vendor +composer install +drush updatedb --entity-updates --no-post-updates -y +drush cr +drush config-import -y +drush config-import -y +drush updatedb -y +drush cr + +sudo chown -R 1000:1000 /efs/${TENANT}/{private,public} + +echo "Updating ${TENANT} CloudFormation stack" +aws cloudformation update-stack --stack-name ${TENANT} --template-body file://scripts/perls_tenants/PERLS_tenant.yml --parameters \ +ParameterKey=VERSION,ParameterValue=${VERSION} \ +ParameterKey=TASKDEFVER,ParameterValue=${TASKDEFVER_new} \ +ParameterKey=TENANT,UsePreviousValue=true \ +ParameterKey=DBPASSWORD,UsePreviousValue=true \ +ParameterKey=SMTPPASSWORD,UsePreviousValue=true \ +ParameterKey=SMTPUSERNAME,UsePreviousValue=true \ +ParameterKey=SMTPFROM,UsePreviousValue=true \ +ParameterKey=SMTPPORT,UsePreviousValue=true \ +ParameterKey=SMTPHOST,UsePreviousValue=true \ +ParameterKey=SMTPPROTOCOL,ParameterValue=tls \ +ParameterKey=PRIORITY,UsePreviousValue=true \ +ParameterKey=LRSPASSWORD,UsePreviousValue=true \ +ParameterKey=LRSUSERNAME,UsePreviousValue=true \ +ParameterKey=LRSHOST,UsePreviousValue=true \ +ParameterKey=SOLRTASKDEFVER,UsePreviousValue=true \ +ParameterKey=SIMPLESAMLAUTHSOURCE,UsePreviousValue=true \ +ParameterKey=SIMPLESAMLCONFIGDIR,UsePreviousValue=true \ +ParameterKey=StackName,UsePreviousValue=true + +aws ecs wait services-stable --cluster PERLSECSCluster --services ${TENANT}-php-svc + diff --git a/scripts/refresh.sh b/scripts/refresh.sh new file mode 100755 index 0000000..93b0f3d --- /dev/null +++ b/scripts/refresh.sh @@ -0,0 +1,49 @@ +#!/bin/bash +set -e + +backup=true +use_local_db='' +use_backup_file='' + +print_usage() { + echo "refresh.sh Refresh Drupal with composer install and attempt to copy STAGE database. Do not restart docker containers." + echo " " + echo "refresh.sh [options]" + echo " " + echo "options:" + echo "-h, --help show brief help" + echo "-n do not backup the database" + echo "-l use local copy of the database instead of STAGE database" + echo "-f use db_backup.sql file instead of existing local database" +} + +while getopts 'nlf' flag; do + case "${flag}" in + n) backup=false ;; + l) use_local_db="-l" ;; + f) use_backup_file="-f" ;; + *) print_usage + exit 1 ;; + esac +done + +# Load environmental variables +set -a +source .env + +# Do a backup before trying to sync stage DB +if [[ "$backup" == true ]] && [[ "$use_backup_file" == '' ]]; then + docker exec ${PROJECT_NAME}_php scripts/backup_db.sh +fi + +docker exec ${PROJECT_NAME}_php composer install -n + +# Execute this script from inside docker container. +# This wipes the db, copies db from stage and imports config. +docker exec ${PROJECT_NAME}_php scripts/sync_site.sh $use_local_db $use_backup_file + +# If our Database sync was successful we update our backup file. +if [[ "$backup" == true ]]; then + echo "== Refreshing db_backup.sql with updated database..." + docker exec ${PROJECT_NAME}_php scripts/backup_db.sh +fi \ No newline at end of file diff --git a/scripts/styles.sh b/scripts/styles.sh new file mode 100755 index 0000000..7f91cca --- /dev/null +++ b/scripts/styles.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash +set -e + +# Todo -- handle npm install fail and gulp build theme fail. +echo "== Generating styles-sheets..." +echo "== Npm install && gulp build-theme" +cd web/themes/custom/perls +npm rebuild node-sass && npm install && ./node_modules/.bin/gulp build-theme +echo "== Cache rebuild" +drush cache:rebuild diff --git a/scripts/sync_site.sh b/scripts/sync_site.sh new file mode 100755 index 0000000..ad196fc --- /dev/null +++ b/scripts/sync_site.sh @@ -0,0 +1,112 @@ +#!/usr/bin/env bash +set -e + +use_local_db=false +use_backup_file=false + +print_usage() { + echo "sync_site.sh should run inside php docker container. Can sync remote repo. Brings in local config." + echo " " + echo "sync_site.sh [options]" + echo " " + echo "options:" + echo "-h, --help show brief help" + echo "-l use local copy of the database instead of STAGE database" + echo "-f use db_backup.sql file instead of existing local database" +} + +while getopts 'nlf' flag; do + case "${flag}" in + l) use_local_db=true ;; + f) use_backup_file=true ;; + *) print_usage + exit 1 ;; + esac +done + +## +# If you have trouble running locally, try from inside a container. +# +# docker exec PERLS_php scripts/sync_site.sh +## + +sync_fail=false + +if [[ "$use_local_db" == false ]] && [[ "$use_backup_file" == false ]]; then + + # PHP_DEV is set to 1 in the PERLS_php docker container + if [ $PHP_DEV ]; then + if [ ! -f ~/.ssh/perls_drush ]; then + echo "== Copy ssh keys to .ssh user directory..." + cp -r ./.ssh ~/ || true + fi + fi + + if [ -f ~/.ssh/perls_drush ]; then + echo "== Setting proper permissions on SSH keys..." + chmod 0600 ~/.ssh/perls_drush ~/.ssh/perls_drush.pub + fi + + echo "== Checking connection to STAGE..." + + drush @stage status && echo "== Successfully connected to stage..." || sync_fail=true + + if [[ "$sync_fail" == true ]]; + then + echo "== Failed to connect to STAGE..." + else + echo "== Drop and sync database from STAGE..." + drush sql:drop -y + + # Attempt to sync db from stage. Allow recovery and continue with db_backup.sql + drush sql:sync @stage @self -y && echo "== Successfully loaded STAGE database" || sync_fail=true + + if [[ "$sync_fail" == true ]]; then + echo "== Failed to copy database from STAGE." + fi + fi +fi + +file_fail=false + +if [[ "$sync_fail" == true ]] || [[ "$use_backup_file" == true ]]; then + if [[ -f db_backup.sql ]]; then + echo "== Importing database from db_backup.sql..." + drush sql-cli < db_backup.sql && echo "== Successfully imported db_backup.sql..." || file_fail=true + else + file_fail=true + echo "== File db_backup.sql not found..." + fi + + if [[ "$file_fail" == true ]]; then + echo "== Failed to load database from db_backup.sql, attempting to build the site from scratch..." + drush site-install --existing-config + fi +fi + +if [[ "$use_local_db" == true ]] || [[ "$file_fail" == true ]]; then + echo "== Using existing local database..." +fi + +echo "== Update database with any code changes..." +drush cr +drush updatedb --no-post-updates -y +drush config-import -y +drush config-import -y +drush updatedb -y +drush sqlq "UPDATE users_field_data SET name='admin', mail='admin@example.com' WHERE uid=1;" +drush cr +drush upwd admin password +drush user:role:add sysadmin admin +drush user:unblock admin +drush wd all -y + +# Set up an oAuth consumer for API calls +# This client ID/secret should only be used in development environments...since it's not very secret. +echo "== Creating oAuth consumer for development..." +drush perls:createConsumer "0bba92e5-68ea-4e9b-8ab0-b43b2022330c" 'not-very-secret' --label="Mobile App-Development" --no-third_party --roles=rest_api_user --redirect="https://example.com/auth" + +echo "== Rebuild search index from local solr..." +# This might fail outside of a docker container +drush search-api:clear +drush search-api:index diff --git a/scripts/tenant.yml b/scripts/tenant.yml new file mode 100644 index 0000000..6f60df2 --- /dev/null +++ b/scripts/tenant.yml @@ -0,0 +1,935 @@ +AWSTemplateFormatVersion: 2010-09-09 +Description: Next-gen template; not yet widely used. +Parameters: + TENANT: + Description: The name of the TENANT + Type: String + SMTPPASSWORDARN: + Description: ARN of secret containing the SMTP Password + Type: String + PRIORITY: + Description: Where to put the listener rule in the LB config + Type: Number + LRSHOST: + Description: Endpoint for TENANT's xapi statements to be sent + Type: String + LRSPASSWORDARN: + Description: ARN of secret containing the LRS Password + Type: String + SMTPUSERNAME: + Description: User for Email account + Type: String + SMTPHOST: + Description: Host for SMTP Connection + Type: String + SMTPFROM: + Description: Email to send from + Type: String + SMTPPORT: + Description: Port for SMTP connection + Type: String + SMTPPROTOCOL: + Description: Protocol for SMTP connections(SSL or TLS) + Type: String + Default: tls + VERSION: + Description: Version of the Container + Type: String + SIMPLESAMLAUTHSOURCE: + Description: SAML auth source + Type: String + Default: perls + SIMPLESAMLCONFIGDIR: + Description: Directory location of SAML config + Type: String + Default: "/var/www/html/private/saml_config" + Project: + Description: Lowercase name of the project for pulling the container + Type: String + BaseStack: + Description: Name of the initial base cloudformation stack + Type: String + ADDRESS: + Description: Address of the CMS + Type: String + BRAND: + Description: Which brand of CMS + AllowedValues: [PERLS] + Type: String + Default: PERLS + SNSTopic: + Description: ARN of the SNS Topic to send alerts to + Type: String + DBPASSWORDARN: + Description: ARN of secret containing the SMTP Password + Type: String + FIREBASEKEY: + Description: Key for sending push notifications + Type: String + FIREBASEID: + Description: ID for sending push notifications + Type: String + ALTHost: + Description: Additional hostname to add to trusted hosts in settings.php + Type: String + Default: '' + SIMPLESAMLHOST: + Description: URL for initiating SSO requests. Only needed if the site is accessible from multiple URLs. + Type: String + Default: '' + +Conditions: + NoAltName: !Equals + - !Ref ALTHost + - '' + +Resources: + TaskDefinitionPHP: + DependsOn: CloudWatchPHPLogGroup + Type: AWS::ECS::TaskDefinition + Properties: + ContainerDefinitions: + - Name: !Sub ${TENANT}-php + Secrets: + - Name: DB_PASSWORD + ValueFrom: !Sub ${DBPASSWORDARN} + - Name: LRS_PASSWORD + ValueFrom: !Sub ${LRSPASSWORDARN} + - Name: SMTP_PASSWORD + ValueFrom: !Sub ${SMTPPASSWORDARN} + Environment: + - Name: DB_DRIVER + Value: mysql + - Name: DB_HOST + Value: + Fn::ImportValue: + !Sub ${BaseStack}-RDS + - Name: DB_NAME + Value: !Sub ${TENANT}_${BRAND} + - Name: DB_PORT + Value: 3306 + - Name: DB_USER + Value: !Sub ${TENANT} + - Name: DRUPAL_SOLR_HOST + Value: + Fn::Join: + - '' + - - !Sub ${TENANT}.solr. + - Fn::ImportValue: + !Sub ${BaseStack}-InternalBaseURL + - Name: SMTP_USERNAME + Value: !Sub ${SMTPUSERNAME} + - Name: LRS_HOST + Value: !Sub ${LRSHOST} + - Name: LRS_USERNAME + Value: !Sub ${TENANT} + - Name: SMTP_FROM + Value: !Sub ${SMTPFROM} + - Name: SMTP_HOST + Value: !Sub ${SMTPHOST} + - Name: SMTP_PORT + Value: !Sub ${SMTPPORT} + - Name: SMTP_PROTOCOL + Value: !Sub ${SMTPPROTOCOL} + - Name: BRAND + Value: !Sub ${BRAND} + - Name: SIMPLESAML_AUTH_SOURCE + Value: !Sub ${SIMPLESAMLAUTHSOURCE} + - Name: SIMPLESAML_CONFIG_DIR + Value: !Sub ${SIMPLESAMLCONFIGDIR} + - Name: REDIS_HOST + Value: !Sub ${TENANT}-redis.internalservice + - Name: FIREBASE_SERVER_KEY + Value: !Sub ${FIREBASEKEY} + - Name: FIREBASE_SENDER_ID + Value: !Sub ${FIREBASEID} + - Name: ADDITIONAL_TRUSTED_HOST + Value: + Fn::If: + - NoAltName + - !Ref AWS::NoValue + - !Sub ${ALTHost} + - Name: SIMPLESAML_HOST + Value: + Fn::If: + - NoAltName + - !Ref AWS::NoValue + - !Sub ${SIMPLESAMLHOST} + + MountPoints: + - SourceVolume: public + ContainerPath: /var/www/html/web/sites/default/files + - SourceVolume: private + ContainerPath: /var/www/html/private + Image: !Sub '${AWS::AccountId}.dkr.ecr.us-east-1.amazonaws.com/${Project}:${VERSION}' + PortMappings: + - ContainerPort: 80 + LogConfiguration: + LogDriver: awslogs + Options: + awslogs-region: us-east-1 + awslogs-group: !Sub ${TENANT}-php + awslogs-stream-prefix: php + Cpu: 512 + ExecutionRoleArn: + Fn::ImportValue: + !Sub ${BaseStack}-ECSTaskExecutionRole + Family: !Sub ${TENANT}-php-task + Memory: 1024 + NetworkMode: awsvpc + RequiresCompatibilities: + - FARGATE + Volumes: + - + EFSVolumeConfiguration: + AuthorizationConfig: + AccessPointId: !Ref EFSPublicAP + IAM: DISABLED + FilesystemId: + Fn::ImportValue: + !Sub ${BaseStack}-EFS + TransitEncryption: ENABLED + Name: public + - + EFSVolumeConfiguration: + AuthorizationConfig: + AccessPointId: !Ref EFSPrivateAP + IAM: DISABLED + FilesystemId: + Fn::ImportValue: + !Sub ${BaseStack}-EFS + TransitEncryption: ENABLED + Name: private + + TaskDefinitionPHPAdmin: + DependsOn: CloudWatchPHPLogGroup + Type: AWS::ECS::TaskDefinition + Properties: + ContainerDefinitions: + - Name: !Sub ${TENANT}-php + Secrets: + - Name: DB_PASSWORD + ValueFrom: !Sub ${DBPASSWORDARN} + - Name: LRS_PASSWORD + ValueFrom: !Sub ${LRSPASSWORDARN} + - Name: SMTP_PASSWORD + ValueFrom: !Sub ${SMTPPASSWORDARN} + Environment: + - Name: DB_DRIVER + Value: mysql + - Name: DB_HOST + Value: + Fn::ImportValue: + !Sub ${BaseStack}-RDS + - Name: DB_NAME + Value: !Sub ${TENANT}_${BRAND} + - Name: DB_PORT + Value: 3306 + - Name: DB_USER + Value: !Sub ${TENANT} + - Name: DRUPAL_SOLR_HOST + Value: + Fn::Join: + - '' + - - !Sub ${TENANT}.solr. + - Fn::ImportValue: + !Sub ${BaseStack}-InternalBaseURL + - Name: SMTP_USERNAME + Value: !Sub ${SMTPUSERNAME} + - Name: LRS_HOST + Value: !Sub ${LRSHOST} + - Name: LRS_USERNAME + Value: !Sub ${TENANT} + - Name: SMTP_FROM + Value: !Sub ${SMTPFROM} + - Name: SMTP_HOST + Value: !Sub ${SMTPHOST} + - Name: SMTP_PORT + Value: !Sub ${SMTPPORT} + - Name: BRAND + Value: !Sub ${BRAND} + - Name: SIMPLESAML_AUTH_SOURCE + Value: !Sub ${SIMPLESAMLAUTHSOURCE} + - Name: SIMPLESAML_CONFIG_DIR + Value: !Sub ${SIMPLESAMLCONFIGDIR} + - Name: REDIS_HOST + Value: !Sub ${TENANT}-redis.internalservice + MountPoints: + - SourceVolume: public + ContainerPath: /var/www/html/web/sites/default/files + - SourceVolume: private + ContainerPath: /var/www/html/private + Image: !Sub '${AWS::AccountId}.dkr.ecr.us-east-1.amazonaws.com/${Project}:${VERSION}' + PortMappings: + - ContainerPort: 80 + LogConfiguration: + LogDriver: awslogs + Options: + awslogs-region: us-east-1 + awslogs-group: !Sub ${TENANT}-php-updates + awslogs-stream-prefix: php + Cpu: 512 + ExecutionRoleArn: + Fn::ImportValue: + !Sub ${BaseStack}-ECSTaskExecutionRole + Family: !Sub ${TENANT}-php-admin-task + Memory: 1024 + NetworkMode: awsvpc + RequiresCompatibilities: + - FARGATE + Volumes: + - + EFSVolumeConfiguration: + AuthorizationConfig: + AccessPointId: !Ref EFSPublicAP + IAM: DISABLED + FilesystemId: + Fn::ImportValue: + !Sub ${BaseStack}-EFS + TransitEncryption: ENABLED + Name: public + - + EFSVolumeConfiguration: + AuthorizationConfig: + AccessPointId: !Ref EFSPrivateAP + IAM: DISABLED + FilesystemId: + Fn::ImportValue: + !Sub ${BaseStack}-EFS + TransitEncryption: ENABLED + Name: private + + TaskDefinitionRedis: + DependsOn: [EFSSolrAP, CloudWatchRedisLogGroup] + Type: AWS::ECS::TaskDefinition + Properties: + RequiresCompatibilities: + - FARGATE + Cpu: 256 + Memory: 512 + ExecutionRoleArn: + Fn::ImportValue: + !Sub ${BaseStack}-ECSTaskExecutionRole + NetworkMode: awsvpc + ContainerDefinitions: + - Name: !Sub ${TENANT}-redis + Image: redis:6 + PortMappings: + - ContainerPort: 6379 + LogConfiguration: + LogDriver: awslogs + Options: + awslogs-region: us-east-1 + awslogs-stream-prefix: redis + awslogs-group: !Sub ${TENANT}-redis + Family: !Sub ${TENANT}-redis-task + + TaskDefinitionSOLR: + DependsOn: CloudWatchSOLRLogGroup + Type: AWS::ECS::TaskDefinition + Properties: + RequiresCompatibilities: + - FARGATE + Cpu: 256 + Memory: 512 + ExecutionRoleArn: + Fn::ImportValue: + !Sub ${BaseStack}-ECSTaskExecutionRole + NetworkMode: awsvpc + ContainerDefinitions: + - Name: !Sub ${TENANT}-solr + Environment: + - Name: SOLR_JAVA_MEM + Value: -Xms384m -Xmx384m + MountPoints: + - SourceVolume: solr + ContainerPath: /var/solr/data + Image: solr:8 + PortMappings: + - ContainerPort: 8983 + LogConfiguration: + LogDriver: awslogs + Options: + awslogs-region: us-east-1 + awslogs-group: !Sub ${TENANT}-solr + awslogs-stream-prefix: solr + Volumes: + - + EFSVolumeConfiguration: + AuthorizationConfig: + AccessPointId: !Ref EFSSolrAP + IAM: DISABLED + FilesystemId: + Fn::ImportValue: + !Sub ${BaseStack}-EFS + TransitEncryption: ENABLED + Name: solr + Family: !Sub ${TENANT}-solr-task + + ServicePHP: + DependsOn: ListenerRulePHP + Type: AWS::ECS::Service + Properties: + PlatformVersion: 1.4.0 + ServiceName: !Sub ${TENANT}-php-svc + Cluster: + Fn::ImportValue: + !Sub ${BaseStack}-ECSCluster + TaskDefinition: !Ref TaskDefinitionPHP + NetworkConfiguration: + AwsvpcConfiguration: + AssignPublicIp: ENABLED + SecurityGroups: + - Fn::ImportValue: + !Sub ${BaseStack}-SGECS + Subnets: + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet1 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet2 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet3 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet4 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet5 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet6 + + DeploymentConfiguration: + MaximumPercent: 200 + MinimumHealthyPercent: 50 + SchedulingStrategy: REPLICA + DesiredCount: 1 + LaunchType: FARGATE + EnableECSManagedTags: true + HealthCheckGracePeriodSeconds: 30 + LoadBalancers: + - ContainerName: !Sub ${TENANT}-php + ContainerPort: 80 + TargetGroupArn: !Ref TargetGroupPHP + Tags: + - Key: TENANT + Value: !Sub ${TENANT} + + ServiceSOLR: + DependsOn: ListenerRuleSOLR + Type: AWS::ECS::Service + Properties: + PlatformVersion: 1.4.0 + ServiceName: !Sub ${TENANT}-solr-svc + Cluster: + Fn::ImportValue: + !Sub ${BaseStack}-ECSCluster + TaskDefinition: !Ref TaskDefinitionSOLR + NetworkConfiguration: + AwsvpcConfiguration: + AssignPublicIp: ENABLED + SecurityGroups: + - Fn::ImportValue: + !Sub ${BaseStack}-SGSolr + Subnets: + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet1 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet2 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet3 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet4 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet5 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet6 + DeploymentConfiguration: + MaximumPercent: 200 + MinimumHealthyPercent: 50 + SchedulingStrategy: REPLICA + DesiredCount: 1 + LaunchType: FARGATE + EnableECSManagedTags: true + HealthCheckGracePeriodSeconds: 30 + LoadBalancers: + - ContainerName: !Sub ${TENANT}-solr + ContainerPort: 8983 + TargetGroupArn: !Ref TargetGroupSOLR + Tags: + - Key: TENANT + Value: !Sub ${TENANT} + + RedisDiscoveryService: + Type: AWS::ServiceDiscovery::Service + Properties: + Description: Discovery Service for redis + DnsConfig: + RoutingPolicy: MULTIVALUE + DnsRecords: + - TTL: 60 + Type: A + HealthCheckCustomConfig: + FailureThreshold: 1 + Name: !Sub ${TENANT}-redis + NamespaceId: + Fn::ImportValue: + !Sub ${BaseStack}-ServiceDiscovery + + ServiceRedis: + Type: AWS::ECS::Service + Properties: + PlatformVersion: 1.4.0 + ServiceName: !Sub ${TENANT}-redis-svc + Cluster: + Fn::ImportValue: + !Sub ${BaseStack}-ECSCluster + TaskDefinition: !Ref TaskDefinitionRedis + NetworkConfiguration: + AwsvpcConfiguration: + AssignPublicIp: ENABLED + SecurityGroups: + - Fn::ImportValue: + !Sub ${BaseStack}-SGRedis + Subnets: + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet1 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet2 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet3 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet4 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet5 + - Fn::ImportValue: + !Sub ${BaseStack}-PrivateSubnet6 + DeploymentConfiguration: + MaximumPercent: 200 + MinimumHealthyPercent: 50 + SchedulingStrategy: REPLICA + DesiredCount: 1 + LaunchType: FARGATE + EnableECSManagedTags: true + ServiceRegistries: + - RegistryArn: !GetAtt RedisDiscoveryService.Arn + Tags: + - Key: TENANT + Value: !Sub ${TENANT} + + ListenerRulePHP: + Type: AWS::ElasticLoadBalancingV2::ListenerRule + Properties: + Actions: + - Type: forward + TargetGroupArn: !Ref TargetGroupPHP + Conditions: + - Field: host-header + HostHeaderConfig: + Values: + - !Sub ${ADDRESS} + ListenerArn: + Fn::ImportValue: + !Sub ${BaseStack}-AppLBListener + Priority: !Sub ${PRIORITY} + + ListenerRuleSOLR: + Type: AWS::ElasticLoadBalancingV2::ListenerRule + Properties: + Actions: + - Type: forward + TargetGroupArn: !Ref TargetGroupSOLR + Conditions: + - Field: host-header + HostHeaderConfig: + Values: + - + Fn::Join: + - '' + - - !Sub ${TENANT}.solr. + - Fn::ImportValue: + !Sub ${BaseStack}-InternalBaseURL + ListenerArn: + Fn::ImportValue: + !Sub ${BaseStack}-SolrLBListener + Priority: !Sub ${PRIORITY} + + + TargetGroupPHP: + Type: AWS::ElasticLoadBalancingV2::TargetGroup + Properties: + HealthCheckEnabled: true + HealthCheckIntervalSeconds: 45 + HealthCheckPath: /ping + HealthCheckProtocol: HTTP + HealthCheckTimeoutSeconds: 30 + HealthyThresholdCount: 2 + Name: !Sub ${TENANT}-php-tg + Port: 80 + Protocol: HTTP + TargetType: ip + TargetGroupAttributes: + - Key: stickiness.enabled + Value: true + - Key: stickiness.lb_cookie.duration_seconds + Value: 3600 + - Key: deregistration_delay.timeout_seconds + Value: 30 + UnhealthyThresholdCount: 2 + VpcId: + Fn::ImportValue: + !Sub ${BaseStack}-VPCID + + TargetGroupSOLR: + Type: AWS::ElasticLoadBalancingV2::TargetGroup + Properties: + HealthCheckEnabled: true + HealthCheckIntervalSeconds: 45 + HealthCheckPath: /solr/#/ + HealthCheckProtocol: HTTP + HealthCheckTimeoutSeconds: 30 + HealthyThresholdCount: 2 + Name: !Sub ${TENANT}-solr-tg + Port: 8983 + Protocol: HTTP + TargetType: ip + UnhealthyThresholdCount: 2 + VpcId: + Fn::ImportValue: + !Sub ${BaseStack}-VPCID + + EFSPublicAP: + Type: AWS::EFS::AccessPoint + Properties: + FileSystemId: + Fn::ImportValue: + !Sub ${BaseStack}-EFS + PosixUser: + Uid: "1000" + Gid: "1000" + RootDirectory: + Path: !Sub "/${TENANT}/public" + + EFSPrivateAP: + Type: AWS::EFS::AccessPoint + Properties: + FileSystemId: + Fn::ImportValue: + !Sub ${BaseStack}-EFS + PosixUser: + Uid: "1000" + Gid: "1000" + RootDirectory: + Path: !Sub "/${TENANT}/private" + + EFSSolrAP: + Type: AWS::EFS::AccessPoint + Properties: + FileSystemId: + Fn::ImportValue: + !Sub ${BaseStack}-EFS + PosixUser: + Uid: "8983" + Gid: "8983" + RootDirectory: + Path: !Sub "/${TENANT}/solr" + + ScalableTarget: + DependsOn: ServicePHP + Type: AWS::ApplicationAutoScaling::ScalableTarget + Properties: + MaxCapacity: 20 + MinCapacity: 1 + RoleARN: + Fn::ImportValue: + !Sub ${BaseStack}-AppAutoScalingRole + ServiceNamespace: ecs + ScalableDimension: ecs:service:DesiredCount + ResourceId: + Fn::Join: + - '/' + - - service + - Fn::ImportValue: + !Sub ${BaseStack}-ECSCluster + - !Sub ${TENANT}-php-svc + + ECSCPUAutoscaling: + DependsOn: [ServicePHP, ScalableTarget] + Type: AWS::ApplicationAutoScaling::ScalingPolicy + Properties: + PolicyName: !Sub ${TENANT}-CPU-AutoScaling + PolicyType: TargetTrackingScaling + ScalableDimension: ecs:service:DesiredCount + ServiceNamespace: ecs + TargetTrackingScalingPolicyConfiguration: + ScaleInCooldown: 300 + ScaleOutCooldown: 120 + TargetValue: 50 + PredefinedMetricSpecification: + PredefinedMetricType: ECSServiceAverageCPUUtilization + ResourceId: + Fn::Join: + - '/' + - - service + - Fn::ImportValue: + !Sub ${BaseStack}-ECSCluster + - !Sub ${TENANT}-php-svc + + ECSMEMAutoscaling: + DependsOn: [ServicePHP, ScalableTarget] + Type: AWS::ApplicationAutoScaling::ScalingPolicy + Properties: + PolicyName: !Sub ${TENANT}-MEM-AutoScaling + PolicyType: TargetTrackingScaling + ScalableDimension: ecs:service:DesiredCount + ServiceNamespace: ecs + TargetTrackingScalingPolicyConfiguration: + ScaleInCooldown: 300 + ScaleOutCooldown: 120 + TargetValue: 50 + PredefinedMetricSpecification: + PredefinedMetricType: ECSServiceAverageMemoryUtilization + ResourceId: + Fn::Join: + - '/' + - - service + - Fn::ImportValue: + !Sub ${BaseStack}-ECSCluster + - !Sub ${TENANT}-php-svc + + CloudWatchPHPLogGroup: + Type: AWS::Logs::LogGroup + Properties: + LogGroupName: !Sub ${TENANT}-php + RetentionInDays: 365 + + CloudWatchPHPAdminLogGroup: + Type: AWS::Logs::LogGroup + Properties: + LogGroupName: !Sub ${TENANT}-php-updates + RetentionInDays: 365 + + CloudWatchSOLRLogGroup: + Type: AWS::Logs::LogGroup + Properties: + LogGroupName: !Sub ${TENANT}-solr + RetentionInDays: 365 + + CloudWatchRedisLogGroup: + Type: AWS::Logs::LogGroup + Properties: + LogGroupName: !Sub ${TENANT}-redis + RetentionInDays: 365 + + SearchAPIMetric: + Type: AWS::Logs::MetricFilter + Properties: + FilterPattern: "ERROR search_api" + LogGroupName: !Ref CloudWatchPHPLogGroup + MetricTransformations: + - MetricName: !Sub ${TENANT}-SOLR-error + MetricNamespace: !Sub ${TENANT} + MetricValue: 1 + + SearchAPIAlarm: + Type: AWS::CloudWatch::Alarm + DependsOn: SearchAPIMetric + Properties: + AlarmActions: + - !Sub ${SNSTopic} + AlarmDescription: "SOLR has triggered an error. Check Watchdog and Status Report" + AlarmName: !Sub ${TENANT}-SOLR-Error-Alarm + ComparisonOperator: GreaterThanOrEqualToThreshold + DatapointsToAlarm: 1 + EvaluationPeriods: 1 + Threshold: 0 + MetricName: !Sub ${TENANT}-SOLR-error + Namespace: !Sub ${TENANT} + Period: 60 + Statistic: Sum + TreatMissingData: notBreaching + + LRSMetric: + Type: AWS::Logs::MetricFilter + Properties: + FilterPattern: "ERROR xapi" + LogGroupName: !Ref CloudWatchPHPLogGroup + MetricTransformations: + - MetricName: !Sub ${TENANT}-LRS-error + MetricNamespace: !Sub ${TENANT} + MetricValue: 1 + + LRSAlarm: + Type: AWS::CloudWatch::Alarm + DependsOn: LRSMetric + Properties: + AlarmActions: + - !Sub ${SNSTopic} + AlarmDescription: "LRS has triggered an error. Check Watchdog and Status Report" + AlarmName: !Sub ${TENANT}-LRS-Error-Alarm + ComparisonOperator: GreaterThanOrEqualToThreshold + DatapointsToAlarm: 1 + EvaluationPeriods: 1 + Threshold: 0 + MetricName: !Sub ${TENANT}-LRS-error + Namespace: !Sub ${TENANT} + Period: 60 + Statistic: Sum + TreatMissingData: notBreaching + + 5xxMetric: + Type: AWS::Logs::MetricFilter + Properties: + FilterPattern: "[ip, id, user, timestamp, request, status_code=5*, size]" + LogGroupName: !Ref CloudWatchPHPLogGroup + MetricTransformations: + - MetricName: !Sub ${TENANT}-5xx-error + MetricNamespace: !Sub ${TENANT} + MetricValue: 1 + + 5xxAlarm: + Type: AWS::CloudWatch::Alarm + DependsOn: 5xxMetric + Properties: + AlarmActions: + - !Sub ${SNSTopic} + AlarmDescription: "Internal Server Error has occured." + AlarmName: !Sub ${TENANT}-5xx-Error-Alarm + ComparisonOperator: GreaterThanOrEqualToThreshold + DatapointsToAlarm: 1 + EvaluationPeriods: 1 + Threshold: 0 + MetricName: !Sub ${TENANT}-5xx-error + Namespace: !Sub ${TENANT} + Period: 60 + Statistic: Sum + TreatMissingData: notBreaching + + ELB5xxAlarm: + Type: AWS::CloudWatch::Alarm + Properties: + AlarmActions: + - !Sub ${SNSTopic} + AlarmDescription: "5xx error has occured on Load Balancer level." + AlarmName: !Sub ${TENANT}-ELB-5xx-Error-Alarm + ComparisonOperator: GreaterThanOrEqualToThreshold + DatapointsToAlarm: 1 + EvaluationPeriods: 5 + Threshold: 0 + MetricName: HTTPCode_ELB_5XX_Count + Namespace: AWS/ApplicationELB + Dimensions: + - Name: LoadBalancer + Value: !Sub ${BaseStack}AppLB + Period: 60 + Statistic: Sum + TreatMissingData: notBreaching + + HealthCheck: + Type: 'AWS::Route53::HealthCheck' + Properties: + HealthCheckConfig: + Port: 443 + Type: HTTPS + ResourcePath: '/user/login' + FullyQualifiedDomainName: !Sub ${ADDRESS} + RequestInterval: 30 + FailureThreshold: 2 + HealthCheckTags: + - + Key: Name + Value: !Sub ${TENANT}-HealthCheck + + HealthCheckAlarm : + Type: AWS::CloudWatch::Alarm + DependsOn: ServicePHP + Properties: + AlarmDescription : "Health Check Alarm" + AlarmName: !Sub ${TENANT}-HealthCheck-Alarm + Namespace: AWS/Route53 + MetricName: HealthCheckStatus + Dimensions: + - Name: HealthCheckId + Value: !Ref HealthCheck + ComparisonOperator: LessThanThreshold + Period: 60 + EvaluationPeriods: 5 + Statistic: Minimum + Threshold: 1.0 + AlarmActions: + - !Sub ${SNSTopic} + + CPUAlarm: + Type: AWS::CloudWatch::Alarm + DependsOn: ServicePHP + Properties: + AlarmActions: + - !Sub ${SNSTopic} + AlarmDescription: "CPU utilitzation alarm" + AlarmName: !Sub ${TENANT}-CPU-Alarm + ComparisonOperator: GreaterThanOrEqualToThreshold + DatapointsToAlarm: 3 + Dimensions: + - Name: ClusterName + Value: + Fn::ImportValue: + !Sub ${BaseStack}-ECSCluster + - Name: ServiceName + Value: !Sub ${TENANT}-php-svc + EvaluationPeriods: 5 + Threshold: 65 + MetricName: CPUUtilization + Namespace: AWS/ECS + Period: 60 + Statistic: Average + TreatMissingData: notBreaching + + MemoryAlarm: + Type: AWS::CloudWatch::Alarm + DependsOn: ServicePHP + Properties: + AlarmActions: + - !Sub ${SNSTopic} + AlarmDescription: "Memory utilitzation alarm" + AlarmName: !Sub ${TENANT}-MEM-Alarm + ComparisonOperator: GreaterThanOrEqualToThreshold + DatapointsToAlarm: 3 + Dimensions: + - Name: ClusterName + Value: + Fn::ImportValue: + !Sub ${BaseStack}-ECSCluster + - Name: ServiceName + Value: !Sub ${TENANT}-php-svc + + EvaluationPeriods: 5 + Threshold: 65 + MetricName: MemoryUtilization + Namespace: AWS/ECS + Period: 60 + Statistic: Average + TreatMissingData: notBreaching + + CronEvent: + Type: AWS::Events::Rule + Properties: + Description: "Scheduled Cloudwatch Event for Tenant Cron runs" + Name: !Sub ${TENANT} + ScheduleExpression: "rate(10 minutes)" + Targets: + - + Arn: + Fn::ImportValue: + "api-CronFunction" + Id: "cron_function" + Input: + Fn::Sub: + '{"tenant": "${TENANT}"}' + + PermissionForEventsToInvokeLambda: + Type: AWS::Lambda::Permission + Properties: + FunctionName: "cron_function" + Action: "lambda:InvokeFunction" + Principal: "events.amazonaws.com" + SourceArn: + Fn::GetAtt: + - "CronEvent" + - "Arn" diff --git a/scripts/test.sh b/scripts/test.sh new file mode 100755 index 0000000..df5c021 --- /dev/null +++ b/scripts/test.sh @@ -0,0 +1,100 @@ +#!/bin/bash +set -e + +# +# Runs tests against the Drupal site and writes results to `tests/artifacts`. +# Must be run from git root. + +set -a + +print_usage() { + echo "test.sh Run Behat tests for Perls" + echo " " + echo "test.sh [options]" + echo " " + echo "options:" + echo "-h, --help show brief help" + echo "-a Run all tests core and recommendation engine." +} +run_all=false +while getopts 'a' flag; do + case "${flag}" in + a) run_all=true ;; + *) print_usage + exit 1 ;; + esac +done + +TAGS='@core_functionality' +if [[ "$run_all" == true ]]; then + TAGS='@core_functionality,@recommendation_engine' +fi + +#Make sure environmental variables are setup +if [ ! -f .env ]; then + if [ -f .env.example ]; then + echo "No .env file found. Copying .env.example to .env" + cp .env.example .env + fi +fi + +# Check that screenshots folder is existing. +if [ -d "artifacts/screenshots" ]; then + rm -R artifacts + mkdir -p artifacts/screenshots +else + mkdir -p artifacts/screenshots +fi + +# Load environmental variables +source .env + + +if [ $(docker inspect -f {{.State.Running}} ${PROJECT_NAME}_chrome 2>/dev/null) ]; then + echo "Remove the old chrome container" + docker stop ${PROJECT_NAME}_chrome + docker rm ${PROJECT_NAME}_chrome +fi + +echo "Starting tests..." +# Check to see if the app container is already running +ALREADY_RUNNING=$(docker inspect -f {{.State.Running}} ${PROJECT_NAME}_php 2>/dev/null) + +if [ ! $ALREADY_RUNNING = "true" ]; then + docker-compose up -d +fi + +echo "Starting a Google Chrome container for running the Behat tests..." +# The Google Chrome container must have access to the file system in order to upload files. +docker run -d --network=${PROJECT_NAME}_network \ +--cap-add=SYS_ADMIN \ +--publish=9222 --name="${PROJECT_NAME}_chrome" \ +justinribeiro/chrome-headless + +ALREADY_RUNNING=$(docker inspect -f {{.State.Running}} ${PROJECT_NAME}_chrome 2>/dev/null) + +if [ ! $ALREADY_RUNNING = "true" ]; then + echo 'Chrome container has stopped.' + exit 1 +fi + +echo "Starting UI tests..." +BEHAT_PARAMS="{\"extensions\":{\"Drupal\\\MinkExtension\":{\"sessions\":{\"javascript\":{\"chrome\":{\"api_url\":\"http://${PROJECT_NAME}_chrome:9222\"}},\"browserChrome\":{\"chrome\":{\"api_url\":\"http://${PROJECT_NAME}_chrome:9222\"}}}}}}" +echo $BEHAT_PARAMS +docker exec -e BEHAT_PARAMS=$BEHAT_PARAMS ${PROJECT_NAME}_php ./vendor/bin/behat --init +docker exec -e BEHAT_PARAMS=$BEHAT_PARAMS ${PROJECT_NAME}_php ./vendor/bin/behat \ +--config=./behat.yml --colors --tags $TAGS + +mkdir ./web/sites/simpletest +mkdir ./web/sites/simpletest/browser_output +chmod 777 ./web/sites/simpletest/browser_output + +./scripts/unit.sh + +echo "Shutting down Chrome..." + +docker network disconnect -f ${PROJECT_NAME}_network ${PROJECT_NAME}_chrome +docker stop ${PROJECT_NAME}_chrome +docker rm ${PROJECT_NAME}_chrome -f + +echo "Finished running tests! 🎉" diff --git a/scripts/unit.sh b/scripts/unit.sh new file mode 100755 index 0000000..36ca5ae --- /dev/null +++ b/scripts/unit.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +docker exec ${PROJECT_NAME}_php ./vendor/bin/phpunit -v -c ./phpunit.xml ./web/core/modules/node/tests/src/Unit diff --git a/simplesamlphp_config/config/authsources.php b/simplesamlphp_config/config/authsources.php new file mode 100644 index 0000000..9824744 --- /dev/null +++ b/simplesamlphp_config/config/authsources.php @@ -0,0 +1,69 @@ + array( + // The default is to use core:AdminPassword, but it can be replaced with + // any authentication source. + 'core:AdminPassword', + ), +); + +$path = getenv('SIMPLESAML_CONFIG_DIR'); +if (!$path) { + $path = '/var/www/html/private/saml_config'; +} +try { + $file_count = 0; + foreach (new DirectoryIterator($path) as $fileInfo) { + if($fileInfo->isDot()) continue; + $ext = $fileInfo->getExtension(); + if ($ext == 'xml') { + $xmldata = file_get_contents($path . '/' . $fileInfo->getFilename()); + $entities = \SimpleSAML\Metadata\SAMLParser::parseDescriptorsString($xmldata); + if (!empty($entities)) { + $file_count++; + $keys = array_unique(array_keys($entities)); + } + } + } + // Set IDP only if we encounter 1 XML file. + if ($file_count == 1 && !empty($keys)) { + $idp = reset($keys); + } + else { + // If there are more files, let the user choose the IDP. + $idp = NULL; + } +} +// If the path cannot be opened. +catch (\UnexpectedValueException $e) { + echo "There seems to be an issue with the SSO configuration path. Please contact the administrator."; +} +// If the path is an empty string. +catch (\RuntimeException $e) { + echo "The SSO configuration could not be loaded. Please contact the administrator."; +} + +$authsource = getenv('SIMPLESAML_AUTH_SOURCE') ?? 'default-sp'; +$config[$authsource] = array( + 'saml:SP', + 'entityID' => $authsource, + 'idp' => $idp, + 'discoURL' => null, + 'acs.Bindings' => array( + 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST', + ), + 'SingleLogoutServiceBinding' => array(), + 'signature.algorithm' => 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256', + 'name' => 'PERLS', + 'NameIDPolicy' => 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress', + 'attributes' => array( + 'mail', + 'sn', + 'givenName', + ), + 'attributes.required' => array ( + 'mail', + ), +); diff --git a/simplesamlphp_config/config/config.php b/simplesamlphp_config/config/config.php new file mode 100644 index 0000000..16bcf95 --- /dev/null +++ b/simplesamlphp_config/config/config.php @@ -0,0 +1,1042 @@ + 'https://' . $_SERVER['HTTP_HOST'] . '/simplesaml/', + + /* + * The 'application' configuration array groups a set configuration options + * relative to an application protected by SimpleSAMLphp. + */ + //'application' => array( + /* + * The 'baseURL' configuration option allows you to specify a protocol, + * host and optionally a port that serves as the canonical base for all + * your application's URLs. This is useful when the environment + * observed in the server differs from the one observed by end users, + * for example, when using a load balancer to offload TLS. + * + * Note that this configuration option does not allow setting a path as + * part of the URL. If your setup involves URL rewriting or any other + * tricks that would result in SimpleSAMLphp observing a URL for your + * application's scripts different than the canonical one, you will + * need to compute the right URLs yourself and pass them dynamically + * to SimpleSAMLphp's API. + */ + //'baseURL' => 'https://example.com' + //), + + /* + * The following settings are *filesystem paths* which define where + * SimpleSAMLphp can find or write the following things: + * - 'certdir': The base directory for certificate and key material. + * - 'loggingdir': Where to write logs. + * - 'datadir': Storage of general data. + * - 'temdir': Saving temporary files. SimpleSAMLphp will attempt to create + * this directory if it doesn't exist. + * When specified as a relative path, this is relative to the SimpleSAMLphp + * root directory. + */ + 'certdir' => 'cert/', + 'loggingdir' => 'log/', + 'datadir' => 'data/', + 'tempdir' => '/tmp/simplesaml', + + /* + * Some information about the technical persons running this installation. + * The email address will be used as the recipient address for error reports, and + * also as the technical contact in generated metadata. + */ + 'technicalcontact_name' => '', + 'technicalcontact_email' => '', + + /* + * The timezone of the server. This option should be set to the timezone you want + * SimpleSAMLphp to report the time in. The default is to guess the timezone based + * on your system timezone. + * + * See this page for a list of valid timezones: http://php.net/manual/en/timezones.php + */ + 'timezone' => 'America/Chicago', + + + + /********************************** + | SECURITY CONFIGURATION OPTIONS | + **********************************/ + + /* + * This is a secret salt used by SimpleSAMLphp when it needs to generate a secure hash + * of a value. It must be changed from its default value to a secret value. The value of + * 'secretsalt' can be any valid string of any length. + * + * A possible way to generate a random salt is by running the following command from a unix shell: + * tr -c -d '0123456789abcdefghijklmnopqrstuvwxyz' /dev/null;echo + */ + 'secretsalt' => 'rOld6lwRJiJJN877PKR90ohHypDY', + + /* + * This password must be kept secret, and modified from the default value 123. + * This password will give access to the installation page of SimpleSAMLphp with + * metadata listing and diagnostics pages. + * You can also put a hash here; run "bin/pwgen.php" to generate one. + */ + 'auth.adminpassword' => '', + + /* + * Set this options to true if you want to require administrator password to access the web interface + * or the metadata pages, respectively. + */ + 'admin.protectindexpage' => true, + 'admin.protectmetadata' => true, + + /* + * Set this option to false if you don't want SimpleSAMLphp to check for new stable releases when + * visiting the configuration tab in the web interface. + */ + 'admin.checkforupdates' => true, + + /* + * Array of domains that are allowed when generating links or redirects + * to URLs. SimpleSAMLphp will use this option to determine whether to + * to consider a given URL valid or not, but you should always validate + * URLs obtained from the input on your own (i.e. ReturnTo or RelayState + * parameters obtained from the $_REQUEST array). + * + * SimpleSAMLphp will automatically add your own domain (either by checking + * it dynamically, or by using the domain defined in the 'baseurlpath' + * directive, the latter having precedence) to the list of trusted domains, + * in case this option is NOT set to NULL. In that case, you are explicitly + * telling SimpleSAMLphp to verify URLs. + * + * Set to an empty array to disallow ALL redirects or links pointing to + * an external URL other than your own domain. This is the default behaviour. + * + * Set to NULL to disable checking of URLs. DO NOT DO THIS UNLESS YOU KNOW + * WHAT YOU ARE DOING! + * + * Example: + * 'trusted.url.domains' => array('sp.example.com', 'app.example.com'), + */ + 'trusted.url.domains' => NULL, + + /* + * Enable regular expression matching of trusted.url.domains. + * + * Set to true to treat the values in trusted.url.domains as regular + * expressions. Set to false to do exact string matching. + * + * If enabled, the start and end delimiters ('^' and '$') will be added to + * all regular expressions in trusted.url.domains. + */ + 'trusted.url.regex' => false, + + /* + * Enable secure POST from HTTPS to HTTP. + * + * If you have some SP's on HTTP and IdP is normally on HTTPS, this option + * enables secure POSTing to HTTP endpoint without warning from browser. + * + * For this to work, module.php/core/postredirect.php must be accessible + * also via HTTP on IdP, e.g. if your IdP is on + * https://idp.example.org/ssp/, then + * http://idp.example.org/ssp/module.php/core/postredirect.php must be accessible. + */ + 'enable.http_post' => false, + + + + /************************ + | ERRORS AND DEBUGGING | + ************************/ + + /* + * The 'debug' option allows you to control how SimpleSAMLphp behaves in certain + * situations where further action may be taken + * + * It can be left unset, in which case, debugging is switched off for all actions. + * If set, it MUST be an array containing the actions that you want to enable, or + * alternatively a hashed array where the keys are the actions and their + * corresponding values are booleans enabling or disabling each particular action. + * + * SimpleSAMLphp provides some pre-defined actiones, though modules could add new + * actions here. Refer to the documentation of every module to learn if they + * allow you to set any more debugging actions. + * + * The pre-defined actions are: + * + * - 'saml': this action controls the logging of SAML messages exchanged with other + * entities. When enabled ('saml' is present in this option, or set to true), all + * SAML messages will be logged, including plaintext versions of encrypted + * messages. + * + * - 'backtraces': this action controls the logging of error backtraces. If you + * want to log backtraces so that you can debug any possible errors happening in + * SimpleSAMLphp, enable this action (add it to the array or set it to true). + * + * - 'validatexml': this action allows you to validate SAML documents against all + * the relevant XML schemas. SAML 1.1 messages or SAML metadata parsed with + * the XML to SimpleSAMLphp metadata converter or the metaedit module will + * validate the SAML documents if this option is enabled. + * + * If you want to disable debugging completely, unset this option or set it to an + * empty array. + */ + 'debug' => array( + 'saml' => false, + 'backtraces' => false, + 'validatexml' => false, + ), + + /* + * When 'showerrors' is enabled, all error messages and stack traces will be output + * to the browser. + * + * When 'errorreporting' is enabled, a form will be presented for the user to report + * the error to 'technicalcontact_email'. + */ + 'showerrors' => false, + 'errorreporting' => false, + + /* + * Custom error show function called from SimpleSAML_Error_Error::show. + * See docs/simplesamlphp-errorhandling.txt for function code example. + * + * Example: + * 'errors.show_function' => array('sspmod_example_Error_Show', 'show'), + */ + + + + /************************** + | LOGGING AND STATISTICS | + **************************/ + + /* + * Define the minimum log level to log. Available levels: + * - SimpleSAML\Logger::ERR No statistics, only errors + * - SimpleSAML\Logger::WARNING No statistics, only warnings/errors + * - SimpleSAML\Logger::NOTICE Statistics and errors + * - SimpleSAML\Logger::INFO Verbose logs + * - SimpleSAML\Logger::DEBUG Full debug logs - not recommended for production + * + * Choose logging handler. + * + * Options: [syslog,file,errorlog] + * + */ + 'logging.level' => SimpleSAML\Logger::DEBUG, + 'logging.handler' => 'syslog', + + /* + * Specify the format of the logs. Its use varies depending on the log handler used (for instance, you cannot + * control here how dates are displayed when using the syslog or errorlog handlers), but in general the options + * are: + * + * - %date{}: the date and time, with its format specified inside the brackets. See the PHP documentation + * of the strftime() function for more information on the format. If the brackets are omitted, the standard + * format is applied. This can be useful if you just want to control the placement of the date, but don't care + * about the format. + * + * - %process: the name of the SimpleSAMLphp process. Remember you can configure this in the 'logging.processname' + * option below. + * + * - %level: the log level (name or number depending on the handler used). + * + * - %stat: if the log entry is intended for statistical purposes, it will print the string 'STAT ' (bear in mind + * the trailing space). + * + * - %trackid: the track ID, an identifier that allows you to track a single session. + * + * - %srcip: the IP address of the client. If you are behind a proxy, make sure to modify the + * $_SERVER['REMOTE_ADDR'] variable on your code accordingly to the X-Forwarded-For header. + * + * - %msg: the message to be logged. + * + */ + //'logging.format' => '%date{%b %d %H:%M:%S} %process %level %stat[%trackid] %msg', + + /* + * Choose which facility should be used when logging with syslog. + * + * These can be used for filtering the syslog output from SimpleSAMLphp into its + * own file by configuring the syslog daemon. + * + * See the documentation for openlog (http://php.net/manual/en/function.openlog.php) for available + * facilities. Note that only LOG_USER is valid on windows. + * + * The default is to use LOG_LOCAL5 if available, and fall back to LOG_USER if not. + */ + 'logging.facility' => defined('LOG_LOCAL5') ? constant('LOG_LOCAL5') : LOG_USER, + + /* + * The process name that should be used when logging to syslog. + * The value is also written out by the other logging handlers. + */ + 'logging.processname' => 'simplesamlphp', + + /* + * Logging: file - Logfilename in the loggingdir from above. + */ + 'logging.logfile' => 'simplesamlphp.log', + + /* + * This is an array of outputs. Each output has at least a 'class' option, which + * selects the output. + */ + 'statistics.out' => array(// Log statistics to the normal log. + /* + array( + 'class' => 'core:Log', + 'level' => 'notice', + ), + */ + // Log statistics to files in a directory. One file per day. + /* + array( + 'class' => 'core:File', + 'directory' => '/var/log/stats', + ), + */ + ), + + + + /*********************** + | PROXY CONFIGURATION | + ***********************/ + + /* + * Proxy to use for retrieving URLs. + * + * Example: + * 'proxy' => 'tcp://proxy.example.com:5100' + */ + 'proxy' => null, + + /* + * Username/password authentication to proxy (Proxy-Authorization: Basic) + * Example: + * 'proxy.auth' = 'myuser:password' + */ + 'proxy.auth' => false, + + + + /************************** + | DATABASE CONFIGURATION | + **************************/ + + /* + * This database configuration is optional. If you are not using + * core functionality or modules that require a database, you can + * skip this configuration. + */ + + /* + * Database connection string. + * Ensure that you have the required PDO database driver installed + * for your connection string. + */ + 'database.dsn' => 'mysql:host=localhost;dbname=saml', + + /* + * SQL database credentials + */ + 'database.username' => 'simplesamlphp', + 'database.password' => 'secret', + + /* + * (Optional) Table prefix + */ + 'database.prefix' => '', + + /* + * True or false if you would like a persistent database connection + */ + 'database.persistent' => false, + + /* + * Database slave configuration is optional as well. If you are only + * running a single database server, leave this blank. If you have + * a master/slave configuration, you can define as many slave servers + * as you want here. Slaves will be picked at random to be queried from. + * + * Configuration options in the slave array are exactly the same as the + * options for the master (shown above) with the exception of the table + * prefix. + */ + 'database.slaves' => array( + /* + array( + 'dsn' => 'mysql:host=myslave;dbname=saml', + 'username' => 'simplesamlphp', + 'password' => 'secret', + 'persistent' => false, + ), + */ + ), + + + + /************* + | PROTOCOLS | + *************/ + + /* + * Which functionality in SimpleSAMLphp do you want to enable. Normally you would enable only + * one of the functionalities below, but in some cases you could run multiple functionalities. + * In example when you are setting up a federation bridge. + */ + 'enable.saml20-idp' => false, + 'enable.shib13-idp' => false, + 'enable.adfs-idp' => false, + 'enable.wsfed-sp' => false, + 'enable.authmemcookie' => false, + + /* + * Default IdP for WS-Fed. + */ + 'default-wsfed-idp' => 'urn:federation:pingfederate:localhost', + + /* + * Whether SimpleSAMLphp should sign the response or the assertion in SAML 1.1 authentication + * responses. + * + * The default is to sign the assertion element, but that can be overridden by setting this + * option to TRUE. It can also be overridden on a pr. SP basis by adding an option with the + * same name to the metadata of the SP. + */ + 'shib13.signresponse' => true, + + + + /*********** + | MODULES | + ***********/ + + /* + * Configuration to override module enabling/disabling. + * + * Example: + * + * 'module.enable' => array( + * 'exampleauth' => TRUE, // Setting to TRUE enables. + * 'saml' => FALSE, // Setting to FALSE disables. + * 'core' => NULL, // Unset or NULL uses default. + * ), + * + */ + + + + /************************* + | SESSION CONFIGURATION | + *************************/ + + /* + * This value is the duration of the session in seconds. Make sure that the time duration of + * cookies both at the SP and the IdP exceeds this duration. + */ + 'session.duration' => 8 * (60 * 60), // 8 hours. + + /* + * Sets the duration, in seconds, data should be stored in the datastore. As the data store is used for + * login and logout requests, this option will control the maximum time these operations can take. + * The default is 4 hours (4*60*60) seconds, which should be more than enough for these operations. + */ + 'session.datastore.timeout' => (4 * 60 * 60), // 4 hours + + /* + * Sets the duration, in seconds, auth state should be stored. + */ + 'session.state.timeout' => (60 * 60), // 1 hour + + /* + * Option to override the default settings for the session cookie name + */ + 'session.cookie.name' => 'SimpleSAMLSessionID', + + /* + * Expiration time for the session cookie, in seconds. + * + * Defaults to 0, which means that the cookie expires when the browser is closed. + * + * Example: + * 'session.cookie.lifetime' => 30*60, + */ + 'session.cookie.lifetime' => 0, + + /* + * Limit the path of the cookies. + * + * Can be used to limit the path of the cookies to a specific subdirectory. + * + * Example: + * 'session.cookie.path' => '/simplesaml/', + */ + 'session.cookie.path' => '/', + + /* + * Cookie domain. + * + * Can be used to make the session cookie available to several domains. + * + * Example: + * 'session.cookie.domain' => '.example.org', + */ + 'session.cookie.domain' => null, + + /* + * Set the secure flag in the cookie. + * + * Set this to TRUE if the user only accesses your service + * through https. If the user can access the service through + * both http and https, this must be set to FALSE. + */ + 'session.cookie.secure' => !empty($_SERVER['HTTPS']), + + /* + * Options to override the default settings for php sessions. + */ + 'session.phpsession.cookiename' => 'SimpleSAML', + 'session.phpsession.savepath' => null, + 'session.phpsession.httponly' => true, + + /* + * Option to override the default settings for the auth token cookie + */ + 'session.authtoken.cookiename' => 'SimpleSAMLAuthToken', + + /* + * Options for remember me feature for IdP sessions. Remember me feature + * has to be also implemented in authentication source used. + * + * Option 'session.cookie.lifetime' should be set to zero (0), i.e. cookie + * expires on browser session if remember me is not checked. + * + * Session duration ('session.duration' option) should be set according to + * 'session.rememberme.lifetime' option. + * + * It's advised to use remember me feature with session checking function + * defined with 'session.check_function' option. + */ + 'session.rememberme.enable' => false, + 'session.rememberme.checked' => false, + 'session.rememberme.lifetime' => (14 * 86400), + + /* + * Custom function for session checking called on session init and loading. + * See docs/simplesamlphp-advancedfeatures.txt for function code example. + * + * Example: + * 'session.check_function' => array('sspmod_example_Util', 'checkSession'), + */ + + + + /************************** + | MEMCACHE CONFIGURATION | + **************************/ + + /* + * Configuration for the 'memcache' session store. This allows you to store + * multiple redundant copies of sessions on different memcache servers. + * + * 'memcache_store.servers' is an array of server groups. Every data + * item will be mirrored in every server group. + * + * Each server group is an array of servers. The data items will be + * load-balanced between all servers in each server group. + * + * Each server is an array of parameters for the server. The following + * options are available: + * - 'hostname': This is the hostname or ip address where the + * memcache server runs. This is the only required option. + * - 'port': This is the port number of the memcache server. If this + * option isn't set, then we will use the 'memcache.default_port' + * ini setting. This is 11211 by default. + * - 'weight': This sets the weight of this server in this server + * group. http://php.net/manual/en/function.Memcache-addServer.php + * contains more information about the weight option. + * - 'timeout': The timeout for this server. By default, the timeout + * is 3 seconds. + * + * Example of redundant configuration with load balancing: + * This configuration makes it possible to lose both servers in the + * a-group or both servers in the b-group without losing any sessions. + * Note that sessions will be lost if one server is lost from both the + * a-group and the b-group. + * + * 'memcache_store.servers' => array( + * array( + * array('hostname' => 'mc_a1'), + * array('hostname' => 'mc_a2'), + * ), + * array( + * array('hostname' => 'mc_b1'), + * array('hostname' => 'mc_b2'), + * ), + * ), + * + * Example of simple configuration with only one memcache server, + * running on the same computer as the web server: + * Note that all sessions will be lost if the memcache server crashes. + * + * 'memcache_store.servers' => array( + * array( + * array('hostname' => 'localhost'), + * ), + * ), + * + */ + 'memcache_store.servers' => array( + array( + array('hostname' => 'localhost'), + ), + ), + + /* + * This value allows you to set a prefix for memcache-keys. The default + * for this value is 'simpleSAMLphp', which is fine in most cases. + * + * When running multiple instances of SSP on the same host, and more + * than one instance is using memcache, you probably want to assign + * a unique value per instance to this setting to avoid data collision. + */ + 'memcache_store.prefix' => '', + + /* + * This value is the duration data should be stored in memcache. Data + * will be dropped from the memcache servers when this time expires. + * The time will be reset every time the data is written to the + * memcache servers. + * + * This value should always be larger than the 'session.duration' + * option. Not doing this may result in the session being deleted from + * the memcache servers while it is still in use. + * + * Set this value to 0 if you don't want data to expire. + * + * Note: The oldest data will always be deleted if the memcache server + * runs out of storage space. + */ + 'memcache_store.expires' => 36 * (60 * 60), // 36 hours. + + + + /************************************* + | LANGUAGE AND INTERNATIONALIZATION | + *************************************/ + + /* + * Languages available, RTL languages, and what language is the default. + */ + 'language.available' => array( + 'en', /*'no', 'nn', 'se', 'da', 'de', 'sv', 'fi', 'es', 'fr', 'it', 'nl', 'lb', 'cs', + 'sl', 'lt', 'hr', 'hu', 'pl', 'pt', 'pt-br', 'tr', 'ja', 'zh', 'zh-tw', 'ru', 'et', + 'he', 'id', 'sr', 'lv', 'ro', 'eu', 'el', 'af'*/ + ), + 'language.rtl' => array('ar', 'dv', 'fa', 'ur', 'he'), + 'language.default' => 'en', + + /* + * Options to override the default settings for the language parameter + */ + 'language.parameter.name' => 'language', + 'language.parameter.setcookie' => true, + + /* + * Options to override the default settings for the language cookie + */ + 'language.cookie.name' => 'language', + 'language.cookie.domain' => null, + 'language.cookie.path' => '/', + 'language.cookie.secure' => false, + 'language.cookie.httponly' => false, + 'language.cookie.lifetime' => (60 * 60 * 24 * 900), + + /* + * Which i18n backend to use. + * + * "SimpleSAMLphp" is the home made system, valid for 1.x. + * For 2.x, only "gettext/gettext" will be possible. + * + * Home-made templates will always use "SimpleSAMLphp". + * To use twig (where avaliable), select "gettext/gettext". + */ + 'language.i18n.backend' => 'SimpleSAMLphp', + + /** + * Custom getLanguage function called from SimpleSAML\Locale\Language::getLanguage(). + * Function should return language code of one of the available languages or NULL. + * See SimpleSAML\Locale\Language::getLanguage() source code for more info. + * + * This option can be used to implement a custom function for determining + * the default language for the user. + * + * Example: + * 'language.get_language_function' => array('sspmod_example_Template', 'getLanguage'), + */ + + /* + * Extra dictionary for attribute names. + * This can be used to define local attributes. + * + * The format of the parameter is a string with :. + * + * Specifying this option will cause us to look for modules//dictionaries/.definition.json + * The dictionary should look something like: + * + * { + * "firstattribute": { + * "en": "English name", + * "no": "Norwegian name" + * }, + * "secondattribute": { + * "en": "English name", + * "no": "Norwegian name" + * } + * } + * + * Note that all attribute names in the dictionary must in lowercase. + * + * Example: 'attributes.extradictionary' => 'ourmodule:ourattributes', + */ + 'attributes.extradictionary' => null, + + + + /************** + | APPEARANCE | + **************/ + + /* + * Which theme directory should be used? + */ + 'theme.use' => 'default', + + /* + * Templating options + * + * By default, twig templates are not cached. To turn on template caching: + * Set 'template.cache' to an absolute path pointing to a directory that + * SimpleSAMLphp has read and write permissions to. + */ + //'template.cache' => '', + + /* + * Set the 'template.auto_reload' to true if you would like SimpleSAMLphp to + * recompile the templates (when using the template cache) if the templates + * change. If you don't want to check the source templates for every request, + * set it to false. + */ + 'template.auto_reload' => false, + + + + /********************* + | DISCOVERY SERVICE | + *********************/ + + /* + * Whether the discovery service should allow the user to save his choice of IdP. + */ + 'idpdisco.enableremember' => true, + 'idpdisco.rememberchecked' => true, + + /* + * The disco service only accepts entities it knows. + */ + 'idpdisco.validate' => true, + + 'idpdisco.extDiscoveryStorage' => null, + + /* + * IdP Discovery service look configuration. + * Wether to display a list of idp or to display a dropdown box. For many IdP' a dropdown box + * gives the best use experience. + * + * When using dropdown box a cookie is used to highlight the previously chosen IdP in the dropdown. + * This makes it easier for the user to choose the IdP + * + * Options: [links,dropdown] + */ + 'idpdisco.layout' => 'dropdown', + + + + /************************************* + | AUTHENTICATION PROCESSING FILTERS | + *************************************/ + + /* + * Authentication processing filters that will be executed for all IdPs + * Both Shibboleth and SAML 2.0 + */ + 'authproc.idp' => array( + /* Enable the authproc filter below to add URN prefixes to all attributes + 10 => array( + 'class' => 'core:AttributeMap', 'addurnprefix' + ), */ + /* Enable the authproc filter below to automatically generated eduPersonTargetedID. + 20 => 'core:TargetedID', + */ + + // Adopts language from attribute to use in UI + 30 => 'core:LanguageAdaptor', + + 45 => array( + 'class' => 'core:StatisticsWithAttribute', + 'attributename' => 'realm', + 'type' => 'saml20-idp-SSO', + ), + + /* When called without parameters, it will fallback to filter attributes ‹the old way› + * by checking the 'attributes' parameter in metadata on IdP hosted and SP remote. + */ + 50 => 'core:AttributeLimit', + + /* + * Search attribute "distinguishedName" for pattern and replaces if found + + 60 => array( + 'class' => 'core:AttributeAlter', + 'pattern' => '/OU=studerende/', + 'replacement' => 'Student', + 'subject' => 'distinguishedName', + '%replace', + ), + */ + + /* + * Consent module is enabled (with no permanent storage, using cookies). + + 90 => array( + 'class' => 'consent:Consent', + 'store' => 'consent:Cookie', + 'focus' => 'yes', + 'checked' => TRUE + ), + */ + // If language is set in Consent module it will be added as an attribute. + 99 => 'core:LanguageAdaptor', + ), + + /* + * Authentication processing filters that will be executed for all SPs + * Both Shibboleth and SAML 2.0 + */ + 'authproc.sp' => array( + /* + 10 => array( + 'class' => 'core:AttributeMap', 'removeurnprefix' + ), + */ + + /* + * Generate the 'group' attribute populated from other variables, including eduPersonAffiliation. + 60 => array( + 'class' => 'core:GenerateGroups', 'eduPersonAffiliation' + ), + */ + /* + * All users will be members of 'users' and 'members' + 61 => array( + 'class' => 'core:AttributeAdd', 'groups' => array('users', 'members') + ), + */ + + // Adopts language from attribute to use in UI + 90 => 'core:LanguageAdaptor', + + ), + + + + /************************** + | METADATA CONFIGURATION | + **************************/ + + /* + * This option configures the metadata sources. The metadata sources is given as an array with + * different metadata sources. When searching for metadata, SimpleSAMLphp will search through + * the array from start to end. + * + * Each element in the array is an associative array which configures the metadata source. + * The type of the metadata source is given by the 'type' element. For each type we have + * different configuration options. + * + * Flat file metadata handler: + * - 'type': This is always 'flatfile'. + * - 'directory': The directory we will load the metadata files from. The default value for + * this option is the value of the 'metadatadir' configuration option, or + * 'metadata/' if that option is unset. + * + * XML metadata handler: + * This metadata handler parses an XML file with either an EntityDescriptor element or an + * EntitiesDescriptor element. The XML file may be stored locally, or (for debugging) on a remote + * web server. + * The XML metadata handler defines the following options: + * - 'type': This is always 'xml'. + * - 'file': Path to the XML file with the metadata. + * - 'url': The URL to fetch metadata from. THIS IS ONLY FOR DEBUGGING - THERE IS NO CACHING OF THE RESPONSE. + * + * MDQ metadata handler: + * This metadata handler looks up for the metadata of an entity at the given MDQ server. + * The MDQ metadata handler defines the following options: + * - 'type': This is always 'mdq'. + * - 'server': Base URL of the MDQ server. Mandatory. + * - 'validateFingerprint': The fingerprint of the certificate used to sign the metadata. You don't need this + * option if you don't want to validate the signature on the metadata. Optional. + * - 'cachedir': Directory where metadata can be cached. Optional. + * - 'cachelength': Maximum time metadata can be cached, in seconds. Defaults to 24 + * hours (86400 seconds). Optional. + * + * PDO metadata handler: + * This metadata handler looks up metadata of an entity stored in a database. + * + * Note: If you are using the PDO metadata handler, you must configure the database + * options in this configuration file. + * + * The PDO metadata handler defines the following options: + * - 'type': This is always 'pdo'. + * + * Examples: + * + * This example defines two flatfile sources. One is the default metadata directory, the other + * is a metadata directory with auto-generated metadata files. + * + * 'metadata.sources' => array( + * array('type' => 'flatfile'), + * array('type' => 'flatfile', 'directory' => 'metadata-generated'), + * ), + * + * This example defines a flatfile source and an XML source. + * 'metadata.sources' => array( + * array('type' => 'flatfile'), + * array('type' => 'xml', 'file' => 'idp.example.org-idpMeta.xml'), + * ), + * + * This example defines an mdq source. + * 'metadata.sources' => array( + * array( + * 'type' => 'mdq', + * 'server' => 'http://mdq.server.com:8080', + * 'cachedir' => '/var/simplesamlphp/mdq-cache', + * 'cachelength' => 86400 + * ) + * ), + * + * This example defines an pdo source. + * 'metadata.sources' => array( + * array('type' => 'pdo') + * ), + * + * Default: + * 'metadata.sources' => array( + * array('type' => 'flatfile') + * ), + */ + 'metadata.sources' => array( + array('type' => 'flatfile'), + ), + + /* + * Should signing of generated metadata be enabled by default. + * + * Metadata signing can also be enabled for a individual SP or IdP by setting the + * same option in the metadata for the SP or IdP. + */ + 'metadata.sign.enable' => false, + + /* + * The default key & certificate which should be used to sign generated metadata. These + * are files stored in the cert dir. + * These values can be overridden by the options with the same names in the SP or + * IdP metadata. + * + * If these aren't specified here or in the metadata for the SP or IdP, then + * the 'certificate' and 'privatekey' option in the metadata will be used. + * if those aren't set, signing of metadata will fail. + */ + 'metadata.sign.privatekey' => null, + 'metadata.sign.privatekey_pass' => null, + 'metadata.sign.certificate' => null, + + + + /**************************** + | DATA STORE CONFIGURATION | + ****************************/ + + /* + * Configure the data store for SimpleSAMLphp. + * + * - 'phpsession': Limited datastore, which uses the PHP session. + * - 'memcache': Key-value datastore, based on memcache. + * - 'sql': SQL datastore, using PDO. + * - 'redis': Key-value datastore, based on redis. + * + * The default datastore is 'phpsession'. + * + * (This option replaces the old 'session.handler'-option.) + */ + 'store.type' => 'sql', + + /* + * The DSN the sql datastore should connect to. + * + * See http://www.php.net/manual/en/pdo.drivers.php for the various + * syntaxes. + */ + 'store.sql.dsn' => 'sqlite:/tmp/simplesamlphp.sq3', + + /* + * The username and password to use when connecting to the database. + */ + 'store.sql.username' => 'user', + 'store.sql.password' => 'pass', + + /* + * The prefix we should use on our tables. + */ + 'store.sql.prefix' => 'SimpleSAMLphp', + + /* + * The hostname and port of the Redis datastore instance. + */ + 'store.redis.host' => 'localhost', + 'store.redis.port' => 6379, + + /* + * The prefix we should use on our Redis datastore. + */ + 'store.redis.prefix' => 'SimpleSAMLphp', +); diff --git a/simplesamlphp_config/metadata/saml20-idp-remote.php b/simplesamlphp_config/metadata/saml20-idp-remote.php new file mode 100644 index 0000000..899a3ab --- /dev/null +++ b/simplesamlphp_config/metadata/saml20-idp-remote.php @@ -0,0 +1,59 @@ +isDot()) continue; + $ext = $fileInfo->getExtension(); + if ($ext == 'xml') { + $xmldata = file_get_contents($path . '/' . $fileInfo->getFilename()); + $entities = \SimpleSAML\Metadata\SAMLParser::parseDescriptorsString($xmldata); + + if (!empty($entities)) { + // Get all metadata for the entities. + foreach ($entities as &$entity) { + $entity = [ + 'shib13-sp-remote' => $entity->getMetadata1xSP(), + 'shib13-idp-remote' => $entity->getMetadata1xIdP(), + 'saml20-sp-remote' => $entity->getMetadata20SP(), + 'saml20-idp-remote' => $entity->getMetadata20IdP(), + ]; + } + + // Transpose from $entities[entityid][type] to $output[type][entityid] + $output = \SimpleSAML\Utils\Arrays::transpose($entities); + + foreach ($output as $type => &$entities) { + foreach ($entities as $entityId => $entityMetadata) { + if ($entityMetadata === NULL) { + continue; + } + + // Remove the entityDescriptor element because it is unused. + unset($entityMetadata['entityDescriptor']); + + $metadata[$entityId] = $entityMetadata; + } + } + } + } + } +} + // If the path cannot be opened. +catch (\UnexpectedValueException $e) { + echo "There seems to be an issue with the SSO configuration path. Please contact the administrator."; +} + // If the path is an empty string. +catch (\RuntimeException $e) { + echo "The SSO configuration could not be loaded. Please contact the administrator."; +} diff --git a/web/.csslintrc b/web/.csslintrc new file mode 100644 index 0000000..177e4fc --- /dev/null +++ b/web/.csslintrc @@ -0,0 +1,40 @@ +--errors=box-model, + display-property-grouping, + duplicate-background-images, + duplicate-properties, + empty-rules, + ids, + import, + important, + known-properties, + outline-none, + overqualified-elements, + qualified-headings, + shorthand, + star-property-hack, + text-indent, + underscore-property-hack, + unique-headings, + unqualified-attributes, + vendor-prefix, + zero-units +--ignore=adjoining-classes, + box-sizing, + bulletproof-font-face, + compatible-vendor-prefixes, + errors, + fallback-colors, + floats, + font-faces, + font-sizes, + gradients, + import-ie-limit, + order-alphabetical, + regex-selectors, + rules-count, + selector-max, + selector-max-approaching, + selector-newline, + universal-selector +--exclude-list=core/assets, + vendor diff --git a/web/.editorconfig b/web/.editorconfig new file mode 100644 index 0000000..686c443 --- /dev/null +++ b/web/.editorconfig @@ -0,0 +1,17 @@ +# Drupal editor configuration normalization +# @see http://editorconfig.org/ + +# This is the top-most .editorconfig file; do not search in parent directories. +root = true + +# All files. +[*] +end_of_line = LF +indent_style = space +indent_size = 2 +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[composer.{json,lock}] +indent_size = 4 diff --git a/web/.eslintignore b/web/.eslintignore new file mode 100644 index 0000000..9c13487 --- /dev/null +++ b/web/.eslintignore @@ -0,0 +1,8 @@ +core/**/* +vendor/**/* +sites/**/files/**/* +libraries/**/* +sites/**/libraries/**/* +profiles/**/libraries/**/* +**/js_test_files/**/* +**/node_modules/**/* diff --git a/web/.eslintrc.json b/web/.eslintrc.json new file mode 100644 index 0000000..d4bbc92 --- /dev/null +++ b/web/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": "./core/.eslintrc.json" +} diff --git a/web/.gitattributes b/web/.gitattributes new file mode 100644 index 0000000..a37894e --- /dev/null +++ b/web/.gitattributes @@ -0,0 +1,61 @@ +# Drupal git normalization +# @see https://www.kernel.org/pub/software/scm/git/docs/gitattributes.html +# @see https://www.drupal.org/node/1542048 + +# Normally these settings would be done with macro attributes for improved +# readability and easier maintenance. However macros can only be defined at the +# repository root directory. Drupal avoids making any assumptions about where it +# is installed. + +# Define text file attributes. +# - Treat them as text. +# - Ensure no CRLF line-endings, neither on checkout nor on checkin. +# - Detect whitespace errors. +# - Exposed by default in `git diff --color` on the CLI. +# - Validate with `git diff --check`. +# - Deny applying with `git apply --whitespace=error-all`. +# - Fix automatically with `git apply --whitespace=fix`. + +*.config text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.css text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.dist text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.engine text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php +*.html text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=html +*.inc text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php +*.install text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php +*.js text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.json text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.lock text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.map text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.md text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.module text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php +*.php text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php +*.po text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.profile text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php +*.script text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.sh text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php +*.sql text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.svg text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.theme text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 diff=php +*.twig text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.txt text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.xml text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 +*.yml text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2 + +# Define binary file attributes. +# - Do not treat them as text. +# - Include binary diff in patches instead of "binary files differ." +*.eot -text diff +*.exe -text diff +*.gif -text diff +*.gz -text diff +*.ico -text diff +*.jpeg -text diff +*.jpg -text diff +*.otf -text diff +*.phar -text diff +*.png -text diff +*.svgz -text diff +*.ttf -text diff +*.woff -text diff +*.woff2 -text diff diff --git a/web/.gitignore b/web/.gitignore new file mode 100644 index 0000000..b20dc31 --- /dev/null +++ b/web/.gitignore @@ -0,0 +1,13 @@ +/INSTALL.txt +/README.txt +/example.gitignore +/README.md + +/core/ +/libraries/ +/modules/contrib/ +/sites/default/files/ +/themes/contrib/ +/themes/custom/perls/js/ +/themes/custom/perls/css/ +/themes/custom/perls/node_modules/ \ No newline at end of file diff --git a/web/.ht.router.php b/web/.ht.router.php new file mode 100644 index 0000000..054f711 --- /dev/null +++ b/web/.ht.router.php @@ -0,0 +1,65 @@ + + + Require all denied + + + Order allow,deny + + + +# Don't show directory listings for URLs which map to a directory. +Options -Indexes + +# Set the default handler. +DirectoryIndex index.php index.html index.htm + +# Add correct encoding for SVGZ. +AddType image/svg+xml svg svgz +AddEncoding gzip svgz + +# Most of the following PHP settings cannot be changed at runtime. See +# sites/default/default.settings.php and +# Drupal\Core\DrupalKernel::bootEnvironment() for settings that can be +# changed at runtime. + +# PHP 7, Apache 1 and 2. + + php_value assert.active 0 + + +# Requires mod_expires to be enabled. + + # Enable expirations. + ExpiresActive On + + # Cache all files for 2 weeks after access (A). + ExpiresDefault A1209600 + + + # Do not allow PHP scripts to be cached unless they explicitly send cache + # headers themselves. Otherwise all scripts would have to overwrite the + # headers set by mod_expires if they want another caching behavior. This may + # fail if an error occurs early in the bootstrap process, and it may cause + # problems if a non-Drupal PHP file is installed in a subdirectory. + ExpiresActive Off + + + +# Set a fallback resource if mod_rewrite is not enabled. This allows Drupal to +# work without clean URLs. This requires Apache version >= 2.2.16. If Drupal is +# not accessed by the top level URL (i.e.: http://example.com/drupal/ instead of +# http://example.com/), the path to index.php will need to be adjusted. + + FallbackResource /index.php + + +# Various rewrite rules. + + RewriteEngine on + + # Set "protossl" to "s" if we were accessed via https://. This is used later + # if you enable "www." stripping or enforcement, in order to ensure that + # you don't bounce between http and https. + RewriteRule ^ - [E=protossl] + RewriteCond %{HTTPS} on + RewriteRule ^ - [E=protossl:s] + + # Make sure Authorization HTTP header is available to PHP + # even when running as CGI or FastCGI. + RewriteRule ^ - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] + + # Block access to "hidden" directories whose names begin with a period. This + # includes directories used by version control systems such as Subversion or + # Git to store control files. Files whose names begin with a period, as well + # as the control files used by CVS, are protected by the FilesMatch directive + # above. + # + # NOTE: This only works when mod_rewrite is loaded. Without mod_rewrite, it is + # not possible to block access to entire directories from .htaccess because + # is not allowed here. + # + # If you do not have mod_rewrite installed, you should remove these + # directories from your webroot or otherwise protect them from being + # downloaded. + RewriteRule "/\.|^\.(?!well-known/)" - [F] + + # If your site can be accessed both with and without the 'www.' prefix, you + # can use one of the following settings to redirect users to your preferred + # URL, either WITH or WITHOUT the 'www.' prefix. Choose ONLY one option: + # + # To redirect all users to access the site WITH the 'www.' prefix, + # (http://example.com/foo will be redirected to http://www.example.com/foo) + # uncomment the following: + # RewriteCond %{HTTP_HOST} . + # RewriteCond %{HTTP_HOST} !^www\. [NC] + # RewriteRule ^ http%{ENV:protossl}://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301] + # + # To redirect all users to access the site WITHOUT the 'www.' prefix, + # (http://www.example.com/foo will be redirected to http://example.com/foo) + # uncomment the following: + # RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC] + # RewriteRule ^ http%{ENV:protossl}://%1%{REQUEST_URI} [L,R=301] + + # Modify the RewriteBase if you are using Drupal in a subdirectory or in a + # VirtualDocumentRoot and the rewrite rules are not working properly. + # For example if your site is at http://example.com/drupal uncomment and + # modify the following line: + # RewriteBase /drupal + # + # If your site is running in a VirtualDocumentRoot at http://example.com/, + # uncomment the following line: + # RewriteBase / + + # Redirect common PHP files to their new locations. + RewriteCond %{REQUEST_URI} ^(.*)?/(install\.php) [OR] + RewriteCond %{REQUEST_URI} ^(.*)?/(rebuild\.php) + RewriteCond %{REQUEST_URI} !core + RewriteRule ^ %1/core/%2 [L,QSA,R=301] + + # Rewrite install.php during installation to see if mod_rewrite is working + RewriteRule ^core/install\.php core/install.php?rewrite=ok [QSA,L] + + # Pass all requests not referring directly to files in the filesystem to + # index.php. + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-d + RewriteCond %{REQUEST_URI} !=/favicon.ico + RewriteRule ^ index.php [L] + + # For security reasons, deny access to other PHP files on public sites. + # Note: The following URI conditions are not anchored at the start (^), + # because Drupal may be located in a subdirectory. To further improve + # security, you can replace '!/' with '!^/'. + # Allow access to PHP files in /core (like authorize.php or install.php): + RewriteCond %{REQUEST_URI} !/core/[^/]*\.php$ + # Allow access to test-specific PHP files: + RewriteCond %{REQUEST_URI} !/core/modules/system/tests/https?\.php + # Allow access to Statistics module's custom front controller. + # Copy and adapt this rule to directly execute PHP files in contributed or + # custom modules or to run another PHP application in the same directory. + RewriteCond %{REQUEST_URI} !/core/modules/statistics/statistics\.php$ + # Deny access to any other PHP files that do not match the rules above. + # Specifically, disallow autoload.php from being served directly. + RewriteRule "^(.+/.*|autoload)\.php($|/)" - [F] + + # Rules to correctly serve gzip compressed CSS and JS files. + # Requires both mod_rewrite and mod_headers to be enabled. + + # Serve gzip compressed CSS files if they exist and the client accepts gzip. + RewriteCond %{HTTP:Accept-encoding} gzip + RewriteCond %{REQUEST_FILENAME}\.gz -s + RewriteRule ^(.*)\.css $1\.css\.gz [QSA] + + # Serve gzip compressed JS files if they exist and the client accepts gzip. + RewriteCond %{HTTP:Accept-encoding} gzip + RewriteCond %{REQUEST_FILENAME}\.gz -s + RewriteRule ^(.*)\.js $1\.js\.gz [QSA] + + # Serve correct content types, and prevent double compression. + RewriteRule \.css\.gz$ - [T=text/css,E=no-gzip:1,E=no-brotli:1] + RewriteRule \.js\.gz$ - [T=text/javascript,E=no-gzip:1,E=no-brotli:1] + + + # Serve correct encoding type. + Header set Content-Encoding gzip + # Force proxies to cache gzipped & non-gzipped css/js files separately. + Header append Vary Accept-Encoding + + + + +# Various header fixes. + + # Disable content sniffing, since it's an attack vector. + Header always set X-Content-Type-Options nosniff + # Disable Proxy header, since it's an attack vector. + RequestHeader unset Proxy + diff --git a/web/autoload.php b/web/autoload.php new file mode 100644 index 0000000..2c470f3 --- /dev/null +++ b/web/autoload.php @@ -0,0 +1,16 @@ +handle($request); +$response->send(); + +$kernel->terminate($request, $response); diff --git a/web/modules/.gitignore b/web/modules/.gitignore new file mode 100644 index 0000000..739a339 --- /dev/null +++ b/web/modules/.gitignore @@ -0,0 +1 @@ +/README.txt \ No newline at end of file diff --git a/web/modules/.gitkeep b/web/modules/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/web/modules/custom/annotator/annotator.info.yml b/web/modules/custom/annotator/annotator.info.yml new file mode 100644 index 0000000..52050e1 --- /dev/null +++ b/web/modules/custom/annotator/annotator.info.yml @@ -0,0 +1,8 @@ +name: Annotation +description: 'Attaches AnnotationJS to LO and an XAPIStateStore to persist the annotations.' +type: module +core: 8.x +core_version_requirement: ^8 || ^9 +dependencies: + - xapi_reporting + - xapi diff --git a/web/modules/custom/annotator/annotator.libraries.yml b/web/modules/custom/annotator/annotator.libraries.yml new file mode 100644 index 0000000..cfe9757 --- /dev/null +++ b/web/modules/custom/annotator/annotator.libraries.yml @@ -0,0 +1,52 @@ +annotations.base: + js: + js/annotator.1.2.10/annotator.min.js: {} + js/annotator.1.2.10/annotator.permissions.min.js: {} + js/plugins/annotator.touch.min.js: {} + js/plugins/annotator.xapistore.js: {} + js/plugins/view_annotator.js: {} + locale/en/annotator.js: {} + js/init.js: {} + css: + component: + css/annotator.1.2.10/annotator.min.css: {} + css/annotator.touch.css: {} + css/style.css: {} + dependencies: + - core/jquery + - xapi_reporting/xapi-reporting.xapi-lib + - annotator/jQuery.i18n + - annotator/jQuery.dateFormat + - annotator/jQuery.slimScroll + - annotator/annotations.xapi_state_store +jQuery.i18n: + remote: https://github.com/recurser/jquery-i18n + version: 1.1.2 + license: + name: MIT + url: https://github.com/recurser/jquery-i18n/blob/develop/LICENSE + gpl-compatible: true + js: + js/lib/jquery.i18n.min.js: { minified: true } +jQuery.dateFormat: + remote: https://github.com/phstc/jquery-dateFormat + version: 1.0 + license: + name: MIT + url: https://github.com/phstc/jquery-dateFormat/blob/master/MIT-LICENSE.txt + gpl-compatible: true + js: + js/lib/jquery.dateFormat.min.js: { minified: true } +jQuery.slimScroll: + remote: https://github.com/rochal/jQuery-slimScroll + version: 1.3.8 + license: + name: MIT + gpl-compatible: true + js: + js/lib/jquery.slimscroll.min.js: { minified: true } +annotations.xapi_state_store: + js: + js/xapi_store_helper/xapi_store_helper.web.js: {} + dependencies: + - xapi_reporting/xapi-reporting.xapi-lib diff --git a/web/modules/custom/annotator/annotator.services.yml b/web/modules/custom/annotator/annotator.services.yml new file mode 100644 index 0000000..d2e3e84 --- /dev/null +++ b/web/modules/custom/annotator/annotator.services.yml @@ -0,0 +1,6 @@ +services: + annotator.annotations_voided_statement_subscriber: + class: Drupal\annotator\EventSubscriber\AnnotationVoidedStatementSubscriber + arguments: ['@xapi.xapi_statement_helper', '@entity_type.manager', '@current_user', '@lrs.request_generator'] + tags: + - { name: event_subscriber } diff --git a/web/modules/custom/annotator/annotator_ui/annotator_ui.info.yml b/web/modules/custom/annotator/annotator_ui/annotator_ui.info.yml new file mode 100644 index 0000000..eec2205 --- /dev/null +++ b/web/modules/custom/annotator/annotator_ui/annotator_ui.info.yml @@ -0,0 +1,9 @@ +name: Annotation UI +description: 'Allows annotations to be viewed in the web interface.' +type: module +core: 8.x +core_version_requirement: ^8 || ^9 +dependencies: + - pdb_vue + - annotator + - xapi_reporting diff --git a/web/modules/custom/annotator/annotator_ui/annotator_ui.routing.yml b/web/modules/custom/annotator/annotator_ui/annotator_ui.routing.yml new file mode 100644 index 0000000..1f0e7d7 --- /dev/null +++ b/web/modules/custom/annotator/annotator_ui/annotator_ui.routing.yml @@ -0,0 +1,7 @@ +annotator_ui.list_annotations: + path: '/user/annotations' + defaults: + _controller: '\Drupal\annotator_ui\Controller\AnnotationController::view' + _title: 'Annotations' + requirements: + _permission: 'access content' diff --git a/web/modules/custom/annotator/annotator_ui/components/annotations_block/annotations_block.css b/web/modules/custom/annotator/annotator_ui/components/annotations_block/annotations_block.css new file mode 100644 index 0000000..cd118a8 --- /dev/null +++ b/web/modules/custom/annotator/annotator_ui/components/annotations_block/annotations_block.css @@ -0,0 +1,55 @@ +body.perls-learner.l-page--path--user.l-page--user-annotations .l-main { + max-width: 1260px; +} + +.annotation-list { + display: flex; + flex-direction: column; +} + +.annotation-container { + display: flex; + padding: 10px; +} + +.annotation-container .information { + flex-grow: 100; + margin-right: 30px; +} +.annotation-container .information:hover { + cursor: pointer; +} + +.information p { + font-size: 16px; +} + +.quote { + background-color: #e8f5f9; + padding: 10px 20px; +} + +.subtitle { + font-size: 11px; + color: #333333; + margin-top: 10px; +} + +.subtitle:after { + display: flex; + content: ''; + width: 75%; + height: 1px; + background: #b5b5b5; + margin-top: 10px; +} + +.delete button { + background-image: url('./images/trash-can.png'); + width: 30px; + height: 45px; + background-repeat: no-repeat; + background-size: contain; + padding: 10px; + background-color: rgba(255, 255, 255, 0); +} diff --git a/web/modules/custom/annotator/annotator_ui/components/annotations_block/annotations_block.info.yml b/web/modules/custom/annotator/annotator_ui/components/annotations_block/annotations_block.info.yml new file mode 100644 index 0000000..c06d446 --- /dev/null +++ b/web/modules/custom/annotator/annotator_ui/components/annotations_block/annotations_block.info.yml @@ -0,0 +1,21 @@ +name: Annotations Block +machine_name: annotator_block +type: pdb +description: 'This block lists the annotations for the given user.' +package: Perls - Vue +core: 8.x +core_version_requirement: ^8 || ^9 +module_status: active +presentation: vue +add_js: + footer: + 'annotations_block.js': {} +add_css: + header: + component: + 'annotations_block.css': {} +template: template.html +libraries: + - pdb_vue/vue.vuex + - xapi_reporting/xapi-reporting.lib-common + - annotator/annotations.xapi_state_store diff --git a/web/modules/custom/annotator/annotator_ui/components/annotations_block/annotations_block.js b/web/modules/custom/annotator/annotator_ui/components/annotations_block/annotations_block.js new file mode 100644 index 0000000..29bd27e --- /dev/null +++ b/web/modules/custom/annotator/annotator_ui/components/annotations_block/annotations_block.js @@ -0,0 +1,90 @@ +const xapi_store = new XAPIStoreHelper(); + +// store.js This is a basic store. +const store = new Vuex.Store({ + state: { + count: 0, + annotations: [], + }, + mutations: { + SET_ANNOTATIONS(state, annotations) { + state.annotations = annotations; + } + }, + actions: { + async fetch_annotations() { + try { + const response = await fetch('/api/annotations'); + const annotations = await response.json(); + return store.commit('SET_ANNOTATIONS', annotations); + } catch {} + }, + remove(store, annotation) { + var annotations = store.state.annotations.filter(_annotation => _annotation.statement_id !== annotation.statement_id); + return new Promise((resolve) => { + store.commit('SET_ANNOTATIONS', annotations); + resolve(annotation); + }).then((annotation) => { + return store.dispatch('persist', annotation); + }); + }, + persist(state, annotation) { + return new Promise((resolve) => { + resolve(); + xapi_store.sendVoidedStatement(annotation); + }); + } + }, +}); + +// app Vue instance +var app = new Vue({ + store, + data: {}, + // computed properties + computed: { + annotations() { + return this.$store.state.annotations; + }, + }, + + // methods that implement data logic. + // note there's no DOM manipulation here at all. + methods: { + removeAnnotation: function (annotation) { + this.$store.dispatch('remove', annotation); + }, + goTo: function(node_url) { + if (!node_url) { + return; + } + window.location.href = node_url; + }, + }, + + // a custom directive to wait for the DOM to be updated + // before focusing on the input field. + // http://vuejs.org/guide/custom-directive.html + directives: { + 'annotation-focus': function (el, value) { + if (value) { + el.focus() + } + } + }, + + mounted() { + this.$store.dispatch('fetch_annotations'); + }, +}) + +// handle routing +function onHashChange() { + window.location.hash = '' +} + +window.addEventListener('hashchange', onHashChange) +onHashChange() + +// mount +app.$mount('.annotationApp') diff --git a/web/modules/custom/annotator/annotator_ui/components/annotations_block/images/trash-can.png b/web/modules/custom/annotator/annotator_ui/components/annotations_block/images/trash-can.png new file mode 100644 index 0000000..c4c3281 Binary files /dev/null and b/web/modules/custom/annotator/annotator_ui/components/annotations_block/images/trash-can.png differ diff --git a/web/modules/custom/annotator/annotator_ui/components/annotations_block/template.html b/web/modules/custom/annotator/annotator_ui/components/annotations_block/template.html new file mode 100644 index 0000000..98a74f3 --- /dev/null +++ b/web/modules/custom/annotator/annotator_ui/components/annotations_block/template.html @@ -0,0 +1,27 @@ +
+
+
+ You have not created any notes yet. +
+
+
+
+

+ {{ annotation.text }} +

+
+
+

+ {{ annotation.quote }} +

+
+
+ {{ annotation.node_title }} {{annotation.date}} +
+
+
+ +
+
+
+
diff --git a/web/modules/custom/annotator/annotator_ui/src/Controller/AnnotationController.php b/web/modules/custom/annotator/annotator_ui/src/Controller/AnnotationController.php new file mode 100644 index 0000000..c3062a1 --- /dev/null +++ b/web/modules/custom/annotator/annotator_ui/src/Controller/AnnotationController.php @@ -0,0 +1,62 @@ +entityTypeManager = $entity_type_manager; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('entity_type.manager') + ); + } + + /** + * Renders VueJS block to show list of annotations. + */ + public function view() { + $block = Block::load(self::BLOCK_NAME); + if (empty($block)) { + throw new \Exception('A block must be defined'); + } + + $block_content = $this->entityTypeManager + ->getViewBuilder('block') + ->view($block); + + return [ + '#type' => 'container', + 'element-content' => $block_content, + ]; + } + +} diff --git a/web/modules/custom/annotator/css/annotator.1.2.10/annotator.min.css b/web/modules/custom/annotator/css/annotator.1.2.10/annotator.min.css new file mode 100644 index 0000000..0584acf --- /dev/null +++ b/web/modules/custom/annotator/css/annotator.1.2.10/annotator.min.css @@ -0,0 +1 @@ +.annotator-notice,.annotator-filter *,.annotator-widget *{font-family:"Helvetica Neue",Arial,Helvetica,sans-serif;font-weight:normal;text-align:left;margin:0;padding:0;background:0;-webkit-transition:none;-moz-transition:none;-o-transition:none;transition:none;-moz-box-shadow:none;-webkit-box-shadow:none;-o-box-shadow:none;box-shadow:none;color:#909090}.annotator-adder{background-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJAAAAAwCAYAAAD+WvNWAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2ZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDowMzgwMTE3NDA3MjA2ODExODRCQUU5RDY0RTkyQTJDNiIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDowOUY5RUFERDYwOEIxMUUxOTQ1RDkyQzU2OTNEMDZENCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDowOUY5RUFEQzYwOEIxMUUxOTQ1RDkyQzU2OTNEMDZENCIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IE1hY2ludG9zaCI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjA1ODAxMTc0MDcyMDY4MTE5MTA5OUIyNDhFRUQ1QkM4IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjAzODAxMTc0MDcyMDY4MTE4NEJBRTlENjRFOTJBMkM2Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+CtAI3wAAGEBJREFUeNrMnAd8FMe9x3+7d6cuEIgqhCQQ3cI0QQyIblPiENcQ20KiPPzBuLzkYSeOA6Q5zufl896L7cQxOMYRVWAgxjE2YDq2qAIZJJkiUYR6Be5O0p3ubnfezF7R6rS7VxBlkvEdd3s735n57b/M7IojhIDjOKgU9xfchnXrFtPjltE6Gne/CJQrj9bVmQsXrqf/JuzDTRs2EO8D52dmap3Hwz/9+X9K/PTtPeGnyBL/oS2LPfwzXljXjv9g9kK/+H8WNXsxB8aPe8SPPAKy+v3GvR7+n0fNacfPaQiIfch98vHHY/R6/bL+ycmLhg0bhq6xsXednjHdbGhAYWEhbpSUrHU4HKv/48UXz7GvNq5f36YTGQsWaA0+N3XeR2N4Xr8sKTF5Ub9+QxEZ1ZWe/673AM2NN3Hl6vcoKy9ZK4qO1Ue2LZX4Zzyf1ab1g1sWafK/GjVzjA78sjE/GLto8oxpiI/vA4h3EZ22KhIRFRUVOPT1AeTnnVsrQFz9QeM+id9bRHoteFaZeCakpS1KSkqCzWaDyWTCvSjhERFIm5SGuLi4JSeOH2cfveQWjLeItPg5TrcsdczERTFdk2G2AMY61+V0V+eAg8EQi8HDJqNnj95Lcs+28jPBTH/un37z6zh+2U8XpC8aO3QUSIMV4qVbd78DPNAnNAaZz83HqeFDl2zfsMXD/17jHvw8ulVEvBb8P9eulSwPU31jY6MkIFEU70llbZnNjeibkIDExMQljMXNRUUkWU6ibEo4mfVZlpiQvCiyUzLqjYC1hdpmevWKd7myNlhbDbeByM4DEd8ncQljcXMd2kq9kaQCbf7XomctG00tT2rScJByM9BsZ+YBkgm9m1UgUlukzIxx/Udg+KgRSxiLm+s98x5OS0DuTvC0LB0ydAgsFus9E453tVgsSHl4OINZKufVEJCHn+P4pX2TUmBsdgmH3NvqoG2aaNv9B4wEYwmUn7qupdPSJkNssECkkyqK97iyNustmDnjMTAWJb3o1a6AH86ZE0YnLSUsLAxWdjndxxISYmC+KGXkyJGGc+fOsVEXifroS/wJQ2aH8RyfwuliYLfffauvViSrFNaJubWUbnEjDPWV5yV++OBPDekfpjPoUnqEdAFpbrl/HaAiiuWjqZr5lP76HoZrjlonP+ck4tWi/oS+fSN0Oh0dfBsEQbjP1QEai+GRceOi3YwLFy/mFObAwx8VEx9BOw2b/d64LS135hB46PQ69EgY6+E/vO1FjrSPhj383XWdIgwGA4iFuhJ6EiLep0rb5h0EIaEhGGyI8/C/Z3K6MVULZLFaeTZBbldyPwtrn7EwJlmMQLRiIIfdIvELrknUSPnQaCxDk7kqYK4e8WNhs95GSFgMc1GqxzkEp8tiTP7y2+Dg2TspLBGJRr5HUG6uRVVjfcD8qb2GwtjSiM6hUdTf85pWiLFITDJ+9l/VLMxht3NuATEroFbs1D+sWfMRNm3aFHAHvv32Wxw7loNHHnkE4eHhGgLiXRNg52RXqWYMIQr0WJqOSvGIhoCs5nI8MyMUT82cGDD/whWlGJpowaUbTdCH91EVkTT/jEVoy88+U+WHyHkuHo0OlFvqEPHjAZg699mA+Ytf2gnb4EiYixsQZ+iiKiLO1b6LifNK2JSvALsgcCK7gn24l3/84x9BiefGjRJs3LgRK1asxOrVa6RgWasdxsKYZFeA9JkaPxGd/CwYFDTqE9OYePoEzL/490Y8Ng54Y8kgPEnPYWmsoJZGUGxDCkhZ0Cy25deyQAKI8xiRaNbIHw5AwtyRAfPXvrYP+mnxGPafjyLy8WRUWm7ScRZV23GuLpI2/FoWCILD4UmVtVzY7t17pNedOz/DuHHj/IvL6EAfPXpUEhB7/+mnn0qB8qJFi+hriOLCouSOKJP35+pWi/GLPl3Y9PHdpdd3PmlBcTnve4lQFKglNCIxrjOendMXOp7DE4/GweaowFfHacqli2rfX5GxihJTW351MHa1Ow2XtgXqOWWQ9Gr6v1zgutmPmFiEyd6Mzgnd0O3JUeBonNj38REotYtoPlCFSBKmmAmQVgskc5/tBcTJV6iJy31pubCWFmeGFh0djStXrvjsALM0Z86cxejRo/CHP/web7/9R2lx8rPPdkquLCUlRVFwRPQkLq2MYrvggGt9lYIHnwIKMThFc6OaaMdK7gl31GFIvAVXK5uwcXc8np+lR2Q4jx9N642L5QKKy6AoIKe7asuvENxwbV453y6MD3FOob3CBJ2onaoxK9hAzLAODEfj9Urot11GxDODwEcYED87BY1XHBCvGZVdGKfASHug17ASflkguZBY1qZVrFYrvvzyK8nlTZkyBa+/vhy/+tWbePfd95CZmYGHH34YDodD3QI5XZh/FsjFL/oKomWT7PM4Wx2mjgGef3wAvsmtxebd5eD5BDwzHdh/muBqhfI5RNHJKgbA73FhgjMT8mkZaaDr67gGwQw+rTeGPTsG1ceKUbK9EP2oBQ2bmwzb0TII143KHXB95mbyZyvD2WFpArQtkDxT8nXcnj17sGvXLixYkIkPP1xNU3Mdli9fjuTkZAwYMAC3b99WHFTGICosvImam1rE6TZ8BNHyeFbrOIu5ErPH6yRL8+XRevxkVk8a89Rg2yEzymujcfmGugVzLh6L7VaetVxY674U0czCWseIJkUax1U1NSB8eiL6zh6Oqq8voM+TI0AcIhq+uIqYqibYi2+5on0FDEK8QudWPrUgGm4X5lyVVF8plgtIq2ZnZ2P//gOSeE6ePCVZmiNHjiI3Nxfx8fG4efOmM1hW/D2Ru7BWRuUZ59yTI0/j1ao8U1U7pslUhSemGvBYWg98cZi6sKQQ6HUcpozrjv4JUSi4SlBbcU6zHacVFdsxauzAA7IYSK16RKlxTDVN8aNooBw3Yygq9hQifGA3KfbpNWkQovt1h+1iPfJriny0o8zIq1+/8Fz1WtXbzSjV7du34/jxE3j66aewb99+nD59GrGxsTRoXojhw4dL+2zp6fM1zyGxKPh0TQskiU97oU82/u0XAanIm6l45k7SYcrYbjhwvAGpw8IxalgMjI0C9p6gqXBJC+rLT2Hz/4zQbKfNZPtjgVy5DnNNoiCq1lb+9t/ZHHZpfSh8Vj/0nDAQ1UcuI3pkHGIf7guHyQrrgRtoLq5DbvUFjP94gWobxLUO1M4KcRoCgmfyxKAtkNlspsHxZzTj+gZPPfWkZHFOnTqFLl26UMGkY968eaiqqsKsWbOllWa1NtzWxPs+DK0YQmKH6HO/Su5m2uxjOWzgHJX40eQQzJjQHfuP12Hk4DCkpsTA1CTi65PAvw6LiIrkcHhjmuI55JUo7F74dGF+WSDl42yUv1q8jaiZyeg9dQgqD19EVEpPdBuVCMHcAuvhUjR/eQVcpAFzvnrdZ1tqRTsGoj9soYGvpbnZZ0dZgCyf4Pr6euz8/HNqXZowZ/ZsfL7zc1y8dAnstpDXXnuNZlw/QGVFRZugWa0dGip5VqO94y5Nfnr11Jpo8GjSWsl1lhp6TKOVuAbSjq5htUif2wU9YsPw9bEGTBnTGQ8NiEJZjQPrdhPsO0Ngp+gtQqsLrDIqt2Ojsad0JXsLyEdwxgRWe+EaBKNV9Ziu4mPSa92F60Cj3bnyTQSYYoGkF9MQ2SMGJbvOoMe0oYhN6QtL6U3UrT0N417qsuwUvmcE4thYOgTUFChn0brOYcpi11oHct9swG4207hjsa3FdR1369YtfPXVbjQ3NUuZ1cFDhyTxJCQk4KWXlmLUyBGoq61t5/DV2mGfK938QHy4MCkyVr1rQrnDRHSgU0gd5s+JQq9uYSgsNmHiyChJPBV1AtbvEbAvl6bN7iUdoqBGxXO3d2Hww4VxAtsW8OMeJHaMw7XO04Wgb+Z4RPXsgvqCUnSnsQ4Tj7X8Nmo/zoVp92WqatE59kIro1o7jCFgF+bLdKkVFs/s+vJLlNy4IYnn22+/ke4s7NOnjySeQYMG4ZZKtuWPKffXAkliCOLWwwjDbaTPMmBY/3DkF93EhBERGDE4GtUNIjbsJTh9kW2rcAGf1+mCA7kAPHsamtX7uKYIET0XpCImJR4150rQLW0AdVtJaKkyoeHjM7AeKwXv0D6HVjv+uzB3Bzn4Z4FcluokjXHYWk9cXG/s2LEDVdXVGDhwIN5++w/oS7Mto9Eo7Z+5B09+btV2OHdM4/8EEFcaH5gBIpg+miD98ThU1bXg6RndEdc9FNcrBfx5sw3fFet8nkN9LEUQBB4D+ZrA1lTbue3RaeZADF4wGU0Vt5A0bywi+3SF5WoDKn53AC1nKtunUV4CUmNQmxefMZBLQX70gJOyory87ySBlJdXSGk5i3lWrPg1uyEMdfX1bY5v8+r93os00BgIUuAtBGQlOGLDlNERMOg59OkRCh1N1ctqBLy7TURZnR53clOOxOIlGE0+uQvzoxvsGAc9f4/pg8EbdIiK7wpOz8N64xZq3zkC8bpJ+Tyil6sK0IXpfWVhfsdA9Bi2lsPclfvfDz30EJYv/y/JfTFRsaq17KEZAwWahYH4dYXLS2xUE0YN6e7hKioTseZzEXlFzoD5TkqwFogXtUMl+XH2biHolprkGVbrhVrUvXsc1hMVUsDMqyygus0kL6qfO+gsTEl4ahdMYUEhevXqheeeew5paRMl12W1WNDU1OQUo49VM07j3IFbIBJQDCTYTJgwPgb1Rg67jjtw5hLB5VKaEJi19sjYBi/bwIz0MwYKfCWaJ/4JqEmwonfacIg1zbi54wKaj5XB9n0thAYLtSCi4tgyQVscLZ4xVhUQgepKtM8YyJcFiomJkdZ7mOtiT1E8/czTUlvSExw03nGn6UrnYC7ufP556X337t19WqCAYiDXSrqvYmwiiIoAUgfcwjfHS3Ekh8DcJMBqE6jV0RYgc3EjU3rQd73QYPQjCQgkjWdxHxOQQPsuqI+/eIum+NFhcIzvgfzDuSAHTsFuskCw2CHatX0fc3GJ41Kdc1HXLLWlKCDGoGBJiIqASBsL5ENAmZmZeOedd/Dff/7zHZn4n86bpykgLwtENCwQke+F+So7jnD42U+A/31jyB3x//sYD60Htrz2woiGBSJtLBC7g0JUH/+mdQUI/c0k/OCjzDvit26+AJ1KOxIDp8DoTwwEHwJ64okfIzw8DCtXrgoYmu3es62M+fPTkTZxIhoaGjouBnKtRPsq2fsFKb5543ldwPxMvxdvEHz+rYAvckSt/CLolWieXeYah5k/yqPmXkDXP04NXDUCQUtBDRo3FaJpy/eqazq8xrKFqoAKCgsbJ0+Zwp6NkTIotcmqr6vDzMcek24GC2ZthN0fxITDnkRVEqr0Gf2/xWq1HTh40OjvXtjt2kuNvRIfgY46dl7KENU5th8WpHo3Cs+sCC/QGKvZVn09x+jvQmKRtapxnDAAOnbbjchpJoDNa/OleidFB/UlFFZaHDbbCXOR0VcM5MYkNTU1gt1mO2M0GVNDQyNosKg+wEwAatbD7xRaxcqxpxnY2pHDbv/Om1EhhvB8Z22qpyFWyxnOXpaq1ydIT2fcj6KnI8y1lFFrpcBP1Pkb7GbBQYQz1Tpzam9dGIhNuC/8XIgOFbwZAsR2/NqbqfQAk9mclZd3nrqoUPDU3XDUEt3LysQTFhaKgoILMJpMWd4LMdq78TRzbWnMaijZg+hwZkXv/eDraJus7VtlB2Gzmtvx+3BhpFlsyfrG+j30ESHQcbwUo9zTSttkbZ+0XUYTZWm3EKYiIPfiLXn//fe3FhUVbygs/B6RkWEwGPSSO3MH1nersjZYW0y4hYUFuHDh4oa//vWv2+VsGjGQ55hLp7O23qou2GCv34Ou0RxCDezc7pju7lQnP4ewEA5dogjsdV+hoTJvw+XcdQr8oiZ/VtWRrRcbSzccNRRB3ykMOjb+7H90cu9qZWKlbek6heKw/jIKzNc3rKs60p5fIwYirpRCzMnJ+RO7FbO8rCxjzJjR6BzTBexpVfcEOhyilKqLYnCrtGyw2Z2JrLrdGHuU2nj7JnLPnMX1ayXrjxw9+o6bp00qI4rwxV9XdvZP9ECuU31RRvd+M4GweBBdJ9c9RtS322gGYvPvtlc1KxMWAoSGOOMdqQ+CEZytAnUX98JYf3l9bekpRX6NPxPi4T9jvvYnGsNy10NrMqbEPoQ4eydECqHO37IO2GhwbnU4bwcIqgP05KFUBqG81AGOVhPfgmqDCUeshSg2V64/aSxS5tdI491VOHHiRD2tby7IzDxcUlKaodfrh1ML0c198JChgzFhwgTYaJARqIiYeEJDDcg9nYv8/EL5AmENFeWF2trajes3bNjLlpXg3DcOyAKx39RX5NXT+ma/4U8dNtVfzuB43XCOa+WP7TMWnfu+AGMTH7CImHg6RVIRVm5HWWmO3DXVEFG4YG1u2Hi9YKcGv+iTP890rZ7WN5/t9cjhq7aqDD3lpz7Awz8quj+e0o8CZ3Y4H8YPVDyRIdgVWYBTlstOQkF67rrGYREu0Dhs447qk6r8akE054Z3vWcrgbxrIg9KAbuzMvfHv/rqqyx/f2EiTcMDEZFbPKdOncaxYye2/u1vf/u9TOWCq115FWSdwFtvvUUUYiBVftdEtuMfOMa8qhchL3ROSA9IRG7xWCu3oap479ais5sC4h82fqlaEK3I75rIdvwL46etQiT3wjNigCJyieffEfk42JS/NavsUED8rybNIWouzG0+OVknIDt5mw588MEHv6WnY4/ppk+aNMkvETHxsOfATp48ycSzhZ7jNzJwUQbr3QE3m8bfVgiMv/jspt+yxzd6gqR3Tpjvl4g84qn4FFVX9m4pOrs5YH6NFD4g/nXlh3/LJXCEi+TSf+KviFzi2RlNxdNcsIWKJ3B+V7jhKwaC68dEdmJe1gGpM1QAq1555RV2zPzJkydrisgtHuoWmXiy6W9XymAFlY4I3j7Yxz5XQPxFeZtXsYioJxHnd07M1BRRq3i2orJ4b3ZxXnaQ/GKH8WeVHlqFRI4gGvN/SkaDM2mIiIknKgSfdTqPg5b87KzSg0Hxu2WtZoG4Nmpr3wFe1gF2DvHvf/87BXmFWYaMqVOmKIqIBWihVDzHqXhyco5n09+soB/bvVQuqlSP7/3lL3/pywIFzF+ct2WlcwsfGZ2TlEXkEU/5Fqd4vtsSFP/QcYsJOpg/6wYVQhIVUScu4zlxNHglEVHxgIrnX53PY39LQTb9TVD8ryQ/7qHXskDenZGbVvdfadDJG6WCWEXIy2xsMqZNYyJqzc5YdsJinmPHjkni+fDDD3/tgpd3QAm4DfwvfvEL4scue1D8VBDMEqEXCBXRgjYicovHUp5NxbMn+8p3nwbFP2TcQuLHFktQ/FklB1ZREYGLQcbzxEtETDzRIdjRJd8pnpIDQfG/kvwjv/5GohK8fFPf3Yl26qTCWEkI+2tohIpoGux2h3SxMfHk5OTIxWPz6oCgkCq2uaHwjTfeIAHcohEUPxXGShaf9IJIRbRIEhErTvFsRmURFc+5bUHxDxmbSeD/PUpB8WeV7F9J+nEgXbiMdLclYmNGLc+2rvnYZyvIXleyPyj+lwfMbTf6ej+vBO9/K5lYT2OrV69e6XwkCBmPPjpDsj7s0Z6cnGOb6Xdu5du84NunibS8/vrrxJ/N047kv3Juu8Tfi/J3TV4srdk33tjELM9m+l1A/INTM+45/7rr+1aiPz0olsuYz4+RNkM/7XoO++35m+l3AfG/PHCuJrQ+yM4QtL3JsV1H16xZs4IKh32eyf7ihks8b8lUr2Q6iVwwHVwC4r96fgfll1brMnX6MCqe3VQ8//LJPzg13etc4n3hX3dt3woumY5/F2SGwoB9joLNWdf2+eR/edCPAxp/fQd0SJ4ttFkMY4KxWCx5Op0u4pNPPlkvi/YV4ZcvX04IuWd/DNAnPxOMYG/J4zg+4lrhFz75B495geAB4s+6+vVbln72PB3l33ztgE/+ZYOfCJie8/GX6v06h8wnyzMDveu9/CqRp4vtxBNM43/5y1/ueMO5I/gl8QRRLp/NfiD4mXiC2oq6U3rXxBOFVUzmY1tcr/Lq6CjxdERxTfwd8Qcrno4orom/I/5gxdMhAlIQkXwF064CLzwI4lERUUD891M8KiIKiP9OxNNhAvISEVFZDpevaJIHRTwKIvKb/0EQj4KI/Oa/U/F0qIA03JnS+wdKPD7cmSL/gyQeH+5Mkb8jxHOnWZiWiOTBLVH6/kEtbmHIglui9P2DWtzCWH3534r8HSUcd/l/AQYA7PGYKl3+RK0AAAAASUVORK5CYII=');background-repeat:no-repeat}.annotator-resize,.annotator-widget::after,.annotator-editor a::after,.annotator-viewer .annotator-controls button,.annotator-viewer .annotator-controls a,.annotator-filter .annotator-filter-navigation button::after,.annotator-filter .annotator-filter-property .annotator-filter-clear{background-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAEiCAYAAAD0w4JOAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6RDY0MTMzNTM2QUQzMTFFMUE2REJERDgwQTM3Njg5NTUiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6RDY0MTMzNTQ2QUQzMTFFMUE2REJERDgwQTM3Njg5NTUiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo2ODkwQjlFQzZBRDExMUUxQTZEQkREODBBMzc2ODk1NSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpENjQxMzM1MjZBRDMxMUUxQTZEQkREODBBMzc2ODk1NSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PkijPpwAABBRSURBVHja7JsJVBRXFoarq5tNQZZWo6BxTRQXNOooxhWQBLcYlwRkMirmOKMnmVFHUcYdDUp0Yo5OopM4cQM1TlyjUSFGwIUWFQUjatxNQEFEFtnX+W/7Sovqqt7w5EwMdc6ltldf3/fevffderxSZWVlZbi5uTXh6rAVFBTkqbVubl07eno2d3BwaGgtZNPGjYf5wsLCDRu/+ir20aNH2dZCcnNzN6uPHTv2S2xsbHZaWpqLJZqJIR9FRMTxdHFJeHiiJZrl5+fniiF0jRdumgsjyOZNm44AshHPxAnXeXEhUzAJJEF8j5cWVoIZg9CmqqiokK3CksWLX3d0dJwy+f3331Cr1RoliEajMQ4Sw2xsbHglTZ6CampquOex8dxz2l5gkEY4qKyslOu1Qa6urpPRs9VkW2RjFmskQCaFhASQLZEZkDlYBBJDnJ2dXSnwmYLxpiDCdVMw3hyIObCnlr1g/nwfQCYpQcQbOTM5tbgDeDEkZPLkoaYgSpqpKysqnkIaNWrkYq7dUEim0EwhmkI1bw1ETjNVTk7OA2sg0jarDyO/ZhiJjtpS4923L1dWVs5VV1vW8Dyv4uzsbLnkc+c4dceOnn1LS0vat23bhnvSgypOpTItajXP2dvbcefOneVSL146ys+dOzvgyuWrMadOJeKGrb6AeRBb7syZM1xqyo9HwfDncZ0L+0dowGXATpw4qVfVGEyAJCUBkvrjUTzrTwzUkirDcfOewk5w9oBp8AD9iljoGt07rTvNpaRcPDqPIOx5+mlOkPnz5wakpV2JiU84ztlRNTVqTsXzeuHValyz4xJ1Ou4CICjrL37WoPsXLAgD7HJMXFw8Z2ur4dT8E23s7Wy4UydPchcupB5FGX8ZOxKUeyYLF84LSLt0OebYsXi9ZvYOdtwJBsE9f7lnVAUFuYp2smxpxJFOnTu9aWtry6VcSDm6cNF8f6WyRkEMFg7rclq0aP7fjZWrDyNmeL9c8iDedu7YMRK7xoHjx28y2tjGcsivt29PaOTsPNAGeSIGidNBwcF9La6aAPH18+UG+QzmtFqtN67pLALt2LYtAUOUHoLMWO/1BMM45o17OgUQ2dEz2R4drYf4AMLzakTNahY5n8FQRid9rpZG26KiE5ypOkP89JqIjZWOVSqeG+zrw7lp3bxRVidbteitUQnOLtQmhhApzMfXFzCtN57R1QJFbdkKiMtAP0Ao7lB16CE5oXtUTYJRB+BZPUzd6uWXE1xcXQcO8R+iqIms3aADWrdpw2VmZrbQJeoCeBdoYinkWTVVHNVC21jrrSopKakh67Y2ChCMXmw0xizbXM2I8dyc9gUObBpTBTw8WqixGw45n5GRnl4XjaZD9kP+DaibVSA8OAu7SHZKWm3GtTYWgfDATOxWQGxElynsepkNAoSq808JhII7DZKHzWpsQGYwiPhHyPzD0NifmtVGrE1WUlSQaDIXkNVm2REgc1jDiqtTBQk1pkmtqgEyCLu/SqpKkFmArDHLsgGxw57euaiXIkSQOeZCBI1egtCs324IxVGy3s9NtYkcqCtkGBtXHkLeAyTBGl8rZPZxCfIAkNIXLB6h9/4A6a/gMv0hvUyCUKgLdlsoXODYXwJ5E7sDzPM7G7OjPtjvgnjSizNkqwDDPoD9AL08E2QXaa7Ua40gLUTXmkHW44Gd2I9ndiZsLVh52ar9AAlmNiRs7eg9ByIOYtkMHGe0+6HBW9ithbSSKXcH8iFs7DuTvYZC31KKpFAuyhhE2v3kJkEK5YJZwytbtru7B8GGQjZCmhopmwkJgcRCu2o5jXwh2yWQWyxS3pH05teQwUpVK4Jkia49YA07l/ast8T3ihR7DfXvhuP/Mq2CATksarsRrBPuQQJx76Kp7vfGzh4F42V8zQe7YtxL+u2EkVoDZJ8+fej8VQi9vPRmg8BpCKXAN5OSkqpNVg0QR7VaPR3n05FLN6k9mcJnYLcK178ErEQRBIgTMtMNyG4Djaqv0XyJMtMBM4jrPCC8vb19KEHatWtXMHbs2LtOTk7lQoHGjRuXjBs37q6Hh0cRyvwZr+5/kW1s3GhXVVWlfxXv27fvhTlz5iybNm1aCuBVeEsqnzFjRmJoaOjS7t27X2fVXIgfdzfQtnnz5sPv3r2r/3/Rvn37WkdHR/8I1UNdXV1X4kdK+vfvPxsPNm3YsKE++JWWlmpbtNBH0C21QDY2NgOEk8LCwlY4340HhwM2DZfKcaxFJ+wsKip6OlfZoEGDwVIQD/Vrzc1Ciyb+/v4UGS9A0nx8fDxRHSdxGbzTaQ2q1qpVq3vnz58XGrYUbZIM0FVo0gOXyqBZ8p49ey6tW7fO8/Hjx7ZUrm3btgbZLe/p6Xnczs6ODI8bMWJEGiDTAfGAFjGo5nc4rh4zZswMaKYPKdSjXl5e8XLdfzQgIEBf6ODBg2qcv47qRcH4GuNlpRWOd+Bap8TERH0CNnz48Gv9+vVLkDNINXrtg8jIyEWootaYQaIHs2AKc5s1a7aVZS8GLuJ0//798M2bN4+NiYlxxztcLR90dHSsGDlyZHpwcHBU06ZNKWUuNRZGnGAjwTdu3BifkpLS7PLly05oJ65r164FMMZ0WH0UXIRG5GJz4pGajaad2RBOnXCZSYa0OrVAMueOEFc23tODuUyKxSBpQBS3hcbd3b396NGj+/v6+np16NDhVfRcNar40/fff5+ya9euk/n5+XeYlsoRomfPnv3j4+O3oJ0e1Ug2uMeDQ4cOfdmlS5deQlSVzgfoqzNkyJDXrl+/Hl9jYrt48eIh/GBHWRCq4HTq1KmtVLC4uDgZu48QVrKFhxGD7mC3DCZxjc5jY2M/o9HGAAQfGlBeXv6YCqEtKLd2weFYNM9jALNwTJ7e5OzZs1Hsx7JXrlzZ3QCk0+nmCb+el5d3Jzw8/ANKpnDqC6FBQLt27dp5CDGZQrnjx49/aACCe2yRNOx9wPsJvQBN3iorK8sXl7l58+bnUpDGwcGh1lQEQqyNt7d3GYUdeqXo1atXKQraissgWlbIDAyaZOzfZ/8+TMd5iEqluhMWFvZHmEIpjncDNAHttR6RUsuC31kDA4LanihUxOq+ivLGNWvWzAYjF4Hs3qJFi6bgWuvU1NStrBepR1satBH+0ERLJBXKyMi4AMP7Ag2bJbRHbm7unQMHDqzPzs7+ic5RNgw7lZxB0oErfumgKYOE5tHYNVSybAHmBlkB+8mXAnDtISALcdhI7LRiUUnmgowmEWj4akXvF1+g4Zs6hYmGRUIyhXLKRIzlUuJshEYOyvZDUBUHaTaCax/jcINcAiHORlpi6NmJHulrIhtZi06ZDViF3HAE43aINAahZAIWD0bl3wD7E55RGYBcXFy84f3vKkFo9IWVJ82aNSsVY34lNF8Ky25pAELW8Ta6VnZCSqvV0hB+ys/Pb/qZM2d2oRxlI+4Y194wAKFLe9IBDduBgYG3e/TooX/dwg+UzZw5U4chnNKatgjDoXAnDc07oikGGrQf1G1AB+3bt8/FABgJ1duvWrXqvUGDBl0HZBYgbSgtRBu6irIRZwONkDTRywqH0UL7zjvvvILBMQLD9+qhQ4cS5GVAvkIju4pMoQY/+osBCDFbh8arIkdEo89euHDhAgC+ZZpsFEP0bzbNmhUhG/nBADRgwIADqEbG0ymaqqrZqN5+xJ5NgBhMzmHcO4cU57gBqGXLlmkTJ07c0K1bt0dPp68qKjoCaLAOibJbZL00o5Oj5CKu6enpS5CIvo3hpjnito2kOsVBQUE/jxo16hP0zUY2q6OYRDijjQJv3boViDzJHdGyCaUz6Lnszp07X0GnbGRv5JXmZCPk/ZRD08wE2UoBez2/xhIJztxshGfZiBsbRSgePWKQEuk8tlI2Yo8M1xOJZz9kI52QWL2CqpYg6F9FHE/duXMnrX24K9c+4s0B7jEKxngQXV6ikI18gQy4h7FsRD116tQ3MzMzL5kK/uiEfTDgNrIgdKv7lStXYk2MHlmIkAV0jKHpYyRkDQxAyOqDULDMCITSGh/kRpMoa8GWsXr16l5SEA8H7AdHtJVrOGjxC+5NQui4mpyc3Ap7Ncb95sgHDGe+7t279x0biovhGovx8H6mSQZpQoYdFRW1VEgJcb/q9u3b6wyq9vDhwz1suD6PzL4nUhZnnG6AUBRshiQ+HJA80WBZmZWV9YkBKCcnZxErUI3R4Ru4Ak1wksO6b9q0abEYwjQtR0IWaABCKvc6bhYLBRGbd+NV9D1UJ4IyEmnjI9ymYecul43YoTfWiwtTBoJrRXK9iLYMUkwicPASChwxIxtZRm9TprKRxpDlaKocmWzkKnYTITbmZiNqNuNH89tjWSSk6aBk2FCWMe9/kf+7vnz5ilp1k55b8q+/moiI5TWiHpCemyVKD1sM44w8bDXI6mrJgercRnWGGbPsGpkB1CqDVP3GXeR3CLI4CsgZFzPGOvmaVRADkLWQWiApxKp4pACxDPQ8IIL3S728xlKHFexIVRevr3faFwZkdQIhE0ZeoJFWLh5ZBTOlidkwc6plFkwpibA4tPAW/FOh3tfqQRaBrHrRMZWNmDvyPheIrPdbmwO8wBmbNB5ZldLI2ZGq3td+RRBNz0NWWr2ShRaguLi4LFOr1R9UVVXdx6U5FoP8/Pym2dvbr8jLy3O2em1NUFDQ4cLCwoA6t9G2bdscpk6des3BwaGyTiC0yachISHX9+zZk4Qq3qtrxuYEmQWJO3v2bEzv3r2/qWui1R6y5Hl4f72vWTgjY0n78UoDZp2rplKpHCCd6gIiB+44evTod1NSUhZb21Yvd+jQYZROp9tZWVlZVlxcnKU03aFo2di8du/evVa88MQqEP58IZ0Itxakhkyj1R51AkkWDui1QzXvWw0SAWmVyjeWguq9vx70XCIkxjD6T3E4ZGlSUlK+1Rrt3buXFpPSmtFbyEimQdRWgRo0aPA2O6b/X6+DXAQs4Hm0EYXZw4CF1Qnk5uZWGhgY+CnaK9KqjM3W1rZ62LBhVydMmDDdw8PjqMWNlJubewL5UWZiYmIo/WPTmgRCiJBLIc2tBdTHo/+3tMaS1IZnRknLX23qpNLBgwddk5OT93p5edG/nFtLtTTbIOPi4uif4TXl5eUFBw4cWOfo6EgfWTS1GiRa7vnzmjVrKD9qXyeQaAuzBCS37OxnyAykf3utCiPck9U8tEIzEpASa15qaHkHLfloY860UL3314Pk4pG7u4ex+7QYhT60bA6Jh2yAlGZkpBu1bOlGn6HtF52P4Z587duVk6xpM1a1cSLIEchJkYazzG0jWuxOCTstfKMv6OhLMlquF8vuDzcH1I5BaKO1o/tEk3jC0sUcUyD69RvckwWDHIuStIDSHjKE3actwlgYoRXj/2HH9GYkfGlInyreEZ3/jXuyoFlWIy8RRBgAxJ+WCRD6cPdfxgzyI3ZMHwPu4Z6sgKaPLO+z6ze5J0usPzMVIYWPKZ0YuJr1lPB91ihImjmhlj5bfI118SlIHkRIRqeYAxFchNZiX+EMP6ScImq7WpuSi5SwTHYyc4u7rFEvWuS09TH79wz6nwADANCoQA3w0fcjAAAAAElFTkSuQmCC');background-repeat:no-repeat}.annotator-hl{background:rgba(255,255,10,0.3)}.annotator-hl-temporary{background:rgba(0,124,255,0.3)}.annotator-wrapper{position:relative}.annotator-adder,.annotator-outer,.annotator-notice{z-index:1020}.annotator-filter{z-index:1010}.annotator-adder,.annotator-outer,.annotator-widget,.annotator-notice{position:absolute;font-size:10px;line-height:1}.annotator-hide{display:none;visibility:hidden}.annotator-adder{margin-top:-48px;margin-left:-24px;width:48px;height:48px;background-position:left top}.annotator-adder:hover{background-position:center top}.annotator-adder:active{background-position:center right}.annotator-adder button{display:block;width:36px;height:41px;margin:0 auto;border:0;background:0;text-indent:-999em;cursor:pointer}.annotator-outer{width:0;height:0}.annotator-widget{margin:0;padding:0;bottom:15px;left:-18px;min-width:265px;background-color:rgba(251,251,251,0.98);border:1px solid rgba(122,122,122,0.6);-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;-webkit-box-shadow:0 5px 15px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 15px rgba(0,0,0,0.2);-o-box-shadow:0 5px 15px rgba(0,0,0,0.2);box-shadow:0 5px 15px rgba(0,0,0,0.2)}.annotator-invert-x .annotator-widget{left:auto;right:-18px}.annotator-invert-y .annotator-widget{bottom:auto;top:8px}.annotator-widget strong{font-weight:bold}.annotator-widget .annotator-listing,.annotator-widget .annotator-item{padding:0;margin:0;list-style:none}.annotator-widget::after{content:"";display:block;width:18px;height:10px;background-position:0 0;position:absolute;bottom:-10px;left:8px}.annotator-invert-x .annotator-widget::after{left:auto;right:8px}.annotator-invert-y .annotator-widget::after{background-position:0 -15px;bottom:auto;top:-9px}.annotator-widget .annotator-item,.annotator-editor .annotator-item input,.annotator-editor .annotator-item textarea{position:relative;font-size:12px}.annotator-viewer .annotator-item{border-top:2px solid rgba(122,122,122,0.2)}.annotator-widget .annotator-item:first-child{border-top:0}.annotator-editor .annotator-item,.annotator-viewer div{border-top:1px solid rgba(133,133,133,0.11)}.annotator-viewer div{padding:6px 6px}.annotator-viewer .annotator-item ol,.annotator-viewer .annotator-item ul{padding:4px 16px}.annotator-viewer div:first-of-type,.annotator-editor .annotator-item:first-child textarea{padding-top:12px;padding-bottom:12px;color:#3c3c3c;font-size:13px;font-style:italic;line-height:1.3;border-top:0}.annotator-viewer .annotator-controls{position:relative;top:5px;right:5px;padding-left:5px;opacity:0;-webkit-transition:opacity .2s ease-in;-moz-transition:opacity .2s ease-in;-o-transition:opacity .2s ease-in;transition:opacity .2s ease-in;float:right}.annotator-viewer li:hover .annotator-controls,.annotator-viewer li .annotator-controls.annotator-visible{opacity:1}.annotator-viewer .annotator-controls button,.annotator-viewer .annotator-controls a{cursor:pointer;display:inline-block;width:13px;height:13px;margin-left:2px;border:0;opacity:.2;text-indent:-900em;background-color:transparent;outline:0}.annotator-viewer .annotator-controls button:hover,.annotator-viewer .annotator-controls button:focus,.annotator-viewer .annotator-controls a:hover,.annotator-viewer .annotator-controls a:focus{opacity:.9}.annotator-viewer .annotator-controls button:active,.annotator-viewer .annotator-controls a:active{opacity:1}.annotator-viewer .annotator-controls button[disabled]{display:none}.annotator-viewer .annotator-controls .annotator-edit{background-position:0 -60px}.annotator-viewer .annotator-controls .annotator-delete{background-position:0 -75px}.annotator-viewer .annotator-controls .annotator-link{background-position:0 -270px}.annotator-editor .annotator-item{position:relative}.annotator-editor .annotator-item label{top:0;display:inline;cursor:pointer;font-size:12px}.annotator-editor .annotator-item input,.annotator-editor .annotator-item textarea{display:block;min-width:100%;padding:10px 8px;border:0;margin:0;color:#3c3c3c;background:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-o-box-sizing:border-box;box-sizing:border-box;resize:none}.annotator-editor .annotator-item textarea::-webkit-scrollbar{height:8px;width:8px}.annotator-editor .annotator-item textarea::-webkit-scrollbar-track-piece{margin:13px 0 3px;background-color:#e5e5e5;-webkit-border-radius:4px}.annotator-editor .annotator-item textarea::-webkit-scrollbar-thumb:vertical{height:25px;background-color:#ccc;-webkit-border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.1)}.annotator-editor .annotator-item textarea::-webkit-scrollbar-thumb:horizontal{width:25px;background-color:#ccc;-webkit-border-radius:4px}.annotator-editor .annotator-item:first-child textarea{min-height:5.5em;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;-o-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0}.annotator-editor .annotator-item input:focus,.annotator-editor .annotator-item textarea:focus{background-color:#f3f3f3;outline:0}.annotator-editor .annotator-item input[type=radio],.annotator-editor .annotator-item input[type=checkbox]{width:auto;min-width:0;padding:0;display:inline;margin:0 4px 0 0;cursor:pointer}.annotator-editor .annotator-checkbox{padding:8px 6px}.annotator-filter,.annotator-filter .annotator-filter-navigation button,.annotator-editor .annotator-controls{text-align:right;padding:3px;border-top:1px solid #d4d4d4;background-color:#d4d4d4;background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),color-stop(0.6,#dcdcdc),to(#d2d2d2));background-image:-moz-linear-gradient(to bottom,#f5f5f5,#dcdcdc 60%,#d2d2d2);background-image:-webkit-linear-gradient(to bottom,#f5f5f5,#dcdcdc 60%,#d2d2d2);background-image:linear-gradient(to bottom,#f5f5f5,#dcdcdc 60%,#d2d2d2);-webkit-box-shadow:inset 1px 0 0 rgba(255,255,255,0.7),inset -1px 0 0 rgba(255,255,255,0.7),inset 0 1px 0 rgba(255,255,255,0.7);-moz-box-shadow:inset 1px 0 0 rgba(255,255,255,0.7),inset -1px 0 0 rgba(255,255,255,0.7),inset 0 1px 0 rgba(255,255,255,0.7);-o-box-shadow:inset 1px 0 0 rgba(255,255,255,0.7),inset -1px 0 0 rgba(255,255,255,0.7),inset 0 1px 0 rgba(255,255,255,0.7);box-shadow:inset 1px 0 0 rgba(255,255,255,0.7),inset -1px 0 0 rgba(255,255,255,0.7),inset 0 1px 0 rgba(255,255,255,0.7);-webkit-border-radius:0 0 5px 5px;-moz-border-radius:0 0 5px 5px;-o-border-radius:0 0 5px 5px;border-radius:0 0 5px 5px}.annotator-editor.annotator-invert-y .annotator-controls{border-top:0;border-bottom:1px solid #b4b4b4;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;-o-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0}.annotator-editor a,.annotator-filter .annotator-filter-property label{position:relative;display:inline-block;padding:0 6px 0 22px;color:#363636;text-shadow:0 1px 0 rgba(255,255,255,0.75);text-decoration:none;line-height:24px;font-size:12px;font-weight:bold;border:1px solid #a2a2a2;background-color:#d4d4d4;background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),color-stop(0.5,#d2d2d2),color-stop(0.5,#bebebe),to(#d2d2d2));background-image:-moz-linear-gradient(to bottom,#f5f5f5,#d2d2d2 50%,#bebebe 50%,#d2d2d2);background-image:-webkit-linear-gradient(to bottom,#f5f5f5,#d2d2d2 50%,#bebebe 50%,#d2d2d2);background-image:linear-gradient(to bottom,#f5f5f5,#d2d2d2 50%,#bebebe 50%,#d2d2d2);-webkit-box-shadow:inset 0 0 5px rgba(255,255,255,0.2),inset 0 0 1px rgba(255,255,255,0.8);-moz-box-shadow:inset 0 0 5px rgba(255,255,255,0.2),inset 0 0 1px rgba(255,255,255,0.8);-o-box-shadow:inset 0 0 5px rgba(255,255,255,0.2),inset 0 0 1px rgba(255,255,255,0.8);box-shadow:inset 0 0 5px rgba(255,255,255,0.2),inset 0 0 1px rgba(255,255,255,0.8);-webkit-border-radius:5px;-moz-border-radius:5px;-o-border-radius:5px;border-radius:5px}.annotator-editor a::after{position:absolute;top:50%;left:5px;display:block;content:"";width:15px;height:15px;margin-top:-7px;background-position:0 -90px}.annotator-editor a:hover,.annotator-editor a:focus,.annotator-editor a.annotator-focus,.annotator-filter .annotator-filter-active label,.annotator-filter .annotator-filter-navigation button:hover{outline:0;border-color:#435aa0;background-color:#3865f9;background-image:-webkit-gradient(linear,left top,left bottom,from(#7691fb),color-stop(0.5,#5075fb),color-stop(0.5,#3865f9),to(#3665fa));background-image:-moz-linear-gradient(to bottom,#7691fb,#5075fb 50%,#3865f9 50%,#3665fa);background-image:-webkit-linear-gradient(to bottom,#7691fb,#5075fb 50%,#3865f9 50%,#3665fa);background-image:linear-gradient(to bottom,#7691fb,#5075fb 50%,#3865f9 50%,#3665fa);color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.42)}.annotator-editor a:hover::after,.annotator-editor a:focus::after{margin-top:-8px;background-position:0 -105px}.annotator-editor a:active,.annotator-filter .annotator-filter-navigation button:active{border-color:#700c49;background-color:#d12e8e;background-image:-webkit-gradient(linear,left top,left bottom,from(#fc7cca),color-stop(0.5,#e85db2),color-stop(0.5,#d12e8e),to(#ff009c));background-image:-moz-linear-gradient(to bottom,#fc7cca,#e85db2 50%,#d12e8e 50%,#ff009c);background-image:-webkit-linear-gradient(to bottom,#fc7cca,#e85db2 50%,#d12e8e 50%,#ff009c);background-image:linear-gradient(to bottom,#fc7cca,#e85db2 50%,#d12e8e 50%,#ff009c)}.annotator-editor a.annotator-save::after{background-position:0 -120px}.annotator-editor a.annotator-save:hover::after,.annotator-editor a.annotator-save:focus::after,.annotator-editor a.annotator-save.annotator-focus::after{margin-top:-8px;background-position:0 -135px}.annotator-editor .annotator-widget::after{background-position:0 -30px}.annotator-editor.annotator-invert-y .annotator-widget .annotator-controls{background-color:#f2f2f2}.annotator-editor.annotator-invert-y .annotator-widget::after{background-position:0 -45px;height:11px}.annotator-resize{position:absolute;top:0;right:0;width:12px;height:12px;background-position:2px -150px}.annotator-invert-x .annotator-resize{right:auto;left:0;background-position:0 -195px}.annotator-invert-y .annotator-resize{top:auto;bottom:0;background-position:2px -165px}.annotator-invert-y.annotator-invert-x .annotator-resize{background-position:0 -180px}.annotator-notice{color:#fff;position:absolute;position:fixed;top:-54px;left:0;width:100%;font-size:14px;line-height:50px;text-align:center;background:black;background:rgba(0,0,0,0.9);border-bottom:4px solid #d4d4d4;-webkit-transition:top .4s ease-out;-moz-transition:top .4s ease-out;-o-transition:top .4s ease-out;transition:top .4s ease-out}.ie6 .annotator-notice{position:absolute}.annotator-notice-success{border-color:#3665f9}.annotator-notice-error{border-color:#ff7e00}.annotator-notice p{margin:0}.annotator-notice a{color:#fff}.annotator-notice-show{top:0}.annotator-tags{margin-bottom:-2px}.annotator-tags .annotator-tag{display:inline-block;padding:0 8px;margin-bottom:2px;line-height:1.6;font-weight:bold;background-color:#e6e6e6;-webkit-border-radius:8px;-moz-border-radius:8px;-o-border-radius:8px;border-radius:8px}.annotator-filter{position:fixed;top:0;right:0;left:0;text-align:left;line-height:0;border:0;border-bottom:1px solid #878787;padding-left:10px;padding-right:10px;-webkit-border-radius:0;-moz-border-radius:0;-o-border-radius:0;border-radius:0;-webkit-box-shadow:inset 0 -1px 0 rgba(255,255,255,0.3);-moz-box-shadow:inset 0 -1px 0 rgba(255,255,255,0.3);-o-box-shadow:inset 0 -1px 0 rgba(255,255,255,0.3);box-shadow:inset 0 -1px 0 rgba(255,255,255,0.3)}.annotator-filter strong{font-size:12px;font-weight:bold;color:#3c3c3c;text-shadow:0 1px 0 rgba(255,255,255,0.7);position:relative;top:-9px}.annotator-filter .annotator-filter-property,.annotator-filter .annotator-filter-navigation{position:relative;display:inline-block;overflow:hidden;line-height:10px;padding:2px 0;margin-right:8px}.annotator-filter .annotator-filter-property label,.annotator-filter .annotator-filter-navigation button{text-align:left;display:block;float:left;line-height:20px;-webkit-border-radius:10px 0 0 10px;-moz-border-radius:10px 0 0 10px;-o-border-radius:10px 0 0 10px;border-radius:10px 0 0 10px}.annotator-filter .annotator-filter-property label{padding-left:8px}.annotator-filter .annotator-filter-property input{display:block;float:right;-webkit-appearance:none;background-color:#fff;border:1px solid #878787;border-left:none;padding:2px 4px;line-height:16px;min-height:16px;font-size:12px;width:150px;color:#333;background-color:#f8f8f8;-webkit-border-radius:0 10px 10px 0;-moz-border-radius:0 10px 10px 0;-o-border-radius:0 10px 10px 0;border-radius:0 10px 10px 0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.2);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.2);-o-box-shadow:inset 0 1px 1px rgba(0,0,0,0.2);box-shadow:inset 0 1px 1px rgba(0,0,0,0.2)}.annotator-filter .annotator-filter-property input:focus{outline:0;background-color:#fff}.annotator-filter .annotator-filter-clear{position:absolute;right:3px;top:6px;border:0;text-indent:-900em;width:15px;height:15px;background-position:0 -90px;opacity:.4}.annotator-filter .annotator-filter-clear:hover,.annotator-filter .annotator-filter-clear:focus{opacity:.8}.annotator-filter .annotator-filter-clear:active{opacity:1}.annotator-filter .annotator-filter-navigation button{border:1px solid #a2a2a2;padding:0;text-indent:-900px;width:20px;min-height:22px;-webkit-box-shadow:inset 0 0 5px rgba(255,255,255,0.2),inset 0 0 1px rgba(255,255,255,0.8);-moz-box-shadow:inset 0 0 5px rgba(255,255,255,0.2),inset 0 0 1px rgba(255,255,255,0.8);-o-box-shadow:inset 0 0 5px rgba(255,255,255,0.2),inset 0 0 1px rgba(255,255,255,0.8);box-shadow:inset 0 0 5px rgba(255,255,255,0.2),inset 0 0 1px rgba(255,255,255,0.8)}.annotator-filter .annotator-filter-navigation button,.annotator-filter .annotator-filter-navigation button:hover,.annotator-filter .annotator-filter-navigation button:focus{color:transparent}.annotator-filter .annotator-filter-navigation button::after{position:absolute;top:8px;left:8px;content:"";display:block;width:9px;height:9px;background-position:0 -210px}.annotator-filter .annotator-filter-navigation button:hover::after{background-position:0 -225px}.annotator-filter .annotator-filter-navigation .annotator-filter-next{-webkit-border-radius:0 10px 10px 0;-moz-border-radius:0 10px 10px 0;-o-border-radius:0 10px 10px 0;border-radius:0 10px 10px 0;border-left:none}.annotator-filter .annotator-filter-navigation .annotator-filter-next::after{left:auto;right:7px;background-position:0 -240px}.annotator-filter .annotator-filter-navigation .annotator-filter-next:hover::after{background-position:0 -255px}.annotator-hl-active{background:rgba(255,255,10,0.8)}.annotator-hl-filtered{background-color:transparent} \ No newline at end of file diff --git a/web/modules/custom/annotator/css/annotator.touch.css b/web/modules/custom/annotator/css/annotator.touch.css new file mode 100644 index 0000000..345c70c --- /dev/null +++ b/web/modules/custom/annotator/css/annotator.touch.css @@ -0,0 +1,519 @@ +/* Annotator Touch Plugin - v1.1.1 + * Copyright 2012-2013, Compendio + * Released under the MIT license + * More Information: https://github.com/aron/annotator.touch.js + */ +.annotator-viewer .annotator-touch-controls .annotator-edit::after { + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAtCAYAAABxsjF3AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NDA0RjExNjU0MUU3MTFFMUFGNzA4RDM2MDNEMkIyQjkiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NDA0RjExNjY0MUU3MTFFMUFGNzA4RDM2MDNEMkIyQjkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo0MDRGMTE2MzQxRTcxMUUxQUY3MDhEMzYwM0QyQjJCOSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo0MDRGMTE2NDQxRTcxMUUxQUY3MDhEMzYwM0QyQjJCOSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pl46a1UAAAVTSURBVHjajJZ7TFtVHMdvHzxKWzo2xqNAeMO6AQNKBKUoZbiUIBhCIuHxh/+4xQwk4HuRGIkJQgmSqfyBqCDMmQjZ4rQR8I+6CMgfAgIiE5oMVt4vESiFUur33Nw2t6XF3eTXc8/p+Zzze5zf71wORVFnIHKIF3X6swsZhwghjyEWqra29tre3t6i5X8es9n8sK2t7XpPT88nAQEBFwFzOVtbWzpPT08K0uJiR8vBwQE1Ojo6IJPJPpRIJNmDg4N3sOnr1PHxsXlubq7zFHUFKpXqSk1Nzcurq6s3Mf+IaLKzs6OkoM4B4C4XoFd5eXnO2tpa/8bGxpRarX7NYDC8AVYNEdPw/Pz8bWdgdXX1C4uLi/d0Ot33u7u7K/v7+7qJiYkQ/HcBInIFS6qqqlQLCwv3Z2Zm7q6vr08zflOXlZVdHhoa+nZycvKyM/hMU1NTiV6v/w47aqDyNOw0AKwlf05PT79HVhkeHo7hO+wobmxsfLG4uPil7e1tU2Bg4CVvb++go6Ojt/l8/sdkAofD4dEhwMNlk3V1dVeLiopuwJMeABPFYvF5DBOwFdCxo1P4zGoWNLzCwsJXgoKC5DDFyOVyzVD3BsCv2ADGLWyYQ2JdUVFxNiwsLAULcXk83h7at/DfbWjHYRanHyxse+eSybDPKzw8XA51H+AkVSJEKoxrIcGQMMwLt8rS0tI5AsIsM8dkMg0fHh6GjIyMaHEA9tE3wUFmqMsDaGcjUSE9PT1TKBRCOZ6ceE0GmbA8+TMKUdKL4cW2cmpqKvFBDORpyFPERMhvkCGIDrG187gNBiiCKpXoV8KB5x08vIBGjfFWLLBvBwMUw8bPYWuRs+wg4QHIIfHGnEosYKTHAXKRy2+6AlNSUtZzcnJI5aAw55q7u/t126LoRCJ21c7AxMTEDRzXVqVS2Z6fn/+Y0aIGG0rpd8QrF9EROgObm5u/FAgE76N7B5lkIuNGo/FccHDw8/QJc3Nzy3AEExISNhnwJnZxw25fwOYIW6J7eWWi6eAia3zYYFxc3BZSsp0F9gJ8xi7ZJRL6lHFDQ0MX2V6tr6/vQjZZwfsAT2gWERGhp+ejIj7w8PAgh4GKjIzc9vX1fZdEAM89gFccQSx8CLO01lD9jOr4iHRQo4zod+P1H4BXnUUgNzf3b5zvX2gYBXyutLT0VnJy8gZKTwDGVBB3Z6BCoVhBlWmEP1bZx1OMVPugvb29sLe3VwoN7MqTSCQy5eXl6UtKSjr9/PzqSMQcE0OMGJbMzs4Wj42NBUxNTYlhNxUfH/8vYq6HPzpxPIlJhhOJwTykuAVDLkFkTFZNMbJAX27srHIwi0MXc4ryYW5PMnmLEQMbJpuybeNLpdKogoICRVZWVkJsbGwMPH4M9R/29/ePdXd3/4py9YjRxr6KyuVyhVar7YDdm46lA1fwqkajacXpSyERsu5Mq5qdnZ2Ea0Xrqu6Q6kra8fFxDTa5YIOhnnhgYODrU8C7KIy3rP2+vr5PwXrScEtLSwaq544L8Ec07rheL+Ji+4aMYaG1hoaGRAJzk5KSMpCWohOfAxaLBpW2AGLOzMyU+vv7J9E3vUDgm5aWpqAn4WLvcLLjT2RHEnccDuXKysqf7P9xe35Gq41PhTYHsB+NgIBRUVHPLS8vn6jpGGum4c3NzVcdvCohYHR09LO43Eed+QJMKQ3jS0eGArjHDP5BSjhqVAEy7HdnICroGpoQGsYPHwXwI/IHvgL+IhAWM7kKHea+Q25OW07gxQcr/vAEH3JdaITsE2Zd4CykDnZvO/H+OsAavHqzE4PjENtTLzr2pwWB/xNgAIkda0u78FfgAAAAAElFTkSuQmCC'); +} + +.annotator-selection-handle::after { + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAoCAYAAAD+MdrbAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MENGMkFGNTMzRTZBMTFFMUJCQThENjQ1NDg5Q0U3NUYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MENGMkFGNTQzRTZBMTFFMUJCQThENjQ1NDg5Q0U3NUYiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpGRERCNTk2ODNFNEQxMUUxQkJBOEQ2NDU0ODlDRTc1RiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDowQ0YyQUY1MjNFNkExMUUxQkJBOEQ2NDU0ODlDRTc1RiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pqv8zQEAAAWBSURBVHjapFdrTFRHFP727i4ioMCCyEOsWbHQihigEVqJL6jV2gcl1OCrtjXVmpAYQ5P6o+mfpi2JScMf0tAftCHRhMjDpg9tAmooTTSBoqC7i2BAXgZ2QXbZXfZx796ec9lVweVVJzk7c+/OfPPNOXO+mauSZRkvUlQq1axnYZHOmt7e3m9HR0dv2Gy2nsHBwYv0btWCMzDDYEYlksD+kOeUgYGBm/Tfmmf6LQ2wvr7+KwbweEW5vLJVLvumWTZbbAqoyWS6yhMGAxTmWeqG/Pz8E9yuqeuCaSQJj71pqPjZAK8oITU19a3KyspjwcYKQcAiOjo6foiMjNxw1/QI1/4NgaCNg0qtw8BEAhqvmJR+hYWFH1Pf+EUBz5w583p6evpehd3lIQgh8RChhVdWQ9bo8NvfHkxanUhMTMxuaGgoXRCQZtSVlpae02g04ddaH6DPHANJFU7LhGKSHAKPKgEXLt9X+m/fvv09qtbNC1hRUVGSkpKyh/104cokZG0svJJABr+pIAmr0dSuwdCjScTFxW1paWn5moZqnwMkdnFFRUUfcfvS790wT62B6At9wi5goqSFpF6Ln2ofKOMyMjLepGrDc4C1tbWnk5OTc6xTLtRfd0OkIDCjp+yemiSswi1TOO4YHoGD197e/j1BhD8BJHZJeXl573L7l/puWL1rIZK/goHNmBo+TRyqLg0rZDIzMz8oLy8veAKYk5OzlaNmd7jx502RGETNyy5goioM9waj0XDVxISE3NzcQoJaLdDDipKSkkwG7uoeg8OzmnynIV9hESOWFKB/OqwKSwrmZqriNfQTHRsbqyS8bcoNn4/Uw7dEpfH5oPZHQZIkChliGFBDG9R49OhRbElbA614C9N2B3dfHFAcx4f7Nintnp6ee4zL7Qiyt4eHh9vk/1msVuvDsLCwdwhnY0CC8ouLiz9hUFEUnUsF8vl8Emll58mTJ08xKV6tigH9SZ6FFysGsn5VQNP8oC+xY5cJxGHuJ1M2pSqYSBJ46DIAXUEVmzclyXstnR0PlhOQiYmJO62trQdnAbKcG43Gv+QXKDU1NZ8zEO9DJCUlZaWlpe1l2fryuxsYd+ho2epF1yp6pnAgbyUOFWVxpuygV/Ua8pf2/PnzudzhrnEE485ErIzUkyOFxQG9Ntwf6FXaer1+cyBToiMiIkL4pdsjQfIJlKeqpSQKJNGHiHBlkXA6nRztGKahrqqq4j2E9LR4rNRa4fG4FlQaxUQZbpcdm1Nmzn06Wjn1PAw4cfv2bUdfX19LRHgoDu2PxbTTohyXc9X6WfN4XQhVW7D7Db0CWFdX10HVuEABclPDXlZWVk1p59iTp8f62HF43M4FGPrgco7jyIEYrFihAZOprq4eIhxzwPOGxsZGc2dnJ98IcPz9dXA5xuZl6XE5kRDJ7GaOEiZD1RSb4N+LFk6f7OzsalKO/oxXE5C1yUEsp4Kwk+CeNuPTokQIggCDwXCVydB449xj9CH/tLW1NXH92cGN8EyPEiPvbEC3HVs32vBaRhLsdvvQzp07f/Tns2UWILFkVe0uKChoHBsb60pOjMK+bSKxtBGQ7I8sgbtGcergTCDotGuyWCys1F3zXUWYpbe5uVnx5Ynil6GWhmkDu2l/Eqj7MfZv80K/XgeedNeuXZeoG+9sW1BAYsmzGQ8fPnxjZGSkPToqDOeO6yA6H0J0mZG0aginj7yi9PVPKvmla+H7IZXdrOBut3uSE//ir3flY180yb39FkUI6CJ63a/Q65Z04eTjkAecPXu2dK6qsORHRUXxJWnHsm6wVFIDoHRfbCDnd3PtZ8amCyrOC30FkBJlBFkWD7hD40aCfQWoFvusoAHRLJnMiPOeg0Bj7PN9VvwnwAD1CUyXisQtngAAAABJRU5ErkJggg=='); +} + +.annotator-button::after { + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAEiCAYAAAD0w4JOAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6RkREQjU5NUUzRTREMTFFMUJCQThENjQ1NDg5Q0U3NUYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6RkREQjU5NUYzRTREMTFFMUJCQThENjQ1NDg5Q0U3NUYiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpDMkY4NEM4QjNERkExMUUxQkJBOEQ2NDU0ODlDRTc1RiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpDMkY4NEM4QzNERkExMUUxQkJBOEQ2NDU0ODlDRTc1RiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PoUNah0AABE5SURBVHja7JwJWFXXtcfPHRhlvmoZNIqaKBrRp74IQaNMCUYTY0gKUuuUL61+mqpx4qlowBippKba1jQxcQJjaJwSjAMxYYhyRUVARUkIRgyjgAgyj++/rufSc89wJ+x7Xy3n+5b7DPv8zt5rr7322vtulFVUVJS4uLj0Y3pw1NXV3VeoXFxGj/DycrOxseljLmTvnj2nFD4TJ1bm5eU5mQPTQmpqavYpvvvuu1+Sk5NNhnEh727ZkiJra2vTPHhn06Zn7ezs3lz4xhvPG9JZbW1tzb69e09rIXRPrn34TnR0Rn19/e49n36afO/evUojIHvwTor2vpybyRCMB0njPpPzM0vB9EHo6NaRAMjRmUKhUEpBlEqlfhAXZmFhIZcqSTeoq6uLeRRHL8gEUHt7u1irTXF2dl6Ilu0k2yIbkwLJ9TS9BjJ/wYIQsiUyAzIHk0rEhTg6OjrTPbJysnapkglAYhDtoQ+mA9IHMQTrBm1Yv94fkPn6IPpgGpAWsmDhwmkODg5OxjQ3H6Zob2szGUIHuWRyzeSiyVXLzYFoD3LJWtOQVVdX3zUHwq9mb+//PwQpE+L3d/n4+jItLa1MZ6dpULlcxlhZWTJZly8zihEjvHybm5uGDRniyTwsnYyRyQyLQiFnrK2tmMuXLzG5V6+fla9duyrk5o38M+fPZ+CBpSaDcRBL5uLFi0xuzrWzYATLcZ+J/J/VITcA+/77c5qi6oNpIZmZgOReO4t3g4mBWlJlGGZdN+x7xhowJV6gr3CF7tGzC+oLTE7O1bPrCMK+T59mtLJ+/dqQvLybZ1LT0hkrqqZSwcjkco3IFQrcs2Iy1GomGxDkDea+K/DZGzZEAnbjTEpKKmNpqWQU8oelsbayYM6fO8dkZ+eeRZ5ggR3V1dWINu3mmC2nR44a+UJQUICm8Onp6UwOIFEb1weLGqQUiAuztLQEJEcSYhDEwqJhXfYbN65/u7f39xCkL/SjI/HQoZeQ9A2bPXuv2aDPP/sszcHR8TkLxIkYJC6ER0T4mhyNaCEBgQHMFP+pjEql8sE9tUmgQwcPpmGI0kAQGWt6PcEwjvngmVqiaq06Nz5LOJjmSCUJCtRAtI1BsK6uTib1uxRNNSPm/MZXskQH4xNEIXTQuUwmZ6YG+DMuKhcf5FWLghIOxKc5OpFOhBA+zD8gADCVD95R61Qtfv+BNCdn5+eCUBK5BERHH5pqdjEp337LVFVVXfjtvLm+ikFPPPEQEhwkWRIp2GBPT6a8vHyAOkMdIndycjIZ8s9qyphAqELVV+Uja2pq6qKwz9yuQjCa2MAf1T2SziZnHtHxn+zYPDwGKJBMh1wpKSku7omyl0G+hPwdUBezQHhxJZJY9pJKtQ/3PE0C4YUVSLZCLDi3ye16Gw0ChKrzPg9C0ycaJE8ZpWxAlrMQBec2OfZIKHu7Ua3G6mSrSEnWAPKBUc0PyBokWyhA5TzvgKwC5M9G2REgU8hJQgbwICsB2WFUpwXECilNelewJdJC1hgLYdhq/ApCK1hHIJ0Qst6/6VOsFGg05EVyepAqyBxA0kyO/CH1rH1ch9wFpPkxcyNovf9GYoWqnRPpMpOQNOPZZb29HxmfRrKf3AXOg3mQF5AksT1/lD47moj0MMSLJs6QA1oY0hD2AzR5JshhtuSirebAs2hXyId4IRHpbNbOtMcANr9QR+7uHlS9GZBPKcTTo09ak1wIOQlddepT9stIdkIGiUBuQ5YC8LVBV4tMX1GIJJEvXh9EB4QSUTcJl8gXwSpe2o5YHU2D7IH015O3HLIAkiymI4LQPOozHuQWZBurG25rfg6ZKlW1BkgF595dVrFrKWVbi/usQZ+HHIPzf7CligDkFEd3M9hGKIWE4dlVQ33NB4k1MqaK9DV/JI14lvlvGo1MnDiR+t5TEIrqn2EHgQsQiqcLMzMzOw2CALFTKBTLcL2ss7Ozn+5iirwESRzufwxYkyQIEHtEprsR3YbpdfBK5cfIswwwgV+XAyK3trZeTZChQ4fWhYaGFtnb23fPdPr27dv02muvFXl4eDQgz+8wdf+9qEHiwdCOjg7NVNzX1zd7zZo1mxcvXpwDeAemWq3Lly/PWL16dczYsWML2GpG4ePugtK6ublNLyoq0vxedPz48cEJCQnXUPTVzs7O2/CRpkmTJq3Ci/379OmjcX7Nzc2qAQM0HnS/DsjCwmKy9qK+vn4Qro/gxemALcatVpyr0AiJDQ0N3WuVtra2U/kgOYqvs8CLUvQLDg6m8C4bkufv7++F6thz82BOpxJUbdCgQaVXrlzRKrYZOskCKB8lGYdbLShZ1tGjR6/v2rXL68GDB5aUb8iQIYLoVu7l5ZVuZWVFhsfMmDEjD5BlgHigFGdQza9x3vnqq68uR8k0LoVa1NvbO1Ws+c+GhIRoMp04cUKB62dRvXgYX19M5Qfh/BDujczIyNBEcdOnT//Rz88vTcwgFWi1JbGxsRtRRZU+g0QLVsAU1rq6uh5goxdBF7EvKyuL3rdvX+iZM2fcMYfjhn+MnZ1d20svvVQcERER379/f4oxm/V1WnvYSMRPP/00Oycnx/XGjRv20BMzevToOhhjMaw+Hl2ERuRGY9yIgh1NR7FDODXCDVZK+NXRAYlc20Gc2fGeXqxhpZEL4vsxLkjp7u4+bNasWZMCAgK8hw8f/hRarhNV/OGbb77JOXz48Lna2trbbCkl58DK8ePHT0pNTd0PPd3r4h3oHndPnjz58dNPPz1BO6gSiCuaUgUFBf1XQUFBapeB4+rVqyfxwRGiIFTB/vz58wcoY2NjYxaSd+FWKrUvwwfdRrIZJvEjXScnJ/+VRhsBCH1ocmtr6wPKBF1QbO2E01Co5wGAFTinnt7v0qVL8ezHKrdt2zZWAFKr1eu0X79///7t6OjoJRRM4TIAQoOAaufOnevgYsq1+dLT05cKQOge+3mKLQPcT9sKKMnLLS0ttdw8hYWFf+ODlDY2NjqLbHCxFj4+Pi3kdmhKMWHChGZktOTmgbdsExkYlFlI32B/GivG9QKZTHY7MjLyNzCFZpwfAWgu9PUhPKWKdX6XBAaEYnshUwNb9zjc8tyxY8cqMGrgyEo3btz4Ju4Nzs3NPcC2IrXoQIGO8I8SfieWMpWUlGTD8D6CYiu0+qipqbmdlJT0YWVl5Q90jbyRSGRiBkknzvjSCUMGiZInIOkjZdlamAtkK+ynlg/AvSpAonDqwO20XJHxVqn0BhFQfKdU71fyohHqkJasKFlPSKbQSpGIvhCIG43QyLGOIldUxYYfjeDeH3G6WyyA4EYjAzH0JKJFfA1EIzvRKKsAaxMbjmDcNrH6IBRMwOLBaP8DYL/FOzIByMnJyQe9/9dSEBp9YeWZK1euzMWY346Sx8CyBwpAiDpeQdMqxSAqlYqG8POBgYHLLl68eBj5KBpxx7j2vACEJh1PJzRsh4WF/Txu3DiasjP4QMuKFSvUGMIprBkCN7wa3UlJ645QxXMC/aG4tnQybNiwGgyAsSj6sLi4uDlTpkwpAGQlIJ4UFkKHzpxoxFFQIgRNNFlhMFqoXn/99ScxOG7B8L192rRpBHkCkE+hZGeOKXTho78IQPDZaiivgzoilL4qKipqAwBfsSXZw4VoZjaurg2IRr4VgCZPnpyEapR0L9F0dKxC9b6E79kLiGBxDuPeZYQ46QLQwIED8+bNm7d7zJgx97qXr9raRgAo2IdE0S2iXlrRqZbqIs7FxcXvIBB9BcONG/y2Ba86jeHh4Xdmzpz5J7TNHnZVRzKIcISOwm7duhWGOMkd3rIfhTNoucpRo0bdRKMQ4Ft2qcxgNEK9n2JoWpkgW6mD0GalH9lAgjE2GpGz0YgLO4qQP7rHQpr4K+xSIGtEuF4IPP0QjYxEYPUkqtoEp58PP56bmJhIex+KtPqR8k026B4zYYwn0ORNEtHIR4iAx+mLRhSLFi16oby8/Loh549GOA4D9hQFoVndb968mWxg9KiAh6yjcwxNf0RAZisAIaoPR8YWPRAKa/wRG82nqAVHyfbt2yfwQXJ0QD90REsxxaEUv+DZfLiO/KysrEFIFRj33RAPTBJkLi0t/ZodihvRNTbh5S/ZkpRQSciw4+PjY7QhIZ53/Pzzz7sEVauqqjrKDtdXENmPR8jiiMvdEPKCrgjiowG5zxks2ysqKv4kAFVXV29kM3RidPgCXYEWOKnDuu/du3cTF8KWtBUBWZgAhFDuWTxs1GaEbz6CqegcVGcLRSR85cPd5iFxF4tGrNAaH3IzUwSCew1irQhdhksGETj5FTKcNiIa2UyzKUPRSF/Ie1BVtUg0ko9kHsTC2GiEvjaUXd8OZT0hLQdlwYYq9Pb+x/dHKPl7723VIfGvTflRsmvLlve6OC3AvzZKpF42GcboedlskNnVEgP1WEc9humzoy6RAbT3d9rHq/dLPTDZC4gZF2uMPeprZkEEIHMhOiA+xCx/JAExDfQoINrez+/lJvX63r7WC+K7EbMDCBE38hiNtGL+yCyYoZIYDTOmWkbBpOzIZNfS29d6Qf+ysMasiY6haMTYkfeRQER7v7kxwGMcsfHtyKyQprevmdnXaFUdss1UkJIDsHNyctqsUCiWdHR0lOHWGpNBgYGBi62trbfev3/f0dyqKcPDw0/V19eH9FhHBw8etFm0aNGPNjY27T0CQScfLFiwoODo0aOZqGJpTwMte8hKSMqlS5fOPPPMM1/0ND4aBnnnUXTa3r72rwQZMo2ejLT00+rInpSOOvCIWbNmzcvJyUmUWlyQNEj2eGL48OEz1Wp1Ynt7e0tjY2OFOSDvI0eO7OTuFzELhH8+4q9fmwtSQBbTJo0egXi/92tKh2qWmQ3iAGlzyRemgh6ZQfb2/v9sEMYw+oE3GhKTmZlZa/ZIe+zYMdoDSls9byEiWQxRmAWytbV9hT2nn513Qa4CZnJQIeZqyc2eAiyyRyAXF5fmsLCwD6CvWLMiNktLy84XX3wxf+7cucs8PDzOmqykmpqa7xEflWdkZKym3yPNCSC0HjIG4mYuoDcaeWzDGlNGEjlr3bT91aJHRTpx4oRzVlbWMW9vb/rJeTC/lEZbdkpKCv0Y3tXa2lqXlJS0y87Ojv7Ior/ZIM52zzs7duzYBMawHoE4R6QpILFtZ3cgy2Uy2TGz/BHzcDcP7dCMBaTJnNkRbe+gLR+exv7a1etGekEi/og2vdOeSFsDeemvE+lvjmgn0C8PTYxTiJiYmN81NDSUGrGv5odPPvnk95i3/MXV1ZXiA7mOQWKkLbS2tqbt1LukjL+lpYXJzs4+7+Xl9a6jo2MQRuVDKMDK06dPl3Xnoq1SRUVF8XqqZBMSEhIYFRU1/+7du+toRxSV8MGDB/46boR2jAGUIAGxXbp06bTKyspvqqurb8TFxf0BE55VeDGOXb3QBd25c0fsL+ls33777RmlpaXHCwsLv6Kt1k1NTYXXrl2jrbC0Rd/OGJDjihUrQkpKSpIKCgqOVVVV5bM6j5szZ84YzDQ/v379+hhDIKft27dHFBcXf4GSnES18qEX2sMVQw/z8/M3EBGB2FP6PKT9+++/P3P27Nm/rq2tbXNzcxvl4ODggXnuWqVSqfmbY9oUxwiMiBf6bd269XmEfUvQIlaAjLW3t6e/0SLIx9y92ZKuFpmIrggNDX0TYd94VLdZLpd3oEpLANH5PzRoX60USEa29NZbb7kMHjx4AqC0ytWAlFb9DtJ+W/ZDmgMfEQXR3mM59GHr6ek5HlVKhwUvQ7OH4H4qZACERl9PrZSVlWn2+qPqHTqdtq2tLROj7MArV66kwtiacN0G5XagSgrasKyTGYefn9/UPn36oNAK6ui13FHCC3Kty/gjm92V2DuK/H+B/leAAQDK0OGpiD5uIgAAAABJRU5ErkJggg=='); +} + +/* Generic Touch Widget Styles */ +.annotator-touch-widget { + font-family: "Helvetica Neue", Arial, Helvetica, sans-serif; + border: 1px solid rgba(0, 0, 0, 0.8); + background: rgba(0, 0, 0, 0.85); + background: -webkit-gradient(linear, left top, left bottom, from(rgba(57, 57, 57, 0.85)), color-stop(0.5, rgba(58, 58, 58, 0.85)), color-stop(0.5, rgba(0, 0, 0, 0.85)), to(rgba(0, 0, 0, 0.85))); + background: -moz-linear-gradient(-90deg, from(rgba(57, 57, 57, 0.85)), color-stop(0.5, rgba(58, 58, 58, 0.85)), color-stop(0.5, rgba(0, 0, 0, 0.85)) 50%, to(rgba(0, 0, 0, 0.85))); + background: -webkit-linear-gradient(-90deg, from(rgba(57, 57, 57, 0.85)), color-stop(0.5, rgba(58, 58, 58, 0.85)) 50%, color-stop(0.5, rgba(0, 0, 0, 0.85)) 50%, to(rgba(0, 0, 0, 0.85)) ); + background: linear-gradient(to bottom, from(rgba(57, 57, 57, 0.85)), color-stop(0.5, rgba(58, 58, 58, 0.85)) 50%, color-stop(0.5, rgba(0, 0, 0, 0.85)) 50%, to(rgba(0, 0, 0, 0.85))); + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + -ms-border-radius: 4px; + -o-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: 0 4px 10px rgba(0, 0, 0, 0.4); + -moz-box-shadow: 0 4px 10px rgba(0, 0, 0, 0.4); + -ms-box-shadow: 0 4px 10px rgba(0, 0, 0, 0.4); + -o-box-shadow: 0 4px 10px rgba(0, 0, 0, 0.4); + box-shadow: 0 4px 10px rgba(0, 0, 0, 0.4); + -webkit-tap-highlight-color: transparent; +} + +.annotator-touch-widget-inner { + background: #efefef; + border: 1px solid rgba(0, 0, 0, 0.8); + margin: 7px; + padding: 6px; + line-height: 0; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + -ms-border-radius: 3px; + -o-border-radius: 3px; + border-radius: 3px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.8); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.8); + -ms-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.8); + -o-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.8); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.8); +} + +.annotator-touch-widget .annotator-button { + cursor: pointer; + font-size: 16px; + line-height: 44px; + padding-left: 40px; + padding-right: 20px; + -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.1); + -ms-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.1); + -o-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 0 rgba(0, 0, 0, 0.1); + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; +} + +.annotator-touch-widget .annotator-button[disabled] { + opacity: 0.3; + cursor: default; +} + +.annotator-touch-widget .annotator-button::after { + left: 15px; +} + +.annotator-touch-widget .annotator-add::after, +.annotator-touch-widget .annotator-add:hover::after, +.annotator-touch-widget .annotator-add:focus::after, +.annotator-touch-widget .annotator-add.annotator-focus::after { + margin-top: -7px; + background-position: 0 -270px; +} + +/* Adder Styles */ +.annotator-touch-controls { + position: fixed; + bottom: 100px; + right: 15px; + min-width: auto; +} + +.annotator-touch-controls.annotator-touch-hide { + right: -9999em; + opacity: 0; + -webkit-transition: opacity 0.2s 0 ease-in, right 0s 0.3s linear; + -moz-transition: opacity 0.2s 0 ease-in, right 0s 0.3s linear; + -ms-transition: opacity 0.2s 0 ease-in, right 0s 0.3s linear; + -o-transition: opacity 0.2s 0 ease-in, right 0s 0.3s linear; + transition: opacity 0.2s 0 ease-in, right 0s 0.3s linear; +} + +.annotator-touch-controls .annotator-button { + line-height: 56px; +} + +/* Viewer Overrides*/ + +.annotator-touch-viewer .annotator-widget { + min-width: 380px; +} + +.annotator-touch-viewer div { + padding: 12px; +} + +.annotator-touch-viewer div:first-of-type { + font-size: 18px; + padding-top: 20px; + padding-bottom: 20px; +} + +.annotator-touch-viewer .annotator-touch-controls { + position: absolute; + top: 0; + left: auto; + right: 0; + display: none; + background: rgba(255, 255, 255, 0.6); + background: -webkit-gradient(linear, right top, left top, from(rgba(255, 255, 255, 0.8)), color-stop(0.9, rgba(255, 255, 255, 0.8)), to(rgba(255, 255, 255, 0))); + background: -moz-linear-gradient(0deg, from(rgba(255, 255, 255, 0.8)) 90%, to(rgba(255, 255, 255, 0))); + background: -webkit-linear-gradient(0deg, from(rgba(255, 255, 255, 0.8)) 90%, to(rgba(255, 255, 255, 0))); + background: linear-gradient(to bottom, from(rgba(255, 255, 255, 0.8)) 90%, to(rgba(255, 255, 255, 0))); + -webkit-box-pack: end; + -webkit-box-align: center; + -webkit-box-orient: horizontal; + -moz-box-pack: end; + -moz-box-align: center; + -moz-box-orient: horizontal; + box-pack: end; + box-align: center; + box-orient: horizontal; + padding: 10px; + bottom: 0; + padding: 0 10px 0 20px; +} + +.annotator-touch-viewer li.annotator-visible .annotator-touch-controls { + display: flex; +} + +.annotator-touch-viewer .annotator-touch-controls button { + line-height: 44px; + padding-left: 40px; + padding-right: 20px; + margin-left: 6px; +} + +.annotator-touch-viewer .annotator-touch-controls .annotator-edit::after { + background-position: 0 -15px; +} + +.annotator-touch-viewer .annotator-touch-controls .annotator-edit:hover::after, +.annotator-touch-viewer .annotator-touch-controls .annotator-edit:focus::after, +.annotator-touch-viewer .annotator-touch-controls .annotator-edit:active::after, +.annotator-touch-viewer .annotator-touch-controls .annotator-edit.annotator-focus::after { + background-position: 0 -30px; +} + +.annotator-touch-viewer .annotator-touch-controls button::after { + left: 15px; +} + +/* Editor Overrides */ + +.annotator-touch-editor { + position: fixed; + top: -1000px !important; + left: 0 !important; + right: 0; + bottom: -1000px; + padding: 1000px 0; + width: 100%; + height: 100%; + background: rgba(255, 255, 255, 0.6); + display: flex; + -webkit-box-pack: center; + -webkit-box-align: center; + -moz-box-pack: center; + -moz-box-align: center; + box-pack: center; + box-align: center; +} + +.annotator-touch-editor .annotator-touch-widget { + pointer-events: all; + position: relative; + width: 80%; + max-width: 680px; +} + +.annotator-touch-editor .annotator-touch-widget-inner { + position: static; + width: auto; + padding: 0; + background: #fff; +} + +.annotator-touch-editor .annotator-widget::after { + display: none; +} + +.annotator-touch-editor .annotator-widget .annotator-item { + border-top-color: rgba(0, 0, 0, 0.15); +} + +.annotator-touch-editor .annotator-widget .annotator-item, +.annotator-touch-editor.annotator-editor .annotator-item label, +.annotator-touch-editor.annotator-editor .annotator-item input, +.annotator-touch-editor.annotator-editor .annotator-item textarea { + font-size: 18px; +} + +.annotator-touch-editor.annotator-editor .annotator-item input, +.annotator-touch-editor.annotator-editor .annotator-item label { + line-height: 30px; + margin-left: 8px; +} + +.annotator-touch-editor.annotator-editor .annotator-item input[checkbox] { + font-size: large; +} + +.annotator-touch-editor .annotator-widget .annotator-item:first-child textarea { + font-size: 18px; + background-color: #fff; + -webkit-border-radius: 3px 3px 0 0; + -moz-border-radius: 3px 3px 0 0; + -o-border-radius: 3px 3px 0 0; + border-radius: 3px 3px 0 0; +} + +.annotator-touch-editor .annotator-resize { + display: none; +} + +.annotator-touch-editor .annotator-controls { + padding: 7px; + background-color: #efefef; + background-image: none; +} + +.annotator-touch-editor .annotator-item-quote { + font-size: 16px; + line-height: 1.2; + border-color: #cebfa2; + background-color: #fbfae9; + color: #a58129; + padding: 10px 7px; +} + +.annotator-item-quote span { + display: block; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + color: #a58129; + font-family: Georgia, serif; +} + +.annotator-item-quote.annotator-touch-expand span { + overflow: visible; + text-overflow: inherit; + white-space: inherit; +} + +.annotator-item-quote button { + font-size: 14px; + line-height: 44px; + margin-top: -13px; + float: right; + text-transform: uppercase; + font-weight: bold; + color: #a58129; + border: none; + background: none; + margin-left: 10px; + cursor: pointer; +} + +.annotator-button::after { + background-repeat: no-repeat; +} + +.annotator-button { + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + position: relative; + display: inline-block; + padding: 0 6px 0 22px; + color: rgb(54, 54, 54); + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.75); + text-decoration: none; + line-height: 24px; + font-size: 12px; + font-weight: bold; + border: 1px solid rgb(162, 162, 162); + background-color: rgb(212, 212, 212); + background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(245, 245, 245)), color-stop(0.5, rgb(210, 210, 210)), color-stop(0.5, rgb(190, 190, 190)), to(rgb(210, 210, 210))); + background-image: -moz-linear-gradient( -90deg, rgb(245, 245, 245), rgb(210, 210, 210) 50%, rgb(190, 190, 190) 50%, rgb(210, 210, 210)); + background-image: -webkit-linear-gradient( -90deg, rgb(245, 245, 245), rgb(210, 210, 210) 50%, rgb(190, 190, 190) 50%, rgb(210, 210, 210)); + background-image: linear-gradient( to bottom, rgb(245, 245, 245), rgb(210, 210, 210) 50%, rgb(190, 190, 190) 50%, rgb(210, 210, 210)); + -webkit-box-shadow: inset 0 0 5px rgba(255, 255, 255, 0.2), inset 0 0 1px rgba(255, 255, 255, 0.8); + -moz-box-shadow: inset 0 0 5px rgba(255, 255, 255, 0.2), inset 0 0 1px rgba(255, 255, 255, 0.8); + -o-box-shadow: inset 0 0 5px rgba(255, 255, 255, 0.2), inset 0 0 1px rgba(255, 255, 255, 0.8); + box-shadow: inset 0 0 5px rgba(255, 255, 255, 0.2), inset 0 0 1px rgba(255, 255, 255, 0.8); + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + -o-border-radius: 5px; + border-radius: 5px; +} + +.annotator-button::after { + position: absolute; + top: 50%; + left: 5px; + display: block; + content: ""; + width: 15px; + height: 15px; + margin-top: -7px; + background-position: 0 -90px; +} + +.annotator-button:hover, +.annotator-button:focus, +.annotator-button.annotator-focus { + outline: none; + border-color: rgb(67, 90, 160); + background-color: rgb(56, 101, 249); + background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(118, 145, 251)), color-stop(0.5, rgb(80, 117, 251)), color-stop(0.5, rgb(56, 101, 249)), to(rgb(54, 101, 250))); + background-image: -moz-linear-gradient( -90deg, rgb(118, 145, 251), rgb(80, 117, 251) 50%, rgb(56, 101, 249) 50%, rgb(54, 101, 250)); + background-image: -webkit-linear-gradient( -90deg, rgb(118, 145, 251), rgb(80, 117, 251) 50%, rgb(56, 101, 249) 50%, rgb(54, 101, 250)); + background-image: linear-gradient( to bottom, rgb(118, 145, 251), rgb(80, 117, 251) 50%, rgb(56, 101, 249) 50%, rgb(54, 101, 250)); + color: rgb(255, 255, 255); + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.42); +} + +.annotator-button:hover::after, +.annotator-button:focus::after { + margin-top: -8px; + background-position: 0 -105px; +} + +.annotator-button:active { + border-color: rgb(112, 12, 73); + background-color: rgb(209, 46, 142); + background-image: -webkit-gradient(linear, left top, left bottom, from(rgb(252, 124, 202)), color-stop(0.5, rgb(232, 93, 178)), color-stop(0.5, rgb(209, 46, 142)), to(rgb(255, 0, 156))); + background-image: -moz-linear-gradient(-90deg, rgb(252, 124, 202), rgb(232, 93, 178) 50%, rgb(209, 46, 142) 50%, rgb(255, 0, 156)); + background-image: -webkit-linear-gradient(-90deg, rgb(252, 124, 202), rgb(232, 93, 178) 50%, rgb(209, 46, 142) 50%, rgb(255, 0, 156)); + background-image: linear-gradient(to bottom, rgb(252, 124, 202), rgb(232, 93, 178) 50%, rgb(209, 46, 142) 50%, rgb(255, 0, 156)); +} + +.annotator-button.annotator-save::after { + background-position: 0 -120px; +} + +.annotator-button.annotator-save::after, +.annotator-button.annotator-save:focus::after, +.annotator-button.annotator-save.annotator-focus::after { + margin-top: -8px; + background-position: 0 -135px; +} + +/* Icon only button styles */ + +[data-annotator-use-icons] .annotator-touch-widget .annotator-button { + /* width & overflow is required by Android WebKit */ + width: 1px; + overflow: hidden; + text-indent: -999em; + padding-left: 25px; +} + +[data-annotator-use-icons] .annotator-touch-controls .annotator-button { + padding-left: 35px; +} + +[data-annotator-use-icons] .annotator-touch-controls .annotator-button::after { + left: 20px; +} + +[data-annotator-use-icons] .annotator-touch-viewer .annotator-touch-controls button { + padding-left: 25px; + text-indent: -9000em; +} + +[data-annotator-use-icons] .annotator-touch-viewer .annotator-touch-controls button::after { + left: 15px; +} + +[data-annotator-use-icons] .annotator-touch-viewer .annotator-widget { + min-width: 320px; +} + +/* Highlighter Selection Styles */ + +.annotator-selection-handle { + cursor: pointer; + display: block; + position: absolute; + width: 44px; + height: 44px; + top: 0; + left: 0; + padding: 0; + margin-left: -22px; + margin-top: -22px; + border-radius: 50%; + /* Removes the tap outline on elements that have bound touch events */ + -webkit-tap-highlight-color: transparent; +} + +.annotator-selection-handle::after { + content: ""; + display: block; + width: 20px; + height: 20px; + position: absolute; + left: 50%; + margin-left: -10px; + bottom: -5px; + background-position: 0 0; + background-repeat: no-repeat; +} + +.annotator-selection-start::after { + top: -5px; + bottom: auto; + background-position: 0 -20px; +} + +.annotator-selection-hide .annotator-selection-handle { + display: none; +} + +/* Styles for smaller screens */ + +@media only screen and (max-width: 480px) { + .annotator-touch-viewer { + left: 0 !important; + width: 100%; + background: none; + min-width: 0; + border: none; + } + + .annotator-touch-viewer .annotator-widget { + position: static; + left: 0; + width: 100%; + height: auto; + min-width: 0; + box-sizing: border-box; + -webkit-box-sizing: border-box; + -webkit-border-radius: none; + border-radius: none; + } + + .annotator-touch-viewer .annotator-widget::after { + display: none; + } + + .annotator-touch-editor { + border: none; + -webkit-box-align: start; + -moz-box-align: start; + box-align: start; + } + + .annotator-touch-editor .annotator-touch-widget { + width: 100%; + max-width: auto; + margin: 0; + border-color: #333; + border-left: none; + border-right: none; + -webkit-box-shadow: none; + -moz-box-shadow: none; + -ms-box-shadow: none; + -o-box-shadow: none; + box-shadow: none; + } + + .annotator-touch-editor .annotator-touch-widget-inner { + width: 100%; + max-width: auto; + margin: 0; + border: 0; + } + + .annotator-touch-editor .annotator-controls { + border-bottom: 1px solid #d4d4d4; + } + + .annotator-touch-editor .annotator-touch-widget, + .annotator-touch-editor .annotator-touch-widget-inner, + .annotator-touch-editor .annotator-touch-widget .annotator-item:first-child textarea, + .annotator-touch-editor .annotator-controls { + border-radius: 0; + } +} diff --git a/web/modules/custom/annotator/css/style.css b/web/modules/custom/annotator/css/style.css new file mode 100644 index 0000000..5e2673b --- /dev/null +++ b/web/modules/custom/annotator/css/style.css @@ -0,0 +1,290 @@ +/** + General Adjustments + ============================================= + */ +#search { + padding: 5px; + padding-left: 20px; + width: 100px; + border: 1px solid #f5f5f5; + font-size: 10px; + color: gray; + margin-right: 5px; + background-image: url('../images/glass.png'); + background-repeat: no-repeat; + background-position: left center; + outline: 0; +} + +.checkbox-inline { + font-size: 0.9em; +} + +.rotate { + -webkit-transform: rotate(-90deg); + -moz-transform: rotate(-90deg); + -ms-transform: rotate(-90deg); + -o-transform: rotate(-90deg); + transform: rotate(-90deg); + /* also accepts left, right, top, bottom coordinates; not required, but a good idea for styling */ + -webkit-transform-origin: 50% 50%; + -moz-transform-origin: 50% 50%; + -ms-transform-origin: 50% 50%; + -o-transform-origin: 50% 50%; + transform-origin: 50% 50%; + text-align: center; + margin: 0 auto; + /* @codingStandardsIgnoreStart */ + /* Should be unset in IE9+ I think. */ + filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3); + /* @codingStandardsIgnoreEnd */ +} + +.annotator-hl-error { + background: #ffcfbf; + cursor: pointer; +} + +.annotator-hl-good { + background: #dfffbf; + cursor: pointer; +} + +.annotator-hl-highlight { + background: rgba(255, 255, 10, 0.3); + text-decoration: underline; + cursor: pointer; +} + +.wrong { + background: #ffcfbf; + border: 1px solid #b3b3b3; + height: 20px; +} + +.good { + background: #dfffbf; + border: 1px solid #b3b3b3; + height: 20px; +} + +.hightlight { + background: #dfffbf; + border: 1px solid #b3b3b3; + height: 20px; +} + +.highlight { + background: rgba(255, 255, 10, 0.3); + border: 1px solid #b3b3b3; + height: 20px; +} + +.caixa_color { + float: left; + width: 20px; + margin-right: 5px; +} + +.anotator_color_box { + float: left; + height: 12px; + margin-bottom: 4px; + width: 99%; +} + +.annotations-list-uoc { + position: fixed; + top: 5em; + right: 1em; + height: 95%; + z-index: 100; +} + +.label-compartit { + border: 1px solid #676767; + padding: 1px 4px 2px; + background-color: #666; + color: #fff; + font-size: 11px; + font-weight: bold; + line-height: 14px; + vertical-align: baseline; + white-space: nowrap; + margin-top: 4px; +} + +.label-counter { + background-color: #666; + color: #fff; + font-size: 11px; + font-weight: bold; +} + +.label-counter-alert { + background-color: #b20000; + color: #fff; + font-size: 11px; + font-weight: bold; +} + +.label { + padding: 1px 4px 2px; + font-weight: bold; + line-height: 14px; + vertical-align: baseline; + white-space: nowrap; + margin-top: 4px; + border: 1px solid #676767; + color: #333; + font-size: 11px; +} + +.container-anotacions { + list-style: none outside none; + position: relative; + width: 100%; + padding: 10px; + margin: 0 0 0 -22.5%; + float: left; + left: 22.5%; +} + +.square { + border: 1px solid #b3b3b3; + height: 20px; +} + +.annotator-viewer-delete { + background-image: url('../images/icono_eliminar.png'); + background-repeat: no-repeat; + background-size: auto; + width: 20px; + height: 20px; +} + +.annotator-viewer-delete:hover { + background-image: url('../images/papelera_over.png'); +} + +.annotator-viewer-edit { + background-image: url('../images/edit-icon.png'); + background-repeat: no-repeat; + background-size: auto; + width: 20px; + height: 20px; +} + +.annotator-viewer-share { + background-image: url('../images/shared-icon.png'); + background-repeat: no-repeat; + background-size: auto; + width: 20px; + height: 20px; +} + +.annotator-marginviewer-element { + border: 1px solid #b3b3b3; + margin: 0px; + margin-bottom: 10px; + width: 227px; + font-size: 12px; + cursor: pointer; +} + +.annotator-marginviewer-element:hover { + border: 1px solid #666; + background: #fff; + background-color: #fff; +} + +.annotator-marginviewer-header { + border-bottom: 1px solid #b3b3b3; + background-color: #e6e6e6; + height: 26px; + padding-right: 0.5em; + padding-left: 0.5em; +} + +.annotator-marginviewer-footer { + background-color: #f5f5f5; + height: 26px; + padding-right: 0.5em; + padding-left: 0.5em; + padding-top: 0.3em; +} + +.annotator-marginviewer-highlighted > .annotator-marginviewer-header { + background-color: #fbed20; +} +.annotator-marginviewer-selected > .annotator-marginviewer-header { + background-color: #fbed20; +} + +.annotator-marginviewer-text, +.annotator-marginviewer-date { + border-bottom: 1px solid #ccc; + background-color: #f5f5f5; + padding: 0.5em; + font-family: arial; + font-size: 11px; + line-height: 1.5em; +} + +.panelTextArea { + width: 96%; +} + +.annotator-marginviewer-quote { + border-bottom: 1px solid #ccc; + background-color: #f5f5f5; + padding: 0.5em; + display: none; + font-family: arial; + font-size: 11px; + line-height: 1.4em; + padding-left: 0.6em; +} + +.anotador_text { + padding-left: 0.1em; +} + +.annotator-marginviewer-selected > .annotator-marginviewer-text { + background: -moz-linear-gradient(top, #fef8cd, #f6edb5); + background: -webkit-gradient(linear, left top, left bottom, from(#fef8cd), to(#f6edb5)); + /* @codingStandardsIgnoreStart */ + filter: progid:DXImageTransform.Microsoft.Gradient(StartColorStr='#fef8cd', EndColorStr='#f6edb5', GradientType=0); + /* @codingStandardsIgnoreEnd */ +} + +.annotator-panel-save, +.annotator-panel-cancel, +.annotator-panel-reset { + position: relative; + display: inline-block; + padding: 0 12px 0 12px; + color: #363636; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.75); + text-decoration: none; + line-height: 20px; + font-size: 10px; + font-weight: bold; + border: 1px solid #a2a2a2; + background-color: #d4d4d4; + border-radius: 5px; + margin-right: 3px; +} + +.filter-panel { + display: none; +} + +.annotator-user, +.annotator-marginviewer-footer > .label { + display: none; +} + +.annotator-viewer-edit img { + display: auto; +} diff --git a/web/modules/custom/annotator/images/edit-icon.png b/web/modules/custom/annotator/images/edit-icon.png new file mode 100644 index 0000000..046dea9 Binary files /dev/null and b/web/modules/custom/annotator/images/edit-icon.png differ diff --git a/web/modules/custom/annotator/images/glass.png b/web/modules/custom/annotator/images/glass.png new file mode 100644 index 0000000..2d1a000 Binary files /dev/null and b/web/modules/custom/annotator/images/glass.png differ diff --git a/web/modules/custom/annotator/images/icono_eliminar.png b/web/modules/custom/annotator/images/icono_eliminar.png new file mode 100644 index 0000000..455c883 Binary files /dev/null and b/web/modules/custom/annotator/images/icono_eliminar.png differ diff --git a/web/modules/custom/annotator/images/papelera_over.png b/web/modules/custom/annotator/images/papelera_over.png new file mode 100644 index 0000000..f3db586 Binary files /dev/null and b/web/modules/custom/annotator/images/papelera_over.png differ diff --git a/web/modules/custom/annotator/images/shared-icon.png b/web/modules/custom/annotator/images/shared-icon.png new file mode 100644 index 0000000..ccf5d59 Binary files /dev/null and b/web/modules/custom/annotator/images/shared-icon.png differ diff --git a/web/modules/custom/annotator/js/annotator.1.2.10/annotator.js b/web/modules/custom/annotator/js/annotator.1.2.10/annotator.js new file mode 100644 index 0000000..cf1941f --- /dev/null +++ b/web/modules/custom/annotator/js/annotator.1.2.10/annotator.js @@ -0,0 +1,1950 @@ + +/* +** Annotator v1.2.10 +** https://github.com/okfn/annotator/ +** +** Copyright 2015, the Annotator project contributors. +** Dual licensed under the MIT and GPLv3 licenses. +** https://github.com/okfn/annotator/blob/master/LICENSE +** +** Built at: 2015-02-26 03:26:47Z + */ + + +// + +// Generated by CoffeeScript 1.6.3 +(function() { + var $, Annotator, Delegator, LinkParser, Range, Util, findChild, fn, functions, g, getNodeName, getNodePosition, gettext, simpleXPathJQuery, simpleXPathPure, _Annotator, _gettext, _i, _j, _len, _len1, _ref, _ref1, _t, + __slice = [].slice, + __hasProp = {}.hasOwnProperty, + __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; + + simpleXPathJQuery = function(relativeRoot) { + var jq; + jq = this.map(function() { + var elem, idx, path, tagName; + path = ''; + elem = this; + while ((elem != null ? elem.nodeType : void 0) === Node.ELEMENT_NODE && elem !== relativeRoot) { + tagName = elem.tagName.replace(":", "\\:"); + idx = $(elem.parentNode).children(tagName).index(elem) + 1; + idx = "[" + idx + "]"; + path = "/" + elem.tagName.toLowerCase() + idx + path; + elem = elem.parentNode; + } + return path; + }); + return jq.get(); + }; + + simpleXPathPure = function(relativeRoot) { + var getPathSegment, getPathTo, jq, rootNode; + getPathSegment = function(node) { + var name, pos; + name = getNodeName(node); + pos = getNodePosition(node); + return "" + name + "[" + pos + "]"; + }; + rootNode = relativeRoot; + getPathTo = function(node) { + var xpath; + xpath = ''; + while (node !== rootNode) { + if (node == null) { + throw new Error("Called getPathTo on a node which was not a descendant of @rootNode. " + rootNode); + } + xpath = (getPathSegment(node)) + '/' + xpath; + node = node.parentNode; + } + xpath = '/' + xpath; + xpath = xpath.replace(/\/$/, ''); + return xpath; + }; + jq = this.map(function() { + var path; + path = getPathTo(this); + return path; + }); + return jq.get(); + }; + + findChild = function(node, type, index) { + var child, children, found, name, _i, _len; + if (!node.hasChildNodes()) { + throw new Error("XPath error: node has no children!"); + } + children = node.childNodes; + found = 0; + for (_i = 0, _len = children.length; _i < _len; _i++) { + child = children[_i]; + name = getNodeName(child); + if (name === type) { + found += 1; + if (found === index) { + return child; + } + } + } + throw new Error("XPath error: wanted child not found."); + }; + + getNodeName = function(node) { + var nodeName; + nodeName = node.nodeName.toLowerCase(); + switch (nodeName) { + case "#text": + return "text()"; + case "#comment": + return "comment()"; + case "#cdata-section": + return "cdata-section()"; + default: + return nodeName; + } + }; + + getNodePosition = function(node) { + var pos, tmp; + pos = 0; + tmp = node; + while (tmp) { + if (tmp.nodeName === node.nodeName) { + pos++; + } + tmp = tmp.previousSibling; + } + return pos; + }; + + gettext = null; + + if (typeof Gettext !== "undefined" && Gettext !== null) { + _gettext = new Gettext({ + domain: "annotator" + }); + gettext = function(msgid) { + return _gettext.gettext(msgid); + }; + } else { + gettext = function(msgid) { + return msgid; + }; + } + + _t = function(msgid) { + return gettext(msgid); + }; + + if (!(typeof jQuery !== "undefined" && jQuery !== null ? (_ref = jQuery.fn) != null ? _ref.jquery : void 0 : void 0)) { + console.error(_t("Annotator requires jQuery: have you included lib/vendor/jquery.js?")); + } + + if (!(JSON && JSON.parse && JSON.stringify)) { + console.error(_t("Annotator requires a JSON implementation: have you included lib/vendor/json2.js?")); + } + + $ = jQuery; + + Util = {}; + + Util.flatten = function(array) { + var flatten; + flatten = function(ary) { + var el, flat, _i, _len; + flat = []; + for (_i = 0, _len = ary.length; _i < _len; _i++) { + el = ary[_i]; + flat = flat.concat(el && $.isArray(el) ? flatten(el) : el); + } + return flat; + }; + return flatten(array); + }; + + Util.contains = function(parent, child) { + var node; + node = child; + while (node != null) { + if (node === parent) { + return true; + } + node = node.parentNode; + } + return false; + }; + + Util.getTextNodes = function(jq) { + var getTextNodes; + getTextNodes = function(node) { + var nodes; + if (node && node.nodeType !== Node.TEXT_NODE) { + nodes = []; + if (node.nodeType !== Node.COMMENT_NODE) { + node = node.lastChild; + while (node) { + nodes.push(getTextNodes(node)); + node = node.previousSibling; + } + } + return nodes.reverse(); + } else { + return node; + } + }; + return jq.map(function() { + return Util.flatten(getTextNodes(this)); + }); + }; + + Util.getLastTextNodeUpTo = function(n) { + var result; + switch (n.nodeType) { + case Node.TEXT_NODE: + return n; + case Node.ELEMENT_NODE: + if (n.lastChild != null) { + result = Util.getLastTextNodeUpTo(n.lastChild); + if (result != null) { + return result; + } + } + break; + } + n = n.previousSibling; + if (n != null) { + return Util.getLastTextNodeUpTo(n); + } else { + return null; + } + }; + + Util.getFirstTextNodeNotBefore = function(n) { + var result; + switch (n.nodeType) { + case Node.TEXT_NODE: + return n; + case Node.ELEMENT_NODE: + if (n.firstChild != null) { + result = Util.getFirstTextNodeNotBefore(n.firstChild); + if (result != null) { + return result; + } + } + break; + } + n = n.nextSibling; + if (n != null) { + return Util.getFirstTextNodeNotBefore(n); + } else { + return null; + } + }; + + Util.readRangeViaSelection = function(range) { + var sel; + sel = Util.getGlobal().getSelection(); + sel.removeAllRanges(); + sel.addRange(range.toRange()); + return sel.toString(); + }; + + Util.xpathFromNode = function(el, relativeRoot) { + var exception, result; + try { + result = simpleXPathJQuery.call(el, relativeRoot); + } catch (_error) { + exception = _error; + console.log("jQuery-based XPath construction failed! Falling back to manual."); + result = simpleXPathPure.call(el, relativeRoot); + } + return result; + }; + + Util.nodeFromXPath = function(xp, root) { + var idx, name, node, step, steps, _i, _len, _ref1; + steps = xp.substring(1).split("/"); + node = root; + for (_i = 0, _len = steps.length; _i < _len; _i++) { + step = steps[_i]; + _ref1 = step.split("["), name = _ref1[0], idx = _ref1[1]; + idx = idx != null ? parseInt((idx != null ? idx.split("]") : void 0)[0]) : 1; + node = findChild(node, name.toLowerCase(), idx); + } + return node; + }; + + Util.escape = function(html) { + return html.replace(/&(?!\w+;)/g, '&').replace(//g, '>').replace(/"/g, '"'); + }; + + Util.uuid = (function() { + var counter; + counter = 0; + return function() { + return counter++; + }; + })(); + + Util.getGlobal = function() { + return (function() { + return this; + })(); + }; + + Util.maxZIndex = function($elements) { + var all, el; + all = (function() { + var _i, _len, _results; + _results = []; + for (_i = 0, _len = $elements.length; _i < _len; _i++) { + el = $elements[_i]; + if ($(el).css('position') === 'static') { + _results.push(-1); + } else { + _results.push(parseFloat($(el).css('z-index')) || -1); + } + } + return _results; + })(); + return Math.max.apply(Math, all); + }; + + Util.mousePosition = function(e, offsetEl) { + var offset, _ref1; + if ((_ref1 = $(offsetEl).css('position')) !== 'absolute' && _ref1 !== 'fixed' && _ref1 !== 'relative') { + offsetEl = $(offsetEl).offsetParent()[0]; + } + offset = $(offsetEl).offset(); + return { + top: e.pageY - offset.top, + left: e.pageX - offset.left + }; + }; + + Util.preventEventDefault = function(event) { + return event != null ? typeof event.preventDefault === "function" ? event.preventDefault() : void 0 : void 0; + }; + + functions = ["log", "debug", "info", "warn", "exception", "assert", "dir", "dirxml", "trace", "group", "groupEnd", "groupCollapsed", "time", "timeEnd", "profile", "profileEnd", "count", "clear", "table", "error", "notifyFirebug", "firebug", "userObjects"]; + + if (typeof console !== "undefined" && console !== null) { + if (console.group == null) { + console.group = function(name) { + return console.log("GROUP: ", name); + }; + } + if (console.groupCollapsed == null) { + console.groupCollapsed = console.group; + } + for (_i = 0, _len = functions.length; _i < _len; _i++) { + fn = functions[_i]; + if (console[fn] == null) { + console[fn] = function() { + return console.log(_t("Not implemented:") + (" console." + name)); + }; + } + } + } else { + this.console = {}; + for (_j = 0, _len1 = functions.length; _j < _len1; _j++) { + fn = functions[_j]; + this.console[fn] = function() {}; + } + this.console['error'] = function() { + var args; + args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + return alert("ERROR: " + (args.join(', '))); + }; + this.console['warn'] = function() { + var args; + args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + return alert("WARNING: " + (args.join(', '))); + }; + } + + Delegator = (function() { + Delegator.prototype.events = {}; + + Delegator.prototype.options = {}; + + Delegator.prototype.element = null; + + function Delegator(element, options) { + this.options = $.extend(true, {}, this.options, options); + this.element = $(element); + this._closures = {}; + this.on = this.subscribe; + this.addEvents(); + } + + Delegator.prototype.destroy = function() { + return this.removeEvents(); + }; + + Delegator.prototype.addEvents = function() { + var event, _k, _len2, _ref1, _results; + _ref1 = Delegator._parseEvents(this.events); + _results = []; + for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) { + event = _ref1[_k]; + _results.push(this._addEvent(event.selector, event.event, event.functionName)); + } + return _results; + }; + + Delegator.prototype.removeEvents = function() { + var event, _k, _len2, _ref1, _results; + _ref1 = Delegator._parseEvents(this.events); + _results = []; + for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) { + event = _ref1[_k]; + _results.push(this._removeEvent(event.selector, event.event, event.functionName)); + } + return _results; + }; + + Delegator.prototype._addEvent = function(selector, event, functionName) { + var closure, + _this = this; + closure = function() { + return _this[functionName].apply(_this, arguments); + }; + if (selector === '' && Delegator._isCustomEvent(event)) { + this.subscribe(event, closure); + } else { + this.element.delegate(selector, event, closure); + } + this._closures["" + selector + "/" + event + "/" + functionName] = closure; + return this; + }; + + Delegator.prototype._removeEvent = function(selector, event, functionName) { + var closure; + closure = this._closures["" + selector + "/" + event + "/" + functionName]; + if (selector === '' && Delegator._isCustomEvent(event)) { + this.unsubscribe(event, closure); + } else { + this.element.undelegate(selector, event, closure); + } + delete this._closures["" + selector + "/" + event + "/" + functionName]; + return this; + }; + + Delegator.prototype.publish = function() { + this.element.triggerHandler.apply(this.element, arguments); + return this; + }; + + Delegator.prototype.subscribe = function(event, callback) { + var closure; + closure = function() { + return callback.apply(this, [].slice.call(arguments, 1)); + }; + closure.guid = callback.guid = ($.guid += 1); + this.element.bind(event, closure); + return this; + }; + + Delegator.prototype.unsubscribe = function() { + this.element.unbind.apply(this.element, arguments); + return this; + }; + + return Delegator; + + })(); + + Delegator._parseEvents = function(eventsObj) { + var event, events, functionName, sel, selector, _k, _ref1; + events = []; + for (sel in eventsObj) { + functionName = eventsObj[sel]; + _ref1 = sel.split(' '), selector = 2 <= _ref1.length ? __slice.call(_ref1, 0, _k = _ref1.length - 1) : (_k = 0, []), event = _ref1[_k++]; + events.push({ + selector: selector.join(' '), + event: event, + functionName: functionName + }); + } + return events; + }; + + Delegator.natives = (function() { + var key, specials, val; + specials = (function() { + var _ref1, _results; + _ref1 = jQuery.event.special; + _results = []; + for (key in _ref1) { + if (!__hasProp.call(_ref1, key)) continue; + val = _ref1[key]; + _results.push(key); + } + return _results; + })(); + return "blur focus focusin focusout load resize scroll unload click dblclick\nmousedown mouseup mousemove mouseover mouseout mouseenter mouseleave\nchange select submit keydown keypress keyup error".split(/[^a-z]+/).concat(specials); + })(); + + Delegator._isCustomEvent = function(event) { + event = event.split('.')[0]; + return $.inArray(event, Delegator.natives) === -1; + }; + + Range = {}; + + Range.sniff = function(r) { + if (r.commonAncestorContainer != null) { + return new Range.BrowserRange(r); + } else if (typeof r.start === "string") { + return new Range.SerializedRange(r); + } else if (r.start && typeof r.start === "object") { + return new Range.NormalizedRange(r); + } else { + console.error(_t("Could not sniff range type")); + return false; + } + }; + + Range.nodeFromXPath = function(xpath, root) { + var customResolver, evaluateXPath, namespace, node, segment; + if (root == null) { + root = document; + } + evaluateXPath = function(xp, nsResolver) { + var exception; + if (nsResolver == null) { + nsResolver = null; + } + try { + return document.evaluate('.' + xp, root, nsResolver, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; + } catch (_error) { + exception = _error; + console.log("XPath evaluation failed."); + console.log("Trying fallback..."); + return Util.nodeFromXPath(xp, root); + } + }; + if (!$.isXMLDoc(document.documentElement)) { + return evaluateXPath(xpath); + } else { + customResolver = document.createNSResolver(document.ownerDocument === null ? document.documentElement : document.ownerDocument.documentElement); + node = evaluateXPath(xpath, customResolver); + if (!node) { + xpath = ((function() { + var _k, _len2, _ref1, _results; + _ref1 = xpath.split('/'); + _results = []; + for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) { + segment = _ref1[_k]; + if (segment && segment.indexOf(':') === -1) { + _results.push(segment.replace(/^([a-z]+)/, 'xhtml:$1')); + } else { + _results.push(segment); + } + } + return _results; + })()).join('/'); + namespace = document.lookupNamespaceURI(null); + customResolver = function(ns) { + if (ns === 'xhtml') { + return namespace; + } else { + return document.documentElement.getAttribute('xmlns:' + ns); + } + }; + node = evaluateXPath(xpath, customResolver); + } + return node; + } + }; + + Range.RangeError = (function(_super) { + __extends(RangeError, _super); + + function RangeError(type, message, parent) { + this.type = type; + this.message = message; + this.parent = parent != null ? parent : null; + RangeError.__super__.constructor.call(this, this.message); + } + + return RangeError; + + })(Error); + + Range.BrowserRange = (function() { + function BrowserRange(obj) { + this.commonAncestorContainer = obj.commonAncestorContainer; + this.startContainer = obj.startContainer; + this.startOffset = obj.startOffset; + this.endContainer = obj.endContainer; + this.endOffset = obj.endOffset; + } + + BrowserRange.prototype.normalize = function(root) { + var n, node, nr, r; + if (this.tainted) { + console.error(_t("You may only call normalize() once on a BrowserRange!")); + return false; + } else { + this.tainted = true; + } + r = {}; + if (this.startContainer.nodeType === Node.ELEMENT_NODE) { + r.start = Util.getFirstTextNodeNotBefore(this.startContainer.childNodes[this.startOffset]); + r.startOffset = 0; + } else { + r.start = this.startContainer; + r.startOffset = this.startOffset; + } + if (this.endContainer.nodeType === Node.ELEMENT_NODE) { + node = this.endContainer.childNodes[this.endOffset]; + if (node != null) { + n = node; + while ((n != null) && (n.nodeType !== Node.TEXT_NODE)) { + n = n.firstChild; + } + if (n != null) { + r.end = n; + r.endOffset = 0; + } + } + if (r.end == null) { + node = this.endContainer.childNodes[this.endOffset - 1]; + r.end = Util.getLastTextNodeUpTo(node); + r.endOffset = r.end.nodeValue.length; + } + } else { + r.end = this.endContainer; + r.endOffset = this.endOffset; + } + nr = {}; + if (r.startOffset > 0) { + if (r.start.nodeValue.length > r.startOffset) { + nr.start = r.start.splitText(r.startOffset); + } else { + nr.start = r.start.nextSibling; + } + } else { + nr.start = r.start; + } + if (r.start === r.end) { + if (nr.start.nodeValue.length > (r.endOffset - r.startOffset)) { + nr.start.splitText(r.endOffset - r.startOffset); + } + nr.end = nr.start; + } else { + if (r.end.nodeValue.length > r.endOffset) { + r.end.splitText(r.endOffset); + } + nr.end = r.end; + } + nr.commonAncestor = this.commonAncestorContainer; + while (nr.commonAncestor.nodeType !== Node.ELEMENT_NODE) { + nr.commonAncestor = nr.commonAncestor.parentNode; + } + return new Range.NormalizedRange(nr); + }; + + BrowserRange.prototype.serialize = function(root, ignoreSelector) { + return this.normalize(root).serialize(root, ignoreSelector); + }; + + return BrowserRange; + + })(); + + Range.NormalizedRange = (function() { + function NormalizedRange(obj) { + this.commonAncestor = obj.commonAncestor; + this.start = obj.start; + this.end = obj.end; + } + + NormalizedRange.prototype.normalize = function(root) { + return this; + }; + + NormalizedRange.prototype.limit = function(bounds) { + var nodes, parent, startParents, _k, _len2, _ref1; + nodes = $.grep(this.textNodes(), function(node) { + return node.parentNode === bounds || $.contains(bounds, node.parentNode); + }); + if (!nodes.length) { + return null; + } + this.start = nodes[0]; + this.end = nodes[nodes.length - 1]; + startParents = $(this.start).parents(); + _ref1 = $(this.end).parents(); + for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) { + parent = _ref1[_k]; + if (startParents.index(parent) !== -1) { + this.commonAncestor = parent; + break; + } + } + return this; + }; + + NormalizedRange.prototype.serialize = function(root, ignoreSelector) { + var end, serialization, start; + serialization = function(node, isEnd) { + var n, nodes, offset, origParent, textNodes, xpath, _k, _len2; + if (ignoreSelector) { + origParent = $(node).parents(":not(" + ignoreSelector + ")").eq(0); + } else { + origParent = $(node).parent(); + } + xpath = Util.xpathFromNode(origParent, root)[0]; + textNodes = Util.getTextNodes(origParent); + nodes = textNodes.slice(0, textNodes.index(node)); + offset = 0; + for (_k = 0, _len2 = nodes.length; _k < _len2; _k++) { + n = nodes[_k]; + offset += n.nodeValue.length; + } + if (isEnd) { + return [xpath, offset + node.nodeValue.length]; + } else { + return [xpath, offset]; + } + }; + start = serialization(this.start); + end = serialization(this.end, true); + return new Range.SerializedRange({ + start: start[0], + end: end[0], + startOffset: start[1], + endOffset: end[1] + }); + }; + + NormalizedRange.prototype.text = function() { + var node; + return ((function() { + var _k, _len2, _ref1, _results; + _ref1 = this.textNodes(); + _results = []; + for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) { + node = _ref1[_k]; + _results.push(node.nodeValue); + } + return _results; + }).call(this)).join(''); + }; + + NormalizedRange.prototype.textNodes = function() { + var end, start, textNodes, _ref1; + textNodes = Util.getTextNodes($(this.commonAncestor)); + _ref1 = [textNodes.index(this.start), textNodes.index(this.end)], start = _ref1[0], end = _ref1[1]; + return $.makeArray(textNodes.slice(start, +end + 1 || 9e9)); + }; + + NormalizedRange.prototype.toRange = function() { + var range; + range = document.createRange(); + range.setStartBefore(this.start); + range.setEndAfter(this.end); + return range; + }; + + return NormalizedRange; + + })(); + + Range.SerializedRange = (function() { + function SerializedRange(obj) { + this.start = obj.start; + this.startOffset = obj.startOffset; + this.end = obj.end; + this.endOffset = obj.endOffset; + } + + SerializedRange.prototype.normalize = function(root) { + var contains, e, length, node, p, range, targetOffset, tn, _k, _l, _len2, _len3, _ref1, _ref2; + range = {}; + _ref1 = ['start', 'end']; + for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) { + p = _ref1[_k]; + try { + node = Range.nodeFromXPath(this[p], root); + } catch (_error) { + e = _error; + throw new Range.RangeError(p, ("Error while finding " + p + " node: " + this[p] + ": ") + e, e); + } + if (!node) { + throw new Range.RangeError(p, "Couldn't find " + p + " node: " + this[p]); + } + length = 0; + targetOffset = this[p + 'Offset']; + if (p === 'end') { + targetOffset--; + } + _ref2 = Util.getTextNodes($(node)); + for (_l = 0, _len3 = _ref2.length; _l < _len3; _l++) { + tn = _ref2[_l]; + if (length + tn.nodeValue.length > targetOffset) { + range[p + 'Container'] = tn; + range[p + 'Offset'] = this[p + 'Offset'] - length; + break; + } else { + length += tn.nodeValue.length; + } + } + if (range[p + 'Offset'] == null) { + throw new Range.RangeError("" + p + "offset", "Couldn't find offset " + this[p + 'Offset'] + " in element " + this[p]); + } + } + contains = document.compareDocumentPosition == null ? function(a, b) { + return a.contains(b); + } : function(a, b) { + return a.compareDocumentPosition(b) & 16; + }; + $(range.startContainer).parents().each(function() { + if (contains(this, range.endContainer)) { + range.commonAncestorContainer = this; + return false; + } + }); + return new Range.BrowserRange(range).normalize(root); + }; + + SerializedRange.prototype.serialize = function(root, ignoreSelector) { + return this.normalize(root).serialize(root, ignoreSelector); + }; + + SerializedRange.prototype.toObject = function() { + return { + start: this.start, + startOffset: this.startOffset, + end: this.end, + endOffset: this.endOffset + }; + }; + + return SerializedRange; + + })(); + + _Annotator = this.Annotator; + + Annotator = (function(_super) { + __extends(Annotator, _super); + + Annotator.prototype.events = { + ".annotator-adder button click": "onAdderClick", + ".annotator-adder button mousedown": "onAdderMousedown", + ".annotator-hl mouseover": "onHighlightMouseover", + ".annotator-hl mouseout": "startViewerHideTimer" + }; + + Annotator.prototype.html = { + adder: '
', + wrapper: '
' + }; + + Annotator.prototype.options = { + readOnly: false + }; + + Annotator.prototype.plugins = {}; + + Annotator.prototype.editor = null; + + Annotator.prototype.viewer = null; + + Annotator.prototype.selectedRanges = null; + + Annotator.prototype.mouseIsDown = false; + + Annotator.prototype.ignoreMouseup = false; + + Annotator.prototype.viewerHideTimer = null; + + function Annotator(element, options) { + this.onDeleteAnnotation = __bind(this.onDeleteAnnotation, this); + this.onEditAnnotation = __bind(this.onEditAnnotation, this); + this.onAdderClick = __bind(this.onAdderClick, this); + this.onAdderMousedown = __bind(this.onAdderMousedown, this); + this.onHighlightMouseover = __bind(this.onHighlightMouseover, this); + this.checkForEndSelection = __bind(this.checkForEndSelection, this); + this.checkForStartSelection = __bind(this.checkForStartSelection, this); + this.clearViewerHideTimer = __bind(this.clearViewerHideTimer, this); + this.startViewerHideTimer = __bind(this.startViewerHideTimer, this); + this.showViewer = __bind(this.showViewer, this); + this.onEditorSubmit = __bind(this.onEditorSubmit, this); + this.onEditorHide = __bind(this.onEditorHide, this); + this.showEditor = __bind(this.showEditor, this); + Annotator.__super__.constructor.apply(this, arguments); + this.plugins = {}; + if (!Annotator.supported()) { + return this; + } + if (!this.options.readOnly) { + this._setupDocumentEvents(); + } + this._setupWrapper()._setupViewer()._setupEditor(); + this._setupDynamicStyle(); + this.adder = $(this.html.adder).appendTo(this.wrapper).hide(); + Annotator._instances.push(this); + } + + Annotator.prototype._setupWrapper = function() { + this.wrapper = $(this.html.wrapper); + this.element.find('script').remove(); + this.element.wrapInner(this.wrapper); + this.wrapper = this.element.find('.annotator-wrapper'); + return this; + }; + + Annotator.prototype._setupViewer = function() { + var _this = this; + this.viewer = new Annotator.Viewer({ + readOnly: this.options.readOnly + }); + this.viewer.hide().on("edit", this.onEditAnnotation).on("delete", this.onDeleteAnnotation).addField({ + load: function(field, annotation) { + if (annotation.text) { + $(field).html(Util.escape(annotation.text)); + } else { + $(field).html("" + (_t('No Comment')) + ""); + } + return _this.publish('annotationViewerTextField', [field, annotation]); + } + }).element.appendTo(this.wrapper).bind({ + "mouseover": this.clearViewerHideTimer, + "mouseout": this.startViewerHideTimer + }); + return this; + }; + + Annotator.prototype._setupEditor = function() { + this.editor = new Annotator.Editor(); + this.editor.hide().on('hide', this.onEditorHide).on('save', this.onEditorSubmit).addField({ + type: 'textarea', + label: _t('Comments') + '\u2026', + load: function(field, annotation) { + return $(field).find('textarea').val(annotation.text || ''); + }, + submit: function(field, annotation) { + return annotation.text = $(field).find('textarea').val(); + } + }); + this.editor.element.appendTo(this.wrapper); + return this; + }; + + Annotator.prototype._setupDocumentEvents = function() { + $(document).bind({ + "mouseup": this.checkForEndSelection, + "mousedown": this.checkForStartSelection + }); + return this; + }; + + Annotator.prototype._setupDynamicStyle = function() { + var max, sel, style, x; + style = $('#annotator-dynamic-style'); + if (!style.length) { + style = $('').appendTo(document.head); + } + sel = '*' + ((function() { + var _k, _len2, _ref1, _results; + _ref1 = ['adder', 'outer', 'notice', 'filter']; + _results = []; + for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) { + x = _ref1[_k]; + _results.push(":not(.annotator-" + x + ")"); + } + return _results; + })()).join(''); + max = Util.maxZIndex($(document.body).find(sel)); + max = Math.max(max, 1000); + style.text([".annotator-adder, .annotator-outer, .annotator-notice {", " z-index: " + (max + 20) + ";", "}", ".annotator-filter {", " z-index: " + (max + 10) + ";", "}"].join("\n")); + return this; + }; + + Annotator.prototype.destroy = function() { + var idx, name, plugin, _base, _ref1; + Annotator.__super__.destroy.apply(this, arguments); + $(document).unbind({ + "mouseup": this.checkForEndSelection, + "mousedown": this.checkForStartSelection + }); + $('#annotator-dynamic-style').remove(); + this.adder.remove(); + this.viewer.destroy(); + this.editor.destroy(); + this.wrapper.find('.annotator-hl').each(function() { + $(this).contents().insertBefore(this); + return $(this).remove(); + }); + this.wrapper.contents().insertBefore(this.wrapper); + this.wrapper.remove(); + this.element.data('annotator', null); + _ref1 = this.plugins; + for (name in _ref1) { + plugin = _ref1[name]; + if (typeof (_base = this.plugins[name]).destroy === "function") { + _base.destroy(); + } + } + idx = Annotator._instances.indexOf(this); + if (idx !== -1) { + return Annotator._instances.splice(idx, 1); + } + }; + + Annotator.prototype.getSelectedRanges = function() { + var browserRange, i, normedRange, r, ranges, rangesToIgnore, selection, _k, _len2; + selection = Util.getGlobal().getSelection(); + ranges = []; + rangesToIgnore = []; + if (!selection.isCollapsed) { + ranges = (function() { + var _k, _ref1, _results; + _results = []; + for (i = _k = 0, _ref1 = selection.rangeCount; 0 <= _ref1 ? _k < _ref1 : _k > _ref1; i = 0 <= _ref1 ? ++_k : --_k) { + r = selection.getRangeAt(i); + browserRange = new Range.BrowserRange(r); + normedRange = browserRange.normalize().limit(this.wrapper[0]); + if (normedRange === null) { + rangesToIgnore.push(r); + } + _results.push(normedRange); + } + return _results; + }).call(this); + selection.removeAllRanges(); + } + for (_k = 0, _len2 = rangesToIgnore.length; _k < _len2; _k++) { + r = rangesToIgnore[_k]; + selection.addRange(r); + } + return $.grep(ranges, function(range) { + if (range) { + selection.addRange(range.toRange()); + } + return range; + }); + }; + + Annotator.prototype.createAnnotation = function() { + var annotation; + annotation = {}; + this.publish('beforeAnnotationCreated', [annotation]); + return annotation; + }; + + Annotator.prototype.setupAnnotation = function(annotation) { + var e, normed, normedRanges, r, root, _k, _l, _len2, _len3, _ref1; + root = this.wrapper[0]; + annotation.ranges || (annotation.ranges = this.selectedRanges); + normedRanges = []; + _ref1 = annotation.ranges; + for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) { + r = _ref1[_k]; + try { + normedRanges.push(Range.sniff(r).normalize(root)); + } catch (_error) { + e = _error; + if (e instanceof Range.RangeError) { + this.publish('rangeNormalizeFail', [annotation, r, e]); + } else { + throw e; + } + } + } + annotation.quote = []; + annotation.ranges = []; + annotation.highlights = []; + for (_l = 0, _len3 = normedRanges.length; _l < _len3; _l++) { + normed = normedRanges[_l]; + annotation.quote.push($.trim(normed.text())); + annotation.ranges.push(normed.serialize(this.wrapper[0], '.annotator-hl')); + $.merge(annotation.highlights, this.highlightRange(normed)); + } + annotation.quote = annotation.quote.join(' / '); + $(annotation.highlights).data('annotation', annotation); + $(annotation.highlights).attr('data-annotation-id', annotation.id); + return annotation; + }; + + Annotator.prototype.updateAnnotation = function(annotation) { + this.publish('beforeAnnotationUpdated', [annotation]); + $(annotation.highlights).attr('data-annotation-id', annotation.id); + this.publish('annotationUpdated', [annotation]); + return annotation; + }; + + Annotator.prototype.deleteAnnotation = function(annotation) { + var child, h, _k, _len2, _ref1; + if (annotation.highlights != null) { + _ref1 = annotation.highlights; + for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) { + h = _ref1[_k]; + if (!(h.parentNode != null)) { + continue; + } + child = h.childNodes[0]; + $(h).replaceWith(h.childNodes); + } + } + this.publish('annotationDeleted', [annotation]); + return annotation; + }; + + Annotator.prototype.loadAnnotations = function(annotations) { + var clone, loader, + _this = this; + if (annotations == null) { + annotations = []; + } + loader = function(annList) { + var n, now, _k, _len2; + if (annList == null) { + annList = []; + } + now = annList.splice(0, 10); + for (_k = 0, _len2 = now.length; _k < _len2; _k++) { + n = now[_k]; + _this.setupAnnotation(n); + } + if (annList.length > 0) { + return setTimeout((function() { + return loader(annList); + }), 10); + } else { + return _this.publish('annotationsLoaded', [clone]); + } + }; + clone = annotations.slice(); + loader(annotations); + return this; + }; + + Annotator.prototype.dumpAnnotations = function() { + if (this.plugins['Store']) { + return this.plugins['Store'].dumpAnnotations(); + } else { + console.warn(_t("Can't dump annotations without Store plugin.")); + return false; + } + }; + + Annotator.prototype.highlightRange = function(normedRange, cssClass) { + var hl, node, white, _k, _len2, _ref1, _results; + if (cssClass == null) { + cssClass = 'annotator-hl'; + } + white = /^\s*$/; + hl = $(""); + _ref1 = normedRange.textNodes(); + _results = []; + for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) { + node = _ref1[_k]; + if (!white.test(node.nodeValue)) { + _results.push($(node).wrapAll(hl).parent().show()[0]); + } + } + return _results; + }; + + Annotator.prototype.highlightRanges = function(normedRanges, cssClass) { + var highlights, r, _k, _len2; + if (cssClass == null) { + cssClass = 'annotator-hl'; + } + highlights = []; + for (_k = 0, _len2 = normedRanges.length; _k < _len2; _k++) { + r = normedRanges[_k]; + $.merge(highlights, this.highlightRange(r, cssClass)); + } + return highlights; + }; + + Annotator.prototype.addPlugin = function(name, options) { + var klass, _base; + if (this.plugins[name]) { + console.error(_t("You cannot have more than one instance of any plugin.")); + } else { + klass = Annotator.Plugin[name]; + if (typeof klass === 'function') { + this.plugins[name] = new klass(this.element[0], options); + this.plugins[name].annotator = this; + if (typeof (_base = this.plugins[name]).pluginInit === "function") { + _base.pluginInit(); + } + } else { + console.error(_t("Could not load ") + name + _t(" plugin. Have you included the appropriate +``` + +Then, on the server, you can replace `__SERVER_DATA__` with a JSON of real data right before sending the response. The client code can then read `window.SERVER_DATA` to use it. **Make sure to [sanitize the JSON before sending it to the client](https://medium.com/node-security/the-most-common-xss-vulnerability-in-react-js-applications-2bdffbcc1fa0) as it makes your app vulnerable to XSS attacks.** + +## Running Tests + +>Note: this feature is available with `react-scripts@0.3.0` and higher.
+>[Read the migration guide to learn how to enable it in older projects!](https://github.com/facebookincubator/create-react-app/blob/master/CHANGELOG.md#migrating-from-023-to-030) + +Create React App uses [Jest](https://facebook.github.io/jest/) as its test runner. To prepare for this integration, we did a [major revamp](https://facebook.github.io/jest/blog/2016/09/01/jest-15.html) of Jest so if you heard bad things about it years ago, give it another try. + +Jest is a Node-based runner. This means that the tests always run in a Node environment and not in a real browser. This lets us enable fast iteration speed and prevent flakiness. + +While Jest provides browser globals such as `window` thanks to [jsdom](https://github.com/tmpvar/jsdom), they are only approximations of the real browser behavior. Jest is intended to be used for unit tests of your logic and your components rather than the DOM quirks. + +We recommend that you use a separate tool for browser end-to-end tests if you need them. They are beyond the scope of Create React App. + +### Filename Conventions + +Jest will look for test files with any of the following popular naming conventions: + +* Files with `.js` suffix in `__tests__` folders. +* Files with `.test.js` suffix. +* Files with `.spec.js` suffix. + +The `.test.js` / `.spec.js` files (or the `__tests__` folders) can be located at any depth under the `src` top level folder. + +We recommend to put the test files (or `__tests__` folders) next to the code they are testing so that relative imports appear shorter. For example, if `App.test.js` and `App.js` are in the same folder, the test just needs to `import App from './App'` instead of a long relative path. Colocation also helps find tests more quickly in larger projects. + +### Command Line Interface + +When you run `npm test`, Jest will launch in the watch mode. Every time you save a file, it will re-run the tests, just like `npm start` recompiles the code. + +The watcher includes an interactive command-line interface with the ability to run all tests, or focus on a search pattern. It is designed this way so that you can keep it open and enjoy fast re-runs. You can learn the commands from the “Watch Usage” note that the watcher prints after every run: + +![Jest watch mode](http://facebook.github.io/jest/img/blog/15-watch.gif) + +### Version Control Integration + +By default, when you run `npm test`, Jest will only run the tests related to files changed since the last commit. This is an optimization designed to make your tests runs fast regardless of how many tests you have. However it assumes that you don’t often commit the code that doesn’t pass the tests. + +Jest will always explicitly mention that it only ran tests related to the files changed since the last commit. You can also press `a` in the watch mode to force Jest to run all tests. + +Jest will always run all tests on a [continuous integration](#continuous-integration) server or if the project is not inside a Git or Mercurial repository. + +### Writing Tests + +To create tests, add `it()` (or `test()`) blocks with the name of the test and its code. You may optionally wrap them in `describe()` blocks for logical grouping but this is neither required nor recommended. + +Jest provides a built-in `expect()` global function for making assertions. A basic test could look like this: + +```js +import sum from './sum'; + +it('sums numbers', () => { + expect(sum(1, 2)).toEqual(3); + expect(sum(2, 2)).toEqual(4); +}); +``` + +All `expect()` matchers supported by Jest are [extensively documented here](http://facebook.github.io/jest/docs/expect.html).
+You can also use [`jest.fn()` and `expect(fn).toBeCalled()`](http://facebook.github.io/jest/docs/expect.html#tohavebeencalled) to create “spies” or mock functions. + +### Testing Components + +There is a broad spectrum of component testing techniques. They range from a “smoke test” verifying that a component renders without throwing, to shallow rendering and testing some of the output, to full rendering and testing component lifecycle and state changes. + +Different projects choose different testing tradeoffs based on how often components change, and how much logic they contain. If you haven’t decided on a testing strategy yet, we recommend that you start with creating simple smoke tests for your components: + +```js +import React from 'react'; +import ReactDOM from 'react-dom'; +import App from './App'; + +it('renders without crashing', () => { + const div = document.createElement('div'); + ReactDOM.render(, div); +}); +``` + +This test mounts a component and makes sure that it didn’t throw during rendering. Tests like this provide a lot value with very little effort so they are great as a starting point, and this is the test you will find in `src/App.test.js`. + +When you encounter bugs caused by changing components, you will gain a deeper insight into which parts of them are worth testing in your application. This might be a good time to introduce more specific tests asserting specific expected output or behavior. + +If you’d like to test components in isolation from the child components they render, we recommend using [`shallow()` rendering API](http://airbnb.io/enzyme/docs/api/shallow.html) from [Enzyme](http://airbnb.io/enzyme/). You can write a smoke test with it too: + +```sh +npm install --save-dev enzyme react-test-renderer +``` + +```js +import React from 'react'; +import { shallow } from 'enzyme'; +import App from './App'; + +it('renders without crashing', () => { + shallow(); +}); +``` + +Unlike the previous smoke test using `ReactDOM.render()`, this test only renders `` and doesn’t go deeper. For example, even if `` itself renders a ` + } + { isReplyAllowed && +
  • + +
  • + } + +
    + ) +}; diff --git a/web/modules/forked/react_comments/js/src/src/components/CommentBox.css b/web/modules/forked/react_comments/js/src/src/components/CommentBox.css new file mode 100644 index 0000000..82fa0e9 --- /dev/null +++ b/web/modules/forked/react_comments/js/src/src/components/CommentBox.css @@ -0,0 +1,196 @@ +.rc_input { + resize: none; +} + +.rc_comment-box-container { + display: flex; + margin-bottom: 10px; +} + +.rc_is-loading .rc_input-wrapper { + filter: blur(2px); +} + +.rc_throbber-wrapper { + position: relative; +} + +.rc_input-outer-wrapper { + flex-grow: 1; + min-width: 200px; +} + +.rc_comment-box-container .ReactThrobber { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + display: flex; + align-items: center; + justify-content: center; +} + +.rc_comment-container .rc_is-reply { + margin-top: 20px; + margin-bottom: 0; +} + +.rc_comment-container .rc_is-edit { + margin-bottom: 0; +} + +.rc_input-wrapper { + display: flex; + flex-direction: column; + flex-grow: 1; + border: 2px solid #dbdfe4; + border-radius: 6px; + font-size: 16px; + margin: 0; + min-height: 48px; + transition: min-height 175ms linear; +} + +.rc_is-open .rc_input-wrapper { + min-height: 100px; + overflow: hidden; +} + +.rc_input-wrapper .DraftEditor-root, +.rc_input-wrapper .DraftEditor-editorContainer { + flex-grow: 1; + display: flex; +} + +.rc_input-wrapper .public-DraftEditorPlaceholder-root { + position: absolute; + padding: 10px; + font-size: 18px; + color: #7f919e; +} + +.rc_input-wrapper .DraftEditor-editorContainer { + position: relative; + padding: 10px; +} + +.rc_input-wrapper .public-DraftEditor-content { + flex-grow: 1; +} + +.rc_input-wrapper .rc_input-actions { + opacity: 0; + height: 0; + transition: all 175ms linear; + display: flex; + justify-content: flex-end; + overflow: hidden; +} + +.rc_is-open .rc_input-actions { + opacity: 1; + height: 25px; + background: #eee; + border-top: 2px solid #dbdfe4; + flex-shrink: 0; +} + +.rc_is-open .rc_input-actions button { + border: 0; + height: 100%; +} + +.rc_login-button { + display: flex; + align-items: center; + justify-content: center; + text-decoration: none; + padding: 5px; + height: 30px; + border: 2px solid #0A76B7; + background: #0A76B7; + border-radius: 5px; + flex-grow: 0; + color: white; + white-space: nowrap; + width: 200px; + align-self: flex-start; + font-size: 12px; +} + +.rc_login-button:hover { + background-color: #0a81c7; + color: white; +} + +.rc_anon-wrapper { + width: 100%; + display: flex; + margin-top: 10px; + flex-wrap: wrap; +} + +.rc_anon-wrapper > div { + margin: 0 10px 10px 0; +} + +.rc_anon-wrapper label { + text-transform: uppercase; + font-size: 10px; + font-family: sans-serif; +} + +.rc_anon-form { +} + +.rc_anon-form-input-wrapper { + display: flex; + justify-content: space-between; +} + +.rc_anon-form input { + display: block; + border: 2px solid #dbdfe4; + border-radius: 4px; + padding: 5px; + width: 200px; + height: 30px; + margin: 0 10px 0 0; +} +.rc_anon-form input:first-child { + margin-bottom: 5px; +} + +.rc_comment-box-avatar { + margin-right: 10px; + flex-shrink: 0; +} + +.rc_comment-box-avatar img { + width: 48px; + height: 48px; +} + +.rc_message { + padding: 5px 10px; + margin: 2px 0 5px 0; + border-radius: 4px; +} + +.rc_message-only .rc_input-wrapper, +.rc_message-only .rc_anon-wrapper { + display:none; +} + +.rc_message-type--error { + color: #D8000C; + border: 1px solid rgba(216, 0, 12, 0.23); + background-color: #FFBABA; +} + +.rc_message-type--success { + color: #0cab0c; + border: 1px solid rgba(0, 216, 3, 0.23); + background-color: #baffba; +} \ No newline at end of file diff --git a/web/modules/forked/react_comments/js/src/src/components/CommentBox.js b/web/modules/forked/react_comments/js/src/src/components/CommentBox.js new file mode 100644 index 0000000..c913ffa --- /dev/null +++ b/web/modules/forked/react_comments/js/src/src/components/CommentBox.js @@ -0,0 +1,259 @@ +import React, { Component } from 'react'; +import './CommentBox.css'; +import Throbber from 'react-throbber'; +import ReactQuill from 'react-quill'; +import 'react-quill/dist/quill.snow.css'; +import Constants from '../utils/constants'; +import validateEmail from '../utils/validateEmail'; +import DOMPurify from 'dompurify'; + +// Limit chat max characters. +const MAX_LENGTH = 300; + +class CommentBox extends Component { + state = { + isOpen: false, + isFocused: false, + isLoading: false, + message: false, + messageOnly: false, + anonName: false, + anonEmail: false, + text: (this.props.type === 'edit') ? this.props.text.replace(/\r\n?|\n/g, '
    ') : '' + }; + + getLoginLink = () => { + return `/user/login?destination=${encodeURIComponent(window.location.pathname)}%23comments-app-container`; + }; + + toggleFocus = () => { + this.setState({ + isFocused: !this.state.isFocused, + isOpen: !this.state.isOpen + }); + }; + + getCommentText = () => { + // Trim the default text (non html) to evaluate if this is empty. + return DOMPurify.sanitize(this.commentBox.getEditor().getText()).trim(); + }; + + validateCommentLength = () => { + if (this.getCommentText().length <= MAX_LENGTH) { + this.setState({message: false}); + return true; + } + + this.setState({ + message: { + message: window.Drupal.t('Your comment is too long (it can only be @max characters long). Current characters count: @current', {'@max': MAX_LENGTH, '@current': this.getCommentText().length}), + type: 'error' + }, + }); + + return false; + }; + + postComment = (commentText) => { + if (this.state.isLoading) return; + + if (!this.userCanPost()) return; + + if (!this.validateCommentLength()) return; + + this.setState({ isLoading: true, message: false }); + this.props.postComment(commentText, this.state.anonName, this.state.anonEmail).then((response) => { + + if (response.code === 'success') { + this.setState({ + isLoading: false, + text: '', + }); + } + else if (response.code === 'queued_for_moderation') { + this.setState({ + message: { + message: response.message, + type: 'success' + }, + isLoading: false, + text: '', + }); + } + }).catch((error) => { + const message = { + message: error.message, + type: 'error' + }; + this.setState({ isLoading: false, message: message }); + }); + }; + + postReply = (commentText) => { + if (this.state.isLoading) return; + + if (!this.userCanPost()) return; + + if (!this.validateCommentLength()) return; + + this.setState({ isLoading: true, message: false }); + this.props.postReply(commentText, this.state.anonName, this.state.anonEmail).then((response) => { + if (response.code === 'success') { + this.setState({ isOpen: false, message: false }); + this.props.closeReplyBox(); + } + else if (response.code === 'queued_for_moderation') { + const message = { + message: response.message, + type: 'success' + }; + this.setState({ message: message, messageOnly: true, isLoading: false }); + } + }).catch((error) => { + const message = { + message: error.message, + type: 'error' + }; + this.setState({ isLoading: false, message: message }); + }); + }; + + saveEdit = (commentText) => { + if (this.state.isLoading) return; + + if (!this.userCanPost()) return; + + this.setState({ isLoading: true, message: false }); + this.props.saveEdit(commentText).then(() => { + this.props.cancelEdit(); + }).catch((error) => { + const message = { + message: error.message, + type: 'error' + }; + this.setState({ isLoading: false, message: message }); + }); + }; + + userCanPost = () => { + const {user, settings} = this.props; + const isAnon = user && user.isAnon; + const anonSetting = settings.anonymous; + + if (isAnon && !this.state.anonName) { + this.setState({ message: { message: window.Drupal.t('Please provide your name or alias to post as a guest'), type: 'error'}}); + return false; + } + else if (isAnon && !this.state.anonEmail && (anonSetting === Constants.anonMustContact)) { + this.setState({ message: { message: window.Drupal.t('Please provide your email to post as a guest'), type: 'error'}}); + return false; + } + else if (isAnon && this.state.anonEmail && !validateEmail(this.state.anonEmail)) { + this.setState({ message: { message: window.Drupal.t('Please provide a valid email address'), type: 'error'}}); + return false; + } + else { + return true; + } + }; + + handleAnonFormChange = (e) => { + if (e.target.value && e.target.id === 'rc_name') { + this.setState({anonName: e.target.value}); + } + else if (e.target.value && e.target.id === 'rc_email') { + this.setState({anonEmail: e.target.value}); + } + else if (e.target.id === 'rc_name') { + this.setState({anonName: false}); + } + else { + this.setState({anonEmail: false}); + } + }; + + componentDidMount() { + if (this.props.user && this.props.type === 'reply') { + const x = window.scrollX; + const y = window.scrollY; + this.commentBox.focus(); + window.scrollTo(x, y); + } + } + + render() { + const { user, settings, type, cancelEdit } = this.props; + const { isOpen, isFocused, isLoading, message, messageOnly, text } = this.state; + + let containerClasses = ['rc_comment-box-container']; + if (isOpen || type === 'reply' || type === 'edit' ) containerClasses.push('rc_is-open'); + if (isLoading) containerClasses.push('rc_is-loading'); + if (messageOnly) containerClasses.push('rc_message-only'); + if (type === 'reply') containerClasses.push('rc_is-reply'); + if (type === 'edit') containerClasses.push('rc_is-edit'); + containerClasses = containerClasses.join(' '); + + const showLoginButton = !user || user.isAnon; + const userCanPostComments = user && user.hasPermission('post comments'); + + return ( +
    + { type !== 'edit' && +
    +
    + {window.Drupal.t('User +
    +
    + } +
    + { message &&
    {message.message}
    } +
    + { isLoading && } +
    + this.commentBox = commentBox} + onChange={(text) => this.setState({ text }, () => this.validateCommentLength())} + onFocus={this.toggleFocus} + onBlur={this.toggleFocus} + modules={{toolbar: false}} + /> +
    + { type === 'edit' && + + + + + } + { (type === 'reply' && user && userCanPostComments) && } + { (type === 'comment' && user && userCanPostComments) && } +
    +
    +
    + + { showLoginButton &&
    +
    + + {window.Drupal.t('Log in')} +
    + { userCanPostComments &&
    +
    + +
    + + { (settings.anonymous !== Constants.anonMayNotContact) && + + } +
    +
    +
    } +
    } +
    +
    + ); + } +} + +export default CommentBox; diff --git a/web/modules/forked/react_comments/js/src/src/components/CommentMenu.js b/web/modules/forked/react_comments/js/src/src/components/CommentMenu.js new file mode 100644 index 0000000..264b699 --- /dev/null +++ b/web/modules/forked/react_comments/js/src/src/components/CommentMenu.js @@ -0,0 +1,46 @@ +import React, { Component } from 'react'; +import ReactDOM from 'react-dom'; +import Caret from '../icons/caret-down'; + +class CommentMenu extends Component { + + documentClick = (e) => { + const menu = ReactDOM.findDOMNode(this.refs.menu); + const toggle = ReactDOM.findDOMNode(this.refs.toggle); + + if (menu && toggle && !menu.contains(e.target) && this.props.id === this.props.openMenu && !toggle.contains(e.target)) { + this.props.toggleMenu(this.props.id); + } + }; + + componentWillMount() { + document.addEventListener('click', this.documentClick, false); + } + + componentWillUnmount() { + document.removeEventListener('click', this.documentClick, false); + } + + render() { + const {user, currentUser, id, openMenu, closeMenu, toggleMenu, deleteComment, publishComment, unpublishComment, published} = this.props; + const userCanDeleteComment = currentUser && !currentUser.isAnon && currentUser.hasPermission('edit own comments') && (user.id === currentUser.id); + const userCanAdministerComments = currentUser && currentUser.hasPermission('administer comments'); + + return (userCanAdministerComments || userCanDeleteComment) && ( +
    +
    { e.preventDefault(); toggleMenu(id);}}>
    +
      + { (userCanAdministerComments && (published === '0')) &&
    • {publishComment(id); closeMenu();}}>{window.Drupal.t('Publish')}
    • } + { (userCanAdministerComments && (published === '1')) &&
    • {unpublishComment(id); closeMenu();}}>{window.Drupal.t('Unpublish')}
    • } + { (userCanAdministerComments || userCanDeleteComment) &&
    • {deleteComment(id); closeMenu();}}>{window.Drupal.t('Delete')}
    • } +
    +
    + ); + } + +} + +export default CommentMenu; diff --git a/web/modules/forked/react_comments/js/src/src/components/DeletedComment.js b/web/modules/forked/react_comments/js/src/src/components/DeletedComment.js new file mode 100644 index 0000000..40a4817 --- /dev/null +++ b/web/modules/forked/react_comments/js/src/src/components/DeletedComment.js @@ -0,0 +1,29 @@ +import React from 'react'; +import ReplyList from './ReplyList'; +import Constants from '../utils/constants'; + +export default (props) => { + const { user } = props; + return ( +
    +
    +
    +
    + {window.Drupal.t('User +
    +
    +
    +
    + {window.Drupal.t('This comment has been deleted.')} +
    +
    +
    + { props.replies && + + } +
    + ); +}; diff --git a/web/modules/forked/react_comments/js/src/src/components/ReplyList.js b/web/modules/forked/react_comments/js/src/src/components/ReplyList.js new file mode 100644 index 0000000..055de8c --- /dev/null +++ b/web/modules/forked/react_comments/js/src/src/components/ReplyList.js @@ -0,0 +1,33 @@ +import React from 'react'; +import Comment from './Comment'; + +export default ({ currentUser, settings, level, replies, replyTo, saveEdit, postReply, vote, toggleMenu, openMenu, flagComment, publishComment, unpublishComment, deleteComment }) => { + // stop nesting on the 2th level (zero indexed) + const REPLY_LEVEL_ALLOWED = 1; + const isReplyAllowed = (REPLY_LEVEL_ALLOWED - 1 > level); + const containerClasses = (level >= REPLY_LEVEL_ALLOWED) ? 'rc_replies rc_reply--max-level' : 'rc_replies'; + + return ( +
    + {replies.map((reply, i) => { + return + })} +
    + ) +}; diff --git a/web/modules/forked/react_comments/js/src/src/icons/caret-down.js b/web/modules/forked/react_comments/js/src/src/icons/caret-down.js new file mode 100644 index 0000000..dd573bd --- /dev/null +++ b/web/modules/forked/react_comments/js/src/src/icons/caret-down.js @@ -0,0 +1,15 @@ +import React from 'react'; + +export default () => { + return ( + + + + ); +}; + + + + + + diff --git a/web/modules/forked/react_comments/js/src/src/icons/chevron-up.js b/web/modules/forked/react_comments/js/src/src/icons/chevron-up.js new file mode 100644 index 0000000..f41d5e1 --- /dev/null +++ b/web/modules/forked/react_comments/js/src/src/icons/chevron-up.js @@ -0,0 +1,9 @@ +import React from 'react'; + +export default () => { + return ( + + + + ); +}; diff --git a/web/modules/forked/react_comments/js/src/src/icons/reply-arrow.js b/web/modules/forked/react_comments/js/src/src/icons/reply-arrow.js new file mode 100644 index 0000000..0e7f154 --- /dev/null +++ b/web/modules/forked/react_comments/js/src/src/icons/reply-arrow.js @@ -0,0 +1,9 @@ +import React from 'react'; + +export default () => { + return ( + + + + ); +}; diff --git a/web/modules/forked/react_comments/js/src/src/index.css b/web/modules/forked/react_comments/js/src/src/index.css new file mode 100644 index 0000000..e69de29 diff --git a/web/modules/forked/react_comments/js/src/src/index.js b/web/modules/forked/react_comments/js/src/src/index.js new file mode 100644 index 0000000..83bfa65 --- /dev/null +++ b/web/modules/forked/react_comments/js/src/src/index.js @@ -0,0 +1,15 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import App from './App'; +// import registerServiceWorker from './registerServiceWorker'; +import './index.css'; +import api from './utils/api'; + +const appContainer = document.getElementById(api.getAppContainerId()); + +if (appContainer) { + ReactDOM.render(, appContainer); +} + +window.renderComments = () => ReactDOM.render(, document.getElementById('comments-app-container')); +// registerServiceWorker(); diff --git a/web/modules/forked/react_comments/js/src/src/registerServiceWorker.js b/web/modules/forked/react_comments/js/src/src/registerServiceWorker.js new file mode 100644 index 0000000..9966897 --- /dev/null +++ b/web/modules/forked/react_comments/js/src/src/registerServiceWorker.js @@ -0,0 +1,51 @@ +// In production, we register a service worker to serve assets from local cache. + +// This lets the app load faster on subsequent visits in production, and gives +// it offline capabilities. However, it also means that developers (and users) +// will only see deployed updates on the "N+1" visit to a page, since previously +// cached resources are updated in the background. + +// To learn more about the benefits of this model, read https://goo.gl/KwvDNy. +// This link also includes instructions on opting out of this behavior. + +export default function register() { + if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { + window.addEventListener('load', () => { + const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; + navigator.serviceWorker + .register(swUrl) + .then(registration => { + registration.onupdatefound = () => { + const installingWorker = registration.installing; + installingWorker.onstatechange = () => { + if (installingWorker.state === 'installed') { + if (navigator.serviceWorker.controller) { + // At this point, the old content will have been purged and + // the fresh content will have been added to the cache. + // It's the perfect time to display a "New content is + // available; please refresh." message in your web app. + console.log('New content is available; please refresh.'); + } else { + // At this point, everything has been precached. + // It's the perfect time to display a + // "Content is cached for offline use." message. + console.log('Content is cached for offline use.'); + } + } + }; + }; + }) + .catch(error => { + console.error('Error during service worker registration:', error); + }); + }); + } +} + +export function unregister() { + if ('serviceWorker' in navigator) { + navigator.serviceWorker.ready.then(registration => { + registration.unregister(); + }); + } +} diff --git a/web/modules/forked/react_comments/js/src/src/utils/api.js b/web/modules/forked/react_comments/js/src/src/utils/api.js new file mode 100644 index 0000000..ee5472b --- /dev/null +++ b/web/modules/forked/react_comments/js/src/src/utils/api.js @@ -0,0 +1,174 @@ +import axios from 'axios'; + +const debug = (process.env.NODE_ENV === 'development'); + +export default class Api { + static getApiBaseUrl() { + return debug ? window.commentsApiBaseUrl : window.location.origin; + } + + static createCsrfPromise() { + return axios.get(`${this.getApiBaseUrl()}/session/token`, {withCredentials: true}) + .then((response) => { + return response.data; + }).catch((err) => { + throw new Error(this.formatErrorMessage(err)); + }); + } + + static getAppContainerId() { + return 'comments-app-container'; + } + + static getComments() { + return axios.get(`${this.getApiBaseUrl()}/react-comments/comments/${window.commentsAppNid}?_format=json`, {withCredentials: true}).catch((err) => { + throw new Error(this.formatErrorMessage(err)); + }); + } + + static getMe() { + return axios.get(`${this.getApiBaseUrl()}/react-comments/me?_format=json`, {withCredentials: true}).catch((err) => { + throw new Error(this.formatErrorMessage(err)); + }); + } + + static postComment(commentText, anonName, anonEmail) { + if (!commentText || !commentText.trim()) { + return Promise.reject({message: window.Drupal.t('Comments cannot be empty.')}); + } + + return this.createCsrfPromise() + .then((csrf) => { + return axios({ + method: 'post', + headers: {'X-CSRF-Token': csrf}, + url: `${this.getApiBaseUrl()}/react-comments/comments/${window.commentsAppNid}?_format=json`, + data: { + reply_comment_id: 0, + comment: commentText, + anon_name: anonName, + anon_email: anonEmail + }, + withCredentials: true + }) + }).then((response) => { + return response.data; + }).catch((err) => { + throw new Error(this.formatErrorMessage(err)); + }); + } + + static postReply(commentId, commentText, anonName, anonEmail) { + if (!commentText || !commentText.trim()) { + return Promise.reject({message: window.Drupal.t('Comments cannot be empty.')}); + } + + return this.createCsrfPromise() + .then((csrf) => { + return axios({ + method: 'post', + headers: {'X-CSRF-Token': csrf}, + url: `${this.getApiBaseUrl()}/react-comments/comments/${window.commentsAppNid}?_format=json`, + data: { + reply_comment_id: commentId, + comment: commentText, + anon_name: anonName, + anon_email: anonEmail + }, + withCredentials: true + }); + }).then((response) => { + return response.data; + }).catch((err) => { + throw new Error(this.formatErrorMessage(err)); + }); + } + + static saveEdit(commentId, commentText) { + if (!commentText || !commentText.trim()) { + return Promise.reject({message: window.Drupal.t('Comments cannot be empty.')}); + } + + return this.createCsrfPromise() + .then((csrf) => { + return axios({ + method: 'patch', + headers: {'X-CSRF-Token': csrf}, + url: `${this.getApiBaseUrl()}/react-comments/comment/${commentId}?_format=json`, + data: { + comment: commentText + }, + withCredentials: true + }); + }).then((response) => { + return response.data; + }).catch((err) => { + throw new Error(this.formatErrorMessage(err)); + }); + } + + static deleteComment(commentId) { + return this.createCsrfPromise() + .then((csrf) => { + return axios({ + method: 'delete', + headers: {'X-CSRF-Token': csrf}, + data: { + '_format': 'json' + }, + url: `${this.getApiBaseUrl()}/react-comments/comment/${commentId}?_format=json`, + withCredentials: true + }); + }).then((response) => { + return response.data; + }).catch((err) => { + throw new Error(this.formatErrorMessage(err)); + }); + } + + static flagComment(commentId) { + return this.putComment(commentId, 'flag'); + } + + static publishComment(commentId) { + return this.putComment(commentId, 'publish'); + } + + static unpublishComment(commentId) { + return this.putComment(commentId, 'unpublish'); + } + + static putComment(commentId, op) { + return this.createCsrfPromise() + .then((csrf) => { + return axios({ + method: 'put', + headers: {'X-CSRF-Token': csrf}, + data: { + 'op': op + }, + url: `${this.getApiBaseUrl()}/react-comments/comment/${commentId}?_format=json`, + withCredentials: true + }); + }).then((response) => { + return response.data; + }).catch((err) => { + throw new Error(this.formatErrorMessage(err)); + }); + } + + static formatErrorMessage(err) { + if (err.response && err.response.data && err.response.data.message) { + return err.response.data.message; + } + + // Axios will return the hard-coded string "Network Error" if there is an + // error processing the request. + // (see https://github.com/axios/axios/blob/9a78465a9268dcd360d7663de686709a68560d3d/lib/adapters/xhr.js#L81) + if (err.message === 'Network Error') { + return 'Your Internet connection appears to be offline. Check your network settings and try again.'; + } + + return err.message; + } +} diff --git a/web/modules/forked/react_comments/js/src/src/utils/constants.js b/web/modules/forked/react_comments/js/src/src/utils/constants.js new file mode 100644 index 0000000..18f73ee --- /dev/null +++ b/web/modules/forked/react_comments/js/src/src/utils/constants.js @@ -0,0 +1,16 @@ +export default { + // api codes + 'unpublished' : '0', + 'published' : '1', + 'flagged' : '2', + 'deleted' : '3', + 'flaggedUnpublished' : '4', + + // comment field settings + 'anonMayNotContact' : 0, + 'anonMayContact' : 1, + 'anonMustContact' : 2, + + // misc + 'defaultAvatarUrl' : 'https://c.disquscdn.com/uploads/users/3645/2480/avatar92.jpg?1390235270' +} diff --git a/web/modules/forked/react_comments/js/src/src/utils/findCommentByIdRecursive.js b/web/modules/forked/react_comments/js/src/src/utils/findCommentByIdRecursive.js new file mode 100644 index 0000000..d18875d --- /dev/null +++ b/web/modules/forked/react_comments/js/src/src/utils/findCommentByIdRecursive.js @@ -0,0 +1,13 @@ +export default function findCommentByIdRecursive(id, commentTree) { + let result = null; + commentTree.forEach(function(el, i) { + if (el.id === id) { + result = el; + } + else if (el.replies) { + el = findCommentByIdRecursive(id, el.replies); + if (el) result = el; + } + }); + return result; +}; diff --git a/web/modules/forked/react_comments/js/src/src/utils/validateEmail.js b/web/modules/forked/react_comments/js/src/src/utils/validateEmail.js new file mode 100644 index 0000000..d1f1ecb --- /dev/null +++ b/web/modules/forked/react_comments/js/src/src/utils/validateEmail.js @@ -0,0 +1,4 @@ +export default function validateEmail(email) { + var re = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; + return re.test(email); +}; \ No newline at end of file diff --git a/web/modules/forked/react_comments/js/src/yarn.lock b/web/modules/forked/react_comments/js/src/yarn.lock new file mode 100644 index 0000000..6a3b7ae --- /dev/null +++ b/web/modules/forked/react_comments/js/src/yarn.lock @@ -0,0 +1,8804 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/runtime@^7.1.2": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.7.tgz#03ff99f64106588c9c403c6ecb8c3bafbbdff1fa" + integrity sha512-9E9FJowqAsytyOY6LG+1KuueckRL+aQW+mKvXRXnuFGyRAyepJPmEo9vgMfXUA6O9u3IeEdv9MAkppFcaQwogQ== + dependencies: + regenerator-runtime "^0.13.4" + +"@types/jquery@^2.0.40": + version "2.0.60" + resolved "https://registry.yarnpkg.com/@types/jquery/-/jquery-2.0.60.tgz#64d93c39f4c3ace0352081f31140cdbe803a7ddd" + integrity sha512-izi6OBEVrAwaHiqWITjOPBbVtcKZKAXTocJqPZsAKA2lvmbpFEyPSAxgcqmisbiMYj9EvrooUEPLHQeQqVMWAg== + +"@types/quill@1.3.10": + version "1.3.10" + resolved "https://registry.yarnpkg.com/@types/quill/-/quill-1.3.10.tgz#dc1f7b6587f7ee94bdf5291bc92289f6f0497613" + integrity sha512-IhW3fPW+bkt9MLNlycw8u8fWb7oO7W5URC9MfZYHBlA24rex9rs23D5DETChu1zvgVdc5ka64ICjJOgQMr6Shw== + dependencies: + parchment "^1.1.2" + +abab@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.4.tgz#5faad9c2c07f60dd76770f71cf025b62a63cfd4e" + integrity sha1-X6rZwsB/YN12dw9xzwJbYqY8/U4= + +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + +accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: + version "1.3.7" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" + integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== + dependencies: + mime-types "~2.1.24" + negotiator "0.6.2" + +acorn-dynamic-import@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz#c752bd210bef679501b6c6cb7fc84f8f47158cc4" + integrity sha1-x1K9IQvvZ5UBtsbLf8hPj0cVjMQ= + dependencies: + acorn "^4.0.3" + +acorn-globals@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-3.1.0.tgz#fd8270f71fbb4996b004fa880ee5d46573a731bf" + integrity sha1-/YJw9x+7SZawBPqIDuXUZXOnMb8= + dependencies: + acorn "^4.0.4" + +acorn-jsx@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" + integrity sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s= + dependencies: + acorn "^3.0.4" + +acorn@^3.0.4: + version "3.3.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" + integrity sha1-ReN/s56No/JbruP/U2niu18iAXo= + +acorn@^4.0.3, acorn@^4.0.4: + version "4.0.13" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787" + integrity sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c= + +acorn@^5.0.0, acorn@^5.5.0: + version "5.7.4" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.4.tgz#3e8d8a9947d0599a1796d10225d7432f4a4acf5e" + integrity sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg== + +address@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/address/-/address-1.0.2.tgz#480081e82b587ba319459fef512f516fe03d58af" + integrity sha1-SACB6CtYe6MZRZ/vUS9Rb+A9WK8= + +address@^1.0.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6" + integrity sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA== + +ajv-keywords@^1.0.0, ajv-keywords@^1.1.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c" + integrity sha1-MU3QpLM2j609/NxU7eYXG4htrzw= + +ajv-keywords@^3.1.0: + version "3.5.2" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== + +ajv@^4.11.2, ajv@^4.7.0, ajv@^4.9.1: + version "4.11.8" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536" + integrity sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY= + dependencies: + co "^4.6.0" + json-stable-stringify "^1.0.1" + +ajv@^6.1.0, ajv@^6.12.3: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + 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" + +align-text@^0.1.1, align-text@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" + integrity sha1-DNkKVhCT810KmSVsIrcGlDP60Rc= + dependencies: + kind-of "^3.0.2" + longest "^1.0.1" + repeat-string "^1.5.2" + +alphanum-sort@^1.0.1, alphanum-sort@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" + integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM= + +anser@1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/anser/-/anser-1.4.1.tgz#c3641863a962cebef941ea2c8706f2cb4f0716bd" + integrity sha1-w2QYY6lizr75Qeoshwbyy08HFr0= + +ansi-align@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f" + integrity sha1-w2rsy6VjuJzrVW82kPCx2eNUf38= + dependencies: + string-width "^2.0.0" + +ansi-escapes@^1.1.0, ansi-escapes@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" + integrity sha1-06ioOzGapneTZisT52HHkRQiMG4= + +ansi-escapes@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-2.0.0.tgz#5bae52be424878dd9783e8910e3fc2922e83c81b" + integrity sha1-W65SvkJIeN2Xg+iRDj/Cki6DyBs= + +ansi-html@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e" + integrity sha1-gTWEAhliqenm/QOflA0S9WynhZ4= + +ansi-regex@^2.0.0, ansi-regex@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= + +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.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= + +ansi-styles@^3.0.0, ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +anymatch@^1.3.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a" + integrity sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA== + dependencies: + micromatch "^2.1.5" + normalize-path "^2.0.0" + +anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + +anymatch@~3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +append-transform@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-0.4.0.tgz#d76ebf8ca94d276e247a36bad44a4b74ab611991" + integrity sha1-126/jKlNJ24keja61EpLdKthGZE= + dependencies: + default-require-extensions "^1.0.0" + +aproba@^1.0.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + +are-we-there-yet@~1.1.2: + version "1.1.7" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz#b15474a932adab4ff8a50d9adfa7e4e926f21146" + 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.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +aria-query@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-0.5.0.tgz#85e3152cd8cc5bab18dbed61cd9c4fce54fa79c3" + integrity sha1-heMVLNjMW6sY2+1hzZxPzlT6ecM= + dependencies: + ast-types-flow "0.0.7" + +arr-diff@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" + integrity sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8= + dependencies: + arr-flatten "^1.0.1" + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= + +arr-flatten@^1.0.1, arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= + +array-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" + integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM= + +array-filter@~0.0.0: + version "0.0.1" + resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec" + integrity sha1-fajPLiZijtcygDWB/SH2fKzS7uw= + +array-find-index@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" + integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E= + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= + +array-includes@^3.0.3: + version "3.1.4" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.4.tgz#f5b493162c760f3539631f005ba2bb46acb45ba9" + integrity sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.1" + get-intrinsic "^1.1.1" + is-string "^1.0.7" + +array-map@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/array-map/-/array-map-0.0.0.tgz#88a2bab73d1cf7bcd5c1b118a003f66f665fa662" + integrity sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI= + +array-reduce@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/array-reduce/-/array-reduce-0.0.0.tgz#173899d3ffd1c7d9383e4479525dbe278cab5f2b" + integrity sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys= + +array-union@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= + dependencies: + array-uniq "^1.0.1" + +array-uniq@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= + +array-unique@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" + integrity sha1-odl8yvy8JiXMcPrc6zalDFiwGlM= + +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= + +arrify@^1.0.0, arrify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= + +asap@~2.0.3: + version "2.0.6" + resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" + integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= + +asn1.js@^5.2.0: + version "5.4.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-5.4.1.tgz#11a980b84ebb91781ce35b0fdc2ee294e3783f07" + integrity sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA== + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + safer-buffer "^2.1.0" + +asn1@~0.2.3: + version "0.2.6" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d" + 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.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= + +assert-plus@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" + integrity sha1-104bh+ev/A24qttwIfP+SBAasjQ= + +assert@^1.1.1: + version "1.5.0" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb" + integrity sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA== + dependencies: + object-assign "^4.1.1" + util "0.10.3" + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= + +ast-types-flow@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad" + integrity sha1-9wtzXGvKGlycItmCw+Oef+ujva0= + +async-each@^1.0.0, async-each@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" + integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== + +async@^2.1.2, async@^2.1.4, async@^2.6.2: + version "2.6.3" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" + integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== + dependencies: + lodash "^4.17.14" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + +atob@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + +autoprefixer@7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-7.1.0.tgz#ae4913adc221fa6ca5ad3a6f8039f6a5c06b3877" + integrity sha1-rkkTrcIh+mylrTpvgDn2pcBrOHc= + dependencies: + browserslist "^2.1.2" + caniuse-lite "^1.0.30000669" + normalize-range "^0.1.2" + num2fraction "^1.2.2" + postcss "^6.0.1" + postcss-value-parser "^3.2.3" + +autoprefixer@^6.3.1: + version "6.7.7" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-6.7.7.tgz#1dbd1c835658e35ce3f9984099db00585c782014" + integrity sha1-Hb0cg1ZY41zj+ZhAmdsAWFx4IBQ= + dependencies: + browserslist "^1.7.6" + caniuse-db "^1.0.30000634" + normalize-range "^0.1.2" + num2fraction "^1.2.2" + postcss "^5.2.16" + postcss-value-parser "^3.2.3" + +aws-sign2@~0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" + integrity sha1-FDQt0428yU0OW4fXY81jYSwOeU8= + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= + +aws4@^1.2.1, aws4@^1.8.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" + integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== + +axios@^0.16.2: + version "0.16.2" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.16.2.tgz#ba4f92f17167dfbab40983785454b9ac149c3c6d" + integrity sha1-uk+S8XFn37q0CYN4VFS5rBScPG0= + dependencies: + follow-redirects "^1.2.3" + is-buffer "^1.1.5" + +axobject-query@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-0.1.0.tgz#62f59dbc59c9f9242759ca349960e7a2fe3c36c0" + integrity sha1-YvWdvFnJ+SQnWco0mWDnov48NsA= + dependencies: + ast-types-flow "0.0.7" + +babel-code-frame@6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.22.0.tgz#027620bee567a88c32561574e7fd0801d33118e4" + integrity sha1-AnYgvuVnqIwyVhV05/0IAdMxGOQ= + dependencies: + chalk "^1.1.0" + esutils "^2.0.2" + js-tokens "^3.0.0" + +babel-code-frame@^6.11.0, babel-code-frame@^6.16.0, babel-code-frame@^6.22.0, babel-code-frame@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" + integrity sha1-Y/1D99weO7fONZR9uP42mj9Yx0s= + dependencies: + chalk "^1.1.3" + esutils "^2.0.2" + js-tokens "^3.0.2" + +babel-core@6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.24.1.tgz#8c428564dce1e1f41fb337ec34f4c3b022b5ad83" + integrity sha1-jEKFZNzh4fQfszfsNPTDsCK1rYM= + dependencies: + babel-code-frame "^6.22.0" + babel-generator "^6.24.1" + babel-helpers "^6.24.1" + babel-messages "^6.23.0" + babel-register "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + babylon "^6.11.0" + convert-source-map "^1.1.0" + debug "^2.1.1" + json5 "^0.5.0" + lodash "^4.2.0" + minimatch "^3.0.2" + path-is-absolute "^1.0.0" + private "^0.1.6" + slash "^1.0.0" + source-map "^0.5.0" + +babel-core@^6.0.0, babel-core@^6.26.0: + version "6.26.3" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207" + 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-eslint@7.2.3: + version "7.2.3" + resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-7.2.3.tgz#b2fe2d80126470f5c19442dc757253a897710827" + integrity sha1-sv4tgBJkcPXBlELcdXJTqJdxCCc= + dependencies: + babel-code-frame "^6.22.0" + babel-traverse "^6.23.1" + babel-types "^6.23.0" + babylon "^6.17.0" + +babel-generator@^6.18.0, babel-generator@^6.24.1, babel-generator@^6.26.0: + version "6.26.1" + resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" + 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.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" + integrity sha1-zORReto1b0IgvK6KAsKzRvmlZmQ= + dependencies: + babel-helper-explode-assignable-expression "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-builder-react-jsx@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.26.0.tgz#39ff8313b75c8b65dceff1f31d383e0ff2a408a0" + integrity sha1-Of+DE7dci2Xc7/HzHTg+D/KkCKA= + dependencies: + babel-runtime "^6.26.0" + babel-types "^6.26.0" + esutils "^2.0.2" + +babel-helper-call-delegate@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" + integrity sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340= + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-define-map@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" + integrity sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8= + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-helper-explode-assignable-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" + integrity sha1-8luCz33BBDPFX3BZLVdGQArCLKo= + 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.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" + integrity sha1-00dbjAPtmCQqJbSDUasYOZ01gKk= + dependencies: + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-get-function-arity@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" + integrity sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0= + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-hoist-variables@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" + integrity sha1-HssnaJydJVE+rbyZFKc/VAi+enY= + 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.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" + integrity sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc= + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-regex@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" + integrity sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI= + dependencies: + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-helper-remap-async-to-generator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" + integrity sha1-XsWBgnrXI/7N04HxySg5BnbkVRs= + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-replace-supers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" + integrity sha1-v22/5Dk40XNpohPKiov3S2qQqxo= + dependencies: + babel-helper-optimise-call-expression "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helpers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" + integrity sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI= + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-jest@20.0.3, babel-jest@^20.0.3: + version "20.0.3" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-20.0.3.tgz#e4a03b13dc10389e140fc645d09ffc4ced301671" + integrity sha1-5KA7E9wQOJ4UD8ZF0J/8TO0wFnE= + dependencies: + babel-core "^6.0.0" + babel-plugin-istanbul "^4.0.0" + babel-preset-jest "^20.0.3" + +babel-loader@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-7.0.0.tgz#2e43a66bee1fff4470533d0402c8a4532fafbaf7" + integrity sha1-LkOma+4f/0RwUz0EAsikUy+vuvc= + dependencies: + find-cache-dir "^0.1.1" + loader-utils "^1.0.2" + mkdirp "^0.5.1" + +babel-messages@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" + integrity sha1-8830cDhYA1sqKVHG7F7fbGLyYw4= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-check-es2015-constants@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" + integrity sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-dynamic-import-node@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-1.1.0.tgz#bd1d88ac7aaf98df4917c384373b04d971a2b37a" + integrity sha512-tTfZbM9Ecwj3GK50mnPrUpinTwA4xXmDiQGCk/aBYbvl1+X8YqldK86wZ1owVJ4u3mrKbRlXMma80J18qwiaTQ== + dependencies: + babel-plugin-syntax-dynamic-import "^6.18.0" + babel-template "^6.26.0" + babel-types "^6.26.0" + +babel-plugin-istanbul@^4.0.0: + version "4.1.6" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.6.tgz#36c59b2192efce81c5b378321b74175add1c9a45" + integrity sha512-PWP9FQ1AhZhS01T/4qLSKoHGY/xvkZdVBGlKM/HuxxS3+sC66HhTNR7+MpbO/so/cz/wY94MeSWJuP1hXIPfwQ== + dependencies: + babel-plugin-syntax-object-rest-spread "^6.13.0" + find-up "^2.1.0" + istanbul-lib-instrument "^1.10.1" + test-exclude "^4.2.1" + +babel-plugin-jest-hoist@^20.0.3: + version "20.0.3" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-20.0.3.tgz#afedc853bd3f8dc3548ea671fbe69d03cc2c1767" + integrity sha1-r+3IU70/jcNUjqZx++adA8wsF2c= + +babel-plugin-syntax-async-functions@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" + integrity sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU= + +babel-plugin-syntax-class-properties@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz#d7eb23b79a317f8543962c505b827c7d6cac27de" + integrity sha1-1+sjt5oxf4VDlixQW4J8fWysJ94= + +babel-plugin-syntax-dynamic-import@6.18.0, babel-plugin-syntax-dynamic-import@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz#8d6a26229c83745a9982a441051572caa179b1da" + integrity sha1-jWomIpyDdFqZgqRBBRVyyqF5sdo= + +babel-plugin-syntax-exponentiation-operator@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" + integrity sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4= + +babel-plugin-syntax-flow@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz#4c3ab20a2af26aa20cd25995c398c4eb70310c8d" + integrity sha1-TDqyCiryaqIM0lmVw5jE63AxDI0= + +babel-plugin-syntax-jsx@^6.3.13, babel-plugin-syntax-jsx@^6.8.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" + integrity sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY= + +babel-plugin-syntax-object-rest-spread@^6.13.0, babel-plugin-syntax-object-rest-spread@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" + integrity sha1-/WU28rzhODb/o6VFjEkDpZe7O/U= + +babel-plugin-syntax-trailing-function-commas@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" + integrity sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM= + +babel-plugin-transform-async-to-generator@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" + integrity sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E= + dependencies: + babel-helper-remap-async-to-generator "^6.24.1" + babel-plugin-syntax-async-functions "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-class-properties@6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz#6a79763ea61d33d36f37b611aa9def81a81b46ac" + integrity sha1-anl2PqYdM9NvN7YRqp3vgagbRqw= + dependencies: + babel-helper-function-name "^6.24.1" + babel-plugin-syntax-class-properties "^6.8.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-arrow-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" + integrity sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" + integrity sha1-u8UbSflk1wy42OC5ToICRs46YUE= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoping@^6.23.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" + integrity sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8= + 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.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" + integrity sha1-WkxYpQyclGHlZLSyo7+ryXolhNs= + 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.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" + integrity sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM= + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-destructuring@6.23.0, babel-plugin-transform-es2015-destructuring@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" + integrity sha1-mXux8auWf2gtKwh2/jWNYOdlxW0= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-duplicate-keys@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" + integrity sha1-c+s9MQypaePvnskcU3QabxV2Qj4= + 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.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" + integrity sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-function-name@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" + integrity sha1-g0yJhTvDaxrw86TF26qU/Y6sqos= + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-literals@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" + integrity sha1-T1SgLWzWbPkVKAAZox0xklN3yi4= + 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.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" + integrity sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ= + 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.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz#58a793863a9e7ca870bdc5a881117ffac27db6f3" + 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.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" + integrity sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM= + 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.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" + integrity sha1-rJl+YoXNGO1hdq22B9YCNErThGg= + 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.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" + integrity sha1-JM72muIcuDp/hgPa0CH1cusnj40= + 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.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" + integrity sha1-V6w1GrScrxSpfNE7CfZv3wpiXys= + 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.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" + integrity sha1-JPh11nIch2YbvZmkYi5R8U3jiqA= + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-spread@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" + integrity sha1-1taKmfia7cRTbIGlQujdnxdG+NE= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-sticky-regex@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" + integrity sha1-AMHNsaynERLN8M9hJsLta0V8zbw= + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-template-literals@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" + integrity sha1-qEs0UPfp+PH2g51taH2oS7EjbY0= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-typeof-symbol@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" + integrity sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-unicode-regex@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" + integrity sha1-04sS9C6nMj9yk4fxinxa4frrNek= + 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.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e" + integrity sha1-KrDJx/MJj6SJB3cruBP+QejeOg4= + 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-flow-strip-types@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz#84cb672935d43714fdc32bce84568d87441cf7cf" + integrity sha1-hMtnKTXUNxT9wyvOhFaNh0Qc988= + dependencies: + babel-plugin-syntax-flow "^6.18.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-object-rest-spread@6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz#0f36692d50fef6b7e2d4b3ac1478137a963b7b06" + integrity sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY= + dependencies: + babel-plugin-syntax-object-rest-spread "^6.8.0" + babel-runtime "^6.26.0" + +babel-plugin-transform-react-constant-elements@6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-constant-elements/-/babel-plugin-transform-react-constant-elements-6.23.0.tgz#2f119bf4d2cdd45eb9baaae574053c604f6147dd" + integrity sha1-LxGb9NLN1F65uqrldAU8YE9hR90= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-react-display-name@^6.23.0: + version "6.25.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.25.0.tgz#67e2bf1f1e9c93ab08db96792e05392bf2cc28d1" + integrity sha1-Z+K/Hx6ck6sI25Z5LgU5K/LMKNE= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-react-jsx-self@6.22.0, babel-plugin-transform-react-jsx-self@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx-self/-/babel-plugin-transform-react-jsx-self-6.22.0.tgz#df6d80a9da2612a121e6ddd7558bcbecf06e636e" + integrity sha1-322AqdomEqEh5t3XVYvL7PBuY24= + dependencies: + babel-plugin-syntax-jsx "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-react-jsx-source@6.22.0, babel-plugin-transform-react-jsx-source@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx-source/-/babel-plugin-transform-react-jsx-source-6.22.0.tgz#66ac12153f5cd2d17b3c19268f4bf0197f44ecd6" + integrity sha1-ZqwSFT9c0tF7PBkmj0vwGX9E7NY= + dependencies: + babel-plugin-syntax-jsx "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-react-jsx@6.24.1, babel-plugin-transform-react-jsx@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.24.1.tgz#840a028e7df460dfc3a2d29f0c0d91f6376e66a3" + integrity sha1-hAoCjn30YN/DotKfDA2R9jduZqM= + dependencies: + babel-helper-builder-react-jsx "^6.24.1" + babel-plugin-syntax-jsx "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-regenerator@6.26.0, babel-plugin-transform-regenerator@^6.22.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" + integrity sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8= + dependencies: + regenerator-transform "^0.10.0" + +babel-plugin-transform-runtime@6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-runtime/-/babel-plugin-transform-runtime-6.23.0.tgz#88490d446502ea9b8e7efb0fe09ec4d99479b1ee" + integrity sha1-iEkNRGUC6puOfvsP4J7E2ZR5se4= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-strict-mode@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" + integrity sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g= + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-preset-env@1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.6.1.tgz#a18b564cc9b9afdf4aae57ae3c1b0d99188e6f48" + integrity sha512-W6VIyA6Ch9ePMI7VptNn2wBM6dbG0eSz25HEiL40nQXCsXGTGZSTZu1Iap+cj3Q0S5a7T9+529l/5Bkvd+afNA== + 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 "^2.1.2" + invariant "^2.2.2" + semver "^5.3.0" + +babel-preset-flow@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-preset-flow/-/babel-preset-flow-6.23.0.tgz#e71218887085ae9a24b5be4169affb599816c49d" + integrity sha1-5xIYiHCFrpoktb5Baa/7WZgWxJ0= + dependencies: + babel-plugin-transform-flow-strip-types "^6.22.0" + +babel-preset-jest@^20.0.3: + version "20.0.3" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-20.0.3.tgz#cbacaadecb5d689ca1e1de1360ebfc66862c178a" + integrity sha1-y6yq3stdaJyh4d4TYOv8ZoYsF4o= + dependencies: + babel-plugin-jest-hoist "^20.0.3" + +babel-preset-react-app@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/babel-preset-react-app/-/babel-preset-react-app-3.1.2.tgz#49ba3681b917c4e5c73a5249d3ef4c48fae064e2" + integrity sha512-/sh5Qd5T08PYa6t4kuCdKh9tXp6/m/Jwyx7PJTqugsYMfsDUJMlBXOs5EwFODHprzjWrmQ0SydnMZu9FY4MZYg== + dependencies: + babel-plugin-dynamic-import-node "1.1.0" + babel-plugin-syntax-dynamic-import "6.18.0" + babel-plugin-transform-class-properties "6.24.1" + babel-plugin-transform-es2015-destructuring "6.23.0" + babel-plugin-transform-object-rest-spread "6.26.0" + babel-plugin-transform-react-constant-elements "6.23.0" + babel-plugin-transform-react-jsx "6.24.1" + babel-plugin-transform-react-jsx-self "6.22.0" + babel-plugin-transform-react-jsx-source "6.22.0" + babel-plugin-transform-regenerator "6.26.0" + babel-plugin-transform-runtime "6.23.0" + babel-preset-env "1.6.1" + babel-preset-react "6.24.1" + +babel-preset-react@6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-preset-react/-/babel-preset-react-6.24.1.tgz#ba69dfaea45fc3ec639b6a4ecea6e17702c91380" + integrity sha1-umnfrqRfw+xjm2pOzqbhdwLJE4A= + dependencies: + babel-plugin-syntax-jsx "^6.3.13" + babel-plugin-transform-react-display-name "^6.23.0" + babel-plugin-transform-react-jsx "^6.24.1" + babel-plugin-transform-react-jsx-self "^6.22.0" + babel-plugin-transform-react-jsx-source "^6.22.0" + babel-preset-flow "^6.23.0" + +babel-register@^6.24.1, babel-register@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" + integrity sha1-btAhFz4vy0htestFxgCahW9kcHE= + 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.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.23.0.tgz#0a9489f144de70efb3ce4300accdb329e2fc543b" + integrity sha1-CpSJ8UTecO+zzkMArM2zKeL8VDs= + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.10.0" + +babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4= + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.11.0" + +babel-template@^6.16.0, babel-template@^6.24.1, babel-template@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" + integrity sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI= + 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.18.0, babel-traverse@^6.23.1, babel-traverse@^6.24.1, babel-traverse@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" + integrity sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4= + 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.18.0, babel-types@^6.19.0, babel-types@^6.23.0, babel-types@^6.24.1, babel-types@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" + integrity sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc= + dependencies: + babel-runtime "^6.26.0" + esutils "^2.0.2" + lodash "^4.17.4" + to-fast-properties "^1.0.3" + +babylon@^6.11.0, babylon@^6.17.0, babylon@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" + integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ== + +balanced-match@^0.4.2: + version "0.4.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" + integrity sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg= + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +base64-js@^1.0.2: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== + 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" + +batch@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" + integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY= + +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= + dependencies: + tweetnacl "^0.14.3" + +big.js@^3.1.3: + version "3.2.0" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" + integrity sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q== + +big.js@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== + +binary-extensions@^1.0.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" + integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +bindings@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" + integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== + dependencies: + file-uri-to-path "1.0.0" + +block-stream@*: + version "0.0.9" + resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" + integrity sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo= + dependencies: + inherits "~2.0.0" + +bluebird@^3.4.7: + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== + +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9: + version "4.12.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" + integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== + +bn.js@^5.0.0, bn.js@^5.1.1: + version "5.2.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.0.tgz#358860674396c6997771a9d051fcc1b57d4ae002" + integrity sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw== + +body-parser@1.19.1: + version "1.19.1" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.1.tgz#1499abbaa9274af3ecc9f6f10396c995943e31d4" + integrity sha512-8ljfQi5eBk8EJfECMrgqNGWPEY5jWP+1IzkzkGdFFEwFQZZyaZ21UqdaHktgiMlH0xLHqIFtE/u2OYE5dOtViA== + dependencies: + bytes "3.1.1" + content-type "~1.0.4" + debug "2.6.9" + depd "~1.1.2" + http-errors "1.8.1" + iconv-lite "0.4.24" + on-finished "~2.3.0" + qs "6.9.6" + raw-body "2.4.2" + type-is "~1.6.18" + +boolbase@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= + +boom@2.x.x: + version "2.10.1" + resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" + integrity sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8= + dependencies: + hoek "2.x.x" + +boxen@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b" + integrity sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw== + dependencies: + ansi-align "^2.0.0" + camelcase "^4.0.0" + chalk "^2.0.1" + cli-boxes "^1.0.0" + string-width "^2.0.0" + term-size "^1.2.0" + widest-line "^2.0.0" + +brace-expansion@^1.0.0, brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^1.8.2: + version "1.8.5" + resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" + integrity sha1-uneWLhLf+WnWt2cR6RS3N4V79qc= + dependencies: + expand-range "^1.8.1" + preserve "^0.2.0" + repeat-element "^1.1.2" + +braces@^2.3.1, braces@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== + 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" + +braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +brorand@^1.0.1, brorand@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= + +browser-resolve@^1.11.2: + version "1.11.3" + resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.3.tgz#9b7cbb3d0f510e4cb86bdbd796124d28b5890af6" + integrity sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ== + dependencies: + resolve "1.1.7" + +browserify-aes@^1.0.0, browserify-aes@^1.0.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== + dependencies: + buffer-xor "^1.0.3" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.3" + inherits "^2.0.1" + safe-buffer "^5.0.1" + +browserify-cipher@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" + integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== + dependencies: + browserify-aes "^1.0.4" + browserify-des "^1.0.0" + evp_bytestokey "^1.0.0" + +browserify-des@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" + integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== + dependencies: + cipher-base "^1.0.1" + des.js "^1.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +browserify-rsa@^4.0.0, browserify-rsa@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.1.0.tgz#b2fd06b5b75ae297f7ce2dc651f918f5be158c8d" + integrity sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog== + dependencies: + bn.js "^5.0.0" + randombytes "^2.0.1" + +browserify-sign@^4.0.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.1.tgz#eaf4add46dd54be3bb3b36c0cf15abbeba7956c3" + integrity sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg== + 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" + +browserify-zlib@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" + integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA== + dependencies: + pako "~1.0.5" + +browserslist@^1.3.6, browserslist@^1.5.2, browserslist@^1.7.6: + version "1.7.7" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-1.7.7.tgz#0bd76704258be829b2398bb50e4b62d1a166b0b9" + integrity sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk= + dependencies: + caniuse-db "^1.0.30000639" + electron-to-chromium "^1.2.7" + +browserslist@^2.1.2: + version "2.11.3" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.11.3.tgz#fe36167aed1bbcde4827ebfe71347a2cc70b99b2" + integrity sha512-yWu5cXT7Av6mVwzWc8lMsJMHWn4xyjSuGYi4IozbVTLUOEYPSagUB8kiMDUHA1fS3zjr8nkxkn9jdvug4BBRmA== + dependencies: + caniuse-lite "^1.0.30000792" + electron-to-chromium "^1.3.30" + +bser@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bser/-/bser-1.0.2.tgz#381116970b2a6deea5646dd15dd7278444b56169" + integrity sha1-OBEWlwsqbe6lZG3RXdcnhES1YWk= + dependencies: + node-int64 "^0.4.0" + +bser@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" + integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== + dependencies: + node-int64 "^0.4.0" + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +buffer-xor@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= + +buffer@^4.3.0: + version "4.9.2" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" + integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + +builtin-modules@^1.0.0, builtin-modules@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" + integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= + +builtin-status-codes@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" + integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= + +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= + +bytes@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.1.tgz#3f018291cb4cbad9accb6e6970bca9c8889e879a" + integrity sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg== + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== + 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" + +call-bind@^1.0.0, call-bind@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + 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.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" + integrity sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8= + dependencies: + callsites "^0.2.0" + +callsites@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" + integrity sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo= + +callsites@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" + integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= + +camel-case@3.0.x: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73" + integrity sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M= + dependencies: + no-case "^2.2.0" + upper-case "^1.1.1" + +camelcase-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" + integrity sha1-MIvur/3ygRkFHvodkyITyRuPkuc= + dependencies: + camelcase "^2.0.0" + map-obj "^1.0.0" + +camelcase@^1.0.2: + version "1.2.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" + integrity sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk= + +camelcase@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" + integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8= + +camelcase@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" + integrity sha1-MvxLn82vhF/N9+c7uXysImHwqwo= + +camelcase@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" + integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= + +caniuse-api@^1.5.2: + version "1.6.1" + resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-1.6.1.tgz#b534e7c734c4f81ec5fbe8aca2ad24354b962c6c" + integrity sha1-tTTnxzTE+B7F++isoq0kNUuWLGw= + dependencies: + browserslist "^1.3.6" + caniuse-db "^1.0.30000529" + lodash.memoize "^4.1.2" + lodash.uniq "^4.5.0" + +caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639: + version "1.0.30001301" + resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30001301.tgz#e81fb9448a99d8bb7b4f0a0c80ee083e32f63de6" + integrity sha512-Ik6X/dtFYFrs7ACNqPiUcg7sH8Y07ntEbBDKLclsdlF6eifNhqvPuhF3K6QnKUqncx/cSKACNVTMTKyvg37Naw== + +caniuse-lite@^1.0.30000669, caniuse-lite@^1.0.30000792: + version "1.0.30001301" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001301.tgz#ebc9086026534cab0dab99425d9c3b4425e5f450" + integrity sha512-csfD/GpHMqgEL3V3uIgosvh+SVIQvCh43SNu9HRbP1lnxkKm1kjDG4f32PP571JplkLjfS+mg2p1gxR7MYrrIA== + +capture-stack-trace@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz#a6c0bbe1f38f3aa0b92238ecb6ff42c344d4135d" + integrity sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw== + +case-sensitive-paths-webpack-plugin@1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-1.1.4.tgz#8aaedd5699a86cac2b34cf40d9b4145758978472" + integrity sha1-iq7dVpmobKwrNM9A2bQUV1iXhHI= + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= + +center-align@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" + integrity sha1-qg0yYptu6XIgBBHL1EYckHvCt60= + dependencies: + align-text "^0.1.3" + lazy-cache "^1.0.3" + +chalk@1.1.3, chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chalk@^2.0.0, chalk@^2.0.1, chalk@^2.4.1: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + 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" + +chardet@^0.4.0: + version "0.4.2" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" + integrity sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I= + +chokidar@^1.6.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" + integrity sha1-eY5ol3gVHIB2tLNg5e3SjNortGg= + dependencies: + anymatch "^1.3.0" + async-each "^1.0.0" + glob-parent "^2.0.0" + inherits "^2.0.1" + is-binary-path "^1.0.0" + is-glob "^2.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.0.0" + optionalDependencies: + fsevents "^1.0.0" + +chokidar@^2.1.8: + version "2.1.8" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" + integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== + 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" + +chokidar@^3.4.1: + 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" + +ci-info@^1.5.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" + integrity sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A== + +cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +circular-json@^0.3.1: + version "0.3.3" + resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" + integrity sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A== + +clap@^1.0.9: + version "1.2.3" + resolved "https://registry.yarnpkg.com/clap/-/clap-1.2.3.tgz#4f36745b32008492557f46412d66d50cb99bce51" + integrity sha512-4CoL/A3hf90V3VIEjeuhSvlGFEHKzOz+Wfc2IVZc+FaUgU0ZQafJTP49fvnULipOPcAfqhyI2duwQyns6xqjYA== + dependencies: + chalk "^1.1.3" + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +clean-css@4.2.x: + version "4.2.4" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.4.tgz#733bf46eba4e607c6891ea57c24a989356831178" + integrity sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A== + dependencies: + source-map "~0.6.0" + +cli-boxes@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" + integrity sha1-T6kXw+WclKAEzWH47lCdplFocUM= + +cli-cursor@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" + integrity sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc= + dependencies: + restore-cursor "^1.0.1" + +cli-cursor@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= + dependencies: + restore-cursor "^2.0.0" + +cli-width@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.1.tgz#b0433d0b4e9c847ef18868a4ef16fd5fc8271c48" + integrity sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw== + +cliui@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" + integrity sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE= + dependencies: + center-align "^0.1.1" + right-align "^0.1.1" + wordwrap "0.0.2" + +cliui@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" + integrity sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0= + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrap-ansi "^2.0.0" + +clone@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" + integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= + +clone@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" + integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= + +coa@~1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/coa/-/coa-1.0.4.tgz#a9ef153660d6a86a8bdec0289a5c684d217432fd" + integrity sha1-qe8VNmDWqGqL3sAomlxoTSF0Mv0= + dependencies: + q "^1.1.2" + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-convert@^1.3.0, color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +color-name@^1.0.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +color-string@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-0.3.0.tgz#27d46fb67025c5c2fa25993bfbf579e47841b991" + integrity sha1-J9RvtnAlxcL6JZk7+/V55HhBuZE= + dependencies: + color-name "^1.0.0" + +color@^0.11.0: + version "0.11.4" + resolved "https://registry.yarnpkg.com/color/-/color-0.11.4.tgz#6d7b5c74fb65e841cd48792ad1ed5e07b904d764" + integrity sha1-bXtcdPtl6EHNSHkq0e1eB7kE12Q= + dependencies: + clone "^1.0.2" + color-convert "^1.3.0" + color-string "^0.3.0" + +colormin@^1.0.5: + version "1.1.2" + resolved "https://registry.yarnpkg.com/colormin/-/colormin-1.1.2.tgz#ea2f7420a72b96881a38aae59ec124a6f7298133" + integrity sha1-6i90IKcrlogaOKrlnsEkpvcpgTM= + dependencies: + color "^0.11.0" + css-color-names "0.0.4" + has "^1.0.1" + +colors@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" + integrity sha1-FopHAXVran9RoSzgyXv6KMCE7WM= + +combined-stream@^1.0.5, combined-stream@^1.0.6, combined-stream@~1.0.5, combined-stream@~1.0.6: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +commander@2.17.x: + version "2.17.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" + integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg== + +commander@~2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" + integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= + +component-emitter@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + +compressible@~2.0.16: + version "2.0.18" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" + integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== + dependencies: + mime-db ">= 1.43.0 < 2" + +compression@^1.5.2: + version "1.7.4" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" + 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.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +concat-stream@^1.5.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +configstore@^3.0.0: + version "3.1.5" + resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.5.tgz#e9af331fadc14dabd544d3e7e76dc446a09a530f" + integrity sha512-nlOhI4+fdzoK5xmJ+NY+1gZK56bwEaWZr8fYuXohZ9Vkc1o3a4T/R3M+yE/w7x/ZVJ1zF8c+oaOvF0dztdUgmA== + dependencies: + dot-prop "^4.2.1" + graceful-fs "^4.1.2" + make-dir "^1.0.0" + unique-string "^1.0.0" + write-file-atomic "^2.0.0" + xdg-basedir "^3.0.0" + +connect-history-api-fallback@^1.3.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc" + integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg== + +console-browserify@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" + integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== + +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= + +constants-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" + integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= + +contains-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" + integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo= + +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + +content-type-parser@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/content-type-parser/-/content-type-parser-1.0.2.tgz#caabe80623e63638b2502fd4c7f12ff4ce2352e7" + integrity sha512-lM4l4CnMEwOLHAHr/P6MEZwZFPJFtAAKgL6pogbXmVZggIqXhdB6RbBtPOTsw2FcXwYhehRGERJmRrjOiIB8pQ== + +content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + +convert-source-map@^1.1.0, convert-source-map@^1.4.0, convert-source-map@^1.5.1: + version "1.8.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" + 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.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= + +cookie@0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" + integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA== + +cookie@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" + integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s= + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= + +core-js@^1.0.0: + version "1.2.7" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" + integrity sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY= + +core-js@^2.4.0, core-js@^2.5.0: + version "2.6.12" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec" + integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== + +core-util-is@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + +cosmiconfig@^2.1.0, cosmiconfig@^2.1.1: + version "2.2.2" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-2.2.2.tgz#6173cebd56fac042c1f4390edf7af6c07c7cb892" + integrity sha512-GiNXLwAFPYHy25XmTPpafYvn3CLAkJ8FLsscq78MQd1Kh0OU6Yzhn4eV2MVF4G9WEQZoWEGltatdR+ntGPMl5A== + dependencies: + is-directory "^0.3.1" + js-yaml "^3.4.3" + minimist "^1.2.0" + object-assign "^4.1.0" + os-homedir "^1.0.1" + parse-json "^2.2.0" + require-from-string "^1.1.0" + +create-ecdh@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" + integrity sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A== + dependencies: + bn.js "^4.1.0" + elliptic "^6.5.3" + +create-error-class@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" + integrity sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y= + dependencies: + capture-stack-trace "^1.0.0" + +create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== + dependencies: + 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@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== + 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" + +create-react-class@^15.6.0: + version "15.7.0" + resolved "https://registry.yarnpkg.com/create-react-class/-/create-react-class-15.7.0.tgz#7499d7ca2e69bb51d13faf59bd04f0c65a1d6c1e" + integrity sha512-QZv4sFWG9S5RUvkTYWbflxeZX+JG7Cz0Tn33rQBJ+WFQTqTfUTjMjiv9tnfXazjsO5r0KhPs+AqCjyrQX6h2ng== + dependencies: + loose-envify "^1.3.1" + object-assign "^4.1.1" + +cross-spawn@5.1.0, cross-spawn@^5.0.1: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk= + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + +cryptiles@2.x.x: + version "2.0.5" + resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" + integrity sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g= + dependencies: + boom "2.x.x" + +crypto-browserify@^3.11.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" + integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== + 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" + +crypto-random-string@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" + integrity sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4= + +css-color-names@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0" + integrity sha1-gIrcLnnPhHOAabZGyyDsJ762KeA= + +css-loader@0.28.1: + version "0.28.1" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-0.28.1.tgz#220325599f8f00452d9ceb4c3ca6c8a66798642d" + integrity sha1-IgMlWZ+PAEUtnOtMPKbIpmeYZC0= + dependencies: + babel-code-frame "^6.11.0" + css-selector-tokenizer "^0.7.0" + cssnano ">=2.6.1 <4" + loader-utils "^1.0.2" + lodash.camelcase "^4.3.0" + object-assign "^4.0.1" + postcss "^5.0.6" + postcss-modules-extract-imports "^1.0.0" + postcss-modules-local-by-default "^1.0.1" + postcss-modules-scope "^1.0.0" + postcss-modules-values "^1.1.0" + postcss-value-parser "^3.3.0" + source-list-map "^0.1.7" + +css-select@^4.1.3: + version "4.2.1" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.2.1.tgz#9e665d6ae4c7f9d65dbe69d0316e3221fb274cdd" + integrity sha512-/aUslKhzkTNCQUB2qTX84lVmfia9NyjP3WpDGtj/WxhwBzWBYUV3DgUpurHTme8UTPcPlAD1DJ+b0nN/t50zDQ== + dependencies: + boolbase "^1.0.0" + css-what "^5.1.0" + domhandler "^4.3.0" + domutils "^2.8.0" + nth-check "^2.0.1" + +css-selector-tokenizer@^0.7.0: + version "0.7.3" + resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.7.3.tgz#735f26186e67c749aaf275783405cf0661fae8f1" + integrity sha512-jWQv3oCEL5kMErj4wRnK/OPoBi0D+P1FR2cDCKYPaMeD2eW3/mttav8HT4hT1CKopiJI/psEULjkClhvJo4Lvg== + dependencies: + cssesc "^3.0.0" + fastparse "^1.1.2" + +css-what@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-5.1.0.tgz#3f7b707aadf633baf62c2ceb8579b545bb40f7fe" + integrity sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw== + +cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== + +"cssnano@>=2.6.1 <4": + version "3.10.0" + resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-3.10.0.tgz#4f38f6cea2b9b17fa01490f23f1dc68ea65c1c38" + integrity sha1-Tzj2zqK5sX+gFJDyPx3GjqZcHDg= + dependencies: + autoprefixer "^6.3.1" + decamelize "^1.1.2" + defined "^1.0.0" + has "^1.0.1" + object-assign "^4.0.1" + postcss "^5.0.14" + postcss-calc "^5.2.0" + postcss-colormin "^2.1.8" + postcss-convert-values "^2.3.4" + postcss-discard-comments "^2.0.4" + postcss-discard-duplicates "^2.0.1" + postcss-discard-empty "^2.0.1" + postcss-discard-overridden "^0.1.1" + postcss-discard-unused "^2.2.1" + postcss-filter-plugins "^2.0.0" + postcss-merge-idents "^2.1.5" + postcss-merge-longhand "^2.0.1" + postcss-merge-rules "^2.0.3" + postcss-minify-font-values "^1.0.2" + postcss-minify-gradients "^1.0.1" + postcss-minify-params "^1.0.4" + postcss-minify-selectors "^2.0.4" + postcss-normalize-charset "^1.1.0" + postcss-normalize-url "^3.0.7" + postcss-ordered-values "^2.1.0" + postcss-reduce-idents "^2.2.2" + postcss-reduce-initial "^1.0.0" + postcss-reduce-transforms "^1.0.3" + postcss-svgo "^2.1.1" + postcss-unique-selectors "^2.0.2" + postcss-value-parser "^3.2.3" + postcss-zindex "^2.0.1" + +csso@~2.3.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/csso/-/csso-2.3.2.tgz#ddd52c587033f49e94b71fc55569f252e8ff5f85" + integrity sha1-3dUsWHAz9J6Utx/FVWnyUuj/X4U= + dependencies: + clap "^1.0.9" + source-map "^0.5.3" + +cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": + version "0.3.8" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" + integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== + +"cssstyle@>= 0.2.37 < 0.3.0": + version "0.2.37" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-0.2.37.tgz#541097234cb2513c83ceed3acddc27ff27987d54" + integrity sha1-VBCXI0yyUTyDzu06zdwn/yeYfVQ= + dependencies: + cssom "0.3.x" + +currently-unhandled@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" + integrity sha1-mI3zP+qxke95mmE2nddsF635V+o= + dependencies: + array-find-index "^1.0.1" + +d@1, d@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" + integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== + dependencies: + es5-ext "^0.10.50" + type "^1.0.1" + +damerau-levenshtein@^1.0.0: + version "1.0.8" + resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7" + integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA== + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= + dependencies: + assert-plus "^1.0.0" + +debug@2.6.9, debug@^2.1.1, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.6, debug@^2.6.8, debug@^2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@^3.1.0, debug@^3.1.1, debug@^3.2.7: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + +decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= + +deep-equal@^1.0.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" + integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== + 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" + +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + +deep-is@~0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== + +default-require-extensions@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-1.0.0.tgz#f37ea15d3e13ffd9b437d33e1a75b5fb97874cb8" + integrity sha1-836hXT4T/9m0N9M+GnW1+5eHTLg= + dependencies: + strip-bom "^2.0.0" + +define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + +defined@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" + integrity sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM= + +del@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" + integrity sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag= + dependencies: + globby "^5.0.0" + is-path-cwd "^1.0.0" + is-path-in-cwd "^1.0.0" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + rimraf "^2.2.8" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + +des.js@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" + integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA== + dependencies: + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= + +detect-indent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" + integrity sha1-920GQ1LN9Docts5hnE7jqUdd4gg= + dependencies: + repeating "^2.0.0" + +detect-libc@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= + +detect-node@^2.0.3: + version "2.1.0" + resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" + integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== + +detect-port-alt@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/detect-port-alt/-/detect-port-alt-1.1.3.tgz#a4d2f061d757a034ecf37c514260a98750f2b131" + integrity sha1-pNLwYddXoDTs83xRQmCph1DysTE= + dependencies: + address "^1.0.1" + debug "^2.6.0" + +diff@^3.2.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" + integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== + +diffie-hellman@^5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" + integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== + dependencies: + bn.js "^4.1.0" + miller-rabin "^4.0.0" + randombytes "^2.0.0" + +doctrine@1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" + integrity sha1-N53Ocw9hZvds76TmcHoVmwLFpvo= + dependencies: + esutils "^2.0.2" + isarray "^1.0.0" + +doctrine@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" + integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== + dependencies: + esutils "^2.0.2" + +dom-converter@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768" + integrity sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA== + dependencies: + utila "~0.4" + +dom-serializer@^1.0.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.3.2.tgz#6206437d32ceefaec7161803230c7a20bc1b4d91" + integrity sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.2.0" + entities "^2.0.0" + +dom-urls@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/dom-urls/-/dom-urls-1.1.0.tgz#001ddf81628cd1e706125c7176f53ccec55d918e" + integrity sha1-AB3fgWKM0ecGElxxdvU8zsVdkY4= + dependencies: + urijs "^1.16.1" + +domain-browser@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" + integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== + +domelementtype@^2.0.1, domelementtype@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57" + integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A== + +domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.0.tgz#16c658c626cf966967e306f966b431f77d4a5626" + integrity sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g== + dependencies: + domelementtype "^2.2.0" + +dompurify@^2.3.0: + version "2.3.4" + resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.3.4.tgz#1cf5cf0105ccb4debdf6db162525bd41e6ddacc6" + integrity sha512-6BVcgOAVFXjI0JTjEvZy901Rghm+7fDQOrNIcxB4+gdhj6Kwp6T9VBhBY/AbagKHJocRkDYGd6wvI+p4/10xtQ== + +domutils@^2.5.2, domutils@^2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135" + integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A== + dependencies: + dom-serializer "^1.0.1" + domelementtype "^2.2.0" + domhandler "^4.2.0" + +dot-prop@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.1.tgz#45884194a71fc2cda71cbb4bceb3a4dd2f433ba4" + integrity sha512-l0p4+mIuJIua0mhxGoh4a+iNL9bmeK5DvnSVQa6T0OhrVmaEa1XScX5Etc673FePCJOArq/4Pa2cLGODUWTPOQ== + dependencies: + is-obj "^1.0.0" + +dotenv@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-4.0.0.tgz#864ef1379aced55ce6f95debecdce179f7a0cd1d" + integrity sha1-hk7xN5rO1Vzm+V3r7NzhefegzR0= + +draft-js@^0.10.1: + version "0.10.5" + resolved "https://registry.yarnpkg.com/draft-js/-/draft-js-0.10.5.tgz#bfa9beb018fe0533dbb08d6675c371a6b08fa742" + integrity sha512-LE6jSCV9nkPhfVX2ggcRLA4FKs6zWq9ceuO/88BpXdNCS7mjRTgs0NsV6piUCJX9YxMsB9An33wnkMmU2sD2Zg== + dependencies: + fbjs "^0.8.15" + immutable "~3.7.4" + object-assign "^4.1.0" + +duplexer3@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" + integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= + +duplexer@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" + integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== + +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= + +electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.30: + version "1.4.53" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.53.tgz#5d80a91c399b44952ef485857fb5b9d4387d2e60" + integrity sha512-rFveSKQczlcav+H3zkKqykU6ANseFwXwkl855jOIap5/0gnEcuIhv2ecz6aoTrXavF6I/CEBeRnBnkB51k06ew== + +elliptic@^6.5.3: + version "6.5.4" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" + integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== + 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" + +emoji-regex@^6.1.0: + version "6.5.1" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-6.5.1.tgz#9baea929b155565c11ea41c6626eaa65cef992c2" + integrity sha512-PAHp6TxrCy7MGMFidro8uikr+zlJJKJ/Q6mm2ExZ7HwkyR9lSVFfE3kt36qcwa24BQL7y0G9axycGjK1A/0uNQ== + +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.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" + integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k= + +emojis-list@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" + integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + +encoding@^0.1.11: + version "0.1.13" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" + integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== + dependencies: + iconv-lite "^0.6.2" + +enhanced-resolve@^3.0.0: + version "3.4.1" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz#0421e339fd71419b3da13d129b3979040230476e" + integrity sha1-BCHjOf1xQZs9oT0Smzl5BAIwR24= + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.4.0" + object-assign "^4.0.1" + tapable "^0.2.7" + +entities@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" + integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== + +errno@^0.1.3, errno@~0.1.7: + version "0.1.8" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" + integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== + dependencies: + prr "~1.0.1" + +error-ex@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +es-abstract@^1.19.1: + version "1.19.1" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.1.tgz#d4885796876916959de78edaa0df456627115ec3" + integrity sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w== + dependencies: + call-bind "^1.0.2" + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + get-intrinsic "^1.1.1" + get-symbol-description "^1.0.0" + has "^1.0.3" + has-symbols "^1.0.2" + internal-slot "^1.0.3" + is-callable "^1.2.4" + is-negative-zero "^2.0.1" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.1" + is-string "^1.0.7" + is-weakref "^1.0.1" + object-inspect "^1.11.0" + object-keys "^1.1.1" + object.assign "^4.1.2" + string.prototype.trimend "^1.0.4" + string.prototype.trimstart "^1.0.4" + unbox-primitive "^1.0.1" + +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + 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.46, es5-ext@^0.10.50, es5-ext@~0.10.14: + version "0.10.53" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.53.tgz#93c5a3acfdbef275220ad72644ad02ee18368de1" + integrity sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q== + dependencies: + es6-iterator "~2.0.3" + es6-symbol "~3.1.3" + next-tick "~1.0.0" + +es6-iterator@^2.0.3, es6-iterator@~2.0.1, es6-iterator@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c= + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + +es6-map@^0.1.3: + version "0.1.5" + resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.5.tgz#9136e0503dcc06a301690f0bb14ff4e364e949f0" + integrity sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA= + dependencies: + d "1" + es5-ext "~0.10.14" + es6-iterator "~2.0.1" + es6-set "~0.1.5" + es6-symbol "~3.1.1" + event-emitter "~0.3.5" + +es6-promise@^4.0.5: + version "4.2.8" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" + integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== + +es6-set@~0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1" + integrity sha1-0rPsXU2ADO2BjbU40ol02wpzzLE= + dependencies: + d "1" + es5-ext "~0.10.14" + es6-iterator "~2.0.1" + es6-symbol "3.1.1" + event-emitter "~0.3.5" + +es6-symbol@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" + integrity sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc= + dependencies: + d "1" + es5-ext "~0.10.14" + +es6-symbol@^3.1.1, es6-symbol@~3.1.1, es6-symbol@~3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" + integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== + dependencies: + d "^1.0.1" + ext "^1.1.2" + +es6-weak-map@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.3.tgz#b6da1f16cc2cc0d9be43e6bdbfc5e7dfcdf31d53" + integrity sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA== + dependencies: + d "1" + es5-ext "^0.10.46" + es6-iterator "^2.0.3" + es6-symbol "^3.1.1" + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= + +escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +escodegen@^1.6.1: + version "1.14.3" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.3.tgz#4e7b81fba61581dc97582ed78cab7f0e8d63f503" + integrity sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw== + dependencies: + esprima "^4.0.1" + estraverse "^4.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + +escope@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3" + integrity sha1-4Bl16BJ4GhY6ba392AOY3GTIicM= + dependencies: + es6-map "^0.1.3" + es6-weak-map "^2.0.1" + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-config-react-app@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/eslint-config-react-app/-/eslint-config-react-app-1.0.5.tgz#98337597bc01cc22991fcbdda07451f3b4511718" + integrity sha1-mDN1l7wBzCKZH8vdoHRR87RRFxg= + +eslint-import-resolver-node@^0.2.0: + version "0.2.3" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.2.3.tgz#5add8106e8c928db2cba232bcd9efa846e3da16c" + integrity sha1-Wt2BBujJKNssuiMrzZ76hG49oWw= + dependencies: + debug "^2.2.0" + object-assign "^4.0.1" + resolve "^1.1.6" + +eslint-loader@1.7.1: + version "1.7.1" + resolved "https://registry.yarnpkg.com/eslint-loader/-/eslint-loader-1.7.1.tgz#50b158dd6272dcefb97e984254837f81a5802ce0" + integrity sha1-ULFY3WJy3O+5fphCVIN/gaWALOA= + dependencies: + find-cache-dir "^0.1.1" + loader-fs-cache "^1.0.0" + loader-utils "^1.0.2" + object-assign "^4.0.1" + object-hash "^1.1.4" + rimraf "^2.6.1" + +eslint-module-utils@^2.0.0: + version "2.7.2" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.7.2.tgz#1d0aa455dcf41052339b63cada8ab5fd57577129" + integrity sha512-zquepFnWCY2ISMFwD/DqzaM++H+7PDzOpUvotJWm/y1BAFt5R4oeULgdrTejKqLkz7MA/tgstsUMNYc7wNdTrg== + dependencies: + debug "^3.2.7" + find-up "^2.1.0" + +eslint-plugin-flowtype@2.33.0: + version "2.33.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.33.0.tgz#b2783814ed2ddcf729953b8f65ff73c90cabee4b" + integrity sha1-sng4FO0t3PcplTuPZf9zyQyr7ks= + dependencies: + lodash "^4.15.0" + +eslint-plugin-import@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.2.0.tgz#72ba306fad305d67c4816348a4699a4229ac8b4e" + integrity sha1-crowb60wXWfEgWNIpGmaQimsi04= + dependencies: + builtin-modules "^1.1.1" + contains-path "^0.1.0" + debug "^2.2.0" + doctrine "1.5.0" + eslint-import-resolver-node "^0.2.0" + eslint-module-utils "^2.0.0" + has "^1.0.1" + lodash.cond "^4.3.0" + minimatch "^3.0.3" + pkg-up "^1.0.0" + +eslint-plugin-jsx-a11y@5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-5.0.3.tgz#4a939f76ec125010528823331bf948cc573380b6" + integrity sha1-SpOfduwSUBBSiCMzG/lIzFczgLY= + dependencies: + aria-query "^0.5.0" + array-includes "^3.0.3" + ast-types-flow "0.0.7" + axobject-query "^0.1.0" + damerau-levenshtein "^1.0.0" + emoji-regex "^6.1.0" + jsx-ast-utils "^1.4.0" + +eslint-plugin-react@7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.0.1.tgz#e78107e1e559c6e2b17786bb67c2e2a010ad0d2f" + integrity sha1-54EH4eVZxuKxd4a7Z8LioBCtDS8= + dependencies: + doctrine "^2.0.0" + has "^1.0.1" + jsx-ast-utils "^1.3.4" + +eslint@3.19.0: + version "3.19.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-3.19.0.tgz#c8fc6201c7f40dd08941b87c085767386a679acc" + integrity sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw= + dependencies: + babel-code-frame "^6.16.0" + chalk "^1.1.3" + concat-stream "^1.5.2" + debug "^2.1.1" + doctrine "^2.0.0" + escope "^3.6.0" + espree "^3.4.0" + esquery "^1.0.0" + estraverse "^4.2.0" + esutils "^2.0.2" + file-entry-cache "^2.0.0" + glob "^7.0.3" + globals "^9.14.0" + ignore "^3.2.0" + imurmurhash "^0.1.4" + inquirer "^0.12.0" + is-my-json-valid "^2.10.0" + is-resolvable "^1.0.0" + js-yaml "^3.5.1" + json-stable-stringify "^1.0.0" + levn "^0.3.0" + lodash "^4.0.0" + mkdirp "^0.5.0" + natural-compare "^1.4.0" + optionator "^0.8.2" + path-is-inside "^1.0.1" + pluralize "^1.2.1" + progress "^1.1.8" + require-uncached "^1.0.2" + shelljs "^0.7.5" + strip-bom "^3.0.0" + strip-json-comments "~2.0.1" + table "^3.7.8" + text-table "~0.2.0" + user-home "^2.0.0" + +espree@^3.4.0: + version "3.5.4" + resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.4.tgz#b0f447187c8a8bed944b815a660bddf5deb5d1a7" + integrity sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A== + dependencies: + acorn "^5.5.0" + acorn-jsx "^3.0.0" + +esprima@^2.6.0: + version "2.7.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" + integrity sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE= + +esprima@^4.0.0, esprima@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esquery@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" + integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== + dependencies: + estraverse "^5.1.0" + +esrecurse@^4.1.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, estraverse@^4.2.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.1.0, estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= + +event-emitter@~0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" + integrity sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk= + dependencies: + d "1" + es5-ext "~0.10.14" + +eventemitter3@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-2.0.3.tgz#b5e1079b59fb5e1ba2771c0a993be060a58c99ba" + integrity sha1-teEHm1n7XhuidxwKmTvgYKWMmbo= + +eventemitter3@^4.0.0: + version "4.0.7" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== + +events@^3.0.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + +eventsource@0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-0.1.6.tgz#0acede849ed7dd1ccc32c811bb11b944d4f29232" + integrity sha1-Cs7ehJ7X3RzMMsgRuxG5RNTykjI= + dependencies: + original ">=0.0.5" + +evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== + dependencies: + md5.js "^1.3.4" + safe-buffer "^5.1.1" + +exec-sh@^0.2.0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.2.2.tgz#2a5e7ffcbd7d0ba2755bdecb16e5a427dfbdec36" + integrity sha512-FIUCJz1RbuS0FKTdaAafAByGS0CPvU3R0MeHxgtl+djzCc//F8HakL8GzmVNZanasTbTAY/3DRFA0KpVqj/eAw== + dependencies: + merge "^1.2.0" + +execa@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" + integrity sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c= + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +exit-hook@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" + integrity sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g= + +expand-brackets@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" + integrity sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s= + dependencies: + is-posix-bracket "^0.1.0" + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +expand-range@^1.8.1: + version "1.8.2" + resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" + integrity sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc= + dependencies: + fill-range "^2.1.0" + +expand-tilde@^2.0.0, expand-tilde@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" + integrity sha1-l+gBqgUt8CRU3kawK/YhZCzchQI= + dependencies: + homedir-polyfill "^1.0.1" + +express@^4.13.3: + version "4.17.2" + resolved "https://registry.yarnpkg.com/express/-/express-4.17.2.tgz#c18369f265297319beed4e5558753cc8c1364cb3" + integrity sha512-oxlxJxcQlYwqPWKVJJtvQiwHgosH/LrLSPA+H4UxpyvSS6jC5aH+5MoHFM+KABgTOt0APue4w66Ha8jCUo9QGg== + dependencies: + accepts "~1.3.7" + array-flatten "1.1.1" + body-parser "1.19.1" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.4.1" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~1.1.2" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "~1.1.2" + fresh "0.5.2" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.9.6" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.17.2" + serve-static "1.14.2" + setprototypeof "1.2.0" + statuses "~1.5.0" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +ext@^1.1.2: + version "1.6.0" + resolved "https://registry.yarnpkg.com/ext/-/ext-1.6.0.tgz#3871d50641e874cc172e2b53f919842d19db4c52" + integrity sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg== + dependencies: + type "^2.5.0" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extend@^3.0.2, extend@~3.0.0, extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +external-editor@^2.0.4: + version "2.2.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5" + integrity sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A== + dependencies: + chardet "^0.4.0" + iconv-lite "^0.4.17" + tmp "^0.0.33" + +extglob@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" + integrity sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE= + dependencies: + is-extglob "^1.0.0" + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== + 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" + +extract-text-webpack-plugin@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/extract-text-webpack-plugin/-/extract-text-webpack-plugin-2.1.0.tgz#69315b885f876dbf96d3819f6a9f1cca7aebf159" + integrity sha1-aTFbiF+Hbb+W04Gfap8cynrr8Vk= + dependencies: + ajv "^4.11.2" + async "^2.1.2" + loader-utils "^1.0.2" + webpack-sources "^0.1.0" + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= + +extsprintf@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" + integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== + +fast-deep-equal@^3.1.1: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-diff@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.1.2.tgz#4b62c42b8e03de3f848460b639079920695d0154" + integrity sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig== + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + +fastparse@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.2.tgz#91728c5a5942eced8531283c79441ee4122c35a9" + integrity sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ== + +faye-websocket@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4" + integrity sha1-TkkvjQTftviQA1B/btvy1QHnxvQ= + dependencies: + websocket-driver ">=0.5.1" + +faye-websocket@~0.11.0: + version "0.11.4" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" + integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== + dependencies: + websocket-driver ">=0.5.1" + +fb-watchman@^1.8.0: + version "1.9.2" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-1.9.2.tgz#a24cf47827f82d38fb59a69ad70b76e3b6ae7383" + integrity sha1-okz0eCf4LTj7Waaa1wt247auc4M= + dependencies: + bser "1.0.2" + +fb-watchman@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.1.tgz#fc84fb39d2709cf3ff6d743706157bb5708a8a85" + integrity sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg== + dependencies: + bser "2.1.1" + +fbjs@^0.8.15, fbjs@^0.8.9: + version "0.8.18" + resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.18.tgz#9835e0addb9aca2eff53295cd79ca1cfc7c9662a" + integrity sha512-EQaWFK+fEPSoibjNy8IxUtaFOMXcWsY0JaVrQoZR9zC8N2Ygf9iDITPWjUTVIax95b6I742JFLqASHfsag/vKA== + dependencies: + core-js "^1.0.0" + isomorphic-fetch "^2.1.1" + loose-envify "^1.0.0" + object-assign "^4.1.0" + promise "^7.1.1" + setimmediate "^1.0.5" + ua-parser-js "^0.7.30" + +figures@^1.3.5: + version "1.7.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" + integrity sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4= + dependencies: + escape-string-regexp "^1.0.5" + object-assign "^4.1.0" + +figures@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" + integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= + dependencies: + escape-string-regexp "^1.0.5" + +file-entry-cache@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" + integrity sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E= + dependencies: + flat-cache "^1.2.1" + object-assign "^4.0.1" + +file-loader@0.11.1: + version "0.11.1" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-0.11.1.tgz#6b328ee1234a729e4e47d36375dd6d35c0e1db84" + integrity sha1-azKO4SNKcp5OR9Njdd1tNcDh24Q= + dependencies: + loader-utils "^1.0.2" + +file-uri-to-path@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" + integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== + +filename-regex@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" + integrity sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY= + +fileset@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/fileset/-/fileset-2.0.3.tgz#8e7548a96d3cc2327ee5e674168723a333bba2a0" + integrity sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA= + dependencies: + glob "^7.0.3" + minimatch "^3.0.3" + +filesize@3.5.10: + version "3.5.10" + resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.5.10.tgz#fc8fa23ddb4ef9e5e0ab6e1e64f679a24a56761f" + integrity sha1-/I+iPdtO+eXgq24eZPZ5okpWdh8= + +fill-range@^2.1.0: + version "2.2.4" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.4.tgz#eb1e773abb056dcd8df2bfdf6af59b8b3a936565" + integrity sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q== + dependencies: + is-number "^2.1.0" + isobject "^2.0.0" + randomatic "^3.0.0" + repeat-element "^1.1.2" + repeat-string "^1.5.2" + +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +finalhandler@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" + integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.3" + statuses "~1.5.0" + unpipe "~1.0.0" + +find-cache-dir@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-0.1.1.tgz#c8defae57c8a52a8a784f9e31c57c742e993a0b9" + integrity sha1-yN765XyKUqinhPnjHFfHQumToLk= + dependencies: + commondir "^1.0.1" + mkdirp "^0.5.1" + pkg-dir "^1.0.0" + +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + +find-up@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= + dependencies: + locate-path "^2.0.0" + +flat-cache@^1.2.1: + version "1.3.4" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.4.tgz#2c2ef77525cc2929007dfffa1dd314aa9c9dee6f" + integrity sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg== + dependencies: + circular-json "^0.3.1" + graceful-fs "^4.1.2" + rimraf "~2.6.2" + write "^0.2.1" + +flatten@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.3.tgz#c1283ac9f27b368abc1e36d1ff7b04501a30356b" + integrity sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg== + +follow-redirects@^1.0.0, follow-redirects@^1.2.3: + version "1.14.7" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.7.tgz#2004c02eb9436eee9a21446a6477debf17e81685" + integrity sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ== + +for-in@^1.0.1, for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= + +for-own@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" + integrity sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4= + dependencies: + for-in "^1.0.1" + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= + +form-data@~2.1.1: + version "2.1.4" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1" + integrity sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE= + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.5" + mime-types "^2.1.12" + +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + 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.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= + dependencies: + map-cache "^0.2.2" + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= + +fs-extra@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-3.0.1.tgz#3794f378c58b342ea7dbbb23095109c4b3b62291" + integrity sha1-N5TzeMWLNC6n27sjCVEJxLO2IpE= + dependencies: + graceful-fs "^4.1.2" + jsonfile "^3.0.0" + universalify "^0.1.0" + +fs-extra@^0.30.0: + version "0.30.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0" + integrity sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A= + dependencies: + graceful-fs "^4.1.2" + jsonfile "^2.1.0" + klaw "^1.0.0" + path-is-absolute "^1.0.0" + rimraf "^2.2.8" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fsevents@1.0.17: + version "1.0.17" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.0.17.tgz#8537f3f12272678765b4fd6528c0f1f66f8f4558" + integrity sha1-hTfz8SJyZ4dltP1lKMDx9m+PRVg= + dependencies: + nan "^2.3.0" + node-pre-gyp "^0.6.29" + +fsevents@^1.0.0, fsevents@^1.2.7: + version "1.2.13" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.13.tgz#f325cb0455592428bcf11b383370ef70e3bfcc38" + integrity sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw== + dependencies: + bindings "^1.5.0" + nan "^2.12.1" + +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-ignore@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/fstream-ignore/-/fstream-ignore-1.0.5.tgz#9c31dae34767018fe1d249b24dada67d092da105" + integrity sha1-nDHa40dnAY/h0kmyTa2mfQktoQU= + dependencies: + fstream "^1.0.0" + inherits "2" + minimatch "^3.0.0" + +fstream@^1.0.0, fstream@^1.0.10, fstream@^1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.12.tgz#4e8ba8ee2d48be4f7d0de505455548eae5932045" + 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.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= + 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" + +generate-function@^2.0.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.3.1.tgz#f069617690c10c868e73b8465746764f97c3479f" + integrity sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ== + dependencies: + is-property "^1.0.2" + +generate-object-property@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0" + integrity sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA= + dependencies: + is-property "^1.0.0" + +get-caller-file@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" + integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== + +get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" + integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + +get-stdin@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" + integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4= + +get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= + +get-symbol-description@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" + integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.1" + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= + dependencies: + assert-plus "^1.0.0" + +glob-base@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" + integrity sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q= + dependencies: + glob-parent "^2.0.0" + is-glob "^2.0.0" + +glob-parent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" + integrity sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg= + dependencies: + is-glob "^2.0.0" + +glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + +glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob@^7.0.0, glob@^7.0.3, glob@^7.1.1, glob@^7.1.3: + version "7.2.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +global-dirs@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445" + integrity sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU= + dependencies: + ini "^1.3.4" + +global-modules@1.0.0, global-modules@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" + integrity sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg== + dependencies: + global-prefix "^1.0.1" + is-windows "^1.0.1" + resolve-dir "^1.0.0" + +global-prefix@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe" + integrity sha1-2/dDxsFJklk8ZVVoy2btMsASLr4= + dependencies: + expand-tilde "^2.0.2" + homedir-polyfill "^1.0.1" + ini "^1.3.4" + is-windows "^1.0.1" + which "^1.2.14" + +globals@^9.14.0, globals@^9.18.0: + version "9.18.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" + integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ== + +globby@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d" + integrity sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0= + dependencies: + array-union "^1.0.1" + arrify "^1.0.0" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +got@^6.7.1: + version "6.7.1" + resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" + integrity sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA= + dependencies: + create-error-class "^3.0.0" + duplexer3 "^0.1.4" + get-stream "^3.0.0" + is-redirect "^1.0.0" + is-retry-allowed "^1.0.0" + is-stream "^1.0.0" + lowercase-keys "^1.0.0" + safe-buffer "^5.0.1" + timed-out "^4.0.0" + unzip-response "^2.0.1" + url-parse-lax "^1.0.0" + +graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9: + version "4.2.9" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96" + integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ== + +growly@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" + integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= + +gzip-size@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-3.0.0.tgz#546188e9bdc337f673772f81660464b389dce520" + integrity sha1-VGGI6b3DN/Zzdy+BZgRks4nc5SA= + dependencies: + duplexer "^0.1.1" + +handle-thing@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-1.2.5.tgz#fd7aad726bf1a5fd16dfc29b2f7a6601d27139c4" + integrity sha1-/Xqtcmvxpf0W38KbL3pmAdJxOcQ= + +handlebars@^4.0.3: + version "4.7.7" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1" + integrity sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA== + dependencies: + minimist "^1.2.5" + neo-async "^2.6.0" + source-map "^0.6.1" + wordwrap "^1.0.0" + optionalDependencies: + uglify-js "^3.1.4" + +har-schema@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e" + integrity sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4= + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= + +har-validator@~4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a" + integrity sha1-M0gdDxu/9gDdID11gSpqX7oALio= + dependencies: + ajv "^4.9.1" + har-schema "^1.0.5" + +har-validator@~5.1.3: + version "5.1.5" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" + 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.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= + dependencies: + ansi-regex "^2.0.0" + +has-bigints@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" + integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== + +has-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + integrity sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo= + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-symbols@^1.0.1, has-symbols@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" + integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== + +has-tostringtag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" + integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== + dependencies: + has-symbols "^1.0.2" + +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +has@^1.0.1, has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +hash-base@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" + integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== + dependencies: + inherits "^2.0.4" + readable-stream "^3.6.0" + safe-buffer "^5.2.0" + +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + +hawk@3.1.3, hawk@~3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" + integrity sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ= + dependencies: + boom "2.x.x" + cryptiles "2.x.x" + hoek "2.x.x" + sntp "1.x.x" + +he@1.2.x: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +hmac-drbg@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +hoek@2.x.x: + version "2.16.3" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" + integrity sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0= + +hoist-non-react-statics@^3.3.0: + version "3.3.2" + resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" + integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== + dependencies: + react-is "^16.7.0" + +home-or-tmp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" + integrity sha1-42w/LSyufXRqhX440Y1fMqeILbg= + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.1" + +homedir-polyfill@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8" + integrity sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA== + dependencies: + parse-passwd "^1.0.0" + +hosted-git-info@^2.1.4: + version "2.8.9" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" + integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== + +hpack.js@^2.1.6: + version "2.1.6" + resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" + integrity sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI= + dependencies: + inherits "^2.0.1" + obuf "^1.0.0" + readable-stream "^2.0.1" + wbuf "^1.1.0" + +html-comment-regex@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.2.tgz#97d4688aeb5c81886a364faa0cad1dda14d433a7" + integrity sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ== + +html-encoding-sniffer@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8" + integrity sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw== + dependencies: + whatwg-encoding "^1.0.1" + +html-entities@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.2.1.tgz#0df29351f0721163515dfb9e5543e5f6eed5162f" + integrity sha1-DfKTUfByEWNRXfueVUPl9u7VFi8= + +html-entities@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.4.0.tgz#cfbd1b01d2afaf9adca1b10ae7dffab98c71d2dc" + integrity sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA== + +html-minifier@^3.2.3: + version "3.5.21" + resolved "https://registry.yarnpkg.com/html-minifier/-/html-minifier-3.5.21.tgz#d0040e054730e354db008463593194015212d20c" + integrity sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA== + dependencies: + camel-case "3.0.x" + clean-css "4.2.x" + commander "2.17.x" + he "1.2.x" + param-case "2.1.x" + relateurl "0.2.x" + uglify-js "3.4.x" + +html-webpack-plugin@2.28.0: + version "2.28.0" + resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-2.28.0.tgz#2e7863b57e5fd48fe263303e2ffc934c3064d009" + integrity sha1-LnhjtX5f1I/iYzA+L/yTTDBk0Ak= + dependencies: + bluebird "^3.4.7" + html-minifier "^3.2.3" + loader-utils "^0.2.16" + lodash "^4.17.3" + pretty-error "^2.0.2" + toposort "^1.0.0" + +htmlparser2@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.1.0.tgz#c4d762b6c3371a05dbe65e94ae43a9f845fb8fb7" + 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.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" + integrity sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc= + +http-errors@1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.8.1.tgz#7c3f28577cbc8a207388455dbd62295ed07bd68c" + integrity sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.1" + +http-errors@~1.6.2: + version "1.6.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= + 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.5" + resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.5.tgz#d7c30d5d3c90d865b4a2e870181f9d6f22ac7ac5" + integrity sha512-x+JVEkO2PoM8qqpbPbOL3cqHPwerep7OwzK7Ay+sMQjKzaKCqWvjoXm5tqMP9tXWWTnTzAjIhXg+J99XYuPhPA== + +http-proxy-middleware@~0.17.4: + version "0.17.4" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.17.4.tgz#642e8848851d66f09d4f124912846dbaeb41b833" + integrity sha1-ZC6ISIUdZvCdTxJJEoRtuutBuDM= + dependencies: + http-proxy "^1.16.2" + is-glob "^3.1.0" + lodash "^4.17.2" + micromatch "^2.3.11" + +http-proxy@^1.16.2: + 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.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" + integrity sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8= + dependencies: + assert-plus "^0.2.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +https-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" + integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= + +iconv-lite@0.4.24, iconv-lite@^0.4.17: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +iconv-lite@^0.6.2: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + +icss-replace-symbols@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz#06ea6f83679a7749e386cfe1fe812ae5db223ded" + integrity sha1-Bupvg2ead0njhs/h/oEq5dsiPe0= + +ieee754@^1.1.4: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + +ignore@^3.2.0: + version "3.3.10" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" + integrity sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug== + +immutable@~3.7.4: + version "3.7.6" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.7.6.tgz#13b4d3cb12befa15482a26fe1b2ebae640071e4b" + integrity sha1-E7TTyxK++hVIKib+Gy665kAHHks= + +import-lazy@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" + integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM= + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + +indent-string@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" + integrity sha1-ji1INIdCEhtKghi3oTfppSBJ3IA= + dependencies: + repeating "^2.0.0" + +indexes-of@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" + integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc= + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +inherits@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +ini@^1.3.4, ini@~1.3.0: + version "1.3.8" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + +inquirer@3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.2.1.tgz#06ceb0f540f45ca548c17d6840959878265fa175" + integrity sha512-QgW3eiPN8gpj/K5vVpHADJJgrrF0ho/dZGylikGX7iqAdRgC9FVKYKWFLx6hZDBFcOLEoSqINYrVPeFAeG/PdA== + dependencies: + ansi-escapes "^2.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" + +inquirer@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-0.12.0.tgz#1ef2bfd63504df0bc75785fff8c2c41df12f077e" + integrity sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34= + dependencies: + ansi-escapes "^1.1.0" + ansi-regex "^2.0.0" + chalk "^1.0.0" + cli-cursor "^1.0.1" + cli-width "^2.0.0" + figures "^1.3.5" + lodash "^4.3.0" + readline2 "^1.0.1" + run-async "^0.1.0" + rx-lite "^3.1.2" + string-width "^1.0.1" + strip-ansi "^3.0.0" + through "^2.3.6" + +internal-slot@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" + integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== + dependencies: + get-intrinsic "^1.1.0" + has "^1.0.3" + side-channel "^1.0.4" + +interpret@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" + integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== + +invariant@^2.2.2, invariant@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== + dependencies: + loose-envify "^1.0.0" + +invert-kv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY= + +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +is-absolute-url@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6" + integrity sha1-UFMN+4T8yap9vnhS6Do3uTufKqY= + +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== + dependencies: + kind-of "^6.0.0" + +is-arguments@^1.0.4: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" + integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + +is-bigint@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" + integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== + dependencies: + has-bigints "^1.0.1" + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= + dependencies: + binary-extensions "^1.0.0" + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-boolean-object@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" + integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + +is-builtin-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" + integrity sha1-VAVy0096wxGfj3bDDLwbHgN6/74= + dependencies: + builtin-modules "^1.0.0" + +is-callable@^1.1.4, is-callable@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" + integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w== + +is-ci@^1.0.10: + version "1.2.1" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c" + integrity sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg== + dependencies: + ci-info "^1.5.0" + +is-core-module@^2.8.1: + version "2.8.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.1.tgz#f59fdfca701d5879d0a6b100a40aa1560ce27211" + integrity sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA== + dependencies: + has "^1.0.3" + +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== + dependencies: + kind-of "^6.0.0" + +is-date-object@^1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" + integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== + dependencies: + has-tostringtag "^1.0.0" + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-directory@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" + integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= + +is-dotfile@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" + integrity sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE= + +is-equal-shallow@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" + integrity sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ= + dependencies: + is-primitive "^2.0.0" + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" + integrity sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA= + +is-extglob@^2.1.0, is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-finite@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.1.0.tgz#904135c77fb42c0641d6aa1bcdbc4daa8da082f3" + integrity sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w== + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + +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@^2.0.0, is-glob@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" + integrity sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM= + dependencies: + is-extglob "^1.0.0" + +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= + dependencies: + is-extglob "^2.1.0" + +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-installed-globally@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.1.0.tgz#0dfd98f5a9111716dd535dda6492f67bf3d25a80" + integrity sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA= + dependencies: + global-dirs "^0.1.0" + is-path-inside "^1.0.0" + +is-my-ip-valid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz#7b351b8e8edd4d3995d4d066680e664d94696824" + integrity sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ== + +is-my-json-valid@^2.10.0: + version "2.20.6" + resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.20.6.tgz#a9d89e56a36493c77bda1440d69ae0dc46a08387" + integrity sha512-1JQwulVNjx8UqkPE/bqDaxtH4PXCe/2VRh/y3p99heOV87HG4Id5/VfDswd+YiAfHcRTfDlWgISycnHuhZq1aw== + dependencies: + generate-function "^2.0.0" + generate-object-property "^1.1.0" + is-my-ip-valid "^1.0.0" + jsonpointer "^5.0.0" + xtend "^4.0.0" + +is-negative-zero@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" + integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== + +is-npm@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" + integrity sha1-8vtjpl5JBbQGyGBydloaTceTufQ= + +is-number-object@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.6.tgz#6a7aaf838c7f0686a50b4553f7e54a96494e89f0" + integrity sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g== + dependencies: + has-tostringtag "^1.0.0" + +is-number@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" + integrity sha1-Afy7s5NGOlSPL0ZszhbezknbkI8= + dependencies: + kind-of "^3.0.2" + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= + dependencies: + kind-of "^3.0.2" + +is-number@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" + integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ== + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-obj@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= + +is-path-cwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" + integrity sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0= + +is-path-in-cwd@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz#5ac48b345ef675339bd6c7a48a912110b241cf52" + integrity sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ== + dependencies: + is-path-inside "^1.0.0" + +is-path-inside@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" + integrity sha1-jvW33lBDej/cprToZe96pVy0gDY= + dependencies: + path-is-inside "^1.0.1" + +is-plain-obj@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= + +is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-posix-bracket@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" + integrity sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q= + +is-primitive@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" + integrity sha1-IHurkWOEmcB7Kt8kCkGochADRXU= + +is-property@^1.0.0, is-property@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" + integrity sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ= + +is-redirect@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" + integrity sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ= + +is-regex@^1.0.4, is-regex@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" + 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.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" + integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg== + +is-retry-allowed@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4" + integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg== + +is-root@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-root/-/is-root-1.0.0.tgz#07b6c233bc394cd9d02ba15c966bd6660d6342d5" + integrity sha1-B7bCM7w5TNnQK6FclmvWZg1jQtU= + +is-shared-array-buffer@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz#97b0c85fbdacb59c9c446fe653b82cf2b5b7cfe6" + integrity sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA== + +is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= + +is-string@^1.0.5, is-string@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" + integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== + dependencies: + has-tostringtag "^1.0.0" + +is-svg@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-2.1.0.tgz#cf61090da0d9efbcab8722deba6f032208dbb0e9" + integrity sha1-z2EJDaDZ77yrhyLeum8DIgjbsOk= + dependencies: + html-comment-regex "^1.1.0" + +is-symbol@^1.0.2, is-symbol@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" + integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== + dependencies: + has-symbols "^1.0.2" + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + +is-utf8@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= + +is-weakref@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" + integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== + dependencies: + call-bind "^1.0.2" + +is-windows@^1.0.1, is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + +is-wsl@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" + integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= + +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + +isomorphic-fetch@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9" + integrity sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk= + dependencies: + node-fetch "^1.0.1" + whatwg-fetch ">=0.10.0" + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= + +istanbul-api@^1.1.1: + version "1.3.7" + resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-1.3.7.tgz#a86c770d2b03e11e3f778cd7aedd82d2722092aa" + integrity sha512-4/ApBnMVeEPG3EkSzcw25wDe4N66wxwn+KKn6b47vyek8Xb3NBAcg4xfuQbS7BqcZuTX4wxfD5lVagdggR3gyA== + dependencies: + async "^2.1.4" + fileset "^2.0.2" + istanbul-lib-coverage "^1.2.1" + istanbul-lib-hook "^1.2.2" + istanbul-lib-instrument "^1.10.2" + istanbul-lib-report "^1.1.5" + istanbul-lib-source-maps "^1.2.6" + istanbul-reports "^1.5.1" + js-yaml "^3.7.0" + mkdirp "^0.5.1" + once "^1.4.0" + +istanbul-lib-coverage@^1.0.1, istanbul-lib-coverage@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.1.tgz#ccf7edcd0a0bb9b8f729feeb0930470f9af664f0" + integrity sha512-PzITeunAgyGbtY1ibVIUiV679EFChHjoMNRibEIobvmrCRaIgwLxNucOSimtNWUhEib/oO7QY2imD75JVgCJWQ== + +istanbul-lib-hook@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.2.2.tgz#bc6bf07f12a641fbf1c85391d0daa8f0aea6bf86" + integrity sha512-/Jmq7Y1VeHnZEQ3TL10VHyb564mn6VrQXHchON9Jf/AEcmQ3ZIiyD1BVzNOKTZf/G3gE+kiGK6SmpF9y3qGPLw== + dependencies: + append-transform "^0.4.0" + +istanbul-lib-instrument@^1.10.1, istanbul-lib-instrument@^1.10.2, istanbul-lib-instrument@^1.4.2: + version "1.10.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.2.tgz#1f55ed10ac3c47f2bdddd5307935126754d0a9ca" + integrity sha512-aWHxfxDqvh/ZlxR8BBaEPVSWDPUkGD63VjGQn3jcw8jCp7sHEMKcrj4xfJn/ABzdMEHiQNyvDQhqm5o8+SQg7A== + dependencies: + babel-generator "^6.18.0" + babel-template "^6.16.0" + babel-traverse "^6.18.0" + babel-types "^6.18.0" + babylon "^6.18.0" + istanbul-lib-coverage "^1.2.1" + semver "^5.3.0" + +istanbul-lib-report@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.5.tgz#f2a657fc6282f96170aaf281eb30a458f7f4170c" + integrity sha512-UsYfRMoi6QO/doUshYNqcKJqVmFe9w51GZz8BS3WB0lYxAllQYklka2wP9+dGZeHYaWIdcXUx8JGdbqaoXRXzw== + dependencies: + istanbul-lib-coverage "^1.2.1" + mkdirp "^0.5.1" + path-parse "^1.0.5" + supports-color "^3.1.2" + +istanbul-lib-source-maps@^1.1.0, istanbul-lib-source-maps@^1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.6.tgz#37b9ff661580f8fca11232752ee42e08c6675d8f" + integrity sha512-TtbsY5GIHgbMsMiRw35YBHGpZ1DVFEO19vxxeiDMYaeOFOCzfnYVxvl6pOUIZR4dtPhAGpSMup8OyF8ubsaqEg== + dependencies: + debug "^3.1.0" + istanbul-lib-coverage "^1.2.1" + mkdirp "^0.5.1" + rimraf "^2.6.1" + source-map "^0.5.3" + +istanbul-reports@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.5.1.tgz#97e4dbf3b515e8c484caea15d6524eebd3ff4e1a" + integrity sha512-+cfoZ0UXzWjhAdzosCPP3AN8vvef8XDkWtTfgaN+7L3YTpNYITnCaEkceo5SEYy644VkHka/P1FvkWvrG/rrJw== + dependencies: + handlebars "^4.0.3" + +jest-changed-files@^20.0.3: + version "20.0.3" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-20.0.3.tgz#9394d5cc65c438406149bef1bf4d52b68e03e3f8" + integrity sha1-k5TVzGXEOEBhSb7xv01Sto4D4/g= + +jest-cli@^20.0.3: + version "20.0.4" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-20.0.4.tgz#e532b19d88ae5bc6c417e8b0593a6fe954b1dc93" + integrity sha1-5TKxnYiuW8bEF+iwWTpv6VSx3JM= + dependencies: + ansi-escapes "^1.4.0" + callsites "^2.0.0" + chalk "^1.1.3" + graceful-fs "^4.1.11" + is-ci "^1.0.10" + istanbul-api "^1.1.1" + istanbul-lib-coverage "^1.0.1" + istanbul-lib-instrument "^1.4.2" + istanbul-lib-source-maps "^1.1.0" + jest-changed-files "^20.0.3" + jest-config "^20.0.4" + jest-docblock "^20.0.3" + jest-environment-jsdom "^20.0.3" + jest-haste-map "^20.0.4" + jest-jasmine2 "^20.0.4" + jest-message-util "^20.0.3" + jest-regex-util "^20.0.3" + jest-resolve-dependencies "^20.0.3" + jest-runtime "^20.0.4" + jest-snapshot "^20.0.3" + jest-util "^20.0.3" + micromatch "^2.3.11" + node-notifier "^5.0.2" + pify "^2.3.0" + slash "^1.0.0" + string-length "^1.0.1" + throat "^3.0.0" + which "^1.2.12" + worker-farm "^1.3.1" + yargs "^7.0.2" + +jest-config@^20.0.4: + version "20.0.4" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-20.0.4.tgz#e37930ab2217c913605eff13e7bd763ec48faeea" + integrity sha1-43kwqyIXyRNgXv8T5712PsSPruo= + dependencies: + chalk "^1.1.3" + glob "^7.1.1" + jest-environment-jsdom "^20.0.3" + jest-environment-node "^20.0.3" + jest-jasmine2 "^20.0.4" + jest-matcher-utils "^20.0.3" + jest-regex-util "^20.0.3" + jest-resolve "^20.0.4" + jest-validate "^20.0.3" + pretty-format "^20.0.3" + +jest-diff@^20.0.3: + version "20.0.3" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-20.0.3.tgz#81f288fd9e675f0fb23c75f1c2b19445fe586617" + integrity sha1-gfKI/Z5nXw+yPHXxwrGURf5YZhc= + dependencies: + chalk "^1.1.3" + diff "^3.2.0" + jest-matcher-utils "^20.0.3" + pretty-format "^20.0.3" + +jest-docblock@^20.0.3: + version "20.0.3" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-20.0.3.tgz#17bea984342cc33d83c50fbe1545ea0efaa44712" + integrity sha1-F76phDQswz2DxQ++FUXqDvqkRxI= + +jest-environment-jsdom@^20.0.3: + version "20.0.3" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-20.0.3.tgz#048a8ac12ee225f7190417713834bb999787de99" + integrity sha1-BIqKwS7iJfcZBBdxODS7mZeH3pk= + dependencies: + jest-mock "^20.0.3" + jest-util "^20.0.3" + jsdom "^9.12.0" + +jest-environment-node@^20.0.3: + version "20.0.3" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-20.0.3.tgz#d488bc4612af2c246e986e8ae7671a099163d403" + integrity sha1-1Ii8RhKvLCRumG6K52caCZFj1AM= + dependencies: + jest-mock "^20.0.3" + jest-util "^20.0.3" + +jest-haste-map@^20.0.4: + version "20.0.5" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-20.0.5.tgz#abad74efb1a005974a7b6517e11010709cab9112" + integrity sha512-0IKAQjUvuZjMCNi/0VNQQF74/H9KB67hsHJqGiwTWQC6XO5Azs7kLWm+6Q/dwuhvDUvABDOBMFK2/FwZ3sZ07Q== + dependencies: + fb-watchman "^2.0.0" + graceful-fs "^4.1.11" + jest-docblock "^20.0.3" + micromatch "^2.3.11" + sane "~1.6.0" + worker-farm "^1.3.1" + +jest-jasmine2@^20.0.4: + version "20.0.4" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-20.0.4.tgz#fcc5b1411780d911d042902ef1859e852e60d5e1" + integrity sha1-/MWxQReA2RHQQpAu8YWehS5g1eE= + dependencies: + chalk "^1.1.3" + graceful-fs "^4.1.11" + jest-diff "^20.0.3" + jest-matcher-utils "^20.0.3" + jest-matchers "^20.0.3" + jest-message-util "^20.0.3" + jest-snapshot "^20.0.3" + once "^1.4.0" + p-map "^1.1.1" + +jest-matcher-utils@^20.0.3: + version "20.0.3" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-20.0.3.tgz#b3a6b8e37ca577803b0832a98b164f44b7815612" + integrity sha1-s6a443yld4A7CDKpixZPRLeBVhI= + dependencies: + chalk "^1.1.3" + pretty-format "^20.0.3" + +jest-matchers@^20.0.3: + version "20.0.3" + resolved "https://registry.yarnpkg.com/jest-matchers/-/jest-matchers-20.0.3.tgz#ca69db1c32db5a6f707fa5e0401abb55700dfd60" + integrity sha1-ymnbHDLbWm9wf6XgQBq7VXAN/WA= + dependencies: + jest-diff "^20.0.3" + jest-matcher-utils "^20.0.3" + jest-message-util "^20.0.3" + jest-regex-util "^20.0.3" + +jest-message-util@^20.0.3: + version "20.0.3" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-20.0.3.tgz#6aec2844306fcb0e6e74d5796c1006d96fdd831c" + integrity sha1-auwoRDBvyw5udNV5bBAG2W/dgxw= + dependencies: + chalk "^1.1.3" + micromatch "^2.3.11" + slash "^1.0.0" + +jest-mock@^20.0.3: + version "20.0.3" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-20.0.3.tgz#8bc070e90414aa155c11a8d64c869a0d5c71da59" + integrity sha1-i8Bw6QQUqhVcEajWTIaaDVxx2lk= + +jest-regex-util@^20.0.3: + version "20.0.3" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-20.0.3.tgz#85bbab5d133e44625b19faf8c6aa5122d085d762" + integrity sha1-hburXRM+RGJbGfr4xqpRItCF12I= + +jest-resolve-dependencies@^20.0.3: + version "20.0.3" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-20.0.3.tgz#6e14a7b717af0f2cb3667c549de40af017b1723a" + integrity sha1-bhSntxevDyyzZnxUneQK8Bexcjo= + dependencies: + jest-regex-util "^20.0.3" + +jest-resolve@^20.0.4: + version "20.0.4" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-20.0.4.tgz#9448b3e8b6bafc15479444c6499045b7ffe597a5" + integrity sha1-lEiz6La6/BVHlETGSZBFt//ll6U= + dependencies: + browser-resolve "^1.11.2" + is-builtin-module "^1.0.0" + resolve "^1.3.2" + +jest-runtime@^20.0.4: + version "20.0.4" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-20.0.4.tgz#a2c802219c4203f754df1404e490186169d124d8" + integrity sha1-osgCIZxCA/dU3xQE5JAYYWnRJNg= + dependencies: + babel-core "^6.0.0" + babel-jest "^20.0.3" + babel-plugin-istanbul "^4.0.0" + chalk "^1.1.3" + convert-source-map "^1.4.0" + graceful-fs "^4.1.11" + jest-config "^20.0.4" + jest-haste-map "^20.0.4" + jest-regex-util "^20.0.3" + jest-resolve "^20.0.4" + jest-util "^20.0.3" + json-stable-stringify "^1.0.1" + micromatch "^2.3.11" + strip-bom "3.0.0" + yargs "^7.0.2" + +jest-snapshot@^20.0.3: + version "20.0.3" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-20.0.3.tgz#5b847e1adb1a4d90852a7f9f125086e187c76566" + integrity sha1-W4R+GtsaTZCFKn+fElCG4YfHZWY= + dependencies: + chalk "^1.1.3" + jest-diff "^20.0.3" + jest-matcher-utils "^20.0.3" + jest-util "^20.0.3" + natural-compare "^1.4.0" + pretty-format "^20.0.3" + +jest-util@^20.0.3: + version "20.0.3" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-20.0.3.tgz#0c07f7d80d82f4e5a67c6f8b9c3fe7f65cfd32ad" + integrity sha1-DAf32A2C9OWmfG+LnD/n9lz9Mq0= + dependencies: + chalk "^1.1.3" + graceful-fs "^4.1.11" + jest-message-util "^20.0.3" + jest-mock "^20.0.3" + jest-validate "^20.0.3" + leven "^2.1.0" + mkdirp "^0.5.1" + +jest-validate@^20.0.3: + version "20.0.3" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-20.0.3.tgz#d0cfd1de4f579f298484925c280f8f1d94ec3cab" + integrity sha1-0M/R3k9XnymEhJJcKA+PHZTsPKs= + dependencies: + chalk "^1.1.3" + jest-matcher-utils "^20.0.3" + leven "^2.1.0" + pretty-format "^20.0.3" + +jest@20.0.3: + version "20.0.3" + resolved "https://registry.yarnpkg.com/jest/-/jest-20.0.3.tgz#e4fd054c4f1170a116a00761da4cfdb73f1cdc33" + integrity sha1-5P0FTE8RcKEWoAdh2kz9tz8c3DM= + dependencies: + jest-cli "^20.0.3" + +js-base64@^2.1.9: + version "2.6.4" + resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.6.4.tgz#f4e686c5de1ea1f867dbcad3d46d969428df98c4" + integrity sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ== + +js-tokens@^3.0.0, js-tokens@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= + +"js-tokens@^3.0.0 || ^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^3.4.3, js-yaml@^3.5.1, js-yaml@^3.7.0: + version "3.14.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +js-yaml@~3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.7.0.tgz#5c967ddd837a9bfdca5f2de84253abe8a1c03b80" + integrity sha1-XJZ93YN6m/3KXy3oQlOr6KHAO4A= + dependencies: + argparse "^1.0.7" + esprima "^2.6.0" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= + +jsdom@^9.12.0: + version "9.12.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-9.12.0.tgz#e8c546fffcb06c00d4833ca84410fed7f8a097d4" + integrity sha1-6MVG//ywbADUgzyoRBD+1/igl9Q= + dependencies: + abab "^1.0.3" + acorn "^4.0.4" + acorn-globals "^3.1.0" + array-equal "^1.0.0" + content-type-parser "^1.0.1" + cssom ">= 0.3.2 < 0.4.0" + cssstyle ">= 0.2.37 < 0.3.0" + escodegen "^1.6.1" + html-encoding-sniffer "^1.0.1" + nwmatcher ">= 1.3.9 < 2.0.0" + parse5 "^1.5.1" + request "^2.79.0" + sax "^1.2.1" + symbol-tree "^3.2.1" + tough-cookie "^2.3.2" + webidl-conversions "^4.0.0" + whatwg-encoding "^1.0.1" + whatwg-url "^4.3.0" + xml-name-validator "^2.0.1" + +jsesc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" + integrity sha1-RsP+yMGJKxKwgz25vHYiF226s0s= + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= + +json-loader@^0.5.4: + version "0.5.7" + resolved "https://registry.yarnpkg.com/json-loader/-/json-loader-0.5.7.tgz#dca14a70235ff82f0ac9a3abeb60d337a365185d" + integrity sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" + integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== + +json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" + integrity sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8= + dependencies: + jsonify "~0.0.0" + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= + +json3@^3.3.2: + version "3.3.3" + resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81" + integrity sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA== + +json5@^0.5.0, json5@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= + +json5@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" + integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== + dependencies: + minimist "^1.2.0" + +jsonfile@^2.1.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" + integrity sha1-NzaitCi4e72gzIO1P6PWM6NcKug= + optionalDependencies: + graceful-fs "^4.1.6" + +jsonfile@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-3.0.1.tgz#a5ecc6f65f53f662c4415c7675a0331d0992ec66" + integrity sha1-pezG9l9T9mLEQVx2daAzHQmS7GY= + optionalDependencies: + graceful-fs "^4.1.6" + +jsonify@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" + integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= + +jsonpointer@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-5.0.0.tgz#f802669a524ec4805fa7389eadbc9921d5dc8072" + integrity sha512-PNYZIdMjVIvVgDSYKTT63Y+KZ6IZvGRNNWcxwD+GNnUz1MKPfv30J8ueCjdwcN0nDx2SlshgyB7Oy0epAzVRRg== + +jsprim@^1.2.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.2.tgz#712c65533a15c878ba59e9ed5f0e26d5b77c5feb" + integrity sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw== + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.4.0" + verror "1.10.0" + +jsx-ast-utils@^1.3.4, jsx-ast-utils@^1.4.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-1.4.1.tgz#3867213e8dd79bf1e8f2300c0cfc1efb182c0df1" + integrity sha1-OGchPo3Xm/Ho8jAMDPwe+xgsDfE= + +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +klaw@^1.0.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" + integrity sha1-QIhDO0azsbolnXh4XY6W9zugJDk= + optionalDependencies: + graceful-fs "^4.1.9" + +latest-version@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15" + integrity sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU= + dependencies: + package-json "^4.0.0" + +lazy-cache@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" + integrity sha1-odePw6UEdMuAhF07O24dpJpEbo4= + +lcid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + integrity sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU= + dependencies: + invert-kv "^1.0.0" + +leven@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580" + integrity sha1-wuep93IJTe6dNCAq6KzORoeHVYA= + +levn@^0.3.0, levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= + 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-fs-cache@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/loader-fs-cache/-/loader-fs-cache-1.0.3.tgz#f08657646d607078be2f0a032f8bd69dd6f277d9" + integrity sha512-ldcgZpjNJj71n+2Mf6yetz+c9bM4xpKtNds4LbqXzU/PTdeAX0g3ytnU1AJMEcTk2Lex4Smpe3Q/eCTsvUBxbA== + dependencies: + find-cache-dir "^0.1.1" + mkdirp "^0.5.1" + +loader-runner@^2.3.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" + integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw== + +loader-utils@^0.2.16: + version "0.2.17" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348" + integrity sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g= + dependencies: + big.js "^3.1.3" + emojis-list "^2.0.0" + json5 "^0.5.0" + object-assign "^4.0.1" + +loader-utils@^1.0.2, loader-utils@^1.x: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" + integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^1.0.1" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +lodash-es@^4.2.1: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee" + integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw== + +lodash._reinterpolate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" + integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= + +lodash.camelcase@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" + integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY= + +lodash.cond@^4.3.0: + version "4.5.2" + resolved "https://registry.yarnpkg.com/lodash.cond/-/lodash.cond-4.5.2.tgz#f471a1da486be60f6ab955d17115523dd1d255d5" + integrity sha1-9HGh2khr5g9quVXRcRVSPdHSVdU= + +lodash.defaults@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" + integrity sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw= + +lodash.memoize@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" + integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= + +lodash.template@^4.4.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab" + integrity sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A== + dependencies: + lodash._reinterpolate "^3.0.0" + lodash.templatesettings "^4.0.0" + +lodash.templatesettings@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz#e481310f049d3cf6d47e912ad09313b154f0fb33" + integrity sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ== + dependencies: + lodash._reinterpolate "^3.0.0" + +lodash.uniq@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" + integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= + +"lodash@>=3.5 <5", lodash@^4.0.0, lodash@^4.15.0, lodash@^4.17.14, lodash@^4.17.2, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +longest@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" + integrity sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc= + +loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1, loose-envify@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + 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.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" + integrity sha1-W0b4AUft7leIcPCG0Eghz5mOVR8= + dependencies: + currently-unhandled "^0.4.1" + signal-exit "^3.0.0" + +lower-case@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac" + integrity sha1-miyr0bno4K6ZOkv31YdcOcQujqw= + +lowercase-keys@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== + +lru-cache@^4.0.1: + version "4.1.5" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" + integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + +make-dir@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" + integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== + dependencies: + pify "^3.0.0" + +makeerror@1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" + integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== + dependencies: + tmpl "1.0.5" + +map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= + +map-obj@^1.0.0, map-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" + integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= + dependencies: + object-visit "^1.0.0" + +math-expression-evaluator@^1.2.14: + version "1.3.9" + resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.3.9.tgz#94e9f39942a2e557ca1133f7136c9ca48a045f8c" + integrity sha512-EDJ6jDSjMZBlOXUI03BwKTTMwigpOzuWQ0RI1XfAcuGDW9jB8/dlOU3Kt1hv4ojI4npJpJXvXBI6NTAZQ0PRPw== + +math-random@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.4.tgz#5dd6943c938548267016d4e34f057583080c514c" + integrity sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A== + +md5.js@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= + +memory-fs@^0.4.0, memory-fs@~0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" + integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI= + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +meow@^3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" + integrity sha1-cstmi0JSKCkKu/qFaJJYcwioAfs= + 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.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= + +merge@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.1.tgz#38bebf80c3220a8a487b6fcfb3941bb11720c145" + integrity sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ== + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= + +micromatch@^2.1.5, micromatch@^2.3.11: + version "2.3.11" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" + integrity sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU= + dependencies: + arr-diff "^2.0.0" + array-unique "^0.2.1" + braces "^1.8.2" + expand-brackets "^0.1.4" + extglob "^0.3.1" + filename-regex "^2.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.1" + kind-of "^3.0.2" + normalize-path "^2.0.1" + object.omit "^2.0.0" + parse-glob "^3.0.4" + regex-cache "^0.4.2" + +micromatch@^3.1.10, micromatch@^3.1.4: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== + 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" + +miller-rabin@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== + dependencies: + bn.js "^4.0.0" + brorand "^1.0.1" + +mime-db@1.51.0, "mime-db@>= 1.43.0 < 2": + version "1.51.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.51.0.tgz#d9ff62451859b18342d960850dc3cfb77e63fb0c" + integrity sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g== + +mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24, mime-types@~2.1.7: + version "2.1.34" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.34.tgz#5a712f9ec1503511a945803640fafe09d3793c24" + integrity sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A== + dependencies: + mime-db "1.51.0" + +mime@1.3.x: + version "1.3.6" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.6.tgz#591d84d3653a6b0b4a3b9df8de5aa8108e72e5e0" + integrity sha1-WR2E02U6awtKO5343lqoEI5y5eA= + +mime@1.6.0, mime@^1.5.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mimic-fn@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" + integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== + +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= + +minimatch@3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774" + integrity sha1-Kk5AkLlrLbBqnX3wEFWmKnfJt3Q= + dependencies: + brace-expansion "^1.0.0" + +minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + +mixin-deep@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" + integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +"mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.5, mkdirp@~0.5.0, mkdirp@~0.5.1: + version "0.5.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== + dependencies: + minimist "^1.2.5" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@2.1.3, ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +mute-stream@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0" + integrity sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA= + +mute-stream@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" + integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= + +nan@^2.12.1, nan@^2.3.0: + version "2.15.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.15.0.tgz#3f34a473ff18e15c1b5626b62903b5ad6e665fee" + integrity sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ== + +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== + 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" + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + +negotiator@0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" + integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== + +neo-async@^2.5.0, neo-async@^2.6.0: + 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.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" + integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= + +no-case@^2.2.0: + version "2.3.2" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac" + integrity sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ== + dependencies: + lower-case "^1.1.1" + +node-fetch@^1.0.1: + version "1.7.3" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" + integrity sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ== + dependencies: + encoding "^0.1.11" + is-stream "^1.0.1" + +node-int64@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" + integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs= + +node-libs-browser@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425" + integrity sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q== + 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-notifier@^5.0.2: + version "5.4.5" + resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.4.5.tgz#0cbc1a2b0f658493b4025775a13ad938e96091ef" + integrity sha512-tVbHs7DyTLtzOiN78izLA85zRqB9NvEXkAf014Vx3jtSvn/xBl6bR8ZYifj+dFcFrKI21huSQgJZ6ZtL3B4HfQ== + dependencies: + growly "^1.3.0" + is-wsl "^1.1.0" + semver "^5.5.0" + shellwords "^0.1.1" + which "^1.3.0" + +node-pre-gyp@^0.6.29: + version "0.6.39" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.39.tgz#c00e96860b23c0e1420ac7befc5044e1d78d8649" + integrity sha512-OsJV74qxnvz/AMGgcfZoDaeDXKD3oY3QVIbBmwszTFkRisTSXbMQyn4UWzUMOtA5SVhrBZOTp0wcoSBgfMfMmQ== + dependencies: + detect-libc "^1.0.2" + hawk "3.1.3" + mkdirp "^0.5.1" + nopt "^4.0.1" + npmlog "^4.0.2" + rc "^1.1.7" + request "2.81.0" + rimraf "^2.6.1" + semver "^5.3.0" + tar "^2.2.1" + tar-pack "^3.4.0" + +nopt@^4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48" + integrity sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg== + dependencies: + abbrev "1" + osenv "^0.1.4" + +normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + 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@^2.0.0, normalize-path@^2.0.1, normalize-path@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= + dependencies: + remove-trailing-separator "^1.0.1" + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +normalize-range@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" + integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI= + +normalize-url@^1.4.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-1.9.1.tgz#2cc0d66b31ea23036458436e3620d85954c66c3c" + integrity sha1-LMDWazHqIwNkWENuNiDYWVTGbDw= + dependencies: + object-assign "^4.0.1" + prepend-http "^1.0.0" + query-string "^4.1.0" + sort-keys "^1.0.0" + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= + dependencies: + path-key "^2.0.0" + +npmlog@^4.0.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + 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.0.1" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.0.1.tgz#2efe162f5c3da06a28959fbd3db75dbeea9f0fc2" + integrity sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w== + dependencies: + boolbase "^1.0.0" + +num2fraction@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" + integrity sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4= + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= + +"nwmatcher@>= 1.3.9 < 2.0.0": + version "1.4.4" + resolved "https://registry.yarnpkg.com/nwmatcher/-/nwmatcher-1.4.4.tgz#2285631f34a95f0d0395cd900c96ed39b58f346e" + integrity sha512-3iuY4N5dhgMpCUrOVnuAdGrgxVqV2cJpM+XNccjR2DKOB1RUP0aA+wGXEiNziG/UKboFyGBIoKOaNlJxx8bciQ== + +oauth-sign@~0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" + integrity sha1-Rqarfwrq2N6unsBWV4C31O/rnUM= + +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + +object-assign@4.1.1, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-hash@^1.1.4: + version "1.3.1" + resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.3.1.tgz#fde452098a951cb145f039bb7d455449ddc126df" + integrity sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA== + +object-inspect@^1.11.0, object-inspect@^1.9.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0" + integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g== + +object-is@^1.0.1: + version "1.1.5" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" + integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +object-keys@^1.0.12, object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= + dependencies: + isobject "^3.0.0" + +object.assign@^4.1.0, object.assign@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" + integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + has-symbols "^1.0.1" + object-keys "^1.1.1" + +object.omit@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" + integrity sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo= + dependencies: + for-own "^0.1.4" + is-extendable "^0.1.1" + +object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= + dependencies: + isobject "^3.0.1" + +obuf@^1.0.0, obuf@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" + integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= + dependencies: + ee-first "1.1.1" + +on-headers@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" + integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== + +once@^1.3.0, once@^1.3.3, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +onetime@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" + integrity sha1-ofeDj4MUxRbwXs78vEzP4EtO14k= + +onetime@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= + dependencies: + mimic-fn "^1.0.0" + +opn@4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/opn/-/opn-4.0.2.tgz#7abc22e644dff63b0a96d5ab7f2790c0f01abc95" + integrity sha1-erwi5kTf9jsKltWrfyeQwPAavJU= + dependencies: + object-assign "^4.0.1" + pinkie-promise "^2.0.0" + +opn@5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/opn/-/opn-5.1.0.tgz#72ce2306a17dbea58ff1041853352b4a8fc77519" + integrity sha512-iPNl7SyM8L30Rm1sjGdLLheyHVw5YXVfi3SKWJzBI7efxRwHojfRFjwE/OLM6qp9xJYMgab8WicTU1cPoY+Hpg== + dependencies: + is-wsl "^1.1.0" + +optionator@^0.8.1, optionator@^0.8.2: + version "0.8.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" + 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" + +original@>=0.0.5: + version "1.0.2" + resolved "https://registry.yarnpkg.com/original/-/original-1.0.2.tgz#e442a61cffe1c5fd20a65f3261c26663b303f25f" + integrity sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg== + dependencies: + url-parse "^1.4.3" + +os-browserify@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" + integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= + +os-homedir@^1.0.0, os-homedir@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= + +os-locale@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" + integrity sha1-IPnxeuKe00XoveWDsT0gCYA8FNk= + 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.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= + +osenv@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" + integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= + +p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== + dependencies: + p-try "^1.0.0" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= + dependencies: + p-limit "^1.1.0" + +p-map@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b" + integrity sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA== + +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= + +package-json@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" + integrity sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0= + dependencies: + got "^6.7.1" + registry-auth-token "^3.0.1" + registry-url "^3.0.3" + semver "^5.1.0" + +pako@~1.0.5: + version "1.0.11" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" + integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== + +param-case@2.1.x: + version "2.1.1" + resolved "https://registry.yarnpkg.com/param-case/-/param-case-2.1.1.tgz#df94fd8cf6531ecf75e6bef9a0858fbc72be2247" + integrity sha1-35T9jPZTHs915r75oIWPvHK+Ikc= + dependencies: + no-case "^2.2.0" + +parchment@^1.1.2, parchment@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/parchment/-/parchment-1.1.4.tgz#aeded7ab938fe921d4c34bc339ce1168bc2ffde5" + integrity sha512-J5FBQt/pM2inLzg4hEWmzQx/8h8D0CiDxaG3vyp9rKrQRSDgBlhjdP5jQGgosEajXPSQouXGHOmVdgo7QmJuOg== + +parse-asn1@^5.0.0, parse-asn1@^5.1.5: + version "5.1.6" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.6.tgz#385080a3ec13cb62a62d39409cb3e88844cdaed4" + integrity sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw== + 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" + +parse-glob@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" + integrity sha1-ssN2z7EfNVE7rdFz7wu246OIORw= + dependencies: + glob-base "^0.3.0" + is-dotfile "^1.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.0" + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= + dependencies: + error-ex "^1.2.0" + +parse-passwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" + integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY= + +parse5@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-1.5.1.tgz#9b7f3b0de32be78dc2401b17573ccaf0f6f59d94" + integrity sha1-m387DeMr543CQBsXVzzK8Pb1nZQ= + +parseurl@~1.3.2, parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= + +path-browserify@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a" + integrity sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ== + +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= + dependencies: + pinkie-promise "^2.0.0" + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + +path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-is-inside@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= + +path-key@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= + +path-parse@^1.0.5, path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= + +path-to-regexp@^1.0.1: + version "1.8.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a" + integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA== + dependencies: + isarray "0.0.1" + +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +pbkdf2@^3.0.3: + version "3.1.2" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" + integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA== + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +performance-now@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" + integrity sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU= + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + +picomatch@^2.0.4, picomatch@^2.2.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pify@^2.0.0, pify@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= + +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= + +pkg-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" + integrity sha1-ektQio1bstYp1EcFb/TpyTFM89Q= + dependencies: + find-up "^1.0.0" + +pkg-up@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-1.0.0.tgz#3e08fb461525c4421624a33b9f7e6d0af5b05a26" + integrity sha1-Pgj7RhUlxEIWJKM7n35tCvWwWiY= + dependencies: + find-up "^1.0.0" + +pluralize@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45" + integrity sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU= + +portfinder@^1.0.9: + version "1.0.28" + resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.28.tgz#67c4622852bd5374dd1dd900f779f53462fac778" + integrity sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA== + dependencies: + async "^2.6.2" + debug "^3.1.1" + mkdirp "^0.5.5" + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= + +postcss-calc@^5.2.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-5.3.1.tgz#77bae7ca928ad85716e2fda42f261bf7c1d65b5e" + integrity sha1-d7rnypKK2FcW4v2kLyYb98HWW14= + dependencies: + postcss "^5.0.2" + postcss-message-helpers "^2.0.0" + reduce-css-calc "^1.2.6" + +postcss-colormin@^2.1.8: + version "2.2.2" + resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-2.2.2.tgz#6631417d5f0e909a3d7ec26b24c8a8d1e4f96e4b" + integrity sha1-ZjFBfV8OkJo9fsJrJMio0eT5bks= + dependencies: + colormin "^1.0.5" + postcss "^5.0.13" + postcss-value-parser "^3.2.3" + +postcss-convert-values@^2.3.4: + version "2.6.1" + resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-2.6.1.tgz#bbd8593c5c1fd2e3d1c322bb925dcae8dae4d62d" + integrity sha1-u9hZPFwf0uPRwyK7kl3K6Nrk1i0= + dependencies: + postcss "^5.0.11" + postcss-value-parser "^3.1.2" + +postcss-discard-comments@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz#befe89fafd5b3dace5ccce51b76b81514be00e3d" + integrity sha1-vv6J+v1bPazlzM5Rt2uBUUvgDj0= + dependencies: + postcss "^5.0.14" + +postcss-discard-duplicates@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-2.1.0.tgz#b9abf27b88ac188158a5eb12abcae20263b91932" + integrity sha1-uavye4isGIFYpesSq8riAmO5GTI= + dependencies: + postcss "^5.0.4" + +postcss-discard-empty@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz#d2b4bd9d5ced5ebd8dcade7640c7d7cd7f4f92b5" + integrity sha1-0rS9nVztXr2Nyt52QMfXzX9PkrU= + dependencies: + postcss "^5.0.14" + +postcss-discard-overridden@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz#8b1eaf554f686fb288cd874c55667b0aa3668d58" + integrity sha1-ix6vVU9ob7KIzYdMVWZ7CqNmjVg= + dependencies: + postcss "^5.0.16" + +postcss-discard-unused@^2.2.1: + version "2.2.3" + resolved "https://registry.yarnpkg.com/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz#bce30b2cc591ffc634322b5fb3464b6d934f4433" + integrity sha1-vOMLLMWR/8Y0Mitfs0ZLbZNPRDM= + dependencies: + postcss "^5.0.14" + uniqs "^2.0.0" + +postcss-filter-plugins@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/postcss-filter-plugins/-/postcss-filter-plugins-2.0.3.tgz#82245fdf82337041645e477114d8e593aa18b8ec" + integrity sha512-T53GVFsdinJhgwm7rg1BzbeBRomOg9y5MBVhGcsV0CxurUdVj1UlPdKtn7aqYA/c/QVkzKMjq2bSV5dKG5+AwQ== + dependencies: + postcss "^5.0.4" + +postcss-flexbugs-fixes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-3.0.0.tgz#7b31cb6c27d0417a35a67914c295f83c403c7ed4" + integrity sha1-ezHLbCfQQXo1pnkUwpX4PEA8ftQ= + dependencies: + postcss "^6.0.1" + +postcss-load-config@^1.x: + version "1.2.0" + resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-1.2.0.tgz#539e9afc9ddc8620121ebf9d8c3673e0ce50d28a" + integrity sha1-U56a/J3chiASHr+djDZz4M5Q0oo= + dependencies: + cosmiconfig "^2.1.0" + object-assign "^4.1.0" + postcss-load-options "^1.2.0" + postcss-load-plugins "^2.3.0" + +postcss-load-options@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/postcss-load-options/-/postcss-load-options-1.2.0.tgz#b098b1559ddac2df04bc0bb375f99a5cfe2b6d8c" + integrity sha1-sJixVZ3awt8EvAuzdfmaXP4rbYw= + dependencies: + cosmiconfig "^2.1.0" + object-assign "^4.1.0" + +postcss-load-plugins@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/postcss-load-plugins/-/postcss-load-plugins-2.3.0.tgz#745768116599aca2f009fad426b00175049d8d92" + integrity sha1-dFdoEWWZrKLwCfrUJrABdQSdjZI= + dependencies: + cosmiconfig "^2.1.1" + object-assign "^4.1.0" + +postcss-loader@2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-2.0.5.tgz#c19d3e8b83eb1ac316f5621ef4c0ef5b3d1b8b3a" + integrity sha1-wZ0+i4PrGsMW9WIe9MDvWz0bizo= + dependencies: + loader-utils "^1.x" + postcss "^6.x" + postcss-load-config "^1.x" + schema-utils "^0.x" + +postcss-merge-idents@^2.1.5: + version "2.1.7" + resolved "https://registry.yarnpkg.com/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz#4c5530313c08e1d5b3bbf3d2bbc747e278eea270" + integrity sha1-TFUwMTwI4dWzu/PSu8dH4njuonA= + dependencies: + has "^1.0.1" + postcss "^5.0.10" + postcss-value-parser "^3.1.1" + +postcss-merge-longhand@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-2.0.2.tgz#23d90cd127b0a77994915332739034a1a4f3d658" + integrity sha1-I9kM0Sewp3mUkVMyc5A0oaTz1lg= + dependencies: + postcss "^5.0.4" + +postcss-merge-rules@^2.0.3: + version "2.1.2" + resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-2.1.2.tgz#d1df5dfaa7b1acc3be553f0e9e10e87c61b5f721" + integrity sha1-0d9d+qexrMO+VT8OnhDofGG19yE= + dependencies: + browserslist "^1.5.2" + caniuse-api "^1.5.2" + postcss "^5.0.4" + postcss-selector-parser "^2.2.2" + vendors "^1.0.0" + +postcss-message-helpers@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-message-helpers/-/postcss-message-helpers-2.0.0.tgz#a4f2f4fab6e4fe002f0aed000478cdf52f9ba60e" + integrity sha1-pPL0+rbk/gAvCu0ABHjN9S+bpg4= + +postcss-minify-font-values@^1.0.2: + version "1.0.5" + resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz#4b58edb56641eba7c8474ab3526cafd7bbdecb69" + integrity sha1-S1jttWZB66fIR0qzUmyv17vey2k= + dependencies: + object-assign "^4.0.1" + postcss "^5.0.4" + postcss-value-parser "^3.0.2" + +postcss-minify-gradients@^1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz#5dbda11373703f83cfb4a3ea3881d8d75ff5e6e1" + integrity sha1-Xb2hE3NwP4PPtKPqOIHY11/15uE= + dependencies: + postcss "^5.0.12" + postcss-value-parser "^3.3.0" + +postcss-minify-params@^1.0.4: + version "1.2.2" + resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz#ad2ce071373b943b3d930a3fa59a358c28d6f1f3" + integrity sha1-rSzgcTc7lDs9kwo/pZo1jCjW8fM= + dependencies: + alphanum-sort "^1.0.1" + postcss "^5.0.2" + postcss-value-parser "^3.0.2" + uniqs "^2.0.0" + +postcss-minify-selectors@^2.0.4: + version "2.1.1" + resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz#b2c6a98c0072cf91b932d1a496508114311735bf" + integrity sha1-ssapjAByz5G5MtGkllCBFDEXNb8= + dependencies: + alphanum-sort "^1.0.2" + has "^1.0.1" + postcss "^5.0.14" + postcss-selector-parser "^2.0.0" + +postcss-modules-extract-imports@^1.0.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.2.1.tgz#dc87e34148ec7eab5f791f7cd5849833375b741a" + integrity sha512-6jt9XZwUhwmRUhb/CkyJY020PYaPJsCyt3UjbaWo6XEbH/94Hmv6MP7fG2C5NDU/BcHzyGYxNtHvM+LTf9HrYw== + dependencies: + postcss "^6.0.1" + +postcss-modules-local-by-default@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz#f7d80c398c5a393fa7964466bd19500a7d61c069" + integrity sha1-99gMOYxaOT+nlkRmvRlQCn1hwGk= + dependencies: + css-selector-tokenizer "^0.7.0" + postcss "^6.0.1" + +postcss-modules-scope@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz#d6ea64994c79f97b62a72b426fbe6056a194bb90" + integrity sha1-1upkmUx5+XtipytCb75gVqGUu5A= + dependencies: + css-selector-tokenizer "^0.7.0" + postcss "^6.0.1" + +postcss-modules-values@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz#ecffa9d7e192518389f42ad0e83f72aec456ea20" + integrity sha1-7P+p1+GSUYOJ9CrQ6D9yrsRW6iA= + dependencies: + icss-replace-symbols "^1.1.0" + postcss "^6.0.1" + +postcss-normalize-charset@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz#ef9ee71212d7fe759c78ed162f61ed62b5cb93f1" + integrity sha1-757nEhLX/nWceO0WL2HtYrXLk/E= + dependencies: + postcss "^5.0.5" + +postcss-normalize-url@^3.0.7: + version "3.0.8" + resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz#108f74b3f2fcdaf891a2ffa3ea4592279fc78222" + integrity sha1-EI90s/L82viRov+j6kWSJ5/HgiI= + dependencies: + is-absolute-url "^2.0.0" + normalize-url "^1.4.0" + postcss "^5.0.14" + postcss-value-parser "^3.2.3" + +postcss-ordered-values@^2.1.0: + version "2.2.3" + resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-2.2.3.tgz#eec6c2a67b6c412a8db2042e77fe8da43f95c11d" + integrity sha1-7sbCpntsQSqNsgQud/6NpD+VwR0= + dependencies: + postcss "^5.0.4" + postcss-value-parser "^3.0.1" + +postcss-reduce-idents@^2.2.2: + version "2.4.0" + resolved "https://registry.yarnpkg.com/postcss-reduce-idents/-/postcss-reduce-idents-2.4.0.tgz#c2c6d20cc958284f6abfbe63f7609bf409059ad3" + integrity sha1-wsbSDMlYKE9qv75j92Cb9AkFmtM= + dependencies: + postcss "^5.0.4" + postcss-value-parser "^3.0.2" + +postcss-reduce-initial@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-1.0.1.tgz#68f80695f045d08263a879ad240df8dd64f644ea" + integrity sha1-aPgGlfBF0IJjqHmtJA343WT2ROo= + dependencies: + postcss "^5.0.4" + +postcss-reduce-transforms@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz#ff76f4d8212437b31c298a42d2e1444025771ae1" + integrity sha1-/3b02CEkN7McKYpC0uFEQCV3GuE= + dependencies: + has "^1.0.1" + postcss "^5.0.8" + postcss-value-parser "^3.0.1" + +postcss-selector-parser@^2.0.0, postcss-selector-parser@^2.2.2: + version "2.2.3" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz#f9437788606c3c9acee16ffe8d8b16297f27bb90" + integrity sha1-+UN3iGBsPJrO4W/+jYsWKX8nu5A= + dependencies: + flatten "^1.0.2" + indexes-of "^1.0.1" + uniq "^1.0.1" + +postcss-svgo@^2.1.1: + version "2.1.6" + resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-2.1.6.tgz#b6df18aa613b666e133f08adb5219c2684ac108d" + integrity sha1-tt8YqmE7Zm4TPwittSGcJoSsEI0= + dependencies: + is-svg "^2.0.0" + postcss "^5.0.14" + postcss-value-parser "^3.2.3" + svgo "^0.7.0" + +postcss-unique-selectors@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz#981d57d29ddcb33e7b1dfe1fd43b8649f933ca1d" + integrity sha1-mB1X0p3csz57Hf4f1DuGSfkzyh0= + dependencies: + alphanum-sort "^1.0.1" + postcss "^5.0.4" + uniqs "^2.0.0" + +postcss-value-parser@^3.0.1, postcss-value-parser@^3.0.2, postcss-value-parser@^3.1.1, postcss-value-parser@^3.1.2, postcss-value-parser@^3.2.3, postcss-value-parser@^3.3.0: + version "3.3.1" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" + integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== + +postcss-zindex@^2.0.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/postcss-zindex/-/postcss-zindex-2.2.0.tgz#d2109ddc055b91af67fc4cb3b025946639d2af22" + integrity sha1-0hCd3AVbka9n/EyzsCWUZjnSryI= + dependencies: + has "^1.0.1" + postcss "^5.0.4" + uniqs "^2.0.0" + +postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0.13, postcss@^5.0.14, postcss@^5.0.16, postcss@^5.0.2, postcss@^5.0.4, postcss@^5.0.5, postcss@^5.0.6, postcss@^5.0.8, postcss@^5.2.16: + version "5.2.18" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-5.2.18.tgz#badfa1497d46244f6390f58b319830d9107853c5" + integrity sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg== + dependencies: + chalk "^1.1.3" + js-base64 "^2.1.9" + source-map "^0.5.6" + supports-color "^3.2.3" + +postcss@^6.0.1, postcss@^6.x: + version "6.0.23" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.23.tgz#61c82cc328ac60e677645f979054eb98bc0e3324" + integrity sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag== + dependencies: + chalk "^2.4.1" + source-map "^0.6.1" + supports-color "^5.4.0" + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= + +prepend-http@^1.0.0, prepend-http@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" + integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= + +preserve@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" + integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks= + +pretty-bytes@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-4.0.2.tgz#b2bf82e7350d65c6c33aa95aaa5a4f6327f61cd9" + integrity sha1-sr+C5zUNZcbDOqlaqlpPYyf2HNk= + +pretty-error@^2.0.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-2.1.2.tgz#be89f82d81b1c86ec8fdfbc385045882727f93b6" + integrity sha512-EY5oDzmsX5wvuynAByrmY0P0hcp+QpnAKbJng2A2MPjVKXCxrDSUkzghVJ4ZGPIv+JC4gX8fPUWscC0RtjsWGw== + dependencies: + lodash "^4.17.20" + renderkid "^2.0.4" + +pretty-format@^20.0.3: + version "20.0.3" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-20.0.3.tgz#020e350a560a1fe1a98dc3beb6ccffb386de8b14" + integrity sha1-Ag41ClYKH+GpjcO+tsz/s4beixQ= + dependencies: + ansi-regex "^2.1.1" + ansi-styles "^3.0.0" + +private@^0.1.6, private@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" + integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= + +progress@^1.1.8: + version "1.1.8" + resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be" + integrity sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74= + +promise@7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/promise/-/promise-7.1.1.tgz#489654c692616b8aa55b0724fa809bb7db49c5bf" + integrity sha1-SJZUxpJha4qlWwck+oCbt9tJxb8= + dependencies: + asap "~2.0.3" + +promise@^7.1.1: + version "7.3.1" + resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" + integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg== + dependencies: + asap "~2.0.3" + +prop-types@^15.5.10, prop-types@^15.6.1: + version "15.8.1" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" + integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.13.1" + +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= + +pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= + +psl@^1.1.28: + version "1.8.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" + integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== + +public-encrypt@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" + integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== + 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" + +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= + +punycode@^1.2.4, punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= + +punycode@^2.1.0, punycode@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +q@^1.1.2: + version "1.5.1" + resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" + integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= + +qs@6.9.6: + version "6.9.6" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.6.tgz#26ed3c8243a431b2924aca84cc90471f35d5a0ee" + integrity sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ== + +qs@~6.4.0: + version "6.4.1" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.1.tgz#2bad97710a5b661c366b378b1e3a44a592ff45e6" + integrity sha512-LQy1Q1fcva/UsnP/6Iaa4lVeM49WiOitu2T4hZCyA/elLKu37L99qcBJk4VCCk+rdLvnMzfKyiN3SZTqdAZGSQ== + +qs@~6.5.2: + version "6.5.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad" + integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA== + +query-string@^4.1.0: + version "4.3.4" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-4.3.4.tgz#bbb693b9ca915c232515b228b1a02b609043dbeb" + integrity sha1-u7aTucqRXCMlFbIosaArYJBD2+s= + dependencies: + object-assign "^4.1.0" + strict-uri-encode "^1.0.0" + +querystring-es3@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" + integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM= + +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= + +querystringify@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" + integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== + +quill-delta@^3.6.2: + version "3.6.3" + resolved "https://registry.yarnpkg.com/quill-delta/-/quill-delta-3.6.3.tgz#b19fd2b89412301c60e1ff213d8d860eac0f1032" + integrity sha512-wdIGBlcX13tCHOXGMVnnTVFtGRLoP0imqxM696fIPwIf5ODIYUHIvHbZcyvGlZFiFhK5XzDC2lpjbxRhnM05Tg== + dependencies: + deep-equal "^1.0.1" + extend "^3.0.2" + fast-diff "1.1.2" + +quill@^1.3.7: + version "1.3.7" + resolved "https://registry.yarnpkg.com/quill/-/quill-1.3.7.tgz#da5b2f3a2c470e932340cdbf3668c9f21f9286e8" + integrity sha512-hG/DVzh/TiknWtE6QmWAF/pxoZKYxfe3J/d/+ShUWkDvvkZQVTPeVmUJVu1uE6DDooC4fWTiCLh84ul89oNz5g== + dependencies: + clone "^2.1.1" + deep-equal "^1.0.1" + eventemitter3 "^2.0.3" + extend "^3.0.2" + parchment "^1.1.4" + quill-delta "^3.6.2" + +randomatic@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.1.1.tgz#b776efc59375984e36c537b2f51a1f0aff0da1ed" + integrity sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw== + dependencies: + is-number "^4.0.0" + kind-of "^6.0.0" + math-random "^1.0.1" + +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +randomfill@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== + dependencies: + randombytes "^2.0.5" + safe-buffer "^5.1.0" + +range-parser@^1.0.3, range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.2.tgz#baf3e9c21eebced59dd6533ac872b71f7b61cb32" + integrity sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ== + dependencies: + bytes "3.1.1" + http-errors "1.8.1" + iconv-lite "0.4.24" + unpipe "1.0.0" + +rc@^1.0.1, rc@^1.1.6, rc@^1.1.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +react-dev-utils@^3.0.0, react-dev-utils@^3.1.0: + version "3.1.3" + resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-3.1.3.tgz#3883b15892213f7852a279128e0469a785608e8e" + integrity sha512-ycJvru3DaeJiCyHyHJiqp2FOBTY1PeLdWnptskgx5GiavgsvKyRYpJfrxCm3X9qMDJJmyP/+qyvCrBAsHUBfZQ== + dependencies: + address "1.0.2" + anser "1.4.1" + babel-code-frame "6.22.0" + chalk "1.1.3" + cross-spawn "5.1.0" + detect-port-alt "1.1.3" + escape-string-regexp "1.0.5" + filesize "3.5.10" + global-modules "1.0.0" + gzip-size "3.0.0" + html-entities "1.2.1" + inquirer "3.2.1" + is-root "1.0.0" + opn "5.1.0" + recursive-readdir "2.2.1" + shell-quote "1.6.1" + sockjs-client "1.1.4" + strip-ansi "3.0.1" + text-table "0.2.0" + +react-dom-factories@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/react-dom-factories/-/react-dom-factories-1.0.2.tgz#eb7705c4db36fb501b3aa38ff759616aa0ff96e0" + integrity sha1-63cFxNs2+1AbOqOP91lhaqD/luA= + +react-dom@^15.6.0: + version "15.7.0" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-15.7.0.tgz#39106dee996d0742fb0f43d567ef8b8153483ab2" + integrity sha512-mpjXqC2t1FuYsILOLCj0kg6pbg460byZkVA/80VtDmKU/pYmoTdHOtaMcTRIDiyXLz4sIur0cQ04nOC6iGndJg== + dependencies: + fbjs "^0.8.9" + loose-envify "^1.1.0" + object-assign "^4.1.0" + prop-types "^15.5.10" + +react-error-overlay@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-1.0.10.tgz#da8cd1eafac41afdca2a33792b23694ef6c528f1" + integrity sha512-/fzpqRGPWlpDvvBwLN7vjE4FAI81ajbWowkrycY8P5RGqE49WIUMIdFjTS5htqJfzxcM599k/x1lCayaq+4qEw== + dependencies: + anser "1.4.1" + babel-code-frame "6.22.0" + babel-runtime "6.23.0" + react-dev-utils "^3.1.0" + settle-promise "1.0.0" + source-map "0.5.6" + +react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== + +react-lifecycles-compat@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" + integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== + +react-quill@^1.3.5: + version "1.3.5" + resolved "https://registry.yarnpkg.com/react-quill/-/react-quill-1.3.5.tgz#8c4ad759da03365b17c79c6c52afa9772259844e" + integrity sha512-/W/rNCW+6QpGz8yQ9tFK5Ka/h/No1RqrcOOvCIOR092OiKzRFlU2xbPEwiP3Wgy/Dx13pi1YhjReDMX/5uotJg== + dependencies: + "@types/quill" "1.3.10" + create-react-class "^15.6.0" + lodash "^4.17.4" + prop-types "^15.5.10" + quill "^1.3.7" + react-dom-factories "^1.0.0" + +react-redux@^5.0.5: + version "5.1.2" + resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-5.1.2.tgz#b19cf9e21d694422727bf798e934a916c4080f57" + integrity sha512-Ns1G0XXc8hDyH/OcBHOxNgQx9ayH3SPxBnFCOidGKSle8pKihysQw2rG/PmciUQRoclhVBO8HMhiRmGXnDja9Q== + dependencies: + "@babel/runtime" "^7.1.2" + hoist-non-react-statics "^3.3.0" + invariant "^2.2.4" + loose-envify "^1.1.0" + prop-types "^15.6.1" + react-is "^16.6.0" + react-lifecycles-compat "^3.0.0" + +react-scripts@1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/react-scripts/-/react-scripts-1.0.7.tgz#fe1436dda03bb45465c76d097cfea4f32eb7cbbb" + integrity sha1-/hQ23aA7tFRlx20JfP6k8y63y7s= + dependencies: + autoprefixer "7.1.0" + babel-core "6.24.1" + babel-eslint "7.2.3" + babel-jest "20.0.3" + babel-loader "7.0.0" + babel-preset-react-app "^3.0.0" + babel-runtime "6.23.0" + case-sensitive-paths-webpack-plugin "1.1.4" + chalk "1.1.3" + css-loader "0.28.1" + dotenv "4.0.0" + eslint "3.19.0" + eslint-config-react-app "^1.0.4" + eslint-loader "1.7.1" + eslint-plugin-flowtype "2.33.0" + eslint-plugin-import "2.2.0" + eslint-plugin-jsx-a11y "5.0.3" + eslint-plugin-react "7.0.1" + extract-text-webpack-plugin "2.1.0" + file-loader "0.11.1" + fs-extra "3.0.1" + html-webpack-plugin "2.28.0" + jest "20.0.3" + object-assign "4.1.1" + postcss-flexbugs-fixes "3.0.0" + postcss-loader "2.0.5" + promise "7.1.1" + react-dev-utils "^3.0.0" + react-error-overlay "^1.0.7" + style-loader "0.17.0" + sw-precache-webpack-plugin "0.9.1" + url-loader "0.5.8" + webpack "2.6.1" + webpack-dev-server "2.4.5" + webpack-manifest-plugin "1.1.0" + whatwg-fetch "2.0.3" + optionalDependencies: + fsevents "1.0.17" + +react-throbber@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/react-throbber/-/react-throbber-1.0.4.tgz#d46adf5a83914900cc1fff613326d68f2ce60080" + integrity sha1-1GrfWoORSQDMH/9hMybWjyzmAIA= + dependencies: + react "^15.4.2" + +react@^15.4.2, react@^15.6.0: + version "15.7.0" + resolved "https://registry.yarnpkg.com/react/-/react-15.7.0.tgz#10308fd42ac6912a250bf00380751abc41ac7106" + integrity sha512-5/MMRYmpmM0sMTHGLossnJCrmXQIiJilD6y3YN3TzAwGFj6zdnMtFv6xmi65PHKRV+pehIHpT7oy67Sr6s9AHA== + dependencies: + create-react-class "^15.6.0" + fbjs "^0.8.9" + loose-envify "^1.1.0" + object-assign "^4.1.0" + prop-types "^15.5.10" + +read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + +read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= + 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.2, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.2.2, readable-stream@^2.2.9, readable-stream@^2.3.3, readable-stream@^2.3.6: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + 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.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readdirp@^2.0.0, readdirp@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== + dependencies: + graceful-fs "^4.1.11" + micromatch "^3.1.10" + readable-stream "^2.0.2" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +readline2@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/readline2/-/readline2-1.0.1.tgz#41059608ffc154757b715d9989d199ffbf372e35" + integrity sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU= + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + mute-stream "0.0.5" + +rechoir@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" + integrity sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q= + dependencies: + resolve "^1.1.6" + +recursive-readdir@2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.1.tgz#90ef231d0778c5ce093c9a48d74e5c5422d13a99" + integrity sha1-kO8jHQd4xc4JPJpI105cVCLROpk= + dependencies: + minimatch "3.0.3" + +redent@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" + integrity sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94= + dependencies: + indent-string "^2.1.0" + strip-indent "^1.0.1" + +reduce-css-calc@^1.2.6: + version "1.3.0" + resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz#747c914e049614a4c9cfbba629871ad1d2927716" + integrity sha1-dHyRTgSWFKTJz7umKYca0dKSdxY= + dependencies: + balanced-match "^0.4.2" + math-expression-evaluator "^1.2.14" + reduce-function-call "^1.0.1" + +reduce-function-call@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/reduce-function-call/-/reduce-function-call-1.0.3.tgz#60350f7fb252c0a67eb10fd4694d16909971300f" + integrity sha512-Hl/tuV2VDgWgCSEeWMLwxLZqX7OK59eU1guxXsRKTAyeYimivsKdtcV4fu3r710tpG5GmDKDhQ0HSZLExnNmyQ== + dependencies: + balanced-match "^1.0.0" + +redux-thunk@^2.2.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.4.1.tgz#0dd8042cf47868f4b29699941de03c9301a75714" + integrity sha512-OOYGNY5Jy2TWvTL1KgAlVy6dcx3siPJ1wTq741EPyUKfn6W6nChdICjZwCd0p8AZBs5kWpZlbkXW2nE/zjUa+Q== + +redux@^3.6.0: + version "3.7.2" + resolved "https://registry.yarnpkg.com/redux/-/redux-3.7.2.tgz#06b73123215901d25d065be342eb026bc1c8537b" + integrity sha512-pNqnf9q1hI5HHZRBkj3bAngGZW/JMCmexDlOxw4XagXY2o1327nHH54LoTjiPJ0gizoqPDRqWyX/00g0hD6w+A== + dependencies: + lodash "^4.2.1" + lodash-es "^4.2.1" + loose-envify "^1.1.0" + symbol-observable "^1.0.3" + +regenerate@^1.2.1: + version "1.4.2" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" + integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== + +regenerator-runtime@^0.10.0: + version "0.10.5" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" + integrity sha1-M2w+/BIgrc7dosn6tntaeVWjNlg= + +regenerator-runtime@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" + integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== + +regenerator-runtime@^0.13.4: + version "0.13.9" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" + integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== + +regenerator-transform@^0.10.0: + version "0.10.1" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" + integrity sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q== + dependencies: + babel-runtime "^6.18.0" + babel-types "^6.19.0" + private "^0.1.6" + +regex-cache@^0.4.2: + version "0.4.4" + resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" + integrity sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ== + dependencies: + is-equal-shallow "^0.1.3" + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + +regexp.prototype.flags@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.1.tgz#b3f4c0059af9e47eca9f3f660e51d81307e72307" + integrity sha512-pMR7hBVUUGI7PMA37m2ofIdQCsomVnas+Jn5UPGAHQ+/LlwKm/aTLJHdasmHRzlfeZwHiAOaRSo2rbBDm3nNUQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +regexpu-core@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" + integrity sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA= + dependencies: + regenerate "^1.2.1" + regjsgen "^0.2.0" + regjsparser "^0.1.4" + +registry-auth-token@^3.0.1: + version "3.4.0" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.4.0.tgz#d7446815433f5d5ed6431cd5dca21048f66b397e" + integrity sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A== + dependencies: + rc "^1.1.6" + safe-buffer "^5.0.1" + +registry-url@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942" + integrity sha1-PU74cPc93h138M+aOBQyRE4XSUI= + dependencies: + rc "^1.0.1" + +regjsgen@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" + integrity sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc= + +regjsparser@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" + integrity sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw= + dependencies: + jsesc "~0.5.0" + +relateurl@0.2.x: + version "0.2.7" + resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" + integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk= + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= + +renderkid@^2.0.4: + 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" + +repeat-element@^1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.4.tgz#be681520847ab58c7568ac75fbfad28ed42d39e9" + integrity sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ== + +repeat-string@^1.5.2, repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= + +repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo= + dependencies: + is-finite "^1.0.0" + +request@2.81.0: + version "2.81.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" + integrity sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA= + dependencies: + aws-sign2 "~0.6.0" + aws4 "^1.2.1" + caseless "~0.12.0" + combined-stream "~1.0.5" + extend "~3.0.0" + forever-agent "~0.6.1" + form-data "~2.1.1" + har-validator "~4.2.1" + hawk "~3.1.3" + http-signature "~1.1.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.7" + oauth-sign "~0.8.1" + performance-now "^0.2.0" + qs "~6.4.0" + safe-buffer "^5.0.1" + stringstream "~0.0.4" + tough-cookie "~2.3.0" + tunnel-agent "^0.6.0" + uuid "^3.0.0" + +request@^2.79.0: + version "2.88.2" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" + 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.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +require-from-string@^1.1.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-1.2.1.tgz#529c9ccef27380adfec9a2f965b649bbee636418" + integrity sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg= + +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= + +require-uncached@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" + integrity sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM= + dependencies: + caller-path "^0.1.0" + resolve-from "^1.0.0" + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= + +resolve-dir@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" + integrity sha1-eaQGRMNivoLybv/nOcm7U4IEb0M= + dependencies: + expand-tilde "^2.0.0" + global-modules "^1.0.0" + +resolve-from@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" + integrity sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY= + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= + +resolve@1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" + integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= + +resolve@^1.1.6, resolve@^1.10.0, resolve@^1.3.2: + version "1.22.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" + integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw== + dependencies: + is-core-module "^2.8.1" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +restore-cursor@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541" + integrity sha1-NGYfRohjJ/7SmRR5FSJS35LapUE= + dependencies: + exit-hook "^1.0.0" + onetime "^1.0.0" + +restore-cursor@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= + dependencies: + onetime "^2.0.0" + signal-exit "^3.0.2" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + +right-align@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" + integrity sha1-YTObci/mo1FWiSENJOFMlhSGE+8= + dependencies: + align-text "^0.1.1" + +rimraf@2, rimraf@^2.2.8, rimraf@^2.5.1, rimraf@^2.6.1: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + +rimraf@~2.6.2: + version "2.6.3" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" + integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== + dependencies: + glob "^7.1.3" + +ripemd160@^2.0.0, ripemd160@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + +run-async@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-0.1.0.tgz#c8ad4a5e110661e402a7d21b530e009f25f8e389" + integrity sha1-yK1KXhEGYeQCp9IbUw4AnyX444k= + dependencies: + once "^1.3.0" + +run-async@^2.2.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" + integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== + +rx-lite-aggregates@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be" + integrity sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74= + dependencies: + rx-lite "*" + +rx-lite@*, rx-lite@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444" + integrity sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ= + +rx-lite@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102" + integrity sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI= + +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + 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.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= + dependencies: + ret "~0.1.10" + +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +sane@~1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/sane/-/sane-1.6.0.tgz#9610c452307a135d29c1fdfe2547034180c46775" + integrity sha1-lhDEUjB6E10pwf3+JUcDQYDEZ3U= + dependencies: + anymatch "^1.3.0" + exec-sh "^0.2.0" + fb-watchman "^1.8.0" + minimatch "^3.0.2" + minimist "^1.1.1" + walker "~1.0.5" + watch "~0.10.0" + +sax@^1.2.1, sax@~1.2.1: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + +schema-utils@^0.x: + version "0.4.7" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.7.tgz#ba74f597d2be2ea880131746ee17d0a093c68187" + integrity sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ== + dependencies: + ajv "^6.1.0" + ajv-keywords "^3.1.0" + +select-hose@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" + integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= + +semver-diff@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" + integrity sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY= + dependencies: + semver "^5.0.3" + +"semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.5.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +send@0.17.2: + version "0.17.2" + resolved "https://registry.yarnpkg.com/send/-/send-0.17.2.tgz#926622f76601c41808012c8bf1688fe3906f7820" + integrity sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww== + dependencies: + debug "2.6.9" + depd "~1.1.2" + destroy "~1.0.4" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "1.8.1" + mime "1.6.0" + ms "2.1.3" + on-finished "~2.3.0" + range-parser "~1.2.1" + statuses "~1.5.0" + +serve-index@^1.7.2: + version "1.9.1" + resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" + integrity sha1-03aNabHn2C5c4FD/9bRTvqEqkjk= + 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.14.2: + version "1.14.2" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.2.tgz#722d6294b1d62626d41b43a013ece4598d292bfa" + integrity sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.17.2" + +serviceworker-cache-polyfill@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/serviceworker-cache-polyfill/-/serviceworker-cache-polyfill-4.0.0.tgz#de19ee73bef21ab3c0740a37b33db62464babdeb" + integrity sha1-3hnuc77yGrPAdAo3sz22JGS6ves= + +set-blocking@^2.0.0, set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + +set-value@^2.0.0, set-value@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" + integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +setimmediate@^1.0.4, setimmediate@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +settle-promise@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/settle-promise/-/settle-promise-1.0.0.tgz#697adb58b821f387ce2757c06efc9de5f0ee33d8" + integrity sha1-aXrbWLgh84fOJ1fAbvyd5fDuM9g= + +sha.js@^2.4.0, sha.js@^2.4.8: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= + +shell-quote@1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.6.1.tgz#f4781949cce402697127430ea3b3c5476f481767" + integrity sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c= + dependencies: + array-filter "~0.0.0" + array-map "~0.0.0" + array-reduce "~0.0.0" + jsonify "~0.0.0" + +shelljs@^0.7.5: + version "0.7.8" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.8.tgz#decbcf874b0d1e5fb72e14b164a9683048e9acb3" + integrity sha1-3svPh0sNHl+3LhSxZKloMEjprLM= + dependencies: + glob "^7.0.0" + interpret "^1.0.0" + rechoir "^0.6.2" + +shellwords@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" + integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== + +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + 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: + version "3.0.6" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.6.tgz#24e630c4b0f03fea446a2bd299e62b4a6ca8d0af" + integrity sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ== + +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= + +slice-ansi@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" + integrity sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU= + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== + 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" + +sntp@1.x.x: + version "1.0.9" + resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" + integrity sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg= + dependencies: + hoek "2.x.x" + +sockjs-client@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.1.2.tgz#f0212a8550e4c9468c8cceaeefd2e3493c033ad5" + integrity sha1-8CEqhVDkyUaMjM6u79LjSTwDOtU= + dependencies: + debug "^2.2.0" + eventsource "0.1.6" + faye-websocket "~0.11.0" + inherits "^2.0.1" + json3 "^3.3.2" + url-parse "^1.1.1" + +sockjs-client@1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.1.4.tgz#5babe386b775e4cf14e7520911452654016c8b12" + integrity sha1-W6vjhrd15M8U51IJEUUmVAFsixI= + dependencies: + debug "^2.6.6" + eventsource "0.1.6" + faye-websocket "~0.11.0" + inherits "^2.0.1" + json3 "^3.3.2" + url-parse "^1.1.8" + +sockjs@0.3.18: + version "0.3.18" + resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.18.tgz#d9b289316ca7df77595ef299e075f0f937eb4207" + integrity sha1-2bKJMWyn33dZXvKZ4HXw+TfrQgc= + dependencies: + faye-websocket "^0.10.0" + uuid "^2.0.2" + +sort-keys@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" + integrity sha1-RBttTTRnmPG05J6JIK37oOVD+a0= + dependencies: + is-plain-obj "^1.0.0" + +source-list-map@^0.1.7, source-list-map@~0.1.7: + version "0.1.8" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-0.1.8.tgz#c550b2ab5427f6b3f21f5afead88c4f5587b2106" + integrity sha1-xVCyq1Qn9rPyH1r+rYjE9Vh7IQY= + +source-list-map@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-1.1.2.tgz#9889019d1024cce55cdc069498337ef6186a11a1" + integrity sha1-mIkBnRAkzOVc3AaUmDN+9hhqEaE= + +source-map-resolve@^0.5.0: + version "0.5.3" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" + 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.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" + integrity sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA== + dependencies: + source-map "^0.5.6" + +source-map-url@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" + integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== + +source-map@0.5.6: + version "0.5.6" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" + integrity sha1-dc449SvwczxafwwRjYEzSiu19BI= + +source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7, source-map@~0.5.1, source-map@~0.5.3: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + +source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +spdx-correct@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" + 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.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" + integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== + +spdx-expression-parse@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + 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.11" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz#50c0d8c40a14ec1bf449bae69a0ea4685a9d9f95" + integrity sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g== + +spdy-transport@^2.0.18: + version "2.1.1" + resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-2.1.1.tgz#c54815d73858aadd06ce63001e7d25fa6441623b" + integrity sha512-q7D8c148escoB3Z7ySCASadkegMmUZW8Wb/Q1u0/XBgDKMO880rLQDj8Twiew/tYi7ghemKUi/whSYOwE17f5Q== + dependencies: + debug "^2.6.8" + detect-node "^2.0.3" + hpack.js "^2.1.6" + obuf "^1.1.1" + readable-stream "^2.2.9" + safe-buffer "^5.0.1" + wbuf "^1.7.2" + +spdy@^3.4.1: + version "3.4.7" + resolved "https://registry.yarnpkg.com/spdy/-/spdy-3.4.7.tgz#42ff41ece5cc0f99a3a6c28aabb73f5c3b03acbc" + integrity sha1-Qv9B7OXMD5mjpsKKq7c/XDsDrLw= + dependencies: + debug "^2.6.8" + handle-thing "^1.2.5" + http-deceiver "^1.2.7" + safe-buffer "^5.0.1" + select-hose "^2.0.0" + spdy-transport "^2.0.18" + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== + dependencies: + extend-shallow "^3.0.0" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +sshpk@^1.7.0: + version "1.17.0" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.17.0.tgz#578082d92d4fe612b13007496e543fa0fbcbe4c5" + 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" + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@~1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + +stream-browserify@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" + integrity sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg== + dependencies: + inherits "~2.0.1" + readable-stream "^2.0.2" + +stream-http@^2.7.2: + version "2.8.3" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" + integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw== + 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" + +strict-uri-encode@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" + integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= + +string-length@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-1.0.1.tgz#56970fb1c38558e9e70b728bf3de269ac45adfac" + integrity sha1-VpcPscOFWOnnC3KL894mmsRa36w= + dependencies: + strip-ansi "^3.0.0" + +string-width@^1.0.1, string-width@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= + 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": + 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.0.0, string-width@^2.1.0, string-width@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string.prototype.trimend@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" + integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +string.prototype.trimstart@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" + integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +string_decoder@^1.0.0, string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +stringstream@~0.0.4: + version "0.0.6" + resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.6.tgz#7880225b0d4ad10e30927d167a1d6f2fd3b33a72" + integrity sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA== + +strip-ansi@3.0.1, strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= + dependencies: + ansi-regex "^3.0.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@3.0.0, strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= + +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= + dependencies: + is-utf8 "^0.2.0" + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= + +strip-indent@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" + integrity sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI= + dependencies: + get-stdin "^4.0.1" + +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= + +style-loader@0.17.0: + version "0.17.0" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.17.0.tgz#e8254bccdb7af74bd58274e36107b4d5ab4df310" + integrity sha1-6CVLzNt690vVgnTjYQe01atN8xA= + dependencies: + loader-utils "^1.0.2" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= + +supports-color@^3.1.0, supports-color@^3.1.1, supports-color@^3.1.2, supports-color@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" + integrity sha1-ZawFBLOVQXHYpklGsq48u4pfVPY= + dependencies: + has-flag "^1.0.0" + +supports-color@^5.3.0, supports-color@^5.4.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +svgo@^0.7.0: + version "0.7.2" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-0.7.2.tgz#9f5772413952135c6fefbf40afe6a4faa88b4bb5" + integrity sha1-n1dyQTlSE1xv779Ar+ak+qiLS7U= + dependencies: + coa "~1.0.1" + colors "~1.1.2" + csso "~2.3.1" + js-yaml "~3.7.0" + mkdirp "~0.5.1" + sax "~1.2.1" + whet.extend "~0.9.9" + +sw-precache-webpack-plugin@0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/sw-precache-webpack-plugin/-/sw-precache-webpack-plugin-0.9.1.tgz#2381ff706fbb6cabdb20a20337de8e58fb49a2a7" + integrity sha1-I4H/cG+7bKvbIKIDN96OWPtJoqc= + dependencies: + del "^2.2.2" + sw-precache "^5.0.0" + uglify-js "^2.8.5" + +sw-precache@^5.0.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/sw-precache/-/sw-precache-5.2.1.tgz#06134f319eec68f3b9583ce9a7036b1c119f7179" + integrity sha512-8FAy+BP/FXE+ILfiVTt+GQJ6UEf4CVHD9OfhzH0JX+3zoy2uFk7Vn9EfXASOtVmmIVbL3jE/W8Z66VgPSZcMhw== + dependencies: + dom-urls "^1.1.0" + es6-promise "^4.0.5" + glob "^7.1.1" + lodash.defaults "^4.2.0" + lodash.template "^4.4.0" + meow "^3.7.0" + mkdirp "^0.5.1" + pretty-bytes "^4.0.2" + sw-toolbox "^3.4.0" + update-notifier "^2.3.0" + +sw-toolbox@^3.4.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/sw-toolbox/-/sw-toolbox-3.6.0.tgz#26df1d1c70348658e4dea2884319149b7b3183b5" + integrity sha1-Jt8dHHA0hljk3qKIQxkUm3sxg7U= + dependencies: + path-to-regexp "^1.0.1" + serviceworker-cache-polyfill "^4.0.0" + +symbol-observable@^1.0.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" + integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== + +symbol-tree@^3.2.1: + version "3.2.4" + resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" + integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== + +table@^3.7.8: + version "3.8.3" + resolved "https://registry.yarnpkg.com/table/-/table-3.8.3.tgz#2bbc542f0fda9861a755d3947fefd8b3f513855f" + integrity sha1-K7xULw/amGGnVdOUf+/Ys/UThV8= + dependencies: + ajv "^4.7.0" + ajv-keywords "^1.0.0" + chalk "^1.1.1" + lodash "^4.0.0" + slice-ansi "0.0.4" + string-width "^2.0.0" + +tapable@^0.2.7, tapable@~0.2.5: + version "0.2.9" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.2.9.tgz#af2d8bbc9b04f74ee17af2b4d9048f807acd18a8" + integrity sha512-2wsvQ+4GwBvLPLWsNfLCDYGsW6xb7aeC6utq2Qh0PFwgEy7K7dsma9Jsmb2zSQj7GvYAyUGSntLtsv++GmgL1A== + +tar-pack@^3.4.0: + version "3.4.1" + resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.4.1.tgz#e1dbc03a9b9d3ba07e896ad027317eb679a10a1f" + integrity sha512-PPRybI9+jM5tjtCbN2cxmmRU7YmqT3Zv/UDy48tAh2XRkLa9bAORtSWLkVc13+GJF+cdTh1yEnHEk3cpTaL5Kg== + dependencies: + debug "^2.2.0" + fstream "^1.0.10" + fstream-ignore "^1.0.5" + once "^1.3.3" + readable-stream "^2.1.4" + rimraf "^2.5.1" + tar "^2.2.1" + uid-number "^0.0.6" + +tar@^2.2.1: + version "2.2.2" + resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.2.tgz#0ca8848562c7299b8b446ff6a4d60cdbb23edc40" + integrity sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA== + dependencies: + block-stream "*" + fstream "^1.0.12" + inherits "2" + +term-size@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69" + integrity sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk= + dependencies: + execa "^0.7.0" + +test-exclude@^4.2.1: + version "4.2.3" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.2.3.tgz#a9a5e64474e4398339245a0a769ad7c2f4a97c20" + integrity sha512-SYbXgY64PT+4GAL2ocI3HwPa4Q4TBKm0cwAVeKOt/Aoc0gSpNRjJX8w0pA1LMKZ3LBmd8pYBqApFNQLII9kavA== + dependencies: + arrify "^1.0.1" + micromatch "^2.3.11" + object-assign "^4.1.0" + read-pkg-up "^1.0.1" + require-main-filename "^1.0.1" + +text-table@0.2.0, text-table@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= + +throat@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/throat/-/throat-3.2.0.tgz#50cb0670edbc40237b9e347d7e1f88e4620af836" + integrity sha512-/EY8VpvlqJ+sFtLPeOgc8Pl7kQVOWv0woD87KTXVHPIAE842FGT+rokxIhe8xIUP1cfgrkt0as0vDLjDiMtr8w== + +through@^2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + +time-stamp@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-2.2.0.tgz#917e0a66905688790ec7bbbde04046259af83f57" + integrity sha512-zxke8goJQpBeEgD82CXABeMh0LSJcj7CXEd0OHOg45HgcofF7pxNwZm9+RknpxpDhwN4gFpySkApKfFYfRQnUA== + +timeago.js@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/timeago.js/-/timeago.js-3.0.2.tgz#32a67e7c0d887ea42ca588d3aae26f77de5e76cc" + integrity sha1-MqZ+fA2IfqQspYjTquJvd95edsw= + dependencies: + "@types/jquery" "^2.0.40" + +timed-out@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" + integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8= + +timers-browserify@^2.0.4: + version "2.0.12" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.12.tgz#44a45c11fbf407f34f97bccd1577c652361b00ee" + integrity sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ== + dependencies: + setimmediate "^1.0.4" + +tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== + dependencies: + os-tmpdir "~1.0.2" + +tmpl@1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" + integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== + +to-arraybuffer@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" + integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= + +to-fast-properties@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" + integrity sha1-uDVx+k2MJbguIxsG46MFXeTKGkc= + +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= + dependencies: + kind-of "^3.0.2" + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +toposort@^1.0.0: + version "1.0.7" + resolved "https://registry.yarnpkg.com/toposort/-/toposort-1.0.7.tgz#2e68442d9f64ec720b8cc89e6443ac6caa950029" + integrity sha1-LmhELZ9k7HILjMieZEOsbKqVACk= + +tough-cookie@^2.3.2, tough-cookie@~2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + +tough-cookie@~2.3.0: + version "2.3.4" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.4.tgz#ec60cee38ac675063ffc97a5c18970578ee83655" + integrity sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA== + dependencies: + punycode "^1.4.1" + +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= + +trim-newlines@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" + integrity sha1-WIeWa7WCpFA6QetST301ARgVphM= + +trim-right@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" + integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= + +tty-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" + integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY= + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= + dependencies: + prelude-ls "~1.1.2" + +type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + 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.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" + integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== + +type@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/type/-/type-2.5.0.tgz#0a2e78c2e77907b252abe5f298c1b01c63f0db3d" + integrity sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw== + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= + +ua-parser-js@^0.7.30: + version "0.7.31" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.31.tgz#649a656b191dffab4f21d5e053e27ca17cbff5c6" + integrity sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ== + +uglify-js@3.4.x: + version "3.4.10" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.10.tgz#9ad9563d8eb3acdfb8d38597d2af1d815f6a755f" + integrity sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw== + dependencies: + commander "~2.19.0" + source-map "~0.6.1" + +uglify-js@^2.8.27, uglify-js@^2.8.5: + version "2.8.29" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" + integrity sha1-KcVzMUgFe7Th913zW3qcty5qWd0= + dependencies: + source-map "~0.5.1" + yargs "~3.10.0" + optionalDependencies: + uglify-to-browserify "~1.0.0" + +uglify-js@^3.1.4: + version "3.14.5" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.14.5.tgz#cdabb7d4954231d80cb4a927654c4655e51f4859" + integrity sha512-qZukoSxOG0urUTvjc2ERMTcAy+BiFh3weWAkeurLwjrCba73poHmG3E36XEjd/JGukMzwTL7uCxZiAexj8ppvQ== + +uglify-to-browserify@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" + integrity sha1-bgkk1r2mta/jSeOabWMoUKD4grc= + +uid-number@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" + integrity sha1-DqEOgDXo61uOREnwbaHHMGY7qoE= + +unbox-primitive@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" + integrity sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw== + dependencies: + function-bind "^1.1.1" + has-bigints "^1.0.1" + has-symbols "^1.0.2" + which-boxed-primitive "^1.0.2" + +union-value@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" + integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^2.0.1" + +uniq@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" + integrity sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8= + +uniqs@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/uniqs/-/uniqs-2.0.0.tgz#ffede4b36b25290696e6e165d4a59edb998e6b02" + integrity sha1-/+3ks2slKQaW5uFl1KWe25mOawI= + +unique-string@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a" + integrity sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo= + dependencies: + crypto-random-string "^1.0.0" + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +unzip-response@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" + integrity sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c= + +upath@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" + integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== + +update-notifier@^2.3.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-2.5.0.tgz#d0744593e13f161e406acb1d9408b72cad08aff6" + integrity sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw== + dependencies: + boxen "^1.2.1" + chalk "^2.0.1" + configstore "^3.0.0" + import-lazy "^2.1.0" + is-ci "^1.0.10" + is-installed-globally "^0.1.0" + is-npm "^1.0.0" + latest-version "^3.0.0" + semver-diff "^2.0.0" + xdg-basedir "^3.0.0" + +upper-case@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598" + integrity sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg= + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +urijs@^1.16.1: + version "1.19.7" + resolved "https://registry.yarnpkg.com/urijs/-/urijs-1.19.7.tgz#4f594e59113928fea63c00ce688fb395b1168ab9" + integrity sha512-Id+IKjdU0Hx+7Zx717jwLPsPeUqz7rAtuVBRLLs+qn+J2nf9NGITWVCxcijgYxBqe83C7sqsQPs6H1pyz3x9gA== + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= + +url-loader@0.5.8: + version "0.5.8" + resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-0.5.8.tgz#b9183b1801e0f847718673673040bc9dc1c715c5" + integrity sha1-uRg7GAHg+EdxhnNnMEC8ncHHFcU= + dependencies: + loader-utils "^1.0.2" + mime "1.3.x" + +url-parse-lax@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" + integrity sha1-evjzA2Rem9eaJy56FKxovAYJ2nM= + dependencies: + prepend-http "^1.0.1" + +url-parse@^1.1.1, url-parse@^1.1.8, url-parse@^1.4.3: + version "1.5.4" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.4.tgz#e4f645a7e2a0852cc8a66b14b292a3e9a11a97fd" + integrity sha512-ITeAByWWoqutFClc/lRZnFplgXgEZr3WJ6XngMM/N9DMIm4K8zXPCZ1Jdu0rERwO84w1WC5wkle2ubwTA4NTBg== + dependencies: + querystringify "^2.1.1" + requires-port "^1.0.0" + +url@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= + dependencies: + punycode "1.3.2" + querystring "0.2.0" + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== + +user-home@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/user-home/-/user-home-2.0.0.tgz#9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f" + integrity sha1-nHC/2Babwdy/SGBODwS4tJzenp8= + dependencies: + os-homedir "^1.0.0" + +util-deprecate@^1.0.1, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +util@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk= + dependencies: + inherits "2.0.1" + +util@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61" + integrity sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ== + dependencies: + inherits "2.0.3" + +utila@~0.4: + version "0.4.0" + resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" + integrity sha1-ihagXURWV6Oupe7MWxKk+lN5dyw= + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= + +uuid@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.3.tgz#67e2e863797215530dff318e5bf9dcebfd47b21a" + integrity sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho= + +uuid@^3.0.0, uuid@^3.3.2: + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== + +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + 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.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= + +vendors@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.4.tgz#e2b800a53e7a29b93506c3cf41100d16c4c4ad8e" + integrity sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w== + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +vm-browserify@^1.0.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" + integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== + +walker@~1.0.5: + version "1.0.8" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" + integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== + dependencies: + makeerror "1.0.12" + +watch@~0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/watch/-/watch-0.10.0.tgz#77798b2da0f9910d595f1ace5b0c2258521f21dc" + integrity sha1-d3mLLaD5kQ1ZXxrOWwwiWFIfIdw= + +watchpack-chokidar2@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz#38500072ee6ece66f3769936950ea1771be1c957" + integrity sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww== + dependencies: + chokidar "^2.1.8" + +watchpack@^1.3.1: + version "1.7.5" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.7.5.tgz#1267e6c55e0b9b5be44c2023aed5437a2c26c453" + integrity sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ== + dependencies: + graceful-fs "^4.1.2" + neo-async "^2.5.0" + optionalDependencies: + chokidar "^3.4.1" + watchpack-chokidar2 "^2.0.1" + +wbuf@^1.1.0, wbuf@^1.7.2: + version "1.7.3" + resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" + integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== + dependencies: + minimalistic-assert "^1.0.0" + +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE= + +webidl-conversions@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" + integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== + +webpack-dev-middleware@^1.10.2: + version "1.12.2" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-1.12.2.tgz#f8fc1120ce3b4fc5680ceecb43d777966b21105e" + integrity sha512-FCrqPy1yy/sN6U/SaEZcHKRXGlqU0DUaEBL45jkUYoB8foVb6wCnbIJ1HKIx+qUFTW+3JpVcCJCxZ8VATL4e+A== + dependencies: + memory-fs "~0.4.1" + mime "^1.5.0" + path-is-absolute "^1.0.0" + range-parser "^1.0.3" + time-stamp "^2.0.0" + +webpack-dev-server@2.4.5: + version "2.4.5" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-2.4.5.tgz#31384ce81136be1080b4b4cde0eb9b90e54ee6cf" + integrity sha1-MThM6BE2vhCAtLTN4OubkOVO5s8= + dependencies: + ansi-html "0.0.7" + chokidar "^1.6.0" + compression "^1.5.2" + connect-history-api-fallback "^1.3.0" + express "^4.13.3" + html-entities "^1.2.0" + http-proxy-middleware "~0.17.4" + opn "4.0.2" + portfinder "^1.0.9" + serve-index "^1.7.2" + sockjs "0.3.18" + sockjs-client "1.1.2" + spdy "^3.4.1" + strip-ansi "^3.0.0" + supports-color "^3.1.1" + webpack-dev-middleware "^1.10.2" + yargs "^6.0.0" + +webpack-manifest-plugin@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/webpack-manifest-plugin/-/webpack-manifest-plugin-1.1.0.tgz#6b6c718aade8a2537995784b46bd2e9836057caa" + integrity sha1-a2xxiq3oolN5lXhLRr0umDYFfKo= + dependencies: + fs-extra "^0.30.0" + lodash ">=3.5 <5" + +webpack-sources@^0.1.0: + version "0.1.5" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-0.1.5.tgz#aa1f3abf0f0d74db7111c40e500b84f966640750" + integrity sha1-qh86vw8NdNtxEcQOUAuE+WZkB1A= + dependencies: + source-list-map "~0.1.7" + source-map "~0.5.3" + +webpack-sources@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-0.2.3.tgz#17c62bfaf13c707f9d02c479e0dcdde8380697fb" + integrity sha1-F8Yr+vE8cH+dAsR54Nzd6DgGl/s= + dependencies: + source-list-map "^1.1.1" + source-map "~0.5.3" + +webpack@2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-2.6.1.tgz#2e0457f0abb1ac5df3ab106c69c672f236785f07" + integrity sha1-LgRX8KuxrF3zqxBsacZy8jZ4Xwc= + dependencies: + acorn "^5.0.0" + acorn-dynamic-import "^2.0.0" + ajv "^4.7.0" + ajv-keywords "^1.1.1" + async "^2.1.2" + enhanced-resolve "^3.0.0" + interpret "^1.0.0" + json-loader "^0.5.4" + json5 "^0.5.1" + loader-runner "^2.3.0" + loader-utils "^0.2.16" + memory-fs "~0.4.1" + mkdirp "~0.5.0" + node-libs-browser "^2.0.0" + source-map "^0.5.3" + supports-color "^3.1.0" + tapable "~0.2.5" + uglify-js "^2.8.27" + watchpack "^1.3.1" + webpack-sources "^0.2.3" + yargs "^6.0.0" + +websocket-driver@>=0.5.1: + version "0.7.4" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" + 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.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" + integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== + +whatwg-encoding@^1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" + integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== + dependencies: + iconv-lite "0.4.24" + +whatwg-fetch@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz#9c84ec2dcf68187ff00bc64e1274b442176e1c84" + integrity sha1-nITsLc9oGH/wC8ZOEnS0QhduHIQ= + +whatwg-fetch@>=0.10.0: + version "3.6.2" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz#dced24f37f2624ed0281725d51d0e2e3fe677f8c" + integrity sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA== + +whatwg-url@^4.3.0: + version "4.8.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-4.8.0.tgz#d2981aa9148c1e00a41c5a6131166ab4683bbcc0" + integrity sha1-0pgaqRSMHgCkHFphMRZqtGg7vMA= + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + +whet.extend@~0.9.9: + version "0.9.9" + resolved "https://registry.yarnpkg.com/whet.extend/-/whet.extend-0.9.9.tgz#f877d5bf648c97e5aa542fadc16d6a259b9c11a1" + integrity sha1-+HfVv2SMl+WqVC+twW1qJZucEaE= + +which-boxed-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" + 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.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" + integrity sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8= + +which@^1.2.12, which@^1.2.14, which@^1.2.9, which@^1.3.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +wide-align@^1.1.0: + version "1.1.5" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" + integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== + dependencies: + string-width "^1.0.2 || 2 || 3 || 4" + +widest-line@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-2.0.1.tgz#7438764730ec7ef4381ce4df82fb98a53142a3fc" + integrity sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA== + dependencies: + string-width "^2.1.1" + +window-size@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" + integrity sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0= + +word-wrap@~1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + +wordwrap@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" + integrity sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8= + +wordwrap@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= + +worker-farm@^1.3.1: + version "1.7.0" + resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" + integrity sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw== + dependencies: + errno "~0.1.7" + +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +write-file-atomic@^2.0.0: + version "2.4.3" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.3.tgz#1fd2e9ae1df3e75b8d8c367443c692d4ca81f481" + integrity sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ== + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + signal-exit "^3.0.2" + +write@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" + integrity sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c= + dependencies: + mkdirp "^0.5.1" + +xdg-basedir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" + integrity sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ= + +xml-name-validator@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-2.0.1.tgz#4d8b8f1eccd3419aa362061becef515e1e559635" + integrity sha1-TYuPHszTQZqjYgYb7O9RXh5VljU= + +xtend@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + +y18n@^3.2.1: + version "3.2.2" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.2.tgz#85c901bd6470ce71fc4bb723ad209b70f7f28696" + integrity sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ== + +yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= + +yargs-parser@^4.2.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-4.2.1.tgz#29cceac0dc4f03c6c87b4a9f217dd18c9f74871c" + integrity sha1-KczqwNxPA8bIe0qfIX3RjJ90hxw= + dependencies: + camelcase "^3.0.0" + +yargs-parser@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.1.tgz#7ede329c1d8cdbbe209bd25cdb990e9b1ebbb394" + integrity sha512-wpav5XYiddjXxirPoCTUPbqM0PXvJ9hiBMvuJgInvo4/lAOTZzUprArw17q2O1P2+GHhbBr18/iQwjL5Z9BqfA== + dependencies: + camelcase "^3.0.0" + object.assign "^4.1.0" + +yargs@^6.0.0: + version "6.6.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-6.6.0.tgz#782ec21ef403345f830a808ca3d513af56065208" + integrity sha1-eC7CHvQDNF+DCoCMo9UTr1YGUgg= + 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" + +yargs@^7.0.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.2.tgz#63a0a5d42143879fdbb30370741374e0641d55db" + integrity sha512-ZEjj/dQYQy0Zx0lgLMLR8QuaqTihnxirir7EwUHp1Axq4e3+k8jXU5K0VLbNvedv1f4EWtBonDIZm0NUr+jCcA== + 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 "^5.0.1" + +yargs@~3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" + integrity sha1-9+572FfdfB0tOMDnTvvWgdFDH9E= + dependencies: + camelcase "^1.0.2" + cliui "^2.1.0" + decamelize "^1.0.0" + window-size "0.1.0" diff --git a/web/modules/forked/react_comments/js/startsWithPolyfill.js b/web/modules/forked/react_comments/js/startsWithPolyfill.js new file mode 100644 index 0000000..95b7f90 --- /dev/null +++ b/web/modules/forked/react_comments/js/startsWithPolyfill.js @@ -0,0 +1,6 @@ +if (!String.prototype.startsWith) { + String.prototype.startsWith = function(searchString, position) { + position = position || 0; + return this.indexOf(searchString, position) === position; + }; +} \ No newline at end of file diff --git a/web/modules/forked/react_comments/react_comments.info.yml b/web/modules/forked/react_comments/react_comments.info.yml new file mode 100644 index 0000000..a0e3548 --- /dev/null +++ b/web/modules/forked/react_comments/react_comments.info.yml @@ -0,0 +1,13 @@ +name: 'React Comments' +description: 'Commenting system built with React' +type: module +# core: 8.x +dependencies: + - drupal:comment + - drupal:rest + +# Information added by Drupal.org packaging script on 2018-12-27 +version: '8.x-1.0-beta1' +core: '8.x' +project: 'react_comments' +datestamp: 1545942484 diff --git a/web/modules/forked/react_comments/react_comments.install b/web/modules/forked/react_comments/react_comments.install new file mode 100644 index 0000000..221e1c5 --- /dev/null +++ b/web/modules/forked/react_comments/react_comments.install @@ -0,0 +1,116 @@ + 'Comment statuses.', + 'fields' => [ + 'cid' => [ + 'description' => 'Comment ID', + 'type' => 'int', + 'length' => 15, + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ], + 'uid' => [ + 'description' => 'User ID', + 'type' => 'int', + 'length' => 15, + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ], + 'status' => [ + 'description' => 'Status.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ], + 'created_at' => [ + 'description' => 'Status timestamp.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ], + ], + 'indexes' => [ + 'cid' => ['cid'], + 'uid' => ['uid'], + ], + ]; + return $schema; +} + +/** + * Implements hook_install(). + */ +function react_comments_install() { + $roles = [ + 'authenticated' => [ + 'restful get comments', + 'restful post comments', + 'restful get me', + 'restful get comment', + 'restful delete comment', + 'restful patch comment', + 'restful put comment' + ], + 'anonymous' => [ + 'restful get comments', + 'restful post comments', + 'restful get me', + ], + ]; + foreach ($roles as $role => $permissions) { + $role = Role::load($role); + foreach ($permissions as $permission) { + $role->grantPermission($permission); + } + $role->save(); + } +} + +/** + * Implements hook_uninstall(). + */ +function react_comments_uninstall() { + // Since this module treats deleted comments as "published" (so that we can see + // replies, and note where in the comment tree deleted comments were) we need to + // set the status of all RC_STATUS_DELETED comments to 0 so that they don't show + // up once the module is turned off. Additionally we're choosing to change the status + // rather than actually delete the comments, because deleting comments in drupal will + // delete all replies, something that may not be immediately obvious to someone + // uninstalling this module. + $query = $query = \Drupal::database()->select('comment_field_data', 'c'); + $query->join('react_comments_status', 's', 'c.cid = s.cid'); + $query->fields('c', ['cid']); + $query->condition('s.status', RC_COMMENT_DELETED); + $deleted_comments = (array) $query->execute()->fetchAllKeyed(0, 0); + + var_dump($deleted_comments); + + if (!empty($deleted_comments)) { + $result = $result = \Drupal::database()->update('comment_field_data') + // let's also set the least important field to something identifiable in case someone has regrets + ->fields(['status' => 0, 'homepage' => 'react_comments_deleted']) + ->condition('comment_field_data.cid', $deleted_comments, 'IN') + ->execute(); + + echo "React comments wants deleted comments to have a status of 1 in the database to preserve replies. On uninstall we unpublish these deleted comments so they won't show up on the front end. $result comments have been unpublished."; + } +} + +/** + * Install default config + */ +function react_comments_update_8001() { + // This is okay cause there hasn't been any config up to this point. + \Drupal::service('config.installer')->installDefaultConfig('module', 'react_comments'); +} diff --git a/web/modules/forked/react_comments/react_comments.libraries.yml b/web/modules/forked/react_comments/react_comments.libraries.yml new file mode 100644 index 0000000..1f4f87a --- /dev/null +++ b/web/modules/forked/react_comments/react_comments.libraries.yml @@ -0,0 +1,9 @@ +react_comments: + css: + theme: + css/dist/react_comments.css: {} + js: + js/startsWithPolyfill.js: { attributes: { defer: true }} + js/dist/react_comments.js: { attributes: { defer: true }} + dependencies: + - core/drupal diff --git a/web/modules/forked/react_comments/react_comments.links.menu.yml b/web/modules/forked/react_comments/react_comments.links.menu.yml new file mode 100644 index 0000000..cd4a116 --- /dev/null +++ b/web/modules/forked/react_comments/react_comments.links.menu.yml @@ -0,0 +1,5 @@ +react_comments.admin: + title: 'React Comments' + description: 'Administer react comments configuration' + parent: system.admin_config + route_name: react_comments.settings \ No newline at end of file diff --git a/web/modules/forked/react_comments/react_comments.module b/web/modules/forked/react_comments/react_comments.module new file mode 100644 index 0000000..49b06b9 --- /dev/null +++ b/web/modules/forked/react_comments/react_comments.module @@ -0,0 +1,59 @@ + $vars['element']['#object'] ? $vars['element']['#object']->id() : NULL, + 'origin' => $base_url + ]); + } +} + +/** + * Implements hook_entity_delete(). + */ +function react_comments_entity_delete(EntityInterface $entity) { + if ($entity->getEntityTypeId() == 'comment') { + $query = \Drupal::database()->delete('react_comments_status'); + $query->condition('cid', $entity->id()); + $query->execute(); + } +} + +/** + * Implements hook_node_links_alter(). + */ +function react_comments_node_links_alter(array &$links, NodeInterface $entity, array &$context) { + unset($links['comment__comment']); +} + +/** + * Implements hook_theme_registry_alter(). + */ +function react_comments_theme_registry_alter(&$theme_registry) { + $theme_registry['field__comment']['path'] = drupal_get_path('module', 'react_comments') . '/templates'; +} + +/** + * Implements hook_theme(). + */ +function react_comments_theme($existing, $type, $theme, $path) { + return [ + 'comments' => [ + 'variables' => ['entity_id' => NULL, 'origin' => NULL, 'is_hidden' => FALSE], + ], + ]; +} diff --git a/web/modules/forked/react_comments/react_comments.routing.yml b/web/modules/forked/react_comments/react_comments.routing.yml new file mode 100644 index 0000000..03e8852 --- /dev/null +++ b/web/modules/forked/react_comments/react_comments.routing.yml @@ -0,0 +1,7 @@ +react_comments.settings: + path: '/admin/config/react_comments' + defaults: + _form: '\Drupal\react_comments\Form\ReactCommentsSettingsForm' + _title: React Comments Settings + requirements: + _permission: 'administer comments' diff --git a/web/modules/forked/react_comments/react_comments.views.inc b/web/modules/forked/react_comments/react_comments.views.inc new file mode 100644 index 0000000..693f6a5 --- /dev/null +++ b/web/modules/forked/react_comments/react_comments.views.inc @@ -0,0 +1,81 @@ + 'cid', + 'title' => t('React Comments: ID'), + 'help' => t('React Comments: Comments'), + 'weight' => -10, + ]; + $data['react_comments_status']['table']['join'] = [ + 'comment_field_data' => [ + 'left_field' => 'cid', + 'field' => 'cid', + ], + 'react_comments_status' => [ + 'left_field' => 'cid', + 'field' => 'cid', + ], + ]; + $data['react_comments_status']['cid'] = [ + 'title' => t('Comment Status'), + 'help' => t('Comment Status'), + 'relationship' => [ + 'base' => 'comment_field_data', + 'base field' => 'cid', + 'id' => 'standard', + 'label' => t('Comment Status'), + ], + ]; + $data['react_comments_status']['uid'] = [ + 'title' => t('User'), + 'help' => t('User'), + 'relationship' => [ + 'base' => 'users_field_data', + 'base field' => 'uid', + 'id' => 'standard', + 'label' => t('User'), + ], + ]; + $data['react_comments_status']['status'] = [ + 'title' => t('React Comment Status'), + 'help' => t('React Comment Status'), + 'field' => [ + 'id' => 'react_comment_status', + ], + 'sort' => [ + 'id' => 'standard', + ], + 'filter' => [ + 'id' => 'react_comment_status', + ], + 'argument' => [ + 'id' => 'numeric', + ], + ]; + $data['react_comments_status']['created_at'] = [ + 'title' => t('Status Created At'), + 'help' => t('Timestamp'), + 'field' => [ + 'id' => 'date', + ], + 'sort' => [ + 'id' => 'date', + ], + 'filter' => [ + 'id' => 'date', + ], + 'argument' => [ + 'id' => 'date', + ], + ]; + return $data; +} diff --git a/web/modules/forked/react_comments/src/CommentFieldSettings.php b/web/modules/forked/react_comments/src/CommentFieldSettings.php new file mode 100644 index 0000000..c0fcb27 --- /dev/null +++ b/web/modules/forked/react_comments/src/CommentFieldSettings.php @@ -0,0 +1,64 @@ +getFieldDefinitions() as $field_name => $definition) { + $field = $node->get($field_name); + if (is_a($field, 'Drupal\comment\CommentFieldItemList')) { + // We're assuming there's only one comment field per node. Seems sensible... + $comment_fields[$nid] = $field; + break; + } + } + } + + return $comment_fields[$nid]; + } + + public static function getCommentFieldStatus($nid) { + $status = null; + + $field = self::getCommentField($nid); + $status = $field->status; + + if (is_null($status)) { + // No comment field found. + return false; + } + else if (($status === '1') || ($status === 1)) { + return 'closed'; + } + else if (($status === '2') || ($status === 2)) { + return 'open'; + } + else { + // shouldn't need this as comment module handles hidden comments already + return 'hidden'; + } + } + + public static function getCommentFieldSettings($nid) { + $field = self::getCommentField($nid); + + return $field ? $field->getSettings() : null; + } + + public static function getCommentFieldConfigCacheTags($nid) { + $field = self::getCommentField($nid); + + return $field->getFieldDefinition()->getCacheTagsToInvalidate(); + } +} diff --git a/web/modules/forked/react_comments/src/Form/ReactCommentsSettingsForm.php b/web/modules/forked/react_comments/src/Form/ReactCommentsSettingsForm.php new file mode 100644 index 0000000..284ecc1 --- /dev/null +++ b/web/modules/forked/react_comments/src/Form/ReactCommentsSettingsForm.php @@ -0,0 +1,104 @@ + 'textfield', + '#title' => $this->t('Allowed HTML Tags'), + '#description' => $this->t('A list of html tags that will be allowed in comments.'), + '#default_value' => $this->config('react_comments.settings')->get('allowed_tags') ?: '

    ' + ]; + + $image_styles = array_map(function($el) { + return $el->get('label'); + }, ImageStyle::loadMultiple()); + + $form['user_avatar_image_style'] = [ + '#type' => 'select', + '#title' => $this->t('User Avatar Image Style'), + '#description' => $this->t("Choose the image style that will get applied to your user avatars. We recommend creating an image style with scale and crop 100 x 100 if you don't already have one"), + '#options' => $image_styles, + '#default_value' => $this->config('react_comments.settings')->get('user_avatar_image_style') ?: 'thumbnail' + ]; + + $form['prefer_gravatar'] = [ + '#type' => 'checkbox', + '#title' => $this->t('Prefer Gravatar'), + '#description' => $this->t('If this box is checked react comments will show gravatar images even if the comment was created by a drupal user with a user picture'), + '#default_value' => $this->config('react_comments.settings')->get('prefer_gravatar') + ]; + + $form['anon_default_avatar_fid'] = [ + '#title' => $this->t('Default Avatar for Anonymous users'), + '#type' => 'managed_file', + '#upload_location' => 'public://react_comments/', + '#default_value' => $this->config('react_comments.settings')->get('anon_default_avatar_fid') + ]; + + return parent::buildForm($form, $form_state); + } + + public function validateForm(array &$form, FormStateInterface $form_state) { + parent::validateForm($form, $form_state); + + if ($anon_default_avatar_fid = $form_state->getValue('anon_default_avatar_fid')) { + $file = File::load($anon_default_avatar_fid[0]); + + $errors = file_validate_is_image($file); + + if (!empty($errors)) { + $form_state->setErrorByName('anon_default_avatar_fid', $this->t('Default Avatar for Anonymous users must be an image file.')); + } + } + + } + + public function submitForm(array &$form, FormStateInterface $form_state) { + $config = $this->config('react_comments.settings'); + + $config_keys = [ + 'allowed_tags', + 'prefer_gravatar', + 'user_avatar_image_style', + 'anon_default_avatar_fid' + ]; + + foreach ($config_keys as $config_key) { + $config->set($config_key, $form_state->getValue($config_key)); + } + + if ($anon_default_avatar_fid = $form_state->getValue('anon_default_avatar_fid')) { + $file = File::load($anon_default_avatar_fid[0]); + $file->setPermanent(); + $file->save(); + $config->set('anon_default_avatar_fid', $anon_default_avatar_fid); + } + + $config->save(); + + // Most of these configs change the way comments are displayed in some way... Unfortunately we gotta clear those caches. + Cache::invalidateTags(['react_comment_list']); + + parent::submitForm($form, $form_state); + } +} diff --git a/web/modules/forked/react_comments/src/Model/Base.php b/web/modules/forked/react_comments/src/Model/Base.php new file mode 100644 index 0000000..d169f6a --- /dev/null +++ b/web/modules/forked/react_comments/src/Model/Base.php @@ -0,0 +1,27 @@ +drupal_user = \Drupal::currentUser(); + $this->cache = \Drupal::cache(); + } + + public function isAdmin() { + // Only admins should be able to edit comments. + return $this->drupal_user->hasPermission('administer comments'); + } + + public function checkPlain($text) { + return (new HtmlEscapedText($text))->__toString(); + } + +} diff --git a/web/modules/forked/react_comments/src/Model/Comment.php b/web/modules/forked/react_comments/src/Model/Comment.php new file mode 100644 index 0000000..7c51077 --- /dev/null +++ b/web/modules/forked/react_comments/src/Model/Comment.php @@ -0,0 +1,195 @@ +select('comment_field_data', 'c'); + $query->join('comment__comment_body', 'b', 'c.cid = b.entity_id'); + $query->fields('c', ['uid', 'pid', 'entity_id', 'subject', 'created', 'changed', 'status', 'hostname', 'name', 'mail']) + ->fields('b', ['comment_body_value']) + ->condition('c.cid', $this->getId()); + $record = $query->execute() + ->fetchObject(); + + if (empty($record->comment_body_value)) return NULL; + + if ($status = $this->loadCustomStatus()) { + $this->setStatus($status); + } + else { + $this->setStatus($record->status); + } + + $user = new User(); + $uid = $this->isVisible() ? $record->uid : 0; + $user->setId($uid)->load(); + + if (empty($user->getEmail()) && !empty($record->mail) && $this->isVisible()) { + $user->setEmail($record->mail); + } + + $this->setReplyId($record->pid) + ->setEntityId($record->entity_id) + ->setUser($user) + ->setName($user->getName() ?: $record->name) + ->setEmail($record->mail) + ->setComment($record->comment_body_value) + ->setIpAddress($record->hostname) + ->setCreatedAt($record->created) + ->setChangedAt($record->changed) + ->setPublishedStatus($record->status); + + $replies = $this->loadReplies($this->getId(), $show_unpublished); + $this->setReplies($replies); + + return $this; + } + + /** + * Save a comment. + */ + public function save() { + $comment = CommentEntity::create([ + // @todo entity_type shouldn't be hardcoded to node + 'entity_type' => 'node', + 'entity_id' => $this->getEntityId(), + 'pid' => $this->getReplyId() ?: null, + 'field_name' => $this->getFieldName(), + 'uid' => $this->getUser()->getId(), + 'comment_type' => $this->getCommentType(), + 'subject' => $this->getSubject(), + 'comment_body' => [ + 'value' => $this->getComment(), + 'format' => 'basic_html' + ], + 'status' => $this->getStatus(), + 'published' => $this->isPublished(), + 'name' => $this->getName(), + 'mail' => $this->getEmail() + ]); + $comment->save(); + $this->setId($comment->id()) + ->updateCustomStatus(); + return $this->getId(); + } + + /** + * Update a comment. + */ + public function update() { + // @todo consider paring this whole class way down and relying more on core Comment entity. + $status = $this->getStatus(); + if (is_numeric($status)) { + $comment = CommentEntity::load($this->getId()); + + $comment->set('pid', $this->getReplyId() ?: null); + $comment->set('entity_id', $this->getEntityId()); + $comment->set('uid', $this->getUser()->getId()); + $comment->set('subject', $this->getSubject()); + $this->updateCustomStatus(); + if (is_numeric($this->customStatusToDrupalStatus($this->getStatus()))) { + $comment->set('status', $this->customStatusToDrupalStatus($this->getStatus())); + } + else { + $comment->set('status', $comment->getStatus()); + } + $comment->set('comment_body', [ + 'value' => $this->getComment(), + 'format' => 'basic_html' + ]); + + return $comment->save(); + } + return NULL; + } + + /** + * Delete a comment. + */ + public function delete() { + $comment = CommentEntity::load($this->getId()); + $user = $this->getUser(); + if ( $this->isAdmin() || ($user->hasPermission('edit own comments') && ($comment->get('uid')->target_id == $user->getId())) ) { + $this->setStatus( RC_COMMENT_DELETED )->update(); + } + return NULL; + } + + /** + * Update additional comment status. + */ + private function loadCustomStatus() { + $query = \Drupal::database()->select('react_comments_status', 's'); + $query->fields('s', ['status']) + ->condition('s.cid', $this->getId()); + return $query->execute() + ->fetchField(); + } + + /** + * Update additional comment status. + */ + private function updateCustomStatus() { + \Drupal::database()->merge('react_comments_status') + ->key(['cid' => $this->getId()]) + ->fields([ + 'cid' => $this->getId(), + 'uid' => $this->getUser()->getId(), + 'status' => $this->getStatus(), + 'created_at' => time(), + ]) + ->execute(); + } + + /** + * Load a comment with its replies recursively. + */ + private function loadReplies($pid = 0, $show_unpublished = FALSE) { + $query = \Drupal::database()->select('comment_field_data', 'c') + ->fields('c') + ->condition('c.pid', $pid) + ->orderBy('c.created') + ->addTag('react_comments_load_replies'); + + if (!$show_unpublished) { + $query->condition('c.status', 1); + } + + $result = $query->execute(); + + $thread = []; + foreach ($result as $item) { + if ($comment = (new Comment())->setId($item->cid)->load($show_unpublished)) { + $thread[] = $comment->model(); + $this->loadReplies($item->cid, $show_unpublished); + } + } + return $thread; + } + + /** + * Convert react comments custom status into drupal published status. + * Use with is_numeric to decide whether to change the drupal status. + */ + private function customStatusToDrupalStatus($custom_status) { + switch($custom_status) { + case RC_COMMENT_PUBLISHED: + case RC_COMMENT_DELETED: + return 1; + case RC_COMMENT_UNPUBLISHED: + return 0; + case RC_COMMENT_FLAGGED: + default: + // changing to flagged state shouldn't effect whether the comment is published or unpublished + return NULL; + } + } + +} diff --git a/web/modules/forked/react_comments/src/Model/CommentBase.php b/web/modules/forked/react_comments/src/Model/CommentBase.php new file mode 100644 index 0000000..b4ecbc3 --- /dev/null +++ b/web/modules/forked/react_comments/src/Model/CommentBase.php @@ -0,0 +1,201 @@ +id = $id; + return $this; + } + + public function getId() { + return (int) $this->id; + } + + public function setReplyId($id) { + $this->reply_id = (int) $id; + return $this; + } + + public function getReplyId() { + return (int) $this->reply_id; + } + + public function setEntityId($id) { + $this->entity_id = $id; + return $this; + } + + public function getEntityId() { + return (int) $this->entity_id; + } + + public function setUser(User $user) { + $this->user = $user; + return $this; + } + + public function getUser() { + return $this->user; + } + + public function getName() { + return $this->name; + } + + public function setName($name) { + $this->name = $name; + return $this; + } + + public function getEmail() { + return $this->email; + } + + public function setEmail($email) { + $this->email = $email; + return $this; + } + + public function setSubject($subject) { + $this->subject = $subject; + return $this; + } + + public function getSubject() { + return empty($this->subject) ? Unicode::truncate($this->getComment(), 60) : $this->subject; + } + + public function setComment($comment) { + $this->comment = $comment; + return $this; + } + + public function getComment() { + $allowed_tags = \Drupal::config('react_comments.settings')->get('allowed_tags'); + return !empty($this->comment) ? strip_tags($this->comment, $allowed_tags) : ''; + } + + public function setReplies(array $replies) { + $this->replies = $replies; + return $this; + } + + public function getReplies() { + return !empty($this->replies) ? $this->replies : NULL; + } + + public function setIpAddress($ip = NULL) { + $this->ip_address = $ip; + return $this; + } + + public function getIpAddress() { + if (empty($this->ip_address)) { + return \Drupal::request()->getClientIp(); + } + return $this->ip_address; + } + + public function setStatus($status) { + $this->status = $status; + return $this; + } + + public function getStatus() { + return $this->status; + } + + public function isVisible() { + return $this->status == RC_COMMENT_PUBLISHED; + } + + public function isPublished() { + return $this->published; + } + + public function setPublishedStatus($status) { + $this->published = $status; + return $this; + } + + public function setCreatedAt($timestamp = NULL) { + $this->created_at = $timestamp; + return $this; + } + + public function getCreatedAt() { + if (empty($this->created_at)) { + return time(); + } + return $this->created_at; + } + + public function setChangedAt($timestamp = NULL) { + $this->changed_at = $timestamp; + return $this; + } + + public function getChangedAt() { + if (empty($this->changed_at)) { + return time(); + } + return $this->changed_at; + } + + public function model() { + return [ + 'id' => $this->getId(), + 'nid' => $this->getEntityId(), + 'subject' => $this->isVisible() ? $this->getSubject() : NULL, + 'comment' => $this->isVisible() ? $this->getComment() : '', + 'status' => $this->getStatus(), + 'published' => $this->isPublished(), + 'user' => $this->getUser()->model(), + 'created_at' => $this->getCreatedAt(), + 'replies' => $this->getReplies(), + 'name' => $this->isVisible() ? $this->getName() : NULL, + 'email' => $this->isVisible() ? $this->getEmail() : NULL + ]; + } + + public function getFieldName() { + return $this->field_name; + } + + public function setFieldName($field_name) { + $this->field_name = $field_name; + return $this; + } + + public function getCommentType() { + return $this->comment_type; + } + + public function setCommentType($comment_type) { + $this->comment_type = $comment_type; + return $this; + } + +} diff --git a/web/modules/forked/react_comments/src/Model/Comments.php b/web/modules/forked/react_comments/src/Model/Comments.php new file mode 100644 index 0000000..63a080a --- /dev/null +++ b/web/modules/forked/react_comments/src/Model/Comments.php @@ -0,0 +1,36 @@ +select('comment_field_data', 'c') + ->fields('c', ['cid']) + ->condition('c.entity_id', $this->getEntityId()) + ->condition('c.pid', NULL, 'IS NULL') + ->orderBy('c.created', 'DESC') + ->addTag('react_comments_load_comments'); + + if (!$show_unpublished) { + // if the user doesn't have the 'administer comments' permission, only load published comments + $query->condition('c.status', RC_COMMENT_PUBLISHED); + } + + $result = $query->execute(); + + $thread = []; + foreach ($result as $record) { + if ($comment = (new Comment())->setId($record->cid)->load($show_unpublished)) { + $thread[] = $comment->model(); + } + } + if (empty($thread)) return NULL; + $this->setComments($thread); + return $this; + } + +} diff --git a/web/modules/forked/react_comments/src/Model/CommentsBase.php b/web/modules/forked/react_comments/src/Model/CommentsBase.php new file mode 100644 index 0000000..387b873 --- /dev/null +++ b/web/modules/forked/react_comments/src/Model/CommentsBase.php @@ -0,0 +1,37 @@ +entity_id = $id; + return $this; + } + + public function getEntityId() { + return (int) $this->entity_id; + } + + public function setComments($comments) { + $this->comments = $comments; + return $this; + } + + public function getComments() { + return $this->comments; + } + + public function model() { + return [ + 'comments' => $this->getComments(), + 'settings' => CommentFieldSettings::getCommentFieldSettings($this->getEntityId()) + ]; + } + +} diff --git a/web/modules/forked/react_comments/src/Model/Me.php b/web/modules/forked/react_comments/src/Model/Me.php new file mode 100644 index 0000000..225583b --- /dev/null +++ b/web/modules/forked/react_comments/src/Model/Me.php @@ -0,0 +1,7 @@ +current_user = $current_user; + return $this; + } + + public function getCurrentUser() { + return $this->current_user; + } + + public function model() { + return [ + 'current_user' => $this->getCurrentUser()->model(), + ]; + } + +} diff --git a/web/modules/forked/react_comments/src/Model/Request.php b/web/modules/forked/react_comments/src/Model/Request.php new file mode 100644 index 0000000..2efa1ca --- /dev/null +++ b/web/modules/forked/react_comments/src/Model/Request.php @@ -0,0 +1,7 @@ +request = \Drupal::request(); + } + + public function parseContentJson() { + $this->contents = json_decode($this->request->getContent(), TRUE); + return $this; + } + + public function getJsonVal($parameter) { + return !empty($this->contents[$parameter]) ? $this->contents[$parameter] : NULL; + } + +} diff --git a/web/modules/forked/react_comments/src/Model/Response.php b/web/modules/forked/react_comments/src/Model/Response.php new file mode 100644 index 0000000..402fdf6 --- /dev/null +++ b/web/modules/forked/react_comments/src/Model/Response.php @@ -0,0 +1,7 @@ +data = $data; + return $this; + } + + public function getData() { + return $this->data; + } + + public function setCode($code) { + $this->code = $code; + return $this; + } + + public function getCode() { + return $this->code; + } + + public function getMessage() { + $messages = [ + 'success' => $this->t('Success'), + 'invalid_nid' => $this->t('Invalid Entity ID supplied'), + 'nid_not_found' => $this->t('Entity ID not found'), + 'invalid_cid' => $this->t('Invalid Comment ID supplied'), + 'cid_not_found' => $this->t('Comment ID not found'), + 'invalid_uid' => $this->t('Invalid User ID supplied'), + 'uid_not_found' => $this->t('User ID not found'), + 'no_comments_found' => $this->t('No comments found for supplied entity'), + 'comment_deleted' => $this->t('Comment does not exist'), + 'already_deleted' => $this->t('Comment was already deleted'), + 'already_flagged' => $this->t('Comment was already flagged'), + 'not_authorized' => $this->t('You are not authorized. Please login'), + 'queued_for_moderation' => $this->t('Your comment has been queued for moderation'), + 'comments_closed' => $this->t('Comments are closed for this post'), + 'comments_hidden' => $this->t('Comments are disabled for this post'), + 'anon_contact_required' => $this->t('Contact info for anonymous users is required'), + 'anon_contact_forbidden' => $this->t('Contact info for anonymous users is forbidden') + ]; + + return !empty($messages[$this->getCode()]) + ? $messages[$this->getCode()] + : $this->t('Unknown error occured'); + } + + public function model() { + return [ + 'code' => $this->getCode(), + 'message' => $this->getMessage(), + 'data' => $this->getData(), + ]; + } + +} diff --git a/web/modules/forked/react_comments/src/Model/User.php b/web/modules/forked/react_comments/src/Model/User.php new file mode 100644 index 0000000..78bfe3a --- /dev/null +++ b/web/modules/forked/react_comments/src/Model/User.php @@ -0,0 +1,83 @@ +load($user); + } + } + + public function load(AccountInterface $user = NULL) { + $user = $user ?: DrupalUser::load($this->getId()); + + if ($user) { + // load the full user entity so we can access the user picture field + $user = DrupalUser::load($user->id()); + + $user_picture = null; + + if ($user->isAnonymous()) { + $user_avatar_image_style = \Drupal::config('react_comments.settings')->get('user_avatar_image_style') ?: 'thumbnail'; + $default_anon_avatar_fid = \Drupal::config('react_comments.settings')->get('anon_default_avatar_fid') ?: null; + + if ($default_anon_avatar_fid) { + $default_anon_avatar_file = File::load($default_anon_avatar_fid[0]); + $user_picture = ImageStyle::load($user_avatar_image_style)->buildUrl($default_anon_avatar_file->getFileUri()); + } + } + else if (isset($user->user_picture) && !$user->user_picture->isEmpty()) { + $user_avatar_image_style = \Drupal::config('react_comments.settings')->get('user_avatar_image_style') ?: 'thumbnail'; + $uri = $user->user_picture->entity->uri->value; + $user_picture = ImageStyle::load($user_avatar_image_style)->buildUrl($uri); + } + + if (is_null($user_picture)) { + $user_picture = $this->getDefault_user_image(); + } + + $this + ->setId($user->id()) + ->setName($user->id() ? $user->getDisplayName() : null) + ->setEmail($user->getEmail()) + ->setThumbnail($user_picture) + ->setPermissions($this->loadPermissions($user)); + } + } + + private function loadPermissions(AccountInterface $user) { + $permissions = [ + 'administer comments', + 'administer comment types', + 'access comments', + 'post comments', + 'skip comment approval', + 'edit own comments' + ]; + foreach ($permissions as $key => $permission) { + if (!$user->hasPermission($permission)) { + unset($permissions[$key]); + } + } + return $permissions; + } + + // Get User default image + private function getDefault_user_image() { + $field = \Drupal\field\Entity\FieldConfig::loadByName('user', 'user', 'user_picture'); + $default_image = $field->getSetting('default_image'); + + if ($default_image) { + $user_avatar_image_style = \Drupal::config('react_comments.settings')->get('user_avatar_image_style') ?: 'thumbnail'; + $file = \Drupal::service('entity.repository')->loadEntityByUuid('file', $default_image['uuid']); + return ImageStyle::load($user_avatar_image_style)->buildUrl($file->getFileUri()); + } + } +} diff --git a/web/modules/forked/react_comments/src/Model/UserBase.php b/web/modules/forked/react_comments/src/Model/UserBase.php new file mode 100644 index 0000000..3cb050c --- /dev/null +++ b/web/modules/forked/react_comments/src/Model/UserBase.php @@ -0,0 +1,116 @@ +id = $id; + return $this; + } + + public function getId() { + return (int) $this->id; + } + + public function setName($name) { + $this->name = $name; + return $this; + } + + public function getName() { + return $this->checkPlain($this->name); + } + + public function setEmail($email) { + $this->email = $email; + return $this; + } + + public function getEmail() { + return $this->checkPlain($this->email); + } + + public function getIpAddress() { + // @todo dependency injection + return \Drupal::request()->getClientIp(); + } + + public function setThumbnail($url) { + $prefer_gravatar = \Drupal::config('react_comments.settings')->get('prefer_gravatar'); + + if ($prefer_gravatar || empty($url)) { + $this->thumbnail = $this->getGravatar($this->getEmail()); + } + else { + $this->thumbnail = $url; + } + + $this->thumbnail = $url; + + return $this; + } + + public function getThumbnail() { + if (!$this->thumbnail) { + $this->thumbnail = $this->getGravatar($this->getEmail()); + } + return $this->thumbnail; + } + + public function getPermissions() { + return $this->permissions; + } + + public function setPermissions($permissions) { + $this->permissions = $permissions; + return $this; + } + + public function hasPermission($permission) { + return in_array($permission, $this->permissions); + } + + public function model() { + return [ + 'id' => $this->getId(), + 'name' => $this->getName(), + 'thumbnail' => $this->getThumbnail(), + 'email' => $this->getEmail(), + 'isAnon' => ($this->getId() === 0), + 'permissions' => $this->getPermissions() + ]; + } + + /** + * Get either a Gravatar URL or complete image tag for a specified email address. + * + * @param string $email The email address + * @param string $s Size in pixels, defaults to 80px [ 1 - 2048 ] + * @param string $d Default imageset to use [ 404 | mm | identicon | monsterid | wavatar ] + * @param string $r Maximum rating (inclusive) [ g | pg | r | x ] + * @param boole $img True to return a complete IMG tag False for just the URL + * @param array $atts Optional, additional key/value attributes to include in the IMG tag + * @return String containing either just a URL or a complete image tag + * @source https://gravatar.com/site/implement/images/php/ + */ + protected function getGravatar( $email, $s = 80, $d = 'mm', $r = 'g', $img = FALSE, $atts = [] ) { + $url = 'https://www.gravatar.com/avatar/'; + $url .= md5( strtolower( trim( $email ) ) ); + $url .= "?s=$s&d=$d&r=$r"; + if ( $img ) { + $url = ' $val ) + $url .= ' ' . $key . '="' . $val . '"'; + $url .= ' />'; + } + return $url; + } + +} diff --git a/web/modules/forked/react_comments/src/Plugin/rest/resource/Comment.php b/web/modules/forked/react_comments/src/Plugin/rest/resource/Comment.php new file mode 100644 index 0000000..ed5ed61 --- /dev/null +++ b/web/modules/forked/react_comments/src/Plugin/rest/resource/Comment.php @@ -0,0 +1,164 @@ +parseContentJson(); + $op = $request->getJsonVal('op'); + + $response = new ResponseModel(); + $response->setCode('cid_not_found'); + + if (empty($cid)) { + $response->setCode('invalid_cid'); + } + else { + $current_user = new User(\Drupal::currentUser()); + if (!$current_user->getId()) { + $response->setCode('not_authorized'); + } + else { + + $comment = (new CommentModel())->setId($cid); + + switch ($op) { + case 'flag': + if ($comment->load()) { + if ($comment->getStatus() != RC_COMMENT_FLAGGED) { + $comment->setStatus( RC_COMMENT_FLAGGED )->update(); + $response->setData($comment->model()) + ->setCode('success'); + } + else { + $response->setData($comment->model()) + ->setCode('already_flagged'); + } + } + break; + case 'publish': + case 'unpublish': + if (!$current_user->hasPermission('administer comments')) break; + + if ($comment->load()) { + $op = ($op === 'publish') ? RC_COMMENT_PUBLISHED : RC_COMMENT_UNPUBLISHED; + if ($comment->getStatus() != $op) { + $comment->setStatus($op)->update(); + $response->setData($comment->model()) + ->setCode('success'); + } + } + } + } + } + + return (new JsonResponse($response->model())); + } + + /** + * Update comment. + */ + public function patch($cid = NULL) { + $request = (new RequestModel())->parseContentJson(); + $response = new ResponseModel(); + if (empty($cid)) { + $response->setCode('invalid_cid'); + } + else { + $current_user = \Drupal::currentUser(); + + if (!$current_user->id()) { + $response->setCode('not_authorized'); + } + + $comment = new CommentModel(); + $response->setCode('cid_not_found'); + if ($comment->setId($cid)->load()) { + if (!$current_user->hasPermission('administer comments') && (CommentFieldSettings::getCommentFieldStatus($comment->getEntityId()) === 'closed')) { + $response->setCode('comments_closed'); + return new JsonResponse($response->model(), 403); + } + else if (($current_user->id() !== (string) $comment->getUser()->getId()) && !$current_user->hasPermission('administer comments')) { + $response->setCode('not_authorized'); + return new JsonResponse($response->model(), 403); + } + else if ($comment->getStatus() !== 0 || $current_user->hasPermission('administer comments')) { + $comment_body = $request->getJsonVal('comment'); + $comment->setComment($comment_body)->update(); + $response->setData($comment->model()) + ->setCode('success'); + } + else { + $response->setCode('comment_deleted'); + } + } + } + $response = new JsonResponse($response->model()); + return $response; + } + + /** + * Delete comment. + */ + public function delete($cid = NULL) { + $response = new ResponseModel(); + if (empty($cid)) { + $response->setCode('invalid_cid'); + } + else { + $current_user = new User(\Drupal::currentUser()); + if (!$current_user->getId()) { + $response->setCode('not_authorized'); + } + else { + $comment = new CommentModel(); + $response->setCode('cid_not_found'); + if ($item = $comment->setId($cid)->load()) { + if (!$current_user->hasPermission('administer comments') && (CommentFieldSettings::getCommentFieldStatus($comment->getEntityId()) === 'closed')) { + $response->setCode('comments_closed'); + return new JsonResponse($response->model(), 403); + } + else if ($item->getStatus() != RC_COMMENT_DELETED) { + $item->setUser($current_user)->delete(); + if ($node = Node::load($comment->getEntityId())) { + Cache::invalidateTags($node->getCacheTags()); + } + $response->setData($item->model()) + ->setCode('success'); + } + else { + $response->setCode('already_deleted'); + } + } + } + } + return (new JsonResponse()); + } + +} diff --git a/web/modules/forked/react_comments/src/Plugin/rest/resource/Comments.php b/web/modules/forked/react_comments/src/Plugin/rest/resource/Comments.php new file mode 100644 index 0000000..5945213 --- /dev/null +++ b/web/modules/forked/react_comments/src/Plugin/rest/resource/Comments.php @@ -0,0 +1,208 @@ +addCacheableDependency($node); + } + + if (empty($entity_id)) { + $response->setCode('invalid_nid'); + } + else if (CommentFieldSettings::getCommentFieldStatus($entity_id) === 'hidden') { + $response->setCode('comments_hidden'); + $res = (new ResourceResponse($response->model(), 403)); + $res->addCacheableDependency($cache_metadata); + return $res; + } + else if (!$node) { + $response->setCode('nid_not_found'); + } + else { + $comments = new CommentsModel(); + + $show_unpublished = \Drupal::currentUser()->hasPermission('administer comments'); + + if ($items = $comments->setEntityId($entity_id)->load($show_unpublished)) { + $response->setData($items->model()) + ->setCode('success'); + + // Since we're exposing properties about each user + // (to display as the comment author), + // we need to invalidate a cached response if any of those users change. + $cache_tags = array_map(function($comment) { + return 'user:' . $comment['user']['id']; + }, $items->getComments()); + $cache_metadata->addCacheTags($cache_tags); + } + else { + $response->setCode('no_comments_found'); + } + } + + $res = (new ResourceResponse($response->model())); + $res->getCacheableMetadata()->addCacheContexts(['user.permissions']); + + // Since we're exposing field config settings (to determine whether or not anons should leave contact info) we need to add the appropriate cache tags. + $res->getCacheableMetadata()->addCacheTags(CommentFieldSettings::getCommentFieldConfigCacheTags($entity_id)); + + $res->getCacheableMetadata()->addCacheTags(['react_comment_list']); + + $res->addCacheableDependency($cache_metadata); + return $res; + } + + public function post($entity_id = NULL) { + $response = new ResponseModel(); + $drupal_user = \Drupal::currentUser(); + + if (empty($entity_id)) { + $response->setCode('invalid_nid'); + return (new JsonResponse($response->model(), 404)); + } + else if ((CommentFieldSettings::getCommentFieldStatus($entity_id) === 'closed') && !$drupal_user->hasPermission('administer comments')) { + $response->setCode('comments_closed'); + return (new JsonResponse($response->model(), 403)); + } + + // @todo make this less specific, comments don't necessarily have to be on a node. + if ($node = Node::load($entity_id)) { + + $request = (new RequestModel())->parseContentJson(); + $comment = new CommentModel(); + $current_user = new User($drupal_user); + $response->setCode('not_authorized'); + + if (is_numeric($current_user->getId()) && $drupal_user->hasPermission('post comments')) { + $comment_body = $request->getJsonVal('comment'); + + $skip_approval = $drupal_user->hasPermission('skip comment approval'); + + if ($skip_approval) { + $comment->setStatus( RC_COMMENT_PUBLISHED ); + } + else { + $comment->setStatus( RC_COMMENT_UNPUBLISHED ); + } + + if ($current_user->getId() === 0) { + $comment_field_settings = CommentFieldSettings::getCommentFieldSettings($entity_id); + + // These two cases should never happen + if (isset($comment_field_settings['anonymous']) && $comment_field_settings['anonymous'] === CommentInterface::ANONYMOUS_MUST_CONTACT && empty($request->getJsonVal('anon_email'))) { + $response->setCode('anon_contact_required'); + return (new JsonResponse($response->model(), 400)); + } + else if (isset($comment_field_settings['anonymous']) && $comment_field_settings['anonymous'] === CommentInterface::ANONYMOUS_MAYNOT_CONTACT && !empty($request->getJsonVal('anon_email'))) { + $response->setCode('anon_contact_forbidden'); + return (new JsonResponse($response->model(), 400)); + } + + $comment->setName($request->getJsonVal('anon_name')); + $comment->setEmail($request->getJsonVal('anon_email')); + } + + $comment_field_name_and_type = $this->getCommentFieldNameAndType($node); + + $comment->setEntityId($entity_id) + ->setUser($current_user) + ->setFieldName($comment_field_name_and_type['name']) + ->setCommentType($comment_field_name_and_type['type']) + ->setComment($comment_body); + $comment->setReplyId($request->getJsonVal('reply_comment_id')); + $comment_id = $comment->save(); + if ($comment_id) { + $response->setData($comment->setId($comment_id)->load()->model()) + ->setCode('queued_for_moderation'); + } + if ($skip_approval) { + $response->setCode('success'); + } + } + + // Invalidate node cache. + Cache::invalidateTags($node->getCacheTags()); + } + else { + $response->setCode('nid_not_found'); + } + + return (new JsonResponse($response->model())); + } + + private function getCommentFieldNameAndType($node) { + // Get the comment field name and type using in the current node + $comment_field_name = 'comment'; + $comment_type = 'comment'; + + $field_definitions = $node->getFieldDefinitions(); + + foreach ($field_definitions as $definition) { + // Get field definitions of a comment field + if ($definition instanceof FieldConfig) { + $type = $definition->get('field_type'); + + if (isset($type) && $type === 'comment') { + // Get comment field name from field definitions + $comment_field_name_value = $definition->get('field_name'); + // Make sure this value is not null + if (isset($comment_field_name)) { + $comment_field_name = $comment_field_name_value; + } + + // Get comment field type from field storage definitions + $fsd = $definition->getFieldStorageDefinition(); + if (isset($fsd)) { + $comment_type_value = $fsd->getSetting('comment_type'); + // Make sure this value is not null + if (isset($comment_type_value)) { + $comment_type = $comment_type_value; + } + } + break; + } + } + } + + return [ + 'name' => $comment_field_name, + 'type' => $comment_type + ]; + } +} diff --git a/web/modules/forked/react_comments/src/Plugin/rest/resource/Me.php b/web/modules/forked/react_comments/src/Plugin/rest/resource/Me.php new file mode 100644 index 0000000..0a80631 --- /dev/null +++ b/web/modules/forked/react_comments/src/Plugin/rest/resource/Me.php @@ -0,0 +1,42 @@ +setCurrentUser($user); + $response->setData($me->model()) + ->setCode('success'); + + $response = (new ResourceResponse($response->model())); + $response->getCacheableMetadata()->setCacheContexts(['user']); + $response->addCacheableDependency($current_user); + return $response; + } + +} diff --git a/web/modules/forked/react_comments/src/Plugin/views/field/ReactCommentsStatus.php b/web/modules/forked/react_comments/src/Plugin/views/field/ReactCommentsStatus.php new file mode 100644 index 0000000..f647a89 --- /dev/null +++ b/web/modules/forked/react_comments/src/Plugin/views/field/ReactCommentsStatus.php @@ -0,0 +1,66 @@ +getValue($values); + if (!empty($this->options['not'])) { + $value = !$value; + } + return $this->getStatusLabel($value); + } + + protected function getStatusLabel($value) { + if ($value == RC_COMMENT_PUBLISHED) { + return $this->t('Published'); + } + elseif ($value == RC_COMMENT_UNPUBLISHED) { + return $this->t('Unpublished'); + } + elseif ($value == RC_COMMENT_FLAGGED) { + return $this->t('Flagged'); + } + elseif ($value == RC_COMMENT_DELETED) { + return $this->t('Deleted'); + } + } + +} diff --git a/web/modules/forked/react_comments/src/Plugin/views/filter/ReactCommentsStatus.php b/web/modules/forked/react_comments/src/Plugin/views/filter/ReactCommentsStatus.php new file mode 100644 index 0000000..ca6d02b --- /dev/null +++ b/web/modules/forked/react_comments/src/Plugin/views/filter/ReactCommentsStatus.php @@ -0,0 +1,54 @@ +ensureMyTable(); + if ($this->value != 'All') { + $field = "$this->tableAlias.$this->realField"; + + $info = $this->operators(); + if (!empty($info[$this->operator]['method'])) { + $this->{$info[$this->operator]['method']}($field); + } + } + } + + protected function opSimple($field) { + if ($this->value['value'] != 'All') { + $this->query->addWhere($this->options['group'], $field, $this->value['value'], $this->operator); + } + } + + /** + * Status filter. + */ + protected function valueForm(&$form, FormStateInterface $form_state) { + $form['value'] = [ + '#type' => 'select', + '#title' => $this->t('Status'), + '#options' => $this->getStatues(), + '#default_value' => !empty($this->value['value']) ? $this->value['value'] : '', + ]; + } + + protected function getStatues() { + return [ + RC_COMMENT_PUBLISHED => $this->t('Published'), + RC_COMMENT_UNPUBLISHED => $this->t('Unpublished'), + RC_COMMENT_FLAGGED => $this->t('Flagged'), + RC_COMMENT_DELETED => $this->t('Deleted'), + ]; + } + +} diff --git a/web/modules/forked/react_comments/templates/field--comment.html.twig b/web/modules/forked/react_comments/templates/field--comment.html.twig new file mode 100644 index 0000000..a942b24 --- /dev/null +++ b/web/modules/forked/react_comments/templates/field--comment.html.twig @@ -0,0 +1 @@ +

    diff --git a/web/profiles/.gitignore b/web/profiles/.gitignore new file mode 100644 index 0000000..739a339 --- /dev/null +++ b/web/profiles/.gitignore @@ -0,0 +1 @@ +/README.txt \ No newline at end of file diff --git a/web/profiles/.gitkeep b/web/profiles/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/web/robots.txt b/web/robots.txt new file mode 100644 index 0000000..18f8df8 --- /dev/null +++ b/web/robots.txt @@ -0,0 +1,61 @@ +# +# robots.txt +# +# This file is to prevent the crawling and indexing of certain parts +# of your site by web crawlers and spiders run by sites like Yahoo! +# and Google. By telling these "robots" where not to go on your site, +# you save bandwidth and server resources. +# +# This file will be ignored unless it is at the root of your host: +# Used: http://example.com/robots.txt +# Ignored: http://example.com/site/robots.txt +# +# For more information about the robots.txt standard, see: +# http://www.robotstxt.org/robotstxt.html + +User-agent: * +# CSS, JS, Images +Allow: /core/*.css$ +Allow: /core/*.css? +Allow: /core/*.js$ +Allow: /core/*.js? +Allow: /core/*.gif +Allow: /core/*.jpg +Allow: /core/*.jpeg +Allow: /core/*.png +Allow: /core/*.svg +Allow: /profiles/*.css$ +Allow: /profiles/*.css? +Allow: /profiles/*.js$ +Allow: /profiles/*.js? +Allow: /profiles/*.gif +Allow: /profiles/*.jpg +Allow: /profiles/*.jpeg +Allow: /profiles/*.png +Allow: /profiles/*.svg +# Directories +Disallow: /core/ +Disallow: /profiles/ +# Files +Disallow: /README.txt +Disallow: /web.config +# Paths (clean URLs) +Disallow: /admin/ +Disallow: /comment/reply/ +Disallow: /filter/tips +Disallow: /node/add/ +Disallow: /search/ +Disallow: /user/register +Disallow: /user/password +Disallow: /user/login +Disallow: /user/logout +# Paths (no clean URLs) +Disallow: /index.php/admin/ +Disallow: /index.php/comment/reply/ +Disallow: /index.php/filter/tips +Disallow: /index.php/node/add/ +Disallow: /index.php/search/ +Disallow: /index.php/user/password +Disallow: /index.php/user/register +Disallow: /index.php/user/login +Disallow: /index.php/user/logout diff --git a/web/sites/.gitignore b/web/sites/.gitignore new file mode 100644 index 0000000..739a339 --- /dev/null +++ b/web/sites/.gitignore @@ -0,0 +1 @@ +/README.txt \ No newline at end of file diff --git a/web/sites/default/default.services.yml b/web/sites/default/default.services.yml new file mode 100644 index 0000000..d21a5c7 --- /dev/null +++ b/web/sites/default/default.services.yml @@ -0,0 +1,190 @@ +parameters: + session.storage.options: + # Default ini options for sessions. + # + # Some distributions of Linux (most notably Debian) ship their PHP + # installations with garbage collection (gc) disabled. Since Drupal depends + # on PHP's garbage collection for clearing sessions, ensure that garbage + # collection occurs by using the most common settings. + # @default 1 + gc_probability: 1 + # @default 100 + gc_divisor: 100 + # + # Set session lifetime (in seconds), i.e. the grace period for session + # data. Sessions are deleted by the session garbage collector after one + # session lifetime has elapsed since the user's last visit. When a session + # is deleted, authenticated users are logged out, and the contents of the + # user's session is discarded. + # @default 200000 + gc_maxlifetime: 200000 + # + # Set session cookie lifetime (in seconds), i.e. the time from the session + # is created to the cookie expires, i.e. when the browser is expected to + # discard the cookie. The value 0 means "until the browser is closed". + # @default 2000000 + cookie_lifetime: 2000000 + # + # Drupal automatically generates a unique session cookie name based on the + # full domain name used to access the site. This mechanism is sufficient + # for most use-cases, including multi-site deployments. However, if it is + # desired that a session can be reused across different subdomains, the + # cookie domain needs to be set to the shared base domain. Doing so assures + # that users remain logged in as they cross between various subdomains. + # To maximize compatibility and normalize the behavior across user agents, + # the cookie domain should start with a dot. + # + # @default none + # cookie_domain: '.example.com' + # + # Set the session ID string length. The length can be between 22 to 256. The + # PHP recommended value is 48. See + # https://www.php.net/manual/session.security.ini.php for more information. + # This value should be kept in sync with + # \Drupal\Core\Session\SessionConfiguration::__construct() + # @default 48 + sid_length: 48 + # + # Set the number of bits in encoded session ID character. The possible + # values are '4' (0-9, a-f), '5' (0-9, a-v), and '6' (0-9, a-z, A-Z, "-", + # ","). The PHP recommended value is 6. See + # https://www.php.net/manual/session.security.ini.php for more information. + # This value should be kept in sync with + # \Drupal\Core\Session\SessionConfiguration::__construct() + # @default 6 + sid_bits_per_character: 6 + twig.config: + # Twig debugging: + # + # When debugging is enabled: + # - The markup of each Twig template is surrounded by HTML comments that + # contain theming information, such as template file name suggestions. + # - Note that this debugging markup will cause automated tests that directly + # check rendered HTML to fail. When running automated tests, 'debug' + # should be set to FALSE. + # - The dump() function can be used in Twig templates to output information + # about template variables. + # - Twig templates are automatically recompiled whenever the source code + # changes (see auto_reload below). + # + # For more information about debugging Twig templates, see + # https://www.drupal.org/node/1906392. + # + # Not recommended in production environments + # @default false + debug: false + # Twig auto-reload: + # + # Automatically recompile Twig templates whenever the source code changes. + # If you don't provide a value for auto_reload, it will be determined + # based on the value of debug. + # + # Not recommended in production environments + # @default null + auto_reload: null + # Twig cache: + # + # By default, Twig templates will be compiled and stored in the filesystem + # to increase performance. Disabling the Twig cache will recompile the + # templates from source each time they are used. In most cases the + # auto_reload setting above should be enabled rather than disabling the + # Twig cache. + # + # Not recommended in production environments + # @default true + cache: true + renderer.config: + # Renderer required cache contexts: + # + # The Renderer will automatically associate these cache contexts with every + # render array, hence varying every render array by these cache contexts. + # + # @default ['languages:language_interface', 'theme', 'user.permissions'] + required_cache_contexts: ['languages:language_interface', 'theme', 'user.permissions'] + # Renderer automatic placeholdering conditions: + # + # Drupal allows portions of the page to be automatically deferred when + # rendering to improve cache performance. That is especially helpful for + # cache contexts that vary widely, such as the active user. On some sites + # those may be different, however, such as sites with only a handful of + # users. If you know what the high-cardinality cache contexts are for your + # site, specify those here. If you're not sure, the defaults are fairly safe + # in general. + # + # For more information about rendering optimizations see + # https://www.drupal.org/developing/api/8/render/arrays/cacheability#optimizing + auto_placeholder_conditions: + # Max-age at or below which caching is not considered worthwhile. + # + # Disable by setting to -1. + # + # @default 0 + max-age: 0 + # Cache contexts with a high cardinality. + # + # Disable by setting to []. + # + # @default ['session', 'user'] + contexts: ['session', 'user'] + # Tags with a high invalidation frequency. + # + # Disable by setting to []. + # + # @default [] + tags: [] + # Cacheability debugging: + # + # Responses with cacheability metadata (CacheableResponseInterface instances) + # get X-Drupal-Cache-Tags, X-Drupal-Cache-Contexts and X-Drupal-Cache-Max-Age + # headers. + # + # For more information about debugging cacheable responses, see + # https://www.drupal.org/developing/api/8/response/cacheable-response-interface + # + # Not recommended in production environments + # @default false + http.response.debug_cacheability_headers: false + factory.keyvalue: {} + # Default key/value storage service to use. + # @default keyvalue.database + # default: keyvalue.database + # Collection-specific overrides. + # state: keyvalue.database + factory.keyvalue.expirable: {} + # Default key/value expirable storage service to use. + # @default keyvalue.database.expirable + # default: keyvalue.database.expirable + # Allowed protocols for URL generation. + filter_protocols: + - http + - https + - ftp + - news + - nntp + - tel + - telnet + - mailto + - irc + - ssh + - sftp + - webcal + - rtsp + + # Configure Cross-Site HTTP requests (CORS). + # Read https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS + # for more information about the topic in general. + # Note: By default the configuration is disabled. + cors.config: + enabled: false + # Specify allowed headers, like 'x-allowed-header'. + allowedHeaders: [] + # Specify allowed request methods, specify ['*'] to allow all possible ones. + allowedMethods: [] + # Configure requests allowed from specific origins. + allowedOrigins: ['*'] + # Sets the Access-Control-Expose-Headers header. + exposedHeaders: false + # Sets the Access-Control-Max-Age header. + maxAge: false + # Sets the Access-Control-Allow-Credentials header. + supportsCredentials: false diff --git a/web/sites/default/default.settings.local.php b/web/sites/default/default.settings.local.php new file mode 100644 index 0000000..7c97910 --- /dev/null +++ b/web/sites/default/default.settings.local.php @@ -0,0 +1,139 @@ + 'databasename', + * 'username' => 'sqlusername', + * 'password' => 'sqlpassword', + * 'host' => 'localhost', + * 'port' => '3306', + * 'driver' => 'mysql', + * 'prefix' => '', + * 'collation' => 'utf8mb4_general_ci', + * ]; + * @endcode + */ +$databases = []; + +/** + * Customizing database settings. + * + * Many of the values of the $databases array can be customized for your + * particular database system. Refer to the sample in the section above as a + * starting point. + * + * The "driver" property indicates what Drupal database driver the + * connection should use. This is usually the same as the name of the + * database type, such as mysql or sqlite, but not always. The other + * properties will vary depending on the driver. For SQLite, you must + * specify a database file name in a directory that is writable by the + * webserver. For most other drivers, you must specify a + * username, password, host, and database name. + * + * Drupal core implements drivers for mysql, pgsql, and sqlite. Other drivers + * can be provided by contributed or custom modules. To use a contributed or + * custom driver, the "namespace" property must be set to the namespace of the + * driver. The code in this namespace must be autoloadable prior to connecting + * to the database, and therefore, prior to when module root namespaces are + * added to the autoloader. To add the driver's namespace to the autoloader, + * set the "autoload" property to the PSR-4 base directory of the driver's + * namespace. This is optional for projects managed with Composer if the + * driver's namespace is in Composer's autoloader. + * + * For each database, you may optionally specify multiple "target" databases. + * A target database allows Drupal to try to send certain queries to a + * different database if it can but fall back to the default connection if not. + * That is useful for primary/replica replication, as Drupal may try to connect + * to a replica server when appropriate and if one is not available will simply + * fall back to the single primary server (The terms primary/replica are + * traditionally referred to as master/slave in database server documentation). + * + * The general format for the $databases array is as follows: + * @code + * $databases['default']['default'] = $info_array; + * $databases['default']['replica'][] = $info_array; + * $databases['default']['replica'][] = $info_array; + * $databases['extra']['default'] = $info_array; + * @endcode + * + * In the above example, $info_array is an array of settings described above. + * The first line sets a "default" database that has one primary database + * (the second level default). The second and third lines create an array + * of potential replica databases. Drupal will select one at random for a given + * request as needed. The fourth line creates a new database with a name of + * "extra". + * + * You can optionally set a prefix for all database table names by using the + * 'prefix' setting. If a prefix is specified, the table name will be prepended + * with its value. Be sure to use valid database characters only, usually + * alphanumeric and underscore. If no prefix is desired, do not set the 'prefix' + * key or set its value to an empty string ''. + * + * For example, to have all database table prefixed with 'main_', set: + * @code + * 'prefix' => 'main_', + * @endcode + * + * Advanced users can add or override initial commands to execute when + * connecting to the database server, as well as PDO connection settings. For + * example, to enable MySQL SELECT queries to exceed the max_join_size system + * variable, and to reduce the database connection timeout to 5 seconds: + * @code + * $databases['default']['default'] = [ + * 'init_commands' => [ + * 'big_selects' => 'SET SQL_BIG_SELECTS=1', + * ], + * 'pdo' => [ + * PDO::ATTR_TIMEOUT => 5, + * ], + * ]; + * @endcode + * + * WARNING: The above defaults are designed for database portability. Changing + * them may cause unexpected behavior, including potential data loss. See + * https://www.drupal.org/developing/api/database/configuration for more + * information on these defaults and the potential issues. + * + * More details can be found in the constructor methods for each driver: + * - \Drupal\Core\Database\Driver\mysql\Connection::__construct() + * - \Drupal\Core\Database\Driver\pgsql\Connection::__construct() + * - \Drupal\Core\Database\Driver\sqlite\Connection::__construct() + * + * Sample Database configuration format for PostgreSQL (pgsql): + * @code + * $databases['default']['default'] = [ + * 'driver' => 'pgsql', + * 'database' => 'databasename', + * 'username' => 'sqlusername', + * 'password' => 'sqlpassword', + * 'host' => 'localhost', + * 'prefix' => '', + * ]; + * @endcode + * + * Sample Database configuration format for SQLite (sqlite): + * @code + * $databases['default']['default'] = [ + * 'driver' => 'sqlite', + * 'database' => '/path/to/databasefilename', + * ]; + * @endcode + * + * Sample Database configuration format for a driver in a contributed module: + * @code + * $databases['default']['default'] = [ + * 'driver' => 'my_driver', + * 'namespace' => 'Drupal\my_module\Driver\Database\my_driver', + * 'autoload' => 'modules/my_module/src/Driver/Database/my_driver/', + * 'database' => 'databasename', + * 'username' => 'sqlusername', + * 'password' => 'sqlpassword', + * 'host' => 'localhost', + * 'prefix' => '', + * ]; + * @endcode + */ + +/** + * Location of the site configuration files. + * + * The $settings['config_sync_directory'] specifies the location of file system + * directory used for syncing configuration data. On install, the directory is + * created. This is used for configuration imports. + * + * The default location for this directory is inside a randomly-named + * directory in the public files path. The setting below allows you to set + * its location. + */ +# $settings['config_sync_directory'] = '/directory/outside/webroot'; + +/** + * Settings: + * + * $settings contains environment-specific configuration, such as the files + * directory and reverse proxy address, and temporary configuration, such as + * security overrides. + * + * @see \Drupal\Core\Site\Settings::get() + */ + +/** + * Salt for one-time login links, cancel links, form tokens, etc. + * + * This variable will be set to a random value by the installer. All one-time + * login links will be invalidated if the value is changed. Note that if your + * site is deployed on a cluster of web servers, you must ensure that this + * variable has the same value on each server. + * + * For enhanced security, you may set this variable to the contents of a file + * outside your document root; you should also ensure that this file is not + * stored with backups of your database. + * + * Example: + * @code + * $settings['hash_salt'] = file_get_contents('/home/example/salt.txt'); + * @endcode + */ +$settings['hash_salt'] = ''; + +/** + * Deployment identifier. + * + * Drupal's dependency injection container will be automatically invalidated and + * rebuilt when the Drupal core version changes. When updating contributed or + * custom code that changes the container, changing this identifier will also + * allow the container to be invalidated as soon as code is deployed. + */ +# $settings['deployment_identifier'] = \Drupal::VERSION; + +/** + * Access control for update.php script. + * + * If you are updating your Drupal installation using the update.php script but + * are not logged in using either an account with the "Administer software + * updates" permission or the site maintenance account (the account that was + * created during installation), you will need to modify the access check + * statement below. Change the FALSE to a TRUE to disable the access check. + * After finishing the upgrade, be sure to open this file again and change the + * TRUE back to a FALSE! + */ +$settings['update_free_access'] = FALSE; + +/** + * Fallback to HTTP for Update Manager and for fetching security advisories. + * + * If your site fails to connect to updates.drupal.org over HTTPS (either when + * fetching data on available updates, or when fetching the feed of critical + * security announcements), you may uncomment this setting and set it to TRUE to + * allow an insecure fallback to HTTP. Note that doing so will open your site up + * to a potential man-in-the-middle attack. You should instead attempt to + * resolve the issues before enabling this option. + * @see https://www.drupal.org/docs/system-requirements/php-requirements#openssl + * @see https://en.wikipedia.org/wiki/Man-in-the-middle_attack + * @see \Drupal\update\UpdateFetcher + * @see \Drupal\system\SecurityAdvisories\SecurityAdvisoriesFetcher + */ +# $settings['update_fetch_with_http_fallback'] = TRUE; + +/** + * External access proxy settings: + * + * If your site must access the Internet via a web proxy then you can enter the + * proxy settings here. Set the full URL of the proxy, including the port, in + * variables: + * - $settings['http_client_config']['proxy']['http']: The proxy URL for HTTP + * requests. + * - $settings['http_client_config']['proxy']['https']: The proxy URL for HTTPS + * requests. + * You can pass in the user name and password for basic authentication in the + * URLs in these settings. + * + * You can also define an array of host names that can be accessed directly, + * bypassing the proxy, in $settings['http_client_config']['proxy']['no']. + */ +# $settings['http_client_config']['proxy']['http'] = 'http://proxy_user:proxy_pass@example.com:8080'; +# $settings['http_client_config']['proxy']['https'] = 'http://proxy_user:proxy_pass@example.com:8080'; +# $settings['http_client_config']['proxy']['no'] = ['127.0.0.1', 'localhost']; + +/** + * Reverse Proxy Configuration: + * + * Reverse proxy servers are often used to enhance the performance + * of heavily visited sites and may also provide other site caching, + * security, or encryption benefits. In an environment where Drupal + * is behind a reverse proxy, the real IP address of the client should + * be determined such that the correct client IP address is available + * to Drupal's logging, statistics, and access management systems. In + * the most simple scenario, the proxy server will add an + * X-Forwarded-For header to the request that contains the client IP + * address. However, HTTP headers are vulnerable to spoofing, where a + * malicious client could bypass restrictions by setting the + * X-Forwarded-For header directly. Therefore, Drupal's proxy + * configuration requires the IP addresses of all remote proxies to be + * specified in $settings['reverse_proxy_addresses'] to work correctly. + * + * Enable this setting to get Drupal to determine the client IP from the + * X-Forwarded-For header. If you are unsure about this setting, do not have a + * reverse proxy, or Drupal operates in a shared hosting environment, this + * setting should remain commented out. + * + * In order for this setting to be used you must specify every possible + * reverse proxy IP address in $settings['reverse_proxy_addresses']. + * If a complete list of reverse proxies is not available in your + * environment (for example, if you use a CDN) you may set the + * $_SERVER['REMOTE_ADDR'] variable directly in settings.php. + * Be aware, however, that it is likely that this would allow IP + * address spoofing unless more advanced precautions are taken. + */ +# $settings['reverse_proxy'] = TRUE; + +/** + * Specify every reverse proxy IP address in your environment. + * This setting is required if $settings['reverse_proxy'] is TRUE. + */ +# $settings['reverse_proxy_addresses'] = ['a.b.c.d', ...]; + +/** + * Reverse proxy trusted headers. + * + * Sets which headers to trust from your reverse proxy. + * + * Common values are: + * - \Symfony\Component\HttpFoundation\Request::HEADER_X_FORWARDED_FOR + * - \Symfony\Component\HttpFoundation\Request::HEADER_X_FORWARDED_HOST + * - \Symfony\Component\HttpFoundation\Request::HEADER_X_FORWARDED_PORT + * - \Symfony\Component\HttpFoundation\Request::HEADER_X_FORWARDED_PROTO + * - \Symfony\Component\HttpFoundation\Request::HEADER_FORWARDED + * + * Note the default value of + * @code + * \Symfony\Component\HttpFoundation\Request::HEADER_X_FORWARDED_FOR | \Symfony\Component\HttpFoundation\Request::HEADER_X_FORWARDED_HOST | \Symfony\Component\HttpFoundation\Request::HEADER_X_FORWARDED_PORT | \Symfony\Component\HttpFoundation\Request::HEADER_X_FORWARDED_PROTO | \Symfony\Component\HttpFoundation\Request::HEADER_FORWARDED + * @endcode + * is not secure by default. The value should be set to only the specific + * headers the reverse proxy uses. For example: + * @code + * \Symfony\Component\HttpFoundation\Request::HEADER_X_FORWARDED_FOR | \Symfony\Component\HttpFoundation\Request::HEADER_X_FORWARDED_HOST | \Symfony\Component\HttpFoundation\Request::HEADER_X_FORWARDED_PORT | \Symfony\Component\HttpFoundation\Request::HEADER_X_FORWARDED_PROTO + * @endcode + * This would trust the following headers: + * - X_FORWARDED_FOR + * - X_FORWARDED_HOST + * - X_FORWARDED_PROTO + * - X_FORWARDED_PORT + * + * @see \Symfony\Component\HttpFoundation\Request::HEADER_X_FORWARDED_FOR + * @see \Symfony\Component\HttpFoundation\Request::HEADER_X_FORWARDED_HOST + * @see \Symfony\Component\HttpFoundation\Request::HEADER_X_FORWARDED_PORT + * @see \Symfony\Component\HttpFoundation\Request::HEADER_X_FORWARDED_PROTO + * @see \Symfony\Component\HttpFoundation\Request::HEADER_FORWARDED + * @see \Symfony\Component\HttpFoundation\Request::setTrustedProxies + */ +# $settings['reverse_proxy_trusted_headers'] = \Symfony\Component\HttpFoundation\Request::HEADER_X_FORWARDED_FOR | \Symfony\Component\HttpFoundation\Request::HEADER_X_FORWARDED_HOST | \Symfony\Component\HttpFoundation\Request::HEADER_X_FORWARDED_PORT | \Symfony\Component\HttpFoundation\Request::HEADER_X_FORWARDED_PROTO | \Symfony\Component\HttpFoundation\Request::HEADER_FORWARDED; + + +/** + * Page caching: + * + * By default, Drupal sends a "Vary: Cookie" HTTP header for anonymous page + * views. This tells a HTTP proxy that it may return a page from its local + * cache without contacting the web server, if the user sends the same Cookie + * header as the user who originally requested the cached page. Without "Vary: + * Cookie", authenticated users would also be served the anonymous page from + * the cache. If the site has mostly anonymous users except a few known + * editors/administrators, the Vary header can be omitted. This allows for + * better caching in HTTP proxies (including reverse proxies), i.e. even if + * clients send different cookies, they still get content served from the cache. + * However, authenticated users should access the site directly (i.e. not use an + * HTTP proxy, and bypass the reverse proxy if one is used) in order to avoid + * getting cached pages from the proxy. + */ +# $settings['omit_vary_cookie'] = TRUE; + + +/** + * Cache TTL for client error (4xx) responses. + * + * Items cached per-URL tend to result in a large number of cache items, and + * this can be problematic on 404 pages which by their nature are unbounded. A + * fixed TTL can be set for these items, defaulting to one hour, so that cache + * backends which do not support LRU can purge older entries. To disable caching + * of client error responses set the value to 0. Currently applies only to + * page_cache module. + */ +# $settings['cache_ttl_4xx'] = 3600; + +/** + * Expiration of cached forms. + * + * Drupal's Form API stores details of forms in a cache and these entries are + * kept for at least 6 hours by default. Expired entries are cleared by cron. + * + * @see \Drupal\Core\Form\FormCache::setCache() + */ +# $settings['form_cache_expiration'] = 21600; + +/** + * Class Loader. + * + * If the APCu extension is detected, the classloader will be optimized to use + * it. Set to FALSE to disable this. + * + * @see https://getcomposer.org/doc/articles/autoloader-optimization.md + */ +# $settings['class_loader_auto_detect'] = FALSE; + +/** + * Authorized file system operations: + * + * The Update Manager module included with Drupal provides a mechanism for + * site administrators to securely install missing updates for the site + * directly through the web user interface. On securely-configured servers, + * the Update manager will require the administrator to provide SSH or FTP + * credentials before allowing the installation to proceed; this allows the + * site to update the new files as the user who owns all the Drupal files, + * instead of as the user the webserver is running as. On servers where the + * webserver user is itself the owner of the Drupal files, the administrator + * will not be prompted for SSH or FTP credentials (note that these server + * setups are common on shared hosting, but are inherently insecure). + * + * Some sites might wish to disable the above functionality, and only update + * the code directly via SSH or FTP themselves. This setting completely + * disables all functionality related to these authorized file operations. + * + * @see https://www.drupal.org/node/244924 + * + * Remove the leading hash signs to disable. + */ +# $settings['allow_authorize_operations'] = FALSE; + +/** + * Default mode for directories and files written by Drupal. + * + * Value should be in PHP Octal Notation, with leading zero. + */ +# $settings['file_chmod_directory'] = 0775; +# $settings['file_chmod_file'] = 0664; + +/** + * Public file base URL: + * + * An alternative base URL to be used for serving public files. This must + * include any leading directory path. + * + * A different value from the domain used by Drupal to be used for accessing + * public files. This can be used for a simple CDN integration, or to improve + * security by serving user-uploaded files from a different domain or subdomain + * pointing to the same server. Do not include a trailing slash. + */ +# $settings['file_public_base_url'] = 'http://downloads.example.com/files'; + +/** + * Public file path: + * + * A local file system path where public files will be stored. This directory + * must exist and be writable by Drupal. This directory must be relative to + * the Drupal installation directory and be accessible over the web. + */ +# $settings['file_public_path'] = 'sites/default/files'; + +/** + * Private file path: + * + * A local file system path where private files will be stored. This directory + * must be absolute, outside of the Drupal installation directory and not + * accessible over the web. + * + * Note: Caches need to be cleared when this value is changed to make the + * private:// stream wrapper available to the system. + * + * See https://www.drupal.org/documentation/modules/file for more information + * about securing private files. + */ +# $settings['file_private_path'] = ''; + +/** + * Temporary file path: + * + * A local file system path where temporary files will be stored. This directory + * must be absolute, outside of the Drupal installation directory and not + * accessible over the web. + * + * If this is not set, the default for the operating system will be used. + * + * @see \Drupal\Component\FileSystem\FileSystem::getOsTemporaryDirectory() + */ +# $settings['file_temp_path'] = '/tmp'; + +/** + * Session write interval: + * + * Set the minimum interval between each session write to database. + * For performance reasons it defaults to 180. + */ +# $settings['session_write_interval'] = 180; + +/** + * String overrides: + * + * To override specific strings on your site with or without enabling the Locale + * module, add an entry to this list. This functionality allows you to change + * a small number of your site's default English language interface strings. + * + * Remove the leading hash signs to enable. + * + * The "en" part of the variable name, is dynamic and can be any langcode of + * any added language. (eg locale_custom_strings_de for german). + */ +# $settings['locale_custom_strings_en'][''] = [ +# 'forum' => 'Discussion board', +# '@count min' => '@count minutes', +# ]; + +/** + * A custom theme for the offline page: + * + * This applies when the site is explicitly set to maintenance mode through the + * administration page or when the database is inactive due to an error. + * The template file should also be copied into the theme. It is located inside + * 'core/modules/system/templates/maintenance-page.html.twig'. + * + * Note: This setting does not apply to installation and update pages. + */ +# $settings['maintenance_theme'] = 'bartik'; + +/** + * PHP settings: + * + * To see what PHP settings are possible, including whether they can be set at + * runtime (by using ini_set()), read the PHP documentation: + * http://php.net/manual/ini.list.php + * See \Drupal\Core\DrupalKernel::bootEnvironment() for required runtime + * settings and the .htaccess file for non-runtime settings. + * Settings defined there should not be duplicated here so as to avoid conflict + * issues. + */ + +/** + * If you encounter a situation where users post a large amount of text, and + * the result is stripped out upon viewing but can still be edited, Drupal's + * output filter may not have sufficient memory to process it. If you + * experience this issue, you may wish to uncomment the following two lines + * and increase the limits of these variables. For more information, see + * http://php.net/manual/pcre.configuration.php. + */ +# ini_set('pcre.backtrack_limit', 200000); +# ini_set('pcre.recursion_limit', 200000); + +/** + * Add Permissions-Policy header to disable Google FLoC. + * + * By default, Drupal sends the 'Permissions-Policy: interest-cohort=()' header + * to disable Google's Federated Learning of Cohorts feature, introduced in + * Chrome 89. + * + * See https://en.wikipedia.org/wiki/Federated_Learning_of_Cohorts for more + * information about FLoC. + * + * If you don't wish to disable FLoC in Chrome, you can set this value + * to FALSE. + */ +# $settings['block_interest_cohort'] = TRUE; + +/** + * Configuration overrides. + * + * To globally override specific configuration values for this site, + * set them here. You usually don't need to use this feature. This is + * useful in a configuration file for a vhost or directory, rather than + * the default settings.php. + * + * Note that any values you provide in these variable overrides will not be + * viewable from the Drupal administration interface. The administration + * interface displays the values stored in configuration so that you can stage + * changes to other environments that don't have the overrides. + * + * There are particular configuration values that are risky to override. For + * example, overriding the list of installed modules in 'core.extension' is not + * supported as module install or uninstall has not occurred. Other examples + * include field storage configuration, because it has effects on database + * structure, and 'core.menu.static_menu_link_overrides' since this is cached in + * a way that is not config override aware. Also, note that changing + * configuration values in settings.php will not fire any of the configuration + * change events. + */ +# $config['system.site']['name'] = 'My Drupal site'; +# $config['user.settings']['anonymous'] = 'Visitor'; + +/** + * Fast 404 pages: + * + * Drupal can generate fully themed 404 pages. However, some of these responses + * are for images or other resource files that are not displayed to the user. + * This can waste bandwidth, and also generate server load. + * + * The options below return a simple, fast 404 page for URLs matching a + * specific pattern: + * - $config['system.performance']['fast_404']['exclude_paths']: A regular + * expression to match paths to exclude, such as images generated by image + * styles, or dynamically-resized images. The default pattern provided below + * also excludes the private file system. If you need to add more paths, you + * can add '|path' to the expression. + * - $config['system.performance']['fast_404']['paths']: A regular expression to + * match paths that should return a simple 404 page, rather than the fully + * themed 404 page. If you don't have any aliases ending in htm or html you + * can add '|s?html?' to the expression. + * - $config['system.performance']['fast_404']['html']: The html to return for + * simple 404 pages. + * + * Remove the leading hash signs if you would like to alter this functionality. + */ +# $config['system.performance']['fast_404']['exclude_paths'] = '/\/(?:styles)|(?:system\/files)\//'; +# $config['system.performance']['fast_404']['paths'] = '/\.(?:txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; +# $config['system.performance']['fast_404']['html'] = '404 Not Found

    Not Found

    The requested URL "@path" was not found on this server.

    '; + +/** + * Load services definition file. + */ +$settings['container_yamls'][] = $app_root . '/' . $site_path . '/services.yml'; + +/** + * Override the default service container class. + * + * This is useful for example to trace the service container for performance + * tracking purposes, for testing a service container with an error condition or + * to test a service container that throws an exception. + */ +# $settings['container_base_class'] = '\Drupal\Core\DependencyInjection\Container'; + +/** + * Override the default yaml parser class. + * + * Provide a fully qualified class name here if you would like to provide an + * alternate implementation YAML parser. The class must implement the + * \Drupal\Component\Serialization\SerializationInterface interface. + */ +# $settings['yaml_parser_class'] = NULL; + +/** + * Trusted host configuration. + * + * Drupal core can use the Symfony trusted host mechanism to prevent HTTP Host + * header spoofing. + * + * To enable the trusted host mechanism, you enable your allowable hosts + * in $settings['trusted_host_patterns']. This should be an array of regular + * expression patterns, without delimiters, representing the hosts you would + * like to allow. + * + * For example: + * @code + * $settings['trusted_host_patterns'] = [ + * '^www\.example\.com$', + * ]; + * @endcode + * will allow the site to only run from www.example.com. + * + * If you are running multisite, or if you are running your site from + * different domain names (eg, you don't redirect http://www.example.com to + * http://example.com), you should specify all of the host patterns that are + * allowed by your site. + * + * For example: + * @code + * $settings['trusted_host_patterns'] = [ + * '^example\.com$', + * '^.+\.example\.com$', + * '^example\.org$', + * '^.+\.example\.org$', + * ]; + * @endcode + * will allow the site to run off of all variants of example.com and + * example.org, with all subdomains included. + */ + +/** + * The default list of directories that will be ignored by Drupal's file API. + * + * By default ignore node_modules and bower_components folders to avoid issues + * with common frontend tools and recursive scanning of directories looking for + * extensions. + * + * @see \Drupal\Core\File\FileSystemInterface::scanDirectory() + * @see \Drupal\Core\Extension\ExtensionDiscovery::scanDirectory() + */ +$settings['file_scan_ignore_directories'] = [ + 'node_modules', + 'bower_components', +]; + +/** + * The default number of entities to update in a batch process. + * + * This is used by update and post-update functions that need to go through and + * change all the entities on a site, so it is useful to increase this number + * if your hosting configuration (i.e. RAM allocation, CPU speed) allows for a + * larger number of entities to be processed in a single batch run. + */ +$settings['entity_update_batch_size'] = 50; + +/** + * Entity update backup. + * + * This is used to inform the entity storage handler that the backup tables as + * well as the original entity type and field storage definitions should be + * retained after a successful entity update process. + */ +$settings['entity_update_backup'] = TRUE; + +/** + * Node migration type. + * + * This is used to force the migration system to use the classic node migrations + * instead of the default complete node migrations. The migration system will + * use the classic node migration only if there are existing migrate_map tables + * for the classic node migrations and they contain data. These tables may not + * exist if you are developing custom migrations and do not want to use the + * complete node migrations. Set this to TRUE to force the use of the classic + * node migrations. + */ +$settings['migrate_node_migrate_type_classic'] = FALSE; + +/** + * Load local development override configuration, if available. + * + * Create a settings.local.php file to override variables on secondary (staging, + * development, etc.) installations of this site. + * + * Typical uses of settings.local.php include: + * - Disabling caching. + * - Disabling JavaScript/CSS compression. + * - Rerouting outgoing emails. + * + * Keep this code block at the end of this file to take full effect. + */ +# +# if (file_exists($app_root . '/' . $site_path . '/settings.local.php')) { +# include $app_root . '/' . $site_path . '/settings.local.php'; +# } diff --git a/web/sites/default/services.yml b/web/sites/default/services.yml new file mode 100755 index 0000000..e2621d3 --- /dev/null +++ b/web/sites/default/services.yml @@ -0,0 +1,7 @@ +parameters: + renderer.config: + required_cache_contexts: ['languages:language_interface', 'theme', 'user.permissions'] + auto_placeholder_conditions: + max-age: 0 + contexts: ['session'] + tags: [] diff --git a/web/sites/default/settings.local.dev.php b/web/sites/default/settings.local.dev.php new file mode 100644 index 0000000..d26129e --- /dev/null +++ b/web/sites/default/settings.local.dev.php @@ -0,0 +1,161 @@ + 'databasename', + * 'username' => 'sqlusername', + * 'password' => 'sqlpassword', + * 'host' => 'localhost', + * 'port' => '3306', + * 'driver' => 'mysql', + * 'prefix' => '', + * 'collation' => 'utf8mb4_general_ci', + * ]; + * @endcode + */ +$databases = []; + +/** + * Customizing database settings. + * + * Many of the values of the $databases array can be customized for your + * particular database system. Refer to the sample in the section above as a + * starting point. + * + * The "driver" property indicates what Drupal database driver the + * connection should use. This is usually the same as the name of the + * database type, such as mysql or sqlite, but not always. The other + * properties will vary depending on the driver. For SQLite, you must + * specify a database file name in a directory that is writable by the + * webserver. For most other drivers, you must specify a + * username, password, host, and database name. + * + * Transaction support is enabled by default for all drivers that support it, + * including MySQL. To explicitly disable it, set the 'transactions' key to + * FALSE. + * Note that some configurations of MySQL, such as the MyISAM engine, don't + * support it and will proceed silently even if enabled. If you experience + * transaction related crashes with such configuration, set the 'transactions' + * key to FALSE. + * + * For each database, you may optionally specify multiple "target" databases. + * A target database allows Drupal to try to send certain queries to a + * different database if it can but fall back to the default connection if not. + * That is useful for primary/replica replication, as Drupal may try to connect + * to a replica server when appropriate and if one is not available will simply + * fall back to the single primary server (The terms primary/replica are + * traditionally referred to as master/slave in database server documentation). + * + * The general format for the $databases array is as follows: + * @code + * $databases['default']['default'] = $info_array; + * $databases['default']['replica'][] = $info_array; + * $databases['default']['replica'][] = $info_array; + * $databases['extra']['default'] = $info_array; + * @endcode + * + * In the above example, $info_array is an array of settings described above. + * The first line sets a "default" database that has one primary database + * (the second level default). The second and third lines create an array + * of potential replica databases. Drupal will select one at random for a given + * request as needed. The fourth line creates a new database with a name of + * "extra". + * + * You can optionally set prefixes for some or all database table names + * by using the 'prefix' setting. If a prefix is specified, the table + * name will be prepended with its value. Be sure to use valid database + * characters only, usually alphanumeric and underscore. If no prefixes + * are desired, leave it as an empty string ''. + * + * To have all database names prefixed, set 'prefix' as a string: + * @code + * 'prefix' => 'main_', + * @endcode + * + * Per-table prefixes are deprecated as of Drupal 8.2, and will be removed in + * Drupal 9.0. After that, only a single prefix for all tables will be + * supported. + * + * To provide prefixes for specific tables, set 'prefix' as an array. + * The array's keys are the table names and the values are the prefixes. + * The 'default' element is mandatory and holds the prefix for any tables + * not specified elsewhere in the array. Example: + * @code + * 'prefix' => [ + * 'default' => 'main_', + * 'users' => 'shared_', + * 'sessions' => 'shared_', + * 'role' => 'shared_', + * 'authmap' => 'shared_', + * ], + * @endcode + * You can also use a reference to a schema/database as a prefix. This may be + * useful if your Drupal installation exists in a schema that is not the default + * or you want to access several databases from the same code base at the same + * time. + * Example: + * @code + * 'prefix' => [ + * 'default' => 'main.', + * 'users' => 'shared.', + * 'sessions' => 'shared.', + * 'role' => 'shared.', + * 'authmap' => 'shared.', + * ]; + * @endcode + * NOTE: MySQL and SQLite's definition of a schema is a database. + * + * Advanced users can add or override initial commands to execute when + * connecting to the database server, as well as PDO connection settings. For + * example, to enable MySQL SELECT queries to exceed the max_join_size system + * variable, and to reduce the database connection timeout to 5 seconds: + * @code + * $databases['default']['default'] = [ + * 'init_commands' => [ + * 'big_selects' => 'SET SQL_BIG_SELECTS=1', + * ], + * 'pdo' => [ + * PDO::ATTR_TIMEOUT => 5, + * ], + * ]; + * @endcode + * + * WARNING: The above defaults are designed for database portability. Changing + * them may cause unexpected behavior, including potential data loss. See + * https://www.drupal.org/developing/api/database/configuration for more + * information on these defaults and the potential issues. + * + * More details can be found in the constructor methods for each driver: + * - \Drupal\Core\Database\Driver\mysql\Connection::__construct() + * - \Drupal\Core\Database\Driver\pgsql\Connection::__construct() + * - \Drupal\Core\Database\Driver\sqlite\Connection::__construct() + * + * Sample Database configuration format for PostgreSQL (pgsql): + * @code + * $databases['default']['default'] = [ + * 'driver' => 'pgsql', + * 'database' => 'databasename', + * 'username' => 'sqlusername', + * 'password' => 'sqlpassword', + * 'host' => 'localhost', + * 'prefix' => '', + * ]; + * @endcode + * + * Sample Database configuration format for SQLite (sqlite): + * @code + * $databases['default']['default'] = [ + * 'driver' => 'sqlite', + * 'database' => '/path/to/databasefilename', + * ]; + * @endcode + */ + +/** + * Location of the site configuration files. + * + * The $config_directories array specifies the location of file system + * directories used for configuration data. On install, the "sync" directory is + * created. This is used for configuration imports. The "active" directory is + * not created by default since the default storage for active configuration is + * the database rather than the file system. (This can be changed. See "Active + * configuration settings" below). + * + * The default location for the "sync" directory is inside a randomly-named + * directory in the public files path. The setting below allows you to override + * the "sync" location. + * + * If you use files for the "active" configuration, you can tell the + * Configuration system where this directory is located by adding an entry with + * array key CONFIG_ACTIVE_DIRECTORY. + * + * Example: + * @code + * $config_directories = [ + * CONFIG_SYNC_DIRECTORY => '/directory/outside/webroot', + * ]; + * @endcode + */ +$config_directories = []; + +/** + * Settings: + * + * $settings contains environment-specific configuration, such as the files + * directory and reverse proxy address, and temporary configuration, such as + * security overrides. + * + * @see \Drupal\Core\Site\Settings::get() + */ + +/** + * Salt for one-time login links, cancel links, form tokens, etc. + * + * This variable will be set to a random value by the installer. All one-time + * login links will be invalidated if the value is changed. Note that if your + * site is deployed on a cluster of web servers, you must ensure that this + * variable has the same value on each server. + * + * For enhanced security, you may set this variable to the contents of a file + * outside your document root; you should also ensure that this file is not + * stored with backups of your database. + * + * Example: + * @code + * $settings['hash_salt'] = file_get_contents('/home/example/salt.txt'); + * @endcode + */ +$settings['hash_salt'] = '#*SxcypMKTM5@J99R!m)-YOU SHOULD CHANGE THIS-h4Iz5u0P(+79fhX58i@U'; + +/** + * Deployment identifier. + * + * Drupal's dependency injection container will be automatically invalidated and + * rebuilt when the Drupal core version changes. When updating contributed or + * custom code that changes the container, changing this identifier will also + * allow the container to be invalidated as soon as code is deployed. + */ +$settings['deployment_identifier'] = getenv('VERSION') ?? \Drupal::VERSION; + +/** + * Access control for update.php script. + * + * If you are updating your Drupal installation using the update.php script but + * are not logged in using either an account with the "Administer software + * updates" permission or the site maintenance account (the account that was + * created during installation), you will need to modify the access check + * statement below. Change the FALSE to a TRUE to disable the access check. + * After finishing the upgrade, be sure to open this file again and change the + * TRUE back to a FALSE! + */ +$settings['update_free_access'] = FALSE; + +/** + * External access proxy settings: + * + * If your site must access the Internet via a web proxy then you can enter the + * proxy settings here. Set the full URL of the proxy, including the port, in + * variables: + * - $settings['http_client_config']['proxy']['http']: The proxy URL for HTTP + * requests. + * - $settings['http_client_config']['proxy']['https']: The proxy URL for HTTPS + * requests. + * You can pass in the user name and password for basic authentication in the + * URLs in these settings. + * + * You can also define an array of host names that can be accessed directly, + * bypassing the proxy, in $settings['http_client_config']['proxy']['no']. + */ +# $settings['http_client_config']['proxy']['http'] = 'http://proxy_user:proxy_pass@example.com:8080'; +# $settings['http_client_config']['proxy']['https'] = 'http://proxy_user:proxy_pass@example.com:8080'; +# $settings['http_client_config']['proxy']['no'] = ['127.0.0.1', 'localhost']; + +/** + * Reverse Proxy Configuration: + * + * Reverse proxy servers are often used to enhance the performance + * of heavily visited sites and may also provide other site caching, + * security, or encryption benefits. In an environment where Drupal + * is behind a reverse proxy, the real IP address of the client should + * be determined such that the correct client IP address is available + * to Drupal's logging, statistics, and access management systems. In + * the most simple scenario, the proxy server will add an + * X-Forwarded-For header to the request that contains the client IP + * address. However, HTTP headers are vulnerable to spoofing, where a + * malicious client could bypass restrictions by setting the + * X-Forwarded-For header directly. Therefore, Drupal's proxy + * configuration requires the IP addresses of all remote proxies to be + * specified in $settings['reverse_proxy_addresses'] to work correctly. + * + * Enable this setting to get Drupal to determine the client IP from the + * X-Forwarded-For header. If you are unsure about this setting, do not have a + * reverse proxy, or Drupal operates in a shared hosting environment, this + * setting should remain commented out. + * + * In order for this setting to be used you must specify every possible + * reverse proxy IP address in $settings['reverse_proxy_addresses']. + * If a complete list of reverse proxies is not available in your + * environment (for example, if you use a CDN) you may set the + * $_SERVER['REMOTE_ADDR'] variable directly in settings.php. + * Be aware, however, that it is likely that this would allow IP + * address spoofing unless more advanced precautions are taken. + */ +# $settings['reverse_proxy'] = TRUE; + +/** + * Specify every reverse proxy IP address in your environment. + * This setting is required if $settings['reverse_proxy'] is TRUE. + */ +# $settings['reverse_proxy_addresses'] = ['a.b.c.d', ...]; + +/** + * Reverse proxy trusted headers. + * + * Sets which headers to trust from your reverse proxy. + * + * Common values are: + * - \Symfony\Component\HttpFoundation\Request::HEADER_X_FORWARDED_ALL + * - \Symfony\Component\HttpFoundation\Request::HEADER_FORWARDED + * + * Note the default value of + * @code + * \Symfony\Component\HttpFoundation\Request::HEADER_X_FORWARDED_ALL | \Symfony\Component\HttpFoundation\Request::HEADER_FORWARDED + * @endcode + * is not secure by default. The value should be set to only the specific + * headers the reverse proxy uses. For example: + * @code + * \Symfony\Component\HttpFoundation\Request::HEADER_X_FORWARDED_ALL + * @endcode + * This would trust the following headers: + * - X_FORWARDED_FOR + * - X_FORWARDED_HOST + * - X_FORWARDED_PROTO + * - X_FORWARDED_PORT + * + * @see \Symfony\Component\HttpFoundation\Request::HEADER_X_FORWARDED_ALL + * @see \Symfony\Component\HttpFoundation\Request::HEADER_FORWARDED + * @see \Symfony\Component\HttpFoundation\Request::setTrustedProxies + */ +# $settings['reverse_proxy_trusted_headers'] = \Symfony\Component\HttpFoundation\Request::HEADER_X_FORWARDED_ALL | \Symfony\Component\HttpFoundation\Request::HEADER_FORWARDED; + + +/** + * Page caching: + * + * By default, Drupal sends a "Vary: Cookie" HTTP header for anonymous page + * views. This tells a HTTP proxy that it may return a page from its local + * cache without contacting the web server, if the user sends the same Cookie + * header as the user who originally requested the cached page. Without "Vary: + * Cookie", authenticated users would also be served the anonymous page from + * the cache. If the site has mostly anonymous users except a few known + * editors/administrators, the Vary header can be omitted. This allows for + * better caching in HTTP proxies (including reverse proxies), i.e. even if + * clients send different cookies, they still get content served from the cache. + * However, authenticated users should access the site directly (i.e. not use an + * HTTP proxy, and bypass the reverse proxy if one is used) in order to avoid + * getting cached pages from the proxy. + */ +# $settings['omit_vary_cookie'] = TRUE; + + +/** + * Cache TTL for client error (4xx) responses. + * + * Items cached per-URL tend to result in a large number of cache items, and + * this can be problematic on 404 pages which by their nature are unbounded. A + * fixed TTL can be set for these items, defaulting to one hour, so that cache + * backends which do not support LRU can purge older entries. To disable caching + * of client error responses set the value to 0. Currently applies only to + * page_cache module. + */ +# $settings['cache_ttl_4xx'] = 3600; + +/** + * Expiration of cached forms. + * + * Drupal's Form API stores details of forms in a cache and these entries are + * kept for at least 6 hours by default. Expired entries are cleared by cron. + * + * @see \Drupal\Core\Form\FormCache::setCache() + */ +# $settings['form_cache_expiration'] = 21600; + +/** + * Class Loader. + * + * If the APC extension is detected, the Symfony APC class loader is used for + * performance reasons. Detection can be prevented by setting + * class_loader_auto_detect to false, as in the example below. + */ +# $settings['class_loader_auto_detect'] = FALSE; + +/* + * If the APC extension is not detected, either because APC is missing or + * because auto-detection has been disabled, auto-loading falls back to + * Composer's ClassLoader, which is good for development as it does not break + * when code is moved in the file system. You can also decorate the base class + * loader with another cached solution than the Symfony APC class loader, as + * all production sites should have a cached class loader of some sort enabled. + * + * To do so, you may decorate and replace the local $class_loader variable. For + * example, to use Symfony's APC class loader without automatic detection, + * uncomment the code below. + */ +/* +if ($settings['hash_salt']) { + $prefix = 'drupal.' . hash('sha256', 'drupal.' . $settings['hash_salt']); + $apc_loader = new \Symfony\Component\ClassLoader\ApcClassLoader($prefix, $class_loader); + unset($prefix); + $class_loader->unregister(); + $apc_loader->register(); + $class_loader = $apc_loader; +} +*/ + +/** + * Authorized file system operations: + * + * The Update Manager module included with Drupal provides a mechanism for + * site administrators to securely install missing updates for the site + * directly through the web user interface. On securely-configured servers, + * the Update manager will require the administrator to provide SSH or FTP + * credentials before allowing the installation to proceed; this allows the + * site to update the new files as the user who owns all the Drupal files, + * instead of as the user the webserver is running as. On servers where the + * webserver user is itself the owner of the Drupal files, the administrator + * will not be prompted for SSH or FTP credentials (note that these server + * setups are common on shared hosting, but are inherently insecure). + * + * Some sites might wish to disable the above functionality, and only update + * the code directly via SSH or FTP themselves. This setting completely + * disables all functionality related to these authorized file operations. + * + * @see https://www.drupal.org/node/244924 + * + * Remove the leading hash signs to disable. + */ +# $settings['allow_authorize_operations'] = FALSE; + +/** + * Default mode for directories and files written by Drupal. + * + * Value should be in PHP Octal Notation, with leading zero. + */ +# $settings['file_chmod_directory'] = 0775; +# $settings['file_chmod_file'] = 0664; + +/** + * Public file base URL: + * + * An alternative base URL to be used for serving public files. This must + * include any leading directory path. + * + * A different value from the domain used by Drupal to be used for accessing + * public files. This can be used for a simple CDN integration, or to improve + * security by serving user-uploaded files from a different domain or subdomain + * pointing to the same server. Do not include a trailing slash. + */ +# $settings['file_public_base_url'] = 'http://downloads.example.com/files'; + +/** + * Public file path: + * + * A local file system path where public files will be stored. This directory + * must exist and be writable by Drupal. This directory must be relative to + * the Drupal installation directory and be accessible over the web. + */ + $settings['file_public_path'] = 'sites/default/files'; + +/** + * Private file path: + * + * A local file system path where private files will be stored. This directory + * must be absolute, outside of the Drupal installation directory and not + * accessible over the web. + * + * Note: Caches need to be cleared when this value is changed to make the + * private:// stream wrapper available to the system. + * + * See https://www.drupal.org/documentation/modules/file for more information + * about securing private files. + */ +# $settings['file_private_path'] = ''; + +/** + * Session write interval: + * + * Set the minimum interval between each session write to database. + * For performance reasons it defaults to 180. + */ +# $settings['session_write_interval'] = 180; + +/** + * String overrides: + * + * To override specific strings on your site with or without enabling the Locale + * module, add an entry to this list. This functionality allows you to change + * a small number of your site's default English language interface strings. + * + * Remove the leading hash signs to enable. + * + * The "en" part of the variable name, is dynamic and can be any langcode of + * any added language. (eg locale_custom_strings_de for german). + */ +# $settings['locale_custom_strings_en'][''] = [ +# 'forum' => 'Discussion board', +# '@count min' => '@count minutes', +# ]; + +/** + * A custom theme for the offline page: + * + * This applies when the site is explicitly set to maintenance mode through the + * administration page or when the database is inactive due to an error. + * The template file should also be copied into the theme. It is located inside + * 'core/modules/system/templates/maintenance-page.html.twig'. + * + * Note: This setting does not apply to installation and update pages. + */ +# $settings['maintenance_theme'] = 'bartik'; + +/** + * PHP settings: + * + * To see what PHP settings are possible, including whether they can be set at + * runtime (by using ini_set()), read the PHP documentation: + * http://php.net/manual/ini.list.php + * See \Drupal\Core\DrupalKernel::bootEnvironment() for required runtime + * settings and the .htaccess file for non-runtime settings. + * Settings defined there should not be duplicated here so as to avoid conflict + * issues. + */ + +/** + * If you encounter a situation where users post a large amount of text, and + * the result is stripped out upon viewing but can still be edited, Drupal's + * output filter may not have sufficient memory to process it. If you + * experience this issue, you may wish to uncomment the following two lines + * and increase the limits of these variables. For more information, see + * http://php.net/manual/pcre.configuration.php. + */ +# ini_set('pcre.backtrack_limit', 200000); +# ini_set('pcre.recursion_limit', 200000); + +/** + * Active configuration settings. + * + * By default, the active configuration is stored in the database in the + * {config} table. To use a different storage mechanism for the active + * configuration, do the following prior to installing: + * - Create an "active" directory and declare its path in $config_directories + * as explained under the 'Location of the site configuration files' section + * above in this file. To enhance security, you can declare a path that is + * outside your document root. + * - Override the 'bootstrap_config_storage' setting here. It must be set to a + * callable that returns an object that implements + * \Drupal\Core\Config\StorageInterface. + * - Override the service definition 'config.storage.active'. Put this + * override in a services.yml file in the same directory as settings.php + * (definitions in this file will override service definition defaults). + */ +# $settings['bootstrap_config_storage'] = ['Drupal\Core\Config\BootstrapConfigStorageFactory', 'getFileStorage']; + +/** + * Configuration overrides. + * + * To globally override specific configuration values for this site, + * set them here. You usually don't need to use this feature. This is + * useful in a configuration file for a vhost or directory, rather than + * the default settings.php. + * + * Note that any values you provide in these variable overrides will not be + * viewable from the Drupal administration interface. The administration + * interface displays the values stored in configuration so that you can stage + * changes to other environments that don't have the overrides. + * + * There are particular configuration values that are risky to override. For + * example, overriding the list of installed modules in 'core.extension' is not + * supported as module install or uninstall has not occurred. Other examples + * include field storage configuration, because it has effects on database + * structure, and 'core.menu.static_menu_link_overrides' since this is cached in + * a way that is not config override aware. Also, note that changing + * configuration values in settings.php will not fire any of the configuration + * change events. + */ +# $config['system.file']['path']['temporary'] = '/tmp'; +# $config['system.site']['name'] = 'My Drupal site'; +# $config['system.theme']['default'] = 'stark'; +# $config['user.settings']['anonymous'] = 'Visitor'; + +/** + * Fast 404 pages: + * + * Drupal can generate fully themed 404 pages. However, some of these responses + * are for images or other resource files that are not displayed to the user. + * This can waste bandwidth, and also generate server load. + * + * The options below return a simple, fast 404 page for URLs matching a + * specific pattern: + * - $config['system.performance']['fast_404']['exclude_paths']: A regular + * expression to match paths to exclude, such as images generated by image + * styles, or dynamically-resized images. The default pattern provided below + * also excludes the private file system. If you need to add more paths, you + * can add '|path' to the expression. + * - $config['system.performance']['fast_404']['paths']: A regular expression to + * match paths that should return a simple 404 page, rather than the fully + * themed 404 page. If you don't have any aliases ending in htm or html you + * can add '|s?html?' to the expression. + * - $config['system.performance']['fast_404']['html']: The html to return for + * simple 404 pages. + * + * Remove the leading hash signs if you would like to alter this functionality. + */ +# $config['system.performance']['fast_404']['exclude_paths'] = '/\/(?:styles)|(?:system\/files)\//'; +# $config['system.performance']['fast_404']['paths'] = '/\.(?:txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'; +# $config['system.performance']['fast_404']['html'] = '404 Not Found

    Not Found

    The requested URL "@path" was not found on this server.

    '; + +/** + * Load services definition file. + */ +$settings['container_yamls'][] = $app_root . '/' . $site_path . '/services.yml'; + +/** + * Override the default service container class. + * + * This is useful for example to trace the service container for performance + * tracking purposes, for testing a service container with an error condition or + * to test a service container that throws an exception. + */ +# $settings['container_base_class'] = '\Drupal\Core\DependencyInjection\Container'; + +/** + * Override the default yaml parser class. + * + * Provide a fully qualified class name here if you would like to provide an + * alternate implementation YAML parser. The class must implement the + * \Drupal\Component\Serialization\SerializationInterface interface. + */ +# $settings['yaml_parser_class'] = NULL; + +/** + * Trusted host configuration. + * + * Drupal core can use the Symfony trusted host mechanism to prevent HTTP Host + * header spoofing. + * + * To enable the trusted host mechanism, you enable your allowable hosts + * in $settings['trusted_host_patterns']. This should be an array of regular + * expression patterns, without delimiters, representing the hosts you would + * like to allow. + * + * For example: + * @code + * $settings['trusted_host_patterns'] = [ + * '^www\.example\.com$', + * ]; + * @endcode + * will allow the site to only run from www.example.com. + * + * If you are running multisite, or if you are running your site from + * different domain names (eg, you don't redirect http://www.example.com to + * http://example.com), you should specify all of the host patterns that are + * allowed by your site. + * + * For example: + * @code + * $settings['trusted_host_patterns'] = [ + * '^example\.com$', + * '^.+\.example\.com$', + * '^example\.org$', + * '^.+\.example\.org$', + * ]; + * @endcode + * will allow the site to run off of all variants of example.com and + * example.org, with all subdomains included. + */ + +/** + * The default list of directories that will be ignored by Drupal's file API. + * + * By default ignore node_modules and bower_components folders to avoid issues + * with common frontend tools and recursive scanning of directories looking for + * extensions. + * + * @see file_scan_directory() + * @see \Drupal\Core\Extension\ExtensionDiscovery::scanDirectory() + */ +$settings['file_scan_ignore_directories'] = [ + 'node_modules', + 'bower_components', +]; + +/** + * The default number of entities to update in a batch process. + * + * This is used by update and post-update functions that need to go through and + * change all the entities on a site, so it is useful to increase this number + * if your hosting configuration (i.e. RAM allocation, CPU speed) allows for a + * larger number of entities to be processed in a single batch run. + */ +$settings['entity_update_batch_size'] = 50; + +/** + * Entity update backup. + * + * This is used to inform the entity storage handler that the backup tables as + * well as the original entity type and field storage definitions should be + * retained after a successful entity update process. + */ +$settings['entity_update_backup'] = TRUE; + +$config['system.performance']['css']['preprocess'] = TRUE; +$config['system.performance']['js']['preprocess'] = TRUE; + +/** + * Override LRS with .env. + */ +if(getenv("LRS_HOST") !== false) { + $config['xapi.settings']['lrs_url'] = getenv('LRS_HOST'); +} +if(getenv("LRS_USERNAME") !== false) { + $config['xapi.settings']['lrs_username'] = getenv('LRS_USERNAME'); +} +if(getenv("LRS_PASSWORD") !== false) { + $config['xapi.settings']['lrs_password'] = getenv('LRS_PASSWORD'); +} + +if (getenv('DRUPAL_SOLR_HOST') !== FALSE) { + $config['search_api.server.solr_search']['backend_config']['connector_config']['host']= getenv('DRUPAL_SOLR_HOST'); +} + +if (getenv('FIREBASE_SERVER_KEY') !== FALSE) { + $config['firebase.settings']['server_key'] = getenv('FIREBASE_SERVER_KEY'); +} +if (getenv('FIREBASE_SENDER_ID') !== FALSE) { + $config['firebase.settings']['sender_id'] = getenv('FIREBASE_SENDER_ID'); +} + +if (getenv('UNSPLASH_APP_NAME') !== FALSE) { + $config['media_unsplash.admin.config']['media_unsplash_app_name'] = getenv('UNSPLASH_APP_NAME'); +} +if (getenv('UNSPLASH_ACCESS_KEY') !== FALSE) { + $config['media_unsplash.admin.config']['media_unsplash_access_key'] = getenv('UNSPLASH_ACCESS_KEY'); +} +if (getenv('UNSPLASH_SECRET_KEY') !== FALSE) { + $config['media_unsplash.admin.config']['media_unsplash_secret_key'] = getenv('UNSPLASH_SECRET_KEY'); +} + +if (getenv('SIMPLESAML_AUTH_SOURCE') !== FALSE) { + $config['simplesamlphp_auth.settings']['auth_source'] = getenv('SIMPLESAML_AUTH_SOURCE'); +} + +$databases['default']['default'] = array ( + 'database' => getenv('DB_NAME'), + 'username' => getenv('DB_USER'), + 'password' => getenv('DB_PASSWORD'), + 'prefix' => '', + 'host' => getenv('DB_HOST'), + 'port' => '', + 'namespace' => 'Drupal\\Core\\Database\\Driver\\mysql', + 'driver' => getenv('DB_DRIVER'), +); + +$config['smtp.settings']['smtp_username'] = getenv('SMTP_USERNAME'); +$config['smtp.settings']['smtp_password'] = getenv('SMTP_PASSWORD'); +$config['smtp.settings']['smtp_from'] = getenv('SMTP_FROM'); +$config['smtp.settings']['smtp_host'] = getenv('SMTP_HOST'); +$config['smtp.settings']['smtp_port'] = getenv('SMTP_PORT'); +$config['smtp.settings']['smtp_protocol'] = getenv('SMTP_PROTOCOL'); + +// Check for perls environment +$config['config_split.config_split.perls']['status'] = TRUE; + +$settings['config_sync_directory'] = '../config/sync'; +$settings['trusted_host_patterns'] = [ + '^.*.usalearning.net$', + '^10\.0\.([1-9]?\d|10[0-5])\.([1-9]?\d|[12]\d\d)$', + '^127.0.0.1$', + '^localhost$' + ]; +if (getenv('ADDITIONAL_TRUSTED_HOST') !== FALSE) { + $settings['trusted_host_patterns'][] = '^'.getenv('ADDITIONAL_TRUSTED_HOST').'$'; +} + +/** + * Load local development override configuration, if available. + * + * Use settings.local.php to override variables on secondary (staging, + * development, etc) installations of this site. Typically used to disable + * caching, JavaScript/CSS compression, re-routing of outgoing emails, and + * other things that should not happen on development and testing sites. + * + * Keep this code block at the end of this file to take full effect. + */ +# +$settings['rebuild_access'] = FALSE; + +if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === '1') { + $_SERVER['SERVER_PORT'] = 443; +} + +if (file_exists($app_root . '/' . $site_path . '/settings.local.' . mb_strtolower(getenv('PROJECT_ENV')) . '.php')) { + include $app_root . '/' . $site_path . '/settings.local.' . mb_strtolower(getenv('PROJECT_ENV')) . '.php'; +} else { + // PROD may not have PROJECT_ENV set. + // So we default to prod settings. + include $app_root . '/' . $site_path . '/settings.local.prod.php'; +} + +if (file_exists($app_root . '/' . $site_path . '/settings.local.php')) { + include $app_root . '/' . $site_path . '/settings.local.php'; +} + +/** + * Sets the prefix to use for cache keys. + * + * This is purposefully at the end of the settings file so that + * environment-specific settings file can override the deployment_identifier. + */ +$settings['cache_prefix'] = 'drupal.' . \Drupal::VERSION . '.' . $settings['deployment_identifier'] ?? 'unknown'; diff --git a/web/sites/development.services.yml b/web/sites/development.services.yml new file mode 100644 index 0000000..bad24a9 --- /dev/null +++ b/web/sites/development.services.yml @@ -0,0 +1,12 @@ +# Local development services. +# +# To activate this feature, follow the instructions at the top of the +# 'example.settings.local.php' file, which sits next to this file. +parameters: + http.response.debug_cacheability_headers: true + twig.config: + debug: true + cache: false +services: + cache.backend.null: + class: Drupal\Core\Cache\NullBackendFactory diff --git a/web/sites/example.settings.local.php b/web/sites/example.settings.local.php new file mode 100644 index 0000000..73671ab --- /dev/null +++ b/web/sites/example.settings.local.php @@ -0,0 +1,155 @@ +..' => 'directory'. As an + * example, to map https://www.drupal.org:8080/mysite/test to the configuration + * directory sites/example.com, the array should be defined as: + * @code + * $sites = [ + * '8080.www.drupal.org.mysite.test' => 'example.com', + * ]; + * @endcode + * The URL, https://www.drupal.org:8080/mysite/test/, could be a symbolic link + * or an Apache Alias directive that points to the Drupal root containing + * index.php. An alias could also be created for a subdomain. See the + * @link https://www.drupal.org/documentation/install online Drupal installation guide @endlink + * for more information on setting up domains, subdomains, and subdirectories. + * + * The following examples look for a site configuration in sites/example.com: + * @code + * URL: http://dev.drupal.org + * $sites['dev.drupal.org'] = 'example.com'; + * + * URL: http://localhost/example + * $sites['localhost.example'] = 'example.com'; + * + * URL: http://localhost:8080/example + * $sites['8080.localhost.example'] = 'example.com'; + * + * URL: https://www.drupal.org:8080/mysite/test/ + * $sites['8080.www.drupal.org.mysite.test'] = 'example.com'; + * @endcode + * + * @see default.settings.php + * @see \Drupal\Core\DrupalKernel::getSitePath() + * @see https://www.drupal.org/documentation/install/multi-site + */ diff --git a/web/sites/monolog.services.yml b/web/sites/monolog.services.yml new file mode 100644 index 0000000..870aa46 --- /dev/null +++ b/web/sites/monolog.services.yml @@ -0,0 +1,30 @@ +parameters: + monolog.channel_handlers: + default: + handlers: ['drupal.dblog', 'stream'] + formatter: 'minimal_line' + monolog.processors: ['message_placeholder', 'current_user', 'request_uri', 'ip', 'referer'] + +services: + # Monolog handlers. + monolog.handler.stream: + class: Monolog\Handler\StreamHandler + arguments: ['php://stdout'] + + # Monolog processors + monolog.processor.current_user: + class: Drupal\monolog\Logger\Processor\CurrentUserProcessor + arguments: ['@current_user'] + monolog.processor.request_uri: + class: Drupal\monolog\Logger\Processor\RequestUriProcessor + arguments: ['@request_stack'] + monolog.processor.referer: + class: Drupal\monolog\Logger\Processor\RefererProcessor + arguments: ['@request_stack'] + monolog.processor.ip: + class: Drupal\monolog\Logger\Processor\IpProcessor + arguments: ['@request_stack'] + monolog.processor.message_placeholder: + class: Drupal\monolog\Logger\Processor\MessagePlaceholderProcessor + arguments: ['@logger.log_message_parser'] + diff --git a/web/sites/prod.services.yml b/web/sites/prod.services.yml new file mode 100644 index 0000000..7a574ee --- /dev/null +++ b/web/sites/prod.services.yml @@ -0,0 +1,8 @@ +services: + # Cache tag checksum backend. Used by redis and most other cache backend + # to deal with cache tag invalidations. + cache_tags.invalidator.checksum: + class: Drupal\redis\Cache\RedisCacheTagsChecksum + arguments: ['@redis.factory'] + tags: + - { name: cache_tags_invalidator } diff --git a/web/themes/.gitignore b/web/themes/.gitignore new file mode 100644 index 0000000..739a339 --- /dev/null +++ b/web/themes/.gitignore @@ -0,0 +1 @@ +/README.txt \ No newline at end of file diff --git a/web/themes/.gitkeep b/web/themes/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/web/themes/custom/perls/.stylelintrc b/web/themes/custom/perls/.stylelintrc new file mode 100644 index 0000000..daa90b9 --- /dev/null +++ b/web/themes/custom/perls/.stylelintrc @@ -0,0 +1,58 @@ +{ + "extends": "stylelint-config-standard", + "rules": { + "no-empty-source": null, + "max-empty-lines": 2, + "length-zero-no-unit": null, + "no-descending-specificity": null, + "comment-whitespace-inside": "always", + "at-rule-empty-line-before": [ + "never", + { + "ignoreAtRules": [ + "extend", + "at-root", + "debug", + "warn", + "error", + "if", + "else", + "for", + "each", + "while", + "mixin", + "include", + "content", + "return", + "function", + "import", + "mixin", + "media", + "font-face", + ] + } + ], + "at-rule-no-unknown": [ + true, + { + "ignoreAtRules": [ + "extend", + "at-root", + "debug", + "warn", + "error", + "if", + "else", + "for", + "each", + "while", + "mixin", + "include", + "content", + "return", + "function" + ] + } + ] + } +} diff --git a/web/themes/custom/perls/color/color.inc b/web/themes/custom/perls/color/color.inc new file mode 100644 index 0000000..276ce62 --- /dev/null +++ b/web/themes/custom/perls/color/color.inc @@ -0,0 +1,94 @@ + [ + 'primary' => t('Primary Color'), + 'secondary' => t('Secondary Color'), + 'tertiary' => t('Tertiary Color'), + 'quiz' => t('Quizzes/Tests'), + 'tip' => t('Tips'), + 'flash' => t('Flashcards'), + 'course' => t('Courses'), + 'podcast' => t('Podcasts'), + // https://www.drupal.org/project/drupal/issues/1236098#comment-13215759 + 'base' => t('Background Color'), + 'text' => t('Text Color'), + 'link' => t('Links'), + 'menu' => t('Menu background'), + ], + // Pre-defined color schemes. + 'schemes' => [ + 'default' => [ + 'title' => t('Blue Waves (default)'), + 'colors' => [ + 'primary' => '#006686', + 'secondary' => '#26a1c6', + 'secondary_lighter' => '#47b9db', + 'secondary_darker' => '#1e809e', + 'tertiary' => '#d6e8ee', + 'tip' => '#dd031d', + 'flash' => '#fc990b', + 'quiz' => '#63378f', + 'course' => '#2588d0', + 'course_darker' => '#1d6ca6', + 'podcast' => '#5d5d5d', + // https://www.drupal.org/project/drupal/issues/1236098#comment-13215759 + 'text' => '#232323', + 'base' => '#ffffff', + 'menu' => '#0084ae', + ], + ], + 'grape' => [ + 'title' => t('Grape'), + 'colors' => [ + 'primary' => '#4e314c', + 'secondary' => '#442941', + 'secondary_lighter' => '#51314d', + 'secondary_darker' => '#362033', + 'tertiary' => '#8b5788', + 'tip' => '#da635b', + 'flash' => '#55984c', + 'quiz' => '#fe9d0b', + 'course' => '#8b5788', + 'course_darker' => '#6f456c', + 'podcast' => '#2777ab', + // https://www.drupal.org/project/drupal/issues/1236098#comment-13215759 + 'text' => '#000000', + 'base' => '#ffffff', + 'menu' => '#9c6197', + ], + ], + 'dark' => [ + 'title' => t('Dark Mode'), + 'colors' => [ + 'primary' => '#1e1f31', + 'secondary' => '#03bf9c', + 'secondary_lighter' => '#03e5bb', + 'secondary_darker' => '#02987c', + 'tertiary' => '#70727c', + 'tip' => '#e63349', + 'flash' => '#541edb', + 'quiz' => '#0098ce', + 'course' => '#109980', + 'course_darker' => '#0c7a66', + 'podcast' => '#ffa632', + // https://www.drupal.org/project/drupal/issues/1236098#comment-13215759 + 'text' => '#ffffff', + 'base' => '#121325', + 'menu' => '#3c3d62', + ], + ], + ], + 'css' => [ + 'dist/css/color.css', + 'dist/css/am4chart-theme.js', + ], + 'preview_html' => 'color/preview.html', + 'preview_library' => 'perls/color.preview', +]; diff --git a/web/themes/custom/perls/color/preview.css b/web/themes/custom/perls/color/preview.css new file mode 100644 index 0000000..0c69e71 --- /dev/null +++ b/web/themes/custom/perls/color/preview.css @@ -0,0 +1,28 @@ +.colors-preview-items { + display: flex; + flex-wrap: nowrap; + overflow-x: auto; +} + +.colors-preview-items > * { + padding: 10px; + max-width: 320px; + width: 320px; + flex: 0 0 auto; +} + +.c-node--card--quiz .c-node__card { + min-height: 400px; +} + +.c-quiz__button.o-button--card { + color: #000 !important; +} + +.o-background-image--article { + background-image: url("https://picsum.photos/600?random=1"); +} + +.o-background-image--course { + background-image: linear-gradient(0deg, var(--course-color) 20%, rgba(0, 0, 0, 0.42) 100%), url("https://picsum.photos/600?random=1"); +} diff --git a/web/themes/custom/perls/color/preview.html b/web/themes/custom/perls/color/preview.html new file mode 100644 index 0000000..01eafe8 --- /dev/null +++ b/web/themes/custom/perls/color/preview.html @@ -0,0 +1,241 @@ +
    + +
    + +
    +
    +
    + +
    +
    + + +
    +
    +
    +
    +
    +
    +
    +

    A tip is a good way to reinforce key information or remind your learners about expectations or processes they should be following.

    +
    +
    +
    +
    +
    +
    +
    + +
    + + +
    +
    +
    +
    +
    +
    + +
    + +
    + +
    +
    + +
    +
    +
    +
    +
    +
    +
    +

    Flashcards

    +
    +
    +
    +
    +
    +
    +
    + + +
    + + +
    +
    + + +
    +
    +
    +
    +
    +
    +

    A flashcard helps your learner informally measure whether they remember key definitions or procedures.

    +
    +
    +
    +
    +
    +
    + +
    + +
    +
    +
    +
    +
    +
    + +
    + +
    +

    + Quizzes and Tests +

    +
    +
    +
    + +
    + + + Correct Answer + +
    +
    + + +

    CORRECT!

    +

    A quiz is a single question to more formally measure a learner's understanding.

    +
    +
    + +
    +
    + + + Incorrect Answer + +
    +
    + + +

    INCORRECT

    +

    When you create a course, you can combine multiple questions to create a test and track individual attempts from each learner.

    + Try Again + +
    +
    + +
    + +
    +
    + +
    + + +
    +
    +
    +
    +
    +
    + +
    + +
    +
    + +
    +

    + + Courses + +

    +
    +
    4 lessons
    +
    + Use a course to guide your learners through a sequential set of content (including articles, web links, tests, and more). Learners are encouraged to start with the first item in the course and work their way through to gain mastery of the information presented here. +
    + Start + +
    + +
    +
    +
    +
    +
    + +
    +
    + +
    + +
    + + +
    +
    +
    + +

    + Articles +

    +
    +
    + +
    +
    +
    +
    +
    +

    An article allows you to build and publish content directly to learners. Try focusing your articles to a single learning objective. You can create many articles under the same topic or course to provide your learners a comprehensive set of content.

    +
    +
    +
    +
    +
    +
    +
    + +
    + +
    +
    + +
    +
    diff --git a/web/themes/custom/perls/color/preview.js b/web/themes/custom/perls/color/preview.js new file mode 100644 index 0000000..ce1d4af --- /dev/null +++ b/web/themes/custom/perls/color/preview.js @@ -0,0 +1,85 @@ +/** + * Implements preview feature for color module. + **/ + +(function ($, Drupal, drupalSettings) { + Drupal.color = { + logoChanged: false, + bgChanged: false, + callback: function callback(context, settings, $form) { + var $colorPalette = $form.find('.js-color-palette'); + var offsetLighter = 20; + var offsetDarker = -20; + + /** + * @variables { + * cssVariable: The css variable to update with the picked . + * name: The input field to get the from. + * offset: Amount for darken and lighten on the . Positive value lightens, negative value darkens, the metric is percentage. + * } + */ + var selectors = [ + { cssVariable: '--primary-color', name: 'primary'}, + { cssVariable: '--secondary-color', name: 'secondary' }, + { cssVariable: '--secondary-lighter', name: 'secondary', offset: offsetLighter }, + { cssVariable: '--secondary-darker', name: 'secondary', offset: offsetDarker }, + { cssVariable: '--tertiary-color', name: 'tertiary'}, + { cssVariable: '--tip-color', name: 'tip'}, + { cssVariable: '--flashcard-color', name: 'flash'}, + { cssVariable: '--test-color', name: 'quiz'}, + { cssVariable: '--quiz-color', name: 'quiz'}, + { cssVariable: '--course-color', name: 'course'}, + { cssVariable: '--course-color-darker', name: 'course', offset: offsetDarker}, + { cssVariable: '--podcast-color', name: 'podcast'}, + { cssVariable: '--menu-background-color', name: 'menu'}, + { cssVariable: '--background-color', name: 'base'}, + { cssVariable: '--foreground-color', name: 'text'}, + ]; + + /** + * Credits to Crish Coyier at css-tricks. + * @function: LightenDarkenColor(col, amt) + */ + function shiftColor(col, amt) { + + var usePound = false; + + if (col[0] === "#") { + col = col.slice(1); + usePound = true; + } + + var num = parseInt(col,16); + + var r = (num >> 16) + amt; + + if (r > 255) r = 255; + else if (r < 0) r = 0; + + var b = ((num >> 8) & 0x00FF) + amt; + + if (b > 255) b = 255; + else if (b < 0) b = 0; + + var g = (num & 0x0000FF) + amt; + + if (g > 255) g = 255; + else if (g < 0) g = 0; + + [r, g, b] = [r,g,b].map(color => color <= 15 ? `0${color.toString(16)}` : color.toString(16)); + + return (usePound?"#":"") + r + b + g; + } + + for (var i = 0; i < selectors.length; i++){ + document.documentElement.style.setProperty( + selectors[i].cssVariable, + shiftColor( + `${$colorPalette.find(`input[name="palette[${selectors[i].name}]"]`).val()}`, + selectors[i].hasOwnProperty('offset') ? selectors[i].offset : 0, + ), + ); + } + } + }; +})(jQuery, Drupal, drupalSettings); diff --git a/web/themes/custom/perls/dist/css/am4chart-theme.js b/web/themes/custom/perls/dist/css/am4chart-theme.js new file mode 100644 index 0000000..e10a097 --- /dev/null +++ b/web/themes/custom/perls/dist/css/am4chart-theme.js @@ -0,0 +1,71 @@ +/** + * @file + * Provides a custom theme for amCharts. + * + * Used by the Veracity VQL renderer. + * + * I know this isn't a CSS file. But, by pretending like it is one, + * it makes it much easier for the Color module to replace the color + * values below with the custom theme colors. + */ + +let colors = { + primary: '#006686', + secondary: '#26a1c6', + tertiary: '#d6e8ee', + tip: '#dd031d', + quiz: '#63378f', + flash: '#fc990b', + course: '#2588d0', + text: '#232323', + base: '#ffffff' +}; + +function am4themes_perls(target) { + // It's feasible that the tertiary color could be white (or some very light color) + // which would be unreadable in the chart. We do a rudimentary check for that + // here and change it to light gray if it appears it may be too light. + if (am4core.colors.rgbToHsl(am4core.color(colors.tertiary).rgb).l >= 0.9) { + colors.tertiary = '#dddddd'; + } + + if (target instanceof am4core.InterfaceColorSet) { + target.setFor("text", am4core.color("#000000")); + } + + if (target instanceof am4charts.ColumnSeries) { + target.events.on('datavalidated', function(e) { + if (e.target.heatRules.length) { + return; + } + + e.target.heatRules.push({ + max: am4core.color(colors.secondary), + min: am4core.color("white"), + property: 'fill', + target: e.target.columns.template, + }); + }); + } + + if (target instanceof am4core.ColorSet) { + target.list = [ + am4core.color(colors.secondary), + am4core.color(colors.secondary).lighten(0.35), + am4core.color(colors.tip), + am4core.color(colors.quiz), + am4core.color(colors.flash), + am4core.color(colors.course), + am4core.color(colors.primary), + am4core.color(colors.tertiary), + am4core.color(colors.secondary).lighten(-0.2), + ]; + } +} + +let customStyling = document.createElement('style'); +document.head.appendChild(customStyling); +customStyling.sheet.insertRule(`.itemicon, .progressChange .iconarea .fa, .textarea { color: ${colors.secondary} !important; }`); +customStyling.sheet.insertRule(`.itemmain { color: ${colors.primary}; }`); +customStyling.sheet.insertRule(`.progressChange .mainarea { color: #000; }`); +customStyling.sheet.insertRule(`.progressChange .flexroot { height: 100%; }`); \ No newline at end of file diff --git a/web/themes/custom/perls/dist/css/color.css b/web/themes/custom/perls/dist/css/color.css new file mode 100644 index 0000000..9aa3822 --- /dev/null +++ b/web/themes/custom/perls/dist/css/color.css @@ -0,0 +1,19 @@ +:root, +::before, +::after { + --primary-color: #006686; + --secondary-color: #26a1c6; + --secondary-lighter: #47b9db; + --secondary-darker: #1e809e; + --tertiary-color: #d6e8ee; + --tip-color: #dd031d; + --flashcard-color: #fc990b; + --test-color: #63378f; + --quiz-color: #63378f; + --course-color: #2588d0; + --course-color-darker: #1d6ca6; + --podcast-color: #5d5d5d; + --foreground-color: #232323; + --background-color: #ffffff; + --menu-background-color: #0084ae; +} diff --git a/web/themes/custom/perls/favicon.ico b/web/themes/custom/perls/favicon.ico new file mode 100644 index 0000000..7cb4a42 Binary files /dev/null and b/web/themes/custom/perls/favicon.ico differ diff --git a/web/themes/custom/perls/fonts/CircularStd-Black.woff b/web/themes/custom/perls/fonts/CircularStd-Black.woff new file mode 100644 index 0000000..3c1aefe Binary files /dev/null and b/web/themes/custom/perls/fonts/CircularStd-Black.woff differ diff --git a/web/themes/custom/perls/fonts/CircularStd-Black.woff2 b/web/themes/custom/perls/fonts/CircularStd-Black.woff2 new file mode 100644 index 0000000..d8d8e64 Binary files /dev/null and b/web/themes/custom/perls/fonts/CircularStd-Black.woff2 differ diff --git a/web/themes/custom/perls/fonts/CircularStd-BlackItalic.woff b/web/themes/custom/perls/fonts/CircularStd-BlackItalic.woff new file mode 100644 index 0000000..90ea21d Binary files /dev/null and b/web/themes/custom/perls/fonts/CircularStd-BlackItalic.woff differ diff --git a/web/themes/custom/perls/fonts/CircularStd-BlackItalic.woff2 b/web/themes/custom/perls/fonts/CircularStd-BlackItalic.woff2 new file mode 100644 index 0000000..e04eb1d Binary files /dev/null and b/web/themes/custom/perls/fonts/CircularStd-BlackItalic.woff2 differ diff --git a/web/themes/custom/perls/fonts/CircularStd-Bold.woff b/web/themes/custom/perls/fonts/CircularStd-Bold.woff new file mode 100644 index 0000000..5204e37 Binary files /dev/null and b/web/themes/custom/perls/fonts/CircularStd-Bold.woff differ diff --git a/web/themes/custom/perls/fonts/CircularStd-Bold.woff2 b/web/themes/custom/perls/fonts/CircularStd-Bold.woff2 new file mode 100644 index 0000000..52a110a Binary files /dev/null and b/web/themes/custom/perls/fonts/CircularStd-Bold.woff2 differ diff --git a/web/themes/custom/perls/fonts/CircularStd-BoldItalic.woff b/web/themes/custom/perls/fonts/CircularStd-BoldItalic.woff new file mode 100644 index 0000000..87d9dbf Binary files /dev/null and b/web/themes/custom/perls/fonts/CircularStd-BoldItalic.woff differ diff --git a/web/themes/custom/perls/fonts/CircularStd-BoldItalic.woff2 b/web/themes/custom/perls/fonts/CircularStd-BoldItalic.woff2 new file mode 100644 index 0000000..b52c05b Binary files /dev/null and b/web/themes/custom/perls/fonts/CircularStd-BoldItalic.woff2 differ diff --git a/web/themes/custom/perls/fonts/CircularStd-Book.woff b/web/themes/custom/perls/fonts/CircularStd-Book.woff new file mode 100644 index 0000000..a4be1de Binary files /dev/null and b/web/themes/custom/perls/fonts/CircularStd-Book.woff differ diff --git a/web/themes/custom/perls/fonts/CircularStd-Book.woff2 b/web/themes/custom/perls/fonts/CircularStd-Book.woff2 new file mode 100644 index 0000000..acaa814 Binary files /dev/null and b/web/themes/custom/perls/fonts/CircularStd-Book.woff2 differ diff --git a/web/themes/custom/perls/fonts/CircularStd-BookItalic.woff b/web/themes/custom/perls/fonts/CircularStd-BookItalic.woff new file mode 100644 index 0000000..fdd5d41 Binary files /dev/null and b/web/themes/custom/perls/fonts/CircularStd-BookItalic.woff differ diff --git a/web/themes/custom/perls/fonts/CircularStd-BookItalic.woff2 b/web/themes/custom/perls/fonts/CircularStd-BookItalic.woff2 new file mode 100644 index 0000000..526cb14 Binary files /dev/null and b/web/themes/custom/perls/fonts/CircularStd-BookItalic.woff2 differ diff --git a/web/themes/custom/perls/fonts/CircularStd-Medium.woff b/web/themes/custom/perls/fonts/CircularStd-Medium.woff new file mode 100644 index 0000000..90d2a35 Binary files /dev/null and b/web/themes/custom/perls/fonts/CircularStd-Medium.woff differ diff --git a/web/themes/custom/perls/fonts/CircularStd-Medium.woff2 b/web/themes/custom/perls/fonts/CircularStd-Medium.woff2 new file mode 100644 index 0000000..6b6797b Binary files /dev/null and b/web/themes/custom/perls/fonts/CircularStd-Medium.woff2 differ diff --git a/web/themes/custom/perls/fonts/CircularStd-MediumItalic.woff b/web/themes/custom/perls/fonts/CircularStd-MediumItalic.woff new file mode 100644 index 0000000..64c0e32 Binary files /dev/null and b/web/themes/custom/perls/fonts/CircularStd-MediumItalic.woff differ diff --git a/web/themes/custom/perls/fonts/CircularStd-MediumItalic.woff2 b/web/themes/custom/perls/fonts/CircularStd-MediumItalic.woff2 new file mode 100644 index 0000000..b51d6ec Binary files /dev/null and b/web/themes/custom/perls/fonts/CircularStd-MediumItalic.woff2 differ diff --git a/web/themes/custom/perls/fonts/GreatVibes-Regular.ttf b/web/themes/custom/perls/fonts/GreatVibes-Regular.ttf new file mode 100644 index 0000000..2e01be3 Binary files /dev/null and b/web/themes/custom/perls/fonts/GreatVibes-Regular.ttf differ diff --git a/web/themes/custom/perls/gulpfile.js b/web/themes/custom/perls/gulpfile.js new file mode 100644 index 0000000..cf0d613 --- /dev/null +++ b/web/themes/custom/perls/gulpfile.js @@ -0,0 +1,123 @@ +'use strict'; + +// Configuration. +var config = {}; + +config.sass = { + srcFiles: [ + './resources/scss/**/*.scss', + './resources/scss/**/*.css' + ], + options: { + outputStyle: 'expanded' + }, + destDir: './resources/scss' +}; + +config.js = { + srcFiles: [ + './resources/scripts/*.js' + ], + destDir: './resources/scripts' +}; + +config.distDir = { + dir: './dist', + publicCssDir: './css', + publicJsDir: './js' +}; + +// Load Gulp and other tools. +var fs = require('fs'); +var gulp = require('gulp'); +var cp = require('child_process'); +const sass = require('gulp-sass')(require('sass')); +var sassGlob = require('gulp-sass-glob'); +var sourcemaps = require('gulp-sourcemaps'); +var autoprefixer = require('gulp-autoprefixer'); +var gulpStylelint = require('gulp-stylelint'); +var cleanCSS = require('gulp-clean-css'); +var uglify = require('gulp-uglify'); +var rename = require("gulp-rename"); + +// Gulp tasks. + +/** + * Sets up watchers. + */ +gulp.task('watch', function () { + gulp.watch('resources/scss/**/*.scss', gulp.series('sass-change', 'lint:scss')); + gulp.watch('resources/scripts/*.js', gulp.series('copy-js')); +}); + +/** + * Processes Sass files. + */ +gulp.task('sass', function () { + return gulp.src(config.sass.srcFiles) + .pipe(sassGlob()) + .pipe(sourcemaps.init()) + .pipe(sass(config.sass.options).on('error', sass.logError)) + .pipe(autoprefixer({ remove: false })) + .pipe(cleanCSS()) + .pipe(rename({ + suffix: '.min' + })) + .pipe(sourcemaps.write('./')) + .pipe(gulp.dest(config.distDir.publicCssDir)); +}); + +/** + * Copies CSS files to the public dir. + */ +gulp.task('copy-css', function () { + return gulp.src(config.sass.destDir + '/**/*.css') + .pipe(rename({ + suffix: '.min' + })) + .pipe(gulp.dest(config.distDir.publicCssDir)); +}); + +/** + * Copies JavaScript files to the public dir. + */ +gulp.task('copy-js', function () { + return gulp.src(config.js.destDir + '/**/*.js') + .pipe(uglify()) + .pipe(rename({ + suffix: '.min' + })) + .pipe(gulp.dest(config.distDir.publicJsDir)); +}); + +/** + * Lints Sass files. + */ +gulp.task('lint:scss', function lintCssTask() { + return gulp.src(config.sass.srcFiles) + .pipe(gulpStylelint({ + reporters: [ + { formatter: 'string', console: true } + ] + })); +}); + +/** + * Task sequence to run when Sass files have changed. + */ +gulp.task('sass-change', gulp.series('sass', 'copy-css')); + +/** + * Task sequence to run that copies all assets to public. + */ +gulp.task('copy-assets', gulp.parallel('copy-css', 'copy-js')); + +/** + * Task sequence generate theme and Pattern Lab files. + */ +gulp.task('build-theme', gulp.series(gulp.parallel('sass-change', 'copy-js'))); + +/** + * Gulp default task. + */ +gulp.task('default', gulp.series('build-theme', 'watch')); diff --git a/web/themes/custom/perls/img/background-login.png b/web/themes/custom/perls/img/background-login.png new file mode 100644 index 0000000..768325e Binary files /dev/null and b/web/themes/custom/perls/img/background-login.png differ diff --git a/web/themes/custom/perls/img/icons/icon-chart-gray.svg b/web/themes/custom/perls/img/icons/icon-chart-gray.svg new file mode 100644 index 0000000..12f3e21 --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-chart-gray.svg @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/themes/custom/perls/img/icons/icon-completed.svg b/web/themes/custom/perls/img/icons/icon-completed.svg new file mode 100644 index 0000000..29e5bb0 --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-completed.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/web/themes/custom/perls/img/icons/icon-courses-gray.svg b/web/themes/custom/perls/img/icons/icon-courses-gray.svg new file mode 100644 index 0000000..1ee4a60 --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-courses-gray.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/web/themes/custom/perls/img/icons/icon-courses.svg b/web/themes/custom/perls/img/icons/icon-courses.svg new file mode 100644 index 0000000..4245d72 --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-courses.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/web/themes/custom/perls/img/icons/icon-discover.svg b/web/themes/custom/perls/img/icons/icon-discover.svg new file mode 100644 index 0000000..9703dab --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-discover.svg @@ -0,0 +1 @@ +icon-discover diff --git a/web/themes/custom/perls/img/icons/icon-dislike.svg b/web/themes/custom/perls/img/icons/icon-dislike.svg new file mode 100644 index 0000000..b7c4209 --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-dislike.svg @@ -0,0 +1,24 @@ + + + + + + background + + + + Layer 1 + + + + + + + + + + + + + + diff --git a/web/themes/custom/perls/img/icons/icon-export-csv.svg b/web/themes/custom/perls/img/icons/icon-export-csv.svg new file mode 100644 index 0000000..be23f87 --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-export-csv.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/web/themes/custom/perls/img/icons/icon-file-gray.svg b/web/themes/custom/perls/img/icons/icon-file-gray.svg new file mode 100644 index 0000000..3c68bc8 --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-file-gray.svg @@ -0,0 +1 @@ +icon-file diff --git a/web/themes/custom/perls/img/icons/icon-file.svg b/web/themes/custom/perls/img/icons/icon-file.svg new file mode 100644 index 0000000..0525c7e --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-file.svg @@ -0,0 +1 @@ +icon-file \ No newline at end of file diff --git a/web/themes/custom/perls/img/icons/icon-flash-cards-gray.svg b/web/themes/custom/perls/img/icons/icon-flash-cards-gray.svg new file mode 100644 index 0000000..ec8d676 --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-flash-cards-gray.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/web/themes/custom/perls/img/icons/icon-flash-cards.svg b/web/themes/custom/perls/img/icons/icon-flash-cards.svg new file mode 100644 index 0000000..666b4f3 --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-flash-cards.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/web/themes/custom/perls/img/icons/icon-group-gray.svg b/web/themes/custom/perls/img/icons/icon-group-gray.svg new file mode 100644 index 0000000..2372826 --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-group-gray.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/web/themes/custom/perls/img/icons/icon-group.svg b/web/themes/custom/perls/img/icons/icon-group.svg new file mode 100644 index 0000000..8afe5e0 --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-group.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/web/themes/custom/perls/img/icons/icon-groups.svg b/web/themes/custom/perls/img/icons/icon-groups.svg new file mode 100644 index 0000000..2cecd25 --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-groups.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/web/themes/custom/perls/img/icons/icon-home.svg b/web/themes/custom/perls/img/icons/icon-home.svg new file mode 100644 index 0000000..14c9db6 --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-home.svg @@ -0,0 +1 @@ +icon-home diff --git a/web/themes/custom/perls/img/icons/icon-image-gray.svg b/web/themes/custom/perls/img/icons/icon-image-gray.svg new file mode 100644 index 0000000..9137a38 --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-image-gray.svg @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/themes/custom/perls/img/icons/icon-image.svg b/web/themes/custom/perls/img/icons/icon-image.svg new file mode 100644 index 0000000..d3c611b --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-image.svg @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/themes/custom/perls/img/icons/icon-info.svg b/web/themes/custom/perls/img/icons/icon-info.svg new file mode 100644 index 0000000..ef266a2 --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-info.svg @@ -0,0 +1,3 @@ + + + diff --git a/web/themes/custom/perls/img/icons/icon-learning-objects-gray.svg b/web/themes/custom/perls/img/icons/icon-learning-objects-gray.svg new file mode 100644 index 0000000..206c9a3 --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-learning-objects-gray.svg @@ -0,0 +1 @@ +icon-learn-package diff --git a/web/themes/custom/perls/img/icons/icon-learning-objects.svg b/web/themes/custom/perls/img/icons/icon-learning-objects.svg new file mode 100644 index 0000000..d01df1a --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-learning-objects.svg @@ -0,0 +1 @@ +icon-learn-package \ No newline at end of file diff --git a/web/themes/custom/perls/img/icons/icon-like.svg b/web/themes/custom/perls/img/icons/icon-like.svg new file mode 100644 index 0000000..1d79b12 --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-like.svg @@ -0,0 +1,24 @@ + + + + + + background + + + + Layer 1 + + + + + + + + + + + + + + diff --git a/web/themes/custom/perls/img/icons/icon-me.svg b/web/themes/custom/perls/img/icons/icon-me.svg new file mode 100644 index 0000000..2cb1d03 --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-me.svg @@ -0,0 +1 @@ +icon-my-profile \ No newline at end of file diff --git a/web/themes/custom/perls/img/icons/icon-notify-groups.svg b/web/themes/custom/perls/img/icons/icon-notify-groups.svg new file mode 100644 index 0000000..c2a91bd --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-notify-groups.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/themes/custom/perls/img/icons/icon-notify-user.svg b/web/themes/custom/perls/img/icons/icon-notify-user.svg new file mode 100644 index 0000000..7be21d3 --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-notify-user.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/web/themes/custom/perls/img/icons/icon-podcasts-gray.svg b/web/themes/custom/perls/img/icons/icon-podcasts-gray.svg new file mode 100644 index 0000000..0c70792 --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-podcasts-gray.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/web/themes/custom/perls/img/icons/icon-podcasts.svg b/web/themes/custom/perls/img/icons/icon-podcasts.svg new file mode 100644 index 0000000..5206548 --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-podcasts.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/web/themes/custom/perls/img/icons/icon-quizzes-gray.svg b/web/themes/custom/perls/img/icons/icon-quizzes-gray.svg new file mode 100644 index 0000000..1151b84 --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-quizzes-gray.svg @@ -0,0 +1 @@ +icon-quiz diff --git a/web/themes/custom/perls/img/icons/icon-quizzes.svg b/web/themes/custom/perls/img/icons/icon-quizzes.svg new file mode 100644 index 0000000..fedd7a9 --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-quizzes.svg @@ -0,0 +1 @@ +icon-quiz \ No newline at end of file diff --git a/web/themes/custom/perls/img/icons/icon-recommendation-black.svg b/web/themes/custom/perls/img/icons/icon-recommendation-black.svg new file mode 100644 index 0000000..bcc9fd3 --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-recommendation-black.svg @@ -0,0 +1,3 @@ + + + diff --git a/web/themes/custom/perls/img/icons/icon-recommendation-white.svg b/web/themes/custom/perls/img/icons/icon-recommendation-white.svg new file mode 100644 index 0000000..185cb29 --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-recommendation-white.svg @@ -0,0 +1,3 @@ + + + diff --git a/web/themes/custom/perls/img/icons/icon-results.svg b/web/themes/custom/perls/img/icons/icon-results.svg new file mode 100644 index 0000000..bddde58 --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-results.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/web/themes/custom/perls/img/icons/icon-search.svg b/web/themes/custom/perls/img/icons/icon-search.svg new file mode 100644 index 0000000..a4313b3 --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-search.svg @@ -0,0 +1 @@ +icon-search--lg \ No newline at end of file diff --git a/web/themes/custom/perls/img/icons/icon-stats-bookmarked.svg b/web/themes/custom/perls/img/icons/icon-stats-bookmarked.svg new file mode 100644 index 0000000..d161c1c --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-stats-bookmarked.svg @@ -0,0 +1 @@ +Stats-Bookmarked \ No newline at end of file diff --git a/web/themes/custom/perls/img/icons/icon-stats-comments-posted.svg b/web/themes/custom/perls/img/icons/icon-stats-comments-posted.svg new file mode 100644 index 0000000..838ff9c --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-stats-comments-posted.svg @@ -0,0 +1,13 @@ + + + + + + diff --git a/web/themes/custom/perls/img/icons/icon-stats-completed.svg b/web/themes/custom/perls/img/icons/icon-stats-completed.svg new file mode 100644 index 0000000..7407b83 --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-stats-completed.svg @@ -0,0 +1 @@ +Stats-Completed \ No newline at end of file diff --git a/web/themes/custom/perls/img/icons/icon-stats-feedback-submissions.svg b/web/themes/custom/perls/img/icons/icon-stats-feedback-submissions.svg new file mode 100644 index 0000000..5a6414e --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-stats-feedback-submissions.svg @@ -0,0 +1,13 @@ + + + + + + + + + diff --git a/web/themes/custom/perls/img/icons/icon-stats-learner-feedback.svg b/web/themes/custom/perls/img/icons/icon-stats-learner-feedback.svg new file mode 100644 index 0000000..343b516 --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-stats-learner-feedback.svg @@ -0,0 +1,14 @@ + + + + + + + + + diff --git a/web/themes/custom/perls/img/icons/icon-stats-members.svg b/web/themes/custom/perls/img/icons/icon-stats-members.svg new file mode 100644 index 0000000..894ec4f --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-stats-members.svg @@ -0,0 +1 @@ +icon-user diff --git a/web/themes/custom/perls/img/icons/icon-stats-recommended.svg b/web/themes/custom/perls/img/icons/icon-stats-recommended.svg new file mode 100644 index 0000000..4757d3b --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-stats-recommended.svg @@ -0,0 +1 @@ +Stats-Recommended \ No newline at end of file diff --git a/web/themes/custom/perls/img/icons/icon-stats-viewed.svg b/web/themes/custom/perls/img/icons/icon-stats-viewed.svg new file mode 100644 index 0000000..b7931d4 --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-stats-viewed.svg @@ -0,0 +1 @@ +Stats-Viewed \ No newline at end of file diff --git a/web/themes/custom/perls/img/icons/icon-tack.svg b/web/themes/custom/perls/img/icons/icon-tack.svg new file mode 100644 index 0000000..e277202 --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-tack.svg @@ -0,0 +1,14 @@ + + + + + + + + + + diff --git a/web/themes/custom/perls/img/icons/icon-tags-gray.svg b/web/themes/custom/perls/img/icons/icon-tags-gray.svg new file mode 100644 index 0000000..9caecf7 --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-tags-gray.svg @@ -0,0 +1 @@ +icon-tag diff --git a/web/themes/custom/perls/img/icons/icon-tags.svg b/web/themes/custom/perls/img/icons/icon-tags.svg new file mode 100644 index 0000000..9e1f819 --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-tags.svg @@ -0,0 +1 @@ +icon-tag \ No newline at end of file diff --git a/web/themes/custom/perls/img/icons/icon-tests-gray.svg b/web/themes/custom/perls/img/icons/icon-tests-gray.svg new file mode 100644 index 0000000..1728166 --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-tests-gray.svg @@ -0,0 +1 @@ +Test Icon \ No newline at end of file diff --git a/web/themes/custom/perls/img/icons/icon-tests.svg b/web/themes/custom/perls/img/icons/icon-tests.svg new file mode 100644 index 0000000..2e9cf22 --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-tests.svg @@ -0,0 +1 @@ +icon-tip-card \ No newline at end of file diff --git a/web/themes/custom/perls/img/icons/icon-tip-cards-gray.svg b/web/themes/custom/perls/img/icons/icon-tip-cards-gray.svg new file mode 100644 index 0000000..64bea27 --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-tip-cards-gray.svg @@ -0,0 +1 @@ +icon-tip-card diff --git a/web/themes/custom/perls/img/icons/icon-tip-cards.svg b/web/themes/custom/perls/img/icons/icon-tip-cards.svg new file mode 100644 index 0000000..2e9cf22 --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-tip-cards.svg @@ -0,0 +1 @@ +icon-tip-card \ No newline at end of file diff --git a/web/themes/custom/perls/img/icons/icon-topics-gray.svg b/web/themes/custom/perls/img/icons/icon-topics-gray.svg new file mode 100644 index 0000000..e9496c7 --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-topics-gray.svg @@ -0,0 +1 @@ +icon-topic diff --git a/web/themes/custom/perls/img/icons/icon-topics.svg b/web/themes/custom/perls/img/icons/icon-topics.svg new file mode 100644 index 0000000..082aedd --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-topics.svg @@ -0,0 +1 @@ +icon-topic \ No newline at end of file diff --git a/web/themes/custom/perls/img/icons/icon-user-avatar.svg b/web/themes/custom/perls/img/icons/icon-user-avatar.svg new file mode 100644 index 0000000..b6e0aae --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-user-avatar.svg @@ -0,0 +1,4 @@ + + + + diff --git a/web/themes/custom/perls/img/icons/icon-users-gray.svg b/web/themes/custom/perls/img/icons/icon-users-gray.svg new file mode 100644 index 0000000..87287a5 --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-users-gray.svg @@ -0,0 +1 @@ +icon-user diff --git a/web/themes/custom/perls/img/icons/icon-users.svg b/web/themes/custom/perls/img/icons/icon-users.svg new file mode 100644 index 0000000..425cd2d --- /dev/null +++ b/web/themes/custom/perls/img/icons/icon-users.svg @@ -0,0 +1 @@ +icon-user \ No newline at end of file diff --git a/web/themes/custom/perls/img/icons/tests-gray.svg b/web/themes/custom/perls/img/icons/tests-gray.svg new file mode 100644 index 0000000..9caecf7 --- /dev/null +++ b/web/themes/custom/perls/img/icons/tests-gray.svg @@ -0,0 +1 @@ +icon-tag diff --git a/web/themes/custom/perls/img/perls-logo.svg b/web/themes/custom/perls/img/perls-logo.svg new file mode 100644 index 0000000..54cc49c --- /dev/null +++ b/web/themes/custom/perls/img/perls-logo.svg @@ -0,0 +1 @@ +perls-logo \ No newline at end of file diff --git a/web/themes/custom/perls/img/sl-logo.svg b/web/themes/custom/perls/img/sl-logo.svg new file mode 100644 index 0000000..6fb67bc --- /dev/null +++ b/web/themes/custom/perls/img/sl-logo.svg @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/themes/custom/perls/img/slgo_logo_in.svg b/web/themes/custom/perls/img/slgo_logo_in.svg new file mode 100644 index 0000000..fa7e66d --- /dev/null +++ b/web/themes/custom/perls/img/slgo_logo_in.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/web/themes/custom/perls/img/slgo_logo_in_white.svg b/web/themes/custom/perls/img/slgo_logo_in_white.svg new file mode 100644 index 0000000..19d0d21 --- /dev/null +++ b/web/themes/custom/perls/img/slgo_logo_in_white.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/web/themes/custom/perls/logo-slgo.svg b/web/themes/custom/perls/logo-slgo.svg new file mode 100644 index 0000000..2d3aac9 --- /dev/null +++ b/web/themes/custom/perls/logo-slgo.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/web/themes/custom/perls/logo.svg b/web/themes/custom/perls/logo.svg new file mode 100644 index 0000000..dfd695f --- /dev/null +++ b/web/themes/custom/perls/logo.svg @@ -0,0 +1,3 @@ + + + diff --git a/web/themes/custom/perls/package-lock.json b/web/themes/custom/perls/package-lock.json new file mode 100644 index 0000000..1223f59 --- /dev/null +++ b/web/themes/custom/perls/package-lock.json @@ -0,0 +1,14333 @@ +{ + "name": "perls", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "perls", + "version": "1.0.0", + "license": "ISC", + "devDependencies": { + "gulp": "^4.0.2", + "gulp-autoprefixer": "^5.0.0", + "gulp-clean-css": "^3.0.8", + "gulp-exec": "^3.0.2", + "gulp-rename": "^1.4.0", + "gulp-sass": "^5.1.0", + "gulp-sass-glob": "^1.0.8", + "gulp-sourcemaps": "^1.12.1", + "gulp-stylelint": "^9.0.0", + "gulp-uglify": "^3.0.2", + "sass": "^1.49.0", + "stylelint": "^10.1.0", + "stylelint-config-standard": "^18.3.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", + "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.16.8.tgz", + "integrity": "sha512-m7OkX0IdKLKPpBlJtF561YJal5y/jyI5fNfWbPxh2D/nbzzGI4qRyrD8xO2jB24u7l+5I2a43scCG2IrfjC50Q==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.16.12", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.16.12.tgz", + "integrity": "sha512-dK5PtG1uiN2ikk++5OzSYsitZKny4wOCD0nrO4TqnW4BVBTQ2NGS3NgilvT/TEyxTST7LNyWV/T4tXDoD3fOgg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.16.8", + "@babel/helper-compilation-targets": "^7.16.7", + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helpers": "^7.16.7", + "@babel/parser": "^7.16.12", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.10", + "@babel/types": "^7.16.8", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0", + "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "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 + }, + "node_modules/@babel/core/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, + "bin": { + "semver": "bin/semver.js" + } + }, + "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": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@babel/generator": { + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.16.8.tgz", + "integrity": "sha512-1ojZwE9+lOXzcWdWmO6TbUzDfqLD39CmEhN8+2cX9XkDo5yW1OpgfejfliysR2AWLpMamTiOiAp/mtroaymhpw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.8", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "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": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz", + "integrity": "sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.16.4", + "@babel/helper-validator-option": "^7.16.7", + "browserslist": "^4.17.5", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/browserslist": { + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.1.tgz", + "integrity": "sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==", + "dev": true, + "dependencies": { + "caniuse-lite": "^1.0.30001286", + "electron-to-chromium": "^1.4.17", + "escalade": "^3.1.1", + "node-releases": "^2.0.1", + "picocolors": "^1.0.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } + }, + "node_modules/@babel/helper-compilation-targets/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, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz", + "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz", + "integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==", + "dev": true, + "dependencies": { + "@babel/helper-get-function-arity": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-get-function-arity": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz", + "integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", + "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", + "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz", + "integrity": "sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-module-imports": "^7.16.7", + "@babel/helper-simple-access": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/helper-validator-identifier": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.7", + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz", + "integrity": "sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", + "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", + "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.16.7.tgz", + "integrity": "sha512-9ZDoqtfY7AuEOt3cxchfii6C7GDyyMBffktR5B2jvWv8u2+efwvpnVKXMWzNehqy68tKgAfSwfdw/lWpthS2bw==", + "dev": true, + "dependencies": { + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.7", + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.16.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", + "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.16.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.16.12", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.12.tgz", + "integrity": "sha512-VfaV15po8RiZssrkPweyvbGVSe4x2y+aciFCgn0n0/SJMR22cwofRV1mtnJQYcSB1wUTaA/X1LnA3es66MCO5A==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/template": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", + "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.16.7", + "@babel/parser": "^7.16.7", + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.16.10", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.10.tgz", + "integrity": "sha512-yzuaYXoRJBGMlBhsMJoUW7G1UmSb/eXr/JHYM/MsOJgavJibLwASijW7oXBdw3NQ6T0bW7Ty5P/VarOs9cHmqw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.16.8", + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-hoist-variables": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/parser": "^7.16.10", + "@babel/types": "^7.16.8", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dev": true, + "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 + }, + "node_modules/@babel/types": { + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.8.tgz", + "integrity": "sha512-smN2DQc5s4M7fntyjGtyIPbRJv6wW4rU/94fmYJ7PKQuZkC0qGMHXJbg6sNGt12JmVr4k5YaptI/XtiLJBnmIg==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@gulp-sourcemaps/map-sources": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/map-sources/-/map-sources-1.0.0.tgz", + "integrity": "sha1-iQrnxdjId/bThIYCFazp1+yUW9o=", + "dev": true, + "dependencies": { + "normalize-path": "^2.0.1", + "through2": "^2.0.3" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/@gulp-sourcemaps/map-sources/node_modules/normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "dependencies": { + "remove-trailing-separator": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@mrmlnc/readdir-enhanced": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", + "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", + "dev": true, + "dependencies": { + "call-me-maybe": "^1.0.1", + "glob-to-regexp": "^0.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", + "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "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/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", + "dev": true + }, + "node_modules/@types/node": { + "version": "17.0.12", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.12.tgz", + "integrity": "sha512-4YpbAsnJXWYK/fpTVFlMIcUIho2AYCi4wg5aNPrG1ng7fn/1/RZfCIpRCiBX+12RVa34RluilnvCqD+g3KiSiA==", + "dev": true + }, + "node_modules/@types/unist": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", + "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==", + "dev": true + }, + "node_modules/@types/vfile": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/vfile/-/vfile-3.0.2.tgz", + "integrity": "sha512-b3nLFGaGkJ9rzOcuXRfHkZMdjsawuDD0ENL9fzTophtBg8FJHSGbH7daXkEpcwy3v7Xol3pAvsmlYyFhR4pqJw==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/unist": "*", + "@types/vfile-message": "*" + } + }, + "node_modules/@types/vfile-message": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/vfile-message/-/vfile-message-2.0.0.tgz", + "integrity": "sha512-GpTIuDpb9u4zIO165fUy9+fXcULdD8HFRNli04GehoMVbeNq7D6OBnqSmg3lxZnC+UvgUhEWKxdKiwYUkGltIw==", + "deprecated": "This is a stub types definition. vfile-message provides its own type definitions, so you do not need this installed.", + "dev": true, + "dependencies": { + "vfile-message": "*" + } + }, + "node_modules/acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "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/ansi-colors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", + "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", + "dev": true, + "dependencies": { + "ansi-wrap": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ansi-cyan": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-cyan/-/ansi-cyan-0.1.1.tgz", + "integrity": "sha1-U4rlKK+JgvKK4w2G8vF0VtJgmHM=", + "dev": true, + "dependencies": { + "ansi-wrap": "0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ansi-gray": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", + "integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=", + "dev": true, + "dependencies": { + "ansi-wrap": "0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ansi-red": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-red/-/ansi-red-0.1.1.tgz", + "integrity": "sha1-jGOPnRCAgAo1PJwoyKgcpHBdlGw=", + "dev": true, + "dependencies": { + "ansi-wrap": "0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "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/ansi-wrap": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", + "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=", + "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, + "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": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "dependencies": { + "remove-trailing-separator": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/append-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz", + "integrity": "sha1-2CIM9GYIFSXv6lBhTz3mUU36WPE=", + "dev": true, + "dependencies": { + "buffer-equal": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", + "dev": true + }, + "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, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-filter": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/arr-filter/-/arr-filter-1.1.2.tgz", + "integrity": "sha1-Q/3d0JHo7xGqTEXZzcGOLf8XEe4=", + "dev": true, + "dependencies": { + "make-iterator": "^1.0.0" + }, + "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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/arr-map/-/arr-map-2.0.2.tgz", + "integrity": "sha1-Onc0X/wc814qkYJWAfnljy4kysQ=", + "dev": true, + "dependencies": { + "make-iterator": "^1.0.0" + }, + "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": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", + "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=", + "dev": true, + "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": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-initial": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/array-initial/-/array-initial-1.1.0.tgz", + "integrity": "sha1-L6dLJnOTccOUe9enrcc74zSz15U=", + "dev": true, + "dependencies": { + "array-slice": "^1.0.0", + "is-number": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-initial/node_modules/is-number": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-last": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/array-last/-/array-last-1.3.0.tgz", + "integrity": "sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg==", + "dev": true, + "dependencies": { + "is-number": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-last/node_modules/is-number": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-slice": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", + "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-sort": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-sort/-/array-sort-1.0.0.tgz", + "integrity": "sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg==", + "dev": true, + "dependencies": { + "default-compare": "^1.0.0", + "get-value": "^2.0.6", + "kind-of": "^5.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "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": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true, + "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": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/async-done": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/async-done/-/async-done-1.3.2.tgz", + "integrity": "sha512-uYkTP8dw2og1tu1nmza1n1CMW0qb8gWWlwqMmLb7MhBVs4BXrFziT6HXUd+/RlRA/i4H9AkofYloUbs1fwMqlw==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.2", + "process-nextick-args": "^2.0.0", + "stream-exhaust": "^1.0.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "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 + }, + "node_modules/async-settle": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-1.0.0.tgz", + "integrity": "sha1-HQqRS7Aldb7IqPOnTlCA9yssDGs=", + "dev": true, + "dependencies": { + "async-done": "^1.2.2" + }, + "engines": { + "node": ">= 0.10" + } + }, + "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, + "bin": { + "atob": "bin/atob.js" + }, + "engines": { + "node": ">= 4.5.0" + } + }, + "node_modules/autoprefixer": { + "version": "8.6.5", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-8.6.5.tgz", + "integrity": "sha512-PLWJN3Xo/rycNkx+mp8iBDMTm3FeWe4VmYaZDSqL5QQB9sLsQkG5k8n+LNDFnhh9kdq2K+egL/icpctOmDHwig==", + "dev": true, + "dependencies": { + "browserslist": "^3.2.8", + "caniuse-lite": "^1.0.30000864", + "normalize-range": "^0.1.2", + "num2fraction": "^1.2.2", + "postcss": "^6.0.23", + "postcss-value-parser": "^3.2.3" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + } + }, + "node_modules/bach": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz", + "integrity": "sha1-Szzpa/JxNPeaG0FKUcFONMO9mIA=", + "dev": true, + "dependencies": { + "arr-filter": "^1.1.1", + "arr-flatten": "^1.0.1", + "arr-map": "^2.0.0", + "array-each": "^1.0.0", + "array-initial": "^1.0.0", + "array-last": "^1.1.1", + "async-done": "^1.2.2", + "async-settle": "^1.0.0", + "now-and-later": "^2.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/bail": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", + "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "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 + }, + "node_modules/base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "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": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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/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/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, + "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, + "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/browserslist": { + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz", + "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==", + "dev": true, + "dependencies": { + "caniuse-lite": "^1.0.30000844", + "electron-to-chromium": "^1.3.47" + }, + "bin": { + "browserslist": "cli.js" + } + }, + "node_modules/buffer-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz", + "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=", + "dev": true, + "engines": { + "node": ">=0.4.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 + }, + "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, + "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, + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-me-maybe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", + "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=", + "dev": true + }, + "node_modules/caller-callsite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", + "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", + "dev": true, + "dependencies": { + "callsites": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/caller-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", + "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", + "dev": true, + "dependencies": { + "caller-callsite": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/camelcase-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz", + "integrity": "sha1-oqpfsa9oh1glnDLBQUJteJI7m3c=", + "dev": true, + "dependencies": { + "camelcase": "^4.1.0", + "map-obj": "^2.0.0", + "quick-lru": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001303", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001303.tgz", + "integrity": "sha512-/Mqc1oESndUNszJP0kx0UaQU9kEv9nNtJ7Kn8AdA0mNnH8eR1cj0kG+NbNuC1Wq/b21eA8prhKRA3bbkjONegQ==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } + }, + "node_modules/ccount": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.1.0.tgz", + "integrity": "sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "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, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/character-entities": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", + "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-html4": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-1.1.4.tgz", + "integrity": "sha512-HRcDxZuZqMx3/a+qrzxdBKBPUpxWEq9xw2OPZ3a/174ihfrQKVsFhqtthBInFy1zZ9GgZyFXOatNujm8M+El3g==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", + "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", + "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "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/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, + "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/class-utils/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/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": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/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": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/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 + }, + "node_modules/class-utils/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": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/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": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/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, + "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/clean-css": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz", + "integrity": "sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g==", + "dev": true, + "dependencies": { + "source-map": "~0.6.0" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "dev": true, + "dependencies": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true, + "engines": { + "node": ">=0.10.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": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "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": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "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/cliui/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/clone-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", + "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/clone-regexp": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clone-regexp/-/clone-regexp-2.2.0.tgz", + "integrity": "sha512-beMpP7BOtTipFuW8hrJvREQ2DrRu3BE7by0ZpibtfBA+qfHYvMGTc2Yb1JMYPKg/JUw0CHYvpg796aNTSW9z7Q==", + "dev": true, + "dependencies": { + "is-regexp": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/clone-stats": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", + "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=", + "dev": true + }, + "node_modules/cloneable-readable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.3.tgz", + "integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "process-nextick-args": "^2.0.0", + "readable-stream": "^2.3.5" + } + }, + "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": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/collapse-white-space": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz", + "integrity": "sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/collection-map": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-map/-/collection-map-1.0.0.tgz", + "integrity": "sha1-rqDwb40mx4DCt1SUOFVEsiVa8Yw=", + "dev": true, + "dependencies": { + "arr-map": "^2.0.2", + "for-own": "^1.0.0", + "make-iterator": "^1.0.0" + }, + "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": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "dependencies": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.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==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "dev": true, + "bin": { + "color-support": "bin.js" + } + }, + "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 + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "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" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.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, + "dependencies": { + "safe-buffer": "~5.1.1" + } + }, + "node_modules/copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/copy-props": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-2.0.5.tgz", + "integrity": "sha512-XBlx8HSqrT0ObQwmSzM7WE5k8FxTV75h1DX1Z3n6NhQ/UYYAvInWYmG06vFt7hQZArE2fuO62aihiWIVQwh1sw==", + "dev": true, + "dependencies": { + "each-props": "^1.3.2", + "is-plain-object": "^5.0.0" + } + }, + "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 + }, + "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/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, + "dependencies": { + "inherits": "^2.0.3", + "source-map": "^0.6.1", + "source-map-resolve": "^0.5.2", + "urix": "^0.1.0" + } + }, + "node_modules/currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "dev": true, + "dependencies": { + "array-find-index": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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, + "dependencies": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, + "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, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/debug-fabulous": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/debug-fabulous/-/debug-fabulous-0.0.4.tgz", + "integrity": "sha1-+gccXYdIRoVCSAdCHKSxawsaB2M=", + "dev": true, + "dependencies": { + "debug": "2.X", + "lazy-debug-legacy": "0.0.X", + "object-assign": "4.1.0" + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", + "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", + "dev": true, + "dependencies": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize-keys/node_modules/map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true, + "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": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/default-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/default-compare/-/default-compare-1.0.0.tgz", + "integrity": "sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ==", + "dev": true, + "dependencies": { + "kind-of": "^5.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/default-resolution": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/default-resolution/-/default-resolution-2.0.0.tgz", + "integrity": "sha1-vLgrqnKtebQmp2cy8aga1t8m1oQ=", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "dependencies": { + "object-keys": "^1.0.12" + }, + "engines": { + "node": ">= 0.4" + } + }, + "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, + "dependencies": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/detect-newline": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", + "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/dir-glob": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", + "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", + "dev": true, + "dependencies": { + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "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/dom-serializer/node_modules/domelementtype": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", + "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/dom-serializer/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/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/domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "dev": true, + "dependencies": { + "domelementtype": "1" + } + }, + "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/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, + "dependencies": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "node_modules/each-props": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/each-props/-/each-props-1.3.2.tgz", + "integrity": "sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.1", + "object.defaults": "^1.1.0" + } + }, + "node_modules/each-props/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, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.4.54", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.54.tgz", + "integrity": "sha512-jRAoneRdSxnpRHO0ANpnEUtQHXxlgfVjrLOnQSisw1ryjXJXvS0pJaR/v2B7S++/tRjgEDp4Sjn5nmgb6uTySw==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "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, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "dev": true + }, + "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, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es5-ext": { + "version": "0.10.53", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", + "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", + "dev": true, + "dependencies": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.3", + "next-tick": "~1.0.0" + } + }, + "node_modules/es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "dev": true, + "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, + "dependencies": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "node_modules/es6-weak-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", + "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", + "dev": true, + "dependencies": { + "d": "1", + "es5-ext": "^0.10.46", + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "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": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.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, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/execall": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/execall/-/execall-2.0.0.tgz", + "integrity": "sha512-0FU2hZ5Hh6iQnarpRtQurM/aAvp3RIbfvgLHrcqJYzhXyV2KFruhuChf9NC6waAhiUR7FFtlugkI4p7f2Fqlow==", + "dev": true, + "dependencies": { + "clone-regexp": "^2.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "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-brackets/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/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": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/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": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/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 + }, + "node_modules/expand-brackets/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": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/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": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/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, + "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/expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "dev": true, + "dependencies": { + "homedir-polyfill": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ext": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.6.0.tgz", + "integrity": "sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg==", + "dev": true, + "dependencies": { + "type": "^2.5.0" + } + }, + "node_modules/ext/node_modules/type": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/type/-/type-2.5.0.tgz", + "integrity": "sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw==", + "dev": true + }, + "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 + }, + "node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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, + "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": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fancy-log": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz", + "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==", + "dev": true, + "dependencies": { + "ansi-gray": "^0.1.1", + "color-support": "^1.1.3", + "parse-node-version": "^1.0.0", + "time-stamp": "^1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "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 + }, + "node_modules/fast-glob": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", + "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", + "dev": true, + "dependencies": { + "@mrmlnc/readdir-enhanced": "^2.2.1", + "@nodelib/fs.stat": "^1.1.2", + "glob-parent": "^3.1.0", + "is-glob": "^4.0.0", + "merge2": "^1.2.3", + "micromatch": "^3.1.10" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "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 + }, + "node_modules/fast-levenshtein": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-1.1.4.tgz", + "integrity": "sha1-5qdUzI8V5YmHqpy9J69m/W9OWvk=", + "dev": true + }, + "node_modules/file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "dev": true, + "dependencies": { + "flat-cache": "^2.0.1" + }, + "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": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "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/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "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/fined": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz", + "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==", + "dev": true, + "dependencies": { + "expand-tilde": "^2.0.2", + "is-plain-object": "^2.0.3", + "object.defaults": "^1.1.0", + "object.pick": "^1.2.0", + "parse-filepath": "^1.0.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/fined/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, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/flagged-respawn": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", + "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "dependencies": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/flatted": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", + "dev": true + }, + "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, + "dependencies": { + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" + } + }, + "node_modules/for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/for-own": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", + "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", + "dev": true, + "dependencies": { + "for-in": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "dependencies": { + "map-cache": "^0.2.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fs-mkdirp-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", + "integrity": "sha1-C3gV/DIBxqaeFNuYzgmMFpNSWes=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.11", + "through2": "^2.0.3" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "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/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "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, + "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.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-stdin": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-7.0.0.tgz", + "integrity": "sha512-zRKcywvrXlXsA0v0i9Io4KDRaAw7+a1ZpjRwl9Wox8PFlVCCHra7E9c4kqXCoCM9nR5tBkaTTZRBoCm60bFqTQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "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/glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "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": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/glob-stream": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz", + "integrity": "sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ=", + "dev": true, + "dependencies": { + "extend": "^3.0.0", + "glob": "^7.1.1", + "glob-parent": "^3.1.0", + "is-negated-glob": "^1.0.0", + "ordered-read-streams": "^1.0.0", + "pumpify": "^1.3.5", + "readable-stream": "^2.1.5", + "remove-trailing-separator": "^1.0.1", + "to-absolute-glob": "^2.0.0", + "unique-stream": "^2.0.2" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", + "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=", + "dev": true + }, + "node_modules/glob-watcher": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-5.0.5.tgz", + "integrity": "sha512-zOZgGGEHPklZNjZQaZ9f41i7F2YwE+tS5ZHrDhbBCk3stwahn5vQxnFmBJZHoYdusR6R1bLSXeGUy/BhctwKzw==", + "dev": true, + "dependencies": { + "anymatch": "^2.0.0", + "async-done": "^1.2.0", + "chokidar": "^2.0.0", + "is-negated-glob": "^1.0.0", + "just-debounce": "^1.0.0", + "normalize-path": "^3.0.0", + "object.defaults": "^1.1.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "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, + "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": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "dev": true, + "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, + "engines": { + "node": ">=4" + } + }, + "node_modules/globby": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz", + "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==", + "dev": true, + "dependencies": { + "@types/glob": "^7.1.1", + "array-union": "^1.0.2", + "dir-glob": "^2.2.2", + "fast-glob": "^2.2.6", + "glob": "^7.1.3", + "ignore": "^4.0.3", + "pify": "^4.0.1", + "slash": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/globby/node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/globby/node_modules/slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/globjoin": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", + "integrity": "sha1-L0SUrIkZ43Z8XLtpHp9GMyQoXUM=", + "dev": true + }, + "node_modules/glogg": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.2.tgz", + "integrity": "sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA==", + "dev": true, + "dependencies": { + "sparkles": "^1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gonzales-pe": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-4.3.0.tgz", + "integrity": "sha512-otgSPpUmdWJ43VXyiNgEYE4luzHCL2pz4wQ0OnDluC6Eg4Ko3Vexy/SrSynglw/eR+OhkzmqFCZa/OFa/RgAOQ==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "gonzales": "bin/gonzales.js" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.9", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", + "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", + "dev": true + }, + "node_modules/gulp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/gulp/-/gulp-4.0.2.tgz", + "integrity": "sha512-dvEs27SCZt2ibF29xYgmnwwCYZxdxhQ/+LFWlbAW8y7jt68L/65402Lz3+CKy0Ov4rOs+NERmDq7YlZaDqUIfA==", + "dev": true, + "dependencies": { + "glob-watcher": "^5.0.3", + "gulp-cli": "^2.2.0", + "undertaker": "^1.2.1", + "vinyl-fs": "^3.0.0" + }, + "bin": { + "gulp": "bin/gulp.js" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-autoprefixer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/gulp-autoprefixer/-/gulp-autoprefixer-5.0.0.tgz", + "integrity": "sha1-gjfCeKaXdScKHK/n1vEBz81YVUQ=", + "dev": true, + "dependencies": { + "autoprefixer": "^8.0.0", + "fancy-log": "^1.3.2", + "plugin-error": "^1.0.1", + "postcss": "^6.0.1", + "through2": "^2.0.0", + "vinyl-sourcemaps-apply": "^0.2.0" + }, + "engines": { + "node": ">=4.5" + } + }, + "node_modules/gulp-clean-css": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/gulp-clean-css/-/gulp-clean-css-3.10.0.tgz", + "integrity": "sha512-7Isf9Y690o/Q5MVjEylH1H7L8WeZ89woW7DnhD5unTintOdZb67KdOayRgp9trUFo+f9UyJtuatV42e/+kghPg==", + "dev": true, + "dependencies": { + "clean-css": "4.2.1", + "plugin-error": "1.0.1", + "through2": "2.0.3", + "vinyl-sourcemaps-apply": "0.2.1" + } + }, + "node_modules/gulp-clean-css/node_modules/through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "dev": true, + "dependencies": { + "readable-stream": "^2.1.5", + "xtend": "~4.0.1" + } + }, + "node_modules/gulp-cli": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-2.3.0.tgz", + "integrity": "sha512-zzGBl5fHo0EKSXsHzjspp3y5CONegCm8ErO5Qh0UzFzk2y4tMvzLWhoDokADbarfZRL2pGpRp7yt6gfJX4ph7A==", + "dev": true, + "dependencies": { + "ansi-colors": "^1.0.1", + "archy": "^1.0.0", + "array-sort": "^1.0.0", + "color-support": "^1.1.3", + "concat-stream": "^1.6.0", + "copy-props": "^2.0.1", + "fancy-log": "^1.3.2", + "gulplog": "^1.0.0", + "interpret": "^1.4.0", + "isobject": "^3.0.1", + "liftoff": "^3.1.0", + "matchdep": "^2.0.0", + "mute-stdout": "^1.0.0", + "pretty-hrtime": "^1.0.0", + "replace-homedir": "^1.0.0", + "semver-greatest-satisfied-range": "^1.1.0", + "v8flags": "^3.2.0", + "yargs": "^7.1.0" + }, + "bin": { + "gulp": "bin/gulp.js" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-exec": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gulp-exec/-/gulp-exec-3.0.2.tgz", + "integrity": "sha512-74sde0n+pQo/Jbe5qsk0sPC4afjnB7VHDUZd4BrRTLt6lsNU451N+kSvCOoSn6q0iqS9ztT1uy8ZE/FRqmXKeQ==", + "dev": true, + "dependencies": { + "lodash.template": "^4.4.0", + "plugin-error": "^0.1.2", + "through2": "^2.0.3" + } + }, + "node_modules/gulp-exec/node_modules/arr-diff": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-1.1.0.tgz", + "integrity": "sha1-aHwydYFjWI/vfeezb6vklesaOZo=", + "dev": true, + "dependencies": { + "arr-flatten": "^1.0.1", + "array-slice": "^0.2.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-exec/node_modules/arr-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-2.1.0.tgz", + "integrity": "sha1-IPnqtexw9cfSFbEHexw5Fh0pLH0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-exec/node_modules/array-slice": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz", + "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-exec/node_modules/extend-shallow": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-1.1.4.tgz", + "integrity": "sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE=", + "dev": true, + "dependencies": { + "kind-of": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-exec/node_modules/kind-of": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz", + "integrity": "sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-exec/node_modules/plugin-error": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-0.1.2.tgz", + "integrity": "sha1-O5uzM1zPAPQl4HQ34ZJ2ln2kes4=", + "dev": true, + "dependencies": { + "ansi-cyan": "^0.1.1", + "ansi-red": "^0.1.1", + "arr-diff": "^1.0.1", + "arr-union": "^2.0.1", + "extend-shallow": "^1.1.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-rename": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/gulp-rename/-/gulp-rename-1.4.0.tgz", + "integrity": "sha512-swzbIGb/arEoFK89tPY58vg3Ok1bw+d35PfUNwWqdo7KM4jkmuGA78JiDNqR+JeZFaeeHnRg9N7aihX3YPmsyg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/gulp-sass": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/gulp-sass/-/gulp-sass-5.1.0.tgz", + "integrity": "sha512-7VT0uaF+VZCmkNBglfe1b34bxn/AfcssquLKVDYnCDJ3xNBaW7cUuI3p3BQmoKcoKFrs9jdzUxyb+u+NGfL4OQ==", + "dev": true, + "dependencies": { + "lodash.clonedeep": "^4.5.0", + "picocolors": "^1.0.0", + "plugin-error": "^1.0.1", + "replace-ext": "^2.0.0", + "strip-ansi": "^6.0.1", + "vinyl-sourcemaps-apply": "^0.2.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/gulp-sass-glob": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/gulp-sass-glob/-/gulp-sass-glob-1.1.0.tgz", + "integrity": "sha512-BYDCjb68iMAxLGt2uuw7jaZ51cnWxAbQ4EtFDOOsMXOc0Ul+SFW1iiMOSI/efpO27ycmX9U8Eb4Clerww5Tf5Q==", + "dev": true, + "dependencies": { + "glob": "^7.1.4", + "minimatch": "^3.0.4", + "slash": "^3.0.0", + "through2": "^3.0.1" + } + }, + "node_modules/gulp-sass-glob/node_modules/through2": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", + "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", + "dev": true, + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "2 || 3" + } + }, + "node_modules/gulp-sourcemaps": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-1.12.1.tgz", + "integrity": "sha1-tDfR89mAzyboEYSCNxjOFa5ll7Y=", + "dev": true, + "dependencies": { + "@gulp-sourcemaps/map-sources": "1.X", + "acorn": "4.X", + "convert-source-map": "1.X", + "css": "2.X", + "debug-fabulous": "0.0.X", + "detect-newline": "2.X", + "graceful-fs": "4.X", + "source-map": "~0.6.0", + "strip-bom": "2.X", + "through2": "2.X", + "vinyl": "1.X" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-stylelint": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/gulp-stylelint/-/gulp-stylelint-9.0.0.tgz", + "integrity": "sha512-JoYzy68jc26Z53ZtCJq9teZ81u3QS5DUwoRKHkPbs6k0xpafOVYnRIoOCDGc59vRWTvMDahxyaTlNvolCzr+sA==", + "dev": true, + "dependencies": { + "chalk": "^2.4.2", + "fancy-log": "^1.3.3", + "mkdirp": "^0.5.1", + "plugin-error": "^1.0.1", + "source-map": "^0.7.3", + "strip-ansi": "^5.2.0", + "through2": "^3.0.1" + }, + "engines": { + "node": ">=8.15.1" + }, + "peerDependencies": { + "stylelint": "^10.0.0" + } + }, + "node_modules/gulp-stylelint/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/gulp-stylelint/node_modules/source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/gulp-stylelint/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/gulp-stylelint/node_modules/through2": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", + "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", + "dev": true, + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "2 || 3" + } + }, + "node_modules/gulp-uglify": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gulp-uglify/-/gulp-uglify-3.0.2.tgz", + "integrity": "sha512-gk1dhB74AkV2kzqPMQBLA3jPoIAPd/nlNzP2XMDSG8XZrqnlCiDGAqC+rZOumzFvB5zOphlFh6yr3lgcAb/OOg==", + "dev": true, + "dependencies": { + "array-each": "^1.0.1", + "extend-shallow": "^3.0.2", + "gulplog": "^1.0.0", + "has-gulplog": "^0.1.0", + "isobject": "^3.0.1", + "make-error-cause": "^1.1.1", + "safe-buffer": "^5.1.2", + "through2": "^2.0.0", + "uglify-js": "^3.0.5", + "vinyl-sourcemaps-apply": "^0.2.0" + } + }, + "node_modules/gulp-uglify/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-uglify/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, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-uglify/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, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulplog": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", + "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", + "dev": true, + "dependencies": { + "glogg": "^1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "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, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/has-gulplog": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz", + "integrity": "sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4=", + "dev": true, + "dependencies": { + "sparkles": "^1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "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": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/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 + }, + "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": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "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, + "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 + }, + "node_modules/html-tags": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.1.0.tgz", + "integrity": "sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "dev": true, + "dependencies": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + } + }, + "node_modules/htmlparser2/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/ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/immutable": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0.tgz", + "integrity": "sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw==", + "dev": true + }, + "node_modules/import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "dev": true, + "dependencies": { + "caller-path": "^2.0.0", + "resolve-from": "^3.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": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/import-lazy": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", + "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", + "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/indexes-of": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", + "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", + "dev": true + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "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 + }, + "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 + }, + "node_modules/interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-absolute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "dev": true, + "dependencies": { + "is-relative": "^1.0.0", + "is-windows": "^1.0.1" + }, + "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, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-accessor-descriptor/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-alphabetical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", + "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumeric": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-alphanumeric/-/is-alphanumeric-1.0.0.tgz", + "integrity": "sha1-Spzvcdr0wAHB2B1j0UDPU/1oifQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-alphanumerical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", + "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", + "dev": true, + "dependencies": { + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "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": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "dependencies": { + "binary-extensions": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "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" + } + ], + "engines": { + "node": ">=4" + } + }, + "node_modules/is-core-module": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", + "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", + "dev": true, + "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, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-data-descriptor/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-decimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", + "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "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, + "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-descriptor/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, + "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": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", + "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": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true, + "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": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "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, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hexadecimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", + "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-negated-glob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", + "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number/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 + }, + "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": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "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-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-regexp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-2.1.0.tgz", + "integrity": "sha512-OZ4IlER3zmRIoB9AqNhEggVxqIH4ofDns5nRrPS6yQxXE1TPCUpFznBfRQmQa8uC+pXqjMnukiJBxCisIxiLGA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-relative": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", + "dev": true, + "dependencies": { + "is-unc-path": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-unc-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", + "dev": true, + "dependencies": { + "unc-path-regex": "^0.1.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "node_modules/is-valid-glob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz", + "integrity": "sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-whitespace-character": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz", + "integrity": "sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-word-character": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.4.tgz", + "integrity": "sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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 + }, + "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, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "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-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/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": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/just-debounce": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/just-debounce/-/just-debounce-1.1.0.tgz", + "integrity": "sha512-qpcRocdkUmf+UTNBYx5w6dexX5J31AKK1OmPwH630a83DdVVUIngk55RSAiIGpQyoH0dlr872VHfPjnQnK1qDQ==", + "dev": true + }, + "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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/known-css-properties": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.14.0.tgz", + "integrity": "sha512-P+0a/gBzLgVlCnK8I7VcD0yuYJscmWn66wH9tlKsQnmVdg689tLEmziwB9PuazZYLkcm07fvWOKCJJqI55sD5Q==", + "dev": true + }, + "node_modules/last-run": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/last-run/-/last-run-1.1.1.tgz", + "integrity": "sha1-RblpQsF7HHnHchmCWbqUO+v4yls=", + "dev": true, + "dependencies": { + "default-resolution": "^2.0.0", + "es6-weak-map": "^2.0.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/lazy-debug-legacy": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/lazy-debug-legacy/-/lazy-debug-legacy-0.0.1.tgz", + "integrity": "sha1-U3cWwHduTPeePtG2IfdljCkRsbE=", + "dev": true, + "peerDependencies": { + "debug": "*" + } + }, + "node_modules/lazystream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", + "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", + "dev": true, + "dependencies": { + "readable-stream": "^2.0.5" + }, + "engines": { + "node": ">= 0.6.3" + } + }, + "node_modules/lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "dev": true, + "dependencies": { + "invert-kv": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lead": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz", + "integrity": "sha1-bxT5mje+Op3XhPVJVpDlkDRm7kI=", + "dev": true, + "dependencies": { + "flush-write-stream": "^1.0.2" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/liftoff": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-3.1.0.tgz", + "integrity": "sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog==", + "dev": true, + "dependencies": { + "extend": "^3.0.0", + "findup-sync": "^3.0.0", + "fined": "^1.0.1", + "flagged-respawn": "^1.0.0", + "is-plain-object": "^2.0.4", + "object.map": "^1.0.0", + "rechoir": "^0.6.2", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/liftoff/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, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/load-json-file/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/load-json-file/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "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 + }, + "node_modules/lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", + "dev": true + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, + "node_modules/lodash.template": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", + "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", + "dev": true, + "dependencies": { + "lodash._reinterpolate": "^3.0.0", + "lodash.templatesettings": "^4.0.0" + } + }, + "node_modules/lodash.templatesettings": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", + "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", + "dev": true, + "dependencies": { + "lodash._reinterpolate": "^3.0.0" + } + }, + "node_modules/log-symbols": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", + "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", + "dev": true, + "dependencies": { + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/longest-streak": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz", + "integrity": "sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "dev": true, + "dependencies": { + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/make-error-cause": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/make-error-cause/-/make-error-cause-1.2.2.tgz", + "integrity": "sha1-3wOI/NCzeBbf8KX7gQiTl3fcvJ0=", + "dev": true, + "dependencies": { + "make-error": "^1.2.0" + } + }, + "node_modules/make-iterator": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", + "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/make-iterator/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/map-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", + "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "dependencies": { + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/markdown-escapes": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.4.tgz", + "integrity": "sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/markdown-table": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz", + "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==", + "dev": true + }, + "node_modules/matchdep": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz", + "integrity": "sha1-xvNINKDY28OzfCfui7yyfHd1WC4=", + "dev": true, + "dependencies": { + "findup-sync": "^2.0.0", + "micromatch": "^3.0.4", + "resolve": "^1.4.0", + "stack-trace": "0.0.10" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/matchdep/node_modules/findup-sync": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", + "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", + "dev": true, + "dependencies": { + "detect-file": "^1.0.0", + "is-glob": "^3.1.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/matchdep/node_modules/is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mathml-tag-names": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", + "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdast-util-compact": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mdast-util-compact/-/mdast-util-compact-1.0.4.tgz", + "integrity": "sha512-3YDMQHI5vRiS2uygEFYaqckibpJtKq5Sj2c8JioeOQBU6INpKbdWzfyLqFFnDwEcEnRFIdMsguzs5pC1Jp4Isg==", + "dev": true, + "dependencies": { + "unist-util-visit": "^1.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/meow": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-5.0.0.tgz", + "integrity": "sha512-CbTqYU17ABaLefO8vCU153ZZlprKYWDljcndKKDCFcYQITzWCXZAVk4QMFZPgvzrnUQ3uItnIE/LoUOwrT15Ig==", + "dev": true, + "dependencies": { + "camelcase-keys": "^4.0.0", + "decamelize-keys": "^1.0.0", + "loud-rejection": "^1.0.0", + "minimist-options": "^3.0.1", + "normalize-package-data": "^2.3.4", + "read-pkg-up": "^3.0.0", + "redent": "^2.0.0", + "trim-newlines": "^2.0.0", + "yargs-parser": "^10.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "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, + "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/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "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, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/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, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/micromatch/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "node_modules/minimist-options": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-3.0.2.tgz", + "integrity": "sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ==", + "dev": true, + "dependencies": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "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, + "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, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mixin-deep/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, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/mute-stdout": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-1.0.1.tgz", + "integrity": "sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/nan": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", + "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==", + "dev": true, + "optional": 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, + "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/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "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, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nanomatch/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, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nanomatch/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", + "dev": true + }, + "node_modules/node-releases": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz", + "integrity": "sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==", + "dev": true + }, + "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, + "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-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-selector": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/normalize-selector/-/normalize-selector-0.2.0.tgz", + "integrity": "sha1-0LFF62kRicY6eNIB3E/bEpPvDAM=", + "dev": true + }, + "node_modules/now-and-later": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz", + "integrity": "sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==", + "dev": true, + "dependencies": { + "once": "^1.3.2" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/num2fraction": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", + "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=", + "dev": true + }, + "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": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz", + "integrity": "sha1-ejs9DpgGPUP0wD8uiubNUahog6A=", + "dev": true, + "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": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "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/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/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": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/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 + }, + "node_modules/object-copy/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": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/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, + "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/object-copy/node_modules/is-descriptor/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, + "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": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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, + "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": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "dependencies": { + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.defaults": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", + "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", + "dev": true, + "dependencies": { + "array-each": "^1.0.1", + "array-slice": "^1.0.0", + "for-own": "^1.0.0", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", + "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=", + "dev": true, + "dependencies": { + "for-own": "^1.0.0", + "make-iterator": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.reduce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.reduce/-/object.reduce-1.0.1.tgz", + "integrity": "sha1-b+NI8qx/oPlcpiEiZZkJaCW7A60=", + "dev": true, + "dependencies": { + "for-own": "^1.0.0", + "make-iterator": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/ordered-read-streams": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", + "integrity": "sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4=", + "dev": true, + "dependencies": { + "readable-stream": "^2.0.1" + } + }, + "node_modules/os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "dev": true, + "dependencies": { + "lcid": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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, + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/parse-entities": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.2.2.tgz", + "integrity": "sha512-NzfpbxW/NPrzZ/yYSoQxyqUZMZXIdCfE0OIN4ESsnptHJECoUk3FZktxNuzQf4tjt5UEopnxpYJbvYuxIFDdsg==", + "dev": true, + "dependencies": { + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" + } + }, + "node_modules/parse-filepath": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", + "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", + "dev": true, + "dependencies": { + "is-absolute": "^1.0.0", + "map-cache": "^0.2.0", + "path-root": "^0.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/parse-node-version": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", + "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true + }, + "node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true, + "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": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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 + }, + "node_modules/path-root": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", + "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", + "dev": true, + "dependencies": { + "path-root-regex": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-root-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", + "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-type/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "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 + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "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/pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true, + "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": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "dependencies": { + "pinkie": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/plugin-error": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz", + "integrity": "sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==", + "dev": true, + "dependencies": { + "ansi-colors": "^1.0.1", + "arr-diff": "^4.0.0", + "arr-union": "^3.1.0", + "extend-shallow": "^3.0.2" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/plugin-error/node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/plugin-error/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, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/plugin-error/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, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "dependencies": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/postcss-html": { + "version": "0.36.0", + "resolved": "https://registry.npmjs.org/postcss-html/-/postcss-html-0.36.0.tgz", + "integrity": "sha512-HeiOxGcuwID0AFsNAL0ox3mW6MHH5cstWN1Z3Y+n6H+g12ih7LHdYxWwEA/QmrebctLjo79xz9ouK3MroHwOJw==", + "dev": true, + "dependencies": { + "htmlparser2": "^3.10.0" + }, + "peerDependencies": { + "postcss": ">=5.0.0", + "postcss-syntax": ">=0.36.0" + } + }, + "node_modules/postcss-jsx": { + "version": "0.36.4", + "resolved": "https://registry.npmjs.org/postcss-jsx/-/postcss-jsx-0.36.4.tgz", + "integrity": "sha512-jwO/7qWUvYuWYnpOb0+4bIIgJt7003pgU3P6nETBLaOyBXuTD55ho21xnals5nBrlpTIFodyd3/jBi6UO3dHvA==", + "dev": true, + "dependencies": { + "@babel/core": ">=7.2.2" + }, + "peerDependencies": { + "postcss": ">=5.0.0", + "postcss-syntax": ">=0.36.0" + } + }, + "node_modules/postcss-less": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/postcss-less/-/postcss-less-3.1.4.tgz", + "integrity": "sha512-7TvleQWNM2QLcHqvudt3VYjULVB49uiW6XzEUFmvwHzvsOEF5MwBrIXZDJQvJNFGjJQTzSzZnDoCJ8h/ljyGXA==", + "dev": true, + "dependencies": { + "postcss": "^7.0.14" + }, + "engines": { + "node": ">=6.14.4" + } + }, + "node_modules/postcss-less/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/postcss-less/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-markdown": { + "version": "0.36.0", + "resolved": "https://registry.npmjs.org/postcss-markdown/-/postcss-markdown-0.36.0.tgz", + "integrity": "sha512-rl7fs1r/LNSB2bWRhyZ+lM/0bwKv9fhl38/06gF6mKMo/NPnp55+K1dSTosSVjFZc0e1ppBlu+WT91ba0PMBfQ==", + "dev": true, + "dependencies": { + "remark": "^10.0.1", + "unist-util-find-all-after": "^1.0.2" + }, + "peerDependencies": { + "postcss": ">=5.0.0", + "postcss-syntax": ">=0.36.0" + } + }, + "node_modules/postcss-media-query-parser": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", + "integrity": "sha1-J7Ocb02U+Bsac7j3Y1HGCeXO8kQ=", + "dev": true + }, + "node_modules/postcss-reporter": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-6.0.1.tgz", + "integrity": "sha512-LpmQjfRWyabc+fRygxZjpRxfhRf9u/fdlKf4VHG4TSPbV2XNsuISzYW1KL+1aQzx53CAppa1bKG4APIB/DOXXw==", + "dev": true, + "dependencies": { + "chalk": "^2.4.1", + "lodash": "^4.17.11", + "log-symbols": "^2.2.0", + "postcss": "^7.0.7" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/postcss-reporter/node_modules/log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dev": true, + "dependencies": { + "chalk": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-reporter/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/postcss-reporter/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-resolve-nested-selector": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz", + "integrity": "sha1-Kcy8fDfe36wwTp//C/FZaz9qDk4=", + "dev": true + }, + "node_modules/postcss-safe-parser": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-4.0.2.tgz", + "integrity": "sha512-Uw6ekxSWNLCPesSv/cmqf2bY/77z11O7jZGPax3ycZMFU/oi2DMH9i89AdHc1tRwFg/arFoEwX0IS3LCUxJh1g==", + "dev": true, + "dependencies": { + "postcss": "^7.0.26" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/postcss-safe-parser/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/postcss-safe-parser/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-sass": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/postcss-sass/-/postcss-sass-0.3.5.tgz", + "integrity": "sha512-B5z2Kob4xBxFjcufFnhQ2HqJQ2y/Zs/ic5EZbCywCkxKd756Q40cIQ/veRDwSrw1BF6+4wUgmpm0sBASqVi65A==", + "dev": true, + "dependencies": { + "gonzales-pe": "^4.2.3", + "postcss": "^7.0.1" + } + }, + "node_modules/postcss-sass/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/postcss-sass/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-scss": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-2.1.1.tgz", + "integrity": "sha512-jQmGnj0hSGLd9RscFw9LyuSVAa5Bl1/KBPqG1NQw9w8ND55nY4ZEsdlVuYJvLPpV+y0nwTV5v/4rHPzZRihQbA==", + "dev": true, + "dependencies": { + "postcss": "^7.0.6" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/postcss-scss/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/postcss-scss/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-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-syntax": { + "version": "0.36.2", + "resolved": "https://registry.npmjs.org/postcss-syntax/-/postcss-syntax-0.36.2.tgz", + "integrity": "sha512-nBRg/i7E3SOHWxF3PpF5WnJM/jQ1YpY9000OaVXlAQj6Zp/kIqJxEDWIZ67tAd7NLuk7zqN4yqe9nc0oNAOs1w==", + "dev": true, + "peerDependencies": { + "postcss": ">=5.0.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/pretty-hrtime": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", + "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "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 + }, + "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, + "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, + "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, + "engines": { + "node": ">=6" + } + }, + "node_modules/quick-lru": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz", + "integrity": "sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "dev": true, + "dependencies": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "dev": true, + "dependencies": { + "find-up": "^2.0.0", + "read-pkg": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "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, + "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/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/rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dev": true, + "dependencies": { + "resolve": "^1.1.6" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/redent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz", + "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=", + "dev": true, + "dependencies": { + "indent-string": "^3.0.0", + "strip-indent": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "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, + "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": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "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, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regex-not/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, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/remark": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/remark/-/remark-10.0.1.tgz", + "integrity": "sha512-E6lMuoLIy2TyiokHprMjcWNJ5UxfGQjaMSMhV+f4idM625UjjK4j798+gPs5mfjzDE6vL0oFKVeZM6gZVSVrzQ==", + "dev": true, + "dependencies": { + "remark-parse": "^6.0.0", + "remark-stringify": "^6.0.0", + "unified": "^7.0.0" + } + }, + "node_modules/remark-parse": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-6.0.3.tgz", + "integrity": "sha512-QbDXWN4HfKTUC0hHa4teU463KclLAnwpn/FBn87j9cKYJWWawbiLgMfP2Q4XwhxxuuuOxHlw+pSN0OKuJwyVvg==", + "dev": true, + "dependencies": { + "collapse-white-space": "^1.0.2", + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-whitespace-character": "^1.0.0", + "is-word-character": "^1.0.0", + "markdown-escapes": "^1.0.0", + "parse-entities": "^1.1.0", + "repeat-string": "^1.5.4", + "state-toggle": "^1.0.0", + "trim": "0.0.1", + "trim-trailing-lines": "^1.0.0", + "unherit": "^1.0.4", + "unist-util-remove-position": "^1.0.0", + "vfile-location": "^2.0.0", + "xtend": "^4.0.1" + } + }, + "node_modules/remark-stringify": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-6.0.4.tgz", + "integrity": "sha512-eRWGdEPMVudijE/psbIDNcnJLRVx3xhfuEsTDGgH4GsFF91dVhw5nhmnBppafJ7+NWINW6C7ZwWbi30ImJzqWg==", + "dev": true, + "dependencies": { + "ccount": "^1.0.0", + "is-alphanumeric": "^1.0.0", + "is-decimal": "^1.0.0", + "is-whitespace-character": "^1.0.0", + "longest-streak": "^2.0.1", + "markdown-escapes": "^1.0.0", + "markdown-table": "^1.1.0", + "mdast-util-compact": "^1.0.0", + "parse-entities": "^1.0.2", + "repeat-string": "^1.5.4", + "state-toggle": "^1.0.0", + "stringify-entities": "^1.0.1", + "unherit": "^1.0.4", + "xtend": "^4.0.1" + } + }, + "node_modules/remove-bom-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz", + "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5", + "is-utf8": "^0.2.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/remove-bom-buffer/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 + }, + "node_modules/remove-bom-stream": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz", + "integrity": "sha1-BfGlk/FuQuH7kOv1nejlaVJflSM=", + "dev": true, + "dependencies": { + "remove-bom-buffer": "^3.0.0", + "safe-buffer": "^5.1.0", + "through2": "^2.0.3" + }, + "engines": { + "node": ">= 0.10" + } + }, + "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": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "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, + "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": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/replace-ext": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-2.0.0.tgz", + "integrity": "sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/replace-homedir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-1.0.0.tgz", + "integrity": "sha1-6H9tUTuSjd6AgmDBK+f+xv9ueYw=", + "dev": true, + "dependencies": { + "homedir-polyfill": "^1.0.1", + "is-absolute": "^1.0.0", + "remove-trailing-separator": "^1.1.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true, + "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": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "dev": true + }, + "node_modules/resolve": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", + "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.8.1", + "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-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "dev": true, + "dependencies": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-options": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz", + "integrity": "sha1-MrueOcBtZzONyTeMDW1gdFZq0TE=", + "dev": true, + "dependencies": { + "value-or-function": "^3.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "deprecated": "https://github.com/lydell/resolve-url#deprecated", + "dev": true + }, + "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, + "engines": { + "node": ">=0.12" + } + }, + "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, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "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/safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "dependencies": { + "ret": "~0.1.10" + } + }, + "node_modules/sass": { + "version": "1.49.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.49.0.tgz", + "integrity": "sha512-TVwVdNDj6p6b4QymJtNtRS2YtLJ/CqZriGg0eIAbAKMlN8Xy6kbv33FsEZSF7FufFFM705SQviHjjThfaQ4VNw==", + "dev": true, + "dependencies": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/sass/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, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/sass/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/sass/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, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/sass/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/" + } + ], + "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/sass/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, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/sass/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/sass/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, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/sass/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, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/sass/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, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/sass/node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/sass/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, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "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/semver-greatest-satisfied-range": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz", + "integrity": "sha1-E+jCZYq5aRywzXEJMkAoDTb3els=", + "dev": true, + "dependencies": { + "sver-compat": "^1.5.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "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, + "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/set-value/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, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/signal-exit": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", + "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/slice-ansi/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": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "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, + "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, + "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": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "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, + "dependencies": { + "kind-of": "^3.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util/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 + }, + "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": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/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": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/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": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/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 + }, + "node_modules/snapdragon/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": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/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": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/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, + "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/snapdragon/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true, + "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==", + "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", + "dev": true, + "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-url": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", + "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", + "deprecated": "See https://github.com/lydell/source-map-url#deprecated", + "dev": true + }, + "node_modules/sparkles": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz", + "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "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, + "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 + }, + "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, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz", + "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==", + "dev": true + }, + "node_modules/specificity": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/specificity/-/specificity-0.4.1.tgz", + "integrity": "sha512-1klA3Gi5PD1Wv9Q0wUoOQN1IWAuPu0D1U03ThXTr0cJ20+/iq2tHSDnK7Kk/0LXJ1ztUB2/1Os0wKmfyNgUQfg==", + "dev": true, + "bin": { + "specificity": "bin/specificity" + } + }, + "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, + "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": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "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, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split-string/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, + "dependencies": { + "isobject": "^3.0.1" + }, + "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": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "node_modules/stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/state-toggle": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.3.tgz", + "integrity": "sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "dependencies": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/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": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/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": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/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 + }, + "node_modules/static-extend/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": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/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": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/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, + "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/stream-exhaust": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz", + "integrity": "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==", + "dev": true + }, + "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 + }, + "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, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/stringify-entities": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-1.3.2.tgz", + "integrity": "sha512-nrBAQClJAPN2p+uGCVJRPIPakKeKWZ9GtBCmormE7pWOSlHat7+x5A8gx85M7HM5Dt0BP3pP5RhVW77WdbJJ3A==", + "dev": true, + "dependencies": { + "character-entities-html4": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-hexadecimal": "^1.0.0" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "dependencies": { + "is-utf8": "^0.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-indent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", + "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/style-search": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz", + "integrity": "sha1-eVjHk+R+MuB9K1yv5cC/jhLneQI=", + "dev": true + }, + "node_modules/stylelint": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-10.1.0.tgz", + "integrity": "sha512-OmlUXrgzEMLQYj1JPTpyZPR9G4bl0StidfHnGJEMpdiQ0JyTq0MPg1xkHk1/xVJ2rTPESyJCDWjG8Kbpoo7Kuw==", + "dev": true, + "dependencies": { + "autoprefixer": "^9.5.1", + "balanced-match": "^1.0.0", + "chalk": "^2.4.2", + "cosmiconfig": "^5.2.0", + "debug": "^4.1.1", + "execall": "^2.0.0", + "file-entry-cache": "^5.0.1", + "get-stdin": "^7.0.0", + "global-modules": "^2.0.0", + "globby": "^9.2.0", + "globjoin": "^0.1.4", + "html-tags": "^3.0.0", + "ignore": "^5.0.6", + "import-lazy": "^4.0.0", + "imurmurhash": "^0.1.4", + "known-css-properties": "^0.14.0", + "leven": "^3.1.0", + "lodash": "^4.17.11", + "log-symbols": "^3.0.0", + "mathml-tag-names": "^2.1.0", + "meow": "^5.0.0", + "micromatch": "^4.0.0", + "normalize-selector": "^0.2.0", + "pify": "^4.0.1", + "postcss": "^7.0.14", + "postcss-html": "^0.36.0", + "postcss-jsx": "^0.36.1", + "postcss-less": "^3.1.4", + "postcss-markdown": "^0.36.0", + "postcss-media-query-parser": "^0.2.3", + "postcss-reporter": "^6.0.1", + "postcss-resolve-nested-selector": "^0.1.1", + "postcss-safe-parser": "^4.0.1", + "postcss-sass": "^0.3.5", + "postcss-scss": "^2.0.0", + "postcss-selector-parser": "^3.1.0", + "postcss-syntax": "^0.36.2", + "postcss-value-parser": "^3.3.1", + "resolve-from": "^5.0.0", + "signal-exit": "^3.0.2", + "slash": "^3.0.0", + "specificity": "^0.4.1", + "string-width": "^4.1.0", + "strip-ansi": "^5.2.0", + "style-search": "^0.1.0", + "sugarss": "^2.0.0", + "svg-tags": "^1.0.0", + "table": "^5.2.3" + }, + "bin": { + "stylelint": "bin/stylelint.js" + }, + "engines": { + "node": ">=8.7.0" + } + }, + "node_modules/stylelint-config-recommended": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-2.2.0.tgz", + "integrity": "sha512-bZ+d4RiNEfmoR74KZtCKmsABdBJr4iXRiCso+6LtMJPw5rd/KnxUWTxht7TbafrTJK1YRjNgnN0iVZaJfc3xJA==", + "dev": true, + "peerDependencies": { + "stylelint": "^8.3.0 || ^9.0.0 || ^10.0.0" + } + }, + "node_modules/stylelint-config-standard": { + "version": "18.3.0", + "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-18.3.0.tgz", + "integrity": "sha512-Tdc/TFeddjjy64LvjPau9SsfVRexmTFqUhnMBrzz07J4p2dVQtmpncRF/o8yZn8ugA3Ut43E6o1GtjX80TFytw==", + "dev": true, + "dependencies": { + "stylelint-config-recommended": "^2.2.0" + }, + "peerDependencies": { + "stylelint": "^8.3.0 || ^9.0.0 || ^10.0.0" + } + }, + "node_modules/stylelint/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/stylelint/node_modules/autoprefixer": { + "version": "9.8.8", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.8.tgz", + "integrity": "sha512-eM9d/swFopRt5gdJ7jrpCwgvEMIayITpojhkkSMRsFHYuH5bkSQ4p/9qTEHtmNudUZh22Tehu7I6CxAW0IXTKA==", + "dev": true, + "dependencies": { + "browserslist": "^4.12.0", + "caniuse-lite": "^1.0.30001109", + "normalize-range": "^0.1.2", + "num2fraction": "^1.2.2", + "picocolors": "^0.2.1", + "postcss": "^7.0.32", + "postcss-value-parser": "^4.1.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + } + }, + "node_modules/stylelint/node_modules/autoprefixer/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/stylelint/node_modules/autoprefixer/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/stylelint/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, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/browserslist": { + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.1.tgz", + "integrity": "sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==", + "dev": true, + "dependencies": { + "caniuse-lite": "^1.0.30001286", + "electron-to-chromium": "^1.4.17", + "escalade": "^3.1.1", + "node-releases": "^2.0.1", + "picocolors": "^1.0.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } + }, + "node_modules/stylelint/node_modules/debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/stylelint/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, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/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/stylelint/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/stylelint/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, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/stylelint/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stylelint/node_modules/micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "dependencies": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/stylelint/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/stylelint/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/stylelint/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/stylelint/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/stylelint/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, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/sugarss": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/sugarss/-/sugarss-2.0.0.tgz", + "integrity": "sha512-WfxjozUk0UVA4jm+U1d736AUpzSrNsQcIbyOkoE364GrtWmIrFdk5lksEupgWMD4VaT/0kVx1dobpiDumSgmJQ==", + "dev": true, + "dependencies": { + "postcss": "^7.0.2" + } + }, + "node_modules/sugarss/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/sugarss/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/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, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "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, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/sver-compat": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/sver-compat/-/sver-compat-1.5.0.tgz", + "integrity": "sha1-PPh9/rTQe0o/FIJ7wYaz/QxkXNg=", + "dev": true, + "dependencies": { + "es6-iterator": "^2.0.1", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/svg-tags": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", + "integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=", + "dev": true + }, + "node_modules/table": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "dev": true, + "dependencies": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/table/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/table/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/table/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": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/table/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/table/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/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/through2-filter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", + "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", + "dev": true, + "dependencies": { + "through2": "~2.0.0", + "xtend": "~4.0.0" + } + }, + "node_modules/time-stamp": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", + "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-absolute-glob": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", + "integrity": "sha1-GGX0PZ50sIItufFFt4z/fQ98hJs=", + "dev": true, + "dependencies": { + "is-absolute": "^1.0.0", + "is-negated-glob": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "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": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-object-path/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 + }, + "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": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "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, + "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": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.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": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "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, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex/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, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-through": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz", + "integrity": "sha1-/JKtq6ByZHvAtn1rA2ZKoZUJOvY=", + "dev": true, + "dependencies": { + "through2": "^2.0.3" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/trim": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", + "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=", + "dev": true + }, + "node_modules/trim-newlines": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz", + "integrity": "sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/trim-trailing-lines": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.4.tgz", + "integrity": "sha512-rjUWSqnfTNrjbB9NQWfPMH/xRK1deHeGsHoVfpxJ++XeYXE0d6B1En37AHfw3jtfTU7dzMzZL2jjpe8Qb5gLIQ==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/trough": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", + "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "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 + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "node_modules/uglify-js": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.15.0.tgz", + "integrity": "sha512-x+xdeDWq7FiORDvyIJ0q/waWd4PhjBNOm5dQUOq2AKC0IEjxOS66Ha9tctiVDGcRQuh69K7fgU5oRuTK4cysSg==", + "dev": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/undertaker": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.3.0.tgz", + "integrity": "sha512-/RXwi5m/Mu3H6IHQGww3GNt1PNXlbeCuclF2QYR14L/2CHPz3DFZkvB5hZ0N/QUkiXWCACML2jXViIQEQc2MLg==", + "dev": true, + "dependencies": { + "arr-flatten": "^1.0.1", + "arr-map": "^2.0.0", + "bach": "^1.0.0", + "collection-map": "^1.0.0", + "es6-weak-map": "^2.0.1", + "fast-levenshtein": "^1.0.0", + "last-run": "^1.1.0", + "object.defaults": "^1.0.0", + "object.reduce": "^1.0.0", + "undertaker-registry": "^1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/undertaker-registry": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-1.0.1.tgz", + "integrity": "sha1-XkvaMI5KiirlhPm5pDWaSZglzFA=", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/unherit": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.3.tgz", + "integrity": "sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ==", + "dev": true, + "dependencies": { + "inherits": "^2.0.0", + "xtend": "^4.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/unified": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-7.1.0.tgz", + "integrity": "sha512-lbk82UOIGuCEsZhPj8rNAkXSDXd6p0QLzIuSsCdxrqnqU56St4eyOB+AlXsVgVeRmetPTYydIuvFfpDIed8mqw==", + "dev": true, + "dependencies": { + "@types/unist": "^2.0.0", + "@types/vfile": "^3.0.0", + "bail": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^1.1.0", + "trough": "^1.0.0", + "vfile": "^3.0.0", + "x-is-string": "^0.1.0" + } + }, + "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, + "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": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", + "dev": true + }, + "node_modules/unique-stream": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz", + "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==", + "dev": true, + "dependencies": { + "json-stable-stringify-without-jsonify": "^1.0.1", + "through2-filter": "^3.0.0" + } + }, + "node_modules/unist-util-find-all-after": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/unist-util-find-all-after/-/unist-util-find-all-after-1.0.5.tgz", + "integrity": "sha512-lWgIc3rrTMTlK1Y0hEuL+k+ApzFk78h+lsaa2gHf63Gp5Ww+mt11huDniuaoq1H+XMK2lIIjjPkncxXcDp3QDw==", + "dev": true, + "dependencies": { + "unist-util-is": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-is": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-3.0.0.tgz", + "integrity": "sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==", + "dev": true + }, + "node_modules/unist-util-remove-position": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-1.1.4.tgz", + "integrity": "sha512-tLqd653ArxJIPnKII6LMZwH+mb5q+n/GtXQZo6S6csPRs5zB0u79Yw8ouR3wTw8wxvdJFhpP6Y7jorWdCgLO0A==", + "dev": true, + "dependencies": { + "unist-util-visit": "^1.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-1.1.2.tgz", + "integrity": "sha512-pNCVrk64LZv1kElr0N1wPiHEUoXNVFERp+mlTg/s9R5Lwg87f9bM/3sQB99w+N9D/qnM9ar3+AKDBwo/gm/iQQ==", + "dev": true + }, + "node_modules/unist-util-visit": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz", + "integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==", + "dev": true, + "dependencies": { + "unist-util-visit-parents": "^2.0.0" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz", + "integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==", + "dev": true, + "dependencies": { + "unist-util-is": "^3.0.0" + } + }, + "node_modules/unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "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": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "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": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "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": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true, + "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, + "engines": { + "node": ">=4", + "yarn": "*" + } + }, + "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, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "deprecated": "Please see https://github.com/lydell/urix#deprecated", + "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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "node_modules/v8flags": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", + "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==", + "dev": true, + "dependencies": { + "homedir-polyfill": "^1.0.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "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, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/value-or-function": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz", + "integrity": "sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM=", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/vfile": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-3.0.1.tgz", + "integrity": "sha512-y7Y3gH9BsUSdD4KzHsuMaCzRjglXN0W2EcMf0gpvu6+SbsGhMje7xDc8AEoeXy6mIwCKMI6BkjMsRjzQbhMEjQ==", + "dev": true, + "dependencies": { + "is-buffer": "^2.0.0", + "replace-ext": "1.0.0", + "unist-util-stringify-position": "^1.0.0", + "vfile-message": "^1.0.0" + } + }, + "node_modules/vfile-location": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.6.tgz", + "integrity": "sha512-sSFdyCP3G6Ka0CEmN83A2YCMKIieHx0EDaj5IDP4g1pa5ZJ4FJDvpO0WODLxo4LUX4oe52gmSCK7Jw4SBghqxA==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.0.tgz", + "integrity": "sha512-4QJbBk+DkPEhBXq3f260xSaWtjE4gPKOfulzfMFF8ZNwaPZieWsg3iVlcmF04+eebzpcpeXOOFMfrYzJHVYg+g==", + "dev": true, + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message/node_modules/unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "dev": true, + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile/node_modules/replace-ext": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", + "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/vfile/node_modules/vfile-message": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-1.1.1.tgz", + "integrity": "sha512-1WmsopSGhWt5laNir+633LszXvZ+Z/lxveBf6yhGsqnQIhlhzooZae7zV6YVM1Sdkw68dtAW3ow0pOdPANugvA==", + "dev": true, + "dependencies": { + "unist-util-stringify-position": "^1.1.1" + } + }, + "node_modules/vinyl": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", + "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", + "dev": true, + "dependencies": { + "clone": "^1.0.0", + "clone-stats": "^0.0.1", + "replace-ext": "0.0.1" + }, + "engines": { + "node": ">= 0.9" + } + }, + "node_modules/vinyl-fs": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz", + "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==", + "dev": true, + "dependencies": { + "fs-mkdirp-stream": "^1.0.0", + "glob-stream": "^6.1.0", + "graceful-fs": "^4.0.0", + "is-valid-glob": "^1.0.0", + "lazystream": "^1.0.0", + "lead": "^1.0.0", + "object.assign": "^4.0.4", + "pumpify": "^1.3.5", + "readable-stream": "^2.3.3", + "remove-bom-buffer": "^3.0.0", + "remove-bom-stream": "^1.2.0", + "resolve-options": "^1.1.0", + "through2": "^2.0.0", + "to-through": "^2.0.0", + "value-or-function": "^3.0.0", + "vinyl": "^2.0.0", + "vinyl-sourcemap": "^1.1.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/vinyl-fs/node_modules/clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/vinyl-fs/node_modules/clone-stats": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", + "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", + "dev": true + }, + "node_modules/vinyl-fs/node_modules/replace-ext": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz", + "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/vinyl-fs/node_modules/vinyl": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz", + "integrity": "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==", + "dev": true, + "dependencies": { + "clone": "^2.1.1", + "clone-buffer": "^1.0.0", + "clone-stats": "^1.0.0", + "cloneable-readable": "^1.0.0", + "remove-trailing-separator": "^1.0.1", + "replace-ext": "^1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/vinyl-sourcemap": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz", + "integrity": "sha1-kqgAWTo4cDqM2xHYswCtS+Y7PhY=", + "dev": true, + "dependencies": { + "append-buffer": "^1.0.2", + "convert-source-map": "^1.5.0", + "graceful-fs": "^4.1.6", + "normalize-path": "^2.1.1", + "now-and-later": "^2.0.0", + "remove-bom-buffer": "^3.0.0", + "vinyl": "^2.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/vinyl-sourcemap/node_modules/clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/vinyl-sourcemap/node_modules/clone-stats": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", + "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", + "dev": true + }, + "node_modules/vinyl-sourcemap/node_modules/normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "dependencies": { + "remove-trailing-separator": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/vinyl-sourcemap/node_modules/replace-ext": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz", + "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/vinyl-sourcemap/node_modules/vinyl": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz", + "integrity": "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==", + "dev": true, + "dependencies": { + "clone": "^2.1.1", + "clone-buffer": "^1.0.0", + "clone-stats": "^1.0.0", + "cloneable-readable": "^1.0.0", + "remove-trailing-separator": "^1.0.1", + "replace-ext": "^1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/vinyl-sourcemaps-apply": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz", + "integrity": "sha1-q2VJ1h0XLCsbh75cUI0jnI74dwU=", + "dev": true, + "dependencies": { + "source-map": "^0.5.1" + } + }, + "node_modules/vinyl-sourcemaps-apply/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/vinyl/node_modules/replace-ext": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", + "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/which-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", + "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "dependencies": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true, + "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": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "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": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "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/wrap-ansi/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "dependencies": { + "ansi-regex": "^2.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": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "node_modules/write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "dev": true, + "dependencies": { + "mkdirp": "^0.5.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/x-is-string": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/x-is-string/-/x-is-string-0.1.0.tgz", + "integrity": "sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI=", + "dev": true + }, + "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, + "engines": { + "node": ">=0.4" + } + }, + "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": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.2.tgz", + "integrity": "sha512-ZEjj/dQYQy0Zx0lgLMLR8QuaqTihnxirir7EwUHp1Axq4e3+k8jXU5K0VLbNvedv1f4EWtBonDIZm0NUr+jCcA==", + "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": "^5.0.1" + } + }, + "node_modules/yargs-parser": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", + "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", + "dev": true, + "dependencies": { + "camelcase": "^4.1.0" + } + }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yargs/node_modules/camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yargs/node_modules/find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "dependencies": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yargs/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": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": true, + "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/yargs/node_modules/parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "dependencies": { + "error-ex": "^1.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yargs/node_modules/path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "dependencies": { + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yargs/node_modules/path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yargs/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yargs/node_modules/read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true, + "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/yargs/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": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true, + "dependencies": { + "find-up": "^1.0.0", + "read-pkg": "^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": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "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/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yargs/node_modules/yargs-parser": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.1.tgz", + "integrity": "sha512-wpav5XYiddjXxirPoCTUPbqM0PXvJ9hiBMvuJgInvo4/lAOTZzUprArw17q2O1P2+GHhbBr18/iQwjL5Z9BqfA==", + "dev": true, + "dependencies": { + "camelcase": "^3.0.0", + "object.assign": "^4.1.0" + } + } + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", + "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.16.7" + } + }, + "@babel/compat-data": { + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.16.8.tgz", + "integrity": "sha512-m7OkX0IdKLKPpBlJtF561YJal5y/jyI5fNfWbPxh2D/nbzzGI4qRyrD8xO2jB24u7l+5I2a43scCG2IrfjC50Q==", + "dev": true + }, + "@babel/core": { + "version": "7.16.12", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.16.12.tgz", + "integrity": "sha512-dK5PtG1uiN2ikk++5OzSYsitZKny4wOCD0nrO4TqnW4BVBTQ2NGS3NgilvT/TEyxTST7LNyWV/T4tXDoD3fOgg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.16.8", + "@babel/helper-compilation-targets": "^7.16.7", + "@babel/helper-module-transforms": "^7.16.7", + "@babel/helpers": "^7.16.7", + "@babel/parser": "^7.16.12", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.10", + "@babel/types": "^7.16.8", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0", + "source-map": "^0.5.0" + }, + "dependencies": { + "debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "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 + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "@babel/generator": { + "version": "7.16.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.16.8.tgz", + "integrity": "sha512-1ojZwE9+lOXzcWdWmO6TbUzDfqLD39CmEhN8+2cX9XkDo5yW1OpgfejfliysR2AWLpMamTiOiAp/mtroaymhpw==", + "dev": true, + "requires": { + "@babel/types": "^7.16.8", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "@babel/helper-compilation-targets": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz", + "integrity": "sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.16.4", + "@babel/helper-validator-option": "^7.16.7", + "browserslist": "^4.17.5", + "semver": "^6.3.0" + }, + "dependencies": { + "browserslist": { + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.1.tgz", + "integrity": "sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001286", + "electron-to-chromium": "^1.4.17", + "escalade": "^3.1.1", + "node-releases": "^2.0.1", + "picocolors": "^1.0.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "@babel/helper-environment-visitor": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz", + "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-function-name": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz", + "integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz", + "integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", + "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-module-imports": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", + "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-module-transforms": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz", + "integrity": "sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng==", + "dev": true, + "requires": { + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-module-imports": "^7.16.7", + "@babel/helper-simple-access": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/helper-validator-identifier": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.7", + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-simple-access": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz", + "integrity": "sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", + "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", + "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "dev": true + }, + "@babel/helper-validator-option": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", + "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", + "dev": true + }, + "@babel/helpers": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.16.7.tgz", + "integrity": "sha512-9ZDoqtfY7AuEOt3cxchfii6C7GDyyMBffktR5B2jvWv8u2+efwvpnVKXMWzNehqy68tKgAfSwfdw/lWpthS2bw==", + "dev": true, + "requires": { + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.16.7", + "@babel/types": "^7.16.7" + } + }, + "@babel/highlight": { + "version": "7.16.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", + "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.16.12", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.12.tgz", + "integrity": "sha512-VfaV15po8RiZssrkPweyvbGVSe4x2y+aciFCgn0n0/SJMR22cwofRV1mtnJQYcSB1wUTaA/X1LnA3es66MCO5A==", + "dev": true + }, + "@babel/template": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", + "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.7", + "@babel/parser": "^7.16.7", + "@babel/types": "^7.16.7" + } + }, + "@babel/traverse": { + "version": "7.16.10", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.10.tgz", + "integrity": "sha512-yzuaYXoRJBGMlBhsMJoUW7G1UmSb/eXr/JHYM/MsOJgavJibLwASijW7oXBdw3NQ6T0bW7Ty5P/VarOs9cHmqw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.16.8", + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-hoist-variables": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/parser": "^7.16.10", + "@babel/types": "^7.16.8", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "dependencies": { + "debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "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.16.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.8.tgz", + "integrity": "sha512-smN2DQc5s4M7fntyjGtyIPbRJv6wW4rU/94fmYJ7PKQuZkC0qGMHXJbg6sNGt12JmVr4k5YaptI/XtiLJBnmIg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.0" + } + }, + "@gulp-sourcemaps/map-sources": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/map-sources/-/map-sources-1.0.0.tgz", + "integrity": "sha1-iQrnxdjId/bThIYCFazp1+yUW9o=", + "dev": true, + "requires": { + "normalize-path": "^2.0.1", + "through2": "^2.0.3" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "@mrmlnc/readdir-enhanced": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", + "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", + "dev": true, + "requires": { + "call-me-maybe": "^1.0.1", + "glob-to-regexp": "^0.3.0" + } + }, + "@nodelib/fs.stat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", + "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", + "dev": true + }, + "@types/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/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", + "dev": true + }, + "@types/node": { + "version": "17.0.12", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.12.tgz", + "integrity": "sha512-4YpbAsnJXWYK/fpTVFlMIcUIho2AYCi4wg5aNPrG1ng7fn/1/RZfCIpRCiBX+12RVa34RluilnvCqD+g3KiSiA==", + "dev": true + }, + "@types/unist": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", + "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==", + "dev": true + }, + "@types/vfile": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/vfile/-/vfile-3.0.2.tgz", + "integrity": "sha512-b3nLFGaGkJ9rzOcuXRfHkZMdjsawuDD0ENL9fzTophtBg8FJHSGbH7daXkEpcwy3v7Xol3pAvsmlYyFhR4pqJw==", + "dev": true, + "requires": { + "@types/node": "*", + "@types/unist": "*", + "@types/vfile-message": "*" + } + }, + "@types/vfile-message": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/vfile-message/-/vfile-message-2.0.0.tgz", + "integrity": "sha512-GpTIuDpb9u4zIO165fUy9+fXcULdD8HFRNli04GehoMVbeNq7D6OBnqSmg3lxZnC+UvgUhEWKxdKiwYUkGltIw==", + "dev": true, + "requires": { + "vfile-message": "*" + } + }, + "acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", + "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" + } + }, + "ansi-colors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", + "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", + "dev": true, + "requires": { + "ansi-wrap": "^0.1.0" + } + }, + "ansi-cyan": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-cyan/-/ansi-cyan-0.1.1.tgz", + "integrity": "sha1-U4rlKK+JgvKK4w2G8vF0VtJgmHM=", + "dev": true, + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-gray": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", + "integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=", + "dev": true, + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-red": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-red/-/ansi-red-0.1.1.tgz", + "integrity": "sha1-jGOPnRCAgAo1PJwoyKgcpHBdlGw=", + "dev": true, + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "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" + } + }, + "ansi-wrap": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", + "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=", + "dev": true + }, + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "append-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz", + "integrity": "sha1-2CIM9GYIFSXv6lBhTz3mUU36WPE=", + "dev": true, + "requires": { + "buffer-equal": "^1.0.0" + } + }, + "archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", + "dev": true + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-filter": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/arr-filter/-/arr-filter-1.1.2.tgz", + "integrity": "sha1-Q/3d0JHo7xGqTEXZzcGOLf8XEe4=", + "dev": true, + "requires": { + "make-iterator": "^1.0.0" + } + }, + "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-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/arr-map/-/arr-map-2.0.2.tgz", + "integrity": "sha1-Onc0X/wc814qkYJWAfnljy4kysQ=", + "dev": true, + "requires": { + "make-iterator": "^1.0.0" + } + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", + "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=", + "dev": true + }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true + }, + "array-initial": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/array-initial/-/array-initial-1.1.0.tgz", + "integrity": "sha1-L6dLJnOTccOUe9enrcc74zSz15U=", + "dev": true, + "requires": { + "array-slice": "^1.0.0", + "is-number": "^4.0.0" + }, + "dependencies": { + "is-number": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", + "dev": true + } + } + }, + "array-last": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/array-last/-/array-last-1.3.0.tgz", + "integrity": "sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg==", + "dev": true, + "requires": { + "is-number": "^4.0.0" + }, + "dependencies": { + "is-number": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", + "dev": true + } + } + }, + "array-slice": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", + "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", + "dev": true + }, + "array-sort": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-sort/-/array-sort-1.0.0.tgz", + "integrity": "sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg==", + "dev": true, + "requires": { + "default-compare": "^1.0.0", + "get-value": "^2.0.6", + "kind-of": "^5.0.2" + } + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "^1.0.1" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true + }, + "async-done": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/async-done/-/async-done-1.3.2.tgz", + "integrity": "sha512-uYkTP8dw2og1tu1nmza1n1CMW0qb8gWWlwqMmLb7MhBVs4BXrFziT6HXUd+/RlRA/i4H9AkofYloUbs1fwMqlw==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.2", + "process-nextick-args": "^2.0.0", + "stream-exhaust": "^1.0.1" + } + }, + "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-settle": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-1.0.0.tgz", + "integrity": "sha1-HQqRS7Aldb7IqPOnTlCA9yssDGs=", + "dev": true, + "requires": { + "async-done": "^1.2.2" + } + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "autoprefixer": { + "version": "8.6.5", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-8.6.5.tgz", + "integrity": "sha512-PLWJN3Xo/rycNkx+mp8iBDMTm3FeWe4VmYaZDSqL5QQB9sLsQkG5k8n+LNDFnhh9kdq2K+egL/icpctOmDHwig==", + "dev": true, + "requires": { + "browserslist": "^3.2.8", + "caniuse-lite": "^1.0.30000864", + "normalize-range": "^0.1.2", + "num2fraction": "^1.2.2", + "postcss": "^6.0.23", + "postcss-value-parser": "^3.2.3" + } + }, + "bach": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz", + "integrity": "sha1-Szzpa/JxNPeaG0FKUcFONMO9mIA=", + "dev": true, + "requires": { + "arr-filter": "^1.1.1", + "arr-flatten": "^1.0.1", + "arr-map": "^2.0.0", + "array-each": "^1.0.0", + "array-initial": "^1.0.0", + "array-last": "^1.1.1", + "async-done": "^1.2.2", + "async-settle": "^1.0.0", + "now-and-later": "^2.0.0" + } + }, + "bail": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", + "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==", + "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": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.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 + }, + "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" + } + }, + "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" + } + }, + "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" + } + }, + "buffer-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz", + "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=", + "dev": true + }, + "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 + }, + "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" + } + }, + "call-me-maybe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", + "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=", + "dev": true + }, + "caller-callsite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", + "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", + "dev": true, + "requires": { + "callsites": "^2.0.0" + } + }, + "caller-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", + "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", + "dev": true, + "requires": { + "caller-callsite": "^2.0.0" + } + }, + "callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", + "dev": true + }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "camelcase-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz", + "integrity": "sha1-oqpfsa9oh1glnDLBQUJteJI7m3c=", + "dev": true, + "requires": { + "camelcase": "^4.1.0", + "map-obj": "^2.0.0", + "quick-lru": "^1.0.0" + } + }, + "caniuse-lite": { + "version": "1.0.30001303", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001303.tgz", + "integrity": "sha512-/Mqc1oESndUNszJP0kx0UaQU9kEv9nNtJ7Kn8AdA0mNnH8eR1cj0kG+NbNuC1Wq/b21eA8prhKRA3bbkjONegQ==", + "dev": true + }, + "ccount": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.1.0.tgz", + "integrity": "sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg==", + "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" + } + }, + "character-entities": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", + "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", + "dev": true + }, + "character-entities-html4": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-1.1.4.tgz", + "integrity": "sha512-HRcDxZuZqMx3/a+qrzxdBKBPUpxWEq9xw2OPZ3a/174ihfrQKVsFhqtthBInFy1zZ9GgZyFXOatNujm8M+El3g==", + "dev": true + }, + "character-entities-legacy": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", + "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==", + "dev": true + }, + "character-reference-invalid": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", + "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", + "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" + } + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-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-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-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" + } + } + } + }, + "clean-css": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz", + "integrity": "sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g==", + "dev": true, + "requires": { + "source-map": "~0.6.0" + } + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "dev": true + }, + "clone-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", + "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=", + "dev": true + }, + "clone-regexp": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clone-regexp/-/clone-regexp-2.2.0.tgz", + "integrity": "sha512-beMpP7BOtTipFuW8hrJvREQ2DrRu3BE7by0ZpibtfBA+qfHYvMGTc2Yb1JMYPKg/JUw0CHYvpg796aNTSW9z7Q==", + "dev": true, + "requires": { + "is-regexp": "^2.0.0" + } + }, + "clone-stats": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", + "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=", + "dev": true + }, + "cloneable-readable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.3.tgz", + "integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "process-nextick-args": "^2.0.0", + "readable-stream": "^2.3.5" + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, + "collapse-white-space": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz", + "integrity": "sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ==", + "dev": true + }, + "collection-map": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-map/-/collection-map-1.0.0.tgz", + "integrity": "sha1-rqDwb40mx4DCt1SUOFVEsiVa8Yw=", + "dev": true, + "requires": { + "arr-map": "^2.0.2", + "for-own": "^1.0.0", + "make-iterator": "^1.0.0" + } + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "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 + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "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" + } + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, + "copy-props": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-2.0.5.tgz", + "integrity": "sha512-XBlx8HSqrT0ObQwmSzM7WE5k8FxTV75h1DX1Z3n6NhQ/UYYAvInWYmG06vFt7hQZArE2fuO62aihiWIVQwh1sw==", + "dev": true, + "requires": { + "each-props": "^1.3.2", + "is-plain-object": "^5.0.0" + } + }, + "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" + } + }, + "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" + } + }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "dev": true, + "requires": { + "array-find-index": "^1.0.1" + } + }, + "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" + } + }, + "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" + } + }, + "debug-fabulous": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/debug-fabulous/-/debug-fabulous-0.0.4.tgz", + "integrity": "sha1-+gccXYdIRoVCSAdCHKSxawsaB2M=", + "dev": true, + "requires": { + "debug": "2.X", + "lazy-debug-legacy": "0.0.X", + "object-assign": "4.1.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decamelize-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", + "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", + "dev": true, + "requires": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "dependencies": { + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true + } + } + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, + "default-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/default-compare/-/default-compare-1.0.0.tgz", + "integrity": "sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ==", + "dev": true, + "requires": { + "kind-of": "^5.0.2" + } + }, + "default-resolution": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/default-resolution/-/default-resolution-2.0.0.tgz", + "integrity": "sha1-vLgrqnKtebQmp2cy8aga1t8m1oQ=", + "dev": true + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + } + }, + "detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", + "dev": true + }, + "detect-newline": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", + "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=", + "dev": true + }, + "dir-glob": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", + "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", + "dev": true, + "requires": { + "path-type": "^3.0.0" + } + }, + "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" + }, + "dependencies": { + "domelementtype": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", + "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", + "dev": true + }, + "entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true + } + } + }, + "domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "dev": true + }, + "domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "dev": true, + "requires": { + "domelementtype": "1" + } + }, + "domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "dev": true, + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "dot-prop": { + "version": "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" + } + }, + "each-props": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/each-props/-/each-props-1.3.2.tgz", + "integrity": "sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.1", + "object.defaults": "^1.1.0" + }, + "dependencies": { + "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" + } + } + } + }, + "electron-to-chromium": { + "version": "1.4.54", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.54.tgz", + "integrity": "sha512-jRAoneRdSxnpRHO0ANpnEUtQHXxlgfVjrLOnQSisw1ryjXJXvS0pJaR/v2B7S++/tRjgEDp4Sjn5nmgb6uTySw==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "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" + } + }, + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "dev": true + }, + "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" + } + }, + "es5-ext": { + "version": "0.10.53", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", + "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", + "dev": true, + "requires": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.3", + "next-tick": "~1.0.0" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "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" + } + }, + "es6-weak-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", + "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "^0.10.46", + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.1" + } + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "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 + }, + "execall": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/execall/-/execall-2.0.0.tgz", + "integrity": "sha512-0FU2hZ5Hh6iQnarpRtQurM/aAvp3RIbfvgLHrcqJYzhXyV2KFruhuChf9NC6waAhiUR7FFtlugkI4p7f2Fqlow==", + "dev": true, + "requires": { + "clone-regexp": "^2.1.0" + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-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-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-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" + } + } + } + }, + "expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "ext": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.6.0.tgz", + "integrity": "sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg==", + "dev": true, + "requires": { + "type": "^2.5.0" + }, + "dependencies": { + "type": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/type/-/type-2.5.0.tgz", + "integrity": "sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw==", + "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": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + } + } + }, + "fancy-log": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz", + "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==", + "dev": true, + "requires": { + "ansi-gray": "^0.1.1", + "color-support": "^1.1.3", + "parse-node-version": "^1.0.0", + "time-stamp": "^1.0.0" + } + }, + "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-glob": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", + "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", + "dev": true, + "requires": { + "@mrmlnc/readdir-enhanced": "^2.2.1", + "@nodelib/fs.stat": "^1.1.2", + "glob-parent": "^3.1.0", + "is-glob": "^4.0.0", + "merge2": "^1.2.3", + "micromatch": "^3.1.10" + } + }, + "fast-json-stable-stringify": { + "version": "2.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": "1.1.4", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-1.1.4.tgz", + "integrity": "sha1-5qdUzI8V5YmHqpy9J69m/W9OWvk=", + "dev": true + }, + "file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "dev": true, + "requires": { + "flat-cache": "^2.0.1" + } + }, + "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": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "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" + } + }, + "fined": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz", + "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==", + "dev": true, + "requires": { + "expand-tilde": "^2.0.2", + "is-plain-object": "^2.0.3", + "object.defaults": "^1.1.0", + "object.pick": "^1.2.0", + "parse-filepath": "^1.0.1" + }, + "dependencies": { + "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" + } + } + } + }, + "flagged-respawn": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", + "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", + "dev": true + }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "requires": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + } + }, + "flatted": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", + "dev": true + }, + "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" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "for-own": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", + "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", + "dev": true, + "requires": { + "for-in": "^1.0.1" + } + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "fs-mkdirp-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", + "integrity": "sha1-C3gV/DIBxqaeFNuYzgmMFpNSWes=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "through2": "^2.0.3" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "1.2.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" + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "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.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, + "get-stdin": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-7.0.0.tgz", + "integrity": "sha512-zRKcywvrXlXsA0v0i9Io4KDRaAw7+a1ZpjRwl9Wox8PFlVCCHra7E9c4kqXCoCM9nR5tBkaTTZRBoCm60bFqTQ==", + "dev": true + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "glob-stream": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz", + "integrity": "sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ=", + "dev": true, + "requires": { + "extend": "^3.0.0", + "glob": "^7.1.1", + "glob-parent": "^3.1.0", + "is-negated-glob": "^1.0.0", + "ordered-read-streams": "^1.0.0", + "pumpify": "^1.3.5", + "readable-stream": "^2.1.5", + "remove-trailing-separator": "^1.0.1", + "to-absolute-glob": "^2.0.0", + "unique-stream": "^2.0.2" + } + }, + "glob-to-regexp": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", + "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=", + "dev": true + }, + "glob-watcher": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-5.0.5.tgz", + "integrity": "sha512-zOZgGGEHPklZNjZQaZ9f41i7F2YwE+tS5ZHrDhbBCk3stwahn5vQxnFmBJZHoYdusR6R1bLSXeGUy/BhctwKzw==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-done": "^1.2.0", + "chokidar": "^2.0.0", + "is-negated-glob": "^1.0.0", + "just-debounce": "^1.0.0", + "normalize-path": "^3.0.0", + "object.defaults": "^1.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": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "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": "9.2.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz", + "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "array-union": "^1.0.2", + "dir-glob": "^2.2.2", + "fast-glob": "^2.2.6", + "glob": "^7.1.3", + "ignore": "^4.0.3", + "pify": "^4.0.1", + "slash": "^2.0.0" + }, + "dependencies": { + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true + } + } + }, + "globjoin": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", + "integrity": "sha1-L0SUrIkZ43Z8XLtpHp9GMyQoXUM=", + "dev": true + }, + "glogg": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.2.tgz", + "integrity": "sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA==", + "dev": true, + "requires": { + "sparkles": "^1.0.0" + } + }, + "gonzales-pe": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-4.3.0.tgz", + "integrity": "sha512-otgSPpUmdWJ43VXyiNgEYE4luzHCL2pz4wQ0OnDluC6Eg4Ko3Vexy/SrSynglw/eR+OhkzmqFCZa/OFa/RgAOQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "graceful-fs": { + "version": "4.2.9", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", + "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", + "dev": true + }, + "gulp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/gulp/-/gulp-4.0.2.tgz", + "integrity": "sha512-dvEs27SCZt2ibF29xYgmnwwCYZxdxhQ/+LFWlbAW8y7jt68L/65402Lz3+CKy0Ov4rOs+NERmDq7YlZaDqUIfA==", + "dev": true, + "requires": { + "glob-watcher": "^5.0.3", + "gulp-cli": "^2.2.0", + "undertaker": "^1.2.1", + "vinyl-fs": "^3.0.0" + } + }, + "gulp-autoprefixer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/gulp-autoprefixer/-/gulp-autoprefixer-5.0.0.tgz", + "integrity": "sha1-gjfCeKaXdScKHK/n1vEBz81YVUQ=", + "dev": true, + "requires": { + "autoprefixer": "^8.0.0", + "fancy-log": "^1.3.2", + "plugin-error": "^1.0.1", + "postcss": "^6.0.1", + "through2": "^2.0.0", + "vinyl-sourcemaps-apply": "^0.2.0" + } + }, + "gulp-clean-css": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/gulp-clean-css/-/gulp-clean-css-3.10.0.tgz", + "integrity": "sha512-7Isf9Y690o/Q5MVjEylH1H7L8WeZ89woW7DnhD5unTintOdZb67KdOayRgp9trUFo+f9UyJtuatV42e/+kghPg==", + "dev": true, + "requires": { + "clean-css": "4.2.1", + "plugin-error": "1.0.1", + "through2": "2.0.3", + "vinyl-sourcemaps-apply": "0.2.1" + }, + "dependencies": { + "through2": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "dev": true, + "requires": { + "readable-stream": "^2.1.5", + "xtend": "~4.0.1" + } + } + } + }, + "gulp-cli": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-2.3.0.tgz", + "integrity": "sha512-zzGBl5fHo0EKSXsHzjspp3y5CONegCm8ErO5Qh0UzFzk2y4tMvzLWhoDokADbarfZRL2pGpRp7yt6gfJX4ph7A==", + "dev": true, + "requires": { + "ansi-colors": "^1.0.1", + "archy": "^1.0.0", + "array-sort": "^1.0.0", + "color-support": "^1.1.3", + "concat-stream": "^1.6.0", + "copy-props": "^2.0.1", + "fancy-log": "^1.3.2", + "gulplog": "^1.0.0", + "interpret": "^1.4.0", + "isobject": "^3.0.1", + "liftoff": "^3.1.0", + "matchdep": "^2.0.0", + "mute-stdout": "^1.0.0", + "pretty-hrtime": "^1.0.0", + "replace-homedir": "^1.0.0", + "semver-greatest-satisfied-range": "^1.1.0", + "v8flags": "^3.2.0", + "yargs": "^7.1.0" + } + }, + "gulp-exec": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gulp-exec/-/gulp-exec-3.0.2.tgz", + "integrity": "sha512-74sde0n+pQo/Jbe5qsk0sPC4afjnB7VHDUZd4BrRTLt6lsNU451N+kSvCOoSn6q0iqS9ztT1uy8ZE/FRqmXKeQ==", + "dev": true, + "requires": { + "lodash.template": "^4.4.0", + "plugin-error": "^0.1.2", + "through2": "^2.0.3" + }, + "dependencies": { + "arr-diff": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-1.1.0.tgz", + "integrity": "sha1-aHwydYFjWI/vfeezb6vklesaOZo=", + "dev": true, + "requires": { + "arr-flatten": "^1.0.1", + "array-slice": "^0.2.3" + } + }, + "arr-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-2.1.0.tgz", + "integrity": "sha1-IPnqtexw9cfSFbEHexw5Fh0pLH0=", + "dev": true + }, + "array-slice": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz", + "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=", + "dev": true + }, + "extend-shallow": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-1.1.4.tgz", + "integrity": "sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE=", + "dev": true, + "requires": { + "kind-of": "^1.1.0" + } + }, + "kind-of": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz", + "integrity": "sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ=", + "dev": true + }, + "plugin-error": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-0.1.2.tgz", + "integrity": "sha1-O5uzM1zPAPQl4HQ34ZJ2ln2kes4=", + "dev": true, + "requires": { + "ansi-cyan": "^0.1.1", + "ansi-red": "^0.1.1", + "arr-diff": "^1.0.1", + "arr-union": "^2.0.1", + "extend-shallow": "^1.1.2" + } + } + } + }, + "gulp-rename": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/gulp-rename/-/gulp-rename-1.4.0.tgz", + "integrity": "sha512-swzbIGb/arEoFK89tPY58vg3Ok1bw+d35PfUNwWqdo7KM4jkmuGA78JiDNqR+JeZFaeeHnRg9N7aihX3YPmsyg==", + "dev": true + }, + "gulp-sass": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/gulp-sass/-/gulp-sass-5.1.0.tgz", + "integrity": "sha512-7VT0uaF+VZCmkNBglfe1b34bxn/AfcssquLKVDYnCDJ3xNBaW7cUuI3p3BQmoKcoKFrs9jdzUxyb+u+NGfL4OQ==", + "dev": true, + "requires": { + "lodash.clonedeep": "^4.5.0", + "picocolors": "^1.0.0", + "plugin-error": "^1.0.1", + "replace-ext": "^2.0.0", + "strip-ansi": "^6.0.1", + "vinyl-sourcemaps-apply": "^0.2.1" + } + }, + "gulp-sass-glob": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/gulp-sass-glob/-/gulp-sass-glob-1.1.0.tgz", + "integrity": "sha512-BYDCjb68iMAxLGt2uuw7jaZ51cnWxAbQ4EtFDOOsMXOc0Ul+SFW1iiMOSI/efpO27ycmX9U8Eb4Clerww5Tf5Q==", + "dev": true, + "requires": { + "glob": "^7.1.4", + "minimatch": "^3.0.4", + "slash": "^3.0.0", + "through2": "^3.0.1" + }, + "dependencies": { + "through2": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", + "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", + "dev": true, + "requires": { + "inherits": "^2.0.4", + "readable-stream": "2 || 3" + } + } + } + }, + "gulp-sourcemaps": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-1.12.1.tgz", + "integrity": "sha1-tDfR89mAzyboEYSCNxjOFa5ll7Y=", + "dev": true, + "requires": { + "@gulp-sourcemaps/map-sources": "1.X", + "acorn": "4.X", + "convert-source-map": "1.X", + "css": "2.X", + "debug-fabulous": "0.0.X", + "detect-newline": "2.X", + "graceful-fs": "4.X", + "source-map": "~0.6.0", + "strip-bom": "2.X", + "through2": "2.X", + "vinyl": "1.X" + } + }, + "gulp-stylelint": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/gulp-stylelint/-/gulp-stylelint-9.0.0.tgz", + "integrity": "sha512-JoYzy68jc26Z53ZtCJq9teZ81u3QS5DUwoRKHkPbs6k0xpafOVYnRIoOCDGc59vRWTvMDahxyaTlNvolCzr+sA==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "fancy-log": "^1.3.3", + "mkdirp": "^0.5.1", + "plugin-error": "^1.0.1", + "source-map": "^0.7.3", + "strip-ansi": "^5.2.0", + "through2": "^3.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + }, + "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" + } + }, + "through2": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", + "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", + "dev": true, + "requires": { + "inherits": "^2.0.4", + "readable-stream": "2 || 3" + } + } + } + }, + "gulp-uglify": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gulp-uglify/-/gulp-uglify-3.0.2.tgz", + "integrity": "sha512-gk1dhB74AkV2kzqPMQBLA3jPoIAPd/nlNzP2XMDSG8XZrqnlCiDGAqC+rZOumzFvB5zOphlFh6yr3lgcAb/OOg==", + "dev": true, + "requires": { + "array-each": "^1.0.1", + "extend-shallow": "^3.0.2", + "gulplog": "^1.0.0", + "has-gulplog": "^0.1.0", + "isobject": "^3.0.1", + "make-error-cause": "^1.1.1", + "safe-buffer": "^5.1.2", + "through2": "^2.0.0", + "uglify-js": "^3.0.5", + "vinyl-sourcemaps-apply": "^0.2.0" + }, + "dependencies": { + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + } + }, + "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" + } + }, + "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" + } + } + } + }, + "gulplog": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", + "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", + "dev": true, + "requires": { + "glogg": "^1.0.0" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-gulplog": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz", + "integrity": "sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4=", + "dev": true, + "requires": { + "sparkles": "^1.0.0" + } + }, + "has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "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 + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "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 + }, + "html-tags": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.1.0.tgz", + "integrity": "sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg==", + "dev": true + }, + "htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "dev": true, + "requires": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + }, + "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" + } + } + } + }, + "ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true + }, + "immutable": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0.tgz", + "integrity": "sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw==", + "dev": true + }, + "import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "dev": true, + "requires": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + } + } + }, + "import-lazy": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", + "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "indent-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", + "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", + "dev": true + }, + "indexes-of": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", + "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.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 + }, + "interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "dev": true + }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "dev": true + }, + "is-absolute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "dev": true, + "requires": { + "is-relative": "^1.0.0", + "is-windows": "^1.0.1" + } + }, + "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" + }, + "dependencies": { + "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 + } + } + }, + "is-alphabetical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", + "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", + "dev": true + }, + "is-alphanumeric": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-alphanumeric/-/is-alphanumeric-1.0.0.tgz", + "integrity": "sha1-Spzvcdr0wAHB2B1j0UDPU/1oifQ=", + "dev": true + }, + "is-alphanumerical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", + "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", + "dev": true, + "requires": { + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "dev": true + }, + "is-core-module": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", + "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", + "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" + }, + "dependencies": { + "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 + } + } + }, + "is-decimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", + "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", + "dev": true + }, + "is-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" + }, + "dependencies": { + "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 + } + } + }, + "is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", + "dev": true + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-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-hexadecimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", + "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", + "dev": true + }, + "is-negated-glob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", + "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=", + "dev": true + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "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 + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true + }, + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true + }, + "is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true + }, + "is-regexp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-2.1.0.tgz", + "integrity": "sha512-OZ4IlER3zmRIoB9AqNhEggVxqIH4ofDns5nRrPS6yQxXE1TPCUpFznBfRQmQa8uC+pXqjMnukiJBxCisIxiLGA==", + "dev": true + }, + "is-relative": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", + "dev": true, + "requires": { + "is-unc-path": "^1.0.0" + } + }, + "is-unc-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", + "dev": true, + "requires": { + "unc-path-regex": "^0.1.2" + } + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "is-valid-glob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz", + "integrity": "sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao=", + "dev": true + }, + "is-whitespace-character": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz", + "integrity": "sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w==", + "dev": true + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "is-word-character": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.4.tgz", + "integrity": "sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA==", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "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" + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-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": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "just-debounce": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/just-debounce/-/just-debounce-1.1.0.tgz", + "integrity": "sha512-qpcRocdkUmf+UTNBYx5w6dexX5J31AKK1OmPwH630a83DdVVUIngk55RSAiIGpQyoH0dlr872VHfPjnQnK1qDQ==", + "dev": true + }, + "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 + }, + "known-css-properties": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.14.0.tgz", + "integrity": "sha512-P+0a/gBzLgVlCnK8I7VcD0yuYJscmWn66wH9tlKsQnmVdg689tLEmziwB9PuazZYLkcm07fvWOKCJJqI55sD5Q==", + "dev": true + }, + "last-run": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/last-run/-/last-run-1.1.1.tgz", + "integrity": "sha1-RblpQsF7HHnHchmCWbqUO+v4yls=", + "dev": true, + "requires": { + "default-resolution": "^2.0.0", + "es6-weak-map": "^2.0.1" + } + }, + "lazy-debug-legacy": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/lazy-debug-legacy/-/lazy-debug-legacy-0.0.1.tgz", + "integrity": "sha1-U3cWwHduTPeePtG2IfdljCkRsbE=", + "dev": true, + "requires": {} + }, + "lazystream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", + "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", + "dev": true, + "requires": { + "readable-stream": "^2.0.5" + } + }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "dev": true, + "requires": { + "invert-kv": "^1.0.0" + } + }, + "lead": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz", + "integrity": "sha1-bxT5mje+Op3XhPVJVpDlkDRm7kI=", + "dev": true, + "requires": { + "flush-write-stream": "^1.0.2" + } + }, + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true + }, + "liftoff": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-3.1.0.tgz", + "integrity": "sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog==", + "dev": true, + "requires": { + "extend": "^3.0.0", + "findup-sync": "^3.0.0", + "fined": "^1.0.1", + "flagged-respawn": "^1.0.0", + "is-plain-object": "^2.0.4", + "object.map": "^1.0.0", + "rechoir": "^0.6.2", + "resolve": "^1.1.7" + }, + "dependencies": { + "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" + } + } + } + }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + } + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", + "dev": true + }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, + "lodash.template": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", + "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", + "dev": true, + "requires": { + "lodash._reinterpolate": "^3.0.0", + "lodash.templatesettings": "^4.0.0" + } + }, + "lodash.templatesettings": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", + "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", + "dev": true, + "requires": { + "lodash._reinterpolate": "^3.0.0" + } + }, + "log-symbols": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", + "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", + "dev": true, + "requires": { + "chalk": "^2.4.2" + } + }, + "longest-streak": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz", + "integrity": "sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==", + "dev": true + }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "dev": true, + "requires": { + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" + } + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "make-error-cause": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/make-error-cause/-/make-error-cause-1.2.2.tgz", + "integrity": "sha1-3wOI/NCzeBbf8KX7gQiTl3fcvJ0=", + "dev": true, + "requires": { + "make-error": "^1.2.0" + } + }, + "make-iterator": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", + "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", + "dev": true, + "requires": { + "kind-of": "^6.0.2" + }, + "dependencies": { + "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 + } + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", + "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "markdown-escapes": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.4.tgz", + "integrity": "sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==", + "dev": true + }, + "markdown-table": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz", + "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==", + "dev": true + }, + "matchdep": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz", + "integrity": "sha1-xvNINKDY28OzfCfui7yyfHd1WC4=", + "dev": true, + "requires": { + "findup-sync": "^2.0.0", + "micromatch": "^3.0.4", + "resolve": "^1.4.0", + "stack-trace": "0.0.10" + }, + "dependencies": { + "findup-sync": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", + "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", + "dev": true, + "requires": { + "detect-file": "^1.0.0", + "is-glob": "^3.1.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + } + }, + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "mathml-tag-names": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", + "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==", + "dev": true + }, + "mdast-util-compact": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mdast-util-compact/-/mdast-util-compact-1.0.4.tgz", + "integrity": "sha512-3YDMQHI5vRiS2uygEFYaqckibpJtKq5Sj2c8JioeOQBU6INpKbdWzfyLqFFnDwEcEnRFIdMsguzs5pC1Jp4Isg==", + "dev": true, + "requires": { + "unist-util-visit": "^1.1.0" + } + }, + "meow": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-5.0.0.tgz", + "integrity": "sha512-CbTqYU17ABaLefO8vCU153ZZlprKYWDljcndKKDCFcYQITzWCXZAVk4QMFZPgvzrnUQ3uItnIE/LoUOwrT15Ig==", + "dev": true, + "requires": { + "camelcase-keys": "^4.0.0", + "decamelize-keys": "^1.0.0", + "loud-rejection": "^1.0.0", + "minimist-options": "^3.0.1", + "normalize-package-data": "^2.3.4", + "read-pkg-up": "^3.0.0", + "redent": "^2.0.0", + "trim-newlines": "^2.0.0", + "yargs-parser": "^10.0.0" + } + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "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": { + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + } + }, + "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" + } + }, + "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" + } + }, + "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 + } + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "minimist-options": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-3.0.2.tgz", + "integrity": "sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ==", + "dev": true, + "requires": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0" + } + }, + "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" + } + }, + "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" + } + } + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "mute-stdout": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-1.0.1.tgz", + "integrity": "sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg==", + "dev": true + }, + "nan": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", + "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==", + "dev": true, + "optional": true + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + } + }, + "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" + } + }, + "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" + } + }, + "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 + } + } + }, + "next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", + "dev": true + }, + "node-releases": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz", + "integrity": "sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==", + "dev": true + }, + "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" + } + }, + "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-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", + "dev": true + }, + "normalize-selector": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/normalize-selector/-/normalize-selector-0.2.0.tgz", + "integrity": "sha1-0LFF62kRicY6eNIB3E/bEpPvDAM=", + "dev": true + }, + "now-and-later": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz", + "integrity": "sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==", + "dev": true, + "requires": { + "once": "^1.3.2" + } + }, + "num2fraction": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", + "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=", + "dev": true + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "object-assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz", + "integrity": "sha1-ejs9DpgGPUP0wD8uiubNUahog6A=", + "dev": true + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "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-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-keys": { + "version": "1.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": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "object.defaults": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", + "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", + "dev": true, + "requires": { + "array-each": "^1.0.1", + "array-slice": "^1.0.0", + "for-own": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "object.map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", + "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=", + "dev": true, + "requires": { + "for-own": "^1.0.0", + "make-iterator": "^1.0.0" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "object.reduce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.reduce/-/object.reduce-1.0.1.tgz", + "integrity": "sha1-b+NI8qx/oPlcpiEiZZkJaCW7A60=", + "dev": true, + "requires": { + "for-own": "^1.0.0", + "make-iterator": "^1.0.0" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "ordered-read-streams": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", + "integrity": "sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4=", + "dev": true, + "requires": { + "readable-stream": "^2.0.1" + } + }, + "os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "dev": true, + "requires": { + "lcid": "^1.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "parse-entities": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.2.2.tgz", + "integrity": "sha512-NzfpbxW/NPrzZ/yYSoQxyqUZMZXIdCfE0OIN4ESsnptHJECoUk3FZktxNuzQf4tjt5UEopnxpYJbvYuxIFDdsg==", + "dev": true, + "requires": { + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" + } + }, + "parse-filepath": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", + "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", + "dev": true, + "requires": { + "is-absolute": "^1.0.0", + "map-cache": "^0.2.0", + "path-root": "^0.1.1" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "parse-node-version": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", + "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", + "dev": true + }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "dev": true + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-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-root": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", + "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", + "dev": true, + "requires": { + "path-root-regex": "^0.1.0" + } + }, + "path-root-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", + "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", + "dev": true + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "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 + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "^2.0.0" + } + }, + "plugin-error": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz", + "integrity": "sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==", + "dev": true, + "requires": { + "ansi-colors": "^1.0.1", + "arr-diff": "^4.0.0", + "arr-union": "^3.1.0", + "extend-shallow": "^3.0.2" + }, + "dependencies": { + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + } + }, + "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" + } + }, + "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" + } + } + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "postcss-html": { + "version": "0.36.0", + "resolved": "https://registry.npmjs.org/postcss-html/-/postcss-html-0.36.0.tgz", + "integrity": "sha512-HeiOxGcuwID0AFsNAL0ox3mW6MHH5cstWN1Z3Y+n6H+g12ih7LHdYxWwEA/QmrebctLjo79xz9ouK3MroHwOJw==", + "dev": true, + "requires": { + "htmlparser2": "^3.10.0" + } + }, + "postcss-jsx": { + "version": "0.36.4", + "resolved": "https://registry.npmjs.org/postcss-jsx/-/postcss-jsx-0.36.4.tgz", + "integrity": "sha512-jwO/7qWUvYuWYnpOb0+4bIIgJt7003pgU3P6nETBLaOyBXuTD55ho21xnals5nBrlpTIFodyd3/jBi6UO3dHvA==", + "dev": true, + "requires": { + "@babel/core": ">=7.2.2" + } + }, + "postcss-less": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/postcss-less/-/postcss-less-3.1.4.tgz", + "integrity": "sha512-7TvleQWNM2QLcHqvudt3VYjULVB49uiW6XzEUFmvwHzvsOEF5MwBrIXZDJQvJNFGjJQTzSzZnDoCJ8h/ljyGXA==", + "dev": true, + "requires": { + "postcss": "^7.0.14" + }, + "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": { + "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" + } + } + } + }, + "postcss-markdown": { + "version": "0.36.0", + "resolved": "https://registry.npmjs.org/postcss-markdown/-/postcss-markdown-0.36.0.tgz", + "integrity": "sha512-rl7fs1r/LNSB2bWRhyZ+lM/0bwKv9fhl38/06gF6mKMo/NPnp55+K1dSTosSVjFZc0e1ppBlu+WT91ba0PMBfQ==", + "dev": true, + "requires": { + "remark": "^10.0.1", + "unist-util-find-all-after": "^1.0.2" + } + }, + "postcss-media-query-parser": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", + "integrity": "sha1-J7Ocb02U+Bsac7j3Y1HGCeXO8kQ=", + "dev": true + }, + "postcss-reporter": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-6.0.1.tgz", + "integrity": "sha512-LpmQjfRWyabc+fRygxZjpRxfhRf9u/fdlKf4VHG4TSPbV2XNsuISzYW1KL+1aQzx53CAppa1bKG4APIB/DOXXw==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "lodash": "^4.17.11", + "log-symbols": "^2.2.0", + "postcss": "^7.0.7" + }, + "dependencies": { + "log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dev": true, + "requires": { + "chalk": "^2.0.1" + } + }, + "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": { + "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" + } + } + } + }, + "postcss-resolve-nested-selector": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz", + "integrity": "sha1-Kcy8fDfe36wwTp//C/FZaz9qDk4=", + "dev": true + }, + "postcss-safe-parser": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-4.0.2.tgz", + "integrity": "sha512-Uw6ekxSWNLCPesSv/cmqf2bY/77z11O7jZGPax3ycZMFU/oi2DMH9i89AdHc1tRwFg/arFoEwX0IS3LCUxJh1g==", + "dev": true, + "requires": { + "postcss": "^7.0.26" + }, + "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": { + "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" + } + } + } + }, + "postcss-sass": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/postcss-sass/-/postcss-sass-0.3.5.tgz", + "integrity": "sha512-B5z2Kob4xBxFjcufFnhQ2HqJQ2y/Zs/ic5EZbCywCkxKd756Q40cIQ/veRDwSrw1BF6+4wUgmpm0sBASqVi65A==", + "dev": true, + "requires": { + "gonzales-pe": "^4.2.3", + "postcss": "^7.0.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": { + "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" + } + } + } + }, + "postcss-scss": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-2.1.1.tgz", + "integrity": "sha512-jQmGnj0hSGLd9RscFw9LyuSVAa5Bl1/KBPqG1NQw9w8ND55nY4ZEsdlVuYJvLPpV+y0nwTV5v/4rHPzZRihQbA==", + "dev": true, + "requires": { + "postcss": "^7.0.6" + }, + "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": { + "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" + } + } + } + }, + "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-syntax": { + "version": "0.36.2", + "resolved": "https://registry.npmjs.org/postcss-syntax/-/postcss-syntax-0.36.2.tgz", + "integrity": "sha512-nBRg/i7E3SOHWxF3PpF5WnJM/jQ1YpY9000OaVXlAQj6Zp/kIqJxEDWIZ67tAd7NLuk7zqN4yqe9nc0oNAOs1w==", + "dev": true, + "requires": {} + }, + "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 + }, + "pretty-hrtime": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", + "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=", + "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 + }, + "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 + }, + "quick-lru": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz", + "integrity": "sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g=", + "dev": true + }, + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + } + }, + "read-pkg-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^3.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" + } + }, + "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" + } + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dev": true, + "requires": { + "resolve": "^1.1.6" + } + }, + "redent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz", + "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=", + "dev": true, + "requires": { + "indent-string": "^3.0.0", + "strip-indent": "^2.0.0" + } + }, + "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": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "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" + } + }, + "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" + } + } + } + }, + "remark": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/remark/-/remark-10.0.1.tgz", + "integrity": "sha512-E6lMuoLIy2TyiokHprMjcWNJ5UxfGQjaMSMhV+f4idM625UjjK4j798+gPs5mfjzDE6vL0oFKVeZM6gZVSVrzQ==", + "dev": true, + "requires": { + "remark-parse": "^6.0.0", + "remark-stringify": "^6.0.0", + "unified": "^7.0.0" + } + }, + "remark-parse": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-6.0.3.tgz", + "integrity": "sha512-QbDXWN4HfKTUC0hHa4teU463KclLAnwpn/FBn87j9cKYJWWawbiLgMfP2Q4XwhxxuuuOxHlw+pSN0OKuJwyVvg==", + "dev": true, + "requires": { + "collapse-white-space": "^1.0.2", + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-whitespace-character": "^1.0.0", + "is-word-character": "^1.0.0", + "markdown-escapes": "^1.0.0", + "parse-entities": "^1.1.0", + "repeat-string": "^1.5.4", + "state-toggle": "^1.0.0", + "trim": "0.0.1", + "trim-trailing-lines": "^1.0.0", + "unherit": "^1.0.4", + "unist-util-remove-position": "^1.0.0", + "vfile-location": "^2.0.0", + "xtend": "^4.0.1" + } + }, + "remark-stringify": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-6.0.4.tgz", + "integrity": "sha512-eRWGdEPMVudijE/psbIDNcnJLRVx3xhfuEsTDGgH4GsFF91dVhw5nhmnBppafJ7+NWINW6C7ZwWbi30ImJzqWg==", + "dev": true, + "requires": { + "ccount": "^1.0.0", + "is-alphanumeric": "^1.0.0", + "is-decimal": "^1.0.0", + "is-whitespace-character": "^1.0.0", + "longest-streak": "^2.0.1", + "markdown-escapes": "^1.0.0", + "markdown-table": "^1.1.0", + "mdast-util-compact": "^1.0.0", + "parse-entities": "^1.0.2", + "repeat-string": "^1.5.4", + "state-toggle": "^1.0.0", + "stringify-entities": "^1.0.1", + "unherit": "^1.0.4", + "xtend": "^4.0.1" + } + }, + "remove-bom-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz", + "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==", + "dev": true, + "requires": { + "is-buffer": "^1.1.5", + "is-utf8": "^0.2.1" + }, + "dependencies": { + "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 + } + } + }, + "remove-bom-stream": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz", + "integrity": "sha1-BfGlk/FuQuH7kOv1nejlaVJflSM=", + "dev": true, + "requires": { + "remove-bom-buffer": "^3.0.0", + "safe-buffer": "^5.1.0", + "through2": "^2.0.3" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "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": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "replace-ext": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-2.0.0.tgz", + "integrity": "sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==", + "dev": true + }, + "replace-homedir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-1.0.0.tgz", + "integrity": "sha1-6H9tUTuSjd6AgmDBK+f+xv9ueYw=", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1", + "is-absolute": "^1.0.0", + "remove-trailing-separator": "^1.1.0" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "dev": true + }, + "resolve": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", + "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "dev": true, + "requires": { + "is-core-module": "^2.8.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + } + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + }, + "resolve-options": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz", + "integrity": "sha1-MrueOcBtZzONyTeMDW1gdFZq0TE=", + "dev": true, + "requires": { + "value-or-function": "^3.0.0" + } + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "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 + }, + "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" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "sass": { + "version": "1.49.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.49.0.tgz", + "integrity": "sha512-TVwVdNDj6p6b4QymJtNtRS2YtLJ/CqZriGg0eIAbAKMlN8Xy6kbv33FsEZSF7FufFFM705SQviHjjThfaQ4VNw==", + "dev": true, + "requires": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.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, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "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 + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": 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" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "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 + }, + "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, + "requires": { + "is-glob": "^4.0.1" + } + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + } + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "semver-greatest-satisfied-range": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz", + "integrity": "sha1-E+jCZYq5aRywzXEJMkAoDTb3els=", + "dev": true, + "requires": { + "sver-compat": "^1.5.0" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "set-value": { + "version": "2.0.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" + }, + "dependencies": { + "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" + } + } + } + }, + "signal-exit": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", + "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + } + } + }, + "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": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-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-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-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" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + } + } + }, + "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": { + "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 + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "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-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "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-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 + }, + "sparkles": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz", + "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==", + "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.11", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz", + "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==", + "dev": true + }, + "specificity": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/specificity/-/specificity-0.4.1.tgz", + "integrity": "sha512-1klA3Gi5PD1Wv9Q0wUoOQN1IWAuPu0D1U03ThXTr0cJ20+/iq2tHSDnK7Kk/0LXJ1ztUB2/1Os0wKmfyNgUQfg==", + "dev": true + }, + "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": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "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" + } + }, + "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" + } + } + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=", + "dev": true + }, + "state-toggle": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.3.tgz", + "integrity": "sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ==", + "dev": true + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-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-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-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" + } + } + } + }, + "stream-exhaust": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz", + "integrity": "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==", + "dev": true + }, + "stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", + "dev": true + }, + "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" + } + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "stringify-entities": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-1.3.2.tgz", + "integrity": "sha512-nrBAQClJAPN2p+uGCVJRPIPakKeKWZ9GtBCmormE7pWOSlHat7+x5A8gx85M7HM5Dt0BP3pP5RhVW77WdbJJ3A==", + "dev": true, + "requires": { + "character-entities-html4": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-hexadecimal": "^1.0.0" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "^0.2.0" + } + }, + "strip-indent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", + "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", + "dev": true + }, + "style-search": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz", + "integrity": "sha1-eVjHk+R+MuB9K1yv5cC/jhLneQI=", + "dev": true + }, + "stylelint": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-10.1.0.tgz", + "integrity": "sha512-OmlUXrgzEMLQYj1JPTpyZPR9G4bl0StidfHnGJEMpdiQ0JyTq0MPg1xkHk1/xVJ2rTPESyJCDWjG8Kbpoo7Kuw==", + "dev": true, + "requires": { + "autoprefixer": "^9.5.1", + "balanced-match": "^1.0.0", + "chalk": "^2.4.2", + "cosmiconfig": "^5.2.0", + "debug": "^4.1.1", + "execall": "^2.0.0", + "file-entry-cache": "^5.0.1", + "get-stdin": "^7.0.0", + "global-modules": "^2.0.0", + "globby": "^9.2.0", + "globjoin": "^0.1.4", + "html-tags": "^3.0.0", + "ignore": "^5.0.6", + "import-lazy": "^4.0.0", + "imurmurhash": "^0.1.4", + "known-css-properties": "^0.14.0", + "leven": "^3.1.0", + "lodash": "^4.17.11", + "log-symbols": "^3.0.0", + "mathml-tag-names": "^2.1.0", + "meow": "^5.0.0", + "micromatch": "^4.0.0", + "normalize-selector": "^0.2.0", + "pify": "^4.0.1", + "postcss": "^7.0.14", + "postcss-html": "^0.36.0", + "postcss-jsx": "^0.36.1", + "postcss-less": "^3.1.4", + "postcss-markdown": "^0.36.0", + "postcss-media-query-parser": "^0.2.3", + "postcss-reporter": "^6.0.1", + "postcss-resolve-nested-selector": "^0.1.1", + "postcss-safe-parser": "^4.0.1", + "postcss-sass": "^0.3.5", + "postcss-scss": "^2.0.0", + "postcss-selector-parser": "^3.1.0", + "postcss-syntax": "^0.36.2", + "postcss-value-parser": "^3.3.1", + "resolve-from": "^5.0.0", + "signal-exit": "^3.0.2", + "slash": "^3.0.0", + "specificity": "^0.4.1", + "string-width": "^4.1.0", + "strip-ansi": "^5.2.0", + "style-search": "^0.1.0", + "sugarss": "^2.0.0", + "svg-tags": "^1.0.0", + "table": "^5.2.3" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "autoprefixer": { + "version": "9.8.8", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.8.tgz", + "integrity": "sha512-eM9d/swFopRt5gdJ7jrpCwgvEMIayITpojhkkSMRsFHYuH5bkSQ4p/9qTEHtmNudUZh22Tehu7I6CxAW0IXTKA==", + "dev": true, + "requires": { + "browserslist": "^4.12.0", + "caniuse-lite": "^1.0.30001109", + "normalize-range": "^0.1.2", + "num2fraction": "^1.2.2", + "picocolors": "^0.2.1", + "postcss": "^7.0.32", + "postcss-value-parser": "^4.1.0" + }, + "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-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 + } + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "browserslist": { + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.1.tgz", + "integrity": "sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001286", + "electron-to-chromium": "^1.4.17", + "escalade": "^3.1.1", + "node-releases": "^2.0.1", + "picocolors": "^1.0.0" + } + }, + "debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "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" + } + }, + "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 + }, + "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 + }, + "micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + } + }, + "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 + }, + "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 + } + } + }, + "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" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + } + } + }, + "stylelint-config-recommended": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-2.2.0.tgz", + "integrity": "sha512-bZ+d4RiNEfmoR74KZtCKmsABdBJr4iXRiCso+6LtMJPw5rd/KnxUWTxht7TbafrTJK1YRjNgnN0iVZaJfc3xJA==", + "dev": true, + "requires": {} + }, + "stylelint-config-standard": { + "version": "18.3.0", + "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-18.3.0.tgz", + "integrity": "sha512-Tdc/TFeddjjy64LvjPau9SsfVRexmTFqUhnMBrzz07J4p2dVQtmpncRF/o8yZn8ugA3Ut43E6o1GtjX80TFytw==", + "dev": true, + "requires": { + "stylelint-config-recommended": "^2.2.0" + } + }, + "sugarss": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/sugarss/-/sugarss-2.0.0.tgz", + "integrity": "sha512-WfxjozUk0UVA4jm+U1d736AUpzSrNsQcIbyOkoE364GrtWmIrFdk5lksEupgWMD4VaT/0kVx1dobpiDumSgmJQ==", + "dev": true, + "requires": { + "postcss": "^7.0.2" + }, + "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": { + "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" + } + } + } + }, + "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" + } + }, + "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 + }, + "sver-compat": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/sver-compat/-/sver-compat-1.5.0.tgz", + "integrity": "sha1-PPh9/rTQe0o/FIJ7wYaz/QxkXNg=", + "dev": true, + "requires": { + "es6-iterator": "^2.0.1", + "es6-symbol": "^3.1.1" + } + }, + "svg-tags": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", + "integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=", + "dev": true + }, + "table": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "dev": true, + "requires": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "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" + } + }, + "through2-filter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", + "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", + "dev": true, + "requires": { + "through2": "~2.0.0", + "xtend": "~4.0.0" + } + }, + "time-stamp": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", + "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=", + "dev": true + }, + "to-absolute-glob": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", + "integrity": "sha1-GGX0PZ50sIItufFFt4z/fQ98hJs=", + "dev": true, + "requires": { + "is-absolute": "^1.0.0", + "is-negated-glob": "^1.0.0" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "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 + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + } + }, + "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" + } + }, + "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" + } + } + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + }, + "to-through": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz", + "integrity": "sha1-/JKtq6ByZHvAtn1rA2ZKoZUJOvY=", + "dev": true, + "requires": { + "through2": "^2.0.3" + } + }, + "trim": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", + "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=", + "dev": true + }, + "trim-newlines": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz", + "integrity": "sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA=", + "dev": true + }, + "trim-trailing-lines": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.4.tgz", + "integrity": "sha512-rjUWSqnfTNrjbB9NQWfPMH/xRK1deHeGsHoVfpxJ++XeYXE0d6B1En37AHfw3jtfTU7dzMzZL2jjpe8Qb5gLIQ==", + "dev": true + }, + "trough": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", + "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==", + "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 + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "uglify-js": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.15.0.tgz", + "integrity": "sha512-x+xdeDWq7FiORDvyIJ0q/waWd4PhjBNOm5dQUOq2AKC0IEjxOS66Ha9tctiVDGcRQuh69K7fgU5oRuTK4cysSg==", + "dev": true + }, + "unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", + "dev": true + }, + "undertaker": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.3.0.tgz", + "integrity": "sha512-/RXwi5m/Mu3H6IHQGww3GNt1PNXlbeCuclF2QYR14L/2CHPz3DFZkvB5hZ0N/QUkiXWCACML2jXViIQEQc2MLg==", + "dev": true, + "requires": { + "arr-flatten": "^1.0.1", + "arr-map": "^2.0.0", + "bach": "^1.0.0", + "collection-map": "^1.0.0", + "es6-weak-map": "^2.0.1", + "fast-levenshtein": "^1.0.0", + "last-run": "^1.1.0", + "object.defaults": "^1.0.0", + "object.reduce": "^1.0.0", + "undertaker-registry": "^1.0.0" + } + }, + "undertaker-registry": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-1.0.1.tgz", + "integrity": "sha1-XkvaMI5KiirlhPm5pDWaSZglzFA=", + "dev": true + }, + "unherit": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.3.tgz", + "integrity": "sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ==", + "dev": true, + "requires": { + "inherits": "^2.0.0", + "xtend": "^4.0.0" + } + }, + "unified": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-7.1.0.tgz", + "integrity": "sha512-lbk82UOIGuCEsZhPj8rNAkXSDXd6p0QLzIuSsCdxrqnqU56St4eyOB+AlXsVgVeRmetPTYydIuvFfpDIed8mqw==", + "dev": true, + "requires": { + "@types/unist": "^2.0.0", + "@types/vfile": "^3.0.0", + "bail": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^1.1.0", + "trough": "^1.0.0", + "vfile": "^3.0.0", + "x-is-string": "^0.1.0" + } + }, + "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": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", + "dev": true + }, + "unique-stream": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz", + "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==", + "dev": true, + "requires": { + "json-stable-stringify-without-jsonify": "^1.0.1", + "through2-filter": "^3.0.0" + } + }, + "unist-util-find-all-after": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/unist-util-find-all-after/-/unist-util-find-all-after-1.0.5.tgz", + "integrity": "sha512-lWgIc3rrTMTlK1Y0hEuL+k+ApzFk78h+lsaa2gHf63Gp5Ww+mt11huDniuaoq1H+XMK2lIIjjPkncxXcDp3QDw==", + "dev": true, + "requires": { + "unist-util-is": "^3.0.0" + } + }, + "unist-util-is": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-3.0.0.tgz", + "integrity": "sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==", + "dev": true + }, + "unist-util-remove-position": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-1.1.4.tgz", + "integrity": "sha512-tLqd653ArxJIPnKII6LMZwH+mb5q+n/GtXQZo6S6csPRs5zB0u79Yw8ouR3wTw8wxvdJFhpP6Y7jorWdCgLO0A==", + "dev": true, + "requires": { + "unist-util-visit": "^1.1.0" + } + }, + "unist-util-stringify-position": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-1.1.2.tgz", + "integrity": "sha512-pNCVrk64LZv1kElr0N1wPiHEUoXNVFERp+mlTg/s9R5Lwg87f9bM/3sQB99w+N9D/qnM9ar3+AKDBwo/gm/iQQ==", + "dev": true + }, + "unist-util-visit": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz", + "integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==", + "dev": true, + "requires": { + "unist-util-visit-parents": "^2.0.0" + } + }, + "unist-util-visit-parents": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz", + "integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==", + "dev": true, + "requires": { + "unist-util-is": "^3.0.0" + } + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + } + } + }, + "upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "dev": true + }, + "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": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "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-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "v8flags": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", + "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "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" + } + }, + "value-or-function": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz", + "integrity": "sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM=", + "dev": true + }, + "vfile": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-3.0.1.tgz", + "integrity": "sha512-y7Y3gH9BsUSdD4KzHsuMaCzRjglXN0W2EcMf0gpvu6+SbsGhMje7xDc8AEoeXy6mIwCKMI6BkjMsRjzQbhMEjQ==", + "dev": true, + "requires": { + "is-buffer": "^2.0.0", + "replace-ext": "1.0.0", + "unist-util-stringify-position": "^1.0.0", + "vfile-message": "^1.0.0" + }, + "dependencies": { + "replace-ext": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", + "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", + "dev": true + }, + "vfile-message": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-1.1.1.tgz", + "integrity": "sha512-1WmsopSGhWt5laNir+633LszXvZ+Z/lxveBf6yhGsqnQIhlhzooZae7zV6YVM1Sdkw68dtAW3ow0pOdPANugvA==", + "dev": true, + "requires": { + "unist-util-stringify-position": "^1.1.1" + } + } + } + }, + "vfile-location": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.6.tgz", + "integrity": "sha512-sSFdyCP3G6Ka0CEmN83A2YCMKIieHx0EDaj5IDP4g1pa5ZJ4FJDvpO0WODLxo4LUX4oe52gmSCK7Jw4SBghqxA==", + "dev": true + }, + "vfile-message": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.0.tgz", + "integrity": "sha512-4QJbBk+DkPEhBXq3f260xSaWtjE4gPKOfulzfMFF8ZNwaPZieWsg3iVlcmF04+eebzpcpeXOOFMfrYzJHVYg+g==", + "dev": true, + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "dependencies": { + "unist-util-stringify-position": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz", + "integrity": "sha512-SdfAl8fsDclywZpfMDTVDxA2V7LjtRDTOFd44wUJamgl6OlVngsqWjxvermMYf60elWHbxhuRCZml7AnuXCaSA==", + "dev": true, + "requires": { + "@types/unist": "^2.0.0" + } + } + } + }, + "vinyl": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", + "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", + "dev": true, + "requires": { + "clone": "^1.0.0", + "clone-stats": "^0.0.1", + "replace-ext": "0.0.1" + }, + "dependencies": { + "replace-ext": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", + "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=", + "dev": true + } + } + }, + "vinyl-fs": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz", + "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==", + "dev": true, + "requires": { + "fs-mkdirp-stream": "^1.0.0", + "glob-stream": "^6.1.0", + "graceful-fs": "^4.0.0", + "is-valid-glob": "^1.0.0", + "lazystream": "^1.0.0", + "lead": "^1.0.0", + "object.assign": "^4.0.4", + "pumpify": "^1.3.5", + "readable-stream": "^2.3.3", + "remove-bom-buffer": "^3.0.0", + "remove-bom-stream": "^1.2.0", + "resolve-options": "^1.1.0", + "through2": "^2.0.0", + "to-through": "^2.0.0", + "value-or-function": "^3.0.0", + "vinyl": "^2.0.0", + "vinyl-sourcemap": "^1.1.0" + }, + "dependencies": { + "clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", + "dev": true + }, + "clone-stats": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", + "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", + "dev": true + }, + "replace-ext": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz", + "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==", + "dev": true + }, + "vinyl": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz", + "integrity": "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==", + "dev": true, + "requires": { + "clone": "^2.1.1", + "clone-buffer": "^1.0.0", + "clone-stats": "^1.0.0", + "cloneable-readable": "^1.0.0", + "remove-trailing-separator": "^1.0.1", + "replace-ext": "^1.0.0" + } + } + } + }, + "vinyl-sourcemap": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz", + "integrity": "sha1-kqgAWTo4cDqM2xHYswCtS+Y7PhY=", + "dev": true, + "requires": { + "append-buffer": "^1.0.2", + "convert-source-map": "^1.5.0", + "graceful-fs": "^4.1.6", + "normalize-path": "^2.1.1", + "now-and-later": "^2.0.0", + "remove-bom-buffer": "^3.0.0", + "vinyl": "^2.0.0" + }, + "dependencies": { + "clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", + "dev": true + }, + "clone-stats": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", + "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", + "dev": true + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "replace-ext": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz", + "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==", + "dev": true + }, + "vinyl": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz", + "integrity": "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==", + "dev": true, + "requires": { + "clone": "^2.1.1", + "clone-buffer": "^1.0.0", + "clone-stats": "^1.0.0", + "cloneable-readable": "^1.0.0", + "remove-trailing-separator": "^1.0.1", + "replace-ext": "^1.0.0" + } + } + } + }, + "vinyl-sourcemaps-apply": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz", + "integrity": "sha1-q2VJ1h0XLCsbh75cUI0jnI74dwU=", + "dev": true, + "requires": { + "source-map": "^0.5.1" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "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-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", + "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", + "dev": true + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } + }, + "x-is-string": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/x-is-string/-/x-is-string-0.1.0.tgz", + "integrity": "sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI=", + "dev": true + }, + "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": "3.2.2", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", + "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", + "dev": true + }, + "yargs": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.2.tgz", + "integrity": "sha512-ZEjj/dQYQy0Zx0lgLMLR8QuaqTihnxirir7EwUHp1Axq4e3+k8jXU5K0VLbNvedv1f4EWtBonDIZm0NUr+jCcA==", + "dev": true, + "requires": { + "camelcase": "^3.0.0", + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "os-locale": "^1.4.0", + "read-pkg-up": "^1.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^1.0.2", + "which-module": "^1.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^5.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", + "dev": true + }, + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "^2.0.0" + } + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true, + "requires": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true, + "requires": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "yargs-parser": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.1.tgz", + "integrity": "sha512-wpav5XYiddjXxirPoCTUPbqM0PXvJ9hiBMvuJgInvo4/lAOTZzUprArw17q2O1P2+GHhbBr18/iQwjL5Z9BqfA==", + "dev": true, + "requires": { + "camelcase": "^3.0.0", + "object.assign": "^4.1.0" + } + } + } + }, + "yargs-parser": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", + "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", + "dev": true, + "requires": { + "camelcase": "^4.1.0" + } + } + } +} diff --git a/web/themes/custom/perls/package.json b/web/themes/custom/perls/package.json new file mode 100644 index 0000000..9c7a7e8 --- /dev/null +++ b/web/themes/custom/perls/package.json @@ -0,0 +1,27 @@ +{ + "name": "perls", + "version": "1.0.0", + "description": "A custom Drupal 8 theme", + "scripts": { + "build": "npm install && gulp build-theme", + "build-theme": "gulp build-theme", + "gulp": "gulp" + }, + "author": "", + "license": "ISC", + "devDependencies": { + "sass": "^1.49.0", + "gulp": "^4.0.2", + "gulp-autoprefixer": "^5.0.0", + "gulp-clean-css": "^3.0.8", + "gulp-exec": "^3.0.2", + "gulp-rename": "^1.4.0", + "gulp-sass": "^5.1.0", + "gulp-sass-glob": "^1.0.8", + "gulp-sourcemaps": "^1.12.1", + "gulp-stylelint": "^9.0.0", + "gulp-uglify": "^3.0.2", + "stylelint": "^10.1.0", + "stylelint-config-standard": "^18.3.0" + } +} diff --git a/web/themes/custom/perls/perls.info.yml b/web/themes/custom/perls/perls.info.yml new file mode 100644 index 0000000..c4281a2 --- /dev/null +++ b/web/themes/custom/perls/perls.info.yml @@ -0,0 +1,37 @@ +name: PERLS +type: theme +description: This is a perls sub theme of Classy +core: 8.x +core_version_requirement: ^8 || ^9 +# Defines the base theme +base theme: classy +# Defines libraries group in which we can add css/js. +libraries: + - perls/perls-base + - perls/slick + - perls/color + - perls/clamp + - perls/sticky + - perls/select2 +ckeditor_stylesheets: + - 'css/main.min.css' +# Regions +regions: + header: Header + highlighted: Highlighted + content: Content + sidebar_first: First sidebar + sidebar_second: Second sidebar + footer: Footer + inactive: 'Inactive (this region is not printed, blocks here are placed programatically).' + +libraries-override: + formtips/formtips: + js: + js/formtips.js: js/formtips.altered.min.js + annotator/annotations.base: + css: + component: + css/annotator.1.2.10/annotator.min.css: css/annotator/annotator.min.css + css/annotator.touch.css: css/annotator/annotator.touch.min.css + css/style.css: false diff --git a/web/themes/custom/perls/perls.libraries.yml b/web/themes/custom/perls/perls.libraries.yml new file mode 100644 index 0000000..712dba9 --- /dev/null +++ b/web/themes/custom/perls/perls.libraries.yml @@ -0,0 +1,52 @@ +perls-base: + version: 1.x + css: + theme: + css/main.min.css: {} + js: + js/main.min.js: {} + js/forms.min.js: {} + js/stack.min.js: {} + js/clamp.init.min.js: {} + js/live-preview.min.js: {} + js/dialog.min.js: {} + js/sticky.init.min.js: {} + dependencies: + - core/jquery + - core/drupal + - core/jquery.once + - core/sortable + +slick: + version: 1.8.1 + js: + /libraries/slick-carousel/slick/slick.min.js: {} + dependencies: + - core/jquery + - core/jquery.once + +clamp: + version: 0.5.1 + js: + /libraries/clamp-js/clamp.js: {} + +color: + version: 1.x + css: + theme: + dist/css/color.css: {} + +color.preview: + version: 1.0.0 + css: + theme: + color/preview.css: { } + js: + color/preview.js: {} + dependencies: + - color/drupal.color + +sticky: + version: 1.3.0 + js: + /libraries/sticky-js/dist/sticky.min.js: { minified: true } diff --git a/web/themes/custom/perls/perls.theme b/web/themes/custom/perls/perls.theme new file mode 100644 index 0000000..565f357 --- /dev/null +++ b/web/themes/custom/perls/perls.theme @@ -0,0 +1,949 @@ +getPath(); + $requestException = Drupal::requestStack()->getCurrentRequest()->attributes->get('exception'); + + if (isset($requestException) && isset($variables['root_path'])) { + unset($variables['root_path']); + } + else { + $variables['current_path'] = \Drupal::service('path_alias.manager')->getAliasByPath($current_path); + } + // Adds a class for the page name if a page manager page is being viewed. + // Class should stay the same regardless of path since it is a machine name. + $page_variant = \Drupal::routeMatch()->getParameter('page_manager_page_variant'); + if (!empty($page_variant)) { + if ($variant = $page_variant->get('page')) { + $variables['attributes']['class'][] = 'page-variant--' . str_replace('_', '-', $variant); + } + } + + // The is_front variable needed in html twig as well, but it's only available + // in page twig. + $variables['is_front'] = \Drupal::service('path.matcher')->isFrontPage(); + + if (\Drupal::service('perls_api.request_inspector')->isMobileApp()) { + $variables['attributes']['class'][] = 'content-only'; + $variables["page"]["#cache"]["contexts"][] = 'headers:user-agent'; + } + + // Adds a body class with the current page manager page id (if it exists). + $page = \Drupal::routeMatch()->getParameter('page_manager_page'); + if (!empty($page)) { + $variables['attributes']['class'][] = 'page--' . $page->id(); + } + $route_name = \Drupal::routeMatch()->getRouteName(); + if ($route_name == 'user_task.my_list') { + $variables['attributes']['class'][] = 'page--user-task-my-list'; + } +} + +/** + * Implements template_preprocess_maintenance_page(). + */ +function perls_preprocess_maintenance_page(&$variables) { + $variables['title'] = t("We'll be back soon"); +} + +/** + * Implements hook_js_settings_alter(). + * + * Adds custom theming information. + */ +function perls_js_settings_alter(array &$settings, AttachedAssetsInterface $assets) { + if ($fid = theme_get_setting('custom_background_pattern', 'perls')) { + $file = File::load($fid[0]); + + $settings['appearance'] = [ + 'custom_background' => $file->createFileUrl(), + 'custom_background_repeat' => theme_get_setting('custom_background_repeat', 'perls') ?? 'repeat-x', + 'custom_background_anchor' => theme_get_setting('custom_background_anchor', 'perls') ?? 'top center', + 'custom_background_size' => theme_get_setting('custom_background_size', 'perls') ?? 'auto', + ]; + } + + // Override the themeing settings for the Veracity charts. + if (isset($settings['veracity_vql'])) { + foreach ($settings['veracity_vql'] as $chart_id => &$chart) { + $chart['theme']['name'] = 'am4themes_perls'; + $chart['theme']['url'] = _perls_get_chart_theme_url(); + $chart['theme']['background'] = '#FFF'; + } + } +} + +/** + * Implements hook_theme_suggestions_HOOK_alter(). + */ +function perls_theme_suggestions_page_alter(&$suggestions, $variables, $hook) { + // 404 template suggestion. + if (!is_null(Drupal::requestStack()->getCurrentRequest()->attributes->get('exception'))) { + $status_code = \Drupal::request()->attributes->get('_route'); + switch ($status_code) { + case 'system.404': + $suggestions[] = 'page__' . (string) $status_code; + break; + } + } +} + +/** + * Implements hook_theme_suggestions_HOOK_alter(). + */ +function perls_theme_suggestions_block_alter(array &$suggestions, array $variables) { + $block = $variables['elements']; + $blockType = $block['#configuration']['provider']; + if ($blockType == "block_content") { + $bundle = $block['content']['#block_content']->bundle(); + array_splice($suggestions, 2, 0, 'block__' . $blockType . '__' . $bundle); + } +} + +/** + * Implements hook_theme_preprocess_node(). + */ +function perls_preprocess_node(&$variables) { + $node = $variables['node']; + $node_type = $node->getType(); + + $linkType = NULL; + if ($node->hasField('field_link_type')) { + $linkType = $node->get('field_link_type')->getString(); + + if (!empty($linkType)) { + $variables['field_link_type'] = $linkType; + } + } + + if ($node_type == 'learn_link' && $linkType !== 'custom') { + $variables['target'] = '_blank'; + } + + // Create node id. + if ($node) { + $variables['id'] = $node->id(); + + // Avoid linking to the author who created the article. + $variables['author_name'] = $node->getOwner()->getDisplayName(); + } + + // Setting url value as per field_link_type. + if ($node->hasField('field_link_type')) { + if ($linkType !== 'custom') { + if (isset($variables['content']['field_content_link'][0])) { + if (!empty($variables['content']['field_content_link'][0]['#options']) && + $variables['content']['field_content_link'][0]['#options']['external'] == TRUE) { + $variables['url'] = $variables['content']['field_content_link'][0]['#url']->getUri(); + } + else { + $variables['url'] = $variables['content']['field_content_link'][0]['#url']->toString(); + } + } + } + else { + if (isset($variables['content']['field_custom_uri'][0])) { + $variables['url'] = $node->get('field_custom_uri')->getString(); + } + } + } +} + +/** + * Implements hook_form_FORM_ID_alter() for user_pass. + */ +function perls_form_user_pass_alter(&$form, &$form_state, $form_id) { + $form['name']['#attributes']['autofocus'] = TRUE; + $form['name']['#attributes']['placeholder'] = t('Email'); + $form['actions']['submit']['#value'] = t('Send Link'); + $form['mail']['#markup'] = FALSE; +} + +/** + * Implements hook_form_FORM_ID_alter() for entity browser. + */ +function perls_form_entity_browser_image_browser_form_alter(&$form, &$form_state, $form_id) { + if (isset($form['widget']['upload'])) { + $form['widget']['upload']['#description'] = t('One file only. @memory_limit limit. Allowed types: @extensions', + [ + '@memory_limit' => format_size(Environment::getUploadMaxSize()), + '@extensions' => $form['widget']['upload']['#upload_validators']['file_validate_extensions'][0], + ]); + } +} + +/** + * Implements hook_theme_preprocess_block(). + */ +function perls_preprocess_block(&$variables) { + // User login form block. + if (isset($variables['content']['user_login_form'])) { + $variables['content']['user_login_form']['name']['#attributes']['autofocus'] = TRUE; + $variables['content']['user_login_form']['name']['#attributes']['placeholder'] = t('Email'); + $variables['content']['user_login_form']['pass']['#attributes']['placeholder'] = t('Password'); + $variables['content']['user_login_form']['actions']['submit']['#value'] = t('Sign in'); + } + + // User links block. + if (isset($variables['content']['user_links'])) { + $variables['content']['user_links']['#items']['create_account']['#title'] = t('Create Account'); + $variables['content']['user_links']['#items']['request_password']['#title'] = t('Forgot Password'); + } + + $content = $variables['elements']['content']; + if (isset($content['#block_content']) && $content['#block_content'] instanceof BlockContentInterface) { + $variables['block_content_bundle'] = $content['#block_content']->bundle(); + } + + // Hide history button so we can verify if history exists first. The class + // will get removed via JS if it does (see main.js). + if ($variables['plugin_id'] == 'go_back_history_block') { + $variables['attributes']['class'] = ['go-back--hidden']; + } + + // Make user fields available for block level twig. + $user = User::load(\Drupal::currentUser()->id()); + /** @var \Drupal\file\FileInterface $image */ + $image = $user->get('user_picture')->entity; + if ($image) { + $variables['user_picture'] = [ + '#theme' => 'image_style', + '#style_name' => 'user_profile_circle', + '#uri' => $image->getFileUri(), + ]; + } + else { + $field = FieldConfig::loadByName('user', 'user', 'user_picture'); + $default_image = $field->getSetting('default_image'); + $file = \Drupal::service('entity.repository')->loadEntityByUuid('file', $default_image['uuid']); + if ($file) { + $image_uri = $file->getFileUri(); + $variables['user_picture'] = [ + '#theme' => 'image_style', + '#style_name' => 'user_profile_circle', + '#uri' => $image_uri, + ]; + } + } +} + +/** + * Implements hook_theme_preprocess_user(). + * + * @throws EntityStorageException + */ +function perls_preprocess_user(&$variables) { + $variables['view_mode'] = $variables['elements']['#view_mode']; + $created = $variables['user']->getCreatedTime(); + $variables['created'] = \Drupal::service('date.formatter')->format($created, 'custom', 'l, F j, Y'); + $variables['url'] = Url::fromUserInput('/user/' . $variables['user']->id() . '/edit'); + + /** @var \Drupal\file\FileInterface $image */ + $image = User::load($variables['user']->id())->get('user_picture')->entity; + if ($image) { + $image_uri = $image->getFileUri(); + $variables['user_picture_uri'] = ImageStyle::load('user_profile_portrait')->buildUrl($image_uri); + } + else { + $field = FieldConfig::loadByName('user', 'user', 'user_picture'); + $default_image = $field->getSetting('default_image'); + $file = \Drupal::service('entity.repository')->loadEntityByUuid('file', $default_image['uuid']); + $variables['user_picture_uri'] = ''; + if ($file) { + $image_uri = $file->getFileUri(); + $variables['user_picture_uri'] = ImageStyle::load('user_profile_portrait')->buildUrl($image_uri); + } + } + + if (User::load($variables['user']->id())->hasRole('sysadmin')) { + $variables['role'] = 'admin'; + } + + $account = User::load($variables['user']->id()); + $roles = Role::loadMultiple($account->getRoles()); + $role = end($roles); + $variables['role'] = $role ? $role->label() : ''; +} + +/** + * Implements hook_theme_preprocess_user(). + */ +function perls_theme_suggestions_user_alter(&$suggestions, $vars, $hook) { + $view_mode = $vars['elements']['#view_mode']; + $suggestions[] = 'user__' . $view_mode; +} + +/** + * Implements hook_form_FORM_ID_alter() for views_bulk_operations_confirm_action. + * + * Improves the UX of the VBO confirmation page. + */ +function perls_form_views_bulk_operations_confirm_action_alter(&$form, &$form_state, $form_id) { + $form_data = $form_state->get('views_bulk_operations'); + + // If there are no entity labels, then the user has requested to + // perform an action to all entities in the view. + if (empty($form_data['entity_labels'])) { + $form['list'] = [ + '#theme' => 'item_list', + '#items' => [t('All @count items', [ + '@count' => $form_data['selected_count'], + ]), + ], + ]; + } + + $form['list']['#title'] = t('Are you sure you want to @action?', ['@action' => strtolower($form_data['action_label'])]); + $form['#title'] = t('@action confirmation', ['@action' => $form_data['action_label']]); + $form['actions']['#type'] = 'actions'; + $form['actions']['submit']['#value'] = $form_data['action_label']; + $form['actions']['submit']['#attributes']['class'][] = 'button--danger'; +} + +/** + * Implements hook_form_FORM_ID_alter() for views_bulk_operations_configure_action. + * + * Improves the UX of the VBO configure page. + */ +function perls_form_views_bulk_operations_configure_action_alter(&$form, &$form_state, $form_id) { + $form_data = $form_state->get('views_bulk_operations'); + $action_label = $form_data['action_label'] ?? ''; + $form['#title'] = t('Configure %action', ['%action' => $action_label]); + $form['actions']['#type'] = 'actions'; + $form['actions']['submit']['#value'] = $action_label; +} + +/** + * Implements hook_form_alter() for forms. + * + * Re-arranges the header of VBO forms and alter tax form titles. + */ +function perls_form_alter(&$form, &$form_state, $form_id) { + $topic_and_tag_form_ids = [ + 'taxonomy_term_tags_form', + 'taxonomy_term_category_form', + ]; + + if (in_array($form_id, $topic_and_tag_form_ids)) { + $term = $form_state->getFormObject()->getEntity(); + + if ($term->isNew()) { + $form['#title'] = t('Create @vocab', [ + '@vocab' => $term->vid->entity->label(), + ]); + } + else { + $form['#title'] = t('Edit @vocab: @label', [ + '@vocab' => $term->vid->entity->label(), + '@label' => $term->label(), + ]); + } + } + + if (isset($form['header']) && isset($form['header']['views_bulk_operations_bulk_form'])) { + $form['header']['views_bulk_operations_bulk_form']['multipage']['#weight'] = 1000; + $form['header']['views_bulk_operations_bulk_form']['select_all']['#weight'] = 1001; + } +} + +/** + * Add display to theme suggestions for taxonomy_term. + */ +function perls_theme_suggestions_taxonomy_term_alter(array &$suggestions, array $variables) { + $term = $variables['elements']['#taxonomy_term']; + $suggestions[] = 'taxonomy_term__' . $variables['elements']['#view_mode']; + $suggestions[] = 'taxonomy_term__' . $term->bundle() . '__' . $variables['elements']['#view_mode']; +} + +/** + * Implements hook_form_BASE_FORM_ID_alter(). + * + * We need to load by hand the formtips js to entity browser forms because the + * entity browser is using modal view. The formtips module attach the library in + * hook_page_bottom hook but this hook doesn't run in modal view. + */ +function perls_form_entity_browser_form_alter(&$form, $form_state, $form_id) { + if (\Drupal::moduleHandler()->moduleExists('formtips')) { + $settings = \Drupal::config('formtips.settings'); + $enabled_themes = $settings->get('formtips_themes'); + if (!empty($enabled_themes) && !array_key_exists('perls', $enabled_themes)) { + return; + } + + $js_settings = [ + 'formtips' => [ + 'selectors' => explode("\r\n", $settings->get('formtips_selectors')), + 'interval' => $settings->get('formtips_interval'), + 'sensitivity' => $settings->get('formtips_sensitivity'), + 'timeout' => $settings->get('formtips_timeout'), + 'max_width' => $settings->get('formtips_max_width'), + 'trigger_action' => $settings->get('formtips_trigger_action'), + ], + ]; + + $form['#attached']['library'][] = 'formtips/formtips'; + $form['#attached']['drupalSettings'] = $js_settings; + }; +} + +/** + * Implements template_preprocess(). + */ +function perls_preprocess_views_view_table(&$variables) { + $route_match = \Drupal::routeMatch(); + if ($route_match->getRouteName() === 'entity.webform_submission.collection') { + $route = $route_match->getRouteObject(); + $route->setDefault('_title', 'Learner Feedback'); + } +} + +/** + * Implements template_preprocess() for layouts. + * + * Add a semantic class for a layout region. + */ +function perls_preprocess_layout(&$variables) { + $variables['attributes']['class'][] = 'layout-section'; + if (isset($variables['settings']['layout_section_id'])) { + $variables['attributes']['class'][] = + 'layout-section--' . + str_replace('_', '-', $variables['settings']['layout_section_id']); + } +} + +/** + * Implements hook_preprocess_HOOK() for tests. + * + * Adds the test header to each question in the test. + */ +function perls_preprocess_field__node__field_quiz__test(&$variables) { + $test = $variables['element']['#object']; + + foreach ($variables['items'] as $index => &$item) { + $item['content']['#header'] = [ + '#markup' => t('

    @item / @total

    @type

    @title

    ', [ + '@item' => $index + 1, + '@total' => count($variables['items']), + '@type' => $test->type->entity->label(), + '@title' => $test->label(), + ]), + ]; + + // Ensure the quiz card is cached based on the test it's in. + array_push($item['content']['#cache']['keys'], 'test', $test->id()); + $item['content']['#cache']['tags'][] = 'node:' . $test->id(); + } +} + +/** + * Implements hook_preprocess_HOOK() for quiz cards. + * + * Applies a header if the question appears as part of a test. + */ +function perls_preprocess_node__quiz__card(&$variables) { + if (isset($variables['elements']['#header'])) { + $variables['header'] = $variables['elements']['#header']; + } +} + +/** + * Implements hook_preprocess_HOOK() for course cards. + */ +function perls_preprocess_node__course__card(&$variables) { + /** @var \Drupal\perls_learner_state\LearnerInfo $learner_info */ + $learner_info = \Drupal::service('perls_learner_state.info'); + $course = $variables['node']; + $count = $learner_info->getCourseLength($course); + $progress = ($count) ? min(100, round($learner_info->getCourseProgress($course) / $count * 100)) : '0'; + + if ($learner_info->isEnrolled($course)) { + $variables['launch_button_title'] = t('Continue'); + $variables['course_status'] = t('@count lessons / @progress% complete', [ + '@count' => $count, + '@progress' => $progress, + ]); + } + else { + $variables['launch_button_title'] = t('Start'); + $variables['course_status'] = t('@count lessons', [ + '@count' => $count, + ]); + } + + $cache_metadata = CacheableMetadata::createFromRenderArray($variables); + $cache_metadata->addCacheContexts(['user']); + foreach ($course->field_learning_content->referencedEntities() as $node) { + $cache_metadata->addCacheTags($node->getCacheTags()); + } + + $cache_metadata->applyTo($variables); +} + +/** + * Implements hook_preprocess_HOOK() for course node pages. + */ +function perls_preprocess_node__course__full(&$variables) { + $course = $variables['node']; + $learner_info = \Drupal::service('perls_learner_state.info'); + $count = $learner_info->getCourseLength($course); + $progress = $learner_info->getCourseProgress($course); + + $variables['course_complete_count'] = $progress; + $variables['course_total_count'] = $count; + // LearnerInfo getCourseLength returns 0 if there is no accessible content. + if (!$count) { + $variables['course_progress'] = t("You do not have access to any of the content within this course. @recommendation.", [ + '@recommendation' => Link::fromTextAndUrl(t('Try something new'), Url::fromRoute(''))->toString(), + ]); + } + elseif ($progress < $count) { + $variables['course_progress'] = t('@complete_count / @total_count completed', [ + '@complete_count' => $progress, + '@total_count' => $count, + ]); + } + else { + $variables['course_progress'] = t("You've completed this course! @recommendation.", [ + '@recommendation' => Link::fromTextAndUrl(t('Try something new'), Url::fromRoute(''))->toString(), + ]); + } + + $variables['#cache']['contexts'][] = 'user'; +} + +/** + * Implements hook_preprocess_HOOK() for course tiles. + */ +function perls_preprocess_node__course__tile(&$variables) { + /** @var \Drupal\perls_learner_state\LearnerInfo $learner_info */ + $learner_info = \Drupal::service('perls_learner_state.info'); + $course = $variables['node']; + $account = User::load($variables['user']->id()); + $course_complete = $learner_info->isCourseComplete($course, $account); + if ($course_complete) { + $variables['course_status'] = t('Completed'); + } + else { + $count = $learner_info->getCourseLength($course); + $progress = ($count) ? $learner_info->getCourseProgress($course) : '0'; + + if ($learner_info->isEnrolled($course)) { + $variables['course_status'] = t('@progress / @count @lesson Complete', [ + '@count' => $count, + '@progress' => $progress, + '@lesson' => \Drupal::translation()->formatPlural( + $count, + 'Lesson', 'Lessons' + ), + ]); + } + } + + $cache_metadata = CacheableMetadata::createFromRenderArray($variables); + $cache_metadata->addCacheContexts(['user']); + foreach ($course->field_learning_content->referencedEntities() as $node) { + $cache_metadata->addCacheTags($node->getCacheTags()); + } + + $cache_metadata->applyTo($variables); +} + +/** + * Implements hook_preprocess_HOOK() for podcast tiles. + */ +function perls_preprocess_node__podcast__tile(&$variables) { + $podcast = $variables['node']; + $episodes = $podcast->get('field_episodes'); + if (!$episodes->isEmpty()) { + $variables['episode_count'] = \Drupal::translation()->formatPlural( + count($episodes), + '1 Episode', '@count Episodes' + ); + } +} + +/** + * Implements hook_preprocess_HOOK() for node tiles. + */ +function perls_preprocess_node__tile(&$variables) { + $node = $variables['node']; + $node_type = $node->getType(); + $variables['link_attributes'] = []; + if (in_array($node_type, ['tip_card', 'quiz', 'flash_card'])) { + $variables['link_attributes'] = new Attribute(); + $variables['link_attributes']->addClass('use-ajax'); + $variables['link_attributes']->setAttribute('dialog', 'modal'); + } +} + +/** + * Implements template_preprocess_views_view(). + */ +function perls_preprocess_views_view_list(&$variables) { + /** @var \Drupal\views\ViewExecutable $view */ + $view = $variables['view']; + $id = $view->id(); + $display = $view->current_display; + if ($id === 'recommended_content' && $display === 'learner_page') { + $block_manager = \Drupal::service('plugin.manager.block'); + $plugin_block = $block_manager->createInstance('prompt_block', []); + $rendered_block = $plugin_block->build(); + if (!empty($rendered_block)) { + $variables['prompt_block'] = $rendered_block; + } + } + + if ($id === 'corpus_activity') { + $rows = $variables['rows']; + + foreach ($rows as $row) { + /** @var \Drupal\views\ResultRow $content */ + $content = $row['content']['#row']; + $variables['attributes']['class'][] = $content->_entity->bundle(); + } + } + + if ($id === 'group_content_by_topic' + || $id === 'history' + || $id === 'bookmarks') { + $more_link = _perls_get_view_more_link($view); + + if ($more_link) { + $variables['rows'][] = [ + 'content' => [ + '#type' => 'container', + '#attributes' => ['class' => 'c-card c-card--more'], + 'link' => $more_link, + ], + ]; + } + } + + if ($id === 'dashboard_tags' + || $id === 'group_index') { + $more_link = _perls_get_view_more_link($view); + + if ($more_link) { + $variables['rows'][] = [ + 'content' => [ + '#type' => 'container', + '#attributes' => ['class' => 'c-chip--more'], + 'link' => $more_link, + ], + ]; + } + } +} + +/** + * Implements hook_form_FORM_ID_alter(). + */ +function perls_form_system_theme_settings_alter(&$form, FormStateInterface $form_state) { + $build_info = $form_state->getBuildInfo(); + if (isset($build_info['args'][0]) && ($theme = $build_info['args'][0]) && color_get_info($theme) && $theme === 'perls' && function_exists('gd_info')) { + $form['#validate'][] = '_perls_scheme_form_validate'; + } + + if (!isset($form['#submit']) || !in_array('perls_theme_settings_submit_handler', $form['#submit'])) { + $form['#submit'][] = 'perls_theme_settings_submit_handler'; + } + + // This alter hook is invoked for both base and child themes; + // but we only want to override what happens for the base theme. + $theme = \Drupal::routeMatch()->getParameter('theme'); + + if ($theme !== 'perls') { + return; + } + + $form['#title'] = t('Customize Theming'); + + // Hide the default theme settings. + unset($form['logo'], $form['favicon']); + $form['theme_settings']['#access'] = FALSE; + + $form['perls'] = [ + '#type' => 'container', + '#weight' => -10, + ]; + + $form['perls']['description'] = [ + '#type' => 'container', + '#attributes' => ['class' => ['page-description']], + ]; + + $form['perls']['description']['content'] = [ + '#type' => 'html_tag', + '#tag' => 'p', + '#value' => t('Customizing the logos and colors will update both the web and mobile app. You can choose all your own colors or customize one of the existing color schemes. Use the preview below to ensure text is easily readable across all content types.'), + ]; + + $form['perls']['custom_logo'] = [ + '#type' => 'managed_image', + '#title' => t('Custom logo'), + '#description' => t('Recommended size: 400x400px.'), + '#default_value' => theme_get_setting('custom_logo', $theme), + '#upload_location' => 'public://branding/', + ]; + + $form['perls']['custom_app_logo'] = [ + '#type' => 'managed_image', + '#title' => t('App logo'), + '#description' => t('Optionally, you may upload a different logo to use in the mobile app.
    Recommended size: 300x90px.'), + '#default_value' => theme_get_setting('custom_app_logo', $theme), + '#upload_location' => 'public://branding/', + ]; + + $form['perls']['custom_favicon'] = [ + '#type' => 'managed_image', + '#title' => t('Favicon'), + '#description' => t('Some browsers show this icon in the address bar or when the user bookmarks the site.
    Recommended size: 300x300px'), + '#default_value' => theme_get_setting('custom_favicon', $theme), + '#upload_location' => 'public://branding/', + '#upload_validators' => [ + 'file_validate_extensions' => ['png'], + ], + ]; + + $form['background'] = [ + '#type' => 'details', + '#title' => t('Background'), + ]; + + $form['background']['custom_background_pattern'] = [ + '#type' => 'managed_image', + '#title' => t('Pattern'), + '#description' => t('The background pattern appears on the login screen, the content management screens, and at the top of the learner screens.
    Tip: Choose a pattern that can tile vertically or horizontally and choose how the pattern should be repeated below.'), + '#default_value' => theme_get_setting('custom_background_pattern', $theme), + '#upload_location' => 'public://branding/', + '#upload_validators' => [ + 'file_validate_extensions' => ['png'], + ], + ]; + + $form['background']['custom_background_repeat'] = [ + '#type' => 'select', + '#title' => t('Repeat'), + '#options' => [ + 'repeat-x' => t('Repeat horizontally'), + 'repeat-y' => t('Repeat vertically'), + 'repeat' => t('Repeat horizontally and vertically'), + ], + '#default_value' => theme_get_setting('custom_background_repeat', $theme), + ]; + + $form['background']['custom_background_anchor'] = [ + '#type' => 'select', + '#title' => t('Anchor'), + '#description' => t('Choose where the repeating background should start'), + '#options' => [ + 'top left' => t('Top left'), + 'top center' => t('Top center'), + 'top right' => t('Top right'), + 'center left' => t('Center left'), + 'center center' => t('Center'), + 'center right' => t('Center right'), + 'bottom left' => t('Bottom left'), + 'bottom center' => t('Bottom center'), + 'bottom right' => t('Bottom right'), + ], + '#default_value' => theme_get_setting('custom_background_anchor', $theme) ?? 'top center', + ]; +} + +/** + * Invoked when the appearance settings have been changed for the theme. + * + * Invoked for both base and child themes; happens before base form submission. + * + * @param array $form + * The form that was submitted. + * @param \Drupal\Core\Form\FormStateInterface $form_state + * The state of the form. + */ +function perls_theme_settings_submit_handler(array &$form, FormStateInterface $form_state) { + $config = \Drupal::configFactory()->getEditable('perls.settings'); + + foreach (['logo', 'app_logo', 'favicon', 'background_pattern'] as $option) { + $field = 'custom_' . $option; + $default_key = $option . '.use_default'; + $path_key = $option . '.path'; + + $value = $form_state->getValue($field); + + if (!empty($value)) { + $file = File::load($value[0]); + $file->setPermanent(); + $file->save(); + + $config->set($default_key, 0); + $config->set($path_key, $file->getFileUri()); + } + elseif ($config->get($path_key) !== NULL) { + $files = \Drupal::entityTypeManager() + ->getStorage('file') + ->loadByProperties(['uri' => $config->get($path_key)]); + + foreach ($files as $file) { + $file->delete(); + } + + $config->set($default_key, 1); + $config->set($path_key, NULL); + } + + // @todo Consider unsetting the file upload field? + // $form_state->unsetValue($field); + } + + $config->save(); +} + +/** + * Get the view more link for a given view. + * + * @param object $view + * The view to get the more link for. + * + * @return array|bool + * Render array for more_link or false. + */ +function _perls_get_view_more_link($view) { + if (is_object($view)) { + $more_link = $view->getDisplay()->renderMoreLink(); + + if ($more_link) { + return $more_link; + } + } + return FALSE; +} + +/** + * Make changes to color form submission. + */ +function _perls_scheme_form_validate(&$form, FormStateInterface $form_state) { + $palette = $form_state->getValue('palette'); + $palette['secondary_lighter'] = _perls_theme_lighter($palette['secondary'], 0.2); + $palette['secondary_darker'] = _perls_theme_darker($palette['secondary'], 0.2); + $palette['course_darker'] = _perls_theme_darker($palette['course'], 0.2); + $form_state->setValue('palette', $palette); +} + +/** + * Get a lighter shade of the given color. + */ +function _perls_theme_lighter($rgb, $amount) { + $source = _color_rgb2hsl(_color_unpack($rgb, TRUE)); + $source[2] = min(1, $source[2] * (1 + $amount)); + return _color_pack(_color_hsl2rgb($source), TRUE); +} + +/** + * Gets a darker shade of a given color. + */ +function _perls_theme_darker($rgb, $amount) { + $source = _color_rgb2hsl(_color_unpack($rgb, TRUE)); + $source[2] = max(0, $source[2] * max(0, 1 - $amount)); + return _color_pack(_color_hsl2rgb($source), TRUE); +} + +/** + * Implements hook_preprocess_HOOK() for duration field. + */ +function perls_preprocess_field__node__field_duration(&$variables) { + $duration = $variables["items"][0]["content"]["#markup"]; + $variables["items"][0]["content"]["#markup"] = gmdate('G:i:s', $duration); +} + +/** + * Implements hook_preprocess_HOOK() for status report info. + * + * Adds deployment identifier. + */ +function perls_preprocess_status_report_general_info(&$variables) { + $variables['drupal']['deployment_identifier'] = Settings::get('deployment_identifier') ?? t('Unknown'); +} + +/** + * Implements hook_preprocess_HOOK() for group. + * + * Updates requirements for whether the current page is the "group page." + */ +function perls_preprocess_group(&$variables) { + $route_match = \Drupal::routeMatch(); + $group = $variables['group']; + $page_group = $route_match->getParameter('group'); + $is_group_page = $route_match->getRouteName() === 'view.group_topics.page_1' + && $page_group + && $page_group->id() == $group->id(); + + $variables['page'] = $variables['page'] || $is_group_page; + $variables['#cache']['contexts'][] = 'route'; +} + +/** + * Determines the amcharts theme URL for the Veracity VQL renderer. + */ +function _perls_get_chart_theme_url() { + $target = 'am4chart-theme.js'; + $stylesheets = \Drupal::config('color.theme.perls')->get('stylesheets'); + + if (isset($stylesheets)) { + foreach ($stylesheets as $file) { + if (basename($file) === $target) { + return file_create_url($file); + } + } + } + + return file_create_url(drupal_get_path('theme', 'perls') . '/dist/css/' . $target); +} + +/** + * Implements template_preprocess_menu_local_action(). + */ +function perls_preprocess_menu_local_action(&$variables) { + $classes = [ + 'o-button--large', + 'push-notification-action-link', + ]; + if (isset($variables['link']['#title']) && in_array($variables['link']['#title'], [ + 'Send Notification by User', + 'Send Notification by Group', + ])) { + if ($variables['link']['#title'] === 'Send Notification by User') { + $classes[] = 'o-button__notify-user'; + } + else { + $classes[] = 'o-button__notify-groups'; + } + + if (isset($variables['link']['#options']['attributes']['class'])) { + $variables['link']['#options']['attributes']['class'] = $classes; + } + } +} diff --git a/web/themes/custom/perls/readme.md b/web/themes/custom/perls/readme.md new file mode 100644 index 0000000..e77f788 --- /dev/null +++ b/web/themes/custom/perls/readme.md @@ -0,0 +1,72 @@ +# Perls Theme + +The below commands should be everything you need to get +setup, whether you're just viewing the latest theme files or actively +doing theme development. + +## Installation + +### Prerequisites: + +- [Node](https://nodejs.org/en/) (8+) +- [npm](https://nodejs.org/) (5+) + +### Installing development dependencies + +In the Perls theme root directory run: + +```sh +npm run build +``` + +This will create the `node_modules` directory and download all dev dependencies, +compile all Perls theme SCSS into CSS and JS files. + + +## Generating theme asset files + +To generate the latest theme assets, run this command: + +```sh +gulp build-theme +``` + +This will generate all CSS/JS files, compile a new Pattern Lab `public` site, +and move the generated CSS/JS into the new `public` site. You might use this +after you pull in some theme changes and want to view them on +your local environment. + +## Developing within the theme + +When working with the theme, there's a few development options available. +These commands must be run from the root of the PERLS theme directory. + +### Watch for file changes + +This will start up a local server via [Browsersync](https://browsersync.io/). +It proxies the local domain `perls.localhost:8000`. + +```sh +gulp +``` + +### Generating theme-specific CSS files + +```sh +gulp sass +``` + +### Rebuild Pattern Lab + +```sh +gulp patterns-change +``` + +_For a larger list of `gulp` commands, see the [gulp file](gulpfile.js)_ + +### Developing + +Place all template files into the `templates` directory and all SCSS +stylesheets into the `resources/scss` directory. When adding new SCSS +stylesheets,remember to `@import` them in `scss/styles.scss`. This will act +as a registry of all stylesheets and allow for control over their load order. diff --git a/web/themes/custom/perls/resources/scripts/clamp.init.js b/web/themes/custom/perls/resources/scripts/clamp.init.js new file mode 100644 index 0000000..741d02a --- /dev/null +++ b/web/themes/custom/perls/resources/scripts/clamp.init.js @@ -0,0 +1,26 @@ +(function ($, Drupal, drupalSettings) { + "use strict"; + + Drupal.behaviors.perlsClamp = { + attach: function (context, settings) { + $(".c-user-profile--card .c-field--name-field-name, .c-node--tile .field--name-title", context) + .once("perls-clamp") + .each(function (i, e) { + $clamp(e, {clamp: 2, animate: true}); + }); + $(".c-node--card--course .c-field--name-field-description p, .c-node--card .c-field--name-field-description", context) + .once("perls-clamp") + .each(function (i, e) { + // Add class to clamped course description element for CSS fallback. + $(e).addClass('perls-clamp'); + $clamp(e, {clamp: 3, animate: true}); + }); + + $(".card--description .c-field--name-field-description p", context) + .once("perls-clamp") + .each(function (i, e) { + $clamp(e, {clamp: 12, animate: true}); + }); + }, + }; +})(jQuery, Drupal, drupalSettings); diff --git a/web/themes/custom/perls/resources/scripts/dialog.js b/web/themes/custom/perls/resources/scripts/dialog.js new file mode 100644 index 0000000..e819a9a --- /dev/null +++ b/web/themes/custom/perls/resources/scripts/dialog.js @@ -0,0 +1,61 @@ +/** + * @file + * Custom JS for PERLS. + */ +(function($, Drupal, drupalSettings) { + 'use strict'; + + /** + * Resolves this issue: + * When JQuery dialog gets opened the focus goes to the first tabbable element inside the dialog's content + * We dont want that, so instead we put the focus on the modal itself. + */ + Drupal.behaviors.perlsDialog = { + attach: function(context, settings) { + var body = 'body'; + + $(body).on('dialogfocus', function () { + $('.ui-dialog', $(this)).focus(); + }); + + $(body).once().on('dialogopen', function (event) { + // Ref to the opened dialog. + var openDialogContainer = (event.target.parentNode) ? $(event.target.parentNode) : null; + $('body').on('click.hideMyDialog', function (event) { + // If the click on the body is not on this specific overlay stop here. + if (!event.target.classList.contains('ui-widget-overlay')) { + return; + } + if (!$(event.target).closest('.ui-widget-content').length && !$(event.target).is('.ui-widget-content')) { + // Close only 1 specific overlay if it exists. + if (openDialogContainer) { + var openDialogClose = openDialogContainer.find('.ui-dialog-titlebar-close'); + // Check if the expected close element was found. + if (openDialogClose.length != 0) { + openDialogClose.click(); + $('body').off('click.hideMyDialog'); + return; + } + } + // Fallback closes every modal that is open. + $('.ui-dialog-titlebar-close').click(); + $('body').off('click.hideMyDialog'); + } + }); + $('html').addClass('stop-scroll'); + }); + + $(body).on('dialogclose', function () { + $('html').removeClass('stop-scroll'); + }); + + $(body).once('renderComments').on('dialogopen', function () { + // renderComments() is defined in web/modules/custom/react_comments + if (typeof window.renderComments !== "undefined") { + window.renderComments(); + } + }); + }, + }; + +})(jQuery, Drupal, drupalSettings); diff --git a/web/themes/custom/perls/resources/scripts/forms.js b/web/themes/custom/perls/resources/scripts/forms.js new file mode 100644 index 0000000..0873231 --- /dev/null +++ b/web/themes/custom/perls/resources/scripts/forms.js @@ -0,0 +1,50 @@ +/** + * @file + * Custom JS for admin forms. + */ + +(function($, Drupal, drupalSettings) { + 'use strict'; + + Drupal.behaviors.PerlsForms = { + attach: function(context, settings) { + $('.vbo-view-form, .views-form', context).once('perls-vbo-init').each(function (i, form) { + attachToBulkForm(form); + }); + }, + }; + + /** + * Attaches to a form that represents bulk operations. + * + * @param {HTMLFormElement} form + * The bulk form to attach to. + */ + function attachToBulkForm(form) { + updateButtonStatus(form); + $('input:checkbox', form).on('change', function(e) { + // When the user toggles the select all button, it may take a _moment_ + // for all the checkboxes to be in their new state. + setTimeout(function() { + updateButtonStatus(form); + }, 1); + }); + } + + /** + * Updates the submit button on form actions based on the selected items. + * + * @param {*} context + * The context. + */ + function updateButtonStatus(context) { + // If the context doesn't have any checkboxes, then there's nothing to do. + if ($('input:checkbox', context).length === 0) { + return; + } + + var isEmptySelection = $('input:checkbox:checked', context).length === 0; + $('.form-actions .form-submit', context).prop('disabled', isEmptySelection); + } + +})(jQuery, Drupal, drupalSettings); diff --git a/web/themes/custom/perls/resources/scripts/formtips.altered.js b/web/themes/custom/perls/resources/scripts/formtips.altered.js new file mode 100644 index 0000000..88e38b0 --- /dev/null +++ b/web/themes/custom/perls/resources/scripts/formtips.altered.js @@ -0,0 +1,125 @@ +/** + * @file: Formtips module file - altered + */ + +(function ($) { + + Drupal.behaviors.perlsFormtipsAltered = { + attach: function (context, settings) { + + function hideOnClickOutside(element, $description) { + var outsideClickListener = function (event) { + var $target = $(event.target); + if (!$target.hasClass('formtip') && !$target.hasClass('formtips-processed')) { + $description.toggleClass('formtips-show', false); + } + } + + $(document).on('click', outsideClickListener); + } + + var formtip_settings = settings.formtips; + var selectors = formtip_settings.selectors; + if ($.isArray(selectors)) { + selectors = selectors.join(', '); + } + + var $descriptions = $('.form-item .description,.form-item .filter-guidelines, .field--widget-autocomplete-deluxe .form-item .description') + .not(selectors) + .not('.formtips-processed'); + + // Filter out empty descriptions. This helps avoid the password strength + // description getting caught in a help. + $descriptions = $descriptions.filter(function () { + return $.trim($(this).text()) !== ''; + }); + if (formtip_settings.max_width.length) { + $descriptions.css('max-width', formtip_settings.max_width); + } + + // Hide descriptions when escaped is hit. + $(document).on('keyup', function (e) { + if (e.which === 27) { + $descriptions.removeClass('formtips-show'); + } + }); + + $descriptions.once('formtips').each(function () { + var isParagraph = false; + var $formtip = $(''); + var $description = $(this); + var $item = $description.closest('.form-item'); + + // If there's a filter wrapper check that. + var $label = $item.find('label:not(.visually-hidden)').first(); + + // Look for a fieldset legend or draggable table label. + if (!$label.length) { + $label = $item.find('.fieldset-legend,.label').first(); + } + + // Use the fieldset if the item is a radio or checkbox. + var $fieldset = $item.find('.fieldset-legend'); + if ($fieldset.length && $item.find('input[type="checkbox"], input[type="radio"]').length) { + $label = $fieldset; + } + + // We need to handle the paragraph differently because the label element + // isn't proper to us. + if ($description.closest('.field--widget-paragraphs, .field--widget-entity-reference-paragraphs').length) { + $label = $item.find('table .field-label').first(); + isParagraph = true; + } + + // Look for a widget label. + var $widget = $item.closest('.autocomplete-deluxe-value-container').closest('.field--widget-autocomplete-deluxe'); + if ($widget.length) { + $item = $widget; + $label = $item.find('label:not(.visually-hidden)').first(); + } + + // If there is no label, skip. + if (!$label.length) { + return; + } + + $description.addClass('formtips-processed'); + + $item.addClass('formtips-item'); + $description.toggleClass('formtips-show', false); + $label.append($formtip); + + // If the current tip text belongs to paragraph where the tip text + // appears at the question mark not under the field. + if (isParagraph) { + $formtip.append($description); + } + + + if (formtip_settings.trigger_action === 'click') { + $formtip.on('click', function () { + $description.toggleClass('formtips-show'); + return false; + }); + // Hide description when clicking elsewhere. + hideOnClickOutside($item[0], $description); + + } + else { + $formtip.hoverIntent({ + sensitivity: formtip_settings.sensitivity, + interval: formtip_settings.interval, + over: function () { + $description.toggleClass('formtips-show', true); + }, + timeout: formtip_settings.timeout, + out: function () { + $description.toggleClass('formtips-show', false); + } + }); + } + }); + } + }; + +})(jQuery); diff --git a/web/themes/custom/perls/resources/scripts/live-preview.js b/web/themes/custom/perls/resources/scripts/live-preview.js new file mode 100644 index 0000000..896078d --- /dev/null +++ b/web/themes/custom/perls/resources/scripts/live-preview.js @@ -0,0 +1,25 @@ +(function($, Drupal, drupalSettings) { + 'use strict'; + + Drupal.behaviors.perlsLivePreview = { + attach: function (context, settings) { + $('.c-block-node-live-preview', context).once('perls-live-preview').each(function() { + $('a', $(this)).attr({target: '_blank', rel: 'noopener'}); + + $(document).ajaxStop(function() { + var $target = $('a', '.c-block-node-live-preview'); + $target.attr({target: '_blank', rel: 'noopener'}); + + $target.on('click', function (e) { + var link = $(e.target).attr('href'); + + if (link.length === 0) { + e.preventDefault(); + alert(Drupal.t('This link will become active after you save your changes.')); + } + }) + }); + }); + }, + }; +})(jQuery, Drupal, drupalSettings); diff --git a/web/themes/custom/perls/resources/scripts/main.js b/web/themes/custom/perls/resources/scripts/main.js new file mode 100644 index 0000000..56ccfed --- /dev/null +++ b/web/themes/custom/perls/resources/scripts/main.js @@ -0,0 +1,270 @@ +/** + * @file + * Custom JS for PERLS. + */ + +(function ($, Drupal, drupalSettings, Sortable) { + 'use strict'; + + Drupal.behaviors.PerlsTheme = { + attach: function (context, settings) { + if (settings.appearance) { + $('body.perls-content-manager, body.perls-learner .c-header, body.l-page--path--user.l-page--user-login, body.l-page--path--user.l-page--user-password, body.l-page--path--user.l-page--user-register').css({ + backgroundImage: 'url(' + settings.appearance.custom_background + ')', + backgroundRepeat: settings.appearance.custom_background_repeat, + backgroundPosition: settings.appearance.custom_background_anchor, + backgroundSize: settings.appearance.custom_background_size, + backgroundBlendMode: 'normal', + backgroundAttachment: 'fixed', + }); + } + + // Content Manager menu hide/show controls. + $('body.perls-content-manager .c-nav__toggle').once().on('click', function() { + $('body').toggleClass('cm-menu-open'); + }); + + $('.js-slick-slider > ul', context).once().on('init', function (event, slick) { + $(this).attr('slick_id', slick.instanceUid); + }); + + /** + * Slick sliders + */ + $('.js-slick-slider > ul', context).slick({ + dots: false, + autoplay: false, + arrows: true, + infinite: false, + speed: 250, + cssEase: 'linear', + variableWidth: true, + draggable: true, + swipeToSlide: true, + }); + + // When viewing a course, automatically slide to the first + // incomplete lesson so the learner can resume where they left off. + $('.c-node--full--course .js-slick-slider > ul', context).each(function () { + var $slider = $(this); + var slides = $('li', $slider); + + // Checking whether "description card" exists. + // * Helps to determine the "resume" position in the slider. * + var x = $(slides[0]).hasClass('course-description') ? 1 : 0; + + for (var i = x; i < slides.length; ++i) { + if ($('.flag.completed', slides[i]).length === 0) { + if (i > x) { + $slider.slick('slickGoTo', i); + } + return; + } + } + }); + + // Focus on the input when a select2 element is opened. + $(document).on('select2:open', function (e) { + var container = document.getElementById('select2-' + e.target.id + '-results').closest('.select2-container--open'); + var input = container && container.querySelector('.select2-search__field'); + if (input) { + input.focus(); + } + }) + // Redundant remove element tracking since draggable from SortableJS + // causes unexpected behavior. + document.addEventListener('mouseup', function(e) { + if (!e.target.closest('.select2-selection__choice__remove')) return; + // Trigger removal via click so select2 handles value update. + e.target.click(); + }, false); + + $('.select2-widget', context).on('select2-init', function (e) { + var config = $(e.target).data('select2-config'); + config.language = { + inputTooShort: function () { + return ('minInputText' in e.currentTarget.dataset) ? e.currentTarget.dataset.minInputText : "Search for selection..."; + }, + noResults: function () { + return ('noResultsText' in e.currentTarget.dataset) ? e.currentTarget.dataset.noResultsText : "No results found"; + } + } + $(e.target).data('select2-config', config); + }); + + /** + * For each card that is over window height, adds toggle. + */ + $('.c-node--card--flash-card', context).each(function (index, item) { + var toggleButton = ''; + if ($(item).height() > $(window).height()) { + $(item).addClass('js-this has-toggle'); + $(item).find('.c-card__content').append(toggleButton); + } + }); + + // Ensures the quiz scrolls back to the top so the feedback is fully in view. + // This is needed in the context of a test where the card height is constant + // and not determined by the intrinsic height. + $('.c-quiz__option a', context).click(function () { + var $container = $(this).parents('.c-card__content').first(); + setTimeout(function () { + $container.scrollTop(0); + }, 600); + }); + + /** + * Contrib back button block. + */ + if ($('.c-block-go-back-history') && window.history.length > 1) { + // Button is hidden by default unless there is history. This prevents a + // "FOUC" that would be seen if the back button was simply removed. + $('.c-block-go-back-history').removeClass('go-back--hidden'); + } + + /** + * History back button. + */ + $('.js-button-back').click(function (e) { + if ($('#edit-back-button').length) { + e.preventDefault(); + $('#edit-back-button').click(); + } else { + e.preventDefault(); + window.location.href = '/user/login' + location.search; + history.back(); + } + }); + + /** + * Clicking on learning content title on course edit page opens edit + * modal for that content item. + */ + var courseTitleClick = function (courseItem) { + $(courseItem).find('.c-card__title-link, .c-card .c-card__link') + .each(function (index, item) { + $(item).on('click', function(event) { + event.preventDefault(); + event.stopPropagation(); + var target = $(event.currentTarget); + if (!target.is('[disabled]')) { + // Prevents multiple synchronous events from being fired. + target.attr('disabled', 'disabled'); + // Trigger event on edit button for content item. + $(courseItem).find('.edit-button').mousedown(); + target.removeAttr('disabled'); + } + }) + }); + }; + + // Initialize the title click edit modal behavior on course edit pages. + if ($('.l-page--node-type--course .c-form--node-course-edit-form').length != 0) { + $('.field--name-field-learning-content .item-container', context).each(function (index, item) { + courseTitleClick(item); + }); + } + + /** + * General helper function to support toggle functions. + */ + var toggleClasses = function (element) { + var $this = element, + $togglePrefix = $this.data('prefix') || 'this'; + + // If the element you need toggled is relative to the toggle, add the + // .js-this class to the parent element and "this" to the data-toggled attr. + if ($this.data('toggled') == "this") { + var $toggled = $this.closest('.js-this'); + var $toggledParent = $this.closest('.js-this').parent().closest('.js-this'); + } + else { + var $toggled = $('.' + $this.data('toggled')); + } + if ($this.attr('aria-expanded', 'true')) { + $this.attr('aria-expanded', 'true') + } + else { + $this.attr('aria-expanded', 'false') + } + + $toggled.toggleClass($togglePrefix + '-is-active'); + + if ($toggledParent) { + $toggledParent.toggleClass($togglePrefix + '-is-active'); + } + + // Remove a class on another element, if needed. + if ($this.data('remove')) { + $('.' + $this.data('remove')).removeClass($this.data('remove')); + } + }; + + /* + * Toggle Active Classes + * + * @description: + * toggle specific classes based on data-attr of clicked element + * + * @requires: + * 'js-toggle' class and a data-attr with the element to be + * toggled's class name both applied to the clicked element + * + * @example usage: + * Toggler + *
    This element's class will be toggled
    + * + */ + + $('.js-toggle', context).on('click', function (e) { + e.preventDefault(); + e.stopPropagation(); + toggleClasses($(this)); + }); + + // Toggle parent class + $('.js-toggle-parent', context).on('click', function (e) { + e.preventDefault(); + var $this = $(this); + $this.toggleClass('this-is-active'); + $this.parent().toggleClass('this-is-active'); + }); + + // Close 'user-menu' dropdown on click event outside (".l-wrap" == entire page) of it. + // This Behaviour only applies to this element. + $('body', context).on('click', function (e) { + if ($(e.target).closest(".c-user-menu").length === 0) { + $(".c-user-menu__toggle, .c-user-menu").toggleClass("this-is-active", false); + } + }); + + // Remove class from search form block if body is clicked + $('.l-main', context).on('click', function () { + $('.c-search-block').removeClass('this-is-active'); + $('.c-search-block__toggle').removeClass('this-is-active'); + }); + + // On click, add focus to input field + $('.c-search-block__toggle', context).on('click', function () { + setTimeout(function () { + $('.c-search-block__form input').focus(); + }, 100); + }); + + // Set Sortable pointer event false for safari browser + // to prevent loses drag event in safari + if ( /^((?!chrome|android).)*safari/i.test(navigator.userAgent)) { + var el = document.getElementsByClassName('sortable'); + var i; + for (i = 0; i < el.length; i++) { + if (el[i]) { + var sortable = new Sortable(el[i], { + supportPointer: false, + }); + } + } + } + } + }; + +})(jQuery, Drupal, drupalSettings, Sortable); diff --git a/web/themes/custom/perls/resources/scripts/stack.js b/web/themes/custom/perls/resources/scripts/stack.js new file mode 100644 index 0000000..209102c --- /dev/null +++ b/web/themes/custom/perls/resources/scripts/stack.js @@ -0,0 +1,33 @@ +(function ($, Drupal, drupalSettings) { + "use strict"; + + Drupal.behaviors.perlsStack = { + attach: function (context, settings) { + $(".c-stack", context) + .once("perls-stack") + .each(function () { + var $stack = $(this); + + $(".stack-advance", $stack).click(_advance); + $(".stack-restart", $stack).click(_restart); + + function _advance() { + var next = $(".top", $stack).next(); + if (next.length == 0) { + return; + } + + $(".top", $stack).removeClass("top"); + next.addClass("top"); + $stack.trigger("afterStackAdvance"); + } + function _restart() { + var item = $(".c-field__item", $stack).first(); + $(".top", $stack).removeClass("top"); + item.addClass("top"); + $stack.trigger("onStackReset"); + } + }); + }, + }; +})(jQuery, Drupal, drupalSettings); diff --git a/web/themes/custom/perls/resources/scripts/sticky.init.js b/web/themes/custom/perls/resources/scripts/sticky.init.js new file mode 100644 index 0000000..bff38af --- /dev/null +++ b/web/themes/custom/perls/resources/scripts/sticky.init.js @@ -0,0 +1,29 @@ +/** + * @file + * Initialize sticky element behavior. + * + * @see https://github.com/rgalus/sticky-js/ for Sticky-JS documentation and options. + */ + +(function (Drupal, drupalSettings) { + "use strict"; + + Drupal.behaviors.perlsSticky = { + attach: function (context, settings) { + var body = document.querySelector('body:not([data-sticky-js-init])'); + if (body) { + if (document.querySelector('body.l-page--manage-theme')) { + var toolbar = document.querySelector('nav.toolbar-bar'); + var offset = (toolbar) ? toolbar.offsetHeight + 20 : 20; + // Init a new "Sticky" class element for our color wheel. + var stickyColorWheel = new Sticky('.color-placeholder .farbtastic', { + 'marginTop': offset, + 'stickyFor': 1100 + }); + } + body.setAttribute('data-sticky-js-init', true); + } + }, + }; + })(Drupal, drupalSettings); + \ No newline at end of file diff --git a/web/themes/custom/perls/resources/scss/_base.fonts.scss b/web/themes/custom/perls/resources/scss/_base.fonts.scss new file mode 100644 index 0000000..fbcd309 --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_base.fonts.scss @@ -0,0 +1,61 @@ +/* ------------------------------------ *\ + $FONTS +\* ------------------------------------ */ + +@import url("https://fonts.googleapis.com/css?family=Open+Sans:400,400i,600,700&display=swap"); + +@font-face { + font-family: 'Circular Std'; + src: url("../fonts/CircularStd-Book.woff2") format("woff2"), url("../fonts/CircularStd-Book.woff") format("woff"); + font-weight: normal; + font-style: normal; +} + +@font-face { + font-family: 'Circular Std'; + src: url("../fonts/CircularStd-BookItalic.woff2") format("woff2"), url("../fonts/CircularStd-BookItalic.woff") format("woff"); + font-weight: normal; + font-style: italic; +} + +@font-face { + font-family: 'Circular Std'; + src: url("../fonts/CircularStd-Medium.woff2") format("woff2"), url("../fonts/CircularStd-Medium.woff") format("woff"); + font-weight: 500; + font-style: normal; +} + +@font-face { + font-family: 'Circular Std'; + src: url("../fonts/CircularStd-MediumItalic.woff2") format("woff2"), url("../fonts/CircularStd-MediumItalic.woff") format("woff"); + font-weight: 500; + font-style: italic; +} + +@font-face { + font-family: 'Circular Std'; + src: url("../fonts/CircularStd-Bold.woff2") format("woff2"), url("../fonts/CircularStd-Bold.woff") format("woff"); + font-weight: bold; + font-style: normal; +} + +@font-face { + font-family: 'Circular Std'; + src: url("../fonts/CircularStd-BoldItalic.woff2") format("woff2"), url("../fonts/CircularStd-BoldItalic.woff") format("woff"); + font-weight: bold; + font-style: italic; +} + +@font-face { + font-family: 'Circular Std'; + src: url("../fonts/CircularStd-Black.woff2") format("woff2"), url("../fonts/CircularStd-Black.woff") format("woff"); + font-weight: 900; + font-style: normal; +} + +@font-face { + font-family: 'Circular Std'; + src: url("../fonts/CircularStd-BlackItalic.woff2") format("woff2"), url("../fonts/CircularStd-BlackItalic.woff") format("woff"); + font-weight: 900; + font-style: italic; +} diff --git a/web/themes/custom/perls/resources/scss/_base.forms.scss b/web/themes/custom/perls/resources/scss/_base.forms.scss new file mode 100644 index 0000000..467cea1 --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_base.forms.scss @@ -0,0 +1,371 @@ +/* ------------------------------------ *\ + $FORMS +\* ------------------------------------ */ + +form ol, +form ul { + list-style: none; + margin-left: 0; +} + +input, +select, +textarea { + @include p; + + width: 100%; + border: none; + outline: 0; + appearance: none; + color: $c-input--text; +} + +::placeholder { + color: $c-input--placeholder; +} + +label, +.label, +.fieldset-legend { + @include o-heading--xs; + + letter-spacing: 1px; + margin-bottom: $space-quarter; + display: block; + font-style: normal; +} + +legend { + margin-bottom: $space-half; + font-weight: bold; +} + +fieldset { + border: 0; + padding: 0; + margin: 0; + min-width: 0; +} + +%input-default-styles { + background-color: $c-input--background; + display: block; + transition: $transition; + box-shadow: none; + border: $border--standard; + border-radius: $border-radius; + padding: $space-half $space; + + &:focus { + border-color: $c-secondary; + color: $c-black; + } +} + +input[type=email], +input[type=number], +input[type=search], +input[type=tel], +input[type=text], +input[type=url], +input[type=password], +input[type=date], +input[type=time], +textarea, +select { + @extend %input-default-styles; +} + +input[type=file] { + line-height: 1; +} + +select, +.select2 .select2-selection { + border: $border--light; + box-shadow: 0 0 3px $c-shadow; + width: auto; + max-width: 100%; + -webkit-appearance: none; + -moz-appearance: none; + -ms-appearance: none; + appearance: none; + cursor: pointer; + text-indent: 0.01px; + text-overflow: ellipsis; + background: $c-input--background url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 116.09 177.37'%3E%3Ctitle%3Eselect%3C/title%3E%3Cpath d='M114.9,116.47a4.1,4.1,0,0,0-5.8,0l-51,51.1L7,116.47a4.1,4.1,0,0,0-5.8,5.8l53.9,53.9a4,4,0,0,0,2.9,1.2,4.18,4.18,0,0,0,2.9-1.2l53.9-53.9A4,4,0,0,0,114.9,116.47ZM1.19,60.9a4.1,4.1,0,0,0,5.8,0L58,9.8l51.1,51.1a4.1,4.1,0,1,0,5.8-5.8L61,1.2A4,4,0,0,0,58.09,0a4.18,4.18,0,0,0-2.9,1.2L1.29,55.1A4,4,0,0,0,1.19,60.9Z' fill='%23606060'/%3E%3C/svg%3E") center right $space-half no-repeat; + background-size: 20px 20px; + padding-right: $space-double; + + &::-ms-expand { + display: none; + } +} +// Local var workaround forcing CSS Max function with all caps, because +// SASS cannot handle browser calculated unit type mixing. +$max-width-select: MAX(230px, 15vw); + +select { + overflow: hidden; + + .views-exposed-form & { + width: 100%; + } + + @include media("large") { + // Only need to override default select for inline forms. + .form-inline select { + max-width: $max-width-select; + } +} + +// Select 2 styles. +.select2.select2-container { + // Normalize styles with traditional select element. + + .selection { + border: $border--light; + border-radius: $border-radius; + box-shadow: 0 0 3px $c-shadow; + display: block; + } + + .select2-selection:not(.select2-selection--multiple) .select2-search__field { + border: $border--light; + box-shadow: 0 0 3px $c-shadow; + } + + .select2-selection { + padding-left: 20px; + padding: $space-quarter $space-double $space-quarter $space; + height: auto; + } + + .select2-selection--multiple { + @include media(">large") { + // Give it a resonable width compared to a small device screen. + max-width: $max-width-select; + } + + .select2-selection__rendered { + display: flex; + flex-wrap: wrap; + flex-direction: row; + } + + .select2-selection__choice + .select2-search__field { + border: none; + height: 0; + } + + &[aria-expanded="true"] { + .select2-selection__choice + .select2-search__field { + height: auto; + } + } + } + + &.select2-container--open .select2-selection--multiple, + &.select2-container--open .selection { + border-color: $c-secondary; + color: $c-black; + } + + &.select2-container--open.select2-container--below .selection { + border-radius: $border-radius $border-radius 0 0; + } + + .select2-selection__arrow { + display: none; + } + + .select2-selection { + border: none; + box-shadow: none; + } + + .select2-selection__rendered { + padding: 0; + vertical-align: middle; + margin: 3px 0; + } + + .select2-selection__placeholder { + color: $c-input--text; + } + + .select2-selection__clear { + margin: 0 $space-quarter; + } + + .form-item & { + .select2-selection__choice { + float: none; + overflow: hidden; + text-overflow: ellipsis; + } + } +} + +.select2-container { + .select2-dropdown { + border-color: $c-secondary; + color: $c-black; + } +} + +input[type="checkbox"], +input[type="radio"] { + outline: none; + margin: 0; + padding: 0; + height: 25px; + width: 25px; + line-height: 1; + cursor: pointer; + display: block; + float: left; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + -webkit-appearance: none; + background-color: transparent; + background-size: 25px 25px; + background-repeat: no-repeat; + border-radius: 3px; + border: $border--standard; +} + +input[type="checkbox"]:disabled, +input[type="radio"]:disabled, +input[type="checkbox"]:disabled:checked, +input[type="radio"]:disabled:checked { + background-color: $c-disabled; +} + +input[type="checkbox"] + label, +input[type="radio"] + label { + display: inline-block; + cursor: pointer; + position: relative; + width: calc(100% - 25px); + margin: 0; + padding: 0; + padding-left: $space-half; + text-transform: none; + letter-spacing: normal; + + @include p; +} + +input[type="checkbox"]:disabled + label, +input[type="radio"]:disabled + label { + color: $c-disabled; +} + +input[type="checkbox"]:checked { + background: $c-secondary url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M20.285 2l-11.285 11.567-5.286-5.011-3.714 3.716 9 8.728 15-15.285z' fill='%23ffffff'/%3E%3C/svg%3E") center center no-repeat; + background-size: 14px 14px; +} + +input[type="radio"]:checked { + background: $c-secondary url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 11 11'%3E%3Cpath d='M5.5,11A5.5,5.5,0,1,1,11,5.5,5.51,5.51,0,0,1,5.5,11Zm0-11A5.5,5.5,0,1,1,0,5.5,5.51,5.51,0,0,1,5.5,0Z' fill='%23ffffff'/%3E%3C/svg%3E") center center no-repeat; + background-size: 11px 11px; +} + +input[type="radio"] { + border-radius: $border-radius--button; +} + +/* clears the 'X' from Internet Explorer */ +input[type="search"]::-ms-clear { + display: none; + width: 0; + height: 0; +} + +input[type="search"]::-ms-reveal { + display: none; + width: 0; + height: 0; +} + +/* clears the 'X' from Chrome */ +input[type="search"]::-webkit-search-decoration, +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-results-button, +input[type="search"]::-webkit-search-results-decoration { + display: none; +} + +/* removes the blue background on Chrome's autocomplete */ +input:-webkit-autofill, +input:-webkit-autofill:hover, +input:-webkit-autofill:focus, +input:-webkit-autofill:active { + -webkit-box-shadow: 0 0 0 30px white inset; +} + +.form-item__label, +.form-item__content { + width: 100%; +} + +// Register form back button alteration. +.l-page--user-register .o-input__submit.edit-back-button { + display: none; +} + +.form-type-date { + input { + max-width: 200px; // Deemed to be a safe width to display a date or time. + border: $border--standard; + border-radius: $border-radius; + display: inline-block; + padding: $space-half $space; + margin-bottom: $space; + } +} + +/* There is an extra margin above "release date" field (podcast episode node) which needs to be removed. @todo: find a better solution */ +#edit-field-release-date-0-value, +#edit-inline-entity-form-field-release-date-0-value { + margin-top: 0; +} + +.node-form { + .media-library-item__preview { + margin-top: 20px; + } + + .field--name-field-artwork { + .details-wrapper { + p { + display: none; + } + + .rendered-entity { + margin: 0; + } + } + + .edit-button { + display: none; + } + } + + #edit-field-artwork { + p { + display: none; + } + } +} diff --git a/web/themes/custom/perls/resources/scss/_base.headings.scss b/web/themes/custom/perls/resources/scss/_base.headings.scss new file mode 100644 index 0000000..a16ceca --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_base.headings.scss @@ -0,0 +1,89 @@ +/* ------------------------------------ *\ + $HEADINGS +\* ------------------------------------ */ + +@mixin o-heading--xxl { + font-family: $ff-font--secondary; + font-size: var(--font-size-xxl, $font-size-xxl); + line-height: 1.2; + font-weight: bold; +} + +h1, +.o-heading--xxl { + @include o-heading--xxl; +} + +@mixin o-heading--xl { + font-family: $ff-font--secondary; + font-size: var(--font-size-xl, $font-size-xl); + line-height: 1.2; + font-weight: bold; +} + +h2, +.o-heading--xl { + @include o-heading--xl; +} + +@mixin o-heading--l { + font-family: $ff-font--secondary; + font-size: var(--font-size-l, $font-size-l); + line-height: 1.1; + font-weight: bold; +} + +h3, +.o-heading--l { + @include o-heading--l; +} + +@mixin o-heading--m { + font-family: $ff-font--secondary; + font-size: var(--font-size-m, $font-size-m); + line-height: 1.2; +} + +h4, +.o-heading--m { + @include o-heading--m; +} + +@mixin o-heading--m--alt { + // node--course--card title preset. + font-family: $ff-font--secondary; + font-size: var(--font-size-m, $font-size-m); + font-weight: normal; + line-height: 1.2; + text-transform: uppercase; +} + +.o-heading--m--alt { + @include o-heading--m--alt; +} + +@mixin o-heading--s { + font-family: $ff-font; + font-size: var(--font-size-s, $font-size-s); + text-transform: uppercase; + font-weight: 900; + letter-spacing: 0.04rem; +} + +h5, +.o-heading--s { + @include o-heading--s; +} + +@mixin o-heading--xs { + font-family: $ff-font; + font-size: var(--font-size-xs, $font-size-xs); + text-transform: uppercase; + font-weight: 900; + letter-spacing: 0.04rem; +} + +h6, +.o-heading--xs { + @include o-heading--xs; +} diff --git a/web/themes/custom/perls/resources/scss/_base.links.scss b/web/themes/custom/perls/resources/scss/_base.links.scss new file mode 100644 index 0000000..fa8138c --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_base.links.scss @@ -0,0 +1,37 @@ +/* ------------------------------------ *\ + $LINKS +\* ------------------------------------ */ + +a { + text-decoration: none; + color: $c-link; + transition: $transition; + + &:hover { + color: $c-link--hover; + } +} + +@mixin o-link { + font-size: var(--font-size-s, $font-size-s); + font-weight: normal; + padding: 0; + border: 0; + border-radius: 0; + color: $c-link; + text-decoration: underline; + background-color: transparent; + line-height: 1; + height: auto; + + &:hover, + &:focus { + color: $c-link--hover; + background-color: transparent; + } +} + +.link, +.o-link { + @include o-link; +} diff --git a/web/themes/custom/perls/resources/scss/_base.lists.scss b/web/themes/custom/perls/resources/scss/_base.lists.scss new file mode 100644 index 0000000..5d8b93b --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_base.lists.scss @@ -0,0 +1,26 @@ +/* ------------------------------------ *\ + $LISTS +\* ------------------------------------ */ + +ol, +ul { + margin: 0; + padding: 0; + list-style: none; +} + +/** + * Definition Lists + */ +dl { + overflow: hidden; + margin: 0 0 $space; +} + +dt { + font-weight: bold; +} + +dd { + margin-left: 0; +} diff --git a/web/themes/custom/perls/resources/scss/_base.main.scss b/web/themes/custom/perls/resources/scss/_base.main.scss new file mode 100644 index 0000000..6373feb --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_base.main.scss @@ -0,0 +1,88 @@ +/* ------------------------------------ *\ + $SITE MAIN +\* ------------------------------------ */ + +html { + overflow-x: hidden; +} + +body { + background: $c-white; + min-height: 100vh; + font: 400 100% / 1.5 $ff-font; + -webkit-text-size-adjust: 100%; + color: $c-black; + overflow-x: hidden; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + font-size: var(--font-size-s, $font-size-s); +} + +.page-overlay { + display: none; + position: fixed; + width: 100%; + height: 100%; + background: rgba(64, 64, 64, 0.65); + top: 0; + left: 0; + z-index: 1270; + + + .message-box-wrapper { + width: 300px; + height: 300px; + left: 50%; + top: 50%; + margin-top: -150px; + margin-left: -150px; + position: relative; + + .box-close-icon { + display: block; + right: -20px; + top: -20px; + position: absolute; + width: 40px; + height: 40px; + z-index: 1; + cursor: pointer; + background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40' viewBox='0 0 381 381'%3E%3Cg id='Group_1393' data-name='Group 1393' transform='translate(-309.875 -603)'%3E%3Ccircle id='Ellipse_120' data-name='Ellipse 120' cx='190.5' cy='190.5' r='190.5' transform='translate(309.875 603)' fill='%23fff'/%3E%3Cpath id='Path_328' data-name='Path 328' d='M181.287-66.544,165.126-82.706l-61.5,61.5-61.5-61.5L25.966-66.544l61.5,61.5-61.5,61.5L42.128,72.615l61.5-61.5,61.5,61.5,16.161-16.161-61.5-61.5Z' transform='translate(400.979 794.554)' fill='%23231f20'/%3E%3C/g%3E%3C/svg%3E"); + } + + .message-box { + width: 100%; + height: 100%; + position: absolute; + overflow: hidden; + + &::before { + content: " "; + position: absolute; + left: -25px; + right: 0; + top: -25px; + bottom: 0; + background-color: $c-gray; + overflow: hidden; + + /* if backdrop support: very transparent and blurred */ + @supports (-webkit-backdrop-filter: blur(30px)) or (backdrop-filter: blur(30px)) { + background-color: rgba($c-gray, 0.3); + -webkit-backdrop-filter: blur(30px); + backdrop-filter: blur(30px); + } + } + } + + .message-box-content { + position: absolute; + padding: 25px; + color: white; + + .form-item__label { + margin-bottom: 20px; + } + } + } +} diff --git a/web/themes/custom/perls/resources/scss/_base.media.scss b/web/themes/custom/perls/resources/scss/_base.media.scss new file mode 100644 index 0000000..affb876 --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_base.media.scss @@ -0,0 +1,34 @@ +/* ------------------------------------ *\ + $MEDIA ELEMENTS +\* ------------------------------------ */ + +/** + * Flexible Media + */ +img, +video, +object, +svg, +iframe { + max-width: 100%; + border: none; + display: block; +} + +img { + height: auto; +} + +svg { + max-height: 100%; +} + +picture, +picture img { + display: block; +} + +figure { + position: relative; + overflow: hidden; +} diff --git a/web/themes/custom/perls/resources/scss/_base.tables.scss b/web/themes/custom/perls/resources/scss/_base.tables.scss new file mode 100644 index 0000000..2780a17 --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_base.tables.scss @@ -0,0 +1,116 @@ +/* ------------------------------------ *\ + $TABLES +\* ------------------------------------ */ + +table { + border-collapse: collapse; + border-spacing: 0; + border: 0; + width: 100%; + position: relative; +} + +.table-caption, +caption { + // removed caption tag by twig because of Safari bug - not able calculate position properly. + // templates/views/views-view-table.html.twig + position: relative; + display: inline-block; + border-bottom: 4px solid $c-secondary; + color: $c-secondary; + text-align: left; + padding-bottom: $space-half; + font-weight: bold; +} + +th, +td { + padding: $space-half; + text-align: left; + max-width: 100%; +} + +th { + @include o-heading--s; + + color: $c-gray--dark; + background-color: $table-row--background--even; + border: $border--light; + overflow: hidden; + text-overflow: ellipsis; + + a { + color: $c-gray--dark; + display: flex; + align-items: center; + + &:hover, + &:focus { + text-decoration: none; + } + } +} + +tr { + &:nth-child(even) { + background: $table-row--background--even; + } + + &:nth-child(odd) { + background: $table-row--background--odd; + } +} + +td { + border: 1px solid transparent; + border-bottom: $border--light; + vertical-align: middle; + word-break: break-word; + + &:first-child { + border-left: $border--light; + width: auto; + } + + &:last-child { + border-right: $border--light; + } +} + +tr.selected td { + background-color: transparent; +} + +// Table dropdown button. +.js td .dropbutton-multiple { + margin-right: 0; + padding-right: 100px; +} + +.field--name-field-table, +.table-overflow, +.c-field--name-field-table { + // Sass does not have handling for the new-er min/max/clamp functions but + // you can force the css function to be used with all caps via variable. + $max-table-scroll-width: MAX(100%, 800px); + width: $max-table-scroll-width; + margin: auto; + // Everywhere except the content edit page + .l-page--path--node .node-form [data-drupal-selector="edit-content"] & { + width: auto; + } + // Many form elements use tables. Dropbuttons and overflow do not work well. + .form-item > & { + overflow: inherit; + } +} + +.paragraph--type--table, +.views-view-table--wrapper, +.table-wrapper { + overflow-x: auto; + + .l-page--path--node .node-form [data-drupal-selector="edit-content"] & { + overflow-x: inherit; + } +} diff --git a/web/themes/custom/perls/resources/scss/_base.text.scss b/web/themes/custom/perls/resources/scss/_base.text.scss new file mode 100644 index 0000000..02871f3 --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_base.text.scss @@ -0,0 +1,26 @@ +/* ------------------------------------ *\ + $TEXT ELEMENTS +\* ------------------------------------ */ + +/** + * Text-Related Elements + */ +p { + @include p; +} + +small { + font-size: 90%; +} + +/** + * Bold + */ +strong, +b { + font-weight: bold; +} + +abbr[title] { + text-decoration: none; +} diff --git a/web/themes/custom/perls/resources/scss/_entity-browser.image-browser.scss b/web/themes/custom/perls/resources/scss/_entity-browser.image-browser.scss new file mode 100644 index 0000000..22ac2eb --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_entity-browser.image-browser.scss @@ -0,0 +1,128 @@ +#entity-browser-image-browser-form .form-actions { + display: block; + margin-left: $space-half; +} + +#entity-browser-image-browser-form .is-entity-browser-submit { + margin-top: $space; +} + +.view-media-entity-browser-view section.c-view__body .c-view__content { + display: flex; + flex-wrap: wrap; + align-content: flex-start; + + .views-row { + margin: 2px 5px; + border: none; + float: left; + width: auto; + + .views-field-thumbnail__target-id { + margin: auto; + } + + .views-field-name { + margin: 0 auto; + } + + img { + box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16); + overflow: hidden; + object-fit: cover; + width: 100%; + height: 150px; + + &:hover { + box-shadow: 0 3px 6px rgba(0, 0, 0, 0.5); + } + } + + .media-info { + position: relative; + background: none; + font-size: 12px; + font-weight: 400; + line-height: 18px; + height: 40px; + overflow: hidden; + text-align: center; + color: $c-black; + max-width: 200px; + + .media-info--Image { + display: none; + } + } + } +} + +#views-exposed-form-media-entity-browser-media-browser-all .form-item-name::before, +#unsplash-wrapper .form-item-search-key::before { + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 475.08 475.08'%3E%3Ctitle%3Esearch%3C/title%3E%3Cpath d='M464.52 412.84l-97.93-97.92Q402 263.82 402 201a197.41 197.41 0 00-15.85-78.09q-15.84-37.26-42.83-64.24t-64.23-42.82a200.29 200.29 0 00-156.18 0Q85.65 31.69 58.67 58.67t-42.82 64.24a200.27 200.27 0 000 156.17q15.84 37.26 42.82 64.24t64.24 42.83A197.61 197.61 0 00201 402q62.82 0 113.92-35.4l97.93 97.64q10.27 10.84 25.69 10.85a36.54 36.54 0 0026-62.24zM291.36 291.36Q253.81 328.91 201 328.9t-90.36-37.54Q73.1 253.81 73.09 201t37.55-90.36Q148.18 73.08 201 73.09t90.36 37.55q37.56 37.53 37.55 90.36t-37.55 90.36z' fill='%23707070'/%3E%3C/svg%3E"); + position: absolute; + margin: $space-and-half+$space-quarter $space-half; + content: ".........."; + background-repeat: no-repeat; + color: rgba(0, 0, 0, 0); +} + +#views-exposed-form-media-entity-browser-media-browser-all .form-item__content input[id^=edit-name] { + padding-left: $space-double; +} + +#unsplash-wrapper input[id^=edit-search-key] { + padding-left: $space-double; +} + +#entity-browser-image-browser-form .input--file__label.o-button.o-button--file { + margin: 0; + background-size: 30px 30px; + background-repeat: no-repeat; + background-position: 50% 40%; + padding: $space 0 $space-half 0; +} +#entity-browser-image-browser-form .unsplash-image-wrapper.unsplash-selected-image { + opacity: 1; +} +#entity-browser-image-browser-form .view-media-entity-browser-view .views-row.checked::after, +#entity-browser-image-browser-form .unsplash-image-wrapper.unsplash-selected-image::after{ + background-color: white; + background-image: none; + opacity: 0.6; + content: "\2713"; + font-size: 100px; + color: #333; + top: 50%; + left: 50%; + position: absolute; + transform: translate(-50%, -50%); + pointer-events: none; + -webkit-transition: none; + transition: none; + width: 100%; + height: 100%; + text-align: center; +} + +#entity-browser-image-browser-form #edit-pictures-pager-pager-load-more { + height: 150px; + border-radius: $border-radius--card; + margin-top: 3px; +} + +#entity-browser-image-browser-form .actions-bottom, +#entity-browser-image-browser-form #edit-actions--2 { + position: fixed; + bottom: 0; + background-color: $c-admin--background; + width: 100%; + margin: 0; + padding: $space-half; + z-index: 10; +} + +#entity-browser-image-browser-form #result-images #edit-pictures, +#entity-browser-image-browser-form .view-media-entity-browser-view { + padding-bottom: $space-triple; +} diff --git a/web/themes/custom/perls/resources/scss/_generic.reset.scss b/web/themes/custom/perls/resources/scss/_generic.reset.scss new file mode 100755 index 0000000..855f5e1 --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_generic.reset.scss @@ -0,0 +1,54 @@ +/* ------------------------------------*\ + $RESET +\*------------------------------------ */ + +/* Border-Box http:/paulirish.com/2012/box-sizing-border-box-ftw/ */ +* { + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +body { + margin: 0; + padding: 0; +} + +blockquote, +body, +div, +figure, +footer, +form, +h1, +h2, +h3, +h4, +h5, +h6, +header, +html, +iframe, +label, +legend, +li, +nav, +object, +ol, +p, +section, +table, +ul { + margin: 0; + padding: 0; +} + +article, +figure, +footer, +header, +hgroup, +nav, +section { + display: block; +} diff --git a/web/themes/custom/perls/resources/scss/_layout.grids.scss b/web/themes/custom/perls/resources/scss/_layout.grids.scss new file mode 100644 index 0000000..c5910be --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_layout.grids.scss @@ -0,0 +1,232 @@ +/* ------------------------------------*\ + $GRIDS +\*------------------------------------ */ + +.l-grid { + display: grid; + grid-template-rows: auto; + grid-column-gap: $space; + grid-row-gap: $space-double; + // Prevents an auto min. width which can cause overflow issues. + grid-template-columns: minmax(0, 1fr); + + @media all and (-ms-high-contrast: none) { + display: flex; + flex-direction: row; + flex-wrap: wrap; + margin-left: -$space; + margin-right: -$space; + + > * { + margin: $space; + } + } + + &-item { + position: relative; + + &--full { + grid-column: 1 / -1; + } + } + + &--large-gutters { + grid-column-gap: $space * 4; + grid-row-gap: $space * 4; + } + + &--small-gutters { + grid-column-gap: $space; + grid-row-gap: $space; + } + + &--xsmall-gutters { + grid-column-gap: $space-half; + grid-row-gap: $space-half; + } + + &--2up { + grid-row-gap: $space; + + @include media(">large") { + grid-row-gap: $space-double; + grid-template-columns: repeat(2, 1fr); + } + + + @media all and (-ms-high-contrast: none) { + > * { + width: calc(50% - #{$space-double}); + } + } + + &--flex { + display: flex; + flex-wrap: wrap; + margin: 0 calc(#{$space} * -1); + + > * { + width: 100%; + padding-left: $space; + padding-right: $space; + margin-top: $space * 2; + + @include media(">large") { + width: 50%; + } + } + } + } + + &--3up { + @include media(">small") { + grid-template-columns: repeat(2, 1fr); + } + + + @include media(">large") { + grid-template-columns: repeat(3, 1fr); + } + + + @media all and (-ms-high-contrast: none) { + > * { + width: calc(33.333% - 40px); + } + } + } + + &--4up { + grid-template-columns: repeat(minmax(200px, 1fr)); + + @include media(">xsmall") { + grid-template-columns: repeat(2, 1fr); + } + + + @include media(">medium") { + grid-template-columns: repeat(3, 1fr); + } + + + @include media(">xlarge") { + grid-template-columns: repeat(4, 1fr); + } + + + @media all and (-ms-high-contrast: none) { + > * { + width: calc(25% - 40px); + } + } + } + + &--4up--at-medium { + grid-template-columns: repeat(2, 1fr); + + @include media(">small") { + grid-template-columns: repeat(3, 1fr); + } + + + @include media(">medium") { + grid-template-columns: repeat(4, 1fr); + } + + + @media all and (-ms-high-contrast: none) { + > * { + width: calc(25% - 40px); + } + } + } + + &--5up { + grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); + + @include media(">large") { + grid-template-columns: repeat(5, 1fr); + } + + + @media all and (-ms-high-contrast: none) { + > * { + width: calc(20% - 40px); + } + } + } + + &--50-1fr { + grid-template-columns: 50px 1fr; + } + + &--tiles ul { + display: grid; + grid-template-rows: auto; + grid-column-gap: $space; + grid-row-gap: $space-double; + grid-template-columns: repeat(minmax(200px, 1fr)); + + @media all and (-ms-high-contrast: none) { + display: flex; + flex-direction: row; + flex-wrap: wrap; + margin-left: -$space; + margin-right: -$space; + + > * { + margin: $space; + } + } + + @include media(">xsmall") { + grid-template-columns: repeat(2, 1fr); + } + + + @include media(">medium") { + grid-template-columns: repeat(3, 1fr); + } + + + @include media(">xlarge") { + grid-template-columns: repeat(4, 1fr); + } + + + @media all and (-ms-high-contrast: none) { + > * { + width: calc(25% - #{$space-double}); + } + } + } +} + +/** + * Views grid layout. + */ +.view--grid { + // This layout describes: + // mobile -> 1col in a row, tablet narrow/wide -> 2/3 cols in a row, desktop -> 4cols in a row + display: grid; + grid-auto-rows: auto; + grid-template-columns: 1fr; + grid-row-gap: $space-double; + grid-column-gap: $space-double; + justify-content: space-evenly; + padding: $space 0; + + @include media(">xsmall") { + grid-template-columns: repeat(2, 1fr); + } + + + @include media(">medium") { + grid-template-columns: repeat(3, 1fr); + } + + + @include media(">xlarge") { + grid-template-columns: repeat(4, minmax(250px, 350px)); + } +} diff --git a/web/themes/custom/perls/resources/scss/_layout.wrappers.scss b/web/themes/custom/perls/resources/scss/_layout.wrappers.scss new file mode 100644 index 0000000..5c0b5e9 --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_layout.wrappers.scss @@ -0,0 +1,60 @@ +/* ------------------------------------ *\ + $WRAPPERS & CONTAINERS +\* ------------------------------------ */ + +/** + * Wrapping element to keep content contained and centered. + */ +.l-wrap { + @include u-center-block; + + padding-left: $space; + padding-right: $space; + + @include media(">medium") { + padding-left: $space-double; + padding-right: $space-double; + } +} + +/** + * Layout containers - keep content centered and within a maximum width. Also + * adjusts left and right padding as the viewport widens. + */ + +.l-container { + max-width: $max-width; + + @include u-center-block; +} + +.l-container--xxs { + max-width: 280px; + + @include u-center-block; +} + +.l-container--xs { + // 700px + max-width: $max-width-small; + + @include u-center-block; +} + +.l-container--s { + max-width: 960px; + + @include u-center-block; +} + +.l-container--m { + max-width: 1060px; + + @include u-center-block; +} + +.l-container--l { + max-width: 1260px; + + @include u-center-block; +} diff --git a/web/themes/custom/perls/resources/scss/_modifier.colors.scss b/web/themes/custom/perls/resources/scss/_modifier.colors.scss new file mode 100644 index 0000000..99d3b10 --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_modifier.colors.scss @@ -0,0 +1,132 @@ +/* ------------------------------------ *\ + $COLOR MODIFIERS +\* ------------------------------------ */ + +/** + * Text Colors + */ +.u-color--black, +.u-color--black a { + color: $c-black; +} + +.u-color--white, +.u-color--white a { + color: $c-white; +} + +.u-color--gray, +.u-color--gray a { + color: $c-gray; +} + +.u-color--gray--light, +.u-color--gray--light a { + color: $c-gray--light; +} + +.u-color--gray--dark, +.u-color--gray--dark a { + color: $c-gray--dark; +} + +.u-color--primary, +.u-color--primary a { + color: $c-primary; +} + +.u-color--secondary, +.u-color--secondary a { + color: $c-secondary; +} + +.u-color--tertiary, +.u-color--tertiary a { + color: $c-secondary; +} + +.u-color--blue { + color: $c-primary; +} + +.u-color--blue a { + color: $c-secondary; +} + +/** + * Background Colors + */ +.u-background-color--none { + background: none; +} + +.u-background-color--black { + background-color: $c-black; +} + +.u-background-color--white { + background-color: $c-white; +} + +.u-background-color--gray { + background-color: $c-gray; +} + +.u-background-color--gray--light { + background-color: $c-gray--light; +} + +.u-background-color--gray--dark { + background-color: $c-gray--dark; +} + +.u-background-color--primary { + background-color: $c-primary; +} + +.u-background-color--secondary { + background-color: $c-secondary; +} + +.u-background-color--tertiary { + background-color: $c-tertiary; +} + +/** + * SVG Fill Colors + */ +.u-path-fill--black { + path { + fill: $c-black; + } +} + +.u-path-fill--white { + path { + fill: $c-white; + } +} + +.u-path-fill--gray { + path { + fill: $c-gray; + } +} + +.u-path-fill--primary { + path { + fill: $c-primary; + } +} + +.u-path-fill--secondary { + path { + fill: $c-secondary; + } +} + +.u-path-fill--tertiary { + path { + fill: $c-tertiary; + } +} diff --git a/web/themes/custom/perls/resources/scss/_modifier.spacing.scss b/web/themes/custom/perls/resources/scss/_modifier.spacing.scss new file mode 100644 index 0000000..2442880 --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_modifier.spacing.scss @@ -0,0 +1,25 @@ +/* ------------------------------------ *\ + $SPACING +\* ------------------------------------ */ + +$sizes: ("": $space, --quarter: calc($space / 4), --half: calc($space / 2), --and-half: $space * 1.5, --double: $space * 2, --triple: $space * 3, --quad: $space * 4, --zero: 0rem); + +$sides: ("": "", --top: "-top", --bottom: "-bottom", --left: "-left", --right: "-right"); + +@each $size_key, $size_value in $sizes { + .u-spacing#{$size_key} { + & > * + * { + margin-top: #{$size_value}; + } + } + + @each $side_key, $side_value in $sides { + .u-padding#{$size_key}#{$side_key} { + padding#{$side_value}: #{$size_value}; + } + + .u-space#{$size_key}#{$side_key} { + margin#{$side_value}: #{$size_value}; + } + } +} diff --git a/web/themes/custom/perls/resources/scss/_module.article.scss b/web/themes/custom/perls/resources/scss/_module.article.scss new file mode 100644 index 0000000..bc51468 --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_module.article.scss @@ -0,0 +1,372 @@ +/* ------------------------------------ *\ + $ARTICLE +\* ------------------------------------ */ + +/** + * Page: Manage Content Types + */ +$content-types: courses "Courses", learning-objects "Learning Objects", tip-cards "Tip Cards", flash-cards "Flashcards", quizzes "Quizzes", tags "Tags", topics "Topics", tests "Tests"; + +@each $slug, $name in $content-types { + .l-page--manage-courses-and-content-library-#{$slug} { + .c-view__banner { + flex-direction: column; + margin-right: -$space; + + @include media(">xlarge") { + margin-right: -$space-double; + } + + > * { + width: 100%; + } + + > *:last-child:not(:first-child) { + display: flex; + margin-left: 0; + padding-right: $space; + justify-content: space-between; + align-items: center; + + @include media(">xlarge") { + padding-right: $space-double; + } + + .c-view__extra-title { + @include o-heading--l; + } + } + } + + .o-button--large:not(.o-button__#{$slug}) { + display: none; + } + } +} + +/** + * Page: Discover, Following + */ +.l-page--discover, +.l-page--following { + .c-block-system-main-block { + h3 { + display: none; + } + } + + .c-view__header { + .views-display-link { + @include o-heading--l; + + color: $c-content--foreground; + margin-top: $space-double; + margin-bottom: $space-quarter; + } + + .vocabulary-tags { + .c-field--name-name { + &::before { + content: '#'; + } + } + } + } +} + +/** + * Page: Nodes full + */ +.l-page--node.perls-learner { + background-color: $c-content--background; + color: $c-content--foreground; + + .l-content { + max-width: 960px; + margin: 0 auto; + + > .c-tabs { + margin-top: $space; + } + + > .o-page-title { + display: none; + } + } + + .c-header { + margin-bottom: 0; + } + + &:not(.l-page--node-type--course) .c-node--card { + margin: $space auto; + max-width: 300px; + + .c-card { + min-height: 600px; + } + } + + .c-node--full--course { + .c-node__header { + margin: $space 0; + + > .c-node__title { + display: inline-block; + vertical-align: middle; + } + + > .flag.completed { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='77.801' height='77.72' viewBox='0 0 77.801 77.72' fill='%23333333'%3E%3Cg id='check' transform='translate(-11.057 -11.14)'%3E%3Cg id='Group'%3E%3Cpath id='Path' d='M50,88.86A38.88,38.88,0,0,0,85.6,34.4a4,4,0,1,0-7.33,3.21A30.85,30.85,0,1,1,64.58,22.8a4,4,0,1,0,3.79-7A38.86,38.86,0,1,0,50,88.86Z'/%3E%3Cpath id='Path-2' data-name='Path' d='M33.73,38.21A4,4,0,1,0,28.2,44L45.8,60.83a4,4,0,0,0,2.76,1.11h.15a4,4,0,0,0,2.82-1.32L85.36,23a4,4,0,1,0-5.95-5.35L48.35,52.19Z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E%0A"); + display: inline-block; + margin: 0 $space-half; + position: static; + transition: none; + vertical-align: middle; + } + } + + .o-bookmark-toggle { + position: relative; + float: right; + width: 35px; + height: 50px; + overflow: hidden; + padding: 0; + border-radius: 0; + cursor: pointer; + background: none; + + .o-flag--bookmark { + position: relative; + left: 0; + right: 0; + background: none; + + button { + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; + background: none; + outline: none; + z-index: 99; + } + + .ajax-progress { + display: none; + } + + & + svg { + fill: $c-secondary; + transform: scaleX(1.3) scaleY(1.4); + } + + & + svg + svg.active { + display: none; + } + + &.is-active { + & + svg { + display: none; + } + + & + svg + svg.active { + display: inline-block; + fill: $c-secondary; + transform: translateY(-5px); + transform-origin: center top; + animation: draw 1.5s linear forwards; + } + } + + &:hover { + & + svg { + transform: scaleX(1.3) scaleY(1.6); + } + + & + svg + svg { + transform: translateY(-3px) !important; + } + } + } + + svg { + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; + z-index: 1; + } + } + + .o-progress { + margin: $space-half 0; + } + } + + .c-block-system-main-block { + margin-top: 0; + } + + .c-footer { + max-width: 960px; + margin: 0 auto ($space-double * 2); + } + + .c-node__header { + @include media("xlarge") { + margin-right: -$space-double; + } + + > * { + width: 100%; + } + + > *:last-child:not(:first-child) { + display: flex; + margin-left: 0; + padding-right: $space; + justify-content: space-between; + align-items: center; + + @include media(">xlarge") { + padding-right: $space-double; + } + + .c-view__extra-title { + @include o-heading--l; + } + } + } +} + +/** + * Two-column layout. + */ +.paragraph--type--layout-two-column { + display: flex; + flex-wrap: wrap; + + .c-block-live-preview-block & { + display: block; + } + + .c-field--name-field-column-left, + .c-field--name-field-column-right { + flex: 1 50%; + flex-basis: calc(50% - #{$space}); + + .c-block-live-preview-block & { + margin: auto; + } + } + + .c-field--name-field-column-left { + margin-right: $space; + + [dir="rtl"] & { + margin-left: $space; + margin-right: 0; + } + } + + .c-field--name-field-column-right { + margin-left: $space; + + [dir="rtl"] & { + margin-right: $space; + margin-left: 0; + } + } + + @include media("xlarge") { + flex-direction: row; + padding: 0 $space-double $space-double $space-double; + } + + + &--left { + order: 1; + + @include media(">large") { + order: 0; + } + } + + &--right { + order: 0; + display: flex; + flex-wrap: nowrap; + justify-content: flex-end; + align-items: center; + margin: $space-half 0; + width: 100%; + + & > * + * { + margin-left: $space; + } + + @include media(">large") { + order: 1; + width: auto; + margin: 0 0 0 $space; + + & > * + * { + margin-left: $space-double; + } + } + } + } + + &__tabs { + width: 100%; + padding: 0 $space $space-half $space-half; + + @include media(">large") { + padding-left: $space-and-half; + } + } + + &--learner { + margin-bottom: $space-double; + box-shadow: 0 0 10px $c-shadow; + + .c-header__logo { + padding-left: $space; + text-align: left; + width: 50%; + + @include media(">large") { + padding-left: $space-double; + width: var(--l-sidebar-width, $l-sidebar-width); + } + } + + .c-header__content { + flex-direction: row; + flex-wrap: nowrap; + width: auto; + padding-bottom: 0; + justify-content: flex-end; + padding-right: $space-double; + + @include media(">xxxlarge") { + padding-right: $space-double; + padding-bottom: $space; + } + + @include media(">large") { + padding-bottom: $space; + } + + & > * + * { + @include media(">xlarge") { + margin-left: $space; + } + + @include media(">xxxlarge") { + margin-left: $space-double; + } + } + } + + @include media("<=large") { + position: relative; + display: flex; + flex-direction: column; + justify-content: flex-end; + padding-top: 0; + box-shadow: none; + + .c-header__logo { + order: 1; + padding: 0 $space $space $space; + } + + .c-header__content { + width: 100%; + order: 0; + padding: 0 $space; + padding-top: 70px; + display: flex; + flex-direction: row; + + .c-nav__learner { + width: 100%; + flex: auto; + position: absolute; + top: 0; + left: 0; + height: 50px; + align-items: center; + justify-content: center; + overflow: hidden; + + ul { + height: 100%; + display: flex; + align-items: stretch; + } + } + } + + .c-header__tabs { + order: 2; + } + } + } +} + +// Adjuct header for Learner article create/edit page +.perls-content-manager.l-page--path--node:not(.toolbar-fixed) { + .c-header__content--left { + flex: 1; + } + + .c-header__content--right { + align-self: flex-start; + } + + .c-nav__learner { + margin-top: 25px; + margin-bottom: 20px; + + ul { + justify-content: flex-end; + } + } +} + +// Adjust heading for dragable field. +table .label { + display: inline-block; +} diff --git a/web/themes/custom/perls/resources/scss/_module.sidebar.scss b/web/themes/custom/perls/resources/scss/_module.sidebar.scss new file mode 100644 index 0000000..ab486f7 --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_module.sidebar.scss @@ -0,0 +1,29 @@ +/* ------------------------------------ *\ + $SIDEBAR +\* ------------------------------------ */ + +.l-sidebar { + z-index: 2; + + &--first { + background-color: $c-admin-nav--background; + border-radius: $border-radius--card 0 0 $border-radius--card; + margin-top: $space-double; + padding: $space; + align-self: flex-start; + } + + &--second { + background: $c-admin-sidebar--background; + color: $c-admin--foreground; + padding: $space; + border-top: $border--standard; + + @include media(">xlarge") { + padding: $space-double; + border-top: 0; + border-left: $border--standard; + height: 100%; + } + } +} diff --git a/web/themes/custom/perls/resources/scss/_objects.ajax.scss b/web/themes/custom/perls/resources/scss/_objects.ajax.scss new file mode 100644 index 0000000..c71c690 --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_objects.ajax.scss @@ -0,0 +1,11 @@ +/* ------------------------------------ *\ + $AJAX +\* ------------------------------------ */ + +// Remove ajax throbber when clicking on flash_card tile, tip_card tile and quiz tile. +// This is for to maintain layout. +.c-card { + .ajax-progress-throbber { + display: none; + } +} diff --git a/web/themes/custom/perls/resources/scss/_objects.autosave.scss b/web/themes/custom/perls/resources/scss/_objects.autosave.scss new file mode 100644 index 0000000..1debf2c --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_objects.autosave.scss @@ -0,0 +1,33 @@ +/* ------------------------------------ *\ + $AUTOSAVE +\* ------------------------------------ */ + +// Dialog +.c-draft { + @include u-spacing($space-half); + + max-width: 400px; +} + +.ui-dialog { + &.ui-corner-all { + border-radius: $border-radius--card; + overflow: hidden; + } + + .ui-dialog-buttonpane { + background-color: $c-white; + } +} + + +// Buttons +.autosave-form-resume-button, +.autosave-form-reject-button { + &:hover, + &:focus, + &:active { + border: none; + font-weight: 700; + } +} diff --git a/web/themes/custom/perls/resources/scss/_objects.blocks.scss b/web/themes/custom/perls/resources/scss/_objects.blocks.scss new file mode 100644 index 0000000..9538900 --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_objects.blocks.scss @@ -0,0 +1,512 @@ +/* ------------------------------------ *\ + $BLOCKS +\* ------------------------------------ */ + +/** + * Header search block + */ +.c-search-block { + display: flex; + overflow: hidden; + + &__form { + opacity: 0; + visibility: hidden; + width: 0; + transition: opacity 0.25s $hard-ease-in; + position: relative; + right: 65px; + z-index: 0; + + form { + & > * + * { + margin-top: 0; + } + } + + .form-item-search-api-fulltext { + margin-right: $space; + } + + input { + border-radius: $border-radius--button; + } + } + + &__toggle { + color: $c-content--foreground; + background-color: transparent; + border-radius: 0; + padding: 0; + display: flex; + align-items: center; + justify-content: center; + z-index: 1; + + svg path { + transition: $transition; + } + + &:hover { + background-color: transparent; + + svg path { + fill: $c-link--hover !important; + } + } + } + + &__icon { + width: 30px; + height: 30px; + + @include media(">xlarge") { + width: 50px; + height: 50px; + } + } + + &.this-is-active { + .c-search-block__form { + opacity: 1; + visibility: visible; + width: 300px; + right: 0; + } + } +} + +/** + * System block + */ +.c-block-system, +.annotator-wrapper { + > *:not(.annotator-adder) { + margin-top: $space-double; + + &:first-child { + margin-top: 0; + } + } +} + +/** + * Live preview block + */ +.c-block-node-live-preview { + @include media(">xlarge") { + padding-top: $space * 6; + } + + .c-card__footer { + .c-field--name-field-tags { + color: #fff; + + .c-field__item::before { + content: '#'; + position: relative; + display: inline-block; + } + + .c-field__item a { + display: inline-block; + position: relative; + + &::before { + content: ''; + } + } + } + } +} + +/** + * Block Content - Text block + */ +.c-block-block-content-text-block { + margin: $space auto; + + h2, + h3 { + margin-top: 20px; + } + + p { + margin-top: 30px; + } + + ol { + margin-top: 30px; + padding-left: 30px; + list-style: decimal; + + ol { + margin-top: 30px; + list-style: lower-alpha; + } + } + + li { + margin-top: 20px; + } +} + +/** + * Block webform - Content Specific Feedback + */ +.c-block--content-specific-feedback, +.c-block-taxonomy-specific-feedback { + background-color: $c-content--background; + border-top: $border--light; + margin: $space-double auto; + + h2 { + margin: $space 0; + } + + .webform-options-display-buttons { + display: flex; + + .webform-options-display-buttons-wrapper { + margin: 0 5px 10px 5px; + } + } + + .fieldset-legend { + font-weight: normal; + padding-bottom: 10px; + font-size: $font-size-s; + } + + .form-item-content-relevant { + margin: 0; + + label { + background: $c-white; + border: 1px solid $c-link; + border-radius: 7px; + padding: $space-quarter $space-and-half; + color: $c-link; + line-height: $font-size-s; + + &:hover { + background: $c-link--hover; + color: $c-white; + + &::before { + background: $c-white; + } + } + + &::before { + background: $c-link; + content: ''; + width: 20px; + height: 19px; + background-size: 20px 19px; + display: inline-block; + vertical-align: -2px; + padding-right: 10px; + } + } + + input:checked + label, + input:hover + label { + background: $c-link; + border-color: $c-link; + color: $c-white; + + &::before { + background: $c-white; + } + } + } + + // Set the proper like and dislike icon. + input[value="-1"] { + & + label::before { + mask: url("../img/icons/icon-dislike.svg") no-repeat; + } + } + + input[value="1"] { + & + label::before { + mask: url("../img/icons/icon-like.svg") no-repeat; + } + } + + .webform-submission-information { + display: none; + } +} +// Specific margin for feedback form. +.c-block--content-specific-feedback { + .relevant-content-rate, + .webform-confirmation { + margin-top: $space; + } + + .relevant-content-rate { + .fieldset-legend.form-required::after { + display: none; + } + } +} + +/** + * Block Group/User Statistics. + */ +.c-block-user-statistics-block, +.c-block-group-statistics-block, +.c-block-node-statistics-block + { + h2 { + @include o-heading--m; + + margin-bottom: $space; + } + + > fieldset { + margin-bottom: $space; + padding-left: 25px; + + legend { + margin-bottom: 0; + } + + .fieldset-legend { + display: flex; + align-items: center; + } + + .fieldset-wrapper { + display: grid; + grid-template-columns: 100px 100px; + grid-auto-rows: 25px; + } + &.node-statistics-feedback_average > .fieldset-wrapper{ + display: block; + } + } + + // Assigning icons to categories. + $statistics-icons: + recommendation url("/themes/custom/perls/img/icons/icon-stats-recommended.svg"), + seen url("/themes/custom/perls/img/icons/icon-stats-viewed.svg"), + bookmarked url("/themes/custom/perls/img/icons/icon-stats-bookmarked.svg"), + completed url("/themes/custom/perls/img/icons/icon-stats-completed.svg"), + members url("/themes/custom/perls/img/icons/icon-stats-members.svg"), + feedback url("/themes/custom/perls/img/icons/icon-stats-feedback-submissions.svg"), + feedback_average url("/themes/custom/perls/img/icons/icon-stats-learner-feedback.svg"), + comments url("/themes/custom/perls/img/icons/icon-stats-comments-posted.svg"); + + $icon-width: 15px; + @each $name, $icon in $statistics-icons { + .group-statistics, + .node-statistics, + .user-statics { + &-#{$name} { + .fieldset-legend::before { + display: inline-block; + content: ""; + width: $icon-width; + height: $icon-width; + min-height: $icon-width; + margin: 0 10px 0 (-25px); + background-image: $icon; + background-size: $icon-width $icon-width; + background-repeat: no-repeat; + background-position: center; + } + } + } + } +} + +.c-block-node-statistics-block { + padding-top: $space-double; +} + +/** + * New dashboard start page block. + */ +.page-variant--new-dashboard .c-block { + & > h2 { + font-size: var(--font-size-l, $font-size-l); + margin-bottom: $space + $space-quarter; + } + + .dashboard-more-url { + display: none; + } + + .layout-section { + margin: 0; + + .l-grid-item:nth-child(1) > * { + margin-top: $space-double + $space-half; + } + + &:first-of-type { + margin-top: 0; + } + + // Without a min-width set by minmax for the grid column, slick carousel + // cannot properly size itself. + &.l-grid { + grid-template-columns: minmax(0, 1fr); + } + + .js-slick-slider { + margin-bottom: -$space; + + // Reset flex layout for cards + .c-node--tile .c-card { + flex: inherit; + } + } + } + + + .c-block-views-blockgroup-index-my-groups-block, + .c-block-views-blockdashboard-tags-following-tags-block { + & > h2 { + margin-bottom: 0; + } + } + + .layout-section--following .l-grid-item > div { + border-top: 1px solid #b5b3b1; + padding-top: $space-double + $space-half; + padding-bottom: $space-double + $space-half; + } + + .layout-section--my-groups { + .l-grid-item > div { + padding-bottom: $space + $space-half; + } + } + + .layout-section--following, + .layout-section--my-groups { + .l-grid-item > div { + border-bottom: 1px solid #b5b3b1; + } + } +} + +.c-block-vidyo-room-block { + h2 { + margin: $space 0; + } +} + +/** + * Related course content block. + */ +.related-course-content { + border-top: $border--light; + margin-top: $space-double; + padding-top: $space; + + &__list-item { + margin-bottom: $space-double; + width: 100%; + min-width: 250px; + flex-grow: 0; + flex-shrink: 1; + flex-basis: calc(33% - #{$space}); + + @include media(">medium") { + // Override the slick slider ruleset to prevent size inconsistency between + // stacked slider elements. + width: 33% !important; + min-width: 250px !important; + } + + [dir="rtl"] & { + margin-left: $space; + } + + .c-node--learn-link .c-node__card{ + margin-top: 0; + } + } + + &__list { + display: flex; + flex-wrap: wrap; + } + + &__list-item-content { + width: 100%; + } + + &__course-info { + margin-bottom: $space-half + $space-quarter; + } + + &__course-title { + display: inline-block; + margin-right: $space-half; + font-size: var(--font-size-m, $font-size-m); + font-weight: bold; + } + + &__course-title-text { + font-style: italic; + } + + &__course-link { + display: inline-block; + } +} +// Prevent slide box-shadow bleed on next course item slider. +.c-block-next-course-content-block { + .slick-slide { + // Hide the shadow as the base rule (off screen slides). + .c-node__card { + box-shadow: none; + } + // Show the shadow for the active slides (first visible). + &.slick-active .c-node__card { + box-shadow: $box-shadow; + } + } + // Show the shadow for siblings of the active slide (other visible slides). + .slick-slide.slick-active ~ .slick-slide .c-node__card { + box-shadow: $box-shadow; + } +} + +/** + * History block default styling. + */ +.c-block-go-back-history { + &.go-back--hidden { + height: 0; + } + // Back button is hidden by default to circumvent FOUC and unnecessary page + // height changes if the button needs to be hidden. + &.go-back--hidden .go-back-history-btn { + opacity: 0; + } + // JS removes the hidden class from the block and the button "gracefully" + // transitions opacity to being visible. + .go-back-history-btn { + opacity: 1; + } +} + +/** + * Task list block styling. + */ +.c-block-vue-componentuser-task-list { + .task__errors { + color: $c-button; + } +} + +.page--user-task-my-list.content-only h1 { + display: none; +} diff --git a/web/themes/custom/perls/resources/scss/_objects.buttons.scss b/web/themes/custom/perls/resources/scss/_objects.buttons.scss new file mode 100644 index 0000000..d1af5b8 --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_objects.buttons.scss @@ -0,0 +1,518 @@ +/* ------------------------------------ *\ + $BUTTONS +\* ------------------------------------ */ + +button { + outline: 0; + border: 0; +} + +@mixin o-button { + border: none; + border-radius: $border-radius--button; + padding: 0 $space-and-half; + outline: 0; + transition: $transition; + font-size: var(--font-size-m, $font-size-m); + font-weight: bold; + background-color: $c-button; + color: $c-button--alt; + width: auto; + cursor: pointer; + line-height: 46px; + + // Height of input fields + height: 46px; + + a { + color: $c-button--alt; + text-decoration: none; + } + + &:disabled { + background-color: $c-gray !important; + } + + &:hover, + &:focus, + a:hover, + a:focus { + color: $c-button--alt; + background-color: $c-button--hover; + } +} + +@mixin o-button--small { + border-radius: $border-radius--button; + border: 2px solid $c-button; + background-color: $c-button--alt; + color: $c-button; + padding: 0 $space; + text-decoration: none; + height: 36px; + line-height: 36px; + + @include p; + + font-weight: normal; + + &:focus, + &:hover { + background-color: $c-button--hover; + border-color: $c-button--hover; + color: $c-button--alt; + } +} + +input[type="submit"], +.field-media-image-image-paragraph input[type="submit"] { + @include o-button--small; +} + +.form-actions input[type="submit"], +input[type="submit"].button--primary, +.button, +.o-button { + @include o-button; +} + +.button--action { + @include o-button--small; +} + +input[type=submit].button--danger, +.button--danger, +.confirmation .form-actions .button--primary { + background-color: $c-gray--light; + border: $border--light; + color: $c-error; + + &:hover, + &:focus { + background-color: $c-error; + } +} + +.button--cancel, +.edit-cancel input, +#edit-cancel { + background-color: transparent; + border: none; + color: $c-secondary; + + &:hover, + &:focus { + background-color: $c-gray--light; + color: $c-secondary; + } +} + +.o-button--small { + @include o-button--small; +} + +.o-button--round { + display: block; + width: 50px; + height: 50px; + min-height: 50px; + padding: 0; + border-radius: 50px; +} + +.o-button--course { + font-size: var(--font-size-s, $font-size-s); + font-weight: 500; + border-radius: 10px; + background-color: $c-button--course; + transition: filter 0.5s; + + &:hover, + &:focus { + background-color: $c-button--course; + filter: brightness(0.9); + } +} + +.o-button--history { + width: 50px; + height: 50px; + min-height: 50px; + background: $c-secondary url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 22.48 22.9'%3E%3Ctitle%3EAsset 1%3C/title%3E%3Cpath d='M0,11.45,11.48,0l2.09,2.12L5.74,9.9H22.48v3H5.74l7.83,7.88L11.48,22.9Z' fill='%23ffffff'/%3E%3C/svg%3E") no-repeat; + background-size: 20px 20px; + background-position: center center; + box-shadow: $box-shadow; + cursor: pointer; + flex-shrink: 0; + transition: $transition; + + &:hover, + &:focus { + background-position: right 18px center; + } +} + +.o-button--back { + display: block; + position: absolute; + top: $space; + left: $space; + z-index: 3; + background: url("data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20viewBox%3D%220%200%2066.2%2066.2%22%3E%3Cdefs%3E%3Cstyle%3E.cls-1%7Bfill%3Anone%3B%7D.cls-2%7Bclip-path%3Aurl%28%23clip-path%29%3B%7D.cls-3%7Bfill%3A%23fff%3B%7D%3C%2Fstyle%3E%3CclipPath%20id%3D%22clip-path%22%20transform%3D%22translate%280%200%29%22%3E%3Crect%20class%3D%22cls-1%22%20width%3D%2266.2%22%20height%3D%2266.2%22%2F%3E%3C%2FclipPath%3E%3C%2Fdefs%3E%3Cg%20id%3D%22Layer_2%22%20data-name%3D%22Layer%202%22%3E%3Cg%20id%3D%22Layer_3%22%20data-name%3D%22Layer%203%22%3E%3Cg%20class%3D%22cls-2%22%3E%3Cg%20id%3D%22Group_1939%22%20data-name%3D%22Group%201939%22%3E%3Cpath%20id%3D%22Path_774%22%20data-name%3D%22Path%20774%22%20class%3D%22cls-3%22%20d%3D%22M33.1%2C0A33.1%2C33.1%2C0%2C1%2C0%2C66.2%2C33.1%2C33.1%2C33.1%2C0%2C0%2C0%2C33.1%2C0h0M45.56%2C34.76H25l9.84%2C9.84-1.74%2C1.73L20.28%2C33.54l12.78-12.8%2C1.74%2C1.74L25%2C32.31h20.6Z%22%20transform%3D%22translate%280%200%29%22%2F%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E") center center no-repeat; + box-shadow: $box-shadow; +} + +.o-button--more { + position: absolute; + bottom: 0; + left: 0; + cursor: pointer; + width: 100%; + text-align: center; + padding: 0; + height: 60px; + display: flex; + align-items: center; + justify-content: center; + background-color: transparent; + opacity: 1; + visibility: visible; + transition: $transition; + transform: scale(1); + + &:hover, + &:focus { + transform: scale(1.05); + } + + &::before { + content: ""; + display: block; + width: 100%; + height: 60px; + position: absolute; + bottom: 0; + left: 0; + background: transparent url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24.22 13.61'%3E%3Ctitle%3Earrow-down%3C/title%3E%3Cpath d='M12.11,13.61A1.54,1.54,0,0,1,11,13.17L.44,2.56A1.5,1.5,0,0,1,2.56.44L12.11,10,21.66.44a1.49,1.49,0,0,1,2.12,0,1.51,1.51,0,0,1,0,2.12L13.17,13.17A1.5,1.5,0,0,1,12.11,13.61Z' fill='%23ffffff'/%3E%3C/svg%3E") bottom $space-half center no-repeat; + background-size: 15px 15px; + z-index: 1; + } + + &::after { + content: ""; + display: block; + width: 100%; + height: 60px; + position: absolute; + bottom: 0; + left: 0; + z-index: 0; + opacity: 1; + visibility: visible; + transition: $transition; + } + + &.this-is-active { + &::before { + background: transparent url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24.22 13.61'%3E%3Ctitle%3Earrow-up%3C/title%3E%3Cpath d='M12.11,0a1.52,1.52,0,0,1,1.06.44L23.78,11.05a1.5,1.5,0,0,1-2.12,2.12L12.11,3.62,2.56,13.17a1.51,1.51,0,0,1-2.12,0,1.49,1.49,0,0,1,0-2.12L11.05.44A1.5,1.5,0,0,1,12.11,0Z' fill='%23ffffff'/%3E%3C/svg%3E") bottom $space-half center no-repeat; + background-size: 15px 15px; + } + + &::after { + opacity: 0; + visibility: hidden; + } + } +} + +.o-button--card { + background-color: $c-white; + border-radius: $border-radius--card; + padding: $space-half $space; + text-transform: uppercase; +} + +.o-button--inline { + display: inline-block; +} + +.o-button--large { + background-color: $c-button; + color: $c-button--alt; + height: 200px; + min-width: 200px; + padding: $space-and-half $space $space; + display: flex; + flex-direction: column; + align-items: center; + justify-content: flex-start; + border-radius: $border-radius--card; + box-shadow: $box-shadow; + text-align: center; + margin: 0 $space 0 0; + font-weight: bold; + + @include o-heading--m; + + &:hover, + &:focus { + color: $c-button--alt; + background-color: $c-button--hover; + } +} + +.o-button--file, +.field--widget-entity-browser-entity-reference .form-item-field-media-image div[class*=edit-field-media-image-entity-browser-entity-browser-open-modal] input[type=submit], +.field-media-image-image-paragraph input.entity-browser-processed[type=submit] { + background-color: $c-button !important; + color: $c-button--alt; + height: 150px; + width: 150px; + min-height: 150px; + padding: $space; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + border-radius: $border-radius--card; + box-shadow: $box-shadow; + text-align: center; + margin: 0 auto; + font-weight: bold; + border: none; + text-decoration: none; + + @include o-heading--s; + + &:hover, + &:focus { + color: $c-button--alt; + background-color: $c-button--hover !important; + } +} + +// Icon map: Uses corresponding class names. +// To change any of these, you only should swap the icon file +// in img/icons/ folder with the correct naming convention. +$icon-map: + image $icon-medium $icon-medium, + group $icon-large $icon-large, + users $icon-large $icon-large, + courses $icon-large $icon-large, + learning-objects $icon-large $icon-large, + export-csv $icon-large $icon-large, + tip-cards $icon-large $icon-large, + flash-cards $icon-large $icon-large, + quizzes $icon-large $icon-large, + tags $icon-xxlarge $icon-large, + topics $icon-large $icon-large, + podcasts $icon-large $icon-large, + tests $icon-large $icon-large, + notify-groups $icon-large $icon-large, + notify-user $icon-large $icon-large; + +@mixin o-button--add-icon($icon-name, $icon-width, $icon-height) { + &::before { + content: ""; + display: block; + width: $icon-width; + height: $icon-height; + min-height: $icon-height; + margin-bottom: $space; + background-image: url("../img/icons/icon-#{$icon-name}.svg"); + background-size: $icon-width $icon-height; + background-repeat: no-repeat; + background-position: center; + } +} + +@each $icon-name, $icon-width, $icon-height in $icon-map { + .o-button__#{$icon-name} { + @include o-button--add-icon($icon-name, $icon-width, $icon-height); + } +} + +.field--widget-entity-browser-entity-reference .form-item-field-media-image div[class*=edit-field-media-image-entity-browser-entity-browser-open-modal] input[type=submit], +.field-media-image-image-paragraph input.entity-browser-processed[type=submit] { + background-image: url("../img/icons/icon-image.svg"); + background-size: $icon-medium $icon-medium; + background-repeat: no-repeat; + background-position: 50% 20%; +} + +.button--primary { + display: inline-block; +} + +.completed-manually-button { + .o-input__submit { + display: inline-block; + } + + .button { + border: none; + font-weight: bold; + color: $c-white; + background-color: $c-gray--dark; + padding: 0 40px; + + &:disabled { + background: $c-disabled !important; + color: $c-gray; + } + } + + .manually-complete-time { + display: inline-block; + } +} + +.flag-following { + .o-button--follow { + font-size: var(--font-size-s, $font-size-s); + font-weight: 500; + padding: 0 25px; + line-height: 40px; + height: 40px; + } +} + +/* Go back arrow. */ +.go-back-history-btn { + display: block; + height: 50px; + width: 50px; + line-height: 1; + cursor: pointer; + color: transparent; + overflow: hidden; + text-indent: -9999px; + padding: 0; + border: 0; + outline: 0; + border-radius: 50%; + z-index: 2; + background: $c-secondary url("data:image/svg+xml,%3C%3Fxml version='1.0' encoding='UTF-8'%3F%3E%3Csvg id='SVGDoc' width='25' height='24' xmlns='http://www.w3.org/2000/svg' version='1.1' xmlns:xlink='http://www.w3.org/1999/xlink' xmlns:avocode='https://avocode.com/' viewBox='0 0 25 24'%3E%3Cdefs%3E%3C/defs%3E%3Cdesc%3EGenerated with Avocode.%3C/desc%3E%3Cg%3E%3Cg%3E%3Ctitle%3EPath 792%3C/title%3E%3Cpath d='M12.13584,2v0l-10.13584,10.13574v0l10.13584,10.13575v0' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='round' stroke-linecap='round' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='3'%3E%3C/path%3E%3C/g%3E%3Cg%3E%3Ctitle%3ELine 130%3C/title%3E%3Cpath d='M23.09743,11.84295h-20.6704' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='round' stroke-linecap='round' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='3'%3E%3C/path%3E%3C/g%3E%3C/g%3E%3C/svg%3E") center center no-repeat; + background-size: 15px 15px; + box-shadow: $box-shadow; + transition: $transition; + opacity: 0.7; + + @include media(">medium") { + height: 80px; + width: 80px; + background-size: 20px 20px; + } + + &:hover, + &:focus { + opacity: 1; + } +} + +@mixin o-button-form { + @include o-button--small; + + padding: 0 $space-and-half; + font-weight: 700; + background-color: $c-button; + color: $c-button--alt; + box-sizing: content-box; +} + +@mixin o-button-reverse { + @include o-button--small; + + font-weight: 700; + box-sizing: content-box; + + &:hover, + &:focus { + background-color: $c-button--hover; + border-color: $c-button--hover; + color: $c-button--alt; + } +} + +@mixin o-button-text { + @include o-button--small; + + border: none; + background-color: transparent; + color: $c-error; + font-weight: 700; + text-decoration: underline; + box-sizing: content-box; + + &:hover, + &:focus { + background-color: $c-error; + color: $c-button--alt; + } +} + +.o-button--view-tip-button { + @include card-icon-button; + + width: 93px; + height: 92px; + min-height: 92px; + background: url("data:image/svg+xml,%3C%3Fxml version='1.0' encoding='UTF-8'%3F%3E%3Csvg id='SVGDoc' width='45' height='45' xmlns='http://www.w3.org/2000/svg' version='1.1' xmlns:xlink='http://www.w3.org/1999/xlink' xmlns:avocode='https://avocode.com/' viewBox='0 0 45 45'%3E%3Cdefs%3E%3C/defs%3E%3Cdesc%3EGenerated with Avocode.%3C/desc%3E%3Cg%3E%3Cg opacity='0.6'%3E%3Ctitle%3EPath 711%3C/title%3E%3Cpath d='M19.98884,36.42796c-0.59173,0.02773 -1.04895,0.52991 -1.02121,1.12165c0.02774,0.59173 0.52992,1.04894 1.12165,1.0212h4.82142c0.59179,0.0001 1.07154,-0.47964 1.07154,-1.07143c0,-0.59179 -0.47974,-1.07153 -1.07154,-1.07153l-4.82142,0.00011c-0.03347,-0.00157 -0.06698,-0.00157 -0.10045,0zM17.84598,32.14225c-0.59174,0.02773 -1.04894,0.52991 -1.02121,1.12165c0.02773,0.59173 0.52991,1.04894 1.12165,1.0212l9.10714,0.00001c0.59179,0.0001 1.07154,-0.47963 1.07154,-1.07143c0,-0.5918 -0.47975,-1.07154 -1.07154,-1.07154l-9.10714,0.00011c-0.03347,-0.00157 -0.06698,-0.00157 -0.10045,0zM22.50001,8.57082c4.75338,0.00001 8.57142,3.79344 8.57142,8.48772c0,2.92705 -0.86213,4.04358 -1.92522,5.47433c-0.93032,1.25202 -1.99853,2.82466 -2.26004,5.32366h-3.31473c0,0 0,-7.10335 0,-8.21987c0,-1.11652 -2.14286,-1.32559 -2.14286,0c0,1.32559 0,8.21987 0,8.21987h-3.31473c-0.26151,-2.499 -1.32972,-4.07165 -2.26004,-5.32366c-1.0631,-1.43075 -1.92523,-2.54728 -1.92523,-5.47433c0,-4.69429 3.81804,-8.48771 8.57142,-8.48772zM22.5,6.42796c-5.90132,0 -10.71428,4.7683 -10.71428,10.63058c0,3.41011 1.28073,5.29348 2.36049,6.74665c1.07976,1.45312 1.92522,2.45063 1.92522,5.12277c0,0.5916 0.47961,1.07131 1.07132,1.07143h10.7144c0.59159,0 1.0713,-0.47962 1.07142,-1.07133c0.00001,-2.67225 0.84547,-3.66975 1.92523,-5.12287c1.07975,-1.45318 2.36049,-3.33654 2.36049,-6.74665c0,-5.86228 -4.81296,-10.63058 -10.71429,-10.63058zM22.5,2.14225c11.25563,0 20.35714,9.1015 20.35714,20.35714c0,11.25562 -9.10151,20.35714 -20.35714,20.35714c-4.48102,0 -8.60834,-1.45122 -11.96986,-3.90067c-0.31711,-0.22983 -0.73435,-0.26834 -1.08817,-0.10045l-6.16071,2.86273l2.86272,-6.16072c0.16789,-0.35382 0.12938,-0.77105 -0.10045,-1.08816c-2.44945,-3.36151 -3.90067,-7.48884 -3.90067,-11.96987c0,-11.25564 9.10151,-20.35714 20.35714,-20.35714zM22.49999,-0.00061c-12.41372,0.00001 -22.49999,10.08627 -22.49999,22.5c0,4.71118 1.48851,9.05735 3.96763,12.67299l-3.86719,8.30357c-0.18927,0.40794 -0.10367,0.89067 0.21432,1.20867c0.318,0.31799 0.80072,0.40359 1.20867,0.21432l8.30357,-3.86719c3.61275,2.47269 7.96851,3.96764 12.67299,3.96764c12.41372,0 22.5,-10.08627 22.5,-22.5c0,-12.41373 -10.08627,-22.49999 -22.49999,-22.5z' fill='%23ffffff' fill-opacity='1'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3EGroup 2131%3C/title%3E%3Cg opacity='0.6'%3E%3Ctitle%3EPath 711%3C/title%3E%3Cpath d='M19.98884,36.42796c-0.59173,0.02773 -1.04895,0.52991 -1.02121,1.12165c0.02774,0.59173 0.52992,1.04894 1.12165,1.0212h4.82142c0.59179,0.0001 1.07154,-0.47964 1.07154,-1.07143c0,-0.59179 -0.47974,-1.07153 -1.07154,-1.07153l-4.82142,0.00011c-0.03347,-0.00157 -0.06698,-0.00157 -0.10045,0zM17.84598,32.14225c-0.59174,0.02773 -1.04894,0.52991 -1.02121,1.12165c0.02773,0.59173 0.52991,1.04894 1.12165,1.0212l9.10714,0.00001c0.59179,0.0001 1.07154,-0.47963 1.07154,-1.07143c0,-0.5918 -0.47975,-1.07154 -1.07154,-1.07154l-9.10714,0.00011c-0.03347,-0.00157 -0.06698,-0.00157 -0.10045,0zM22.50001,8.57082c4.75338,0.00001 8.57142,3.79344 8.57142,8.48772c0,2.92705 -0.86213,4.04358 -1.92522,5.47433c-0.93032,1.25202 -1.99853,2.82466 -2.26004,5.32366h-3.31473c0,0 0,-7.10335 0,-8.21987c0,-1.11652 -2.14286,-1.32559 -2.14286,0c0,1.32559 0,8.21987 0,8.21987h-3.31473c-0.26151,-2.499 -1.32972,-4.07165 -2.26004,-5.32366c-1.0631,-1.43075 -1.92523,-2.54728 -1.92523,-5.47433c0,-4.69429 3.81804,-8.48771 8.57142,-8.48772zM22.5,6.42796c-5.90132,0 -10.71428,4.7683 -10.71428,10.63058c0,3.41011 1.28073,5.29348 2.36049,6.74665c1.07976,1.45312 1.92522,2.45063 1.92522,5.12277c0,0.5916 0.47961,1.07131 1.07132,1.07143h10.7144c0.59159,0 1.0713,-0.47962 1.07142,-1.07133c0.00001,-2.67225 0.84547,-3.66975 1.92523,-5.12287c1.07975,-1.45318 2.36049,-3.33654 2.36049,-6.74665c0,-5.86228 -4.81296,-10.63058 -10.71429,-10.63058zM22.5,2.14225c11.25563,0 20.35714,9.1015 20.35714,20.35714c0,11.25562 -9.10151,20.35714 -20.35714,20.35714c-4.48102,0 -8.60834,-1.45122 -11.96986,-3.90067c-0.31711,-0.22983 -0.73435,-0.26834 -1.08817,-0.10045l-6.16071,2.86273l2.86272,-6.16072c0.16789,-0.35382 0.12938,-0.77105 -0.10045,-1.08816c-2.44945,-3.36151 -3.90067,-7.48884 -3.90067,-11.96987c0,-11.25564 9.10151,-20.35714 20.35714,-20.35714zM22.49999,-0.00061c-12.41372,0.00001 -22.49999,10.08627 -22.49999,22.5c0,4.71118 1.48851,9.05735 3.96763,12.67299l-3.86719,8.30357c-0.18927,0.40794 -0.10367,0.89067 0.21432,1.20867c0.318,0.31799 0.80072,0.40359 1.20867,0.21432l8.30357,-3.86719c3.61275,2.47269 7.96851,3.96764 12.67299,3.96764c12.41372,0 22.5,-10.08627 22.5,-22.5c0,-12.41373 -10.08627,-22.49999 -22.49999,-22.5z' fill='%23ffffff' fill-opacity='1'%3E%3C/path%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/svg%3E") center center/93px 92px no-repeat; +} + +.o-button--view { + @include card-icon-button; + + .c-node--flash-card & { + @extend .o-button-flash-card; + } +} + +.o-button-flash-card { + @include card-icon-button; + + width: 94px; + height: 98px; + min-height: 98px; + opacity: 0.7; + background: url("data:image/svg+xml,%3C%3Fxml version='1.0' encoding='UTF-8'%3F%3E%3Csvg id='SVGDoc' width='44' height='47' xmlns='http://www.w3.org/2000/svg' version='1.1' xmlns:xlink='http://www.w3.org/1999/xlink' xmlns:avocode='https://avocode.com/' viewBox='0 0 44 47'%3E%3Cdefs%3E%3C/defs%3E%3Cdesc%3EGenerated with Avocode.%3C/desc%3E%3Cg%3E%3Cg opacity='0.6'%3E%3Ctitle%3EPath 716%3C/title%3E%3Cpath d='M43.37091,3.66132c-0.06775,-0.32617 -0.19177,-0.62988 -0.33838,-0.92236c-0.0564,-0.10126 -0.11267,-0.19122 -0.16907,-0.28125c-0.13538,-0.17993 -0.27063,-0.34869 -0.41724,-0.49493c-0.14661,-0.14624 -0.3158,-0.28125 -0.49609,-0.4162c-0.09033,-0.05621 -0.18054,-0.11249 -0.28198,-0.16864c-0.29321,-0.1463 -0.59766,-0.27002 -0.92468,-0.33746c-0.22546,-0.04504 -0.45105,-0.06757 -0.68774,-0.06757h-21.42456c-0.23682,0 -0.4624,0.02252 -0.68799,0.06757c-0.3269,0.06744 -0.64258,0.19116 -0.92456,0.33746c-0.10144,0.05615 -0.19165,0.11243 -0.28186,0.16864c-0.18042,0.12378 -0.34961,0.26996 -0.49622,0.4162c-0.34949,0.34869 -0.63135,0.78748 -0.80054,1.25989c-0.12402,0.34875 -0.19165,0.7312 -0.19165,1.12482h1.12756c0,-0.40491 0.11267,-0.79858 0.31567,-1.12482c0.38342,-0.67493 1.1051,-1.12488 1.93958,-1.12488h21.42456c1.24036,0 2.25525,1.01239 2.25525,2.24969v35.99567c0,1.23737 -1.01489,2.24976 -2.25525,2.24976h-12.40369c0,0.40503 -0.11279,0.79865 -0.3158,1.12488h12.71948c0.23669,0 0.46228,-0.02246 0.68774,-0.0675c0.32703,-0.0675 0.63147,-0.19122 0.92468,-0.33746c0.10144,-0.05627 0.19165,-0.11243 0.28198,-0.1687c0.1803,-0.13495 0.34949,-0.26996 0.49609,-0.4162c0.14661,-0.14624 0.28186,-0.315 0.41724,-0.49493c0.0564,-0.08997 0.11267,-0.18005 0.16907,-0.28125c0.14661,-0.29242 0.27063,-0.59619 0.33838,-0.92236c0.04504,-0.22498 0.06763,-0.45001 0.06763,-0.68622v-35.99567c0,-0.23621 -0.02258,-0.46118 -0.06763,-0.68616z' fill='%23ffffff' fill-opacity='1'%3E%3C/path%3E%3Cpath d='M43.37091,3.66132c-0.06775,-0.32617 -0.19177,-0.62988 -0.33838,-0.92236c-0.0564,-0.10126 -0.11267,-0.19122 -0.16907,-0.28125c-0.13538,-0.17993 -0.27063,-0.34869 -0.41724,-0.49493c-0.14661,-0.14624 -0.3158,-0.28125 -0.49609,-0.4162c-0.09033,-0.05621 -0.18054,-0.11249 -0.28198,-0.16864c-0.29321,-0.1463 -0.59766,-0.27002 -0.92468,-0.33746c-0.22546,-0.04504 -0.45105,-0.06757 -0.68774,-0.06757h-21.42456c-0.23682,0 -0.4624,0.02252 -0.68799,0.06757c-0.3269,0.06744 -0.64258,0.19116 -0.92456,0.33746c-0.10144,0.05615 -0.19165,0.11243 -0.28186,0.16864c-0.18042,0.12378 -0.34961,0.26996 -0.49622,0.4162c-0.34949,0.34869 -0.63135,0.78748 -0.80054,1.25989c-0.12402,0.34875 -0.19165,0.7312 -0.19165,1.12482h1.12756c0,-0.40491 0.11267,-0.79858 0.31567,-1.12482c0.38342,-0.67493 1.1051,-1.12488 1.93958,-1.12488h21.42456c1.24036,0 2.25525,1.01239 2.25525,2.24969v35.99567c0,1.23737 -1.01489,2.24976 -2.25525,2.24976h-12.40369c0,0.40503 -0.11279,0.79865 -0.3158,1.12488h12.71948c0.23669,0 0.46228,-0.02246 0.68774,-0.0675c0.32703,-0.0675 0.63147,-0.19122 0.92468,-0.33746c0.10144,-0.05627 0.19165,-0.11243 0.28198,-0.1687c0.1803,-0.13495 0.34949,-0.26996 0.49609,-0.4162c0.14661,-0.14624 0.28186,-0.315 0.41724,-0.49493c0.0564,-0.08997 0.11267,-0.18005 0.16907,-0.28125c0.14661,-0.29242 0.27063,-0.59619 0.33838,-0.92236c0.04504,-0.22498 0.06763,-0.45001 0.06763,-0.68622v-35.99567c0,-0.23621 -0.02258,-0.46118 -0.06763,-0.68616z' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='miter' stroke-linecap='butt' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='0.5'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3EPath 719%3C/title%3E%3Cpath d='M34.13678,19.94879c-0.98096,2.23267 -2.98816,3.80005 -5.32227,4.22858c-0.37207,0.06763 -0.74426,0.11273 -1.12756,0.11273c-0.06775,0.01123 -0.13538,0.01123 -0.203,0.01123h-0.06775c-3.61951,-0.01123 -6.73181,-2.70624 -7.25049,-6.29205l-0.07898,-0.47357v0h-1.9845c-0.4624,0.01129 -0.30444,-0.33826 -0.30444,-0.33826v0l2.66113,-4.88257c0.01123,-0.02258 0.06763,-0.07898 0.11279,-0.07898c0.0564,-0.02252 0.18042,0.06769 0.25928,0.18048l2.7063,4.87122c-0.01123,0.14661 -0.13538,0.24811 -0.3158,0.24811h-2.02966v0l0.13538,0.67651c0.59753,2.87549 3.15723,4.96155 6.07776,4.96155h0.28198c0.3833,-0.01129 0.76672,-0.0451 1.12756,-0.12402c1.89441,-0.38342 3.48425,-1.66895 4.26233,-3.46179c0.12402,-0.22552 0.39465,-0.33826 0.6427,-0.25934c0.30457,0.07892 0.47363,0.39465 0.41724,0.62018z' fill='%23ffffff' fill-opacity='1'%3E%3C/path%3E%3Cpath d='M34.13678,19.94879c-0.98096,2.23267 -2.98816,3.80005 -5.32227,4.22858c-0.37207,0.06763 -0.74426,0.11273 -1.12756,0.11273c-0.06775,0.01123 -0.13538,0.01123 -0.203,0.01123h-0.06775c-3.61951,-0.01123 -6.73181,-2.70624 -7.25049,-6.29205l-0.07898,-0.47357v0h-1.9845c-0.4624,0.01129 -0.30444,-0.33826 -0.30444,-0.33826v0l2.66113,-4.88257c0.01123,-0.02258 0.06763,-0.07898 0.11279,-0.07898c0.0564,-0.02252 0.18042,0.06769 0.25928,0.18048l2.7063,4.87122c-0.01123,0.14661 -0.13538,0.24811 -0.3158,0.24811h-2.02966v0l0.13538,0.67651c0.59753,2.87549 3.15723,4.96155 6.07776,4.96155h0.28198c0.3833,-0.01129 0.76672,-0.0451 1.12756,-0.12402c1.89441,-0.38342 3.48425,-1.66895 4.26233,-3.46179c0.12402,-0.22552 0.39465,-0.33826 0.6427,-0.25934c0.30457,0.07892 0.47363,0.39465 0.41724,0.62018z' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='miter' stroke-linecap='butt' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='0.5'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3EPath 718%3C/title%3E%3Cpath d='M28.87872,21.59094v-14.30133c0,-0.23206 -0.02258,-0.45312 -0.06763,-0.67419c-0.06763,-0.32043 -0.19177,-0.6189 -0.33838,-0.90625c-0.0564,-0.09943 -0.11267,-0.18793 -0.16907,-0.27637c-0.13538,-0.17676 -0.27063,-0.34253 -0.41724,-0.48627c-0.14661,-0.14374 -0.3158,-0.27631 -0.49609,-0.409c-0.09021,-0.05518 -0.18054,-0.11041 -0.28198,-0.16571c-0.29321,-0.14368 -0.59766,-0.26526 -0.92456,-0.33154c-0.22559,-0.04425 -0.45117,-0.06635 -0.68787,-0.06635h-21.42456c-0.23682,0 -0.4624,0.02209 -0.68787,0.06635c-0.32703,0.06628 -0.6427,0.18787 -0.92468,0.33154c-0.10144,0.0553 -0.19165,0.11053 -0.28186,0.16571c-0.18042,0.12164 -0.34961,0.26526 -0.49609,0.409c-0.62024,0.60791 -0.99231,1.42584 -0.99231,2.34308v35.36755c0,0.91742 0.37207,1.73523 0.99231,2.3432c0.14648,0.14362 0.31567,0.28735 0.49609,0.40894c0.09021,0.05524 0.18042,0.11053 0.28186,0.16571c0.28198,0.14368 0.59766,0.26532 0.92468,0.3316c0.22546,0.04419 0.45105,0.06628 0.68787,0.06628h21.42456c0.23669,0 0.46228,-0.02209 0.68787,-0.06628c0.3269,-0.06628 0.63135,-0.18793 0.92456,-0.3316c0.10144,-0.05518 0.19177,-0.11047 0.28198,-0.16571c0.1803,-0.13269 0.34949,-0.26532 0.49609,-0.40894c0.14661,-0.14368 0.28186,-0.30957 0.41724,-0.48633c0.0564,-0.08844 0.11267,-0.17682 0.16907,-0.27631c0.07898,-0.15479 0.14661,-0.30951 0.203,-0.47534c0.03381,-0.07727 0.0564,-0.14362 0.07898,-0.2099c0.02246,-0.06641 0.04504,-0.14374 0.0564,-0.22107c0.04504,-0.22107 0.06763,-0.44214 0.06763,-0.67426v-16.99847c-0.36084,0.06628 -0.74426,0.09949 -1.12756,0.09949v16.89899c0,0.39801 -0.11279,0.78479 -0.3158,1.10522c-0.3833,0.66321 -1.1051,1.10529 -1.93945,1.10529h-21.42456c-1.24048,0 -2.25525,-0.99463 -2.25525,-2.21051v-35.36755c0,-1.2157 1.01477,-2.21045 2.25525,-2.21045h21.42456c1.24036,0 2.25525,0.99475 2.25525,2.21045v14.46716c0.3833,-0.01105 0.76672,-0.06628 1.12756,-0.16583z' fill='%23ffffff' fill-opacity='1'%3E%3C/path%3E%3Cpath d='M28.87872,21.59094v-14.30133c0,-0.23206 -0.02258,-0.45312 -0.06763,-0.67419c-0.06763,-0.32043 -0.19177,-0.6189 -0.33838,-0.90625c-0.0564,-0.09943 -0.11267,-0.18793 -0.16907,-0.27637c-0.13538,-0.17676 -0.27063,-0.34253 -0.41724,-0.48627c-0.14661,-0.14374 -0.3158,-0.27631 -0.49609,-0.409c-0.09021,-0.05518 -0.18054,-0.11041 -0.28198,-0.16571c-0.29321,-0.14368 -0.59766,-0.26526 -0.92456,-0.33154c-0.22559,-0.04425 -0.45117,-0.06635 -0.68787,-0.06635h-21.42456c-0.23682,0 -0.4624,0.02209 -0.68787,0.06635c-0.32703,0.06628 -0.6427,0.18787 -0.92468,0.33154c-0.10144,0.0553 -0.19165,0.11053 -0.28186,0.16571c-0.18042,0.12164 -0.34961,0.26526 -0.49609,0.409c-0.62024,0.60791 -0.99231,1.42584 -0.99231,2.34308v35.36755c0,0.91742 0.37207,1.73523 0.99231,2.3432c0.14648,0.14362 0.31567,0.28735 0.49609,0.40894c0.09021,0.05524 0.18042,0.11053 0.28186,0.16571c0.28198,0.14368 0.59766,0.26532 0.92468,0.3316c0.22546,0.04419 0.45105,0.06628 0.68787,0.06628h21.42456c0.23669,0 0.46228,-0.02209 0.68787,-0.06628c0.3269,-0.06628 0.63135,-0.18793 0.92456,-0.3316c0.10144,-0.05518 0.19177,-0.11047 0.28198,-0.16571c0.1803,-0.13269 0.34949,-0.26532 0.49609,-0.40894c0.14661,-0.14368 0.28186,-0.30957 0.41724,-0.48633c0.0564,-0.08844 0.11267,-0.17682 0.16907,-0.27631c0.07898,-0.15479 0.14661,-0.30951 0.203,-0.47534c0.03381,-0.07727 0.0564,-0.14362 0.07898,-0.2099c0.02246,-0.06641 0.04504,-0.14374 0.0564,-0.22107c0.04504,-0.22107 0.06763,-0.44214 0.06763,-0.67426v-16.99847c-0.36084,0.06628 -0.74426,0.09949 -1.12756,0.09949v16.89899c0,0.39801 -0.11279,0.78479 -0.3158,1.10522c-0.3833,0.66321 -1.1051,1.10529 -1.93945,1.10529h-21.42456c-1.24048,0 -2.25525,-0.99463 -2.25525,-2.21051v-35.36755c0,-1.2157 1.01477,-2.21045 2.25525,-2.21045h21.42456c1.24036,0 2.25525,0.99475 2.25525,2.21045v14.46716c0.3833,-0.01105 0.76672,-0.06628 1.12756,-0.16583z' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='miter' stroke-linecap='butt' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='0.5'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3EGroup 2066%3C/title%3E%3Cg opacity='0.6'%3E%3Ctitle%3EGroup 2066%3C/title%3E%3Cg opacity='0.6'%3E%3Ctitle%3EPath 719%3C/title%3E%3Cpath d='M34.13678,19.94879c-0.98096,2.23267 -2.98816,3.80005 -5.32227,4.22858c-0.37207,0.06763 -0.74426,0.11273 -1.12756,0.11273c-0.06775,0.01123 -0.13538,0.01123 -0.203,0.01123h-0.06775c-3.61951,-0.01123 -6.73181,-2.70624 -7.25049,-6.29205l-0.07898,-0.47357v0h-1.9845c-0.4624,0.01129 -0.30444,-0.33826 -0.30444,-0.33826v0l2.66113,-4.88257c0.01123,-0.02258 0.06763,-0.07898 0.11279,-0.07898c0.0564,-0.02252 0.18042,0.06769 0.25928,0.18048l2.7063,4.87122c-0.01123,0.14661 -0.13538,0.24811 -0.3158,0.24811h-2.02966v0l0.13538,0.67651c0.59753,2.87549 3.15723,4.96155 6.07776,4.96155h0.28198c0.3833,-0.01129 0.76672,-0.0451 1.12756,-0.12402c1.89441,-0.38342 3.48425,-1.66895 4.26233,-3.46179c0.12402,-0.22552 0.39465,-0.33826 0.6427,-0.25934c0.30457,0.07892 0.47363,0.39465 0.41724,0.62018z' fill='%23ffffff' fill-opacity='1'%3E%3C/path%3E%3Cpath d='M34.13678,19.94879c-0.98096,2.23267 -2.98816,3.80005 -5.32227,4.22858c-0.37207,0.06763 -0.74426,0.11273 -1.12756,0.11273c-0.06775,0.01123 -0.13538,0.01123 -0.203,0.01123h-0.06775c-3.61951,-0.01123 -6.73181,-2.70624 -7.25049,-6.29205l-0.07898,-0.47357v0h-1.9845c-0.4624,0.01129 -0.30444,-0.33826 -0.30444,-0.33826v0l2.66113,-4.88257c0.01123,-0.02258 0.06763,-0.07898 0.11279,-0.07898c0.0564,-0.02252 0.18042,0.06769 0.25928,0.18048l2.7063,4.87122c-0.01123,0.14661 -0.13538,0.24811 -0.3158,0.24811h-2.02966v0l0.13538,0.67651c0.59753,2.87549 3.15723,4.96155 6.07776,4.96155h0.28198c0.3833,-0.01129 0.76672,-0.0451 1.12756,-0.12402c1.89441,-0.38342 3.48425,-1.66895 4.26233,-3.46179c0.12402,-0.22552 0.39465,-0.33826 0.6427,-0.25934c0.30457,0.07892 0.47363,0.39465 0.41724,0.62018z' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='miter' stroke-linecap='butt' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='0.5'%3E%3C/path%3E%3C/g%3E%3C/g%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3EGroup 2132%3C/title%3E%3Cg opacity='0.6'%3E%3Ctitle%3ERectangle 940%3C/title%3E%3Cg opacity='0.6'%3E%3Ctitle%3EPath 714%3C/title%3E%3Cpath d='M33.68463,19.32599c-0.24805,-0.07892 -0.51868,0.03381 -0.6427,0.25934c-0.77808,1.79285 -2.36792,3.07837 -4.26233,3.46179c-0.36084,0.07892 -0.74426,0.11273 -1.12756,0.12402h-0.28198c-2.92053,0 -5.48022,-2.08606 -6.07776,-4.96155l-0.13538,-0.67651v0h2.02966c0.18042,0 0.30457,-0.1015 0.3158,-0.24811l-2.7063,-4.87122c-0.07886,-0.11279 -0.20288,-0.203 -0.25928,-0.18048c-0.04517,0 -0.10156,0.0564 -0.11279,0.07898l-2.66113,4.88257v0c0,0 -0.15796,0.34955 0.30444,0.33826h1.9845v0l0.07898,0.47357c0.51868,3.58582 3.63098,6.28082 7.25049,6.29205h0.06775c0.06763,0 0.13525,0 0.203,-0.01123c0.3833,0 0.75549,-0.0451 1.12756,-0.11273c2.33411,-0.42853 4.34131,-1.99591 5.32227,-4.22858c0.0564,-0.22552 -0.11267,-0.54126 -0.41724,-0.62018z' fill='%23ffffff' fill-opacity='1'%3E%3C/path%3E%3Cpath d='M33.68463,19.32599c-0.24805,-0.07892 -0.51868,0.03381 -0.6427,0.25934c-0.77808,1.79285 -2.36792,3.07837 -4.26233,3.46179c-0.36084,0.07892 -0.74426,0.11273 -1.12756,0.12402h-0.28198c-2.92053,0 -5.48022,-2.08606 -6.07776,-4.96155l-0.13538,-0.67651v0h2.02966c0.18042,0 0.30457,-0.1015 0.3158,-0.24811l-2.7063,-4.87122c-0.07886,-0.11279 -0.20288,-0.203 -0.25928,-0.18048c-0.04517,0 -0.10156,0.0564 -0.11279,0.07898l-2.66113,4.88257v0c0,0 -0.15796,0.34955 0.30444,0.33826h1.9845v0l0.07898,0.47357c0.51868,3.58582 3.63098,6.28082 7.25049,6.29205h0.06775c0.06763,0 0.13525,0 0.203,-0.01123c0.3833,0 0.75549,-0.0451 1.12756,-0.11273c2.33411,-0.42853 4.34131,-1.99591 5.32227,-4.22858c0.0564,-0.22552 -0.11267,-0.54126 -0.41724,-0.62018z' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='miter' stroke-linecap='butt' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='0.5'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3EPath 715%3C/title%3E%3Cpath d='M43.43854,4.34747v0v35.99567c0,0.23621 -0.02258,0.46124 -0.06763,0.68622c-0.06775,0.32617 -0.19177,0.62994 -0.33838,0.92236c-0.0564,0.1012 -0.11267,0.19128 -0.16907,0.28125c-0.12402,0.17993 -0.2594,0.34869 -0.41724,0.49493c-0.14661,0.14624 -0.3158,0.28125 -0.49609,0.4162c-0.09033,0.05627 -0.18054,0.11243 -0.28198,0.1687c-0.29321,0.14624 -0.59766,0.26996 -0.92468,0.33746c-0.22546,0.04504 -0.45105,0.0675 -0.68774,0.0675h-12.71948c0.203,-0.32623 0.3158,-0.71985 0.3158,-1.12488v-17.19922c0.3833,0 0.76672,-0.03363 1.12756,-0.1012v17.30042v0h11.27612c1.24036,0 2.25525,-1.01239 2.25525,-2.24976v-35.99567c0,-1.2373 -1.01489,-2.24969 -2.25525,-2.24969h-21.42456c-0.83447,0 -1.31396,1.09131 -1.69727,1.76624h8.70508c0.23669,0 0.4624,0.02252 0.68787,0.06757c0.32703,0.0675 0.63147,0.19122 0.92468,0.3374c0.10144,0.05627 0.19165,0.11255 0.28186,0.1687c0.1803,0.12378 0.34949,0.25879 0.49609,0.41626c0.15796,0.14618 0.29321,0.31494 0.41724,0.49493c0.0564,0.08997 0.11267,0.17999 0.16919,0.28119c0.14661,0.29248 0.09607,0.12097 0.1637,0.44714c0.04504,0.22504 0,0.28381 0,0.52002v15.2644c-0.36084,0.10132 -0.74426,0.15747 -1.12756,0.16876v-15.43317c0,-1.23737 -1.01489,-2.24976 -2.25525,-2.24976h-10.14844c0,-0.39362 0.06763,-0.77606 0.19165,-1.12482c0.16919,-0.47241 0.45105,-0.91119 0.80054,-1.25989c0.14661,-0.15741 0.3158,-0.29242 0.49622,-0.4162c0.09021,-0.05621 0.18042,-0.11249 0.28186,-0.16864c0.28198,-0.1463 0.59766,-0.27002 0.92456,-0.33746c0.22559,-0.04504 0.45117,-0.06757 0.68799,-0.06757h21.42456c0.23669,0 0.46228,0.02252 0.68774,0.06757c0.32703,0.06744 0.63147,0.19116 0.92468,0.33746c0.10144,0.05615 0.19165,0.11243 0.28198,0.16864c0.1803,0.12378 0.34949,0.25879 0.49609,0.4162c0.15784,0.14624 0.29321,0.315 0.41724,0.49493c0.0564,0.09003 0.11267,0.17999 0.16907,0.28125c0.14661,0.29248 0.27063,0.59619 0.33838,0.92236c0.04504,0.22498 0.06763,0.44995 0.06763,0.68616z' fill='%23ffffff' fill-opacity='1'%3E%3C/path%3E%3Cpath d='M43.43854,4.34747v0v35.99567c0,0.23621 -0.02258,0.46124 -0.06763,0.68622c-0.06775,0.32617 -0.19177,0.62994 -0.33838,0.92236c-0.0564,0.1012 -0.11267,0.19128 -0.16907,0.28125c-0.12402,0.17993 -0.2594,0.34869 -0.41724,0.49493c-0.14661,0.14624 -0.3158,0.28125 -0.49609,0.4162c-0.09033,0.05627 -0.18054,0.11243 -0.28198,0.1687c-0.29321,0.14624 -0.59766,0.26996 -0.92468,0.33746c-0.22546,0.04504 -0.45105,0.0675 -0.68774,0.0675h-12.71948c0.203,-0.32623 0.3158,-0.71985 0.3158,-1.12488v-17.19922c0.3833,0 0.76672,-0.03363 1.12756,-0.1012v17.30042v0h11.27612c1.24036,0 2.25525,-1.01239 2.25525,-2.24976v-35.99567c0,-1.2373 -1.01489,-2.24969 -2.25525,-2.24969h-21.42456c-0.83447,0 -1.31396,1.09131 -1.69727,1.76624h8.70508c0.23669,0 0.4624,0.02252 0.68787,0.06757c0.32703,0.0675 0.63147,0.19122 0.92468,0.3374c0.10144,0.05627 0.19165,0.11255 0.28186,0.1687c0.1803,0.12378 0.34949,0.25879 0.49609,0.41626c0.15796,0.14618 0.29321,0.31494 0.41724,0.49493c0.0564,0.08997 0.11267,0.17999 0.16919,0.28119c0.14661,0.29248 0.09607,0.12097 0.1637,0.44714c0.04504,0.22504 0,0.28381 0,0.52002v15.2644c-0.36084,0.10132 -0.74426,0.15747 -1.12756,0.16876v-15.43317c0,-1.23737 -1.01489,-2.24976 -2.25525,-2.24976h-10.14844c0,-0.39362 0.06763,-0.77606 0.19165,-1.12482c0.16919,-0.47241 0.45105,-0.91119 0.80054,-1.25989c0.14661,-0.15741 0.3158,-0.29242 0.49622,-0.4162c0.09021,-0.05621 0.18042,-0.11249 0.28186,-0.16864c0.28198,-0.1463 0.59766,-0.27002 0.92456,-0.33746c0.22559,-0.04504 0.45117,-0.06757 0.68799,-0.06757h21.42456c0.23669,0 0.46228,0.02252 0.68774,0.06757c0.32703,0.06744 0.63147,0.19116 0.92468,0.33746c0.10144,0.05615 0.19165,0.11243 0.28198,0.16864c0.1803,0.12378 0.34949,0.25879 0.49609,0.4162c0.15784,0.14624 0.29321,0.315 0.41724,0.49493c0.0564,0.09003 0.11267,0.17999 0.16907,0.28125c0.14661,0.29248 0.27063,0.59619 0.33838,0.92236c0.04504,0.22498 0.06763,0.44995 0.06763,0.68616z' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='miter' stroke-linecap='butt' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='0.5'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3EPath 716%3C/title%3E%3Cpath d='M43.37091,3.66132c-0.06775,-0.32617 -0.19177,-0.62988 -0.33838,-0.92236c-0.0564,-0.10126 -0.11267,-0.19122 -0.16907,-0.28125c-0.13538,-0.17993 -0.27063,-0.34869 -0.41724,-0.49493c-0.14661,-0.14624 -0.3158,-0.28125 -0.49609,-0.4162c-0.09033,-0.05621 -0.18054,-0.11249 -0.28198,-0.16864c-0.29321,-0.1463 -0.59766,-0.27002 -0.92468,-0.33746c-0.22546,-0.04504 -0.45105,-0.06757 -0.68774,-0.06757h-21.42456c-0.23682,0 -0.4624,0.02252 -0.68799,0.06757c-0.3269,0.06744 -0.64258,0.19116 -0.92456,0.33746c-0.10144,0.05615 -0.19165,0.11243 -0.28186,0.16864c-0.18042,0.12378 -0.34961,0.26996 -0.49622,0.4162c-0.34949,0.34869 -0.63135,0.78748 -0.80054,1.25989c-0.12402,0.34875 -0.19165,0.7312 -0.19165,1.12482h1.12756c0,-0.40491 0.11267,-0.79858 0.31567,-1.12482c0.38342,-0.67493 1.1051,-1.12488 1.93958,-1.12488h21.42456c1.24036,0 2.25525,1.01239 2.25525,2.24969v35.99567c0,1.23737 -1.01489,2.24976 -2.25525,2.24976h-12.40369c0,0.40503 -0.11279,0.79865 -0.3158,1.12488h12.71948c0.23669,0 0.46228,-0.02246 0.68774,-0.0675c0.32703,-0.0675 0.63147,-0.19122 0.92468,-0.33746c0.10144,-0.05627 0.19165,-0.11243 0.28198,-0.1687c0.1803,-0.13495 0.34949,-0.26996 0.49609,-0.4162c0.14661,-0.14624 0.28186,-0.315 0.41724,-0.49493c0.0564,-0.08997 0.11267,-0.18005 0.16907,-0.28125c0.14661,-0.29242 0.27063,-0.59619 0.33838,-0.92236c0.04504,-0.22498 0.06763,-0.45001 0.06763,-0.68622v-35.99567c0,-0.23621 -0.02258,-0.46118 -0.06763,-0.68616z' fill='%23ffffff' fill-opacity='1'%3E%3C/path%3E%3Cpath d='M43.37091,3.66132c-0.06775,-0.32617 -0.19177,-0.62988 -0.33838,-0.92236c-0.0564,-0.10126 -0.11267,-0.19122 -0.16907,-0.28125c-0.13538,-0.17993 -0.27063,-0.34869 -0.41724,-0.49493c-0.14661,-0.14624 -0.3158,-0.28125 -0.49609,-0.4162c-0.09033,-0.05621 -0.18054,-0.11249 -0.28198,-0.16864c-0.29321,-0.1463 -0.59766,-0.27002 -0.92468,-0.33746c-0.22546,-0.04504 -0.45105,-0.06757 -0.68774,-0.06757h-21.42456c-0.23682,0 -0.4624,0.02252 -0.68799,0.06757c-0.3269,0.06744 -0.64258,0.19116 -0.92456,0.33746c-0.10144,0.05615 -0.19165,0.11243 -0.28186,0.16864c-0.18042,0.12378 -0.34961,0.26996 -0.49622,0.4162c-0.34949,0.34869 -0.63135,0.78748 -0.80054,1.25989c-0.12402,0.34875 -0.19165,0.7312 -0.19165,1.12482h1.12756c0,-0.40491 0.11267,-0.79858 0.31567,-1.12482c0.38342,-0.67493 1.1051,-1.12488 1.93958,-1.12488h21.42456c1.24036,0 2.25525,1.01239 2.25525,2.24969v35.99567c0,1.23737 -1.01489,2.24976 -2.25525,2.24976h-12.40369c0,0.40503 -0.11279,0.79865 -0.3158,1.12488h12.71948c0.23669,0 0.46228,-0.02246 0.68774,-0.0675c0.32703,-0.0675 0.63147,-0.19122 0.92468,-0.33746c0.10144,-0.05627 0.19165,-0.11243 0.28198,-0.1687c0.1803,-0.13495 0.34949,-0.26996 0.49609,-0.4162c0.14661,-0.14624 0.28186,-0.315 0.41724,-0.49493c0.0564,-0.08997 0.11267,-0.18005 0.16907,-0.28125c0.14661,-0.29242 0.27063,-0.59619 0.33838,-0.92236c0.04504,-0.22498 0.06763,-0.45001 0.06763,-0.68622v-35.99567c0,-0.23621 -0.02258,-0.46118 -0.06763,-0.68616z' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='miter' stroke-linecap='butt' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='0.5'%3E%3C/path%3E%3C/g%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3ERectangle 941%3C/title%3E%3Cg opacity='0.6'%3E%3Ctitle%3EPath 717%3C/title%3E%3Cpath d='M28.87872,21.43719v0v-14.14758c0,-0.23206 -0.02258,-0.45312 -0.06763,-0.67419c-0.06763,-0.32043 -0.19177,-0.6189 -0.33838,-0.90625c-0.0564,-0.09943 -0.11267,-0.18793 -0.16907,-0.27637c-0.12402,-0.17676 -0.2594,-0.34253 -0.41724,-0.48627c-0.14661,-0.15466 -0.3158,-0.28735 -0.49609,-0.409c-0.09021,-0.05518 -0.18054,-0.11041 -0.28198,-0.16571c-0.29321,-0.14368 -0.59766,-0.26526 -0.92456,-0.33154c-0.22559,-0.04425 -0.45117,-0.06635 -0.68787,-0.06635h-21.42456c-0.23682,0 -0.4624,0.02209 -0.68787,0.06635c-0.32703,0.06628 -0.6427,0.18787 -0.92468,0.33154c-0.10144,0.0553 -0.19165,0.11053 -0.28186,0.16571c-0.18042,0.12164 -0.34961,0.25433 -0.49609,0.409c-0.62024,0.60791 -0.99231,1.42584 -0.99231,2.34308v35.36755c0,0.91742 0.37207,1.73523 0.99231,2.3432c0.14648,0.14362 0.31567,0.28735 0.49609,0.40894c0.09021,0.05524 0.18042,0.11053 0.28186,0.16571c0.28198,0.14368 0.59766,0.26532 0.92468,0.3316c0.22546,0.04419 0.45105,0.06628 0.68787,0.06628h21.42456c0.23669,0 0.46228,-0.02209 0.68787,-0.06628c0.3269,-0.06628 0.63135,-0.18793 0.92456,-0.3316c0.10144,-0.05518 0.19177,-0.11047 0.28198,-0.16571c0.1803,-0.13269 0.34949,-0.26532 0.49609,-0.40894c0.15784,-0.14368 0.29321,-0.30957 0.41724,-0.48633c0.0564,-0.08844 0.11267,-0.17682 0.16907,-0.27631c0.07898,-0.15479 0.15796,-0.30951 0.21423,-0.47534c0.02258,-0.07727 0.04517,-0.14362 0.06775,-0.2099c0.02246,-0.06641 0.04504,-0.14374 0.0564,-0.22107c0.04504,-0.22107 0.06763,-0.44214 0.06763,-0.67426v-16.99847c-0.36084,0.06628 -0.74426,0.09949 -1.12756,0.09949v16.89899c0,0.39801 -0.11279,0.78479 -0.3158,1.10522c-0.3833,0.66321 -1.1051,1.10529 -1.93945,1.10529h-21.42456c-1.24048,0 -2.25525,-0.99463 -2.25525,-2.21051v-35.36755c0,-1.2157 1.01477,-2.21045 2.25525,-2.21045h21.42456c1.24036,0 2.25525,0.99475 2.25525,2.21045v14.31342c0.3833,-0.01111 0.76672,-0.06628 1.12756,-0.16583z' fill='%23ffffff' fill-opacity='1'%3E%3C/path%3E%3Cpath d='M28.87872,21.43719v0v-14.14758c0,-0.23206 -0.02258,-0.45312 -0.06763,-0.67419c-0.06763,-0.32043 -0.19177,-0.6189 -0.33838,-0.90625c-0.0564,-0.09943 -0.11267,-0.18793 -0.16907,-0.27637c-0.12402,-0.17676 -0.2594,-0.34253 -0.41724,-0.48627c-0.14661,-0.15466 -0.3158,-0.28735 -0.49609,-0.409c-0.09021,-0.05518 -0.18054,-0.11041 -0.28198,-0.16571c-0.29321,-0.14368 -0.59766,-0.26526 -0.92456,-0.33154c-0.22559,-0.04425 -0.45117,-0.06635 -0.68787,-0.06635h-21.42456c-0.23682,0 -0.4624,0.02209 -0.68787,0.06635c-0.32703,0.06628 -0.6427,0.18787 -0.92468,0.33154c-0.10144,0.0553 -0.19165,0.11053 -0.28186,0.16571c-0.18042,0.12164 -0.34961,0.25433 -0.49609,0.409c-0.62024,0.60791 -0.99231,1.42584 -0.99231,2.34308v35.36755c0,0.91742 0.37207,1.73523 0.99231,2.3432c0.14648,0.14362 0.31567,0.28735 0.49609,0.40894c0.09021,0.05524 0.18042,0.11053 0.28186,0.16571c0.28198,0.14368 0.59766,0.26532 0.92468,0.3316c0.22546,0.04419 0.45105,0.06628 0.68787,0.06628h21.42456c0.23669,0 0.46228,-0.02209 0.68787,-0.06628c0.3269,-0.06628 0.63135,-0.18793 0.92456,-0.3316c0.10144,-0.05518 0.19177,-0.11047 0.28198,-0.16571c0.1803,-0.13269 0.34949,-0.26532 0.49609,-0.40894c0.15784,-0.14368 0.29321,-0.30957 0.41724,-0.48633c0.0564,-0.08844 0.11267,-0.17682 0.16907,-0.27631c0.07898,-0.15479 0.15796,-0.30951 0.21423,-0.47534c0.02258,-0.07727 0.04517,-0.14362 0.06775,-0.2099c0.02246,-0.06641 0.04504,-0.14374 0.0564,-0.22107c0.04504,-0.22107 0.06763,-0.44214 0.06763,-0.67426v-16.99847c-0.36084,0.06628 -0.74426,0.09949 -1.12756,0.09949v16.89899c0,0.39801 -0.11279,0.78479 -0.3158,1.10522c-0.3833,0.66321 -1.1051,1.10529 -1.93945,1.10529h-21.42456c-1.24048,0 -2.25525,-0.99463 -2.25525,-2.21051v-35.36755c0,-1.2157 1.01477,-2.21045 2.25525,-2.21045h21.42456c1.24036,0 2.25525,0.99475 2.25525,2.21045v14.31342c0.3833,-0.01111 0.76672,-0.06628 1.12756,-0.16583z' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='miter' stroke-linecap='butt' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='0.5'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3EPath 718%3C/title%3E%3Cpath d='M28.87872,21.59094v-14.30133c0,-0.23206 -0.02258,-0.45312 -0.06763,-0.67419c-0.06763,-0.32043 -0.19177,-0.6189 -0.33838,-0.90625c-0.0564,-0.09943 -0.11267,-0.18793 -0.16907,-0.27637c-0.13538,-0.17676 -0.27063,-0.34253 -0.41724,-0.48627c-0.14661,-0.14374 -0.3158,-0.27631 -0.49609,-0.409c-0.09021,-0.05518 -0.18054,-0.11041 -0.28198,-0.16571c-0.29321,-0.14368 -0.59766,-0.26526 -0.92456,-0.33154c-0.22559,-0.04425 -0.45117,-0.06635 -0.68787,-0.06635h-21.42456c-0.23682,0 -0.4624,0.02209 -0.68787,0.06635c-0.32703,0.06628 -0.6427,0.18787 -0.92468,0.33154c-0.10144,0.0553 -0.19165,0.11053 -0.28186,0.16571c-0.18042,0.12164 -0.34961,0.26526 -0.49609,0.409c-0.62024,0.60791 -0.99231,1.42584 -0.99231,2.34308v35.36755c0,0.91742 0.37207,1.73523 0.99231,2.3432c0.14648,0.14362 0.31567,0.28735 0.49609,0.40894c0.09021,0.05524 0.18042,0.11053 0.28186,0.16571c0.28198,0.14368 0.59766,0.26532 0.92468,0.3316c0.22546,0.04419 0.45105,0.06628 0.68787,0.06628h21.42456c0.23669,0 0.46228,-0.02209 0.68787,-0.06628c0.3269,-0.06628 0.63135,-0.18793 0.92456,-0.3316c0.10144,-0.05518 0.19177,-0.11047 0.28198,-0.16571c0.1803,-0.13269 0.34949,-0.26532 0.49609,-0.40894c0.14661,-0.14368 0.28186,-0.30957 0.41724,-0.48633c0.0564,-0.08844 0.11267,-0.17682 0.16907,-0.27631c0.07898,-0.15479 0.14661,-0.30951 0.203,-0.47534c0.03381,-0.07727 0.0564,-0.14362 0.07898,-0.2099c0.02246,-0.06641 0.04504,-0.14374 0.0564,-0.22107c0.04504,-0.22107 0.06763,-0.44214 0.06763,-0.67426v-16.99847c-0.36084,0.06628 -0.74426,0.09949 -1.12756,0.09949v16.89899c0,0.39801 -0.11279,0.78479 -0.3158,1.10522c-0.3833,0.66321 -1.1051,1.10529 -1.93945,1.10529h-21.42456c-1.24048,0 -2.25525,-0.99463 -2.25525,-2.21051v-35.36755c0,-1.2157 1.01477,-2.21045 2.25525,-2.21045h21.42456c1.24036,0 2.25525,0.99475 2.25525,2.21045v14.46716c0.3833,-0.01105 0.76672,-0.06628 1.12756,-0.16583z' fill='%23ffffff' fill-opacity='1'%3E%3C/path%3E%3Cpath d='M28.87872,21.59094v-14.30133c0,-0.23206 -0.02258,-0.45312 -0.06763,-0.67419c-0.06763,-0.32043 -0.19177,-0.6189 -0.33838,-0.90625c-0.0564,-0.09943 -0.11267,-0.18793 -0.16907,-0.27637c-0.13538,-0.17676 -0.27063,-0.34253 -0.41724,-0.48627c-0.14661,-0.14374 -0.3158,-0.27631 -0.49609,-0.409c-0.09021,-0.05518 -0.18054,-0.11041 -0.28198,-0.16571c-0.29321,-0.14368 -0.59766,-0.26526 -0.92456,-0.33154c-0.22559,-0.04425 -0.45117,-0.06635 -0.68787,-0.06635h-21.42456c-0.23682,0 -0.4624,0.02209 -0.68787,0.06635c-0.32703,0.06628 -0.6427,0.18787 -0.92468,0.33154c-0.10144,0.0553 -0.19165,0.11053 -0.28186,0.16571c-0.18042,0.12164 -0.34961,0.26526 -0.49609,0.409c-0.62024,0.60791 -0.99231,1.42584 -0.99231,2.34308v35.36755c0,0.91742 0.37207,1.73523 0.99231,2.3432c0.14648,0.14362 0.31567,0.28735 0.49609,0.40894c0.09021,0.05524 0.18042,0.11053 0.28186,0.16571c0.28198,0.14368 0.59766,0.26532 0.92468,0.3316c0.22546,0.04419 0.45105,0.06628 0.68787,0.06628h21.42456c0.23669,0 0.46228,-0.02209 0.68787,-0.06628c0.3269,-0.06628 0.63135,-0.18793 0.92456,-0.3316c0.10144,-0.05518 0.19177,-0.11047 0.28198,-0.16571c0.1803,-0.13269 0.34949,-0.26532 0.49609,-0.40894c0.14661,-0.14368 0.28186,-0.30957 0.41724,-0.48633c0.0564,-0.08844 0.11267,-0.17682 0.16907,-0.27631c0.07898,-0.15479 0.14661,-0.30951 0.203,-0.47534c0.03381,-0.07727 0.0564,-0.14362 0.07898,-0.2099c0.02246,-0.06641 0.04504,-0.14374 0.0564,-0.22107c0.04504,-0.22107 0.06763,-0.44214 0.06763,-0.67426v-16.99847c-0.36084,0.06628 -0.74426,0.09949 -1.12756,0.09949v16.89899c0,0.39801 -0.11279,0.78479 -0.3158,1.10522c-0.3833,0.66321 -1.1051,1.10529 -1.93945,1.10529h-21.42456c-1.24048,0 -2.25525,-0.99463 -2.25525,-2.21051v-35.36755c0,-1.2157 1.01477,-2.21045 2.25525,-2.21045h21.42456c1.24036,0 2.25525,0.99475 2.25525,2.21045v14.46716c0.3833,-0.01105 0.76672,-0.06628 1.12756,-0.16583z' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='miter' stroke-linecap='butt' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='0.5'%3E%3C/path%3E%3C/g%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3EGroup 2066%3C/title%3E%3Cg opacity='0.6'%3E%3Ctitle%3EGroup 2066%3C/title%3E%3Cg opacity='0.6'%3E%3Ctitle%3EPath 719%3C/title%3E%3Cpath d='M34.13678,19.94879c-0.98096,2.23267 -2.98816,3.80005 -5.32227,4.22858c-0.37207,0.06763 -0.74426,0.11273 -1.12756,0.11273c-0.06775,0.01123 -0.13538,0.01123 -0.203,0.01123h-0.06775c-3.61951,-0.01123 -6.73181,-2.70624 -7.25049,-6.29205l-0.07898,-0.47357v0h-1.9845c-0.4624,0.01129 -0.30444,-0.33826 -0.30444,-0.33826v0l2.66113,-4.88257c0.01123,-0.02258 0.06763,-0.07898 0.11279,-0.07898c0.0564,-0.02252 0.18042,0.06769 0.25928,0.18048l2.7063,4.87122c-0.01123,0.14661 -0.13538,0.24811 -0.3158,0.24811h-2.02966v0l0.13538,0.67651c0.59753,2.87549 3.15723,4.96155 6.07776,4.96155h0.28198c0.3833,-0.01129 0.76672,-0.0451 1.12756,-0.12402c1.89441,-0.38342 3.48425,-1.66895 4.26233,-3.46179c0.12402,-0.22552 0.39465,-0.33826 0.6427,-0.25934c0.30457,0.07892 0.47363,0.39465 0.41724,0.62018z' fill='%23ffffff' fill-opacity='1'%3E%3C/path%3E%3Cpath d='M34.13678,19.94879c-0.98096,2.23267 -2.98816,3.80005 -5.32227,4.22858c-0.37207,0.06763 -0.74426,0.11273 -1.12756,0.11273c-0.06775,0.01123 -0.13538,0.01123 -0.203,0.01123h-0.06775c-3.61951,-0.01123 -6.73181,-2.70624 -7.25049,-6.29205l-0.07898,-0.47357v0h-1.9845c-0.4624,0.01129 -0.30444,-0.33826 -0.30444,-0.33826v0l2.66113,-4.88257c0.01123,-0.02258 0.06763,-0.07898 0.11279,-0.07898c0.0564,-0.02252 0.18042,0.06769 0.25928,0.18048l2.7063,4.87122c-0.01123,0.14661 -0.13538,0.24811 -0.3158,0.24811h-2.02966v0l0.13538,0.67651c0.59753,2.87549 3.15723,4.96155 6.07776,4.96155h0.28198c0.3833,-0.01129 0.76672,-0.0451 1.12756,-0.12402c1.89441,-0.38342 3.48425,-1.66895 4.26233,-3.46179c0.12402,-0.22552 0.39465,-0.33826 0.6427,-0.25934c0.30457,0.07892 0.47363,0.39465 0.41724,0.62018z' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='miter' stroke-linecap='butt' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='0.5'%3E%3C/path%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3ERectangle 940%3C/title%3E%3Cg opacity='0.6'%3E%3Ctitle%3EPath 714%3C/title%3E%3Cpath d='M33.68463,19.32599c-0.24805,-0.07892 -0.51868,0.03381 -0.6427,0.25934c-0.77808,1.79285 -2.36792,3.07837 -4.26233,3.46179c-0.36084,0.07892 -0.74426,0.11273 -1.12756,0.12402h-0.28198c-2.92053,0 -5.48022,-2.08606 -6.07776,-4.96155l-0.13538,-0.67651v0h2.02966c0.18042,0 0.30457,-0.1015 0.3158,-0.24811l-2.7063,-4.87122c-0.07886,-0.11279 -0.20288,-0.203 -0.25928,-0.18048c-0.04517,0 -0.10156,0.0564 -0.11279,0.07898l-2.66113,4.88257v0c0,0 -0.15796,0.34955 0.30444,0.33826h1.9845v0l0.07898,0.47357c0.51868,3.58582 3.63098,6.28082 7.25049,6.29205h0.06775c0.06763,0 0.13525,0 0.203,-0.01123c0.3833,0 0.75549,-0.0451 1.12756,-0.11273c2.33411,-0.42853 4.34131,-1.99591 5.32227,-4.22858c0.0564,-0.22552 -0.11267,-0.54126 -0.41724,-0.62018z' fill='%23ffffff' fill-opacity='1'%3E%3C/path%3E%3Cpath d='M33.68463,19.32599c-0.24805,-0.07892 -0.51868,0.03381 -0.6427,0.25934c-0.77808,1.79285 -2.36792,3.07837 -4.26233,3.46179c-0.36084,0.07892 -0.74426,0.11273 -1.12756,0.12402h-0.28198c-2.92053,0 -5.48022,-2.08606 -6.07776,-4.96155l-0.13538,-0.67651v0h2.02966c0.18042,0 0.30457,-0.1015 0.3158,-0.24811l-2.7063,-4.87122c-0.07886,-0.11279 -0.20288,-0.203 -0.25928,-0.18048c-0.04517,0 -0.10156,0.0564 -0.11279,0.07898l-2.66113,4.88257v0c0,0 -0.15796,0.34955 0.30444,0.33826h1.9845v0l0.07898,0.47357c0.51868,3.58582 3.63098,6.28082 7.25049,6.29205h0.06775c0.06763,0 0.13525,0 0.203,-0.01123c0.3833,0 0.75549,-0.0451 1.12756,-0.11273c2.33411,-0.42853 4.34131,-1.99591 5.32227,-4.22858c0.0564,-0.22552 -0.11267,-0.54126 -0.41724,-0.62018z' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='miter' stroke-linecap='butt' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='0.5'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3EPath 715%3C/title%3E%3Cpath d='M43.43854,4.34747v0v35.99567c0,0.23621 -0.02258,0.46124 -0.06763,0.68622c-0.06775,0.32617 -0.19177,0.62994 -0.33838,0.92236c-0.0564,0.1012 -0.11267,0.19128 -0.16907,0.28125c-0.12402,0.17993 -0.2594,0.34869 -0.41724,0.49493c-0.14661,0.14624 -0.3158,0.28125 -0.49609,0.4162c-0.09033,0.05627 -0.18054,0.11243 -0.28198,0.1687c-0.29321,0.14624 -0.59766,0.26996 -0.92468,0.33746c-0.22546,0.04504 -0.45105,0.0675 -0.68774,0.0675h-12.71948c0.203,-0.32623 0.3158,-0.71985 0.3158,-1.12488v-17.19922c0.3833,0 0.76672,-0.03363 1.12756,-0.1012v17.30042v0h11.27612c1.24036,0 2.25525,-1.01239 2.25525,-2.24976v-35.99567c0,-1.2373 -1.01489,-2.24969 -2.25525,-2.24969h-21.42456c-0.83447,0 -1.31396,1.09131 -1.69727,1.76624h8.70508c0.23669,0 0.4624,0.02252 0.68787,0.06757c0.32703,0.0675 0.63147,0.19122 0.92468,0.3374c0.10144,0.05627 0.19165,0.11255 0.28186,0.1687c0.1803,0.12378 0.34949,0.25879 0.49609,0.41626c0.15796,0.14618 0.29321,0.31494 0.41724,0.49493c0.0564,0.08997 0.11267,0.17999 0.16919,0.28119c0.14661,0.29248 0.09607,0.12097 0.1637,0.44714c0.04504,0.22504 0,0.28381 0,0.52002v15.2644c-0.36084,0.10132 -0.74426,0.15747 -1.12756,0.16876v-15.43317c0,-1.23737 -1.01489,-2.24976 -2.25525,-2.24976h-10.14844c0,-0.39362 0.06763,-0.77606 0.19165,-1.12482c0.16919,-0.47241 0.45105,-0.91119 0.80054,-1.25989c0.14661,-0.15741 0.3158,-0.29242 0.49622,-0.4162c0.09021,-0.05621 0.18042,-0.11249 0.28186,-0.16864c0.28198,-0.1463 0.59766,-0.27002 0.92456,-0.33746c0.22559,-0.04504 0.45117,-0.06757 0.68799,-0.06757h21.42456c0.23669,0 0.46228,0.02252 0.68774,0.06757c0.32703,0.06744 0.63147,0.19116 0.92468,0.33746c0.10144,0.05615 0.19165,0.11243 0.28198,0.16864c0.1803,0.12378 0.34949,0.25879 0.49609,0.4162c0.15784,0.14624 0.29321,0.315 0.41724,0.49493c0.0564,0.09003 0.11267,0.17999 0.16907,0.28125c0.14661,0.29248 0.27063,0.59619 0.33838,0.92236c0.04504,0.22498 0.06763,0.44995 0.06763,0.68616z' fill='%23ffffff' fill-opacity='1'%3E%3C/path%3E%3Cpath d='M43.43854,4.34747v0v35.99567c0,0.23621 -0.02258,0.46124 -0.06763,0.68622c-0.06775,0.32617 -0.19177,0.62994 -0.33838,0.92236c-0.0564,0.1012 -0.11267,0.19128 -0.16907,0.28125c-0.12402,0.17993 -0.2594,0.34869 -0.41724,0.49493c-0.14661,0.14624 -0.3158,0.28125 -0.49609,0.4162c-0.09033,0.05627 -0.18054,0.11243 -0.28198,0.1687c-0.29321,0.14624 -0.59766,0.26996 -0.92468,0.33746c-0.22546,0.04504 -0.45105,0.0675 -0.68774,0.0675h-12.71948c0.203,-0.32623 0.3158,-0.71985 0.3158,-1.12488v-17.19922c0.3833,0 0.76672,-0.03363 1.12756,-0.1012v17.30042v0h11.27612c1.24036,0 2.25525,-1.01239 2.25525,-2.24976v-35.99567c0,-1.2373 -1.01489,-2.24969 -2.25525,-2.24969h-21.42456c-0.83447,0 -1.31396,1.09131 -1.69727,1.76624h8.70508c0.23669,0 0.4624,0.02252 0.68787,0.06757c0.32703,0.0675 0.63147,0.19122 0.92468,0.3374c0.10144,0.05627 0.19165,0.11255 0.28186,0.1687c0.1803,0.12378 0.34949,0.25879 0.49609,0.41626c0.15796,0.14618 0.29321,0.31494 0.41724,0.49493c0.0564,0.08997 0.11267,0.17999 0.16919,0.28119c0.14661,0.29248 0.09607,0.12097 0.1637,0.44714c0.04504,0.22504 0,0.28381 0,0.52002v15.2644c-0.36084,0.10132 -0.74426,0.15747 -1.12756,0.16876v-15.43317c0,-1.23737 -1.01489,-2.24976 -2.25525,-2.24976h-10.14844c0,-0.39362 0.06763,-0.77606 0.19165,-1.12482c0.16919,-0.47241 0.45105,-0.91119 0.80054,-1.25989c0.14661,-0.15741 0.3158,-0.29242 0.49622,-0.4162c0.09021,-0.05621 0.18042,-0.11249 0.28186,-0.16864c0.28198,-0.1463 0.59766,-0.27002 0.92456,-0.33746c0.22559,-0.04504 0.45117,-0.06757 0.68799,-0.06757h21.42456c0.23669,0 0.46228,0.02252 0.68774,0.06757c0.32703,0.06744 0.63147,0.19116 0.92468,0.33746c0.10144,0.05615 0.19165,0.11243 0.28198,0.16864c0.1803,0.12378 0.34949,0.25879 0.49609,0.4162c0.15784,0.14624 0.29321,0.315 0.41724,0.49493c0.0564,0.09003 0.11267,0.17999 0.16907,0.28125c0.14661,0.29248 0.27063,0.59619 0.33838,0.92236c0.04504,0.22498 0.06763,0.44995 0.06763,0.68616z' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='miter' stroke-linecap='butt' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='0.5'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3EPath 716%3C/title%3E%3Cpath d='M43.37091,3.66132c-0.06775,-0.32617 -0.19177,-0.62988 -0.33838,-0.92236c-0.0564,-0.10126 -0.11267,-0.19122 -0.16907,-0.28125c-0.13538,-0.17993 -0.27063,-0.34869 -0.41724,-0.49493c-0.14661,-0.14624 -0.3158,-0.28125 -0.49609,-0.4162c-0.09033,-0.05621 -0.18054,-0.11249 -0.28198,-0.16864c-0.29321,-0.1463 -0.59766,-0.27002 -0.92468,-0.33746c-0.22546,-0.04504 -0.45105,-0.06757 -0.68774,-0.06757h-21.42456c-0.23682,0 -0.4624,0.02252 -0.68799,0.06757c-0.3269,0.06744 -0.64258,0.19116 -0.92456,0.33746c-0.10144,0.05615 -0.19165,0.11243 -0.28186,0.16864c-0.18042,0.12378 -0.34961,0.26996 -0.49622,0.4162c-0.34949,0.34869 -0.63135,0.78748 -0.80054,1.25989c-0.12402,0.34875 -0.19165,0.7312 -0.19165,1.12482h1.12756c0,-0.40491 0.11267,-0.79858 0.31567,-1.12482c0.38342,-0.67493 1.1051,-1.12488 1.93958,-1.12488h21.42456c1.24036,0 2.25525,1.01239 2.25525,2.24969v35.99567c0,1.23737 -1.01489,2.24976 -2.25525,2.24976h-12.40369c0,0.40503 -0.11279,0.79865 -0.3158,1.12488h12.71948c0.23669,0 0.46228,-0.02246 0.68774,-0.0675c0.32703,-0.0675 0.63147,-0.19122 0.92468,-0.33746c0.10144,-0.05627 0.19165,-0.11243 0.28198,-0.1687c0.1803,-0.13495 0.34949,-0.26996 0.49609,-0.4162c0.14661,-0.14624 0.28186,-0.315 0.41724,-0.49493c0.0564,-0.08997 0.11267,-0.18005 0.16907,-0.28125c0.14661,-0.29242 0.27063,-0.59619 0.33838,-0.92236c0.04504,-0.22498 0.06763,-0.45001 0.06763,-0.68622v-35.99567c0,-0.23621 -0.02258,-0.46118 -0.06763,-0.68616z' fill='%23ffffff' fill-opacity='1'%3E%3C/path%3E%3Cpath d='M43.37091,3.66132c-0.06775,-0.32617 -0.19177,-0.62988 -0.33838,-0.92236c-0.0564,-0.10126 -0.11267,-0.19122 -0.16907,-0.28125c-0.13538,-0.17993 -0.27063,-0.34869 -0.41724,-0.49493c-0.14661,-0.14624 -0.3158,-0.28125 -0.49609,-0.4162c-0.09033,-0.05621 -0.18054,-0.11249 -0.28198,-0.16864c-0.29321,-0.1463 -0.59766,-0.27002 -0.92468,-0.33746c-0.22546,-0.04504 -0.45105,-0.06757 -0.68774,-0.06757h-21.42456c-0.23682,0 -0.4624,0.02252 -0.68799,0.06757c-0.3269,0.06744 -0.64258,0.19116 -0.92456,0.33746c-0.10144,0.05615 -0.19165,0.11243 -0.28186,0.16864c-0.18042,0.12378 -0.34961,0.26996 -0.49622,0.4162c-0.34949,0.34869 -0.63135,0.78748 -0.80054,1.25989c-0.12402,0.34875 -0.19165,0.7312 -0.19165,1.12482h1.12756c0,-0.40491 0.11267,-0.79858 0.31567,-1.12482c0.38342,-0.67493 1.1051,-1.12488 1.93958,-1.12488h21.42456c1.24036,0 2.25525,1.01239 2.25525,2.24969v35.99567c0,1.23737 -1.01489,2.24976 -2.25525,2.24976h-12.40369c0,0.40503 -0.11279,0.79865 -0.3158,1.12488h12.71948c0.23669,0 0.46228,-0.02246 0.68774,-0.0675c0.32703,-0.0675 0.63147,-0.19122 0.92468,-0.33746c0.10144,-0.05627 0.19165,-0.11243 0.28198,-0.1687c0.1803,-0.13495 0.34949,-0.26996 0.49609,-0.4162c0.14661,-0.14624 0.28186,-0.315 0.41724,-0.49493c0.0564,-0.08997 0.11267,-0.18005 0.16907,-0.28125c0.14661,-0.29242 0.27063,-0.59619 0.33838,-0.92236c0.04504,-0.22498 0.06763,-0.45001 0.06763,-0.68622v-35.99567c0,-0.23621 -0.02258,-0.46118 -0.06763,-0.68616z' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='miter' stroke-linecap='butt' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='0.5'%3E%3C/path%3E%3C/g%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3EGroup 2066%3C/title%3E%3Cg opacity='0.6'%3E%3Ctitle%3EPath 719%3C/title%3E%3Cpath d='M34.13678,19.94879c-0.98096,2.23267 -2.98816,3.80005 -5.32227,4.22858c-0.37207,0.06763 -0.74426,0.11273 -1.12756,0.11273c-0.06775,0.01123 -0.13538,0.01123 -0.203,0.01123h-0.06775c-3.61951,-0.01123 -6.73181,-2.70624 -7.25049,-6.29205l-0.07898,-0.47357v0h-1.9845c-0.4624,0.01129 -0.30444,-0.33826 -0.30444,-0.33826v0l2.66113,-4.88257c0.01123,-0.02258 0.06763,-0.07898 0.11279,-0.07898c0.0564,-0.02252 0.18042,0.06769 0.25928,0.18048l2.7063,4.87122c-0.01123,0.14661 -0.13538,0.24811 -0.3158,0.24811h-2.02966v0l0.13538,0.67651c0.59753,2.87549 3.15723,4.96155 6.07776,4.96155h0.28198c0.3833,-0.01129 0.76672,-0.0451 1.12756,-0.12402c1.89441,-0.38342 3.48425,-1.66895 4.26233,-3.46179c0.12402,-0.22552 0.39465,-0.33826 0.6427,-0.25934c0.30457,0.07892 0.47363,0.39465 0.41724,0.62018z' fill='%23ffffff' fill-opacity='1'%3E%3C/path%3E%3Cpath d='M34.13678,19.94879c-0.98096,2.23267 -2.98816,3.80005 -5.32227,4.22858c-0.37207,0.06763 -0.74426,0.11273 -1.12756,0.11273c-0.06775,0.01123 -0.13538,0.01123 -0.203,0.01123h-0.06775c-3.61951,-0.01123 -6.73181,-2.70624 -7.25049,-6.29205l-0.07898,-0.47357v0h-1.9845c-0.4624,0.01129 -0.30444,-0.33826 -0.30444,-0.33826v0l2.66113,-4.88257c0.01123,-0.02258 0.06763,-0.07898 0.11279,-0.07898c0.0564,-0.02252 0.18042,0.06769 0.25928,0.18048l2.7063,4.87122c-0.01123,0.14661 -0.13538,0.24811 -0.3158,0.24811h-2.02966v0l0.13538,0.67651c0.59753,2.87549 3.15723,4.96155 6.07776,4.96155h0.28198c0.3833,-0.01129 0.76672,-0.0451 1.12756,-0.12402c1.89441,-0.38342 3.48425,-1.66895 4.26233,-3.46179c0.12402,-0.22552 0.39465,-0.33826 0.6427,-0.25934c0.30457,0.07892 0.47363,0.39465 0.41724,0.62018z' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='miter' stroke-linecap='butt' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='0.5'%3E%3C/path%3E%3C/g%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3EPath 717%3C/title%3E%3Cpath d='M28.87872,21.43719v0v-14.14758c0,-0.23206 -0.02258,-0.45312 -0.06763,-0.67419c-0.06763,-0.32043 -0.19177,-0.6189 -0.33838,-0.90625c-0.0564,-0.09943 -0.11267,-0.18793 -0.16907,-0.27637c-0.12402,-0.17676 -0.2594,-0.34253 -0.41724,-0.48627c-0.14661,-0.15466 -0.3158,-0.28735 -0.49609,-0.409c-0.09021,-0.05518 -0.18054,-0.11041 -0.28198,-0.16571c-0.29321,-0.14368 -0.59766,-0.26526 -0.92456,-0.33154c-0.22559,-0.04425 -0.45117,-0.06635 -0.68787,-0.06635h-21.42456c-0.23682,0 -0.4624,0.02209 -0.68787,0.06635c-0.32703,0.06628 -0.6427,0.18787 -0.92468,0.33154c-0.10144,0.0553 -0.19165,0.11053 -0.28186,0.16571c-0.18042,0.12164 -0.34961,0.25433 -0.49609,0.409c-0.62024,0.60791 -0.99231,1.42584 -0.99231,2.34308v35.36755c0,0.91742 0.37207,1.73523 0.99231,2.3432c0.14648,0.14362 0.31567,0.28735 0.49609,0.40894c0.09021,0.05524 0.18042,0.11053 0.28186,0.16571c0.28198,0.14368 0.59766,0.26532 0.92468,0.3316c0.22546,0.04419 0.45105,0.06628 0.68787,0.06628h21.42456c0.23669,0 0.46228,-0.02209 0.68787,-0.06628c0.3269,-0.06628 0.63135,-0.18793 0.92456,-0.3316c0.10144,-0.05518 0.19177,-0.11047 0.28198,-0.16571c0.1803,-0.13269 0.34949,-0.26532 0.49609,-0.40894c0.15784,-0.14368 0.29321,-0.30957 0.41724,-0.48633c0.0564,-0.08844 0.11267,-0.17682 0.16907,-0.27631c0.07898,-0.15479 0.15796,-0.30951 0.21423,-0.47534c0.02258,-0.07727 0.04517,-0.14362 0.06775,-0.2099c0.02246,-0.06641 0.04504,-0.14374 0.0564,-0.22107c0.04504,-0.22107 0.06763,-0.44214 0.06763,-0.67426v-16.99847c-0.36084,0.06628 -0.74426,0.09949 -1.12756,0.09949v16.89899c0,0.39801 -0.11279,0.78479 -0.3158,1.10522c-0.3833,0.66321 -1.1051,1.10529 -1.93945,1.10529h-21.42456c-1.24048,0 -2.25525,-0.99463 -2.25525,-2.21051v-35.36755c0,-1.2157 1.01477,-2.21045 2.25525,-2.21045h21.42456c1.24036,0 2.25525,0.99475 2.25525,2.21045v14.31342c0.3833,-0.01111 0.76672,-0.06628 1.12756,-0.16583z' fill='%23ffffff' fill-opacity='1'%3E%3C/path%3E%3Cpath d='M28.87872,21.43719v0v-14.14758c0,-0.23206 -0.02258,-0.45312 -0.06763,-0.67419c-0.06763,-0.32043 -0.19177,-0.6189 -0.33838,-0.90625c-0.0564,-0.09943 -0.11267,-0.18793 -0.16907,-0.27637c-0.12402,-0.17676 -0.2594,-0.34253 -0.41724,-0.48627c-0.14661,-0.15466 -0.3158,-0.28735 -0.49609,-0.409c-0.09021,-0.05518 -0.18054,-0.11041 -0.28198,-0.16571c-0.29321,-0.14368 -0.59766,-0.26526 -0.92456,-0.33154c-0.22559,-0.04425 -0.45117,-0.06635 -0.68787,-0.06635h-21.42456c-0.23682,0 -0.4624,0.02209 -0.68787,0.06635c-0.32703,0.06628 -0.6427,0.18787 -0.92468,0.33154c-0.10144,0.0553 -0.19165,0.11053 -0.28186,0.16571c-0.18042,0.12164 -0.34961,0.25433 -0.49609,0.409c-0.62024,0.60791 -0.99231,1.42584 -0.99231,2.34308v35.36755c0,0.91742 0.37207,1.73523 0.99231,2.3432c0.14648,0.14362 0.31567,0.28735 0.49609,0.40894c0.09021,0.05524 0.18042,0.11053 0.28186,0.16571c0.28198,0.14368 0.59766,0.26532 0.92468,0.3316c0.22546,0.04419 0.45105,0.06628 0.68787,0.06628h21.42456c0.23669,0 0.46228,-0.02209 0.68787,-0.06628c0.3269,-0.06628 0.63135,-0.18793 0.92456,-0.3316c0.10144,-0.05518 0.19177,-0.11047 0.28198,-0.16571c0.1803,-0.13269 0.34949,-0.26532 0.49609,-0.40894c0.15784,-0.14368 0.29321,-0.30957 0.41724,-0.48633c0.0564,-0.08844 0.11267,-0.17682 0.16907,-0.27631c0.07898,-0.15479 0.15796,-0.30951 0.21423,-0.47534c0.02258,-0.07727 0.04517,-0.14362 0.06775,-0.2099c0.02246,-0.06641 0.04504,-0.14374 0.0564,-0.22107c0.04504,-0.22107 0.06763,-0.44214 0.06763,-0.67426v-16.99847c-0.36084,0.06628 -0.74426,0.09949 -1.12756,0.09949v16.89899c0,0.39801 -0.11279,0.78479 -0.3158,1.10522c-0.3833,0.66321 -1.1051,1.10529 -1.93945,1.10529h-21.42456c-1.24048,0 -2.25525,-0.99463 -2.25525,-2.21051v-35.36755c0,-1.2157 1.01477,-2.21045 2.25525,-2.21045h21.42456c1.24036,0 2.25525,0.99475 2.25525,2.21045v14.31342c0.3833,-0.01111 0.76672,-0.06628 1.12756,-0.16583z' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='miter' stroke-linecap='butt' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='0.5'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3EPath 714%3C/title%3E%3Cpath d='M33.68463,19.32599c-0.24805,-0.07892 -0.51868,0.03381 -0.6427,0.25934c-0.77808,1.79285 -2.36792,3.07837 -4.26233,3.46179c-0.36084,0.07892 -0.74426,0.11273 -1.12756,0.12402h-0.28198c-2.92053,0 -5.48022,-2.08606 -6.07776,-4.96155l-0.13538,-0.67651v0h2.02966c0.18042,0 0.30457,-0.1015 0.3158,-0.24811l-2.7063,-4.87122c-0.07886,-0.11279 -0.20288,-0.203 -0.25928,-0.18048c-0.04517,0 -0.10156,0.0564 -0.11279,0.07898l-2.66113,4.88257v0c0,0 -0.15796,0.34955 0.30444,0.33826h1.9845v0l0.07898,0.47357c0.51868,3.58582 3.63098,6.28082 7.25049,6.29205h0.06775c0.06763,0 0.13525,0 0.203,-0.01123c0.3833,0 0.75549,-0.0451 1.12756,-0.11273c2.33411,-0.42853 4.34131,-1.99591 5.32227,-4.22858c0.0564,-0.22552 -0.11267,-0.54126 -0.41724,-0.62018z' fill='%23ffffff' fill-opacity='1'%3E%3C/path%3E%3Cpath d='M33.68463,19.32599c-0.24805,-0.07892 -0.51868,0.03381 -0.6427,0.25934c-0.77808,1.79285 -2.36792,3.07837 -4.26233,3.46179c-0.36084,0.07892 -0.74426,0.11273 -1.12756,0.12402h-0.28198c-2.92053,0 -5.48022,-2.08606 -6.07776,-4.96155l-0.13538,-0.67651v0h2.02966c0.18042,0 0.30457,-0.1015 0.3158,-0.24811l-2.7063,-4.87122c-0.07886,-0.11279 -0.20288,-0.203 -0.25928,-0.18048c-0.04517,0 -0.10156,0.0564 -0.11279,0.07898l-2.66113,4.88257v0c0,0 -0.15796,0.34955 0.30444,0.33826h1.9845v0l0.07898,0.47357c0.51868,3.58582 3.63098,6.28082 7.25049,6.29205h0.06775c0.06763,0 0.13525,0 0.203,-0.01123c0.3833,0 0.75549,-0.0451 1.12756,-0.11273c2.33411,-0.42853 4.34131,-1.99591 5.32227,-4.22858c0.0564,-0.22552 -0.11267,-0.54126 -0.41724,-0.62018z' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='miter' stroke-linecap='butt' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='0.5'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3EPath 715%3C/title%3E%3Cpath d='M43.43854,4.34747v0v35.99567c0,0.23621 -0.02258,0.46124 -0.06763,0.68622c-0.06775,0.32617 -0.19177,0.62994 -0.33838,0.92236c-0.0564,0.1012 -0.11267,0.19128 -0.16907,0.28125c-0.12402,0.17993 -0.2594,0.34869 -0.41724,0.49493c-0.14661,0.14624 -0.3158,0.28125 -0.49609,0.4162c-0.09033,0.05627 -0.18054,0.11243 -0.28198,0.1687c-0.29321,0.14624 -0.59766,0.26996 -0.92468,0.33746c-0.22546,0.04504 -0.45105,0.0675 -0.68774,0.0675h-12.71948c0.203,-0.32623 0.3158,-0.71985 0.3158,-1.12488v-17.19922c0.3833,0 0.76672,-0.03363 1.12756,-0.1012v17.30042v0h11.27612c1.24036,0 2.25525,-1.01239 2.25525,-2.24976v-35.99567c0,-1.2373 -1.01489,-2.24969 -2.25525,-2.24969h-21.42456c-0.83447,0 -1.31396,1.09131 -1.69727,1.76624h8.70508c0.23669,0 0.4624,0.02252 0.68787,0.06757c0.32703,0.0675 0.63147,0.19122 0.92468,0.3374c0.10144,0.05627 0.19165,0.11255 0.28186,0.1687c0.1803,0.12378 0.34949,0.25879 0.49609,0.41626c0.15796,0.14618 0.29321,0.31494 0.41724,0.49493c0.0564,0.08997 0.11267,0.17999 0.16919,0.28119c0.14661,0.29248 0.09607,0.12097 0.1637,0.44714c0.04504,0.22504 0,0.28381 0,0.52002v15.2644c-0.36084,0.10132 -0.74426,0.15747 -1.12756,0.16876v-15.43317c0,-1.23737 -1.01489,-2.24976 -2.25525,-2.24976h-10.14844c0,-0.39362 0.06763,-0.77606 0.19165,-1.12482c0.16919,-0.47241 0.45105,-0.91119 0.80054,-1.25989c0.14661,-0.15741 0.3158,-0.29242 0.49622,-0.4162c0.09021,-0.05621 0.18042,-0.11249 0.28186,-0.16864c0.28198,-0.1463 0.59766,-0.27002 0.92456,-0.33746c0.22559,-0.04504 0.45117,-0.06757 0.68799,-0.06757h21.42456c0.23669,0 0.46228,0.02252 0.68774,0.06757c0.32703,0.06744 0.63147,0.19116 0.92468,0.33746c0.10144,0.05615 0.19165,0.11243 0.28198,0.16864c0.1803,0.12378 0.34949,0.25879 0.49609,0.4162c0.15784,0.14624 0.29321,0.315 0.41724,0.49493c0.0564,0.09003 0.11267,0.17999 0.16907,0.28125c0.14661,0.29248 0.27063,0.59619 0.33838,0.92236c0.04504,0.22498 0.06763,0.44995 0.06763,0.68616z' fill='%23ffffff' fill-opacity='1'%3E%3C/path%3E%3Cpath d='M43.43854,4.34747v0v35.99567c0,0.23621 -0.02258,0.46124 -0.06763,0.68622c-0.06775,0.32617 -0.19177,0.62994 -0.33838,0.92236c-0.0564,0.1012 -0.11267,0.19128 -0.16907,0.28125c-0.12402,0.17993 -0.2594,0.34869 -0.41724,0.49493c-0.14661,0.14624 -0.3158,0.28125 -0.49609,0.4162c-0.09033,0.05627 -0.18054,0.11243 -0.28198,0.1687c-0.29321,0.14624 -0.59766,0.26996 -0.92468,0.33746c-0.22546,0.04504 -0.45105,0.0675 -0.68774,0.0675h-12.71948c0.203,-0.32623 0.3158,-0.71985 0.3158,-1.12488v-17.19922c0.3833,0 0.76672,-0.03363 1.12756,-0.1012v17.30042v0h11.27612c1.24036,0 2.25525,-1.01239 2.25525,-2.24976v-35.99567c0,-1.2373 -1.01489,-2.24969 -2.25525,-2.24969h-21.42456c-0.83447,0 -1.31396,1.09131 -1.69727,1.76624h8.70508c0.23669,0 0.4624,0.02252 0.68787,0.06757c0.32703,0.0675 0.63147,0.19122 0.92468,0.3374c0.10144,0.05627 0.19165,0.11255 0.28186,0.1687c0.1803,0.12378 0.34949,0.25879 0.49609,0.41626c0.15796,0.14618 0.29321,0.31494 0.41724,0.49493c0.0564,0.08997 0.11267,0.17999 0.16919,0.28119c0.14661,0.29248 0.09607,0.12097 0.1637,0.44714c0.04504,0.22504 0,0.28381 0,0.52002v15.2644c-0.36084,0.10132 -0.74426,0.15747 -1.12756,0.16876v-15.43317c0,-1.23737 -1.01489,-2.24976 -2.25525,-2.24976h-10.14844c0,-0.39362 0.06763,-0.77606 0.19165,-1.12482c0.16919,-0.47241 0.45105,-0.91119 0.80054,-1.25989c0.14661,-0.15741 0.3158,-0.29242 0.49622,-0.4162c0.09021,-0.05621 0.18042,-0.11249 0.28186,-0.16864c0.28198,-0.1463 0.59766,-0.27002 0.92456,-0.33746c0.22559,-0.04504 0.45117,-0.06757 0.68799,-0.06757h21.42456c0.23669,0 0.46228,0.02252 0.68774,0.06757c0.32703,0.06744 0.63147,0.19116 0.92468,0.33746c0.10144,0.05615 0.19165,0.11243 0.28198,0.16864c0.1803,0.12378 0.34949,0.25879 0.49609,0.4162c0.15784,0.14624 0.29321,0.315 0.41724,0.49493c0.0564,0.09003 0.11267,0.17999 0.16907,0.28125c0.14661,0.29248 0.27063,0.59619 0.33838,0.92236c0.04504,0.22498 0.06763,0.44995 0.06763,0.68616z' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='miter' stroke-linecap='butt' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='0.5'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3ERectangle 941%3C/title%3E%3Cg opacity='0.6'%3E%3Ctitle%3EPath 717%3C/title%3E%3Cpath d='M28.87872,21.43719v0v-14.14758c0,-0.23206 -0.02258,-0.45312 -0.06763,-0.67419c-0.06763,-0.32043 -0.19177,-0.6189 -0.33838,-0.90625c-0.0564,-0.09943 -0.11267,-0.18793 -0.16907,-0.27637c-0.12402,-0.17676 -0.2594,-0.34253 -0.41724,-0.48627c-0.14661,-0.15466 -0.3158,-0.28735 -0.49609,-0.409c-0.09021,-0.05518 -0.18054,-0.11041 -0.28198,-0.16571c-0.29321,-0.14368 -0.59766,-0.26526 -0.92456,-0.33154c-0.22559,-0.04425 -0.45117,-0.06635 -0.68787,-0.06635h-21.42456c-0.23682,0 -0.4624,0.02209 -0.68787,0.06635c-0.32703,0.06628 -0.6427,0.18787 -0.92468,0.33154c-0.10144,0.0553 -0.19165,0.11053 -0.28186,0.16571c-0.18042,0.12164 -0.34961,0.25433 -0.49609,0.409c-0.62024,0.60791 -0.99231,1.42584 -0.99231,2.34308v35.36755c0,0.91742 0.37207,1.73523 0.99231,2.3432c0.14648,0.14362 0.31567,0.28735 0.49609,0.40894c0.09021,0.05524 0.18042,0.11053 0.28186,0.16571c0.28198,0.14368 0.59766,0.26532 0.92468,0.3316c0.22546,0.04419 0.45105,0.06628 0.68787,0.06628h21.42456c0.23669,0 0.46228,-0.02209 0.68787,-0.06628c0.3269,-0.06628 0.63135,-0.18793 0.92456,-0.3316c0.10144,-0.05518 0.19177,-0.11047 0.28198,-0.16571c0.1803,-0.13269 0.34949,-0.26532 0.49609,-0.40894c0.15784,-0.14368 0.29321,-0.30957 0.41724,-0.48633c0.0564,-0.08844 0.11267,-0.17682 0.16907,-0.27631c0.07898,-0.15479 0.15796,-0.30951 0.21423,-0.47534c0.02258,-0.07727 0.04517,-0.14362 0.06775,-0.2099c0.02246,-0.06641 0.04504,-0.14374 0.0564,-0.22107c0.04504,-0.22107 0.06763,-0.44214 0.06763,-0.67426v-16.99847c-0.36084,0.06628 -0.74426,0.09949 -1.12756,0.09949v16.89899c0,0.39801 -0.11279,0.78479 -0.3158,1.10522c-0.3833,0.66321 -1.1051,1.10529 -1.93945,1.10529h-21.42456c-1.24048,0 -2.25525,-0.99463 -2.25525,-2.21051v-35.36755c0,-1.2157 1.01477,-2.21045 2.25525,-2.21045h21.42456c1.24036,0 2.25525,0.99475 2.25525,2.21045v14.31342c0.3833,-0.01111 0.76672,-0.06628 1.12756,-0.16583z' fill='%23ffffff' fill-opacity='1'%3E%3C/path%3E%3Cpath d='M28.87872,21.43719v0v-14.14758c0,-0.23206 -0.02258,-0.45312 -0.06763,-0.67419c-0.06763,-0.32043 -0.19177,-0.6189 -0.33838,-0.90625c-0.0564,-0.09943 -0.11267,-0.18793 -0.16907,-0.27637c-0.12402,-0.17676 -0.2594,-0.34253 -0.41724,-0.48627c-0.14661,-0.15466 -0.3158,-0.28735 -0.49609,-0.409c-0.09021,-0.05518 -0.18054,-0.11041 -0.28198,-0.16571c-0.29321,-0.14368 -0.59766,-0.26526 -0.92456,-0.33154c-0.22559,-0.04425 -0.45117,-0.06635 -0.68787,-0.06635h-21.42456c-0.23682,0 -0.4624,0.02209 -0.68787,0.06635c-0.32703,0.06628 -0.6427,0.18787 -0.92468,0.33154c-0.10144,0.0553 -0.19165,0.11053 -0.28186,0.16571c-0.18042,0.12164 -0.34961,0.25433 -0.49609,0.409c-0.62024,0.60791 -0.99231,1.42584 -0.99231,2.34308v35.36755c0,0.91742 0.37207,1.73523 0.99231,2.3432c0.14648,0.14362 0.31567,0.28735 0.49609,0.40894c0.09021,0.05524 0.18042,0.11053 0.28186,0.16571c0.28198,0.14368 0.59766,0.26532 0.92468,0.3316c0.22546,0.04419 0.45105,0.06628 0.68787,0.06628h21.42456c0.23669,0 0.46228,-0.02209 0.68787,-0.06628c0.3269,-0.06628 0.63135,-0.18793 0.92456,-0.3316c0.10144,-0.05518 0.19177,-0.11047 0.28198,-0.16571c0.1803,-0.13269 0.34949,-0.26532 0.49609,-0.40894c0.15784,-0.14368 0.29321,-0.30957 0.41724,-0.48633c0.0564,-0.08844 0.11267,-0.17682 0.16907,-0.27631c0.07898,-0.15479 0.15796,-0.30951 0.21423,-0.47534c0.02258,-0.07727 0.04517,-0.14362 0.06775,-0.2099c0.02246,-0.06641 0.04504,-0.14374 0.0564,-0.22107c0.04504,-0.22107 0.06763,-0.44214 0.06763,-0.67426v-16.99847c-0.36084,0.06628 -0.74426,0.09949 -1.12756,0.09949v16.89899c0,0.39801 -0.11279,0.78479 -0.3158,1.10522c-0.3833,0.66321 -1.1051,1.10529 -1.93945,1.10529h-21.42456c-1.24048,0 -2.25525,-0.99463 -2.25525,-2.21051v-35.36755c0,-1.2157 1.01477,-2.21045 2.25525,-2.21045h21.42456c1.24036,0 2.25525,0.99475 2.25525,2.21045v14.31342c0.3833,-0.01111 0.76672,-0.06628 1.12756,-0.16583z' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='miter' stroke-linecap='butt' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='0.5'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3EPath 718%3C/title%3E%3Cpath d='M28.87872,21.59094v-14.30133c0,-0.23206 -0.02258,-0.45312 -0.06763,-0.67419c-0.06763,-0.32043 -0.19177,-0.6189 -0.33838,-0.90625c-0.0564,-0.09943 -0.11267,-0.18793 -0.16907,-0.27637c-0.13538,-0.17676 -0.27063,-0.34253 -0.41724,-0.48627c-0.14661,-0.14374 -0.3158,-0.27631 -0.49609,-0.409c-0.09021,-0.05518 -0.18054,-0.11041 -0.28198,-0.16571c-0.29321,-0.14368 -0.59766,-0.26526 -0.92456,-0.33154c-0.22559,-0.04425 -0.45117,-0.06635 -0.68787,-0.06635h-21.42456c-0.23682,0 -0.4624,0.02209 -0.68787,0.06635c-0.32703,0.06628 -0.6427,0.18787 -0.92468,0.33154c-0.10144,0.0553 -0.19165,0.11053 -0.28186,0.16571c-0.18042,0.12164 -0.34961,0.26526 -0.49609,0.409c-0.62024,0.60791 -0.99231,1.42584 -0.99231,2.34308v35.36755c0,0.91742 0.37207,1.73523 0.99231,2.3432c0.14648,0.14362 0.31567,0.28735 0.49609,0.40894c0.09021,0.05524 0.18042,0.11053 0.28186,0.16571c0.28198,0.14368 0.59766,0.26532 0.92468,0.3316c0.22546,0.04419 0.45105,0.06628 0.68787,0.06628h21.42456c0.23669,0 0.46228,-0.02209 0.68787,-0.06628c0.3269,-0.06628 0.63135,-0.18793 0.92456,-0.3316c0.10144,-0.05518 0.19177,-0.11047 0.28198,-0.16571c0.1803,-0.13269 0.34949,-0.26532 0.49609,-0.40894c0.14661,-0.14368 0.28186,-0.30957 0.41724,-0.48633c0.0564,-0.08844 0.11267,-0.17682 0.16907,-0.27631c0.07898,-0.15479 0.14661,-0.30951 0.203,-0.47534c0.03381,-0.07727 0.0564,-0.14362 0.07898,-0.2099c0.02246,-0.06641 0.04504,-0.14374 0.0564,-0.22107c0.04504,-0.22107 0.06763,-0.44214 0.06763,-0.67426v-16.99847c-0.36084,0.06628 -0.74426,0.09949 -1.12756,0.09949v16.89899c0,0.39801 -0.11279,0.78479 -0.3158,1.10522c-0.3833,0.66321 -1.1051,1.10529 -1.93945,1.10529h-21.42456c-1.24048,0 -2.25525,-0.99463 -2.25525,-2.21051v-35.36755c0,-1.2157 1.01477,-2.21045 2.25525,-2.21045h21.42456c1.24036,0 2.25525,0.99475 2.25525,2.21045v14.46716c0.3833,-0.01105 0.76672,-0.06628 1.12756,-0.16583z' fill='%23ffffff' fill-opacity='1'%3E%3C/path%3E%3Cpath d='M28.87872,21.59094v-14.30133c0,-0.23206 -0.02258,-0.45312 -0.06763,-0.67419c-0.06763,-0.32043 -0.19177,-0.6189 -0.33838,-0.90625c-0.0564,-0.09943 -0.11267,-0.18793 -0.16907,-0.27637c-0.13538,-0.17676 -0.27063,-0.34253 -0.41724,-0.48627c-0.14661,-0.14374 -0.3158,-0.27631 -0.49609,-0.409c-0.09021,-0.05518 -0.18054,-0.11041 -0.28198,-0.16571c-0.29321,-0.14368 -0.59766,-0.26526 -0.92456,-0.33154c-0.22559,-0.04425 -0.45117,-0.06635 -0.68787,-0.06635h-21.42456c-0.23682,0 -0.4624,0.02209 -0.68787,0.06635c-0.32703,0.06628 -0.6427,0.18787 -0.92468,0.33154c-0.10144,0.0553 -0.19165,0.11053 -0.28186,0.16571c-0.18042,0.12164 -0.34961,0.26526 -0.49609,0.409c-0.62024,0.60791 -0.99231,1.42584 -0.99231,2.34308v35.36755c0,0.91742 0.37207,1.73523 0.99231,2.3432c0.14648,0.14362 0.31567,0.28735 0.49609,0.40894c0.09021,0.05524 0.18042,0.11053 0.28186,0.16571c0.28198,0.14368 0.59766,0.26532 0.92468,0.3316c0.22546,0.04419 0.45105,0.06628 0.68787,0.06628h21.42456c0.23669,0 0.46228,-0.02209 0.68787,-0.06628c0.3269,-0.06628 0.63135,-0.18793 0.92456,-0.3316c0.10144,-0.05518 0.19177,-0.11047 0.28198,-0.16571c0.1803,-0.13269 0.34949,-0.26532 0.49609,-0.40894c0.14661,-0.14368 0.28186,-0.30957 0.41724,-0.48633c0.0564,-0.08844 0.11267,-0.17682 0.16907,-0.27631c0.07898,-0.15479 0.14661,-0.30951 0.203,-0.47534c0.03381,-0.07727 0.0564,-0.14362 0.07898,-0.2099c0.02246,-0.06641 0.04504,-0.14374 0.0564,-0.22107c0.04504,-0.22107 0.06763,-0.44214 0.06763,-0.67426v-16.99847c-0.36084,0.06628 -0.74426,0.09949 -1.12756,0.09949v16.89899c0,0.39801 -0.11279,0.78479 -0.3158,1.10522c-0.3833,0.66321 -1.1051,1.10529 -1.93945,1.10529h-21.42456c-1.24048,0 -2.25525,-0.99463 -2.25525,-2.21051v-35.36755c0,-1.2157 1.01477,-2.21045 2.25525,-2.21045h21.42456c1.24036,0 2.25525,0.99475 2.25525,2.21045v14.46716c0.3833,-0.01105 0.76672,-0.06628 1.12756,-0.16583z' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='miter' stroke-linecap='butt' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='0.5'%3E%3C/path%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/svg%3E") center center/94px 98px no-repeat; +} + +.o-button-course-tile { + @include card-icon-button; + + z-index: 1; + width: 110px; + height: 90px; + min-height: 90px; + background: url("data:image/svg+xml,%3C%3Fxml version='1.0' encoding='UTF-8'%3F%3E%3Csvg id='SVGDoc' width='47' height='54' xmlns='http://www.w3.org/2000/svg' version='1.1' xmlns:xlink='http://www.w3.org/1999/xlink' xmlns:avocode='https://avocode.com/' viewBox='0 0 47 54'%3E%3Cdefs%3E%3C/defs%3E%3Cdesc%3EGenerated with Avocode.%3C/desc%3E%3Cg%3E%3Cg opacity='0.6'%3E%3Ctitle%3EPath 1027%3C/title%3E%3Cpath d='M39.08664,7.16107l-0.00122,-0.00564c-0.08379,-0.37337 -0.21628,-0.7348 -0.39729,-1.08072c-0.06219,-0.11108 -0.12469,-0.21135 -0.18509,-0.30831l-0.01439,-0.02235c-0.29175,-0.41367 -0.64963,-0.77077 -1.0639,-1.06149l-0.01187,-0.00797c-0.09203,-0.05719 -0.20007,-0.12391 -0.3188,-0.1909l-0.0078,-0.00424c-0.34019,-0.17703 -0.70258,-0.30909 -1.08263,-0.39366c-0.26308,-0.05277 -0.53247,-0.07954 -0.80057,-0.07954h-18.21632c0.05061,-0.15615 0.11862,-0.30684 0.20537,-0.44817l0.00452,-0.00771c0.38698,-0.68247 1.11572,-1.10516 1.90027,-1.10135h23.48293c1.21486,0.00217 2.2072,0.99226 2.21205,2.20616v39.45757c-0.00485,1.21495 -0.99719,2.20503 -2.2117,2.20728h-3.41382v-38.3531c0.00041,-0.27 -0.02634,-0.54113 -0.07973,-0.80585zM31.87711,49.63022v-18.30538l0.00729,-0.31542l-0.01276,0.00243v-19.82146c0.00026,-0.26533 -0.0265,-0.53152 -0.08101,-0.79694c-0.08424,-0.36835 -0.21689,-0.72415 -0.39713,-1.06226c-0.05954,-0.10607 -0.11871,-0.19896 -0.17599,-0.28881l-0.0213,-0.0331c-0.14151,-0.20753 -0.30641,-0.39999 -0.49004,-0.57217c-0.1778,-0.18076 -0.37572,-0.34236 -0.59425,-0.48421c-0.09671,-0.0591 -0.20103,-0.12218 -0.31845,-0.18743l-0.00772,-0.00407c-0.34044,-0.17426 -0.70256,-0.30432 -1.08235,-0.3876c-0.26489,-0.05181 -0.53784,-0.07764 -0.80396,-0.07712h-18.29144c0.04999,-0.14904 0.11594,-0.29297 0.19904,-0.42841l0.00452,-0.00771c0.3856,-0.67995 1.10931,-1.10134 1.8916,-1.10134h23.4915c1.21497,0.00216 2.20738,0.99233 2.21216,2.20624v39.45747c-0.00478,1.21495 -0.99719,2.20512 -2.21172,2.20729zM30.12076,32.16492v17.79372c0.00087,0.3797 -0.10527,0.75058 -0.30666,1.07274l-0.00424,0.00687c-0.38994,0.66859 -1.1107,1.08218 -1.88571,1.08218c-0.00505,0 -0.01006,-0.00009 -0.01501,-0.00009h-23.48941c-0.00511,0 -0.01006,0.00009 -0.01517,0.00009c-1.19615,0 -2.17929,-0.96884 -2.19481,-2.16353v-38.76331c0.01604,-1.19744 0.99927,-2.16595 2.19662,-2.16595c0.00504,0 0.01015,0 0.01508,0.00009h23.48518c0.00504,-0.00009 0.00987,-0.00009 0.01491,-0.00009c1.19571,0 2.17896,0.96861 2.19498,2.16249v20.97479zM46.47191,3.85097l-0.00131,-0.00572c-0.08388,-0.37338 -0.21629,-0.73472 -0.39731,-1.08081c-0.06151,-0.10953 -0.12312,-0.20848 -0.18265,-0.30415l-0.01698,-0.02652c-0.29169,-0.41358 -0.64964,-0.77077 -1.06383,-1.06148l-0.01196,-0.00789c-0.09177,-0.0572 -0.19972,-0.12374 -0.31862,-0.1909l-0.0078,-0.00433c-0.34036,-0.17703 -0.70284,-0.309 -1.08272,-0.39358c-0.26317,-0.05277 -0.53256,-0.07954 -0.80067,-0.07954h-23.48761c-0.27112,0.00104 -0.54088,0.02643 -0.8094,0.08033c-0.37633,0.08154 -0.73975,0.21394 -1.08592,0.39669c-0.10329,0.05798 -0.20537,0.11906 -0.32114,0.19246l-0.0083,0.00555c-0.20859,0.14366 -0.40511,0.30717 -0.58456,0.48637c-0.41385,0.41471 -0.73802,0.92518 -0.93802,1.4782c-0.07729,0.21906 -0.13455,0.44314 -0.17218,0.6706h-3.47022c-0.2683,0 -0.53778,0.02677 -0.80475,0.08041c-0.37633,0.08145 -0.73965,0.21386 -1.08583,0.39661c-0.10286,0.05762 -0.20485,0.11871 -0.32121,0.19245l-0.00842,0.00554c-0.20865,0.14384 -0.40518,0.30736 -0.58446,0.48639c-0.41385,0.4147 -0.73801,0.92518 -0.938,1.47819c-0.07513,0.21273 -0.13153,0.43014 -0.16924,0.65084h-3.37674c-0.26862,0.00113 -0.54036,0.02539 -0.8089,0.07799c-0.37529,0.08007 -0.73845,0.21039 -1.08496,0.39037c-0.11023,0.06066 -0.20988,0.12097 -0.32521,0.19168c-0.21437,0.13898 -0.41368,0.30206 -0.58714,0.47926c-0.74332,0.71783 -1.16861,1.72221 -1.16669,2.75519v38.76547c-0.00192,1.03334 0.42337,2.03772 1.16521,2.75397c0.17946,0.17618 0.37607,0.33699 0.58429,0.47806l0.04445,0.02748c0.08943,0.05475 0.18198,0.11143 0.29063,0.16992c0.34097,0.17703 0.70413,0.30745 1.08368,0.38828c0.26428,0.05176 0.53664,0.07626 0.80403,0.07722h23.49107c0.26689,0 0.5349,-0.026 0.80205,-0.07841c0.37399,-0.08208 0.73619,-0.21205 1.08342,-0.39003c0.10321,-0.05676 0.20535,-0.11681 0.32129,-0.18907l0.01259,-0.00841c0.20215,-0.14299 0.39609,-0.30156 0.57544,-0.47052c0.18518,-0.17296 0.35156,-0.36681 0.49887,-0.5831l0.00519,-0.00821c0.06091,-0.09558 0.12392,-0.19455 0.18942,-0.31032c0.07521,-0.13907 0.14264,-0.28334 0.20181,-0.4303h3.59952c0.26871,0 0.53836,-0.02679 0.80682,-0.08067c0.37476,-0.08353 0.73714,-0.21561 1.08435,-0.39626c0.10355,-0.05807 0.2057,-0.11923 0.3214,-0.19264l0.01006,-0.00674c0.41438,-0.2908 0.77216,-0.6479 1.0639,-1.06149l0.02713,-0.0428c0.05641,-0.09038 0.11455,-0.18379 0.1759,-0.29454c0.17738,-0.33907 0.30995,-0.7005 0.39503,-1.07976c0.01031,-0.05147 0.01889,-0.10338 0.02722,-0.15529h3.47327c0.26862,0 0.53828,-0.02676 0.8069,-0.08067c0.37425,-0.08345 0.73671,-0.2155 1.08446,-0.39642c0.10275,-0.05763 0.20476,-0.1188 0.32103,-0.19238l0.01024,-0.00684c0.41428,-0.2908 0.77214,-0.6479 1.06383,-1.06149l0.02841,-0.04489c0.05598,-0.08966 0.11386,-0.18239 0.17479,-0.29245c0.17737,-0.33907 0.30986,-0.70049 0.39505,-1.07976c0.0531,-0.26404 0.07979,-0.53439 0.07954,-0.80319v-39.45816c0.00034,-0.26991 -0.02635,-0.54096 -0.07954,-0.80577z' fill='%23ffffff' fill-opacity='1'%3E%3C/path%3E%3C/g%3E%3C/g%3E%3C/svg%3E") center center/95px 110px no-repeat; +} + +.o-button-course-podcast { + @include card-icon-button; + + width: 99px; + height: 99px; + min-height: 99px; + z-index: 1; + background: url("data:image/svg+xml,%3C%3Fxml version='1.0' encoding='UTF-8'%3F%3E%3Csvg id='SVGDoc' width='46' height='46' xmlns='http://www.w3.org/2000/svg' version='1.1' xmlns:xlink='http://www.w3.org/1999/xlink' xmlns:avocode='https://avocode.com/' viewBox='0 0 46 46'%3E%3Cdefs%3E%3C/defs%3E%3Cdesc%3EGenerated with Avocode.%3C/desc%3E%3Cg%3E%3Cg opacity='0.6'%3E%3Ctitle%3ELine 172%3C/title%3E%3Cpath d='M15.00098,19h4' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='miter' stroke-linecap='square' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='2'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3ELine 171%3C/title%3E%3Cpath d='M27.00098,27h4' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='miter' stroke-linecap='square' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='2'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3ELine 168%3C/title%3E%3Cpath d='M15.00098,11h4' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='miter' stroke-linecap='square' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='2'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3EPath 1028%3C/title%3E%3Cpath d='M5.10098,28.9c-5.46801,-5.46745 -5.46801,-14.33254 0,-19.8' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='miter' stroke-linecap='square' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='2'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3ELine 175%3C/title%3E%3Cpath d='M20.00098,37v8' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='miter' stroke-linecap='square' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='2'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3ELine 169%3C/title%3E%3Cpath d='M27.00098,11h4' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='miter' stroke-linecap='square' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='2'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3EPath 1030%3C/title%3E%3Cpath d='M40.90098,28.9c5.46802,-5.46746 5.46802,-14.33254 0,-19.8' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='miter' stroke-linecap='square' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='2'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3ELine 170%3C/title%3E%3Cpath d='M15.00098,27h4' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='miter' stroke-linecap='square' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='2'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3ERectangle 2190%3C/title%3E%3Cpath d='M19.00098,37c-2.20914,0 -4,-1.79086 -4,-4v-28c0,-2.20914 1.79086,-4 4,-4h8c2.20914,0 4,1.79086 4,4v28c0,2.20914 -1.79086,4 -4,4z' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='miter' stroke-linecap='square' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='2'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3Epodcast-mic%3C/title%3E%3Cg opacity='0.6'%3E%3Ctitle%3ERectangle 2190%3C/title%3E%3Cpath d='M19.00098,37c-2.20914,0 -4,-1.79086 -4,-4v-28c0,-2.20914 1.79086,-4 4,-4h8c2.20914,0 4,1.79086 4,4v28c0,2.20914 -1.79086,4 -4,4z' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='miter' stroke-linecap='square' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='2'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3EPath 1028%3C/title%3E%3Cpath d='M5.10098,28.9c-5.46801,-5.46745 -5.46801,-14.33254 0,-19.8' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='miter' stroke-linecap='square' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='2'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3EPath 1029%3C/title%3E%3Cpath d='M9.34398,13.343c-3.12439,3.12423 -3.12439,8.18977 0,11.314' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='miter' stroke-linecap='square' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='2'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3EPath 1030%3C/title%3E%3Cpath d='M40.90098,28.9c5.46802,-5.46746 5.46802,-14.33254 0,-19.8' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='miter' stroke-linecap='square' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='2'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3EPath 1031%3C/title%3E%3Cpath d='M36.65798,13.343c3.12439,3.12423 3.12439,8.18977 0,11.314' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='miter' stroke-linecap='square' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='2'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3ELine 168%3C/title%3E%3Cpath d='M15.00098,11h4' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='miter' stroke-linecap='square' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='2'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3ELine 169%3C/title%3E%3Cpath d='M27.00098,11h4' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='miter' stroke-linecap='square' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='2'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3ELine 170%3C/title%3E%3Cpath d='M15.00098,27h4' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='miter' stroke-linecap='square' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='2'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3ELine 171%3C/title%3E%3Cpath d='M27.00098,27h4' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='miter' stroke-linecap='square' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='2'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3ELine 172%3C/title%3E%3Cpath d='M15.00098,19h4' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='miter' stroke-linecap='square' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='2'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3ELine 173%3C/title%3E%3Cpath d='M27.00098,19h4' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='miter' stroke-linecap='square' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='2'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3ELine 174%3C/title%3E%3Cpath d='M26.00098,37v8' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='miter' stroke-linecap='square' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='2'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3ELine 175%3C/title%3E%3Cpath d='M20.00098,37v8' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='miter' stroke-linecap='square' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='2'%3E%3C/path%3E%3C/g%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3ELine 173%3C/title%3E%3Cpath d='M27.00098,19h4' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='miter' stroke-linecap='square' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='2'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3EPath 1031%3C/title%3E%3Cpath d='M36.65798,13.343c3.12439,3.12423 3.12439,8.18977 0,11.314' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='miter' stroke-linecap='square' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='2'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3EPath 1029%3C/title%3E%3Cpath d='M9.34398,13.343c-3.12439,3.12423 -3.12439,8.18977 0,11.314' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='miter' stroke-linecap='square' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='2'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3ELine 174%3C/title%3E%3Cpath d='M26.00098,37v8' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='miter' stroke-linecap='square' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='2'%3E%3C/path%3E%3C/g%3E%3C/g%3E%3C/svg%3E") center center/99px 99px no-repeat; +} + +.o-button--quiz { + @include card-icon-button; + + width: 95px; + height: 95px; + min-height: 95px; + background: url("data:image/svg+xml,%3C%3Fxml version='1.0' encoding='UTF-8'%3F%3E%3Csvg id='SVGDoc' width='45' height='45' xmlns='http://www.w3.org/2000/svg' version='1.1' xmlns:xlink='http://www.w3.org/1999/xlink' xmlns:avocode='https://avocode.com/' viewBox='0 0 45 45'%3E%3Cdefs%3E%3C/defs%3E%3Cdesc%3EGenerated with Avocode.%3C/desc%3E%3Cg%3E%3Cg opacity='0.6'%3E%3Ctitle%3EPath 710%3C/title%3E%3Cpath d='M4.55106,9.24434c0.14223,0.14223 0.37927,0.23705 0.5689,0.23705c0.18964,0 0.42668,-0.09482 0.56891,-0.23705l1.13781,-1.13781v0l1.13781,1.13781c0.14223,0.14223 0.37927,0.23705 0.56891,0.23705c0.23705,0 0.42668,-0.09482 0.56891,-0.23705c0.33187,-0.33186 0.33187,-0.85336 0,-1.18522l-1.043,-1.13782v0l1.13782,-1.13781c0.33186,-0.33186 0.33186,-0.85336 0,-1.18522c-0.33186,-0.33186 -0.85336,-0.33186 -1.18522,0l-1.13781,1.13781v0l-1.13782,-1.13781c-0.33186,-0.33186 -0.85336,-0.33186 -1.18522,0c-0.33186,0.33186 -0.33186,0.85336 0,1.18522l1.13781,1.13781v0l-1.13781,1.13782c-0.33186,0.33186 -0.33186,0.85336 0,1.18522z' fill='%23ffffff' fill-opacity='1'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3EPath 709%3C/title%3E%3Cpath d='M9.19713,35.8497c-0.33186,-0.33186 -0.85336,-0.33186 -1.18522,0l-1.13781,1.13781v0l-1.13782,-1.13781c-0.33186,-0.33186 -0.85336,-0.33186 -1.18522,0c-0.33186,0.33186 -0.33186,0.85336 0,1.18522l1.13781,1.13781v0l-1.13781,1.13782c-0.33186,0.33186 -0.33186,0.85336 0,1.18522c0.14223,0.14223 0.37927,0.23705 0.5689,0.23705c0.18964,0 0.42668,-0.09482 0.56891,-0.23705l1.13781,-1.1378v0l1.13781,1.1378c0.14223,0.14223 0.37927,0.23705 0.56891,0.23705c0.23705,0 0.42668,-0.09482 0.56891,-0.23705c0.33186,-0.33186 0.33186,-0.85336 0,-1.18522l-1.043,-1.13782v0l1.13781,-1.13781c0.33186,-0.33186 0.33186,-0.85336 0,-1.18522z' fill='%23ffffff' fill-opacity='1'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3EPath 708%3C/title%3E%3Cpath d='M6.86721,43.38771c-2.88905,0 -5.20976,-2.32303 -5.20976,-5.21498c0,-2.89195 2.32071,-5.21498 5.20976,-5.21498c2.88905,0 5.20976,2.32303 5.20976,5.21498c0,2.84454 -2.32071,5.21498 -5.20976,5.21498zM42.38324,33.85852h-30.16418c-1.27876,-1.5645 -3.17322,-2.60748 -5.35184,-2.60748c-3.78891,0 -6.86741,3.08157 -6.86741,6.87428c0,3.79271 3.07849,6.87428 6.86741,6.87428c2.17862,0 4.07308,-1.043 5.35184,-2.60747h30.16418c0.47361,0 0.85251,-0.37929 0.85251,-0.85338v-6.82687c0,-0.47411 -0.3789,-0.85336 -0.85251,-0.85336z' fill='%23ffffff' fill-opacity='1'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3EPath 707%3C/title%3E%3Cpath d='M8.34377,20.55573v0l-2.08599,2.37045v0l-1.043,-1.04301c-0.33186,-0.33186 -0.85336,-0.33186 -1.18522,0c-0.33186,0.33187 -0.33186,0.85336 0,1.18523l1.65931,1.65931c0.14223,0.14223 0.37927,0.23705 0.56891,0.23705c0,0 0,0 0.04741,0c0.23705,0 0.42668,-0.09482 0.61632,-0.28446l2.7023,-3.03416c0.28445,-0.33187 0.28445,-0.85336 -0.09482,-1.18523c-0.37927,-0.28445 -0.90077,-0.23705 -1.18522,0.09481z' fill='%23ffffff' fill-opacity='1'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3EPath 706%3C/title%3E%3Cpath d='M6.86823,27.76195c-2.88947,0 -5.21053,-2.32304 -5.21053,-5.21498c0,-2.89194 2.32105,-5.21498 5.21053,-5.21498c2.88948,0 5.21053,2.32303 5.21053,5.21498c0,2.89194 -2.32106,5.21498 -5.21053,5.21498zM43.91962,18.28016h-31.69876c-1.27895,-1.56449 -3.17369,-2.60749 -5.35263,-2.60749c-3.78947,0 -6.86842,3.08157 -6.86842,6.87429c0,3.79271 3.07895,6.87429 6.86842,6.87429c2.17895,0 4.07369,-1.043 5.35263,-2.60749h31.69876c0.47368,0 0.85263,-0.37928 0.85263,-0.85336v-6.87429c0,-0.47409 -0.37895,-0.80595 -0.85263,-0.80595z' fill='%23ffffff' fill-opacity='1'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3EPath 705%3C/title%3E%3Cpath d='M6.8741,1.70633c2.89194,0 5.21498,2.32304 5.21498,5.21498c0,2.89194 -2.32304,5.21498 -5.21498,5.21498c-2.89194,0 -5.21498,-2.32304 -5.21498,-5.21498c0,-2.84453 2.37045,-5.21498 5.21498,-5.21498zM6.8741,13.7956c2.18081,0 4.07717,-1.043 5.35721,-2.60749h23.89104c0.47408,0 0.85337,-0.37927 0.85337,-0.85336v-6.87429c0,-0.47409 -0.37928,-0.85336 -0.85337,-0.85336h-23.89104c-1.28004,-1.56449 -3.1764,-2.60749 -5.35721,-2.60749c-3.79271,0.04741 -6.87429,3.12899 -6.87429,6.9217c0,3.79271 3.08158,6.87429 6.87429,6.87429z' fill='%23ffffff' fill-opacity='1'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3EGroup 2130%3C/title%3E%3Cg opacity='0.6'%3E%3Ctitle%3EPath 705%3C/title%3E%3Cpath d='M6.8741,1.70633c2.89194,0 5.21498,2.32304 5.21498,5.21498c0,2.89194 -2.32304,5.21498 -5.21498,5.21498c-2.89194,0 -5.21498,-2.32304 -5.21498,-5.21498c0,-2.84453 2.37045,-5.21498 5.21498,-5.21498zM6.8741,13.7956c2.18081,0 4.07717,-1.043 5.35721,-2.60749h23.89104c0.47408,0 0.85337,-0.37927 0.85337,-0.85336v-6.87429c0,-0.47409 -0.37928,-0.85336 -0.85337,-0.85336h-23.89104c-1.28004,-1.56449 -3.1764,-2.60749 -5.35721,-2.60749c-3.79271,0.04741 -6.87429,3.12899 -6.87429,6.9217c0,3.79271 3.08158,6.87429 6.87429,6.87429z' fill='%23ffffff' fill-opacity='1'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3EPath 706%3C/title%3E%3Cpath d='M6.86823,27.76195c-2.88947,0 -5.21053,-2.32304 -5.21053,-5.21498c0,-2.89194 2.32105,-5.21498 5.21053,-5.21498c2.88948,0 5.21053,2.32303 5.21053,5.21498c0,2.89194 -2.32106,5.21498 -5.21053,5.21498zM43.91962,18.28016h-31.69876c-1.27895,-1.56449 -3.17369,-2.60749 -5.35263,-2.60749c-3.78947,0 -6.86842,3.08157 -6.86842,6.87429c0,3.79271 3.07895,6.87429 6.86842,6.87429c2.17895,0 4.07369,-1.043 5.35263,-2.60749h31.69876c0.47368,0 0.85263,-0.37928 0.85263,-0.85336v-6.87429c0,-0.47409 -0.37895,-0.80595 -0.85263,-0.80595z' fill='%23ffffff' fill-opacity='1'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3EPath 707%3C/title%3E%3Cpath d='M8.34377,20.55573v0l-2.08599,2.37045v0l-1.043,-1.04301c-0.33186,-0.33186 -0.85336,-0.33186 -1.18522,0c-0.33186,0.33187 -0.33186,0.85336 0,1.18523l1.65931,1.65931c0.14223,0.14223 0.37927,0.23705 0.56891,0.23705c0,0 0,0 0.04741,0c0.23705,0 0.42668,-0.09482 0.61632,-0.28446l2.7023,-3.03416c0.28445,-0.33187 0.28445,-0.85336 -0.09482,-1.18523c-0.37927,-0.28445 -0.90077,-0.23705 -1.18522,0.09481z' fill='%23ffffff' fill-opacity='1'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3EPath 708%3C/title%3E%3Cpath d='M6.86721,43.38771c-2.88905,0 -5.20976,-2.32303 -5.20976,-5.21498c0,-2.89195 2.32071,-5.21498 5.20976,-5.21498c2.88905,0 5.20976,2.32303 5.20976,5.21498c0,2.84454 -2.32071,5.21498 -5.20976,5.21498zM42.38324,33.85852h-30.16418c-1.27876,-1.5645 -3.17322,-2.60748 -5.35184,-2.60748c-3.78891,0 -6.86741,3.08157 -6.86741,6.87428c0,3.79271 3.07849,6.87428 6.86741,6.87428c2.17862,0 4.07308,-1.043 5.35184,-2.60747h30.16418c0.47361,0 0.85251,-0.37929 0.85251,-0.85338v-6.82687c0,-0.47411 -0.3789,-0.85336 -0.85251,-0.85336z' fill='%23ffffff' fill-opacity='1'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3EPath 709%3C/title%3E%3Cpath d='M9.19713,35.8497c-0.33186,-0.33186 -0.85336,-0.33186 -1.18522,0l-1.13781,1.13781v0l-1.13782,-1.13781c-0.33186,-0.33186 -0.85336,-0.33186 -1.18522,0c-0.33186,0.33186 -0.33186,0.85336 0,1.18522l1.13781,1.13781v0l-1.13781,1.13782c-0.33186,0.33186 -0.33186,0.85336 0,1.18522c0.14223,0.14223 0.37927,0.23705 0.5689,0.23705c0.18964,0 0.42668,-0.09482 0.56891,-0.23705l1.13781,-1.1378v0l1.13781,1.1378c0.14223,0.14223 0.37927,0.23705 0.56891,0.23705c0.23705,0 0.42668,-0.09482 0.56891,-0.23705c0.33186,-0.33186 0.33186,-0.85336 0,-1.18522l-1.043,-1.13782v0l1.13781,-1.13781c0.33186,-0.33186 0.33186,-0.85336 0,-1.18522z' fill='%23ffffff' fill-opacity='1'%3E%3C/path%3E%3C/g%3E%3Cg opacity='0.6'%3E%3Ctitle%3EPath 710%3C/title%3E%3Cpath d='M4.55106,9.24434c0.14223,0.14223 0.37927,0.23705 0.5689,0.23705c0.18964,0 0.42668,-0.09482 0.56891,-0.23705l1.13781,-1.13781v0l1.13781,1.13781c0.14223,0.14223 0.37927,0.23705 0.56891,0.23705c0.23705,0 0.42668,-0.09482 0.56891,-0.23705c0.33187,-0.33186 0.33187,-0.85336 0,-1.18522l-1.043,-1.13782v0l1.13782,-1.13781c0.33186,-0.33186 0.33186,-0.85336 0,-1.18522c-0.33186,-0.33186 -0.85336,-0.33186 -1.18522,0l-1.13781,1.13781v0l-1.13782,-1.13781c-0.33186,-0.33186 -0.85336,-0.33186 -1.18522,0c-0.33186,0.33186 -0.33186,0.85336 0,1.18522l1.13781,1.13781v0l-1.13781,1.13782c-0.33186,0.33186 -0.33186,0.85336 0,1.18522z' fill='%23ffffff' fill-opacity='1'%3E%3C/path%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/svg%3E") center center/95px 95px no-repeat; +} + +.o-button--event-button { + @include card-icon-button; + + width: 93px; + height: 92px; + min-height: 92px; + opacity: 0.6; + background: url("data:image/svg+xml,%3Csvg id='Layer_1' data-name='Layer 1' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 60 60'%3E%3Cdefs%3E%3Cstyle%3E.cls-1%7Bfill:%23fff;%7D%3C/style%3E%3C/defs%3E%3Cg id='Group_2118' data-name='Group 2118'%3E%3Cg id='Group_2116' data-name='Group 2116'%3E%3Cpath class='cls-1' d='M51.63,56.42a1.85,1.85,0,0,1-.69-.12h0l-13.8-5.52a30.56,30.56,0,0,1-7.31.8C13.89,51.58,1,40.82,1,27.59s12.94-24,28.83-24,28.84,10.76,28.84,24a21.43,21.43,0,0,1-6.13,14.77L53.77,54a2.35,2.35,0,0,1-.85,2l-.11.07a2.72,2.72,0,0,1-1.14.39Zm-.28-2.09a1.63,1.63,0,0,1,.23.07.42.42,0,0,0,.12,0,.35.35,0,0,0,.08-.22L50.4,41.62l.35-.34a19.44,19.44,0,0,0,5.87-13.7c0-12.12-12-22-26.84-22S3,15.46,3,27.59s12,22,26.83,22a29.12,29.12,0,0,0,7.15-.82l.31-.07Z'/%3E%3C/g%3E%3Cg id='Group_2117' data-name='Group 2117'%3E%3Cpath class='cls-1' d='M18.89,39.48a4.64,4.64,0,0,1-4.63-4.63V20.33a4.64,4.64,0,0,1,4.63-4.63H33.41A4.63,4.63,0,0,1,38,20.33v2l5.82-2.91a1,1,0,0,1,1,.05,1,1,0,0,1,.48.85V34.85a1,1,0,0,1-1.45.89L38,32.84v2a4.63,4.63,0,0,1-4.63,4.63Zm0-21.78a2.63,2.63,0,0,0-2.63,2.63V34.85a2.63,2.63,0,0,0,2.63,2.63H33.41A2.63,2.63,0,0,0,36,34.85V31.22a1,1,0,0,1,.48-.85,1,1,0,0,1,1-.05l5.82,2.91V22l-5.82,2.9a1,1,0,0,1-1,0A1,1,0,0,1,36,24V20.33a2.63,2.63,0,0,0-2.63-2.63Z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E") center center/93px 92px no-repeat; +} diff --git a/web/themes/custom/perls/resources/scss/_objects.cards.scss b/web/themes/custom/perls/resources/scss/_objects.cards.scss new file mode 100644 index 0000000..a3a7124 --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_objects.cards.scss @@ -0,0 +1,1216 @@ +/* ------------------------------------ *\ + $CARDS +\* ------------------------------------ */ + +.c-node { + position: relative; + width: 100%; + word-wrap: break-word; + word-break: break-word; + + &__actions { + display: flex; + width: 100%; + justify-content: space-between; + + &-edit { + margin-left: $space; + } + } + + & &__byline { + margin-top: 0; + } + + .c-node__content { + color: $c-content--foreground; + } +} + +.c-card { + display: flex; + flex-direction: column; + border-radius: $border-radius--card; + box-shadow: $box-shadow; + position: relative; + overflow: hidden; + min-height: 250px; + + &::after { + display: block; + font-weight: bold; + text-transform: uppercase; + color: rgba($c-black, 0.1); + position: absolute; + top: 0; + left: -5px; + font-size: 100px; + line-height: 1; + white-space: pre; + font-family: $ff-font--secondary; + z-index: 0; + pointer-events: none; + } + + &__header { + padding: $space; + + .status { + float: right; + font-weight: bold; + } + + h3 { + clear: both; + font-size: 1.25em; + } + + h5 { + font-weight: normal; + text-transform: none; + } + } + + &__title { + @include o-heading--l; + @include u-visible; + + display: block; + } + + &__content { + flex-grow: 1; + overflow: auto; + position: relative; + padding: $space; + z-index: 1; + + a { + display: block; + } + } + + &__footer { + padding: $space-half $space; + display: block; + border-bottom-left-radius: $border-radius--card; + border-bottom-right-radius: $border-radius--card; + font-size: var(--font-size-xs, $font-size-xs); + background-color: rgba($c-black, 0.3); + transform-style: preserve-3d; + + .c-field--name-field-tags { + max-height: 36px; + overflow: hidden; + } + } + + &__link { + flex-grow: 1; + } + + /** + * Inline background image. If inline-background class added by "node--tile.html.twig". + */ + &.inline-background { + background-repeat: no-repeat; + background-size: cover; + background-position: center; + + &::before { + height: 60%; + width: 100%; + background-image: linear-gradient(0, $c-tile-gradient 0%, #000000 100%); + position: absolute; + top: 0; + left: 0; + content: ""; + display: block; + z-index: 0; + } + + .c-card__footer { + position: relative; + background-color: rgba($c-black, 0.3); + overflow: hidden; + + /* if backdrop support: very transparent and blurred */ + @supports (-webkit-backdrop-filter: blur(30px)) or (backdrop-filter: blur(30px)) { + background-color: rgba($c-black, 0.3); + -webkit-backdrop-filter: blur(30px); + backdrop-filter: blur(30px); + } + } + } +} + +.o-progress, +.o-episode-count { + .c-node--tile--course &, + .c-node--tile--podcast & { + color: white; + z-index: 1; + text-align: center; + padding: $space $space + $space-half; + font-size: $font-size-s; + margin: auto 0 0; + z-index: 1; + } +} + +.c-node--tile--course { + .inline-background { + &::after { + height: 100%; + width: 100%; + background-image: $c-course-gradient; + position: absolute; + top: 0; + left: 0; + content: ""; + display: block; + z-index: 0; + } + } + + .u-middle-block { + @extend .o-button-course-tile; + } +} + +.c-node--tile--event { + .inline-background { + &::after { + height: 100%; + width: 100%; + background-image: $c-event-gradient; + position: absolute; + top: 0; + left: 0; + content: ""; + display: block; + z-index: 0; + } + } +} + +.c-node--tile--event, +.c-node--card--event { + .u-middle-block { + @extend .o-button--event-button; + } +} + +.c-node--tile--podcast { + .inline-background { + &::after { + height: 100%; + width: 100%; + background-image: $c-podcast-gradient; + position: absolute; + top: 0; + left: 0; + content: ""; + display: block; + z-index: 0; + } + } +} + +.c-node--podcast-episode, +.c-node--tile--podcast-episode, +.c-node--tile--podcast { + .u-middle-block { + @extend .o-button-course-podcast; + } +} + +.c-node--tile--quiz { + .u-middle-block { + @extend .o-button--quiz; + } + + &.c-node--quiz { + .c-card__title { + font-size: var(--font-size-l, $font-size-l); + } + } +} + +.c-node--card .c-card__content { + margin-top: $space-double-half; +} + +.c-node--card .c-node__content .recommendation-info-trigger { + display: none; +} + +.c-card--more { + background: $c-button; + font-family: $ff-font--secondary; + font-size: var(--font-size-l, $font-size-l); + font-weight: 700; + width: 100%; + + &:hover { + background: $c-button--hover; + } + + .more-link { + height: 100%; + width: 100%; + + a { + align-items: center; + color: $c-button--alt; + display: flex; + flex-direction: column; + height: 100%; + justify-content: center; + transition: color 0.3s, transform 0.3s; + width: 100%; + + &::before { + content: '•••'; + font-size: 200%; + height: $space-double + $space-half; + margin-top: -$space; + } + + &:hover { + color: $c-button--alt; + transform: scale(1.05); + } + } + } +} + +.c-node--tile { + // Set line-height for clamp.js on tiles to prevent overflow clipping. + .c-node__content .c-card__title { + line-height: 1.3; + } + + .c-card__footer { + background: none; + padding: 0; + font-size: var(--font-size-s, $font-size-s); + margin-top: $space-half; + } + + .c-field--name-field-tags { + max-height: unset; + + a { + color: $c-secondary; + } + + a:hover { + color: $c-secondary--dark; + } + } + + .c-card__link { + position: absolute; + width: 100%; + height: 100%; + z-index: 2; + } + + .flag.completed ~ .o-flag--bookmark ~ .recommendation-info { + top: $space-double + $space-half; + } + + .c-node__content { + .recommendation-info-trigger { + display: none; + } + } + + .recommendation-info { + display: flex; + flex-direction: row; + justify-content: flex-end; + position: absolute; + top: $space-half; + left: $space; + + &-trigger { + $recommendation-icon-white: "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMC44NCAyMC44NCI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOiNmZmY7fTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJMYXllcl8yIiBkYXRhLW5hbWU9IkxheWVyIDIiPjxnIGlkPSJMYXllcl8xLTIiIGRhdGEtbmFtZT0iTGF5ZXIgMSI+PHBhdGggY2xhc3M9ImNscy0xIiBkPSJNMTcuNzksMy4wNWExMC40MiwxMC40MiwwLDEsMCwzLjA1LDcuMzdBMTAuNDMsMTAuNDMsMCwwLDAsMTcuNzksMy4wNVpNMTAuNDIsMTlBOC41NSw4LjU1LDAsMSwxLDE5LDEwLjQyLDguNTQsOC41NCwwLDAsMSwxMC40MiwxOVoiLz48cGF0aCBjbGFzcz0iY2xzLTEiIGQ9Ik0xMy4zNyw5LjExYTcuODEsNy44MSwwLDAsMS0xLjIsMS4xN2wtLjQyLjM3YS45MS45MSwwLDAsMC0uMzQuNzZjMCwuMzIsMCwuNjQsMCwxYS4yNi4yNiwwLDAsMS0uMjMuMjhoLS43OXYwSDkuNmEuMjMuMjMsMCwwLDEtLjI1LS4yMXYwYTgsOCwwLDAsMSwuMTUtMkExLjc3LDEuNzcsMCwwLDEsMTAsOS42MWMuMjEtLjIzLjQ0LS40Mi42Ni0uNjNzLjUtLjQ0Ljc1LS42NWEuODcuODcsMCwwLDAsLjE1LTEuMjIsMSwxLDAsMCwwLS4zNC0uMjYsMS40NSwxLjQ1LDAsMCwwLTIsLjU5LjU0LjU0LDAsMCwwLS4wNy4xM0EyLjkxLDIuOTEsMCwwLDAsOSw4YzAsLjE4LS4xNC4yNS0uMzIuMjJMNy4yMiw4QS4yNy4yNywwLDAsMSw3LDcuNzN2MEEzLjA3LDMuMDcsMCwwLDEsOS41LDVhNC4zNiw0LjM2LDAsMCwxLDIuNjIuMjQsMi44NSwyLjg1LDAsMCwxLDEuNTksMS42N0EyLjIyLDIuMjIsMCwwLDEsMTMuMzcsOS4xMVoiLz48cGF0aCBjbGFzcz0iY2xzLTEiIGQ9Ik0xMS40NCwxNC45YTEsMSwwLDEsMS0xLTFBMSwxLDAsMCwxLDExLjQ0LDE0LjlaIi8+PC9nPjwvZz48L3N2Zz4="; + display: block; + width: $space + $space-quarter; + height: $space + $space-quarter; + cursor: pointer; + background: url($recommendation-icon-white) center center no-repeat; + background-size: $space + $space-quarter; + opacity: 0.5; + transition: opacity 0.25s $hard-ease-in; + z-index: 3; + + &:hover { + opacity: 1; + } + } + + &-content { + display: none; + } + } +} + +.c-node--card, +.c-node--teaser { + &, + a { + color: $c-white; + outline: 0; + display: block; + + &:hover { + color: $c-white; + } + } + + .perls-content-manager &, + .c-node--full--course & { + // When on the full course view, if the node content + // is _after_ (i.e. outside of) the card, then the text + // should be the body color. + .c-node__card + .c-node__content { + &, + a { + color: $c-content--foreground; + } + } + } +} + +.c-node--tile, +.c-node--card, +.c-node--teaser { + + .c-stack & { + &, + .c-card { + height: 100%; + } + } + + .c-card { + background-color: $c-card; + } + + .o-button--more::after { + background: transparent; + } + + &--test { + .c-card { + background-color: $c-card--test; + + &__title { + @include o-heading--m; + } + } + + .o-button--more::after { + background: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, $c-card--test 80%); + } + } + + &--quiz { + .c-card { + background-color: $c-card--quiz; + + &__title { + @include o-heading--m; + } + } + + .o-button--more::after { + background: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, $c-card--quiz 80%); + } + } + + &--tip-card { + .c-card { + background-color: $c-card--tip; + + &__title { + @include o-heading--l; + } + } + + .o-button--more::after { + background: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, $c-card--tip 80%); + } + } + + &--flash-card, + .o-button--more { + .c-card { + background-color: $c-card--flashcard; + + &__title { + @include o-heading--l; + } + } + + .o-button--more::after { + background: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, $c-card--flashcard 80%); + } + } + + &--course { + .c-card { + background-color: $c-card--course; + } + } + + &--podcast, + &--podcast-episode { + .c-card { + background-color: $c-card--podcast; + } + } + + .c-field__label { + display: none; + } +} + +.c-node--card .c-node__content, +.c-node--tile .c-node__content { + color: $c-content--foreground; + + a { + color: $c-content--foreground; + } +} + +.c-node--tile--flash-card { + .u-middle-block { + @extend .o-button-flash-card; + } +} + +.c-node--tile--tip-card { + .u-middle-block { + @extend .o-button--view-tip-button; + } +} + +.c-node--card--test { + .flag.completed { + display: none; + } + + .c-card--results { + background-color: $c-card--results; + color: $c-black; + height: 100%; + + .feedback { + font-size: 1.25em; + margin: $space 0; + } + + .feedback::before { + background: url(../img/icons/icon-results.svg) no-repeat; + background-size: 50px 70px; + content: ''; + display: block; + margin-bottom: $space; + height: 70px; + width: 50px; + } + + .c-card__footer { + background: none; + } + } +} + +/** + * Node card + */ +.c-node--card { + .c-card { + &__content:first-child, + .o-flag--bookmark + .c-card__content { + padding: 70px $space $space-double; + } + } + + &.has-toggle { + > * { + position: relative; + } + + .c-node__content { + max-height: 500px; + overflow: hidden; + + .o-button--more { + width: 50px; + height: 50px; + border-radius: 50px; + background-color: $c-secondary; + margin: 0 auto; + right: 0; + + &::before { + background-position: center center; + height: 50px; + } + + &::after { + display: none; + } + } + } + + .c-node__card, + .c-card__content { + max-height: 100vh; + overflow: hidden; + justify-content: flex-start; + } + + .c-card--back { + justify-content: flex-start; + min-height: 100vh; + } + } + + &.has-toggle.this-is-active { + .c-node__card, + .c-card__content, + .c-card--back { + max-height: 100%; + } + } + + .c-node__content, + .c-card__content { + &.this-is-active { + max-height: 100%; + overflow: visible; + } + + .title--section { + font-size: 0; + + > a, + > .c-field--name-field-card-front { + display: inline-block; + width: 90%; + vertical-align: top; + } + } + } + + .recommendation-info { + display: flex; + flex-direction: row; + justify-content: flex-end; + position: absolute; + top: $space-half; + left: $space; + + &-trigger { + $recommendation-icon-white: "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMC44NCAyMC44NCI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOiNmZmY7fTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJMYXllcl8yIiBkYXRhLW5hbWU9IkxheWVyIDIiPjxnIGlkPSJMYXllcl8xLTIiIGRhdGEtbmFtZT0iTGF5ZXIgMSI+PHBhdGggY2xhc3M9ImNscy0xIiBkPSJNMTcuNzksMy4wNWExMC40MiwxMC40MiwwLDEsMCwzLjA1LDcuMzdBMTAuNDMsMTAuNDMsMCwwLDAsMTcuNzksMy4wNVpNMTAuNDIsMTlBOC41NSw4LjU1LDAsMSwxLDE5LDEwLjQyLDguNTQsOC41NCwwLDAsMSwxMC40MiwxOVoiLz48cGF0aCBjbGFzcz0iY2xzLTEiIGQ9Ik0xMy4zNyw5LjExYTcuODEsNy44MSwwLDAsMS0xLjIsMS4xN2wtLjQyLjM3YS45MS45MSwwLDAsMC0uMzQuNzZjMCwuMzIsMCwuNjQsMCwxYS4yNi4yNiwwLDAsMS0uMjMuMjhoLS43OXYwSDkuNmEuMjMuMjMsMCwwLDEtLjI1LS4yMXYwYTgsOCwwLDAsMSwuMTUtMkExLjc3LDEuNzcsMCwwLDEsMTAsOS42MWMuMjEtLjIzLjQ0LS40Mi42Ni0uNjNzLjUtLjQ0Ljc1LS42NWEuODcuODcsMCwwLDAsLjE1LTEuMjIsMSwxLDAsMCwwLS4zNC0uMjYsMS40NSwxLjQ1LDAsMCwwLTIsLjU5LjU0LjU0LDAsMCwwLS4wNy4xM0EyLjkxLDIuOTEsMCwwLDAsOSw4YzAsLjE4LS4xNC4yNS0uMzIuMjJMNy4yMiw4QS4yNy4yNywwLDAsMSw3LDcuNzN2MEEzLjA3LDMuMDcsMCwwLDEsOS41LDVhNC4zNiw0LjM2LDAsMCwxLDIuNjIuMjQsMi44NSwyLjg1LDAsMCwxLDEuNTksMS42N0EyLjIyLDIuMjIsMCwwLDEsMTMuMzcsOS4xMVoiLz48cGF0aCBjbGFzcz0iY2xzLTEiIGQ9Ik0xMS40NCwxNC45YTEsMSwwLDEsMS0xLTFBMSwxLDAsMCwxLDExLjQ0LDE0LjlaIi8+PC9nPjwvZz48L3N2Zz4="; + display: block; + width: $space + $space-quarter; + height: $space + $space-quarter; + cursor: pointer; + background: url($recommendation-icon-white) center center no-repeat; + background-size: $space + $space-quarter; + opacity: 0.8; + transition: opacity 0.25s $hard-ease-in; + z-index: 3; + + &:hover { + opacity: 1; + } + } + + &-content { + display: none; + } + } + + .flag.completed + .o-flag--bookmark + .recommendation-info { + left: $space-and-half + $space-and-half; + } +} + +.c-node--card--quiz .recommendation-info { + left: $space; +} + +.quiz-in-test .c-node--card--quiz .recommendation-info { + display: none; +} + +/** + * Node full + */ +.c-node--full { + > .c-node__header { + .c-card { + justify-content: flex-end; + + a { + color: $c-white; + } + } + } + + .c-card__footer { + .c-field--name-field-tags { + max-height: none; + overflow: visible; + } + } + + .o-rich-text .o-button { + display: inline-block; + text-decoration: none; + } +} + +/** + * Node teaser + */ +.c-node--teaser { + .c-card { + min-height: 200px; + + &__title { + overflow: hidden; + + span { + display: -webkit-box; + -webkit-line-clamp: 3; + -webkit-box-orient: vertical; + -moz-line-clamp: 3; + -moz-box-orient: vertical; + overflow: hidden; + line-height: 1.2; + } + } + + &__content { + max-height: 160px; + } + + &__footer { + min-height: 40px; + } + + &::after { + display: none; + } + } +} + +/** + * Node card: flash card + */ + $flash-card-transition: transform 1s ease 0s, opacity 0.25s ease 0.5s; +.c-node--card--flash-card { + // 2000px fixes animation on extra long cards. + perspective: 2000px; + + .c-card { + display: flex; + position: relative; + flex-direction: row; + justify-content: center; + width: 100%; + height: 100%; + transform-style: preserve-3d; + transition: $flash-card-transition; + + &.this-is-active { + transform: rotateY(180deg); + + &::after { + opacity: 0; + visibility: hidden; + } + + .c-card--front { + opacity: 0; + visibility: hidden; + + & > * { + opacity: 0; + visibility: hidden; + } + } + + .c-card--back { + opacity: 1; + visibility: visible; + } + } + + &__content { + height: 100%; + display: flex; + flex-direction: column; + justify-content: center; + } + + &--front, + &--back { + width: 100%; + display: flex; + flex-direction: column; + justify-content: center; + box-sizing: border-box; + transform: rotateY(0deg); + min-height: 300px; + transition: $flash-card-transition; + } + + &--front { + position: relative; + opacity: 1; + visibility: visible; + backface-visibility: hidden; + + .o-button--view { + margin-top: 50%; + margin-bottom: 50%; + } + } + + &--back { + padding: ($space-double * 2) $space $space-double; + transform: rotateY(-180deg); + transition: $flash-card-transition; + opacity: 0; + visibility: hidden; + background-color: $c-card--flashcard; + + // pulls the back of the card under the front. + // This way they can be the same height and be both relative. + // So parent item can calculate height relative to its biggest child. + margin-left: -100%; + } + + &::after { + z-index: -1; + visibility: visible; + transition: all 1s ease; + } + } + + .c-field--name-field-card-front p { + @include o-heading--l; + } +} + +/** + * Node card: quiz + */ +.c-node--card--quiz { + color: $c-white; + + a { + color: $c-white; + } + + .c-card.this-is-active { + .o-flag, + .flag, + .c-card__title { + @include u-hidden; + + transition-delay: 0.5s; + } + + .c-quiz__option { + @include u-hidden; + + pointer-events: none; + transition-delay: 0.5s; + + &.this-is-active { + @include u-visible; + + pointer-events: auto; + + .c-quiz__answer { + display: flex; + overflow: visible; + } + } + } + + .c-quiz__question { + @include u-hidden; + + transition-delay: 0.5s; + } + + .c-quiz__answer { + @include u-visible; + + display: none; + transition-delay: 0.5s; + } + } + + .c-card__footer { + display: none; + + .top & { + display: block; + } + } +} + +.slick-track .c-node--card--quiz .c-node__card.c-card { + height: calc(100% - 24px); +} + +/** + * Node card: course + */ + +.c-node--card--course { + .inline-background { + &::before { + background: none; + } + } + + .c-card__content { + margin: 50px 0; + } + + .title--section { + > h2 { + display: inline-block; + width: 90%; + vertical-align: top; + } + } + + .o-progress { + margin: 0; + + span { + padding: 0 $space-quarter; + } + } + + .o-button { + margin-top: $space-double; + text-align: center; + } +} + + +/** + * User profile: card + */ +.c-user-profile--card { + width: 100%; + + .c-card { + position: relative; + min-height: 200px; + + &__content { + display: grid; + grid-template-rows: auto; + grid-column-gap: 0; + grid-template-columns: 4fr 5fr; + padding: 0; + min-height: inherit; + background-color: #efefef; + + &__left { + background-repeat: no-repeat; + background-position: center; + background-size: cover; + border-radius: 0 0 100% 0; + + // Default background if there is no picture. + background-color: $c-white; + } + + &__right { + display: flex; + flex-direction: column; + justify-content: space-between; + text-align: right; + margin-left: -$space-and-half; + + // Keep space (padding-bottom)for absolute positioned __footer. + padding: $space-half $space $space-double-half $space; + } + } + + &__footer { + position: absolute; + right: 0; + bottom: 0; + left: 0; + z-index: 2; + background-color: rgba($c-black, 0.6); + overflow: hidden; + + /* if backdrop support: very transparent and blurred */ + @supports (-webkit-backdrop-filter: blur(30px)) or (backdrop-filter: blur(30px)) { + background-color: rgba($c-black, 0.4); + -webkit-backdrop-filter: blur(30px); + backdrop-filter: blur(30px); + } + } + } + + .c-user-profile__created { + font-family: $ff-font--secondary; + font-size: $font-size-xs; + font-weight: 600; + color: $c-white; + + &__label { + margin-right: $space-half; + } + } + + .c-user-profile__details { + &__user-name { + @include o-heading--m; + + color: $c-secondary; + font-weight: 900; + text-transform: capitalize; + word-break: break-word; + word-wrap: break-word; + } + + &__role { + font-size: $font-size-s; + font-family: $ff-font--secondary; + color: $c-black; + font-weight: 600; + text-transform: capitalize; + } + } + + .c-user-profile__actions-edit { + color: $c-link; + display: inline-block; + } +} + +/** + * Node 'course' full: description card + */ +.card--description { + background-color: $c-card--course; + color: $c-white; +} + +/** + * Taxonomy term Card + */ +.taxonomy-vocabulary__card { + .c-card { + background-color: $c-taxonomy-term-card; + } + + &.taxonomy-vocabulary--tags { + &.c-node--teaser { + .c-card:not(.inline-background) { + &::before { + height: 100%; + width: 100%; + background-image: $c-teaser-gradient; + position: absolute; + top: 0; + left: 0; + content: ""; + display: block; + z-index: 0; + } + + &::after { + content: ""; + display: block; + position: absolute; + z-index: 0; + width: 84px; + height: 84px; + top: unset; + right: 30px; + bottom: 25px; + left: unset; + background: center no-repeat url("data:image/svg+xml,%3C%3Fxml version='1.0' encoding='UTF-8'%3F%3E%3Csvg id='SVGDoc' width='84' height='84' xmlns='http://www.w3.org/2000/svg' version='1.1' xmlns:xlink='http://www.w3.org/1999/xlink' xmlns:avocode='https://avocode.com/' viewBox='0 0 84 84'%3E%3Cdefs%3E%3C/defs%3E%3Cdesc%3EGenerated with Avocode.%3C/desc%3E%3Cg%3E%3Cg%3E%3Ctitle%3EPath 2%3C/title%3E%3Cpath d='M33.70634,32.68831h18.58791l-2.19127,18.62434h-18.58744zM81.48151,32.68831c0.61755,0.00037 1.20992,-0.24477 1.64659,-0.68146c0.43667,-0.43667 0.68183,-1.02904 0.68147,-1.64659l-0.00001,-9.31216c0.00037,-0.61755 -0.24479,-1.20991 -0.68147,-1.64659c-0.43667,-0.43667 -1.02903,-0.68183 -1.64658,-0.68146h-13.53909l1.88573,-16.02578c0.07767,-0.66059 -0.13108,-1.32282 -0.57351,-1.81947c-0.44243,-0.49665 -1.07625,-0.78022 -1.74138,-0.77909h-9.31218c-1.18121,0.00075 -2.17535,0.88453 -2.31442,2.05753l-1.94916,16.56682h-18.58768l1.88571,-16.02578c0.07766,-0.66058 -0.13108,-1.32282 -0.5735,-1.81947c-0.44243,-0.49664 -1.07625,-0.78021 -1.74138,-0.77909h-9.31218c-1.18121,0.00074 -2.17534,0.88453 -2.31443,2.05753l-1.94915,16.56682h-19.01685c-0.61755,-0.00037 -1.20991,0.24479 -1.64658,0.68146c-0.43667,0.43668 -0.68183,1.02904 -0.68146,1.64659v9.31216c-0.00037,0.61755 0.24479,1.20992 0.68146,1.64659c0.43667,0.43668 1.02904,0.68183 1.64659,0.68146h17.3736l-2.19127,18.62434h-15.18233c-0.61755,-0.00037 -1.20991,0.24478 -1.64659,0.68146c-0.43667,0.43668 -0.68183,1.02904 -0.68146,1.64658v9.31218c-0.00037,0.61755 0.24479,1.20992 0.68146,1.64658c0.43667,0.43668 1.02904,0.68183 1.64659,0.68147l13.53908,-0.00001l-1.88572,16.02345c-0.07722,0.66071 0.1316,1.32294 0.57387,1.81985c0.44226,0.4969 1.07581,0.78112 1.74102,0.78104h9.31217c1.18079,0.00034 2.17516,-0.88267 2.31443,-2.05521l1.94915,-16.56913h18.58768l-1.88571,16.02345c-0.07722,0.66071 0.1316,1.32294 0.57387,1.81985c0.44226,0.4969 1.0758,0.78114 1.74102,0.78105l9.31217,-0.00001c1.18079,0.00034 2.17516,-0.88267 2.31442,-2.05521l1.94916,-16.56913h19.01685c0.61755,0.00038 1.20992,-0.24478 1.64659,-0.68145c0.43667,-0.43668 0.68183,-1.02904 0.68147,-1.64659l-0.00001,-9.31218c0.00037,-0.61755 -0.24479,-1.20992 -0.68146,-1.64658c-0.43668,-0.43668 -1.02904,-0.68183 -1.64659,-0.68147l-17.37337,0.00001l2.19081,-18.62434z' fill='%238d8d8d' fill-opacity='1'%3E%3C/path%3E%3C/g%3E%3C/g%3E%3C/svg%3E"); + } + } + } + } +} + +/** + * Group card + */ + .c-group--default { + width: 100%; + padding-bottom: $space-and-half; + + .c-node__header .inline-background { + border-radius: 0; + } + + .membership-link .button { + padding: $space-half $space-and-half; + } + + .c-group__description .c-field--name-field-description { + max-height: unset; + } + + } + + .c-group--card { + width: 100%; + + .membership-link { + position: absolute; + bottom: $space-quarter; + right: $space-quarter; + + a { + font-size: 0; + width: 60px; + padding: 0; + background-color: unset; + line-height: 60px; + height: 60px; + + &::before { + content: '+'; + font-size: 60px; + font-weight: 700; + color: white; + display: block; + padding: 0 $space-half; + } + + } + } + .c-card { + background-color: $c-gray; + width: 100%; + + &::after { + @include media(">xlarge") { + font-size: 7vw; + } + } + + &__content, + &__content:first-child { + display: flex; + flex-direction: column; + justify-content: flex-end; + padding: $space; + padding-top: $space; + margin-top: 0; + flex: 1; + } + + &__title-link { + position: absolute; + top: 0; + left: 0; + display: flex; + align-items: flex-end; + justify-content: flex-start; + height: 100%; + padding: $space; + } + + &__title { + overflow: hidden; + + > .title-span { + display: -webkit-box; + -webkit-line-clamp: 5; + -webkit-box-orient: vertical; + -moz-line-clamp: 5; + -moz-box-orient: vertical; + overflow: hidden; + line-height: 1.2; + } + } + } + .c-group__description { + padding-left: 0; + padding-right: 0; + } + } + + .c-block-views-blockgroup-index-my-groups { + .c-group--card { + .c-group__content { + width: 100%; + height: 100%; + position: absolute; + padding: 0; + + .title--section { + width: 100%; + height: 100%; + + > a { + width: 100%; + height: 100%; + padding: $space; + } + + } + + } + .c-group__description { + display: none; + } + .membership-link { + display: none; + a::before { + content: '–'; + } + } + } +} + +.c-group--card.group--info-card { + .membership-link { + width:100%; + height:100%; + bottom: 0; + right: 0; + z-index: 30; + + a { + width: 100%; + height: 100%; + + &::before { + position: absolute; + bottom: $space-quarter; + right: $space-quarter; + } + } + } +} diff --git a/web/themes/custom/perls/resources/scss/_objects.charts.scss b/web/themes/custom/perls/resources/scss/_objects.charts.scss new file mode 100644 index 0000000..0a0ae26 --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_objects.charts.scss @@ -0,0 +1,45 @@ +/* ------------------------------------ *\ + Charts +\* ------------------------------------ */ + +.c-block-veracity-chart-block { + h2 { + @include o-heading--l; + } + + .no-data { + align-items: center; + border: $border--light; + color: $c-empty; + display: flex; + justify-content: center; + + .empty-message { + @include add-icon('icon-chart-gray.svg', $icon-xlarge, $icon-xlarge); + } + } + +} + +.veracity-result-render.progresschange { + height: 300px; +} + +.page-variant--user-insights .update-goal-button { + display: none; +} + +body.content-only.page-variant--user-insights { + h1 { + display: none; + } + + .update-goal-button { + display: inline-block; + } + // The vql charts have their own padding and are offset left. A negative + // margin aligns the block title with the chart y-axis label. + .veracity-result-render:not(.no-data) { + margin-left: - #{$space + $space-quarter}; + } +} diff --git a/web/themes/custom/perls/resources/scss/_objects.chip.scss b/web/themes/custom/perls/resources/scss/_objects.chip.scss new file mode 100644 index 0000000..a2a2ce4 --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_objects.chip.scss @@ -0,0 +1,58 @@ +/* ------------------------------------ *\ + $CHIP +\* ------------------------------------ */ +$chip-padding: $space - $space-quarter $space-double; +.c-chip__link { + // Style for "Rectangle". + border-radius: $border-radius; + background-color: $c-chip; + color: $c-chip-text; + transition: $transition; + display: block; + padding: $chip-padding; + line-height: 1rem; + + &:hover { + background-color: $c-chip-hover; + color: $c-chip-text; + } + + &:hover { + color: $c-chip-text; + } +} + +.chip__title { + color: inherit; + font-size: var(--font-size-m, $font-size-m); + line-height: inherit; + font-weight: normal; + + & > * { + display: inline-block; + } +} + +.chip-list { + li { + display: inline-block; + padding: $space $space 0 0; + vertical-align: middle; + + [dir="rtl"] & { + margin: $space 0 0 $space; + } + } +} + +.c-chip--more .more-link { + a { + @include o-button; + + line-height: 1rem; + border-radius: 6px; + padding: $chip-padding; + display: block; + font-weight: 400; + } +} diff --git a/web/themes/custom/perls/resources/scss/_objects.color-palette.scss b/web/themes/custom/perls/resources/scss/_objects.color-palette.scss new file mode 100644 index 0000000..9e308e1 --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_objects.color-palette.scss @@ -0,0 +1,60 @@ +/* ------------------------------------ *\ + $COLOR-PALETTE +\* ------------------------------------ */ + +.color-palette { + display: inline-flex; + flex-direction: column; + flex-wrap: nowrap; + justify-content: flex-start; + align-items: flex-start; + + @include media(">xlarge") { + float: left; + // Account for width of color picker element, set by the farbtastic library. + width: calc(100% - 195px); + padding-right: $space; + } + + > * { + flex: 0 0 100%; + max-width: 100%; + } +} + +.color-placeholder { + @include media(">xlarge") { + margin-top: 110px; + } +} + +.color-palette-element { + display: flex; + flex-direction: row; + flex-wrap: nowrap; + justify-content: flex-start; + align-items: center; + + > .form-item { + display: flex; + flex-direction: row; + flex-wrap: nowrap; + justify-content: flex-start; + align-items: center; + height: auto; + margin: 0; + } + + .help-text { + display: block; + top: 0; + } + + .color-palette__hook { + float: none; + } + + .form-item label { + margin-top: 0; + } +} diff --git a/web/themes/custom/perls/resources/scss/_objects.comments.scss b/web/themes/custom/perls/resources/scss/_objects.comments.scss new file mode 100644 index 0000000..0be39f4 --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_objects.comments.scss @@ -0,0 +1,117 @@ +.c-node--discussion { + .c-node__title { + font-size: var(--font-size-l); + padding-top: $space; + } +} + +.comments-app-container { + button { + color: $c-button; + } + + .rc_comment-box-container { + .rc_comment-box-avatar__image-wrapper { + @include avatar; + } + + .rc_input-outer-wrapper { + min-width: 100px; + } + + .rc_input-wrapper { + background: $c-gray--light; + border: $border--light; + min-height: initial; + + &, + .public-DraftEditorPlaceholder-root { + font-size: var(--font-size-s); + } + + .quill { + min-height: $space-triple; + overflow: hidden; + } + + .ql-editor { + line-height: 1; + font-size: 16px; + } + + .ql-container.ql-snow { + border: none; + } + + .ql-container:focus-within .ql-blank::before { + display: none; + } + } + + .rc_input-actions { + background: none; + border: none; + + button { + background: transparent; + } + } + } + + .rc_comment { + .rc_comment-container { + border: $border--light; + border-color: $c-gray-2; + border-radius: $border-radius; + padding: $space-half; + + @media (hover: none) { + .rc_comment-menu-toggle { + display: block; + } + } + } + + .rc_avatar__image-wrapper { + @include avatar; + + flex-grow: 0; + flex-shrink: 0; + } + + .rc_body { + font-size: var(--font-size-s); + + & > * { + margin: $space-quarter 0; + } + + .rc_comment-details { + .rc_username { + font-size: var(--font-size-s); + font-weight: 600; + } + + svg { + display: inline-block; + } + } + + .rc_comment-footer { + font-size: var(--font-size-xs); + + > * { + display: inline-block; + } + + .rc_time-ago { + color: $c-gray; + } + + .rc_actions-wrapper { + margin: 0 $space-half; + } + } + } + } +} diff --git a/web/themes/custom/perls/resources/scss/_objects.dialog.scss b/web/themes/custom/perls/resources/scss/_objects.dialog.scss new file mode 100644 index 0000000..a30d5f3 --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_objects.dialog.scss @@ -0,0 +1,86 @@ +/* ------------------------------------ *\ + $DIALOGS +\* ------------------------------------ */ + +.ui-dialog { + .ui-dialog-titlebar { + background-color: $c-admin--background; + border-width: 0; + + &-close { + right: 1em; + } + } + + .ui-dialog-content { + padding: 1em; + + .c-node--card { + .c-card { + min-height: 600px; + } + } + } + .ui-dialog-buttonpane { + border-width: 0; + + .ui-button { + margin: 10px 15px 10px 0; + + &.button--primary { + @include o-button-form; + } + + &:not(.button--primary) { + @include o-button-reverse; + } + } + } +} + +.ui-button { + .ui-icon { + background-image: url("data:image/svg+xml,%3Csvg id='Capa_1' enable-background='new 0 0 386.667 386.667' height='512' viewBox='0 0 386.667 386.667' width='512' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='m386.667 45.564-45.564-45.564-147.77 147.769-147.769-147.769-45.564 45.564 147.769 147.769-147.769 147.77 45.564 45.564 147.769-147.769 147.769 147.769 45.564-45.564-147.768-147.77z' fill='%23232323'/%3E%3C/svg%3E%0A"); + background-size: contain; + background-position: center; + background-repeat: no-repeat; + } + + &:hover { + .ui-icon { + background-image: url("data:image/svg+xml,%3Csvg id='Capa_1' enable-background='new 0 0 386.667 386.667' height='512' viewBox='0 0 386.667 386.667' width='512' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='m386.667 45.564-45.564-45.564-147.77 147.769-147.769-147.769-45.564 45.564 147.769 147.769-147.769 147.77 45.564 45.564 147.769-147.769 147.769 147.769 45.564-45.564-147.768-147.77z' fill='%23232323'/%3E%3C/svg%3E%0A"); + background-size: contain; + background-position: center; + background-repeat: no-repeat; + } + } +} + +.ui-widget-overlay { + background-color: $c-black; +} + +.l--entity-browser--iframe { + .o-page-title { + color: $c-admin--foreground; + } +} + +/** + * Achievement notification hide when content-only class exists. + */ +.content-only { + .achievement-notification-dialog { + display: none !important; + } +} + +/** + * Fix for safari enter key submission of ckeditor link modal via hidden input. + */ +.editor-link-dialog { + .form-actions input[type="submit"] { + display: inline !important; + opacity: 0; + } +} diff --git a/web/themes/custom/perls/resources/scss/_objects.entity-browser.scss b/web/themes/custom/perls/resources/scss/_objects.entity-browser.scss new file mode 100644 index 0000000..2bf2767 --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_objects.entity-browser.scss @@ -0,0 +1,153 @@ +/* ------------------------------------ *\ + $ENTITY BROWSER +\* ------------------------------------ */ + +/** + * Tab navigation. OVERRIDE + */ +.eb-tabs ul { + display: flex; + flex-direction: row; + flex-wrap: wrap; + justify-content: flex-start; + align-items: flex-start; + margin: $space-double 0 $space; + border-bottom: $border--light; +} + +.eb-tabs ul li.active { + border: 0; +} + +.eb-tabs ul li a { + color: $c-gray; + font-weight: normal; + padding: $space-half $space; + margin-bottom: $space-half; + background-color: transparent; + transition: background 0.25s $hard-ease-in, color 0.25s $hard-ease-in; + display: block; + white-space: nowrap; + + &:hover { + color: $c-secondary; + + &::after { + opacity: 1; + } + + &.active::after { + opacity: 0; + } + } + + &::after { + content: ""; + display: block; + width: 100%; + height: 2px; + background-color: $c-secondary; + opacity: 0; + transition: $transition; + } + + &.is-active { + background-color: $c-primary; + border-radius: $border-radius--card; + padding: $space-half $space; + color: $c-white; + font-weight: bold; + cursor: default; + } +} + +.entities-list.entity-type--node { + @include make-row($space); + @include row-cols(2, $space); + + .field--name-field-episodes & { + @include row-cols(1, $space); + + counter-reset: row; + margin: $space-quarter 0; + + > * { + display: flex; + flex-direction: row; + justify-content: flex-start; + align-items: center; + + &::before { + @include o-heading--s; + + counter-increment: row; + content: counter(row) ". "; + margin-right: $space-quarter; + } + } + + .o-input { + margin: 0 $space-quarter; + } + + .item-container { + margin: $space-quarter 0; + border: $border--light; + border-radius: $border-radius--card; + } + } + + .item-container { + margin: $space 0; + padding: 10px; + + &:hover { + opacity: 1; + border-radius: 10px; + background-color: $c-admin-item--hover; + } + + &, + .c-card a { + &:hover { + cursor: move; + } + } + } + + .o-input { + display: inline-block; + } +} + +.field--widget-entity-browser-entity-reference { + .o-input__submit { + .entity-browser-processed { + color: $c-white; + background-color: $c-black; + border-color: $c-black; + } + + .ajax-progress-throbber { + .throbber { + padding: 1px 6px 2px; + } + + .message { + display: none; + } + } + } +} + +.disable-episode-reference-dg .item-container { + &:hover { + cursor: auto !important; + } +} + +.entity-browser-learning-content-form { + .vertical-tabs__menu-item { + background: $c-gray-1; + } +} diff --git a/web/themes/custom/perls/resources/scss/_objects.fields.scss b/web/themes/custom/perls/resources/scss/_objects.fields.scss new file mode 100644 index 0000000..045e877 --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_objects.fields.scss @@ -0,0 +1,244 @@ +/* ------------------------------------ *\ + $COMPONENTS +\* ------------------------------------ */ + +/** + * Field tags + */ +.c-field--name-field-tags { + display: flex; + flex-wrap: wrap; + + & > * + * { + margin-top: 0; + } + + .c-field__item { + margin-right: $space-half; + + a { + &:hover { + text-decoration: underline; + } + + &::before { + content: "#"; + } + } + } +} + +/** + * Field title + */ +.c-field--name-field-title { + h3 { + @include o-heading--s; + } +} + +/** + * Field caption + */ +.c-field--name-field-caption { + font-size: var(--font-size-xs, $font-size-xs); + font-style: italic; + margin-top: $space-quarter !important; +} + +/** + * Field body + */ +.c-field--name-field-body, +.c-field--name-field-paragraph-body, +.c-field--name-field-learning-content, +.c-field--type-text-long { + & > * + * { + margin-top: $space; + } +} + +/** + * Field option + */ + +.c-quiz__question { + @include u-visible; + + position: relative; + border-radius: $border-radius--card; + border: 1px solid $c-white; + padding: $space-half; + padding-left: $space-double; + cursor: pointer; + height: auto; + z-index: 1; + + &::before { + content: ""; + display: inline-block; + height: 10px; + width: 10px; + border-radius: 10px; + border: 1px solid $c-white; + background-color: transparent; + position: absolute; + left: 15px; + top: 15px; + transition: $transition; + } + + &:hover, + &:focus, + &:active, + &:target, + &.this-is-active { + background-color: rgba($c-white, 0.2); + border-color: transparent; + + &::before { + background-color: $c-white; + } + } +} + +.c-quiz__answer { + @include u-hidden; + + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + display: flex; + align-items: center; + flex-direction: column; + text-align: center; + overflow: hidden; + + .answer--inner { + display: flex; + flex-direction: column; + align-items: center; + padding: $space; + margin: auto 0; + } +} + +.c-quiz__button { + color: $c-card--quiz; +} + +.c-field--name-field-prerequisites { + > .c-field__label { + @include o-heading--xs; + } + + .c-field__items { + display: flex; + flex-direction: row; + flex-wrap: wrap; + justify-content: flex-start; + align-items: center; + + .c-field__item { + flex-basis: auto; + margin: $space-quarter $space-half $space-quarter 0; + } + + a { + display: block; + border-radius: $border-radius--card; + background-color: $c-secondary; + padding: $space-half $space; + color: $c-white; + + &::before { + content: "#"; + } + + &:hover { + text-decoration: underline; + } + } + } +} + +.c-field--name-field-description { + @include scrollbars; + + max-height: 250px; + overflow-y: auto; + + .card--description & { + max-height: 400px; + overflow: hidden; + } + + .c-node--card--course & { + overflow: hidden; + max-height: 75px; // 3 lines. + } + // Show only first p if description has been clamped. See clamp.init.js. + &.perls-clamp p ~ p { + display: none; + } +} + +.xapi-content-button > .link { + @include o-button; + + display: inline-block; + text-decoration: none; +} + +.field--type-description-field { + // field on the "form display" at content types. + @include description-container; +} + +.form-item { + &-topic, + &-field-topic, + &-entitygroupfield-add-more-add-relation { + select { + width: 60%; + } + + .form--inline & { + select { + width: 300px; + } + } + } +} + +/** + * Event page fields. + */ +.c-field--name-field-related-content { + .js-slick-slider { + padding: $space 0; + + li::before { + content: ""; + } + } +} + +.c-field--name-field-schedule { + .c-field__label { + font-size: var(--font-size-l, $font-size-l); + } + + .date-recur-occurrences li, + .date-recur-date { + font-size: var(--font-size-m, $font-size-m); + } +} + +.c-field--name-field-additional-details { + .c-field__label { + font-size: var(--font-size-l, $font-size-l); + } +} diff --git a/web/themes/custom/perls/resources/scss/_objects.file.scss b/web/themes/custom/perls/resources/scss/_objects.file.scss new file mode 100644 index 0000000..4908427 --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_objects.file.scss @@ -0,0 +1,9 @@ +/* ------------------------------------ *\ + $FILES +\* ------------------------------------ */ + +.file { + &--audio { + @include u-break-word(); + } +} diff --git a/web/themes/custom/perls/resources/scss/_objects.forms.scss b/web/themes/custom/perls/resources/scss/_objects.forms.scss new file mode 100644 index 0000000..ae9da5f --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_objects.forms.scss @@ -0,0 +1,1522 @@ +/* ------------------------------------ *\ + $SPECIFIC FORMS +\* ------------------------------------ */ + +/** + * Form margins + */ +form { + .field-add-more-submit { + margin: 0; + } + + .form-managed-file, + .paragraphs-subform { + & > * + * { + margin-top: $space; + } + + .file { + display: block; + overflow: hidden; + text-overflow: ellipsis; + } + } + + .file--image { + margin-top: $space; + margin-bottom: $space-half; + } + + .paragraph-type-top { + @include o-heading--s; + + align-items: flex-end; + } + + .paragraphs-subform { + .form-item__label { + display: none; + } + } + + .paragraphs-actions { + .button:disabled { + background: none !important; + } + } + + .l-grid { + margin-top: 0 !important; + } + + &.c-form--views-form-manage-groups-manage-groups { + td.views-field-id { + word-break: normal; + } + } +} + +.container-inline { + div { + display: block; + } +} + +.form--inline { + display: flex; + flex-wrap: wrap; + margin-top: -$space; + + .form-item { + float: none; + margin-right: $space; + margin-top: $space; + } + + .form-actions { + align-self: center; + } +} + +/** + * General form styles + */ +.filter-wrapper { + position: relative; + top: -3px; + padding: $space-half; + padding-top: 13px; + border: $border--light; + + .form-item label { + display: block; + } +} + +.form-wrapper { + &.form-actions { + & > * + * { + margin-top: 0; + } + } + + &.container-inline { + display: flex; + flex-wrap: wrap; + align-items: center; + + > * { + margin-top: $space-quarter; + margin-bottom: $space-quarter; + margin-right: $space-half; + } + } + + &.paragraph-top { + & > * + * { + margin-top: 0; + } + } + + .form-note { + color: $c-gray; + font-size: 90%; + margin-top: 0; + } +} + +.form-actions { + display: flex; + align-items: center; + margin-bottom: 0; + + & > * + * { + margin: 0; + margin-left: $space; + } +} + +.form-item { + margin-top: 0; + margin-bottom: 0; +} + +.form-item-pass { + > .form-item__content { + display: flex; + flex-wrap: wrap; + justify-content: space-between; + + @include media("<=small") { + @include u-spacing($space); + } + } + + .form-type-password { + width: 100%; + max-width: 100%; + + @include media(">small") { + width: calc(50% - 10px); + } + + + input { + width: 100%; + } + } +} + +.form-item-display-name, +.form-item-learning-content { + min-width: 116px; +} + +.description { + margin-top: $space-quarter; + display: block; + width: 100%; +} + +input.form-autocomplete { + // overrides the ui styles on load + background-position: right 10px center !important; + padding-right: $space-double; +} + +.media-image-edit-form { + input[name*="_remove_button"] { + display: none; + } +} + +/** + * Details expand element + */ +details { + border: $border--light; + margin-bottom: 0; + + summary { + @include o-heading--s; + + padding: $space-half; + background-color: $c-gray--light; + outline: 0; + } + + &.container-inline.form-wrapper > * { + margin: 0; + } + + > .details-wrapper { + padding: $space; + margin: 0; + + & > * + * { + margin-top: $space; + } + + table .o-input__submit { + margin-top: 0 !important; + + input[type='submit'] { + @include o-link; + } + } + } +} + +/** + * Vertical tabs + */ +.vertical-tabs { + border-color: $border-color--light; + margin-bottom: 0; + + &__menu, + &__menu-item { + border-color: $border-color--light; + + &.is-selected a { + text-decoration: none; + } + + a { + padding: $space-half; + } + } +} + +/** + * Draggable handle in form tables + */ +tr.draggable { + td:first-child { + width: 10px; + padding: 0; + position: relative; + vertical-align: middle !important; + + + td { + padding: $space-half; + } + + a.tabledrag-handle { + width: 40px; + content: ""; + margin: 0; + padding: $space-half; + padding-right: 0; + float: none; + display: flex; + justify-content: center; + align-items: center; + height: 100%; + + .handle { + width: 20px; + height: 20px; + margin: 0; + padding: 0; + background-size: 20px; + background-position: center center; + } + } + + abbr { + position: absolute; + top: $space-quarter; + left: $space-quarter; + color: $c-error; + display: block; + line-height: 1; + border: 0; + } + } +} + +/** + * Dropbutton + */ +.dropbutton-wrapper { + // overrides the default style + min-height: 35px !important; +} + +.dropbutton-widget { + border-radius: 3px; + border: $border--light; + box-shadow: 0 0 3px $c-shadow; + + .dropbutton-action > * { + padding: $space-quarter $space-half; + color: $c-gray; + + &:hover { + color: $c-secondary; + } + } + + input[type='submit'] { + @include o-link; + + text-decoration: none; + color: $c-gray; + line-height: 1.2; + + &:hover { + color: $c-secondary; + } + } +} + +/** + * Paragraph dropdown + */ +.paragraphs-dropdown { + .paragraphs-dropdown-toggle { + &:focus, + &:hover { + background-color: $c-white; + border: $border--light; + } + } + + .paragraphs-dropdown-actions { + border-radius: 3px; + border: $border--light; + + .o-input { + margin: 0; + display: block; + width: 100%; + + + .o-input { + border-top: $border--light; + } + + input[type='submit'] { + @include o-link; + + padding: $space-quarter $space-half; + } + } + } +} + +.paragraphs-dropbutton-wrapper { + margin-top: 0 !important; +} + +/** + * Search forms + */ +.c-form--views-exposed-form-manage-events-page, +.c-form--views-exposed-form-manage-content-manage-tests, +.c-form--views-exposed-form-manage-podcasts-page-1, +.c-form--views-exposed-form-history-learner-page, +.c-form--views-exposed-form-bookmarks-learner-page, +.c-form--views-exposed-form-dashboard-page-1, +.c-form--views-exposed-form-manage-content-page-1, +.c-form--views-exposed-form-manage-vocabularies-page-1, +.c-form--views-exposed-form-content-for-review-page-1, +.c-form--views-exposed-form-manage-groups-manage-groups, +.c-form--views-exposed-form-my-content-page-1, +.c-form--views-exposed-form-group-content-by-topic-page-1 { + .form--inline { + display: flex; + flex-direction: row; + position: relative; + margin-top: 0; + } + + label { + display: none; + } + + .form-item { + margin: 0; + float: none; + } + + .form-actions { + input[type="submit"] { + position: absolute; + top: 50%; + left: 0; + width: 50px; + height: 50px; + text-indent: 9999px; + border-radius: 0; + transform: translateY(-50%); + background-color: transparent; + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 475.08 475.08'%3E%3Ctitle%3Esearch%3C/title%3E%3Cpath d='M464.52 412.84l-97.93-97.92Q402 263.82 402 201a197.41 197.41 0 00-15.85-78.09q-15.84-37.26-42.83-64.24t-64.23-42.82a200.29 200.29 0 00-156.18 0Q85.65 31.69 58.67 58.67t-42.82 64.24a200.27 200.27 0 000 156.17q15.84 37.26 42.82 64.24t64.24 42.83A197.61 197.61 0 00201 402q62.82 0 113.92-35.4l97.93 97.64q10.27 10.84 25.69 10.85a36.54 36.54 0 0026-62.24zM291.36 291.36Q253.81 328.91 201 328.9t-90.36-37.54Q73.1 253.81 73.09 201t37.55-90.36Q148.18 73.08 201 73.09t90.36 37.55q37.56 37.53 37.55 90.36t-37.55 90.36z' fill='%23707070'/%3E%3C/svg%3E"); + background-position: center center; + background-size: 20px 20px; + background-repeat: no-repeat; + + &:focus, + &:hover { + background-color: transparent; + } + } + } + + input[type="text"] { + padding-left: 50px; + height: 50px; + border-radius: $border-radius--button; + background-color: $c-admin-search--background; + border-color: transparent; + + &::placeholder { + color: $c-secondary; + } + + &:focus { + border-color: $c-secondary; + } + } +} + +/** + * Select exposed form + */ + .c-view--manage-content .views-exposed-form.c-form--views-exposed-form-manage-content-page-4 { + .form--inline { + flex-wrap: wrap; + flex-direction: column; + align-items: flex-start; + + @include media(">large") { + flex-direction: row; + } + + .form-item { + flex: 0 1 auto; + margin: 0 0 $space 0; + + &.form-item-title { + margin-top: $space; + margin-right: $space; + max-width: 300px; + } + } + } + + .form-type-select { + margin-left: 20px; + + label { + display: block; + } + } + + .form-actions { + @include media(">xlarge") { + margin-top: $space; + } + } +} + +.c-view--manage-content .views-exposed-form.c-form--views-exposed-form-manage-content-page-4 .form-item + .form-item { + margin-right: $space; +} + +.c-view-id--manage_content.c-view-display-id--page_4 { + .views-exposed-form { + margin-right: 0; + width: 100%; + } + + .c-view__filters { + flex-wrap: wrap; + + .c-view__extra-title { + flex: 1 0 100%; + } + } +} + +/** + * User login form + */ +.l-page--user-login .c-user-login { + input { + border: 0; + } + + &__title, + &__links a { + color: $c-login--foreground; + } +} + +.c-user-login { + width: 100%; + margin: $space auto; + position: relative; + + @include media(">small") { + margin: $space-double auto; + max-width: 260px; + } + + + label { + display: none; + } + + input { + border: $border--standard; + } + + &__title { + color: $c-gray; + } + + &__links { + display: flex; + flex-direction: column; + justify-content: flex-end; + text-align: right; + margin-top: 0 !important; + + .item-list ul { + list-style: none; + } + + a { + text-decoration: underline; + color: $c-gray; + font-size: var(--font-size-xs, $font-size-xs); + } + } + + .user-login-form { + > a { + text-decoration: underline; + color: $c-white; + font-size: var(--font-size-xs, $font-size-xs); + } + } +} + +// Input form button style +.c-form--user-pass, +.c-form--user-register-form, +.c-user-login { + .form-actions { + position: relative; + height: 80px; + margin-top: $space; + margin-bottom: $space; + display: flex; + justify-content: flex-end; + } + + .o-input__submit { + width: auto; + position: relative; + bottom: 0; + right: 0; + display: flex; + justify-content: flex-end; + cursor: pointer; + transition: $transition; + + &::after { + content: ""; + display: block; + width: 80px; + height: 80px; + position: absolute; + border-radius: 50%; + box-shadow: $box-shadow; + top: 0; + right: 0; + z-index: 0; + background: $c-secondary url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 43.34 43.05'%3E%3Ctitle%3Earrow%3C/title%3E%3Cpath d='M43.34,21.52,21.82,43.05l-3.54-3.54L33.77,24H0V19H33.77L18.28,3.54,21.82,0Z' fill='%23fff'/%3E%3C/svg%3E") no-repeat; + background-size: 20px 20px; + background-position: center center; + transition: $transition; + } + + &:hover { + input[type="submit"] { + color: $c-secondary; + } + + &::after { + background-position: right 25px center; + } + } + + input { + border-color: transparent; + } + + input[type="submit"] { + @include o-heading--l; + + @include media("<370px") { + font-size: 18px; + } + + padding: 0; + border-radius: 0; + border: 0; + background-color: transparent; + color: $c-login--foreground; + position: relative; + padding-right: 100px; + height: 80px; + z-index: 1; + + &:focus, + &:hover { + background-color: transparent; + } + } + } +} + +/** + * User registration form. + */ +.c-form--user-register-form, +.c-form--user-interests-form, +.c-form--user-groups-form { + .o-input__submit.edit-back-button { + transition-property: background-position; + } + + .step-info { + font-weight: normal; + margin: 15px 0; + + &.step-label + .form-item { + margin: 0; + } + + &.step-instructions { + small { + display: block; + font-size: 0.8em; + margin: 5px 0; + } + } + } + + .form-type-password-confirm { + .description { + display: none; + } + } + + .iso-grid { + margin: 5px -5px; + } + + .iso-grid-item { + display: inline-block; + + input { + display: none; + + &:checked + label { + background-color: $c-secondary; + color: $c-white; + } + + &:checked:disabled + label { + background-color: $c-disabled; + color: $c-white; + } + + &.error + label { + border: 2px solid $c-error; + } + } + + label { + background-color: $c-white; + border-radius: $border-radius--card; + color: $c-secondary; + font-weight: bold; + margin: 5px; + padding: 10px 20px; + width: auto; + box-shadow: 0 0 3px $c-shadow; + } + } +} + +/** + * User interest and group form on "interest" page and "groups" page. + */ +.c-form--user-interests-form, +.c-form--user-groups-form { + .l-page--user-interests &, + .l-page--user-groups & { + position: relative; + + .form-item-field-interests-wrapper-filter-field, + .js-form-item-field-add-groups-wrapper-filter-field { + padding-right: 120px; // Make space for "save" button. + } + + .o-input__submit { + position: absolute; + top: 0; + right: 0; + + .button--primary { // Alter default primary button bg-color to "black". + background-color: $c-black; + } + } + } +} + +/** + * User forgot password form + */ +.c-form--user-pass { + label { + display: none; + } +} + +/** + * Image and file button + */ +.field--name-field-image, +.field--name-field-learning-package, +.field--type-file, +.importusers { + .form-type-managed-file > .form-item__content { + display: flex; + align-items: center; + justify-content: center; + + > * { + margin: 0; + + &:last-child { + margin-left: $space; + } + } + + > .image-widget { + flex: 1 0; + width: 100%; + } + } +} + +.field--type-field-xapi-content-file-item, +.form-managed-file { + .o-button { + @include o-button--add-icon(file, $icon-medium, $icon-medium); + + &::before { + margin-bottom: 0; + margin-top: 15px; + } + } +} + +.field--type-image, +.form-type-managed-image .form-managed-file { + .o-button { + @include o-button--add-icon(image, $icon-medium, $icon-medium); + + &::before { + margin-bottom: 0; + margin-top: 15px; + } + } +} + +/** + * User image button + */ +.field--name-user-picture { + .form-item__content { + text-align: center; + } + + .description { + color: $c-content--foreground; + } + + .image-widget { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + text-align: center; + + .image-widget-inner-wrapper { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + position: relative; + width: 200px; + margin: 0 auto; + } + + .image-preview { + margin-bottom: $space; + margin-left: auto; + margin-right: auto; + + img { + box-shadow: $box-shadow; + height: 200px; + width: 200px; + } + } + + &-data { + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; + flex-wrap: wrap; + margin: 0; + + a { + word-break: break-word; + word-wrap: break-word; + } + + span { + margin: 0 2.5px; + color: $c-content--foreground; + } + + .file-size, + .file--image { + display: none; + + @include media(">medium") { + display: inline-block; + } + } + + .o-input { + position: absolute; + top: 0; + left: 0; + right: 0; + height: 200px; + width: 200px; + margin: 0 auto; + border-radius: 50%; + overflow: hidden; + z-index: 2; + + &::before { + content: ""; + background: rgba($c-gray, 0.4); + position: absolute; + width: 200px; + height: 200px; + display: flex; + top: 0; + pointer-events: none; + } + + &::after { + @include o-heading--m; + + content: "Edit photo"; + position: absolute; + width: 200px; + height: 200px; + display: flex; + align-items: center; + justify-content: center; + text-align: center; + top: 0; + pointer-events: none; + color: $c-white; + font-weight: bold; + background: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 11.3 11.3'%3E%3Ctitle%3Eedit%3C/title%3E%3Cpath d='M8.33,0,6.06,2.26h0l-.47.48L5.36,3h0L0,8.33l.12,2.85L3,11.3,9,5.23,11.3,3ZM2.57,10.28l-1.49-.06L1,8.72l5-5L7.62,5.23ZM8.33,4.53,6.77,3,8.33,1.41,9.88,3Z' fill='%23ffffff'/%3E%3C/svg%3E") top 75px center no-repeat; + background-size: 30px 30px; + overflow: hidden; + padding-top: $space; + } + + input { + margin: 0 auto; + text-indent: 9999px; + width: 200px; + height: 200px; + border-radius: 50%; + background-color: transparent; + border: none; + } + } + + .o-button--file { + @include o-heading--m; + + position: absolute; + top: 0; + left: 0; + right: 0; + width: 200px; + height: 200px; + margin: auto; + padding: 0; + border-radius: 50%; + z-index: 3; + text-transform: capitalize; + letter-spacing: normal; + + &::before { + margin-bottom: $space-half; + } + + + input { + height: 0; + } + } + + .file { + background-image: none; + padding: 0; + } + } + } +} + +/** + * Manage forms + */ +.c-view--dashboard .c-form, +.c-form--views-form-manage-events-page, +.c-form--views-form-manage-content-manage-tests, +.c-form--views-form-manage-podcasts-page-1, +.c-form--views-form-manage-groups-manage-groups, +.c-form--views-form-manage-content-page-1-course, +.c-form--views-form-manage-content-page-1-learn-articlelearn-linklearn-package, +.c-form--views-form-manage-content-page-4-learn-articlelearn-linklearn-filelearn-package, +.c-form--views-form-manage-content-page-1-tip-card, +.c-form--views-form-manage-content-page-1-flash-card, +.c-form--views-form-manage-content-page-1-quiz, +.c-form--views-form-manage-content-page-1-tags, +.c-form--views-form-my-content-page-1, +.c-form--views-form-content-for-review-page-1, +.c-form--views-form-content-feedback-rating-all-feedback-rating, +.vbo-view-form { + > .form-wrapper > .form-wrapper { + display: flex; + align-items: flex-end; + flex-wrap: wrap; + padding: $space 0; + + .form-item { + margin-right: $space; + } + + .form-item-select-all { + width: 100%; + } + } + + .vbo-multipage-selector { + /* + The design team requested to hide the multipage selector. + However, we need to keep the markup on the page in order + for VBO to work correctly (see #1598). + */ + display: none; + width: 100%; + } + + > .form-actions { + display: none; + } +} + +.views-exposed-form { + .form--inline { + padding: 0; + display: flex; + flex-wrap: wrap; + + @include media(">xlarge") { + flex-wrap: nowrap; + + .c-view--entity-browser-lists & { + flex-wrap: wrap; + } + } + + + label { + white-space: nowrap; + } + + .form-item { + float: none; + } + + .form-actions { + align-self: flex-end; + + @include media(">xlarge") { + align-self: flex-start; + margin-top: 43px; + } + } + } +} + +.c-view--entity-browser-lists { + .views-exposed-form .form--inline { + flex: wrap; + flex-direction: column; + + @include media(">large") { + flex-direction: row; + } + + .form-item { + flex: 0 auto; + + @include media(">large") { + &.form-type-select { + max-width: 16%; + } + } + } + } +} + +.l-page--suggestions { + .l-content { + max-width: 900px; + margin: 0 auto; + } + + .c-form { + .button.button--primary { + background-color: $c-secondary; + } + } +} + +/** + * Recent Log page form + */ +.c-form--views-exposed-form-watchdog-page { + > .form--inline { + display: grid; + grid-template-columns: repeat(3, max-content); + grid-column-gap: $space; + } + + input.button.form-submit { + position: relative; + text-indent: 0; + background-image: none; + display: inline-block; + transform: none; + + @include o-button; + } +} + +input.input--file { + @include u-hidden; + + font-size: 0; + margin: 0; + padding: 0; + height: 0; + display: block; + + &__label { + display: inline-flex; + max-width: 200px; + } +} + +.form-type-managed-file, +.form-item-field-media-image, +.field-media-image-image-paragraph .form-type-item { + .form-item { + &__label { + pointer-events: none; + + .formtip { + pointer-events: auto; + } + } + + &__content { + border: $border--light; + border-radius: $border-radius; + padding: $space; + background-color: $c-white; + overflow: hidden; + max-width: 100%; + } + } + + .entity-type--media { + & > .item-container { + max-width: 100%; + } + + .media-library-item__name { + text-overflow: ellipsis; + overflow: hidden; + max-width: 100%; + } + } +} + +tr.paragraph-type--image { + // Target the paragraph image file cell to prevent long filename wrapping. + td:nth-child(2) { + width: 100%; + max-width: 0; + white-space: nowrap; + } +} + +.webform-dropbutton .dropbutton-wrapper .dropbutton-widget { + background-color: $c-white; +} + +.field--type-group-content { + .field-multiple-table { + .u-spacing > * + * { + margin-top: 0; + } + } + + .gcontent-type-title { + align-self: center; + } +} + +.field--type-entitygroupfield { + .draggable { + height: 55px; + } + + .gcontent-type-title { + flex: 1 50%; + max-width: 300px; + height: 56px; + margin: auto 0 auto 0; + padding: 1em; + } + + .entitygroupfield-dropbutton-wrapper { + flex: 1 50%; + margin: 0; + + .dropbutton .o-input__submit { + padding-right: 10px; + margin: 10px auto; + } + + .dropbutton-multiple { + padding-right: 0; + display: flex; + justify-content: flex-end; + } + + .ajax-progress-throbber { + .throbber { + padding: 0 $space-half; + } + + .message { + display: none; + } + } + + .button:disabled { + background: none !important; + } + } + + .ajax-new-content { + .gcontent-subform { + margin: 0; + } + + .o-input__submit { + margin-right: 2em; + padding-right: 6.5em; + } + } +} + +.node-test-form, +.node-test-edit-form, +.entity-browser-learning-content-form { + .field--name-field-pass-mark { + input { + width: 100px; + display: inline-block; + } + + .field-suffix { + display: inline-block; + } + } +} + +.read-only-input { + background-color: $c-disabled !important; +} + +.c-form--user-form .goals-tab { + label { + display: inline-block; + } + + input[type="number"] { + width: 100px; + display: inline-block; + } +} + +.timepicker { + width: 150px; +} + +.ui-timepicker-wrapper { + width: 150px; +} + +.node-podcast-episode-form { + input:read-only { + background-color: $c-disabled !important; + } +} + +.autocomplete-deluxe-container.autocomplete-deluxe-multiple { + background: none; // Get rid of shadow from autocomplete deluxe + @extend %input-default-styles; + + .autocomplete-deluxe-form { + padding: 0; + } + + .autocomplete-deluxe-item { + margin: 2px 5px 2px 0; + padding: $space-quarter $space-and-half $space-quarter $space-half; + background-color: $c-input--background; + border-radius: $border-radius--card; + } + + .autocomplete-deluxe-throbber { + margin: 2px 5px; + } + + .autocomplete-deluxe-item-delete { + top: 50%; + right: 5px; + transform: translateY(-50%); + } +} + +.ui-autocomplete { + .ui-menu-item { + a { + border-color: transparent; + transition: none; + + &.ui-state-active { + background-color: $c-secondary; + color: $c-white; + } + } + } +} + +.field--widget-inline-entity-form-complex { + .fieldset-wrapper { + border: $border--light; + border-radius: $border-radius; + padding: $space $space-half; + } +} + +.ief-entity-operations { + &.u-spacing { + > * { + display: inline-block; + margin: 5px; + } + } +} + +.ief-entity-table { + margin-bottom: $space; +} + +.ief-form { + .form-wrapper { + .o-input__submit { + display: inline-block; + margin: $space-half; + } + } +} + +.system-theme-settings { + .color-palette__lock { + display: none; + } +} + +.node-form, +.content-moderation-entity-moderation-assignment-form { + .form-actions { + flex-wrap: wrap; + margin-top: 10px; + } + + .o-input__submit { + margin: 10px 15px 10px 0; + + input[type=submit].primary { + @include o-button-form; + } + } + + .edit-submit { + input[type=submit] { + @include o-button-form; + } + } + + .edit-send-for-review, + .edit-return-to-draft, + .edit-create-new-draft, + .edit-approve-and-publish, + .edit-preview, + .edit-create-new-draft, + .edit-publish { + input[type=submit]:not(.primary) { + @include o-button-reverse; + } + } + + div[class^="o-input o-input__submit edit-archive"] { + order: 2; + + input[type=submit] { + @include o-button-text; + } + } + + .button--danger { + @include o-button-text; + + order: 1; + margin: 0; + line-height: 36px; + } + + .field--name-uid { + .js-form-wrapper { + display: flex; + align-items: center; + } + + input[value="Change author"] { + @include o-link; + + margin-left: 10px; + background-color: transparent !important; + } + } +} + +.content-moderation-entity-moderation-assignment-form, +.entity-moderation-notice { + padding: $space; + background-color: $c-gray--light; + + .js-form-wrapper { + display: flex; + flex-direction: row; + flex-wrap: wrap; + } + + .o-input__submit { + margin: 10px 15px 10px 0; + } +} + +.date-recur-modular-alpha-widget { + > * { + margin-top: $space; + } + + .date-recur__dates { + flex-wrap: wrap; + + > * { + flex: 0 1 auto; + padding: 0 $space 0 0; + } + } + + .date { + .form-type-date { + display: inline-block; + margin-right: $space-half; + } + + .form-type-select { + line-height: 1.2; + } + } + + .date-recur__mode { + .form-item { + display: inline-block; + vertical-align: middle; + margin-right: $space; + } + + .form-type-number { + .form-item__content { + display: flex; + align-items: flex-end; + + input { + margin-right: 1ch; + width: calc(6ch + #{$space-double}); + text-align: center; + } + } + } + } + + .date-recur__weekdays, + .date-recur__ordinals { + .fieldset-wrapper { + width: 100%; + + .form-checkboxes, + .form-radios { + display: grid; + grid-gap: $space-half; + + + grid-template-columns: repeat(minmax(200px, 1fr)); + + @include media(">medium") { + grid-template-columns: repeat(auto-fill, minmax(150px, 25%)); + } + } + } + } + + .date-recur__ends.ends { + display: block; + } + + .date-recur__end-details { + padding: 0; + margin-top: $space-half; + + .form-item__content > *, + .form-item { + display: inline-block; + margin-right: $space-half; + width: auto; + } + } + +} + +.l-page--manage-auto-email-approval { + .form-item__label { + label { + padding: 10px 0; + margin: 0; + } + } + + div[class*="edit-top-domain-whitelist-add-more"] { + padding-top: 15px; + } +} diff --git a/web/themes/custom/perls/resources/scss/_objects.formtips.scss b/web/themes/custom/perls/resources/scss/_objects.formtips.scss new file mode 100644 index 0000000..ff67b6b --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_objects.formtips.scss @@ -0,0 +1,54 @@ +/* ------------------------------------ *\ + $FORMTIPS +\* ------------------------------------ */ + +.formtip { + &:hover, + &:focus, + &:active { + background-color: $c-link--hover; + border-color: $c-link--hover; + } +} + +div.description.formtips-processed, +.form-item .description.formtips-processed { + padding: 10px; + color: $c-admin-tip--foreground; + background: $c-admin-tip--background; + box-shadow: none; + border: 2px solid $c-admin-tip--border; + border-radius: 4px; + top: calc(100% + 10px); + left: 5px; + + &::before { + border-bottom-color: $c-admin-tip--border; + border-width: 8px; + top: -16px; + } +} + +.field--widget-paragraphs, +.field--widget-entity-reference-paragraphs { + .formtip { + font-size: $font-size-s; + + &::before { + font-size: $font-size-xs; + } + + .description { + top: 40px; + left: auto; + text-transform: initial; + font-size: 0.8em; + font-weight: normal; + + &::before { + top: -17px; + left: -2px; + } + } + } +} diff --git a/web/themes/custom/perls/resources/scss/_objects.icons.scss b/web/themes/custom/perls/resources/scss/_objects.icons.scss new file mode 100644 index 0000000..c76585d --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_objects.icons.scss @@ -0,0 +1,137 @@ +/* ------------------------------------ *\ + $ICONS +\* ------------------------------------ */ + +/** + * Icon Sizing + */ +.o-icon { + display: inline-block; +} + +.u-icon--xs { + width: $icon-xsmall; + height: $icon-xsmall; +} + +.u-icon--s { + width: $icon-small; + height: $icon-small; +} + +.u-icon--m { + width: $icon-medium; + height: $icon-medium; +} + +.u-icon--l { + width: $icon-large; + height: $icon-large; +} + +.u-icon--xl { + width: $icon-xlarge; + height: $icon-xlarge; +} + +/** + * XL Round icons + */ +.o-icon--round--outline { + display: block; + width: $icon-xlarge; + height: $icon-xlarge; + min-height: $icon-xlarge; + border-radius: $icon-xlarge; + border: 2px solid $c-white; +} + +/** + * Quiz status icons + */ +.o-icon--correct { + background: transparent url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 76.47 58.82'%3E%3Cpath d='M32.61,58.82a7,7,0,0,1-4.51-1.65L0,33.46l9-10.7L31.67,41.87,65.59,0,76.47,8.81,38.05,56.23a7,7,0,0,1-4.78,2.56Q32.94,58.82,32.61,58.82Z' fill='%23fff'/%3E%3C/svg%3E") center center no-repeat; + background-size: 40px 40px; +} + +.o-icon--incorrect { + background: transparent url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 67.85 68.44'%3E%3Ctitle%3EAsset 2%3C/title%3E%3Cpath d='M43.53,34.22,67.85,58.54,58,68.44,33.63,44.12,9.9,67.85,0,58,23.73,34.22,0,10.48,9.9.59,33.63,24.32,58,0l9.9,9.9Z' fill='%23fff'/%3E%3C/svg%3E") center center no-repeat; + background-size: 35px 35px; +} + +/** + * Flag: bookmark + */ +.o-flag--bookmark { + width: 35px; + height: 50px; + min-height: 50px; + background: transparent url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 69 97.83'%3E%3Ctitle%3Ebookmark%3C/title%3E%3Cpath d='M3,97.83a3,3,0,0,1-1.42-.36A3,3,0,0,1,0,94.83V0H6V89.27l27.4-18a3,3,0,0,1,3.34,0L63,89.16V0h6V94.83a3,3,0,0,1-4.69,2.48L35,77.37l-30.37,20A3.06,3.06,0,0,1,3,97.83Z' fill='%23fff'/%3E%3C/svg%3E") top center no-repeat; + background-size: 35px 50px; + overflow: hidden; + display: block; + position: absolute; + top: 0; + right: $space; + z-index: 3; + transition: $transition; + transform: translateY(-5px); + + @include u-visible; + + button { + width: 100%; + height: 100%; + border: 0; + outline: 0; + padding: 0; + margin: 0; + background-color: transparent; + } + + &:hover, + &:focus { + transform: translateY(-1px); + } + + &.is-active { + background: transparent url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 35.27 50'%3E%3Ctitle%3Ebookmark%3C/title%3E%3Cpath d='M1.53,50a1.51,1.51,0,0,1-.72-.18A1.54,1.54,0,0,1,0,48.47V0H35.27V48.47a1.54,1.54,0,0,1-2.4,1.26l-15-10.19L2.38,49.75A1.53,1.53,0,0,1,1.53,50Z' fill='%23ffffff'/%3E%3C/svg%3E") top center no-repeat; + background-size: 35px 50px; + } +} + +.flag { + &.completed { + width: 25px; + height: 25px; + min-height: 25px; + background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='77.801' height='77.72' viewBox='0 0 77.801 77.72' fill='%23ffffff'%3E%3Cg id='check' transform='translate(-11.057 -11.14)'%3E%3Cg fill-opacity='0.5' id='Group'%3E%3Cpath id='Path' d='M50,88.86A38.88,38.88,0,0,0,85.6,34.4a4,4,0,1,0-7.33,3.21A30.85,30.85,0,1,1,64.58,22.8a4,4,0,1,0,3.79-7A38.86,38.86,0,1,0,50,88.86Z'/%3E%3Cpath id='Path-2' data-name='Path' d='M33.73,38.21A4,4,0,1,0,28.2,44L45.8,60.83a4,4,0,0,0,2.76,1.11h.15a4,4,0,0,0,2.82-1.32L85.36,23a4,4,0,1,0-5.95-5.35L48.35,52.19Z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E%0A") top center no-repeat; + background-size: 25px 25px; + overflow: hidden; + position: absolute; + top: $space-half; + left: $space; + z-index: 3; + font-size: 0; + transition: $transition; + } + + &.uncompleted { + display: none; + } +} + +.o-status { + margin-bottom: 5px; + + span { + background-color: $c-gray--light; + border-radius: $border-radius; + color: $c-gray--dark; + display: inline-block; + font-weight: normal; + font-size: $font-size-xs; + padding: 5px; + text-transform: uppercase; + } +} diff --git a/web/themes/custom/perls/resources/scss/_objects.lists.scss b/web/themes/custom/perls/resources/scss/_objects.lists.scss new file mode 100644 index 0000000..d86030c --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_objects.lists.scss @@ -0,0 +1,73 @@ +/* ------------------------------------ *\ + $LIST TYPES +\* ------------------------------------ */ + +/** + * Tabs + */ +.c-tabs { + position: absolute; + bottom: 0; + left: $space; + + @include media(">medium") { + left: $space-double; + } + + + ul { + display: flex; + align-items: flex-end; + border: 0; + margin: 0; + padding: 0; + + li { + margin-right: 2px; + + &.is-active a { + background-color: $c-admin--background; + color: $c-admin--foreground; + } + + a { + background-color: darken($c-gray--light, 5%); + color: $c-secondary; + border-top-left-radius: $border-radius; + border-top-right-radius: $border-radius; + + &:hover { + background-color: $c-white; + } + } + } + } +} + +.c-section-content { + .c-tabs { + margin-bottom: 25px; + position: static; + + ul { + li a { + border-radius: 5px; + } + } + } +} + +/** + Item lists + */ +.item-list ul { + list-style: disc; + margin: 1em 0; +} + +/** + Entity browser modal tabs + */ +.eb-tabs ul li.active { + border-bottom-color: $c-content--foreground; +} diff --git a/web/themes/custom/perls/resources/scss/_objects.logo.scss b/web/themes/custom/perls/resources/scss/_objects.logo.scss new file mode 100644 index 0000000..3bf2241 --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_objects.logo.scss @@ -0,0 +1,23 @@ +/* ------------------------------------ *\ + Logo +\* ------------------------------------ */ + +@mixin logo($size: 120px) { + text-align: center; + + img { + display: inline-block; + height: auto; + max-height: $size; + // In most cases, we're height-constrained--so we allow the logo to be up to twice the width as it is tall. + max-width: $size * 2; + } +} + +@mixin small-logo { + @include logo(100px); +} + +@mixin big-logo { + @include logo(200px); +} diff --git a/web/themes/custom/perls/resources/scss/_objects.media.scss b/web/themes/custom/perls/resources/scss/_objects.media.scss new file mode 100644 index 0000000..c314633 --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_objects.media.scss @@ -0,0 +1,29 @@ +/* ------------------------------------ *\ + $MEDIA +\* ------------------------------------ */ + +/** + * Image styles. + */ +.image-style-user-profile-circle { + border-radius: 50%; + width: 200px; + max-width: 100%; +} + +.achievement-image { + margin: 0 auto; + padding: 0.6em; +} + +/** + * Field audio file. + */ +.c-field--name-field-audio-file { + audio { + display: block; + width: 100%; + // Browser default width of the audio element. Remove for full width. + max-width: 300px; + } +} diff --git a/web/themes/custom/perls/resources/scss/_objects.messaging.scss b/web/themes/custom/perls/resources/scss/_objects.messaging.scss new file mode 100644 index 0000000..b3b539e --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_objects.messaging.scss @@ -0,0 +1,7 @@ +/* ------------------------------------ *\ + $MESSAGES +\* ------------------------------------ */ + +.messages { + margin-bottom: $space; +} diff --git a/web/themes/custom/perls/resources/scss/_objects.navs.scss b/web/themes/custom/perls/resources/scss/_objects.navs.scss new file mode 100644 index 0000000..7a2c7f4 --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_objects.navs.scss @@ -0,0 +1,457 @@ +/* ------------------------------------ *\ + $NAVIGATION +\* ------------------------------------ */ + +/** + * Sidebar menu + */ +.c-nav__content-management { + margin: 0 (-$space) $space 0; + + @include media("xlarge") { + margin-left: $space; + } + + .c-menu { + li { + a { + @include o-heading--m; + + display: block; + font-weight: bold; + letter-spacing: 0.04rem; + text-transform: uppercase; + color: $c-admin-nav--foreground; + text-decoration: none; + line-height: 1.3; + transition: $transition; + border-top: 1px solid rgba($c-admin-nav--foreground, 0.4); + padding-top: $space-double; + margin-bottom: $space-double; + padding-right: $space; + + &:hover { + color: $c-link; + } + } + } + + li:first-child a { + border-top: 0; + } + + li.c-menu__item--expanded { + > a { + margin-bottom: $space; + } + + & .c-menu__item--expanded { + > a { + margin-bottom: 0; + } + } + } + } + + .c-submenu { + padding-bottom: $space; + + li { + a, + span { + padding: $space $space; + margin: 2px 0 2px 0; + border-radius: $border-radius--button 0 0 $border-radius--button; + border: 0; + color: $c-admin-nav--foreground; + + @include o-heading--s; + + &:hover, + &.is-active { + background-color: $c-admin-nav--background--active; + color: $c-admin-nav--foreground--active; + } + + &.is-active { + font-weight: normal; + } + } + + span { + display: block; + &:hover { + background-color: $c-admin-nav--background; + } + } + } + + & .c-submenu { + padding-bottom: 0; + + li { + a { + margin-left: $space; + } + } + } + } +} +/** + * Responsive toggle button. + */ +.c-nav__toggle { + background: transparent; + display: none; + position: absolute; + bottom: 0; + left: 0; + margin-left: $space; + margin-bottom: $space; + width: $space-double; + height: $space-double; + background: $c-button; + padding: $space-half; + border-radius: $border-radius; + + @include media("large") { + right: 40px; + } + } + + &.this-is-active { + opacity: 1; + visibility: visible; + } + + &__toggle { + // fallback solution for no user profile picture. + $icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='141' height='141'%3E%3Cpath fill='transparent' d='M0 141V0h141v141z'/%3E%3Cpath fill='%23ffffff' d='M118.742 120.825l.156 18.94a.644.644 0 01-.644.645H22.057a.644.644 0 01-.633-.636l.29-18.818s0-10.53 15.822-15.413h.041c.513-.126 11.371-2.508 15.855-3.261.273-.105.502-.298.652-.549a7.745 7.745 0 00.73-2.521.647.647 0 00-.217-.573c-1.39-1.217-7.773-8.326-9.938-22.67-2.255-14.995 5.386-30.945 25.488-32.033 20.133.863 28.311 17.504 25.763 32.167-2.431 13.936-8.584 21.306-9.902 22.558-.146.137-.521.428-.497.628.114.85.402 1.666.847 2.398.09.186.576.578 1.294.71 4.769.877 13.772 2.836 15.087 3.127h.041c15.82 4.895 15.962 15.301 15.962 15.301z'/%3E%3C/svg%3E"); + + background-color: transparent; + padding: 0; + background-image: colored-icon($icon, $c-learner-nav--icon); + background-repeat: no-repeat; + background-position: top center; + background-size: 75% 75%; + width: 50px; + height: 50px; + } + + &__header__item { + display: flex; + flex-direction: column; + justify-content: center; + white-space: nowrap; + } + + .c-menu__item a { + display: block; + color: $c-account-menu--foreground; + border-top: 1px solid rgba($c-white, 0.4); + padding-top: $space-half; + padding-bottom: $space-half; + white-space: nowrap; + + &:hover { + color: $c-account-menu--foreground--active; + } + } + + $switcher-variants: content-manager-user-menu OFF $c-admin-toggle--off left $space-quarter $space, learner-user-menu ON $c-admin-toggle--on right $space $space-quarter; + + @each $name, $text, $color, $position, $space-right, $space-left in $switcher-variants { + &.c-user-menu__#{$name} { + .c-menu__item--view-as-learner a { + display: flex; + flex-direction: row; + justify-content: space-between; + + &::after { + content: "#{$text}"; + display: inline-block; + margin-left: $space-half; + padding-right: $space-right; + padding-left: $space-left; + color: $c-account-menu--foreground; + font-size: $font-size-xs - 1; + line-height: 22px; + background-image: radial-gradient(circle at center, $color 0%, $color 55%, $c-disabled 55%, transparent 80%, transparent 80%, transparent 100%), linear-gradient(to right, $c-gray-5 0%, $c-gray-5 100%); + background-size: 18px 18px, 100% 100%; + background-position: center $position, center center; + background-repeat: no-repeat, no-repeat; + border-radius: $border-radius--card; + } + } + } + } +} diff --git a/web/themes/custom/perls/resources/scss/_objects.notifications.scss b/web/themes/custom/perls/resources/scss/_objects.notifications.scss new file mode 100644 index 0000000..13bd56d --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_objects.notifications.scss @@ -0,0 +1,71 @@ +/* ------------------------------------ *\ + Push Notifications +\* ------------------------------------ */ + +.push-notification-wrapper { + > * + * { + margin: $space 0; + } + + details { + .c-field { + margin: $space-half; + } + } +} + +.push-notifications-list { + table { + td:first-child { + width: 50%; + } + } +} + +.push-notification { + background: $c-gray--light; + border-radius: $border-radius; + box-shadow: $box-shadow; + max-width: 500px; + overflow: hidden; + + > * { + display: flex; + padding: $space-half; + + > :first-child { + flex: 1; + } + } + + &__header { + background: $c-gray-2; + font-size: var(--font-size-xs, $font-size-xs); + } + + &__content { + h3 { + font-size: var(--font-size-m, $font-size-m); + margin-bottom: $space-quarter; + } + } + + &__image { + overflow: hidden; + width: 15%; + + img { + max-width: 100%; + } + } + + &__item { + h4 { + margin: $space-quarter 0; + } + + .c-node--tile { + width: 300px; + } + } +} diff --git a/web/themes/custom/perls/resources/scss/_objects.prompt.scss b/web/themes/custom/perls/resources/scss/_objects.prompt.scss new file mode 100644 index 0000000..4b7e220 --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_objects.prompt.scss @@ -0,0 +1,192 @@ +/* ------------------------------------ *\ + $PROMPTS +\* ------------------------------------ */ + +.prompt-modal { + font-size: 0; + display: inline-block; + + .prompt-link { + padding: 10px 20px; + position: relative; + border-radius: 15px; + a { + display: table; + color: $c-white; + } + + .ajax-progress-throbber { + width: 100%; + height: 100%; + position: absolute; + left: 0; + top: 0; + background: $c-overlay; + border-radius: 15px; + + .throbber { + width: 100%; + height: 100%; + left: 50%; + right: 50%; + position: absolute; + } + } + } + + .prompt-tile-icon { + display: table-cell; + } + + .prompt-tile-title { + display: table-cell; + vertical-align: middle; + font-size: 1rem; + padding-left: 10px; + } + +} + + +.prompt-questions { + .c-stack { // c-stack => deck of cards + width: 100%; + } + + form { + max-width: 100%; + } + + .prompt-wrapper { // A card + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + height: auto; + min-height: 400px; + padding: 1rem; + color: $c-white; + background-color: $c-card--prompt; + border-radius: $border-radius--card; + box-shadow: $box-shadow; + overflow: hidden; + } + + .summary { + @include u-spacing($space-double); + + color: $c-black; + background-color: $c-card--results; + text-align: center; + + &--title { + @include o-heading--m; + @include u-break-word; + + font-weight: 700; + } + } + + .form-type-radios { + @include u-spacing($space-double); + + .form-radios { + @include u-spacing($space); + } + + > .form-item__label { + label { // Prompt title/question. + @include o-heading--m; + @include u-break-word; + + &::after { + display: none; + } + } + } + } + + .webform-button--submit { // Hide default webform submit button => triggered by js. + @include visually-hidden(); + } + + .form-type-radio { + .form-item__content { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + } + + input { + visibility: hidden; + opacity: 0; + height: 0; + width: 0; + } + + label { + @include u-visible; + + position: relative; + width: 100%; + border-radius: $border-radius--card; + border: 1px solid $c-white; + padding: $space-half; + padding-left: $space-double; + cursor: pointer; + height: auto; + z-index: 1; + + &::before { + content: ""; + display: inline-block; + height: 10px; + width: 10px; + border-radius: 10px; + border: 1px solid $c-white; + background-color: transparent; + position: absolute; + left: 15px; + top: 15px; + transition: $transition; + } + + &:hover, + &:focus, + &:active, + &:target, + &.this-is-active { + background-color: rgba($c-white, 0.2); + border-color: transparent; + + &::before { + background-color: $c-white; + } + } + } + } + + .tile-view { + .prompt-question { + text-transform: uppercase; + font-weight: 900; + letter-spacing: 1px; + color: $c-white; + + &:link { + color: $c-white; + } + } + } +} + +.prompt-questions-modal { + .ui-dialog-buttonpane { + display: none; + } + + li { + list-style: none; + } +} diff --git a/web/themes/custom/perls/resources/scss/_objects.stack.scss b/web/themes/custom/perls/resources/scss/_objects.stack.scss new file mode 100644 index 0000000..6cb11a1 --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_objects.stack.scss @@ -0,0 +1,59 @@ +/** + * Stack component. + * + * Lays out it's immediate children to resemble a stack of cards. + * The object with the `.top` class is considered to be the top of the stack. + * Shows up to three cards at a time--the top card and two behind it. + */ +@mixin stack { + position: relative; + + // All immediate children are considered the cards in the stack. + > * { + height: 100%; + opacity: 0; + pointer-events: none; + position: absolute; + transform: translate3d(-50%, 0, 0) rotateY(-90deg); + transition: transform 0.5s ease-in-out, filter 0.5s ease-in-out, opacity 0.75s; + width: 90%; + z-index: 11; + } + + // Use to denote the top of the stack. + // Can be moved with JavaScript and the stack will animate the change. + > .top { + opacity: 1; + pointer-events: all; + transform: none; + z-index: 10; + } + + > .top + * { + filter: brightness(85%); + opacity: 1; + transform: translate3d(8%, 0, 0) scale(0.95); + z-index: 9; + } + + > .top + * + * { + filter: brightness(70%); + opacity: 1; + transform: translate3d(16%, 0, 0) scale(0.9); + z-index: 8; + } + + > .top + * + * + * { + filter: brightness(50%); + transform: translate3d(24%, 0, 0) scale(0.85); + transition: none; + z-index: 7; + } +} + +.c-stack { + @include stack; + + height: 100%; + min-height: 600px; +} diff --git a/web/themes/custom/perls/resources/scss/_objects.system-status.scss b/web/themes/custom/perls/resources/scss/_objects.system-status.scss new file mode 100644 index 0000000..293acee --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_objects.system-status.scss @@ -0,0 +1,148 @@ +/* ------------------------------------ *\ + $SYSTEM STATUS REPORTS +\* ------------------------------------ */ + +.system-status-general-info { + > * { + margin: $space 0 0 0; + } + + &__items { + display: grid; + grid-template-columns: 1fr 1fr 1fr; + grid-auto-rows: auto; + grid-column-gap: $space-half; + grid-row-gap: $space-half; + } + + &__item { + margin: 0; + padding: $space; + border-radius: $border-radius--card; + border: $border--light; + + > * { + margin-bottom: $space; + display: inline-flex; + + &:last-child:not(:first-child) { + margin-bottom: 0; + } + } + + &:nth-child(7) { + grid-column: 1 / 4; + } + + &-title { + display: block; + width: 100%; + padding-bottom: $space-quarter; + border-bottom: $border--standard; + margin-bottom: $space; + } + + a + h4, + h3 + h4 { + margin-top: 0; + } + + h4, + h5, + h6 { + display: block; + width: 100%; + margin-bottom: 0; + margin-top: $space; + } + + .cron-description__run-cron { + display: table; + } + } +} + +.system-status-report { + &__group { + > * { + margin-top: $space; + } + + &__item { + border: $border--light; + border-radius: $border-radius--card; + padding: $space; + + > * { + margin-top: $space-half; + } + } + } + + &__status-title { + background-color: $c-gray--light; + } + + &__entry { + border: $border--light; + border-radius: $border-radius--card; + overflow: hidden; + } + + &__entry__value { + padding: $space; + font-weight: bold; + + h3 { + margin-top: $space; + margin-bottom: $space-quarter; + } + + ul { + list-style-type: circle; + } + + dt { + margin-top: $space; + } + + .description { + font-weight: normal; + } + + .cron-description__run-cron { + margin-top: $space; + } + } +} + +.system-status-report-counters { + flex-wrap: nowrap; + + &__item { + border-radius: $border-radius; + margin: $space-quarter; + } +} + +.info-elements { + display: grid; + grid-template-columns: 1fr 1fr; + grid-auto-rows: auto; + grid-column-gap: $space; + grid-row-gap: $space; + + .info-element { + display: flex; + flex-direction: column; + border: $border--light; + border-radius: $border-radius--card; + background-color: $c-gray--light; + padding: $space-half; + + &__label { + border-bottom: $border--standard; + margin-bottom: $space-quarter; + } + } +} diff --git a/web/themes/custom/perls/resources/scss/_objects.tables.scss b/web/themes/custom/perls/resources/scss/_objects.tables.scss new file mode 100644 index 0000000..18c26c3 --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_objects.tables.scss @@ -0,0 +1,115 @@ +/* ------------------------------------ *\ + $SPECIFIC TABLES +\* ------------------------------------ */ + +table { + .button { + @include o-link; + } + + .tabledrag-hide { + text-align: center; + } + + .paragraph-type { + @include o-heading--s; + } + + tr:nth-child(odd) { + .paragraphs-description .paragraphs-content-wrapper::after { + background: linear-gradient(to right, rgba(0, 0, 0, 0) 0%, $table-row--background--odd 100%); + } + } +} + +table.views-table, +table.sticky-table, +table.sticky-header, +table.sticky-enabled { + th { + border-color: $c-white; + } +} + +// Special table td cases on given fields. +td.views-field-user-picture { + width: calc(50px + #{$space}); + + img { + width: 50px; + box-shadow: none; + margin: 0 auto; + display: block; + } +} + +.views-field-type, +.views-field-changed { + white-space: nowrap; +} + +// Special table th cases on given fields. +th.views-field-views-bulk-operations-bulk-form { + overflow: visible; + width: 25px; + + input { + position: relative; + margin: 0; + float: none; + } +} + +// Hides the show row weights +.tabledrag-toggle-weight-wrapper { + display: none; +} + +td.views-field-operations { + .dropbutton-widget { + right: 0; + } +} + +.c-view--webform-submissions td.views-field-operations { + .dropbutton-widget { + left: 0; + right: auto; + } +} + +table.webform-results-table { + tbody tr { + :nth-child(4), + :nth-child(5) { + white-space: normal; + } + } + + .webform-dropbutton { + .dropbutton-wrapper { + margin-right: 20px; + padding-right: 100px; + } + } +} + +tr.promoted { + border-left: solid 4px $c-secondary; +} + +tr.unpublished { + border-left: solid 4px $c-gray; +} + +td.views-field-counter { + word-break: normal; + text-align: center; + + tr.sticky & { + background: url("../img/icons/icon-tack.svg") center no-repeat; + background-size: $icon-small $icon-small; + text-indent: -9999px; + width: $icon-small; + } +} diff --git a/web/themes/custom/perls/resources/scss/_objects.tabs.scss b/web/themes/custom/perls/resources/scss/_objects.tabs.scss new file mode 100644 index 0000000..d06f2d1 --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_objects.tabs.scss @@ -0,0 +1,41 @@ +/* ------------------------------------ *\ + $TABS +\* ------------------------------------ */ + +.layout--tabs .tabs { + margin-top: $space + $space-double; + margin-bottom: $space + $space-quarter; + + a { + color: var(--foreground-color, #231f20); + padding: 0; + + &.is-active { + background: none; + color: var(--foreground-color, #231f20); + border-bottom: 3px solid $c-secondary; + + .label { + font-weight: bold; + } + } + + &:hover { + background: none; + + .label { + transition: font-weight 0.25s $hard-ease-in; + } + } + + .label { + font-size: var(--font-size-m, $font-size-m); + text-transform: capitalize; + font-weight: normal; + } + } + + & > li.tabs__tab { + margin-right: $space-double - $space-quarter; + } +} diff --git a/web/themes/custom/perls/resources/scss/_objects.text.scss b/web/themes/custom/perls/resources/scss/_objects.text.scss new file mode 100644 index 0000000..61036ba --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_objects.text.scss @@ -0,0 +1,200 @@ +/* ------------------------------------ *\ + $TEXT TYPES +\* ------------------------------------ */ + +/** + * Page Title + */ +.o-page-title, +.page-title { + @include o-heading--xl; + + text-transform: uppercase; + + .page-variant--new-dashboard & { + display: none; + } +} + +/** + * Description element + */ +.page-description { + @include description-container; +} + +/** + * Font Families + */ +.u-font { + font-family: $ff-font; +} + +.u-font--primary { + font-family: $ff-font--primary; +} + +.u-font--secondary { + font-family: $ff-font--secondary; +} + +/** + * Text Sizes + */ +.u-font--xs { + font-size: var(--font-size-xs, $font-size-xs); +} + +.u-font--s { + font-size: var(--font-size-s, $font-size-s); +} + +.u-font--m { + font-size: var(--font-size-m, $font-size-m); +} + +.u-font--l { + font-size: var(--font-size-l, $font-size-l); +} + +.u-font--xl { + font-size: var(--font-size-xl, $font-size-xl); +} + +.u-font--xxl { + font-size: var(--font-size-xxl, $font-size-xxl); +} + +/** + * Text Positioning + */ +.u-text-align--center { + text-align: center; +} + +/** + * Text Decorations + */ +.u-text-decoration--underline { + text-decoration: underline; +} + +/** + * Text Transform + */ +.u-text-transform--uppercase { + text-transform: uppercase; +} + +.u-text-transform--normal { + text-transform: normal; +} + +/** + * Rich text editor text + */ +.o-rich-text { + word-break: break-word; + + p, + li { + @include p; + } + + a[href]:not(.button) { + text-decoration: underline; + } + + .c-node { + height: 100%; + max-height: 100%; + + a { + text-decoration: none; + } + } + + h1, + h2, + h3, + h4, + h5, + h6 { + margin-top: 0; + padding-top: $space; + } + + h2:empty, + h3:empty, + p:empty { + display: none; + } +} + +ol, +ul { + .o-rich-text & { + padding-left: 0; + margin-left: 0; + + li { + list-style: none; + padding-left: $space; + margin-left: $space; + position: relative; + + &::before { + content: ""; + width: $space; + height: auto; + display: inline-block; + position: absolute; + left: 0; + line-height: inherit; + font-size: inherit; + } + + li { + list-style: none; + margin-left: $space-half; + } + } + } +} + +ol { + .o-rich-text & { + counter-reset: item; + + li { + &::before { + content: counter(item) ". "; + counter-increment: item; + } + + li { + counter-reset: item; + + &::before { + content: '\002010'; + } + } + } + } +} + +ul { + .o-rich-text & { + li { + &::before { + content: '\002022'; + } + + li { + &::before { + content: '\0025E6'; + } + } + } + } +} diff --git a/web/themes/custom/perls/resources/scss/_objects.vidyo.scss b/web/themes/custom/perls/resources/scss/_objects.vidyo.scss new file mode 100644 index 0000000..26aada8 --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_objects.vidyo.scss @@ -0,0 +1,25 @@ +/** + * Vidyo styling. + */ + +.vidyo-client { + .toolbar { + background-color: $c-primary; + } + + #toolbarLeft { + text-align: left; + } + + #toolbarCenter { + text-align: center; + } + + #toolbarRight { + text-align: right; + } + + .toolbarButton { + background-color: $c-primary; + } +} diff --git a/web/themes/custom/perls/resources/scss/_objects.views.scss b/web/themes/custom/perls/resources/scss/_objects.views.scss new file mode 100644 index 0000000..4878f5b --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_objects.views.scss @@ -0,0 +1,546 @@ +/* ------------------------------------ *\ + $VIEWS +\* ------------------------------------ */ + +.c-view__banner { + display: flex; + flex-direction: column; + + h2 { + @include o-heading--l; + } + + > *:first-child { + flex: 1; + order: 1; + } + + > *:last-child:not(:first-child) { + order: 0; + margin-bottom: $space; + + @include media(">medium") { + order: 1; + margin-bottom: 0; + } + } +} + +.c-view__filters { + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + + > * { + margin: $space $space 0 0; + } +} + +.c-view__extra-title { + @include o-heading--l; +} + +.c-view__header { + display: flex; + flex-direction: row; + align-items: center; + justify-content: flex-start; +} + +/** + * Enhanced dashboard sliders. + */ +.page-variant--new-dashboard { + .c-view { + .js-slick-slider { + .slick-list { + overflow: hidden; + } + + li:not(.slick-slide), + .slick-slide { + padding: 0 $space-half; + } + } + } +} + +/** + * 'Most recent' and 'Recent users' sliders. + */ +.c-view--recent-users, +.c-view--most-recent-content, +.c-view--most-recent-vocabulary { + padding: $space 0; + display: block; + position: relative; + overflow: hidden; + + .c-view-display-id--manage_tests & { + margin-left: -10px; + } + + .c-view__header p { + @include o-heading--l; + } + + .js-slick-slider { + margin-left: 0; + margin-right: -$space; + padding-right: $space; + + .slick-next { + right: $space-double; + transform: rotate(180deg) translateY(-70%); + } + + .slick-prev { + transform: translateY(70%); + } + + .slick-list { + padding: 0; + overflow: hidden; + } + + ul:not(.slick-slider) { + padding-left: 0; + padding-right: 0; + } + + li:not(.slick-slide), + .slick-slide { + padding: 0 $space-half; + } + } +} + +.c-view-id--recommended_content { + .js-slick-slider .slick-track { + align-items: stretch; + } +} + +.c-view--most-recent-content { + .views-exposed-form { + display: none; + } +} + +.l-page--manage-courses-and-content-library-tags { + .c-view-display-id--most_recent_topics { + display: none; + } +} + +.l-page--manage-courses-and-content-library-topics { + .c-view-display-id--most_recent_tags { + display: none; + } +} + +.l-page--manage-courses-and-content-library-tags, +.l-page--manage-courses-and-content-library-topics { + .c-view--most-recent-vocabulary { + .taxonomy-term--teaser { + position: relative; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + min-height: 200px; + width: 100%; + padding: 20px; + background-color: $c-gray--light; + border-radius: $border-radius--card; + box-shadow: $box-shadow; + overflow: hidden; + } + } +} + +.c-view--recent-users { + .js-slick-slider .slick-slide { + min-width: 330px; + } +} + +/** + * Manage users view. + */ +.c-view--manage-users { + .c-view__banner { + flex-direction: column; + margin-right: -$space; + + @include media(">xlarge") { + margin-right: -$space-double; + } + + + .c-view__filters { + margin-left: 0; + padding-right: $space; + + @include media(">xlarge") { + padding-right: $space-double; + } + } + } +} + +/** + * Manage content and vocabularies view. + */ +.c-view--manage-users, +.c-view--manage-vocabularies, +.c-view--manage-content { + .c-view__header { + > p { + margin-left: $space-half; + } + + .slick-track { + align-items: flex-end; + } + + .o-button--large { + align-self: flex-end; + margin-bottom: $space-double; + } + } +} + +// +// Resolves issue: +// At "Content" >> "Learning Objects" page, +// in view's header section, few too many create new buttons pushed the "most recent" carousel to way far off right, +// to a point where it is unusable. +// Resolution: Break carousel into new line until a specific screen width. +.c-view-id--manage_content.c-view-display-id--page_4, +.c-nav__push-notification-manage { + .c-view__header, + .c-menu { + @include media(" .item-list { + display: inline-flex; + flex-direction: column; + justify-content: flex-start; + align-items: flex-start; + width: 310px; // to accomodate current text lengths for equal heights. + height: 170px; + white-space: normal; + margin-right: $space-half; + border-radius: $border-radius; + position: relative; + + h3, + h3 a { + @include o-heading--l; + + display: block; + width: 100%; + height: 100%; + margin-top: 0; + margin-bottom: 0; + + span { + @include o-heading--xxl; + + display: block; + clear: both; + margin-bottom: $space-half; + } + } + + h3 { + padding: ($space-half + $space-quarter) $space; + } + } + + ul { + display: none; + } + + .views-field-title { + display: flex; + flex-direction: column-reverse; + justify-content: start; + align-items: flex-start; + + .field-content { // Large number + @include o-heading--xxl; + } + + .views-label-title { + font-size: $font-size-s; + } + } + } + } +} + +.c-block-views-blockcorpus-activity-corpus-activity-long { + margin-top: $space; + + .c-view--corpus-activity { + padding: $space-and-half 0 ($space-double * 2); + + .c-view__content { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); + + > .item-list { + display: inline-flex; + flex-direction: column; + justify-content: space-between; + align-items: flex-start; + white-space: normal; + margin: 0 $space-half $space-half 0; + padding: $space $space $space-half; + border-radius: $border-radius; + color: $c-white; + position: relative; + + h3 { + margin-bottom: $space-half; + + a { + @include o-heading--l; + + &::after { + content: ""; + display: block; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + } + } + } + } + + ul, + ul > li { + list-style: none; + margin: 0; + padding: 0; + } + } + } +} + +.c-view--corpus-activity { + .c-view__content { + > .item-list { + background-color: $c-secondary; + color: $c-white; + + & a { + color: $c-white; + } + + $color-map: + course $c-card--course, + tip_card $c-card--tip, + flash_card $c-card--flashcard, + quiz $c-card--quiz, + test $c-card--test, + podcast $c-card--podcast, + podcast_episode $c-card--podcast; + + @each $selector, $color in $color-map { + &.#{$selector} { + background-color: $color; + } + } + } + } +} + +.views-empty { + .cm-empty { + &-container { + display: flex; + flex-direction: column; + justify-content: center; + max-width: 350px; + margin: ($space-double * 2) auto; + text-align: center; + } + + &-title { + font-family: $ff-font--secondary; + font-size: var(--font-size-l, $font-size-l); + line-height: 1.1; + color: $c-empty; + font-weight: 600; + margin-bottom: $space-half; + display: flex; + justify-content: center; + flex-direction: column; + + @mixin add-icon-gray($icon-name, $icon-width, $icon-height) { + &::before { + content: ""; + display: block; + width: $icon-width; + height: $icon-height; + min-height: $icon-height; + margin: $space auto; + background-image: url("../img/icons/icon-#{$icon-name}-gray.svg"); + background-size: $icon-width $icon-height; + background-repeat: no-repeat; + background-position: center; + } + } + + $icon-map: + image image $icon-medium $icon-medium, + dashboard topics $icon-large $icon-large, + groups group $icon-large $icon-large, + users users $icon-large $icon-large, + course courses $icon-large $icon-large, + learning-objects learning-objects $icon-large $icon-large, + tip_card tip-cards $icon-large $icon-large, + flash_card flash-cards $icon-large $icon-large, + quiz quizzes $icon-large $icon-large, + tag tags $icon-xxlarge $icon-large, + topic topics $icon-large $icon-large, + test tests $icon-large $icon-large, + podcast podcasts $icon-large $icon-large; + + @each $selector, $icon-name, $icon-width, $icon-height in $icon-map { + &.#{$selector} { + @include add-icon-gray($icon-name, $icon-width, $icon-height); + } + } + } + + &-message { + @include p; + + color: $c-empty; + margin-bottom: $space-and-half; + } + } + + .o-button { + margin-bottom: $space; + } +} + +.c-view--dashboard { + .c-view__extra-title { + display: none; + } +} + +.c-view--stat-course-feedback { + td.views-field-operations .dropbutton-widget { + left: 0; + right: inherit; + } +} + +.c-view__footer.u-spacing { + margin-top: $space; +} + +.c-view--taxonomy-term { + .taxonomy-term--full { + h2 { + margin: $space-half 0; + + a { + color: $c-content--foreground; + } + } + } + + .vocabulary-tags { + + h2 { + display: inline-block; + } + + .content { + display: inline-block; + } + + .c-field--name-name { + &::before { + content: '#'; + } + } + } + + .flag-following { + margin-left: 20px; + } +} + +.c-block-views-blockgroup-index-my-groups, +.c-view--group-topics .o-topic-row{ + padding-bottom: $space; + padding-top: $space-half; +} + +.c-view--group-topics .c-view__banner h2 { + padding-bottom: $space; +} + +.c-view--group-content-by-topic, +.c-view--dashboard-tags, +.c-block-views-blockhistory-recent-viewed-block, +.c-block-views-blockgroup-index-my-groups-block, +.c-block-views-blockbookmarks-favorites-block { + .c-view__more { + display: none; + } +} +.c-view-id--content_for_review_block.c-view-display-id--block_1 { + padding-top: $space-double; +} + +.l-page--manage-push-notifications { + .push-notification-action-link { + width: 225px; + } +} diff --git a/web/themes/custom/perls/resources/scss/_settings.variables.scss b/web/themes/custom/perls/resources/scss/_settings.variables.scss new file mode 100644 index 0000000..217d744 --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_settings.variables.scss @@ -0,0 +1,315 @@ +/* ------------------------------------ *\ + $VARIABLES +\* ------------------------------------ */ + +// +// How to use this file +// ==================== +// The PERLS appearance is highly customizable. +// +// * Palettes - define the colors to use around the app. +// * Customizations - choose how the palettes are used. +// * Mappings - fine-grain control over how specific colors map to interface elements. +// +// Note: Talk to developers before making significant changes to color names or how this file works. +// + +// +// Palettes +// ======== +// + +// +// Brand Palette +// ------------- +// These colors must match those in dist/css/color.css for dynamic theming. +// Do not use these colors directly. +// These must all be colors; they cannot use CSS variables. +// +$-palette-primary: #006686; +$-palette-secondary: #26a1c6; +$-palette-tertiary: #d6e8ee; +$-palette-tip: #dd031d; +$-palette-flashcard: #fc990b; +$-palette-quiz: #63378f; +$-palette-course: #2588d0; +$-palette-podcast: #5d5d5d; + +// +// Neutral Palette +// ---------------- +// Because who doesn't need some gray in their life. +// Avoid using these colors directly. +// These must all be colors; they cannot use CSS variables. +// +$c-white: #fff; // Must be pure or off-white. +$c-gray-1: #f5f5f5; // Used for light grays. +$c-gray-2: #ccc; // Used for disabled fields. +$c-gray-3: #7a7b7a; // Used for empty messages. +$c-gray-4: #707070; // Default gray. +$c-gray-5: #606060; // Used for form text. +$c-gray-6: #231f20; // Used for dark grays. +$c-black: #000; // Must be pure or off-black. + +// +// Other Colors +// ------------ +// These other colors are used for specific scenarios. +// They may be directly referenced. +// +$c-error: #d60000; +$c-valid: #089e00; +$c-warning: #fff664; +$c-information: #000db5; +$c-overlay: rgba($c-black, 0.8); +$c-disabled: $c-gray-2; +$c-shadow: rgba($c-black, 0.16); + +// +// Customizations +// ============== +// With the palette defined, now customize how those colors are used. +// Some of this can be controlled with CSS variables (dynamic theming). +// +// While these can be used directly, consider instead adding a mapping below. +// +// Where CSS variables are used, SASS color functions cannot be used. +// At some point, I'd like to have Drupal dynamically compile the SASS +// and use SASS variables instead of CSS variables for dynamic theming. +// + +$c-primary: var(--primary-color, $-palette-primary); +$c-secondary: var(--secondary-color, $-palette-secondary); +$c-secondary--light: var(--secondary-lighter, lighten($-palette-secondary, 20%)); +$c-secondary--dark: var(--secondary-darker, darken($-palette-secondary, 20%)); +$c-tertiary: var(--tertiary-color, $-palette-tertiary); + +$c-gray--light: $c-gray-1; +$c-gray: $c-gray-4; +$c-gray--dark: $c-gray-6; + +$c-primary--alt: $c-white; // Color to use against the primary color for text and icons. +$c-secondary--alt: $c-white; // Color to use against the secondary color for text and icons. + +$c-content--background: var(--background-color, $c-white); +$c-content--foreground: var(--foreground-color, $c-gray--dark); + +$c-menu-background: var(--menu-background-color, #463e3f); + +$c-card: $c-gray; +$c-card--tip: var(--tip-color, $-palette-tip); +$c-card--quiz: var(--quiz-color, $-palette-quiz); +$c-card--flashcard: var(--flashcard-color, $-palette-flashcard); +$c-card--test: var(--test-color, $-palette-quiz); +$c-card--course: var(--course-color, $-palette-course); +$c-button--course: var(--course-color-darker, $-palette-course); +$c-card--podcast: var(--podcast-color, $-palette-podcast); +$c-card--results: $c-gray--light; +$c-card--prompt: $c-primary; +$c-teaser-gradient: linear-gradient(180deg, lighten($c-gray-3, 10%) 0%, $c-gray-5 100%); +$c-tile-gradient: rgba($c-gray-6, 0); +$c-course-gradient: linear-gradient(180deg, rgba(#000, 0) 0%, rgba(darken($-palette-course, 5%), 0.95) 75%, $-palette-course 100%); +$c-podcast-gradient: linear-gradient(180deg, rgba(#000, 0) 0%, $c-tile-gradient 75%, #000000 100%); +$c-event-gradient: $c-podcast-gradient; + +// +// Mappings +// ======== +// For even greater control, adjust how the colors are mapped +// to various interface elements. +// + +// +// Interactivity +// +$c-link: $c-secondary; +$c-link--hover: $c-secondary--dark; +$c-button: $c-secondary; +$c-button--alt: $c-secondary--alt; +$c-button--hover: $c-secondary--dark; +$c-input--background: $c-white; +$c-input--text: $c-gray-5; +$c-input--placeholder: $c-gray-5; +$c-empty: $c-gray-3; +$c-chip: $c-gray-3; +$c-chip-hover: darken($c-chip, 20%); +$c-chip-text: $c-primary--alt; + +// +// Login +// +$c-login--background: $c-primary; +$c-login--foreground: $c-primary--alt; +$login--background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1022 745.56'%3E%3Cpath fill='%23e0e0e0' d='M511 62.86c36.11 6.47 66.81 17.24 92.62 31 60.85-7.55 114.62 5.54 151.91 41.64 58.43 56.58 57.75 160.65 15.52 273.43 92.6-26.41 181-34.27 251-25.43V0H522.33a426.75 426.75 0 00-37.71 58.76q12.74 1.67 26.38 4.1z'/%3E%3Cpath fill='%23e6f5fd' d='M1022 652.43v20'/%3E%3Cpath fill='%23B8B8B8' d='M83.58 180c125.29-56.5 121.85-104.9 99.49-126.62C151.17 22.38 55.32 28.36 0 61v130.71c19.32 6.73 46.52 5 83.58-11.71z'/%3E%3Cpath fill='%23ececec' d='M755.53 135.48c-37.29-36.1-91.06-49.19-151.91-41.64C682.91 136.05 715.94 206.4 716.93 267c1.32 80.34-126.44 191-262.1 101.42-2.18-1.45-4.34-2.89-6.49-4.34-54.85-37-97.81-75.69-127.36-112.25-143.23 146.11-195.09 319.94-105.85 416.89 61.84 67.19 159.1 93.21 256.78 66.5 59.71-16.33 119.59-52.38 171.63-110.77q14.52-16.29 28.17-34.9c43-58.82 77-120.95 99.34-180.64 42.23-112.78 42.95-216.85-15.52-273.43z'/%3E%3Cpath fill='%23B8B8B8' d='M716.93 267c-1-60.61-34-131-113.31-173.17-25.81-13.74-56.51-24.51-92.62-31q-13.67-2.45-26.38-4.1C356.14 41.9 298.2 82.6 279.66 122.13c-15 32 .15 78.77 41.32 129.71 29.55 36.56 72.51 75.28 127.36 112.25 2.15 1.45 4.31 2.89 6.49 4.34C590.49 458 718.25 347.35 716.93 267z'/%3E%3C/svg%3E"); +$login--background-blend: overlay; +$login--background-repeat: no-repeat; +$login--background-position: top -10vh center; +$login--background-size: auto 200vh; +// +// Learner +// +$c-learner-header--background: $c-secondary; +$c-learner-nav--icon: $c-secondary--alt; // Must be a color (cannot be dynamic). +$c-learner-nav--icon--active: $c-primary; +$c-learner-nav--active: $c-secondary--alt; +$c-learner-nav--inactive: $c-secondary--alt; +$c-learner-nav--hover: $c-secondary--alt; + +// +// Admin / Content Manager +// +$c-admin--background: $c-white; +$c-admin--foreground: $c-black; +$c-admin-header--background: $c-secondary; +$c-admin-header--foreground: $c-secondary--alt; +$c-admin-nav--background: $c-menu-background; +$c-admin-nav--foreground: $c-primary--alt; +$c-admin-nav--background--active: $c-secondary; +$c-admin-nav--foreground--active: $c-secondary--alt; +$c-admin-sidebar--background: $c-gray--light; +$c-admin-tip--background: $c-gray--light; +$c-admin-tip--foreground: $c-admin--foreground; +$c-admin-tip--border: darken($c-admin-tip--background, 5%); +$c-admin-search--background: $c-gray--light; +$c-admin-pager--hover: $c-gray--light; +$c-admin-item--hover: $c-gray--light; +$c-admin-toggle--on: $c-valid; +$c-admin-toggle--off: $c-error; +$c-taxonomy-term-card: #999; + +// +// Account Menu (Dropdown) +// +$c-account-menu--background: $c-menu-background; +$c-account-menu--foreground: $c-white; +$c-account-menu--foreground--active: $c-secondary; + +// +// Advanced Customizations +// ===================== +// +// Browser default px used for media queries +$max-width-px: 1260px; +$max-width: $max-width-px !default; +$max-width-small: 700px; +$sidebar-width: 300px; +$body-min-height: 650px; + +/** + * Typography + */ +$ff-font: "Circular Std", sans-serif; + +// Theme typefaces +$ff-font--primary: "Circular Std", sans-serif; +$ff-font--secondary: "Open Sans", sans-serif; + +/** + * Icons + */ +$icon-xsmall: 15px; +$icon-small: 20px; +$icon-medium: 30px; +$icon-large: 50px; +$icon-xlarge: 70px; +$icon-xxlarge: 100px; + +/** + * Animation + */ +$hard-ease-in: cubic-bezier(0.86, 0, 0.07, 1); +$transition: all 0.25s $hard-ease-in; + +/** + * Border Styles + */ +$border-color: $c-gray; +$border-color--light: $c-gray--light; +$border-radius: 5px; +$border-radius--card: 10px; +$border-radius--button: 50px; +$border--standard: 1px solid $border-color; +$border--light: 1px solid $border-color--light; +$box-shadow: 0 10px 10px $c-shadow; +$box-shadow-reversed: 0 -10px 10px $c-shadow; + +/** + * Tables + */ +$table-row--background--even: $c-admin--background; +$table-row--background--odd: $c-gray--light; + +/** + * Default Spacing/Padding + * Maintain a spacing system divisible by 10 + */ +$space: 20px; +$space-quarter: calc($space / 4); +$space-half: calc($space / 2); +$space-third: calc($space / 1.5); +$space-and-half: $space * 1.5; +$space-double: $space * 2; +$space-double-half: $space * 2.5; +$space-triple: $space * 3; +$space-quad: $space * 4; + +/** + * Common Breakpoints + */ +$xsmall: 350px; +$small: 500px; +$medium: 700px; +$large: 900px; +$xlarge: 1100px; +$xxlarge: 1300px; +$xxxlarge: 1500px; +$xxxxlarge: 1800px; +$xxxxxlarge: 2200px; + +$breakpoints: ("xsmall": $xsmall, "small": $small, "medium": $medium, "large": $large, "xlarge": $xlarge, "xxlarge": $xxlarge, "xxxlarge": $xxxlarge, "xxxxlarge": $xxxxlarge, "xxxxxlarge": $xxxxxlarge); + +/** + * Font Sizes + */ +$font-size-xs: 12px; +$font-size-s: 16px; +$font-size-m: 21px; +$font-size-l: 27px; +$font-size-xl: 38px; +$font-size-xxl: 42px; +$l-sidebar-width: 20%; +$l-main-width: 80%; + +/** + * Native Custom Properties + */ +:root { + --font-size-xs: 12px; + --font-size-s: 16px; + --font-size-m: 17px; + --font-size-l: 23px; + --font-size-xl: 34px; + --font-size-xxl: 38px; + --l-sidebar-width: 30%; + --l-main-width: 70%; +} + +// XLarge Breakpoint +@media screen and (min-width: $xlarge) { + :root { + --l-sidebar-width: 20%; + --l-main-width: 80%; + } +} + +// XXLarge Breakpoint +@media screen and (min-width: $xxlarge) { + :root { + --font-size-xs: 12px; + --font-size-s: 15px; + --font-size-m: 21px; + --font-size-l: 27px; + --font-size-xl: 38px; + --font-size-xxl: 42px; + } +} diff --git a/web/themes/custom/perls/resources/scss/_theme.maintenance.scss b/web/themes/custom/perls/resources/scss/_theme.maintenance.scss new file mode 100644 index 0000000..da0c4e9 --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_theme.maintenance.scss @@ -0,0 +1,31 @@ +body.maintenance-page { + background-color: $c-login--background; + color: $c-login--foreground; + text-align: center; + + .layout-container { + display: flex; + flex-direction: column; + height: 100vh; + margin: 0 auto; + max-width: 600px; + justify-content: center; + padding: $space-double; + } + + h1 { + margin: $space; + } + + .o-logo { + margin-bottom: $space-double; + + @include big-logo; + + @include media(" *:first-child { + width: var(--l-sidebar-width, $l-sidebar-width); + } + + > *:last-child { + width: var(--l-main-width, $l-main-width); + } + + > *:first-child:last-child { + width: 100%; + } + } + + /** + * Content Manager theme responsive menu and layout changes. + */ + @include media(" *:last-child { + margin-left: 0; + } + } + + &.cm-menu-open .c-tabs { + margin-left: 300px; + } + + .c-menu li a { + padding: $space $space-half 0 $space-half; + margin-bottom: $space; + } + + .c-submenu { + padding: 0; + + li a, + li span.is-active { + padding: $space-half $space; + margin-bottom: $space-half; + } + } + + .c-tabs { + margin-left: 0; + transition: $transition; + left: $space-quad; + } + + .l-main { + > *:first-child { + width: 300px; + } + + > *:last-child { + width: 100vw; + margin-left: -300px; + transition: $transition; + } + } + } + + .l-body { + display: flex; + flex-direction: column; + z-index: 2; + + @include media(">xlarge") { + flex-direction: row; + flex-wrap: nowrap; + } + + &__content { + background-color: $c-admin--background; + border-top-left-radius: $border-radius--card; + color: $c-admin--foreground; + width: 100%; + height: 100%; + display: block; + z-index: 1; + } + + &__sidebar { + width: 100%; + position: relative; + + @include media(">xlarge") { + margin-right: 0; + width: 40%; + } + } + + &.has-sidebar { + .l-body__content { + width: 100%; + box-shadow: 0 10px 20px rgba($c-black, 0.2); + position: relative; + + @include media(">xlarge") { + width: 60%; + } + + .l-content { + @include media(">xlarge") { + overflow: visible; + } + } + + .o-input.edit-top-preview-button { + display: none; + + .ajax-progress-throbber { + position: relative; + height: 0; + top: -30px; + padding: 0; + left: 105%; + + [dir="rtl"] & { + left: unset; + right: 105%; + } + } + + @include media(">xlarge") { + display: flex; + flex-direction: column; + position: absolute; + left: auto; + width: 180px; + top: $space-double; + right: calc(-180px - #{$space-double}); + pointer-events: none; + + [dir="rtl"] & { + right: unset; + left: calc(-180px - #{$space-double}); + } + } + + input { + @include o-button--small; + + text-indent: 9999px; + position: relative; + pointer-events: all; + + &:focus { + background-color: $c-white; + border-color: $c-secondary; + } + + &:focus:hover { + background-color: $c-admin--foreground; + border-color: $c-admin--foreground; + } + } + + &::before { + content: "Preview"; + margin-bottom: $space; + font-weight: bold; + + @include o-heading--m; + } + + &::after { + position: absolute; + bottom: 0; + left: 0; + right: 0; + text-align: center; + color: $c-secondary; + font-weight: bold; + content: "Refresh Preview"; + pointer-events: none; + cursor: pointer; + transition: $transition; + height: 36px; + width: 100%; + line-height: 36px; + } + + &:hover, + &:focus { + &::after { + color: $c-white; + } + } + } + } + + .l-sidebar--second { + padding-top: $space-double; + padding-bottom: $space-double; + } + } + } + + &.l-page--batch .l-body { + margin-right: 40px; + + &__content { + border-radius: $border-radius--card; + } + } + + .l-content { + padding: $space-double $space; + + @include media(">xlarge") { + padding: $space-double; + } + + .c-view__banner .c-view__content { + overflow: hidden; + } + } + + .c-node--card, + .c-node--full { + .c-node__header { + z-index: 0; + position: relative; + } + + .c-node__content { + z-index: 1; + position: relative; + background-color: $c-content--background; + border-radius: $border-radius--card; + box-shadow: $box-shadow; + padding: $space; + margin-top: -15px !important; + } + + .c-card__footer { + padding-bottom: 25px; + } + } + + .c-node--card--course { + width: 100%; + + .c-field--name-field-learning-content { + max-height: 100%; + overflow: visible; + } + } + + &.l-page--manage-webform-submissions { + .c-block-system-main-block { + overflow-x: scroll; + overflow-y: auto; + -ms-overflow-style: none; + } + } + + &.l-page--node-add-learn-link { + .l-body { + &.has-sidebar { + .l-sidebar--second { + // Adding more contrast to learn_link preview section. + background-color: #f5f5f5; + } + } + } + } +} + +.l--entity-browser--iframe { + background-color: $c-white; + color: $c-admin--foreground; +} diff --git a/web/themes/custom/perls/resources/scss/_theme.perls-learner.scss b/web/themes/custom/perls/resources/scss/_theme.perls-learner.scss new file mode 100644 index 0000000..fae9944 --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_theme.perls-learner.scss @@ -0,0 +1,75 @@ +body.perls-learner { + background-color: $c-content--background; + color: $c-content--foreground; + + .l-main { + margin-bottom: $space-quad; + } + + .o-page-title { + color: $c-content--foreground; + } + + .c-header { + background-color: $c-learner-header--background; + } + + .c-search-block { + &__toggle { + svg path { + fill: $c-learner-nav--icon; + } + } + } + + .c-tabs { + position: relative; + left: auto; + + ul { + border-bottom: $border--light; + + li a { + background-color: $c-gray--light; + + &:hover { + background-color: darken($c-gray--light, 5%); + } + } + } + } + + .c-pager { + margin-top: $space; + + &__items { + justify-content: center; + } + + @include pagerColorVariant($c-content--foreground, $c-link, transparent, $c-link--hover, $c-content--background, $c-content--background, $c-content--foreground); + } + + &.l-page--acknowledgements, + &.l-page--terms-of-use { + .l-content { + max-width: 960px; + margin: 0 auto; + } + } + + /** + * Normalize search page width and title. + */ + &.l-page--path--node.path-search, + &.l-page--path--search { + .l-content { + max-width: inherit; + } + } + + &.path-search { + .o-page-title { + margin: $space-double 0 $space 0; + } + } +} diff --git a/web/themes/custom/perls/resources/scss/_theme.user.scss b/web/themes/custom/perls/resources/scss/_theme.user.scss new file mode 100644 index 0000000..8af0fa4 --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_theme.user.scss @@ -0,0 +1,194 @@ +/** + * Learner user edit page + */ +body.perls-learner.l-page--path--user { + .l-main { + max-width: $max-width-small; + + @include u-center-block; + } + + &.l-page--user-interests, + &.l-page--user-content-my-content, + &.l-page--user-groups, + &.page--user_insights { + .l-main { + max-width: $max-width; + } + + .iso-grid { + max-height: none; + } + } + + .l-grid:not(.c-user-menu__header) { + display: block; + } +} + +/** + * User login page + */ +body.l-page--path--user.l-page--user-login { + background-color: $c-login--background; + background-image: $login--background-image; + background-blend-mode: $login--background-blend; + background-repeat: $login--background-repeat; + background-position: $login--background-position; + background-size: $login--background-size; + color: $c-login--foreground; + + .l-main { + display: flex; + flex-direction: column; + justify-content: center; + padding-top: $space-double; + padding-bottom: $space-double; + max-width: none; + margin: 0; + + $current-height-of-login-form: 600px; + @media screen and (min-height: $current-height-of-login-form) { + min-height: 100vh; + } + } + + .simplesamlphp-auth-login-link { + display: block; + } + + .o-logo { + margin-bottom: $space-double; + + @include big-logo; + + + @include media("small") { + justify-content: flex-start; + } + + + .l-article__header { + display: flex; + justify-content: space-between; + align-items: center; + padding: $space-double 0; + + .o-logo { + margin-left: $space-double; + + @include small-logo; + } + } + + .l-article__body { + flex: 1; + + @include media(">small") { + flex: inherit; + + @include u-center-block; + } + + + .o-icon { + display: block; + margin: 0 auto $space-double auto; + } + } + + .timezone-wrapper { + display: none; + } +} + +.l-article__user-password { + .l-article__body { + @include media(">small") { + max-width: 320px; + padding-top: 10vh; + } + } +} + +.l-article__user-register { + .l-article__body { + margin-bottom: $space-double; + } +} diff --git a/web/themes/custom/perls/resources/scss/_tools.functions.scss b/web/themes/custom/perls/resources/scss/_tools.functions.scss new file mode 100644 index 0000000..4764c35 --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_tools.functions.scss @@ -0,0 +1,18 @@ +/* ------------------------------------*\ + $FUNCTIONS +\*------------------------------------ */ + +@function str-replace($string, $search, $replace: '') { + $index: str-index($string, $search); + + @if $index { + @return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace); + } + + @return $string; +} + +@function colored-icon($svg, $new-fill, $current-fill: '%23ffffff') { + $color: str-replace(inspect($new-fill), '#', '%23'); + @return str-replace($svg, $current-fill, $color); +} diff --git a/web/themes/custom/perls/resources/scss/_tools.include-media.scss b/web/themes/custom/perls/resources/scss/_tools.include-media.scss new file mode 100755 index 0000000..c6c6691 --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_tools.include-media.scss @@ -0,0 +1,520 @@ +@charset "UTF-8"; + +// _ _ _ _ _ +// (_) | | | | | (_) +// _ _ __ ___| |_ _ __| | ___ _ __ ___ ___ __| |_ __ _ +// | | '_ \ / __| | | | |/ _` |/ _ \ | '_ ` _ \ / _ \/ _` | |/ _` | +// | | | | | (__| | |_| | (_| | __/ | | | | | | __/ (_| | | (_| | +// |_|_| |_|\___|_|\__,_|\__,_|\___| |_| |_| |_|\___|\__,_|_|\__,_| +// +// Simple, elegant and maintainable media queries in Sass +// v1.4.9 +// +// http://include-media.com +// +// Authors: Eduardo Boucas (@eduardoboucas) +// Hugo Giraudel (@hugogiraudel) +// +// This project is licensed under the terms of the MIT license + +//// +/// include-media library public configuration +/// @author Eduardo Boucas +/// @access public +//// + +/// +/// Creates a list of global breakpoints +/// +/// @example scss - Creates a single breakpoint with the label `phone` +/// $breakpoints: ('phone': 320px); +/// +$breakpoints: ("phone": 320px, "tablet": 768px, "desktop": 1024px) !default; + +/// +/// Creates a list of static expressions or media types +/// +/// @example scss - Creates a single media type (screen) +/// $media-expressions: ('screen': 'screen'); +/// +/// @example scss - Creates a static expression with logical disjunction (OR operator) +/// $media-expressions: ( +/// 'retina2x': '(-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi)' +/// ); +/// +$media-expressions: ("screen": "screen", "print": "print", "handheld": "handheld", "landscape": "(orientation: landscape)", "portrait": "(orientation: portrait)", "retina2x": "(-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi), (min-resolution: 2dppx)", "retina3x": "(-webkit-min-device-pixel-ratio: 3), (min-resolution: 350dpi), (min-resolution: 3dppx)") !default; + +/// +/// Defines a number to be added or subtracted from each unit when declaring breakpoints with exclusive intervals +/// +/// @example scss - Interval for pixels is defined as `1` by default +/// @include media('>128px') {} +/// +/// /* Generates: +/// @media (min-width: 129px) {} +/// +/// @example scss - Interval for ems is defined as `0.01` by default +/// @include media('>20em') {} +/// +/// /* Generates: +/// @media (min-width: 20.01em) {} +/// +/// @example scss - Interval for rems is defined as `0.1` by default, to be used with `font-size: 62.5%;` +/// @include media('>2.0rem') {} +/// +/// /* Generates: +/// @media (min-width: 2.1rem) {} +/// +$unit-intervals: ("px": 1, "em": 0.01, "rem": 0.1, "": 0) !default; + +/// +/// Defines whether support for media queries is available, useful for creating separate stylesheets +/// for browsers that don't support media queries. +/// +/// @example scss - Disables support for media queries +/// $im-media-support: false; +/// @include media('>=tablet') { +/// .foo { +/// color: tomato; +/// } +/// } +/// +/// /* Generates: +/// .foo { +/// color: tomato; +/// } +/// +$im-media-support: true !default; + +/// +/// Selects which breakpoint to emulate when support for media queries is disabled. Media queries that start at or +/// intercept the breakpoint will be displayed, any others will be ignored. +/// +/// @example scss - This media query will show because it intercepts the static breakpoint +/// $im-media-support: false; +/// $im-no-media-breakpoint: 'desktop'; +/// @include media('>=tablet') { +/// .foo { +/// color: tomato; +/// } +/// } +/// +/// /* Generates: +/// .foo { +/// color: tomato; +/// } +/// +/// @example scss - This media query will NOT show because it does not intercept the desktop breakpoint +/// $im-media-support: false; +/// $im-no-media-breakpoint: 'tablet'; +/// @include media('>=desktop') { +/// .foo { +/// color: tomato; +/// } +/// } +/// +/// /* No output +/// +$im-no-media-breakpoint: "desktop" !default; + +/// +/// Selects which media expressions are allowed in an expression for it to be used when media queries +/// are not supported. +/// +/// @example scss - This media query will show because it intercepts the static breakpoint and contains only accepted media expressions +/// $im-media-support: false; +/// $im-no-media-breakpoint: 'desktop'; +/// $im-no-media-expressions: ('screen'); +/// @include media('>=tablet', 'screen') { +/// .foo { +/// color: tomato; +/// } +/// } +/// +/// /* Generates: +/// .foo { +/// color: tomato; +/// } +/// +/// @example scss - This media query will NOT show because it intercepts the static breakpoint but contains a media expression that is not accepted +/// $im-media-support: false; +/// $im-no-media-breakpoint: 'desktop'; +/// $im-no-media-expressions: ('screen'); +/// @include media('>=tablet', 'retina2x') { +/// .foo { +/// color: tomato; +/// } +/// } +/// +/// /* No output +/// +$im-no-media-expressions: "screen", "portrait", "landscape" !default; + +//// +/// Cross-engine logging engine +/// @author Hugo Giraudel +/// @access private +//// + +/// +/// Log a message either with `@error` if supported +/// else with `@warn`, using `feature-exists('at-error')` +/// to detect support. +/// +/// @param {String} $message - Message to log +/// +@function im-log($message) { + @if feature-exists("at-error") { + @error $message; + } + @else { + @warn $message; + + $_: noop(); + } + + @return $message; +} + +/// +/// Determines whether a list of conditions is intercepted by the static breakpoint. +/// +/// @param {Arglist} $conditions - Media query conditions +/// +/// @return {Boolean} - Returns true if the conditions are intercepted by the static breakpoint +/// +@function im-intercepts-static-breakpoint($conditions...) { + $no-media-breakpoint-value: map-get($breakpoints, $im-no-media-breakpoint); + + @each $condition in $conditions { + @if not map-has-key($media-expressions, $condition) { + $operator: get-expression-operator($condition); + $prefix: get-expression-prefix($operator); + $value: get-expression-value($condition, $operator); + + @if $prefix == "max" and $value <= $no-media-breakpoint-value or $prefix == "min" and $value > $no-media-breakpoint-value { + @return false; + } + } + @else if not index($im-no-media-expressions, $condition) { + @return false; + } + } + + @return true; +} + +//// +/// Parsing engine +/// @author Hugo Giraudel +/// @access private +//// + +/// +/// Get operator of an expression +/// +/// @param {String} $expression - Expression to extract operator from +/// +/// @return {String} - Any of `>=`, `>`, `<=`, `<`, `≥`, `≤` +/// +@function get-expression-operator($expression) { + @each $operator in ">=", ">", "<=", "<", "≥", "≤" { + @if str-index($expression, $operator) { + @return $operator; + } + } + + // It is not possible to include a mixin inside a function, so we have to + // rely on the `im-log(..)` function rather than the `log(..)` mixin. Because + // functions cannot be called anywhere in Sass, we need to hack the call in + // a dummy variable, such as `$_`. If anybody ever raise a scoping issue with + // Sass 3.3, change this line in `@if im-log(..) {}` instead. + $_: im-log("No operator found in `#{$expression}`."); +} + +/// +/// Get dimension of an expression, based on a found operator +/// +/// @param {String} $expression - Expression to extract dimension from +/// @param {String} $operator - Operator from `$expression` +/// +/// @return {String} - `width` or `height` (or potentially anything else) +/// +@function get-expression-dimension($expression, $operator) { + $operator-index: str-index($expression, $operator); + $parsed-dimension: str-slice($expression, 0, $operator-index - 1); + $dimension: "width"; + + @if str-length($parsed-dimension) > 0 { + $dimension: $parsed-dimension; + } + + @return $dimension; +} + +/// +/// Get dimension prefix based on an operator +/// +/// @param {String} $operator - Operator +/// +/// @return {String} - `min` or `max` +/// +@function get-expression-prefix($operator) { + @return if(index(("<", "<=", "≤"), $operator), "max", "min"); +} + +/// +/// Get value of an expression, based on a found operator +/// +/// @param {String} $expression - Expression to extract value from +/// @param {String} $operator - Operator from `$expression` +/// +/// @return {Number} - A numeric value +/// +@function get-expression-value($expression, $operator) { + $operator-index: str-index($expression, $operator); + $value: str-slice($expression, $operator-index + str-length($operator)); + + @if map-has-key($breakpoints, $value) { + $value: map-get($breakpoints, $value); + } + @else { + $value: to-number($value); + } + + $interval: map-get($unit-intervals, unit($value)); + + @if not $interval { + // It is not possible to include a mixin inside a function, so we have to + // rely on the `im-log(..)` function rather than the `log(..)` mixin. Because + // functions cannot be called anywhere in Sass, we need to hack the call in + // a dummy variable, such as `$_`. If anybody ever raise a scoping issue with + // Sass 3.3, change this line in `@if im-log(..) {}` instead. + $_: im-log("Unknown unit `#{unit($value)}`."); + } + + @if $operator == ">" { + $value: $value + $interval; + } + @else if $operator == "<" { + $value: $value - $interval; + } + + @return $value; +} + +/// +/// Parse an expression to return a valid media-query expression +/// +/// @param {String} $expression - Expression to parse +/// +/// @return {String} - Valid media query +/// +@function parse-expression($expression) { + // If it is part of $media-expressions, it has no operator + // then there is no need to go any further, just return the value + @if map-has-key($media-expressions, $expression) { + @return map-get($media-expressions, $expression); + } + + $operator: get-expression-operator($expression); + $dimension: get-expression-dimension($expression, $operator); + $prefix: get-expression-prefix($operator); + $value: get-expression-value($expression, $operator); + + @return "(#{$prefix}-#{$dimension}: #{$value})"; +} + +/// +/// Slice `$list` between `$start` and `$end` indexes +/// +/// @access private +/// +/// @param {List} $list - List to slice +/// @param {Number} $start [1] - Start index +/// @param {Number} $end [length($list)] - End index +/// +/// @return {List} Sliced list +/// +@function slice($list, $start: 1, $end: length($list)) { + @if length($list) < 1 or $start > $end { + @return (); + } + + $result: (); + + @for $i from $start through $end { + $result: append($result, nth($list, $i)); + } + + @return $result; +} + +//// +/// String to number converter +/// @author Hugo Giraudel +/// @access private +//// + +/// +/// Casts a string into a number +/// +/// @param {String | Number} $value - Value to be parsed +/// +/// @return {Number} +/// +@function to-number($value) { + @if type-of($value) == "number" { + @return $value; + } + @else if type-of($value) != "string" { + $_: im-log("Value for `to-number` should be a number or a string."); + } + + $first-character: str-slice($value, 1, 1); + $result: 0; + $digits: 0; + $minus: $first-character == "-"; + $numbers: ("0": 0, "1": 1, "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8, "9": 9); + + // Remove +/- sign if present at first character + @if $first-character == "+" or $first-character == "-" { + $value: str-slice($value, 2); + } + + @for $i from 1 through str-length($value) { + $character: str-slice($value, $i, $i); + + @if not (index(map-keys($numbers), $character) or $character == ".") { + @return to-length(if($minus, -$result, $result), str-slice($value, $i)); + } + + @if $character == "." { + $digits: 1; + } + @else if $digits == 0 { + $result: $result * 10 + map-get($numbers, $character); + } + @else { + $digits: $digits * 10; + $result: $result + map-get($numbers, $character) / $digits; + } + } + + @return if($minus, -$result, $result); +} + +/// +/// Add `$unit` to `$value` +/// +/// @param {Number} $value - Value to add unit to +/// @param {String} $unit - String representation of the unit +/// +/// @return {Number} - `$value` expressed in `$unit` +/// +@function to-length($value, $unit) { + $units: ("px": 1px, "cm": 1cm, "mm": 1mm, "%": 1%, "ch": 1ch, "pc": 1pc, "in": 1in, "em": 1em, "rem": 1rem, "pt": 1pt, "ex": 1ex, "vw": 1vw, "vh": 1vh, "vmin": 1vmin, "vmax": 1vmax); + + @if not index(map-keys($units), $unit) { + $_: im-log("Invalid unit `#{$unit}`."); + } + + @return $value * map-get($units, $unit); +} + +/// +/// This mixin aims at redefining the configuration just for the scope of +/// the call. It is helpful when having a component needing an extended +/// configuration such as custom breakpoints (referred to as tweakpoints) +/// for instance. +/// +/// @author Hugo Giraudel +/// +/// @param {Map} $tweakpoints [()] - Map of tweakpoints to be merged with `$breakpoints` +/// @param {Map} $tweak-media-expressions [()] - Map of tweaked media expressions to be merged with `$media-expression` +/// +/// @example scss - Extend the global breakpoints with a tweakpoint +/// @include media-context(('custom': 678px)) { +/// .foo { +/// @include media('>phone', '<=custom') { +/// // ... +/// } +/// } +/// } +/// +/// @example scss - Extend the global media expressions with a custom one +/// @include media-context($tweak-media-expressions: ('all': 'all')) { +/// .foo { +/// @include media('all', '>phone') { +/// // ... +/// } +/// } +/// } +/// +/// @example scss - Extend both configuration maps +/// @include media-context(('custom': 678px), ('all': 'all')) { +/// .foo { +/// @include media('all', '>phone', '<=custom') { +/// // ... +/// } +/// } +/// } +/// +@mixin media-context($tweakpoints: (), $tweak-media-expressions: ()) { + // Save global configuration + $global-breakpoints: $breakpoints; + $global-media-expressions: $media-expressions; + + // Update global configuration + $breakpoints: map-merge($breakpoints, $tweakpoints) !global; + $media-expressions: map-merge($media-expressions, $tweak-media-expressions) !global; + + @content; + + // Restore global configuration + $breakpoints: $global-breakpoints !global; + $media-expressions: $global-media-expressions !global; +} + +//// +/// include-media public exposed API +/// @author Eduardo Boucas +/// @access public +//// + +/// +/// Generates a media query based on a list of conditions +/// +/// @param {Arglist} $conditions - Media query conditions +/// +/// @example scss - With a single set breakpoint +/// @include media('>phone') { } +/// +/// @example scss - With two set breakpoints +/// @include media('>phone', '<=tablet') { } +/// +/// @example scss - With custom values +/// @include media('>=358px', '<850px') { } +/// +/// @example scss - With set breakpoints with custom values +/// @include media('>desktop', '<=1350px') { } +/// +/// @example scss - With a static expression +/// @include media('retina2x') { } +/// +/// @example scss - Mixing everything +/// @include media('>=350px', ' 0 { + @media #{unquote(parse-expression(nth($conditions, 1)))} { + // Recursive call + @include media(slice($conditions, 2)...) { + @content; + } + } + } +} diff --git a/web/themes/custom/perls/resources/scss/_tools.mixins.scss b/web/themes/custom/perls/resources/scss/_tools.mixins.scss new file mode 100644 index 0000000..a790685 --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_tools.mixins.scss @@ -0,0 +1,202 @@ +/* ------------------------------------*\ + $MIXINS +\*------------------------------------ */ + +/** + * Standard paragraph + */ +@mixin p { + font-size: var(--font-size-s, $font-size-s); + line-height: 1.6; + font-family: $ff-font; +} + +p { + @include p; +} + +@mixin u-center-block { + margin-left: auto; + margin-right: auto; + width: 100%; + position: relative; +} + +.u-center-block { + @include u-center-block; +} + +@mixin visually-hidden { + position: absolute !important; + overflow: hidden; + width: 1px; + height: 1px; + padding: 0; + border: 0; + clip: rect(1px, 1px, 1px, 1px); +} + +@mixin u-hidden { + opacity: 0; + visibility: hidden; + transition: $transition; +} + +@mixin u-visible { + opacity: 1; + visibility: visible; + transition: $transition; +} + +@mixin u-middle-block { + margin-top: auto; + margin-bottom: auto; +} + +.u-middle-block { + @include u-middle-block; +} + +@mixin multi-select-map($selector-map) { + @each $selector in $selector-map { + .#{$selector} { + @content; + } + } +} + +@mixin u-spacing($space) { + & > * + * { + margin-top: $space; + } +} + +@mixin u-break-word { + overflow-wrap: break-word; + word-wrap: break-word; + word-break: break-word; +} + +@mixin make-row($gutter: 0) { + display: flex; + flex-wrap: wrap; + margin-right: -1 * calc($gutter / 2); + margin-left: -1 * calc($gutter / 2); +} + +@mixin make-col-ready($gutter: 0) { + position: relative; + // Prevent columns from becoming too narrow when at smaller grid tiers by + // always setting `width: 100%;`. This works because we use `flex` values + // later on to override this initial width. + width: 100%; + padding-right: $gutter / 2; + padding-left: $gutter / 2; +} + +@mixin make-col($size, $columns: 12) { + flex: 0 0 percentage($size / $columns); + // Add a `max-width` to ensure content within each column does not blow out + // the width of the column. Applies to IE10+ and Firefox. Chrome and Safari + // do not appear to require this. + max-width: percentage($size / $columns); +} + +@mixin make-col-auto() { + flex: 0 0 auto; + width: auto; + max-width: 100%; // Reset earlier grid tiers +} + +// Row columns +// +// Specify on a parent element(e.g., .row) to force immediate children into NN +// numberof columns. Supports wrapping to new lines, but does not do a Masonry +// style grid. +@mixin row-cols($count, $gutters: 0) { + & > * { + flex: 0 0 calc(100% / $count); + max-width: calc(100% / $count); + padding-right: calc($gutters / 2); + padding-left: calc($gutters / 2); + } +} + +@mixin scrollbars { + &::-webkit-scrollbar { + height: 8px; + width: 8px; + } + + &::-webkit-scrollbar-track { + border-radius: 10px; + background-color: $c-gray--light; + } + + &::-webkit-scrollbar-thumb { + border-radius: 10px; + background-color: $c-gray; + } +} + +@mixin avatar { + border-radius: 50%; + overflow: hidden; + text-align: center; + height: $icon-large; + width: $icon-large; + + img { + display: inline; + max-width: none; + height: 100%; + width: 100%; + } + + @include media("<=small") { + height: $icon-medium; + width: $icon-medium; + } +} + +@mixin card-icon-button { + width: $icon-xlarge; + height: $icon-xlarge; + min-height: $icon-xlarge; + // Buttons have a border-radius set which effects the icon. + border-radius: 0; + background: url("data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20142.64%20142.64%22%3E%3Cdefs%3E%3Cstyle%3E.cls-1%7Bfill%3A%23fff%3B%7D%3C%2Fstyle%3E%3C%2Fdefs%3E%3Cg%20id%3D%22Layer_2%22%20data-name%3D%22Layer%202%22%3E%3Cg%20id%3D%22Layer_1-2%22%20data-name%3D%22Layer%201%22%3E%3Cg%20id%3D%22Group_997%22%20data-name%3D%22Group%20997%22%3E%3Cpath%20class%3D%22cls-1%22%20d%3D%22M87.06%2C70.66A16.36%2C16.36%2C0%2C0%2C1%2C70.71%2C87h0A16.35%2C16.35%2C0%2C1%2C1%2C87.06%2C70.66Z%22%2F%3E%3Cpath%20class%3D%22cls-1%22%20d%3D%22M71.32%2C0a71.32%2C71.32%2C0%2C1%2C0%2C71.32%2C71.32A71.32%2C71.32%2C0%2C0%2C0%2C71.32%2C0Zm34.59%2C73.54C101%2C79.94%2C87.66%2C94.79%2C70.72%2C94.79S40.45%2C79.9%2C35.51%2C73.52a4.68%2C4.68%2C0%2C0%2C1%2C0-5.72c4.88-6.39%2C18.06-21.26%2C35.22-21.26%2C17%2C0%2C30.26%2C14.85%2C35.2%2C21.25A4.67%2C4.67%2C0%2C0%2C1%2C105.91%2C73.54Z%22%2F%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E") center center no-repeat; + opacity: 0.9; + transition: $transition; + transform: scale(1); + + &:hover, + &:focus { + transform: scale(1.05); + } +} + +// Provide uniform styles for description elements. +@mixin description-container { + margin: 0 0 $space; + padding: $space; + border-radius: $border-radius; + background: $c-admin-tip--background; + color: $c-black; + max-width: 1000px; +} + +@mixin add-icon($icon-src, $icon-width, $icon-height) { + &::before { + content: ""; + display: block; + width: $icon-width; + height: $icon-height; + min-height: $icon-height; + margin: $space auto; + background-image: url("../img/icons/#{$icon-src}"); + background-size: $icon-width $icon-height; + background-repeat: no-repeat; + background-position: center; + } +} diff --git a/web/themes/custom/perls/resources/scss/_tools.mq-tests.scss b/web/themes/custom/perls/resources/scss/_tools.mq-tests.scss new file mode 100644 index 0000000..8055ae7 --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_tools.mq-tests.scss @@ -0,0 +1,124 @@ +/* ------------------------------------*\ + $MEDIA QUERY TESTS +\*------------------------------------ */ + +@if $tests == true { + body { + &::before { + display: block; + position: fixed; + z-index: 9999; + background: black; + bottom: 0; + right: 0; + padding: 0.5em 1em; + content: "No Media Query"; + color: transparentize(#fff, 0.25); + border-top-left-radius: 10px; + font-size: 12 / 16 + em; + + @media print { + display: none; + } + } + + &::after { + display: block; + position: fixed; + height: 5px; + bottom: 0; + left: 0; + right: 0; + z-index: 9999; + content: ""; + background: black; + + @media print { + display: none; + } + } + + @include media(">xsmall") { + &::before { + content: "xsmall: 350px"; + } + + &::after, + &::before { + background: dodgerblue; + } + } + + + @include media(">small") { + &::before { + content: "small: 500px"; + } + + &::after, + &::before { + background: darkseagreen; + } + } + + + @include media(">medium") { + &::before { + content: "medium: 700px"; + } + + &::after, + &::before { + background: lightcoral; + } + } + + + @include media(">large") { + &::before { + content: "large: 900px"; + } + + &::after, + &::before { + background: mediumvioletred; + } + } + + + @include media(">xlarge") { + &::before { + content: "xlarge: 1100px"; + } + + &::after, + &::before { + background: hotpink; + } + } + + + @include media(">xxlarge") { + &::before { + content: "xxlarge: 1300px"; + } + + &::after, + &::before { + background: orangered; + } + } + + + @include media(">xxxlarge") { + &::before { + content: "xxxlarge: 1500px"; + } + + &::after, + &::before { + background: dodgerblue; + } + } + } +} diff --git a/web/themes/custom/perls/resources/scss/_trumps.helper-classes.scss b/web/themes/custom/perls/resources/scss/_trumps.helper-classes.scss new file mode 100644 index 0000000..594f5a8 --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_trumps.helper-classes.scss @@ -0,0 +1,27 @@ +/* ------------------------------------ *\ + $HELPER/TRUMP CLASSES +\* ------------------------------------ */ + +/** + * Completely remove from the flow but leave available to screen readers. + */ +.is-vishidden, +.visually-hidden { + position: absolute !important; + overflow: hidden; + width: 1px; + height: 1px; + padding: 0; + border: 0; + clip: rect(1px, 1px, 1px, 1px); +} + +.is-vishidden, +.visually-hidden, +input[type="hidden"] { + margin-top: 0 !important; +} + +.stop-scroll { + overflow: hidden; +} diff --git a/web/themes/custom/perls/resources/scss/_vendor.slick.scss b/web/themes/custom/perls/resources/scss/_vendor.slick.scss new file mode 100644 index 0000000..0b5501c --- /dev/null +++ b/web/themes/custom/perls/resources/scss/_vendor.slick.scss @@ -0,0 +1,164 @@ +@charset "UTF-8"; + +/* Slider */ + +/** + * Custom slick styles + */ + +.js-slick-slider { + position: relative; + margin-left: -$space-double; + margin-right: -$space-double; + + .slick-list, + .slick-track, + .slick-slide { + height: auto; + width: 100%; + display: flex; + } + + .slick-list { + overflow: hidden; + padding: 0 $space; + } + + > ul:not(.slick-slider) { + padding: 0 $space; + } + + > ul:not(.slick-slider), + .slick-track { + position: relative; + display: flex; + flex-wrap: nowrap; + flex-direction: row; + align-items: flex-start; + justify-content: flex-start; + padding-bottom: $space; + } + + > ul > li:not(.slick-slide), + .slick-slide { + padding: 0 $space; + outline: 0; + width: 70vw; + min-width: 70vw; + + @include media(">medium") { + width: 33vw; + min-width: 33vw; + } + + + @include media(">xlarge") { + width: 25vw; + min-width: 25vw; + } + + + @include media(">xxlarge") { + width: 20vw; + min-width: 20vw; + } + } +} + +/* Arrows */ +.slick-prev, +.slick-next { + position: absolute; + display: block; + height: 50px; + width: 50px; + line-height: 1; + cursor: pointer; + color: transparent; + overflow: hidden; + text-indent: 9999px; + background: transparent; + top: 25px; + padding: 0; + border: 0; + outline: 0; + border-radius: 50%; + z-index: 2; + box-shadow: $box-shadow; + transform: translateY(100%); + visibility: visible; + // Prevents text height from effecting psuedo element positioning. + font-size: 0; + + &::after { + background: url("data:image/svg+xml,%3C%3Fxml version='1.0' encoding='UTF-8'%3F%3E%3Csvg id='SVGDoc' width='25' height='24' xmlns='http://www.w3.org/2000/svg' version='1.1' xmlns:xlink='http://www.w3.org/1999/xlink' xmlns:avocode='https://avocode.com/' viewBox='0 0 25 24'%3E%3Cdefs%3E%3C/defs%3E%3Cdesc%3EGenerated with Avocode.%3C/desc%3E%3Cg%3E%3Cg%3E%3Ctitle%3EPath 792%3C/title%3E%3Cpath d='M12.13584,2v0l-10.13584,10.13574v0l10.13584,10.13575v0' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='round' stroke-linecap='round' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='3'%3E%3C/path%3E%3C/g%3E%3Cg%3E%3Ctitle%3ELine 130%3C/title%3E%3Cpath d='M23.09743,11.84295h-20.6704' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='round' stroke-linecap='round' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='3'%3E%3C/path%3E%3C/g%3E%3C/g%3E%3C/svg%3E") center center no-repeat; + background-size: 15px 15px; + position: relative; + width: 15px; + height: 15px; + display: block; + margin: auto; + height: 100%; + opacity: 1; + z-index: 1; + transform: translateY(-100%); + content: ""; + + @include media(">medium") { + width: 25px; + background-size: 25px 25px; + } + } + + &::before { + position: relative; + content: ""; + background: $c-secondary; + border-radius: 50%; + width: 100%; + display: block; + height: 100%; + z-index: 0; + opacity: 0.6; + transition: $transition; + } + + &:hover::before { + transition: $transition; + opacity: 1; + } + + @include media(">medium") { + top: 0; + height: 80px; + width: 80px; + } + + &.slick-disabled { + opacity: 0; + visibility: hidden; + } +} + +.slick-next { + right: $space; + // Arrow is rotated so we have to translate the other way to center in parent. + transform: rotate(180deg) translateY(-100%); + box-shadow: $box-shadow-reversed; +} + +.slick-prev { + left: $space; +} + +@include media(" to override inline styles. + height: 48px !important; + width: unset !important; + top: auto !important; + bottom: 10px !important; + left: -1px !important; + padding: 0 12px 0 48px !important; + background-color: $color-primary !important; + font-size: 0; + transform: translateX(-100%); + background-image: url($icon-edit); + background-position: left 12px center; + background-size: 24px 24px; + background-repeat: no-repeat; + box-shadow: $box-shadow-base; + border-top-left-radius: 10px; + border-bottom-left-radius: 10px; + word-break: keep-all; + + .label-counter { + float: none !important; + padding: 0 !important; + display: flex; + flex-direction: column; + justify-content: center; + height: 48px; + } +} + +.annotator-hl-error { + background: #ffcfbf; + cursor: pointer; +} + +.annotator-hl-good { + background: #dfffbf; + cursor: pointer; +} + +.annotator-hl-highlight { + background: rgba(255, 255, 10, 0.3); + text-decoration: underline; + cursor: pointer; +} + +.wrong { + background: #ffcfbf; + border: 1px solid #b3b3b3; + height: 20px; +} + +.good { + background: #dfffbf; + border: 1px solid #b3b3b3; + height: 20px; +} + +.highlight, +.hightlight { // todo - looks like a typo in the javascript classing. + display: none; // TODO - hide it - not needed. +} + +.annotations-list-uoc { + position: fixed; + top: 0; + right: 0; + height: 100%; + z-index: 1000; + margin-top: 0 !important; + background-color: #fff !important; + color: #000; + border-left: 3px solid $color-primary; + box-shadow: -6px 6px 6px rgba(0, 0, 0, 0.16); +} + +.label-compartit { + border: 1px solid #676767; + padding: 1px 4px 2px; + background-color: #666666; + color: #ffffff; + font-size: 11px; + font-weight: bold; + line-height: 14px; + vertical-align: baseline; + white-space: nowrap; + margin-top: 4px; +} + +.label-counter { + color: #ffffff; + font-size: 20px; + font-weight: 400; + background-color: transparent; + +} + +.label-counter-alert { + background-color: #b20000; + color: #ffffff; + font-size: 11px; + font-weight: bold; +} + +.container-anotacions { + list-style: none; + position: relative; + width: 100%; + padding: 0 0 10px 0; +} + +.annotator-viewer-delete { + background-image: url($icon-delete-black); + background-repeat: no-repeat; + background-size: auto; + width: 20px; + height: 20px; + transition: transform .3s ease; + + &:hover { + transform: translateY(-2px); + } +} + +.annotator-viewer-edit { + background-image: url($icon-edit-black); + background-repeat: no-repeat; + background-size: auto; + width: 20px; + height: 20px; + transition: transform .3s ease; + + &:hover { + transform: translateY(-2px); + } +} + +.annotator-viewer-share { + display: none !important; // TODO - hide this, no need for this feature. + background-repeat: no-repeat; + background-size: auto; + width: 20px; + height: 20px; +} + +.annotator-marginviewer-element { + width: 227px; + margin: 10px 0; + padding: 10px; + cursor: pointer; + + > * { + &:not(:last-child) { + margin-bottom: 5px; + } + } + + &:hover { + background-color: rgba($color-primary, .1); + } +} + +.annotator-marginviewer-header { + height: 26px; +} + +.annotator-marginviewer-footer { + border-bottom: 1px solid #d6d6d6; + display: flex; + flex-direction: row; + justify-content: space-between; + + > * { + margin: 5px !important; + float: none !important; + display: inline-block; + } +} + +.annotator-marginviewer-date { + font-size: 12px; + font-weight: 100; +} + +.panelTextArea { + width: 100%; + margin: 0; + padding: 5px; +} + +.annotator-marginviewer-quote { + display: none; + background-color: rgba($color-highlight, .5); +} + +.anotador_text { + &:empty:before { + content: "No Comment"; + font-style: italic; + } +} + +.filter-panel { + display: none; +} + +.annotator-user, +.annotator-marginviewer-footer>.label { + display: none; +} + +.annotations-init { + pointer-events: none; + border-color: $c-disabled; + .rotate { + background-color: $c-disabled !important; + } +} diff --git a/web/themes/custom/perls/resources/scss/annotator/_annotator.variables.scss b/web/themes/custom/perls/resources/scss/annotator/_annotator.variables.scss new file mode 100644 index 0000000..3fdc588 --- /dev/null +++ b/web/themes/custom/perls/resources/scss/annotator/_annotator.variables.scss @@ -0,0 +1,39 @@ +// +// @File: AnnotatorJS custom theming. +// VARIABLES. +// ========== + +// Var globals. +$color-primary: $c-secondary; +$color-primary-dark: $c-secondary--dark; +$color-highlight: #ffd800; +$color-text-base: #333; +$color-white: #fff; +$color-black: #000; +$color-stripe: #e8f5f9; +$font-family-base: $ff-font; +$font-size-base: 12px; + +// Var border. +$border-color-base: #707070; +$border-base: 1px solid $border-color-base; + +// Var box-shadows. +$box-shadow-base: 0 3px 6px rgba(0, 0, 0, 0.16); + +// Var icons. +@function make-url-ready($encoded-svg) { + @return "data:image/svg+xml,#{$encoded-svg}"; +} + +$icon-edit: make-url-ready("%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 329.531 329.531'%3E%3Cpath d='M242.712 18.778c-4.296-4.296-4.296-11.261 0-15.557 4.296-4.295 11.26-4.295 15.556 0l42.589 42.587c4.296 4.296 4.296 11.261 0 15.557a10.97 10.97 0 01-7.778 3.222c-2.815 0-5.63-1.074-7.778-3.222l-42.589-42.587zm63.481 288.753H23.338c-6.075 0-11 4.925-11 11s4.925 11 11 11h282.854c6.075 0 11-4.925 11-11s-4.924-11-10.999-11zM28.675 275.405a10.998 10.998 0 01-2.861-10.573l15.176-57.767a11.003 11.003 0 012.861-4.983l169.027-169.03c4.296-4.295 11.26-4.295 15.556 0l42.591 42.589a10.998 10.998 0 010 15.556L101.997 260.225a11 11 0 01-4.982 2.86l-57.766 15.18a10.996 10.996 0 01-10.574-2.86zM51.879 252.2l36.666-9.636L247.691 83.419l-27.034-27.032L61.512 215.534 51.879 252.2z' fill='%23fff'/%3E%3C/svg%3E%0A"); +$icon-edit-black: make-url-ready("%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 329.531 329.531'%3E%3Cpath d='M242.712 18.778c-4.296-4.296-4.296-11.261 0-15.557 4.296-4.295 11.26-4.295 15.556 0l42.589 42.587c4.296 4.296 4.296 11.261 0 15.557a10.97 10.97 0 01-7.778 3.222c-2.815 0-5.63-1.074-7.778-3.222l-42.589-42.587zm63.481 288.753H23.338c-6.075 0-11 4.925-11 11s4.925 11 11 11h282.854c6.075 0 11-4.925 11-11s-4.924-11-10.999-11zM28.675 275.405a10.998 10.998 0 01-2.861-10.573l15.176-57.767a11.003 11.003 0 012.861-4.983l169.027-169.03c4.296-4.295 11.26-4.295 15.556 0l42.591 42.589a10.998 10.998 0 010 15.556L101.997 260.225a11 11 0 01-4.982 2.86l-57.766 15.18a10.996 10.996 0 01-10.574-2.86zM51.879 252.2l36.666-9.636L247.691 83.419l-27.034-27.032L61.512 215.534 51.879 252.2z' fill='%23000'/%3E%3C/svg%3E%0A"); + +$icon-delete: make-url-ready("%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 407.521 407.521' fill='%23fff'%3E%3Cpath d='M335.94 114.944H71.581c-2.86-.243-5.694.702-7.837 2.612a8.8806 8.8806 0 00-2.612 7.837l27.167 236.669c3.186 26.093 25.436 45.647 51.722 45.453h131.657c27.026.385 49.791-20.104 52.245-47.02l22.465-236.147a8.882 8.882 0 00-2.612-6.792 10.4459 10.4459 0 00-7.836-2.612zM303.026 359.45c-1.642 15.909-15.366 27.803-31.347 27.167H140.022c-15.694.637-29.184-11.024-30.825-26.645l-26.122-224.13h241.371l-21.42 223.608zM374.079 47.026H266.454V30.307c.58-16.148-12.04-29.708-28.188-30.288a29.104 29.104 0 00-1.591-.014h-65.829c-16.156-.299-29.494 12.555-29.793 28.711-.01.53-.005 1.061.014 1.591v16.718H33.442c-5.771 0-10.449 4.678-10.449 10.449s4.678 10.449 10.449 10.449h340.637c5.771 0 10.449-4.678 10.449-10.449s-4.679-10.448-10.449-10.448zM245.556 30.307v16.718h-83.592V30.307c-.589-4.579 2.646-8.768 7.225-9.357a8.3343 8.3343 0 011.656-.047h65.829c4.605-.326 8.603 3.142 8.929 7.748.04.552.024 1.107-.047 1.656z'/%3E%3C/svg%3E%0A"); +$icon-delete-black: make-url-ready("%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 407.521 407.521'%3E%3Cpath d='M335.94 114.944H71.581c-2.86-.243-5.694.702-7.837 2.612a8.8806 8.8806 0 00-2.612 7.837l27.167 236.669c3.186 26.093 25.436 45.647 51.722 45.453h131.657c27.026.385 49.791-20.104 52.245-47.02l22.465-236.147a8.882 8.882 0 00-2.612-6.792 10.4459 10.4459 0 00-7.836-2.612zM303.026 359.45c-1.642 15.909-15.366 27.803-31.347 27.167H140.022c-15.694.637-29.184-11.024-30.825-26.645l-26.122-224.13h241.371l-21.42 223.608zM374.079 47.026H266.454V30.307c.58-16.148-12.04-29.708-28.188-30.288a29.104 29.104 0 00-1.591-.014h-65.829c-16.156-.299-29.494 12.555-29.793 28.711-.01.53-.005 1.061.014 1.591v16.718H33.442c-5.771 0-10.449 4.678-10.449 10.449s4.678 10.449 10.449 10.449h340.637c5.771 0 10.449-4.678 10.449-10.449s-4.679-10.448-10.449-10.448zM245.556 30.307v16.718h-83.592V30.307c-.589-4.579 2.646-8.768 7.225-9.357a8.3343 8.3343 0 011.656-.047h65.829c4.605-.326 8.603 3.142 8.929 7.748.04.552.024 1.107-.047 1.656z'/%3E%3C/svg%3E%0A"); + +$icon-save: make-url-ready("%3Csvg id='SVGDoc' width='18' height='18' xmlns='http://www.w3.org/2000/svg' version='1.1' xmlns:xlink='http://www.w3.org/1999/xlink' xmlns:avocode='https://avocode.com/' viewBox='0 0 18 18'%3E%3Cdefs%3E%3C/defs%3E%3Cg%3E%3Cg%3E%3Ctitle%3EGroup 1481%3C/title%3E%3Cg%3E%3Ctitle%3EPath 747%3C/title%3E%3C/g%3E%3Cg%3E%3Ctitle%3ELine 143%3C/title%3E%3Cpath d='M10,17l7,-7' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='round' stroke-linecap='round' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='1.5'%3E%3C/path%3E%3C/g%3E%3Cg%3E%3Ctitle%3EPath 748%3C/title%3E%3Cpath d='M10,17v0v-6c0,-0.55229 0.44772,-1 1,-1h6v0v-7c0,-1.10457 -0.89543,-2 -2,-2h-12c-1.10457,0 -2,0.89543 -2,2v12c0,1.10457 0.89543,2 2,2h7v0' fill-opacity='0' fill='%23ffffff' stroke-dashoffset='0' stroke-linejoin='round' stroke-linecap='round' stroke-opacity='1' stroke='%23ffffff' stroke-miterlimit='20' stroke-width='1.5'%3E%3C/path%3E%3C/g%3E%3C/g%3E%3C/g%3E%3C/svg%3E"); + +// Un-used icons. Keeping it here for placeholder, might be utilized later. +$icon-link: null; +$icon-resize: null; diff --git a/web/themes/custom/perls/resources/scss/annotator/annotator.scss b/web/themes/custom/perls/resources/scss/annotator/annotator.scss new file mode 100644 index 0000000..5a579bd --- /dev/null +++ b/web/themes/custom/perls/resources/scss/annotator/annotator.scss @@ -0,0 +1,9 @@ +// +// @File: AnnotatorJS custom theming. +@import "../settings.variables"; +@import "annotator.variables"; + +// Imports. +// ======== +@import "annotator.base"; +@import "annotator.style"; diff --git a/web/themes/custom/perls/resources/scss/annotator/annotator.touch.scss b/web/themes/custom/perls/resources/scss/annotator/annotator.touch.scss new file mode 100644 index 0000000..7ee450f --- /dev/null +++ b/web/themes/custom/perls/resources/scss/annotator/annotator.touch.scss @@ -0,0 +1,488 @@ +/* Annotator Touch Plugin - v1.1.1 + * Copyright 2012-2013, Compendio + * Released under the MIT license + * More Information: https://github.com/aron/annotator.touch.js + */ +@import "../settings.variables"; +@import "annotator.variables"; + +// stylelint-disable +.annotator-viewer .annotator-touch-controls { + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAtCAYAAABxsjF3AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NDA0RjExNjU0MUU3MTFFMUFGNzA4RDM2MDNEMkIyQjkiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NDA0RjExNjY0MUU3MTFFMUFGNzA4RDM2MDNEMkIyQjkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo0MDRGMTE2MzQxRTcxMUUxQUY3MDhEMzYwM0QyQjJCOSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo0MDRGMTE2NDQxRTcxMUUxQUY3MDhEMzYwM0QyQjJCOSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pl46a1UAAAVTSURBVHjajJZ7TFtVHMdvHzxKWzo2xqNAeMO6AQNKBKUoZbiUIBhCIuHxh/+4xQwk4HuRGIkJQgmSqfyBqCDMmQjZ4rQR8I+6CMgfAgIiE5oMVt4vESiFUur33Nw2t6XF3eTXc8/p+Zzze5zf71wORVFnIHKIF3X6swsZhwghjyEWqra29tre3t6i5X8es9n8sK2t7XpPT88nAQEBFwFzOVtbWzpPT08K0uJiR8vBwQE1Ojo6IJPJPpRIJNmDg4N3sOnr1PHxsXlubq7zFHUFKpXqSk1Nzcurq6s3Mf+IaLKzs6OkoM4B4C4XoFd5eXnO2tpa/8bGxpRarX7NYDC8AVYNEdPw/Pz8bWdgdXX1C4uLi/d0Ot33u7u7K/v7+7qJiYkQ/HcBInIFS6qqqlQLCwv3Z2Zm7q6vr08zflOXlZVdHhoa+nZycvKyM/hMU1NTiV6v/w47aqDyNOw0AKwlf05PT79HVhkeHo7hO+wobmxsfLG4uPil7e1tU2Bg4CVvb++go6Ojt/l8/sdkAofD4dEhwMNlk3V1dVeLiopuwJMeABPFYvF5DBOwFdCxo1P4zGoWNLzCwsJXgoKC5DDFyOVyzVD3BsCv2ADGLWyYQ2JdUVFxNiwsLAULcXk83h7at/DfbWjHYRanHyxse+eSybDPKzw8XA51H+AkVSJEKoxrIcGQMMwLt8rS0tI5AsIsM8dkMg0fHh6GjIyMaHEA9tE3wUFmqMsDaGcjUSE9PT1TKBRCOZ6ceE0GmbA8+TMKUdKL4cW2cmpqKvFBDORpyFPERMhvkCGIDrG187gNBiiCKpXoV8KB5x08vIBGjfFWLLBvBwMUw8bPYWuRs+wg4QHIIfHGnEosYKTHAXKRy2+6AlNSUtZzcnJI5aAw55q7u/t126LoRCJ21c7AxMTEDRzXVqVS2Z6fn/+Y0aIGG0rpd8QrF9EROgObm5u/FAgE76N7B5lkIuNGo/FccHDw8/QJc3Nzy3AEExISNhnwJnZxw25fwOYIW6J7eWWi6eAia3zYYFxc3BZSsp0F9gJ8xi7ZJRL6lHFDQ0MX2V6tr6/vQjZZwfsAT2gWERGhp+ejIj7w8PAgh4GKjIzc9vX1fZdEAM89gFccQSx8CLO01lD9jOr4iHRQo4zod+P1H4BXnUUgNzf3b5zvX2gYBXyutLT0VnJy8gZKTwDGVBB3Z6BCoVhBlWmEP1bZx1OMVPugvb29sLe3VwoN7MqTSCQy5eXl6UtKSjr9/PzqSMQcE0OMGJbMzs4Wj42NBUxNTYlhNxUfH/8vYq6HPzpxPIlJhhOJwTykuAVDLkFkTFZNMbJAX27srHIwi0MXc4ryYW5PMnmLEQMbJpuybeNLpdKogoICRVZWVkJsbGwMPH4M9R/29/ePdXd3/4py9YjRxr6KyuVyhVar7YDdm46lA1fwqkajacXpSyERsu5Mq5qdnZ2Ea0Xrqu6Q6kra8fFxDTa5YIOhnnhgYODrU8C7KIy3rP2+vr5PwXrScEtLSwaq544L8Ec07rheL+Ji+4aMYaG1hoaGRAJzk5KSMpCWohOfAxaLBpW2AGLOzMyU+vv7J9E3vUDgm5aWpqAn4WLvcLLjT2RHEnccDuXKysqf7P9xe35Gq41PhTYHsB+NgIBRUVHPLS8vn6jpGGum4c3NzVcdvCohYHR09LO43Eed+QJMKQ3jS0eGArjHDP5BSjhqVAEy7HdnICroGpoQGsYPHwXwI/IHvgL+IhAWM7kKHea+Q25OW07gxQcr/vAEH3JdaITsE2Zd4CykDnZvO/H+OsAavHqzE4PjENtTLzr2pwWB/xNgAIkda0u78FfgAAAAAElFTkSuQmCC'); +} + +.annotator-selection-handle::after { + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAoCAYAAAD+MdrbAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MENGMkFGNTMzRTZBMTFFMUJCQThENjQ1NDg5Q0U3NUYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MENGMkFGNTQzRTZBMTFFMUJCQThENjQ1NDg5Q0U3NUYiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpGRERCNTk2ODNFNEQxMUUxQkJBOEQ2NDU0ODlDRTc1RiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDowQ0YyQUY1MjNFNkExMUUxQkJBOEQ2NDU0ODlDRTc1RiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pqv8zQEAAAWBSURBVHjapFdrTFRHFP727i4ioMCCyEOsWbHQihigEVqJL6jV2gcl1OCrtjXVmpAYQ5P6o+mfpi2JScMf0tAftCHRhMjDpg9tAmooTTSBoqC7i2BAXgZ2QXbZXfZx796ec9lVweVVJzk7c+/OfPPNOXO+mauSZRkvUlQq1axnYZHOmt7e3m9HR0dv2Gy2nsHBwYv0btWCMzDDYEYlksD+kOeUgYGBm/Tfmmf6LQ2wvr7+KwbweEW5vLJVLvumWTZbbAqoyWS6yhMGAxTmWeqG/Pz8E9yuqeuCaSQJj71pqPjZAK8oITU19a3KyspjwcYKQcAiOjo6foiMjNxw1/QI1/4NgaCNg0qtw8BEAhqvmJR+hYWFH1Pf+EUBz5w583p6evpehd3lIQgh8RChhVdWQ9bo8NvfHkxanUhMTMxuaGgoXRCQZtSVlpae02g04ddaH6DPHANJFU7LhGKSHAKPKgEXLt9X+m/fvv09qtbNC1hRUVGSkpKyh/104cokZG0svJJABr+pIAmr0dSuwdCjScTFxW1paWn5moZqnwMkdnFFRUUfcfvS790wT62B6At9wi5goqSFpF6Ln2ofKOMyMjLepGrDc4C1tbWnk5OTc6xTLtRfd0OkIDCjp+yemiSswi1TOO4YHoGD197e/j1BhD8BJHZJeXl573L7l/puWL1rIZK/goHNmBo+TRyqLg0rZDIzMz8oLy8veAKYk5OzlaNmd7jx502RGETNyy5goioM9waj0XDVxISE3NzcQoJaLdDDipKSkkwG7uoeg8OzmnynIV9hESOWFKB/OqwKSwrmZqriNfQTHRsbqyS8bcoNn4/Uw7dEpfH5oPZHQZIkChliGFBDG9R49OhRbElbA614C9N2B3dfHFAcx4f7Nintnp6ee4zL7Qiyt4eHh9vk/1msVuvDsLCwdwhnY0CC8ouLiz9hUFEUnUsF8vl8Emll58mTJ08xKV6tigH9SZ6FFysGsn5VQNP8oC+xY5cJxGHuJ1M2pSqYSBJ46DIAXUEVmzclyXstnR0PlhOQiYmJO62trQdnAbKcG43Gv+QXKDU1NZ8zEO9DJCUlZaWlpe1l2fryuxsYd+ho2epF1yp6pnAgbyUOFWVxpuygV/Ua8pf2/PnzudzhrnEE485ErIzUkyOFxQG9Ntwf6FXaer1+cyBToiMiIkL4pdsjQfIJlKeqpSQKJNGHiHBlkXA6nRztGKahrqqq4j2E9LR4rNRa4fG4FlQaxUQZbpcdm1Nmzn06Wjn1PAw4cfv2bUdfX19LRHgoDu2PxbTTohyXc9X6WfN4XQhVW7D7Db0CWFdX10HVuEABclPDXlZWVk1p59iTp8f62HF43M4FGPrgco7jyIEYrFihAZOprq4eIhxzwPOGxsZGc2dnJ98IcPz9dXA5xuZl6XE5kRDJ7GaOEiZD1RSb4N+LFk6f7OzsalKO/oxXE5C1yUEsp4Kwk+CeNuPTokQIggCDwXCVydB449xj9CH/tLW1NXH92cGN8EyPEiPvbEC3HVs32vBaRhLsdvvQzp07f/Tns2UWILFkVe0uKChoHBsb60pOjMK+bSKxtBGQ7I8sgbtGcergTCDotGuyWCys1F3zXUWYpbe5uVnx5Ynil6GWhmkDu2l/Eqj7MfZv80K/XgeedNeuXZeoG+9sW1BAYsmzGQ8fPnxjZGSkPToqDOeO6yA6H0J0mZG0aginj7yi9PVPKvmla+H7IZXdrOBut3uSE//ir3flY180yb39FkUI6CJ63a/Q65Z04eTjkAecPXu2dK6qsORHRUXxJWnHsm6wVFIDoHRfbCDnd3PtZ8amCyrOC30FkBJlBFkWD7hD40aCfQWoFvusoAHRLJnMiPOeg0Bj7PN9VvwnwAD1CUyXisQtngAAAABJRU5ErkJggg=='); +} + +/* Generic Touch Widget Styles */ +.annotator-touch-widget .annotator-button { + cursor: pointer; + font-size: 16px; + line-height: 44px; + padding-left: 40px; + padding-right: 20px; + -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.1); + -ms-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.1); + -o-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 0 rgba(0, 0, 0, 0.1); + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; +} + +.annotator-touch-widget .annotator-button[disabled] { + opacity: 0.3; + cursor: default; +} + +/* Adder Styles */ +.annotator-touch-controls { + position: fixed; + bottom: 100px; + right: 0px; + min-width: auto; +} + +.annotator-touch-controls.annotator-touch-hide { + right: -9999em; + opacity: 0; + -webkit-transition: opacity 0.2s 0 ease-in, right 0s 0.3s linear; + -moz-transition: opacity 0.2s 0 ease-in, right 0s 0.3s linear; + -ms-transition: opacity 0.2s 0 ease-in, right 0s 0.3s linear; + -o-transition: opacity 0.2s 0 ease-in, right 0s 0.3s linear; + transition: opacity 0.2s 0 ease-in, right 0s 0.3s linear; +} + +.annotator-touch-controls .annotator-button { + line-height: 56px; +} + +/* Viewer Overrides*/ + +.annotator-touch-viewer .annotator-widget { + min-width: 380px; +} + +.annotator-touch-viewer div { + padding: 12px; +} + +.annotator-touch-viewer div:first-of-type { + font-size: 18px; + padding-top: 20px; + padding-bottom: 20px; +} + +.annotator-touch-viewer .annotator-touch-controls { + position: absolute; + top: 0; + left: auto; + right: 0; + display: none; + background: rgba(255, 255, 255, 0.6); + background: -webkit-gradient(linear, right top, left top, from(rgba(255, 255, 255, 0.8)), color-stop(0.9, rgba(255, 255, 255, 0.8)), to(rgba(255, 255, 255, 0))); + background: -moz-linear-gradient(0deg, from(rgba(255, 255, 255, 0.8)) 90%, to(rgba(255, 255, 255, 0))); + background: -webkit-linear-gradient(0deg, from(rgba(255, 255, 255, 0.8)) 90%, to(rgba(255, 255, 255, 0))); + background: linear-gradient(to bottom, from(rgba(255, 255, 255, 0.8)) 90%, to(rgba(255, 255, 255, 0))); + -webkit-box-pack: end; + -webkit-box-align: center; + -webkit-box-orient: horizontal; + -moz-box-pack: end; + -moz-box-align: center; + -moz-box-orient: horizontal; + box-pack: end; + box-align: center; + box-orient: horizontal; + padding: 10px; + bottom: 0; + padding: 0 10px 0 20px; +} + +.annotator-touch-viewer li.annotator-visible .annotator-touch-controls { + display: flex; +} + +.annotator-touch-viewer .annotator-touch-controls button { + line-height: 44px; + padding-left: 40px; + padding-right: 20px; + margin: 5px; +} + +.annotator-touch-viewer .annotator-touch-controls .annotator-edit::after { + background-position: 0 -15px; +} + +.annotator-touch-viewer .annotator-touch-controls .annotator-edit:hover::after, +.annotator-touch-viewer .annotator-touch-controls .annotator-edit:focus::after, +.annotator-touch-viewer .annotator-touch-controls .annotator-edit:active::after, +.annotator-touch-viewer .annotator-touch-controls .annotator-edit.annotator-focus::after { + background-position: 0 -30px; +} + +.annotator-touch-viewer .annotator-touch-controls button::after { + left: 15px; +} + +/* Editor Overrides */ + +.annotator-touch-editor { + position: fixed; + top: -1000px !important; + left: 0 !important; + right: 0; + bottom: -1000px; + padding: 1000px 0; + width: 100%; + height: 100%; + background: rgba(255, 255, 255, 0.6); + display: flex; + -webkit-box-pack: center; + -webkit-box-align: center; + -moz-box-pack: center; + -moz-box-align: center; + box-pack: center; + box-align: center; +} + +.annotator-touch-editor .annotator-touch-widget { + pointer-events: all; + position: relative; + width: 80%; + max-width: 680px; + margin: auto; +} + +.annotator-touch-editor .annotator-touch-widget-inner { + position: static; + width: auto; + padding: 0; + background: $color-white; +} + +.annotator-touch-editor .annotator-widget::after { + display: none; +} + +.annotator-touch-editor .annotator-widget .annotator-item { + border-top-color: rgba(0, 0, 0, 0.15); +} + +.annotator-touch-editor .annotator-widget .annotator-item, +.annotator-touch-editor.annotator-editor .annotator-item label, +.annotator-touch-editor.annotator-editor .annotator-item input, +.annotator-touch-editor.annotator-editor .annotator-item textarea { + font-size: 18px; +} + +.annotator-touch-editor.annotator-editor .annotator-item input, +.annotator-touch-editor.annotator-editor .annotator-item label { + line-height: 30px; + margin-left: 8px; +} + +.annotator-touch-editor.annotator-editor .annotator-item input[checkbox] { + font-size: large; +} + +.annotator-touch-editor .annotator-widget .annotator-item:first-child textarea { + font-size: 18px; + background-color: $color-white; + -webkit-border-radius: 3px 3px 0 0; + -moz-border-radius: 3px 3px 0 0; + -o-border-radius: 3px 3px 0 0; + border-radius: 3px 3px 0 0; +} + +.annotator-touch-editor .annotator-resize { + display: none; +} + +.annotator-touch-editor .annotator-controls { + padding: 7px; + background-color: $color-white; + background-image: none; + box-shadow: 0 6px 6px rgba(0, 0, 0, 0.16); +} + +.annotator-touch-editor .annotator-item-quote { + font-size: 16px; + line-height: 1.2; + background-color: $color-stripe; + color: #a58129; + padding: 10px 7px; +} + +.annotator-item-quote span { + display: block; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + font-family: "Open Sans, sans-serif"; + font-style: italic; + font-size: 14px; +} + +.annotator-item-quote.annotator-touch-expand span { + overflow: visible; + text-overflow: inherit; + white-space: inherit; +} + +.annotator-item-quote button { + font-size: 14px; + line-height: 44px; + margin-top: -13px; + float: right; + text-transform: uppercase; + font-weight: bold; + color: #a58129; + border: none; + background: none; + margin-left: 10px; + cursor: pointer; +} + +.annotator-button::after { + background-repeat: no-repeat; +} + +.annotator-button { + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + position: relative; + display: inline-block; + padding: 0 6px 0 22px; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.75); + text-decoration: none; + line-height: 24px; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + -o-border-radius: 5px; + border-radius: 5px; + color: $color-white; + background-color: $color-primary; + background-image: url($icon-save); + background-repeat: no-repeat; + background-position: left 12px center; + background-size: 18px 18px; + border: none; + box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16); + font-family: $font-family-base; + font-size: 18px; + font-weight: 400; +} + +.annotator-button::after { + position: absolute; + top: 50%; + left: 5px; + display: none; + content: ""; + width: 15px; + height: 15px; + margin-top: -7px; + background-position: 0 -90px; + background-image: none; +} + +.annotator-button:hover::after, +.annotator-button:focus::after { + margin-top: -8px; + background-position: 0 -105px; +} + +.annotator-button:active, +.annotator-button:hover { + background-color: $color-primary-dark; + color: $color-white; +} + +.annotator-button.annotator-save::after { + background-position: 0 -120px; +} + +.annotator-button.annotator-save::after, +.annotator-button.annotator-save:focus::after, +.annotator-button.annotator-save.annotator-focus::after { + margin-top: -8px; + background-position: 0 -135px; +} + +.annotator-touch-editor .annotator-button { + color: $color-white; + text-shadow: none; + + &.annotator-focus { + color: $color-white; + } +} + +/* Icon only button styles */ + +[data-annotator-use-icons] .annotator-touch-widget .annotator-button { + /* width & overflow is required by Android WebKit */ + width: 1px; + overflow: hidden; + text-indent: -999em; + padding-left: 25px; +} + +[data-annotator-use-icons] .annotator-touch-controls .annotator-button { + padding-left: 35px; +} + +[data-annotator-use-icons] .annotator-touch-controls .annotator-button::after { + left: 20px; +} + +[data-annotator-use-icons] .annotator-touch-viewer .annotator-touch-controls button { + padding-left: 25px; + text-indent: -9000em; +} + +[data-annotator-use-icons] .annotator-touch-viewer .annotator-touch-controls button::after { + left: 15px; +} + +[data-annotator-use-icons] .annotator-touch-viewer .annotator-widget { + min-width: 320px; +} + +/* Highlighter Selection Styles */ + +.annotator-selection-handle { + cursor: pointer; + display: block; + position: absolute; + width: 44px; + height: 44px; + top: 0; + left: 0; + padding: 0; + margin-left: -22px; + margin-top: -22px; + border-radius: 50%; + /* Removes the tap outline on elements that have bound touch events */ + -webkit-tap-highlight-color: transparent; +} + +.annotator-selection-handle::after { + content: ""; + display: block; + width: 20px; + height: 20px; + position: absolute; + left: 50%; + margin-left: -10px; + bottom: -5px; + background-position: 0 0; + background-repeat: no-repeat; +} + +.annotator-selection-start::after { + top: -5px; + bottom: auto; + background-position: 0 -20px; +} + +.annotator-selection-hide .annotator-selection-handle { + display: none; +} + +/* Styles for smaller screens */ + +@media only screen and (max-width: 480px) { + .annotator-touch-viewer { + left: 0 !important; + width: 100%; + background: none; + min-width: 0; + border: none; + } + + .annotator-touch-viewer .annotator-widget { + position: static; + left: 0; + width: 100%; + height: auto; + min-width: 0; + box-sizing: border-box; + -webkit-box-sizing: border-box; + -webkit-border-radius: none; + border-radius: none; + } + + .annotator-touch-viewer .annotator-widget::after { + display: none; + } + + .annotator-touch-editor { + border: none; + -webkit-box-align: start; + -moz-box-align: start; + box-align: start; + } + + .annotator-touch-editor .annotator-touch-widget { + width: 100%; + max-width: auto; + margin: 0; + border-color: #333; + border-left: none; + border-right: none; + -webkit-box-shadow: none; + -moz-box-shadow: none; + -ms-box-shadow: none; + -o-box-shadow: none; + box-shadow: none; + } + + .annotator-touch-editor .annotator-touch-widget-inner { + width: 100%; + max-width: auto; + margin: 0; + border: 0; + } + + .annotator-touch-editor .annotator-controls { + border-bottom: 1px solid #d4d4d4; + } + + .annotator-touch-editor .annotator-touch-widget, + .annotator-touch-editor .annotator-touch-widget-inner, + .annotator-touch-editor .annotator-touch-widget .annotator-item:first-child textarea, + .annotator-touch-editor .annotator-controls { + border-radius: 0; + } + + .annotator-cancel.annotator-button { + display: none; + } + + .annotator-touch-widget .annotator-listing { + display: flex; + flex-direction: column; + .annotator-item.annotator-item-quote { + order: 1; + } + .annotator-item { + order: 2; + } + } + + .annotator-button.annotator-delete { + background-image: url($icon-delete); + } + + .annotator-button.annotator-add { + background-image: url($icon-edit); + } + + .annotator-editor a.annotator-save.annotator-focus.annotator-button { + color: $color-white; + } +} diff --git a/web/themes/custom/perls/resources/scss/main.scss b/web/themes/custom/perls/resources/scss/main.scss new file mode 100644 index 0000000..c9de50f --- /dev/null +++ b/web/themes/custom/perls/resources/scss/main.scss @@ -0,0 +1,178 @@ +/** + * CONTENTS + * + * SETTINGS + * Variables............Globally-available variables and config. + * + * TOOLS + * Mixins...............Useful mixins. + * Include Media........Sass library for writing CSS media queries. + * Media Query Test.....Displays the current breakport you're in. + * + * GENERIC + * Reset................A level playing field. + * + * BASE + * Forms................Common and default form styles. + * Headings.............H1 - H6 styles. + * Links................Link styles. + * Lists................Default list styles. + * Main.................Page body defaults. + * Media................Image and video styles. + * Tables...............Default table styles. + * Text.................Default text styles. + * + * LAYOUT + * Grids................Grid/column classes. + * Wrappers.............Wrapping/constraining elements. + * + * COMPONENTS + * Blocks...............Modular components often consisting of text and media. + * Cards................Modular components for mainly text and data (card-like). + * Fields...............Drupal field elements. + * Buttons..............Various button styles and styles. + * Icons................Icon styles and settings. + * Lists................Various site list styles. + * Navs.................Site navigations. + * Views................Drupal view elements. + * Forms................Specific form styling. + * Tables...............Specific table styling. + * Messaging............Styles for prompts, banners, and messages. + * Media................Specific media objects, e.g. figures + * + * TEXT + * Text.................Various text-specific class definitions. + * + * PAGE STRUCTURE + * Article..............Post-type pages with styled text. + * Footer...............The main page footer. + * Header...............The main page header. + * + * MODIFIERS + * Colors...............Text and background colors. + * Spacings.............Padding and margins in classes. + * + * THEME + * PERLS CMS.............Styles for CMS theme. + * PERLS Learner.........Styles for Learner theme. + * User..................Styles for user pages. + * + * TRUMPS + * Helper Classes.......Helper classes loaded last in the cascade. + */ + +/* ------------------------------------ *\ + $SETTINGS +\* ------------------------------------ */ +@import "settings.variables"; + +/* ------------------------------------ *\ + $TOOLS +\* ------------------------------------ */ +@import "tools.functions"; +@import "tools.include-media"; +@import "tools.mixins"; + +$tests: false; + +@import "tools.mq-tests"; + +/* ------------------------------------*\ + $GENERIC +\* ------------------------------------ */ +@import "generic.reset"; + +/* ------------------------------------ *\ + $BASE +\* ------------------------------------ */ +@import "base.fonts"; +@import "base.headings"; +@import "base.forms"; +@import "base.links"; +@import "base.lists"; +@import "base.main"; +@import "base.media"; +@import "base.tables"; +@import "base.text"; + +/* ------------------------------------ *\ + $LAYOUT +\* ------------------------------------ */ +@import "layout.grids"; +@import "layout.wrappers"; + +/* ------------------------------------ *\ + $TEXT +\* ------------------------------------ */ +@import "objects.text"; + +/* ------------------------------------ *\ + $COMPONENTS +\* ------------------------------------ */ +@import "objects.buttons"; +@import "objects.blocks"; +@import "objects.stack"; +@import "objects.autosave"; +@import "objects.cards"; +@import "objects.chip"; +@import "objects.color-palette"; +@import "objects.fields"; +@import "objects.file"; +@import "objects.icons"; +@import "objects.lists"; +@import "objects.navs"; +@import "objects.notifications"; +@import "objects.prompt"; +@import "objects.views"; +@import "objects.forms"; +@import "objects.formtips"; +@import "objects.tables"; +@import "objects.tabs"; +@import "objects.messaging"; +@import "objects.media"; +@import "objects.dialog"; +@import "objects.entity-browser"; +@import "objects.ajax"; +@import "objects.system-status"; +@import "objects.logo"; +@import "objects.comments"; +@import "objects.charts"; +@import "objects.vidyo"; + +/* ------------------------------------ *\ + $PAGE STRUCTURE +\* ------------------------------------ */ +@import "module.header"; +@import "module.footer"; +@import "module.article"; +@import "module.sidebar"; +@import "module.ckeditor"; + +/* ------------------------------------ *\ + $VENDOR +\* ------------------------------------ */ +@import "vendor.slick"; + +/* ------------------------------------ *\ + $THEME +\* ------------------------------------ */ +@import "theme.perls-learner"; +@import "theme.perls-cms"; +@import "theme.user"; +@import "theme.maintenance"; + +/* ------------------------------------ *\ + $MODIFIERS +\* ------------------------------------ */ +@import "modifier.colors"; +@import "modifier.spacing"; + +/* ------------------------------------ *\ + $TRUMPS +\* ------------------------------------ */ +@import "trumps.helper-classes"; + +/* ------------------------------------ *\ + $ENTITY BROWSWER - IMAGE BROWSER +\* ------------------------------------ */ +@import "entity-browser.image-browser"; diff --git a/web/themes/custom/perls/templates/admin/color-scheme-form.html.twig b/web/themes/custom/perls/templates/admin/color-scheme-form.html.twig new file mode 100644 index 0000000..9f9335f --- /dev/null +++ b/web/themes/custom/perls/templates/admin/color-scheme-form.html.twig @@ -0,0 +1,33 @@ +{# +/** + * @file + * Theme override for a theme's color form. + * + * Available variables: + * - form: Form elements for the color scheme form, including: + * - scheme: A color scheme form element. For example: a select element with + * color theme presets, or a color picker widget. + * - palette: Color fields that can be changed by entering in a new hex value. + * - html_preview: A HTML preview of the theme's current color scheme. + * + * @see template_preprocess_color_scheme_form() + */ +#} +
    + {{ form.scheme }} +
    + + {% for element in form.palette %} + {% if element['#type'] == 'textfield' %} +
    + {{ element }} +
    + {% endif %} + {% endfor %} + +
    + {{ form|without('scheme', 'palette') }} + +
    +

    {{ 'Preview'|t }}

    +{{ html_preview }} diff --git a/web/themes/custom/perls/templates/admin/status-report-general-info.html.twig b/web/themes/custom/perls/templates/admin/status-report-general-info.html.twig new file mode 100644 index 0000000..b01f01e --- /dev/null +++ b/web/themes/custom/perls/templates/admin/status-report-general-info.html.twig @@ -0,0 +1,122 @@ +{# +/** + * @file + * Theme override for the status report general info. + * + * Available variables: + * - drupal: The status of Drupal installation: + * - value: The current status of Drupal installation. + * - description: The description for current status of Drupal installation. + * - cron: The status of cron: + * - value: The current status of cron. + * - description: The description for current status of cron. + * - cron.run_cron: An array to render a button for running cron. + * - database_system: The status of database system: + * - value: The current status of database sytem. + * - description: The description for current status of cron. + * - database_system_version: The info about current database version: + * - value: The current version of database. + * - description: The description for current version of database. + * - php: The current version of PHP: + * - value: The status of currently installed PHP version. + * - description: The description for current installed PHP version. + * - php_memory_limit: The info about current PHP memory limit: + * - value: The status of currently set PHP memory limit. + * - description: The description for currently set PHP memory limit. + * - webserver: The info about currently installed web server: + * - value: The status of currently installed web server. + * - description: The description for the status of currently installed web + * server. + */ +#} + +
    +
    +

    {{ 'General System Information'|t }}

    +
    +
    +
    +

    {{ 'Version'|t }}

    +

    {{ 'App'|t }}

    {{ drupal.deployment_identifier }} +

    {{ 'Drupal'|t }}

    {{ drupal.value }} + + {% if drupal.description %} + {{ drupal.description }} + {% endif %} +
    +
    +

    {{ 'Last Cron Run'|t }}

    + {{ cron.value }} + {% if cron.run_cron %} + {{ cron.run_cron }} + {% endif %} + {% if cron.description %} + {{ cron.description }} + {% endif %} +
    +
    +

    {{ 'Cache'|t }}

    + +
    +
    +

    {{ 'Web Server'|t }}

    + {{ webserver.value }} + {% if webserver.description %} + {{ webserver.description }} + {% endif %} +
    +
    +

    {{ 'PHP'|t }}

    +

    {{ 'Version'|t }}

    {{ php.value }} + {% if php.description %} + {{ php.description }} + {% endif %} + +

    {{ 'Memory limit'|t }}

    {{ php_memory_limit.value }} + {% if php_memory_limit.description %} + {{ php_memory_limit.description }} + {% endif %} +
    +
    +

    {{ 'Database'|t }}

    +

    {{ 'Version'|t }}

    {{ database_system_version.value }} + {% if database_system_version.description %} + {{ database_system_version.description }} + {% endif %} + +

    {{ 'System'|t }}

    {{ database_system.value }} + {% if database_system.description %} + {{ database_system.description }} + {% endif %} +
    +
    +

    {{ 'Users'|t }}

    + +
    +
    +
    {{ 'Logged in within past 14 days: '|t }}
    +
    {{ users_logged_in_past_two_weeks }}
    +
    +
    +
    {{ 'Total number of Learners in the system: '|t }}
    +
    {{ number_of_learners }}
    +
    +
    +
    {{ 'Total number of Content Managers in the system: '|t }}
    +
    {{ number_of_content_managers }}
    +
    +
    +
    {{ 'Total number of Administrators in the system: '|t }}
    +
    {{ number_of_administrators }}
    +
    +
    +
    {{ 'Total number of All Users in the system: '|t }}
    +
    {{ number_of_all_users }}
    +
    +
    + +
    +
    +
    diff --git a/web/themes/custom/perls/templates/admin/status-report-grouped.html.twig b/web/themes/custom/perls/templates/admin/status-report-grouped.html.twig new file mode 100644 index 0000000..7f8b51f --- /dev/null +++ b/web/themes/custom/perls/templates/admin/status-report-grouped.html.twig @@ -0,0 +1,53 @@ +{# +/** + * @file + * Theme override of grouped status report requirements. + * + * - grouped_requirements: Contains grouped requirements. + * Each group contains: + * - title: The title of the group. + * - type: The severity of the group. + * - items: The requirement instances. + * Each requirement item contains: + * - title: The title of the requirement. + * - value: (optional) The requirement's status. + * - description: (optional) The requirement's description. + * - severity_title: The title of the severity. + * - severity_status: Indicates the severity status. + */ +#} +{{ attach_library('core/drupal.collapse') }} +
    +
    + {% for group in grouped_requirements %} +
    +
    +

    {{ group.title }}

    +
    + {% for requirement in group.items %} +
    + {% + set summary_classes = [ + 'system-status-report__status-title', + group.type in ['warning', 'error'] ? 'system-status-report__status-icon system-status-report__status-icon--' ~ group.type + ] + %} + + {% if requirement.severity_title %} + {{ requirement.severity_title }} + {% endif %} + {{ requirement.title }} + +
    + {{ requirement.value }} + {% if requirement.description %} +
    {{ requirement.description }}
    + {% endif %} +
    +
    + {% endfor %} +
    + {% endfor %} +
    +
    + diff --git a/web/themes/custom/perls/templates/audio/audioplayer.html.twig b/web/themes/custom/perls/templates/audio/audioplayer.html.twig new file mode 100644 index 0000000..2fa1f20 --- /dev/null +++ b/web/themes/custom/perls/templates/audio/audioplayer.html.twig @@ -0,0 +1,24 @@ +{# +/** + * @file + * Default implementation for Audiofield audio players. + * + * Available variables: + * - plugin_id: the name of the plugin being used for templating. + * - plugin_theme: the name of the specific plugin theme, if it exists. + * - files: array of render info for each file. + * - settings: array of settings for thie player. + * + * @ingroup themeable + */ +#} +
    + {% for file in files %} +
    + +
    + {% endfor %} +
    diff --git a/web/themes/custom/perls/templates/blocks/block--content-manager-user-menu.html.twig b/web/themes/custom/perls/templates/blocks/block--content-manager-user-menu.html.twig new file mode 100644 index 0000000..c912154 --- /dev/null +++ b/web/themes/custom/perls/templates/blocks/block--content-manager-user-menu.html.twig @@ -0,0 +1 @@ +{% extends "block--user-menu.html.twig" %} diff --git a/web/themes/custom/perls/templates/blocks/block--content-specific-feedback.html.twig b/web/themes/custom/perls/templates/blocks/block--content-specific-feedback.html.twig new file mode 100644 index 0000000..9762c74 --- /dev/null +++ b/web/themes/custom/perls/templates/blocks/block--content-specific-feedback.html.twig @@ -0,0 +1,56 @@ +{# +/** + * @file + * Theme override to display a block. + * + * Available variables: + * - plugin_id: The ID of the block implementation. + * - label: The configured label of the block if visible. + * - configuration: A list of the block's configuration values. + * - label: The configured label for the block. + * - label_display: The display settings for the label. + * - provider: The module or other provider that provided this block plugin. + * - Block plugin specific settings will also be stored here. + * - content: The content of this block. + * - attributes: array of HTML attributes populated by modules, intended to + * be added to the main container tag of this template. + * - id: A valid HTML ID and guaranteed unique. + * - title_attributes: Same as attributes, except applied to the main title + * tag that appears in the template. + * - title_prefix: Additional output populated by modules, intended to be + * displayed in front of the main title tag that appears in the template. + * - title_suffix: Additional output populated by modules, intended to be + * displayed after the main title tag that appears in the template. + * + * @see template_preprocess_block() + */ +#} +{% if block_content_bundle %} + {% + set block_bundle = 'c-block-' ~ configuration.provider|clean_class ~ '-' ~ block_content_bundle|clean_class + %} +{% endif %} + +{% + set classes = [ + 'c-block', + 'c-block-' ~ configuration.provider|clean_class, + block_bundle, + 'c-block-' ~ plugin_id|clean_class, + 'c-block--content-specific-feedback' + ] +%} + + + {{ title_prefix }} + + {% if label %} + {{ label }} + {% endif %} + + {{ title_suffix }} + + {% block content %} + {{ content }} + {% endblock %} + diff --git a/web/themes/custom/perls/templates/blocks/block--learner-user-menu.html.twig b/web/themes/custom/perls/templates/blocks/block--learner-user-menu.html.twig new file mode 100644 index 0000000..c912154 --- /dev/null +++ b/web/themes/custom/perls/templates/blocks/block--learner-user-menu.html.twig @@ -0,0 +1 @@ +{% extends "block--user-menu.html.twig" %} diff --git a/web/themes/custom/perls/templates/blocks/block--local-tasks-block.html.twig b/web/themes/custom/perls/templates/blocks/block--local-tasks-block.html.twig new file mode 100644 index 0000000..e71f2e6 --- /dev/null +++ b/web/themes/custom/perls/templates/blocks/block--local-tasks-block.html.twig @@ -0,0 +1,3 @@ +
    + {{ content }} +
    \ No newline at end of file diff --git a/web/themes/custom/perls/templates/blocks/block--page-title-block.html.twig b/web/themes/custom/perls/templates/blocks/block--page-title-block.html.twig new file mode 100644 index 0000000..7120614 --- /dev/null +++ b/web/themes/custom/perls/templates/blocks/block--page-title-block.html.twig @@ -0,0 +1,3 @@ +
    +

    {{ elements.content['#title'] }}

    +
    \ No newline at end of file diff --git a/web/themes/custom/perls/templates/blocks/block--perls-views-search-block.html.twig b/web/themes/custom/perls/templates/blocks/block--perls-views-search-block.html.twig new file mode 100644 index 0000000..3c632f2 --- /dev/null +++ b/web/themes/custom/perls/templates/blocks/block--perls-views-search-block.html.twig @@ -0,0 +1,11 @@ +
    +
    + {{ content }} +
    + + +
    diff --git a/web/themes/custom/perls/templates/blocks/block--system-branding-block.html.twig b/web/themes/custom/perls/templates/blocks/block--system-branding-block.html.twig new file mode 100644 index 0000000..a070bc9 --- /dev/null +++ b/web/themes/custom/perls/templates/blocks/block--system-branding-block.html.twig @@ -0,0 +1,26 @@ +{# +/** + * @file + * Theme override for a branding block. + * + * Each branding element variable (logo, name, slogan) is only available if + * enabled in the block configuration. + * + * Available variables: + * - site_logo: Logo for site as defined in Appearance or theme settings. + * - site_name: Name for site as defined in Site information settings. + * - site_slogan: Slogan for site as defined in Site information settings. + */ +#} + + diff --git a/web/themes/custom/perls/templates/blocks/block--system-menu-block.html.twig b/web/themes/custom/perls/templates/blocks/block--system-menu-block.html.twig new file mode 100644 index 0000000..c0a32ce --- /dev/null +++ b/web/themes/custom/perls/templates/blocks/block--system-menu-block.html.twig @@ -0,0 +1,55 @@ +{# +/** + * @file + * Theme override for a menu block. + * + * Available variables: + * - plugin_id: The ID of the block implementation. + * - label: The configured label of the block if visible. + * - configuration: A list of the block's configuration values. + * - label: The configured label for the block. + * - label_display: The display settings for the label. + * - provider: The module or other provider that provided this block plugin. + * - Block plugin specific settings will also be stored here. + * - content: The content of this block. + * - attributes: HTML attributes for the containing element. + * - id: A valid HTML ID and guaranteed unique. + * - title_attributes: HTML attributes for the title element. + * - content_attributes: HTML attributes for the content element. + * - title_prefix: Additional output populated by modules, intended to be + * displayed in front of the main title tag that appears in the template. + * - title_suffix: Additional output populated by modules, intended to be + * displayed after the main title tag that appears in the template. + * + * Headings should be used on navigation menus that consistently appear on + * multiple pages. When this menu block's label is configured to not be + * displayed, it is automatically made invisible using the 'visually-hidden' CSS + * class, which still keeps it visible for screen-readers and assistive + * technology. Headings allow screen-reader and keyboard only users to navigate + * to or skip the links. + * See http://juicystudio.com/article/screen-readers-display-none.php and + * http://www.w3.org/TR/WCAG-TECHS/H42.html for more information. + */ +#} +{% + set classes = [ + 'c-block', + 'c-block__menu', + 'c-nav', + 'c-nav__' ~ derivative_plugin_id|clean_class, + ] +%} + +{% set heading_id = attributes.id ~ '-menu'|clean_id %} + + diff --git a/web/themes/custom/perls/templates/blocks/block--taxonomy-specific-feedback.html.twig b/web/themes/custom/perls/templates/blocks/block--taxonomy-specific-feedback.html.twig new file mode 100644 index 0000000..0bb5583 --- /dev/null +++ b/web/themes/custom/perls/templates/blocks/block--taxonomy-specific-feedback.html.twig @@ -0,0 +1,56 @@ +{# +/** + * @file + * Theme override to display a block. + * + * Available variables: + * - plugin_id: The ID of the block implementation. + * - label: The configured label of the block if visible. + * - configuration: A list of the block's configuration values. + * - label: The configured label for the block. + * - label_display: The display settings for the label. + * - provider: The module or other provider that provided this block plugin. + * - Block plugin specific settings will also be stored here. + * - content: The content of this block. + * - attributes: array of HTML attributes populated by modules, intended to + * be added to the main container tag of this template. + * - id: A valid HTML ID and guaranteed unique. + * - title_attributes: Same as attributes, except applied to the main title + * tag that appears in the template. + * - title_prefix: Additional output populated by modules, intended to be + * displayed in front of the main title tag that appears in the template. + * - title_suffix: Additional output populated by modules, intended to be + * displayed after the main title tag that appears in the template. + * + * @see template_preprocess_block() + */ +#} +{% if block_content_bundle %} + {% + set block_bundle = 'c-block-' ~ configuration.provider|clean_class ~ '-' ~ block_content_bundle|clean_class + %} +{% endif %} + +{% + set classes = [ + 'c-block', + 'c-block-' ~ configuration.provider|clean_class, + block_bundle, + 'c-block-' ~ plugin_id|clean_class, + 'c-block-taxonomy-specific-feedback' + ] +%} + + + {{ title_prefix }} + + {% if label %} + {{ label }} + {% endif %} + + {{ title_suffix }} + + {% block content %} + {{ content }} + {% endblock %} + diff --git a/web/themes/custom/perls/templates/blocks/block--user-login-block.html.twig b/web/themes/custom/perls/templates/blocks/block--user-login-block.html.twig new file mode 100644 index 0000000..4bba07b --- /dev/null +++ b/web/themes/custom/perls/templates/blocks/block--user-login-block.html.twig @@ -0,0 +1,11 @@ + diff --git a/web/themes/custom/perls/templates/blocks/block--user-menu.html.twig b/web/themes/custom/perls/templates/blocks/block--user-menu.html.twig new file mode 100644 index 0000000..34732a5 --- /dev/null +++ b/web/themes/custom/perls/templates/blocks/block--user-menu.html.twig @@ -0,0 +1,70 @@ +{# +/** + * @file + * Theme override for a menu block. + * + * Available variables: + * - plugin_id: The ID of the block implementation. + * - label: The configured label of the block if visible. + * - configuration: A list of the block's configuration values. + * - label: The configured label for the block. + * - label_display: The display settings for the label. + * - provider: The module or other provider that provided this block plugin. + * - Block plugin specific settings will also be stored here. + * - content: The content of this block. + * - attributes: HTML attributes for the containing element. + * - id: A valid HTML ID and guaranteed unique. + * - title_attributes: HTML attributes for the title element. + * - content_attributes: HTML attributes for the content element. + * - title_prefix: Additional output populated by modules, intended to be + * displayed in front of the main title tag that appears in the template. + * - title_suffix: Additional output populated by modules, intended to be + * displayed after the main title tag that appears in the template. + * + * Headings should be used on navigation menus that consistently appear on + * multiple pages. When this menu block's label is configured to not be + * displayed, it is automatically made invisible using the 'visually-hidden' CSS + * class, which still keeps it visible for screen-readers and assistive + * technology. Headings allow screen-reader and keyboard only users to navigate + * to or skip the links. + * See http://juicystudio.com/article/screen-readers-display-none.php and + * http://www.w3.org/TR/WCAG-TECHS/H42.html for more information. + */ +#} +{% + set classes = [ + 'c-block', + 'c-block__menu', + 'c-nav', + 'c-nav__' ~ derivative_plugin_id|clean_class, +] +%} + +{% set heading_id = attributes.id ~ '-menu'|clean_id %} + + diff --git a/web/themes/custom/perls/templates/blocks/block.html.twig b/web/themes/custom/perls/templates/blocks/block.html.twig new file mode 100644 index 0000000..cfe5946 --- /dev/null +++ b/web/themes/custom/perls/templates/blocks/block.html.twig @@ -0,0 +1,59 @@ +{# +/** + * @file + * Theme override to display a block. + * + * Available variables: + * - plugin_id: The ID of the block implementation. + * - label: The configured label of the block if visible. + * - configuration: A list of the block's configuration values. + * - label: The configured label for the block. + * - label_display: The display settings for the label. + * - provider: The module or other provider that provided this block plugin. + * - Block plugin specific settings will also be stored here. + * - content: The content of this block. + * - attributes: array of HTML attributes populated by modules, intended to + * be added to the main container tag of this template. + * - id: A valid HTML ID and guaranteed unique. + * - title_attributes: Same as attributes, except applied to the main title + * tag that appears in the template. + * - title_prefix: Additional output populated by modules, intended to be + * displayed in front of the main title tag that appears in the template. + * - title_suffix: Additional output populated by modules, intended to be + * displayed after the main title tag that appears in the template. + * + * @see template_preprocess_block() + */ +#} +{% if block_content_bundle %} + {% + set block_bundle = 'c-block-' ~ configuration.provider|clean_class ~ '-' ~ block_content_bundle|clean_class + %} +{% endif %} + +{% + set classes = [ + 'c-block', + 'c-block-' ~ configuration.provider|clean_class, + block_bundle, + 'c-block-' ~ plugin_id|clean_class, + ] +%} + + + {{ title_prefix }} + + {% if label %} + {{ label }} + {% endif %} + + {{ title_suffix }} + + {% if more_url %} +
    {{ more_url }}
    + {% endif %} + + {% block content %} + {{ content }} + {% endblock %} + diff --git a/web/themes/custom/perls/templates/content-edit/image-widget.html.twig b/web/themes/custom/perls/templates/content-edit/image-widget.html.twig new file mode 100644 index 0000000..df509e5 --- /dev/null +++ b/web/themes/custom/perls/templates/content-edit/image-widget.html.twig @@ -0,0 +1,26 @@ +{# +/** + * @file + * Theme override for an image field widget. + * + * Available variables: + * - attributes: HTML attributes for the containing element. + * - data: Render elements of the image widget. + * + * @see template_preprocess_image_widget() + */ +#} + +
    + {% if data.preview %} +
    + {{ data.preview }} +
    + {% endif %} +
    + {# Render widget data without the image preview that was output already. #} + {# Render widget data without file size. #} + {{ data|without('preview', 'file_88') }} +
    +
    + diff --git a/web/themes/custom/perls/templates/content/comment--field-comments--learn-article.html.twig b/web/themes/custom/perls/templates/content/comment--field-comments--learn-article.html.twig new file mode 100644 index 0000000..c393366 --- /dev/null +++ b/web/themes/custom/perls/templates/content/comment--field-comments--learn-article.html.twig @@ -0,0 +1,105 @@ +{# +/** + * @file + * Theme override for comments. + * + * Available variables: + * - author: Comment author. Can be a link or plain text. + * - content: The content-related items for the comment display. Use + * {{ content }} to print them all, or print a subset such as + * {{ content.field_example }}. Use the following code to temporarily suppress + * the printing of a given child element: + * @code + * {{ content|without('field_example') }} + * @endcode + * - created: Formatted date and time for when the comment was created. + * Preprocess functions can reformat it by calling DateFormatter::format() + * with the desired parameters on the 'comment.created' variable. + * - changed: Formatted date and time for when the comment was last changed. + * Preprocess functions can reformat it by calling DateFormatter::format() + * with the desired parameters on the 'comment.changed' variable. + * - permalink: Comment permalink. + * - submitted: Submission information created from author and created + * during template_preprocess_comment(). + * - user_picture: The comment author's profile picture. + * - status: Comment status. Possible values are: + * unpublished, published, or preview. + * - title: Comment title, linked to the comment. + * - attributes: HTML attributes for the containing element. + * The attributes.class may contain one or more of the following classes: + * - comment: The current template type; e.g., 'theming hook'. + * - by-anonymous: Comment by an unregistered user. + * - by-{entity-type}-author: Comment by the author of the parent entity, + * eg. by-node-author. + * - preview: When previewing a new or edited comment. + * The following applies only to viewers who are registered users: + * - unpublished: An unpublished comment visible only to administrators. + * - title_prefix: Additional output populated by modules, intended to be + * displayed in front of the main title tag that appears in the template. + * - title_suffix: Additional output populated by modules, intended to be + * displayed after the main title tag that appears in the template. + * - content_attributes: List of classes for the styling of the comment content. + * - title_attributes: Same as attributes, except applied to the main title + * tag that appears in the template. + * - threaded: A flag indicating whether the comments are threaded or not. + * + * These variables are provided to give context about the parent comment (if + * any): + * - parent_comment: Full parent comment entity (if any). + * - parent_author: Equivalent to author for the parent comment. + * - parent_created: Equivalent to created for the parent comment. + * - parent_changed: Equivalent to changed for the parent comment. + * - parent_title: Equivalent to title for the parent comment. + * - parent_permalink: Equivalent to permalink for the parent comment. + * - parent: A text string of parent comment submission information created from + * 'parent_author' and 'parent_created' during template_preprocess_comment(). + * This information is presented to help screen readers follow lengthy + * discussion threads. You can hide this from sighted users using the class + * visually-hidden. + * + * These two variables are provided for context: + * - comment: Full comment object. + * - entity: Entity the comments are attached to. + * + * @see template_preprocess_comment() + */ +#} +{% if threaded %} + {{ attach_library('classy/indented') }} +{% endif %} +{% + set classes = [ + 'comment', + 'js-comment', + status != 'published' ? status, + comment.owner.anonymous ? 'by-anonymous', + author_id and author_id == commented_entity.getOwnerId() ? 'by-' ~ commented_entity.getEntityTypeId() ~ '-author', + ] +%} + + {# + Hide the "new" indicator by default, let a piece of JavaScript ask the + server which comments are new for the user. Rendering the final "new" + indicator here would break the render cache. + #} + + +
    + {{ user_picture }} + + + {# + Indicate the semantic relationship between parent and child comments for + accessibility. The list is difficult to navigate in a screen reader + without this information. + #} + {% if parent %} +

    {{ parent }}

    + {% endif %} + +
    + + + {{ content }} + + diff --git a/web/themes/custom/perls/templates/content/group--card.html.twig b/web/themes/custom/perls/templates/content/group--card.html.twig new file mode 100644 index 0000000..5a7f5c0 --- /dev/null +++ b/web/themes/custom/perls/templates/content/group--card.html.twig @@ -0,0 +1,75 @@ +{# +/** + * @file + * Default theme implementation to display a group. + * + * Available variables: + * - group: The group entity with limited access to object properties and + * methods. Only "getter" methods (method names starting with "get", "has", + * or "is") and a few common methods such as "id" and "label" are available. + * Calling other methods (such as group.delete) will result in an exception. + * - label: The title of the group. + * - content: All group items. Use {{ content }} to print them all, + * or print a subset such as {{ content.field_example }}. Use + * {{ content|without('field_example') }} to temporarily suppress the + * printing of a given child element. + * - url: Direct URL of the current group. + * - attributes: HTML attributes for the containing element. + * The attributes.class element may contain one or more of the following + * classes: + * - group: The current template type (also known as a "theming hook"). + * - group--[type]: The current group type. For example, if the group is a + * "Classroom" it would result in "group--classroom". Note that the machine + * name will often be in a short form of the human readable label. + * - group--[view_mode]: The View Mode of the group; for example, a + * teaser would result in: "group--teaser", and full: "group--full". + * - title_attributes: Same as attributes, except applied to the main title + * tag that appears in the template. + * - content_attributes: Same as attributes, except applied to the main + * content tag that appears in the template. + * - title_prefix: Additional output populated by modules, intended to be + * displayed in front of the main title tag that appears in the template. + * - title_suffix: Additional output populated by modules, intended to be + * displayed after the main title tag that appears in the template. + * - view_mode: View mode; for example, "teaser" or "full". + * - page: Flag for the full page state. Will be true if view_mode is 'full'. + * + * @see template_preprocess_group() + * + * @ingroup themeable + */ +#} + + {% if content.field_media_image.0 %} +
    + + {% else %} +
    + {% endif %} + + + +
    + {{content.membership_link}} +
    + + {{ content|without('field_media_image', 'membership_link') }} + + diff --git a/web/themes/custom/perls/templates/content/group--chip.html.twig b/web/themes/custom/perls/templates/content/group--chip.html.twig new file mode 100644 index 0000000..4104ead --- /dev/null +++ b/web/themes/custom/perls/templates/content/group--chip.html.twig @@ -0,0 +1,52 @@ +{# +/** + * @file + * Default theme implementation to display a group. + * + * Available variables: + * - group: The group entity with limited access to object properties and + * methods. Only "getter" methods (method names starting with "get", "has", + * or "is") and a few common methods such as "id" and "label" are available. + * Calling other methods (such as group.delete) will result in an exception. + * - label: The title of the group. + * - content: All group items. Use {{ content }} to print them all, + * or print a subset such as {{ content.field_example }}. Use + * {{ content|without('field_example') }} to temporarily suppress the + * printing of a given child element. + * - url: Direct URL of the current group. + * - attributes: HTML attributes for the containing element. + * The attributes.class element may contain one or more of the following + * classes: + * - group: The current template type (also known as a "theming hook"). + * - group--[type]: The current group type. For example, if the group is a + * "Classroom" it would result in "group--classroom". Note that the machine + * name will often be in a short form of the human readable label. + * - group--[view_mode]: The View Mode of the group; for example, a + * teaser would result in: "group--teaser", and full: "group--full". + * - title_attributes: Same as attributes, except applied to the main title + * tag that appears in the template. + * - content_attributes: Same as attributes, except applied to the main + * content tag that appears in the template. + * - title_prefix: Additional output populated by modules, intended to be + * displayed in front of the main title tag that appears in the template. + * - title_suffix: Additional output populated by modules, intended to be + * displayed after the main title tag that appears in the template. + * - view_mode: View mode; for example, "teaser" or "full". + * - page: Flag for the full page state. Will be true if view_mode is 'full'. + * + * @see template_preprocess_group() + * + * @ingroup themeable + */ +#} + + +
    + + + {{ label }} + + +
    +
    + diff --git a/web/themes/custom/perls/templates/content/group--default.html.twig b/web/themes/custom/perls/templates/content/group--default.html.twig new file mode 100644 index 0000000..8609f5e --- /dev/null +++ b/web/themes/custom/perls/templates/content/group--default.html.twig @@ -0,0 +1,74 @@ +{# +/** + * @file + * Default theme implementation to display a group. + * + * Available variables: + * - group: The group entity with limited access to object properties and + * methods. Only "getter" methods (method names starting with "get", "has", + * or "is") and a few common methods such as "id" and "label" are available. + * Calling other methods (such as group.delete) will result in an exception. + * - label: The title of the group. + * - content: All group items. Use {{ content }} to print them all, + * or print a subset such as {{ content.field_example }}. Use + * {{ content|without('field_example') }} to temporarily suppress the + * printing of a given child element. + * - url: Direct URL of the current group. + * - attributes: HTML attributes for the containing element. + * The attributes.class element may contain one or more of the following + * classes: + * - group: The current template type (also known as a "theming hook"). + * - group--[type]: The current group type. For example, if the group is a + * "Classroom" it would result in "group--classroom". Note that the machine + * name will often be in a short form of the human readable label. + * - group--[view_mode]: The View Mode of the group; for example, a + * teaser would result in: "group--teaser", and full: "group--full". + * - title_attributes: Same as attributes, except applied to the main title + * tag that appears in the template. + * - content_attributes: Same as attributes, except applied to the main + * content tag that appears in the template. + * - title_prefix: Additional output populated by modules, intended to be + * displayed in front of the main title tag that appears in the template. + * - title_suffix: Additional output populated by modules, intended to be + * displayed after the main title tag that appears in the template. + * - view_mode: View mode; for example, "teaser" or "full". + * - page: Flag for the full page state. Will be true if view_mode is 'full'. + * + * @see template_preprocess_group() + * + * @ingroup themeable + */ +#} + +
    + {% if content.field_media_image.0 %} +
    + + {% else %} +
    + {% endif %} +
    +
    +
    + + {{ label }} + +
    + + {{ content|without('field_media_image') }} +
    + diff --git a/web/themes/custom/perls/templates/content/group--info-card.html.twig b/web/themes/custom/perls/templates/content/group--info-card.html.twig new file mode 100644 index 0000000..b4e60da --- /dev/null +++ b/web/themes/custom/perls/templates/content/group--info-card.html.twig @@ -0,0 +1,73 @@ +{# +/** + * @file + * Default theme implementation to display a group. + * + * Available variables: + * - group: The group entity with limited access to object properties and + * methods. Only "getter" methods (method names starting with "get", "has", + * or "is") and a few common methods such as "id" and "label" are available. + * Calling other methods (such as group.delete) will result in an exception. + * - label: The title of the group. + * - content: All group items. Use {{ content }} to print them all, + * or print a subset such as {{ content.field_example }}. Use + * {{ content|without('field_example') }} to temporarily suppress the + * printing of a given child element. + * - url: Direct URL of the current group. + * - attributes: HTML attributes for the containing element. + * The attributes.class element may contain one or more of the following + * classes: + * - group: The current template type (also known as a "theming hook"). + * - group--[type]: The current group type. For example, if the group is a + * "Classroom" it would result in "group--classroom". Note that the machine + * name will often be in a short form of the human readable label. + * - group--[view_mode]: The View Mode of the group; for example, a + * teaser would result in: "group--teaser", and full: "group--full". + * - title_attributes: Same as attributes, except applied to the main title + * tag that appears in the template. + * - content_attributes: Same as attributes, except applied to the main + * content tag that appears in the template. + * - title_prefix: Additional output populated by modules, intended to be + * displayed in front of the main title tag that appears in the template. + * - title_suffix: Additional output populated by modules, intended to be + * displayed after the main title tag that appears in the template. + * - view_mode: View mode; for example, "teaser" or "full". + * - page: Flag for the full page state. Will be true if view_mode is 'full'. + * + * @see template_preprocess_group() + * + * @ingroup themeable + */ +#} + + {% if content.field_media_image.0 %} +
    + + {% else %} +
    + {% endif %} + + +
    + + + {{ label }} + + +
    +
    + {{content.membership_link}} +
    + + {{ content|without('field_media_image', 'membership_link') }} + + diff --git a/web/themes/custom/perls/templates/content/push-notification.html.twig b/web/themes/custom/perls/templates/content/push-notification.html.twig new file mode 100644 index 0000000..5be76f0 --- /dev/null +++ b/web/themes/custom/perls/templates/content/push-notification.html.twig @@ -0,0 +1,67 @@ +{# +/** + * @file + * Default theme implementation for push notifications. + * + * Available variables: + * - title: The title of the push notification. + * - body: The body of the push notification. + * - image: The image URL associated with the notification. + * - send_time: The time the notification was sent; formatted as a string. + * - sent: Whether the push notification has been sent. + * - status: The status of the notification. Possible values are: + * queued, sent, cancelled + * - site_name: The site name. + * - data: Arbitrary data associated with the push notification. + * - content: Additional content associated with the push notification. + * - view_mode: The current view mode. + * - attributes: HTML attributes for the container. + * - title_attributes: HTML attributes for the message title. + * + * Additionally, the push notification entity is provided for context: + * - push_notification: The push notification object. + * + * @see template_preprocess_push_notification() + * + * @ingroup themeable + */ +#} + + +
    +
    +
    {{site_name}}
    +
    {{send_time}}
    +
    +
    +
    + {{title}} +

    {{body}}

    +
    + {% if image %} +
    + {{'Notification +
    + {% endif %} +
    +
    + + {% if content.related_item %} +
    +

    {{'Related Content'|t}}

    + {{content.related_item}} +
    + {% endif %} + + {% if not teaser %} +
    + {{'Info'|t}} + {{content | without('related_item')}} +
    + +
    + JSON +
    {{json}}
    +
    + {% endif %} + diff --git a/web/themes/custom/perls/templates/content/taxonomy-term--tags--chip.html.twig b/web/themes/custom/perls/templates/content/taxonomy-term--tags--chip.html.twig new file mode 100644 index 0000000..5dec7c4 --- /dev/null +++ b/web/themes/custom/perls/templates/content/taxonomy-term--tags--chip.html.twig @@ -0,0 +1,44 @@ +{# +/** + * @file + * Theme override to display a taxonomy term. + * + * Available variables: + * - url: URL of the current term. + * - name: Name of the current term. + * - content: Items for the content of the term (fields and description). + * Use 'content' to print them all, or print a subset such as + * 'content.description'. Use the following code to exclude the + * printing of a given child element: + * @code + * {{ content|without('description') }} + * @endcode + * - attributes: HTML attributes for the wrapper. + * - page: Flag for the full page state. + * - term: The taxonomy term entity, including: + * - id: The ID of the taxonomy term. + * - bundle: Machine name of the current vocabulary. + * - view_mode: View mode, e.g. 'full', 'teaser', etc. + * + * @see template_preprocess_taxonomy_term() + */ +#} +{% set base_class = 'taxonomy-term--' ~ view_mode|clean_class %} +{% + set classes = [ + 'taxonomy-term', + 'vocabulary-' ~ term.bundle|clean_class, + base_class, + 'c-chip' + ] +%} + + + {{ title_prefix }} +

    + # + {{ name }} +

    + {{ title_suffix }} +
    + diff --git a/web/themes/custom/perls/templates/content/taxonomy-term--teaser.html.twig b/web/themes/custom/perls/templates/content/taxonomy-term--teaser.html.twig new file mode 100644 index 0000000..a0aa477 --- /dev/null +++ b/web/themes/custom/perls/templates/content/taxonomy-term--teaser.html.twig @@ -0,0 +1,51 @@ +{# +/** + * @file + * Theme override to display a taxonomy term. + * + * Available variables: + * - url: URL of the current term. + * - name: Name of the current term. + * - content: Items for the content of the term (fields and description). + * Use 'content' to print them all, or print a subset such as + * 'content.description'. Use the following code to exclude the + * printing of a given child element: + * @code + * {{ content|without('description') }} + * @endcode + * - attributes: HTML attributes for the wrapper. + * - page: Flag for the full page state. + * - term: The taxonomy term entity, including: + * - id: The ID of the taxonomy term. + * - bundle: Machine name of the current vocabulary. + * - view_mode: View mode, e.g. 'full', 'teaser', etc. + * + * @see template_preprocess_taxonomy_term() + */ +#} +
    + {% if content.field_media_image.0 %} +
    + + {% else %} +
    + {% endif %} +
    +
    +
    + {{ 'Published'|t }} +
    + Edit +
    + +

    + {{ name }} +

    +
    +
    +
    +
    diff --git a/web/themes/custom/perls/templates/content/taxonomy-term.html.twig b/web/themes/custom/perls/templates/content/taxonomy-term.html.twig new file mode 100644 index 0000000..a632e46 --- /dev/null +++ b/web/themes/custom/perls/templates/content/taxonomy-term.html.twig @@ -0,0 +1,44 @@ +{# +/** + * @file + * Theme override to display a taxonomy term. + * + * Available variables: + * - url: URL of the current term. + * - name: Name of the current term. + * - content: Items for the content of the term (fields and description). + * Use 'content' to print them all, or print a subset such as + * 'content.description'. Use the following code to exclude the + * printing of a given child element: + * @code + * {{ content|without('description') }} + * @endcode + * - attributes: HTML attributes for the wrapper. + * - page: Flag for the full page state. + * - term: The taxonomy term entity, including: + * - id: The ID of the taxonomy term. + * - bundle: Machine name of the current vocabulary. + * - view_mode: View mode, e.g. 'full', 'teaser', etc. + * + * @see template_preprocess_taxonomy_term() + */ +#} +{% + set classes = [ + 'taxonomy-term', + 'vocabulary-' ~ term.bundle|clean_class, + 'taxonomy-term--' ~ view_mode|clean_class, + ] +%} + + {{ title_prefix }} +

    {{ name }}

    + {{ title_suffix }} +
    + {% if term.bundle == 'tags' %} + {{ content|without('description') }} + {% else %} + {{ content }} + {% endif %} +
    +
    diff --git a/web/themes/custom/perls/templates/content/xapi-content-file-formatter.html.twig b/web/themes/custom/perls/templates/content/xapi-content-file-formatter.html.twig new file mode 100644 index 0000000..fe85b31 --- /dev/null +++ b/web/themes/custom/perls/templates/content/xapi-content-file-formatter.html.twig @@ -0,0 +1,20 @@ +{# +/** + * @file + * Default formatter for an xAPI package file. + * + * Available variables: + * - link: The link to launch the activity. + * - name: The name of the activity. + * - description: The description of the activity. + * + * @see template_preprocess() + * + * @ingroup themeable + */ +#} +

    {{ name }}

    +{% if description %} +

    {{ description }}

    +{% endif %} +
    {{ link }}
    diff --git a/web/themes/custom/perls/templates/dataset/table.html.twig b/web/themes/custom/perls/templates/dataset/table.html.twig new file mode 100644 index 0000000..2c31000 --- /dev/null +++ b/web/themes/custom/perls/templates/dataset/table.html.twig @@ -0,0 +1,117 @@ +{# +/** + * @file + * Theme override to display a table. + * + * Available variables: + * - attributes: HTML attributes to apply to the tag. + * - caption: A localized string for the tag. + * Note: Drupal currently supports only one table header row, see + * https://www.drupal.org/node/893530 and + * http://api.drupal.org/api/drupal/includes!theme.inc/function/theme_table/7#comment-5109. + * - header: Table header cells. Each cell contains the following properties: + * - tag: The HTML tag name to use; either 'th' or 'td'. + * - attributes: HTML attributes to apply to the tag. + * - content: A localized string for the title of the column. + * - field: Field name (required for column sorting). + * - sort: Default sort order for this column ("asc" or "desc"). + * - sticky: A flag indicating whether to use a "sticky" table header. + * - rows: Table rows. Each row contains the following properties: + * - attributes: HTML attributes to apply to the tag. + * - data: Table cells. + * - no_striping: A flag indicating that the row should receive no + * 'even / odd' styling. Defaults to FALSE. + * - cells: Table cells of the row. Each cell contains the following keys: + * - tag: The HTML tag name to use; either 'th' or 'td'. + * - attributes: Any HTML attributes, such as "colspan", to apply to the + * table cell. + * - content: The string to display in the table cell. + * - active_table_sort: A boolean indicating whether the cell is the active + table sort. + * - footer: Table footer rows, in the same format as the rows variable. + * - empty: The message to display in an extra row if table does not have + * any rows. + * - no_striping: A boolean indicating that the row should receive no striping. + * - header_columns: The number of columns in the header. + * + * @see template_preprocess_table() + */ +#} +
    +
    + + {% if caption %} +
    + {% endif %} + + {% for colgroup in colgroups %} + {% if colgroup.cols %} + + {% for col in colgroup.cols %} + + {% endfor %} + + {% else %} + + {% endif %} + {% endfor %} + + {% if header %} + + + {% for cell in header %} + {% + set cell_classes = [ + cell.active_table_sort ? 'is-active', + ] + %} + <{{ cell.tag }}{{ cell.attributes.addClass(cell_classes) }}> + {{- cell.content -}} + + {% endfor %} + + + {% endif %} + + {% if rows %} + + {% for row in rows %} + {% + set row_classes = [ + not no_striping ? cycle(['odd', 'even'], loop.index0), + ] + %} + + {% for cell in row.cells %} + <{{ cell.tag }}{{ cell.attributes }}> + {{- cell.content -}} + + {% endfor %} + + {% endfor %} + + {% elseif empty %} + + + + + + {% endif %} + {% if footer %} + + {% for row in footer %} + + {% for cell in row.cells %} + <{{ cell.tag }}{{ cell.attributes }}> + {{- cell.content -}} + + {% endfor %} + + {% endfor %} + + {% endif %} +
    tag. + * - colgroups: Column groups. Each group contains the following properties: + * - attributes: HTML attributes to apply to the
    {{ caption }}
    {{ empty }}
    + + diff --git a/web/themes/custom/perls/templates/field/field--field-option.html.twig b/web/themes/custom/perls/templates/field/field--field-option.html.twig new file mode 100644 index 0000000..fecf61e --- /dev/null +++ b/web/themes/custom/perls/templates/field/field--field-option.html.twig @@ -0,0 +1,91 @@ +{# +/** + * @file + * Theme override for a field. + * + * To override output, copy the "field.html.twig" from the templates directory + * to your theme's directory and customize it, just like customizing other + * Drupal templates such as page.html.twig or node.html.twig. + * + * Instead of overriding the theming for all fields, you can also just override + * theming for a subset of fields using + * @link themeable Theme hook suggestions. @endlink For example, + * here are some theme hook suggestions that can be used for a field_foo field + * on an article node type: + * - field--node--field-foo--article.html.twig + * - field--node--field-foo.html.twig + * - field--node--article.html.twig + * - field--field-foo.html.twig + * - field--text-with-summary.html.twig + * - field.html.twig + * + * Available variables: + * - attributes: HTML attributes for the containing element. + * - label_hidden: Whether to show the field label or not. + * - title_attributes: HTML attributes for the title. + * - label: The label for the field. + * - multiple: TRUE if a field can contain multiple items. + * - items: List of all the field items. Each item contains: + * - attributes: List of HTML attributes for each item. + * - content: The field item's content. + * - entity_type: The entity type to which the field belongs. + * - field_name: The name of the field. + * - field_type: The type of the field. + * - label_display: The display settings for the label. + * + * + * @see template_preprocess_field() + */ +#} +{% + set classes = [ + 'c-field', + 'c-field--name-' ~ field_name|clean_class, + 'c-field--type-' ~ field_type|clean_class, + 'c-field--label-' ~ label_display, + 'u-space--double--top' + ] +%} + + {% if multiple %} +
    + {% endif %} + + {% for item in items %} +
    + + {{ item.content['#paragraph'].field_answer.0.value }} + + +
    +
    + {% if (item.content['#paragraph'].field_correct.0.value == 1) %} + {% set status_label = "CORRECT!" %} + {% set status_value = "correct" %} + {% else %} + {% set status_label = "INCORRECT" %} + {% set status_value = "incorrect" %} + {% endif %} + + + +

    {{ status_label }}

    + +

    {{ item.content['#paragraph'].field_rationale.0.value }}

    + + {% if (item.content['#paragraph'].field_correct.0.value == 0 and not is_test) %} + + {% endif %} + + {% if is_test %} + + {% endif %} +
    +
    +
    + {% endfor %} + + {% if multiple %} +
    + {% endif %} + diff --git a/web/themes/custom/perls/templates/field/field--field-type-description.html.twig b/web/themes/custom/perls/templates/field/field--field-type-description.html.twig new file mode 100644 index 0000000..37434d1 --- /dev/null +++ b/web/themes/custom/perls/templates/field/field--field-type-description.html.twig @@ -0,0 +1,80 @@ +{# +/** + * @file + * Theme override for a field. + * + * To override output, copy the "field.html.twig" from the templates directory + * to your theme's directory and customize it, just like customizing other + * Drupal templates such as page.html.twig or node.html.twig. + * + * Instead of overriding the theming for all fields, you can also just override + * theming for a subset of fields using + * @link themeable Theme hook suggestions. @endlink For example, + * here are some theme hook suggestions that can be used for a field_foo field + * on an article node type: + * - field--node--field-foo--article.html.twig + * - field--node--field-foo.html.twig + * - field--node--article.html.twig + * - field--field-foo.html.twig + * - field--text-with-summary.html.twig + * - field.html.twig + * + * Available variables: + * - attributes: HTML attributes for the containing element. + * - label_hidden: Whether to show the field label or not. + * - title_attributes: HTML attributes for the title. + * - label: The label for the field. + * - multiple: TRUE if a field can contain multiple items. + * - items: List of all the field items. Each item contains: + * - attributes: List of HTML attributes for each item. + * - content: The field item's content. + * - entity_type: The entity type to which the field belongs. + * - field_name: The name of the field. + * - field_type: The type of the field. + * - label_display: The display settings for the label. + * + * + * @see template_preprocess_field() + */ +#} +{% + set classes = [ + 'c-field', + 'c-field--name-' ~ field_name|clean_class, + 'c-field--type-' ~ field_type|clean_class, + 'c-field--label-' ~ label_display, + ] +%} +{% + set title_classes = [ + 'c-field__label', + label_display == 'visually_hidden' ? 'visually-hidden', + ] +%} + +{% if label_hidden %} + {% if multiple %} + + {% for item in items %} + {{ item.content }} + {% endfor %} + + {% else %} + {% for item in items %} + {{ item.content }} + {% endfor %} + {% endif %} +{% else %} + + {{ label }} + {% if multiple %} +
    + {% endif %} + {% for item in items %} + {{ item.content }}
    + {% endfor %} + {% if multiple %} + + {% endif %} + +{% endif %} diff --git a/web/themes/custom/perls/templates/field/field--node--field-learning-content--course.html.twig b/web/themes/custom/perls/templates/field/field--node--field-learning-content--course.html.twig new file mode 100644 index 0000000..ee46a4a --- /dev/null +++ b/web/themes/custom/perls/templates/field/field--node--field-learning-content--course.html.twig @@ -0,0 +1,57 @@ +{# +/** + * @file + * Theme override for a field. + * + * To override output, copy the "field.html.twig" from the templates directory + * to your theme's directory and customize it, just like customizing other + * Drupal templates such as page.html.twig or node.html.twig. + * + * Instead of overriding the theming for all fields, you can also just override + * theming for a subset of fields using + * @link themeable Theme hook suggestions. @endlink For example, + * here are some theme hook suggestions that can be used for a field_foo field + * on an article node type: + * - field--node--field-foo--article.html.twig + * - field--node--field-foo.html.twig + * - field--node--article.html.twig + * - field--field-foo.html.twig + * - field--text-with-summary.html.twig + * - field.html.twig + * + * Available variables: + * - attributes: HTML attributes for the containing element. + * - label_hidden: Whether to show the field label or not. + * - title_attributes: HTML attributes for the title. + * - label: The label for the field. + * - multiple: TRUE if a field can contain multiple items. + * - items: List of all the field items. Each item contains: + * - attributes: List of HTML attributes for each item. + * - content: The field item's content. + * - entity_type: The entity type to which the field belongs. + * - field_name: The name of the field. + * - field_type: The type of the field. + * - label_display: The display settings for the label. + * + * + * @see template_preprocess_field() + */ +#} +{% + set classes = [ + 'c-field', + 'c-field--name-' ~ field_name|clean_class, + 'c-field--type-' ~ field_type|clean_class, + 'c-field--label-' ~ label_display, + ] +%} +{% + set title_classes = [ + 'c-field__label', + label_display == 'visually_hidden' ? 'visually-hidden', + ] +%} + +{% for item in items %} + {{ item.content }} +{% endfor %} diff --git a/web/themes/custom/perls/templates/field/field--node--field-quiz--test.html.twig b/web/themes/custom/perls/templates/field/field--node--field-quiz--test.html.twig new file mode 100644 index 0000000..4e17946 --- /dev/null +++ b/web/themes/custom/perls/templates/field/field--node--field-quiz--test.html.twig @@ -0,0 +1,59 @@ +{# +/** + * @file + * Questions in a test. + * + * To override output, copy the "field.html.twig" from the templates directory + * to your theme's directory and customize it, just like customizing other + * Drupal templates such as page.html.twig or node.html.twig. + * + * Instead of overriding the theming for all fields, you can also just override + * theming for a subset of fields using + * @link themeable Theme hook suggestions. @endlink For example, + * here are some theme hook suggestions that can be used for a field_foo field + * on an article node type: + * - field--node--field-foo--article.html.twig + * - field--node--field-foo.html.twig + * - field--node--article.html.twig + * - field--field-foo.html.twig + * - field--text-with-summary.html.twig + * - field.html.twig + * + * Available variables: + * - attributes: HTML attributes for the containing element. + * - label_hidden: Whether to show the field label or not. + * - title_attributes: HTML attributes for the title. + * - label: The label for the field. + * - multiple: TRUE if a field can contain multiple items. + * - items: List of all the field items. Each item contains: + * - attributes: List of HTML attributes for each item. + * - content: The field item's content. + * - entity_type: The entity type to which the field belongs. + * - field_name: The name of the field. + * - field_type: The type of the field. + * - label_display: The display settings for the label. + * + * + * @see template_preprocess_field() + */ +#} +{% + set classes = [ + 'c-field', + 'c-field--name-' ~ field_name|clean_class, + 'c-field--type-' ~ field_type|clean_class, + 'c-field--label-' ~ label_display, + ] +%} +{% + set mark_top = is_completed ? '' : 'top' +%} + + + {% for item in items %} + {{ item.content }} + {% endfor %} +
    + {{ results }} +
    + \ No newline at end of file diff --git a/web/themes/custom/perls/templates/field/field--node--field-related-content--event.html.twig b/web/themes/custom/perls/templates/field/field--node--field-related-content--event.html.twig new file mode 100644 index 0000000..c4fe87b --- /dev/null +++ b/web/themes/custom/perls/templates/field/field--node--field-related-content--event.html.twig @@ -0,0 +1,70 @@ +{# +/** + * @file + * Theme override for a field. + * + * To override output, copy the "field.html.twig" from the templates directory + * to your theme's directory and customize it, just like customizing other + * Drupal templates such as page.html.twig or node.html.twig. + * + * Instead of overriding the theming for all fields, you can also just override + * theming for a subset of fields using + * @link themeable Theme hook suggestions. @endlink For example, + * here are some theme hook suggestions that can be used for a field_foo field + * on an article node type: + * - field--node--field-foo--article.html.twig + * - field--node--field-foo.html.twig + * - field--node--article.html.twig + * - field--field-foo.html.twig + * - field--text-with-summary.html.twig + * - field.html.twig + * + * Available variables: + * - attributes: HTML attributes for the containing element. + * - label_hidden: Whether to show the field label or not. + * - title_attributes: HTML attributes for the title. + * - label: The label for the field. + * - multiple: TRUE if a field can contain multiple items. + * - items: List of all the field items. Each item contains: + * - attributes: List of HTML attributes for each item. + * - content: The field item's content. + * - entity_type: The entity type to which the field belongs. + * - field_name: The name of the field. + * - field_type: The type of the field. + * - label_display: The display settings for the label. + * + * + * @see template_preprocess_field() + */ +#} +{% + set classes = [ + 'c-field', + 'c-field--name-' ~ field_name|clean_class, + 'c-field--type-' ~ field_type|clean_class, + 'c-field--label-' ~ label_display, + ] +%} +{% + set title_classes = [ + 'c-field__label', + label_display == 'visually_hidden' ? 'visually-hidden', + ] +%} + + + {{ label }} + {% if multiple %} +
    + {% endif %} +
    +
      + {% for item in items %} + {{ item.content }} + {% endfor %} +
    +
    + {% if multiple %} +
    + {% endif %} + diff --git a/web/themes/custom/perls/templates/field/field.html.twig b/web/themes/custom/perls/templates/field/field.html.twig new file mode 100644 index 0000000..37434d1 --- /dev/null +++ b/web/themes/custom/perls/templates/field/field.html.twig @@ -0,0 +1,80 @@ +{# +/** + * @file + * Theme override for a field. + * + * To override output, copy the "field.html.twig" from the templates directory + * to your theme's directory and customize it, just like customizing other + * Drupal templates such as page.html.twig or node.html.twig. + * + * Instead of overriding the theming for all fields, you can also just override + * theming for a subset of fields using + * @link themeable Theme hook suggestions. @endlink For example, + * here are some theme hook suggestions that can be used for a field_foo field + * on an article node type: + * - field--node--field-foo--article.html.twig + * - field--node--field-foo.html.twig + * - field--node--article.html.twig + * - field--field-foo.html.twig + * - field--text-with-summary.html.twig + * - field.html.twig + * + * Available variables: + * - attributes: HTML attributes for the containing element. + * - label_hidden: Whether to show the field label or not. + * - title_attributes: HTML attributes for the title. + * - label: The label for the field. + * - multiple: TRUE if a field can contain multiple items. + * - items: List of all the field items. Each item contains: + * - attributes: List of HTML attributes for each item. + * - content: The field item's content. + * - entity_type: The entity type to which the field belongs. + * - field_name: The name of the field. + * - field_type: The type of the field. + * - label_display: The display settings for the label. + * + * + * @see template_preprocess_field() + */ +#} +{% + set classes = [ + 'c-field', + 'c-field--name-' ~ field_name|clean_class, + 'c-field--type-' ~ field_type|clean_class, + 'c-field--label-' ~ label_display, + ] +%} +{% + set title_classes = [ + 'c-field__label', + label_display == 'visually_hidden' ? 'visually-hidden', + ] +%} + +{% if label_hidden %} + {% if multiple %} + + {% for item in items %} + {{ item.content }} + {% endfor %} + + {% else %} + {% for item in items %} + {{ item.content }} + {% endfor %} + {% endif %} +{% else %} + + {{ label }} + {% if multiple %} +
    + {% endif %} + {% for item in items %} + {{ item.content }}
    + {% endfor %} + {% if multiple %} + + {% endif %} + +{% endif %} diff --git a/web/themes/custom/perls/templates/field/flag--bookmark.html.twig b/web/themes/custom/perls/templates/field/flag--bookmark.html.twig new file mode 100644 index 0000000..b30fe1e --- /dev/null +++ b/web/themes/custom/perls/templates/field/flag--bookmark.html.twig @@ -0,0 +1,39 @@ +{# +/** + * @file + * Default theme implementation for flag links. + * + * Available variables: + * - attributes: HTML attributes for the link element. + * - title: The flag link title. + * - action: 'flag' or 'unflag' + * - flag: The flag object. + * - flaggable: The flaggable entity. + */ +#} +{% apply spaceless %} +{# Attach the flag CSS library.#} +{{ attach_library('flag/flag.link') }} + +{# Depending on the flag action, set the appropriate action class. #} +{% if action == 'unflag' %} + {% set action_class = 'is-active' %} +{% endif %} + +{# Set the remaining Flag CSS classes. #} +{% + set classes = [ + 'o-flag', + 'o-flag--' ~ flag.id()|clean_class, + 'js-flag-' ~ flag.id()|clean_class ~ '-' ~ flaggable.id(), + action_class, + ] +%} + +{# Set nofollow to prevent search bots from crawling anonymous flag links #} +{% set attributes = attributes.setAttribute('rel', 'nofollow') %} + +
    + +
    +{% endapply %} diff --git a/web/themes/custom/perls/templates/field/flag--following.html.twig b/web/themes/custom/perls/templates/field/flag--following.html.twig new file mode 100644 index 0000000..eee92b9 --- /dev/null +++ b/web/themes/custom/perls/templates/field/flag--following.html.twig @@ -0,0 +1,43 @@ +{# +/** + * @file + * Default theme implementation for flag links. + * + * Available functions: + * - flagcount(flag, flaggable) gets the number of flaggings for the given flag and flaggable. + * + * Available variables: + * - attributes: HTML attributes for the link element. + * - title: The flag link title. + * - action: 'flag' or 'unflag' + * - flag: The flag object. + * - flaggable: The flaggable entity. + */ +#} +{% spaceless %} +{# Attach the flag CSS library.#} +{{ attach_library('flag/flag.link') }} + +{# Depending on the flag action, set the appropriate action class. #} +{% if action == 'unflag' %} + {% set action_class = 'action-unflag' %} +{% else %} + {% set action_class = 'action-flag' %} +{% endif %} + +{# Set the remaining Flag CSS classes. #} +{% + set classes = [ + 'flag', + 'flag-' ~ flag.id()|clean_class, + 'o-flag-' ~ flag.id()|clean_class, + 'js-flag-' ~ flag.id()|clean_class ~ '-' ~ flaggable.id(), + action_class + ] +%} + +{# Set nofollow to prevent search bots from crawling anonymous flag links #} +{% set attributes = attributes.setAttribute('rel', 'nofollow') %} + +
    {{ title }}
    +{% endspaceless %} diff --git a/web/themes/custom/perls/templates/form/container.html.twig b/web/themes/custom/perls/templates/form/container.html.twig new file mode 100644 index 0000000..161a47d --- /dev/null +++ b/web/themes/custom/perls/templates/form/container.html.twig @@ -0,0 +1,29 @@ +{# +/** + * @file + * Theme override of a container used to wrap child elements. + * + * Used for grouped form items. Can also be used as a theme wrapper for any + * renderable element, to surround it with a
    and HTML attributes. + * See \Drupal\Core\Render\Element\RenderElement for more + * information on the #theme_wrappers render array property, and + * \Drupal\Core\Render\Element\container for usage of the container render + * element. + * + * Available variables: + * - attributes: HTML attributes for the containing element. + * - children: The rendered child elements of the container. + * - has_parent: A flag to indicate that the container has one or more parent + containers. + * + * @see template_preprocess_container() + */ +#} +{% + set classes = [ + has_parent ? 'js-form-wrapper', + has_parent ? 'form-wrapper', + 'u-spacing', + ] +%} +{{ children }}
    diff --git a/web/themes/custom/perls/templates/form/date-recur-modular-alpha-widget.html.twig b/web/themes/custom/perls/templates/form/date-recur-modular-alpha-widget.html.twig new file mode 100644 index 0000000..ce93e88 --- /dev/null +++ b/web/themes/custom/perls/templates/form/date-recur-modular-alpha-widget.html.twig @@ -0,0 +1,28 @@ +{% set base_class = 'date-recur' %} + +
    + {{ widget.mode }} + {{ widget.daily_count }} +
    +
    +
    {{ widget.start }}
    +
    {{ widget.end }}
    +
    {{ widget.time_zone }}
    +
    +
    + {{ widget.weekdays_help }} + {{ widget.weekdays }} +
    +
    + {{ widget.ordinals }} +
    +
    +
    + {{ widget.ends_mode }} +
    +
    + {{ widget.ends_count }} + {{ widget.ends_date }} +
    +
    + diff --git a/web/themes/custom/perls/templates/form/field-multiple-value-form.html.twig b/web/themes/custom/perls/templates/form/field-multiple-value-form.html.twig new file mode 100644 index 0000000..0af1aa5 --- /dev/null +++ b/web/themes/custom/perls/templates/form/field-multiple-value-form.html.twig @@ -0,0 +1,44 @@ +{# +/** + * @file + * Theme override for an individual form element. + * + * Available variables for all fields: + * - multiple: Whether there are multiple instances of the field. + * + * Available variables for single cardinality fields: + * - elements: Form elements to be rendered. + * + * Available variables when there are multiple fields. + * - table: Table of field items. + * - description: The description element containing the following properties: + * - content: The description content of the form element. + * - attributes: HTML attributes to apply to the description container. + * - button: "Add another item" button. + * + * @see template_preprocess_field_multiple_value_form() + */ +#} + +{% if multiple %} + {% + set classes = [ + 'js-form-item', + 'form-item', + 'u-spacing' + ] + %} + + {{ table }} + {% if description.content %} + {{ description.content }} + {% endif %} + {% if button %} +
    {{ button }}
    + {% endif %} + +{% else %} + {% for element in elements %} + {{ element }} + {% endfor %} +{% endif %} diff --git a/web/themes/custom/perls/templates/form/form-element.html.twig b/web/themes/custom/perls/templates/form/form-element.html.twig new file mode 100644 index 0000000..ea23f3d --- /dev/null +++ b/web/themes/custom/perls/templates/form/form-element.html.twig @@ -0,0 +1,99 @@ +{# +/** + * @file + * Theme override for a form element. + * + * Available variables: + * - attributes: HTML attributes for the containing element. + * - errors: (optional) Any errors for this form element, may not be set. + * - prefix: (optional) The form element prefix, may not be set. + * - suffix: (optional) The form element suffix, may not be set. + * - required: The required marker, or empty if the associated form element is + * not required. + * - type: The type of the element. + * - name: The name of the element. + * - label: A rendered label element. + * - label_display: Label display setting. It can have these values: + * - before: The label is output before the element. This is the default. + * The label includes the #title and the required marker, if #required. + * - after: The label is output after the element. For example, this is used + * for radio and checkbox #type elements. If the #title is empty but the + * field is #required, the label will contain only the required marker. + * - invisible: Labels are critical for screen readers to enable them to + * properly navigate through forms but can be visually distracting. This + * property hides the label for everyone except screen readers. + * - attribute: Set the title attribute on the element to create a tooltip but + * output no label element. This is supported only for checkboxes and radios + * in \Drupal\Core\Render\Element\CompositeFormElementTrait::preRenderCompositeFormElement(). + * It is used where a visual label is not needed, such as a table of + * checkboxes where the row and column provide the context. The tooltip will + * include the title and required marker. + * - description: (optional) A list of description properties containing: + * - content: A description of the form element, may not be set. + * - attributes: (optional) A list of HTML attributes to apply to the + * description content wrapper. Will only be set when description is set. + * - description_display: Description display setting. It can have these values: + * - before: The description is output before the element. + * - after: The description is output after the element. This is the default + * value. + * - invisible: The description is output after the element, hidden visually + * but available to screen readers. + * - disabled: True if the element is disabled. + * - title_display: Title display setting. + * + * @see template_preprocess_form_element() + */ +#} +{% + set classes = [ + 'js-form-item', + 'form-item', + 'js-form-type-' ~ type|clean_class, + 'form-type-' ~ type|clean_class, + 'js-form-item-' ~ name|clean_class, + 'form-item-' ~ name|clean_class, + title_display not in ['after', 'before'] ? 'form-no-label', + disabled == 'disabled' ? 'form-disabled', + errors ? 'form-item--error', + ] +%} +{% + set description_classes = [ + 'description', + description_display == 'invisible' ? 'visually-hidden', + ] +%} + + {% if label_display in ['before', 'invisible'] %} +
    + {{ label }} +
    + {% endif %} +
    + {% if prefix is not empty %} + {{ prefix }} + {% endif %} + {% if description_display == 'before' and description.content %} + + {{ description.content }} +
    + {% endif %} + {{ children }} + {% if suffix is not empty %} + {{ suffix }} + {% endif %} + {% if label_display == 'after' %} + {{ label }} + {% endif %} + {% if errors %} +
    + {{ errors }} +
    + {% endif %} + {% if description_display in ['after', 'invisible'] and description.content %} + + {{ description.content }} + + {% endif %} + + diff --git a/web/themes/custom/perls/templates/form/form.html.twig b/web/themes/custom/perls/templates/form/form.html.twig new file mode 100644 index 0000000..0ee7606 --- /dev/null +++ b/web/themes/custom/perls/templates/form/form.html.twig @@ -0,0 +1,22 @@ +{# +/** + * @file + * Theme override for a 'form' element. + * + * Available variables + * - attributes: A list of HTML attributes for the wrapper element. + * - children: The child elements of the form. + * + * @see template_preprocess_form() + */ +#} +{% + set classes = [ + 'c-form', + 'c-form--' ~ element['#id'], + 'u-spacing', + ] +%} + + {{ children }} + diff --git a/web/themes/custom/perls/templates/form/input--file.html.twig b/web/themes/custom/perls/templates/form/input--file.html.twig new file mode 100644 index 0000000..5dadbde --- /dev/null +++ b/web/themes/custom/perls/templates/form/input--file.html.twig @@ -0,0 +1,14 @@ +{# +/** + * @file + * Theme override for an 'input' #type form element. + * + * Available variables: + * - attributes: A list of HTML attributes for the input element. + * - children: Optional additional rendered elements. + * + * @see template_preprocess_input() + */ +#} + +{{ children }} diff --git a/web/themes/custom/perls/templates/form/input--submit.html.twig b/web/themes/custom/perls/templates/form/input--submit.html.twig new file mode 100644 index 0000000..aa430dc --- /dev/null +++ b/web/themes/custom/perls/templates/form/input--submit.html.twig @@ -0,0 +1,4 @@ + +
    + {{ children }} +
    diff --git a/web/themes/custom/perls/templates/form/webform.html.twig b/web/themes/custom/perls/templates/form/webform.html.twig new file mode 100644 index 0000000..c207e21 --- /dev/null +++ b/web/themes/custom/perls/templates/form/webform.html.twig @@ -0,0 +1,35 @@ +{# +/** + * @file + * Theme implementation for a 'webform' element. + * + * This is an copy of the webform.html.twig theme_wrapper which includes the + * 'title_prefix' and 'title_suffix' variables needed for + * contextual links to appear. + * + * Available variables + * - attributes: A list of HTML attributes for the wrapper element. + * - children: The child elements of the webform. + * - title_prefix: Additional output populated by modules, intended to be + * displayed in front of the main title tag that appears in the template. + * - title_suffix: Additional output populated by modules, intended to be + * displayed after the main title tag that appears in the template. + * + * @see template_preprocess_webform() + * @see _webform_form_after_build() + * + * @ingroup themeable + */ +#} +{% + set classes = [ + 'c-form', + 'c-form--' ~ element['#id'], + 'u-spacing', +] +%} + + {{ title_prefix }} + {{ children }} + {{ title_suffix }} + diff --git a/web/themes/custom/perls/templates/layout/html.html.twig b/web/themes/custom/perls/templates/layout/html.html.twig new file mode 100644 index 0000000..c27fb94 --- /dev/null +++ b/web/themes/custom/perls/templates/layout/html.html.twig @@ -0,0 +1,65 @@ +{# +/** + * @file + * Theme override for the basic structure of a single Drupal page. + * + * Variables: + * - logged_in: A flag indicating if user is logged in. + * - root_path: The root path of the current page (e.g., node, admin, user). + * - node_type: The content type for the current node, if the page is a node. + * - head_title: List of text elements that make up the head_title variable. + * May contain or more of the following: + * - title: The title of the page. + * - name: The name of the site. + * - slogan: The slogan of the site. + * - page_top: Initial rendered markup. This should be printed before 'page'. + * - page: The rendered page markup. + * - page_bottom: Closing rendered markup. This variable should be printed after + * 'page'. + * - db_offline: A flag indicating if the database is offline. + * - placeholder_token: The token for generating head, css, js and js-bottom + * placeholders. + * + * @see template_preprocess_html() + */ +#} +{% + set body_classes = [ + logged_in ? 'user-logged-in', + root_path ? 'l-page--path--' ~ root_path|clean_class : '', + node_type ? 'l-page--node l-page--node-type--' ~ node_type|clean_class, + db_offline ? 'db-offline', + current_path ? 'l-page-' ~ current_path|clean_class, + is_front ? 'l-page--path--frontpage' : '' + ] +%} + + + + + {{ head_title|safe_join(' | ') }} + + + + + {# + Keyboard navigation/accessibility link to main content section in + page.html.twig. + #} + + {{ 'Skip to main content'|t }} + + {{ page_top }} + {{ page }} + {{ page_bottom }} + +
    +
    + +
    +
    +
    +
    +
    + + diff --git a/web/themes/custom/perls/templates/layout/layout--onecol.html.twig b/web/themes/custom/perls/templates/layout/layout--onecol.html.twig new file mode 100644 index 0000000..ec75a7a --- /dev/null +++ b/web/themes/custom/perls/templates/layout/layout--onecol.html.twig @@ -0,0 +1,25 @@ +{# +/** + * @file + * Default theme implementation to display a one-column layout. + * + * Available variables: + * - content: The content for this layout. + * - attributes: HTML attributes for the layout
    . + * + * @ingroup themeable + */ +#} +{% + set classes = [ + 'l-grid', + 'l-grid--1up', + ] +%} +{% if content %} + +
    + {{ content.content }} +
    +
    +{% endif %} diff --git a/web/themes/custom/perls/templates/layout/layout--twocol.html.twig b/web/themes/custom/perls/templates/layout/layout--twocol.html.twig new file mode 100644 index 0000000..b3fc2bc --- /dev/null +++ b/web/themes/custom/perls/templates/layout/layout--twocol.html.twig @@ -0,0 +1,45 @@ +{# +/** + * @file + * Default theme implementation to display a one-column layout. + * + * Available variables: + * - content: The content for this layout. + * - attributes: HTML attributes for the layout
    . + * + * @ingroup themeable + */ +#} +{% + set classes = [ + 'l-grid', + 'l-grid--2up', + ] +%} +{% if content %} + + {% if content.top %} +
    + {{ content.top }} +
    + {% endif %} + + {% if content.first %} +
    + {{ content.first }} +
    + {% endif %} + + {% if content.second %} +
    + {{ content.second }} +
    + {% endif %} + + {% if content.bottom %} +
    + {{ content.bottom }} +
    + {% endif %} +
    +{% endif %} diff --git a/web/themes/custom/perls/templates/layout/layout.html.twig b/web/themes/custom/perls/templates/layout/layout.html.twig new file mode 100644 index 0000000..60fb87b --- /dev/null +++ b/web/themes/custom/perls/templates/layout/layout.html.twig @@ -0,0 +1,23 @@ +{# +/** + * @file + * Template for a generic layout. + */ +#} +{% + set classes = [ + 'l-grid', + 'l-grid__' ~ layout.id|clean_class, + ] +%} +{% if content %} + + {% for region in layout.getRegionNames %} + {% if content[region] %} +
    + {{ content[region] }} +
    + {% endif %} + {% endfor %} + +{% endif %} diff --git a/web/themes/custom/perls/templates/layout/maintenance-page.html.twig b/web/themes/custom/perls/templates/layout/maintenance-page.html.twig new file mode 100644 index 0000000..2ac557b --- /dev/null +++ b/web/themes/custom/perls/templates/layout/maintenance-page.html.twig @@ -0,0 +1,52 @@ +{# +/** + * @file + * Theme override to display a single Drupal page while offline. + * + * All available variables are mirrored in page.html.twig. + * Some may be blank but they are provided for consistency. + * + * @see template_preprocess_maintenance_page() + */ +#} +
    + +
    + {% if logo %} + + {% endif %} +
    + +
    + {% if title %} +

    {{ title }}

    + {% endif %} + + {{ page.highlighted }} + + {{ page.content }} +
    + + {% if page.sidebar_first %} + {# /.layout-sidebar-first #} + {% endif %} + + {% if page.sidebar_second %} + {# /.layout-sidebar-second #} + {% endif %} + + {% if page.footer %} +
    + {{ page.footer }} +
    + {% endif %} + +
    {# /.layout-container #} diff --git a/web/themes/custom/perls/templates/layout/page--entity-browser--iframe.html.twig b/web/themes/custom/perls/templates/layout/page--entity-browser--iframe.html.twig new file mode 100644 index 0000000..aa44c7e --- /dev/null +++ b/web/themes/custom/perls/templates/layout/page--entity-browser--iframe.html.twig @@ -0,0 +1,32 @@ +{# +/** + * @file + * Theme override for the IFrame entity browser. Template copied from core/modules/system/templates/page.html.twig + * + * @see template_preprocess_page() + * @see html.html.twig + */ +#} +
    + + {# + We ommit most of the regions in this template, which generally includes + messages too. Since this is not desired we try to figure out where messages + live and display them separately. + + @see entity_browser_preprocess_page__entity_browser__iframe() + #} + {{ messages }} + +
    + {# link is in html.html.twig #} + +
    + + {{ page.content }} + +
    {# /.layout-content #} + +
    + +
    {# /.layout-container #} diff --git a/web/themes/custom/perls/templates/layout/page--vidyo-room.html.twig b/web/themes/custom/perls/templates/layout/page--vidyo-room.html.twig new file mode 100644 index 0000000..8e1f9f8 --- /dev/null +++ b/web/themes/custom/perls/templates/layout/page--vidyo-room.html.twig @@ -0,0 +1,60 @@ +{# +/** + * @file + * Theme override to display a single page. + * + * The doctype, html, head and body tags are not in this template. Instead they + * can be found in the html.html.twig template in this directory. + * + * Available variables: + * + * General utility variables: + * - base_path: The base URL path of the Drupal installation. Will usually be + * "/" unless you have installed Drupal in a sub-directory. + * - is_front: A flag indicating if the current page is the front page. + * - logged_in: A flag indicating if the user is registered and signed in. + * - is_admin: A flag indicating if the user has permission to access + * administration pages. + * + * Site identity: + * - front_page: The URL of the front page. Use this instead of base_path when + * linking to the front page. This includes the language domain or prefix. + * + * Page content (in order of occurrence in the default page.html.twig): + * - node: Fully loaded node, if there is an automatically-loaded node + * associated with the page and the node ID is the second argument in the + * page's path (e.g. node/12345 and node/12345/revisions, but not + * comment/reply/12345). + * + * Regions: + * - page.header: Items for the header region. + * - page.primary_menu: Items for the primary menu region. + * - page.secondary_menu: Items for the secondary menu region. + * - page.highlighted: Items for the highlighted content region. + * - page.help: Dynamic help text, mostly for admin pages. + * - page.content: The main content of the current page. + * - page.sidebar_first: Items for the first sidebar. + * - page.sidebar_second: Items for the second sidebar. + * - page.footer: Items for the footer region. + * - page.breadcrumb: Items for the breadcrumb region. + * + * @see template_preprocess_page() + * @see html.html.twig + */ +#} + +
    +
    + {% if page.highlighted|render|trim is not empty %} +
    + {{ page.highlighted }} +
    + {% endif %} + + {% if page.content|render|trim is not empty %} +
    + {{ page.content }} +
    + {% endif %} +
    +
    diff --git a/web/themes/custom/perls/templates/layout/page.html.twig b/web/themes/custom/perls/templates/layout/page.html.twig new file mode 100644 index 0000000..8862b5c --- /dev/null +++ b/web/themes/custom/perls/templates/layout/page.html.twig @@ -0,0 +1,96 @@ +{# +/** + * @file + * Theme override to display a single page. + * + * The doctype, html, head and body tags are not in this template. Instead they + * can be found in the html.html.twig template in this directory. + * + * Available variables: + * + * General utility variables: + * - base_path: The base URL path of the Drupal installation. Will usually be + * "/" unless you have installed Drupal in a sub-directory. + * - is_front: A flag indicating if the current page is the front page. + * - logged_in: A flag indicating if the user is registered and signed in. + * - is_admin: A flag indicating if the user has permission to access + * administration pages. + * + * Site identity: + * - front_page: The URL of the front page. Use this instead of base_path when + * linking to the front page. This includes the language domain or prefix. + * + * Page content (in order of occurrence in the default page.html.twig): + * - node: Fully loaded node, if there is an automatically-loaded node + * associated with the page and the node ID is the second argument in the + * page's path (e.g. node/12345 and node/12345/revisions, but not + * comment/reply/12345). + * + * Regions: + * - page.header: Items for the header region. + * - page.primary_menu: Items for the primary menu region. + * - page.secondary_menu: Items for the secondary menu region. + * - page.highlighted: Items for the highlighted content region. + * - page.help: Dynamic help text, mostly for admin pages. + * - page.content: The main content of the current page. + * - page.sidebar_first: Items for the first sidebar. + * - page.sidebar_second: Items for the second sidebar. + * - page.footer: Items for the footer region. + * - page.breadcrumb: Items for the breadcrumb region. + * + * @see template_preprocess_page() + * @see html.html.twig + */ +#} +{% if page.sidebar_second|render|trim is not empty %} + {% set body_class = " has-sidebar" %} +{% else %} + {% set body_class = "" %} +{% endif %} + +
    + {% if page.header|render|trim is not empty %} + {{ page.header }} + {% endif %} + +
    + {% if page.sidebar_first|render|trim is not empty %} + + {% endif %} + +
    + {# Skip to main content link in html.html.twig #} + + +
    +
    + {% if page.highlighted|render|trim is not empty %} +
    + {{ page.highlighted }} +
    + {% endif %} + + {% if page.content|render|trim is not empty %} +
    + {{ page.content }} +
    + {% endif %} +
    +
    + + {% if page.sidebar_second|render|trim is not empty %} +
    + +
    + {% endif %} +
    +
    + + {% if page.footer|render|trim is not empty %} + {{ page.footer }} + {% endif %} +
    diff --git a/web/themes/custom/perls/templates/layout/region--content.html.twig b/web/themes/custom/perls/templates/layout/region--content.html.twig new file mode 100644 index 0000000..cddd070 --- /dev/null +++ b/web/themes/custom/perls/templates/layout/region--content.html.twig @@ -0,0 +1 @@ +{{ content }} diff --git a/web/themes/custom/perls/templates/layout/region--footer.html.twig b/web/themes/custom/perls/templates/layout/region--footer.html.twig new file mode 100644 index 0000000..4d47b20 --- /dev/null +++ b/web/themes/custom/perls/templates/layout/region--footer.html.twig @@ -0,0 +1,3 @@ +
    + {{ content }} +
    diff --git a/web/themes/custom/perls/templates/layout/region--header.html.twig b/web/themes/custom/perls/templates/layout/region--header.html.twig new file mode 100644 index 0000000..306c662 --- /dev/null +++ b/web/themes/custom/perls/templates/layout/region--header.html.twig @@ -0,0 +1,21 @@ + diff --git a/web/themes/custom/perls/templates/layout/region--highlighted.html.twig b/web/themes/custom/perls/templates/layout/region--highlighted.html.twig new file mode 100644 index 0000000..cddd070 --- /dev/null +++ b/web/themes/custom/perls/templates/layout/region--highlighted.html.twig @@ -0,0 +1 @@ +{{ content }} diff --git a/web/themes/custom/perls/templates/misc/results-card.html.twig b/web/themes/custom/perls/templates/misc/results-card.html.twig new file mode 100644 index 0000000..c2c89d7 --- /dev/null +++ b/web/themes/custom/perls/templates/misc/results-card.html.twig @@ -0,0 +1,37 @@ +{# +/** + * @file + * Results card. + * + * Available variables: + * - result_title: The title to display on the results card. + * - result_status: The status of the test (e.g. "Completed"). + * - result_type: The type of results being shown (e.g. "Test"). + * - feedback: The feedback to display to the user. + */ +#} + +{% + set classes = [ + 'c-card', + 'c-card--results', + 'c-card--results-' ~ result_type|clean_class, + ] +%} + + +
    +

    {{ result_status }}

    +
    {{ result_type }}
    +

    {{ result_title }}

    +
    +
    + + +
    + + + + diff --git a/web/themes/custom/perls/templates/misc/status-messages.html.twig b/web/themes/custom/perls/templates/misc/status-messages.html.twig new file mode 100644 index 0000000..6a477f4 --- /dev/null +++ b/web/themes/custom/perls/templates/misc/status-messages.html.twig @@ -0,0 +1,55 @@ +{# +/** + * @file + * Theme override for status messages. + * + * Displays status, error, and warning messages, grouped by type. + * + * An invisible heading identifies the messages for assistive technology. + * Sighted users see a colored box. See http://www.w3.org/TR/WCAG-TECHS/H69.html + * for info. + * + * Add an ARIA label to the contentinfo area so that assistive technology + * user agents will better describe this landmark. + * + * Available variables: + * - message_list: List of messages to be displayed, grouped by type. + * - status_headings: List of all status types. + * - attributes: HTML attributes for the element, including: + * - class: HTML classes. + */ +#} +
    +{% block messages %} +{% for type, messages in message_list %} + {% + set classes = [ + 'messages', + 'messages--' ~ type, + ] + %} +
    + {% if type == 'error' %} +
    + {% endif %} + {% if status_headings[type] %} +

    {{ status_headings[type] }}

    + {% endif %} + {% if messages|length > 1 %} +
      + {% for message in messages %} +
    • {{ message }}
    • + {% endfor %} +
    + {% else %} + {{ messages|first }} + {% endif %} + {% if type == 'error' %} +
    + {% endif %} +
    + {# Remove type specific classes. #} + {% set attributes = attributes.removeClass(classes) %} +{% endfor %} +{% endblock messages %} +
    diff --git a/web/themes/custom/perls/templates/navigation/menu.html.twig b/web/themes/custom/perls/templates/navigation/menu.html.twig new file mode 100644 index 0000000..c3fee25 --- /dev/null +++ b/web/themes/custom/perls/templates/navigation/menu.html.twig @@ -0,0 +1,56 @@ +{# +/** + * @file + * Theme override to display a menu. + * + * Available variables: + * - menu_name: The machine name of the menu. + * - items: A nested list of menu items. Each menu item contains: + * - attributes: HTML attributes for the menu item. + * - below: The menu item child items. + * - title: The menu link title. + * - url: The menu link url, instance of \Drupal\Core\Url + * - localized_options: Menu link localized options. + * - is_expanded: TRUE if the link has visible children within the current + * menu tree. + * - is_collapsed: TRUE if the link has children within the current menu tree + * that are not currently visible. + * - in_active_trail: TRUE if the link is in the active trail. + */ +#} +{% import _self as menus %} + +{# + We call a macro which calls itself to render the full tree. + @see https://twig.symfony.com/doc/1.x/tags/macro.html +#} +{{ menus.menu_links(items, attributes, 0) }} + +{% macro menu_links(items, attributes, menu_level) %} + {% import _self as menus %} + {% if items %} + + {% for item in items %} + {% + set item_classes = [ + 'c-menu__item', + 'c-menu__item--' ~ item.title|replace({' ': '-'})|lower, + item.is_expanded ? 'c-menu__item--expanded', + item.is_collapsed ? 'c-menu__item--collapsed', + item.in_active_trail ? 'c-menu__item--active-trail', + ] + %} + + + {{ link(item.title, item.url) }} + + {% if item.below %} +
    + {{ menus.menu_links(item.below, attributes, menu_level + 1) }} +
    + {% endif %} + + {% endfor %} + + {% endif %} +{% endmacro %} diff --git a/web/themes/custom/perls/templates/navigation/pager.html.twig b/web/themes/custom/perls/templates/navigation/pager.html.twig new file mode 100644 index 0000000..fb9e8bd --- /dev/null +++ b/web/themes/custom/perls/templates/navigation/pager.html.twig @@ -0,0 +1,105 @@ +{# +/** + * @file + * Theme override to display a pager. + * + * Available variables: + * - heading_id: Pagination heading ID. + * - items: List of pager items. + * The list is keyed by the following elements: + * - first: Item for the first page; not present on the first page of results. + * - previous: Item for the previous page; not present on the first page + * of results. + * - next: Item for the next page; not present on the last page of results. + * - last: Item for the last page; not present on the last page of results. + * - pages: List of pages, keyed by page number. + * Sub-sub elements: + * items.first, items.previous, items.next, items.last, and each item inside + * items.pages contain the following elements: + * - href: URL with appropriate query parameters for the item. + * - attributes: A keyed list of HTML attributes for the item. + * - text: The visible text used for the item link, such as "‹ Previous" + * or "Next ›". + * - current: The page number of the current page. + * - ellipses: If there are more pages than the quantity allows, then an + * ellipsis before or after the listed pages may be present. + * - previous: Present if the currently visible list of pages does not start + * at the first page. + * - next: Present if the visible list of pages ends before the last page. + * + * @see template_preprocess_pager() + */ +#} +{% if items %} + +{% endif %} diff --git a/web/themes/custom/perls/templates/node/node--card.html.twig b/web/themes/custom/perls/templates/node/node--card.html.twig new file mode 100644 index 0000000..e8a41be --- /dev/null +++ b/web/themes/custom/perls/templates/node/node--card.html.twig @@ -0,0 +1,166 @@ +{# +/** + * @file + * Theme override to display a node. + * + * Available variables: + * - node: The node entity with limited access to object properties and methods. + * Only method names starting with "get", "has", or "is" and a few common + * methods such as "id", "label", and "bundle" are available. For example: + * - node.getCreatedTime() will return the node creation timestamp. + * - node.hasField('field_example') returns TRUE if the node bundle includes + * field_example. (This does not indicate the presence of a value in this + * field.) + * - node.isPublished() will return whether the node is published or not. + * Calling other methods, such as node.delete(), will result in an exception. + * See \Drupal\node\Entity\Node for a full list of public properties and + * methods for the node object. + * - label: (optional) The title of the node. + * - content: All node items. Use {{ content }} to print them all, + * or print a subset such as {{ content.field_example }}. Use + * {{ content|without('field_example') }} to temporarily suppress the printing + * of a given child element. + * - author_picture: The node author user entity, rendered using the "compact" + * view mode. + * - metadata: Metadata for this node. + * - date: (optional) Themed creation date field. + * - author_name: (optional) Themed author name field. + * - url: Direct URL of the current node. + * - display_submitted: Whether submission information should be displayed. + * - attributes: HTML attributes for the containing element. + * The attributes.class element may contain one or more of the following + * classes: + * - node: The current template type (also known as a "theming hook"). + * - node--type-[type]: The current node type. For example, if the node is an + * "Article" it would result in "node--type-article". Note that the machine + * name will often be in a short form of the human readable label. + * - node--view-mode-[view_mode]: The View Mode of the node; for example, a + * teaser would result in: "node--view-mode-teaser", and + * full: "node--view-mode-full". + * The following are controlled through the node publishing options. + * - node--promoted: Appears on nodes promoted to the front page. + * - node--sticky: Appears on nodes ordered above other non-sticky nodes in + * teaser listings. + * - node--unpublished: Appears on unpublished nodes visible only to site + * admins. + * - title_attributes: Same as attributes, except applied to the main title + * tag that appears in the template. + * - content_attributes: Same as attributes, except applied to the main + * content tag that appears in the template. + * - author_attributes: Same as attributes, except applied to the author of + * the node tag that appears in the template. + * - title_prefix: Additional output populated by modules, intended to be + * displayed in front of the main title tag that appears in the template. + * - title_suffix: Additional output populated by modules, intended to be + * displayed after the main title tag that appears in the template. + * - view_mode: View mode; for example, "teaser" or "full". + * - teaser: Flag for the teaser state. Will be true if view_mode is 'teaser'. + * - page: Flag for the full page state. Will be true if view_mode is 'full'. + * - readmore: Flag for more state. Will be true if the teaser content of the + * node cannot hold the main body content. + * - logged_in: Flag for authenticated user status. Will be true when the + * current user is a logged-in member. + * - is_admin: Flag for admin user status. Will be true when the current user + * is an administrator. + * + * @see template_preprocess_node() + * + * @todo Remove the id attribute (or make it a class), because if that gets + * rendered twice on a page this is invalid CSS for example: two lists + * in different view modes. + */ +#} +{% + set classes = [ + 'c-node', + view_mode ? 'c-node--' ~ view_mode|clean_class, + 'c-node--' ~ node.bundle|clean_class, + view_mode ? 'c-node--' ~ view_mode|clean_class ~ '--' ~ node.bundle|clean_class, + node.isPromoted() ? 'is-promoted', + node.isSticky() ? 'is-sticky', + not node.isPublished() ? 'is-unpublished', + 'u-spacing' +] +%} + + {% if content.field_media_image.0 %} +
    + {% set image_uri = node.field_media_image.0.entity.field_media_image.entity.fileuri %} + + {% elseif content.field_artwork.0 %} +
    + + {% else %} +
    + {% endif %} + + {{ content.flag_completed }} + {{ content.flag_bookmark }} + + + {% if content.recommendation_reason %} +
    + +
    + {{ content.recommendation_reason }} +
    +
    + {% endif %} + + {% if content.field_tags.0 %} + + {% endif %} +
    + + +
    + {% if label and not page %} + + + {% if not node.isPublished() %} +
    + {{ 'Unpublished'|t }} +
    + {% endif %} + + {{ label }} + +
    + {% endif %} + {% if content.recommendation_reason %} + +
    + {{ content.recommendation_reason }} +
    + {% endif %} +
    +
    + {{ content| without('flag_bookmark', 'flag_completed', 'field_tags', 'field_image', 'field_media_image', 'flag_recommendation', 'recommendation_reason', 'field_artwork', 'id') }} +
    +
    + diff --git a/web/themes/custom/perls/templates/node/node--course--card.html.twig b/web/themes/custom/perls/templates/node/node--course--card.html.twig new file mode 100644 index 0000000..d4bb347 --- /dev/null +++ b/web/themes/custom/perls/templates/node/node--course--card.html.twig @@ -0,0 +1,134 @@ +{# +/** + * @file + * Theme override to display a node. + * + * Available variables: + * - node: The node entity with limited access to object properties and methods. + * Only method names starting with "get", "has", or "is" and a few common + * methods such as "id", "label", and "bundle" are available. For example: + * - node.getCreatedTime() will return the node creation timestamp. + * - node.hasField('field_example') returns TRUE if the node bundle includes + * field_example. (This does not indicate the presence of a value in this + * field.) + * - node.isPublished() will return whether the node is published or not. + * Calling other methods, such as node.delete(), will result in an exception. + * See \Drupal\node\Entity\Node for a full list of public properties and + * methods for the node object. + * - label: (optional) The title of the node. + * - content: All node items. Use {{ content }} to print them all, + * or print a subset such as {{ content.field_example }}. Use + * {{ content|without('field_example') }} to temporarily suppress the printing + * of a given child element. + * - author_picture: The node author user entity, rendered using the "compact" + * view mode. + * - metadata: Metadata for this node. + * - date: (optional) Themed creation date field. + * - author_name: (optional) Themed author name field. + * - url: Direct URL of the current node. + * - display_submitted: Whether submission information should be displayed. + * - attributes: HTML attributes for the containing element. + * The attributes.class element may contain one or more of the following + * classes: + * - node: The current template type (also known as a "theming hook"). + * - node--type-[type]: The current node type. For example, if the node is an + * "Article" it would result in "node--type-article". Note that the machine + * name will often be in a short form of the human readable label. + * - node--view-mode-[view_mode]: The View Mode of the node; for example, a + * teaser would result in: "node--view-mode-teaser", and + * full: "node--view-mode-full". + * The following are controlled through the node publishing options. + * - node--promoted: Appears on nodes promoted to the front page. + * - node--sticky: Appears on nodes ordered above other non-sticky nodes in + * teaser listings. + * - node--unpublished: Appears on unpublished nodes visible only to site + * admins. + * - title_attributes: Same as attributes, except applied to the main title + * tag that appears in the template. + * - content_attributes: Same as attributes, except applied to the main + * content tag that appears in the template. + * - author_attributes: Same as attributes, except applied to the author of + * the node tag that appears in the template. + * - title_prefix: Additional output populated by modules, intended to be + * displayed in front of the main title tag that appears in the template. + * - title_suffix: Additional output populated by modules, intended to be + * displayed after the main title tag that appears in the template. + * - view_mode: View mode; for example, "teaser" or "full". + * - teaser: Flag for the teaser state. Will be true if view_mode is 'teaser'. + * - page: Flag for the full page state. Will be true if view_mode is 'full'. + * - readmore: Flag for more state. Will be true if the teaser content of the + * node cannot hold the main body content. + * - logged_in: Flag for authenticated user status. Will be true when the + * current user is a logged-in member. + * - is_admin: Flag for admin user status. Will be true when the current user + * is an administrator. + * + * @see template_preprocess_node() + * + * @todo Remove the id attribute (or make it a class), because if that gets + * rendered twice on a page this is invalid CSS for example: two lists + * in different view modes. + */ +#} +{% + set classes = [ + 'c-node', + view_mode ? 'c-node--' ~ view_mode|clean_class, + 'c-node--' ~ node.bundle|clean_class, + view_mode ? 'c-node--' ~ view_mode|clean_class ~ '--' ~ node.bundle|clean_class, + node.isPromoted() ? 'is-promoted', + node.isSticky() ? 'is-sticky', + not node.isPublished() ? 'is-unpublished', + 'u-spacing', + ] +%} + +
    + {% if content.field_media_image.0 %} +
    + {% set image_uri = node.field_media_image.0.entity.field_media_image.entity.fileuri %} + + {% else %} +
    + {% endif %} + + {{ content.flag_completed }} + {{ content.flag_bookmark }} + {% if content.recommendation_reason %} +
    + +
    + {{ content.recommendation_reason }} +
    +
    + {% endif %} + + +
    + {% if label and not page %} + + {{ label }} + + {% endif %} +
    +
    {{ course_status }}
    + +
    + {{ content.field_description }} +
    + + {{ launch_button_title }} +
    +
    +
    diff --git a/web/themes/custom/perls/templates/node/node--course--full.html.twig b/web/themes/custom/perls/templates/node/node--course--full.html.twig new file mode 100644 index 0000000..53fd710 --- /dev/null +++ b/web/themes/custom/perls/templates/node/node--course--full.html.twig @@ -0,0 +1,127 @@ +{# +/** + * @file + * Course detail view. + * + * Available variables: + * - node: The node entity with limited access to object properties and methods. + * Only method names starting with "get", "has", or "is" and a few common + * methods such as "id", "label", and "bundle" are available. For example: + * - node.getCreatedTime() will return the node creation timestamp. + * - node.hasField('field_example') returns TRUE if the node bundle includes + * field_example. (This does not indicate the presence of a value in this + * field.) + * - node.isPublished() will return whether the node is published or not. + * Calling other methods, such as node.delete(), will result in an exception. + * See \Drupal\node\Entity\Node for a full list of public properties and + * methods for the node object. + * - label: (optional) The title of the node. + * - content: All node items. Use {{ content }} to print them all, + * or print a subset such as {{ content.field_example }}. Use + * {{ content|without('field_example') }} to temporarily suppress the printing + * of a given child element. + * - author_picture: The node author user entity, rendered using the "compact" + * view mode. + * - metadata: Metadata for this node. + * - date: (optional) Themed creation date field. + * - author_name: (optional) Themed author name field. + * - url: Direct URL of the current node. + * - display_submitted: Whether submission information should be displayed. + * - attributes: HTML attributes for the containing element. + * The attributes.class element may contain one or more of the following + * classes: + * - node: The current template type (also known as a "theming hook"). + * - node--type-[type]: The current node type. For example, if the node is an + * "Article" it would result in "node--type-article". Note that the machine + * name will often be in a short form of the human readable label. + * - node--view-mode-[view_mode]: The View Mode of the node; for example, a + * teaser would result in: "node--view-mode-teaser", and + * full: "node--view-mode-full". + * The following are controlled through the node publishing options. + * - node--promoted: Appears on nodes promoted to the front page. + * - node--sticky: Appears on nodes ordered above other non-sticky nodes in + * teaser listings. + * - node--unpublished: Appears on unpublished nodes visible only to site + * admins. + * - title_attributes: Same as attributes, except applied to the main title + * tag that appears in the template. + * - content_attributes: Same as attributes, except applied to the main + * content tag that appears in the template. + * - author_attributes: Same as attributes, except applied to the author of + * the node tag that appears in the template. + * - title_prefix: Additional output populated by modules, intended to be + * displayed in front of the main title tag that appears in the template. + * - title_suffix: Additional output populated by modules, intended to be + * displayed after the main title tag that appears in the template. + * - view_mode: View mode; for example, "teaser" or "full". + * - teaser: Flag for the teaser state. Will be true if view_mode is 'teaser'. + * - page: Flag for the full page state. Will be true if view_mode is 'full'. + * - readmore: Flag for more state. Will be true if the teaser content of the + * node cannot hold the main body content. + * - logged_in: Flag for authenticated user status. Will be true when the + * current user is a logged-in member. + * - is_admin: Flag for admin user status. Will be true when the current user + * is an administrator. + * + * @see template_preprocess_node() + */ +#} +{% + set classes = [ + 'c-node', + view_mode ? 'c-node--' ~ view_mode|clean_class, + 'c-node--' ~ node.bundle|clean_class, + view_mode ? 'c-node--' ~ view_mode|clean_class ~ '--' ~ node.bundle|clean_class, + node.isPromoted() ? 'is-promoted', + node.isSticky() ? 'is-sticky', + not node.isPublished() ? 'is-unpublished', + 'u-spacing--double' +] +%} + + +
    +
    + {{ content.flag_bookmark }} + Stats-Bookmarked + + bookmark +
    + {% if label %} + + {{ title_prefix }} + {{ label }} + {{ title_suffix }} + + {% endif %} + {{ content.flag_completed }} + {{ content.field_tags }} +
    + {{ course_progress }} +
    +
    + + +
    +
      + + {% if content.field_description[0] %} +
    • +
      +
      +
      {{ 'Description' | t }}
      +
      +
      + {{ content.field_description }} +
      +
      +
    • + {% endif %} + + {{ content.field_learning_content }} + +
    +
    +
    + + diff --git a/web/themes/custom/perls/templates/node/node--course--tile.html.twig b/web/themes/custom/perls/templates/node/node--course--tile.html.twig new file mode 100644 index 0000000..ded60f6 --- /dev/null +++ b/web/themes/custom/perls/templates/node/node--course--tile.html.twig @@ -0,0 +1,165 @@ +{# +/** + * @file + * Theme override to display a node. + * + * Available variables: + * - node: The node entity with limited access to object properties and methods. + * Only method names starting with "get", "has", or "is" and a few common + * methods such as "id", "label", and "bundle" are available. For example: + * - node.getCreatedTime() will return the node creation timestamp. + * - node.hasField('field_example') returns TRUE if the node bundle includes + * field_example. (This does not indicate the presence of a value in this + * field.) + * - node.isPublished() will return whether the node is published or not. + * Calling other methods, such as node.delete(), will result in an exception. + * See \Drupal\node\Entity\Node for a full list of public properties and + * methods for the node object. + * - label: (optional) The title of the node. + * - content: All node items. Use {{ content }} to print them all, + * or print a subset such as {{ content.field_example }}. Use + * {{ content|without('field_example') }} to temporarily suppress the printing + * of a given child element. + * - author_picture: The node author user entity, rendered using the "compact" + * view mode. + * - metadata: Metadata for this node. + * - date: (optional) Themed creation date field. + * - author_name: (optional) Themed author name field. + * - url: Direct URL of the current node. + * - display_submitted: Whether submission information should be displayed. + * - attributes: HTML attributes for the containing element. + * The attributes.class element may contain one or more of the following + * classes: + * - node: The current template type (also known as a "theming hook"). + * - node--type-[type]: The current node type. For example, if the node is an + * "Article" it would result in "node--type-article". Note that the machine + * name will often be in a short form of the human readable label. + * - node--view-mode-[view_mode]: The View Mode of the node; for example, a + * teaser would result in: "node--view-mode-teaser", and + * full: "node--view-mode-full". + * The following are controlled through the node publishing options. + * - node--promoted: Appears on nodes promoted to the front page. + * - node--sticky: Appears on nodes ordered above other non-sticky nodes in + * teaser listings. + * - node--unpublished: Appears on unpublished nodes visible only to site + * admins. + * - title_attributes: Same as attributes, except applied to the main title + * tag that appears in the template. + * - content_attributes: Same as attributes, except applied to the main + * content tag that appears in the template. + * - author_attributes: Same as attributes, except applied to the author of + * the node tag that appears in the template. + * - title_prefix: Additional output populated by modules, intended to be + * displayed in front of the main title tag that appears in the template. + * - title_suffix: Additional output populated by modules, intended to be + * displayed after the main title tag that appears in the template. + * - view_mode: View mode; for example, "teaser" or "full". + * - teaser: Flag for the teaser state. Will be true if view_mode is 'teaser'. + * - page: Flag for the full page state. Will be true if view_mode is 'full'. + * - readmore: Flag for more state. Will be true if the teaser content of the + * node cannot hold the main body content. + * - logged_in: Flag for authenticated user status. Will be true when the + * current user is a logged-in member. + * - is_admin: Flag for admin user status. Will be true when the current user + * is an administrator. + * + * @see template_preprocess_node() + * + * @todo Remove the id attribute (or make it a class), because if that gets + * rendered twice on a page this is invalid CSS for example: two lists + * in different view modes. + */ +#} +{% + set classes = [ + 'c-node', + view_mode ? 'c-node--' ~ view_mode|clean_class, + 'c-node--' ~ node.bundle|clean_class, + view_mode ? 'c-node--' ~ view_mode|clean_class ~ '--' ~ node.bundle|clean_class, + node.isPromoted() ? 'is-promoted', + node.isSticky() ? 'is-sticky', + not node.isPublished() ? 'is-unpublished', + 'u-spacing--half' +] +%} + + {% if content.field_media_image.0 %} +
    + {% set image_uri = node.field_media_image.0.entity.field_media_image.entity.fileuri %} + + {% elseif content.field_artwork.0 %} +
    + + {% else %} +
    + {% endif %} + {{ content.flag_completed }} + {{ content.flag_bookmark }} + + + {% if content.recommendation_reason %} +
    + +
    + {{ content.recommendation_reason }} +
    +
    + {% endif %} +
    {{ course_status }}
    +
    + + +
    + {% if label and not page %} + + + {% if not node.isPublished() %} +
    + {{ 'Unpublished'|t }} +
    + {% endif %} + + {{ label }} + +
    + {% endif %} + {% if content.recommendation_reason %} + +
    + {{ content.recommendation_reason }} +
    + {% endif %} +
    +
    + {{ content| without('flag_bookmark', 'flag_completed', 'field_tags', 'field_image', 'field_media_image', 'flag_recommendation', 'recommendation_reason', 'field_artwork', 'id') }} +
    +
    + {% if content.field_tags.0 %} + + {% endif %} + diff --git a/web/themes/custom/perls/templates/node/node--discussion.html.twig b/web/themes/custom/perls/templates/node/node--discussion.html.twig new file mode 100644 index 0000000..85d0fdb --- /dev/null +++ b/web/themes/custom/perls/templates/node/node--discussion.html.twig @@ -0,0 +1,95 @@ +{# +/** + * @file + * Theme override to display a node. + * + * Available variables: + * - node: The node entity with limited access to object properties and methods. + * Only method names starting with "get", "has", or "is" and a few common + * methods such as "id", "label", and "bundle" are available. For example: + * - node.getCreatedTime() will return the node creation timestamp. + * - node.hasField('field_example') returns TRUE if the node bundle includes + * field_example. (This does not indicate the presence of a value in this + * field.) + * - node.isPublished() will return whether the node is published or not. + * Calling other methods, such as node.delete(), will result in an exception. + * See \Drupal\node\Entity\Node for a full list of public properties and + * methods for the node object. + * - label: (optional) The title of the node. + * - content: All node items. Use {{ content }} to print them all, + * or print a subset such as {{ content.field_example }}. Use + * {{ content|without('field_example') }} to temporarily suppress the printing + * of a given child element. + * - author_picture: The node author user entity, rendered using the "compact" + * view mode. + * - metadata: Metadata for this node. + * - date: (optional) Themed creation date field. + * - author_name: (optional) Themed author name field. + * - url: Direct URL of the current node. + * - display_submitted: Whether submission information should be displayed. + * - attributes: HTML attributes for the containing element. + * The attributes.class element may contain one or more of the following + * classes: + * - node: The current template type (also known as a "theming hook"). + * - node--type-[type]: The current node type. For example, if the node is an + * "Article" it would result in "node--type-article". Note that the machine + * name will often be in a short form of the human readable label. + * - node--view-mode-[view_mode]: The View Mode of the node; for example, a + * teaser would result in: "node--view-mode-teaser", and + * full: "node--view-mode-full". + * The following are controlled through the node publishing options. + * - node--promoted: Appears on nodes promoted to the front page. + * - node--sticky: Appears on nodes ordered above other non-sticky nodes in + * teaser listings. + * - node--unpublished: Appears on unpublished nodes visible only to site + * admins. + * - title_attributes: Same as attributes, except applied to the main title + * tag that appears in the template. + * - content_attributes: Same as attributes, except applied to the main + * content tag that appears in the template. + * - author_attributes: Same as attributes, except applied to the author of + * the node tag that appears in the template. + * - title_prefix: Additional output populated by modules, intended to be + * displayed in front of the main title tag that appears in the template. + * - title_suffix: Additional output populated by modules, intended to be + * displayed after the main title tag that appears in the template. + * - view_mode: View mode; for example, "teaser" or "full". + * - teaser: Flag for the teaser state. Will be true if view_mode is 'teaser'. + * - page: Flag for the full page state. Will be true if view_mode is 'full'. + * - readmore: Flag for more state. Will be true if the teaser content of the + * node cannot hold the main body content. + * - logged_in: Flag for authenticated user status. Will be true when the + * current user is a logged-in member. + * - is_admin: Flag for admin user status. Will be true when the current user + * is an administrator. + * + * @see template_preprocess_node() + * + * @todo Remove the id attribute (or make it a class), because if that gets + * rendered twice on a page this is invalid CSS for example: two lists + * in different view modes. + */ +#} + +{% + set classes = [ + 'c-node', + view_mode ? 'c-node--' ~ view_mode|clean_class, + 'c-node--' ~ node.bundle|clean_class, + view_mode ? 'c-node--' ~ view_mode|clean_class ~ '--' ~ node.bundle|clean_class, + node.isPromoted() ? 'is-promoted', + node.isSticky() ? 'is-sticky', + not node.isPublished() ? 'is-unpublished' + ] +%} + + +

    {{ 'Discussing' | t}} {{ label }}

    +
    + {% if content.field_comments[0] %} + {{ content.field_comments }} + {% else %} +

    {{ 'Comments are closed.' | t }}

    + {% endif %} +
    + diff --git a/web/themes/custom/perls/templates/node/node--event--full.html.twig b/web/themes/custom/perls/templates/node/node--event--full.html.twig new file mode 100644 index 0000000..8f33fc8 --- /dev/null +++ b/web/themes/custom/perls/templates/node/node--event--full.html.twig @@ -0,0 +1,140 @@ +{# +/** + * @file + * Theme override to display a node. + * + * Available variables: + * - node: The node entity with limited access to object properties and methods. + * Only method names starting with "get", "has", or "is" and a few common + * methods such as "id", "label", and "bundle" are available. For example: + * - node.getCreatedTime() will return the node creation timestamp. + * - node.hasField('field_example') returns TRUE if the node bundle includes + * field_example. (This does not indicate the presence of a value in this + * field.) + * - node.isPublished() will return whether the node is published or not. + * Calling other methods, such as node.delete(), will result in an exception. + * See \Drupal\node\Entity\Node for a full list of public properties and + * methods for the node object. + * - label: (optional) The title of the node. + * - content: All node items. Use {{ content }} to print them all, + * or print a subset such as {{ content.field_example }}. Use + * {{ content|without('field_example') }} to temporarily suppress the printing + * of a given child element. + * - author_picture: The node author user entity, rendered using the "compact" + * view mode. + * - metadata: Metadata for this node. + * - date: (optional) Themed creation date field. + * - author_name: (optional) Themed author name field. + * - url: Direct URL of the current node. + * - display_submitted: Whether submission information should be displayed. + * - attributes: HTML attributes for the containing element. + * The attributes.class element may contain one or more of the following + * classes: + * - node: The current template type (also known as a "theming hook"). + * - node--type-[type]: The current node type. For example, if the node is an + * "Article" it would result in "node--type-article". Note that the machine + * name will often be in a short form of the human readable label. + * - node--view-mode-[view_mode]: The View Mode of the node; for example, a + * teaser would result in: "node--view-mode-teaser", and + * full: "node--view-mode-full". + * The following are controlled through the node publishing options. + * - node--promoted: Appears on nodes promoted to the front page. + * - node--sticky: Appears on nodes ordered above other non-sticky nodes in + * teaser listings. + * - node--unpublished: Appears on unpublished nodes visible only to site + * admins. + * - title_attributes: Same as attributes, except applied to the main title + * tag that appears in the template. + * - content_attributes: Same as attributes, except applied to the main + * content tag that appears in the template. + * - author_attributes: Same as attributes, except applied to the author of + * the node tag that appears in the template. + * - title_prefix: Additional output populated by modules, intended to be + * displayed in front of the main title tag that appears in the template. + * - title_suffix: Additional output populated by modules, intended to be + * displayed after the main title tag that appears in the template. + * - view_mode: View mode; for example, "teaser" or "full". + * - teaser: Flag for the teaser state. Will be true if view_mode is 'teaser'. + * - page: Flag for the full page state. Will be true if view_mode is 'full'. + * - readmore: Flag for more state. Will be true if the teaser content of the + * node cannot hold the main body content. + * - logged_in: Flag for authenticated user status. Will be true when the + * current user is a logged-in member. + * - is_admin: Flag for admin user status. Will be true when the current user + * is an administrator. + * + * @see template_preprocess_node() + * + * @todo Remove the id attribute (or make it a class), because if that gets + * rendered twice on a page this is invalid CSS for example: two lists + * in different view modes. + */ +#} +{% + set classes = [ + 'c-node', + view_mode ? 'c-node--' ~ view_mode|clean_class, + 'c-node--' ~ node.bundle|clean_class, + view_mode ? 'c-node--' ~ view_mode|clean_class ~ '--' ~ node.bundle|clean_class, + node.isPromoted() ? 'is-promoted', + node.isSticky() ? 'is-sticky', + not node.isPublished() ? 'is-unpublished', + 'u-spacing--double' +] +%} + + +
    + {% if content.field_media_image.0 %} + {% set image_uri = node.field_media_image.0.entity.field_media_image.entity.fileuri %} +
    + + {% else %} +
    + {% endif %} + + {{ content.flag_completed }} + {{ content.flag_bookmark }} + + {% if content.field_tags.0 %} + + {% endif %} +
    +
    + + + {% if label %} + + {{ title_prefix }} + {{ label }} + {{ title_suffix }} + + {% endif %} + +
    + {{ content.field_schedule }} + {{ content.field_description }} + {{ content.field_additional_details }} + {{ content.field_virtual_meeting_room }} + {{ content.field_related_content }} + {{ content.field_type_description }} +
    +
    +
    + diff --git a/web/themes/custom/perls/templates/node/node--flash-card--card.html.twig b/web/themes/custom/perls/templates/node/node--flash-card--card.html.twig new file mode 100644 index 0000000..998507c --- /dev/null +++ b/web/themes/custom/perls/templates/node/node--flash-card--card.html.twig @@ -0,0 +1,118 @@ +{# +/** + * @file + * Theme override to display a node. + * + * Available variables: + * - node: The node entity with limited access to object properties and methods. + * Only method names starting with "get", "has", or "is" and a few common + * methods such as "id", "label", and "bundle" are available. For example: + * - node.getCreatedTime() will return the node creation timestamp. + * - node.hasField('field_example') returns TRUE if the node bundle includes + * field_example. (This does not indicate the presence of a value in this + * field.) + * - node.isPublished() will return whether the node is published or not. + * Calling other methods, such as node.delete(), will result in an exception. + * See \Drupal\node\Entity\Node for a full list of public properties and + * methods for the node object. + * - label: (optional) The title of the node. + * - content: All node items. Use {{ content }} to print them all, + * or print a subset such as {{ content.field_example }}. Use + * {{ content|without('field_example') }} to temporarily suppress the printing + * of a given child element. + * - author_picture: The node author user entity, rendered using the "compact" + * view mode. + * - metadata: Metadata for this node. + * - date: (optional) Themed creation date field. + * - author_name: (optional) Themed author name field. + * - url: Direct URL of the current node. + * - display_submitted: Whether submission information should be displayed. + * - attributes: HTML attributes for the containing element. + * The attributes.class element may contain one or more of the following + * classes: + * - node: The current template type (also known as a "theming hook"). + * - node--type-[type]: The current node type. For example, if the node is an + * "Article" it would result in "node--type-article". Note that the machine + * name will often be in a short form of the human readable label. + * - node--view-mode-[view_mode]: The View Mode of the node; for example, a + * teaser would result in: "node--view-mode-teaser", and + * full: "node--view-mode-full". + * The following are controlled through the node publishing options. + * - node--promoted: Appears on nodes promoted to the front page. + * - node--sticky: Appears on nodes ordered above other non-sticky nodes in + * teaser listings. + * - node--unpublished: Appears on unpublished nodes visible only to site + * admins. + * - title_attributes: Same as attributes, except applied to the main title + * tag that appears in the template. + * - content_attributes: Same as attributes, except applied to the main + * content tag that appears in the template. + * - author_attributes: Same as attributes, except applied to the author of + * the node tag that appears in the template. + * - title_prefix: Additional output populated by modules, intended to be + * displayed in front of the main title tag that appears in the template. + * - title_suffix: Additional output populated by modules, intended to be + * displayed after the main title tag that appears in the template. + * - view_mode: View mode; for example, "teaser" or "full". + * - teaser: Flag for the teaser state. Will be true if view_mode is 'teaser'. + * - page: Flag for the full page state. Will be true if view_mode is 'full'. + * - readmore: Flag for more state. Will be true if the teaser content of the + * node cannot hold the main body content. + * - logged_in: Flag for authenticated user status. Will be true when the + * current user is a logged-in member. + * - is_admin: Flag for admin user status. Will be true when the current user + * is an administrator. + * + * @see template_preprocess_node() + * + * @todo Remove the id attribute (or make it a class), because if that gets + * rendered twice on a page this is invalid CSS for example: two lists + * in different view modes. + */ +#} +{% + set classes = [ + 'c-node', + view_mode ? 'c-node--' ~ view_mode|clean_class, + 'c-node--' ~ node.bundle|clean_class, + view_mode ? 'c-node--' ~ view_mode|clean_class ~ '--' ~ node.bundle|clean_class, + node.isPromoted() ? 'is-promoted', + node.isSticky() ? 'is-sticky', + not node.isPublished() ? 'is-unpublished', + ] +%} + +
    +
    +
    + {{ content.flag_completed }} + {{ content.flag_bookmark }} + {% if content.recommendation_reason %} +
    + +
    + {{ content.recommendation_reason }} +
    +
    + {% endif %} + + +
    + {{ content.field_card_front }} +
    + +
    + + {% if content.field_tags.0 %} + + {% endif %} +
    + +
    + + {{ content.field_card_back }} +
    + +
    diff --git a/web/themes/custom/perls/templates/node/node--learn-article--full.html.twig b/web/themes/custom/perls/templates/node/node--learn-article--full.html.twig new file mode 100644 index 0000000..522d71b --- /dev/null +++ b/web/themes/custom/perls/templates/node/node--learn-article--full.html.twig @@ -0,0 +1,177 @@ +{# +/** + * @file + * Theme override to display a node. + * + * Available variables: + * - node: The node entity with limited access to object properties and methods. + * Only method names starting with "get", "has", or "is" and a few common + * methods such as "id", "label", and "bundle" are available. For example: + * - node.getCreatedTime() will return the node creation timestamp. + * - node.hasField('field_example') returns TRUE if the node bundle includes + * field_example. (This does not indicate the presence of a value in this + * field.) + * - node.isPublished() will return whether the node is published or not. + * Calling other methods, such as node.delete(), will result in an exception. + * See \Drupal\node\Entity\Node for a full list of public properties and + * methods for the node object. + * - label: (optional) The title of the node. + * - content: All node items. Use {{ content }} to print them all, + * or print a subset such as {{ content.field_example }}. Use + * {{ content|without('field_example') }} to temporarily suppress the printing + * of a given child element. + * - author_picture: The node author user entity, rendered using the "compact" + * view mode. + * - metadata: Metadata for this node. + * - date: (optional) Themed creation date field. + * - author_name: (optional) Themed author name field. + * - url: Direct URL of the current node. + * - display_submitted: Whether submission information should be displayed. + * - attributes: HTML attributes for the containing element. + * The attributes.class element may contain one or more of the following + * classes: + * - node: The current template type (also known as a "theming hook"). + * - node--type-[type]: The current node type. For example, if the node is an + * "Article" it would result in "node--type-article". Note that the machine + * name will often be in a short form of the human readable label. + * - node--view-mode-[view_mode]: The View Mode of the node; for example, a + * teaser would result in: "node--view-mode-teaser", and + * full: "node--view-mode-full". + * The following are controlled through the node publishing options. + * - node--promoted: Appears on nodes promoted to the front page. + * - node--sticky: Appears on nodes ordered above other non-sticky nodes in + * teaser listings. + * - node--unpublished: Appears on unpublished nodes visible only to site + * admins. + * - title_attributes: Same as attributes, except applied to the main title + * tag that appears in the template. + * - content_attributes: Same as attributes, except applied to the main + * content tag that appears in the template. + * - author_attributes: Same as attributes, except applied to the author of + * the node tag that appears in the template. + * - title_prefix: Additional output populated by modules, intended to be + * displayed in front of the main title tag that appears in the template. + * - title_suffix: Additional output populated by modules, intended to be + * displayed after the main title tag that appears in the template. + * - view_mode: View mode; for example, "teaser" or "full". + * - teaser: Flag for the teaser state. Will be true if view_mode is 'teaser'. + * - page: Flag for the full page state. Will be true if view_mode is 'full'. + * - readmore: Flag for more state. Will be true if the teaser content of the + * node cannot hold the main body content. + * - logged_in: Flag for authenticated user status. Will be true when the + * current user is a logged-in member. + * - is_admin: Flag for admin user status. Will be true when the current user + * is an administrator. + * + * @see template_preprocess_node() + * + * @todo Remove the id attribute (or make it a class), because if that gets + * rendered twice on a page this is invalid CSS for example: two lists + * in different view modes. + */ +#} +{% + set classes = [ + 'c-node', + view_mode ? 'c-node--' ~ view_mode|clean_class, + 'c-node--' ~ node.bundle|clean_class, + view_mode ? 'c-node--' ~ view_mode|clean_class ~ '--' ~ node.bundle|clean_class, + node.isPromoted() ? 'is-promoted', + node.isSticky() ? 'is-sticky', + not node.isPublished() ? 'is-unpublished', + 'u-spacing--double' + ] +%} + + +
    + {% if content.field_media_image.0 %} + {% set image_uri = node.field_media_image.0.entity.field_media_image.entity.fileuri %} +
    + + {% else %} +
    + {% endif %} + + {{ content.flag_completed }} + {{ content.flag_bookmark }} + + {% if content.field_tags.0 %} + + {% endif %} +
    +
    + + + {% if label %} + + {{ title_prefix }} + {{ label }} + {{ title_suffix }} + + {% if content.field_shows_byline.0|render|trim and (node.getOwnerId != 0) %} + + {% endif %} + {% endif %} + +
    + {{ content.content_moderation_control}} + {{ content.field_body }} + {{ content.field_file }} + {{ content.field_learning_content }} + {{ content.field_card_front }} + {{ content.field_card_back }} + {{ content.field_options }} + {{ content.field_description }} + {% if content.field_content_link %} + {% if content.field_content_link.0['#options']['extrenal'] == true %} + {% set url = content.field_content_link.0['#url'].getUri() %} + {% else %} + {% set url = content.field_content_link.0['#url'].toString() %} + {% endif %} + + Read more + {% endif %} + {% if content.completed_manually %} + {{ content.completed_manually }} + {% endif %} + +
    +
    + + {% if content.field_comments[0] %} + {% + set modal_options = { + width: 800, + dialogClass: 'dialog--comment', + position: { + my: 'center top', + at: 'center top+10%' + }, + } + %} + {% set button_style = "display: inline-block;" %} + {{ 'View comments'|t }} + {% endif %} + + diff --git a/web/themes/custom/perls/templates/node/node--learn-package--full.html.twig b/web/themes/custom/perls/templates/node/node--learn-package--full.html.twig new file mode 100644 index 0000000..15ccb0c --- /dev/null +++ b/web/themes/custom/perls/templates/node/node--learn-package--full.html.twig @@ -0,0 +1,141 @@ +{# +/** + * @file + * Theme override to display a node. + * + * Available variables: + * - node: The node entity with limited access to object properties and methods. + * Only method names starting with "get", "has", or "is" and a few common + * methods such as "id", "label", and "bundle" are available. For example: + * - node.getCreatedTime() will return the node creation timestamp. + * - node.hasField('field_example') returns TRUE if the node bundle includes + * field_example. (This does not indicate the presence of a value in this + * field.) + * - node.isPublished() will return whether the node is published or not. + * Calling other methods, such as node.delete(), will result in an exception. + * See \Drupal\node\Entity\Node for a full list of public properties and + * methods for the node object. + * - label: (optional) The title of the node. + * - content: All node items. Use {{ content }} to print them all, + * or print a subset such as {{ content.field_example }}. Use + * {{ content|without('field_example') }} to temporarily suppress the printing + * of a given child element. + * - author_picture: The node author user entity, rendered using the "compact" + * view mode. + * - metadata: Metadata for this node. + * - date: (optional) Themed creation date field. + * - author_name: (optional) Themed author name field. + * - url: Direct URL of the current node. + * - display_submitted: Whether submission information should be displayed. + * - attributes: HTML attributes for the containing element. + * The attributes.class element may contain one or more of the following + * classes: + * - node: The current template type (also known as a "theming hook"). + * - node--type-[type]: The current node type. For example, if the node is an + * "Article" it would result in "node--type-article". Note that the machine + * name will often be in a short form of the human readable label. + * - node--view-mode-[view_mode]: The View Mode of the node; for example, a + * teaser would result in: "node--view-mode-teaser", and + * full: "node--view-mode-full". + * The following are controlled through the node publishing options. + * - node--promoted: Appears on nodes promoted to the front page. + * - node--sticky: Appears on nodes ordered above other non-sticky nodes in + * teaser listings. + * - node--unpublished: Appears on unpublished nodes visible only to site + * admins. + * - title_attributes: Same as attributes, except applied to the main title + * tag that appears in the template. + * - content_attributes: Same as attributes, except applied to the main + * content tag that appears in the template. + * - author_attributes: Same as attributes, except applied to the author of + * the node tag that appears in the template. + * - title_prefix: Additional output populated by modules, intended to be + * displayed in front of the main title tag that appears in the template. + * - title_suffix: Additional output populated by modules, intended to be + * displayed after the main title tag that appears in the template. + * - view_mode: View mode; for example, "teaser" or "full". + * - teaser: Flag for the teaser state. Will be true if view_mode is 'teaser'. + * - page: Flag for the full page state. Will be true if view_mode is 'full'. + * - readmore: Flag for more state. Will be true if the teaser content of the + * node cannot hold the main body content. + * - logged_in: Flag for authenticated user status. Will be true when the + * current user is a logged-in member. + * - is_admin: Flag for admin user status. Will be true when the current user + * is an administrator. + * + * @see template_preprocess_node() + * + * @todo Remove the id attribute (or make it a class), because if that gets + * rendered twice on a page this is invalid CSS for example: two lists + * in different view modes. + */ +#} +{% + set classes = [ + 'c-node', + view_mode ? 'c-node--' ~ view_mode|clean_class, + 'c-node--' ~ node.bundle|clean_class, + view_mode ? 'c-node--' ~ view_mode|clean_class ~ '--' ~ node.bundle|clean_class, + node.isPromoted() ? 'is-promoted', + node.isSticky() ? 'is-sticky', + not node.isPublished() ? 'is-unpublished', + 'u-spacing--double' + ] +%} + + +
    + {% if content.field_media_image.0 %} +
    + {% set image_uri = node.field_media_image.0.entity.field_media_image.entity.fileuri %} + + {% else %} +
    + {% endif %} + + {{ content.flag_completed }} + {{ content.flag_bookmark }} + + {% if content.field_tags.0 %} + + {% endif %} +
    +
    + + + {% if label %} + + {{ title_prefix }} + {{ label }} + {{ title_suffix }} + + {% endif %} + +
    + {{ content.field_description }} + {% if content.field_learning_package.0 %} + {{ content.field_learning_package.0 }} + {% endif %} + {{ content.field_course }} + {{ content.field_flash_card }} + {{ content.field_quiz }} +
    +
    + + diff --git a/web/themes/custom/perls/templates/node/node--podcast--full.html.twig b/web/themes/custom/perls/templates/node/node--podcast--full.html.twig new file mode 100644 index 0000000..39947ca --- /dev/null +++ b/web/themes/custom/perls/templates/node/node--podcast--full.html.twig @@ -0,0 +1,129 @@ +{# +/** + * @file + * Theme override to display a node. + * + * Available variables: + * - node: The node entity with limited access to object properties and methods. + * Only method names starting with "get", "has", or "is" and a few common + * methods such as "id", "label", and "bundle" are available. For example: + * - node.getCreatedTime() will return the node creation timestamp. + * - node.hasField('field_example') returns TRUE if the node bundle includes + * field_example. (This does not indicate the presence of a value in this + * field.) + * - node.isPublished() will return whether the node is published or not. + * Calling other methods, such as node.delete(), will result in an exception. + * See \Drupal\node\Entity\Node for a full list of public properties and + * methods for the node object. + * - label: (optional) The title of the node. + * - content: All node items. Use {{ content }} to print them all, + * or print a subset such as {{ content.field_example }}. Use + * {{ content|without('field_example') }} to temporarily suppress the printing + * of a given child element. + * - author_picture: The node author user entity, rendered using the "compact" + * view mode. + * - metadata: Metadata for this node. + * - date: (optional) Themed creation date field. + * - author_name: (optional) Themed author name field. + * - url: Direct URL of the current node. + * - display_submitted: Whether submission information should be displayed. + * - attributes: HTML attributes for the containing element. + * The attributes.class element may contain one or more of the following + * classes: + * - node: The current template type (also known as a "theming hook"). + * - node--type-[type]: The current node type. For example, if the node is an + * "Article" it would result in "node--type-article". Note that the machine + * name will often be in a short form of the human readable label. + * - node--view-mode-[view_mode]: The View Mode of the node; for example, a + * teaser would result in: "node--view-mode-teaser", and + * full: "node--view-mode-full". + * The following are controlled through the node publishing options. + * - node--promoted: Appears on nodes promoted to the front page. + * - node--sticky: Appears on nodes ordered above other non-sticky nodes in + * teaser listings. + * - node--unpublished: Appears on unpublished nodes visible only to site + * admins. + * - title_attributes: Same as attributes, except applied to the main title + * tag that appears in the template. + * - content_attributes: Same as attributes, except applied to the main + * content tag that appears in the template. + * - author_attributes: Same as attributes, except applied to the author of + * the node tag that appears in the template. + * - title_prefix: Additional output populated by modules, intended to be + * displayed in front of the main title tag that appears in the template. + * - title_suffix: Additional output populated by modules, intended to be + * displayed after the main title tag that appears in the template. + * - view_mode: View mode; for example, "teaser" or "full". + * - teaser: Flag for the teaser state. Will be true if view_mode is 'teaser'. + * - page: Flag for the full page state. Will be true if view_mode is 'full'. + * - readmore: Flag for more state. Will be true if the teaser content of the + * node cannot hold the main body content. + * - logged_in: Flag for authenticated user status. Will be true when the + * current user is a logged-in member. + * - is_admin: Flag for admin user status. Will be true when the current user + * is an administrator. + * + * @see template_preprocess_node() + */ +#} +{% + set classes = [ + 'c-node', + view_mode ? 'c-node--' ~ view_mode|clean_class, + 'c-node--' ~ node.bundle|clean_class, + view_mode ? 'c-node--' ~ view_mode|clean_class ~ '--' ~ node.bundle|clean_class, + node.isPromoted() ? 'is-promoted', + node.isSticky() ? 'is-sticky', + not node.isPublished() ? 'is-unpublished', + 'u-spacing--double' + ] +%} + +
    + {% if content.field_artwork.0 %} +
    + + {% else %} +
    + {% endif %} + + {{ content.flag_completed }} + {{ content.flag_bookmark }} + + {% if content.field_tags.0 %} + + {% endif %} +
    +
    + + + {% if label %} + + {{ title_prefix }} + {{ label }} + {{ title_suffix }} + + {% endif %} + +
    + {{ content| without('flag_bookmark', 'field_tags', 'field_artwork', 'id') }} +
    +
    + + diff --git a/web/themes/custom/perls/templates/node/node--podcast--tile.html.twig b/web/themes/custom/perls/templates/node/node--podcast--tile.html.twig new file mode 100644 index 0000000..0427726 --- /dev/null +++ b/web/themes/custom/perls/templates/node/node--podcast--tile.html.twig @@ -0,0 +1,167 @@ +{# +/** + * @file + * Theme override to display a node. + * + * Available variables: + * - node: The node entity with limited access to object properties and methods. + * Only method names starting with "get", "has", or "is" and a few common + * methods such as "id", "label", and "bundle" are available. For example: + * - node.getCreatedTime() will return the node creation timestamp. + * - node.hasField('field_example') returns TRUE if the node bundle includes + * field_example. (This does not indicate the presence of a value in this + * field.) + * - node.isPublished() will return whether the node is published or not. + * Calling other methods, such as node.delete(), will result in an exception. + * See \Drupal\node\Entity\Node for a full list of public properties and + * methods for the node object. + * - label: (optional) The title of the node. + * - content: All node items. Use {{ content }} to print them all, + * or print a subset such as {{ content.field_example }}. Use + * {{ content|without('field_example') }} to temporarily suppress the printing + * of a given child element. + * - author_picture: The node author user entity, rendered using the "compact" + * view mode. + * - metadata: Metadata for this node. + * - date: (optional) Themed creation date field. + * - author_name: (optional) Themed author name field. + * - url: Direct URL of the current node. + * - display_submitted: Whether submission information should be displayed. + * - attributes: HTML attributes for the containing element. + * The attributes.class element may contain one or more of the following + * classes: + * - node: The current template type (also known as a "theming hook"). + * - node--type-[type]: The current node type. For example, if the node is an + * "Article" it would result in "node--type-article". Note that the machine + * name will often be in a short form of the human readable label. + * - node--view-mode-[view_mode]: The View Mode of the node; for example, a + * teaser would result in: "node--view-mode-teaser", and + * full: "node--view-mode-full". + * The following are controlled through the node publishing options. + * - node--promoted: Appears on nodes promoted to the front page. + * - node--sticky: Appears on nodes ordered above other non-sticky nodes in + * teaser listings. + * - node--unpublished: Appears on unpublished nodes visible only to site + * admins. + * - title_attributes: Same as attributes, except applied to the main title + * tag that appears in the template. + * - content_attributes: Same as attributes, except applied to the main + * content tag that appears in the template. + * - author_attributes: Same as attributes, except applied to the author of + * the node tag that appears in the template. + * - title_prefix: Additional output populated by modules, intended to be + * displayed in front of the main title tag that appears in the template. + * - title_suffix: Additional output populated by modules, intended to be + * displayed after the main title tag that appears in the template. + * - view_mode: View mode; for example, "teaser" or "full". + * - teaser: Flag for the teaser state. Will be true if view_mode is 'teaser'. + * - page: Flag for the full page state. Will be true if view_mode is 'full'. + * - readmore: Flag for more state. Will be true if the teaser content of the + * node cannot hold the main body content. + * - logged_in: Flag for authenticated user status. Will be true when the + * current user is a logged-in member. + * - is_admin: Flag for admin user status. Will be true when the current user + * is an administrator. + * + * @see template_preprocess_node() + * + * @todo Remove the id attribute (or make it a class), because if that gets + * rendered twice on a page this is invalid CSS for example: two lists + * in different view modes. + */ +#} +{% + set classes = [ + 'c-node', + view_mode ? 'c-node--' ~ view_mode|clean_class, + 'c-node--' ~ node.bundle|clean_class, + view_mode ? 'c-node--' ~ view_mode|clean_class ~ '--' ~ node.bundle|clean_class, + node.isPromoted() ? 'is-promoted', + node.isSticky() ? 'is-sticky', + not node.isPublished() ? 'is-unpublished', + 'u-spacing--half' +] +%} + + {% if content.field_media_image.0 %} +
    + {% set image_uri = node.field_media_image.0.entity.field_media_image.entity.fileuri %} + + {% elseif content.field_artwork.0 %} +
    + + {% else %} +
    + {% endif %} + {{ content.flag_completed }} + {{ content.flag_bookmark }} + + + {% if content.recommendation_reason %} +
    + +
    + {{ content.recommendation_reason }} +
    +
    + {% endif %} + {% if episode_count %} +
    {{ episode_count }}
    + {% endif %} +
    + + +
    + {% if label and not page %} + + + {% if not node.isPublished() %} +
    + {{ 'Unpublished'|t }} +
    + {% endif %} + + {{ label }} + +
    + {% endif %} + {% if content.recommendation_reason %} + +
    + {{ content.recommendation_reason }} +
    + {% endif %} +
    +
    + {{ content| without('flag_bookmark', 'flag_completed', 'field_tags', 'field_image', 'field_media_image', 'flag_recommendation', 'recommendation_reason', 'field_artwork', 'id') }} +
    +
    + {% if content.field_tags.0 %} + + {% endif %} + diff --git a/web/themes/custom/perls/templates/node/node--podcast-episode--full.html.twig b/web/themes/custom/perls/templates/node/node--podcast-episode--full.html.twig new file mode 100644 index 0000000..8951d5f --- /dev/null +++ b/web/themes/custom/perls/templates/node/node--podcast-episode--full.html.twig @@ -0,0 +1,115 @@ +{# +/** + * @file + * Theme override to display a node. + * + * Available variables: + * - node: The node entity with limited access to object properties and methods. + * Only method names starting with "get", "has", or "is" and a few common + * methods such as "id", "label", and "bundle" are available. For example: + * - node.getCreatedTime() will return the node creation timestamp. + * - node.hasField('field_example') returns TRUE if the node bundle includes + * field_example. (This does not indicate the presence of a value in this + * field.) + * - node.isPublished() will return whether the node is published or not. + * Calling other methods, such as node.delete(), will result in an exception. + * See \Drupal\node\Entity\Node for a full list of public properties and + * methods for the node object. + * - label: (optional) The title of the node. + * - content: All node items. Use {{ content }} to print them all, + * or print a subset such as {{ content.field_example }}. Use + * {{ content|without('field_example') }} to temporarily suppress the printing + * of a given child element. + * - author_picture: The node author user entity, rendered using the "compact" + * view mode. + * - metadata: Metadata for this node. + * - date: (optional) Themed creation date field. + * - author_name: (optional) Themed author name field. + * - url: Direct URL of the current node. + * - display_submitted: Whether submission information should be displayed. + * - attributes: HTML attributes for the containing element. + * The attributes.class element may contain one or more of the following + * classes: + * - node: The current template type (also known as a "theming hook"). + * - node--type-[type]: The current node type. For example, if the node is an + * "Article" it would result in "node--type-article". Note that the machine + * name will often be in a short form of the human readable label. + * - node--view-mode-[view_mode]: The View Mode of the node; for example, a + * teaser would result in: "node--view-mode-teaser", and + * full: "node--view-mode-full". + * The following are controlled through the node publishing options. + * - node--promoted: Appears on nodes promoted to the front page. + * - node--sticky: Appears on nodes ordered above other non-sticky nodes in + * teaser listings. + * - node--unpublished: Appears on unpublished nodes visible only to site + * admins. + * - title_attributes: Same as attributes, except applied to the main title + * tag that appears in the template. + * - content_attributes: Same as attributes, except applied to the main + * content tag that appears in the template. + * - author_attributes: Same as attributes, except applied to the author of + * the node tag that appears in the template. + * - title_prefix: Additional output populated by modules, intended to be + * displayed in front of the main title tag that appears in the template. + * - title_suffix: Additional output populated by modules, intended to be + * displayed after the main title tag that appears in the template. + * - view_mode: View mode; for example, "teaser" or "full". + * - teaser: Flag for the teaser state. Will be true if view_mode is 'teaser'. + * - page: Flag for the full page state. Will be true if view_mode is 'full'. + * - readmore: Flag for more state. Will be true if the teaser content of the + * node cannot hold the main body content. + * - logged_in: Flag for authenticated user status. Will be true when the + * current user is a logged-in member. + * - is_admin: Flag for admin user status. Will be true when the current user + * is an administrator. + * + * @see template_preprocess_node() + * + * @todo Remove the id attribute (or make it a class), because if that gets + * rendered twice on a page this is invalid CSS for example: two lists + * in different view modes. + */ +#} +{% + set classes = [ + 'c-node', + view_mode ? 'c-node--' ~ view_mode|clean_class, + 'c-node--' ~ node.bundle|clean_class, + view_mode ? 'c-node--' ~ view_mode|clean_class ~ '--' ~ node.bundle|clean_class, + node.isPromoted() ? 'is-promoted', + node.isSticky() ? 'is-sticky', + not node.isPublished() ? 'is-unpublished', + 'u-spacing--double' + ] +%} + + +
    +
    + + {{ content.flag_completed }} + {{ content.flag_bookmark }} + + {% if content.field_tags.0 %} + + {% endif %} +
    +
    + + + {% if label %} + + {{ title_prefix }} + {{ label }} + {{ title_suffix }} + + {% endif %} + +
    + {{ content| without('flag_bookmark', 'flag_completed', 'field_tags') }} +
    +
    + + diff --git a/web/themes/custom/perls/templates/node/node--podcast-episode--tile.html.twig b/web/themes/custom/perls/templates/node/node--podcast-episode--tile.html.twig new file mode 100644 index 0000000..1fed29a --- /dev/null +++ b/web/themes/custom/perls/templates/node/node--podcast-episode--tile.html.twig @@ -0,0 +1,135 @@ +{# +/** + * @file + * Theme override to display a node. + * + * Available variables: + * - node: The node entity with limited access to object properties and methods. + * Only method names starting with "get", "has", or "is" and a few common + * methods such as "id", "label", and "bundle" are available. For example: + * - node.getCreatedTime() will return the node creation timestamp. + * - node.hasField('field_example') returns TRUE if the node bundle includes + * field_example. (This does not indicate the presence of a value in this + * field.) + * - node.isPublished() will return whether the node is published or not. + * Calling other methods, such as node.delete(), will result in an exception. + * See \Drupal\node\Entity\Node for a full list of public properties and + * methods for the node object. + * - label: (optional) The title of the node. + * - content: All node items. Use {{ content }} to print them all, + * or print a subset such as {{ content.field_example }}. Use + * {{ content|without('field_example') }} to temporarily suppress the printing + * of a given child element. + * - author_picture: The node author user entity, rendered using the "compact" + * view mode. + * - metadata: Metadata for this node. + * - date: (optional) Themed creation date field. + * - author_name: (optional) Themed author name field. + * - url: Direct URL of the current node. + * - display_submitted: Whether submission information should be displayed. + * - attributes: HTML attributes for the containing element. + * The attributes.class element may contain one or more of the following + * classes: + * - node: The current template type (also known as a "theming hook"). + * - node--type-[type]: The current node type. For example, if the node is an + * "Article" it would result in "node--type-article". Note that the machine + * name will often be in a short form of the human readable label. + * - node--view-mode-[view_mode]: The View Mode of the node; for example, a + * teaser would result in: "node--view-mode-teaser", and + * full: "node--view-mode-full". + * The following are controlled through the node publishing options. + * - node--promoted: Appears on nodes promoted to the front page. + * - node--sticky: Appears on nodes ordered above other non-sticky nodes in + * teaser listings. + * - node--unpublished: Appears on unpublished nodes visible only to site + * admins. + * - title_attributes: Same as attributes, except applied to the main title + * tag that appears in the template. + * - content_attributes: Same as attributes, except applied to the main + * content tag that appears in the template. + * - author_attributes: Same as attributes, except applied to the author of + * the node tag that appears in the template. + * - title_prefix: Additional output populated by modules, intended to be + * displayed in front of the main title tag that appears in the template. + * - title_suffix: Additional output populated by modules, intended to be + * displayed after the main title tag that appears in the template. + * - view_mode: View mode; for example, "teaser" or "full". + * - teaser: Flag for the teaser state. Will be true if view_mode is 'teaser'. + * - page: Flag for the full page state. Will be true if view_mode is 'full'. + * - readmore: Flag for more state. Will be true if the teaser content of the + * node cannot hold the main body content. + * - logged_in: Flag for authenticated user status. Will be true when the + * current user is a logged-in member. + * - is_admin: Flag for admin user status. Will be true when the current user + * is an administrator. + * + * @see template_preprocess_node() + * + * @todo Remove the id attribute (or make it a class), because if that gets + * rendered twice on a page this is invalid CSS for example: two lists + * in different view modes. + */ +#} +{% + set classes = [ + 'c-node', + view_mode ? 'c-node--' ~ view_mode|clean_class, + 'c-node--' ~ node.bundle|clean_class, + view_mode ? 'c-node--' ~ view_mode|clean_class ~ '--' ~ node.bundle|clean_class, + node.isPromoted() ? 'is-promoted', + node.isSticky() ? 'is-sticky', + not node.isPublished() ? 'is-unpublished', + 'u-spacing--half' +] +%} + +
    + {{ content.flag_completed }} + {{ content.flag_bookmark }} + + + {% if content.recommendation_reason %} +
    + +
    + {{ content.recommendation_reason }} +
    +
    + {% endif %} + {% if episode_count %} +
    {{ episode_count }}
    + {% endif %} +
    + + +
    + {% if label and not page %} + + + {% if not node.isPublished() %} +
    + {{ 'Unpublished'|t }} +
    + {% endif %} + + {{ label }} + +
    + {% endif %} + {% if content.recommendation_reason %} + +
    + {{ content.recommendation_reason }} +
    + {% endif %} +
    +
    + {{ content| without('flag_bookmark', 'flag_completed', 'field_tags', 'field_image', 'field_media_image', 'flag_recommendation', 'recommendation_reason', 'field_artwork') }} +
    + + {% if content.field_tags.0 %} + + {% endif %} + diff --git a/web/themes/custom/perls/templates/node/node--quiz--card.html.twig b/web/themes/custom/perls/templates/node/node--quiz--card.html.twig new file mode 100644 index 0000000..3af61cc --- /dev/null +++ b/web/themes/custom/perls/templates/node/node--quiz--card.html.twig @@ -0,0 +1,121 @@ +{# +/** + * @file + * Theme override to display a node. + * + * Available variables: + * - node: The node entity with limited access to object properties and methods. + * Only method names starting with "get", "has", or "is" and a few common + * methods such as "id", "label", and "bundle" are available. For example: + * - node.getCreatedTime() will return the node creation timestamp. + * - node.hasField('field_example') returns TRUE if the node bundle includes + * field_example. (This does not indicate the presence of a value in this + * field.) + * - node.isPublished() will return whether the node is published or not. + * Calling other methods, such as node.delete(), will result in an exception. + * See \Drupal\node\Entity\Node for a full list of public properties and + * methods for the node object. + * - label: (optional) The title of the node. + * - content: All node items. Use {{ content }} to print them all, + * or print a subset such as {{ content.field_example }}. Use + * {{ content|without('field_example') }} to temporarily suppress the printing + * of a given child element. + * - author_picture: The node author user entity, rendered using the "compact" + * view mode. + * - metadata: Metadata for this node. + * - date: (optional) Themed creation date field. + * - author_name: (optional) Themed author name field. + * - url: Direct URL of the current node. + * - display_submitted: Whether submission information should be displayed. + * - attributes: HTML attributes for the containing element. + * The attributes.class element may contain one or more of the following + * classes: + * - node: The current template type (also known as a "theming hook"). + * - node--type-[type]: The current node type. For example, if the node is an + * "Article" it would result in "node--type-article". Note that the machine + * name will often be in a short form of the human readable label. + * - node--view-mode-[view_mode]: The View Mode of the node; for example, a + * teaser would result in: "node--view-mode-teaser", and + * full: "node--view-mode-full". + * The following are controlled through the node publishing options. + * - node--promoted: Appears on nodes promoted to the front page. + * - node--sticky: Appears on nodes ordered above other non-sticky nodes in + * teaser listings. + * - node--unpublished: Appears on unpublished nodes visible only to site + * admins. + * - title_attributes: Same as attributes, except applied to the main title + * tag that appears in the template. + * - content_attributes: Same as attributes, except applied to the main + * content tag that appears in the template. + * - author_attributes: Same as attributes, except applied to the author of + * the node tag that appears in the template. + * - title_prefix: Additional output populated by modules, intended to be + * displayed in front of the main title tag that appears in the template. + * - title_suffix: Additional output populated by modules, intended to be + * displayed after the main title tag that appears in the template. + * - view_mode: View mode; for example, "teaser" or "full". + * - teaser: Flag for the teaser state. Will be true if view_mode is 'teaser'. + * - page: Flag for the full page state. Will be true if view_mode is 'full'. + * - readmore: Flag for more state. Will be true if the teaser content of the + * node cannot hold the main body content. + * - logged_in: Flag for authenticated user status. Will be true when the + * current user is a logged-in member. + * - is_admin: Flag for admin user status. Will be true when the current user + * is an administrator. + * + * @see template_preprocess_node() + * + * @todo Remove the id attribute (or make it a class), because if that gets + * rendered twice on a page this is invalid CSS for example: two lists + * in different view modes. + */ +#} +{% + set classes = [ + 'c-node', + view_mode ? 'c-node--' ~ view_mode|clean_class, + 'c-node--' ~ node.bundle|clean_class, + view_mode ? 'c-node--' ~ view_mode|clean_class ~ '--' ~ node.bundle|clean_class, + node.isPromoted() ? 'is-promoted', + node.isSticky() ? 'is-sticky', + not node.isPublished() ? 'is-unpublished', + ] +%} + +
    +
    + {% if header %} +
    + {{ header }} +
    + {% endif %} + {{ content.flag_completed }} + {{ content.flag_bookmark }} + {% if content.recommendation_reason %} +
    + +
    + {{ content.recommendation_reason }} +
    +
    + {% endif %} + + +
    + {% if label and not page %} + + {{ label }} + + {% endif %} +
    + + {{ content.field_option }} +
    + + {% if content.field_tags.0 %} + + {% endif %} + +
    diff --git a/web/themes/custom/perls/templates/node/node--row.html.twig b/web/themes/custom/perls/templates/node/node--row.html.twig new file mode 100644 index 0000000..4a27faa --- /dev/null +++ b/web/themes/custom/perls/templates/node/node--row.html.twig @@ -0,0 +1,103 @@ +{# +/** + * @file + * Theme override to display a node. + * + * Available variables: + * - node: The node entity with limited access to object properties and methods. + * Only method names starting with "get", "has", or "is" and a few common + * methods such as "id", "label", and "bundle" are available. For example: + * - node.getCreatedTime() will return the node creation timestamp. + * - node.hasField('field_example') returns TRUE if the node bundle includes + * field_example. (This does not indicate the presence of a value in this + * field.) + * - node.isPublished() will return whether the node is published or not. + * Calling other methods, such as node.delete(), will result in an exception. + * See \Drupal\node\Entity\Node for a full list of public properties and + * methods for the node object. + * - label: (optional) The title of the node. + * - content: All node items. Use {{ content }} to print them all, + * or print a subset such as {{ content.field_example }}. Use + * {{ content|without('field_example') }} to temporarily suppress the printing + * of a given child element. + * - author_picture: The node author user entity, rendered using the "compact" + * view mode. + * - metadata: Metadata for this node. + * - date: (optional) Themed creation date field. + * - author_name: (optional) Themed author name field. + * - url: Direct URL of the current node. + * - display_submitted: Whether submission information should be displayed. + * - attributes: HTML attributes for the containing element. + * The attributes.class element may contain one or more of the following + * classes: + * - node: The current template type (also known as a "theming hook"). + * - node--type-[type]: The current node type. For example, if the node is an + * "Article" it would result in "node--type-article". Note that the machine + * name will often be in a short form of the human readable label. + * - node--view-mode-[view_mode]: The View Mode of the node; for example, a + * teaser would result in: "node--view-mode-teaser", and + * full: "node--view-mode-full". + * The following are controlled through the node publishing options. + * - node--promoted: Appears on nodes promoted to the front page. + * - node--sticky: Appears on nodes ordered above other non-sticky nodes in + * teaser listings. + * - node--unpublished: Appears on unpublished nodes visible only to site + * admins. + * - title_attributes: Same as attributes, except applied to the main title + * tag that appears in the template. + * - content_attributes: Same as attributes, except applied to the main + * content tag that appears in the template. + * - author_attributes: Same as attributes, except applied to the author of + * the node tag that appears in the template. + * - title_prefix: Additional output populated by modules, intended to be + * displayed in front of the main title tag that appears in the template. + * - title_suffix: Additional output populated by modules, intended to be + * displayed after the main title tag that appears in the template. + * - view_mode: View mode; for example, "teaser" or "full". + * - teaser: Flag for the teaser state. Will be true if view_mode is 'teaser'. + * - page: Flag for the full page state. Will be true if view_mode is 'full'. + * - readmore: Flag for more state. Will be true if the teaser content of the + * node cannot hold the main body content. + * - logged_in: Flag for authenticated user status. Will be true when the + * current user is a logged-in member. + * - is_admin: Flag for admin user status. Will be true when the current user + * is an administrator. + * - node.field_main_image.entity.uri.value: to add image style use -> + * node.field_main_image.entity.uri.value | image_style('[image_style_name]') + * + * @see template_preprocess_node() + * + * @todo Remove the id attribute (or make it a class), because if that gets + * rendered twice on a page this is invalid CSS for example: two lists + * in different view modes. + */ +#} +{% + set classes = [ + 'c-node', + view_mode ? 'c-node--' ~ view_mode|clean_class, + 'c-node--' ~ node.bundle|clean_class, + view_mode ? 'c-node--' ~ view_mode|clean_class ~ '--' ~ node.bundle|clean_class, + node.isPromoted() ? 'is-promoted', + node.isSticky() ? 'is-sticky', + not node.isPublished() ? 'is-unpublished', +] +%} + + +
    + +
    + {% if label and not page %} + + + {{ label }} + + + {% endif %} + + {{ content | without('flag_bookmark', 'flag_completed') }} +
    + +
    + diff --git a/web/themes/custom/perls/templates/node/node--teaser.html.twig b/web/themes/custom/perls/templates/node/node--teaser.html.twig new file mode 100644 index 0000000..9063ba0 --- /dev/null +++ b/web/themes/custom/perls/templates/node/node--teaser.html.twig @@ -0,0 +1,130 @@ +{# +/** + * @file + * Theme override to display a node. + * + * Available variables: + * - node: The node entity with limited access to object properties and methods. + * Only method names starting with "get", "has", or "is" and a few common + * methods such as "id", "label", and "bundle" are available. For example: + * - node.getCreatedTime() will return the node creation timestamp. + * - node.hasField('field_example') returns TRUE if the node bundle includes + * field_example. (This does not indicate the presence of a value in this + * field.) + * - node.isPublished() will return whether the node is published or not. + * Calling other methods, such as node.delete(), will result in an exception. + * See \Drupal\node\Entity\Node for a full list of public properties and + * methods for the node object. + * - label: (optional) The title of the node. + * - content: All node items. Use {{ content }} to print them all, + * or print a subset such as {{ content.field_example }}. Use + * {{ content|without('field_example') }} to temporarily suppress the printing + * of a given child element. + * - author_picture: The node author user entity, rendered using the "compact" + * view mode. + * - metadata: Metadata for this node. + * - date: (optional) Themed creation date field. + * - author_name: (optional) Themed author name field. + * - url: Direct URL of the current node. + * - display_submitted: Whether submission information should be displayed. + * - attributes: HTML attributes for the containing element. + * The attributes.class element may contain one or more of the following + * classes: + * - node: The current template type (also known as a "theming hook"). + * - node--type-[type]: The current node type. For example, if the node is an + * "Article" it would result in "node--type-article". Note that the machine + * name will often be in a short form of the human readable label. + * - node--view-mode-[view_mode]: The View Mode of the node; for example, a + * teaser would result in: "node--view-mode-teaser", and + * full: "node--view-mode-full". + * The following are controlled through the node publishing options. + * - node--promoted: Appears on nodes promoted to the front page. + * - node--sticky: Appears on nodes ordered above other non-sticky nodes in + * teaser listings. + * - node--unpublished: Appears on unpublished nodes visible only to site + * admins. + * - title_attributes: Same as attributes, except applied to the main title + * tag that appears in the template. + * - content_attributes: Same as attributes, except applied to the main + * content tag that appears in the template. + * - author_attributes: Same as attributes, except applied to the author of + * the node tag that appears in the template. + * - title_prefix: Additional output populated by modules, intended to be + * displayed in front of the main title tag that appears in the template. + * - title_suffix: Additional output populated by modules, intended to be + * displayed after the main title tag that appears in the template. + * - view_mode: View mode; for example, "teaser" or "full". + * - teaser: Flag for the teaser state. Will be true if view_mode is 'teaser'. + * - page: Flag for the full page state. Will be true if view_mode is 'full'. + * - readmore: Flag for more state. Will be true if the teaser content of the + * node cannot hold the main body content. + * - logged_in: Flag for authenticated user status. Will be true when the + * current user is a logged-in member. + * - is_admin: Flag for admin user status. Will be true when the current user + * is an administrator. + * + * @see template_preprocess_node() + * + * @todo Remove the id attribute (or make it a class), because if that gets + * rendered twice on a page this is invalid CSS for example: two lists + * in different view modes. + */ +#} +{% + set classes = [ + 'c-node', + view_mode ? 'c-node--' ~ view_mode|clean_class, + 'c-node--' ~ node.bundle|clean_class, + view_mode ? 'c-node--' ~ view_mode|clean_class ~ '--' ~ node.bundle|clean_class, + node.isPromoted() ? 'is-promoted', + node.isSticky() ? 'is-sticky', + not node.isPublished() ? 'is-unpublished', + ] +%} +
    + {% if content.field_media_image.0 %} +
    + {% set image_uri = node.field_media_image.0.entity.field_media_image.entity.fileuri %} + + {% elseif content.field_artwork.0 %} +
    + + {% else %} +
    + {% endif %} + {% if label and not page %} +
    +
    +
    + {% if node.isPublished() %} + {{ 'Published'|t }} + {% else %} + {{ 'Unpublished'|t }} + {% endif %} +
    + Edit +
    + + {% if label and not page %} + + + {{ label }} + + + {% endif %} +
    + {% endif %} + + +
    +
    diff --git a/web/themes/custom/perls/templates/node/node--test--card.html.twig b/web/themes/custom/perls/templates/node/node--test--card.html.twig new file mode 100644 index 0000000..d99d200 --- /dev/null +++ b/web/themes/custom/perls/templates/node/node--test--card.html.twig @@ -0,0 +1,84 @@ +{# +/** + * @file + * Theme override to display a test card. + * + * Available variables: + * - node: The node entity with limited access to object properties and methods. + * Only method names starting with "get", "has", or "is" and a few common + * methods such as "id", "label", and "bundle" are available. For example: + * - node.getCreatedTime() will return the node creation timestamp. + * - node.hasField('field_example') returns TRUE if the node bundle includes + * field_example. (This does not indicate the presence of a value in this + * field.) + * - node.isPublished() will return whether the node is published or not. + * Calling other methods, such as node.delete(), will result in an exception. + * See \Drupal\node\Entity\Node for a full list of public properties and + * methods for the node object. + * - label: (optional) The title of the node. + * - content: All node items. Use {{ content }} to print them all, + * or print a subset such as {{ content.field_example }}. Use + * {{ content|without('field_example') }} to temporarily suppress the printing + * of a given child element. + * - author_picture: The node author user entity, rendered using the "compact" + * view mode. + * - metadata: Metadata for this node. + * - date: (optional) Themed creation date field. + * - author_name: (optional) Themed author name field. + * - url: Direct URL of the current node. + * - display_submitted: Whether submission information should be displayed. + * - attributes: HTML attributes for the containing element. + * The attributes.class element may contain one or more of the following + * classes: + * - node: The current template type (also known as a "theming hook"). + * - node--type-[type]: The current node type. For example, if the node is an + * "Article" it would result in "node--type-article". Note that the machine + * name will often be in a short form of the human readable label. + * - node--view-mode-[view_mode]: The View Mode of the node; for example, a + * teaser would result in: "node--view-mode-teaser", and + * full: "node--view-mode-full". + * The following are controlled through the node publishing options. + * - node--promoted: Appears on nodes promoted to the front page. + * - node--sticky: Appears on nodes ordered above other non-sticky nodes in + * teaser listings. + * - node--unpublished: Appears on unpublished nodes visible only to site + * admins. + * - title_attributes: Same as attributes, except applied to the main title + * tag that appears in the template. + * - content_attributes: Same as attributes, except applied to the main + * content tag that appears in the template. + * - author_attributes: Same as attributes, except applied to the author of + * the node tag that appears in the template. + * - title_prefix: Additional output populated by modules, intended to be + * displayed in front of the main title tag that appears in the template. + * - title_suffix: Additional output populated by modules, intended to be + * displayed after the main title tag that appears in the template. + * - view_mode: View mode; for example, "teaser" or "full". + * - teaser: Flag for the teaser state. Will be true if view_mode is 'teaser'. + * - page: Flag for the full page state. Will be true if view_mode is 'full'. + * - readmore: Flag for more state. Will be true if the teaser content of the + * node cannot hold the main body content. + * - logged_in: Flag for authenticated user status. Will be true when the + * current user is a logged-in member. + * - is_admin: Flag for admin user status. Will be true when the current user + * is an administrator. + * + * @see template_preprocess_node() + * + */ +#} +{% + set classes = [ + 'c-node', + view_mode ? 'c-node--' ~ view_mode|clean_class, + 'c-node--' ~ node.bundle|clean_class, + view_mode ? 'c-node--' ~ view_mode|clean_class ~ '--' ~ node.bundle|clean_class, + node.isPromoted() ? 'is-promoted', + node.isSticky() ? 'is-sticky', + not node.isPublished() ? 'is-unpublished', +] +%} + + {{ content.flag_completed }} + {{ content.field_quiz }} + diff --git a/web/themes/custom/perls/templates/node/node--test--teaser.html.twig b/web/themes/custom/perls/templates/node/node--test--teaser.html.twig new file mode 100644 index 0000000..5d37b9a --- /dev/null +++ b/web/themes/custom/perls/templates/node/node--test--teaser.html.twig @@ -0,0 +1 @@ +{% extends "@perls/node/node--teaser.html.twig" %} diff --git a/web/themes/custom/perls/templates/node/node--test--tile.html.twig b/web/themes/custom/perls/templates/node/node--test--tile.html.twig new file mode 100644 index 0000000..0ff54ba --- /dev/null +++ b/web/themes/custom/perls/templates/node/node--test--tile.html.twig @@ -0,0 +1 @@ +{% extends "@perls/node/node--tile.html.twig" %} diff --git a/web/themes/custom/perls/templates/node/node--tile.html.twig b/web/themes/custom/perls/templates/node/node--tile.html.twig new file mode 100644 index 0000000..edd09db --- /dev/null +++ b/web/themes/custom/perls/templates/node/node--tile.html.twig @@ -0,0 +1,164 @@ +{# +/** + * @file + * Theme override to display a node. + * + * Available variables: + * - node: The node entity with limited access to object properties and methods. + * Only method names starting with "get", "has", or "is" and a few common + * methods such as "id", "label", and "bundle" are available. For example: + * - node.getCreatedTime() will return the node creation timestamp. + * - node.hasField('field_example') returns TRUE if the node bundle includes + * field_example. (This does not indicate the presence of a value in this + * field.) + * - node.isPublished() will return whether the node is published or not. + * Calling other methods, such as node.delete(), will result in an exception. + * See \Drupal\node\Entity\Node for a full list of public properties and + * methods for the node object. + * - label: (optional) The title of the node. + * - content: All node items. Use {{ content }} to print them all, + * or print a subset such as {{ content.field_example }}. Use + * {{ content|without('field_example') }} to temporarily suppress the printing + * of a given child element. + * - author_picture: The node author user entity, rendered using the "compact" + * view mode. + * - metadata: Metadata for this node. + * - date: (optional) Themed creation date field. + * - author_name: (optional) Themed author name field. + * - url: Direct URL of the current node. + * - display_submitted: Whether submission information should be displayed. + * - attributes: HTML attributes for the containing element. + * The attributes.class element may contain one or more of the following + * classes: + * - node: The current template type (also known as a "theming hook"). + * - node--type-[type]: The current node type. For example, if the node is an + * "Article" it would result in "node--type-article". Note that the machine + * name will often be in a short form of the human readable label. + * - node--view-mode-[view_mode]: The View Mode of the node; for example, a + * teaser would result in: "node--view-mode-teaser", and + * full: "node--view-mode-full". + * The following are controlled through the node publishing options. + * - node--promoted: Appears on nodes promoted to the front page. + * - node--sticky: Appears on nodes ordered above other non-sticky nodes in + * teaser listings. + * - node--unpublished: Appears on unpublished nodes visible only to site + * admins. + * - title_attributes: Same as attributes, except applied to the main title + * tag that appears in the template. + * - content_attributes: Same as attributes, except applied to the main + * content tag that appears in the template. + * - author_attributes: Same as attributes, except applied to the author of + * the node tag that appears in the template. + * - title_prefix: Additional output populated by modules, intended to be + * displayed in front of the main title tag that appears in the template. + * - title_suffix: Additional output populated by modules, intended to be + * displayed after the main title tag that appears in the template. + * - view_mode: View mode; for example, "teaser" or "full". + * - teaser: Flag for the teaser state. Will be true if view_mode is 'teaser'. + * - page: Flag for the full page state. Will be true if view_mode is 'full'. + * - readmore: Flag for more state. Will be true if the teaser content of the + * node cannot hold the main body content. + * - logged_in: Flag for authenticated user status. Will be true when the + * current user is a logged-in member. + * - is_admin: Flag for admin user status. Will be true when the current user + * is an administrator. + * + * @see template_preprocess_node() + * + * @todo Remove the id attribute (or make it a class), because if that gets + * rendered twice on a page this is invalid CSS for example: two lists + * in different view modes. + */ +#} +{% + set classes = [ + 'c-node', + view_mode ? 'c-node--' ~ view_mode|clean_class, + 'c-node--' ~ node.bundle|clean_class, + view_mode ? 'c-node--' ~ view_mode|clean_class ~ '--' ~ node.bundle|clean_class, + node.isPromoted() ? 'is-promoted', + node.isSticky() ? 'is-sticky', + not node.isPublished() ? 'is-unpublished', + 'u-spacing--half' +] +%} + + {% if content.field_media_image.0 %} +
    + {% set image_uri = node.field_media_image.0.entity.field_media_image.entity.fileuri %} + + {% elseif content.field_artwork.0 %} +
    + + {% else %} +
    + {% endif %} + + {{ content.flag_completed }} + {{ content.flag_bookmark }} + +
    + {% if label and not page %} + + {% if not node.isPublished() %} +
    + {{ 'Unpublished'|t }} +
    + {% endif %} + + {{ label }} + +
    + {% endif %} + {% if content.recommendation_reason %} + +
    + {{ content.recommendation_reason }} +
    + {% endif %} +
    +
    + {{ content| without('flag_bookmark', 'flag_completed', 'field_tags', 'field_image', 'field_media_image', 'flag_recommendation', 'recommendation_reason', 'field_artwork', 'id') }} +
    +
    + {% if content.field_tags.0 %} + + {% endif %} + diff --git a/web/themes/custom/perls/templates/node/node--tip-card--card.html.twig b/web/themes/custom/perls/templates/node/node--tip-card--card.html.twig new file mode 100644 index 0000000..c1b201b --- /dev/null +++ b/web/themes/custom/perls/templates/node/node--tip-card--card.html.twig @@ -0,0 +1,120 @@ +{# +/** + * @file + * Theme override to display a node. + * + * Available variables: + * - node: The node entity with limited access to object properties and methods. + * Only method names starting with "get", "has", or "is" and a few common + * methods such as "id", "label", and "bundle" are available. For example: + * - node.getCreatedTime() will return the node creation timestamp. + * - node.hasField('field_example') returns TRUE if the node bundle includes + * field_example. (This does not indicate the presence of a value in this + * field.) + * - node.isPublished() will return whether the node is published or not. + * Calling other methods, such as node.delete(), will result in an exception. + * See \Drupal\node\Entity\Node for a full list of public properties and + * methods for the node object. + * - label: (optional) The title of the node. + * - content: All node items. Use {{ content }} to print them all, + * or print a subset such as {{ content.field_example }}. Use + * {{ content|without('field_example') }} to temporarily suppress the printing + * of a given child element. + * - author_picture: The node author user entity, rendered using the "compact" + * view mode. + * - metadata: Metadata for this node. + * - date: (optional) Themed creation date field. + * - author_name: (optional) Themed author name field. + * - url: Direct URL of the current node. + * - display_submitted: Whether submission information should be displayed. + * - attributes: HTML attributes for the containing element. + * The attributes.class element may contain one or more of the following + * classes: + * - node: The current template type (also known as a "theming hook"). + * - node--type-[type]: The current node type. For example, if the node is an + * "Article" it would result in "node--type-article". Note that the machine + * name will often be in a short form of the human readable label. + * - node--view-mode-[view_mode]: The View Mode of the node; for example, a + * teaser would result in: "node--view-mode-teaser", and + * full: "node--view-mode-full". + * The following are controlled through the node publishing options. + * - node--promoted: Appears on nodes promoted to the front page. + * - node--sticky: Appears on nodes ordered above other non-sticky nodes in + * teaser listings. + * - node--unpublished: Appears on unpublished nodes visible only to site + * admins. + * - title_attributes: Same as attributes, except applied to the main title + * tag that appears in the template. + * - content_attributes: Same as attributes, except applied to the main + * content tag that appears in the template. + * - author_attributes: Same as attributes, except applied to the author of + * the node tag that appears in the template. + * - title_prefix: Additional output populated by modules, intended to be + * displayed in front of the main title tag that appears in the template. + * - title_suffix: Additional output populated by modules, intended to be + * displayed after the main title tag that appears in the template. + * - view_mode: View mode; for example, "teaser" or "full". + * - teaser: Flag for the teaser state. Will be true if view_mode is 'teaser'. + * - page: Flag for the full page state. Will be true if view_mode is 'full'. + * - readmore: Flag for more state. Will be true if the teaser content of the + * node cannot hold the main body content. + * - logged_in: Flag for authenticated user status. Will be true when the + * current user is a logged-in member. + * - is_admin: Flag for admin user status. Will be true when the current user + * is an administrator. + * + * @see template_preprocess_node() + * + * @todo Remove the id attribute (or make it a class), because if that gets + * rendered twice on a page this is invalid CSS for example: two lists + * in different view modes. + */ +#} +{% + set classes = [ + 'c-node', + view_mode ? 'c-node--' ~ view_mode|clean_class, + 'c-node--' ~ node.bundle|clean_class, + view_mode ? 'c-node--' ~ view_mode|clean_class ~ '--' ~ node.bundle|clean_class, + node.isPromoted() ? 'is-promoted', + node.isSticky() ? 'is-sticky', + not node.isPublished() ? 'is-unpublished', + ] +%} + +
    +
    + {{ content.flag_completed }} + {{ content.flag_bookmark }} + {% if content.recommendation_reason %} +
    + +
    + {{ content.recommendation_reason }} +
    +
    + {% endif %} + + +
    + {% if label and not page %} + + + {{ label }} + + + {% endif %} +
    + +
    + {{ content.field_card_front }} +
    +
    + + {% if content.field_tags.0 %} + + {% endif %} +
    + diff --git a/web/themes/custom/perls/templates/node/node.html.twig b/web/themes/custom/perls/templates/node/node.html.twig new file mode 100644 index 0000000..10845a8 --- /dev/null +++ b/web/themes/custom/perls/templates/node/node.html.twig @@ -0,0 +1,168 @@ +{# +/** + * @file + * Theme override to display a node. + * + * Available variables: + * - node: The node entity with limited access to object properties and methods. + * Only method names starting with "get", "has", or "is" and a few common + * methods such as "id", "label", and "bundle" are available. For example: + * - node.getCreatedTime() will return the node creation timestamp. + * - node.hasField('field_example') returns TRUE if the node bundle includes + * field_example. (This does not indicate the presence of a value in this + * field.) + * - node.isPublished() will return whether the node is published or not. + * Calling other methods, such as node.delete(), will result in an exception. + * See \Drupal\node\Entity\Node for a full list of public properties and + * methods for the node object. + * - label: (optional) The title of the node. + * - content: All node items. Use {{ content }} to print them all, + * or print a subset such as {{ content.field_example }}. Use + * {{ content|without('field_example') }} to temporarily suppress the printing + * of a given child element. + * - author_picture: The node author user entity, rendered using the "compact" + * view mode. + * - metadata: Metadata for this node. + * - date: (optional) Themed creation date field. + * - author_name: (optional) Themed author name field. + * - url: Direct URL of the current node. + * - display_submitted: Whether submission information should be displayed. + * - attributes: HTML attributes for the containing element. + * The attributes.class element may contain one or more of the following + * classes: + * - node: The current template type (also known as a "theming hook"). + * - node--type-[type]: The current node type. For example, if the node is an + * "Article" it would result in "node--type-article". Note that the machine + * name will often be in a short form of the human readable label. + * - node--view-mode-[view_mode]: The View Mode of the node; for example, a + * teaser would result in: "node--view-mode-teaser", and + * full: "node--view-mode-full". + * The following are controlled through the node publishing options. + * - node--promoted: Appears on nodes promoted to the front page. + * - node--sticky: Appears on nodes ordered above other non-sticky nodes in + * teaser listings. + * - node--unpublished: Appears on unpublished nodes visible only to site + * admins. + * - title_attributes: Same as attributes, except applied to the main title + * tag that appears in the template. + * - content_attributes: Same as attributes, except applied to the main + * content tag that appears in the template. + * - author_attributes: Same as attributes, except applied to the author of + * the node tag that appears in the template. + * - title_prefix: Additional output populated by modules, intended to be + * displayed in front of the main title tag that appears in the template. + * - title_suffix: Additional output populated by modules, intended to be + * displayed after the main title tag that appears in the template. + * - view_mode: View mode; for example, "teaser" or "full". + * - teaser: Flag for the teaser state. Will be true if view_mode is 'teaser'. + * - page: Flag for the full page state. Will be true if view_mode is 'full'. + * - readmore: Flag for more state. Will be true if the teaser content of the + * node cannot hold the main body content. + * - logged_in: Flag for authenticated user status. Will be true when the + * current user is a logged-in member. + * - is_admin: Flag for admin user status. Will be true when the current user + * is an administrator. + * + * @see template_preprocess_node() + * + * @todo Remove the id attribute (or make it a class), because if that gets + * rendered twice on a page this is invalid CSS for example: two lists + * in different view modes. + */ +#} +{% + set classes = [ + 'c-node', + view_mode ? 'c-node--' ~ view_mode|clean_class, + 'c-node--' ~ node.bundle|clean_class, + view_mode ? 'c-node--' ~ view_mode|clean_class ~ '--' ~ node.bundle|clean_class, + node.isPromoted() ? 'is-promoted', + node.isSticky() ? 'is-sticky', + not node.isPublished() ? 'is-unpublished', + 'u-spacing--double' + ] +%} + +
    + {% if content.field_media_image.0 %} +
    + {% set image_uri = node.field_media_image.0.entity.field_media_image.entity.fileuri %} + + {% else %} +
    + {% endif %} + + {{ content.flag_completed }} + {{ content.flag_bookmark }} + + {% if content.field_tags.0 %} + + {% endif %} +
    +
    + + + {% if label %} + + {{ title_prefix }} + {{ label }} + {{ title_suffix }} + + {% endif %} + +
    + {{ content.field_description }} + {{ content.field_body }} + {{ content.field_file }} + {{ content.field_learning_content }} + {{ content.field_card_front }} + {{ content.field_card_back }} + {{ content.field_options }} + {% if field_link_type %} + {% if field_link_type != 'custom' %} + Read more + {% else %} + Launch +
    This content may only be available in the mobile app.
    + {% endif %} + {% endif %} + {% if content.completed_manually %} + {{ content.completed_manually }} + {% endif %} + +
    +
    + + +{% if content.field_comments[0] %} +
    + {% + set modal_options = { + width: 800, + dialogClass: 'dialog--comment', + position: { + my: 'center top', + at: 'center top+10%' + }, + } + %} + {% set button_style = "display: inline-block;" %} + {{ 'View comments'|t }} +
    +{% endif %} diff --git a/web/themes/custom/perls/templates/user/user--card.html.twig b/web/themes/custom/perls/templates/user/user--card.html.twig new file mode 100644 index 0000000..89c9b3b --- /dev/null +++ b/web/themes/custom/perls/templates/user/user--card.html.twig @@ -0,0 +1,52 @@ +{# +/** + * @file + * Theme override to present all user data. + * + * This template is used when viewing a registered user's page, + * e.g., example.com/user/123. 123 being the user's ID. + * + * Available variables: + * - content: A list of content items. Use 'content' to print all content, or + * print a subset such as 'content.field_example'. Fields attached to a user + * such as 'user_picture' are available as 'content.user_picture'. + * - attributes: HTML attributes for the container element. + * - user: A Drupal User entity. + * - view_mode: display mode of user. + * - created: date of creation. Format of date example 'Friday, June 1, 2019'. + * - url: url to edit page of user. + * + * @see template_preprocess_user() + */ +#} + +{% + set classes = [ + 'c-user-profile', + view_mode ? 'c-user-profile--' ~ view_mode|clean_class, + 'c-user-profile--' ~ role|clean_class, + view_mode ? 'c-user--' ~ view_mode|clean_class ~ '--' ~ role|clean_class, +] +%} + + + diff --git a/web/themes/custom/perls/templates/views/views-mini-pager.html.twig b/web/themes/custom/perls/templates/views/views-mini-pager.html.twig new file mode 100644 index 0000000..1c34ba4 --- /dev/null +++ b/web/themes/custom/perls/templates/views/views-mini-pager.html.twig @@ -0,0 +1,41 @@ +{# +/** + * @file + * Theme override for a views mini-c-pager. + * + * Available variables: + * - items: List of c-pager items. + * + * @see template_preprocess_views_mini_c-pager() + */ +#} +{% if items.previous or items.next %} + +{% endif %} diff --git a/web/themes/custom/perls/templates/views/views-view--content_for_review.html.twig b/web/themes/custom/perls/templates/views/views-view--content_for_review.html.twig new file mode 100644 index 0000000..fe1f195 --- /dev/null +++ b/web/themes/custom/perls/templates/views/views-view--content_for_review.html.twig @@ -0,0 +1,129 @@ +{# +/** + * @file + * Theme override for a main view template. + * + * Available variables: + * - attributes: Remaining HTML attributes for the element. + * - css_name: A css-safe version of the view name. + * - css_class: The user-specified classes names, if any. + * - header: The optional header. + * - footer: The optional footer. + * - rows: The results of the view query, if any. + * - empty: The content to display if there are no rows. + * - pager: The optional pager next/prev links to display. + * - exposed: Exposed widget form/info to display. + * - feed_icons: Optional feed icons to display. + * - more: An optional link to the next page of results. + * - title: Title of the view, only used when displaying in the admin preview. + * - title_prefix: Additional output populated by modules, intended to be + * displayed in front of the view title. + * - title_suffix: Additional output populated by modules, intended to be + * displayed after the view title. + * - attachment_before: An optional attachment view to be displayed before the + * view content. + * - attachment_after: An optional attachment view to be displayed after the + * view content. + * - dom_id: Unique id for every view being printed to give unique class for + * Javascript. + * + * @see template_preprocess_views_view() + */ +#} +{% + set classes = [ + 'c-view', + 'c-view--manage-content', + 'c-content-list', + 'c-view--' ~ id|clean_class, + 'c-view-id--' ~ id, + 'c-view-display-id--' ~ display_id, + dom_id ? 'js-view-dom-id-' ~ dom_id, + 'u-spacing', +] +%} + +{% set extra_title %} + {% if view.exposedInput is empty %} + {% trans %}All {{ view.getTitle() }}{% endtrans %} + {% else %} + {% trans %}Filtered {{ view.getTitle() }}{% endtrans %} + {% endif %} +{% endset %} + + + {% if header or title or exposed %} +
    + {% if header %} +
    + {{ header }} +
    + {% elseif title %} +
    + {% if title_prefix %} + {{ title_prefix }} + {% endif %} + + {{ title }} + + {% if title_suffix %} + {{ title_suffix }} + {% endif %} +
    + {% endif %} + + {% if exposed %} +
    + {% if extra_title %} +
    + {{ extra_title|trim|spaceless }} +
    + {% endif %} + {{ exposed }} +
    + {% endif %} +
    + {% endif %} + + {% if attachment_before %} +
    + {{ attachment_before }} +
    + {% endif %} + +
    + {% if rows %} +
    + {{ rows }} +
    + {% elseif empty %} +
    + {{ empty }} +
    + {% endif %} + + {% if footer %} +
    + {{ footer }} +
    + {% endif %} + + {% if pager %} +
    + {{ pager }} +
    + {% endif %} + + {% if more %} +
    + {{ more }} +
    + {% endif %} +
    + + {% if attachment_after %} +
    + {{ attachment_after }} +
    + {% endif %} +
    diff --git a/web/themes/custom/perls/templates/views/views-view-table.html.twig b/web/themes/custom/perls/templates/views/views-view-table.html.twig new file mode 100644 index 0000000..25fe4ed --- /dev/null +++ b/web/themes/custom/perls/templates/views/views-view-table.html.twig @@ -0,0 +1,131 @@ +{# +/** + * @file + * Theme override for displaying a view as a table. + * + * Available variables: + * - attributes: Remaining HTML attributes for the element. + * - class: HTML classes that can be used to style contextually through CSS. + * - title : The title of this group of rows. + * - header: The table header columns. + * - attributes: Remaining HTML attributes for the element. + * - content: HTML classes to apply to each header cell, indexed by + * the header's key. + * - default_classes: A flag indicating whether default classes should be + * used. + * - caption_needed: Is the caption tag needed. + * - caption: The caption for this table. + * - accessibility_description: Extended description for the table details. + * - accessibility_summary: Summary for the table details. + * - rows: Table row items. Rows are keyed by row number. + * - attributes: HTML classes to apply to each row. + * - columns: Row column items. Columns are keyed by column number. + * - attributes: HTML classes to apply to each column. + * - content: The column content. + * - default_classes: A flag indicating whether default classes should be + * used. + * - responsive: A flag indicating whether table is responsive. + * - sticky: A flag indicating whether table header is sticky. + * + * @see template_preprocess_views_view_table() + */ +#} +{% + set classes = [ + 'views-table', + 'views-view-table', + 'cols-' ~ header|length, + responsive ? 'responsive-enabled', + sticky ? 'sticky-enabled', + ] +%} + +
    +
    + {% if caption_needed %} +
    + {% if caption %} + {{ caption }} + {% else %} + {{ title }} + {% endif %} + {% if (summary is not empty) or (description is not empty) %} +
    + {% if summary is not empty %} + {{ summary }} + {% endif %} + {% if description is not empty %} + {{ description }} + {% endif %} +
    + {% endif %} +
    + {% endif %} + + {% if header %} + + + {% for key, column in header %} + {% if column.default_classes %} + {% + set column_classes = [ + 'views-field', + 'views-field-' ~ fields[key], + ] + %} + {% endif %} + + {%- if column.wrapper_element -%} + <{{ column.wrapper_element }}> + {%- if column.url -%} + {{ column.content }}{{ column.sort_indicator }} + {%- else -%} + {{ column.content }}{{ column.sort_indicator }} + {%- endif -%} + + {%- else -%} + {%- if column.url -%} + {{ column.content }}{{ column.sort_indicator }} + {%- else -%} + {{- column.content }}{{ column.sort_indicator }} + {%- endif -%} + {%- endif -%} + + {% endfor %} + + + {% endif %} + + {% for row in rows %} + + {% for key, column in row.columns %} + {% if column.default_classes %} + {% + set column_classes = [ + 'views-field' + ] + %} + {% for field in column.fields %} + {% set column_classes = column_classes|merge(['views-field-' ~ field]) %} + {% endfor %} + {% endif %} + + {%- if column.wrapper_element -%} + <{{ column.wrapper_element }}> + {% for content in column.content %} + {{ content.separator }}{{ content.field_output }} + {% endfor %} + + {%- else -%} + {% for content in column.content %} + {{- content.separator }}{{ content.field_output -}} + {% endfor %} + {%- endif %} + + {% endfor %} + + {% endfor %} + + +
    +
    diff --git a/web/themes/custom/perls/templates/views/views-view.html.twig b/web/themes/custom/perls/templates/views/views-view.html.twig new file mode 100644 index 0000000..3837728 --- /dev/null +++ b/web/themes/custom/perls/templates/views/views-view.html.twig @@ -0,0 +1,116 @@ +{# +/** + * @file + * Theme override for a main view template. + * + * Available variables: + * - attributes: Remaining HTML attributes for the element. + * - css_name: A css-safe version of the view name. + * - css_class: The user-specified classes names, if any. + * - header: The optional header. + * - footer: The optional footer. + * - rows: The results of the view query, if any. + * - empty: The content to display if there are no rows. + * - pager: The optional pager next/prev links to display. + * - exposed: Exposed widget form/info to display. + * - feed_icons: Optional feed icons to display. + * - more: An optional link to the next page of results. + * - title: Title of the view, only used when displaying in the admin preview. + * - title_prefix: Additional output populated by modules, intended to be + * displayed in front of the view title. + * - title_suffix: Additional output populated by modules, intended to be + * displayed after the view title. + * - attachment_before: An optional attachment view to be displayed before the + * view content. + * - attachment_after: An optional attachment view to be displayed after the + * view content. + * - dom_id: Unique id for every view being printed to give unique class for + * Javascript. + * + * @see template_preprocess_views_view() + */ +#} +{% + set classes = [ + 'c-view', + 'c-view--' ~ id|clean_class, + 'c-view-id--' ~ id, + 'c-view-display-id--' ~ display_id, + dom_id ? 'js-view-dom-id-' ~ dom_id, + 'u-spacing', + ] +%} + +{% apply spaceless %} + + {% if header or title or exposed %} +
    + {% if header %} +
    + {{ header }} +
    + {% elseif title %} +
    + {% if title_prefix %} + {{ title_prefix }} + {% endif %} + + {{ title }} + + {% if title_suffix %} + {{ title_suffix }} + {% endif %} +
    + {% endif %} + + {% if exposed %} +
    + {{ exposed }} +
    + {% endif %} +
    + {% endif %} + + {% if attachment_before %} +
    + {{ attachment_before }} +
    + {% endif %} + +
    + {% if rows %} +
    + {{ rows }} +
    + {% elseif empty %} +
    + {{ empty }} +
    + {% endif %} + + {% if pager %} +
    + {{ pager }} +
    + {% endif %} + + {% if more %} +
    + {{ more }} +
    + {% endif %} +
    + + {% if attachment_after %} +
    + {{ attachment_after }} +
    + {% endif %} + + {% if footer %} +
    + {{ footer }} +
    + {% endif %} +
    +{% endapply %} diff --git a/web/themes/custom/perls_content_manager/favicon.ico b/web/themes/custom/perls_content_manager/favicon.ico new file mode 100644 index 0000000..7cb4a42 Binary files /dev/null and b/web/themes/custom/perls_content_manager/favicon.ico differ diff --git a/web/themes/custom/perls_content_manager/logo.svg b/web/themes/custom/perls_content_manager/logo.svg new file mode 100644 index 0000000..dfd695f --- /dev/null +++ b/web/themes/custom/perls_content_manager/logo.svg @@ -0,0 +1,3 @@ + + + diff --git a/web/themes/custom/perls_content_manager/perls_content_manager.info.yml b/web/themes/custom/perls_content_manager/perls_content_manager.info.yml new file mode 100644 index 0000000..5c98180 --- /dev/null +++ b/web/themes/custom/perls_content_manager/perls_content_manager.info.yml @@ -0,0 +1,15 @@ +name: 'Perls: Content manager' +type: theme +description: This a subtheme of content manager role. +core: 8.x +core_version_requirement: ^8 || ^9 +base theme: perls +# Regions +regions: + header: Header + highlighted: Highlighted + content: Content + sidebar_first: First sidebar + sidebar_second: Second sidebar + footer: Footer + inactive: 'Inactive (this region is not printed, blocks here are placed programatically).' diff --git a/web/themes/custom/perls_content_manager/perls_content_manager.theme b/web/themes/custom/perls_content_manager/perls_content_manager.theme new file mode 100644 index 0000000..1115e73 --- /dev/null +++ b/web/themes/custom/perls_content_manager/perls_content_manager.theme @@ -0,0 +1,77 @@ + $result) { + // If the result is not a node, then don't bother doing anything. + if (!($result->_entity instanceof NodeInterface) || !isset($variables['rows'][$row_index])) { + continue; + } + + /** @var \Drupal\node\NodeInterface $node */ + $node = $result->_entity; + $row = &$variables['rows'][$row_index]; + $classes = []; + + if ($node->isPromoted()) { + $classes[] = 'promoted'; + } + + if ($node->isSticky()) { + $classes[] = 'sticky'; + } + + if (!$node->isPublished()) { + $classes[] = 'unpublished'; + } + + if (isset($row['attributes']['class'])) { + array_unshift($classes, $row['attributes']['class']); + } + + $row['attributes']['class'] = implode(' ', $classes); + $row['attributes']['title'] = _perls_content_manager_row_tip($node); + } +} + +/** + * Generates a tooltip for a node. + * + * @param \Drupal\node\NodeInterface $node + * The node. + * + * @return string|null + * The tooltip to show when hovering over the node; NULL for no tip. + */ +function _perls_content_manager_row_tip(NodeInterface $node) { + $context = [ + '@type' => $node->type->entity->label(), + ]; + + if (!$node->isPublished()) { + return t('This @type is not published; learners cannot see it.', $context); + } + elseif ($node->isPromoted() && $node->isSticky()) { + return t('This @type is both promoted and sticky; it is highly visible to learners.', $context); + } + elseif ($node->isPromoted()) { + return t('This @type is promoted; it is being recommended to learners.', $context); + } + elseif ($node->isSticky()) { + return t('This @type is sticky; it is being shown as trending content.', $context); + } + + return NULL; +} diff --git a/web/themes/custom/perls_content_manager/templates/views/views-view--manage--bundle.html.twig b/web/themes/custom/perls_content_manager/templates/views/views-view--manage--bundle.html.twig new file mode 100644 index 0000000..fe1f195 --- /dev/null +++ b/web/themes/custom/perls_content_manager/templates/views/views-view--manage--bundle.html.twig @@ -0,0 +1,129 @@ +{# +/** + * @file + * Theme override for a main view template. + * + * Available variables: + * - attributes: Remaining HTML attributes for the element. + * - css_name: A css-safe version of the view name. + * - css_class: The user-specified classes names, if any. + * - header: The optional header. + * - footer: The optional footer. + * - rows: The results of the view query, if any. + * - empty: The content to display if there are no rows. + * - pager: The optional pager next/prev links to display. + * - exposed: Exposed widget form/info to display. + * - feed_icons: Optional feed icons to display. + * - more: An optional link to the next page of results. + * - title: Title of the view, only used when displaying in the admin preview. + * - title_prefix: Additional output populated by modules, intended to be + * displayed in front of the view title. + * - title_suffix: Additional output populated by modules, intended to be + * displayed after the view title. + * - attachment_before: An optional attachment view to be displayed before the + * view content. + * - attachment_after: An optional attachment view to be displayed after the + * view content. + * - dom_id: Unique id for every view being printed to give unique class for + * Javascript. + * + * @see template_preprocess_views_view() + */ +#} +{% + set classes = [ + 'c-view', + 'c-view--manage-content', + 'c-content-list', + 'c-view--' ~ id|clean_class, + 'c-view-id--' ~ id, + 'c-view-display-id--' ~ display_id, + dom_id ? 'js-view-dom-id-' ~ dom_id, + 'u-spacing', +] +%} + +{% set extra_title %} + {% if view.exposedInput is empty %} + {% trans %}All {{ view.getTitle() }}{% endtrans %} + {% else %} + {% trans %}Filtered {{ view.getTitle() }}{% endtrans %} + {% endif %} +{% endset %} + + + {% if header or title or exposed %} +
    + {% if header %} +
    + {{ header }} +
    + {% elseif title %} +
    + {% if title_prefix %} + {{ title_prefix }} + {% endif %} + + {{ title }} + + {% if title_suffix %} + {{ title_suffix }} + {% endif %} +
    + {% endif %} + + {% if exposed %} +
    + {% if extra_title %} +
    + {{ extra_title|trim|spaceless }} +
    + {% endif %} + {{ exposed }} +
    + {% endif %} +
    + {% endif %} + + {% if attachment_before %} +
    + {{ attachment_before }} +
    + {% endif %} + +
    + {% if rows %} +
    + {{ rows }} +
    + {% elseif empty %} +
    + {{ empty }} +
    + {% endif %} + + {% if footer %} +
    + {{ footer }} +
    + {% endif %} + + {% if pager %} +
    + {{ pager }} +
    + {% endif %} + + {% if more %} +
    + {{ more }} +
    + {% endif %} +
    + + {% if attachment_after %} +
    + {{ attachment_after }} +
    + {% endif %} +
    diff --git a/web/themes/custom/perls_content_manager/templates/views/views-view--manage-content.html.twig b/web/themes/custom/perls_content_manager/templates/views/views-view--manage-content.html.twig new file mode 100644 index 0000000..60d6483 --- /dev/null +++ b/web/themes/custom/perls_content_manager/templates/views/views-view--manage-content.html.twig @@ -0,0 +1 @@ +{% extends "views-view--manage--bundle.html.twig" %} diff --git a/web/themes/custom/perls_content_manager/templates/views/views-view--manage-events.html.twig b/web/themes/custom/perls_content_manager/templates/views/views-view--manage-events.html.twig new file mode 100644 index 0000000..60d6483 --- /dev/null +++ b/web/themes/custom/perls_content_manager/templates/views/views-view--manage-events.html.twig @@ -0,0 +1 @@ +{% extends "views-view--manage--bundle.html.twig" %} diff --git a/web/themes/custom/perls_content_manager/templates/views/views-view--manage-groups.html.twig b/web/themes/custom/perls_content_manager/templates/views/views-view--manage-groups.html.twig new file mode 100644 index 0000000..60d6483 --- /dev/null +++ b/web/themes/custom/perls_content_manager/templates/views/views-view--manage-groups.html.twig @@ -0,0 +1 @@ +{% extends "views-view--manage--bundle.html.twig" %} diff --git a/web/themes/custom/perls_content_manager/templates/views/views-view--manage-podcasts.html.twig b/web/themes/custom/perls_content_manager/templates/views/views-view--manage-podcasts.html.twig new file mode 100644 index 0000000..60d6483 --- /dev/null +++ b/web/themes/custom/perls_content_manager/templates/views/views-view--manage-podcasts.html.twig @@ -0,0 +1 @@ +{% extends "views-view--manage--bundle.html.twig" %} diff --git a/web/themes/custom/perls_content_manager/templates/views/views-view--manage-users.html.twig b/web/themes/custom/perls_content_manager/templates/views/views-view--manage-users.html.twig new file mode 100644 index 0000000..60d6483 --- /dev/null +++ b/web/themes/custom/perls_content_manager/templates/views/views-view--manage-users.html.twig @@ -0,0 +1 @@ +{% extends "views-view--manage--bundle.html.twig" %} diff --git a/web/themes/custom/perls_content_manager/templates/views/views-view--manage-vocabularies.html.twig b/web/themes/custom/perls_content_manager/templates/views/views-view--manage-vocabularies.html.twig new file mode 100644 index 0000000..60d6483 --- /dev/null +++ b/web/themes/custom/perls_content_manager/templates/views/views-view--manage-vocabularies.html.twig @@ -0,0 +1 @@ +{% extends "views-view--manage--bundle.html.twig" %} diff --git a/web/themes/custom/perls_learner/favicon.ico b/web/themes/custom/perls_learner/favicon.ico new file mode 100644 index 0000000..7cb4a42 Binary files /dev/null and b/web/themes/custom/perls_learner/favicon.ico differ diff --git a/web/themes/custom/perls_learner/logo.svg b/web/themes/custom/perls_learner/logo.svg new file mode 100644 index 0000000..dfd695f --- /dev/null +++ b/web/themes/custom/perls_learner/logo.svg @@ -0,0 +1,3 @@ + + + diff --git a/web/themes/custom/perls_learner/perls_learner.info.yml b/web/themes/custom/perls_learner/perls_learner.info.yml new file mode 100644 index 0000000..2d6b469 --- /dev/null +++ b/web/themes/custom/perls_learner/perls_learner.info.yml @@ -0,0 +1,13 @@ +name: 'Perls: Learner' +type: theme +description: This a subtheme of learner role. +core: 8.x +base theme: perls +core_version_requirement: ^8 || ^9 +# Regions +regions: + header_top: Header Top + header: Header + content: Content + footer: Footer + inactive: 'Inactive (this region is not printed, blocks here are placed programatically).' diff --git a/web/themes/custom/perls_learner/templates/layout/page--user--login.html.twig b/web/themes/custom/perls_learner/templates/layout/page--user--login.html.twig new file mode 100644 index 0000000..352a975 --- /dev/null +++ b/web/themes/custom/perls_learner/templates/layout/page--user--login.html.twig @@ -0,0 +1,58 @@ +{# +/** + * @file + * Theme override to display a single page. + * + * The doctype, html, head and body tags are not in this template. Instead they + * can be found in the html.html.twig template in this directory. + * + * Available variables: + * + * General utility variables: + * - base_path: The base URL path of the Drupal installation. Will usually be + * "/" unless you have installed Drupal in a sub-directory. + * - is_front: A flag indicating if the current page is the front page. + * - logged_in: A flag indicating if the user is registered and signed in. + * - is_admin: A flag indicating if the user has permission to access + * administration pages. + * + * Site identity: + * - front_page: The URL of the front page. Use this instead of base_path when + * linking to the front page. This includes the language domain or prefix. + * + * Page content (in order of occurrence in the default page.html.twig): + * - node: Fully loaded node, if there is an automatically-loaded node + * associated with the page and the node ID is the second argument in the + * page's path (e.g. node/12345 and node/12345/revisions, but not + * comment/reply/12345). + * + * Regions: + * - page.header: Items for the header region. + * - page.primary_menu: Items for the primary menu region. + * - page.secondary_menu: Items for the secondary menu region. + * - page.highlighted: Items for the highlighted content region. + * - page.help: Dynamic help text, mostly for admin pages. + * - page.content: The main content of the current page. + * - page.sidebar_first: Items for the first sidebar. + * - page.sidebar_second: Items for the second sidebar. + * - page.footer: Items for the footer region. + * - page.breadcrumb: Items for the breadcrumb region. + * + * @see template_preprocess_page() + * @see html.html.twig + */ +#} +
    +
    +
    + {# Skip to main content link in html.html.twig #} + + + {{ drupal_block('system_branding_block') }} + + {{ drupal_entity('block', 'perls_learner_messages', check_access=false) }} + + {{ drupal_entity('block', 'perls_learner_login', check_access=false) }} +
    +
    +
    diff --git a/web/themes/custom/perls_learner/templates/layout/page--user--password.html.twig b/web/themes/custom/perls_learner/templates/layout/page--user--password.html.twig new file mode 100644 index 0000000..a05db67 --- /dev/null +++ b/web/themes/custom/perls_learner/templates/layout/page--user--password.html.twig @@ -0,0 +1,74 @@ +{# +/** + * @file + * Theme override to display a single page. + * + * The doctype, html, head and body tags are not in this template. Instead they + * can be found in the html.html.twig template in this directory. + * + * Available variables: + * + * General utility variables: + * - base_path: The base URL path of the Drupal installation. Will usually be + * "/" unless you have installed Drupal in a sub-directory. + * - is_front: A flag indicating if the current page is the front page. + * - logged_in: A flag indicating if the user is registered and signed in. + * - is_admin: A flag indicating if the user has permission to access + * administration pages. + * + * Site identity: + * - front_page: The URL of the front page. Use this instead of base_path when + * linking to the front page. This includes the language domain or prefix. + * + * Page content (in order of occurrence in the default page.html.twig): + * - node: Fully loaded node, if there is an automatically-loaded node + * associated with the page and the node ID is the second argument in the + * page's path (e.g. node/12345 and node/12345/revisions, but not + * comment/reply/12345). + * + * Regions: + * - page.header: Items for the header region. + * - page.primary_menu: Items for the primary menu region. + * - page.secondary_menu: Items for the secondary menu region. + * - page.highlighted: Items for the highlighted content region. + * - page.help: Dynamic help text, mostly for admin pages. + * - page.content: The main content of the current page. + * - page.sidebar_first: Items for the first sidebar. + * - page.sidebar_second: Items for the second sidebar. + * - page.footer: Items for the footer region. + * - page.breadcrumb: Items for the breadcrumb region. + * + * @see template_preprocess_page() + * @see html.html.twig + */ +#} +
    +
    +
    + {# Skip to main content link in html.html.twig #} + + +
    +
    + + + {{ drupal_block('system_branding_block') }} +
    + +
    + + + + +
    +

    {{ 'Forgot Password'|trans }}

    + +

    {{ "No worries, we'll send you a link to reset it!"|trans }}

    +
    + + {{ page.content }} +
    +
    +
    +
    +
    diff --git a/web/themes/custom/perls_learner/templates/layout/page--user--register.html.twig b/web/themes/custom/perls_learner/templates/layout/page--user--register.html.twig new file mode 100644 index 0000000..3dedeae --- /dev/null +++ b/web/themes/custom/perls_learner/templates/layout/page--user--register.html.twig @@ -0,0 +1,65 @@ +{# +/** + * @file + * Theme override to display a single page. + * + * The doctype, html, head and body tags are not in this template. Instead they + * can be found in the html.html.twig template in this directory. + * + * Available variables: + * + * General utility variables: + * - base_path: The base URL path of the Drupal installation. Will usually be + * "/" unless you have installed Drupal in a sub-directory. + * - is_front: A flag indicating if the current page is the front page. + * - logged_in: A flag indicating if the user is registered and signed in. + * - is_admin: A flag indicating if the user has permission to access + * administration pages. + * + * Site identity: + * - front_page: The URL of the front page. Use this instead of base_path when + * linking to the front page. This includes the language domain or prefix. + * + * Page content (in order of occurrence in the default page.html.twig): + * - node: Fully loaded node, if there is an automatically-loaded node + * associated with the page and the node ID is the second argument in the + * page's path (e.g. node/12345 and node/12345/revisions, but not + * comment/reply/12345). + * + * Regions: + * - page.header: Items for the header region. + * - page.primary_menu: Items for the primary menu region. + * - page.secondary_menu: Items for the secondary menu region. + * - page.highlighted: Items for the highlighted content region. + * - page.help: Dynamic help text, mostly for admin pages. + * - page.content: The main content of the current page. + * - page.sidebar_first: Items for the first sidebar. + * - page.sidebar_second: Items for the second sidebar. + * - page.footer: Items for the footer region. + * - page.breadcrumb: Items for the breadcrumb region. + * + * @see template_preprocess_page() + * @see html.html.twig + */ +#} +
    +
    +
    + {# Skip to main content link in html.html.twig #} + + +
    +
    + + + {{ drupal_block('system_branding_block') }} +
    + +
    + {{ page.content }} +
    +
    + +
    +
    +
    diff --git a/web/themes/custom/perls_learner/templates/layout/page.html.twig b/web/themes/custom/perls_learner/templates/layout/page.html.twig new file mode 100644 index 0000000..406c7df --- /dev/null +++ b/web/themes/custom/perls_learner/templates/layout/page.html.twig @@ -0,0 +1,78 @@ +{# +/** + * @file + * Theme override to display a single page. + * + * The doctype, html, head and body tags are not in this template. Instead they + * can be found in the html.html.twig template in this directory. + * + * Available variables: + * + * General utility variables: + * - base_path: The base URL path of the Drupal installation. Will usually be + * "/" unless you have installed Drupal in a sub-directory. + * - is_front: A flag indicating if the current page is the front page. + * - logged_in: A flag indicating if the user is registered and signed in. + * - is_admin: A flag indicating if the user has permission to access + * administration pages. + * + * Site identity: + * - front_page: The URL of the front page. Use this instead of base_path when + * linking to the front page. This includes the language domain or prefix. + * + * Page content (in order of occurrence in the default page.html.twig): + * - node: Fully loaded node, if there is an automatically-loaded node + * associated with the page and the node ID is the second argument in the + * page's path (e.g. node/12345 and node/12345/revisions, but not + * comment/reply/12345). + * + * Regions: + * - page.header: Items for the header region. + * - page.primary_menu: Items for the primary menu region. + * - page.secondary_menu: Items for the secondary menu region. + * - page.highlighted: Items for the highlighted content region. + * - page.help: Dynamic help text, mostly for admin pages. + * - page.content: The main content of the current page. + * - page.sidebar_first: Items for the first sidebar. + * - page.sidebar_second: Items for the second sidebar. + * - page.footer: Items for the footer region. + * - page.breadcrumb: Items for the breadcrumb region. + * + * @see template_preprocess_page() + * @see html.html.twig + */ +#} +{% if page.header or page.header_top %} + +{% endif %} + +
    +
    + {# Skip to main content link in html.html.twig #} + + + {% if page.content|render|trim is not empty %} +
    + {{ page.content }} +
    + {% endif %} +
    +
    + +{% if page.footer|render|trim is not empty %} + {{ page.footer }} +{% endif %} diff --git a/web/themes/custom/perls_learner/templates/layout/region--header-top.html.twig b/web/themes/custom/perls_learner/templates/layout/region--header-top.html.twig new file mode 100644 index 0000000..cddd070 --- /dev/null +++ b/web/themes/custom/perls_learner/templates/layout/region--header-top.html.twig @@ -0,0 +1 @@ +{{ content }} diff --git a/web/themes/custom/perls_learner/templates/layout/region--header.html.twig b/web/themes/custom/perls_learner/templates/layout/region--header.html.twig new file mode 100644 index 0000000..cddd070 --- /dev/null +++ b/web/themes/custom/perls_learner/templates/layout/region--header.html.twig @@ -0,0 +1 @@ +{{ content }} diff --git a/web/themes/custom/perls_learner/templates/views/views-view--my-content.html.twig b/web/themes/custom/perls_learner/templates/views/views-view--my-content.html.twig new file mode 100644 index 0000000..fe1f195 --- /dev/null +++ b/web/themes/custom/perls_learner/templates/views/views-view--my-content.html.twig @@ -0,0 +1,129 @@ +{# +/** + * @file + * Theme override for a main view template. + * + * Available variables: + * - attributes: Remaining HTML attributes for the element. + * - css_name: A css-safe version of the view name. + * - css_class: The user-specified classes names, if any. + * - header: The optional header. + * - footer: The optional footer. + * - rows: The results of the view query, if any. + * - empty: The content to display if there are no rows. + * - pager: The optional pager next/prev links to display. + * - exposed: Exposed widget form/info to display. + * - feed_icons: Optional feed icons to display. + * - more: An optional link to the next page of results. + * - title: Title of the view, only used when displaying in the admin preview. + * - title_prefix: Additional output populated by modules, intended to be + * displayed in front of the view title. + * - title_suffix: Additional output populated by modules, intended to be + * displayed after the view title. + * - attachment_before: An optional attachment view to be displayed before the + * view content. + * - attachment_after: An optional attachment view to be displayed after the + * view content. + * - dom_id: Unique id for every view being printed to give unique class for + * Javascript. + * + * @see template_preprocess_views_view() + */ +#} +{% + set classes = [ + 'c-view', + 'c-view--manage-content', + 'c-content-list', + 'c-view--' ~ id|clean_class, + 'c-view-id--' ~ id, + 'c-view-display-id--' ~ display_id, + dom_id ? 'js-view-dom-id-' ~ dom_id, + 'u-spacing', +] +%} + +{% set extra_title %} + {% if view.exposedInput is empty %} + {% trans %}All {{ view.getTitle() }}{% endtrans %} + {% else %} + {% trans %}Filtered {{ view.getTitle() }}{% endtrans %} + {% endif %} +{% endset %} + + + {% if header or title or exposed %} +
    + {% if header %} +
    + {{ header }} +
    + {% elseif title %} +
    + {% if title_prefix %} + {{ title_prefix }} + {% endif %} + + {{ title }} + + {% if title_suffix %} + {{ title_suffix }} + {% endif %} +
    + {% endif %} + + {% if exposed %} +
    + {% if extra_title %} +
    + {{ extra_title|trim|spaceless }} +
    + {% endif %} + {{ exposed }} +
    + {% endif %} +
    + {% endif %} + + {% if attachment_before %} +
    + {{ attachment_before }} +
    + {% endif %} + +
    + {% if rows %} +
    + {{ rows }} +
    + {% elseif empty %} +
    + {{ empty }} +
    + {% endif %} + + {% if footer %} +
    + {{ footer }} +
    + {% endif %} + + {% if pager %} +
    + {{ pager }} +
    + {% endif %} + + {% if more %} +
    + {{ more }} +
    + {% endif %} +
    + + {% if attachment_after %} +
    + {{ attachment_after }} +
    + {% endif %} + diff --git a/web/themes/custom/perls_learner/templates/views/views-view-list--recommended-content--learner-page.html.twig b/web/themes/custom/perls_learner/templates/views/views-view-list--recommended-content--learner-page.html.twig new file mode 100644 index 0000000..be6b335 --- /dev/null +++ b/web/themes/custom/perls_learner/templates/views/views-view-list--recommended-content--learner-page.html.twig @@ -0,0 +1,42 @@ +{# +/** + * @file + * Theme override for a view template to display a list of rows. + * + * Available variables: + * - attributes: HTML attributes for the container. + * - rows: A list of rows for this list. + * - attributes: The row's HTML attributes. + * - content: The row's contents. + * - title: The title of this group of rows. May be empty. + * - list: @todo. + * - type: Starting tag will be either a ul or ol. + * - attributes: HTML attributes for the list element. + * + * @see template_preprocess_views_view_list() + */ +#} +{% if attributes -%} + + {% endif %} + {% if title %} +

    {{ title }}

    + {% endif %} + + <{{ list.type }}{{ list.attributes }}> + + {% for row in rows %} + + {% if prompt_block and loop.index == 1 %} + {{ prompt_block }} + {% endif %} + + {{- row.content -}} + + {% endfor %} + + + +{% if attributes -%} + +{% endif %} diff --git a/web/themes/custom/perls_learner/templates/views/views-view-list--recommended-content--recommended-block.html.twig b/web/themes/custom/perls_learner/templates/views/views-view-list--recommended-content--recommended-block.html.twig new file mode 100644 index 0000000..be6b335 --- /dev/null +++ b/web/themes/custom/perls_learner/templates/views/views-view-list--recommended-content--recommended-block.html.twig @@ -0,0 +1,42 @@ +{# +/** + * @file + * Theme override for a view template to display a list of rows. + * + * Available variables: + * - attributes: HTML attributes for the container. + * - rows: A list of rows for this list. + * - attributes: The row's HTML attributes. + * - content: The row's contents. + * - title: The title of this group of rows. May be empty. + * - list: @todo. + * - type: Starting tag will be either a ul or ol. + * - attributes: HTML attributes for the list element. + * + * @see template_preprocess_views_view_list() + */ +#} +{% if attributes -%} + + {% endif %} + {% if title %} +

    {{ title }}

    + {% endif %} + + <{{ list.type }}{{ list.attributes }}> + + {% for row in rows %} + + {% if prompt_block and loop.index == 1 %} + {{ prompt_block }} + {% endif %} + + {{- row.content -}} + + {% endfor %} + + + +{% if attributes -%} + +{% endif %} diff --git a/web/update.php b/web/update.php new file mode 100644 index 0000000..b65649c --- /dev/null +++ b/web/update.php @@ -0,0 +1,30 @@ +handle($request); +$response->send(); + +$kernel->terminate($request, $response); diff --git a/web/web.config b/web/web.config new file mode 100644 index 0000000..79a0433 --- /dev/null +++ b/web/web.config @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +