diff --git a/.docker-compose/api/.env b/.docker-compose/api/.env new file mode 100644 index 0000000..f643a2f --- /dev/null +++ b/.docker-compose/api/.env @@ -0,0 +1 @@ +PHP_IDE_CONFIG=serverName=cojedzie diff --git a/docker/php/log.conf b/.docker-compose/api/log.conf similarity index 100% rename from docker/php/log.conf rename to .docker-compose/api/log.conf diff --git a/.docker-compose/nginx/cojedzie-rr.conf b/.docker-compose/nginx/cojedzie-rr.conf new file mode 100644 index 0000000..9664cb5 --- /dev/null +++ b/.docker-compose/nginx/cojedzie-rr.conf @@ -0,0 +1,31 @@ +server { + root /var/www/front/public/; + + server_name cojedzie.localhost; + + location /_profiler/ { + try_files $uri $uri/ @api; + } + + location /bundles/ { + try_files $uri $uri/ @api; + } + + location /api/ { + try_files $uri $uri/ @api; + } + + location / { + try_files $uri $uri/ @frontend; + } + + location @frontend { + proxy_pass http://frontend:3000; + proxy_intercept_errors on; + } + + location @api { + proxy_pass http://api:8080; + proxy_intercept_errors on; + } +} diff --git a/.docker-compose/nginx/cojedzie.conf b/.docker-compose/nginx/cojedzie.conf new file mode 100644 index 0000000..b60243d --- /dev/null +++ b/.docker-compose/nginx/cojedzie.conf @@ -0,0 +1,44 @@ +server { + root /var/www/front/public/; + server_name cojedzie.localhost; + + location /api/ { + root /var/www/api/public/; + try_files $uri $uri/ index.php$is_args$args; + } + + location /_profiler/ { + root /var/www/api/public/; + try_files $uri $uri/ index.php$is_args$args; + } + + location /bundles/ { + root /var/www/api/public/; + try_files $uri $uri/; + } + + location / { + try_files $uri $uri/ @frontend; + } + + location @frontend { + proxy_pass http://frontend:3000; + proxy_intercept_errors on; + } + + location ~ (.+).php(/|$) { + root /var/www/api/public/; + + fastcgi_pass api:9000; + fastcgi_split_path_info ^(.+\.php)(/.*)$; + + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME /var/www/public/$fastcgi_script_name; + fastcgi_param DOCUMENT_ROOT /var/www/public/; + + fastcgi_param APP_ENV "dev"; + fastcgi_param DATABASE_URL "sqlite:///%kernel.project_dir%/var/app.db"; + + internal; + } +} diff --git a/.env.dist b/.env.dist deleted file mode 100644 index 3bab831..0000000 --- a/.env.dist +++ /dev/null @@ -1,17 +0,0 @@ -# This file is a "template" of which env vars need to be defined for your application -# Copy this file to .env file for development, create environment variables when deploying to production -# https://symfony.com/doc/current/best_practices/configuration.html#infrastructure-related-configuration - -GOOGLE_ANALYTICS= - -###> symfony/framework-bundle ### -APP_ENV=dev -APP_SECRET=1bdf86cdc78fba654e4f2c309c6bbdbd -###< symfony/framework-bundle ### - -###> doctrine/doctrine-bundle ### -# Format described at http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url -# For an SQLite database, use: "sqlite:///%kernel.project_dir%/var/data.db" -# Configure your db driver and server_version in config/packages/doctrine.yaml -DATABASE_URL=sqlite:///%kernel.project_dir%/var/app.db -###< doctrine/doctrine-bundle ### diff --git a/.gitignore b/.gitignore index 429897d..85e7c1d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,19 +1 @@ - -###> symfony/framework-bundle ### -/.env -/public/bundles/ -/var/ -/vendor/ -###< symfony/framework-bundle ### - -###> symfony/web-server-bundle ### -/.web-server-pid -###< symfony/web-server-bundle ### - -/node_modules/ /.idea/ -/public/* -!/public/index.php -!/public/manifest.jso - -/yarn-error.log diff --git a/CLA.md b/CLA.md new file mode 100644 index 0000000..4a8ef42 --- /dev/null +++ b/CLA.md @@ -0,0 +1,71 @@ +# Co Jedzie Individual Contributor License Agreement + +Adapted from http://www.apache.org/licenses/icla.txt © The Apache Software Foundation + +Thank you for your interest in Co Jedzie (the **"Project"**) by Kacper Donat (the **"Author"**). In order to clarify the +intellectual property license granted with Contributions from any person or entity, the Author must have a Contributor +License Agreement ("CLA") on file that has been signed by each Contributor, indicating agreement to the license terms +below. This license is for your protection as a Contributor as well as the protection of the Author and its users; it +does not change your rights to use your own Contributions for any other purpose. + +You accept and agree to the following terms and conditions for Your present and future Contributions submitted to the +Author. In return, the Author shall not use Your Contributions in a way that is contrary to the public benefit or +inconsistent with its bylaws in effect at the time of the Contribution. Except for the license granted herein to the +Author and recipients of software distributed by the Author, You reserve all right, title, and interest in and to Your +Contributions. + +1. Definitions. + - **"You"** (or **"Your"**) shall mean the copyright owner or legal entity authorized by the copyright owner that is + making this Agreement with the Author. For legal entities, the entity making a Contribution and all other entities + that control, are controlled by, or are under common control with that entity are considered to be a single + Contributor. For the purposes of this definition, **"control"** means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or + more of the outstanding shares, or (iii) beneficial ownership of such entity. + + - **"Contribution"** shall mean any original work of authorship, including any modifications or additions to an existing + work, that is intentionally submitted by You to the Author for inclusion in, or documentation of, any of the products + owned or managed by the Author (the **"Work"**). For the purposes of this definition, **"submitted"** means any form + of electronic, verbal, or written communication sent to the Author or its representatives, including but not limited + to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed + by, or on behalf of, the Author for the purpose of discussing and improving the Work, but excluding communication that + is conspicuously marked or otherwise designated in writing by You as **"Not a Contribution."** + +2. Grant of Copyright License. Subject to the terms and conditions of this Agreement, You hereby grant to the Author and + to recipients of software distributed by the Author a perpetual, worldwide, non-exclusive, no-charge, royalty-free, + irrevocable copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, + sublicense, re-license, and distribute Your Contributions and such derivative works. + +3. Grant of Patent License. Subject to the terms and conditions of this Agreement, You hereby grant to the Author and to + recipients of software distributed by the Author a perpetual, worldwide, non-exclusive, no-charge, royalty-free, + irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, + and otherwise transfer the Work, where such license applies only to those patent claims licensable by You that are + necessarily infringed by Your Contribution(s) alone or by combination of Your Contribution(s) with the Work to which + such Contribution(s) was submitted. If any entity institutes patent litigation against You or any other entity ( + including a cross-claim or counterclaim in a lawsuit) alleging that your Contribution, or the Work to which you have + contributed, constitutes direct or contributory patent infringement, then any patent licenses granted to that entity + under this Agreement for that Contribution or Work shall terminate as of the date such litigation is filed. + +4. You represent that you are legally entitled to grant the above license. If your employer(s) has rights to + intellectual property that you create that includes your Contributions, you represent that you have received + permission to make Contributions on behalf of that employer, that your employer has waived such rights for your + Contributions to the Author, or that your employer has executed a separate Corporate CLA with the Author. + +5. You represent that each of Your Contributions is Your original creation (see section 7 for submissions on behalf of + others). You represent that Your Contribution submissions include complete details of any third-party license or + other restriction (including, but not limited to, related patents and trademarks) of which you are personally aware + and which are associated with any part of Your Contributions. + +6. You are not expected to provide support for Your Contributions, except to the extent You desire to provide support. + You may provide support for free, for a fee, or not at all. Unless required by applicable law or agreed to in + writing, You provide Your Contributions on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + express or implied, including, without limitation, any warranties or conditions of TITLE, NON- INFRINGEMENT, + MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. + +7. Should You wish to submit work that is not Your original creation, You may submit it to the Author separately from + any Contribution, identifying the complete details of its source and of any license or other restriction (including, + but not limited to, related patents, trademarks, and license agreements) of which you are personally aware, and + conspicuously marking the work as "Submitted on behalf of a third-party: [named here]". + +8. You agree to notify the Author of any facts or circumstances of which you become aware that would make these + representations inaccurate in any respect. + diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..040b0b0 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,38 @@ +# How to contribute? + +Thanks for your interest in the project! + +## I'd like to propose some feature / change... + +Cool! Go ahead, [create an issue] and describe your proposal so anyone can see it. You can also vote on features that +you want the most. + +## I've found a bug! + +Well, less cool! Before creating an issue, please check if the bug remains after hard refreshing (usually `ctrl+F5`) the +application. If the answer is yes, or this is not the first encounter of it please [create an issue] and describe the +problem. If you can, please attach screenshots (especially if this is visual bug), and console logs (especially for +connection problems) - this will help to reproduce the problem. + +## I've got some spare resources on my server... +Soon you will be able to help the project by hosting your own API node that will be available for clients to use. +More details to come soon. + +## I want to contribute some code... + +That's great! If you want to make changes to API (which is responsible for collecting and supplying applicaiton with +data) please check the [API contribution guidelines], if you are interested in UI side of the app please read the +[frontend contribution guidelines]. + +### Contributor License Agreement + +Unfortunately due to this project nature and license I need you to sign [Contributor License Agreement] - the nice thing +is that it can be done with simple push of a button! **You still will have full copyright to your contribution** but +basically you consent that you are entitled to code you are submitting and also to allow me to license this project on +other terms if needed to, for example, local governments. If you don't want to sign - I understand - but I won't be able +to accept your contribution :( + +[Contributor License Agreement]: ./CLA.md +[create an issue]: https://github.com/cojedzie/cojedzie/issues/new +[API contribution guidelines]: ./api/CONTRIBUTING.md +[frontend contribution guidelines]: ./front/CONTRIBUTING.md diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..92d7487 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,41 @@ +“Commons Clause” License Condition v1.0 + +The Software is provided to you by the Licensor under the License, as defined +below, subject to the following condition. + +Without limiting other conditions in the License, the grant of rights under the +License will not include, and the License does not grant to you, the right to +Sell the Software. + +For purposes of the foregoing, “Sell” means practicing any or all of the rights +granted to you under the License to provide to third parties, for a fee or other +consideration (including without limitation fees for hosting or consulting/ +support services related to the Software), a product or service whose value +derives, entirely or substantially, from the functionality of the Software. Any +license notice or attribution required by the License must also include this +Commons Clause License Condition notice. + +Software: Co Jedzie + +License: MIT + +Licensor: Kacper Donat + +Copyright 2020 Kacper Donat + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..be9b2a7 --- /dev/null +++ b/README.md @@ -0,0 +1,32 @@ +# [Co Jedzie](https://cojedzie.pl) + + + +Co Jedzie is an app that allows you to quickly and easily check realtime departure times on public transport stops. It +aims to be the central hub for all public transport information you will need. + +You can use the app at [cojedzie.pl](https://cojedzie.pl). + +## Roadmap +Co Jedzie is in active development, roadmap of the project can be found on [trello]. This roadmap is regularly updated +and represents current state of the project. Feel free to take a look. + +### Contributing to roadmap +If you have found a bug or want to propose some changes feel free to create an [issue] explaining your proposal or +problem. Issue management and discussion would be done on the github, but planning will be carried away to the [trello] +trello with linked issue. + +## Contributing +Wan't to contribute? Nice! Please see [CONTRIBUTING.md] + +## License +This project is [fair-code](https://faircode.io/) licensed under [MIT with Commons Clause](./LICENSE.md). Basically, Co +Jedzie is free and code is available to everyone, but it's not allowed to make money directly with it without +authors permission. + +Note that data collected from available data sources is licensed by their respective owners, thus it may be +available under different terms than the project itself and may require additional permissions to use. + +[trello]: https://trello.com/b/QXqDvmoG/co-jedzie +[issue]: https://github.com/cojedzie/cojedzie/issues/new +[CONTRIBUTING.md]: ./CONTRIBUTING.md diff --git a/api/.dockerignore b/api/.dockerignore new file mode 100644 index 0000000..768d5ef --- /dev/null +++ b/api/.dockerignore @@ -0,0 +1,2 @@ +/vendor/ +/var/ diff --git a/api/.env b/api/.env new file mode 100644 index 0000000..9af5833 --- /dev/null +++ b/api/.env @@ -0,0 +1,22 @@ +# This file is a "template" of which env vars need to be defined for your application +# Copy this file to .env file for development, create environment variables when deploying to production +# https://symfony.com/doc/current/best_practices/configuration.html#infrastructure-related-configuration + +###> symfony/framework-bundle ### +APP_ENV=dev +APP_SECRET=494a9d1f8cc383f16075f4d5e54ae1a2 +#TRUSTED_PROXIES=127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 +#TRUSTED_HOSTS='^(localhost|example\.com)$' +###< symfony/framework-bundle ### + +###> doctrine/doctrine-bundle ### +# Format described at https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url +# IMPORTANT: You MUST configure your server version, either here or in config/packages/doctrine.yaml +# +DATABASE_URL="sqlite:///%kernel.project_dir%/var/app.db" +# DATABASE_URL="mysql://db_user:db_password@127.0.0.1:3306/db_name?serverVersion=5.7" +###< doctrine/doctrine-bundle ### + +###> symfony/messenger ### +APP_EVENT_QUEUE_DSN="doctrine://default" +###< symfony/messenger ### diff --git a/api/.gitignore b/api/.gitignore new file mode 100644 index 0000000..5aa718b --- /dev/null +++ b/api/.gitignore @@ -0,0 +1,16 @@ +###> symfony/framework-bundle ### +/.env.local +/.env.local.php +/.env.*.local +/config/secrets/prod/prod.decrypt.private.php +/public/bundles/ +/var/ +/vendor/ +###< symfony/framework-bundle ### +/node_modules/ +/public/* +!/public/index.php + +###> baldinof/roadrunner-bundle ### +/bin/rr +###< baldinof/roadrunner-bundle ### diff --git a/api/.rr.dev.yaml b/api/.rr.dev.yaml new file mode 100644 index 0000000..709cd3d --- /dev/null +++ b/api/.rr.dev.yaml @@ -0,0 +1,11 @@ +include: + - .rr.yaml + +reload: + enabled: true + interval: 1s + patterns: [".php"] + services: + http: + dirs: ["."] + recursive: true diff --git a/api/.rr.yaml b/api/.rr.yaml new file mode 100644 index 0000000..79cff58 --- /dev/null +++ b/api/.rr.yaml @@ -0,0 +1,13 @@ +http: + address: "0.0.0.0:8080" + + uploads: + forbid: [".php", ".exe", ".bat"] + + workers: + command: "php bin/console baldinof:roadrunner:worker" + relay: "unix://var/roadrunner.sock" + +static: + dir: "public" + forbid: [".php", ".htaccess"] diff --git a/api/CONTRIBUTING.md b/api/CONTRIBUTING.md new file mode 100644 index 0000000..6ca8468 --- /dev/null +++ b/api/CONTRIBUTING.md @@ -0,0 +1,3 @@ +# Contributing guidelines + +TBD diff --git a/api/Dockerfile b/api/Dockerfile new file mode 100644 index 0000000..710ad89 --- /dev/null +++ b/api/Dockerfile @@ -0,0 +1,28 @@ +FROM php:7.4-fpm-alpine + +COPY --from=mlocati/php-extension-installer /usr/bin/install-php-extensions /usr/local/bin/ +COPY --from=composer:latest /usr/bin/composer /usr/bin/composer + +RUN install-php-extensions bcmath intl opcache zip sockets xdebug-^3.0; +RUN apk add git; + +# XDebug +RUN echo "xdebug.mode=debug" >> $PHP_INI_DIR/conf.d/docker-php-ext-xdebug.ini && \ + echo "xdebug.discover_client_host=On" >> $PHP_INI_DIR/conf.d/docker-php-ext-xdebug.ini; + +# Blackfire +RUN version=$(php -r "echo PHP_MAJOR_VERSION.PHP_MINOR_VERSION;") \ + && curl -A "Docker" -o /tmp/blackfire-probe.tar.gz -D - -L -s https://blackfire.io/api/v1/releases/probe/php/linux/amd64/$version \ + && mkdir -p /tmp/blackfire \ + && tar zxpf /tmp/blackfire-probe.tar.gz -C /tmp/blackfire \ + && mv /tmp/blackfire/blackfire-*.so $(php -r "echo ini_get ('extension_dir');")/blackfire.so \ + && printf "extension=blackfire.so\nblackfire.agent_socket=tcp://blackfire:8707\n" > $PHP_INI_DIR/conf.d/blackfire.ini \ + && rm -rf /tmp/blackfire /tmp/blackfire-probe.tar.gz + +# Timezone +RUN ln -snf /usr/share/zoneinfo/Europe/Warsaw /etc/localtime && \ + echo "date.timezone = Europe/Warsaw" >> /usr/local/etc/php/conf.d/datetime.ini; + +WORKDIR /var/www + +EXPOSE 9001 diff --git a/bin/console b/api/bin/console similarity index 100% rename from bin/console rename to api/bin/console diff --git a/api/bin/docker-entrypoint.sh b/api/bin/docker-entrypoint.sh new file mode 100644 index 0000000..214eb4c --- /dev/null +++ b/api/bin/docker-entrypoint.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +exec "$@" diff --git a/api/bin/docker-init.sh b/api/bin/docker-init.sh new file mode 100755 index 0000000..0799aea --- /dev/null +++ b/api/bin/docker-init.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +./bin/console doctrine:migrations:migrate --no-interaction + +exec "$@" diff --git a/composer.json b/api/composer.json similarity index 61% rename from composer.json rename to api/composer.json index af906e6..18f4cc4 100644 --- a/composer.json +++ b/api/composer.json @@ -1,34 +1,37 @@ { - "name": "kadet/czydojade", + "name": "kadet/cojedzie", + "description": "Co Jedzie", "type": "project", - "license": "MIT", + "license": "MIT with Commons Clause", "require": { - "php": "^7.1.3", + "php": "^7.4", "ext-ctype": "*", "ext-iconv": "*", "ext-json": "*", + "baldinof/roadrunner-bundle": "^1.3", "cerbero/json-objects": "^1.1", - "doctrine/doctrine-cache-bundle": "^1.4", + "illuminate/collections": "^8.35", "jms/serializer-bundle": "^3.5", + "kadet/functional": "dev-master", "nelmio/api-doc-bundle": "^3.5", - "nesbot/carbon": "^1.33", + "nesbot/carbon": "^2.46.0", "ocramius/proxy-manager": "^2.0", "sensio/framework-extra-bundle": "^5.2", - "symfony/asset": "^4.4", - "symfony/console": "^4.4", + "spiral/roadrunner": "^1.8", + "symfony/asset": "^5.2", + "symfony/console": "^5.2", + "symfony/doctrine-messenger": "5.2.*", "symfony/flex": "^1.1", - "symfony/framework-bundle": "^4.4", + "symfony/framework-bundle": "^5.2", + "symfony/messenger": "5.2.*", "symfony/monolog-bundle": "^3.3", "symfony/orm-pack": "^1.0", "symfony/profiler-pack": "^1.0", - "symfony/twig-bundle": "^4.4", - "symfony/yaml": "^4.4", - "tightenco/collect": "^5.6" - }, - "require-dev": { - "symfony/dotenv": "^4.4", - "symfony/web-server-bundle": "^4.4", - "kadet/functional": "dev-master" + "symfony/twig-bundle": "^5.2", + "symfony/yaml": "^5.2", + "symfony/dotenv": "5.2.*", + "symfony/amqp-messenger": "5.2.*", + "symfony/redis-messenger": "5.2.*" }, "config": { "preferred-install": { @@ -37,14 +40,17 @@ "sort-packages": true, "secure-http": false, "platform": { - "php": "7.3.12" + "php": "7.4.15" } }, "autoload": { "psr-4": { "App\\": "src/" }, - "files": ["./src/Functions/index.php"] + "files": [ + "vendor/symfony/dependency-injection/Loader/Configurator/ContainerConfigurator.php", + "./src/Functions/index.php" + ] }, "autoload-dev": { "psr-4": { @@ -75,7 +81,8 @@ }, "extra": { "symfony": { - "allow-contrib": true + "allow-contrib": true, + "require": "5.2.*" } }, "repositories": [ @@ -83,5 +90,8 @@ "type": "vcs", "url": "https://git.kadet.net/kadet/functional-php.git" } - ] + ], + "require-dev": { + "symfony/maker-bundle": "^1.30" + } } diff --git a/composer.lock b/api/composer.lock similarity index 53% rename from composer.lock rename to api/composer.lock index b88b749..a8bc93c 100644 --- a/composer.lock +++ b/api/composer.lock @@ -4,29 +4,118 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "8efb4e4271b8598760e37b9b33d9a14f", + "content-hash": "3703fdd98d8c7ed6539721bde9035bba", "packages": [ { - "name": "cerbero/json-objects", - "version": "v1.1.2", + "name": "baldinof/roadrunner-bundle", + "version": "1.5.3", "source": { "type": "git", - "url": "https://github.com/cerbero90/json-objects.git", - "reference": "21eac219bb20ca80318fec88821217d7417ee09a" + "url": "https://github.com/Baldinof/roadrunner-bundle.git", + "reference": "541bfe21cf76233f70b2b840b8f8260c6b779d83" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/cerbero90/json-objects/zipball/21eac219bb20ca80318fec88821217d7417ee09a", - "reference": "21eac219bb20ca80318fec88821217d7417ee09a", + "url": "https://api.github.com/repos/Baldinof/roadrunner-bundle/zipball/541bfe21cf76233f70b2b840b8f8260c6b779d83", + "reference": "541bfe21cf76233f70b2b840b8f8260c6b779d83", "shasum": "" }, "require": { - "php": "~7.1", - "psr/http-message": "^1.0", - "salsify/json-streaming-parser": "^8.0" + "dflydev/fig-cookies": "^3.0", + "jean85/pretty-package-versions": "^1.5 || ^2.0", + "php": ">=7.3", + "php-http/discovery": "^1.9", + "psr/http-factory": "^1.0", + "psr/http-factory-implementation": "1.0.0", + "psr/http-server-handler": "^1.0", + "psr/http-server-middleware": "^1.0", + "psr/log": "^1.1", + "spiral/goridge": "^2.0.2", + "spiral/roadrunner": "^1.5", + "symfony/config": "^4.4 || ^5.0", + "symfony/dependency-injection": "^4.4 || ^5.0", + "symfony/http-kernel": "^4.4 || ^5.0", + "symfony/psr-http-message-bridge": "^1.1 || ^2.0", + "symfony/yaml": "^4.4 || ^5.0" + }, + "conflict": { + "doctrine/doctrine-bundle": "<2.1.1" }, "require-dev": { - "mockery/mockery": "^1.2", + "blackfire/php-sdk": "^1.21", + "doctrine/doctrine-bundle": "^2.1.1", + "doctrine/mongodb-odm": "^2.2", + "doctrine/orm": "^2.7.3", + "friendsofphp/php-cs-fixer": "^2.16", + "nyholm/psr7": "^1.2", + "ocramius/package-versions": "^1.10 || ^2.0", + "phpspec/prophecy": "^1.11", + "phpspec/prophecy-phpunit": "^2.0", + "phpstan/phpstan": "^0.12.2", + "phpunit/phpunit": "^9.1", + "sentry/sentry-symfony": "^3.4||^4.0", + "symfony/framework-bundle": "^4.0||^5.0", + "symfony/proxy-manager-bridge": "^4.0 || ^5.0", + "symfony/var-dumper": "^4.0||^5.0" + }, + "suggest": { + "nyholm/psr7": "For a super lightweight PSR-7/17 implementation", + "symfony/proxy-manager-bridge": "For doctrine re-connection implementation" + }, + "type": "symfony-bundle", + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Baldinof\\RoadRunnerBundle\\": "src", + "Tests\\Baldinof\\RoadRunnerBundle\\": "tests" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Florent Baldino", + "email": "baldinof@gmail.com" + } + ], + "description": "A RoadRunner worker as a Symfony Bundle", + "support": { + "issues": "https://github.com/Baldinof/roadrunner-bundle/issues", + "source": "https://github.com/Baldinof/roadrunner-bundle/tree/1.5.3" + }, + "funding": [ + { + "url": "https://github.com/Baldinof", + "type": "github" + } + ], + "time": "2021-03-30T07:23:57+00:00" + }, + { + "name": "cerbero/json-objects", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/cerbero90/json-objects.git", + "reference": "d0e2bfed9b5562746733865ec3f5c1febc0b5534" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/cerbero90/json-objects/zipball/d0e2bfed9b5562746733865ec3f5c1febc0b5534", + "reference": "d0e2bfed9b5562746733865ec3f5c1febc0b5534", + "shasum": "" + }, + "require": { + "php": "^7.1||^8.0", + "psr/http-message": "^1.0", + "salsify/json-streaming-parser": "^8.2" + }, + "require-dev": { + "mockery/mockery": "^1.3", "phpunit/phpunit": ">=7.0", "squizlabs/php_codesniffer": "^3.0" }, @@ -62,36 +151,173 @@ "parser", "stream" ], - "time": "2019-04-26T13:04:36+00:00" + "support": { + "issues": "https://github.com/cerbero90/json-objects/issues", + "source": "https://github.com/cerbero90/json-objects/tree/v1.2.0" + }, + "time": "2021-01-14T01:52:31+00:00" }, { - "name": "doctrine/annotations", - "version": "v1.8.0", + "name": "composer/package-versions-deprecated", + "version": "1.11.99.1", "source": { "type": "git", - "url": "https://github.com/doctrine/annotations.git", - "reference": "904dca4eb10715b92569fbcd79e201d5c349b6bc" + "url": "https://github.com/composer/package-versions-deprecated.git", + "reference": "7413f0b55a051e89485c5cb9f765fe24bb02a7b6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/904dca4eb10715b92569fbcd79e201d5c349b6bc", - "reference": "904dca4eb10715b92569fbcd79e201d5c349b6bc", + "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/7413f0b55a051e89485c5cb9f765fe24bb02a7b6", + "reference": "7413f0b55a051e89485c5cb9f765fe24bb02a7b6", "shasum": "" }, "require": { - "doctrine/lexer": "1.*", - "php": "^7.1" + "composer-plugin-api": "^1.1.0 || ^2.0", + "php": "^7 || ^8" + }, + "replace": { + "ocramius/package-versions": "1.11.99" }, "require-dev": { - "doctrine/cache": "1.*", - "phpunit/phpunit": "^7.5" + "composer/composer": "^1.9.3 || ^2.0@dev", + "ext-zip": "^1.13", + "phpunit/phpunit": "^6.5 || ^7" + }, + "type": "composer-plugin", + "extra": { + "class": "PackageVersions\\Installer", + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "PackageVersions\\": "src/PackageVersions" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be" + } + ], + "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", + "support": { + "issues": "https://github.com/composer/package-versions-deprecated/issues", + "source": "https://github.com/composer/package-versions-deprecated/tree/1.11.99.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": "2020-11-11T10:22:58+00:00" + }, + { + "name": "dflydev/fig-cookies", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/dflydev/dflydev-fig-cookies.git", + "reference": "ea6934204b1b34ffdf5130dc7e0928d18ced2498" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dflydev/dflydev-fig-cookies/zipball/ea6934204b1b34ffdf5130dc7e0928d18ced2498", + "reference": "ea6934204b1b34ffdf5130dc7e0928d18ced2498", + "shasum": "" + }, + "require": { + "ext-pcre": "*", + "php": "^7.2 || ^8.0", + "psr/http-message": "^1" + }, + "require-dev": { + "doctrine/coding-standard": "^8", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-phpunit": "^0.12.16", + "phpunit/phpunit": "^7.2.6 || ^9", + "scrutinizer/ocular": "^1.8", + "squizlabs/php_codesniffer": "^3.3", + "vimeo/psalm": "^4.4" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.7.x-dev" + "dev-main": "3.0.x-dev" } }, + "autoload": { + "psr-4": { + "Dflydev\\FigCookies\\": "src/Dflydev/FigCookies" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Beau Simensen", + "email": "beau@dflydev.com" + } + ], + "description": "Cookies for PSR-7 HTTP Message Interface.", + "keywords": [ + "cookies", + "psr-7", + "psr7" + ], + "support": { + "issues": "https://github.com/dflydev/dflydev-fig-cookies/issues", + "source": "https://github.com/dflydev/dflydev-fig-cookies/tree/v3.0.0" + }, + "time": "2021-01-22T02:53:56+00:00" + }, + { + "name": "doctrine/annotations", + "version": "1.12.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/annotations.git", + "reference": "b17c5014ef81d212ac539f07a1001832df1b6d3b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/b17c5014ef81d212ac539f07a1001832df1b6d3b", + "reference": "b17c5014ef81d212ac539f07a1001832df1b6d3b", + "shasum": "" + }, + "require": { + "doctrine/lexer": "1.*", + "ext-tokenizer": "*", + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/cache": "1.*", + "doctrine/coding-standard": "^6.0 || ^8.1", + "phpstan/phpstan": "^0.12.20", + "phpunit/phpunit": "^7.5 || ^9.1.5" + }, + "type": "library", "autoload": { "psr-4": { "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" @@ -124,30 +350,34 @@ } ], "description": "Docblock Annotations Parser", - "homepage": "http://www.doctrine-project.org", + "homepage": "https://www.doctrine-project.org/projects/annotations.html", "keywords": [ "annotations", "docblock", "parser" ], - "time": "2019-10-01T18:55:10+00:00" + "support": { + "issues": "https://github.com/doctrine/annotations/issues", + "source": "https://github.com/doctrine/annotations/tree/1.12.1" + }, + "time": "2021-02-21T21:00:45+00:00" }, { "name": "doctrine/cache", - "version": "1.10.0", + "version": "1.10.2", "source": { "type": "git", "url": "https://github.com/doctrine/cache.git", - "reference": "382e7f4db9a12dc6c19431743a2b096041bcdd62" + "reference": "13e3381b25847283a91948d04640543941309727" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/cache/zipball/382e7f4db9a12dc6c19431743a2b096041bcdd62", - "reference": "382e7f4db9a12dc6c19431743a2b096041bcdd62", + "url": "https://api.github.com/repos/doctrine/cache/zipball/13e3381b25847283a91948d04640543941309727", + "reference": "13e3381b25847283a91948d04640543941309727", "shasum": "" }, "require": { - "php": "~7.1" + "php": "~7.1 || ^8.0" }, "conflict": { "doctrine/common": ">2.2,<2.4" @@ -212,37 +442,50 @@ "redis", "xcache" ], - "time": "2019-11-29T15:36:20+00:00" + "support": { + "issues": "https://github.com/doctrine/cache/issues", + "source": "https://github.com/doctrine/cache/tree/1.10.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%2Fcache", + "type": "tidelift" + } + ], + "time": "2020-07-07T18:54:01+00:00" }, { "name": "doctrine/collections", - "version": "1.6.4", + "version": "1.6.7", "source": { "type": "git", "url": "https://github.com/doctrine/collections.git", - "reference": "6b1e4b2b66f6d6e49983cebfe23a21b7ccc5b0d7" + "reference": "55f8b799269a1a472457bd1a41b4f379d4cfba4a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/collections/zipball/6b1e4b2b66f6d6e49983cebfe23a21b7ccc5b0d7", - "reference": "6b1e4b2b66f6d6e49983cebfe23a21b7ccc5b0d7", + "url": "https://api.github.com/repos/doctrine/collections/zipball/55f8b799269a1a472457bd1a41b4f379d4cfba4a", + "reference": "55f8b799269a1a472457bd1a41b4f379d4cfba4a", "shasum": "" }, "require": { - "php": "^7.1.3" + "php": "^7.1.3 || ^8.0" }, "require-dev": { "doctrine/coding-standard": "^6.0", "phpstan/phpstan-shim": "^0.9.2", "phpunit/phpunit": "^7.0", - "vimeo/psalm": "^3.2.2" + "vimeo/psalm": "^3.8.1" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.6.x-dev" - } - }, "autoload": { "psr-4": { "Doctrine\\Common\\Collections\\": "lib/Doctrine/Common/Collections" @@ -282,47 +525,39 @@ "iterators", "php" ], - "time": "2019-11-13T13:07:11+00:00" + "support": { + "issues": "https://github.com/doctrine/collections/issues", + "source": "https://github.com/doctrine/collections/tree/1.6.7" + }, + "time": "2020-07-27T17:53:49+00:00" }, { "name": "doctrine/common", - "version": "2.12.0", + "version": "3.1.1", "source": { "type": "git", "url": "https://github.com/doctrine/common.git", - "reference": "2053eafdf60c2172ee1373d1b9289ba1db7f1fc6" + "reference": "2afde5a9844126bc311cd5f548b5475e75f800d3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/common/zipball/2053eafdf60c2172ee1373d1b9289ba1db7f1fc6", - "reference": "2053eafdf60c2172ee1373d1b9289ba1db7f1fc6", + "url": "https://api.github.com/repos/doctrine/common/zipball/2afde5a9844126bc311cd5f548b5475e75f800d3", + "reference": "2afde5a9844126bc311cd5f548b5475e75f800d3", "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.1", - "doctrine/reflection": "^1.0", - "php": "^7.1" + "doctrine/persistence": "^2.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", + "doctrine/coding-standard": "^6.0 || ^8.0", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-phpunit": "^0.12", + "phpunit/phpunit": "^7.5.20 || ^8.5 || ^9.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" @@ -358,41 +593,61 @@ "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.", + "description": "PHP Doctrine Common project is a library that provides additional functionality that other Doctrine projects depend on such as better reflection support, proxies and much more.", "homepage": "https://www.doctrine-project.org/projects/common.html", "keywords": [ "common", "doctrine", "php" ], - "time": "2020-01-10T15:49:25+00:00" + "support": { + "issues": "https://github.com/doctrine/common/issues", + "source": "https://github.com/doctrine/common/tree/3.1.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%2Fcommon", + "type": "tidelift" + } + ], + "time": "2021-01-20T19:58:05+00:00" }, { "name": "doctrine/dbal", - "version": "v2.10.1", + "version": "2.13.0", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "c2b8e6e82732a64ecde1cddf9e1e06cb8556e3d8" + "reference": "67d56d3203b33db29834e6b2fcdbfdc50535d796" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/c2b8e6e82732a64ecde1cddf9e1e06cb8556e3d8", - "reference": "c2b8e6e82732a64ecde1cddf9e1e06cb8556e3d8", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/67d56d3203b33db29834e6b2fcdbfdc50535d796", + "reference": "67d56d3203b33db29834e6b2fcdbfdc50535d796", "shasum": "" }, "require": { "doctrine/cache": "^1.0", + "doctrine/deprecations": "^0.5.3", "doctrine/event-manager": "^1.0", "ext-pdo": "*", - "php": "^7.2" + "php": "^7.1 || ^8" }, "require-dev": { - "doctrine/coding-standard": "^6.0", - "jetbrains/phpstorm-stubs": "^2019.1", - "phpstan/phpstan": "^0.11.3", - "phpunit/phpunit": "^8.4.1", - "symfony/console": "^2.0.5|^3.0|^4.0|^5.0" + "doctrine/coding-standard": "8.2.0", + "jetbrains/phpstorm-stubs": "2020.2", + "phpstan/phpstan": "0.12.81", + "phpunit/phpunit": "^7.5.20|^8.5|9.5.0", + "symfony/console": "^2.0.5|^3.0|^4.0|^5.0", + "vimeo/psalm": "4.6.4" }, "suggest": { "symfony/console": "For helpful console commands such as SQL execution and import of files." @@ -401,12 +656,6 @@ "bin/doctrine-dbal" ], "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.10.x-dev", - "dev-develop": "3.0.x-dev" - } - }, "autoload": { "psr-4": { "Doctrine\\DBAL\\": "lib/Doctrine/DBAL" @@ -457,27 +706,88 @@ "sqlserver", "sqlsrv" ], - "time": "2020-01-04T12:56:21+00:00" + "support": { + "issues": "https://github.com/doctrine/dbal/issues", + "source": "https://github.com/doctrine/dbal/tree/2.13.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%2Fdbal", + "type": "tidelift" + } + ], + "time": "2021-03-28T18:10:53+00:00" }, { - "name": "doctrine/doctrine-bundle", - "version": "2.0.6", + "name": "doctrine/deprecations", + "version": "v0.5.3", "source": { "type": "git", - "url": "https://github.com/doctrine/DoctrineBundle.git", - "reference": "0ef972d3b730f975c80db9fffa4b2a0258c91442" + "url": "https://github.com/doctrine/deprecations.git", + "reference": "9504165960a1f83cc1480e2be1dd0a0478561314" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/0ef972d3b730f975c80db9fffa4b2a0258c91442", - "reference": "0ef972d3b730f975c80db9fffa4b2a0258c91442", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/9504165960a1f83cc1480e2be1dd0a0478561314", + "reference": "9504165960a1f83cc1480e2be1dd0a0478561314", "shasum": "" }, "require": { - "doctrine/dbal": "^2.9.0", - "doctrine/persistence": "^1.3.3", - "jdorn/sql-formatter": "^1.2.16", - "php": "^7.1", + "php": "^7.1|^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^6.0|^7.0|^8.0", + "phpunit/phpunit": "^7.0|^8.0|^9.0", + "psr/log": "^1.0" + }, + "suggest": { + "psr/log": "Allows logging deprecations via PSR-3 logger implementation" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", + "homepage": "https://www.doctrine-project.org/", + "support": { + "issues": "https://github.com/doctrine/deprecations/issues", + "source": "https://github.com/doctrine/deprecations/tree/v0.5.3" + }, + "time": "2021-03-21T12:59:47+00:00" + }, + { + "name": "doctrine/doctrine-bundle", + "version": "2.3.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/DoctrineBundle.git", + "reference": "8b922578bdee2243a26202b13df795e170efaef8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/8b922578bdee2243a26202b13df795e170efaef8", + "reference": "8b922578bdee2243a26202b13df795e170efaef8", + "shasum": "" + }, + "require": { + "doctrine/dbal": "^2.9.0|^3.0", + "doctrine/persistence": "^1.3.3|^2.0", + "doctrine/sql-formatter": "^1.0.1", + "php": "^7.1 || ^8.0", "symfony/cache": "^4.3.3|^5.0", "symfony/config": "^4.3.3|^5.0", "symfony/console": "^3.4.30|^4.3.3|^5.0", @@ -491,17 +801,18 @@ "twig/twig": "<1.34|>=2.0,<2.4" }, "require-dev": { - "doctrine/coding-standard": "^6.0", + "doctrine/coding-standard": "^8.0", "doctrine/orm": "^2.6", - "ocramius/proxy-manager": "^2.1", - "phpunit/phpunit": "^7.5", + "friendsofphp/proxy-manager-lts": "^1.0", + "phpunit/phpunit": "^7.5 || ^8.0 || ^9.3", "symfony/phpunit-bridge": "^4.2", "symfony/property-info": "^4.3.3|^5.0", + "symfony/proxy-manager-bridge": "^3.4|^4.3.3|^5.0", "symfony/twig-bridge": "^3.4.30|^4.3.3|^5.0", "symfony/validator": "^3.4.30|^4.3.3|^5.0", "symfony/web-profiler-bundle": "^3.4.30|^4.3.3|^5.0", "symfony/yaml": "^3.4.30|^4.3.3|^5.0", - "twig/twig": "^1.34|^2.12" + "twig/twig": "^1.34|^2.12|^3.0" }, "suggest": { "doctrine/orm": "The Doctrine ORM integration is optional in the bundle.", @@ -510,7 +821,7 @@ "type": "symfony-bundle", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "2.3.x-dev" } }, "autoload": { @@ -548,125 +859,52 @@ "orm", "persistence" ], - "time": "2019-12-19T13:47:07+00:00" - }, - { - "name": "doctrine/doctrine-cache-bundle", - "version": "1.4.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/DoctrineCacheBundle.git", - "reference": "6bee2f9b339847e8a984427353670bad4e7bdccb" + "support": { + "issues": "https://github.com/doctrine/DoctrineBundle/issues", + "source": "https://github.com/doctrine/DoctrineBundle/tree/2.3.0" }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/DoctrineCacheBundle/zipball/6bee2f9b339847e8a984427353670bad4e7bdccb", - "reference": "6bee2f9b339847e8a984427353670bad4e7bdccb", - "shasum": "" - }, - "require": { - "doctrine/cache": "^1.4.2", - "doctrine/inflector": "^1.0", - "php": "^7.1", - "symfony/doctrine-bridge": "^3.4|^4.0" - }, - "require-dev": { - "instaclick/coding-standard": "~1.1", - "instaclick/object-calisthenics-sniffs": "dev-master", - "instaclick/symfony2-coding-standard": "dev-remaster", - "phpunit/phpunit": "^7.0", - "predis/predis": "~0.8", - "satooshi/php-coveralls": "^1.0", - "squizlabs/php_codesniffer": "~1.5", - "symfony/console": "^3.4|^4.0", - "symfony/finder": "^3.4|^4.0", - "symfony/framework-bundle": "^3.4|^4.0", - "symfony/phpunit-bridge": "^3.4|^4.0", - "symfony/security-acl": "^2.8", - "symfony/validator": "^3.4|^4.0", - "symfony/yaml": "^3.4|^4.0" - }, - "suggest": { - "symfony/security-acl": "For using this bundle to cache ACLs" - }, - "type": "symfony-bundle", - "extra": { - "branch-alias": { - "dev-master": "1.4.x-dev" - } - }, - "autoload": { - "psr-4": { - "Doctrine\\Bundle\\DoctrineCacheBundle\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ + "funding": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" }, { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" }, { - "name": "Fabio B. Silva", - "email": "fabio.bat.silva@gmail.com" - }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@hotmail.com" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, - { - "name": "Doctrine Project", - "homepage": "http://www.doctrine-project.org/" + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fdoctrine-bundle", + "type": "tidelift" } ], - "description": "Symfony Bundle for Doctrine Cache", - "homepage": "https://www.doctrine-project.org", - "keywords": [ - "cache", - "caching" - ], - "time": "2019-11-29T11:22:01+00:00" + "time": "2021-03-16T16:24:04+00:00" }, { "name": "doctrine/doctrine-migrations-bundle", - "version": "2.1.2", + "version": "2.2.2", "source": { "type": "git", "url": "https://github.com/doctrine/DoctrineMigrationsBundle.git", - "reference": "856437e8de96a70233e1f0cc2352fc8dd15a899d" + "reference": "85f0b847174daf243362c7da80efe1539be64f47" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/DoctrineMigrationsBundle/zipball/856437e8de96a70233e1f0cc2352fc8dd15a899d", - "reference": "856437e8de96a70233e1f0cc2352fc8dd15a899d", + "url": "https://api.github.com/repos/doctrine/DoctrineMigrationsBundle/zipball/85f0b847174daf243362c7da80efe1539be64f47", + "reference": "85f0b847174daf243362c7da80efe1539be64f47", "shasum": "" }, "require": { "doctrine/doctrine-bundle": "~1.0|~2.0", "doctrine/migrations": "^2.2", - "php": "^7.1", + "php": "^7.1|^8.0", "symfony/framework-bundle": "~3.4|~4.0|~5.0" }, "require-dev": { - "doctrine/coding-standard": "^5.0", + "doctrine/coding-standard": "^8.0", "mikey179/vfsstream": "^1.6", - "phpstan/phpstan": "^0.9.2", - "phpstan/phpstan-strict-rules": "^0.9", - "phpunit/phpunit": "^6.4|^7.0" + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-strict-rules": "^0.12", + "phpunit/phpunit": "^7.0|^8.0|^9.0" }, "type": "symfony-bundle", "extra": { @@ -707,24 +945,42 @@ "migrations", "schema" ], - "time": "2019-11-13T12:57:41+00:00" + "support": { + "issues": "https://github.com/doctrine/DoctrineMigrationsBundle/issues", + "source": "https://github.com/doctrine/DoctrineMigrationsBundle/tree/2.2.2" + }, + "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%2Fdoctrine-migrations-bundle", + "type": "tidelift" + } + ], + "time": "2020-12-23T15:06:17+00:00" }, { "name": "doctrine/event-manager", - "version": "1.1.0", + "version": "1.1.1", "source": { "type": "git", "url": "https://github.com/doctrine/event-manager.git", - "reference": "629572819973f13486371cb611386eb17851e85c" + "reference": "41370af6a30faa9dc0368c4a6814d596e81aba7f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/event-manager/zipball/629572819973f13486371cb611386eb17851e85c", - "reference": "629572819973f13486371cb611386eb17851e85c", + "url": "https://api.github.com/repos/doctrine/event-manager/zipball/41370af6a30faa9dc0368c4a6814d596e81aba7f", + "reference": "41370af6a30faa9dc0368c4a6814d596e81aba7f", "shasum": "" }, "require": { - "php": "^7.1" + "php": "^7.1 || ^8.0" }, "conflict": { "doctrine/common": "<2.9@dev" @@ -783,37 +1039,59 @@ "event system", "events" ], - "time": "2019-11-10T09:48:07+00:00" + "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.3.1", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/doctrine/inflector.git", - "reference": "ec3a55242203ffa6a4b27c58176da97ff0a7aec1" + "reference": "9cf661f4eb38f7c881cac67c75ea9b00bf97b210" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/inflector/zipball/ec3a55242203ffa6a4b27c58176da97ff0a7aec1", - "reference": "ec3a55242203ffa6a4b27c58176da97ff0a7aec1", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/9cf661f4eb38f7c881cac67c75ea9b00bf97b210", + "reference": "9cf661f4eb38f7c881cac67c75ea9b00bf97b210", "shasum": "" }, "require": { - "php": "^7.1" + "php": "^7.2 || ^8.0" }, "require-dev": { - "phpunit/phpunit": "^6.2" + "doctrine/coding-standard": "^7.0", + "phpstan/phpstan": "^0.11", + "phpstan/phpstan-phpunit": "^0.11", + "phpstan/phpstan-strict-rules": "^0.11", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3.x-dev" + "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/", @@ -842,48 +1120,67 @@ "email": "schmittjoh@gmail.com" } ], - "description": "Common String Manipulations with regard to casing and singular/plural rules.", - "homepage": "http://www.doctrine-project.org", + "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", - "pluralize", - "singularize", - "string" + "inflector", + "lowercase", + "manipulation", + "php", + "plural", + "singular", + "strings", + "uppercase", + "words" ], - "time": "2019-10-30T19:59:35+00:00" + "support": { + "issues": "https://github.com/doctrine/inflector/issues", + "source": "https://github.com/doctrine/inflector/tree/2.0.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%2Finflector", + "type": "tidelift" + } + ], + "time": "2020-05-29T15:13:26+00:00" }, { "name": "doctrine/instantiator", - "version": "1.3.0", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "ae466f726242e637cebdd526a7d991b9433bacf1" + "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/ae466f726242e637cebdd526a7d991b9433bacf1", - "reference": "ae466f726242e637cebdd526a7d991b9433bacf1", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b", + "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b", "shasum": "" }, "require": { - "php": "^7.1" + "php": "^7.1 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^6.0", + "doctrine/coding-standard": "^8.0", "ext-pdo": "*", "ext-phar": "*", - "phpbench/phpbench": "^0.13", - "phpstan/phpstan-phpunit": "^0.11", - "phpstan/phpstan-shim": "^0.11", - "phpunit/phpunit": "^7.0" + "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", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } - }, "autoload": { "psr-4": { "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" @@ -897,7 +1194,7 @@ { "name": "Marco Pivetta", "email": "ocramius@gmail.com", - "homepage": "http://ocramius.github.com/" + "homepage": "https://ocramius.github.io/" } ], "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", @@ -906,24 +1203,42 @@ "constructor", "instantiate" ], - "time": "2019-10-21T16:45:58+00:00" + "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.0", + "version": "1.2.1", "source": { "type": "git", "url": "https://github.com/doctrine/lexer.git", - "reference": "5242d66dbeb21a30dd8a3e66bf7a73b66e05e1f6" + "reference": "e864bbf5904cb8f5bb334f99209b48018522f042" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/lexer/zipball/5242d66dbeb21a30dd8a3e66bf7a73b66e05e1f6", - "reference": "5242d66dbeb21a30dd8a3e66bf7a73b66e05e1f6", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/e864bbf5904cb8f5bb334f99209b48018522f042", + "reference": "e864bbf5904cb8f5bb334f99209b48018522f042", "shasum": "" }, "require": { - "php": "^7.2" + "php": "^7.2 || ^8.0" }, "require-dev": { "doctrine/coding-standard": "^6.0", @@ -968,28 +1283,46 @@ "parser", "php" ], - "time": "2019-10-30T14:39:59+00:00" + "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/migrations", - "version": "2.2.1", + "version": "2.3.1", "source": { "type": "git", "url": "https://github.com/doctrine/migrations.git", - "reference": "a3987131febeb0e9acb3c47ab0df0af004588934" + "reference": "af915024d41669600354efe78664ee86dfca62e1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/migrations/zipball/a3987131febeb0e9acb3c47ab0df0af004588934", - "reference": "a3987131febeb0e9acb3c47ab0df0af004588934", + "url": "https://api.github.com/repos/doctrine/migrations/zipball/af915024d41669600354efe78664ee86dfca62e1", + "reference": "af915024d41669600354efe78664ee86dfca62e1", "shasum": "" }, "require": { + "composer/package-versions-deprecated": "^1.8", "doctrine/dbal": "^2.9", - "ocramius/package-versions": "^1.3", "ocramius/proxy-manager": "^2.0.2", "php": "^7.1", - "symfony/console": "^3.4||^4.0||^5.0", + "symfony/console": "^3.4||^4.4.16||^5.0", "symfony/stopwatch": "^3.4||^4.0||^5.0" }, "require-dev": { @@ -1002,7 +1335,7 @@ "phpstan/phpstan-deprecation-rules": "^0.10", "phpstan/phpstan-phpunit": "^0.10", "phpstan/phpstan-strict-rules": "^0.10", - "phpunit/phpunit": "^7.0", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.4", "symfony/process": "^3.4||^4.0||^5.0", "symfony/yaml": "^3.4||^4.0||^5.0" }, @@ -1050,39 +1383,62 @@ "migrations", "php" ], - "time": "2019-12-04T06:09:14+00:00" + "support": { + "issues": "https://github.com/doctrine/migrations/issues", + "source": "https://github.com/doctrine/migrations/tree/2.3.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%2Fmigrations", + "type": "tidelift" + } + ], + "time": "2020-12-05T19:13:58+00:00" }, { "name": "doctrine/orm", - "version": "v2.7.0", + "version": "2.8.2", "source": { "type": "git", "url": "https://github.com/doctrine/orm.git", - "reference": "4d763ca4c925f647b248b9fa01b5f47aa3685d62" + "reference": "ebae57eb9637acd8252b398df3121b120688ed5c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/orm/zipball/4d763ca4c925f647b248b9fa01b5f47aa3685d62", - "reference": "4d763ca4c925f647b248b9fa01b5f47aa3685d62", + "url": "https://api.github.com/repos/doctrine/orm/zipball/ebae57eb9637acd8252b398df3121b120688ed5c", + "reference": "ebae57eb9637acd8252b398df3121b120688ed5c", "shasum": "" }, "require": { - "doctrine/annotations": "^1.8", + "composer/package-versions-deprecated": "^1.8", + "doctrine/annotations": "^1.11.1", "doctrine/cache": "^1.9.1", "doctrine/collections": "^1.5", - "doctrine/common": "^2.11", - "doctrine/dbal": "^2.9.3", + "doctrine/common": "^3.0.3", + "doctrine/dbal": "^2.10.0", "doctrine/event-manager": "^1.1", + "doctrine/inflector": "^1.4|^2.0", "doctrine/instantiator": "^1.3", - "doctrine/persistence": "^1.2", + "doctrine/lexer": "^1.0", + "doctrine/persistence": "^2.0", "ext-pdo": "*", - "php": "^7.1", + "php": "^7.2|^8.0", "symfony/console": "^3.0|^4.0|^5.0" }, "require-dev": { - "doctrine/coding-standard": "^5.0", - "phpunit/phpunit": "^7.5", - "symfony/yaml": "^3.4|^4.0|^5.0" + "doctrine/coding-standard": "^8.0", + "phpstan/phpstan": "^0.12.18", + "phpunit/phpunit": "^8.5|^9.4", + "symfony/yaml": "^3.4|^4.0|^5.0", + "vimeo/psalm": "4.1.1" }, "suggest": { "symfony/yaml": "If you want to use YAML Metadata Mapping Driver" @@ -1133,20 +1489,24 @@ "database", "orm" ], - "time": "2019-11-19T08:38:05+00:00" + "support": { + "issues": "https://github.com/doctrine/orm/issues", + "source": "https://github.com/doctrine/orm/tree/2.8.2" + }, + "time": "2021-02-16T22:10:18+00:00" }, { "name": "doctrine/persistence", - "version": "1.3.4", + "version": "2.1.0", "source": { "type": "git", "url": "https://github.com/doctrine/persistence.git", - "reference": "ff7e08b0f814be2cd20c52dc3c8a262579376b94" + "reference": "9899c16934053880876b920a3b8b02ed2337ac1d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/persistence/zipball/ff7e08b0f814be2cd20c52dc3c8a262579376b94", - "reference": "ff7e08b0f814be2cd20c52dc3c8a262579376b94", + "url": "https://api.github.com/repos/doctrine/persistence/zipball/9899c16934053880876b920a3b8b02ed2337ac1d", + "reference": "9899c16934053880876b920a3b8b02ed2337ac1d", "shasum": "" }, "require": { @@ -1154,23 +1514,20 @@ "doctrine/cache": "^1.0", "doctrine/collections": "^1.0", "doctrine/event-manager": "^1.0", - "doctrine/reflection": "^1.0", - "php": "^7.1" + "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" + "composer/package-versions-deprecated": "^1.11", + "doctrine/coding-standard": "^6.0 || ^8.0", + "doctrine/common": "^3.0", + "phpstan/phpstan": "^0.12", + "phpunit/phpunit": "^7.5.20 || ^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", @@ -1216,229 +1573,35 @@ "orm", "persistence" ], - "time": "2020-01-09T19:49:17+00:00" + "support": { + "issues": "https://github.com/doctrine/persistence/issues", + "source": "https://github.com/doctrine/persistence/tree/2.1.0" + }, + "time": "2020-10-24T22:13:54+00:00" }, { - "name": "doctrine/reflection", - "version": "v1.1.0", + "name": "doctrine/sql-formatter", + "version": "1.1.1", "source": { "type": "git", - "url": "https://github.com/doctrine/reflection.git", - "reference": "bc420ead87fdfe08c03ecc3549db603a45b06d4c" + "url": "https://github.com/doctrine/sql-formatter.git", + "reference": "56070bebac6e77230ed7d306ad13528e60732871" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/reflection/zipball/bc420ead87fdfe08c03ecc3549db603a45b06d4c", - "reference": "bc420ead87fdfe08c03ecc3549db603a45b06d4c", + "url": "https://api.github.com/repos/doctrine/sql-formatter/zipball/56070bebac6e77230ed7d306ad13528e60732871", + "reference": "56070bebac6e77230ed7d306ad13528e60732871", "shasum": "" }, "require": { - "doctrine/annotations": "^1.0", - "ext-tokenizer": "*", - "php": "^7.1" - }, - "conflict": { - "doctrine/common": "<2.9" + "php": "^7.1 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^5.0", - "doctrine/common": "^2.10", - "phpstan/phpstan": "^0.11.0", - "phpstan/phpstan-phpunit": "^0.11.0", - "phpunit/phpunit": "^7.0" + "bamarni/composer-bin-plugin": "^1.4" }, - "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" + "bin": [ + "bin/sql-formatter" ], - "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" - ], - "time": "2020-01-08T19:53:19+00:00" - }, - { - "name": "exsyst/swagger", - "version": "v0.4.1", - "source": { - "type": "git", - "url": "https://github.com/GuilhemN/swagger.git", - "reference": "a02984db5edacdce2b4e09dae5ba8fe17a0e449e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/GuilhemN/swagger/zipball/a02984db5edacdce2b4e09dae5ba8fe17a0e449e", - "reference": "a02984db5edacdce2b4e09dae5ba8fe17a0e449e", - "shasum": "" - }, - "require": { - "php": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.5" - }, - "type": "library", - "autoload": { - "psr-4": { - "EXSyst\\Component\\Swagger\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ener-Getick", - "email": "egetick@gmail.com" - } - ], - "description": "A php library to manipulate Swagger specifications", - "time": "2018-07-27T06:40:00+00:00" - }, - { - "name": "hoa/compiler", - "version": "3.17.08.08", - "source": { - "type": "git", - "url": "https://github.com/hoaproject/Compiler.git", - "reference": "aa09caf0bf28adae6654ca6ee415ee2f522672de" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/hoaproject/Compiler/zipball/aa09caf0bf28adae6654ca6ee415ee2f522672de", - "reference": "aa09caf0bf28adae6654ca6ee415ee2f522672de", - "shasum": "" - }, - "require": { - "hoa/consistency": "~1.0", - "hoa/exception": "~1.0", - "hoa/file": "~1.0", - "hoa/iterator": "~2.0", - "hoa/math": "~1.0", - "hoa/protocol": "~1.0", - "hoa/regex": "~1.0", - "hoa/visitor": "~2.0" - }, - "require-dev": { - "hoa/json": "~2.0", - "hoa/test": "~2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } - }, - "autoload": { - "psr-4": { - "Hoa\\Compiler\\": "." - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Ivan Enderlin", - "email": "ivan.enderlin@hoa-project.net" - }, - { - "name": "Hoa community", - "homepage": "https://hoa-project.net/" - } - ], - "description": "The Hoa\\Compiler library.", - "homepage": "https://hoa-project.net/", - "keywords": [ - "algebraic", - "ast", - "compiler", - "context-free", - "coverage", - "exhaustive", - "grammar", - "isotropic", - "language", - "lexer", - "library", - "ll1", - "llk", - "parser", - "pp", - "random", - "regular", - "rule", - "sampler", - "syntax", - "token", - "trace", - "uniform" - ], - "time": "2017-08-08T07:44:07+00:00" - }, - { - "name": "hoa/consistency", - "version": "1.17.05.02", - "source": { - "type": "git", - "url": "https://github.com/hoaproject/Consistency.git", - "reference": "fd7d0adc82410507f332516faf655b6ed22e4c2f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/hoaproject/Consistency/zipball/fd7d0adc82410507f332516faf655b6ed22e4c2f", - "reference": "fd7d0adc82410507f332516faf655b6ed22e4c2f", - "shasum": "" - }, - "require": { - "hoa/exception": "~1.0", - "php": ">=5.5.0" - }, - "require-dev": { - "hoa/stream": "~1.0", - "hoa/test": "~2.0" - }, "type": "library", "extra": { "branch-alias": { @@ -1447,707 +1610,8 @@ }, "autoload": { "psr-4": { - "Hoa\\Consistency\\": "." - }, - "files": [ - "Prelude.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Ivan Enderlin", - "email": "ivan.enderlin@hoa-project.net" - }, - { - "name": "Hoa community", - "homepage": "https://hoa-project.net/" + "Doctrine\\SqlFormatter\\": "src" } - ], - "description": "The Hoa\\Consistency library.", - "homepage": "https://hoa-project.net/", - "keywords": [ - "autoloader", - "callable", - "consistency", - "entity", - "flex", - "keyword", - "library" - ], - "time": "2017-05-02T12:18:12+00:00" - }, - { - "name": "hoa/event", - "version": "1.17.01.13", - "source": { - "type": "git", - "url": "https://github.com/hoaproject/Event.git", - "reference": "6c0060dced212ffa3af0e34bb46624f990b29c54" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/hoaproject/Event/zipball/6c0060dced212ffa3af0e34bb46624f990b29c54", - "reference": "6c0060dced212ffa3af0e34bb46624f990b29c54", - "shasum": "" - }, - "require": { - "hoa/consistency": "~1.0", - "hoa/exception": "~1.0" - }, - "require-dev": { - "hoa/test": "~2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Hoa\\Event\\": "." - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Ivan Enderlin", - "email": "ivan.enderlin@hoa-project.net" - }, - { - "name": "Hoa community", - "homepage": "https://hoa-project.net/" - } - ], - "description": "The Hoa\\Event library.", - "homepage": "https://hoa-project.net/", - "keywords": [ - "event", - "library", - "listener", - "observer" - ], - "time": "2017-01-13T15:30:50+00:00" - }, - { - "name": "hoa/exception", - "version": "1.17.01.16", - "source": { - "type": "git", - "url": "https://github.com/hoaproject/Exception.git", - "reference": "091727d46420a3d7468ef0595651488bfc3a458f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/hoaproject/Exception/zipball/091727d46420a3d7468ef0595651488bfc3a458f", - "reference": "091727d46420a3d7468ef0595651488bfc3a458f", - "shasum": "" - }, - "require": { - "hoa/consistency": "~1.0", - "hoa/event": "~1.0" - }, - "require-dev": { - "hoa/test": "~2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Hoa\\Exception\\": "." - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Ivan Enderlin", - "email": "ivan.enderlin@hoa-project.net" - }, - { - "name": "Hoa community", - "homepage": "https://hoa-project.net/" - } - ], - "description": "The Hoa\\Exception library.", - "homepage": "https://hoa-project.net/", - "keywords": [ - "exception", - "library" - ], - "time": "2017-01-16T07:53:27+00:00" - }, - { - "name": "hoa/file", - "version": "1.17.07.11", - "source": { - "type": "git", - "url": "https://github.com/hoaproject/File.git", - "reference": "35cb979b779bc54918d2f9a4e02ed6c7a1fa67ca" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/hoaproject/File/zipball/35cb979b779bc54918d2f9a4e02ed6c7a1fa67ca", - "reference": "35cb979b779bc54918d2f9a4e02ed6c7a1fa67ca", - "shasum": "" - }, - "require": { - "hoa/consistency": "~1.0", - "hoa/event": "~1.0", - "hoa/exception": "~1.0", - "hoa/iterator": "~2.0", - "hoa/stream": "~1.0" - }, - "require-dev": { - "hoa/test": "~2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Hoa\\File\\": "." - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Ivan Enderlin", - "email": "ivan.enderlin@hoa-project.net" - }, - { - "name": "Hoa community", - "homepage": "https://hoa-project.net/" - } - ], - "description": "The Hoa\\File library.", - "homepage": "https://hoa-project.net/", - "keywords": [ - "Socket", - "directory", - "file", - "finder", - "library", - "link", - "temporary" - ], - "time": "2017-07-11T07:42:15+00:00" - }, - { - "name": "hoa/iterator", - "version": "2.17.01.10", - "source": { - "type": "git", - "url": "https://github.com/hoaproject/Iterator.git", - "reference": "d1120ba09cb4ccd049c86d10058ab94af245f0cc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/hoaproject/Iterator/zipball/d1120ba09cb4ccd049c86d10058ab94af245f0cc", - "reference": "d1120ba09cb4ccd049c86d10058ab94af245f0cc", - "shasum": "" - }, - "require": { - "hoa/consistency": "~1.0", - "hoa/exception": "~1.0" - }, - "require-dev": { - "hoa/test": "~2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - } - }, - "autoload": { - "psr-4": { - "Hoa\\Iterator\\": "." - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Ivan Enderlin", - "email": "ivan.enderlin@hoa-project.net" - }, - { - "name": "Hoa community", - "homepage": "https://hoa-project.net/" - } - ], - "description": "The Hoa\\Iterator library.", - "homepage": "https://hoa-project.net/", - "keywords": [ - "iterator", - "library" - ], - "time": "2017-01-10T10:34:47+00:00" - }, - { - "name": "hoa/math", - "version": "1.17.05.16", - "source": { - "type": "git", - "url": "https://github.com/hoaproject/Math.git", - "reference": "7150785d30f5d565704912116a462e9f5bc83a0c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/hoaproject/Math/zipball/7150785d30f5d565704912116a462e9f5bc83a0c", - "reference": "7150785d30f5d565704912116a462e9f5bc83a0c", - "shasum": "" - }, - "require": { - "hoa/compiler": "~3.0", - "hoa/consistency": "~1.0", - "hoa/exception": "~1.0", - "hoa/iterator": "~2.0", - "hoa/protocol": "~1.0", - "hoa/zformat": "~1.0" - }, - "require-dev": { - "hoa/test": "~2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Hoa\\Math\\": "." - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Ivan Enderlin", - "email": "ivan.enderlin@hoa-project.net" - }, - { - "name": "Hoa community", - "homepage": "https://hoa-project.net/" - } - ], - "description": "The Hoa\\Math library.", - "homepage": "https://hoa-project.net/", - "keywords": [ - "arrangement", - "combination", - "combinatorics", - "counting", - "library", - "math", - "permutation", - "sampler", - "set" - ], - "time": "2017-05-16T08:02:17+00:00" - }, - { - "name": "hoa/protocol", - "version": "1.17.01.14", - "source": { - "type": "git", - "url": "https://github.com/hoaproject/Protocol.git", - "reference": "5c2cf972151c45f373230da170ea015deecf19e2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/hoaproject/Protocol/zipball/5c2cf972151c45f373230da170ea015deecf19e2", - "reference": "5c2cf972151c45f373230da170ea015deecf19e2", - "shasum": "" - }, - "require": { - "hoa/consistency": "~1.0", - "hoa/exception": "~1.0" - }, - "require-dev": { - "hoa/test": "~2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Hoa\\Protocol\\": "." - }, - "files": [ - "Wrapper.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Ivan Enderlin", - "email": "ivan.enderlin@hoa-project.net" - }, - { - "name": "Hoa community", - "homepage": "https://hoa-project.net/" - } - ], - "description": "The Hoa\\Protocol library.", - "homepage": "https://hoa-project.net/", - "keywords": [ - "library", - "protocol", - "resource", - "stream", - "wrapper" - ], - "time": "2017-01-14T12:26:10+00:00" - }, - { - "name": "hoa/regex", - "version": "1.17.01.13", - "source": { - "type": "git", - "url": "https://github.com/hoaproject/Regex.git", - "reference": "7e263a61b6fb45c1d03d8e5ef77668518abd5bec" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/hoaproject/Regex/zipball/7e263a61b6fb45c1d03d8e5ef77668518abd5bec", - "reference": "7e263a61b6fb45c1d03d8e5ef77668518abd5bec", - "shasum": "" - }, - "require": { - "hoa/consistency": "~1.0", - "hoa/exception": "~1.0", - "hoa/math": "~1.0", - "hoa/protocol": "~1.0", - "hoa/ustring": "~4.0", - "hoa/visitor": "~2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Hoa\\Regex\\": "." - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Ivan Enderlin", - "email": "ivan.enderlin@hoa-project.net" - }, - { - "name": "Hoa community", - "homepage": "https://hoa-project.net/" - } - ], - "description": "The Hoa\\Regex library.", - "homepage": "https://hoa-project.net/", - "keywords": [ - "compiler", - "library", - "regex" - ], - "time": "2017-01-13T16:10:24+00:00" - }, - { - "name": "hoa/stream", - "version": "1.17.02.21", - "source": { - "type": "git", - "url": "https://github.com/hoaproject/Stream.git", - "reference": "3293cfffca2de10525df51436adf88a559151d82" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/hoaproject/Stream/zipball/3293cfffca2de10525df51436adf88a559151d82", - "reference": "3293cfffca2de10525df51436adf88a559151d82", - "shasum": "" - }, - "require": { - "hoa/consistency": "~1.0", - "hoa/event": "~1.0", - "hoa/exception": "~1.0", - "hoa/protocol": "~1.0" - }, - "require-dev": { - "hoa/test": "~2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Hoa\\Stream\\": "." - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Ivan Enderlin", - "email": "ivan.enderlin@hoa-project.net" - }, - { - "name": "Hoa community", - "homepage": "https://hoa-project.net/" - } - ], - "description": "The Hoa\\Stream library.", - "homepage": "https://hoa-project.net/", - "keywords": [ - "Context", - "bucket", - "composite", - "filter", - "in", - "library", - "out", - "protocol", - "stream", - "wrapper" - ], - "time": "2017-02-21T16:01:06+00:00" - }, - { - "name": "hoa/ustring", - "version": "4.17.01.16", - "source": { - "type": "git", - "url": "https://github.com/hoaproject/Ustring.git", - "reference": "e6326e2739178799b1fe3fdd92029f9517fa17a0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/hoaproject/Ustring/zipball/e6326e2739178799b1fe3fdd92029f9517fa17a0", - "reference": "e6326e2739178799b1fe3fdd92029f9517fa17a0", - "shasum": "" - }, - "require": { - "hoa/consistency": "~1.0", - "hoa/exception": "~1.0" - }, - "require-dev": { - "hoa/test": "~2.0" - }, - "suggest": { - "ext-iconv": "ext/iconv must be present (or a third implementation) to use Hoa\\Ustring::transcode().", - "ext-intl": "To get a better Hoa\\Ustring::toAscii() and Hoa\\Ustring::compareTo()." - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.x-dev" - } - }, - "autoload": { - "psr-4": { - "Hoa\\Ustring\\": "." - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Ivan Enderlin", - "email": "ivan.enderlin@hoa-project.net" - }, - { - "name": "Hoa community", - "homepage": "https://hoa-project.net/" - } - ], - "description": "The Hoa\\Ustring library.", - "homepage": "https://hoa-project.net/", - "keywords": [ - "library", - "search", - "string", - "unicode" - ], - "time": "2017-01-16T07:08:25+00:00" - }, - { - "name": "hoa/visitor", - "version": "2.17.01.16", - "source": { - "type": "git", - "url": "https://github.com/hoaproject/Visitor.git", - "reference": "c18fe1cbac98ae449e0d56e87469103ba08f224a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/hoaproject/Visitor/zipball/c18fe1cbac98ae449e0d56e87469103ba08f224a", - "reference": "c18fe1cbac98ae449e0d56e87469103ba08f224a", - "shasum": "" - }, - "require": { - "hoa/consistency": "~1.0" - }, - "require-dev": { - "hoa/test": "~2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - } - }, - "autoload": { - "psr-4": { - "Hoa\\Visitor\\": "." - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Ivan Enderlin", - "email": "ivan.enderlin@hoa-project.net" - }, - { - "name": "Hoa community", - "homepage": "https://hoa-project.net/" - } - ], - "description": "The Hoa\\Visitor library.", - "homepage": "https://hoa-project.net/", - "keywords": [ - "library", - "structure", - "visit", - "visitor" - ], - "time": "2017-01-16T07:02:03+00:00" - }, - { - "name": "hoa/zformat", - "version": "1.17.01.10", - "source": { - "type": "git", - "url": "https://github.com/hoaproject/Zformat.git", - "reference": "522c381a2a075d4b9dbb42eb4592dd09520e4ac2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/hoaproject/Zformat/zipball/522c381a2a075d4b9dbb42eb4592dd09520e4ac2", - "reference": "522c381a2a075d4b9dbb42eb4592dd09520e4ac2", - "shasum": "" - }, - "require": { - "hoa/consistency": "~1.0", - "hoa/exception": "~1.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Hoa\\Zformat\\": "." - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Ivan Enderlin", - "email": "ivan.enderlin@hoa-project.net" - }, - { - "name": "Hoa community", - "homepage": "https://hoa-project.net/" - } - ], - "description": "The Hoa\\Zformat library.", - "homepage": "https://hoa-project.net/", - "keywords": [ - "library", - "parameter", - "zformat" - ], - "time": "2017-01-10T10:39:54+00:00" - }, - { - "name": "jdorn/sql-formatter", - "version": "v1.2.17", - "source": { - "type": "git", - "url": "https://github.com/jdorn/sql-formatter.git", - "reference": "64990d96e0959dff8e059dfcdc1af130728d92bc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/jdorn/sql-formatter/zipball/64990d96e0959dff8e059dfcdc1af130728d92bc", - "reference": "64990d96e0959dff8e059dfcdc1af130728d92bc", - "shasum": "" - }, - "require": { - "php": ">=5.2.4" - }, - "require-dev": { - "phpunit/phpunit": "3.7.*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3.x-dev" - } - }, - "autoload": { - "classmap": [ - "lib" - ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -2161,35 +1625,292 @@ } ], "description": "a PHP SQL highlighting library", - "homepage": "https://github.com/jdorn/sql-formatter/", + "homepage": "https://github.com/doctrine/sql-formatter/", "keywords": [ "highlight", "sql" ], - "time": "2014-01-12T16:20:24+00:00" + "support": { + "issues": "https://github.com/doctrine/sql-formatter/issues", + "source": "https://github.com/doctrine/sql-formatter/tree/1.1.x" + }, + "time": "2020-07-30T16:57:33+00:00" }, { - "name": "jms/metadata", - "version": "2.1.0", + "name": "exsyst/swagger", + "version": "v0.4.2", "source": { "type": "git", - "url": "https://github.com/schmittjoh/metadata.git", - "reference": "8d8958103485c2cbdd9a9684c3869312ebdaf73a" + "url": "https://github.com/GuilhemN/swagger.git", + "reference": "5d4ad40fe816b7783adc090b64fba6c392be64bc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/schmittjoh/metadata/zipball/8d8958103485c2cbdd9a9684c3869312ebdaf73a", - "reference": "8d8958103485c2cbdd9a9684c3869312ebdaf73a", + "url": "https://api.github.com/repos/GuilhemN/swagger/zipball/5d4ad40fe816b7783adc090b64fba6c392be64bc", + "reference": "5d4ad40fe816b7783adc090b64fba6c392be64bc", "shasum": "" }, "require": { - "php": "^7.2" + "php": "^7.0|^8.0" + }, + "require-dev": { + "symfony/phpunit-bridge": "^4.1.8|^5.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "EXSyst\\Component\\Swagger\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilhem Niot", + "email": "guilhem@gniot.fr" + } + ], + "description": "A php library to manipulate Swagger specifications", + "support": { + "issues": "https://github.com/GuilhemN/swagger/issues", + "source": "https://github.com/GuilhemN/swagger/tree/v0.4.2" + }, + "time": "2020-11-19T17:14:18+00:00" + }, + { + "name": "illuminate/collections", + "version": "v8.35.1", + "source": { + "type": "git", + "url": "https://github.com/illuminate/collections.git", + "reference": "0a7a96520928b61df1750b4e1909588f10ae2abe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/collections/zipball/0a7a96520928b61df1750b4e1909588f10ae2abe", + "reference": "0a7a96520928b61df1750b4e1909588f10ae2abe", + "shasum": "" + }, + "require": { + "illuminate/contracts": "^8.0", + "illuminate/macroable": "^8.0", + "php": "^7.3|^8.0" + }, + "suggest": { + "symfony/var-dumper": "Required to use the dump method (^5.1.4)." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "8.x-dev" + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Support\\": "" + }, + "files": [ + "helpers.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Collections package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2021-03-25T14:54:04+00:00" + }, + { + "name": "illuminate/contracts", + "version": "v8.35.1", + "source": { + "type": "git", + "url": "https://github.com/illuminate/contracts.git", + "reference": "121cea1d8b8772bc7fee99c71ecf0f57c1d77b3b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/contracts/zipball/121cea1d8b8772bc7fee99c71ecf0f57c1d77b3b", + "reference": "121cea1d8b8772bc7fee99c71ecf0f57c1d77b3b", + "shasum": "" + }, + "require": { + "php": "^7.3|^8.0", + "psr/container": "^1.0", + "psr/simple-cache": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "8.x-dev" + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Contracts\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Contracts package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2021-03-12T14:45:30+00:00" + }, + { + "name": "illuminate/macroable", + "version": "v8.35.1", + "source": { + "type": "git", + "url": "https://github.com/illuminate/macroable.git", + "reference": "300aa13c086f25116b5f3cde3ca54ff5c822fb05" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/macroable/zipball/300aa13c086f25116b5f3cde3ca54ff5c822fb05", + "reference": "300aa13c086f25116b5f3cde3ca54ff5c822fb05", + "shasum": "" + }, + "require": { + "php": "^7.3|^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "8.x-dev" + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Support\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Macroable package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2020-10-27T15:20:30+00:00" + }, + { + "name": "jean85/pretty-package-versions", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/Jean85/pretty-package-versions.git", + "reference": "b2c4ec2033a0196317a467cb197c7c843b794ddf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/b2c4ec2033a0196317a467cb197c7c843b794ddf", + "reference": "b2c4ec2033a0196317a467cb197c7c843b794ddf", + "shasum": "" + }, + "require": { + "composer-runtime-api": "^2.0.0", + "php": "^7.1|^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.17", + "jean85/composer-provided-replaced-stub-package": "^1.0", + "phpstan/phpstan": "^0.12.66", + "phpunit/phpunit": "^7.5|^8.5|^9.4", + "vimeo/psalm": "^4.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Jean85\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Alessandro Lai", + "email": "alessandro.lai85@gmail.com" + } + ], + "description": "A library to get pretty versions strings of installed dependencies", + "keywords": [ + "composer", + "package", + "release", + "versions" + ], + "support": { + "issues": "https://github.com/Jean85/pretty-package-versions/issues", + "source": "https://github.com/Jean85/pretty-package-versions/tree/2.0.3" + }, + "time": "2021-02-22T10:52:38+00:00" + }, + { + "name": "jms/metadata", + "version": "2.5.0", + "source": { + "type": "git", + "url": "https://github.com/schmittjoh/metadata.git", + "reference": "b5c52549807b2d855b3d7e36ec164c00eb547338" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/schmittjoh/metadata/zipball/b5c52549807b2d855b3d7e36ec164c00eb547338", + "reference": "b5c52549807b2d855b3d7e36ec164c00eb547338", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0" }, "require-dev": { "doctrine/cache": "^1.0", - "doctrine/coding-standard": "^4.0", - "phpunit/phpunit": "^7.0", - "symfony/cache": "^3.1|^4.0" + "doctrine/coding-standard": "^8.0", + "mikey179/vfsstream": "^1.6.7", + "phpunit/phpunit": "^8.5|^9.0", + "psr/container": "^1.0", + "symfony/cache": "^3.1|^4.0|^5.0", + "symfony/dependency-injection": "^3.1|^4.0|^5.0" }, "type": "library", "extra": { @@ -2223,42 +1944,44 @@ "xml", "yaml" ], - "time": "2019-09-17T15:30:40+00:00" + "support": { + "issues": "https://github.com/schmittjoh/metadata/issues", + "source": "https://github.com/schmittjoh/metadata/tree/2.5.0" + }, + "time": "2021-03-07T19:20:09+00:00" }, { "name": "jms/serializer", - "version": "3.4.0", + "version": "3.12.2", "source": { "type": "git", "url": "https://github.com/schmittjoh/serializer.git", - "reference": "e2d3c49d9322a08ee32221a5623c898160dada79" + "reference": "ea54838a0acd960839b7401bfd83fcd6ebe34aed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/schmittjoh/serializer/zipball/e2d3c49d9322a08ee32221a5623c898160dada79", - "reference": "e2d3c49d9322a08ee32221a5623c898160dada79", + "url": "https://api.github.com/repos/schmittjoh/serializer/zipball/ea54838a0acd960839b7401bfd83fcd6ebe34aed", + "reference": "ea54838a0acd960839b7401bfd83fcd6ebe34aed", "shasum": "" }, "require": { "doctrine/annotations": "^1.0", "doctrine/instantiator": "^1.0.3", - "hoa/compiler": "^3.17.08.08", + "doctrine/lexer": "^1.1", "jms/metadata": "^2.0", - "php": "^7.2" - }, - "conflict": { - "hoa/consistency": "<1.17.05.02", - "hoa/core": "*", - "hoa/iterator": "<2.16.03.15" + "php": "^7.2||^8.0", + "phpstan/phpdoc-parser": "^0.4" }, "require-dev": { - "doctrine/coding-standard": "^5.0", + "doctrine/coding-standard": "^8.1", "doctrine/orm": "~2.1", + "doctrine/persistence": "^1.3.3|^2.0|^3.0", "doctrine/phpcr-odm": "^1.3|^2.0", "ext-pdo_sqlite": "*", "jackalope/jackalope-doctrine-dbal": "^1.1.5", "ocramius/proxy-manager": "^1.0|^2.0", - "phpunit/phpunit": "^7.5||^8.0", + "phpstan/phpstan": "^0.12.65", + "phpunit/phpunit": "^8.0||^9.0", "psr/container": "^1.0", "symfony/dependency-injection": "^3.0|^4.0|^5.0", "symfony/expression-language": "^3.0|^4.0|^5.0", @@ -2267,7 +1990,7 @@ "symfony/translation": "^3.0|^4.0|^5.0", "symfony/validator": "^3.1.9|^4.0|^5.0", "symfony/yaml": "^3.3|^4.0|^5.0", - "twig/twig": "~1.34|~2.4" + "twig/twig": "~1.34|~2.4|^3.0" }, "suggest": { "doctrine/cache": "Required if you like to use cache functionality.", @@ -2277,7 +2000,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.4-dev" + "dev-master": "3.12-dev" } }, "autoload": { @@ -2308,31 +2031,43 @@ "serialization", "xml" ], - "time": "2019-12-14T20:49:23+00:00" + "support": { + "issues": "https://github.com/schmittjoh/serializer/issues", + "source": "https://github.com/schmittjoh/serializer/tree/3.12.2" + }, + "funding": [ + { + "url": "https://github.com/goetas", + "type": "github" + } + ], + "time": "2021-03-23T12:37:04+00:00" }, { "name": "jms/serializer-bundle", - "version": "3.5.0", + "version": "3.9.1", "source": { "type": "git", "url": "https://github.com/schmittjoh/JMSSerializerBundle.git", - "reference": "5793ec59b2243365a625c0fd78415732097c11e8" + "reference": "2fbf2385668dd715d030567fd41e181bbf41fb42" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/schmittjoh/JMSSerializerBundle/zipball/5793ec59b2243365a625c0fd78415732097c11e8", - "reference": "5793ec59b2243365a625c0fd78415732097c11e8", + "url": "https://api.github.com/repos/schmittjoh/JMSSerializerBundle/zipball/2fbf2385668dd715d030567fd41e181bbf41fb42", + "reference": "2fbf2385668dd715d030567fd41e181bbf41fb42", "shasum": "" }, "require": { - "jms/serializer": "^2.3|^3.0", - "php": "^7.2", + "jms/metadata": "^2.5", + "jms/serializer": "^3.0", + "php": "^7.2 || ^8.0", "symfony/dependency-injection": "^3.3 || ^4.0 || ^5.0", "symfony/framework-bundle": "^3.0 || ^4.0 || ^5.0" }, "require-dev": { + "doctrine/coding-standard": "^8.1", "doctrine/orm": "^2.4", - "phpunit/phpunit": "^6.0", + "phpunit/phpunit": "^8.0 || ^9.0", "symfony/expression-language": "^3.0 || ^4.0 || ^5.0", "symfony/finder": "^3.0 || ^4.0 || ^5.0", "symfony/form": "^3.0 || ^4.0 || ^5.0", @@ -2343,12 +2078,13 @@ }, "suggest": { "jms/di-extra-bundle": "Required to get lazy loading (de)serialization visitors, ^1.3", + "symfony/expression-language": "Required for opcache preloading, ^3.0 || ^4.0 || ^5.0", "symfony/finder": "Required for cache warmup, supported versions ^3.0|^4.0" }, "type": "symfony-bundle", "extra": { "branch-alias": { - "dev-master": "3.5-dev" + "dev-master": "3.9-dev" } }, "autoload": { @@ -2381,69 +2117,234 @@ "serialization", "xml" ], - "time": "2019-11-29T13:03:07+00:00" + "support": { + "issues": "https://github.com/schmittjoh/JMSSerializerBundle/issues", + "source": "https://github.com/schmittjoh/JMSSerializerBundle/tree/3.9.1" + }, + "funding": [ + { + "url": "https://github.com/goetas", + "type": "github" + } + ], + "time": "2021-03-23T12:21:23+00:00" }, { - "name": "kylekatarnls/update-helper", - "version": "1.2.0", + "name": "kadet/functional", + "version": "dev-master", "source": { "type": "git", - "url": "https://github.com/kylekatarnls/update-helper.git", - "reference": "5786fa188e0361b9adf9e8199d7280d1b2db165e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/kylekatarnls/update-helper/zipball/5786fa188e0361b9adf9e8199d7280d1b2db165e", - "reference": "5786fa188e0361b9adf9e8199d7280d1b2db165e", - "shasum": "" + "url": "https://git.kadet.net/kadet/functional-php.git", + "reference": "0b58a4c6207d6e7b95902bb81e49b9ec207fc909" }, "require": { - "composer-plugin-api": "^1.1.0 || ^2.0.0", - "php": ">=5.3.0" + "php": ">=7.1" }, "require-dev": { - "codeclimate/php-test-reporter": "dev-master", - "composer/composer": "2.0.x-dev || ^2.0.0-dev", - "phpunit/phpunit": ">=4.8.35 <6.0" - }, - "type": "composer-plugin", - "extra": { - "class": "UpdateHelper\\ComposerPlugin" + "phpunit/phpunit": "^7.0", + "psy/psysh": "@stable" }, + "default-branch": true, + "type": "library", "autoload": { - "psr-0": { - "UpdateHelper\\": "src/" - } + "psr-4": { + "Kadet\\Functional\\": "./src/" + }, + "files": [ + "./src/functions.php", + "./src/Predicates/index.php" + ] }, - "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { - "name": "Kyle", - "email": "kylekatarnls@gmail.com" + "name": "Kacper Donat", + "email": "kadet1090@gmail.com" } ], - "description": "Update helper", - "time": "2019-07-29T11:03:54+00:00" + "description": "Functional library for PHP", + "time": "2018-09-08T09:28:23+00:00" }, { - "name": "monolog/monolog", - "version": "2.0.2", + "name": "laminas/laminas-diactoros", + "version": "2.5.0", "source": { "type": "git", - "url": "https://github.com/Seldaek/monolog.git", - "reference": "c861fcba2ca29404dc9e617eedd9eff4616986b8" + "url": "https://github.com/laminas/laminas-diactoros.git", + "reference": "4ff7400c1c12e404144992ef43c8b733fd9ad516" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/c861fcba2ca29404dc9e617eedd9eff4616986b8", - "reference": "c861fcba2ca29404dc9e617eedd9eff4616986b8", + "url": "https://api.github.com/repos/laminas/laminas-diactoros/zipball/4ff7400c1c12e404144992ef43c8b733fd9ad516", + "reference": "4ff7400c1c12e404144992ef43c8b733fd9ad516", "shasum": "" }, "require": { - "php": "^7.2", + "laminas/laminas-zendframework-bridge": "^1.0", + "php": "^7.3 || ~8.0.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.0" + }, + "conflict": { + "phpspec/prophecy": "<1.9.0" + }, + "provide": { + "psr/http-factory-implementation": "1.0", + "psr/http-message-implementation": "1.0" + }, + "replace": { + "zendframework/zend-diactoros": "^2.2.1" + }, + "require-dev": { + "ext-curl": "*", + "ext-dom": "*", + "ext-gd": "*", + "ext-libxml": "*", + "http-interop/http-factory-tests": "^0.8.0", + "laminas/laminas-coding-standard": "~1.0.0", + "php-http/psr7-integration-tests": "^1.1", + "phpspec/prophecy-phpunit": "^2.0", + "phpunit/phpunit": "^9.1" + }, + "type": "library", + "extra": { + "laminas": { + "config-provider": "Laminas\\Diactoros\\ConfigProvider", + "module": "Laminas\\Diactoros" + } + }, + "autoload": { + "files": [ + "src/functions/create_uploaded_file.php", + "src/functions/marshal_headers_from_sapi.php", + "src/functions/marshal_method_from_sapi.php", + "src/functions/marshal_protocol_version_from_sapi.php", + "src/functions/marshal_uri_from_sapi.php", + "src/functions/normalize_server.php", + "src/functions/normalize_uploaded_files.php", + "src/functions/parse_cookie_header.php", + "src/functions/create_uploaded_file.legacy.php", + "src/functions/marshal_headers_from_sapi.legacy.php", + "src/functions/marshal_method_from_sapi.legacy.php", + "src/functions/marshal_protocol_version_from_sapi.legacy.php", + "src/functions/marshal_uri_from_sapi.legacy.php", + "src/functions/normalize_server.legacy.php", + "src/functions/normalize_uploaded_files.legacy.php", + "src/functions/parse_cookie_header.legacy.php" + ], + "psr-4": { + "Laminas\\Diactoros\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "PSR HTTP Message implementations", + "homepage": "https://laminas.dev", + "keywords": [ + "http", + "laminas", + "psr", + "psr-17", + "psr-7" + ], + "support": { + "chat": "https://laminas.dev/chat", + "docs": "https://docs.laminas.dev/laminas-diactoros/", + "forum": "https://discourse.laminas.dev", + "issues": "https://github.com/laminas/laminas-diactoros/issues", + "rss": "https://github.com/laminas/laminas-diactoros/releases.atom", + "source": "https://github.com/laminas/laminas-diactoros" + }, + "funding": [ + { + "url": "https://funding.communitybridge.org/projects/laminas-project", + "type": "community_bridge" + } + ], + "time": "2020-11-18T18:39:28+00:00" + }, + { + "name": "laminas/laminas-zendframework-bridge", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/laminas/laminas-zendframework-bridge.git", + "reference": "6cccbddfcfc742eb02158d6137ca5687d92cee32" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laminas/laminas-zendframework-bridge/zipball/6cccbddfcfc742eb02158d6137ca5687d92cee32", + "reference": "6cccbddfcfc742eb02158d6137ca5687d92cee32", + "shasum": "" + }, + "require": { + "php": "^7.3 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7 || ^6.5 || ^7.5 || ^8.1 || ^9.3", + "psalm/plugin-phpunit": "^0.15.1", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "^4.6" + }, + "type": "library", + "extra": { + "laminas": { + "module": "Laminas\\ZendFrameworkBridge" + } + }, + "autoload": { + "files": [ + "src/autoload.php" + ], + "psr-4": { + "Laminas\\ZendFrameworkBridge\\": "src//" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Alias legacy ZF class names to Laminas Project equivalents.", + "keywords": [ + "ZendFramework", + "autoloading", + "laminas", + "zf" + ], + "support": { + "forum": "https://discourse.laminas.dev/", + "issues": "https://github.com/laminas/laminas-zendframework-bridge/issues", + "rss": "https://github.com/laminas/laminas-zendframework-bridge/releases.atom", + "source": "https://github.com/laminas/laminas-zendframework-bridge" + }, + "funding": [ + { + "url": "https://funding.communitybridge.org/projects/laminas-project", + "type": "community_bridge" + } + ], + "time": "2021-02-25T21:54:58+00:00" + }, + { + "name": "monolog/monolog", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/monolog.git", + "reference": "1cb1cde8e8dd0f70cc0fe51354a59acad9302084" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/1cb1cde8e8dd0f70cc0fe51354a59acad9302084", + "reference": "1cb1cde8e8dd0f70cc0fe51354a59acad9302084", + "shasum": "" + }, + "require": { + "php": ">=7.2", "psr/log": "^1.0.1" }, "provide": { @@ -2452,16 +2353,17 @@ "require-dev": { "aws/aws-sdk-php": "^2.4.9 || ^3.0", "doctrine/couchdb": "~1.0@dev", - "elasticsearch/elasticsearch": "^6.0", + "elasticsearch/elasticsearch": "^7", "graylog2/gelf-php": "^1.4.2", - "jakub-onderka/php-parallel-lint": "^0.9", + "mongodb/mongodb": "^1.8", "php-amqplib/php-amqplib": "~2.4", "php-console/php-console": "^3.1.3", "phpspec/prophecy": "^1.6.1", - "phpunit/phpunit": "^8.3", + "phpstan/phpstan": "^0.12.59", + "phpunit/phpunit": "^8.5", "predis/predis": "^1.1", "rollbar/rollbar": "^1.3", - "ruflin/elastica": ">=0.90 <3.0", + "ruflin/elastica": ">=0.90 <7.0.1", "swiftmailer/swiftmailer": "^5.3|^6.0" }, "suggest": { @@ -2481,7 +2383,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.x-dev" + "dev-main": "2.x-dev" } }, "autoload": { @@ -2497,66 +2399,81 @@ { "name": "Jordi Boggiano", "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" + "homepage": "https://seld.be" } ], "description": "Sends your logs to files, sockets, inboxes, databases and various web services", - "homepage": "http://github.com/Seldaek/monolog", + "homepage": "https://github.com/Seldaek/monolog", "keywords": [ "log", "logging", "psr-3" ], - "time": "2019-12-20T14:22:59+00:00" + "support": { + "issues": "https://github.com/Seldaek/monolog/issues", + "source": "https://github.com/Seldaek/monolog/tree/2.2.0" + }, + "funding": [ + { + "url": "https://github.com/Seldaek", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/monolog/monolog", + "type": "tidelift" + } + ], + "time": "2020-12-14T13:15:25+00:00" }, { "name": "nelmio/api-doc-bundle", - "version": "v3.5.0", + "version": "v3.8.2", "source": { "type": "git", "url": "https://github.com/nelmio/NelmioApiDocBundle.git", - "reference": "f596adfb4d16e65d1a1941f907092a119d4c76cb" + "reference": "e57ede23ed765c86a4440b4cd4fde46ff7d67483" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nelmio/NelmioApiDocBundle/zipball/f596adfb4d16e65d1a1941f907092a119d4c76cb", - "reference": "f596adfb4d16e65d1a1941f907092a119d4c76cb", + "url": "https://api.github.com/repos/nelmio/NelmioApiDocBundle/zipball/e57ede23ed765c86a4440b4cd4fde46ff7d67483", + "reference": "e57ede23ed765c86a4440b4cd4fde46ff7d67483", "shasum": "" }, "require": { "exsyst/swagger": "^0.4.1", - "php": "^7.0", - "phpdocumentor/reflection-docblock": "^3.1|^4.0", - "symfony/framework-bundle": "^3.4|^4.0", - "symfony/options-resolver": "^3.4.4|^4.0", - "symfony/property-info": "^3.4|^4.0", + "php": ">=7.1.3", + "phpdocumentor/reflection-docblock": "^3.1|^4.0|^5.0", + "symfony/framework-bundle": "^3.4|^4.0|^5.0", + "symfony/options-resolver": "^3.4.4|^4.0|^5.0", + "symfony/property-info": "^3.4|^4.0|^5.0", "zircote/swagger-php": "^2.0.9" }, "conflict": { "symfony/framework-bundle": "4.2.7" }, "require-dev": { - "api-platform/core": "^2.1.0", + "api-platform/core": "^2.1.2", "doctrine/annotations": "^1.2", "doctrine/common": "^2.4", - "friendsofsymfony/rest-bundle": "^2.0", + "friendsofsymfony/rest-bundle": "^2.0|^3.0", "jms/serializer": "^1.14|^3.0", - "jms/serializer-bundle": "^2.0|^3.0", + "jms/serializer-bundle": "^2.3|^3.0", "sensio/framework-extra-bundle": "^3.0.13|^4.0|^5.0", - "symfony/asset": "^3.4|^4.0", - "symfony/browser-kit": "^3.4|^4.0", - "symfony/cache": "^3.4|^4.0", - "symfony/config": "^3.4|^4.0", - "symfony/console": "^3.4|^4.0", - "symfony/dom-crawler": "^3.4|^4.0", - "symfony/form": "^3.4|^4.0", - "symfony/phpunit-bridge": "^3.4.24|^4.0", - "symfony/property-access": "^3.4|^4.0", - "symfony/routing": "^3.4|^4.0", - "symfony/stopwatch": "^3.4|^4.0", - "symfony/templating": "^3.4|^4.0", - "symfony/twig-bundle": "^3.4|^4.0", - "symfony/validator": "^3.4|^4.0", + "symfony/asset": "^3.4|^4.0|^5.0", + "symfony/browser-kit": "^3.4|^4.0|^5.0", + "symfony/cache": "^3.4|^4.0|^5.0", + "symfony/config": "^3.4|^4.0|^5.0", + "symfony/console": "^3.4|^4.0|^5.0", + "symfony/dom-crawler": "^3.4|^4.0|^5.0", + "symfony/expression-language": "^3.4|^4.0|^5.0", + "symfony/form": "^3.4|^4.0|^5.0", + "symfony/phpunit-bridge": "^3.4.24|^4.0|^5.0", + "symfony/property-access": "^3.4|^4.0|^5.0", + "symfony/routing": "^3.4.42|^4.0|^5.0", + "symfony/stopwatch": "^3.4|^4.0|^5.0", + "symfony/templating": "^3.4|^4.0|^5.0", + "symfony/twig-bundle": "^3.4|^4.0|^5.0", + "symfony/validator": "^3.4|^4.0|^5.0", "willdurand/hateoas-bundle": "^1.0|^2.0" }, "suggest": { @@ -2566,13 +2483,16 @@ "type": "symfony-bundle", "extra": { "branch-alias": { - "dev-master": "3.2.x-dev" + "dev-3.x": "3.7.x-dev" } }, "autoload": { "psr-4": { "Nelmio\\ApiDocBundle\\": "" - } + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -2595,47 +2515,65 @@ "documentation", "rest" ], - "time": "2019-11-21T17:18:16+00:00" + "support": { + "issues": "https://github.com/nelmio/NelmioApiDocBundle/issues", + "source": "https://github.com/nelmio/NelmioApiDocBundle/tree/v3.8.2" + }, + "time": "2020-12-29T09:27:09+00:00" }, { "name": "nesbot/carbon", - "version": "1.39.1", + "version": "2.46.0", "source": { "type": "git", "url": "https://github.com/briannesbitt/Carbon.git", - "reference": "4be0c005164249208ce1b5ca633cd57bdd42ff33" + "reference": "2fd2c4a77d58a4e95234c8a61c5df1f157a91bf4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/4be0c005164249208ce1b5ca633cd57bdd42ff33", - "reference": "4be0c005164249208ce1b5ca633cd57bdd42ff33", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/2fd2c4a77d58a4e95234c8a61c5df1f157a91bf4", + "reference": "2fd2c4a77d58a4e95234c8a61c5df1f157a91bf4", "shasum": "" }, "require": { - "kylekatarnls/update-helper": "^1.1", - "php": ">=5.3.9", - "symfony/translation": "~2.6 || ~3.0 || ~4.0" + "ext-json": "*", + "php": "^7.1.8 || ^8.0", + "symfony/polyfill-mbstring": "^1.0", + "symfony/translation": "^3.4 || ^4.0 || ^5.0" }, "require-dev": { - "composer/composer": "^1.2", - "friendsofphp/php-cs-fixer": "~2", - "phpunit/phpunit": "^4.8.35 || ^5.7" + "doctrine/orm": "^2.7", + "friendsofphp/php-cs-fixer": "^2.14 || ^3.0", + "kylekatarnls/multi-tester": "^2.0", + "phpmd/phpmd": "^2.9", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^0.12.54", + "phpunit/phpunit": "^7.5.20 || ^8.5.14", + "squizlabs/php_codesniffer": "^3.4" }, "bin": [ - "bin/upgrade-carbon" + "bin/carbon" ], "type": "library", "extra": { - "update-helper": "Carbon\\Upgrade", + "branch-alias": { + "dev-master": "2.x-dev", + "dev-3.x": "3.x-dev" + }, "laravel": { "providers": [ "Carbon\\Laravel\\ServiceProvider" ] + }, + "phpstan": { + "includes": [ + "extension.neon" + ] } }, "autoload": { "psr-4": { - "": "src/" + "Carbon\\": "src/Carbon/" } }, "notification-url": "https://packagist.org/downloads/", @@ -2647,67 +2585,34 @@ "name": "Brian Nesbitt", "email": "brian@nesbot.com", "homepage": "http://nesbot.com" + }, + { + "name": "kylekatarnls", + "homepage": "http://github.com/kylekatarnls" } ], - "description": "A simple API extension for DateTime.", + "description": "An API extension for DateTime that supports 281 different languages.", "homepage": "http://carbon.nesbot.com", "keywords": [ "date", "datetime", "time" ], - "time": "2019-10-14T05:51:36+00:00" - }, - { - "name": "ocramius/package-versions", - "version": "1.5.1", - "source": { - "type": "git", - "url": "https://github.com/Ocramius/PackageVersions.git", - "reference": "1d32342b8c1eb27353c8887c366147b4c2da673c" + "support": { + "issues": "https://github.com/briannesbitt/Carbon/issues", + "source": "https://github.com/briannesbitt/Carbon" }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Ocramius/PackageVersions/zipball/1d32342b8c1eb27353c8887c366147b4c2da673c", - "reference": "1d32342b8c1eb27353c8887c366147b4c2da673c", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.0.0", - "php": "^7.3.0" - }, - "require-dev": { - "composer/composer": "^1.8.6", - "doctrine/coding-standard": "^6.0.0", - "ext-zip": "*", - "infection/infection": "^0.13.4", - "phpunit/phpunit": "^8.2.5", - "vimeo/psalm": "^3.4.9" - }, - "type": "composer-plugin", - "extra": { - "class": "PackageVersions\\Installer", - "branch-alias": { - "dev-master": "1.6.x-dev" - } - }, - "autoload": { - "psr-4": { - "PackageVersions\\": "src/PackageVersions" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ + "funding": [ { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com" + "url": "https://opencollective.com/Carbon", + "type": "open_collective" + }, + { + "url": "https://tidelift.com/funding/github/packagist/nesbot/carbon", + "type": "tidelift" } ], - "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", - "time": "2019-07-17T15:49:50+00:00" + "time": "2021-02-24T17:30:44+00:00" }, { "name": "ocramius/proxy-manager", @@ -2777,32 +2682,102 @@ "proxy pattern", "service proxies" ], + "support": { + "issues": "https://github.com/Ocramius/ProxyManager/issues", + "source": "https://github.com/Ocramius/ProxyManager/tree/2.2.x" + }, "time": "2019-08-10T08:37:15+00:00" }, { - "name": "phpdocumentor/reflection-common", - "version": "2.0.0", + "name": "php-http/discovery", + "version": "1.13.0", "source": { "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a" + "url": "https://github.com/php-http/discovery.git", + "reference": "788f72d64c43dc361e7fcc7464c3d947c64984a7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/63a995caa1ca9e5590304cd845c15ad6d482a62a", - "reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a", + "url": "https://api.github.com/repos/php-http/discovery/zipball/788f72d64c43dc361e7fcc7464c3d947c64984a7", + "reference": "788f72d64c43dc361e7fcc7464c3d947c64984a7", "shasum": "" }, "require": { - "php": ">=7.1" + "php": "^7.1 || ^8.0" + }, + "conflict": { + "nyholm/psr7": "<1.0" }, "require-dev": { - "phpunit/phpunit": "~6" + "graham-campbell/phpspec-skip-example-extension": "^5.0", + "php-http/httplug": "^1.0 || ^2.0", + "php-http/message-factory": "^1.0", + "phpspec/phpspec": "^5.1 || ^6.1", + "puli/composer-plugin": "1.0.0-beta10" + }, + "suggest": { + "php-http/message": "Allow to use Guzzle, Diactoros or Slim Framework factories", + "puli/composer-plugin": "Sets up Puli which is recommended for Discovery to work. Check http://docs.php-http.org/en/latest/discovery.html for more details." }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.x-dev" + "dev-master": "1.9-dev" + } + }, + "autoload": { + "psr-4": { + "Http\\Discovery\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "Finds installed HTTPlug implementations and PSR-7 message factories", + "homepage": "http://php-http.org", + "keywords": [ + "adapter", + "client", + "discovery", + "factory", + "http", + "message", + "psr7" + ], + "support": { + "issues": "https://github.com/php-http/discovery/issues", + "source": "https://github.com/php-http/discovery/tree/1.13.0" + }, + "time": "2020-11-27T14:49:42+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-2.x": "2.x-dev" } }, "autoload": { @@ -2829,45 +2804,45 @@ "reflection", "static analysis" ], - "time": "2018-08-07T13:53:10+00:00" + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", + "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + }, + "time": "2020-06-27T09:03:43+00:00" }, { "name": "phpdocumentor/reflection-docblock", - "version": "4.3.4", + "version": "5.2.2", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "da3fd972d6bafd628114f7e7e036f45944b62e9c" + "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/da3fd972d6bafd628114f7e7e036f45944b62e9c", - "reference": "da3fd972d6bafd628114f7e7e036f45944b62e9c", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/069a785b2141f5bcf49f3e353548dc1cce6df556", + "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556", "shasum": "" }, "require": { - "php": "^7.0", - "phpdocumentor/reflection-common": "^1.0.0 || ^2.0.0", - "phpdocumentor/type-resolver": "~0.4 || ^1.0.0", - "webmozart/assert": "^1.0" + "ext-filter": "*", + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.2", + "phpdocumentor/type-resolver": "^1.3", + "webmozart/assert": "^1.9.1" }, "require-dev": { - "doctrine/instantiator": "^1.0.5", - "mockery/mockery": "^1.0", - "phpdocumentor/type-resolver": "0.4.*", - "phpunit/phpunit": "^6.4" + "mockery/mockery": "~1.3.2" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.x-dev" + "dev-master": "5.x-dev" } }, "autoload": { "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src/" - ] + "phpDocumentor\\Reflection\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -2878,38 +2853,44 @@ { "name": "Mike van Riel", "email": "me@mikevanriel.com" + }, + { + "name": "Jaap van Otterdijk", + "email": "account@ijaap.nl" } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2019-12-28T18:55:12+00:00" + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/master" + }, + "time": "2020-09-03T19:13:55+00:00" }, { "name": "phpdocumentor/type-resolver", - "version": "1.0.1", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "2e32a6d48972b2c1976ed5d8967145b6cec4a4a9" + "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/2e32a6d48972b2c1976ed5d8967145b6cec4a4a9", - "reference": "2e32a6d48972b2c1976ed5d8967145b6cec4a4a9", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", + "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", "shasum": "" }, "require": { - "php": "^7.1", + "php": "^7.2 || ^8.0", "phpdocumentor/reflection-common": "^2.0" }, "require-dev": { - "ext-tokenizer": "^7.1", - "mockery/mockery": "~1", - "phpunit/phpunit": "^7.0" + "ext-tokenizer": "*" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.x-dev" + "dev-1.x": "1.x-dev" } }, "autoload": { @@ -2928,7 +2909,61 @@ } ], "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", - "time": "2019-08-22T18:11:29+00:00" + "support": { + "issues": "https://github.com/phpDocumentor/TypeResolver/issues", + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.4.0" + }, + "time": "2020-09-17T18:55:26+00:00" + }, + { + "name": "phpstan/phpdoc-parser", + "version": "0.4.14", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpdoc-parser.git", + "reference": "cf4fc7d2aeca6910fba061901ffd7d107ccfdbcc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/cf4fc7d2aeca6910fba061901ffd7d107ccfdbcc", + "reference": "cf4fc7d2aeca6910fba061901ffd7d107ccfdbcc", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "phing/phing": "^2.16.3", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^0.12.60", + "phpstan/phpstan-strict-rules": "^0.12.5", + "phpunit/phpunit": "^7.5.20", + "symfony/process": "^5.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.4-dev" + } + }, + "autoload": { + "psr-4": { + "PHPStan\\PhpDocParser\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPDoc parser with support for nullable, intersection and generic types", + "support": { + "issues": "https://github.com/phpstan/phpdoc-parser/issues", + "source": "https://github.com/phpstan/phpdoc-parser/tree/0.4.14" + }, + "time": "2021-03-19T10:54:14+00:00" }, { "name": "psr/cache", @@ -2974,31 +3009,29 @@ "psr", "psr-6" ], + "support": { + "source": "https://github.com/php-fig/cache/tree/master" + }, "time": "2016-08-06T20:24:11+00:00" }, { "name": "psr/container", - "version": "1.0.0", + "version": "1.1.1", "source": { "type": "git", "url": "https://github.com/php-fig/container.git", - "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" + "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", - "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "url": "https://api.github.com/repos/php-fig/container/zipball/8622567409010282b7aeebe4bb841fe98b58dcaf", + "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=7.2.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, "autoload": { "psr-4": { "Psr\\Container\\": "src/" @@ -3011,7 +3044,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common Container Interface (PHP FIG PSR-11)", @@ -3023,7 +3056,116 @@ "container-interop", "psr" ], - "time": "2017-02-14T16:28:37+00:00" + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/1.1.1" + }, + "time": "2021-03-05T17:36:06+00:00" + }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+00:00" + }, + { + "name": "psr/http-factory", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be", + "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be", + "shasum": "" + }, + "require": { + "php": ">=7.0.0", + "psr/http-message": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-factory/tree/master" + }, + "time": "2019-04-30T12:38:16+00:00" }, { "name": "psr/http-message", @@ -3073,20 +3215,137 @@ "request", "response" ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/master" + }, "time": "2016-08-06T14:39:51+00:00" }, { - "name": "psr/log", - "version": "1.1.2", + "name": "psr/http-server-handler", + "version": "1.0.1", "source": { "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "446d54b4cb6bf489fc9d75f55843658e6f25d801" + "url": "https://github.com/php-fig/http-server-handler.git", + "reference": "aff2f80e33b7f026ec96bb42f63242dc50ffcae7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/446d54b4cb6bf489fc9d75f55843658e6f25d801", - "reference": "446d54b4cb6bf489fc9d75f55843658e6f25d801", + "url": "https://api.github.com/repos/php-fig/http-server-handler/zipball/aff2f80e33b7f026ec96bb42f63242dc50ffcae7", + "reference": "aff2f80e33b7f026ec96bb42f63242dc50ffcae7", + "shasum": "" + }, + "require": { + "php": ">=7.0", + "psr/http-message": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Server\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP server-side request handler", + "keywords": [ + "handler", + "http", + "http-interop", + "psr", + "psr-15", + "psr-7", + "request", + "response", + "server" + ], + "support": { + "issues": "https://github.com/php-fig/http-server-handler/issues", + "source": "https://github.com/php-fig/http-server-handler/tree/master" + }, + "time": "2018-10-30T16:46:14+00:00" + }, + { + "name": "psr/http-server-middleware", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-server-middleware.git", + "reference": "2296f45510945530b9dceb8bcedb5cb84d40c5f5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-server-middleware/zipball/2296f45510945530b9dceb8bcedb5cb84d40c5f5", + "reference": "2296f45510945530b9dceb8bcedb5cb84d40c5f5", + "shasum": "" + }, + "require": { + "php": ">=7.0", + "psr/http-message": "^1.0", + "psr/http-server-handler": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Server\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP server-side middleware", + "keywords": [ + "http", + "http-interop", + "middleware", + "psr", + "psr-15", + "psr-7", + "request", + "response" + ], + "support": { + "issues": "https://github.com/php-fig/http-server-middleware/issues", + "source": "https://github.com/php-fig/http-server-middleware/tree/master" + }, + "time": "2018-10-30T17:12:04+00:00" + }, + { + "name": "psr/log", + "version": "1.1.3", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/0f73288fd15629204f9d42b7055f72dacbe811fc", + "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc", "shasum": "" }, "require": { @@ -3120,30 +3379,83 @@ "psr", "psr-3" ], - "time": "2019-11-01T11:05:21+00:00" + "support": { + "source": "https://github.com/php-fig/log/tree/1.1.3" + }, + "time": "2020-03-23T09:12:05+00:00" }, { - "name": "salsify/json-streaming-parser", - "version": "v8.1.0", + "name": "psr/simple-cache", + "version": "1.0.1", "source": { "type": "git", - "url": "https://github.com/salsify/jsonstreamingparser.git", - "reference": "0e5b5cb12611fe5376af653b360e12e8c6c6f3bd" + "url": "https://github.com/php-fig/simple-cache.git", + "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/salsify/jsonstreamingparser/zipball/0e5b5cb12611fe5376af653b360e12e8c6c6f3bd", - "reference": "0e5b5cb12611fe5376af653b360e12e8c6c6f3bd", + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", + "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\SimpleCache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interfaces for simple caching", + "keywords": [ + "cache", + "caching", + "psr", + "psr-16", + "simple-cache" + ], + "support": { + "source": "https://github.com/php-fig/simple-cache/tree/master" + }, + "time": "2017-10-23T01:57:42+00:00" + }, + { + "name": "salsify/json-streaming-parser", + "version": "v8.2.0", + "source": { + "type": "git", + "url": "https://github.com/salsify/jsonstreamingparser.git", + "reference": "4ae5394136a037e09402ba8b48dbf4e20475e69d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/salsify/jsonstreamingparser/zipball/4ae5394136a037e09402ba8b48dbf4e20475e69d", + "reference": "4ae5394136a037e09402ba8b48dbf4e20475e69d", "shasum": "" }, "require": { "ext-ctype": "*", "ext-mbstring": "*", - "php": "^7.1" + "php": ">=7.1" }, "require-dev": { - "ext-json": "*", - "satooshi/php-coveralls": "~2.0" + "ext-json": "*" }, "type": "library", "extra": { @@ -3188,59 +3500,61 @@ "parser", "streaming" ], - "time": "2019-10-13T13:40:17+00:00" + "support": { + "issues": "https://github.com/salsify/jsonstreamingparser/issues", + "source": "https://github.com/salsify/jsonstreamingparser/tree/master" + }, + "time": "2020-05-22T20:10:04+00:00" }, { "name": "sensio/framework-extra-bundle", - "version": "v5.5.3", + "version": "v5.6.1", "source": { "type": "git", "url": "https://github.com/sensiolabs/SensioFrameworkExtraBundle.git", - "reference": "98f0807137b13d0acfdf3c255a731516e97015de" + "reference": "430d14c01836b77c28092883d195a43ce413ee32" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sensiolabs/SensioFrameworkExtraBundle/zipball/98f0807137b13d0acfdf3c255a731516e97015de", - "reference": "98f0807137b13d0acfdf3c255a731516e97015de", + "url": "https://api.github.com/repos/sensiolabs/SensioFrameworkExtraBundle/zipball/430d14c01836b77c28092883d195a43ce413ee32", + "reference": "430d14c01836b77c28092883d195a43ce413ee32", "shasum": "" }, "require": { "doctrine/annotations": "^1.0", - "php": ">=7.1.3", - "symfony/config": "^4.3|^5.0", - "symfony/dependency-injection": "^4.3|^5.0", - "symfony/framework-bundle": "^4.3|^5.0", - "symfony/http-kernel": "^4.3|^5.0" + "php": ">=7.2.5", + "symfony/config": "^4.4|^5.0", + "symfony/dependency-injection": "^4.4|^5.0", + "symfony/framework-bundle": "^4.4|^5.0", + "symfony/http-kernel": "^4.4|^5.0" }, "conflict": { - "doctrine/doctrine-cache-bundle": "<1.3.1" + "doctrine/doctrine-cache-bundle": "<1.3.1", + "doctrine/persistence": "<1.3" }, "require-dev": { + "doctrine/dbal": "^2.10|^3.0", "doctrine/doctrine-bundle": "^1.11|^2.0", "doctrine/orm": "^2.5", "nyholm/psr7": "^1.1", - "symfony/browser-kit": "^4.3|^5.0", - "symfony/dom-crawler": "^4.3|^5.0", - "symfony/expression-language": "^4.3|^5.0", - "symfony/finder": "^4.3|^5.0", + "symfony/browser-kit": "^4.4|^5.0", + "symfony/doctrine-bridge": "^4.4|^5.0", + "symfony/dom-crawler": "^4.4|^5.0", + "symfony/expression-language": "^4.4|^5.0", + "symfony/finder": "^4.4|^5.0", "symfony/monolog-bridge": "^4.0|^5.0", "symfony/monolog-bundle": "^3.2", - "symfony/phpunit-bridge": "^4.3.5|^5.0", + "symfony/phpunit-bridge": "^4.4.9|^5.0.9", "symfony/psr-http-message-bridge": "^1.1", - "symfony/security-bundle": "^4.3|^5.0", - "symfony/twig-bundle": "^4.3|^5.0", - "symfony/yaml": "^4.3|^5.0", + "symfony/security-bundle": "^4.4|^5.0", + "symfony/twig-bundle": "^4.4|^5.0", + "symfony/yaml": "^4.4|^5.0", "twig/twig": "^1.34|^2.4|^3.0" }, - "suggest": { - "symfony/expression-language": "", - "symfony/psr-http-message-bridge": "To use the PSR-7 converters", - "symfony/security-bundle": "" - }, "type": "symfony-bundle", "extra": { "branch-alias": { - "dev-master": "5.5.x-dev" + "dev-master": "5.6.x-dev" } }, "autoload": { @@ -3266,38 +3580,214 @@ "annotations", "controllers" ], - "time": "2019-12-27T08:57:19+00:00" + "support": { + "issues": "https://github.com/sensiolabs/SensioFrameworkExtraBundle/issues", + "source": "https://github.com/sensiolabs/SensioFrameworkExtraBundle/tree/v5.6.1" + }, + "time": "2020-08-25T19:10:18+00:00" }, { - "name": "symfony/asset", - "version": "v4.4.2", + "name": "spiral/goridge", + "version": "v2.4.5", "source": { "type": "git", - "url": "https://github.com/symfony/asset.git", - "reference": "7ec5fc653dab63d7519a6f411982ee224a696d66" + "url": "https://github.com/spiral/goridge-php.git", + "reference": "a7373de7f86a5452f8ad61bd1340dc158626f7f8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/asset/zipball/7ec5fc653dab63d7519a6f411982ee224a696d66", - "reference": "7ec5fc653dab63d7519a6f411982ee224a696d66", + "url": "https://api.github.com/repos/spiral/goridge-php/zipball/a7373de7f86a5452f8ad61bd1340dc158626f7f8", + "reference": "a7373de7f86a5452f8ad61bd1340dc158626f7f8", "shasum": "" }, "require": { - "php": "^7.1.3" + "ext-json": "*", + "php": ">=7.2" }, "require-dev": { - "symfony/http-foundation": "^3.4|^4.0|^5.0", - "symfony/http-kernel": "^3.4|^4.0|^5.0" + "phpstan/phpstan": "^0.12.23", + "phpunit/phpunit": "~8.0", + "spiral/code-style": "^1.0" + }, + "type": "goridge", + "autoload": { + "psr-4": { + "Spiral\\Goridge\\": "src/" + }, + "files": [ + "src/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Anton Titov / Wolfy-J", + "email": "wolfy.jd@gmail.com" + } + ], + "description": "High-performance PHP-to-Golang RPC bridge", + "support": { + "issues": "https://github.com/spiral/goridge-php/issues", + "source": "https://github.com/spiral/goridge-php/tree/v2.4.5" + }, + "time": "2020-08-14T14:28:30+00:00" + }, + { + "name": "spiral/roadrunner", + "version": "v1.9.2", + "source": { + "type": "git", + "url": "https://github.com/spiral/roadrunner.git", + "reference": "b934cc5e46e8b8ce92cacc4fe0094603992706f2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spiral/roadrunner/zipball/b934cc5e46e8b8ce92cacc4fe0094603992706f2", + "reference": "b934cc5e46e8b8ce92cacc4fe0094603992706f2", + "shasum": "" + }, + "require": { + "composer/package-versions-deprecated": "^1.8", + "ext-curl": "*", + "ext-json": "*", + "laminas/laminas-diactoros": "^1.3.6 || ^2.0", + "php": "^7.2 || ^8.0", + "psr/http-factory": "^1.0.1", + "psr/http-message": "^1.0.1", + "spiral/goridge": "^2.4.2", + "symfony/console": "^2.5.0 || ^3.0.0 || ^4.0.0 || ^5.0.0" + }, + "require-dev": { + "phpstan/phpstan": "~0.12.34" + }, + "bin": [ + "bin/rr" + ], + "type": "server", + "autoload": { + "psr-4": { + "Spiral\\RoadRunner\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Anton Titov / Wolfy-J", + "email": "wolfy.jd@gmail.com" + }, + { + "name": "RoadRunner Community", + "homepage": "https://github.com/spiral/roadrunner/graphs/contributors" + } + ], + "description": "High-performance PHP application server, load-balancer and process manager written in Golang", + "support": { + "issues": "https://github.com/spiral/roadrunner/issues", + "source": "https://github.com/spiral/roadrunner/tree/v1.9.2" + }, + "time": "2021-01-14T16:04:43+00:00" + }, + { + "name": "symfony/amqp-messenger", + "version": "v5.2.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/amqp-messenger.git", + "reference": "cf309a35ed08caa77886ee6a352b8491c7681424" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/amqp-messenger/zipball/cf309a35ed08caa77886ee6a352b8491c7681424", + "reference": "cf309a35ed08caa77886ee6a352b8491c7681424", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1", + "symfony/messenger": "^5.1" + }, + "require-dev": { + "symfony/event-dispatcher": "^4.4|^5.0", + "symfony/process": "^4.4|^5.0", + "symfony/property-access": "^4.4|^5.0", + "symfony/serializer": "^4.4|^5.0" + }, + "type": "symfony-bridge", + "autoload": { + "psr-4": { + "Symfony\\Component\\Messenger\\Bridge\\Amqp\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony AMQP extension Messenger Bridge", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/amqp-messenger/tree/v5.2.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-01-27T11:19:04+00:00" + }, + { + "name": "symfony/asset", + "version": "v5.2.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/asset.git", + "reference": "54a42aa50f9359d1184bf7e954521b45ca3d5828" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/asset/zipball/54a42aa50f9359d1184bf7e954521b45ca3d5828", + "reference": "54a42aa50f9359d1184bf7e954521b45ca3d5828", + "shasum": "" + }, + "require": { + "php": ">=7.2.5" + }, + "require-dev": { + "symfony/http-client": "^4.4|^5.0", + "symfony/http-foundation": "^4.4|^5.0", + "symfony/http-kernel": "^4.4|^5.0" }, "suggest": { "symfony/http-foundation": "" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.4-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\Asset\\": "" @@ -3320,59 +3810,75 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Asset Component", + "description": "Manages URL generation and versioning of web assets such as CSS stylesheets, JavaScript files and image files", "homepage": "https://symfony.com", - "time": "2019-10-12T00:35:04+00:00" + "support": { + "source": "https://github.com/symfony/asset/tree/v5.2.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-01-27T10:01:46+00:00" }, { "name": "symfony/cache", - "version": "v5.0.2", + "version": "v5.2.6", "source": { "type": "git", "url": "https://github.com/symfony/cache.git", - "reference": "6e8d978878ae5de705ec9fabbb6011cc18776bc9" + "reference": "093d69bb10c959553c8beb828b8d4ea250a247dd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/6e8d978878ae5de705ec9fabbb6011cc18776bc9", - "reference": "6e8d978878ae5de705ec9fabbb6011cc18776bc9", + "url": "https://api.github.com/repos/symfony/cache/zipball/093d69bb10c959553c8beb828b8d4ea250a247dd", + "reference": "093d69bb10c959553c8beb828b8d4ea250a247dd", "shasum": "" }, "require": { - "php": "^7.2.5", - "psr/cache": "~1.0", - "psr/log": "~1.0", + "php": ">=7.2.5", + "psr/cache": "^1.0|^2.0", + "psr/log": "^1.1", "symfony/cache-contracts": "^1.1.7|^2", + "symfony/polyfill-php80": "^1.15", "symfony/service-contracts": "^1.1|^2", "symfony/var-exporter": "^4.4|^5.0" }, "conflict": { - "doctrine/dbal": "<2.5", + "doctrine/dbal": "<2.10", "symfony/dependency-injection": "<4.4", "symfony/http-kernel": "<4.4", "symfony/var-dumper": "<4.4" }, "provide": { - "psr/cache-implementation": "1.0", + "psr/cache-implementation": "1.0|2.0", "psr/simple-cache-implementation": "1.0", - "symfony/cache-implementation": "1.0" + "symfony/cache-implementation": "1.0|2.0" }, "require-dev": { "cache/integration-tests": "dev-master", - "doctrine/cache": "~1.6", - "doctrine/dbal": "~2.5", - "predis/predis": "~1.1", + "doctrine/cache": "^1.6", + "doctrine/dbal": "^2.10|^3.0", + "predis/predis": "^1.1", "psr/simple-cache": "^1.0", "symfony/config": "^4.4|^5.0", "symfony/dependency-injection": "^4.4|^5.0", + "symfony/filesystem": "^4.4|^5.0", + "symfony/http-kernel": "^4.4|^5.0", + "symfony/messenger": "^4.4|^5.0", "symfony/var-dumper": "^4.4|^5.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\Cache\\": "" @@ -3395,30 +3901,47 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Cache component with PSR-6, PSR-16, and tags", + "description": "Provides an extended PSR-6, PSR-16 (and tags) implementation", "homepage": "https://symfony.com", "keywords": [ "caching", "psr6" ], - "time": "2019-12-12T13:03:32+00:00" + "support": { + "source": "https://github.com/symfony/cache/tree/v5.2.6" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-03-16T09:10:13+00:00" }, { "name": "symfony/cache-contracts", - "version": "v2.0.1", + "version": "v2.2.0", "source": { "type": "git", "url": "https://github.com/symfony/cache-contracts.git", - "reference": "23ed8bfc1a4115feca942cb5f1aacdf3dcdf3c16" + "reference": "8034ca0b61d4dd967f3698aaa1da2507b631d0cb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/23ed8bfc1a4115feca942cb5f1aacdf3dcdf3c16", - "reference": "23ed8bfc1a4115feca942cb5f1aacdf3dcdf3c16", + "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/8034ca0b61d4dd967f3698aaa1da2507b631d0cb", + "reference": "8034ca0b61d4dd967f3698aaa1da2507b631d0cb", "shasum": "" }, "require": { - "php": "^7.2.5", + "php": ">=7.2.5", "psr/cache": "^1.0" }, "suggest": { @@ -3427,7 +3950,11 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-master": "2.2-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" } }, "autoload": { @@ -3459,26 +3986,45 @@ "interoperability", "standards" ], - "time": "2019-11-18T17:27:11+00:00" + "support": { + "source": "https://github.com/symfony/cache-contracts/tree/v2.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-09-07T11:33:47+00:00" }, { "name": "symfony/config", - "version": "v5.0.2", + "version": "v5.2.4", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "7f930484966350906185ba0a604728f7898b7ba0" + "reference": "212d54675bf203ff8aef7d8cee8eecfb72f4a263" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/7f930484966350906185ba0a604728f7898b7ba0", - "reference": "7f930484966350906185ba0a604728f7898b7ba0", + "url": "https://api.github.com/repos/symfony/config/zipball/212d54675bf203ff8aef7d8cee8eecfb72f4a263", + "reference": "212d54675bf203ff8aef7d8cee8eecfb72f4a263", "shasum": "" }, "require": { - "php": "^7.2.5", + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1", "symfony/filesystem": "^4.4|^5.0", - "symfony/polyfill-ctype": "~1.8" + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-php80": "^1.15" }, "conflict": { "symfony/finder": "<4.4" @@ -3494,11 +4040,6 @@ "symfony/yaml": "To use the yaml reference dumper" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\Config\\": "" @@ -3521,47 +4062,67 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Config Component", + "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "homepage": "https://symfony.com", - "time": "2019-12-18T13:50:31+00:00" + "support": { + "source": "https://github.com/symfony/config/tree/v5.2.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-02-23T23:58:19+00:00" }, { "name": "symfony/console", - "version": "v4.4.2", + "version": "v5.2.6", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "82437719dab1e6bdd28726af14cb345c2ec816d0" + "reference": "35f039df40a3b335ebf310f244cb242b3a83ac8d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/82437719dab1e6bdd28726af14cb345c2ec816d0", - "reference": "82437719dab1e6bdd28726af14cb345c2ec816d0", + "url": "https://api.github.com/repos/symfony/console/zipball/35f039df40a3b335ebf310f244cb242b3a83ac8d", + "reference": "35f039df40a3b335ebf310f244cb242b3a83ac8d", "shasum": "" }, "require": { - "php": "^7.1.3", + "php": ">=7.2.5", "symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-php73": "^1.8", - "symfony/service-contracts": "^1.1|^2" + "symfony/polyfill-php80": "^1.15", + "symfony/service-contracts": "^1.1|^2", + "symfony/string": "^5.1" }, "conflict": { - "symfony/dependency-injection": "<3.4", - "symfony/event-dispatcher": "<4.3|>=5", + "symfony/dependency-injection": "<4.4", + "symfony/dotenv": "<5.1", + "symfony/event-dispatcher": "<4.4", "symfony/lock": "<4.4", - "symfony/process": "<3.3" + "symfony/process": "<4.4" }, "provide": { "psr/log-implementation": "1.0" }, "require-dev": { "psr/log": "~1.0", - "symfony/config": "^3.4|^4.0|^5.0", - "symfony/dependency-injection": "^3.4|^4.0|^5.0", - "symfony/event-dispatcher": "^4.3", + "symfony/config": "^4.4|^5.0", + "symfony/dependency-injection": "^4.4|^5.0", + "symfony/event-dispatcher": "^4.4|^5.0", "symfony/lock": "^4.4|^5.0", - "symfony/process": "^3.4|^4.0|^5.0", - "symfony/var-dumper": "^4.3|^5.0" + "symfony/process": "^4.4|^5.0", + "symfony/var-dumper": "^4.4|^5.0" }, "suggest": { "psr/log": "For using the console logger", @@ -3570,11 +4131,6 @@ "symfony/process": "" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.4-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\Console\\": "" @@ -3597,97 +4153,66 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Console Component", + "description": "Eases the creation of beautiful and testable command line interfaces", "homepage": "https://symfony.com", - "time": "2019-12-17T10:32:23+00:00" - }, - { - "name": "symfony/debug", - "version": "v4.4.2", - "source": { - "type": "git", - "url": "https://github.com/symfony/debug.git", - "reference": "5c4c1db977dc70bb3250e1308d3e8c6341aa38f5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/5c4c1db977dc70bb3250e1308d3e8c6341aa38f5", - "reference": "5c4c1db977dc70bb3250e1308d3e8c6341aa38f5", - "shasum": "" - }, - "require": { - "php": "^7.1.3", - "psr/log": "~1.0" - }, - "conflict": { - "symfony/http-kernel": "<3.4" - }, - "require-dev": { - "symfony/http-kernel": "^3.4|^4.0|^5.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.4-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Debug\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" + "keywords": [ + "cli", + "command line", + "console", + "terminal" ], - "authors": [ + "support": { + "source": "https://github.com/symfony/console/tree/v5.2.6" + }, + "funding": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "url": "https://symfony.com/sponsor", + "type": "custom" }, { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "description": "Symfony Debug Component", - "homepage": "https://symfony.com", - "time": "2019-12-16T14:46:54+00:00" + "time": "2021-03-28T09:42:18+00:00" }, { "name": "symfony/dependency-injection", - "version": "v5.0.2", + "version": "v5.2.6", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "f9dbfbf487d08f60b1c83220edcd16559d1e40a2" + "reference": "1e66194bed2a69fa395d26bf1067e5e34483afac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/f9dbfbf487d08f60b1c83220edcd16559d1e40a2", - "reference": "f9dbfbf487d08f60b1c83220edcd16559d1e40a2", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/1e66194bed2a69fa395d26bf1067e5e34483afac", + "reference": "1e66194bed2a69fa395d26bf1067e5e34483afac", "shasum": "" }, "require": { - "php": "^7.2.5", + "php": ">=7.2.5", "psr/container": "^1.0", + "symfony/deprecation-contracts": "^2.1", + "symfony/polyfill-php80": "^1.15", "symfony/service-contracts": "^1.1.6|^2" }, "conflict": { - "symfony/config": "<5.0", + "symfony/config": "<5.1", "symfony/finder": "<4.4", "symfony/proxy-manager-bridge": "<4.4", "symfony/yaml": "<4.4" }, "provide": { "psr/container-implementation": "1.0", - "symfony/service-implementation": "1.0" + "symfony/service-implementation": "1.0|2.0" }, "require-dev": { - "symfony/config": "^5.0", + "symfony/config": "^5.1", "symfony/expression-language": "^4.4|^5.0", "symfony/yaml": "^4.4|^5.0" }, @@ -3699,11 +4224,6 @@ "symfony/yaml": "" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\DependencyInjection\\": "" @@ -3726,63 +4246,155 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony DependencyInjection Component", + "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", - "time": "2019-12-19T16:01:11+00:00" + "support": { + "source": "https://github.com/symfony/dependency-injection/tree/v5.2.6" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-03-22T11:10:24+00:00" }, { - "name": "symfony/doctrine-bridge", - "version": "v4.4.2", + "name": "symfony/deprecation-contracts", + "version": "v2.2.0", "source": { "type": "git", - "url": "https://github.com/symfony/doctrine-bridge.git", - "reference": "3e40beb8dbb06d2967e37938f4c3f20f425137a6" + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "5fa56b4074d1ae755beb55617ddafe6f5d78f665" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/3e40beb8dbb06d2967e37938f4c3f20f425137a6", - "reference": "3e40beb8dbb06d2967e37938f4c3f20f425137a6", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/5fa56b4074d1ae755beb55617ddafe6f5d78f665", + "reference": "5fa56b4074d1ae755beb55617ddafe6f5d78f665", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/master" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-09-07T11:33:47+00:00" + }, + { + "name": "symfony/doctrine-bridge", + "version": "v5.2.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/doctrine-bridge.git", + "reference": "72b6d743c6108e2b8d15ab94e1a8a224c4d0d144" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/72b6d743c6108e2b8d15ab94e1a8a224c4d0d144", + "reference": "72b6d743c6108e2b8d15ab94e1a8a224c4d0d144", "shasum": "" }, "require": { "doctrine/event-manager": "~1.0", - "doctrine/persistence": "^1.3", - "php": "^7.1.3", + "doctrine/persistence": "^2", + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php80": "^1.15", "symfony/service-contracts": "^1.1|^2" }, "conflict": { - "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0", - "symfony/dependency-injection": "<3.4", - "symfony/form": "<4.4", - "symfony/http-kernel": "<4.3.7", - "symfony/messenger": "<4.3", - "symfony/security-core": "<4.4", - "symfony/validator": "<4.4.2|<5.0.2,>=5.0" + "doctrine/dbal": "<2.10", + "phpunit/phpunit": "<5.4.3", + "symfony/dependency-injection": "<4.4", + "symfony/form": "<5.1", + "symfony/http-kernel": "<5", + "symfony/messenger": "<4.4", + "symfony/property-info": "<5", + "symfony/security-bundle": "<5", + "symfony/security-core": "<5", + "symfony/validator": "<5.2" }, "require-dev": { - "doctrine/annotations": "~1.7", + "composer/package-versions-deprecated": "^1.8", + "doctrine/annotations": "^1.10.4", "doctrine/cache": "~1.6", "doctrine/collections": "~1.0", - "doctrine/data-fixtures": "1.0.*", - "doctrine/dbal": "~2.4", - "doctrine/orm": "^2.6.3", - "doctrine/reflection": "~1.0", - "symfony/config": "^4.2|^5.0", - "symfony/dependency-injection": "^3.4|^4.0|^5.0", - "symfony/expression-language": "^3.4|^4.0|^5.0", - "symfony/form": "^4.4|^5.0", - "symfony/http-kernel": "^4.3.7", + "doctrine/data-fixtures": "^1.1", + "doctrine/dbal": "^2.10|^3.0", + "doctrine/orm": "^2.7.3", + "symfony/cache": "^5.1", + "symfony/config": "^4.4|^5.0", + "symfony/dependency-injection": "^4.4|^5.0", + "symfony/doctrine-messenger": "^5.1", + "symfony/expression-language": "^4.4|^5.0", + "symfony/form": "^5.1.3", + "symfony/http-kernel": "^5.0", "symfony/messenger": "^4.4|^5.0", - "symfony/property-access": "^3.4|^4.0|^5.0", - "symfony/property-info": "^3.4|^4.0|^5.0", - "symfony/proxy-manager-bridge": "^3.4|^4.0|^5.0", - "symfony/security-core": "^4.4|^5.0", - "symfony/stopwatch": "^3.4|^4.0|^5.0", - "symfony/translation": "^3.4|^4.0|^5.0", - "symfony/validator": "^4.4.2|^5.0.2", - "symfony/var-dumper": "^3.4|^4.0|^5.0" + "symfony/property-access": "^4.4|^5.0", + "symfony/property-info": "^5.0", + "symfony/proxy-manager-bridge": "^4.4|^5.0", + "symfony/security-core": "^5.0", + "symfony/stopwatch": "^4.4|^5.0", + "symfony/translation": "^4.4|^5.0", + "symfony/uid": "^5.1", + "symfony/validator": "^5.2", + "symfony/var-dumper": "^4.4|^5.0" }, "suggest": { "doctrine/data-fixtures": "", @@ -3793,11 +4405,6 @@ "symfony/validator": "" }, "type": "symfony-bridge", - "extra": { - "branch-alias": { - "dev-master": "4.4-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Bridge\\Doctrine\\": "" @@ -3820,40 +4427,126 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Doctrine Bridge", + "description": "Provides integration for Doctrine with various Symfony components", "homepage": "https://symfony.com", - "time": "2019-12-17T08:15:02+00:00" + "support": { + "source": "https://github.com/symfony/doctrine-bridge/tree/v5.2.6" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-03-10T22:10:15+00:00" }, { - "name": "symfony/error-handler", - "version": "v4.4.2", + "name": "symfony/doctrine-messenger", + "version": "v5.2.5", "source": { "type": "git", - "url": "https://github.com/symfony/error-handler.git", - "reference": "6d7d7712a6ff5215ec26215672293b154f1db8c1" + "url": "https://github.com/symfony/doctrine-messenger.git", + "reference": "10136ef0e31ca9839254bd909ef42421b61bc118" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/6d7d7712a6ff5215ec26215672293b154f1db8c1", - "reference": "6d7d7712a6ff5215ec26215672293b154f1db8c1", + "url": "https://api.github.com/repos/symfony/doctrine-messenger/zipball/10136ef0e31ca9839254bd909ef42421b61bc118", + "reference": "10136ef0e31ca9839254bd909ef42421b61bc118", "shasum": "" }, "require": { - "php": "^7.1.3", - "psr/log": "~1.0", - "symfony/debug": "^4.4", + "php": ">=7.2.5", + "symfony/messenger": "^5.1", + "symfony/service-contracts": "^1.1|^2" + }, + "conflict": { + "doctrine/dbal": "<2.10", + "doctrine/persistence": "<1.3" + }, + "require-dev": { + "doctrine/dbal": "^2.10|^3.0", + "doctrine/persistence": "^1.3|^2", + "symfony/property-access": "^4.4|^5.0", + "symfony/serializer": "^4.4|^5.0" + }, + "type": "symfony-bridge", + "autoload": { + "psr-4": { + "Symfony\\Component\\Messenger\\Bridge\\Doctrine\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Doctrine Messenger Bridge", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/doctrine-messenger/tree/v5.2.5" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-03-05T12:14:19+00:00" + }, + { + "name": "symfony/error-handler", + "version": "v5.2.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/error-handler.git", + "reference": "bdb7fb4188da7f4211e4b88350ba0dfdad002b03" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/bdb7fb4188da7f4211e4b88350ba0dfdad002b03", + "reference": "bdb7fb4188da7f4211e4b88350ba0dfdad002b03", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/log": "^1.0", + "symfony/polyfill-php80": "^1.15", "symfony/var-dumper": "^4.4|^5.0" }, "require-dev": { + "symfony/deprecation-contracts": "^2.1", "symfony/http-kernel": "^4.4|^5.0", "symfony/serializer": "^4.4|^5.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.4-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\ErrorHandler\\": "" @@ -3876,54 +4569,69 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony ErrorHandler Component", + "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", - "time": "2019-12-16T14:46:54+00:00" + "support": { + "source": "https://github.com/symfony/error-handler/tree/v5.2.6" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-03-16T09:07:47+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v4.4.2", + "version": "v5.2.4", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "b3c3068a72623287550fe20b84a2b01dcba2686f" + "reference": "d08d6ec121a425897951900ab692b612a61d6240" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/b3c3068a72623287550fe20b84a2b01dcba2686f", - "reference": "b3c3068a72623287550fe20b84a2b01dcba2686f", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/d08d6ec121a425897951900ab692b612a61d6240", + "reference": "d08d6ec121a425897951900ab692b612a61d6240", "shasum": "" }, "require": { - "php": "^7.1.3", - "symfony/event-dispatcher-contracts": "^1.1" + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1", + "symfony/event-dispatcher-contracts": "^2", + "symfony/polyfill-php80": "^1.15" }, "conflict": { - "symfony/dependency-injection": "<3.4" + "symfony/dependency-injection": "<4.4" }, "provide": { "psr/event-dispatcher-implementation": "1.0", - "symfony/event-dispatcher-implementation": "1.1" + "symfony/event-dispatcher-implementation": "2.0" }, "require-dev": { "psr/log": "~1.0", - "symfony/config": "^3.4|^4.0|^5.0", - "symfony/dependency-injection": "^3.4|^4.0|^5.0", - "symfony/expression-language": "^3.4|^4.0|^5.0", - "symfony/http-foundation": "^3.4|^4.0|^5.0", + "symfony/config": "^4.4|^5.0", + "symfony/dependency-injection": "^4.4|^5.0", + "symfony/error-handler": "^4.4|^5.0", + "symfony/expression-language": "^4.4|^5.0", + "symfony/http-foundation": "^4.4|^5.0", "symfony/service-contracts": "^1.1|^2", - "symfony/stopwatch": "^3.4|^4.0|^5.0" + "symfony/stopwatch": "^4.4|^5.0" }, "suggest": { "symfony/dependency-injection": "", "symfony/http-kernel": "" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.4-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\EventDispatcher\\": "" @@ -3946,35 +4654,56 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony EventDispatcher Component", + "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", - "time": "2019-11-28T13:33:56+00:00" + "support": { + "source": "https://github.com/symfony/event-dispatcher/tree/v5.2.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-02-18T17:12:37+00:00" }, { "name": "symfony/event-dispatcher-contracts", - "version": "v1.1.7", + "version": "v2.2.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "c43ab685673fb6c8d84220c77897b1d6cdbe1d18" + "reference": "0ba7d54483095a198fa51781bc608d17e84dffa2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/c43ab685673fb6c8d84220c77897b1d6cdbe1d18", - "reference": "c43ab685673fb6c8d84220c77897b1d6cdbe1d18", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/0ba7d54483095a198fa51781bc608d17e84dffa2", + "reference": "0ba7d54483095a198fa51781bc608d17e84dffa2", "shasum": "" }, "require": { - "php": "^7.1.3" + "php": ">=7.2.5", + "psr/event-dispatcher": "^1" }, "suggest": { - "psr/event-dispatcher": "", "symfony/event-dispatcher-implementation": "" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1-dev" + "dev-master": "2.2-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" } }, "autoload": { @@ -4006,32 +4735,44 @@ "interoperability", "standards" ], - "time": "2019-09-17T09:54:03+00:00" + "support": { + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v2.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-09-07T11:33:47+00:00" }, { "name": "symfony/filesystem", - "version": "v5.0.2", + "version": "v5.2.6", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "1d71f670bc5a07b9ccc97dc44f932177a322d4e6" + "reference": "8c86a82f51658188119e62cff0a050a12d09836f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/1d71f670bc5a07b9ccc97dc44f932177a322d4e6", - "reference": "1d71f670bc5a07b9ccc97dc44f932177a322d4e6", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/8c86a82f51658188119e62cff0a050a12d09836f", + "reference": "8c86a82f51658188119e62cff0a050a12d09836f", "shasum": "" }, "require": { - "php": "^7.2.5", + "php": ">=7.2.5", "symfony/polyfill-ctype": "~1.8" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\Filesystem\\": "" @@ -4054,33 +4795,45 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Filesystem Component", + "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", - "time": "2019-11-26T23:25:11+00:00" + "support": { + "source": "https://github.com/symfony/filesystem/tree/v5.2.6" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-03-28T14:30:26+00:00" }, { "name": "symfony/finder", - "version": "v5.0.2", + "version": "v5.2.4", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "17874dd8ab9a19422028ad56172fb294287a701b" + "reference": "0d639a0943822626290d169965804f79400e6a04" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/17874dd8ab9a19422028ad56172fb294287a701b", - "reference": "17874dd8ab9a19422028ad56172fb294287a701b", + "url": "https://api.github.com/repos/symfony/finder/zipball/0d639a0943822626290d169965804f79400e6a04", + "reference": "0d639a0943822626290d169965804f79400e6a04", "shasum": "" }, "require": { - "php": "^7.2.5" + "php": ">=7.2.5" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\Finder\\": "" @@ -4103,38 +4856,56 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Finder Component", + "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", - "time": "2019-11-18T17:27:11+00:00" + "support": { + "source": "https://github.com/symfony/finder/tree/v5.2.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-02-15T18:55:04+00:00" }, { "name": "symfony/flex", - "version": "v1.6.0", + "version": "v1.12.2", "source": { "type": "git", "url": "https://github.com/symfony/flex.git", - "reference": "952f45d1c5077e658cb16a61d11603bee873f968" + "reference": "e472606b4b3173564f0edbca8f5d32b52fc4f2c9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/flex/zipball/952f45d1c5077e658cb16a61d11603bee873f968", - "reference": "952f45d1c5077e658cb16a61d11603bee873f968", + "url": "https://api.github.com/repos/symfony/flex/zipball/e472606b4b3173564f0edbca8f5d32b52fc4f2c9", + "reference": "e472606b4b3173564f0edbca8f5d32b52fc4f2c9", "shasum": "" }, "require": { - "composer-plugin-api": "^1.0", - "php": "^7.0" + "composer-plugin-api": "^1.0|^2.0", + "php": ">=7.1" }, "require-dev": { - "composer/composer": "^1.0.2", - "symfony/dotenv": "^3.4|^4.0|^5.0", - "symfony/phpunit-bridge": "^3.4.19|^4.1.8|^5.0", - "symfony/process": "^2.7|^3.0|^4.0|^5.0" + "composer/composer": "^1.0.2|^2.0", + "symfony/dotenv": "^4.4|^5.0", + "symfony/filesystem": "^4.4|^5.0", + "symfony/phpunit-bridge": "^4.4|^5.0", + "symfony/process": "^3.4|^4.4|^5.0" }, "type": "composer-plugin", "extra": { "branch-alias": { - "dev-master": "1.5-dev" + "dev-main": "1.12-dev" }, "class": "Symfony\\Flex\\Flex" }, @@ -4154,96 +4925,120 @@ } ], "description": "Composer plugin for Symfony", - "time": "2019-12-13T18:05:11+00:00" + "support": { + "issues": "https://github.com/symfony/flex/issues", + "source": "https://github.com/symfony/flex/tree/v1.12.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-02-16T14:05:05+00:00" }, { "name": "symfony/framework-bundle", - "version": "v4.4.2", + "version": "v5.2.6", "source": { "type": "git", "url": "https://github.com/symfony/framework-bundle.git", - "reference": "c80526b4c22f6ddc23080225bf276f094d2c398e" + "reference": "8889da18c6faa76c6149a90e6542be4afe723f2f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/c80526b4c22f6ddc23080225bf276f094d2c398e", - "reference": "c80526b4c22f6ddc23080225bf276f094d2c398e", + "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/8889da18c6faa76c6149a90e6542be4afe723f2f", + "reference": "8889da18c6faa76c6149a90e6542be4afe723f2f", "shasum": "" }, "require": { "ext-xml": "*", - "php": "^7.1.3", - "symfony/cache": "^4.4|^5.0", - "symfony/config": "^4.3.4|^5.0", - "symfony/dependency-injection": "^4.4.1|^5.0.1", + "php": ">=7.2.5", + "symfony/cache": "^5.2", + "symfony/config": "^5.0", + "symfony/dependency-injection": "^5.2", + "symfony/deprecation-contracts": "^2.1", "symfony/error-handler": "^4.4.1|^5.0.1", - "symfony/filesystem": "^3.4|^4.0|^5.0", - "symfony/finder": "^3.4|^4.0|^5.0", - "symfony/http-foundation": "^4.4|^5.0", - "symfony/http-kernel": "^4.4", + "symfony/event-dispatcher": "^5.1", + "symfony/filesystem": "^4.4|^5.0", + "symfony/finder": "^4.4|^5.0", + "symfony/http-foundation": "^5.2.1", + "symfony/http-kernel": "^5.2.1", "symfony/polyfill-mbstring": "~1.0", - "symfony/routing": "^4.4|^5.0" + "symfony/polyfill-php80": "^1.15", + "symfony/routing": "^5.2" }, "conflict": { "doctrine/persistence": "<1.3", - "phpdocumentor/reflection-docblock": "<3.0", - "phpdocumentor/type-resolver": "<0.2.1", - "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0", - "symfony/asset": "<3.4", - "symfony/browser-kit": "<4.3", - "symfony/console": "<4.3", - "symfony/dom-crawler": "<4.3", - "symfony/dotenv": "<4.3.6", - "symfony/form": "<4.3.5", + "phpdocumentor/reflection-docblock": "<3.2.2", + "phpdocumentor/type-resolver": "<1.4.0", + "phpunit/phpunit": "<5.4.3", + "symfony/asset": "<5.1", + "symfony/browser-kit": "<4.4", + "symfony/console": "<5.2.5", + "symfony/dom-crawler": "<4.4", + "symfony/dotenv": "<5.1", + "symfony/form": "<5.2", "symfony/http-client": "<4.4", "symfony/lock": "<4.4", - "symfony/mailer": "<4.4", + "symfony/mailer": "<5.2", "symfony/messenger": "<4.4", "symfony/mime": "<4.4", - "symfony/property-info": "<3.4", - "symfony/security-bundle": "<4.4", - "symfony/serializer": "<4.4", - "symfony/stopwatch": "<3.4", - "symfony/translation": "<4.4", - "symfony/twig-bridge": "<4.1.1", + "symfony/property-access": "<5.2", + "symfony/property-info": "<4.4", + "symfony/serializer": "<5.2", + "symfony/stopwatch": "<4.4", + "symfony/translation": "<5.0", + "symfony/twig-bridge": "<4.4", "symfony/twig-bundle": "<4.4", - "symfony/validator": "<4.4", + "symfony/validator": "<5.2", "symfony/web-profiler-bundle": "<4.4", - "symfony/workflow": "<4.3.6" + "symfony/workflow": "<5.2" }, "require-dev": { - "doctrine/annotations": "~1.7", + "doctrine/annotations": "^1.10.4", "doctrine/cache": "~1.0", + "doctrine/persistence": "^1.3|^2.0", "paragonie/sodium_compat": "^1.8", - "phpdocumentor/reflection-docblock": "^3.0|^4.0", - "symfony/asset": "^3.4|^4.0|^5.0", - "symfony/browser-kit": "^4.3|^5.0", - "symfony/console": "^4.3.4|^5.0", - "symfony/css-selector": "^3.4|^4.0|^5.0", - "symfony/dom-crawler": "^4.3|^5.0", - "symfony/dotenv": "^4.3.6|^5.0", - "symfony/expression-language": "^3.4|^4.0|^5.0", - "symfony/form": "^4.3.5|^5.0", + "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", + "symfony/asset": "^5.1", + "symfony/browser-kit": "^4.4|^5.0", + "symfony/console": "^5.2", + "symfony/css-selector": "^4.4|^5.0", + "symfony/dom-crawler": "^4.4|^5.0", + "symfony/dotenv": "^5.1", + "symfony/expression-language": "^4.4|^5.0", + "symfony/form": "^5.2", "symfony/http-client": "^4.4|^5.0", "symfony/lock": "^4.4|^5.0", - "symfony/mailer": "^4.4|^5.0", - "symfony/messenger": "^4.4|^5.0", + "symfony/mailer": "^5.2", + "symfony/messenger": "^5.2", "symfony/mime": "^4.4|^5.0", "symfony/polyfill-intl-icu": "~1.0", - "symfony/process": "^3.4|^4.0|^5.0", - "symfony/property-info": "^3.4|^4.0|^5.0", - "symfony/security-csrf": "^3.4|^4.0|^5.0", - "symfony/security-http": "^3.4|^4.0|^5.0", - "symfony/serializer": "^4.4|^5.0", - "symfony/stopwatch": "^3.4|^4.0|^5.0", - "symfony/templating": "^3.4|^4.0|^5.0", - "symfony/translation": "^4.4|^5.0", + "symfony/process": "^4.4|^5.0", + "symfony/property-info": "^4.4|^5.0", + "symfony/security-bundle": "^5.1", + "symfony/security-core": "^4.4|^5.2", + "symfony/security-csrf": "^4.4|^5.0", + "symfony/security-http": "^4.4|^5.0", + "symfony/serializer": "^5.2", + "symfony/stopwatch": "^4.4|^5.0", + "symfony/string": "^5.0", + "symfony/translation": "^5.0", "symfony/twig-bundle": "^4.4|^5.0", - "symfony/validator": "^4.4|^5.0", + "symfony/validator": "^5.2", "symfony/web-link": "^4.4|^5.0", - "symfony/workflow": "^4.3.6|^5.0", - "symfony/yaml": "^3.4|^4.0|^5.0", - "twig/twig": "^1.41|^2.10|^3.0" + "symfony/workflow": "^5.2", + "symfony/yaml": "^4.4|^5.0", + "twig/twig": "^2.10|^3.0" }, "suggest": { "ext-apcu": "For best performance of the system caches", @@ -4256,11 +5051,6 @@ "symfony/yaml": "For using the debug:config and lint:yaml commands" }, "type": "symfony-bundle", - "extra": { - "branch-alias": { - "dev-master": "4.4-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Bundle\\FrameworkBundle\\": "" @@ -4283,39 +5073,136 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony FrameworkBundle", + "description": "Provides a tight integration between Symfony components and the Symfony full-stack framework", "homepage": "https://symfony.com", - "time": "2019-12-17T08:15:02+00:00" + "support": { + "source": "https://github.com/symfony/framework-bundle/tree/v5.2.6" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-03-22T14:43:01+00:00" }, { - "name": "symfony/http-foundation", - "version": "v5.0.2", + "name": "symfony/http-client-contracts", + "version": "v2.3.1", "source": { "type": "git", - "url": "https://github.com/symfony/http-foundation.git", - "reference": "5dd7f6be6e62d86ba6f3154cf40e78936367978b" + "url": "https://github.com/symfony/http-client-contracts.git", + "reference": "41db680a15018f9c1d4b23516059633ce280ca33" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/5dd7f6be6e62d86ba6f3154cf40e78936367978b", - "reference": "5dd7f6be6e62d86ba6f3154cf40e78936367978b", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/41db680a15018f9c1d4b23516059633ce280ca33", + "reference": "41db680a15018f9c1d4b23516059633ce280ca33", "shasum": "" }, "require": { - "php": "^7.2.5", - "symfony/mime": "^4.4|^5.0", - "symfony/polyfill-mbstring": "~1.1" + "php": ">=7.2.5" }, - "require-dev": { - "predis/predis": "~1.0", - "symfony/expression-language": "^4.4|^5.0" + "suggest": { + "symfony/http-client-implementation": "" }, "type": "library", "extra": { + "branch-version": "2.3", "branch-alias": { - "dev-master": "5.0-dev" + "dev-main": "2.3-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" } }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\HttpClient\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to HTTP clients", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/http-client-contracts/tree/v2.3.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-14T17:08:19+00:00" + }, + { + "name": "symfony/http-foundation", + "version": "v5.2.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-foundation.git", + "reference": "54499baea7f7418bce7b5ec92770fd0799e8e9bf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/54499baea7f7418bce7b5ec92770fd0799e8e9bf", + "reference": "54499baea7f7418bce7b5ec92770fd0799e8e9bf", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1", + "symfony/polyfill-mbstring": "~1.1", + "symfony/polyfill-php80": "^1.15" + }, + "require-dev": { + "predis/predis": "~1.0", + "symfony/cache": "^4.4|^5.0", + "symfony/expression-language": "^4.4|^5.0", + "symfony/mime": "^4.4|^5.0" + }, + "suggest": { + "symfony/mime": "To use the file extension guesser" + }, + "type": "library", "autoload": { "psr-4": { "Symfony\\Component\\HttpFoundation\\": "" @@ -4338,61 +5225,88 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony HttpFoundation Component", + "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", - "time": "2019-12-19T16:01:11+00:00" + "support": { + "source": "https://github.com/symfony/http-foundation/tree/v5.2.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-02-25T17:16:57+00:00" }, { "name": "symfony/http-kernel", - "version": "v4.4.2", + "version": "v5.2.6", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "fe310d2e95cd4c356836c8ecb0895a46d97fede2" + "reference": "f34de4c61ca46df73857f7f36b9a3805bdd7e3b2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/fe310d2e95cd4c356836c8ecb0895a46d97fede2", - "reference": "fe310d2e95cd4c356836c8ecb0895a46d97fede2", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/f34de4c61ca46df73857f7f36b9a3805bdd7e3b2", + "reference": "f34de4c61ca46df73857f7f36b9a3805bdd7e3b2", "shasum": "" }, "require": { - "php": "^7.1.3", + "php": ">=7.2.5", "psr/log": "~1.0", - "symfony/error-handler": "^4.4", - "symfony/event-dispatcher": "^4.4", + "symfony/deprecation-contracts": "^2.1", + "symfony/error-handler": "^4.4|^5.0", + "symfony/event-dispatcher": "^5.0", + "symfony/http-client-contracts": "^1.1|^2", "symfony/http-foundation": "^4.4|^5.0", "symfony/polyfill-ctype": "^1.8", - "symfony/polyfill-php73": "^1.9" + "symfony/polyfill-php73": "^1.9", + "symfony/polyfill-php80": "^1.15" }, "conflict": { - "symfony/browser-kit": "<4.3", - "symfony/config": "<3.4", - "symfony/console": ">=5", - "symfony/dependency-injection": "<4.3", - "symfony/translation": "<4.2", - "twig/twig": "<1.34|<2.4,>=2" + "symfony/browser-kit": "<4.4", + "symfony/cache": "<5.0", + "symfony/config": "<5.0", + "symfony/console": "<4.4", + "symfony/dependency-injection": "<5.1.8", + "symfony/doctrine-bridge": "<5.0", + "symfony/form": "<5.0", + "symfony/http-client": "<5.0", + "symfony/mailer": "<5.0", + "symfony/messenger": "<5.0", + "symfony/translation": "<5.0", + "symfony/twig-bridge": "<5.0", + "symfony/validator": "<5.0", + "twig/twig": "<2.13" }, "provide": { "psr/log-implementation": "1.0" }, "require-dev": { - "psr/cache": "~1.0", - "symfony/browser-kit": "^4.3|^5.0", - "symfony/config": "^3.4|^4.0|^5.0", - "symfony/console": "^3.4|^4.0", - "symfony/css-selector": "^3.4|^4.0|^5.0", - "symfony/dependency-injection": "^4.3|^5.0", - "symfony/dom-crawler": "^3.4|^4.0|^5.0", - "symfony/expression-language": "^3.4|^4.0|^5.0", - "symfony/finder": "^3.4|^4.0|^5.0", - "symfony/process": "^3.4|^4.0|^5.0", - "symfony/routing": "^3.4|^4.0|^5.0", - "symfony/stopwatch": "^3.4|^4.0|^5.0", - "symfony/templating": "^3.4|^4.0|^5.0", - "symfony/translation": "^4.2|^5.0", + "psr/cache": "^1.0|^2.0|^3.0", + "symfony/browser-kit": "^4.4|^5.0", + "symfony/config": "^5.0", + "symfony/console": "^4.4|^5.0", + "symfony/css-selector": "^4.4|^5.0", + "symfony/dependency-injection": "^5.1.8", + "symfony/dom-crawler": "^4.4|^5.0", + "symfony/expression-language": "^4.4|^5.0", + "symfony/finder": "^4.4|^5.0", + "symfony/process": "^4.4|^5.0", + "symfony/routing": "^4.4|^5.0", + "symfony/stopwatch": "^4.4|^5.0", + "symfony/translation": "^4.4|^5.0", "symfony/translation-contracts": "^1.1|^2", - "twig/twig": "^1.34|^2.4|^3.0" + "twig/twig": "^2.13|^3.0.4" }, "suggest": { "symfony/browser-kit": "", @@ -4401,11 +5315,6 @@ "symfony/dependency-injection": "" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.4-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\HttpKernel\\": "" @@ -4428,103 +5337,75 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony HttpKernel Component", + "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", - "time": "2019-12-19T16:23:40+00:00" + "support": { + "source": "https://github.com/symfony/http-kernel/tree/v5.2.6" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-03-29T05:16:58+00:00" }, { - "name": "symfony/inflector", - "version": "v5.0.2", + "name": "symfony/messenger", + "version": "v5.2.5", "source": { "type": "git", - "url": "https://github.com/symfony/inflector.git", - "reference": "aaeb5e293294070d1b061fa3d7889bac69909320" + "url": "https://github.com/symfony/messenger.git", + "reference": "bc012fde3b96cfa3adf22f4d8a2e17860dc24a65" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/inflector/zipball/aaeb5e293294070d1b061fa3d7889bac69909320", - "reference": "aaeb5e293294070d1b061fa3d7889bac69909320", + "url": "https://api.github.com/repos/symfony/messenger/zipball/bc012fde3b96cfa3adf22f4d8a2e17860dc24a65", + "reference": "bc012fde3b96cfa3adf22f4d8a2e17860dc24a65", "shasum": "" }, "require": { - "php": "^7.2.5", - "symfony/polyfill-ctype": "~1.8" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Inflector\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Inflector Component", - "homepage": "https://symfony.com", - "keywords": [ - "inflection", - "pluralize", - "singularize", - "string", - "symfony", - "words" - ], - "time": "2019-11-18T17:27:11+00:00" - }, - { - "name": "symfony/mime", - "version": "v5.0.2", - "source": { - "type": "git", - "url": "https://github.com/symfony/mime.git", - "reference": "0e6a4ced216e49d457eddcefb61132173a876d79" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/0e6a4ced216e49d457eddcefb61132173a876d79", - "reference": "0e6a4ced216e49d457eddcefb61132173a876d79", - "shasum": "" - }, - "require": { - "php": "^7.2.5", - "symfony/polyfill-intl-idn": "^1.10", - "symfony/polyfill-mbstring": "^1.0" + "php": ">=7.2.5", + "psr/log": "~1.0", + "symfony/amqp-messenger": "^5.1", + "symfony/deprecation-contracts": "^2.1", + "symfony/doctrine-messenger": "^5.1", + "symfony/polyfill-php80": "^1.15", + "symfony/redis-messenger": "^5.1" }, "conflict": { - "symfony/mailer": "<4.4" + "symfony/event-dispatcher": "<4.4", + "symfony/framework-bundle": "<4.4", + "symfony/http-kernel": "<4.4" }, "require-dev": { - "egulias/email-validator": "^2.1.10", - "symfony/dependency-injection": "^4.4|^5.0" + "psr/cache": "^1.0|^2.0|^3.0", + "symfony/console": "^4.4|^5.0", + "symfony/dependency-injection": "^4.4|^5.0", + "symfony/event-dispatcher": "^4.4|^5.0", + "symfony/http-kernel": "^4.4|^5.0", + "symfony/process": "^4.4|^5.0", + "symfony/property-access": "^4.4|^5.0", + "symfony/serializer": "^4.4|^5.0", + "symfony/service-contracts": "^1.1|^2", + "symfony/stopwatch": "^4.4|^5.0", + "symfony/validator": "^4.4|^5.0" + }, + "suggest": { + "enqueue/messenger-adapter": "For using the php-enqueue library as a transport." }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0-dev" - } - }, "autoload": { "psr-4": { - "Symfony\\Component\\Mime\\": "" + "Symfony\\Component\\Messenger\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -4536,39 +5417,53 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Samuel Roze", + "email": "samuel.roze@gmail.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "A library to manipulate MIME messages", + "description": "Helps applications send and receive messages to/from other applications or via message queues", "homepage": "https://symfony.com", - "keywords": [ - "mime", - "mime-type" + "support": { + "source": "https://github.com/symfony/messenger/tree/v5.2.5" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } ], - "time": "2019-11-30T14:12:50+00:00" + "time": "2021-03-06T07:59:01+00:00" }, { "name": "symfony/monolog-bridge", - "version": "v5.0.2", + "version": "v5.2.5", "source": { "type": "git", "url": "https://github.com/symfony/monolog-bridge.git", - "reference": "dfac10ea8a5863949966d9b6030984c079bec665" + "reference": "8a330ab86c4bdf3983b26abf64bf85574edf0d52" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/monolog-bridge/zipball/dfac10ea8a5863949966d9b6030984c079bec665", - "reference": "dfac10ea8a5863949966d9b6030984c079bec665", + "url": "https://api.github.com/repos/symfony/monolog-bridge/zipball/8a330ab86c4bdf3983b26abf64bf85574edf0d52", + "reference": "8a330ab86c4bdf3983b26abf64bf85574edf0d52", "shasum": "" }, "require": { "monolog/monolog": "^1.25.1|^2", - "php": "^7.2.5", + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1", "symfony/http-kernel": "^4.4|^5.0", "symfony/service-contracts": "^1.1|^2" }, @@ -4579,6 +5474,8 @@ "require-dev": { "symfony/console": "^4.4|^5.0", "symfony/http-client": "^4.4|^5.0", + "symfony/mailer": "^4.4|^5.0", + "symfony/mime": "^4.4|^5.0", "symfony/security-core": "^4.4|^5.0", "symfony/var-dumper": "^4.4|^5.0" }, @@ -4588,11 +5485,6 @@ "symfony/var-dumper": "For using the debugging handlers like the console handler or the log server handler." }, "type": "symfony-bridge", - "extra": { - "branch-alias": { - "dev-master": "5.0-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Bridge\\Monolog\\": "" @@ -4615,36 +5507,53 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Monolog Bridge", + "description": "Provides integration for Monolog with various Symfony components", "homepage": "https://symfony.com", - "time": "2019-12-10T11:06:55+00:00" + "support": { + "source": "https://github.com/symfony/monolog-bridge/tree/v5.2.5" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-03-06T07:59:01+00:00" }, { "name": "symfony/monolog-bundle", - "version": "v3.5.0", + "version": "v3.7.0", "source": { "type": "git", "url": "https://github.com/symfony/monolog-bundle.git", - "reference": "dd80460fcfe1fa2050a7103ad818e9d0686ce6fd" + "reference": "4054b2e940a25195ae15f0a49ab0c51718922eb4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/monolog-bundle/zipball/dd80460fcfe1fa2050a7103ad818e9d0686ce6fd", - "reference": "dd80460fcfe1fa2050a7103ad818e9d0686ce6fd", + "url": "https://api.github.com/repos/symfony/monolog-bundle/zipball/4054b2e940a25195ae15f0a49ab0c51718922eb4", + "reference": "4054b2e940a25195ae15f0a49ab0c51718922eb4", "shasum": "" }, "require": { "monolog/monolog": "~1.22 || ~2.0", - "php": ">=5.6", - "symfony/config": "~3.4 || ~4.0 || ^5.0", - "symfony/dependency-injection": "~3.4.10 || ^4.0.10 || ^5.0", - "symfony/http-kernel": "~3.4 || ~4.0 || ^5.0", - "symfony/monolog-bridge": "~3.4 || ~4.0 || ^5.0" + "php": ">=7.1.3", + "symfony/config": "~4.4 || ^5.0", + "symfony/dependency-injection": "^4.4 || ^5.0", + "symfony/http-kernel": "~4.4 || ^5.0", + "symfony/monolog-bridge": "~4.4 || ^5.0" }, "require-dev": { - "symfony/console": "~3.4 || ~4.0 || ^5.0", - "symfony/phpunit-bridge": "^3.4.19 || ^4.0 || ^5.0", - "symfony/yaml": "~3.4 || ~4.0 || ^5.0" + "symfony/console": "~4.4 || ^5.0", + "symfony/phpunit-bridge": "^5.1", + "symfony/yaml": "~4.4 || ^5.0" }, "type": "symfony-bundle", "extra": { @@ -4671,40 +5580,56 @@ }, { "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" + "homepage": "https://symfony.com/contributors" } ], "description": "Symfony MonologBundle", - "homepage": "http://symfony.com", + "homepage": "https://symfony.com", "keywords": [ "log", "logging" ], - "time": "2019-11-13T13:11:14+00:00" + "support": { + "issues": "https://github.com/symfony/monolog-bundle/issues", + "source": "https://github.com/symfony/monolog-bundle/tree/v3.7.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-03-31T07:20:47+00:00" }, { "name": "symfony/options-resolver", - "version": "v4.4.2", + "version": "v5.2.4", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "2be23e63f33de16b49294ea6581f462932a77e2f" + "reference": "5d0f633f9bbfcf7ec642a2b5037268e61b0a62ce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/2be23e63f33de16b49294ea6581f462932a77e2f", - "reference": "2be23e63f33de16b49294ea6581f462932a77e2f", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/5d0f633f9bbfcf7ec642a2b5037268e61b0a62ce", + "reference": "5d0f633f9bbfcf7ec642a2b5037268e61b0a62ce", "shasum": "" }, "require": { - "php": "^7.1.3" + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1", + "symfony/polyfill-php73": "~1.0", + "symfony/polyfill-php80": "^1.15" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.4-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\OptionsResolver\\": "" @@ -4727,34 +5652,51 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony OptionsResolver Component", + "description": "Provides an improved replacement for the array_replace PHP function", "homepage": "https://symfony.com", "keywords": [ "config", "configuration", "options" ], - "time": "2019-10-28T21:57:16+00:00" + "support": { + "source": "https://github.com/symfony/options-resolver/tree/v5.2.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-01-27T12:56:27+00:00" }, { "name": "symfony/orm-pack", - "version": "v1.0.7", + "version": "v1.1.0", "source": { "type": "git", "url": "https://github.com/symfony/orm-pack.git", - "reference": "c57f5e05232ca40626eb9fa52a32bc8565e9231c" + "reference": "7dd2ed9ba6d7af79f90bdc77522605d40463e533" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/orm-pack/zipball/c57f5e05232ca40626eb9fa52a32bc8565e9231c", - "reference": "c57f5e05232ca40626eb9fa52a32bc8565e9231c", + "url": "https://api.github.com/repos/symfony/orm-pack/zipball/7dd2ed9ba6d7af79f90bdc77522605d40463e533", + "reference": "7dd2ed9ba6d7af79f90bdc77522605d40463e533", "shasum": "" }, "require": { - "doctrine/doctrine-bundle": "^1.6.10|^2.0", - "doctrine/doctrine-migrations-bundle": "^1.3|^2.0", - "doctrine/orm": "^2.5.11", - "php": "^7.0" + "composer/package-versions-deprecated": "*", + "doctrine/doctrine-bundle": "^2", + "doctrine/doctrine-migrations-bundle": "^2", + "doctrine/orm": "^2" }, "type": "symfony-pack", "notification-url": "https://packagist.org/downloads/", @@ -4762,26 +5704,42 @@ "MIT" ], "description": "A pack for the Doctrine ORM", - "time": "2019-10-18T05:41:09+00:00" + "support": { + "issues": "https://github.com/symfony/orm-pack/issues", + "source": "https://github.com/symfony/orm-pack/tree/master" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-07-08T14:31:54+00:00" }, { - "name": "symfony/polyfill-intl-idn", - "version": "v1.13.1", + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.22.1", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "6f9c239e61e1b0c9229a28ff89a812dc449c3d46" + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "5601e09b69f26c1828b13b6bb87cb07cddba3170" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/6f9c239e61e1b0c9229a28ff89a812dc449c3d46", - "reference": "6f9c239e61e1b0c9229a28ff89a812dc449c3d46", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/5601e09b69f26c1828b13b6bb87cb07cddba3170", + "reference": "5601e09b69f26c1828b13b6bb87cb07cddba3170", "shasum": "" }, "require": { - "php": ">=5.3.3", - "symfony/polyfill-mbstring": "^1.3", - "symfony/polyfill-php72": "^1.9" + "php": ">=7.1" }, "suggest": { "ext-intl": "For best performance" @@ -4789,12 +5747,16 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.13-dev" + "dev-main": "1.22-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" } }, "autoload": { "psr-4": { - "Symfony\\Polyfill\\Intl\\Idn\\": "" + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" }, "files": [ "bootstrap.php" @@ -4806,42 +5768,143 @@ ], "authors": [ { - "name": "Laurent Bassin", - "email": "laurent@bassin.info" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", + "description": "Symfony polyfill for intl's grapheme_* functions", "homepage": "https://symfony.com", "keywords": [ "compatibility", - "idn", + "grapheme", "intl", "polyfill", "portable", "shim" ], - "time": "2019-11-27T13:56:44+00:00" + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.22.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-01-22T09:19:47+00:00" }, { - "name": "symfony/polyfill-mbstring", - "version": "v1.13.1", + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.22.1", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "7b4aab9743c30be783b73de055d24a39cf4b954f" + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "43a0283138253ed1d48d352ab6d0bdb3f809f248" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/7b4aab9743c30be783b73de055d24a39cf4b954f", - "reference": "7b4aab9743c30be783b73de055d24a39cf4b954f", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/43a0283138253ed1d48d352ab6d0bdb3f809f248", + "reference": "43a0283138253ed1d48d352ab6d0bdb3f809f248", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.22-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.22.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-01-22T09:19:47+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.22.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "5232de97ee3b75b0360528dae24e73db49566ab1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/5232de97ee3b75b0360528dae24e73db49566ab1", + "reference": "5232de97ee3b75b0360528dae24e73db49566ab1", + "shasum": "" + }, + "require": { + "php": ">=7.1" }, "suggest": { "ext-mbstring": "For best performance" @@ -4849,7 +5912,11 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.13-dev" + "dev-main": "1.22-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" } }, "autoload": { @@ -4883,84 +5950,50 @@ "portable", "shim" ], - "time": "2019-11-27T14:18:11+00:00" - }, - { - "name": "symfony/polyfill-php72", - "version": "v1.13.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "66fea50f6cb37a35eea048d75a7d99a45b586038" + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.22.1" }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/66fea50f6cb37a35eea048d75a7d99a45b586038", - "reference": "66fea50f6cb37a35eea048d75a7d99a45b586038", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.13-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php72\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ + "funding": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "url": "https://symfony.com/sponsor", + "type": "custom" }, { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "time": "2019-11-27T13:56:44+00:00" + "time": "2021-01-22T09:19:47+00:00" }, { "name": "symfony/polyfill-php73", - "version": "v1.13.1", + "version": "v1.22.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "4b0e2222c55a25b4541305a053013d5647d3a25f" + "reference": "a678b42e92f86eca04b7fa4c0f6f19d097fb69e2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/4b0e2222c55a25b4541305a053013d5647d3a25f", - "reference": "4b0e2222c55a25b4541305a053013d5647d3a25f", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/a678b42e92f86eca04b7fa4c0f6f19d097fb69e2", + "reference": "a678b42e92f86eca04b7fa4c0f6f19d097fb69e2", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.13-dev" + "dev-main": "1.22-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" } }, "autoload": { @@ -4996,24 +6029,123 @@ "portable", "shim" ], - "time": "2019-11-27T16:25:15+00:00" + "support": { + "source": "https://github.com/symfony/polyfill-php73/tree/v1.22.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-01-07T16:49:33+00:00" }, { - "name": "symfony/profiler-pack", - "version": "v1.0.4", + "name": "symfony/polyfill-php80", + "version": "v1.22.1", "source": { "type": "git", - "url": "https://github.com/symfony/profiler-pack.git", - "reference": "99c4370632c2a59bb0444852f92140074ef02209" + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/profiler-pack/zipball/99c4370632c2a59bb0444852f92140074ef02209", - "reference": "99c4370632c2a59bb0444852f92140074ef02209", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/dc3063ba22c2a1fd2f45ed856374d79114998f91", + "reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.22-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.22.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-01-07T16:49:33+00:00" + }, + { + "name": "symfony/profiler-pack", + "version": "v1.0.5", + "source": { + "type": "git", + "url": "https://github.com/symfony/profiler-pack.git", + "reference": "29ec66471082b4eb068db11eb4f0a48c277653f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/profiler-pack/zipball/29ec66471082b4eb068db11eb4f0a48c277653f7", + "reference": "29ec66471082b4eb068db11eb4f0a48c277653f7", "shasum": "" }, "require": { - "php": "^7.0", "symfony/stopwatch": "*", "symfony/twig-bundle": "*", "symfony/web-profiler-bundle": "*" @@ -5024,37 +6156,57 @@ "MIT" ], "description": "A pack for the Symfony web profiler", - "time": "2018-12-10T12:11:44+00:00" + "support": { + "issues": "https://github.com/symfony/profiler-pack/issues", + "source": "https://github.com/symfony/profiler-pack/tree/v1.0.5" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-08-12T06:50:46+00:00" }, { "name": "symfony/property-info", - "version": "v4.4.2", + "version": "v5.2.4", "source": { "type": "git", "url": "https://github.com/symfony/property-info.git", - "reference": "8afd280f159697177e48eefa89efd4db60a57665" + "reference": "7185bbc74e6f49c3f1b5936b4d9e4ca133921189" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-info/zipball/8afd280f159697177e48eefa89efd4db60a57665", - "reference": "8afd280f159697177e48eefa89efd4db60a57665", + "url": "https://api.github.com/repos/symfony/property-info/zipball/7185bbc74e6f49c3f1b5936b4d9e4ca133921189", + "reference": "7185bbc74e6f49c3f1b5936b4d9e4ca133921189", "shasum": "" }, "require": { - "php": "^7.1.3", - "symfony/inflector": "^3.4|^4.0|^5.0" + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1", + "symfony/polyfill-php80": "^1.15", + "symfony/string": "^5.1" }, "conflict": { - "phpdocumentor/reflection-docblock": "<3.0||>=3.2.0,<3.2.2", - "phpdocumentor/type-resolver": "<0.3.0", - "symfony/dependency-injection": "<3.4" + "phpdocumentor/reflection-docblock": "<3.2.2", + "phpdocumentor/type-resolver": "<1.4.0", + "symfony/dependency-injection": "<4.4" }, "require-dev": { - "doctrine/annotations": "~1.7", - "phpdocumentor/reflection-docblock": "^3.0|^4.0", - "symfony/cache": "^3.4|^4.0|^5.0", - "symfony/dependency-injection": "^3.4|^4.0|^5.0", - "symfony/serializer": "^3.4|^4.0|^5.0" + "doctrine/annotations": "^1.10.4", + "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", + "symfony/cache": "^4.4|^5.0", + "symfony/dependency-injection": "^4.4|^5.0", + "symfony/serializer": "^4.4|^5.0" }, "suggest": { "phpdocumentor/reflection-docblock": "To use the PHPDoc", @@ -5063,11 +6215,6 @@ "symfony/serializer": "To use Serializer metadata" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.4-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\PropertyInfo\\": "" @@ -5090,7 +6237,7 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Property Info Component", + "description": "Extracts information about PHP class' properties using metadata of popular sources", "homepage": "https://symfony.com", "keywords": [ "doctrine", @@ -5100,24 +6247,198 @@ "type", "validator" ], - "time": "2019-11-05T16:11:08+00:00" + "support": { + "source": "https://github.com/symfony/property-info/tree/v5.2.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-02-17T15:24:54+00:00" }, { - "name": "symfony/routing", - "version": "v5.0.2", + "name": "symfony/psr-http-message-bridge", + "version": "v2.1.0", "source": { "type": "git", - "url": "https://github.com/symfony/routing.git", - "reference": "120c5fa4f4ef5466cbb510ece8126e0007285301" + "url": "https://github.com/symfony/psr-http-message-bridge.git", + "reference": "81db2d4ae86e9f0049828d9343a72b9523884e5d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/120c5fa4f4ef5466cbb510ece8126e0007285301", - "reference": "120c5fa4f4ef5466cbb510ece8126e0007285301", + "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/81db2d4ae86e9f0049828d9343a72b9523884e5d", + "reference": "81db2d4ae86e9f0049828d9343a72b9523884e5d", "shasum": "" }, "require": { - "php": "^7.2.5" + "php": ">=7.1", + "psr/http-message": "^1.0", + "symfony/http-foundation": "^4.4 || ^5.0" + }, + "require-dev": { + "nyholm/psr7": "^1.1", + "psr/log": "^1.1", + "symfony/browser-kit": "^4.4 || ^5.0", + "symfony/config": "^4.4 || ^5.0", + "symfony/event-dispatcher": "^4.4 || ^5.0", + "symfony/framework-bundle": "^4.4 || ^5.0", + "symfony/http-kernel": "^4.4 || ^5.0", + "symfony/phpunit-bridge": "^4.4.19 || ^5.2" + }, + "suggest": { + "nyholm/psr7": "For a super lightweight PSR-7/17 implementation" + }, + "type": "symfony-bridge", + "extra": { + "branch-alias": { + "dev-main": "2.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Bridge\\PsrHttpMessage\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "description": "PSR HTTP message bridge", + "homepage": "http://symfony.com", + "keywords": [ + "http", + "http-message", + "psr-17", + "psr-7" + ], + "support": { + "issues": "https://github.com/symfony/psr-http-message-bridge/issues", + "source": "https://github.com/symfony/psr-http-message-bridge/tree/v2.1.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-02-17T10:35:25+00:00" + }, + { + "name": "symfony/redis-messenger", + "version": "v5.2.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/redis-messenger.git", + "reference": "7e68914bf35cda948ee4d9081b8eaed9fd783fe5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/redis-messenger/zipball/7e68914bf35cda948ee4d9081b8eaed9fd783fe5", + "reference": "7e68914bf35cda948ee4d9081b8eaed9fd783fe5", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1", + "symfony/messenger": "^5.1" + }, + "require-dev": { + "symfony/property-access": "^4.4|^5.0", + "symfony/serializer": "^4.4|^5.0" + }, + "type": "symfony-bridge", + "autoload": { + "psr-4": { + "Symfony\\Component\\Messenger\\Bridge\\Redis\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Redis extension Messenger Bridge", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/redis-messenger/tree/v5.2.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-01-27T11:24:50+00:00" + }, + { + "name": "symfony/routing", + "version": "v5.2.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/routing.git", + "reference": "31fba555f178afd04d54fd26953501b2c3f0c6e6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/routing/zipball/31fba555f178afd04d54fd26953501b2c3f0c6e6", + "reference": "31fba555f178afd04d54fd26953501b2c3f0c6e6", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1", + "symfony/polyfill-php80": "^1.15" }, "conflict": { "symfony/config": "<5.0", @@ -5125,7 +6446,7 @@ "symfony/yaml": "<4.4" }, "require-dev": { - "doctrine/annotations": "~1.2", + "doctrine/annotations": "^1.10.4", "psr/log": "~1.0", "symfony/config": "^5.0", "symfony/dependency-injection": "^4.4|^5.0", @@ -5141,11 +6462,6 @@ "symfony/yaml": "For using the YAML loader" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\Routing\\": "" @@ -5168,7 +6484,7 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Routing Component", + "description": "Maps an HTTP request to a set of configuration variables", "homepage": "https://symfony.com", "keywords": [ "router", @@ -5176,24 +6492,41 @@ "uri", "url" ], - "time": "2019-12-12T13:03:32+00:00" + "support": { + "source": "https://github.com/symfony/routing/tree/v5.2.6" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-03-14T13:53:33+00:00" }, { "name": "symfony/service-contracts", - "version": "v2.0.1", + "version": "v2.2.0", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "144c5e51266b281231e947b51223ba14acf1a749" + "reference": "d15da7ba4957ffb8f1747218be9e1a121fd298a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/144c5e51266b281231e947b51223ba14acf1a749", - "reference": "144c5e51266b281231e947b51223ba14acf1a749", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/d15da7ba4957ffb8f1747218be9e1a121fd298a1", + "reference": "d15da7ba4957ffb8f1747218be9e1a121fd298a1", "shasum": "" }, "require": { - "php": "^7.2.5", + "php": ">=7.2.5", "psr/container": "^1.0" }, "suggest": { @@ -5202,7 +6535,11 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-master": "2.2-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" } }, "autoload": { @@ -5234,32 +6571,44 @@ "interoperability", "standards" ], - "time": "2019-11-18T17:27:11+00:00" + "support": { + "source": "https://github.com/symfony/service-contracts/tree/master" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-09-07T11:33:47+00:00" }, { "name": "symfony/stopwatch", - "version": "v5.0.2", + "version": "v5.2.4", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "d410282956706e0b08681a5527447a8e6b6f421e" + "reference": "b12274acfab9d9850c52583d136a24398cdf1a0c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/d410282956706e0b08681a5527447a8e6b6f421e", - "reference": "d410282956706e0b08681a5527447a8e6b6f421e", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/b12274acfab9d9850c52583d136a24398cdf1a0c", + "reference": "b12274acfab9d9850c52583d136a24398cdf1a0c", "shasum": "" }, "require": { - "php": "^7.2.5", + "php": ">=7.2.5", "symfony/service-contracts": "^1.0|^2" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\Stopwatch\\": "" @@ -5282,48 +6631,150 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Stopwatch Component", + "description": "Provides a way to profile code", "homepage": "https://symfony.com", - "time": "2019-11-18T17:27:11+00:00" + "support": { + "source": "https://github.com/symfony/stopwatch/tree/v5.2.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-01-27T10:15:41+00:00" }, { - "name": "symfony/translation", - "version": "v4.4.2", + "name": "symfony/string", + "version": "v5.2.6", "source": { "type": "git", - "url": "https://github.com/symfony/translation.git", - "reference": "f7669f48a9633bf8139bc026c755e894b7206677" + "url": "https://github.com/symfony/string.git", + "reference": "ad0bd91bce2054103f5eaa18ebeba8d3bc2a0572" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/f7669f48a9633bf8139bc026c755e894b7206677", - "reference": "f7669f48a9633bf8139bc026c755e894b7206677", + "url": "https://api.github.com/repos/symfony/string/zipball/ad0bd91bce2054103f5eaa18ebeba8d3bc2a0572", + "reference": "ad0bd91bce2054103f5eaa18ebeba8d3bc2a0572", "shasum": "" }, "require": { - "php": "^7.1.3", + "php": ">=7.2.5", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.0", + "symfony/polyfill-intl-normalizer": "~1.0", "symfony/polyfill-mbstring": "~1.0", - "symfony/translation-contracts": "^1.1.6|^2" + "symfony/polyfill-php80": "~1.15" + }, + "require-dev": { + "symfony/error-handler": "^4.4|^5.0", + "symfony/http-client": "^4.4|^5.0", + "symfony/translation-contracts": "^1.1|^2", + "symfony/var-exporter": "^4.4|^5.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "files": [ + "Resources/functions.php" + ], + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", + "homepage": "https://symfony.com", + "keywords": [ + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" + ], + "support": { + "source": "https://github.com/symfony/string/tree/v5.2.6" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-03-17T17:12:15+00:00" + }, + { + "name": "symfony/translation", + "version": "v5.2.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation.git", + "reference": "2cc7f45d96db9adfcf89adf4401d9dfed509f4e1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation/zipball/2cc7f45d96db9adfcf89adf4401d9dfed509f4e1", + "reference": "2cc7f45d96db9adfcf89adf4401d9dfed509f4e1", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php80": "^1.15", + "symfony/translation-contracts": "^2.3" }, "conflict": { - "symfony/config": "<3.4", - "symfony/dependency-injection": "<3.4", - "symfony/http-kernel": "<4.4", - "symfony/yaml": "<3.4" + "symfony/config": "<4.4", + "symfony/dependency-injection": "<5.0", + "symfony/http-kernel": "<5.0", + "symfony/twig-bundle": "<5.0", + "symfony/yaml": "<4.4" }, "provide": { - "symfony/translation-implementation": "1.0" + "symfony/translation-implementation": "2.3" }, "require-dev": { "psr/log": "~1.0", - "symfony/config": "^3.4|^4.0|^5.0", - "symfony/console": "^3.4|^4.0|^5.0", - "symfony/dependency-injection": "^3.4|^4.0|^5.0", - "symfony/finder": "~2.8|~3.0|~4.0|^5.0", - "symfony/http-kernel": "^4.4", - "symfony/intl": "^3.4|^4.0|^5.0", + "symfony/config": "^4.4|^5.0", + "symfony/console": "^4.4|^5.0", + "symfony/dependency-injection": "^5.0", + "symfony/finder": "^4.4|^5.0", + "symfony/http-kernel": "^5.0", + "symfony/intl": "^4.4|^5.0", "symfony/service-contracts": "^1.1.2|^2", - "symfony/yaml": "^3.4|^4.0|^5.0" + "symfony/yaml": "^4.4|^5.0" }, "suggest": { "psr/log-implementation": "To use logging capability in translator", @@ -5331,12 +6782,10 @@ "symfony/yaml": "" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.4-dev" - } - }, "autoload": { + "files": [ + "Resources/functions.php" + ], "psr-4": { "Symfony\\Component\\Translation\\": "" }, @@ -5358,26 +6807,43 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Translation Component", + "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", - "time": "2019-12-12T12:53:52+00:00" + "support": { + "source": "https://github.com/symfony/translation/tree/v5.2.6" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-03-23T19:33:48+00:00" }, { "name": "symfony/translation-contracts", - "version": "v2.0.1", + "version": "v2.3.0", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "8cc682ac458d75557203b2f2f14b0b92e1c744ed" + "reference": "e2eaa60b558f26a4b0354e1bbb25636efaaad105" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/8cc682ac458d75557203b2f2f14b0b92e1c744ed", - "reference": "8cc682ac458d75557203b2f2f14b0b92e1c744ed", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/e2eaa60b558f26a4b0354e1bbb25636efaaad105", + "reference": "e2eaa60b558f26a4b0354e1bbb25636efaaad105", "shasum": "" }, "require": { - "php": "^7.2.5" + "php": ">=7.2.5" }, "suggest": { "symfony/translation-implementation": "" @@ -5385,7 +6851,11 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-master": "2.3-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" } }, "autoload": { @@ -5417,61 +6887,84 @@ "interoperability", "standards" ], - "time": "2019-11-18T17:27:11+00:00" + "support": { + "source": "https://github.com/symfony/translation-contracts/tree/v2.3.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-09-28T13:05:58+00:00" }, { "name": "symfony/twig-bridge", - "version": "v4.4.2", + "version": "v5.2.6", "source": { "type": "git", "url": "https://github.com/symfony/twig-bridge.git", - "reference": "936cf6f5b973377345e8ac43870987ef8e747ce3" + "reference": "a65d8d38c66f147f29b73d53d14e8c9a983653b8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/936cf6f5b973377345e8ac43870987ef8e747ce3", - "reference": "936cf6f5b973377345e8ac43870987ef8e747ce3", + "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/a65d8d38c66f147f29b73d53d14e8c9a983653b8", + "reference": "a65d8d38c66f147f29b73d53d14e8c9a983653b8", "shasum": "" }, "require": { - "php": "^7.1.3", + "php": ">=7.2.5", + "symfony/polyfill-php80": "^1.15", "symfony/translation-contracts": "^1.1|^2", - "twig/twig": "^1.41|^2.10|^3.0" + "twig/twig": "^2.13|^3.0.4" }, "conflict": { - "symfony/console": "<3.4", - "symfony/form": "<4.4", - "symfony/http-foundation": "<4.3", - "symfony/translation": "<4.2", - "symfony/workflow": "<4.3" + "phpdocumentor/reflection-docblock": "<3.2.2", + "phpdocumentor/type-resolver": "<1.4.0", + "symfony/console": "<4.4", + "symfony/form": "<5.1", + "symfony/http-foundation": "<4.4", + "symfony/http-kernel": "<4.4", + "symfony/translation": "<5.2", + "symfony/workflow": "<5.2" }, "require-dev": { - "egulias/email-validator": "^2.1.10", - "symfony/asset": "^3.4|^4.0|^5.0", - "symfony/console": "^3.4|^4.0|^5.0", - "symfony/dependency-injection": "^3.4|^4.0|^5.0", - "symfony/error-handler": "^4.4|^5.0", - "symfony/expression-language": "^3.4|^4.0|^5.0", - "symfony/finder": "^3.4|^4.0|^5.0", - "symfony/form": "^4.3.5", - "symfony/http-foundation": "^4.3|^5.0", - "symfony/http-kernel": "^4.4", - "symfony/mime": "^4.3|^5.0", + "egulias/email-validator": "^2.1.10|^3", + "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", + "symfony/asset": "^4.4|^5.0", + "symfony/console": "^4.4|^5.0", + "symfony/dependency-injection": "^4.4|^5.0", + "symfony/expression-language": "^4.4|^5.0", + "symfony/finder": "^4.4|^5.0", + "symfony/form": "^5.1.9", + "symfony/http-foundation": "^4.4|^5.0", + "symfony/http-kernel": "^4.4|^5.0", + "symfony/intl": "^4.4|^5.0", + "symfony/mime": "^5.2", "symfony/polyfill-intl-icu": "~1.0", - "symfony/routing": "^3.4|^4.0|^5.0", + "symfony/property-info": "^4.4|^5.1", + "symfony/routing": "^4.4|^5.0", "symfony/security-acl": "^2.8|^3.0", - "symfony/security-core": "^3.0|^4.0|^5.0", - "symfony/security-csrf": "^3.4|^4.0|^5.0", - "symfony/security-http": "^3.4|^4.0|^5.0", - "symfony/stopwatch": "^3.4|^4.0|^5.0", - "symfony/templating": "^3.4|^4.0|^5.0", - "symfony/translation": "^4.2.1|^5.0", + "symfony/security-core": "^4.4|^5.0", + "symfony/security-csrf": "^4.4|^5.0", + "symfony/security-http": "^4.4|^5.0", + "symfony/serializer": "^5.2", + "symfony/stopwatch": "^4.4|^5.0", + "symfony/translation": "^5.2", "symfony/web-link": "^4.4|^5.0", - "symfony/workflow": "^4.3|^5.0", - "symfony/yaml": "^3.4|^4.0|^5.0", - "twig/cssinliner-extra": "^2.12", - "twig/inky-extra": "^2.12", - "twig/markdown-extra": "^2.12" + "symfony/workflow": "^5.2", + "symfony/yaml": "^4.4|^5.0", + "twig/cssinliner-extra": "^2.12|^3", + "twig/inky-extra": "^2.12|^3", + "twig/markdown-extra": "^2.12|^3" }, "suggest": { "symfony/asset": "For using the AssetExtension", @@ -5484,18 +6977,12 @@ "symfony/security-csrf": "For using the CsrfExtension", "symfony/security-http": "For using the LogoutUrlExtension", "symfony/stopwatch": "For using the StopwatchExtension", - "symfony/templating": "For using the TwigEngine", "symfony/translation": "For using the TranslationExtension", "symfony/var-dumper": "For using the DumpExtension", "symfony/web-link": "For using the WebLinkExtension", "symfony/yaml": "For using the YamlExtension" }, "type": "symfony-bridge", - "extra": { - "branch-alias": { - "dev-master": "4.4-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Bridge\\Twig\\": "" @@ -5518,59 +7005,71 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Twig Bridge", + "description": "Provides integration for Twig with various Symfony components", "homepage": "https://symfony.com", - "time": "2019-12-05T05:58:42+00:00" + "support": { + "source": "https://github.com/symfony/twig-bridge/tree/v5.2.6" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-03-16T09:10:13+00:00" }, { "name": "symfony/twig-bundle", - "version": "v4.4.2", + "version": "v5.2.4", "source": { "type": "git", "url": "https://github.com/symfony/twig-bundle.git", - "reference": "a6e7bd9731256a55b2270c1283de8bc3bda06e8f" + "reference": "5ebbb5f0e8bfaa0b4b37cb25ff97f83b18caf221" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/twig-bundle/zipball/a6e7bd9731256a55b2270c1283de8bc3bda06e8f", - "reference": "a6e7bd9731256a55b2270c1283de8bc3bda06e8f", + "url": "https://api.github.com/repos/symfony/twig-bundle/zipball/5ebbb5f0e8bfaa0b4b37cb25ff97f83b18caf221", + "reference": "5ebbb5f0e8bfaa0b4b37cb25ff97f83b18caf221", "shasum": "" }, "require": { - "php": "^7.1.3", - "symfony/http-foundation": "^4.3|^5.0", - "symfony/http-kernel": "^4.4", + "php": ">=7.2.5", + "symfony/config": "^4.4|^5.0", + "symfony/http-foundation": "^4.4|^5.0", + "symfony/http-kernel": "^5.0", "symfony/polyfill-ctype": "~1.8", - "symfony/twig-bridge": "^4.4|^5.0", - "twig/twig": "^1.41|^2.10|^3.0" + "symfony/twig-bridge": "^5.0", + "twig/twig": "^2.13|^3.0.4" }, "conflict": { - "symfony/dependency-injection": "<4.1", - "symfony/framework-bundle": "<4.4", - "symfony/translation": "<4.2" + "symfony/dependency-injection": "<5.2", + "symfony/framework-bundle": "<5.0", + "symfony/translation": "<5.0" }, "require-dev": { - "doctrine/annotations": "~1.7", + "doctrine/annotations": "^1.10.4", "doctrine/cache": "~1.0", - "symfony/asset": "^3.4|^4.0|^5.0", - "symfony/dependency-injection": "^4.2.5|^5.0", - "symfony/expression-language": "^3.4|^4.0|^5.0", - "symfony/finder": "^3.4|^4.0|^5.0", - "symfony/form": "^3.4|^4.0|^5.0", - "symfony/framework-bundle": "^4.4|^5.0", - "symfony/routing": "^3.4|^4.0|^5.0", - "symfony/stopwatch": "^3.4|^4.0|^5.0", - "symfony/templating": "^3.4|^4.0|^5.0", - "symfony/translation": "^4.2|^5.0", - "symfony/web-link": "^3.4|^4.0|^5.0", - "symfony/yaml": "^3.4|^4.0|^5.0" + "symfony/asset": "^4.4|^5.0", + "symfony/dependency-injection": "^5.2", + "symfony/expression-language": "^4.4|^5.0", + "symfony/finder": "^4.4|^5.0", + "symfony/form": "^4.4|^5.0", + "symfony/framework-bundle": "^5.0", + "symfony/routing": "^4.4|^5.0", + "symfony/stopwatch": "^4.4|^5.0", + "symfony/translation": "^5.0", + "symfony/web-link": "^4.4|^5.0", + "symfony/yaml": "^4.4|^5.0" }, "type": "symfony-bundle", - "extra": { - "branch-alias": { - "dev-master": "4.4-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Bundle\\TwigBundle\\": "" @@ -5593,38 +7092,55 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony TwigBundle", + "description": "Provides a tight integration of Twig into the Symfony full-stack framework", "homepage": "https://symfony.com", - "time": "2019-12-10T11:13:11+00:00" + "support": { + "source": "https://github.com/symfony/twig-bundle/tree/v5.2.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-01-27T10:15:41+00:00" }, { "name": "symfony/var-dumper", - "version": "v4.4.2", + "version": "v5.2.6", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "be330f919bdb395d1e0c3f2bfb8948512d6bdd99" + "reference": "89412a68ea2e675b4e44f260a5666729f77f668e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/be330f919bdb395d1e0c3f2bfb8948512d6bdd99", - "reference": "be330f919bdb395d1e0c3f2bfb8948512d6bdd99", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/89412a68ea2e675b4e44f260a5666729f77f668e", + "reference": "89412a68ea2e675b4e44f260a5666729f77f668e", "shasum": "" }, "require": { - "php": "^7.1.3", + "php": ">=7.2.5", "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php72": "~1.5" + "symfony/polyfill-php80": "^1.15" }, "conflict": { - "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0", - "symfony/console": "<3.4" + "phpunit/phpunit": "<5.4.3", + "symfony/console": "<4.4" }, "require-dev": { "ext-iconv": "*", - "symfony/console": "^3.4|^4.0|^5.0", + "symfony/console": "^4.4|^5.0", "symfony/process": "^4.4|^5.0", - "twig/twig": "^1.34|^2.4|^3.0" + "twig/twig": "^2.13|^3.0.4" }, "suggest": { "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", @@ -5635,11 +7151,6 @@ "Resources/bin/var-dump-server" ], "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.4-dev" - } - }, "autoload": { "files": [ "Resources/functions/dump.php" @@ -5665,40 +7176,53 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony mechanism for exploring and dumping PHP variables", + "description": "Provides mechanisms for walking through any arbitrary PHP variable", "homepage": "https://symfony.com", "keywords": [ "debug", "dump" ], - "time": "2019-12-18T13:41:29+00:00" + "support": { + "source": "https://github.com/symfony/var-dumper/tree/v5.2.6" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-03-28T09:42:18+00:00" }, { "name": "symfony/var-exporter", - "version": "v5.0.2", + "version": "v5.2.4", "source": { "type": "git", "url": "https://github.com/symfony/var-exporter.git", - "reference": "1b9653e68d5b701bf6d9c91bdd3660078c9f4f28" + "reference": "5aed4875ab514c8cb9b6ff4772baa25fa4c10307" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/1b9653e68d5b701bf6d9c91bdd3660078c9f4f28", - "reference": "1b9653e68d5b701bf6d9c91bdd3660078c9f4f28", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/5aed4875ab514c8cb9b6ff4772baa25fa4c10307", + "reference": "5aed4875ab514c8cb9b6ff4772baa25fa4c10307", "shasum": "" }, "require": { - "php": "^7.2.5" + "php": ">=7.2.5", + "symfony/polyfill-php80": "^1.15" }, "require-dev": { - "symfony/var-dumper": "^4.4|^5.0" + "symfony/var-dumper": "^4.4.9|^5.0.9" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\VarExporter\\": "" @@ -5721,7 +7245,7 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "A blend of var_export() + serialize() to turn any serializable data structure to plain PHP code", + "description": "Allows exporting any serializable PHP data structure to plain PHP code", "homepage": "https://symfony.com", "keywords": [ "clone", @@ -5731,46 +7255,60 @@ "instantiate", "serialize" ], - "time": "2019-12-01T08:48:26+00:00" + "support": { + "source": "https://github.com/symfony/var-exporter/tree/v5.2.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-01-27T10:01:46+00:00" }, { "name": "symfony/web-profiler-bundle", - "version": "v5.0.2", + "version": "v5.2.6", "source": { "type": "git", "url": "https://github.com/symfony/web-profiler-bundle.git", - "reference": "6cc40446060e174a690e0f6da90731133b29b664" + "reference": "58e5be2aa69041ff35250537190d9ec29136782a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/web-profiler-bundle/zipball/6cc40446060e174a690e0f6da90731133b29b664", - "reference": "6cc40446060e174a690e0f6da90731133b29b664", + "url": "https://api.github.com/repos/symfony/web-profiler-bundle/zipball/58e5be2aa69041ff35250537190d9ec29136782a", + "reference": "58e5be2aa69041ff35250537190d9ec29136782a", "shasum": "" }, "require": { - "php": "^7.2.5", + "php": ">=7.2.5", "symfony/config": "^4.4|^5.0", - "symfony/framework-bundle": "^4.4|^5.0", - "symfony/http-kernel": "^4.4|^5.0", + "symfony/framework-bundle": "^5.1", + "symfony/http-kernel": "^5.2", "symfony/routing": "^4.4|^5.0", "symfony/twig-bundle": "^4.4|^5.0", - "twig/twig": "^2.10|^3.0" + "twig/twig": "^2.13|^3.0.4" }, "conflict": { + "symfony/dependency-injection": "<5.2", "symfony/form": "<4.4", "symfony/messenger": "<4.4" }, "require-dev": { + "symfony/browser-kit": "^4.4|^5.0", "symfony/console": "^4.4|^5.0", - "symfony/dependency-injection": "^4.4|^5.0", + "symfony/css-selector": "^4.4|^5.0", "symfony/stopwatch": "^4.4|^5.0" }, "type": "symfony-bundle", - "extra": { - "branch-alias": { - "dev-master": "5.0-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Bundle\\WebProfilerBundle\\": "" @@ -5793,43 +7331,59 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony WebProfilerBundle", + "description": "Provides a development tool that gives detailed information about the execution of any request", "homepage": "https://symfony.com", - "time": "2019-11-21T07:02:40+00:00" + "support": { + "source": "https://github.com/symfony/web-profiler-bundle/tree/v5.2.6" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-03-16T09:10:13+00:00" }, { "name": "symfony/yaml", - "version": "v4.4.2", + "version": "v5.2.5", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "a08832b974dd5fafe3085a66d41fe4c84bb2628c" + "reference": "298a08ddda623485208506fcee08817807a251dd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/a08832b974dd5fafe3085a66d41fe4c84bb2628c", - "reference": "a08832b974dd5fafe3085a66d41fe4c84bb2628c", + "url": "https://api.github.com/repos/symfony/yaml/zipball/298a08ddda623485208506fcee08817807a251dd", + "reference": "298a08ddda623485208506fcee08817807a251dd", "shasum": "" }, "require": { - "php": "^7.1.3", + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1", "symfony/polyfill-ctype": "~1.8" }, "conflict": { - "symfony/console": "<3.4" + "symfony/console": "<4.4" }, "require-dev": { - "symfony/console": "^3.4|^4.0|^5.0" + "symfony/console": "^4.4|^5.0" }, "suggest": { "symfony/console": "For validating YAML files using the lint command" }, + "bin": [ + "Resources/bin/yaml-lint" + ], "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.4-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\Yaml\\": "" @@ -5852,87 +7406,54 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Yaml Component", + "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", - "time": "2019-12-10T10:33:21+00:00" - }, - { - "name": "tightenco/collect", - "version": "v5.8.35", - "source": { - "type": "git", - "url": "https://github.com/tightenco/collect.git", - "reference": "c93a7039e6207ad533a09109838fe80933fcc72c" + "support": { + "source": "https://github.com/symfony/yaml/tree/v5.2.5" }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/tightenco/collect/zipball/c93a7039e6207ad533a09109838fe80933fcc72c", - "reference": "c93a7039e6207ad533a09109838fe80933fcc72c", - "shasum": "" - }, - "require": { - "php": "^7.1.3", - "symfony/var-dumper": ">=3.4 <5" - }, - "require-dev": { - "mockery/mockery": "^1.0", - "nesbot/carbon": "^1.26.3", - "phpunit/phpunit": "^7.0" - }, - "type": "library", - "autoload": { - "files": [ - "src/Collect/Support/helpers.php", - "src/Collect/Support/alias.php" - ], - "psr-4": { - "Tightenco\\Collect\\": "src/Collect" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ + "funding": [ { - "name": "Taylor Otwell", - "email": "taylorotwell@gmail.com" + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "description": "Collect - Illuminate Collections as a separate package.", - "keywords": [ - "collection", - "laravel" - ], - "time": "2019-09-17T18:57:01+00:00" + "time": "2021-03-06T07:59:01+00:00" }, { "name": "twig/twig", - "version": "v3.0.1", + "version": "v3.3.0", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "28f856a4c57eeb24485916e8a68403f41a133616" + "reference": "1f3b7e2c06cc05d42936a8ad508ff1db7975cdc5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/28f856a4c57eeb24485916e8a68403f41a133616", - "reference": "28f856a4c57eeb24485916e8a68403f41a133616", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/1f3b7e2c06cc05d42936a8ad508ff1db7975cdc5", + "reference": "1f3b7e2c06cc05d42936a8ad508ff1db7975cdc5", "shasum": "" }, "require": { - "php": "^7.2.5", + "php": ">=7.2.5", "symfony/polyfill-ctype": "^1.8", "symfony/polyfill-mbstring": "^1.3" }, "require-dev": { "psr/container": "^1.0", - "symfony/phpunit-bridge": "^4.4|^5.0" + "symfony/phpunit-bridge": "^4.4.9|^5.0.9" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "3.3-dev" } }, "autoload": { @@ -5966,33 +7487,53 @@ "keywords": [ "templating" ], - "time": "2019-12-28T07:17:28+00:00" + "support": { + "issues": "https://github.com/twigphp/Twig/issues", + "source": "https://github.com/twigphp/Twig/tree/v3.3.0" + }, + "funding": [ + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/twig/twig", + "type": "tidelift" + } + ], + "time": "2021-02-08T09:54:36+00:00" }, { "name": "webmozart/assert", - "version": "1.6.0", + "version": "1.10.0", "source": { "type": "git", - "url": "https://github.com/webmozart/assert.git", - "reference": "573381c0a64f155a0d9a23f4b0c797194805b925" + "url": "https://github.com/webmozarts/assert.git", + "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/573381c0a64f155a0d9a23f4b0c797194805b925", - "reference": "573381c0a64f155a0d9a23f4b0c797194805b925", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25", + "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25", "shasum": "" }, "require": { - "php": "^5.3.3 || ^7.0", + "php": "^7.2 || ^8.0", "symfony/polyfill-ctype": "^1.8" }, "conflict": { - "vimeo/psalm": "<3.6.0" + "phpstan/phpstan": "<0.12.20", + "vimeo/psalm": "<4.6.1 || 4.6.2" }, "require-dev": { - "phpunit/phpunit": "^4.8.36 || ^7.5.13" + "phpunit/phpunit": "^8.5.13" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, "autoload": { "psr-4": { "Webmozart\\Assert\\": "src/" @@ -6014,7 +7555,11 @@ "check", "validate" ], - "time": "2019-11-24T13:36:37+00:00" + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.10.0" + }, + "time": "2021-03-09T10:59:23+00:00" }, { "name": "zendframework/zend-code", @@ -6071,6 +7616,14 @@ "code", "zf" ], + "support": { + "chat": "https://zendframework-slack.herokuapp.com", + "docs": "https://docs.zendframework.com/zend-code/", + "forum": "https://discourse.zendframework.com/c/questions/components", + "issues": "https://github.com/zendframework/zend-code/issues", + "rss": "https://github.com/zendframework/zend-code/releases.atom", + "source": "https://github.com/zendframework/zend-code" + }, "abandoned": "laminas/laminas-code", "time": "2019-12-10T19:21:15+00:00" }, @@ -6126,32 +7679,35 @@ "events", "zf2" ], + "support": { + "issues": "https://github.com/zendframework/zend-eventmanager/issues", + "source": "https://github.com/zendframework/zend-eventmanager/tree/master" + }, "abandoned": "laminas/laminas-eventmanager", "time": "2018-04-25T15:33:34+00:00" }, { "name": "zircote/swagger-php", - "version": "2.0.14", + "version": "2.1.0", "source": { "type": "git", "url": "https://github.com/zircote/swagger-php.git", - "reference": "f2a00f26796e5cd08fd812275ba2db3d1e807663" + "reference": "5b26395e0e652ca8fc8e2327659f670422eedccd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zircote/swagger-php/zipball/f2a00f26796e5cd08fd812275ba2db3d1e807663", - "reference": "f2a00f26796e5cd08fd812275ba2db3d1e807663", + "url": "https://api.github.com/repos/zircote/swagger-php/zipball/5b26395e0e652ca8fc8e2327659f670422eedccd", + "reference": "5b26395e0e652ca8fc8e2327659f670422eedccd", "shasum": "" }, "require": { - "doctrine/annotations": "*", - "php": ">=5.6", - "symfony/finder": ">=2.2" + "doctrine/annotations": "^1.7", + "php": ">=7.2", + "symfony/finder": ">=3.4" }, "require-dev": { - "phpunit/phpunit": ">=4.8.35 <=5.6", - "squizlabs/php_codesniffer": ">=2.7", - "zendframework/zend-form": "<2.8" + "phpunit/phpunit": "^8 || ^9", + "squizlabs/php_codesniffer": ">=2.7" }, "bin": [ "bin/swagger" @@ -6189,73 +7745,92 @@ "rest", "service discovery" ], - "time": "2019-05-17T10:10:34+00:00" + "support": { + "issues": "https://github.com/zircote/swagger-php/issues", + "source": "https://github.com/zircote/swagger-php/tree/2.1.0" + }, + "time": "2020-11-29T21:40:13+00:00" } ], "packages-dev": [ { - "name": "kadet/functional", - "version": "dev-master", + "name": "nikic/php-parser", + "version": "v4.10.4", "source": { "type": "git", - "url": "https://git.kadet.net/kadet/functional-php.git", - "reference": "0b58a4c6207d6e7b95902bb81e49b9ec207fc909" - }, - "require": { - "php": ">=7.1" - }, - "require-dev": { - "phpunit/phpunit": "^7.0", - "psy/psysh": "@stable" - }, - "type": "library", - "autoload": { - "psr-4": { - "Kadet\\Functional\\": "./src/" - }, - "files": [ - "./src/functions.php", - "./src/Predicates/index.php" - ] - }, - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Kacper Donat", - "email": "kadet1090@gmail.com" - } - ], - "description": "Functional library for PHP", - "time": "2018-09-08T09:28:23+00:00" - }, - { - "name": "symfony/dotenv", - "version": "v4.4.2", - "source": { - "type": "git", - "url": "https://github.com/symfony/dotenv.git", - "reference": "c387ab37887f997162a8579d335b38f328d27859" + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "c6d052fc58cb876152f89f532b95a8d7907e7f0e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dotenv/zipball/c387ab37887f997162a8579d335b38f328d27859", - "reference": "c387ab37887f997162a8579d335b38f328d27859", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/c6d052fc58cb876152f89f532b95a8d7907e7f0e", + "reference": "c6d052fc58cb876152f89f532b95a8d7907e7f0e", "shasum": "" }, "require": { - "php": "^7.1.3" + "ext-tokenizer": "*", + "php": ">=7.0" }, "require-dev": { - "symfony/process": "^3.4.2|^4.0|^5.0" + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" }, + "bin": [ + "bin/php-parse" + ], "type": "library", "extra": { "branch-alias": { - "dev-master": "4.4-dev" + "dev-master": "4.9-dev" } }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v4.10.4" + }, + "time": "2020-12-20T10:01:03+00:00" + }, + { + "name": "symfony/dotenv", + "version": "v5.2.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/dotenv.git", + "reference": "783f12027c6b40ab0e93d6136d9f642d1d67cd6b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dotenv/zipball/783f12027c6b40ab0e93d6136d9f642d1d67cd6b", + "reference": "783f12027c6b40ab0e93d6136d9f642d1d67cd6b", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1" + }, + "require-dev": { + "symfony/process": "^4.4|^5.0" + }, + "type": "library", "autoload": { "psr-4": { "Symfony\\Component\\Dotenv\\": "" @@ -6285,115 +7860,112 @@ "env", "environment" ], - "time": "2019-12-19T15:57:49+00:00" + "support": { + "source": "https://github.com/symfony/dotenv/tree/v5.2.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-01-27T10:01:46+00:00" }, { - "name": "symfony/process", - "version": "v5.0.2", + "name": "symfony/maker-bundle", + "version": "v1.30.2", "source": { "type": "git", - "url": "https://github.com/symfony/process.git", - "reference": "ea2dc31b59d63abd9bc2356ac72eb7b3f3469f0e" + "url": "https://github.com/symfony/maker-bundle.git", + "reference": "a395a85aa4ded6c1fa3da118d60329b64b6c2acd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/ea2dc31b59d63abd9bc2356ac72eb7b3f3469f0e", - "reference": "ea2dc31b59d63abd9bc2356ac72eb7b3f3469f0e", + "url": "https://api.github.com/repos/symfony/maker-bundle/zipball/a395a85aa4ded6c1fa3da118d60329b64b6c2acd", + "reference": "a395a85aa4ded6c1fa3da118d60329b64b6c2acd", "shasum": "" }, "require": { - "php": "^7.2.5" + "doctrine/inflector": "^1.2|^2.0", + "nikic/php-parser": "^4.0", + "php": ">=7.1.3", + "symfony/config": "^4.0|^5.0", + "symfony/console": "^4.0|^5.0", + "symfony/dependency-injection": "^4.0|^5.0", + "symfony/deprecation-contracts": "^2.2", + "symfony/filesystem": "^4.0|^5.0", + "symfony/finder": "^4.0|^5.0", + "symfony/framework-bundle": "^4.0|^5.0", + "symfony/http-kernel": "^4.0|^5.0" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Process\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Process Component", - "homepage": "https://symfony.com", - "time": "2019-12-10T11:06:55+00:00" - }, - { - "name": "symfony/web-server-bundle", - "version": "v4.4.2", - "source": { - "type": "git", - "url": "https://github.com/symfony/web-server-bundle.git", - "reference": "301dad4563b21a791a796da9a736408215b9e9fc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/web-server-bundle/zipball/301dad4563b21a791a796da9a736408215b9e9fc", - "reference": "301dad4563b21a791a796da9a736408215b9e9fc", - "shasum": "" - }, - "require": { - "php": "^7.1.3", - "symfony/config": "^3.4|^4.0|^5.0", - "symfony/console": "^3.4|^4.0|^5.0", - "symfony/dependency-injection": "^3.4|^4.0|^5.0", - "symfony/http-kernel": "^3.4|^4.0|^5.0", - "symfony/polyfill-ctype": "~1.8", - "symfony/process": "^3.4.2|^4.0.2|^5.0" - }, - "suggest": { - "symfony/expression-language": "For using the filter option of the log server.", - "symfony/monolog-bridge": "For using the log server." + "require-dev": { + "composer/semver": "^3.0@dev", + "doctrine/doctrine-bundle": "^1.8|^2.0", + "doctrine/orm": "^2.3", + "friendsofphp/php-cs-fixer": "^2.8", + "friendsoftwig/twigcs": "^4.1.0|^5.0.0", + "symfony/http-client": "^4.3|^5.0", + "symfony/phpunit-bridge": "^4.3|^5.0", + "symfony/process": "^4.0|^5.0", + "symfony/security-core": "^4.0|^5.0", + "symfony/yaml": "^4.0|^5.0" }, "type": "symfony-bundle", "extra": { "branch-alias": { - "dev-master": "4.4-dev" + "dev-main": "1.0-dev" } }, "autoload": { "psr-4": { - "Symfony\\Bundle\\WebServerBundle\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] + "Symfony\\Bundle\\MakerBundle\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony WebServerBundle", - "homepage": "https://symfony.com", - "time": "2019-11-26T23:16:41+00:00" + "description": "Symfony Maker helps you create empty commands, controllers, form classes, tests and more so you can forget about writing boilerplate code.", + "homepage": "https://symfony.com/doc/current/bundles/SymfonyMakerBundle/index.html", + "keywords": [ + "code generator", + "generator", + "scaffold", + "scaffolding" + ], + "support": { + "issues": "https://github.com/symfony/maker-bundle/issues", + "source": "https://github.com/symfony/maker-bundle/tree/v1.30.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-03-23T13:53:38+00:00" } ], "aliases": [], @@ -6404,13 +7976,14 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": "^7.1.3", + "php": "^7.4", "ext-ctype": "*", "ext-iconv": "*", "ext-json": "*" }, "platform-dev": [], "platform-overrides": { - "php": "7.3.12" - } + "php": "7.4.15" + }, + "plugin-api-version": "2.0.0" } diff --git a/api/config/bootstrap.php b/api/config/bootstrap.php new file mode 100644 index 0000000..55560fb --- /dev/null +++ b/api/config/bootstrap.php @@ -0,0 +1,23 @@ +<?php + +use Symfony\Component\Dotenv\Dotenv; + +require dirname(__DIR__).'/vendor/autoload.php'; + +if (!class_exists(Dotenv::class)) { + throw new LogicException('Please run "composer require symfony/dotenv" to load the ".env" files configuring the application.'); +} + +// Load cached env vars if the .env.local.php file exists +// Run "composer dump-env prod" to create it (requires symfony/flex >=1.2) +if (is_array($env = @include dirname(__DIR__).'/.env.local.php') && (!isset($env['APP_ENV']) || ($_SERVER['APP_ENV'] ?? $_ENV['APP_ENV'] ?? $env['APP_ENV']) === $env['APP_ENV'])) { + (new Dotenv(false))->populate($env); +} else { + // load all the .env files + (new Dotenv(false))->loadEnv(dirname(__DIR__).'/.env'); +} + +$_SERVER += $_ENV; +$_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = ($_SERVER['APP_ENV'] ?? $_ENV['APP_ENV'] ?? null) ?: 'dev'; +$_SERVER['APP_DEBUG'] = $_SERVER['APP_DEBUG'] ?? $_ENV['APP_DEBUG'] ?? 'prod' !== $_SERVER['APP_ENV']; +$_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = (int) $_SERVER['APP_DEBUG'] || filter_var($_SERVER['APP_DEBUG'], FILTER_VALIDATE_BOOLEAN) ? '1' : '0'; diff --git a/config/bundles.php b/api/config/bundles.php similarity index 81% rename from config/bundles.php rename to api/config/bundles.php index 47980cd..f42212d 100644 --- a/config/bundles.php +++ b/api/config/bundles.php @@ -2,14 +2,14 @@ return [ Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true], - Symfony\Bundle\WebServerBundle\WebServerBundle::class => ['dev' => true], Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle::class => ['all' => true], Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true], - Doctrine\Bundle\DoctrineCacheBundle\DoctrineCacheBundle::class => ['all' => true], Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true], Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true], Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true], Nelmio\ApiDocBundle\NelmioApiDocBundle::class => ['all' => true], JMS\SerializerBundle\JMSSerializerBundle::class => ['all' => true], Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true], + Baldinof\RoadRunnerBundle\BaldinofRoadRunnerBundle::class => ['all' => true], + Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true], ]; diff --git a/api/config/packages/baldinof_road_runner.yaml b/api/config/packages/baldinof_road_runner.yaml new file mode 100644 index 0000000..65267f3 --- /dev/null +++ b/api/config/packages/baldinof_road_runner.yaml @@ -0,0 +1,18 @@ +baldinof_road_runner: + # The kernel is preserved between requests. Change this to `true` + # if you want to reboot it, and use a fresh container on each request. + should_reboot_kernel: false + + # Integrations are automatically detected, depending on installed bundle & current configuration + # See https://github.com/baldinof/roadrunner-bundle#integrations + default_integrations: true + + # Allow to send prometheus metrics to the master RoadRunner process, + # via a `Spiral\RoadRunner\MetricsInterface` service. + # See https://github.com/baldinof/roadrunner-bundle#metrics + metrics_enabled: false + + # You can use middlewares to manipulate PSR requests & responses. + # See https://github.com/baldinof/roadrunner-bundle#middlewares + # middlewares: + # - App\Middleware\YourMiddleware diff --git a/api/config/packages/cache.yaml b/api/config/packages/cache.yaml new file mode 100644 index 0000000..6899b72 --- /dev/null +++ b/api/config/packages/cache.yaml @@ -0,0 +1,19 @@ +framework: + cache: + # Unique name of your app: used to compute stable namespaces for cache keys. + #prefix_seed: your_vendor_name/app_name + + # The "app" cache stores to the filesystem by default. + # The data in this cache should persist between deploys. + # Other options include: + + # Redis + #app: cache.adapter.redis + #default_redis_provider: redis://localhost + + # APCu (not recommended with heavy random-write workloads as memory fragmentation can cause perf issues) + #app: cache.adapter.apcu + + # Namespaced pools use the above "app" backend by default + #pools: + #my.dedicated.cache: null diff --git a/config/packages/dev/jms_serializer.yaml b/api/config/packages/dev/jms_serializer.yaml similarity index 100% rename from config/packages/dev/jms_serializer.yaml rename to api/config/packages/dev/jms_serializer.yaml diff --git a/config/packages/dev/monolog.yaml b/api/config/packages/dev/monolog.yaml similarity index 100% rename from config/packages/dev/monolog.yaml rename to api/config/packages/dev/monolog.yaml diff --git a/config/packages/dev/routing.yaml b/api/config/packages/dev/routing.yaml similarity index 100% rename from config/packages/dev/routing.yaml rename to api/config/packages/dev/routing.yaml diff --git a/config/packages/dev/web_profiler.yaml b/api/config/packages/dev/web_profiler.yaml similarity index 83% rename from config/packages/dev/web_profiler.yaml rename to api/config/packages/dev/web_profiler.yaml index e92166a..7bb98b9 100644 --- a/config/packages/dev/web_profiler.yaml +++ b/api/config/packages/dev/web_profiler.yaml @@ -1,5 +1,5 @@ web_profiler: - toolbar: true + toolbar: false intercept_redirects: false framework: diff --git a/config/packages/doctrine.yaml b/api/config/packages/doctrine.yaml similarity index 76% rename from config/packages/doctrine.yaml rename to api/config/packages/doctrine.yaml index ca2f098..42dc149 100644 --- a/config/packages/doctrine.yaml +++ b/api/config/packages/doctrine.yaml @@ -5,14 +5,13 @@ doctrine: dbal: driver: 'pdo_sqlite' url: '%env(resolve:DATABASE_URL)%' - logging: true - profiling: true + logging: '%kernel.debug%' + profiling: '%kernel.debug%' types: datetime: App\Doctrine\CarbonDateTimeType - orm: - auto_generate_proxy_classes: '%kernel.debug%' - naming_strategy: doctrine.orm.naming_strategy.underscore + auto_generate_proxy_classes: true + naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware auto_mapping: true mappings: App: @@ -20,4 +19,4 @@ doctrine: type: annotation dir: '%kernel.project_dir%/src/Entity' prefix: 'App\Entity' - alias: Entity + alias: App diff --git a/api/config/packages/doctrine_migrations.yaml b/api/config/packages/doctrine_migrations.yaml new file mode 100644 index 0000000..263db11 --- /dev/null +++ b/api/config/packages/doctrine_migrations.yaml @@ -0,0 +1,3 @@ +doctrine_migrations: + migrations_paths: + 'DoctrineMigrations': '%kernel.project_dir%/migrations' diff --git a/api/config/packages/framework.yaml b/api/config/packages/framework.yaml new file mode 100644 index 0000000..aaed681 --- /dev/null +++ b/api/config/packages/framework.yaml @@ -0,0 +1,6 @@ +framework: + secret: '%env(APP_SECRET)%' + csrf_protection: false + + php_errors: + log: true diff --git a/config/packages/jms_serializer.yaml b/api/config/packages/jms_serializer.yaml similarity index 85% rename from config/packages/jms_serializer.yaml rename to api/config/packages/jms_serializer.yaml index d25fa03..d83e1d3 100644 --- a/config/packages/jms_serializer.yaml +++ b/api/config/packages/jms_serializer.yaml @@ -1,4 +1,8 @@ jms_serializer: + default_context: + serialization: + serialize_null: true + visitors: xml_serialization: format_output: '%kernel.debug%' diff --git a/api/config/packages/messenger.yaml b/api/config/packages/messenger.yaml new file mode 100644 index 0000000..2de8b54 --- /dev/null +++ b/api/config/packages/messenger.yaml @@ -0,0 +1,11 @@ +parameters: + env(APP_EVENT_QUEUE): "doctrine://default" + +framework: + messenger: + transports: + main: '%env(resolve:APP_EVENT_QUEUE)%' + sync: 'sync://' + + routing: + 'App\Message\UpdateDataMessage': main diff --git a/config/packages/nelmio_api_doc.yaml b/api/config/packages/nelmio_api_doc.yaml similarity index 76% rename from config/packages/nelmio_api_doc.yaml rename to api/config/packages/nelmio_api_doc.yaml index 6235eb6..edbcb92 100644 --- a/config/packages/nelmio_api_doc.yaml +++ b/api/config/packages/nelmio_api_doc.yaml @@ -1,7 +1,7 @@ nelmio_api_doc: documentation: info: - title: Czy Dojadę? + title: Co Jedzie? version: 0.1.0 parameters: provider: @@ -13,7 +13,7 @@ nelmio_api_doc: areas: path_patterns: - - ^/[^\/]+/api(?!/doc$) # Accepts routes under /api except /api/doc + - /api(?!/doc$) # Accepts routes under /api except /api/doc diff --git a/api/config/packages/prod/doctrine.yaml b/api/config/packages/prod/doctrine.yaml new file mode 100644 index 0000000..084f59a --- /dev/null +++ b/api/config/packages/prod/doctrine.yaml @@ -0,0 +1,20 @@ +doctrine: + orm: + auto_generate_proxy_classes: false + metadata_cache_driver: + type: pool + pool: doctrine.system_cache_pool + query_cache_driver: + type: pool + pool: doctrine.system_cache_pool + result_cache_driver: + type: pool + pool: doctrine.result_cache_pool + +framework: + cache: + pools: + doctrine.result_cache_pool: + adapter: cache.app + doctrine.system_cache_pool: + adapter: cache.system diff --git a/config/packages/prod/jms_serializer.yaml b/api/config/packages/prod/jms_serializer.yaml similarity index 100% rename from config/packages/prod/jms_serializer.yaml rename to api/config/packages/prod/jms_serializer.yaml diff --git a/config/packages/prod/monolog.yaml b/api/config/packages/prod/monolog.yaml similarity index 100% rename from config/packages/prod/monolog.yaml rename to api/config/packages/prod/monolog.yaml diff --git a/config/packages/routing.yaml b/api/config/packages/routing.yaml similarity index 98% rename from config/packages/routing.yaml rename to api/config/packages/routing.yaml index 368bc7f..80f4810 100644 --- a/config/packages/routing.yaml +++ b/api/config/packages/routing.yaml @@ -1,3 +1,4 @@ framework: router: strict_requirements: ~ + diff --git a/config/packages/sensio_framework_extra.yaml b/api/config/packages/sensio_framework_extra.yaml similarity index 100% rename from config/packages/sensio_framework_extra.yaml rename to api/config/packages/sensio_framework_extra.yaml diff --git a/config/packages/test/framework.yaml b/api/config/packages/test/framework.yaml similarity index 100% rename from config/packages/test/framework.yaml rename to api/config/packages/test/framework.yaml diff --git a/config/packages/test/monolog.yaml b/api/config/packages/test/monolog.yaml similarity index 100% rename from config/packages/test/monolog.yaml rename to api/config/packages/test/monolog.yaml diff --git a/api/config/packages/test/twig.yaml b/api/config/packages/test/twig.yaml new file mode 100644 index 0000000..8c6e0b4 --- /dev/null +++ b/api/config/packages/test/twig.yaml @@ -0,0 +1,2 @@ +twig: + strict_variables: true diff --git a/config/packages/test/web_profiler.yaml b/api/config/packages/test/web_profiler.yaml similarity index 100% rename from config/packages/test/web_profiler.yaml rename to api/config/packages/test/web_profiler.yaml diff --git a/config/packages/translation.yaml b/api/config/packages/translation.yaml similarity index 100% rename from config/packages/translation.yaml rename to api/config/packages/translation.yaml diff --git a/api/config/packages/twig.yaml b/api/config/packages/twig.yaml new file mode 100644 index 0000000..6403e6a --- /dev/null +++ b/api/config/packages/twig.yaml @@ -0,0 +1,5 @@ +twig: + default_path: '%kernel.project_dir%/templates' + debug: '%kernel.debug%' + strict_variables: '%kernel.debug%' + exception_controller: null diff --git a/api/config/preload.php b/api/config/preload.php new file mode 100644 index 0000000..064bdcd --- /dev/null +++ b/api/config/preload.php @@ -0,0 +1,9 @@ +<?php + +if (file_exists(dirname(__DIR__).'/var/cache/prod/srcApp_KernelProdContainer.preload.php')) { + require dirname(__DIR__).'/var/cache/prod/srcApp_KernelProdContainer.preload.php'; +} + +if (file_exists(dirname(__DIR__).'/var/cache/prod/App_KernelProdContainer.preload.php')) { + require dirname(__DIR__).'/var/cache/prod/App_KernelProdContainer.preload.php'; +} diff --git a/api/config/routes.yaml b/api/config/routes.yaml new file mode 100644 index 0000000..0c54567 --- /dev/null +++ b/api/config/routes.yaml @@ -0,0 +1,16 @@ +api_v1: + resource: ../src/Controller/Api/v1 + type: annotation + prefix: /api/v1/{provider} + +api_v1_providers: + path: /api/v1/providers + methods: ["GET"] + defaults: + _controller: '\App\Controller\Api\v1\ProviderController::index' + +api_v1_providers_one: + path: /api/v1/providers/{id} + methods: ["GET"] + defaults: + _controller: '\App\Controller\Api\v1\ProviderController::one' diff --git a/config/routes/annotations.yaml b/api/config/routes/annotations.yaml similarity index 100% rename from config/routes/annotations.yaml rename to api/config/routes/annotations.yaml diff --git a/api/config/routes/dev/framework.yaml b/api/config/routes/dev/framework.yaml new file mode 100644 index 0000000..bcbbf13 --- /dev/null +++ b/api/config/routes/dev/framework.yaml @@ -0,0 +1,3 @@ +_errors: + resource: '@FrameworkBundle/Resources/config/routing/errors.xml' + prefix: /_error diff --git a/config/routes/dev/web_profiler.yaml b/api/config/routes/dev/web_profiler.yaml similarity index 100% rename from config/routes/dev/web_profiler.yaml rename to api/config/routes/dev/web_profiler.yaml diff --git a/config/routes/nelmio_api_doc.yaml b/api/config/routes/nelmio_api_doc.yaml similarity index 100% rename from config/routes/nelmio_api_doc.yaml rename to api/config/routes/nelmio_api_doc.yaml diff --git a/config/services.yaml b/api/config/services.yaml similarity index 82% rename from config/services.yaml rename to api/config/services.yaml index 853ef0a..aeb122d 100644 --- a/config/services.yaml +++ b/api/config/services.yaml @@ -19,11 +19,14 @@ services: App\Provider\Provider: tags: [ app.provider ] + App\Service\Converter: + tags: [ app.converter ] + # makes classes in src/ available to be used as services # this creates a service per class whose id is the fully-qualified class name App\: resource: '../src/*' - exclude: '../src/{DependencyInjection,Entity,Model,Migrations,Tests,Functions,Kernel.php}' + exclude: '../src/{DependencyInjection,Exception,Modifier,Entity,Model,Migrations,Tests,Functions,Handler,Kernel.php}' # controllers are imported separately to make sure services can be injected # as action arguments even if you don't extend any base controller class @@ -35,12 +38,9 @@ services: resource: '../src/Provider' public: true - # add more service definitions when explicit configuration is needed - # please note that last definitions always *replace* previous ones - - #assets - assets.modified_time_version_strategy: - class: App\Asset\ModifiedTimeVersionStrategy + App\Handler\: + resource: '../src/Handler' + tags: [ app.handler ] #eerialziser jms_serializer.serialized_name_annotation_strategy: @@ -53,7 +53,7 @@ services: #proxy configuration proxy.locator: - class: 'ProxyManager\FileLocator\FileLocator' + class: 'App\Service\Proxy\FileLocator' arguments: ['%kernel.cache_dir%/proxy'] proxy.strategy: @@ -71,16 +71,10 @@ services: # converter App\Service\AggregateConverter: arguments: - - !tagged_iterator app.converter + - !tagged_iterator app.converter App\Service\Converter: '@App\Service\AggregateConverter' - App\Service\EntityConverter: - tags: ['app.converter'] - - App\Service\ScheduledStopConverter: - tags: ['app.converter'] - # serializer configuration App\Service\SerializerContextFactory: arguments: @@ -90,3 +84,7 @@ services: # other servces App\Service\ProviderResolver: arguments: [!tagged app.provider, '%kernel.debug%'] + + App\Service\HandlerProvider: + arguments: [!tagged_locator app.handler] + shared: false diff --git a/src/Controller/.gitignore b/api/migrations/.gitignore similarity index 100% rename from src/Controller/.gitignore rename to api/migrations/.gitignore diff --git a/src/Migrations/Version20180907212032.php b/api/migrations/Version20180907212032.php similarity index 100% rename from src/Migrations/Version20180907212032.php rename to api/migrations/Version20180907212032.php diff --git a/src/Migrations/Version20181027124203.php b/api/migrations/Version20181027124203.php similarity index 100% rename from src/Migrations/Version20181027124203.php rename to api/migrations/Version20181027124203.php diff --git a/src/Migrations/Version20190111212909.php b/api/migrations/Version20190111212909.php similarity index 100% rename from src/Migrations/Version20190111212909.php rename to api/migrations/Version20190111212909.php diff --git a/src/Migrations/Version20200103160747.php b/api/migrations/Version20200103160747.php similarity index 100% rename from src/Migrations/Version20200103160747.php rename to api/migrations/Version20200103160747.php diff --git a/src/Migrations/Version20200103170517.php b/api/migrations/Version20200103170517.php similarity index 100% rename from src/Migrations/Version20200103170517.php rename to api/migrations/Version20200103170517.php diff --git a/src/Migrations/Version20200131151757.php b/api/migrations/Version20200131151757.php similarity index 100% rename from src/Migrations/Version20200131151757.php rename to api/migrations/Version20200131151757.php diff --git a/src/Migrations/Version20200206183956.php b/api/migrations/Version20200206183956.php similarity index 100% rename from src/Migrations/Version20200206183956.php rename to api/migrations/Version20200206183956.php diff --git a/api/migrations/Version20200314112552.php b/api/migrations/Version20200314112552.php new file mode 100644 index 0000000..a16a743 --- /dev/null +++ b/api/migrations/Version20200314112552.php @@ -0,0 +1,43 @@ +<?php + +declare(strict_types=1); + +namespace DoctrineMigrations; + +use Doctrine\DBAL\Schema\Schema; +use Doctrine\Migrations\AbstractMigration; + +/** + * Auto-generated Migration: Please modify to your needs! + */ +final class Version20200314112552 extends AbstractMigration +{ + public function getDescription() : string + { + return ''; + } + + public function up(Schema $schema) : void + { + // this up() migration is auto-generated, please modify it to your needs + $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'sqlite', 'Migration can only be executed safely on \'sqlite\'.'); + + $this->addSql('CREATE TEMPORARY TABLE __temp__trip_stop AS SELECT stop_id, trip_id, sequence, arrival, departure FROM trip_stop'); + $this->addSql('DROP TABLE trip_stop'); + $this->addSql('CREATE TABLE trip_stop (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, sequence INTEGER NOT NULL, arrival DATETIME NOT NULL, departure DATETIME NOT NULL, stop_id VARCHAR(255) DEFAULT NULL, trip_id VARCHAR(255) DEFAULT NULL)'); + $this->addSql('INSERT INTO trip_stop (stop_id, trip_id, sequence, arrival, departure) SELECT stop_id, trip_id, sequence, arrival, departure FROM __temp__trip_stop'); + $this->addSql('DROP TABLE __temp__trip_stop'); + } + + public function down(Schema $schema) : void + { + // this down() migration is auto-generated, please modify it to your needs + $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'sqlite', 'Migration can only be executed safely on \'sqlite\'.'); + + $this->addSql('CREATE TEMPORARY TABLE __temp__trip_stop AS SELECT sequence, arrival, departure, stop_id, trip_id FROM trip_stop'); + $this->addSql('DROP TABLE trip_stop'); + $this->addSql('CREATE TABLE trip_stop (sequence INTEGER NOT NULL, stop_id VARCHAR(255) NOT NULL COLLATE BINARY, trip_id VARCHAR(255) NOT NULL COLLATE BINARY, arrival DATETIME NOT NULL, departure DATETIME NOT NULL, PRIMARY KEY(stop_id, trip_id, sequence))'); + $this->addSql('INSERT INTO trip_stop (sequence, arrival, departure, stop_id, trip_id) SELECT sequence, arrival, departure, stop_id, trip_id FROM __temp__trip_stop'); + $this->addSql('DROP TABLE __temp__trip_stop'); + } +} diff --git a/api/public/index.php b/api/public/index.php new file mode 100644 index 0000000..d0b6e02 --- /dev/null +++ b/api/public/index.php @@ -0,0 +1,27 @@ +<?php + +use App\Kernel; +use Symfony\Component\ErrorHandler\Debug; +use Symfony\Component\HttpFoundation\Request; + +require dirname(__DIR__).'/config/bootstrap.php'; + +if ($_SERVER['APP_DEBUG']) { + umask(0000); + + Debug::enable(); +} + +if ($trustedProxies = $_SERVER['TRUSTED_PROXIES'] ?? false) { + Request::setTrustedProxies(explode(',', $trustedProxies), Request::HEADER_X_FORWARDED_FOR | Request::HEADER_X_FORWARDED_PORT | Request::HEADER_X_FORWARDED_PROTO); +} + +if ($trustedHosts = $_SERVER['TRUSTED_HOSTS'] ?? false) { + Request::setTrustedHosts([$trustedHosts]); +} + +$kernel = new Kernel($_SERVER['APP_ENV'], (bool) $_SERVER['APP_DEBUG']); +$request = Request::createFromGlobals(); +$response = $kernel->handle($request); +$response->send(); +$kernel->terminate($request, $response); diff --git a/api/rr.Dockerfile b/api/rr.Dockerfile new file mode 100644 index 0000000..0f6dd9e --- /dev/null +++ b/api/rr.Dockerfile @@ -0,0 +1,29 @@ +FROM cojedzie/api:latest-rr + +COPY --from=mlocati/php-extension-installer /usr/bin/install-php-extensions /usr/local/bin/ +COPY --from=composer:latest /usr/bin/composer /usr/bin/composer + +RUN install-php-extensions xdebug-^3.0; +RUN apk add git; + +# XDebug +RUN echo "xdebug.mode=debug" >> $PHP_INI_DIR/conf.d/docker-php-ext-xdebug.ini && \ + echo "xdebug.client_host=172.17.0.1" >> $PHP_INI_DIR/conf.d/docker-php-ext-xdebug.ini && \ + echo "xdebug.start_with_request=On" >> $PHP_INI_DIR/conf.d/docker-php-ext-xdebug.ini; + +# Blackfire +RUN version=$(php -r "echo PHP_MAJOR_VERSION.PHP_MINOR_VERSION;") \ + && curl -A "Docker" -o /tmp/blackfire-probe.tar.gz -D - -L -s https://blackfire.io/api/v1/releases/probe/php/linux/amd64/$version \ + && mkdir -p /tmp/blackfire \ + && tar zxpf /tmp/blackfire-probe.tar.gz -C /tmp/blackfire \ + && mv /tmp/blackfire/blackfire-*.so $(php -r "echo ini_get ('extension_dir');")/blackfire.so \ + && printf "extension=blackfire.so\nblackfire.agent_socket=tcp://blackfire:8707\n" > $PHP_INI_DIR/conf.d/blackfire.ini \ + && rm -rf /tmp/blackfire /tmp/blackfire-probe.tar.gz + +# Timezone +RUN ln -snf /usr/share/zoneinfo/Europe/Warsaw /etc/localtime && \ + echo "date.timezone = Europe/Warsaw" >> /usr/local/etc/php/conf.d/datetime.ini; + +WORKDIR /var/www + +EXPOSE 9001 diff --git a/ruleset.xml b/api/ruleset.xml similarity index 97% rename from ruleset.xml rename to api/ruleset.xml index 79c2e2d..8b74543 100644 --- a/ruleset.xml +++ b/api/ruleset.xml @@ -1,6 +1,6 @@ <?xml version="1.0"?> -<rulset name="Kadet.CzyDojade"> - <description>Czy Dojadę ruleset</description> +<rulset name="CoJedzie"> + <description>Co Jedzie ruleset</description> <arg name="colors"/> <arg name="parallel" value="75"/> diff --git a/api/src/Command/UpdateCommand.php b/api/src/Command/UpdateCommand.php new file mode 100644 index 0000000..5890fd4 --- /dev/null +++ b/api/src/Command/UpdateCommand.php @@ -0,0 +1,48 @@ +<?php + +namespace App\Command; + +use App\Message\UpdateDataMessage; +use App\Service\DataUpdater; +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Messenger\MessageBusInterface; + +class UpdateCommand extends Command +{ + /** @var DataUpdater */ + private $updater; + /** @var MessageBusInterface */ + private $bus; + + public function __construct(DataUpdater $updater, MessageBusInterface $bus) + { + parent::__construct('app:update'); + + $this->updater = $updater; + $this->bus = $bus; + } + + protected function configure() + { + $this->addOption( + 'async', 'a', + InputOption::VALUE_NONE, + 'Run in worker process via message queue.' + ); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + if ($input->getOption('async')) { + $this->bus->dispatch(new UpdateDataMessage()); + $output->writeln("Update request sent to message queue."); + } else { + $this->updater->update($output); + } + + return Command::SUCCESS; + } +} diff --git a/src/Controller/Api/v1/DeparturesController.php b/api/src/Controller/Api/v1/DeparturesController.php similarity index 71% rename from src/Controller/Api/v1/DeparturesController.php rename to api/src/Controller/Api/v1/DeparturesController.php index 410a753..2f98869 100644 --- a/src/Controller/Api/v1/DeparturesController.php +++ b/api/src/Controller/Api/v1/DeparturesController.php @@ -5,6 +5,10 @@ namespace App\Controller\Api\v1; use App\Controller\Controller; use App\Model\Departure; +use App\Modifier\FieldFilter; +use App\Modifier\IdFilter; +use App\Modifier\Limit; +use App\Modifier\With; use App\Provider\DepartureRepository; use App\Provider\StopRepository; use App\Service\SerializerContextFactory; @@ -32,11 +36,11 @@ class DeparturesController extends Controller * @SWG\Schema(type="array", @SWG\Items(ref=@Model(type=Departure::class))) * ) */ - public function stop(DepartureRepository $departures, StopRepository $stops, $stop) + public function stop(DepartureRepository $departures, StopRepository $stops, $stop, Request $request) { - $stop = $stops->getById($stop); + $stop = $stops->first(new IdFilter($stop)); - return $this->json($departures->getForStop($stop)); + return $this->json($departures->current(collect($stop), ...$this->getModifiersFromRequest($request))); } /** @@ -64,16 +68,21 @@ class DeparturesController extends Controller */ public function stops(DepartureRepository $departures, StopRepository $stops, Request $request) { - $stops = $stops - ->getManyById($request->query->get('stop')) - ->flatMap(ref([ $departures, 'getForStop' ])) - ->sortBy(property('departure')); + $stops = $stops->all(new IdFilter($request->query->get('stop', []))); + $result = $departures->current($stops, ...$this->getModifiersFromRequest($request)); return $this->json( - $stops->values()->slice(0, (int)$request->query->get('limit', 8)), + $result->values()->slice(0, (int)$request->query->get('limit', 8)), 200, [], $this->serializerContextFactory->create(Departure::class, ['Default']) ); } + + private function getModifiersFromRequest(Request $request) + { + if ($request->query->has('limit')) { + yield Limit::count($request->query->getInt('limit')); + } + } } diff --git a/src/Controller/Api/v1/MessagesController.php b/api/src/Controller/Api/v1/MessagesController.php similarity index 100% rename from src/Controller/Api/v1/MessagesController.php rename to api/src/Controller/Api/v1/MessagesController.php diff --git a/api/src/Controller/Api/v1/ProviderController.php b/api/src/Controller/Api/v1/ProviderController.php new file mode 100644 index 0000000..ff192a7 --- /dev/null +++ b/api/src/Controller/Api/v1/ProviderController.php @@ -0,0 +1,34 @@ +<?php + +namespace App\Controller\Api\v1; + +use App\Controller\Controller; +use App\Exception\NonExistentServiceException; +use App\Service\Converter; +use App\Service\ProviderResolver; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; +use function Kadet\Functional\ref; + +class ProviderController extends Controller +{ + public function index(ProviderResolver $resolver, Converter $converter) + { + $providers = $resolver + ->all() + ->map(ref([$converter, 'convert'])) + ->values() + ->toArray() + ; + return $this->json($providers); + } + + public function one(ProviderResolver $resolver, Converter $converter, $id) + { + try { + $provider = $resolver->resolve($id); + return $this->json($converter->convert($provider)); + } catch (NonExistentServiceException $exception) { + throw new NotFoundHttpException($exception->getMessage()); + } + } +} diff --git a/src/Controller/Api/v1/StopsController.php b/api/src/Controller/Api/v1/StopsController.php similarity index 67% rename from src/Controller/Api/v1/StopsController.php rename to api/src/Controller/Api/v1/StopsController.php index 76c19a1..c78190d 100644 --- a/src/Controller/Api/v1/StopsController.php +++ b/api/src/Controller/Api/v1/StopsController.php @@ -1,20 +1,22 @@ <?php - namespace App\Controller\Api\v1; use App\Controller\Controller; use App\Model\Stop; -use App\Model\Track; use App\Model\StopGroup; +use App\Model\TrackStop; +use App\Modifier\FieldFilter; +use App\Modifier\IdFilter; +use App\Modifier\RelatedFilter; +use App\Modifier\With; use App\Provider\StopRepository; use App\Provider\TrackRepository; -use App\Service\Proxy\ReferenceFactory; +use Illuminate\Support\Collection; use Nelmio\ApiDocBundle\Annotation\Model; use Swagger\Annotations as SWG; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Annotation\Route; -use Tightenco\Collect\Support\Collection; /** * Class StopsController @@ -38,7 +40,8 @@ class StopsController extends Controller * name="id", * in="query", * type="array", - * description="Stop identificators to retrieve at once. Can be used to bulk load data. If not specified will return all data.", + * description="Stop identificators to retrieve at once. Can be used to bulk load data. If not specified will + * return all data.", * @SWG\Items(type="string") * ) * @@ -46,16 +49,9 @@ class StopsController extends Controller */ public function index(Request $request, StopRepository $stops) { - switch (true) { - case $request->query->has('id'): - $result = $stops->getManyById($request->query->get('id')); - break; + $modifiers = $this->getModifiersFromRequest($request); - default: - $result = $stops->getAll(); - } - - return $this->json($result->all()); + return $this->json($stops->all(...$modifiers)->toArray()); } /** @@ -76,16 +72,9 @@ class StopsController extends Controller */ public function groups(Request $request, StopRepository $stops) { - switch (true) { - case $request->query->has('name'): - $result = $stops->findByName($request->query->get('name')); - break; + $modifiers = $this->getModifiersFromRequest($request); - default: - $result = $stops->getAll(); - } - - return $this->json(static::group($result)->all()); + return $this->json(static::group($stops->all(...$modifiers))->toArray()); } /** @@ -106,7 +95,7 @@ class StopsController extends Controller */ public function one(Request $request, StopRepository $stops, $id) { - return $this->json($stops->getById($id)); + return $this->json($stops->first(new IdFilter($id), new With("destinations"))); } /** @@ -115,21 +104,12 @@ class StopsController extends Controller * @SWG\Response( * response=200, * description="Returns specific stop referenced via identificator.", - * @SWG\Schema(type="object", properties={ - * @SWG\Property(property="track", type="object", ref=@Model(type=Track::class)), - * @SWG\Property(property="order", type="integer", minimum="0") - * }) + * @SWG\Schema(ref=@Model(type=TrackStop::class)) * ) - * - * @SWG\Tag(name="Tracks") */ - public function tracks(ReferenceFactory $reference, TrackRepository $tracks, $id) + public function tracks(TrackRepository $tracks, $id) { - $stop = $reference->get(Stop::class, $id); - - return $this->json($tracks->getByStop($stop)->map(function ($tuple) { - return array_combine(['track', 'order'], $tuple); - })); + return $this->json($tracks->stops(new RelatedFilter(Stop::reference($id)))); } public static function group(Collection $stops) @@ -145,4 +125,19 @@ class StopsController extends Controller return $group; })->values(); } + + private function getModifiersFromRequest(Request $request) + { + if ($request->query->has('name')) { + yield FieldFilter::contains('name', $request->query->get('name')); + } + + if ($request->query->has('id')) { + yield new IdFilter($request->query->get('id')); + } + + if ($request->query->has('include-destinations')) { + yield new With("destinations"); + } + } } diff --git a/api/src/Controller/Api/v1/TracksController.php b/api/src/Controller/Api/v1/TracksController.php new file mode 100644 index 0000000..9dc7c4e --- /dev/null +++ b/api/src/Controller/Api/v1/TracksController.php @@ -0,0 +1,98 @@ +<?php + +namespace App\Controller\Api\v1; + +use App\Controller\Controller; +use App\Model\Line; +use App\Model\Stop; +use App\Model\Track; +use App\Modifier\IdFilter; +use App\Modifier\RelatedFilter; +use App\Provider\TrackRepository; +use Swagger\Annotations as SWG; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Routing\Annotation\Route; +use function App\Functions\encapsulate; +use function Kadet\Functional\ref; + +/** + * @Route("/tracks") + * @SWG\Tag(name="Tracks") + */ +class TracksController extends Controller +{ + /** + * @SWG\Response( + * response=200, + * description="Returns all tracks for specific provider, e.g. ZTM Gdańsk.", + * ) + * @Route("/", methods={"GET"}) + */ + public function index(Request $request, TrackRepository $repository) + { + $modifiers = $this->getModifiersFromRequest($request); + + return $this->json($repository->all(...$modifiers)); + } + + /** + * @Route("/stops", methods={"GET"}) + * @Route("/{track}/stops", methods={"GET"}) + * + * @SWG\Tag(name="Tracks") + * + * @SWG\Response(response=200, description="Stops related to specified query.") + */ + public function stops(Request $request, TrackRepository $repository) + { + $modifiers = $this->getStopsModifiersFromRequest($request); + + return $this->json($repository->stops(...$modifiers)); + } + + private function getModifiersFromRequest(Request $request) + { + if ($request->query->has('stop')) { + $stop = encapsulate($request->query->get('stop')); + $stop = collect($stop)->map([Stop::class, 'reference']); + + yield new RelatedFilter($stop, Stop::class); + } + + if ($request->query->has('line')) { + $line = encapsulate($request->query->get('line')); + $line = collect($line)->map([Line::class, 'reference']); + + yield new RelatedFilter($line, Line::class); + } + + if ($request->query->has('id')) { + $id = encapsulate($request->query->get('id')); + + yield new IdFilter($id); + } + } + + private function getStopsModifiersFromRequest(Request $request) + { + if ($request->query->has('stop')) { + $stop = encapsulate($request->query->get('stop')); + $stop = collect($stop)->map(ref([Stop::class, 'reference'])); + + yield new RelatedFilter($stop); + } + + if ($request->query->has('track') || $request->attributes->has('track')) { + $track = $request->get('track'); + $track = Track::reference($track); + + yield new RelatedFilter($track); + } + + if ($request->query->has('id')) { + $id = encapsulate($request->query->get('id')); + + yield new IdFilter($id); + } + } +} diff --git a/src/Controller/Api/v1/TripController.php b/api/src/Controller/Api/v1/TripController.php similarity index 74% rename from src/Controller/Api/v1/TripController.php rename to api/src/Controller/Api/v1/TripController.php index 9f1583e..b91c8cb 100644 --- a/src/Controller/Api/v1/TripController.php +++ b/api/src/Controller/Api/v1/TripController.php @@ -4,6 +4,8 @@ namespace App\Controller\Api\v1; use App\Controller\Controller; use App\Model\Trip; +use App\Modifier\IdFilter; +use App\Modifier\With; use App\Provider\TripRepository; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; @@ -14,11 +16,11 @@ use Symfony\Component\Routing\Annotation\Route; class TripController extends Controller { /** - * @Route("/{id}") + * @Route("/{id}", methods={"GET"}) */ public function one($id, TripRepository $repository) { - $trip = $repository->getById($id); + $trip = $repository->first(new IdFilter($id), new With('schedule')); return $this->json($trip, Response::HTTP_OK, [], $this->serializerContextFactory->create(Trip::class)); } diff --git a/src/Controller/Controller.php b/api/src/Controller/Controller.php similarity index 100% rename from src/Controller/Controller.php rename to api/src/Controller/Controller.php diff --git a/src/Doctrine/CarbonDateTimeType.php b/api/src/Doctrine/CarbonDateTimeType.php similarity index 100% rename from src/Doctrine/CarbonDateTimeType.php rename to api/src/Doctrine/CarbonDateTimeType.php diff --git a/src/Entity/Entity.php b/api/src/Entity/Entity.php similarity index 100% rename from src/Entity/Entity.php rename to api/src/Entity/Entity.php diff --git a/src/Entity/LineEntity.php b/api/src/Entity/LineEntity.php similarity index 100% rename from src/Entity/LineEntity.php rename to api/src/Entity/LineEntity.php diff --git a/src/Entity/OperatorEntity.php b/api/src/Entity/OperatorEntity.php similarity index 100% rename from src/Entity/OperatorEntity.php rename to api/src/Entity/OperatorEntity.php diff --git a/src/Entity/ProviderEntity.php b/api/src/Entity/ProviderEntity.php similarity index 100% rename from src/Entity/ProviderEntity.php rename to api/src/Entity/ProviderEntity.php diff --git a/src/Entity/ProviderReferenceTrait.php b/api/src/Entity/ProviderReferenceTrait.php similarity index 100% rename from src/Entity/ProviderReferenceTrait.php rename to api/src/Entity/ProviderReferenceTrait.php diff --git a/src/Entity/ReferableEntityTrait.php b/api/src/Entity/ReferableEntityTrait.php similarity index 100% rename from src/Entity/ReferableEntityTrait.php rename to api/src/Entity/ReferableEntityTrait.php diff --git a/src/Entity/StopEntity.php b/api/src/Entity/StopEntity.php similarity index 100% rename from src/Entity/StopEntity.php rename to api/src/Entity/StopEntity.php diff --git a/src/Entity/TrackEntity.php b/api/src/Entity/TrackEntity.php similarity index 87% rename from src/Entity/TrackEntity.php rename to api/src/Entity/TrackEntity.php index a0eaa1d..856297b 100644 --- a/src/Entity/TrackEntity.php +++ b/api/src/Entity/TrackEntity.php @@ -45,16 +45,18 @@ class TrackEntity implements Entity, Fillable /** * Stops in track - * @var StopInTrack[]|Collection - * @ORM\OneToMany(targetEntity=StopInTrack::class, fetch="LAZY", mappedBy="track", cascade={"persist"}) + * + * @var TrackStopEntity[]|Collection + * @ORM\OneToMany(targetEntity=TrackStopEntity::class, fetch="LAZY", mappedBy="track", cascade={"persist"}) * @ORM\OrderBy({"order": "ASC"}) */ private $stopsInTrack; /** * Final stop in this track. - * @var StopInTrack - * @ORM\OneToOne(targetEntity=StopInTrack::class, fetch="LAZY") + * + * @var TrackStopEntity + * @ORM\OneToOne(targetEntity=TrackStopEntity::class, fetch="LAZY") */ private $final; @@ -114,7 +116,7 @@ class TrackEntity implements Entity, Fillable $this->final = $this->stopsInTrack->last(); } - public function getFinal(): StopInTrack + public function getFinal(): TrackStopEntity { return $this->final; } diff --git a/src/Entity/StopInTrack.php b/api/src/Entity/TrackStopEntity.php similarity index 96% rename from src/Entity/StopInTrack.php rename to api/src/Entity/TrackStopEntity.php index 26cbd55..b32c84b 100644 --- a/src/Entity/StopInTrack.php +++ b/api/src/Entity/TrackStopEntity.php @@ -14,7 +14,7 @@ use Doctrine\ORM\Mapping as ORM; * @ORM\UniqueConstraint(name="stop_in_track_idx", columns={"stop_id", "track_id", "sequence"}) * }) */ -class StopInTrack implements Fillable, Referable +class TrackStopEntity implements Fillable, Referable { use FillTrait, ReferableEntityTrait; diff --git a/src/Entity/TripEntity.php b/api/src/Entity/TripEntity.php similarity index 100% rename from src/Entity/TripEntity.php rename to api/src/Entity/TripEntity.php diff --git a/src/Entity/TripStopEntity.php b/api/src/Entity/TripStopEntity.php similarity index 87% rename from src/Entity/TripStopEntity.php rename to api/src/Entity/TripStopEntity.php index f90df10..f80b012 100644 --- a/src/Entity/TripStopEntity.php +++ b/api/src/Entity/TripStopEntity.php @@ -4,6 +4,7 @@ namespace App\Entity; use App\Model\Fillable; use App\Model\FillTrait; +use App\Model\Referable; use App\Model\Trip; use App\Service\IdUtils; use Carbon\Carbon; @@ -14,21 +15,28 @@ use JMS\Serializer\Tests\Fixtures\Discriminator\Car; * @ORM\Entity * @ORM\Table("trip_stop") */ -class TripStopEntity implements Fillable +class TripStopEntity implements Fillable, Referable { - use FillTrait; + use FillTrait, ReferableEntityTrait; + + /** + * Identifier for stop coming from provider + * + * @ORM\Column(type="integer") + * @ORM\Id + * @ORM\GeneratedValue + */ + private $id; /** * @var StopEntity * @ORM\ManyToOne(targetEntity=StopEntity::class, fetch="EAGER") - * @ORM\Id */ private $stop; /** * @var TripEntity * @ORM\ManyToOne(targetEntity=TripEntity::class, fetch="EAGER", inversedBy="stops") - * @ORM\Id */ private $trip; @@ -37,7 +45,6 @@ class TripStopEntity implements Fillable * @var int * * @ORM\Column(name="sequence", type="integer") - * @ORM\Id */ private $order; diff --git a/src/Event/DataUpdateEvent.php b/api/src/Event/DataUpdateEvent.php similarity index 100% rename from src/Event/DataUpdateEvent.php rename to api/src/Event/DataUpdateEvent.php diff --git a/api/src/Event/HandleDatabaseModifierEvent.php b/api/src/Event/HandleDatabaseModifierEvent.php new file mode 100644 index 0000000..c548d59 --- /dev/null +++ b/api/src/Event/HandleDatabaseModifierEvent.php @@ -0,0 +1,34 @@ +<?php + +namespace App\Event; + +use App\Event\HandleModifierEvent; +use App\Modifier\Modifier; +use App\Provider\Repository; +use Doctrine\ORM\QueryBuilder; + +class HandleDatabaseModifierEvent extends HandleModifierEvent +{ + private $builder; + + public function __construct( + Modifier $modifier, + Repository $repository, + QueryBuilder $builder, + array $meta = [] + ) { + parent::__construct($modifier, $repository, $meta); + + $this->builder = $builder; + } + + public function getBuilder(): QueryBuilder + { + return $this->builder; + } + + public function replaceBuilder(QueryBuilder $builder): void + { + $this->builder = $builder; + } +} diff --git a/api/src/Event/HandleModifierEvent.php b/api/src/Event/HandleModifierEvent.php new file mode 100644 index 0000000..5544af4 --- /dev/null +++ b/api/src/Event/HandleModifierEvent.php @@ -0,0 +1,35 @@ +<?php + +namespace App\Event; + +use App\Modifier\Modifier; +use App\Provider\Repository; + +class HandleModifierEvent +{ + private $repository; + private $modifier; + private $meta = []; + + public function __construct(Modifier $modifier, Repository $repository, array $meta = []) + { + $this->repository = $repository; + $this->modifier = $modifier; + $this->meta = $meta; + } + + public function getModifier(): Modifier + { + return $this->modifier; + } + + public function getRepository() + { + return $this->repository; + } + + public function getMeta(): array + { + return $this->meta; + } +} diff --git a/api/src/Event/PostProcessEvent.php b/api/src/Event/PostProcessEvent.php new file mode 100644 index 0000000..5d23040 --- /dev/null +++ b/api/src/Event/PostProcessEvent.php @@ -0,0 +1,27 @@ +<?php + +namespace App\Event; + +use App\Modifier\Modifier; +use App\Provider\Repository; + +class PostProcessEvent extends HandleModifierEvent +{ + private $data; + + public function __construct($data, Modifier $modifier, Repository $repository, array $meta = []) + { + parent::__construct($modifier, $repository, $meta); + $this->data = $data; + } + + public function getData() + { + return $this->data; + } + + public function setData($data): void + { + $this->data = $data; + } +} diff --git a/api/src/Exception/InvalidArgumentException.php b/api/src/Exception/InvalidArgumentException.php new file mode 100644 index 0000000..14789e4 --- /dev/null +++ b/api/src/Exception/InvalidArgumentException.php @@ -0,0 +1,13 @@ +<?php + +namespace App\Exception; + +class InvalidArgumentException extends \InvalidArgumentException +{ + public static function invalidType($parameter, $value, array $expected = []) + { + return new static( + sprintf('Expected %s to be of type: %s. %s given.', $parameter, implode(', ', $expected), gettype($value)) + ); + } +} diff --git a/api/src/Exception/NonExistentServiceException.php b/api/src/Exception/NonExistentServiceException.php new file mode 100644 index 0000000..b19aef2 --- /dev/null +++ b/api/src/Exception/NonExistentServiceException.php @@ -0,0 +1,9 @@ +<?php + + +namespace App\Exception; + + +class NonExistentServiceException extends \LogicException +{ +} diff --git a/api/src/Exception/NotSupportedException.php b/api/src/Exception/NotSupportedException.php new file mode 100644 index 0000000..1af7250 --- /dev/null +++ b/api/src/Exception/NotSupportedException.php @@ -0,0 +1,7 @@ +<?php + +namespace App\Exception; + +class NotSupportedException extends \LogicException +{ +} diff --git a/api/src/Exception/UnsupportedModifierException.php b/api/src/Exception/UnsupportedModifierException.php new file mode 100644 index 0000000..1a03b80 --- /dev/null +++ b/api/src/Exception/UnsupportedModifierException.php @@ -0,0 +1,13 @@ +<?php + +namespace App\Exception; + +use App\Modifier\Modifier; + +class UnsupportedModifierException extends \LogicException +{ + public static function createFromModifier(Modifier $modifier) + { + return new static(sprintf("Modifier %s is not supported.", get_class($modifier))); + } +} diff --git a/src/Functions/helpers.php b/api/src/Functions/helpers.php similarity index 76% rename from src/Functions/helpers.php rename to api/src/Functions/helpers.php index 46f1c7a..57e138f 100644 --- a/src/Functions/helpers.php +++ b/api/src/Functions/helpers.php @@ -12,4 +12,10 @@ function encapsulate($value) default: return [ $value ]; } -} \ No newline at end of file +} + +function setup($value, $callback) +{ + $callback($value); + return $value; +} diff --git a/api/src/Functions/index.php b/api/src/Functions/index.php new file mode 100644 index 0000000..5215295 --- /dev/null +++ b/api/src/Functions/index.php @@ -0,0 +1,3 @@ +<?php + +require_once __DIR__ . '/helpers.php'; diff --git a/api/src/Handler/Database/FieldFilterDatabaseHandler.php b/api/src/Handler/Database/FieldFilterDatabaseHandler.php new file mode 100644 index 0000000..e7e8b1a --- /dev/null +++ b/api/src/Handler/Database/FieldFilterDatabaseHandler.php @@ -0,0 +1,63 @@ +<?php + +namespace App\Handler\Database; + +use App\Event\HandleDatabaseModifierEvent; +use App\Event\HandleModifierEvent; +use App\Handler\ModifierHandler; +use App\Model\ScheduledStop; +use App\Model\Stop; +use App\Modifier\FieldFilter; +use function App\Functions\encapsulate; + +class FieldFilterDatabaseHandler implements ModifierHandler +{ + protected $mapping = [ + Stop::class => [ + 'name' => 'name', + ], + ScheduledStop::class => [ + 'departure' => 'departure', + 'arrival' => 'arrival', + ] + ]; + + public function process(HandleModifierEvent $event) + { + if (!$event instanceof HandleDatabaseModifierEvent) { + return; + } + + /** @var FieldFilter $modifier */ + $modifier = $event->getModifier(); + $builder = $event->getBuilder(); + $alias = $event->getMeta()['alias']; + + $field = $this->mapFieldName($event->getMeta()['type'], $modifier->getField()); + $operator = $modifier->getOperator(); + $value = $modifier->getValue(); + + $parameter = sprintf(":%s_%s", $alias, $field); + + if ($operator === 'in' || $operator === 'not in') { + $parameter = "($parameter)"; + $value = encapsulate($value); + } + + $builder + ->andWhere(sprintf("%s.%s %s %s", $alias, $field, $operator, $parameter)) + ->setParameter($parameter, $value) + ; + } + + protected function mapFieldName(string $class, string $field) + { + if (!isset($this->mapping[$class][$field])) { + throw new \InvalidArgumentException( + sprintf("Unable to map field %s of %s into entity field.", $field, $class) + ); + } + + return $this->mapping[$class][$field]; + } +} diff --git a/api/src/Handler/Database/GenericWithDatabaseHandler.php b/api/src/Handler/Database/GenericWithDatabaseHandler.php new file mode 100644 index 0000000..26445c7 --- /dev/null +++ b/api/src/Handler/Database/GenericWithDatabaseHandler.php @@ -0,0 +1,103 @@ +<?php + +namespace App\Handler\Database; + +use App\Event\HandleDatabaseModifierEvent; +use App\Event\HandleModifierEvent; +use App\Handler\ModifierHandler; +use App\Model\ScheduledStop; +use App\Model\Track; +use App\Model\TrackStop; +use App\Model\Trip; +use App\Modifier\RelatedFilter; +use App\Service\EntityReferenceFactory; +use App\Service\IdUtils; +use Doctrine\ORM\EntityManagerInterface; +use function Kadet\Functional\Transforms\property; + +class GenericWithDatabaseHandler implements ModifierHandler +{ + protected $mapping = [ + Track::class => [ + 'line' => 'line', + 'stops' => 'stopsInTrack', + ], + Trip::class => [ + 'schedule' => 'stops.stop', + ], + TrackStop::class => [ + 'track' => 'track', + ], + ScheduledStop::class => [ + 'trip' => 'trip', + 'track' => 'trip.track', + 'destination' => 'trip.track.final', + ], + ]; + + private $em; + private $id; + private $references; + + public function __construct( + EntityManagerInterface $em, + IdUtils $idUtils, + EntityReferenceFactory $references + ) { + $this->em = $em; + $this->id = $idUtils; + $this->references = $references; + } + + public function process(HandleModifierEvent $event) + { + if (!$event instanceof HandleDatabaseModifierEvent) { + return; + } + + /** @var RelatedFilter $modifier */ + $modifier = $event->getModifier(); + $builder = $event->getBuilder(); + $alias = $event->getMeta()['alias']; + $type = $event->getMeta()['type']; + + if (!array_key_exists($modifier->getRelationship(), $this->mapping[$type])) { + throw new \InvalidArgumentException( + sprintf("Relationship %s is not supported for .", $type) + ); + } + + $relationship = $this->mapping[$type][$modifier->getRelationship()]; + + foreach ($this->getRelationships($relationship, $alias) as [$relationshipPath, $relationshipAlias]) { + $selected = collect($builder->getDQLPart('select'))->flatMap(property('parts')); + + if ($selected->contains($relationshipAlias)) { + continue; + } + + $builder + ->join($relationshipPath, $relationshipAlias) + ->addSelect($relationshipAlias); + } + } + + /** + * @inheritDoc + */ + public static function getSubscribedServices() + { + return [ + TrackByStopDatabaseHandler::class, + ]; + } + + private function getRelationships($relationship, $alias) + { + $relationships = explode('.', $relationship); + + foreach ($relationships as $current) { + yield [sprintf("%s.%s", $alias, $current), $alias = sprintf('%s_%s', $alias, $current)]; + } + } +} diff --git a/api/src/Handler/Database/IdFilterDatabaseHandler.php b/api/src/Handler/Database/IdFilterDatabaseHandler.php new file mode 100644 index 0000000..9f95d94 --- /dev/null +++ b/api/src/Handler/Database/IdFilterDatabaseHandler.php @@ -0,0 +1,44 @@ +<?php + +namespace App\Handler\Database; + +use App\Handler\ModifierHandler; +use App\Modifier\IdFilter; +use App\Event\HandleDatabaseModifierEvent; +use App\Event\HandleModifierEvent; +use App\Service\IdUtils; +use function Kadet\Functional\apply; + +class IdFilterDatabaseHandler implements ModifierHandler +{ + /** + * @var IdUtils + */ + private $id; + + public function __construct(IdUtils $id) + { + $this->id = $id; + } + + public function process(HandleModifierEvent $event) + { + if (!$event instanceof HandleDatabaseModifierEvent) { + return; + } + + /** @var IdFilter $modifier */ + $modifier = $event->getModifier(); + $builder = $event->getBuilder(); + $alias = $event->getMeta()['alias']; + $provider = $event->getMeta()['provider']; + + $id = $modifier->getId(); + $mapper = apply([$this->id, 'generate'], $provider); + + $builder + ->andWhere($modifier->isMultiple() ? "{$alias} in (:id)" : "{$alias} = :id") + ->setParameter(':id', $modifier->isMultiple() ? array_map($mapper, $id) : $mapper($id)); + ; + } +} diff --git a/api/src/Handler/Database/LimitDatabaseHandler.php b/api/src/Handler/Database/LimitDatabaseHandler.php new file mode 100644 index 0000000..3f445a9 --- /dev/null +++ b/api/src/Handler/Database/LimitDatabaseHandler.php @@ -0,0 +1,27 @@ +<?php + +namespace App\Handler\Database; + +use App\Event\HandleDatabaseModifierEvent; +use App\Event\HandleModifierEvent; +use App\Handler\ModifierHandler; +use App\Modifier\Limit; + +class LimitDatabaseHandler implements ModifierHandler +{ + public function process(HandleModifierEvent $event) + { + if (!$event instanceof HandleDatabaseModifierEvent) { + return; + } + + /** @var Limit $modifier */ + $modifier = $event->getModifier(); + $builder = $event->getBuilder(); + + $builder + ->setFirstResult($modifier->getOffset()) + ->setMaxResults($modifier->getCount()) + ; + } +} diff --git a/api/src/Handler/Database/RelatedFilterDatabaseGenericHandler.php b/api/src/Handler/Database/RelatedFilterDatabaseGenericHandler.php new file mode 100644 index 0000000..f366e8e --- /dev/null +++ b/api/src/Handler/Database/RelatedFilterDatabaseGenericHandler.php @@ -0,0 +1,107 @@ +<?php + +namespace App\Handler\Database; + +use App\Event\HandleDatabaseModifierEvent; +use App\Event\HandleModifierEvent; +use App\Handler\ModifierHandler; +use App\Model\Line; +use App\Model\ScheduledStop; +use App\Model\Stop; +use App\Model\Track; +use App\Model\TrackStop; +use App\Model\Trip; +use App\Modifier\RelatedFilter; +use App\Service\IdUtils; +use App\Service\EntityReferenceFactory; +use Doctrine\ORM\EntityManagerInterface; +use Psr\Container\ContainerInterface; +use Symfony\Contracts\Service\ServiceSubscriberInterface; + +class RelatedFilterDatabaseGenericHandler implements ModifierHandler, ServiceSubscriberInterface +{ + protected $mapping = [ + Track::class => [ + Line::class => 'line', + Stop::class => TrackByStopDatabaseHandler::class, + ], + TrackStop::class => [ + Stop::class => 'stop', + Track::class => 'track', + ], + ScheduledStop::class => [ + Stop::class => 'stop', + Trip::class => 'trip', + ], + ]; + + private $em; + private $inner; + private $id; + private $references; + + public function __construct( + ContainerInterface $inner, + EntityManagerInterface $em, + IdUtils $idUtils, + EntityReferenceFactory $references + ) { + $this->inner = $inner; + $this->em = $em; + $this->id = $idUtils; + $this->references = $references; + } + + public function process(HandleModifierEvent $event) + { + if (!$event instanceof HandleDatabaseModifierEvent) { + return; + } + + /** @var RelatedFilter $modifier */ + $modifier = $event->getModifier(); + $builder = $event->getBuilder(); + $alias = $event->getMeta()['alias']; + $type = $event->getMeta()['type']; + + if (!array_key_exists($type, $this->mapping)) { + throw new \InvalidArgumentException( + sprintf("Relationship filtering for %s is not supported.", $type) + ); + } + + if (!array_key_exists($modifier->getRelationship(), $this->mapping[$type])) { + throw new \InvalidArgumentException( + sprintf("Relationship %s is not supported for %s.", $modifier->getRelationship(), $type) + ); + } + + $relationship = $this->mapping[$type][$modifier->getRelationship()]; + + if ($this->inner->has($relationship)) { + /** @var ModifierHandler $inner */ + $inner = $this->inner->get($relationship); + $inner->process($event); + + return; + } + + $parameter = sprintf(":%s_%s", $alias, $relationship); + $reference = $this->references->create($modifier->getRelated(), $event->getMeta()['provider']); + + $builder + ->join(sprintf('%s.%s', $alias, $relationship), $relationship) + ->andWhere(sprintf($modifier->isMultiple() ? "%s in (%s)" : "%s = %s", $relationship, $parameter)) + ->setParameter($parameter, $reference); + } + + /** + * @inheritDoc + */ + public static function getSubscribedServices() + { + return [ + TrackByStopDatabaseHandler::class, + ]; + } +} diff --git a/api/src/Handler/Database/TrackByStopDatabaseHandler.php b/api/src/Handler/Database/TrackByStopDatabaseHandler.php new file mode 100644 index 0000000..fe84aa0 --- /dev/null +++ b/api/src/Handler/Database/TrackByStopDatabaseHandler.php @@ -0,0 +1,45 @@ +<?php + +namespace App\Handler\Database; + +use App\Entity\TrackStopEntity; +use App\Event\HandleDatabaseModifierEvent; +use App\Event\HandleModifierEvent; +use App\Handler\ModifierHandler; +use App\Modifier\RelatedFilter; +use App\Service\EntityReferenceFactory; + +class TrackByStopDatabaseHandler implements ModifierHandler +{ + private $references; + + public function __construct(EntityReferenceFactory $references) + { + $this->references = $references; + } + + public function process(HandleModifierEvent $event) + { + if (!$event instanceof HandleDatabaseModifierEvent) { + return; + } + + /** @var RelatedFilter $modifier */ + $modifier = $event->getModifier(); + $builder = $event->getBuilder(); + $alias = $event->getMeta()['alias']; + + $relationship = 'stopsInTrack'; + + $parameter = sprintf(":%s_%s", $alias, $relationship); + $reference = $this->references->create($modifier->getRelated(), $event->getMeta()['provider']); + + $condition = $modifier->isMultiple() ? 'stop_in_track.stop IN (%s)' : 'stop_in_track.stop = %s'; + + $builder + ->join(sprintf("%s.%s", $alias, $relationship), 'stop_in_track') + ->andWhere(sprintf($condition, $parameter)) + ->setParameter($parameter, $reference) + ; + } +} diff --git a/api/src/Handler/Database/WithDestinationsDatabaseHandler.php b/api/src/Handler/Database/WithDestinationsDatabaseHandler.php new file mode 100644 index 0000000..b159371 --- /dev/null +++ b/api/src/Handler/Database/WithDestinationsDatabaseHandler.php @@ -0,0 +1,82 @@ +<?php + +namespace App\Handler\Database; + +use App\Entity\TrackEntity; +use App\Event\PostProcessEvent; +use App\Handler\PostProcessingHandler; +use App\Model\Destination; +use App\Model\Stop; +use App\Service\CacheableConverter; +use App\Service\Converter; +use App\Service\IdUtils; +use Doctrine\ORM\EntityManagerInterface; +use Illuminate\Support\Collection; +use Kadet\Functional as f; +use Kadet\Functional\Transforms as t; + +class WithDestinationsDatabaseHandler implements PostProcessingHandler +{ + private $em; + private $converter; + private $id; + + public function __construct(EntityManagerInterface $entityManager, Converter $converter, IdUtils $id) + { + $this->em = $entityManager; + $this->converter = $converter; + $this->id = $id; + + if ($this->converter instanceof CacheableConverter) { + $this->converter = clone $this->converter; + $this->converter->reset(); + } + } + + public function postProcess(PostProcessEvent $event) + { + $provider = $event->getMeta()['provider']; + $stops = $event + ->getData() + ->map(t\property('id')) + ->map(f\apply([$this->id, 'generate'], $provider)) + ->all(); + + $destinations = collect($this->em->createQueryBuilder() + ->select('t', 'tl', 'f', 'fs', 'ts') + ->from(TrackEntity::class, 't') + ->join('t.stopsInTrack', 'ts') + ->join('t.line', 'tl') + ->where('ts.stop IN (:stops)') + ->join('t.final', 'f') + ->join('f.stop', 'fs') + ->getQuery() + ->execute(['stops' => $stops])) + ->reduce(function ($grouped, TrackEntity $track) { + foreach ($track->getStopsInTrack()->map(t\property('stop'))->map(t\property('id')) as $stop) { + $grouped[$stop] = ($grouped[$stop] ?? collect())->add($track); + } + + return $grouped; + }, collect()) + ->map(function (Collection $tracks) { + return $tracks + ->groupBy(function (TrackEntity $track) { + return $track->getFinal()->getStop()->getId(); + })->map(function (Collection $tracks, $id) { + return Destination::createFromArray([ + 'stop' => $this->converter->convert($tracks->first()->getFinal()->getStop()), + 'lines' => $tracks + ->map(t\property('line')) + ->unique(t\property('id')) + ->map(f\ref([$this->converter, 'convert'])) + ->values(), + ]); + })->values(); + }); + + $event->getData()->each(function (Stop $stop) use ($provider, $destinations) { + $stop->setDestinations($destinations[$this->id->generate($provider, $stop->getId())]); + }); + } +} diff --git a/api/src/Handler/ModifierHandler.php b/api/src/Handler/ModifierHandler.php new file mode 100644 index 0000000..237f87d --- /dev/null +++ b/api/src/Handler/ModifierHandler.php @@ -0,0 +1,10 @@ +<?php + +namespace App\Handler; + +use App\Event\HandleModifierEvent; + +interface ModifierHandler +{ + public function process(HandleModifierEvent $event); +} diff --git a/api/src/Handler/PostProcessingHandler.php b/api/src/Handler/PostProcessingHandler.php new file mode 100644 index 0000000..a18f0d8 --- /dev/null +++ b/api/src/Handler/PostProcessingHandler.php @@ -0,0 +1,10 @@ +<?php + +namespace App\Handler; + +use App\Event\PostProcessEvent; + +interface PostProcessingHandler +{ + public function postProcess(PostProcessEvent $event); +} diff --git a/src/Kernel.php b/api/src/Kernel.php similarity index 63% rename from src/Kernel.php rename to api/src/Kernel.php index 68c3c16..1cd0572 100644 --- a/src/Kernel.php +++ b/api/src/Kernel.php @@ -2,7 +2,6 @@ namespace App; -use Doctrine\Common\Annotations\AnnotationReader; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; use Symfony\Component\Config\Loader\LoaderInterface; use Symfony\Component\Config\Resource\FileResource; @@ -14,53 +13,42 @@ class Kernel extends BaseKernel { use MicroKernelTrait; - const CONFIG_EXTS = '.{php,xml,yaml,yml}'; + private const CONFIG_EXTS = '.{php,xml,yaml,yml}'; - public function getCacheDir() - { - return $this->getProjectDir().'/var/cache/'.$this->environment; - } - - public function getLogDir() - { - return $this->getProjectDir().'/var/log'; - } - - public function registerBundles() + public function registerBundles(): iterable { $contents = require $this->getProjectDir().'/config/bundles.php'; foreach ($contents as $class => $envs) { - if (isset($envs['all']) || isset($envs[$this->environment])) { + if ($envs[$this->environment] ?? $envs['all'] ?? false) { yield new $class(); } } } - protected function configureContainer(ContainerBuilder $container, LoaderInterface $loader) + public function getProjectDir(): string + { + return \dirname(__DIR__); + } + + protected function configureContainer(ContainerBuilder $container, LoaderInterface $loader): void { $container->addResource(new FileResource($this->getProjectDir().'/config/bundles.php')); - // Feel free to remove the "container.autowiring.strict_mode" parameter - // if you are using symfony/dependency-injection 4.0+ as it's the default behavior - $container->setParameter('container.autowiring.strict_mode', true); - $container->setParameter('container.dumper.inline_class_loader', true); + $container->setParameter('container.dumper.inline_class_loader', \PHP_VERSION_ID < 70400 || $this->debug); + $container->setParameter('container.dumper.inline_factories', true); $confDir = $this->getProjectDir().'/config'; $loader->load($confDir.'/{packages}/*'.self::CONFIG_EXTS, 'glob'); - $loader->load($confDir.'/{packages}/'.$this->environment.'/**/*'.self::CONFIG_EXTS, 'glob'); + $loader->load($confDir.'/{packages}/'.$this->environment.'/*'.self::CONFIG_EXTS, 'glob'); $loader->load($confDir.'/{services}'.self::CONFIG_EXTS, 'glob'); $loader->load($confDir.'/{services}_'.$this->environment.self::CONFIG_EXTS, 'glob'); - - if (!file_exists($this->getCacheDir().'/proxy')) { - mkdir($this->getCacheDir().'/proxy'); - } } - protected function configureRoutes(RouteCollectionBuilder $routes) + protected function configureRoutes(RouteCollectionBuilder $routes): void { $confDir = $this->getProjectDir().'/config'; + $routes->import($confDir.'/{routes}/'.$this->environment.'/*'.self::CONFIG_EXTS, '/', 'glob'); $routes->import($confDir.'/{routes}/*'.self::CONFIG_EXTS, '/', 'glob'); - $routes->import($confDir.'/{routes}/'.$this->environment.'/**/*'.self::CONFIG_EXTS, '/', 'glob'); $routes->import($confDir.'/{routes}'.self::CONFIG_EXTS, '/', 'glob'); } } diff --git a/api/src/Message/UpdateDataMessage.php b/api/src/Message/UpdateDataMessage.php new file mode 100644 index 0000000..173ded5 --- /dev/null +++ b/api/src/Message/UpdateDataMessage.php @@ -0,0 +1,7 @@ +<?php + +namespace App\Message; + +final class UpdateDataMessage +{ +} diff --git a/api/src/MessageHandler/UpdateDataMessageHandler.php b/api/src/MessageHandler/UpdateDataMessageHandler.php new file mode 100644 index 0000000..7f19e4f --- /dev/null +++ b/api/src/MessageHandler/UpdateDataMessageHandler.php @@ -0,0 +1,34 @@ +<?php + +namespace App\MessageHandler; + +use App\Message\UpdateDataMessage; +use App\Output\LoggerOutput; +use App\Service\DataUpdater; +use Psr\Log\LoggerAwareInterface; +use Psr\Log\LoggerAwareTrait; +use Symfony\Component\Messenger\Handler\MessageHandlerInterface; + +final class UpdateDataMessageHandler implements MessageHandlerInterface, LoggerAwareInterface +{ + use LoggerAwareTrait; + + /** @var DataUpdater */ + private $updater; + + public function __construct(DataUpdater $updater) + { + $this->updater = $updater; + } + + public function __invoke(UpdateDataMessage $message) + { + try { + $this->updater->update(new LoggerOutput($this->logger)); + } catch (\Exception $exception) { + $this->logger->critical($exception->getMessage(), [ + 'backtrace' => $exception->getTraceAsString() + ]); + } + } +} diff --git a/src/Model/Departure.php b/api/src/Model/Departure.php similarity index 100% rename from src/Model/Departure.php rename to api/src/Model/Departure.php diff --git a/api/src/Model/Destination.php b/api/src/Model/Destination.php new file mode 100644 index 0000000..889c7e1 --- /dev/null +++ b/api/src/Model/Destination.php @@ -0,0 +1,52 @@ +<?php + +namespace App\Model; + +use Illuminate\Support\Collection; +use JMS\Serializer\Annotation as Serializer; +use Nelmio\ApiDocBundle\Annotation\Model; +use Swagger\Annotations as SWG; + +class Destination implements Fillable +{ + use FillTrait; + + /** + * Stop associated with destination. + * @Serializer\Type(Stop::class) + * @var Stop + */ + private $stop; + + /** + * @Serializer\Type("Collection") + * @SWG\Property(type="array", @SWG\Items(ref=@Model(type=Line::class, groups={"Default"}))) + * @var Line[]|Collection<Line> + */ + private $lines; + + public function __construct() + { + $this->lines = collect(); + } + + public function getStop(): Stop + { + return $this->stop; + } + + public function setStop(Stop $stop): void + { + $this->stop = $stop; + } + + public function getLines(): Collection + { + return $this->lines; + } + + public function setLines(iterable $lines): void + { + $this->lines = collect($lines); + } +} diff --git a/src/Model/FillTrait.php b/api/src/Model/FillTrait.php similarity index 100% rename from src/Model/FillTrait.php rename to api/src/Model/FillTrait.php diff --git a/src/Model/Fillable.php b/api/src/Model/Fillable.php similarity index 100% rename from src/Model/Fillable.php rename to api/src/Model/Fillable.php diff --git a/src/Model/JustReference.php b/api/src/Model/JustReference.php similarity index 100% rename from src/Model/JustReference.php rename to api/src/Model/JustReference.php diff --git a/src/Model/Line.php b/api/src/Model/Line.php similarity index 98% rename from src/Model/Line.php rename to api/src/Model/Line.php index b339218..2661f1e 100644 --- a/src/Model/Line.php +++ b/api/src/Model/Line.php @@ -2,10 +2,10 @@ namespace App\Model; +use Illuminate\Support\Collection; use JMS\Serializer\Annotation as Serializer; use Nelmio\ApiDocBundle\Annotation\Model; use Swagger\Annotations as SWG; -use Tightenco\Collect\Support\Collection; class Line implements Fillable, Referable { @@ -138,4 +138,4 @@ class Line implements Fillable, Referable { $this->operator = $operator; } -} \ No newline at end of file +} diff --git a/src/Model/Location.php b/api/src/Model/Location.php similarity index 100% rename from src/Model/Location.php rename to api/src/Model/Location.php diff --git a/src/Model/Message.php b/api/src/Model/Message.php similarity index 100% rename from src/Model/Message.php rename to api/src/Model/Message.php diff --git a/src/Model/Operator.php b/api/src/Model/Operator.php similarity index 100% rename from src/Model/Operator.php rename to api/src/Model/Operator.php diff --git a/api/src/Model/Provider.php b/api/src/Model/Provider.php new file mode 100644 index 0000000..0ca7e92 --- /dev/null +++ b/api/src/Model/Provider.php @@ -0,0 +1,117 @@ +<?php + +namespace App\Model; + +use Carbon\Carbon; +use JMS\Serializer\Annotation as Serializer; +use Swagger\Annotations as SWG; + +class Provider implements Fillable, Referable +{ + use FillTrait; + + /** + * Short identifier of provider, ex. "trojmiasto" + * @SWG\Property(example="trojmiasto") + * @Serializer\Type("string") + * @var string + */ + private $id; + + /** + * Full name of the provider, ex. "MZKZG Trójmiasto" + * @SWG\Property(example="MZKZG Trójmiasto") + * @Serializer\Type("string") + * @var string + */ + private $name; + + /** + * Short name of the provider for easier identification, ex. "Trójmiasto" or "Warszawa" + * @SWG\Property(example="Trójmiasto") + * @Serializer\Type("string") + * @var string + */ + private $shortName; + + /** + * Attribution to be presented for this provider, can contain HTML tags. + * @SWG\Property(example="Copyright by XYZ inc.") + * @Serializer\Type("string") + * @var string|null + */ + private $attribution; + + /** + * Time when data was last synchronized with this provider. + * @Serializer\Type("Carbon") + * @var Carbon|null + */ + private $lastUpdate; + + /** + * Location of provider centre of interest. + * @var Location + */ + private $location; + + public function getId(): string + { + return $this->id; + } + + public function setId(string $id): void + { + $this->id = $id; + } + + public function getName(): string + { + return $this->name; + } + + public function setName(string $name): void + { + $this->name = $name; + } + + public function getShortName(): string + { + return $this->shortName; + } + + public function setShortName(string $shortName): void + { + $this->shortName = $shortName; + } + + public function getAttribution(): ?string + { + return $this->attribution; + } + + public function setAttribution(?string $attribution): void + { + $this->attribution = $attribution; + } + + public function getLastUpdate(): ?Carbon + { + return $this->lastUpdate; + } + + public function setLastUpdate(?Carbon $lastUpdate): void + { + $this->lastUpdate = $lastUpdate; + } + + public function getLocation(): Location + { + return $this->location; + } + + public function setLocation(Location $location): void + { + $this->location = $location; + } +} diff --git a/src/Model/Referable.php b/api/src/Model/Referable.php similarity index 100% rename from src/Model/Referable.php rename to api/src/Model/Referable.php diff --git a/src/Model/ReferableTrait.php b/api/src/Model/ReferableTrait.php similarity index 100% rename from src/Model/ReferableTrait.php rename to api/src/Model/ReferableTrait.php diff --git a/api/src/Model/ScheduledStop.php b/api/src/Model/ScheduledStop.php new file mode 100644 index 0000000..5042a49 --- /dev/null +++ b/api/src/Model/ScheduledStop.php @@ -0,0 +1,56 @@ +<?php + +namespace App\Model; + +use Carbon\Carbon; + +class ScheduledStop extends TrackStop +{ + /** + * Arrival time. + * @var Carbon + */ + private $arrival; + + /** + * Departure time. + * @var Carbon + */ + private $departure; + + /** + * Exact trip that this scheduled stop is part of. + * @var Trip|null + */ + private $trip; + + public function getArrival(): Carbon + { + return $this->arrival; + } + + public function setArrival(Carbon $arrival): void + { + $this->arrival = $arrival; + } + + public function getDeparture(): Carbon + { + return $this->departure; + } + + public function setDeparture(Carbon $departure): void + { + $this->departure = $departure; + } + + public function getTrip(): ?Trip + { + return $this->trip; + } + + public function setTrip(?Trip $trip): void + { + $this->trip = $trip; + } +} diff --git a/src/Model/Stop.php b/api/src/Model/Stop.php similarity index 94% rename from src/Model/Stop.php rename to api/src/Model/Stop.php index a37764a..bac6e78 100644 --- a/src/Model/Stop.php +++ b/api/src/Model/Stop.php @@ -2,10 +2,10 @@ namespace App\Model; +use Illuminate\Support\Collection; use JMS\Serializer\Annotation as Serializer; use Nelmio\ApiDocBundle\Annotation\Model; use Swagger\Annotations as SWG; -use Tightenco\Collect\Support\Collection; /** * Class Stop @@ -73,9 +73,9 @@ class Stop implements Referable, Fillable * * @Serializer\Groups({"WithDestinations"}) * @Serializer\Type("Collection") - * @SWG\Property(type="array", @SWG\Items(ref=@Model(type=Stop::class, groups={"Default"}))) + * @SWG\Property(type="array", @SWG\Items(ref=@Model(type=Destination::class, groups={"Default"}))) * - * @var Collection<Stop> + * @var Collection<Destination> */ private $destinations; diff --git a/src/Model/StopGroup.php b/api/src/Model/StopGroup.php similarity index 94% rename from src/Model/StopGroup.php rename to api/src/Model/StopGroup.php index a2ef876..6ed17ff 100644 --- a/src/Model/StopGroup.php +++ b/api/src/Model/StopGroup.php @@ -2,11 +2,10 @@ namespace App\Model; +use Illuminate\Support\Collection; use JMS\Serializer\Annotation as Serializer; use Nelmio\ApiDocBundle\Annotation\Model; use Swagger\Annotations as SWG; -use Tightenco\Collect\Support\Collection; -use App\Model\Stop; /** * Class StopGroup diff --git a/src/Model/Track.php b/api/src/Model/Track.php similarity index 80% rename from src/Model/Track.php rename to api/src/Model/Track.php index bd62451..bcbed78 100644 --- a/src/Model/Track.php +++ b/api/src/Model/Track.php @@ -2,10 +2,10 @@ namespace App\Model; +use Illuminate\Support\Collection; use JMS\Serializer\Annotation as Serializer; use Nelmio\ApiDocBundle\Annotation\Model; use Swagger\Annotations as SWG; -use Tightenco\Collect\Support\Collection; class Track implements Referable, Fillable { @@ -42,6 +42,14 @@ class Track implements Referable, Fillable */ private $stops; + /** + * Destination stop of this track + * @var Stop|null + * @Serializer\Type(Stop::class) + * @SWG\Property(ref=@Model(type=Stop::class)) + */ + private $destination; + /** * Track constructor. */ @@ -89,4 +97,14 @@ class Track implements Referable, Fillable { return $this->stops = collect($stops); } -} \ No newline at end of file + + public function getDestination(): ?Stop + { + return $this->destination; + } + + public function setDestination(?Stop $destination): void + { + $this->destination = $destination; + } +} diff --git a/src/Model/ScheduledStop.php b/api/src/Model/TrackStop.php similarity index 51% rename from src/Model/ScheduledStop.php rename to api/src/Model/TrackStop.php index abfda2d..283151a 100644 --- a/src/Model/ScheduledStop.php +++ b/api/src/Model/TrackStop.php @@ -2,18 +2,12 @@ namespace App\Model; -use Carbon\Carbon; +use JMS\Serializer\Annotation as Serializer; -class ScheduledStop implements Fillable +class TrackStop implements Fillable { use FillTrait; - /** - * Stop (as a place) related to that scheduled bus stop - * @var Stop - */ - private $stop; - /** * Order in trip * @var int @@ -21,16 +15,16 @@ class ScheduledStop implements Fillable private $order; /** - * Arrival time - * @var Carbon + * Stop (as a place) related to that scheduled bus stop + * @var Stop */ - private $arrival; + private $stop; /** - * Departure time - * @var Carbon + * Track that this stop is part of. + * @var Track|null */ - private $departure; + private $track; public function getStop() { @@ -52,23 +46,13 @@ class ScheduledStop implements Fillable $this->order = $order; } - public function getArrival(): Carbon + public function getTrack(): ?Track { - return $this->arrival; + return $this->track; } - public function setArrival(Carbon $arrival): void + public function setTrack(?Track $track): void { - $this->arrival = $arrival; - } - - public function getDeparture(): Carbon - { - return $this->departure; - } - - public function setDeparture(Carbon $departure): void - { - $this->departure = $departure; + $this->track = $track; } } diff --git a/src/Model/Trip.php b/api/src/Model/Trip.php similarity index 83% rename from src/Model/Trip.php rename to api/src/Model/Trip.php index eaea219..cd160eb 100644 --- a/src/Model/Trip.php +++ b/api/src/Model/Trip.php @@ -3,8 +3,8 @@ namespace App\Model; use App\Serialization\SerializeAs; +use Illuminate\Support\Collection; use JMS\Serializer\Annotation as Serializer; -use Tightenco\Collect\Support\Collection; class Trip implements Referable, Fillable { @@ -40,6 +40,12 @@ class Trip implements Referable, Fillable */ private $schedule; + /** + * Destination stop of this trip + * @var Stop|null + */ + private $destination; + /** * Track constructor. */ @@ -87,4 +93,14 @@ class Trip implements Referable, Fillable { return $this->schedule = collect($schedule); } + + public function getDestination(): ?Stop + { + return $this->destination; + } + + public function setDestination(?Stop $destination): void + { + $this->destination = $destination; + } } diff --git a/src/Model/Vehicle.php b/api/src/Model/Vehicle.php similarity index 100% rename from src/Model/Vehicle.php rename to api/src/Model/Vehicle.php diff --git a/api/src/Modifier/FieldFilter.php b/api/src/Modifier/FieldFilter.php new file mode 100644 index 0000000..e813949 --- /dev/null +++ b/api/src/Modifier/FieldFilter.php @@ -0,0 +1,37 @@ +<?php + +namespace App\Modifier; + +class FieldFilter implements Modifier +{ + private $field; + private $value; + private $operator; + + public function __construct(string $field, $value, string $operator = '=') + { + $this->field = $field; + $this->value = $value; + $this->operator = $operator; + } + + public static function contains(string $field, string $value) + { + return new static($field, "%$value%", 'LIKE'); + } + + public function getField(): string + { + return $this->field; + } + + public function getValue() + { + return $this->value; + } + + public function getOperator(): string + { + return $this->operator; + } +} diff --git a/api/src/Modifier/IdFilter.php b/api/src/Modifier/IdFilter.php new file mode 100644 index 0000000..0e791a4 --- /dev/null +++ b/api/src/Modifier/IdFilter.php @@ -0,0 +1,32 @@ +<?php + +namespace App\Modifier; + +use App\Exception\InvalidArgumentException; +use App\Modifier\Modifier; +use App\Service\IterableUtils; + +class IdFilter implements Modifier +{ + /** @var string|array */ + private $id; + + public function __construct($id) + { + if (!is_iterable($id) && !is_string($id)) { + throw InvalidArgumentException::invalidType('id', $id, ['string', 'array']); + } + + $this->id = is_iterable($id) ? IterableUtils::toArray($id) : $id; + } + + public function getId() + { + return $this->id; + } + + public function isMultiple() + { + return is_array($this->id); + } +} diff --git a/api/src/Modifier/Limit.php b/api/src/Modifier/Limit.php new file mode 100644 index 0000000..7b73f8d --- /dev/null +++ b/api/src/Modifier/Limit.php @@ -0,0 +1,30 @@ +<?php + +namespace App\Modifier; + +class Limit implements Modifier +{ + private $offset; + private $count; + + public function __construct(int $offset = 0, ?int $count = null) + { + $this->offset = $offset; + $this->count = $count; + } + + public function getOffset() + { + return $this->offset; + } + + public function getCount() + { + return $this->count; + } + + public static function count(int $count) + { + return new static(0, $count); + } +} diff --git a/api/src/Modifier/Modifier.php b/api/src/Modifier/Modifier.php new file mode 100644 index 0000000..e1b3e62 --- /dev/null +++ b/api/src/Modifier/Modifier.php @@ -0,0 +1,8 @@ +<?php + +namespace App\Modifier; + +interface Modifier +{ + +} diff --git a/api/src/Modifier/RelatedFilter.php b/api/src/Modifier/RelatedFilter.php new file mode 100644 index 0000000..3375880 --- /dev/null +++ b/api/src/Modifier/RelatedFilter.php @@ -0,0 +1,38 @@ +<?php + +namespace App\Modifier; + +use App\Exception\InvalidArgumentException; +use App\Model\Referable; +use App\Service\IterableUtils; + +class RelatedFilter implements Modifier +{ + private $relationship; + private $reference; + + public function __construct($reference, ?string $relation = null) + { + if (!is_iterable($reference) && !$reference instanceof Referable) { + throw InvalidArgumentException::invalidType('object', $reference, [Referable::class, 'iterable']); + } + + $this->reference = is_iterable($reference) ? IterableUtils::toArray($reference) : $reference; + $this->relationship = $relation ?: get_class($reference); + } + + public function getRelationship(): string + { + return $this->relationship; + } + + public function getRelated() + { + return $this->reference; + } + + public function isMultiple() + { + return is_array($this->reference); + } +} diff --git a/api/src/Modifier/With.php b/api/src/Modifier/With.php new file mode 100644 index 0000000..bbbbd67 --- /dev/null +++ b/api/src/Modifier/With.php @@ -0,0 +1,18 @@ +<?php + +namespace App\Modifier; + +class With implements Modifier +{ + private $relationship; + + public function __construct(string $relationship) + { + $this->relationship = $relationship; + } + + public function getRelationship(): string + { + return $this->relationship; + } +} diff --git a/api/src/Output/LoggerOutput.php b/api/src/Output/LoggerOutput.php new file mode 100644 index 0000000..8421cf7 --- /dev/null +++ b/api/src/Output/LoggerOutput.php @@ -0,0 +1,30 @@ +<?php + + +namespace App\Output; + +use Psr\Log\LoggerInterface; +use Symfony\Component\Console\Formatter\OutputFormatterInterface; +use Symfony\Component\Console\Output\Output; + +class LoggerOutput extends Output +{ + /** @var LoggerInterface */ + private $logger; + + public function __construct( + LoggerInterface $logger, + ?int $verbosity = self::VERBOSITY_NORMAL, + bool $decorated = false, + OutputFormatterInterface $formatter = null + ) { + parent::__construct($verbosity, $decorated, $formatter); + + $this->logger = $logger; + } + + protected function doWrite(string $message, bool $newline) + { + $this->logger->info($message); + } +} diff --git a/api/src/Provider/Database/DatabaseRepository.php b/api/src/Provider/Database/DatabaseRepository.php new file mode 100644 index 0000000..7e7f86b --- /dev/null +++ b/api/src/Provider/Database/DatabaseRepository.php @@ -0,0 +1,159 @@ +<?php + +namespace App\Provider\Database; + +use App\Entity\ProviderEntity; +use App\Event\HandleDatabaseModifierEvent; +use App\Event\PostProcessEvent; +use App\Handler\Database\FieldFilterDatabaseHandler; +use App\Handler\Database\IdFilterDatabaseHandler; +use App\Handler\Database\LimitDatabaseHandler; +use App\Handler\Database\RelatedFilterDatabaseGenericHandler; +use App\Handler\Database\GenericWithDatabaseHandler; +use App\Handler\ModifierHandler; +use App\Handler\PostProcessingHandler; +use App\Model\Referable; +use App\Modifier\FieldFilter; +use App\Modifier\IdFilter; +use App\Modifier\Limit; +use App\Modifier\Modifier; +use App\Modifier\RelatedFilter; +use App\Modifier\With; +use App\Provider\Repository; +use App\Service\Converter; +use App\Service\HandlerProvider; +use App\Service\IdUtils; +use Doctrine\ORM\EntityManagerInterface; +use Doctrine\ORM\QueryBuilder; +use Doctrine\ORM\Tools\Pagination\Paginator; + +abstract class DatabaseRepository implements Repository +{ + const DEFAULT_LIMIT = 100; + + /** @var EntityManagerInterface */ + protected $em; + + /** @var ProviderEntity */ + protected $provider; + + /** @var IdUtils */ + protected $id; + + /** @var Converter */ + protected $converter; + + /** @var HandlerProvider */ + protected $handlers; + + /** + * DatabaseRepository constructor. + * + * @param EntityManagerInterface $em + */ + public function __construct( + EntityManagerInterface $em, + IdUtils $id, + Converter $converter, + HandlerProvider $handlers + ) { + $this->em = $em; + $this->id = $id; + $this->converter = $converter; + $this->handlers = $handlers; + + $this->handlers->loadConfiguration(array_merge([ + IdFilter::class => IdFilterDatabaseHandler::class, + Limit::class => LimitDatabaseHandler::class, + FieldFilter::class => FieldFilterDatabaseHandler::class, + RelatedFilter::class => RelatedFilterDatabaseGenericHandler::class, + With::class => GenericWithDatabaseHandler::class, + ], static::getHandlers())); + } + + /** @return static */ + public function withProvider(ProviderEntity $provider) + { + $result = clone $this; + $result->provider = $provider; + + return $result; + } + + protected function convert($entity) + { + return $this->converter->convert($entity); + } + + protected function reference($class, Referable $referable) + { + $id = $this->id->generate($this->provider, $referable->getId()); + + return $this->em->getReference($class, $id); + } + + protected function processQueryBuilder(QueryBuilder $builder, iterable $modifiers, array $meta = []) + { + $reducers = []; + + foreach ($modifiers as $modifier) { + $handler = $this->handlers->get($modifier); + + if ($handler instanceof ModifierHandler) { + $event = new HandleDatabaseModifierEvent($modifier, $this, $builder, array_merge([ + 'provider' => $this->provider, + ], $meta)); + + $handler->process($event); + } + + if ($handler instanceof PostProcessingHandler) { + $reducers[] = function ($result) use ($meta, $modifier, $handler) { + $event = new PostProcessEvent($result, $modifier, $this, array_merge([ + 'provider' => $this->provider, + ], $meta)); + + $handler->postProcess($event); + + return $event->getData(); + }; + } + + } + + return collect($reducers); + } + + protected function allFromQueryBuilder(QueryBuilder $builder, iterable $modifiers, array $meta = []) + { + $builder->setMaxResults(self::DEFAULT_LIMIT); + + $reducers = $this->processQueryBuilder($builder, $modifiers, $meta); + $query = $builder->getQuery(); + + $paginator = new Paginator($query); + $result = collect($paginator)->map(\Closure::fromCallable([$this, 'convert'])); + + return $reducers->reduce(function ($result, $reducer) { + return $reducer($result); + }, $result); + } + + public function first(Modifier ...$modifiers) + { + return $this->all(Limit::count(1), ...$modifiers)->first(); + } + + /** + * Returns array describing handlers for each modifier type. Syntax is as follows: + * [ IdFilter::class => IdFilterDatabaseHandler::class ] + * + * It is internally used as part of service subscriber. + * + * @return array + */ + protected static function getHandlers() + { + return []; + } +} diff --git a/api/src/Provider/Database/GenericLineRepository.php b/api/src/Provider/Database/GenericLineRepository.php new file mode 100644 index 0000000..31dd9e0 --- /dev/null +++ b/api/src/Provider/Database/GenericLineRepository.php @@ -0,0 +1,27 @@ +<?php + +namespace App\Provider\Database; + +use App\Entity\LineEntity; +use App\Model\Line; +use App\Modifier\Modifier; +use App\Provider\LineRepository; +use Illuminate\Support\Collection; + +class GenericLineRepository extends DatabaseRepository implements LineRepository +{ + public function all(Modifier ...$modifiers): Collection + { + $builder = $this->em + ->createQueryBuilder() + ->from(LineEntity::class, 'line') + ->select('line') + ; + + return $this->allFromQueryBuilder($builder, $modifiers, [ + 'alias' => 'line', + 'entity' => LineEntity::class, + 'type' => Line::class, + ]); + } +} diff --git a/api/src/Provider/Database/GenericOperatorRepository.php b/api/src/Provider/Database/GenericOperatorRepository.php new file mode 100644 index 0000000..a3aafa7 --- /dev/null +++ b/api/src/Provider/Database/GenericOperatorRepository.php @@ -0,0 +1,27 @@ +<?php + +namespace App\Provider\Database; + +use App\Entity\OperatorEntity; +use App\Model\Operator; +use App\Modifier\Modifier; +use App\Provider\OperatorRepository; +use Illuminate\Support\Collection; + +class GenericOperatorRepository extends DatabaseRepository implements OperatorRepository +{ + public function all(Modifier ...$modifiers): Collection + { + $builder = $this->em + ->createQueryBuilder() + ->from(OperatorEntity::class, 'operator') + ->select('operator') + ; + + return $this->allFromQueryBuilder($builder, $modifiers, [ + 'alias' => 'operator', + 'entity' => OperatorEntity::class, + 'type' => Operator::class, + ]); + } +} diff --git a/src/Provider/Database/GenericScheduleRepository.php b/api/src/Provider/Database/GenericScheduleRepository.php similarity index 79% rename from src/Provider/Database/GenericScheduleRepository.php rename to api/src/Provider/Database/GenericScheduleRepository.php index 551c288..b3b5165 100644 --- a/src/Provider/Database/GenericScheduleRepository.php +++ b/api/src/Provider/Database/GenericScheduleRepository.php @@ -3,18 +3,15 @@ namespace App\Provider\Database; use App\Entity\StopEntity; -use App\Entity\StopInTrack; use App\Entity\TrackEntity; -use App\Entity\TripEntity; use App\Entity\TripStopEntity; use App\Model\Departure; -use App\Model\Line; +use App\Model\ScheduledStop; use App\Model\Stop; -use App\Model\Vehicle; +use App\Modifier\Modifier; use App\Provider\ScheduleRepository; use Carbon\Carbon; -use Tightenco\Collect\Support\Collection; -use function Kadet\Functional\ref; +use Illuminate\Support\Collection; class GenericScheduleRepository extends DatabaseRepository implements ScheduleRepository { @@ -70,4 +67,20 @@ class GenericScheduleRepository extends DatabaseRepository implements ScheduleRe ]); }); } + + public function all(Modifier ...$modifiers): Collection + { + $builder = $this->em + ->createQueryBuilder() + ->select('trip_stop') + ->from(TripStopEntity::class, 'trip_stop') + ->orderBy('trip_stop.departure', 'ASC') + ; + + return $this->allFromQueryBuilder($builder, $modifiers, [ + 'alias' => 'trip_stop', + 'type' => ScheduledStop::class, + 'entity' => TripStopEntity::class, + ]); + } } diff --git a/api/src/Provider/Database/GenericStopRepository.php b/api/src/Provider/Database/GenericStopRepository.php new file mode 100644 index 0000000..e609a6f --- /dev/null +++ b/api/src/Provider/Database/GenericStopRepository.php @@ -0,0 +1,41 @@ +<?php + +namespace App\Provider\Database; + +use App\Entity\StopEntity; +use App\Handler\Database\GenericWithDatabaseHandler; +use App\Handler\Database\WithDestinationsDatabaseHandler; +use App\Model\Stop; +use App\Modifier\Modifier; +use App\Modifier\With; +use App\Provider\StopRepository; +use Illuminate\Support\Collection; + +class GenericStopRepository extends DatabaseRepository implements StopRepository +{ + public function all(Modifier ...$modifiers): Collection + { + $builder = $this->em + ->createQueryBuilder() + ->from(StopEntity::class, 'stop') + ->select('stop') + ; + + return $this->allFromQueryBuilder($builder, $modifiers, [ + 'alias' => 'stop', + 'entity' => StopEntity::class, + 'type' => Stop::class, + ]); + } + + protected static function getHandlers() + { + return array_merge(parent::getHandlers(), [ + With::class => function (With $modifier) { + return $modifier->getRelationship() === 'destinations' + ? WithDestinationsDatabaseHandler::class + : GenericWithDatabaseHandler::class; + }, + ]); + } +} diff --git a/api/src/Provider/Database/GenericTrackRepository.php b/api/src/Provider/Database/GenericTrackRepository.php new file mode 100644 index 0000000..c877b75 --- /dev/null +++ b/api/src/Provider/Database/GenericTrackRepository.php @@ -0,0 +1,42 @@ +<?php + +namespace App\Provider\Database; + +use App\Entity\TrackEntity; +use App\Entity\TrackStopEntity; +use App\Model\Track; +use App\Model\TrackStop; +use App\Modifier\Modifier; +use App\Provider\TrackRepository; +use Illuminate\Support\Collection; + +class GenericTrackRepository extends DatabaseRepository implements TrackRepository +{ + public function stops(Modifier ...$modifiers): Collection + { + $builder = $this->em + ->createQueryBuilder() + ->from(TrackStopEntity::class, 'track_stop') + ->select(['track_stop']); + + return $this->allFromQueryBuilder($builder, $modifiers, [ + 'alias' => 'track_stop', + 'entity' => TrackStopEntity::class, + 'type' => TrackStop::class, + ]); + } + + public function all(Modifier ...$modifiers): Collection + { + $builder = $this->em + ->createQueryBuilder() + ->from(TrackEntity::class, 'track') + ->select('track'); + + return $this->allFromQueryBuilder($builder, $modifiers, [ + 'alias' => 'track', + 'entity' => TrackEntity::class, + 'type' => Track::class, + ]); + } +} diff --git a/api/src/Provider/Database/GenericTripRepository.php b/api/src/Provider/Database/GenericTripRepository.php new file mode 100644 index 0000000..1117329 --- /dev/null +++ b/api/src/Provider/Database/GenericTripRepository.php @@ -0,0 +1,26 @@ +<?php + +namespace App\Provider\Database; + +use App\Entity\TripEntity; +use App\Model\Trip; +use App\Modifier\Modifier; +use App\Provider\TripRepository; +use Illuminate\Support\Collection; + +class GenericTripRepository extends DatabaseRepository implements TripRepository +{ + public function all(Modifier ...$modifiers): Collection + { + $builder = $this->em + ->createQueryBuilder() + ->from(TripEntity::class, 'trip') + ->select('trip'); + + return $this->allFromQueryBuilder($builder, $modifiers, [ + 'alias' => 'trip', + 'entity' => TripEntity::class, + 'type' => Trip::class, + ]); + } +} diff --git a/api/src/Provider/DepartureRepository.php b/api/src/Provider/DepartureRepository.php new file mode 100644 index 0000000..89d66ef --- /dev/null +++ b/api/src/Provider/DepartureRepository.php @@ -0,0 +1,12 @@ +<?php + + +namespace App\Provider; + + +use App\Modifier\Modifier; + +interface DepartureRepository extends Repository +{ + public function current(iterable $stops, Modifier ...$modifiers); +} diff --git a/src/Provider/Dummy/DummyDepartureRepository.php b/api/src/Provider/Dummy/DummyDepartureRepository.php similarity index 59% rename from src/Provider/Dummy/DummyDepartureRepository.php rename to api/src/Provider/Dummy/DummyDepartureRepository.php index 5210943..fd6ebc0 100644 --- a/src/Provider/Dummy/DummyDepartureRepository.php +++ b/api/src/Provider/Dummy/DummyDepartureRepository.php @@ -4,12 +4,11 @@ namespace App\Provider\Dummy; use App\Model\Departure; use App\Model\Line; -use App\Model\Stop; use App\Model\Vehicle; +use App\Modifier\Modifier; use App\Provider\DepartureRepository; use App\Service\Proxy\ReferenceFactory; use Carbon\Carbon; -use Tightenco\Collect\Support\Collection; class DummyDepartureRepository implements DepartureRepository { @@ -25,21 +24,21 @@ class DummyDepartureRepository implements DepartureRepository $this->reference = $reference; } - public function getForStop(Stop $stop): Collection + public function current(iterable $stops, Modifier ...$modifiers) { return collect([ - [ 1, Line::TYPE_TRAM, 'lorem ipsum', 2137 ], - [ 1, Line::TYPE_TRAM, 'lorem ipsum', 2137 ], - [ 1, Line::TYPE_TRAM, 'lorem ipsum', 2137 ], - [ 1, Line::TYPE_TRAM, 'lorem ipsum', 2137 ], - [ 1, Line::TYPE_TRAM, 'lorem ipsum', 2137 ], - [ 1, Line::TYPE_TRAM, 'lorem ipsum', 2137 ], - [ 1, Line::TYPE_TRAM, 'lorem ipsum', 2137 ], - [ 1, Line::TYPE_TRAM, 'lorem ipsum', 2137 ], - [ 1, Line::TYPE_TRAM, 'lorem ipsum', 2137 ], - [ 1, Line::TYPE_TRAM, 'lorem ipsum', 2137 ], + [1, Line::TYPE_TRAM, 'lorem ipsum', 2137], + [1, Line::TYPE_TRAM, 'lorem ipsum', 2137], + [1, Line::TYPE_TRAM, 'lorem ipsum', 2137], + [1, Line::TYPE_TRAM, 'lorem ipsum', 2137], + [1, Line::TYPE_TRAM, 'lorem ipsum', 2137], + [1, Line::TYPE_TRAM, 'lorem ipsum', 2137], + [1, Line::TYPE_TRAM, 'lorem ipsum', 2137], + [1, Line::TYPE_TRAM, 'lorem ipsum', 2137], + [1, Line::TYPE_TRAM, 'lorem ipsum', 2137], + [1, Line::TYPE_TRAM, 'lorem ipsum', 2137], ])->map(function ($departure) use ($stop) { - list($symbol, $type, $display, $vehicle) = $departure; + [$symbol, $type, $display, $vehicle] = $departure; $scheduled = new Carbon(); $estimated = (clone $scheduled)->addSeconds(40); @@ -53,4 +52,4 @@ class DummyDepartureRepository implements DepartureRepository ]); }); } -} \ No newline at end of file +} diff --git a/src/Provider/Dummy/DummyMessageRepository.php b/api/src/Provider/Dummy/DummyMessageRepository.php similarity index 94% rename from src/Provider/Dummy/DummyMessageRepository.php rename to api/src/Provider/Dummy/DummyMessageRepository.php index 86ee2f0..8a0d0a7 100644 --- a/src/Provider/Dummy/DummyMessageRepository.php +++ b/api/src/Provider/Dummy/DummyMessageRepository.php @@ -6,7 +6,7 @@ use App\Model\Message; use App\Model\Stop; use App\Provider\MessageRepository; use Carbon\Carbon; -use Tightenco\Collect\Support\Collection; +use Illuminate\Support\Collection; class DummyMessageRepository implements MessageRepository { @@ -30,4 +30,4 @@ class DummyMessageRepository implements MessageRepository { return $this->getAll(); } -} \ No newline at end of file +} diff --git a/src/Provider/Dummy/DummyProvider.php b/api/src/Provider/Dummy/DummyProvider.php similarity index 93% rename from src/Provider/Dummy/DummyProvider.php rename to api/src/Provider/Dummy/DummyProvider.php index 722c03a..fa22c78 100644 --- a/src/Provider/Dummy/DummyProvider.php +++ b/api/src/Provider/Dummy/DummyProvider.php @@ -3,6 +3,7 @@ namespace App\Provider\Dummy; use App\Exception\NotSupportedException; +use App\Model\Location; use App\Provider\DepartureRepository; use App\Provider\LineRepository; use App\Provider\MessageRepository; @@ -78,6 +79,11 @@ class DummyProvider implements Provider return null; } + public function getLocation(): Location + { + return new Location(21.4474, 54.7837); + } + public function getTripRepository(): TripRepository { throw new NotSupportedException(); diff --git a/src/Provider/Dummy/DummyStopRepository.php b/api/src/Provider/Dummy/DummyStopRepository.php similarity index 75% rename from src/Provider/Dummy/DummyStopRepository.php rename to api/src/Provider/Dummy/DummyStopRepository.php index caea318..04cec66 100644 --- a/src/Provider/Dummy/DummyStopRepository.php +++ b/api/src/Provider/Dummy/DummyStopRepository.php @@ -3,9 +3,10 @@ namespace App\Provider\Dummy; use App\Model\Stop; +use App\Modifier\Modifier; use App\Provider\StopRepository; use App\Service\Proxy\ReferenceFactory; -use Tightenco\Collect\Support\Collection; +use Illuminate\Support\Collection; use Kadet\Functional as f; class DummyStopRepository implements StopRepository @@ -41,4 +42,14 @@ class DummyStopRepository implements StopRepository { return collect(); } + + public function first(Modifier ...$modifiers) + { + // TODO: Implement first() method. + } + + public function all(Modifier ...$modifiers): Collection + { + // TODO: Implement all() method. + } } diff --git a/api/src/Provider/FluentRepository.php b/api/src/Provider/FluentRepository.php new file mode 100644 index 0000000..dad83ea --- /dev/null +++ b/api/src/Provider/FluentRepository.php @@ -0,0 +1,12 @@ +<?php + +namespace App\Provider; + +use App\Modifier\Modifier; +use Illuminate\Support\Collection; + +interface FluentRepository extends Repository +{ + public function first(Modifier ...$modifiers); + public function all(Modifier ...$modifiers): Collection; +} diff --git a/api/src/Provider/LineRepository.php b/api/src/Provider/LineRepository.php new file mode 100644 index 0000000..2ab6884 --- /dev/null +++ b/api/src/Provider/LineRepository.php @@ -0,0 +1,8 @@ +<?php + + +namespace App\Provider; + +interface LineRepository extends FluentRepository +{ +} diff --git a/src/Provider/MessageRepository.php b/api/src/Provider/MessageRepository.php similarity index 80% rename from src/Provider/MessageRepository.php rename to api/src/Provider/MessageRepository.php index dd8fbba..2c8239b 100644 --- a/src/Provider/MessageRepository.php +++ b/api/src/Provider/MessageRepository.php @@ -5,10 +5,10 @@ namespace App\Provider; use App\Model\Stop; -use Tightenco\Collect\Support\Collection; +use Illuminate\Support\Collection; interface MessageRepository { public function getAll(): Collection; public function getForStop(Stop $stop): Collection; -} \ No newline at end of file +} diff --git a/api/src/Provider/OperatorRepository.php b/api/src/Provider/OperatorRepository.php new file mode 100644 index 0000000..bd6b21f --- /dev/null +++ b/api/src/Provider/OperatorRepository.php @@ -0,0 +1,9 @@ +<?php + + +namespace App\Provider; + + +interface OperatorRepository extends FluentRepository +{ +} diff --git a/src/Provider/Provider.php b/api/src/Provider/Provider.php similarity index 90% rename from src/Provider/Provider.php rename to api/src/Provider/Provider.php index d270290..482953a 100644 --- a/src/Provider/Provider.php +++ b/api/src/Provider/Provider.php @@ -2,6 +2,7 @@ namespace App\Provider; +use App\Model\Location; use Carbon\Carbon; interface Provider @@ -17,6 +18,7 @@ interface Provider public function getShortName(): string; public function getIdentifier(): string; public function getAttribution(): ?string; + public function getLocation(): Location; public function getLastUpdate(): ?Carbon; } diff --git a/src/Provider/Repository.php b/api/src/Provider/Repository.php similarity index 96% rename from src/Provider/Repository.php rename to api/src/Provider/Repository.php index 008cc99..75b1ed1 100644 --- a/src/Provider/Repository.php +++ b/api/src/Provider/Repository.php @@ -6,5 +6,4 @@ namespace App\Provider; interface Repository { - -} \ No newline at end of file +} diff --git a/src/Provider/ScheduleRepository.php b/api/src/Provider/ScheduleRepository.php similarity index 76% rename from src/Provider/ScheduleRepository.php rename to api/src/Provider/ScheduleRepository.php index 951a20f..ba5376e 100644 --- a/src/Provider/ScheduleRepository.php +++ b/api/src/Provider/ScheduleRepository.php @@ -4,9 +4,9 @@ namespace App\Provider; use App\Model\Stop; use Carbon\Carbon; -use Tightenco\Collect\Support\Collection; +use Illuminate\Support\Collection; -interface ScheduleRepository +interface ScheduleRepository extends FluentRepository { const DEFAULT_DEPARTURES_COUNT = 16; diff --git a/api/src/Provider/StopRepository.php b/api/src/Provider/StopRepository.php new file mode 100644 index 0000000..0c8e5e5 --- /dev/null +++ b/api/src/Provider/StopRepository.php @@ -0,0 +1,9 @@ +<?php + + +namespace App\Provider; + + +interface StopRepository extends FluentRepository +{ +} diff --git a/api/src/Provider/TrackRepository.php b/api/src/Provider/TrackRepository.php new file mode 100644 index 0000000..dbf4ac7 --- /dev/null +++ b/api/src/Provider/TrackRepository.php @@ -0,0 +1,11 @@ +<?php + +namespace App\Provider; + +use App\Modifier\Modifier; +use Illuminate\Support\Collection; + +interface TrackRepository extends FluentRepository +{ + public function stops(Modifier ...$modifiers): Collection; +} diff --git a/api/src/Provider/TripRepository.php b/api/src/Provider/TripRepository.php new file mode 100644 index 0000000..17459d8 --- /dev/null +++ b/api/src/Provider/TripRepository.php @@ -0,0 +1,9 @@ +<?php + +namespace App\Provider; + +use App\Model\Trip; + +interface TripRepository extends FluentRepository +{ +} diff --git a/src/Provider/ZtmGdansk/ZtmGdanskDataUpdateSubscriber.php b/api/src/Provider/ZtmGdansk/ZtmGdanskDataUpdateSubscriber.php similarity index 98% rename from src/Provider/ZtmGdansk/ZtmGdanskDataUpdateSubscriber.php rename to api/src/Provider/ZtmGdansk/ZtmGdanskDataUpdateSubscriber.php index 146ef55..fbf0129 100644 --- a/src/Provider/ZtmGdansk/ZtmGdanskDataUpdateSubscriber.php +++ b/api/src/Provider/ZtmGdansk/ZtmGdanskDataUpdateSubscriber.php @@ -6,8 +6,8 @@ use App\Entity\LineEntity; use App\Entity\OperatorEntity; use App\Entity\ProviderEntity; use App\Entity\StopEntity; -use App\Entity\StopInTrack; use App\Entity\TrackEntity; +use App\Entity\TrackStopEntity; use App\Entity\TripEntity; use App\Entity\TripStopEntity; use App\Event\DataUpdateEvent; @@ -17,10 +17,10 @@ use App\Service\IdUtils; use Carbon\Carbon; use Cerbero\JsonObjects\JsonObjects; use Doctrine\ORM\EntityManagerInterface; -use Symfony\Component\Console\Helper\ProgressBar; +use Illuminate\Support\Collection; use Psr\Log\LoggerInterface; +use Symfony\Component\Console\Helper\ProgressBar; use Symfony\Component\EventDispatcher\EventSubscriberInterface; -use Tightenco\Collect\Support\Collection; use function Kadet\Functional\ref; use function Kadet\Functional\Transforms\property; @@ -216,7 +216,7 @@ class ZtmGdanskDataUpdateSubscriber implements EventSubscriberInterface return !in_array($stop['stopId'], $this->stopBlacklist); }) ->map(function ($stop) use ($entity, $provider) { - return StopInTrack::createFromArray([ + return TrackStopEntity::createFromArray([ 'stop' => $this->em->getReference( StopEntity::class, $this->ids->generate($provider, $stop['stopId']) diff --git a/api/src/Provider/ZtmGdansk/ZtmGdanskDepartureRepository.php b/api/src/Provider/ZtmGdansk/ZtmGdanskDepartureRepository.php new file mode 100644 index 0000000..a7a8fcd --- /dev/null +++ b/api/src/Provider/ZtmGdansk/ZtmGdanskDepartureRepository.php @@ -0,0 +1,224 @@ +<?php + +namespace App\Provider\ZtmGdansk; + +use App\Model\Departure; +use App\Model\Line; +use App\Model\ScheduledStop; +use App\Model\Stop; +use App\Model\Vehicle; +use App\Modifier\FieldFilter; +use App\Modifier\IdFilter; +use App\Modifier\Limit; +use App\Modifier\Modifier; +use App\Modifier\RelatedFilter; +use App\Modifier\With; +use App\Provider\DepartureRepository; +use App\Provider\LineRepository; +use App\Provider\ScheduleRepository; +use App\Service\IterableUtils; +use App\Service\ModifierUtils; +use App\Service\Proxy\ReferenceFactory; +use Carbon\Carbon; +use Illuminate\Support\Collection; +use Kadet\Functional\Transforms as t; +use function App\Functions\setup; +use function Kadet\Functional\ref; + +class ZtmGdanskDepartureRepository implements DepartureRepository +{ + const ESTIMATES_URL = 'http://ckan2.multimediagdansk.pl/delays'; + + /** @var LineRepository */ + private $lines; + + /** @var ReferenceFactory */ + private $reference; + + /** @var ScheduleRepository */ + private $schedule; + + /** + * @param LineRepository $lines + */ + public function __construct(LineRepository $lines, ScheduleRepository $schedule, ReferenceFactory $reference) + { + $this->lines = $lines; + $this->reference = $reference; + $this->schedule = $schedule; + } + + public function current(iterable $stops, Modifier ...$modifiers) + { + $real = IterableUtils::toCollection($stops) + ->flatMap(ref([$this, 'getRealDepartures'])) + ->sortBy(t\property('estimated')) + ; + + $now = Carbon::now()->second(0); + $first = $real->map(t\getter('scheduled'))->min() ?? $now; + $scheduled = $this->getScheduledDepartures($stops, $first, ...$this->extractModifiers($modifiers)); + + $result = $this->pair($scheduled, $real)->filter(function (Departure $departure) use ($now) { + return $departure->getDeparture() > $now; + }); + + return $this->processResultWithModifiers($result, $modifiers); + } + + private function getRealDepartures(Stop $stop) + { + try { + $estimates = file_get_contents(static::ESTIMATES_URL . "?stopId=" . $stop->getId()); + $estimates = json_decode($estimates, true)['delay']; + } catch (\Error $e) { + return collect(); + } + + $estimates = collect($estimates); + + $lines = $estimates->map(function ($delay) { + return $delay['routeId']; + })->unique(); + + $lines = $this->lines->all(new IdFilter($lines))->keyBy(t\property('id')); + + return collect($estimates)->map(function ($delay) use ($stop, $lines) { + $scheduled = (new Carbon($delay['theoreticalTime'], 'Europe/Warsaw'))->tz('UTC'); + $estimated = (clone $scheduled)->addSeconds($delay['delayInSeconds']); + + return Departure::createFromArray([ + 'key' => sprintf('%s::%s', $delay['routeId'], $scheduled->format('H:i')), + 'scheduled' => $scheduled, + 'estimated' => $estimated, + 'stop' => $stop, + 'display' => trim($delay['headsign']), + 'vehicle' => $this->reference->get(Vehicle::class, $delay['vehicleCode']), + 'line' => $lines->get($delay['routeId']) ?: Line::createFromArray([ + 'symbol' => $delay['routeId'], + 'type' => Line::TYPE_UNKNOWN, + ]), + ]); + })->values(); + } + + private function getScheduledDepartures($stop, Carbon $time, Modifier ...$modifiers) + { + return $this->schedule->all( + new RelatedFilter($stop, Stop::class), + new FieldFilter('departure', $time, '>='), + new With('track'), + new With('destination'), + ...$modifiers + ); + } + + private function pair(Collection $schedule, Collection $real) + { + $key = function ($departure) { + if ($departure instanceof Departure) { + return sprintf( + "%s::%s", + $departure->getLine()->getId(), + $departure->getScheduled()->format("H:i") + ); + } elseif ($departure instanceof ScheduledStop) { + return sprintf( + "%s::%s", + $departure->getTrack()->getLine()->getId(), + $departure->getDeparture()->format("H:i") + ); + } else { + throw new \Exception(); + } + }; + + $schedule = $schedule->keyBy($key)->all(); + $real = $real->keyBy($key); + + return $real->map(function (Departure $real, $key) use (&$schedule) { + $scheduled = null; + + if (array_key_exists($key, $schedule)) { + $scheduled = $schedule[$key]; + unset($schedule[$key]); + } + + return [ + 'estimated' => $real, + 'scheduled' => $scheduled, + ]; + })->merge(collect($schedule)->map(function (ScheduledStop $scheduled) { + return [ + 'estimated' => null, + 'scheduled' => $scheduled, + ]; + }))->map(function ($pair) { + return $this->merge($pair['estimated'], $pair['scheduled']); + })->sortBy(function (Departure $departure) { + $time = $departure->getEstimated() ?? $departure->getScheduled(); + return $time->getTimestamp(); + }); + } + + private function merge(?Departure $real, ?ScheduledStop $scheduled) + { + if (!$real) { + return $this->convertScheduledStopToDeparture($scheduled); + } + + if (!$scheduled) { + return $real; + } + + return setup(clone $real, function (Departure $departure) use ($scheduled, $real) { + $departure->setDisplay($this->extractDisplayFromScheduledStop($scheduled)); + $departure->setTrack($scheduled->getTrack()); + $departure->setTrip($scheduled->getTrip()); + }); + } + + private function convertScheduledStopToDeparture(ScheduledStop $stop): Departure + { + return setup(new Departure(), function (Departure $converted) use ($stop) { + $converted->setDisplay($this->extractDisplayFromScheduledStop($stop)); + $converted->setLine($stop->getTrack()->getLine()); + $converted->setTrack($stop->getTrack()); + $converted->setTrip($stop->getTrip()); + $converted->setScheduled($stop->getDeparture()); + $converted->setStop($stop->getStop()); + }); + } + + private function extractDisplayFromScheduledStop(ScheduledStop $stop) + { + return $stop->getTrack()->getDestination()->getName(); + } + + private function extractModifiers(iterable $modifiers) + { + $result = []; + + /** @var Limit $limit */ + if ($limit = ModifierUtils::getOfType($modifiers, Limit::class)) { + $result[] = new Limit($limit->getOffset(), $limit->getCount() * 2); + } else { + $result[] = Limit::count(16); + } + + return $result; + } + + private function processResultWithModifiers(Collection $result, iterable $modifiers) + { + foreach ($modifiers as $modifier) { + switch (true) { + case $modifier instanceof Limit: + $result = $result->slice($modifier->getOffset(), $modifier->getCount()); + break; + } + } + + return $result; + } +} diff --git a/src/Provider/ZtmGdansk/ZtmGdanskMessageRepository.php b/api/src/Provider/ZtmGdansk/ZtmGdanskMessageRepository.php similarity index 94% rename from src/Provider/ZtmGdansk/ZtmGdanskMessageRepository.php rename to api/src/Provider/ZtmGdansk/ZtmGdanskMessageRepository.php index d87b5f7..b79f2d8 100644 --- a/src/Provider/ZtmGdansk/ZtmGdanskMessageRepository.php +++ b/api/src/Provider/ZtmGdansk/ZtmGdanskMessageRepository.php @@ -7,11 +7,9 @@ namespace App\Provider\ZtmGdansk; use App\Model\Message; use App\Model\Stop; use App\Provider\MessageRepository; -use App\Provider\ZtmGdansk\ZtmGdanskProvider; -use App\Service\IdUtils; use Carbon\Carbon; +use Illuminate\Support\Collection; use Symfony\Component\Cache\Adapter\AdapterInterface; -use Tightenco\Collect\Support\Collection; class ZtmGdanskMessageRepository implements MessageRepository { @@ -69,4 +67,4 @@ class ZtmGdanskMessageRepository implements MessageRepository return $item->get(); } -} \ No newline at end of file +} diff --git a/src/Provider/ZtmGdansk/ZtmGdanskMessageTypeClassifier.php b/api/src/Provider/ZtmGdansk/ZtmGdanskMessageTypeClassifier.php similarity index 100% rename from src/Provider/ZtmGdansk/ZtmGdanskMessageTypeClassifier.php rename to api/src/Provider/ZtmGdansk/ZtmGdanskMessageTypeClassifier.php diff --git a/src/Provider/ZtmGdansk/ZtmGdanskProvider.php b/api/src/Provider/ZtmGdansk/ZtmGdanskProvider.php similarity index 85% rename from src/Provider/ZtmGdansk/ZtmGdanskProvider.php rename to api/src/Provider/ZtmGdansk/ZtmGdanskProvider.php index 26b2cbb..35035ea 100644 --- a/src/Provider/ZtmGdansk/ZtmGdanskProvider.php +++ b/api/src/Provider/ZtmGdansk/ZtmGdanskProvider.php @@ -4,6 +4,7 @@ namespace App\Provider\ZtmGdansk; use App\Entity\ProviderEntity; +use App\Model\Location; use App\Provider\Database\GenericLineRepository; use App\Provider\Database\GenericScheduleRepository; use App\Provider\Database\GenericStopRepository; @@ -13,11 +14,9 @@ use App\Provider\DepartureRepository; use App\Provider\LineRepository; use App\Provider\MessageRepository; use App\Provider\Provider; -use App\Provider\ScheduleRepository; use App\Provider\StopRepository; use App\Provider\TrackRepository; use App\Provider\TripRepository; -use App\Provider\ZtmGdansk\{ZtmGdanskDepartureRepository, ZtmGdanskMessageRepository}; use App\Service\Proxy\ReferenceFactory; use Carbon\Carbon; use Doctrine\ORM\EntityManagerInterface; @@ -29,11 +28,11 @@ class ZtmGdanskProvider implements Provider private $stops; private $tracks; private $messages; - - /** @var ProviderEntity */ - private $entity; private $trips; + private ProviderEntity $entity; + private EntityManagerInterface $em; + public function getName(): string { return 'MZKZG - Trójmiasto'; @@ -54,6 +53,11 @@ class ZtmGdanskProvider implements Provider return '<a href="http://ztm.gda.pl/otwarty_ztm">Otwarte Dane</a> Zarządu Transportu Miejskiego w Gdańsku'; } + public function getLocation(): Location + { + return new Location(18.6466, 54.3520); + } + public function __construct( EntityManagerInterface $em, GenericLineRepository $lines, @@ -64,7 +68,9 @@ class ZtmGdanskProvider implements Provider ZtmGdanskMessageRepository $messages, ReferenceFactory $referenceFactory ) { - $provider = $em->getReference(ProviderEntity::class, $this->getIdentifier()); + $this->em = $em; + + $provider = $this->refreshProviderEntity(); $lines = $lines->withProvider($provider); $stops = $stops->withProvider($provider); @@ -113,6 +119,13 @@ class ZtmGdanskProvider implements Provider public function getLastUpdate(): ?Carbon { + $this->refreshProviderEntity(); + return $this->entity->getUpdateDate(); } + + private function refreshProviderEntity(): ProviderEntity + { + return $this->entity = $this->em->getReference(ProviderEntity::class, $this->getIdentifier()); + } } diff --git a/src/Serialization/CarbonHandler.php b/api/src/Serialization/CarbonHandler.php similarity index 98% rename from src/Serialization/CarbonHandler.php rename to api/src/Serialization/CarbonHandler.php index 84c48dd..1f47f75 100644 --- a/src/Serialization/CarbonHandler.php +++ b/api/src/Serialization/CarbonHandler.php @@ -5,6 +5,7 @@ declare(strict_types=1); namespace App\Serialization; use Carbon\Carbon; +use Illuminate\Support\Collection; use JMS\Serializer\DeserializationContext; use JMS\Serializer\GraphNavigatorInterface; use JMS\Serializer\Handler\DateHandler; @@ -12,7 +13,6 @@ use JMS\Serializer\Handler\SubscribingHandlerInterface; use JMS\Serializer\SerializationContext; use JMS\Serializer\Visitor\DeserializationVisitorInterface; use JMS\Serializer\Visitor\SerializationVisitorInterface; -use Tightenco\Collect\Support\Collection; /** * Class LaravelCollectionHandler diff --git a/src/Serialization/LaravelCollectionHandler.php b/api/src/Serialization/LaravelCollectionHandler.php similarity index 98% rename from src/Serialization/LaravelCollectionHandler.php rename to api/src/Serialization/LaravelCollectionHandler.php index dd97dd6..2cc2ff9 100644 --- a/src/Serialization/LaravelCollectionHandler.php +++ b/api/src/Serialization/LaravelCollectionHandler.php @@ -4,13 +4,13 @@ declare(strict_types=1); namespace App\Serialization; +use Illuminate\Support\Collection; use JMS\Serializer\DeserializationContext; use JMS\Serializer\GraphNavigatorInterface; use JMS\Serializer\Handler\SubscribingHandlerInterface; use JMS\Serializer\SerializationContext; use JMS\Serializer\Visitor\DeserializationVisitorInterface; use JMS\Serializer\Visitor\SerializationVisitorInterface; -use Tightenco\Collect\Support\Collection; /** * Class LaravelCollectionHandler @@ -84,4 +84,4 @@ final class LaravelCollectionHandler implements SubscribingHandlerInterface return new Collection($visitor->visitArray($data, $type)); } -} \ No newline at end of file +} diff --git a/src/Serialization/SerializeAs.php b/api/src/Serialization/SerializeAs.php similarity index 100% rename from src/Serialization/SerializeAs.php rename to api/src/Serialization/SerializeAs.php diff --git a/api/src/Service/AggregateConverter.php b/api/src/Service/AggregateConverter.php new file mode 100644 index 0000000..f56b1ed --- /dev/null +++ b/api/src/Service/AggregateConverter.php @@ -0,0 +1,84 @@ +<?php + +namespace App\Service; + +use Illuminate\Support\Collection; +use function Kadet\Functional\Predicates\instance; + +class AggregateConverter implements Converter, CacheableConverter +{ + private $converters; + private $cachedConverters; + + public function __construct(iterable $converters) + { + $this->converters = $converters; + } + + public function convert($entity) + { + $this->ensureCachedConverters(); + + /** @var Converter $converter */ + $converter = $this->cachedConverters->first(function (Converter $converter) use ($entity) { + return $converter->supports($entity); + }); + + if ($converter == null) { + throw new \InvalidArgumentException(sprintf('Cannot convert entity of type %s.', is_object($entity) ? get_class($entity) : gettype($entity))); + } + + return $converter->convert($entity); + } + + public function supports($entity) + { + return $this->converters->some(function (Converter $converter) use ($entity) { + return $converter->supports($entity); + }); + } + + public function getConverters(): Collection + { + $this->ensureCachedConverters(); + + return clone $this->cachedConverters; + } + + public function reset() + { + $this->ensureCachedConverters(); + + $this + ->cachedConverters + ->filter(instance(CacheableConverter::class)) + ->each(function (CacheableConverter $converter) { + $converter->reset(); + }) + ; + } + + public function __clone() + { + $this->ensureCachedConverters(); + + $this->cachedConverters = $this->cachedConverters->map(function ($object) { + return clone $object; + }); + } + + private function ensureCachedConverters() + { + if (!$this->cachedConverters) { + $this->cachedConverters = collect($this->converters) + ->filter(function (Converter $converter) { + return $converter !== $this && !$converter instanceof AggregateConverter; + }) + ->each(function (Converter $converter) { + if ($converter instanceof RecursiveConverter) { + $converter->setParent($this); + } + }); + } + } +} diff --git a/api/src/Service/CacheableConverter.php b/api/src/Service/CacheableConverter.php new file mode 100644 index 0000000..e67996c --- /dev/null +++ b/api/src/Service/CacheableConverter.php @@ -0,0 +1,9 @@ +<?php + +namespace App\Service; + +use Symfony\Contracts\Service\ResetInterface; + +interface CacheableConverter extends Converter, ResetInterface +{ +} diff --git a/src/Service/Converter.php b/api/src/Service/Converter.php similarity index 100% rename from src/Service/Converter.php rename to api/src/Service/Converter.php diff --git a/src/Service/DataUpdater.php b/api/src/Service/DataUpdater.php similarity index 77% rename from src/Service/DataUpdater.php rename to api/src/Service/DataUpdater.php index a31bba0..1839b92 100644 --- a/src/Service/DataUpdater.php +++ b/api/src/Service/DataUpdater.php @@ -5,6 +5,7 @@ namespace App\Service; use App\Event\DataUpdateEvent; use Doctrine\DBAL\Schema\Table; use Doctrine\ORM\EntityManagerInterface; +use Kadet\Functional as f; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; @@ -18,11 +19,6 @@ class DataUpdater /** @var EntityManagerInterface */ private $em; - /** - * DataUpdater constructor. - * - * @param EventDispatcherInterface $dispatcher - */ public function __construct(EventDispatcherInterface $dispatcher, EntityManagerInterface $em) { $this->dispatcher = $dispatcher; @@ -41,11 +37,13 @@ class DataUpdater copy($path, $backup); try { - collect($schema->listTables())->reject(function (Table $schema) { - return $schema->getName() === 'migration_versions'; - })->each([$schema, 'dropAndCreateTable']); + collect($schema->listTables()) + ->reject(f\ref([$this, 'shouldTableBePreserved'])) + ->each(f\ref([$schema, 'dropAndCreateTable'])) + ; $this->dispatcher->dispatch(new DataUpdateEvent($output), DataUpdateEvent::NAME); + unlink($backup); } catch (\Throwable $exception) { $connection->close(); @@ -56,4 +54,9 @@ class DataUpdater throw $exception; } } + + private function shouldTableBePreserved(Table $schema) + { + return in_array($schema->getName(), ['migration_versions', 'messenger_messages']); + } } diff --git a/src/Service/EntityConverter.php b/api/src/Service/EntityConverter.php similarity index 87% rename from src/Service/EntityConverter.php rename to api/src/Service/EntityConverter.php index 222a7c8..75e265a 100644 --- a/src/Service/EntityConverter.php +++ b/api/src/Service/EntityConverter.php @@ -2,26 +2,26 @@ namespace App\Service; -use App\Entity\{Entity, LineEntity, OperatorEntity, StopEntity, TrackEntity, TripEntity, TripStopEntity}; +use App\Entity\{Entity, LineEntity, OperatorEntity, StopEntity, TrackEntity, TripEntity}; use App\Model\{Line, Location, Operator, ScheduledStop, Stop, Track, Trip}; use App\Service\Proxy\ReferenceFactory; use Doctrine\ORM\PersistentCollection; use Doctrine\ORM\Proxy\Proxy; -use Kadet\Functional as f; use Kadet\Functional\Transforms as t; -use const Kadet\Functional\_; -final class EntityConverter implements Converter, RecursiveConverter +final class EntityConverter implements Converter, RecursiveConverter, CacheableConverter { use RecursiveConverterTrait; private $id; private $reference; + private $cache; public function __construct(IdUtils $id, ReferenceFactory $reference) { $this->id = $id; $this->reference = $reference; + $this->cache = []; } /** @@ -30,21 +30,22 @@ final class EntityConverter implements Converter, RecursiveConverter * * @return Line|Track|Stop|Operator|Trip|ScheduledStop */ - public function convert($entity, array $cache = []) + public function convert($entity) { - if (array_key_exists($key = get_class($entity).':'.$this->getId($entity), $cache)) { - return $cache[$key]; + if (array_key_exists($key = get_class($entity) . ':' . $this->getId($entity), $this->cache)) { + return $this->cache[$key]; } if ($entity instanceof Proxy && !$entity->__isInitialized()) { return $this->reference($entity); } - $result = $this->create($entity); - $cache = $cache + [$key => $result]; - $convert = function ($entity) use ($cache) { + $result = $this->create($entity); + $this->cache[$key] = $result; + + $convert = function ($entity) { return $this->supports($entity) - ? $this->convert($entity, $cache) + ? $this->convert($entity) : $this->parent->convert($entity); }; @@ -78,6 +79,7 @@ final class EntityConverter implements Converter, RecursiveConverter ->map(t\property('stop')) ->map($convert), 'line' => $convert($entity->getLine()), + 'destination' => $convert($entity->getFinal()->getStop()), ]); break; @@ -154,7 +156,7 @@ final class EntityConverter implements Converter, RecursiveConverter private function create(Entity $entity) { - $id = $this->id->of($entity); + $id = $this->id->of($entity); $class = $this->getModelClassForEntity($entity); return $class::createFromArray(['id' => $id]); @@ -162,7 +164,7 @@ final class EntityConverter implements Converter, RecursiveConverter private function reference(Entity $entity) { - $id = $this->id->strip($this->getId($entity)); + $id = $this->id->strip($this->getId($entity)); $class = $this->getModelClassForEntity($entity); return $this->reference->get($class, ['id' => $id]); @@ -172,4 +174,9 @@ final class EntityConverter implements Converter, RecursiveConverter { return $entity instanceof Entity; } + + public function reset() + { + $this->cache = []; + } } diff --git a/api/src/Service/EntityReferenceFactory.php b/api/src/Service/EntityReferenceFactory.php new file mode 100644 index 0000000..6a3f072 --- /dev/null +++ b/api/src/Service/EntityReferenceFactory.php @@ -0,0 +1,68 @@ +<?php + +namespace App\Service; + +use App\Entity\LineEntity; +use App\Entity\ProviderEntity; +use App\Entity\StopEntity; +use App\Entity\TrackEntity; +use App\Exception\InvalidArgumentException; +use App\Model\Line; +use App\Model\Referable; +use App\Model\Stop; +use App\Model\Track; +use Doctrine\ORM\EntityManagerInterface; +use Illuminate\Support\Collection; +use function Kadet\Functional\partial; +use function Kadet\Functional\ref; +use const Kadet\Functional\_; + +final class EntityReferenceFactory +{ + protected $mapping = [ + Line::class => LineEntity::class, + Stop::class => StopEntity::class, + Track::class => TrackEntity::class, + ]; + + private $em; + private $id; + + public function __construct(EntityManagerInterface $em, IdUtils $id) + { + $this->em = $em; + $this->id = $id; + } + + public function create($object, ProviderEntity $provider) + { + switch (true) { + case $object instanceof Referable: + return $this->createEntityReference($object, $provider); + case is_array($object): + return array_map(partial(ref([$this, 'createEntityReference']), _, $provider), $object); + case $object instanceof Collection: + return $object->map(partial(ref([$this, 'createEntityReference']), _, $provider)); + default: + throw InvalidArgumentException::invalidType( + 'object', + $object, + [Referable::class, Collection::class, 'array'] + ); + } + } + + private function createEntityReference(Referable $object, ProviderEntity $provider) + { + $class = get_class($object); + + if (!array_key_exists($class, $this->mapping)) { + throw new \InvalidArgumentException(sprintf("Cannot make entity reference of %s.", $class)); + } + + return $this->em->getReference( + $this->mapping[$class], + $this->id->generate($provider, $object->getId()) + ); + } +} diff --git a/api/src/Service/HandlerProvider.php b/api/src/Service/HandlerProvider.php new file mode 100644 index 0000000..59d5edb --- /dev/null +++ b/api/src/Service/HandlerProvider.php @@ -0,0 +1,44 @@ +<?php + +namespace App\Service; + +use App\Exception\UnsupportedModifierException; +use App\Modifier\Modifier; +use Symfony\Component\DependencyInjection\ServiceLocator; + +class HandlerProvider +{ + private $configuration = []; + private $handlerLocator; + + public function __construct(ServiceLocator $handlerLocator) + { + $this->handlerLocator = $handlerLocator; + } + + public function loadConfiguration(array $providers) + { + $this->configuration = $providers; + } + + public function get(Modifier $modifier) + { + $class = get_class($modifier); + + if (!array_key_exists($class, $this->configuration)) { + throw UnsupportedModifierException::createFromModifier($modifier); + } + + $handler = $this->configuration[$class]; + + if (is_callable($handler)) { + $handler = $handler($modifier); + } + + if (is_string($handler)) { + return $this->handlerLocator->get($handler); + } + + return $handler; + } +} diff --git a/src/Service/IdUtils.php b/api/src/Service/IdUtils.php similarity index 89% rename from src/Service/IdUtils.php rename to api/src/Service/IdUtils.php index 61bc00b..e652ad4 100644 --- a/src/Service/IdUtils.php +++ b/api/src/Service/IdUtils.php @@ -11,6 +11,7 @@ class IdUtils public function generate(ProviderEntity $provider, $id) { + // todo: use array cache if not fast enough return sprintf('%s%s%s', $provider->getId(), self::DELIMITER, $id); } @@ -23,4 +24,4 @@ class IdUtils { return $this->strip($entity->getId()); } -} \ No newline at end of file +} diff --git a/src/Service/IterableUtils.php b/api/src/Service/IterableUtils.php similarity index 93% rename from src/Service/IterableUtils.php rename to api/src/Service/IterableUtils.php index 5018060..883cf62 100644 --- a/src/Service/IterableUtils.php +++ b/api/src/Service/IterableUtils.php @@ -3,7 +3,7 @@ namespace App\Service; use Doctrine\Common\Collections\ArrayCollection; -use Tightenco\Collect\Support\Collection; +use Illuminate\Support\Collection; final class IterableUtils { diff --git a/api/src/Service/ModifierUtils.php b/api/src/Service/ModifierUtils.php new file mode 100644 index 0000000..69f0fb4 --- /dev/null +++ b/api/src/Service/ModifierUtils.php @@ -0,0 +1,29 @@ +<?php + +namespace App\Service; + +use Kadet\Functional\Predicate; +use function Kadet\Functional\Predicates\instance; + +final class ModifierUtils +{ + public static function get(iterable $modifiers, Predicate $predicate) + { + return collect($modifiers)->first($predicate); + } + + public static function getOfType(iterable $modifiers, $class) + { + return self::get($modifiers, instance($class)); + } + + public static function hasAny(iterable $modifiers, Predicate $predicate) + { + return collect($modifiers)->contains($predicate); + } + + public static function hasAnyOfType(iterable $modifiers, $class) + { + return collect($modifiers)->contains(instance($class)); + } +} diff --git a/src/Service/Normalizer/JustReferenceNormalizer.php b/api/src/Service/Normalizer/JustReferenceNormalizer.php similarity index 100% rename from src/Service/Normalizer/JustReferenceNormalizer.php rename to api/src/Service/Normalizer/JustReferenceNormalizer.php diff --git a/src/Service/Normalizer/StopNormalizer.php b/api/src/Service/Normalizer/StopNormalizer.php similarity index 100% rename from src/Service/Normalizer/StopNormalizer.php rename to api/src/Service/Normalizer/StopNormalizer.php diff --git a/api/src/Service/ProviderConverter.php b/api/src/Service/ProviderConverter.php new file mode 100644 index 0000000..1cc7c7f --- /dev/null +++ b/api/src/Service/ProviderConverter.php @@ -0,0 +1,29 @@ +<?php + +namespace App\Service; + +use App\Model\Provider as ProviderDTO; +use App\Provider\Provider; + +class ProviderConverter implements Converter +{ + public function convert($entity) + { + /** @var Provider $entity */ + + return ProviderDTO::createFromArray([ + 'id' => $entity->getIdentifier(), + 'shortName' => $entity->getShortName(), + 'name' => $entity->getName(), + 'attribution' => $entity->getAttribution(), + 'lastUpdate' => $entity->getLastUpdate() ? clone $entity->getLastUpdate() : null, + 'location' => $entity->getLocation(), + ]); + } + + public function supports($entity) + { + return $entity instanceof Provider; + } +} + diff --git a/src/Service/ProviderParameterConverter.php b/api/src/Service/ProviderParameterConverter.php similarity index 100% rename from src/Service/ProviderParameterConverter.php rename to api/src/Service/ProviderParameterConverter.php diff --git a/src/Service/ProviderResolver.php b/api/src/Service/ProviderResolver.php similarity index 69% rename from src/Service/ProviderResolver.php rename to api/src/Service/ProviderResolver.php index 85e2758..a23e2b8 100644 --- a/src/Service/ProviderResolver.php +++ b/api/src/Service/ProviderResolver.php @@ -6,9 +6,9 @@ namespace App\Service; use App\Exception\NonExistentServiceException; use App\Provider\Dummy\DummyProvider; use App\Provider\Provider; -use Kadet\Functional\Transforms as t; +use Illuminate\Support\Collection; use Kadet\Functional\Predicates as p; -use Tightenco\Collect\Support\Collection; +use Kadet\Functional\Transforms as t; class ProviderResolver { @@ -23,16 +23,19 @@ class ProviderResolver } } - /**\ - * @param string $name - * - * @return \App\Provider\Provider - * @throws \App\Exception\NonExistentServiceException - */ - public function resolve(string $name): Provider + public function resolve(?string $name): ?Provider { + if (empty($name)) { + return null; + } + if (!$this->providers->has($name)) { - $message = sprintf("Provider '%s' doesn't exist, you can choose from: %s", $name, $this->providers->keys()->implode(', ')); + $message = sprintf( + "Provider '%s' doesn't exist, you can choose from: %s", + $name, + $this->providers->keys()->implode(', ') + ); + throw new NonExistentServiceException($message); } @@ -44,4 +47,4 @@ class ProviderResolver { return clone $this->providers; } -} \ No newline at end of file +} diff --git a/api/src/Service/Proxy/FileLocator.php b/api/src/Service/Proxy/FileLocator.php new file mode 100644 index 0000000..0d34263 --- /dev/null +++ b/api/src/Service/Proxy/FileLocator.php @@ -0,0 +1,17 @@ +<?php + +namespace App\Service\Proxy; + +final class FileLocator extends \ProxyManager\FileLocator\FileLocator +{ + public function __construct(string $proxiesDirectory) + { + $absolutePath = realpath($proxiesDirectory); + + if ($absolutePath === false) { + mkdir($proxiesDirectory, 0755, true); + } + + parent::__construct($proxiesDirectory); + } +} diff --git a/src/Service/Proxy/ReferenceFactory.php b/api/src/Service/Proxy/ReferenceFactory.php similarity index 100% rename from src/Service/Proxy/ReferenceFactory.php rename to api/src/Service/Proxy/ReferenceFactory.php diff --git a/src/Service/Proxy/ReferenceObjectGenerator.php b/api/src/Service/Proxy/ReferenceObjectGenerator.php similarity index 100% rename from src/Service/Proxy/ReferenceObjectGenerator.php rename to api/src/Service/Proxy/ReferenceObjectGenerator.php diff --git a/src/Service/RecursiveConverter.php b/api/src/Service/RecursiveConverter.php similarity index 100% rename from src/Service/RecursiveConverter.php rename to api/src/Service/RecursiveConverter.php diff --git a/src/Service/RecursiveConverterTrait.php b/api/src/Service/RecursiveConverterTrait.php similarity index 100% rename from src/Service/RecursiveConverterTrait.php rename to api/src/Service/RecursiveConverterTrait.php diff --git a/src/Service/RepositoryParameterConverter.php b/api/src/Service/RepositoryParameterConverter.php similarity index 100% rename from src/Service/RepositoryParameterConverter.php rename to api/src/Service/RepositoryParameterConverter.php diff --git a/api/src/Service/ScheduledStopConverter.php b/api/src/Service/ScheduledStopConverter.php new file mode 100644 index 0000000..d4cfc97 --- /dev/null +++ b/api/src/Service/ScheduledStopConverter.php @@ -0,0 +1,41 @@ +<?php + +namespace App\Service; + +use App\Entity\TrackStopEntity; +use App\Entity\TripStopEntity; +use App\Model\ScheduledStop; +use App\Model\TrackStop; + +class ScheduledStopConverter implements Converter, RecursiveConverter +{ + use RecursiveConverterTrait; + + public function convert($entity) + { + if ($entity instanceof TrackStopEntity) { + return TrackStop::createFromArray([ + 'stop' => $this->parent->convert($entity->getStop()), + 'track' => $this->parent->convert($entity->getTrack()), + 'order' => $entity->getOrder(), + ]); + } + + if ($entity instanceof TripStopEntity) { + return ScheduledStop::createFromArray([ + 'arrival' => $entity->getArrival(), + 'departure' => $entity->getDeparture(), + 'stop' => $this->parent->convert($entity->getStop()), + 'order' => $entity->getOrder(), + 'track' => $this->parent->convert($entity->getTrip()->getTrack()), + 'trip' => $this->parent->convert($entity->getTrip()), + ]); + } + } + + public function supports($entity) + { + return $entity instanceof TripStopEntity + || $entity instanceof TrackStopEntity; + } +} diff --git a/src/Service/SerializerContextFactory.php b/api/src/Service/SerializerContextFactory.php similarity index 95% rename from src/Service/SerializerContextFactory.php rename to api/src/Service/SerializerContextFactory.php index 94156b9..310235f 100644 --- a/src/Service/SerializerContextFactory.php +++ b/api/src/Service/SerializerContextFactory.php @@ -23,7 +23,7 @@ final class SerializerContextFactory public function create($subject, array $groups = ['Default']) { - return SerializationContext::create()->setGroups($this->groups($subject, $groups)); + return SerializationContext::create()->setSerializeNull(true)->setGroups($this->groups($subject, $groups)); } private function groups($subject, array $groups) diff --git a/api/src/Subscriber/JSONFormatSubscriber.php b/api/src/Subscriber/JSONFormatSubscriber.php new file mode 100644 index 0000000..373a373 --- /dev/null +++ b/api/src/Subscriber/JSONFormatSubscriber.php @@ -0,0 +1,28 @@ +<?php + + +namespace App\Subscriber; + + +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\HttpKernel\Event\RequestEvent; +use Symfony\Component\HttpKernel\KernelEvents; + +class JSONFormatSubscriber implements EventSubscriberInterface +{ + public static function getSubscribedEvents() + { + return [ + KernelEvents::REQUEST => "onRequest", + ]; + } + + public function onRequest(RequestEvent $event) + { + $request = $event->getRequest(); + + if (!$request->attributes->has('_format')) { + $request->attributes->set('_format', 'json'); + } + } +} diff --git a/src/Subscriber/JustReferenceSerializationSubscriber.php b/api/src/Subscriber/JustReferenceSerializationSubscriber.php similarity index 100% rename from src/Subscriber/JustReferenceSerializationSubscriber.php rename to api/src/Subscriber/JustReferenceSerializationSubscriber.php diff --git a/api/src/Subscriber/RequestCleanupSubscriber.php b/api/src/Subscriber/RequestCleanupSubscriber.php new file mode 100644 index 0000000..ac84b85 --- /dev/null +++ b/api/src/Subscriber/RequestCleanupSubscriber.php @@ -0,0 +1,39 @@ +<?php + +namespace App\Subscriber; + +use App\Service\Converter; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\HttpKernel\Event\TerminateEvent; +use Symfony\Component\HttpKernel\KernelEvents; +use Symfony\Contracts\Service\ResetInterface; + +class RequestCleanupSubscriber implements EventSubscriberInterface +{ + /** @var ContainerInterface */ + private ContainerInterface $container; + private Converter $converter; + + public function __construct(ContainerInterface $container, Converter $converter) + { + $this->container = $container; + $this->converter = $converter; + } + + public static function getSubscribedEvents() + { + return [ + KernelEvents::TERMINATE => ['onTerminate'] + ]; + } + + public function onTerminate(TerminateEvent $event) + { + $this->container->get('doctrine')->reset(); + + if ($this->converter instanceof ResetInterface) { + $this->converter->reset(); + } + } +} diff --git a/symfony.lock b/api/symfony.lock similarity index 67% rename from symfony.lock rename to api/symfony.lock index 6946a9f..e8f3e9c 100644 --- a/symfony.lock +++ b/api/symfony.lock @@ -1,7 +1,25 @@ { + "baldinof/roadrunner-bundle": { + "version": "1.2", + "recipe": { + "repo": "github.com/symfony/recipes-contrib", + "branch": "master", + "version": "1.2", + "ref": "47c159c44eb9e6902828da4acbb4199757dd378f" + }, + "files": [ + "config/packages/baldinof_road_runner.yaml" + ] + }, "cerbero/json-objects": { "version": "v1.1.2" }, + "composer/package-versions-deprecated": { + "version": "1.11.99.1" + }, + "dflydev/fig-cookies": { + "version": "v2.0.1" + }, "doctrine/annotations": { "version": "1.0", "recipe": { @@ -23,26 +41,36 @@ "doctrine/dbal": { "version": "v2.8.0" }, + "doctrine/deprecations": { + "version": "v0.5.3" + }, "doctrine/doctrine-bundle": { - "version": "1.6", + "version": "2.0", "recipe": { "repo": "github.com/symfony/recipes", "branch": "master", - "version": "1.6", - "ref": "ae205d5114e719deb64d2110f56ef910787d1e04" - } - }, - "doctrine/doctrine-cache-bundle": { - "version": "1.3.3" + "version": "2.0", + "ref": "368794356c1fb634e58b38ad2addb36933f2e73e" + }, + "files": [ + "config/packages/doctrine.yaml", + "config/packages/prod/doctrine.yaml", + "src/Entity/.gitignore", + "src/Repository/.gitignore" + ] }, "doctrine/doctrine-migrations-bundle": { - "version": "1.2", + "version": "2.2", "recipe": { "repo": "github.com/symfony/recipes", "branch": "master", - "version": "1.2", - "ref": "c1431086fec31f17fbcfe6d6d7e92059458facc1" - } + "version": "2.2", + "ref": "baaa439e3e3179e69e3da84b671f0a3e4a2f56ad" + }, + "files": [ + "config/packages/doctrine_migrations.yaml", + "migrations/.gitignore" + ] }, "doctrine/event-manager": { "version": "v1.0.0" @@ -65,8 +93,8 @@ "doctrine/persistence": { "version": "v1.0.0" }, - "doctrine/reflection": { - "version": "v1.0.0" + "doctrine/sql-formatter": { + "version": "1.1.1" }, "exsyst/swagger": { "version": "v0.4.1" @@ -110,9 +138,21 @@ "hoa/zformat": { "version": "1.17.01.10" }, + "illuminate/collections": { + "version": "v8.35.1" + }, + "illuminate/contracts": { + "version": "v8.35.1" + }, + "illuminate/macroable": { + "version": "v8.35.1" + }, "jdorn/sql-formatter": { "version": "v1.2.17" }, + "jean85/pretty-package-versions": { + "version": "2.0.3" + }, "jms/metadata": { "version": "1.7.0" }, @@ -136,8 +176,11 @@ "kadet/functional": { "version": "dev-master" }, - "kylekatarnls/update-helper": { - "version": "1.2.0" + "laminas/laminas-diactoros": { + "version": "2.5.0" + }, + "laminas/laminas-zendframework-bridge": { + "version": "1.1.1" }, "monolog/monolog": { "version": "1.23.0" @@ -154,6 +197,9 @@ "nesbot/carbon": { "version": "1.33.0" }, + "nikic/php-parser": { + "version": "v4.10.4" + }, "ocramius/package-versions": { "version": "1.3.0" }, @@ -163,6 +209,9 @@ "php": { "version": "7.3.12" }, + "php-http/discovery": { + "version": "1.13.0" + }, "phpdocumentor/reflection-common": { "version": "1.0.1" }, @@ -172,15 +221,30 @@ "phpdocumentor/type-resolver": { "version": "0.4.0" }, + "phpstan/phpdoc-parser": { + "version": "0.4.14" + }, "psr/cache": { "version": "1.0.1" }, "psr/container": { "version": "1.0.0" }, + "psr/event-dispatcher": { + "version": "1.0.0" + }, + "psr/http-factory": { + "version": "1.0.1" + }, "psr/http-message": { "version": "1.0.1" }, + "psr/http-server-handler": { + "version": "1.0.1" + }, + "psr/http-server-middleware": { + "version": "1.0.1" + }, "psr/log": { "version": "1.0.2" }, @@ -199,6 +263,15 @@ "ref": "fb7e19da7f013d0d422fa9bce16f5c510e27609b" } }, + "spiral/goridge": { + "version": "v2.4.5" + }, + "spiral/roadrunner": { + "version": "v1.8.4" + }, + "symfony/amqp-messenger": { + "version": "v5.2.4" + }, "symfony/asset": { "version": "v4.1.4" }, @@ -220,15 +293,18 @@ "ref": "e3868d2f4a5104f19f844fe551099a00c6562527" } }, - "symfony/debug": { - "version": "v4.1.3" - }, "symfony/dependency-injection": { "version": "v4.1.3" }, + "symfony/deprecation-contracts": { + "version": "v2.2.0" + }, "symfony/doctrine-bridge": { "version": "v4.1.4" }, + "symfony/doctrine-messenger": { + "version": "v5.2.5" + }, "symfony/dotenv": { "version": "v4.1.3" }, @@ -253,17 +329,35 @@ "repo": "github.com/symfony/recipes", "branch": "master", "version": "1.0", - "ref": "e921bdbfe20cdefa3b82f379d1cd36df1bc8d115" - } + "ref": "c0eeb50665f0f77226616b6038a9b06c03752d8e" + }, + "files": [ + ".env" + ] }, "symfony/framework-bundle": { - "version": "3.3", + "version": "4.4", "recipe": { "repo": "github.com/symfony/recipes", "branch": "master", - "version": "3.3", - "ref": "87c585d24de9f43bca80ebcfd5cf5cb39445d95f" - } + "version": "4.4", + "ref": "df1f2fe60b8fbb5cf7e26a7af19445c128a13b90" + }, + "files": [ + "config/bootstrap.php", + "config/packages/cache.yaml", + "config/packages/framework.yaml", + "config/packages/test/framework.yaml", + "config/preload.php", + "config/routes/dev/framework.yaml", + "config/services.yaml", + "public/index.php", + "src/Controller/.gitignore", + "src/Kernel.php" + ] + }, + "symfony/http-client-contracts": { + "version": "v2.3.1" }, "symfony/http-foundation": { "version": "v4.1.3" @@ -271,11 +365,26 @@ "symfony/http-kernel": { "version": "v4.1.3" }, - "symfony/inflector": { - "version": "v4.1.3" + "symfony/maker-bundle": { + "version": "1.0", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "master", + "version": "1.0", + "ref": "fadbfe33303a76e25cb63401050439aa9b1a9c7f" + } }, - "symfony/mime": { - "version": "v5.0.2" + "symfony/messenger": { + "version": "4.3", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "master", + "version": "4.3", + "ref": "e9a414b113ceadbf4e52abe37bf8f1b443f06ccb" + }, + "files": [ + "config/packages/messenger.yaml" + ] }, "symfony/monolog-bridge": { "version": "v4.1.4" @@ -295,20 +404,20 @@ "symfony/orm-pack": { "version": "v1.0.5" }, - "symfony/polyfill-intl-idn": { - "version": "v1.13.1" + "symfony/polyfill-intl-grapheme": { + "version": "v1.22.1" + }, + "symfony/polyfill-intl-normalizer": { + "version": "v1.20.0" }, "symfony/polyfill-mbstring": { "version": "v1.9.0" }, - "symfony/polyfill-php72": { - "version": "v1.9.0" - }, "symfony/polyfill-php73": { "version": "v1.13.1" }, - "symfony/process": { - "version": "v4.1.3" + "symfony/polyfill-php80": { + "version": "v1.20.0" }, "symfony/profiler-pack": { "version": "v1.0.4" @@ -319,6 +428,12 @@ "symfony/property-info": { "version": "v4.1.3" }, + "symfony/psr-http-message-bridge": { + "version": "v2.0.2" + }, + "symfony/redis-messenger": { + "version": "v5.2.4" + }, "symfony/routing": { "version": "4.0", "recipe": { @@ -340,6 +455,9 @@ "symfony/stopwatch": { "version": "v4.1.12" }, + "symfony/string": { + "version": "v5.2.6" + }, "symfony/translation": { "version": "3.3", "recipe": { @@ -356,13 +474,18 @@ "version": "v4.1.3" }, "symfony/twig-bundle": { - "version": "3.3", + "version": "4.4", "recipe": { "repo": "github.com/symfony/recipes", "branch": "master", - "version": "3.3", - "ref": "f75ac166398e107796ca94cc57fa1edaa06ec47f" - } + "version": "4.4", + "ref": "15a41bbd66a1323d09824a189b485c126bbefa51" + }, + "files": [ + "config/packages/test/twig.yaml", + "config/packages/twig.yaml", + "templates/base.html.twig" + ] }, "symfony/var-dumper": { "version": "v4.1.3" @@ -384,21 +507,9 @@ "config/routes/dev/web_profiler.yaml" ] }, - "symfony/web-server-bundle": { - "version": "3.3", - "recipe": { - "repo": "github.com/symfony/recipes", - "branch": "master", - "version": "3.3", - "ref": "dae9b39fd6717970be7601101ce5aa960bf53d9a" - } - }, "symfony/yaml": { "version": "v4.1.3" }, - "tightenco/collect": { - "version": "v5.6.33" - }, "twig/twig": { "version": "v2.5.0" }, diff --git a/templates/bundles/NelmioApiDocBundle/SwaggerUi/index.html.twig b/api/templates/bundles/NelmioApiDocBundle/SwaggerUi/index.html.twig similarity index 74% rename from templates/bundles/NelmioApiDocBundle/SwaggerUi/index.html.twig rename to api/templates/bundles/NelmioApiDocBundle/SwaggerUi/index.html.twig index 0d4e685..d156f6d 100644 --- a/templates/bundles/NelmioApiDocBundle/SwaggerUi/index.html.twig +++ b/api/templates/bundles/NelmioApiDocBundle/SwaggerUi/index.html.twig @@ -5,5 +5,5 @@ {% block stylesheets %} {{ parent() }} <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:400,700|Source+Code+Pro:300,600|Titillium+Web:400,600,700"> - <link rel="stylesheet" href="{{ asset('dist/api.css') }}" /> -{% endblock stylesheets %} \ No newline at end of file + <link rel="stylesheet" href="/dist/api.css" /> +{% endblock stylesheets %} diff --git a/src/Migrations/.gitignore b/api/translations/.gitignore similarity index 100% rename from src/Migrations/.gitignore rename to api/translations/.gitignore diff --git a/build/api/fpm.Dockerfile b/build/api/fpm.Dockerfile new file mode 100644 index 0000000..4f23641 --- /dev/null +++ b/build/api/fpm.Dockerfile @@ -0,0 +1,6 @@ +ARG BASE_VERSION=latest +ARG REGISTRY=docker.io + +FROM $REGISTRY/cojedzie/base:${BASE_VERSION}-fpm as base + +CMD ["./bin/docker-init.sh", "php-fpm"] diff --git a/build/api/rr.Dockerfile b/build/api/rr.Dockerfile new file mode 100644 index 0000000..5fe6e2b --- /dev/null +++ b/build/api/rr.Dockerfile @@ -0,0 +1,10 @@ +ARG BASE_VERSION=latest +ARG REGISTRY=docker.io + +FROM $REGISTRY/cojedzie/base:${BASE_VERSION} as base + +COPY --from=spiralscout/roadrunner:1.9.2 /usr/bin/rr /usr/bin/rr + +EXPOSE 8080 + +CMD ["./bin/docker-init.sh", "rr", "serve", "-v"] diff --git a/build/base/Dockerfile b/build/base/Dockerfile new file mode 100644 index 0000000..0e343ab --- /dev/null +++ b/build/base/Dockerfile @@ -0,0 +1,32 @@ +FROM php:7.4-alpine + +LABEL maintainer="Kacper Donat <kacper@kadet.net>" + +COPY --from=mlocati/php-extension-installer /usr/bin/install-php-extensions /usr/local/bin/ +COPY --from=composer:latest /usr/bin/composer /usr/bin/composer + +WORKDIR /var/www + +RUN install-php-extensions bcmath intl opcache zip sockets; + +COPY composer.json composer.lock ./ + +RUN apk add git && \ + composer install --no-dev --no-scripts --no-plugins --prefer-dist --no-progress --no-interaction && \ + composer dump-autoload --optimize && \ + composer check-platform-reqs && \ + composer clear-cache && \ + apk del --purge git + +COPY . . + +ENV APP_ENV=prod +ENV DATABASE_URL="sqlite:////var/db/app.db" +ENV PATH=$PATH:/var/www/bin + +RUN composer run-script post-install-cmd + +VOLUME /var/db + +# This image is not meant to be run, just to prepare all required files +CMD ["/bin/false"] diff --git a/build/base/cli.Dockerfile b/build/base/cli.Dockerfile new file mode 100644 index 0000000..72552b6 --- /dev/null +++ b/build/base/cli.Dockerfile @@ -0,0 +1,27 @@ +ARG BASE_VERSION=latest +ARG REGISTRY=docker.io + +FROM $REGISTRY/cojedzie/base:$BASE_VERSION as base + +FROM php:7.4-cli-alpine + +LABEL maintainer="Kacper Donat <kacper@kadet.net>" + +COPY --from=mlocati/php-extension-installer /usr/bin/install-php-extensions /usr/local/bin/ + +WORKDIR /var/www + +RUN install-php-extensions bcmath intl opcache zip sockets; + +COPY composer.json composer.lock ./ + +COPY --from=base /var/www /var/www + +ENV APP_ENV=prod +ENV DATABASE_URL="sqlite:////var/db/app.db" +ENV PATH=$PATH:/var/www/bin + +VOLUME /var/db + +# This image is not meant to be run, just to prepare all required files +CMD ["/bin/false"] diff --git a/build/base/fpm.Dockerfile b/build/base/fpm.Dockerfile new file mode 100644 index 0000000..06bd388 --- /dev/null +++ b/build/base/fpm.Dockerfile @@ -0,0 +1,27 @@ +ARG BASE_VERSION=latest +ARG REGISTRY=docker.io + +FROM $REGISTRY/cojedzie/base:$BASE_VERSION as base + +FROM php:7.4-fpm-alpine + +LABEL maintainer="Kacper Donat <kacper@kadet.net>" + +COPY --from=mlocati/php-extension-installer /usr/bin/install-php-extensions /usr/local/bin/ + +WORKDIR /var/www + +RUN install-php-extensions bcmath intl opcache zip sockets; + +COPY composer.json composer.lock ./ + +COPY --from=base /var/www /var/www + +ENV APP_ENV=prod +ENV DATABASE_URL="sqlite:////var/db/app.db" +ENV PATH=$PATH:/var/www/bin + +VOLUME /var/db + +# This image is not meant to be run, just to prepare all required files +CMD ["/bin/false"] diff --git a/build/front/Dockerfile b/build/front/Dockerfile new file mode 100644 index 0000000..4231ba4 --- /dev/null +++ b/build/front/Dockerfile @@ -0,0 +1,36 @@ +FROM node:15.2.1 as build + +WORKDIR /app +COPY . . + +# install dependencies +RUN yarn install +RUN find resources/fontawesome -type f -name '*.tgz' | sed s/^/file:/ | xargs yarn add-no-save + +# build stuff +RUN yarn run build:app +RUN yarn run build:server + +# server dependencies step +FROM node:15.2.1 as prod-dependencies + +WORKDIR /app + +COPY . . + +# install dependencies +RUN yarn install --production + +FROM node:15.2.1-slim + +LABEL maintainer="Kacper Donat <kacper@kadet.net>" + +WORKDIR /app + +COPY --from=build /app/build/ build +COPY --from=build /app/resources/ resources +COPY --from=prod-dependencies /app/node_modules/ node_modules + +EXPOSE 3000 + +CMD ["node", "build/server.js"] diff --git a/build/release.sh b/build/release.sh new file mode 100755 index 0000000..9dcf916 --- /dev/null +++ b/build/release.sh @@ -0,0 +1,171 @@ +#!/bin/bash + +TAGS=$* +BUILD=$(dirname $0) +ROOT=$BUILD/.. + +REGISTRY="docker.io" +TAGS=() +DRY=0 +PUSH=0 +BUILD_BASE=1 + +BUILT_TAGS=() + +export DOCKER_BUILDKIT=1 + +usage () { + echo "usage: $0 [-h|--help] [-d|--dry] [--no-base|-B] [-p|--push] [-r|--registry registry] [-t|--tag tag] -- images..."; +} + +run () { + if [[ $DRY == 1 ]]; then + echo "$@" + else + "$@" + fi +} + +# usage: build [-d|--default] [-v|--variant variant] [-R|--no-register] <image> <context> +build () { + ARGS=() + IS_DEFAULT=0 + SUFFIX="" + VARIANT="" + REGISTER=1 + + options=$(getopt -l "default,variant:,no-register" -o "dv:R" -- "$@") + eval set -- "$options" + + while true; + do + case "$1" in + -d|--default) + IS_DEFAULT=1 + shift + ;; + -v|--variant) + VARIANT="$2" + shift 2 + ;; + -R|--no-register) + REGISTER=0 + shift + ;; + --) + shift + break + ;; + *) + echo "build: unknown option $1" + exit 1 + esac + done + + IMAGE=$1 + CONTEXT=$2 + shift 2; + + # check for variant + if [[ -z "$VARIANT" ]]; then + ARGS+=("-f" "$BUILD/$IMAGE/Dockerfile") + else + ARGS+=("-f" "$BUILD/$IMAGE/$VARIANT.Dockerfile") + SUFFIX="-$VARIANT" + fi + + for TAG in "${TAGS[@]}"; do + ARGS+=("-t" "$REGISTRY/cojedzie/$IMAGE:$TAG$SUFFIX") + [[ $REGISTER -eq 1 ]] && BUILT_TAGS+=("$REGISTRY/cojedzie/$IMAGE:$TAG$SUFFIX") + + if [[ $IS_DEFAULT == 1 ]]; then + ARGS+=("-t" "$REGISTRY/cojedzie/$IMAGE:$TAG") + [[ $REGISTER -eq 1 ]] && BUILT_TAGS+=("$REGISTRY/cojedzie/$IMAGE:$TAG") + fi + done + + echo "Building $IMAGE $VARIANT" + run docker build --build-arg "BASE_VERSION=${TAGS[0]}" --build-arg "REGISTRY=$REGISTRY" "$CONTEXT" "${ARGS[@]}" "$@" +} + +options=$(getopt -l "help,dry,registry:,tag:,push,no-base" -o "hdr:t:pB" -- "$@") +eval set -- "$options" + +while true; +do + case "$1" in + -h|--help) + usage + exit 0 + ;; + -t|--tag) + TAGS+=("$2") + shift 2 + ;; + -p|--push) + PUSH=1 + shift + ;; + -B|--no-base) + BUILD_BASE=0 + shift + ;; + -r|--registry) + REGISTRY="$2" + shift 2 + ;; + -d|--dry) + DRY=1 + shift + ;; + --) + shift + break; + esac +done + +# set default tags if user have not provided any +if [ ${#TAGS[@]} -eq 0 ]; then + TAGS=("latest") +fi + +if [ $# -eq 0 ]; then + set -- api standalone worker front +fi + +if [ $BUILD_BASE -eq 1 ]; then + build --no-register base $ROOT/api/ || exit 1 + build --no-register --variant fpm base $ROOT/api/ || exit 1 + build --no-register --variant cli base $ROOT/api/ || exit 1 +fi + +while [ $# -gt 0 ] +do + case "$1" in + api) + build api $BUILD/api/ --variant rr --default || exit 1 + build api $BUILD/api/ --variant fpm || exit 1 + ;; + standalone) + build standalone $BUILD/standalone/ --variant rr --default || exit 1 + ;; + worker) + build worker $BUILD/worker/ || exit 1 + ;; + front) + build front $ROOT/front/ || exit 1 + ;; + *) + >&2 echo "$1 is not a valid image to build" + esac + shift +done + +if [ $PUSH -eq 1 ]; then + for TAG in "${BUILT_TAGS[@]}"; do + docker push $TAG + done +else + echo "Created tags:" + printf " - %s\n" "${BUILT_TAGS[@]}" +fi diff --git a/build/standalone/rr.Dockerfile b/build/standalone/rr.Dockerfile new file mode 100644 index 0000000..a41406d --- /dev/null +++ b/build/standalone/rr.Dockerfile @@ -0,0 +1,38 @@ +ARG BASE_VERSION=latest +ARG REGISTRY=docker.io + +FROM ${REGISTRY}/cojedzie/api:${BASE_VERSION}-rr + +# escape=` +RUN apk add supervisor gettext && \ + { \ + echo '[supervisord]'; \ + echo 'nodaemon=true'; \ + echo ; \ + echo '[program:roadrunner]'; \ + echo 'command=rr serve -v'; \ + echo 'startsecs=0'; \ + echo 'start=true'; \ + echo 'autorestart=true'; \ + echo 'stdout_logfile=/dev/stdout'; \ + echo 'stderr_logfile=/dev/stderr'; \ + echo 'stdout_logfile_maxbytes=0'; \ + echo 'stderr_logfile_maxbytes=0'; \ + echo ; \ + echo '[program:messenger-consumer]'; \ + echo 'command=php /var/www/bin/console messenger:consume $COJEDZIE_WORKER_OPTS $COJEDZIE_WORKER_QUEUES'; \ + echo 'startsecs=0'; \ + echo 'start=true'; \ + echo 'autorestart=true'; \ + echo 'stdout_logfile=/dev/stdout'; \ + echo 'stderr_logfile=/dev/stderr'; \ + echo 'stdout_logfile_maxbytes=0'; \ + echo 'stderr_logfile_maxbytes=0'; \ + } | tee /etc/supervisord.conf.tpl; + +COPY ./supervisord-init.sh ./bin/ + +ENV COJEDZIE_WORKER_QUEUES=main +ENV COJEDZIE_WORKER_OPTS="-vv --time-limit=86400 --limit=10 --memory-limit=128M" + +CMD ["./bin/supervisord-init.sh", "supervisord", "-c", "/etc/supervisord.conf"] diff --git a/build/standalone/supervisord-init.sh b/build/standalone/supervisord-init.sh new file mode 100755 index 0000000..a61b86e --- /dev/null +++ b/build/standalone/supervisord-init.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +if [ -f /etc/supervisord.conf.tpl ]; then + envsubst < /etc/supervisord.conf.tpl > /etc/supervisord.conf +fi + +exec "$@" diff --git a/build/worker/Dockerfile b/build/worker/Dockerfile new file mode 100644 index 0000000..1fe0fc3 --- /dev/null +++ b/build/worker/Dockerfile @@ -0,0 +1,27 @@ +ARG BASE_VERSION=latest +ARG REGISTRY=docker.io + +FROM $REGISTRY/cojedzie/base:${BASE_VERSION}-cli + +RUN apk add supervisor gettext && \ + { \ + echo '[supervisord]'; \ + echo 'nodaemon=true'; \ + echo ; \ + echo '[program:messenger-consumer]'; \ + echo 'command=php /var/www/bin/console messenger:consume $COJEDZIE_WORKER_OPTS $COJEDZIE_WORKER_QUEUES'; \ + echo 'startsecs=0'; \ + echo 'start=true'; \ + echo 'autorestart=true'; \ + echo 'stdout_logfile=/dev/stdout'; \ + echo 'stderr_logfile=/dev/stderr'; \ + echo 'stdout_logfile_maxbytes=0'; \ + echo 'stderr_logfile_maxbytes=0'; \ + } | tee /etc/supervisord.conf.tpl; + +COPY ./supervisord-init.sh ./bin/ + +ENV COJEDZIE_WORKER_QUEUES=main +ENV COJEDZIE_WORKER_OPTS="-vv --time-limit=86400 --limit=10 --memory-limit=128M" + +CMD ["./bin/supervisord-init.sh", "supervisord", "-c", "/etc/supervisord.conf"] diff --git a/build/worker/supervisord-init.sh b/build/worker/supervisord-init.sh new file mode 100755 index 0000000..a61b86e --- /dev/null +++ b/build/worker/supervisord-init.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +if [ -f /etc/supervisord.conf.tpl ]; then + envsubst < /etc/supervisord.conf.tpl > /etc/supervisord.conf +fi + +exec "$@" diff --git a/config/packages/doctrine_migrations.yaml b/config/packages/doctrine_migrations.yaml deleted file mode 100644 index 70959a6..0000000 --- a/config/packages/doctrine_migrations.yaml +++ /dev/null @@ -1,3 +0,0 @@ -doctrine_migrations: - dir_name: '%kernel.project_dir%/src/Migrations' - namespace: DoctrineMigrations diff --git a/config/packages/framework.yaml b/config/packages/framework.yaml deleted file mode 100644 index 8b24418..0000000 --- a/config/packages/framework.yaml +++ /dev/null @@ -1,30 +0,0 @@ -framework: - secret: '%env(APP_SECRET)%' - #default_locale: en - #csrf_protection: true - #http_method_override: true - - # Enables session support. Note that the session will ONLY be started if you read or write from it. - # Remove or comment this section to explicitly disable session support. - session: - handler_id: ~ - - #esi: true - #fragments: true - php_errors: - log: true - - cache: - # Put the unique name of your app here: the prefix seed - # is used to compute stable namespaces for cache keys. - #prefix_seed: your_vendor_name/app_name - - # The app cache caches to the filesystem by default. - # Other options include: - - # Redis - #app: cache.adapter.redis - #default_redis_provider: redis://localhost - - # APCu (not recommended with heavy random-write workloads as memory fragmentation can cause perf issues) - #app: cache.adapter.apcu diff --git a/config/packages/prod/doctrine.yaml b/config/packages/prod/doctrine.yaml deleted file mode 100644 index 2f16f0f..0000000 --- a/config/packages/prod/doctrine.yaml +++ /dev/null @@ -1,31 +0,0 @@ -doctrine: - orm: - metadata_cache_driver: - type: service - id: doctrine.system_cache_provider - query_cache_driver: - type: service - id: doctrine.system_cache_provider - result_cache_driver: - type: service - id: doctrine.result_cache_provider - -services: - doctrine.result_cache_provider: - class: Symfony\Component\Cache\DoctrineProvider - public: false - arguments: - - '@doctrine.result_cache_pool' - doctrine.system_cache_provider: - class: Symfony\Component\Cache\DoctrineProvider - public: false - arguments: - - '@doctrine.system_cache_pool' - -framework: - cache: - pools: - doctrine.result_cache_pool: - adapter: cache.app - doctrine.system_cache_pool: - adapter: cache.system diff --git a/config/packages/twig.yaml b/config/packages/twig.yaml deleted file mode 100644 index 95f2509..0000000 --- a/config/packages/twig.yaml +++ /dev/null @@ -1,6 +0,0 @@ -twig: - paths: ['%kernel.project_dir%/templates'] - debug: '%kernel.debug%' - strict_variables: '%kernel.debug%' - globals: - ga_tracking: "%env(GOOGLE_ANALYTICS)%" diff --git a/config/routes.yaml b/config/routes.yaml deleted file mode 100644 index b42047c..0000000 --- a/config/routes.yaml +++ /dev/null @@ -1,4 +0,0 @@ -api_v1: - resource: ../src/Controller/Api/v1 - type: annotation - prefix: /{provider}/api/v1 diff --git a/config/routes/dev/twig.yaml b/config/routes/dev/twig.yaml deleted file mode 100644 index f4ee839..0000000 --- a/config/routes/dev/twig.yaml +++ /dev/null @@ -1,3 +0,0 @@ -_errors: - resource: '@TwigBundle/Resources/config/routing/errors.xml' - prefix: /_error diff --git a/docker-compose.rr.yml b/docker-compose.rr.yml new file mode 100644 index 0000000..1b7b518 --- /dev/null +++ b/docker-compose.rr.yml @@ -0,0 +1,43 @@ +version: '3.4' + +services: + nginx: + image: nginx:latest + ports: + - "8080:80" + volumes: + - ./front:/var/www/front:cached + - ./api:/var/www/api:cached + - .docker-compose/nginx/cojedzie-rr.conf:/etc/nginx/conf.d/cojedzie-rr.conf + + api: + build: + context: ./api + dockerfile: rr.Dockerfile + env_file: + - .docker-compose/api/.env + - api/.env.local + environment: + - TRUSTED_PROXIES=172.0.0.0/8 + ports: + - 8888:8080 + volumes: + - ./api:/var/www:cached + - .docker-compose/api/log.conf:/usr/local/etc/php-fpm.d/zz-log.conf + command: ["rr", "serve", "-c", ".rr.yaml"] + + frontend: + image: node:15.2.1 + working_dir: /app + environment: + - APP_API=http://nginx/api + volumes: + - ./front:/app + command: ["node", "build/server.js"] + + blackfire: + image: blackfire/blackfire + ports: ["8707"] + environment: + - BLACKFIRE_SERVER_ID + - BLACKFIRE_SERVER_TOKEN diff --git a/docker-compose.yml b/docker-compose.yml index 24c33b1..6eec0da 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,4 @@ -version: '2' +version: '3.4' services: nginx: @@ -6,14 +6,32 @@ services: ports: - "8080:80" volumes: - - ./:/var/www:cached - - ./docker/nginx/czydojade:/etc/nginx/conf.d/czydojade.conf + - ./front:/var/www/front:cached + - ./api:/var/www/api:cached + - .docker-compose/nginx/cojedzie.conf:/etc/nginx/conf.d/cojedzie.conf - php: - build: docker/php - mem_limit: 2g + api: + build: + context: ./api + dockerfile: Dockerfile env_file: - - ./docker/php/.env + - .docker-compose/api/.env volumes: - - ./:/var/www:cached - - ./docker/php/log.conf:/usr/local/etc/php-fpm.d/zz-log.conf + - ./api:/var/www:cached + - .docker-compose/api/log.conf:/usr/local/etc/php-fpm.d/zz-log.conf + + frontend: + image: node:15.2.1 + working_dir: /app + environment: + - APP_API=http://nginx/api + volumes: + - ./front:/app + command: ["node", "build/server.js"] + + blackfire: + image: blackfire/blackfire + ports: ["8707"] + environment: + - BLACKFIRE_SERVER_ID + - BLACKFIRE_SERVER_TOKEN diff --git a/docker/nginx/czydojade b/docker/nginx/czydojade deleted file mode 100644 index e9fbde6..0000000 --- a/docker/nginx/czydojade +++ /dev/null @@ -1,29 +0,0 @@ -server { - root /var/www/public/; - server_name czydojade.localhost; - - index index.php; - - location / { - try_files $uri $uri/ /index.php?$args; - - location ~ \.(js|css)$ { - expires 1y; - } - - location ~ ^/index\.php(/|$) { - fastcgi_pass php:9000; - fastcgi_split_path_info ^(.+\.php)(/.*)$; - - include fastcgi_params; - fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; - fastcgi_param DOCUMENT_ROOT $realpath_root; - - fastcgi_param APP_ENV "dev"; - fastcgi_param DATABASE_URL "sqlite:///%kernel.project_dir%/var/app.db"; - fastcgi_param GOOGLE_ANALYTICS "UA-00000-00"; - - internal; - } - } -} \ No newline at end of file diff --git a/docker/php/.env b/docker/php/.env deleted file mode 100644 index eb54481..0000000 --- a/docker/php/.env +++ /dev/null @@ -1,2 +0,0 @@ -XDEBUG_CONFIG=remote_host=172.17.0.1 remote_port=9001 -PHP_IDE_CONFIG=serverName=czydojade diff --git a/docker/php/Dockerfile b/docker/php/Dockerfile deleted file mode 100644 index 6142fa0..0000000 --- a/docker/php/Dockerfile +++ /dev/null @@ -1,23 +0,0 @@ -FROM php:7.3-fpm - -RUN apt-get update && \ - apt-get install -y --no-install-recommends git zip libzip-dev - -RUN docker-php-ext-install zip - -RUN pecl install xdebug-2.9.0 && docker-php-ext-enable xdebug - -RUN echo "xdebug.remote_enable = 1" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini; -RUN echo "date.timezone = Europe/Warsaw" >> /usr/local/etc/php/conf.d/datetime.ini; - -RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" -RUN php composer-setup.php -RUN php -r "unlink('composer-setup.php');" - -RUN mv composer.phar /usr/local/bin/composer -RUN chmod +x /usr/local/bin/composer -RUN ln -snf /usr/share/zoneinfo/Europe/Warsaw /etc/localtime - -WORKDIR /var/www - -EXPOSE 9001 diff --git a/front/.dockerignore b/front/.dockerignore new file mode 100644 index 0000000..c7c2b54 --- /dev/null +++ b/front/.dockerignore @@ -0,0 +1,4 @@ +/node_modules/ +/build/ +yarn-error* +npm-debug* diff --git a/front/.gitignore b/front/.gitignore new file mode 100644 index 0000000..02ec49f --- /dev/null +++ b/front/.gitignore @@ -0,0 +1,6 @@ +yarn-error.log + +/public/* +!/public/.gitkeep +/node_modules/ +/build/ diff --git a/front/CONTRIBUTING.md b/front/CONTRIBUTING.md new file mode 100644 index 0000000..6ca8468 --- /dev/null +++ b/front/CONTRIBUTING.md @@ -0,0 +1,3 @@ +# Contributing guidelines + +TBD diff --git a/package.json b/front/package.json similarity index 71% rename from package.json rename to front/package.json index 07a27f5..e43d65e 100644 --- a/package.json +++ b/front/package.json @@ -1,19 +1,23 @@ { - "name": "czydojade", + "name": "cojedzie", "version": "1.0.0", "author": "Kacper Donat <kadet1090@gmail.com>", "license": "MIT", "devDependencies": { "@fortawesome/fontawesome-svg-core": "^1.2.4", - "@fortawesome/pro-light-svg-icons": "^5.3.1", - "@fortawesome/pro-regular-svg-icons": "^5.3.1", - "@fortawesome/pro-solid-svg-icons": "^5.3.1", "@fortawesome/vue-fontawesome": "^0.1.1", - "@types/bootstrap": "^4.1.2", + "@types/bootstrap": "^4.3.1", + "@types/ejs": "^3.0.5", + "@types/express": "^4.17.9", "@types/jquery": "^3.3.6", + "@types/mapbox-gl-leaflet": "^0.0.1", "@types/moment": "^2.13.0", "@types/popper.js": "^1.11.0", - "bootstrap": "^4.1.3", + "@types/request": "^2.48.5", + "@types/uuid": "^3.4.6", + "@types/vue-moment": "^4.0.0", + "@types/workbox-window": "^4.3.3", + "bootstrap": "^4.3.1", "css-loader": "^1.0.0", "file-loader": "^2.0.0", "jquery": "^3.3.1", @@ -31,14 +35,11 @@ "webpack": "^4.17.0", "webpack-cli": "^3.1.0", "xmldom": "^0.1.27", - "xpath": "^0.0.27" - }, - "dependencies": { - "@types/mapbox-gl-leaflet": "^0.0.1", - "@types/uuid": "^3.4.6", - "@types/workbox-window": "^4.3.3", + "xpath": "^0.0.27", + "yarn-add-no-save": "^1.0.3", "clean-webpack-plugin": "^3.0.0", "copy-webpack-plugin": "^4.5.2", + "html-webpack-plugin": "^4.5.0", "imagemin-webpack-plugin": "^2.3.0", "mapbox-gl": "^1.6.1", "mapbox-gl-leaflet": "^0.0.11", @@ -46,12 +47,23 @@ "portal-vue": "^2.1.7", "vue-dragscroll": "^1.10.2", "vue-fragment": "^1.5.1", + "vue-moment": "^4.1.0", "vue-removed-hook-mixin": "^0.1.1", + "vue-router": "^3.4.8", "vue2-leaflet": "^1.0.2", "vuex": "^3.0.1", "vuex-class": "^0.3.1", "vuex-persist": "^2.2.0", "workbox-webpack-plugin": "^4.3.1", "workbox-window": "^4.3.1" + }, + "dependencies": { + "ejs": "^3.1.5", + "express": "^4.17.1", + "request": "^2.88.2" + }, + "scripts": { + "build:server": "tsc -p server", + "build:app": "webpack --config webpack.config.js --mode production --progress" } } diff --git a/front/resources/fontawesome/.gitignore b/front/resources/fontawesome/.gitignore new file mode 100644 index 0000000..39d81c9 --- /dev/null +++ b/front/resources/fontawesome/.gitignore @@ -0,0 +1,3 @@ +# this folder is created to store fontawesome pro packages +* +!.gitignore diff --git a/resources/icons/light/bus.svg b/front/resources/icons/light/bus.svg similarity index 100% rename from resources/icons/light/bus.svg rename to front/resources/icons/light/bus.svg diff --git a/resources/icons/light/icons.ai b/front/resources/icons/light/icons.ai similarity index 100% rename from resources/icons/light/icons.ai rename to front/resources/icons/light/icons.ai diff --git a/resources/icons/light/metro.svg b/front/resources/icons/light/metro.svg similarity index 100% rename from resources/icons/light/metro.svg rename to front/resources/icons/light/metro.svg diff --git a/resources/icons/light/train.svg b/front/resources/icons/light/train.svg similarity index 100% rename from resources/icons/light/train.svg rename to front/resources/icons/light/train.svg diff --git a/resources/icons/light/tram.svg b/front/resources/icons/light/tram.svg similarity index 100% rename from resources/icons/light/tram.svg rename to front/resources/icons/light/tram.svg diff --git a/resources/icons/light/trolleybus.svg b/front/resources/icons/light/trolleybus.svg similarity index 100% rename from resources/icons/light/trolleybus.svg rename to front/resources/icons/light/trolleybus.svg diff --git a/resources/icons/light/unknown.svg b/front/resources/icons/light/unknown.svg similarity index 100% rename from resources/icons/light/unknown.svg rename to front/resources/icons/light/unknown.svg diff --git a/resources/images/app-icon.ai b/front/resources/images/app-icon.ai similarity index 100% rename from resources/images/app-icon.ai rename to front/resources/images/app-icon.ai diff --git a/front/resources/images/background-2x.png b/front/resources/images/background-2x.png new file mode 100755 index 0000000..0797290 Binary files /dev/null and b/front/resources/images/background-2x.png differ diff --git a/front/resources/images/background.png b/front/resources/images/background.png new file mode 100755 index 0000000..542bd95 Binary files /dev/null and b/front/resources/images/background.png differ diff --git a/resources/images/favicon-2x.png b/front/resources/images/favicon-2x.png similarity index 100% rename from resources/images/favicon-2x.png rename to front/resources/images/favicon-2x.png diff --git a/resources/images/favicon-72.png b/front/resources/images/favicon-72.png similarity index 100% rename from resources/images/favicon-72.png rename to front/resources/images/favicon-72.png diff --git a/resources/images/favicon.ai b/front/resources/images/favicon.ai similarity index 100% rename from resources/images/favicon.ai rename to front/resources/images/favicon.ai diff --git a/resources/images/favicon.ico b/front/resources/images/favicon.ico similarity index 100% rename from resources/images/favicon.ico rename to front/resources/images/favicon.ico diff --git a/resources/images/favicon.png b/front/resources/images/favicon.png similarity index 100% rename from resources/images/favicon.png rename to front/resources/images/favicon.png diff --git a/resources/images/icon-128.png b/front/resources/images/icon-128.png similarity index 100% rename from resources/images/icon-128.png rename to front/resources/images/icon-128.png diff --git a/resources/images/icon-192.png b/front/resources/images/icon-192.png similarity index 100% rename from resources/images/icon-192.png rename to front/resources/images/icon-192.png diff --git a/resources/images/icon-256.png b/front/resources/images/icon-256.png similarity index 100% rename from resources/images/icon-256.png rename to front/resources/images/icon-256.png diff --git a/resources/images/icon-512.png b/front/resources/images/icon-512.png similarity index 100% rename from resources/images/icon-512.png rename to front/resources/images/icon-512.png diff --git a/resources/images/icon-64.png b/front/resources/images/icon-64.png similarity index 100% rename from resources/images/icon-64.png rename to front/resources/images/icon-64.png diff --git a/resources/images/icon-96.png b/front/resources/images/icon-96.png similarity index 100% rename from resources/images/icon-96.png rename to front/resources/images/icon-96.png diff --git a/front/resources/images/icon-maskable.png b/front/resources/images/icon-maskable.png new file mode 100644 index 0000000..3c42216 Binary files /dev/null and b/front/resources/images/icon-maskable.png differ diff --git a/front/resources/images/icon-monochrome.png b/front/resources/images/icon-monochrome.png new file mode 100644 index 0000000..c6f580f Binary files /dev/null and b/front/resources/images/icon-monochrome.png differ diff --git a/resources/images/ios-192.png b/front/resources/images/ios-192.png similarity index 100% rename from resources/images/ios-192.png rename to front/resources/images/ios-192.png diff --git a/resources/images/ios-80.png b/front/resources/images/ios-80.png similarity index 100% rename from resources/images/ios-80.png rename to front/resources/images/ios-80.png diff --git a/resources/images/ios.png b/front/resources/images/ios.png similarity index 100% rename from resources/images/ios.png rename to front/resources/images/ios.png diff --git a/resources/images/kadet-net-logo.png b/front/resources/images/kadet-net-logo.png similarity index 100% rename from resources/images/kadet-net-logo.png rename to front/resources/images/kadet-net-logo.png diff --git a/front/resources/images/logo-cojedzie.ai b/front/resources/images/logo-cojedzie.ai new file mode 100755 index 0000000..2ae4583 --- /dev/null +++ b/front/resources/images/logo-cojedzie.ai @@ -0,0 +1,1313 @@ +%PDF-1.5 %���� +1 0 obj <</Metadata 2 0 R/OCProperties<</D<</ON[5 0 R 24 0 R 42 0 R]/Order 43 0 R/RBGroups[]>>/OCGs[5 0 R 24 0 R 42 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <</Length 41746/Subtype/XML/Type/Metadata>>stream +<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> +<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c143 79.161356, 2017/09/07-01:11:22 "> + <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> + <rdf:Description rdf:about="" + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:xmp="http://ns.adobe.com/xap/1.0/" + xmlns:xmpGImg="http://ns.adobe.com/xap/1.0/g/img/" + xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/" + xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#" + xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#" + xmlns:illustrator="http://ns.adobe.com/illustrator/1.0/" + xmlns:xmpTPg="http://ns.adobe.com/xap/1.0/t/pg/" + xmlns:stDim="http://ns.adobe.com/xap/1.0/sType/Dimensions#" + xmlns:xmpG="http://ns.adobe.com/xap/1.0/g/" + xmlns:pdf="http://ns.adobe.com/pdf/1.3/"> + <dc:format>application/pdf</dc:format> + <dc:title> + <rdf:Alt> + <rdf:li xml:lang="x-default">Mobile</rdf:li> + </rdf:Alt> + </dc:title> + <xmp:CreatorTool>Adobe Illustrator CC 22.1 (Windows)</xmp:CreatorTool> + <xmp:CreateDate>2020-02-10T19:02+01:00</xmp:CreateDate> + <xmp:ModifyDate>2020-02-10T20:45:43+01:00</xmp:ModifyDate> + <xmp:MetadataDate>2020-02-10T20:45:43+01:00</xmp:MetadataDate> + <xmp:Thumbnails> + <rdf:Alt> + <rdf:li rdf:parseType="Resource"> + <xmpGImg:width>256</xmpGImg:width> + <xmpGImg:height>120</xmpGImg:height> + <xmpGImg:format>JPEG</xmpGImg:format> + <xmpGImg:image>/9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA
AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK
DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f
Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgAeAEAAwER
AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA
AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB
UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE
1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ
qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy
obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp
0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo
+DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7
FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7F
XYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FX
Yq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXY
q7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq
7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7
FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYqo3t7Z2NrLeXs8draQ
KXnuJnWONFHVndiFUe5xV4p5x/5y8/LDQ5JLfSRceYbpKjlaqIrao7GaWhPzRGGKvK9W/wCc1/PN
3KY9D8vafZhzRFuDPeSb9KFGtwT/ALH6MVQa/n1/zlFqTLJYabc8HNEW10dpFJO4ALRyn8cVb/5W
t/zmBB6k02m6uYutJNBCogr2ItVP3k4qsP8Azk5/zkJoY5axpsTKn2v0hpssA8d/TNv2xVknl/8A
5zfuwyp5h8sRup+1Pp85Qge0Mwev/IwYq9s8hfn7+WPneWO00rVPq2qS7Jpl+v1e4YnoqVLRyN7I
7HFXoeKuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV8Zf85GeZvN3
nn84k/Laxn9DTre5tbKztWcpDJc3CIxnnpWvEy0Gxoo2FScVeteQ/wDnEb8uNBhin8wCTzHqYoXM
5aK1Vv8AIgQ/EP8AjIzfIYq9h0by15d0SIQ6NpdppsQFOFpBHAKf881XFUyxV2KuxVivmT8qvy48
yRsuteXLG6ZxQziFYp6e08XCUfQ2Kvm388P+cWNM8r6Be+bfKF/LHZ6comu9Lu25sqcgOUEwofhr
9l6n/K7Yq9S/5xU/MTXfOHkK5t9cla6vtEuFtEvXNXlgaMNH6h6s67gt3FK71OKvasVQuqarpuk6
fPqWp3UVlYWq+pcXU7BI0Ud2ZtsVeF+Yv+czPy20+7a30mxv9ZVDQ3SIlvC3unqkSH6UGKpx5J/5
yu/K3zLexWF1JcaDeTELH+kVRYGc9hPGzqvzk44q9mBBFRuD0OKuxV2KuxV4zr3/ADlh+V+h67qO
i3sWpm80u6msrkx28bJ6tvI0T8SZRVeSmm2KvX7C9hvrG2vYaiG6iSaLkKNxkUMtRvvQ4qr4q7FX
Yq7FWGfml+a/l38ttItNV1y3vLm3vLj6rElikUjh+DSVYSyQilEPfFUP+VX5yeWPzMt9Rn0G1vbZ
NMeJJxfRxRljMGK8PSlmr9g1rTFWd4q7FXg3mn/nLfyroH5g3HlaTSZ57CxuTZajrCyqvpyo/CXh
BwJdY2qCeYO2wxV7yCCKjcHocVdirsVY55/8/eXvInlubzBrzyLZxOsSRQqHmllf7McakqCxAJ3I
FAcVfCHmrUn/ADS/OaW68vg2EnmO9t4bD643AxuY0hBkaL1aDktfhrir0j/oT/8AOj/qYdK/6TL7
/slxVVtf+cPfzea5iW78y6bFbFgJpYrm9lkVK/EVjaCIMQOgLj5jFXo9zqP5DfkVBHZXry615nCh
5OQF7f1I+18ZWK2U9lqpI/m64ql8X/OZ/wCXd9K1nqvl6/XTZqpI7C3uAVJ25xFlFPHc/Tiqzz7/
AM4+6H5/0uw81/lRq0NgmofvJIpJ7iOwkjNatGiJK8MisOLR8QvspG6rBv8AoT/86P8AqYdK/wCk
y+/7JcVSXzn/AM4x/mp5Z8ralr2q63p1xp+nQma5ghurx5GQECirJbopO/dhiqP/AOcYfzs8o+Qo
b7RfMKXES6vdxOl/GqNBCAnCs1WDha91U4q+1cVfD3/OVX5q3vmbztceVrOcroHl6UwNEp+Ga9T4
ZpHA6+m1Y1r0oT+1iqY/lV/ziPrHmrQrfXvMepnRbO9QS2VlFF6ty8TCqyOWZVjDChUUYkdaYqr3
v/OGfmyDznY6bbanHdeWbkNJda1wEUkCIRyjaAs/KRgfgo1D340xV9RXOo+T/wAtvJlqup6h9Q0P
SoY7WGe7keWVgi0VR9p5HIH2VHyFBiryLUf+c1fy6guzFZ6Tql5ArUNxxhiBG/xIrSFj/suOKvQv
y4/Pj8uvzAl+qaPevbarxLfoq+UQ3BAFSUozxyUG54OSB1xV6Fir81vzY/8AJp+cv+25qX/UZJir
9CtH1XTdJ8i6bqWp3UVlYWunW0lxdTsEjRREu7M22KvItZ/5zN/LCyvXt7Gy1LU4kJH1uKKOKJvd
BNIkn/BIMVZn+W//ADkF+XPn66XT9MupLHWGBKaZfqsUslBVvSKs8clKVorcqb0xV6Jd3drZ2st3
dzJb2sCGSeeVgiIiirMzNQAAdzirxHzH/wA5h/lXpV69pYRX+temxV7m0iRINtjxaZ42bfuFofHF
Xj//ADkJ+fXk78yvJmmWGj295aX9nqAuJoLuNADH6MickeN5Ad2HWhxVO/8AnE3zbovlHyP568w6
1I0em2M2nmdkXm/7wyRKFXuSzjFXp3/Q3v5N/wDLTff9Ijf1xVFaX/zlV+VOqala6bp76hcX17Kk
FtAloxZ5JGCqo37k4q8q/MFv+cXk/NXUtS16XV11W1vXOraZBHWymuo2Act8Jk4swJYK4r7d1X01
5v8AOnljyfo76v5j1CPT7FTxV3qXdzuEjjUF3bbooPj0xV4tcf8AOa35bx3TRw6Rq00CtQTiO3Us
O5CmavyrTFXqX5d/m55F/MC2kl8u3/qXMADXOnzr6VzED3aM9V/ykJX3xV5l/wA5q/8AkrNK/wC2
5b/9Qd3ir5f/ACU/8m55Q/7atr/ydGKv0fxV2KvFfzd/5xj0H8wfNEHmKHUm0a7kVY9VEcImFwsY
ojirpwk4gJy3FANtt1Xz1/zkX+UfkX8uLrRrPy9ql1dahdpI99ZXbxSuka8RHLWJIuHM8hQjem3T
FXr3/OElxqb+UPMMExY6bDfxmzrXiJXirOF7dBGSPfFX0jirAPz+/wDJNebP+YFv+JLir86sVfqp
ir8zNR4t+YNz+maBG1Z/0kWrxobk+tWvxU64q/TJFRUVYwFRQAirsAB0ApireKvgj/nJ7z7qHmf8
0NS09pW/RXl+RtPsravwCSL4biQgbcnlBFf5QB2xV6d5G/5wy0vUPKtrf+ZtYu7bWL2FZ1trNYxF
b+oAypJ6qM0jBT8VOO+29KlV4P5/8meYPyu8/PpRvP8ATtPaK707UrflGWQ/HFKtd1YEUI3owIqe
uKvvr8sPNknm78v9C8xTKFuNQtUe5VRRfXSsc3Efy+ojU9sVfn7+bH/k0/OX/bc1L/qMkxV6n/zl
F571K4j8r+TIJGj0uy0mzvbuMEgTXE0Q4cx3Ecajj7scVeTeVR+W4gmbzY2sm4JIt49KW1CAU2Z3
uGJO/wCyFHzxVKJrmCy1c3Oh3FxHFbzCXT7mQCG5TieSMfTZwrr4q2Kva/z0/O3W/Nf5eeStK5mH
9K2H6R13h8InmguZbNelKJ6tpJJx6br4Yqv/ACI/5xli8/aD/ibzBqE1ho0zvFYQWgX15jExSSQv
IroihlKj4TU16U3VY1+fP5F3H5Y39jNbXp1HQ9T5razyLxmjkiClo5ePwmoaqsOu+wpuqzH/AJxr
/Lqw/MHyH5v8u6he3FjZvfadPLJa8Ob+kk5VD6iuOPIhunbFWE/n3+XHkf8AL3XrXy/oOpXmo6mI
vX1T6yYikKyUMKARoh5svxGv7JXxxV6j/wA4d/lT60835h6pFWKEva6Cjj7Um6z3Ar/LvGvvy8MV
eI/nX/5Nzzf/ANtW6/5OnFWQ/wDOSvnvUfNP5p6taySt+jdAnk0ywttwqGBuE706cnlVt/DiO2Ks
W0lPyo/QfHV5de/TrAn1LSOz+qI29Bwkf1JB035L8sVSzyh5r1byl5msfMGjzNHeWEokTfiJE6PG
4FfhkSqsPA4q+xf+cp9J1Pzb+TOn6hodrJeJDeWuqyRRKZJPqz20qcgq1J4m4UmnQVPQYq+VPyfZ
bP8ANnyo94RbJDqlq0zTfuwgEgNWLUp9OKv0L/xZ5V/6vNj/ANJMP/NWKu/xZ5V/6vNj/wBJMP8A
zViqWed/NLWH5eeYvMGgzw3dxp2n3dxayxsssYlhhZwTTkp4EciMVfB/5ceSfMH5s/mF+jrjUWN1
dB73VdUuC0sgiQgO+5q7EsqqK037DFX3R5N0z8v/ACBoFv5W0u/tbWCxr6q3FxEJ3lY1eSapWrsf
YU6AAADFU7/xZ5V/6vNj/wBJMP8AzVirA/z28yeXbn8ofNMFvqlnNPJZMI4o54mdjyXYKGJOKvg7
QfLmu+YNRg07RrGa+u7iRYo44UZ/iY/tECigdSTsBvir9QsVfC3/ADlL+V195W8+XXmG2gY6B5il
a5jnUfBFdv8AFPC57FmrIviDt9k4qyb8qf8AnLy48u+X7fQvNunTarHYosVlqNs6Cf0kFEjlSTir
lRtz5Vp1BO5VVdR/5zR1yXzpY3dhpYt/KVuSl7pzlXurhX2Mnq0ARk6oq7fzE12VeXfnto6Q+ern
zJYK0nl/zdXWtHu2RkEiXPxzKQwFHjlZgy9eh7jFXv8A5I/5zI8nnyzbp5ttryHXraMJcG1iWWK5
ZRT1EJdOLPSrK1AD0JxV87fmr5/1P80PzAfV4bJ4zcelY6TpyVklESsRGnwj4nd3LbdzQYq+7vyq
8qXHlP8ALvQPL1yQbuxtVW6oagTSEyyqD3Cu5AxV8A/mx/5NPzl/23NS/wCoyTFXpn/OUXkzUbSf
yv5sRGfS9S0iztJJQKiO5gi+w3hzjIK+NG8MVRn5S/nF+SOn+VYNJ89eS7CbVLBCkeqRaZZ3JukF
SplLqriX9kk1DdSRir1b8nfMf5FfmZd6rZ2nkTRtNvbB/UtrSewsWkmszRRN8MdAwfZ1FeNV3NcV
ef8A/OYX5aLpbaD5j0LTorTQLa2Olz21nEsUFs3ryXEbenGFVRK9xJvT7XXciqql/wA4/wD/ADk3
oXlHyrF5T82QXAtLFpDpmoWyCWkcrtK0UyFg2zseLLXY0oKVxVif/ORX582v5kXNjpmi20tt5f0x
2mV7gBZp52HHmVUsEVFqFFa7knwCr1L8ipE/Kb8iNY88+YIvSl1aQXOnWjfDJOgQR2ab/F+9dmb2
T4sVfLWra5deYPMlxrOvTySz6jcmfUJ4wC9Har+mrFV+FdkWoHQdMVfVXlv/AJy4/LTSdM07y/o3
lrVY7W1jjtLK3UWxNBRVH97uzHqe5xV86/nUSfzb83Eih/St1Uf89Diqd/8AORnkzUfK35s61LPG
TaazcyarYXDLVJFuXMsiiooTHKzKR8vHFXp+g/nv/wA46v5aSfXPy90+LzBFGBNZ22k2LwSygU5R
SMBxRjueYqv+V3VeqflFF+Sn5keVE1qy8laFa3cTmDUtPOn2btBMNwOXpLyV1+JWp7dQcVevW9vB
bwR29vGsNvCqxwwxqFREUUVVUUAAAoAMVfCH5xeXJ/Mv/OSuq+X4Jlt5tV1C1tY53BKo0sEKhiBv
QVxVmf8A0JD5q/6mWx/5EzYq7/oSHzV/1Mtj/wAiZsVep6bo2l/kN+RepRa6w8wK0sr3FqoEcVxL
e8YFgUOGpGUUcyQf2jTtirCf+cc/zh8m6v59/QkHkrTfLmqalBMllf6YnEusSmd4JarWhWLlUGlV
6Yqv8/8A/OIXmDzJ511rzBa+Y7aODVbuS7SK4ikMieq3IoSm1EJ4r7UxVj//AEJD5q/6mWx/5EzY
qkfnf/nErzF5T8p6n5juNes7mDTITPJBHFKruAQKAnbvir0f/nCH/lFvMv8AzHQ/8mcVfSmKoHW9
D0fXNMn0vWLOK+0+5XjPbTqGRh8j0I7EbjFXgnmH/nCryPe3jz6JrN7pELty+quqXcaD+WMsY5Kf
6zMcVTbyR/ziH+W/l+8jvtWluPMVzEQyQ3QWO1DDcEwJu/ydyvtir1Tzh5C8p+cNFOjeYNOjvLEb
wjdHhYCgaF1oyEex9jtirwjUP+cIfLEl0z6f5mvba1J+GGeCKdx/z0VoQf8AgcVejflh/wA47fl/
+X90upWccupa4oITU70qzRchRvRjUKkdR3oW7cqYqzLzp548s+TdEm1jzBex2ltGrGNGI9WZwKiO
FOrufAfTtir86r19S88+f7mWyt6aj5l1SWWG2XcLLezlwtfBTJ18MVfo5f8AlTQNS8tjy5qlnHf6
QYEtntpxyVkjUKp8Qw4ghgag7g1xV4Rrf/OE3k65vHl0fXr3TrdzUW00cd0Fr2VqwtQduVT74qzz
8q/+cdfI35eX/wClrN7jUtb4siX92y/ulccXEUcYVV5DqW5H3xV6TqWm6fqdhcafqNvHd2N0hiub
aZQ8bowoVZT1xV4D5l/5wt8jX961xoerXmjROam0ZVu4l9oy5jkA/wBZ2xVNfI3/ADiL+XXl2+j1
DVpp/MV1CwaKK6Cx2oYbgmBK8/k7lfbFWafml+TPl78yINPtdb1HUbSy00s8Fnp8kEUTOwC83EkM
xLKo4rvsCfHFXn3/AEJV+Vn/AFddc/6SLP8A7JMVTDy9/wA4h/lloevadrVvf6vcXGm3MV3DDcTW
rQtJA4kQSKlsjFeS7jkMVUvNf/OI/krzL5l1PX7rWdShudUuZLqaKIwcFaVixC8oyab9zir1Hz1+
XvlLzzo50rzJYrdwLVreYHhNA5FOcMg+JT+B7gjFXhl3/wA4QeWXuy9p5mvYbOu0MsEUslK9PUVo
x/wmKvXvyv8Ayd8m/lvZXEGgxzSXV5x+u6hdOHmlCV4r8IRFVeRoFUe9cVZxir4r8zf+tkw/9tzT
/wDk1DirNv8AnL/8zvOmganpHlvQr6fSrK6tWvLq7tXMUszGRoxF6iEOqoEqQCK8t8VVf+cQPzM8
5+YbvWvL+vXtxqtpZQR3dreXTtLLExfg0RlerMrg1UMduJpir33zv5N0Xzn5YvfLmtI7WF8oDtE3
GRHRg6SIxBAZGUEVBHiCMVedflV/zjP5S/L7zEfMMV/c6pqUaPHZNOqRpCJAVdgqdXKHjWvQnbFX
sOKvgH8z/wA7PzPvfzC1aaLXb/SYtPvZoLLTrWeSCOFIJGjVWjQqrPQfGWBrv22xV9D6l5t1jzb/
AM4k3vmDWQP0nd6XMty4UIJGguWgEvEAAeoIg5oKb7bYqkX/ADhD/wAot5l/5jof+TOKvpTFXYq7
FXYq7FXYq7FXxD+bP5R/mr5u/OLzE+laBf3NpLdn6rezo0NqYuK0KTz8Iyo/yTir3D8hv+cbrH8v
5l8wa5PHqPmlkKRekCbe0VxRhEWAZ5GGxcgbbAdSVXt2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2Ku
xV8RedtRsdN/5y7N/fzpa2VrrNhLcXErBUjRYoSzMx2AAxV7/wCfte/5xw8+6fFZeZvMGk3QtizW
lwl4sU0JenL05EYGjcRVTUGgqNsVX+Q/Mf8Azjl5D02XT/LPmDSLOO4YPdSteLJNMyiimSR2LHjU
0HQVNBucVZN/yuv8o/8Aqb9K/wCkqL+uKu/5XX+Uf/U36V/0lRf1xV3/ACuv8o/+pv0r/pKi/rir
zfzbov8Azib5r8wNr2razpZ1CUhrtoNQ9BJyNqyrG6jl4stCe5xVFfmz+Y35TP8Ak3rvl7y7r+lM
Rp/1bTtNtJ4+ilQscaKewGKse/5wh/5RbzL/AMx0P/JnFX0pirsVdirsVdirsVdirsVdirsVdirs
VdirsVdirsVdirsVdirsVdirsVdir55/5ye/I/y5quk6x+YkNxLZ6zY2qvdxIFeK69ILGhYGjK4S
i8gegG2KvHPyL/5x4s/zN8vX+rT63JpbWV39UEKW6zBh6SScqmRKfbpirHvN35R2+gfnNY/l2mpv
cQ3l3p9odRMQVlF+YwW9PkQeHq/zb4q9r/6Ec0r/AKm6f/pCT/qtirv+hHNK/wCpun/6Qk/6rYqx
f8zf+cTtP8l+RdW8zxeZJb2TTY0kW1a1WMPzlSOhcStT7demKpH+R3/OONl+ZnlO716fXZNMe2v5
LEQJbrMGEcMMvPkZE6+tSlO2KsS1T8qrey/OtPy4Gou8L39tY/pIxANS4VGL+lyp8PqdOWKvuT8s
vy10D8vPLKaDoxkkRpGnu7qYgyzTMApdqAAfCoAA6AfTirLMVdirsVdirsVdirsVdirsVdirsVdi
rsVdirsVdirsVdirsVdirsVdirsVSjzf5ZsvNHlfVPL167R2uqW720ksdOacxs612qpod8VfItx/
zh7+btlcyw6Zq2nS2nImOVbmeAsOgLx+keLU6ip+eKsr/Kn/AJxP826V5207zJ5w1O1aHSp47u3t
rSSWeaWeBg8XN5EjVUVgDsSTSm3XFX1NirsVSLzz5SsvN/lHVPLV7I0NvqcJiM0dCyMCGRwD14uo
NO+KvkqX/nD/APOCzmkh0/VdOe15EpIl1cQ8h0BZPS2ag33PzxVmf5Pf84q+aNB872XmjzhqNrIu
mSC4trS0klmkknQUjMjukYVUNG2rWlNsVfT+Kv8A/9k=</xmpGImg:image> + </rdf:li> + </rdf:Alt> + </xmp:Thumbnails> + <xmpMM:OriginalDocumentID>uuid:C1BCCE1871B8DB11993190FCD52B4E9F</xmpMM:OriginalDocumentID> + <xmpMM:DocumentID>xmp.did:d81b3b0d-0e8f-c849-b804-e1e269280e9e</xmpMM:DocumentID> + <xmpMM:InstanceID>uuid:7aa877f2-4af2-431b-9320-eb2b2a4d2bac</xmpMM:InstanceID> + <xmpMM:RenditionClass>proof:pdf</xmpMM:RenditionClass> + <xmpMM:DerivedFrom rdf:parseType="Resource"> + <stRef:instanceID>uuid:a752ce14-e6d8-4298-87fb-c8da083631b3</stRef:instanceID> + <stRef:documentID>xmp.did:0c3af16f-48bb-7a4d-9f1e-e4defd3f9a11</stRef:documentID> + <stRef:originalDocumentID>uuid:C1BCCE1871B8DB11993190FCD52B4E9F</stRef:originalDocumentID> + <stRef:renditionClass>proof:pdf</stRef:renditionClass> + </xmpMM:DerivedFrom> + <xmpMM:History> + <rdf:Seq> + <rdf:li rdf:parseType="Resource"> + <stEvt:action>saved</stEvt:action> + <stEvt:instanceID>xmp.iid:f9e2fba2-6d27-bc4d-9723-a29fada23bc8</stEvt:instanceID> + <stEvt:when>2018-09-22T13:42:09+02:00</stEvt:when> + <stEvt:softwareAgent>Adobe Illustrator CC 22.1 (Windows)</stEvt:softwareAgent> + <stEvt:changed>/</stEvt:changed> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <stEvt:action>saved</stEvt:action> + <stEvt:instanceID>xmp.iid:d81b3b0d-0e8f-c849-b804-e1e269280e9e</stEvt:instanceID> + <stEvt:when>2020-02-10T19:02+01:00</stEvt:when> + <stEvt:softwareAgent>Adobe Illustrator CC 22.1 (Windows)</stEvt:softwareAgent> + <stEvt:changed>/</stEvt:changed> + </rdf:li> + </rdf:Seq> + </xmpMM:History> + <illustrator:Type>Document</illustrator:Type> + <illustrator:StartupProfile>Mobile</illustrator:StartupProfile> + <xmpTPg:NPages>1</xmpTPg:NPages> + <xmpTPg:HasVisibleTransparency>False</xmpTPg:HasVisibleTransparency> + <xmpTPg:HasVisibleOverprint>False</xmpTPg:HasVisibleOverprint> + <xmpTPg:MaxPageSize rdf:parseType="Resource"> + <stDim:w>1808.740000</stDim:w> + <stDim:h>576.000000</stDim:h> + <stDim:unit>Pixels</stDim:unit> + </xmpTPg:MaxPageSize> + <xmpTPg:PlateNames> + <rdf:Seq> + <rdf:li>Cyan</rdf:li> + <rdf:li>Magenta</rdf:li> + <rdf:li>Yellow</rdf:li> + <rdf:li>Black</rdf:li> + </rdf:Seq> + </xmpTPg:PlateNames> + <xmpTPg:SwatchGroups> + <rdf:Seq> + <rdf:li rdf:parseType="Resource"> + <xmpG:groupName>Default Swatch Group</xmpG:groupName> + <xmpG:groupType>0</xmpG:groupType> + <xmpG:Colorants> + <rdf:Seq> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>White</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>255</xmpG:red> + <xmpG:green>255</xmpG:green> + <xmpG:blue>255</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>Black</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>0</xmpG:red> + <xmpG:green>0</xmpG:green> + <xmpG:blue>0</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>RGB Red</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>255</xmpG:red> + <xmpG:green>0</xmpG:green> + <xmpG:blue>0</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>RGB Yellow</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>255</xmpG:red> + <xmpG:green>255</xmpG:green> + <xmpG:blue>0</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>RGB Green</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>0</xmpG:red> + <xmpG:green>255</xmpG:green> + <xmpG:blue>0</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>RGB Cyan</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>0</xmpG:red> + <xmpG:green>255</xmpG:green> + <xmpG:blue>255</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>RGB Blue</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>0</xmpG:red> + <xmpG:green>0</xmpG:green> + <xmpG:blue>255</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>RGB Magenta</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>255</xmpG:red> + <xmpG:green>0</xmpG:green> + <xmpG:blue>255</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>R=193 G=39 B=45</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>193</xmpG:red> + <xmpG:green>39</xmpG:green> + <xmpG:blue>45</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>R=237 G=28 B=36</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>237</xmpG:red> + <xmpG:green>28</xmpG:green> + <xmpG:blue>36</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>R=241 G=90 B=36</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>241</xmpG:red> + <xmpG:green>90</xmpG:green> + <xmpG:blue>36</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>R=247 G=147 B=30</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>247</xmpG:red> + <xmpG:green>147</xmpG:green> + <xmpG:blue>30</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>R=251 G=176 B=59</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>251</xmpG:red> + <xmpG:green>176</xmpG:green> + <xmpG:blue>59</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>R=252 G=238 B=33</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>252</xmpG:red> + <xmpG:green>238</xmpG:green> + <xmpG:blue>33</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>R=217 G=224 B=33</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>217</xmpG:red> + <xmpG:green>224</xmpG:green> + <xmpG:blue>33</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>R=140 G=198 B=63</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>140</xmpG:red> + <xmpG:green>198</xmpG:green> + <xmpG:blue>63</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>R=57 G=181 B=74</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>57</xmpG:red> + <xmpG:green>181</xmpG:green> + <xmpG:blue>74</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>R=0 G=146 B=69</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>0</xmpG:red> + <xmpG:green>146</xmpG:green> + <xmpG:blue>69</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>R=0 G=104 B=55</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>0</xmpG:red> + <xmpG:green>104</xmpG:green> + <xmpG:blue>55</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>R=34 G=181 B=115</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>34</xmpG:red> + <xmpG:green>181</xmpG:green> + <xmpG:blue>115</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>R=0 G=169 B=157</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>0</xmpG:red> + <xmpG:green>169</xmpG:green> + <xmpG:blue>157</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>R=41 G=171 B=226</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>41</xmpG:red> + <xmpG:green>171</xmpG:green> + <xmpG:blue>226</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>R=0 G=113 B=188</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>0</xmpG:red> + <xmpG:green>113</xmpG:green> + <xmpG:blue>188</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>R=46 G=49 B=146</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>46</xmpG:red> + <xmpG:green>49</xmpG:green> + <xmpG:blue>146</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>R=27 G=20 B=100</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>27</xmpG:red> + <xmpG:green>20</xmpG:green> + <xmpG:blue>100</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>R=102 G=45 B=145</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>102</xmpG:red> + <xmpG:green>45</xmpG:green> + <xmpG:blue>145</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>R=147 G=39 B=143</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>147</xmpG:red> + <xmpG:green>39</xmpG:green> + <xmpG:blue>143</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>R=158 G=0 B=93</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>158</xmpG:red> + <xmpG:green>0</xmpG:green> + <xmpG:blue>93</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>R=212 G=20 B=90</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>212</xmpG:red> + <xmpG:green>20</xmpG:green> + <xmpG:blue>90</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>R=237 G=30 B=121</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>237</xmpG:red> + <xmpG:green>30</xmpG:green> + <xmpG:blue>121</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>R=199 G=178 B=153</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>199</xmpG:red> + <xmpG:green>178</xmpG:green> + <xmpG:blue>153</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>R=153 G=134 B=117</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>153</xmpG:red> + <xmpG:green>134</xmpG:green> + <xmpG:blue>117</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>R=115 G=99 B=87</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>115</xmpG:red> + <xmpG:green>99</xmpG:green> + <xmpG:blue>87</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>R=83 G=71 B=65</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>83</xmpG:red> + <xmpG:green>71</xmpG:green> + <xmpG:blue>65</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>R=198 G=156 B=109</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>198</xmpG:red> + <xmpG:green>156</xmpG:green> + <xmpG:blue>109</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>R=166 G=124 B=82</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>166</xmpG:red> + <xmpG:green>124</xmpG:green> + <xmpG:blue>82</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>R=140 G=98 B=57</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>140</xmpG:red> + <xmpG:green>98</xmpG:green> + <xmpG:blue>57</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>R=117 G=76 B=36</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>117</xmpG:red> + <xmpG:green>76</xmpG:green> + <xmpG:blue>36</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>R=96 G=56 B=19</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>96</xmpG:red> + <xmpG:green>56</xmpG:green> + <xmpG:blue>19</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>R=66 G=33 B=11</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>66</xmpG:red> + <xmpG:green>33</xmpG:green> + <xmpG:blue>11</xmpG:blue> + </rdf:li> + </rdf:Seq> + </xmpG:Colorants> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:groupName>Grays</xmpG:groupName> + <xmpG:groupType>1</xmpG:groupType> + <xmpG:Colorants> + <rdf:Seq> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>R=0 G=0 B=0</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>0</xmpG:red> + <xmpG:green>0</xmpG:green> + <xmpG:blue>0</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>R=26 G=26 B=26</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>26</xmpG:red> + <xmpG:green>26</xmpG:green> + <xmpG:blue>26</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>R=51 G=51 B=51</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>51</xmpG:red> + <xmpG:green>51</xmpG:green> + <xmpG:blue>51</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>R=77 G=77 B=77</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>77</xmpG:red> + <xmpG:green>77</xmpG:green> + <xmpG:blue>77</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>R=102 G=102 B=102</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>102</xmpG:red> + <xmpG:green>102</xmpG:green> + <xmpG:blue>102</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>R=128 G=128 B=128</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>128</xmpG:red> + <xmpG:green>128</xmpG:green> + <xmpG:blue>128</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>R=153 G=153 B=153</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>153</xmpG:red> + <xmpG:green>153</xmpG:green> + <xmpG:blue>153</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>R=179 G=179 B=179</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>179</xmpG:red> + <xmpG:green>179</xmpG:green> + <xmpG:blue>179</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>R=204 G=204 B=204</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>204</xmpG:red> + <xmpG:green>204</xmpG:green> + <xmpG:blue>204</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>R=230 G=230 B=230</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>230</xmpG:red> + <xmpG:green>230</xmpG:green> + <xmpG:blue>230</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>R=242 G=242 B=242</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>242</xmpG:red> + <xmpG:green>242</xmpG:green> + <xmpG:blue>242</xmpG:blue> + </rdf:li> + </rdf:Seq> + </xmpG:Colorants> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:groupName>Mobile Color Group</xmpG:groupName> + <xmpG:groupType>1</xmpG:groupType> + <xmpG:Colorants> + <rdf:Seq> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>R=136 G=168 B=13</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>136</xmpG:red> + <xmpG:green>168</xmpG:green> + <xmpG:blue>13</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>R=127 G=71 B=221</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>127</xmpG:red> + <xmpG:green>71</xmpG:green> + <xmpG:blue>221</xmpG:blue> + </rdf:li> + <rdf:li rdf:parseType="Resource"> + <xmpG:swatchName>R=251 G=174 B=23</xmpG:swatchName> + <xmpG:mode>RGB</xmpG:mode> + <xmpG:type>PROCESS</xmpG:type> + <xmpG:red>251</xmpG:red> + <xmpG:green>174</xmpG:green> + <xmpG:blue>23</xmpG:blue> + </rdf:li> + </rdf:Seq> + </xmpG:Colorants> + </rdf:li> + </rdf:Seq> + </xmpTPg:SwatchGroups> + <pdf:Producer>Adobe PDF library 15.00</pdf:Producer> + </rdf:Description> + </rdf:RDF> +</x:xmpmeta> + + + + + + + + + + + + + + + + + + + + + +<?xpacket end="w"?> +endstream endobj 3 0 obj <</Count 1/Kids[7 0 R]/Type/Pages>> endobj 7 0 obj <</ArtBox[56.9269 32.0 1751.81 544.0]/BleedBox[0.0 0.0 1808.74 576.0]/Contents 44 0 R/CropBox[0.0 0.0 1808.74 576.0]/LastModified(D:20200210204543+02'00')/MediaBox[0.0 0.0 1808.74 576.0]/Parent 3 0 R/PieceInfo<</Illustrator 45 0 R>>/Resources<</ColorSpace<</CS0 46 0 R>>/ExtGState<</GS0 47 0 R>>/Properties<</MC0 42 0 R>>>>/Thumb 48 0 R/TrimBox[0.0 0.0 1808.74 576.0]/Type/Page>> endobj 44 0 obj <</Filter/FlateDecode/Length 4312>>stream +H�|�I�]� E�wgWV]t��iA�F�a�����M����]�H�Ym~����˟����z�~{ţ�~�g�xK��?^?�����o���qD�w��`�O,����#�b:RK�s�ԐrL�������w ����(�x��r;�9�ُw�a�y|���+�R %fl}�;���o�G_W#i;g]��!g)���`;9�X�-��t"c@҉V��n�#�&�f(�^�Lʡ�~�(=����B3 �5��V���V&4�Zl��j�h)IJ��ΎVBԝ�� TCg�pl=�5/��m��>�p���ݴ֕���p][ �m�������0���N���cBϞ��ձ�e�X�;K��y�$���3X���)�K��C����[�\߳�^)E�l�L��Lo�^Vd +Wd{���`t��!�� d4p����3z�c*�_�}.�C���G��W����^��z˹����S�K����KcJnL��6�:#5�G?/��}�o|�Uo3�^��]Gou�ת>���~�:�V��6}�o\�JŴ,���zޣ� ��aC�Y��Z���}���t��COU��\,��94)*��+�bo���Ђ +�?����@�9�Af'�^J�$w%�Vl����Z̾R�� ��[_���k�N���Z�a*;9��9BR�'���&����=��&fw�be�z�ұ�)�aװ6�Y�(,��BY�Wv�͞��:��82 ʬ��7Se�r�!W{w�XPК9S�"7J�h��nN� l��LOf +�H�:Qԭ ��ҹV^�Am�ۋ�uYX������n1p��?y��z#{u���ζ(Z�;{O��X�ҷ�x��EK(j7�)O~p�#SѬl�v�(z��~(�]'�����ۼ�h%OVV�f!�m�r�c���<�$\}����zeI���6�?��o��P�=-K��qk�x�ۺ�ń�H�'��]b��2�cy���*���m�����դ��E���,���f�m�B�M[�>�"���re_�q�S�NuJr����Gv]a-�G�m�g�x魑DETT]Y������#uºG_:i1� ���>�,}X�uo�#RsʺE!v���O���&��k�ˢ?��������O +�Ӕ��Y��p��x��߂#�C��?.�����S*�sMV�����ȿk�� ��v�G.�|"�$�u��n�^��%i��,֘խ�N-��̭f?�Ş��S+��ءXY�^E(E����W|�~ڜ'�:�ZV�i,�����RC�!}R�;��Х�ɥ��L���$�tK��j��F�^2��|��x��8��kXXS�א�ԬD�����2���G�TS�#�X"�X������a:�t�����s�>bM8f�^��}�۪�x�)��RUQ���@�ëf�F;i�!P�����S����r.���ૌ��N�>��Q"q' e�XVrGN5۾��"Zf��j�e��v��H�!���M�n[0�bWϰD~�N��٢�%"��;���QbR���a�\<����GX=5�����1�@�H@��ғ4eM�k%��I����hl]��C7����V�ۢ�r�K6[�p�_S��F� cJq��:���p�R�#Gw��d01��T[���DG52���S{��&P2�o A>�i*���~H�!�(�q����k3]�wͰ��!$�\/H�*�%<��.�����K�4����nчTQ���-Y���iVʮ8+�q�y�hN7FL�R���xiJV@�\��1Ɣ��"@��P2h3�bY���]���FF���"�9��h���qd��2s��k,�{x]��Y<G���Fq��T}]�;c�|�P)L/ +���X�6�V=\}G��R�$��$S��b�"�T ;&%]�����G>[� +��m<���ƙ}I��ڋ� 7���f۩Y,�l�ߒ�f������}���A)Z��a�c�~ip�<�p���$��*%� +�0����i���{�J���i��h�Z!)� q(4Y�o��m�T��ޤR*Ś���-+�o��a#L��i�{� ��d�^Q�3��Jc�j�)����3�";q�� �+`G �#��#�J�Bihb/K�@wP&����Z��Acy<F�,�i�,�+yh�<���B�e>f�j<���p��i&�H���Ӆ;�I�i�)jh��q\��[� +� ���.E�.7����_L�j����W%Un�mz�[�C*zҵ@��DLg��,HH&�X�ńo$�Q�@vK�.�h��%[o�>���-�J���PQ��QSV!n$�e���H�ddf��h�,Ff��$>^T���b�q"0��I_m�}�2�� ��2��Ղ� ���y������yl�ċŶ�XB�w�!�U�lBI�9U � �7�N5�L�Li'q��)͊���)�6��VŚ��J�(W�����2���b��/)b�B 22�V\�Z2��C1rQ��[�Z4&K�J���X�� +�I�v�rK���TU��A�xjѥ����N1�!5d�^�+j1�z���T2��ڱY��*q��� ��Jm�RRζ�S�p>U7�D�kßDž��b�*��ߧBL��6���+弪���r,�J�!����[T**���n�[QE���v�����P-��� ��E��؟i +�FAڼ +}���,���f����M�$5��s��@K�O{�Xr +����|]U3b@�H����tF�#���ΰq�^-_�T��*�d]:x��V��'��7e��Kp[�t=]��0�ж�s�Kc�����G��eA�KR���d5�]�mQi�8���?�M���{�L.)Ҥ�:m�-�U,6�����5�8!��^����y�gl�V���4�}������V[�[�+��rx�]��m�їK*2��{m�h��C4̰H|U��q3"���l}�dn���+�6�E��Nq�Ӗ�M�m�հnO�qv>�N��+v&�Mf���|�Q�p$Iٲ��[��C(I�$Pj��-D�2s�$�t���e��^Pe����i�S,�� N�.q�A�q��8 +�&���f�Q�`��R�����\suoPa��eY����L���_z�` �KUJ�(Я�1��Y}�����{m4�"Ցs8kmA6�/�h.�T[��PIx�^g��������`�V�c=��W�᱑ڌ����<�5p� ���GU��ˢ��5;B��&Sk�dl%"�h�IZPC���iN�����7r��|�p���jxY[����4%��_ +z��:��B��x��lV�IH� �_�����\������-+L� �@�����BHO�123կ=��{��$�(��E6�5������Rρ�P�F��'0�#��g��{�oa��o�>T�D��o*�nrT���tN�*���HB��x)�3H]�|�oo�=r���!�\��S��(%I��TD�E�V�'S�]��S鉎<���y�����4���� ��mk���5_���:�ip܉ ;��v��([����t[��^�ݑ͔�,��aY���Er�OZVj�]vT���H��9�<�_�����y�}N؊������^@���h�MkCA7,�����{�*��ݞ���Rs��� +�PDRwu{��U2nVM3/������A�U&�<��ZY �OHz_����*4�@Ǭ1�C:�[>��K ���r� �YmӜ�8f�B�reKaH����%8�w����{����C���j�����L%TW��z�T�- rҺD8��" rPCk������O�Gѯq F�p;�P��!*�{�W��5���o��o�x<��c��f�bҁ�̅(��uw�6Ԕ_ˠEaR������]n����O�1-�7|nd���6�� ^_|�s��q�7��8�`=�_c���b�+�o a�d �+���Y�o�$KuM��v)C"2���,��eu�4Ma�ULLt��y����%ipW-�c��q��z���h�#;��&�̢{\ξh�BD�����]�lB��5��n����x�J̀S�X6q��������>M8 ~\0��冏�b#H@R��\�|��%�w�[�)�H���$���Z�]��T�p����������̀>����w`��ϸ`�iŕ��b�#VP֜� �U����s{��p�E�?~�[h�-���Y��f�}�,����*��P�g��*��U(�[��Y��l�� +��B��N��_~z�����X�O +endstream endobj 48 0 obj <</BitsPerComponent 8/ColorSpace 49 0 R/Filter[/ASCII85Decode/FlateDecode]/Height 33/Length 330/Width 106>>stream +8;Yi^=VAS*$q#+9$g'Lo!%kK-ALU1Ur7*X+Sn1"1>5pV*.rKo'gk=A!@d._\/\6cq +FoNs)en\cn=BUh%>31?3d67p7nWPlo87Lf\c>$6K3rp&\b\L(?r8)Jq3=0AUfbBer +%4^j0Q,J$tm\#-&!\7X$EDj]8,8kje$L/5QE2S+^F!fD70p7Wq7PZFFPH'E/Oc<AD +@jF:R4BmJ3,W-/'grWV0@/f9KWBenjO&:.Q4i?R3D_u_He5':a.ma8ki_1TKWXHC- +,*eatGnB\+krmH7a=;@)P8sH/Fs6&++aMRP:nEO<H9EYsT5BmWnifr5*WlD9'!ts~> +endstream endobj 49 0 obj [/Indexed/DeviceRGB 255 50 0 R] endobj 50 0 obj <</Filter[/ASCII85Decode/FlateDecode]/Length 428>>stream +8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0 +b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup` +E1r!/,*0[*9.aFIR2&b-C#s<Xl5FH@[<=!#6V)uDBXnIr.F>oRZ7Dl%MLY\.?d>Mn +6%Q2oYfNRF$$+ON<+]RUJmC0I<jlL.oXisZ;SYU[/7#<&37rclQKqeJe#,UF7Rgb1 +VNWFKf>nDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j<etJICj7e7nPMb=O6S7UOH< +PO7r\I.Hu&e0d&E<.')fERr/l+*W,)q^D*ai5<uuLX.7g/>$XKrcYp0n+Xl_nU*O( +l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~> +endstream endobj 42 0 obj <</Intent 51 0 R/Name(Layer 1)/Type/OCG/Usage 52 0 R>> endobj 51 0 obj [/View/Design] endobj 52 0 obj <</CreatorInfo<</Creator(Adobe Illustrator 22.1)/Subtype/Artwork>>>> endobj 47 0 obj <</AIS false/BM/Normal/CA 1.0/OP false/OPM 1/SA true/SMask/None/Type/ExtGState/ca 1.0/op false>> endobj 46 0 obj [/ICCBased 53 0 R] endobj 53 0 obj <</Filter/FlateDecode/Length 2574/N 3>>stream +H���yTSw�oɞ����c [���5la�QIBH�ADED���2�mtFOE�.�c��}���0��8��8G�Ng�����9�w���߽�����'����0��֠�J��b� � + �2y�.-;!���K�Z� ���^�i�"L��0���-�� �@8(��r�;q��7�L��y��&�Q��q�4�j���|�9�� +�V��)g�B�0�i�W��8#�8wթ��8_�٥ʨQ����Q�j@�&�A)/��g�>'K����t�;\�� ӥ$պF�ZUn����(4T�%)뫔�0C&�����Z��i���8��bx��E���B�;�����P���ӓ̹�A�om?�W= +�x������-������[����0����}��y)7ta�����>j���T�7���@���tܛ�`q�2��ʀ��&���6�Z�L�Ą?�_��yxg)˔z���çL�U���*�u�Sk�Se�O4?�c����.�������R� ߁��-��2�5������ ��S�>ӣV����d�`r��n~��Y�&�+`��;�A4�� ���A9��=�-�t��l�`;��~p���� �Gp| ��[`L��`<� "A�YA�+��Cb(��R�,��*�T�2B-� +�ꇆ��n���Q�t�}MA�0�al������S�x ��k�&�^���>�0|>_�'��,�G!"F$H:R��!z��F�Qd?r9�\A&�G���rQ��h������E��]�a�4z�Bg�����E#H �*B=��0H�I��p�p�0MxJ$�D1��D, V���ĭ����KĻ�Y�dE�"E��I2���E�B�G��t�4MzN�����r!YK� ���?%_&�#���(��0J:EAi��Q�(�()ӔWT6U@���P+���!�~��m���D�e�Դ�!��h�Ӧh/��']B/����ҏӿ�?a0n�hF!��X���8����܌k�c&5S�����6�l��Ia�2c�K�M�A�!�E�#��ƒ�d�V��(�k��e���l ����}�}�C�q�9 +N'��)�].�u�J�r� +��w�G� xR^���[�oƜch�g�`>b���$���*~� �:����E���b��~���,m,�-��ݖ,�Y��¬�*�6X�[ݱF�=�3�뭷Y��~dó ���t���i�z�f�6�~`{�v���.�Ng����#{�}�}��������j������c1X6���fm���;'_9 �r�:�8�q�:��˜�O:ϸ8������u��Jq���nv=���M����m����R 4 � +n�3ܣ�k�Gݯz=��[=��=�<�=G</z�^�^j��^�� ޡ�Z�Q�B�0FX'�+������t���<�u�-���{���_�_�ߘ�-G�,�}���/���Hh8�m�W�2p[����AiA��N�#8$X�?�A�KHI�{!7�<q��W�y(!46�-���a�a���a�W�� ��@�@�`l���YĎ��H,�$����(�(Y�h�7��ъ���b<b*b��<�����~�L&Y&9��%�u�M�s�s��NpJP%�M�IJlN<�DHJIڐtCj'�KwKg�C��%�N��d��|�ꙪO=��%�mL���u�v�x:H��oL��!Ȩ��C&13#s$�/Y����������=�Osbs�rn��sO�1��v�=ˏ��ϟ\�h٢���#��¼����oZ<]T�Ut}�`IÒsK��V-���Y,+>TB(�/�S�,]6*�-���W:#��7�*���e��^YDY�}U�j��AyT�`�#�D=���"�b{ų���+�ʯ:�!kJ4G�m��t�}uC�%���K7YV��fF���Y�.�=b��?S��ƕƩ�Ⱥ����y��� چ���k�5%4��m�7�lqlio�Z�lG+�Z�z���mzy��]�����?u�u�w|�"űN���wW&���e֥ﺱ*|����j��5k��yݭ���ǯg��^y�kEk�����l�D_p߶������7Dm����o꿻1m��l�{��Mś� n�L�l�<9��O��[����$�����h�՛B��������d�Ҟ@��������i�ءG���&����v��V�ǥ8��������n��R�ĩ7�������u��\�ЭD���-��������u��`�ֲK�³8���%�������y��h��Y�ѹJ�º;���.���!������ +�����z���p���g���_���X���Q���K���F���Aǿ�=ȼ�:ɹ�8ʷ�6˶�5̵�5͵�6ζ�7ϸ�9к�<Ѿ�?���D���I���N���U���\���d���l���v��ۀ�܊�ݖ�ޢ�)߯�6��D���S���c���s���� ����2��F���[���p������(��@���X���r������4���P���m��������8���W���w����)���K���m������� +endstream endobj 45 0 obj <</LastModified(D:20200210204543+02'00')/Private 54 0 R>> endobj 54 0 obj <</AIMetaData 55 0 R/AIPrivateData1 56 0 R/AIPrivateData2 57 0 R/AIPrivateData3 58 0 R/ContainerVersion 11/CreatorVersion 22/NumBlock 3/RoundtripStreamType 1/RoundtripVersion 17>> endobj 55 0 obj <</Length 1390>>stream +%!PS-Adobe-3.0 +%%Creator: Adobe Illustrator(R) 17.0 +%%AI8_CreatorVersion: 22.1.0 +%%For: (Kacper Donat) () +%%Title: (logo-cojedzie.ai) +%%CreationDate: 2/10/2020 8:45 PM +%%Canvassize: 16383 +%%BoundingBox: -2 -1262 1752 -460 +%%HiResBoundingBox: -1.11095703125011 -1262 1751.81311523438 -460.7744140625 +%%DocumentProcessColors: Cyan Magenta Yellow Black +%AI5_FileFormat 13.0 +%AI12_BuildNumber: 312 +%AI3_ColorUsage: Color +%AI7_ImageSettings: 0 +%%RGBProcessColor: 0 0 0 ([Registration]) +%AI3_Cropmarks: 0 -1294 1808.74 -718 +%AI3_TemplateBox: 1241.3885546875 -544.5 1241.3885546875 -544.5 +%AI3_TileBox: 516.76999961853 -1303.60000038147 1291.96997558594 -708.400024414063 +%AI3_DocumentPreview: None +%AI5_ArtSize: 14400 14400 +%AI5_RulerUnits: 6 +%AI9_ColorModel: 1 +%AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 +%AI5_TargetResolution: 800 +%AI5_NumLayers: 1 +%AI17_Begin_Content_if_version_gt:17 1 +%AI9_OpenToView: -32.1114453125001 -240 0.9 1678 1348 18 1 0 124 87 0 0 0 0 1 0 1 1 0 1 +%AI17_Alternate_Content +%AI9_OpenToView: -32.1114453125001 -240 0.9 1678 1348 18 1 0 124 87 0 0 0 0 1 0 1 1 0 1 +%AI17_End_Versioned_Content +%AI5_OpenViewLayers: 7 +%%PageOrigin:1152.8885546875 -648 +%AI7_GridSettings: 16 4 16 4 1 0 0.800000011920929 0.800000011920929 0.800000011920929 0.899999976158142 0.899999976158142 0.899999976158142 +%AI9_Flatten: 1 +%AI12_CMSettings: 00.MS +%%EndComments + +endstream endobj 56 0 obj <</Length 5834>>stream +%%BoundingBox: -2 -1262 1752 -460 +%%HiResBoundingBox: -1.11095703125011 -1262 1751.81311523438 -460.7744140625 +%AI7_Thumbnail: 128 60 8 +%%BeginData: 5655 Hex Bytes +%0000330000660000990000CC0033000033330033660033990033CC0033FF +%0066000066330066660066990066CC0066FF009900009933009966009999 +%0099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF3300FF66 +%00FF9900FFCC3300003300333300663300993300CC3300FF333300333333 +%3333663333993333CC3333FF3366003366333366663366993366CC3366FF +%3399003399333399663399993399CC3399FF33CC0033CC3333CC6633CC99 +%33CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF660000660033 +%6600666600996600CC6600FF6633006633336633666633996633CC6633FF +%6666006666336666666666996666CC6666FF669900669933669966669999 +%6699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066FF33 +%66FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF +%9933009933339933669933999933CC9933FF996600996633996666996699 +%9966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC33 +%99CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFF +%CC0000CC0033CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399 +%CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933 +%CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFF +%CCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0033FF0066FF0099FF00CC +%FF3300FF3333FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699 +%FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33 +%FFCC66FFCC99FFCCCCFFCCFFFFFF33FFFF66FFFF99FFFFCC110000001100 +%000011111111220000002200000022222222440000004400000044444444 +%550000005500000055555555770000007700000077777777880000008800 +%000088888888AA000000AA000000AAAAAAAABB000000BB000000BBBBBBBB +%DD000000DD000000DDDDDDDDEE000000EE000000EEEEEEEE0000000000FF +%00FF0000FFFFFF0000FF00FFFFFF00FFFFFF +%524C45FDFCFFFDFCFFFDFCFFFDFCFFFDFCFFFDFCFFFDFCFFFDFCFFFDFCFF +%FDFCFFFDFCFFFD10FFA8A852522727F827F8F8F8FD04277D7DA8A8FD6AFF +%A87D2727FD11F827277DA8FD65FF7D27FD06F82727FD04527D5252275227 +%FD07F827A8FD62FF52FD04F8277DA8FD0FFF7D5227FD04F8A8FD60FF52F8 +%F8F87DA8FD15FF7D52F8F8F8A8FD5FFFF8F827FD1AFFA8F8F827FD5EFFA8 +%F8F87DFFFFA8FFFFFFA8FFFFFFA8FD05FFA8FFA8FFFFFFA8FD04FF52F827 +%FD5FFFF8F8F8FD0A27A8FD04FFA87DF8FD0927F8F827FD4CFFA8FD11FFA8 +%FD0BF852FD08FFA8FD0BF852FD0BFF7D5227527DFD12FFA87D7D7DFD16FF +%A8527D7DFD0BFF27F87DFD0FFF7D52F8F8277D527D527D527D7DFFFFA852 +%5227527DFFFFA8527D527D527D527DF8F8F852A8FD07FF7DFD07F852FD10 +%FF52F8F8F87DFD15FF27F8F827FD0AFF52F8F8F8A8FD0DFF7DFD04F87DFD +%08FFA852FD06F827FD0AFF52F8F8F827FD06FF52FD09F87DFD0FFF7DF8F8 +%F8A8FD15FF52F8F827FD0AFFA8F8F827FD0EFF7DFD04F87DFD09FFFD08F8 +%7DFD09FF27FD04F8FD05FF7DFD05F827FD04F8A8FD0FFF52F8F8F87DFD15 +%FF52F8F827FD0BFFA852FD0FFF52FD04F87DFD09FFA8F827527DF8F8F827 +%FD09FF27FD04F8FD05FFFD04F852FFFFFF5227A8FD04FFA85252527DA8FD +%06FF7DF8F8F8A8FD04FF5252527DA8FD07FF7D5252527D52F8F827FFA8A8 +%7DA8A8A87DA8A8FFA8A8A8FD04FF7D525252A8FD05FF7DFD04F87DFD0EFF +%27F8F8F8FD09FF27FD04F8FD04FF52F8F8F852FD05FFA8FFFFFFA827FD06 +%F852FD05FF52F8F8F87DFFFF7DFD06F827FD04FFA8FD09F827A827FD07F8 +%7D7DF8F8F8A8FF7D27FD05F827A8FFFFFF52FD04F87DFD0DFF7DF8F8F852 +%FD09FF52FD04F8FD04FF52F8F8F8FD09FFA8FD09F852FD04FF7DF8F8F8A8 +%FF7DFD08F827FFFFA8FD0AF827A8FD07F827FFA8F8F8F8FFA8FD08F827A8 +%FFFF7DFD04F87DFD0CFF7DFD04F8A8FD09FF27FD04F8FD04FF27F8F852FD +%09FF27F8F8F8275252FD04F87DFFFFFF52F8F8F8A8A8F8F8F827527D27F8 +%F8F87DFFFD04F8277D27FD04F8277D525252FD04F87DFF7DF8F827A827F8 +%F8F8525252F8F8F852FFFF52FD04F87DFD0BFF7DFD04F87DFD0AFF52FD04 +%F8FD04FF27F8F827FD08FFA8F8F8F852FFFFFFA8F8F8F852FFFFFF7DF8F8 +%F8A852F8F8F8277D5252F8F8F8527DF8F8F852FFFFFF7DF8F8F827FFFFFF +%A8F8F8F827FFFF7DF8F8F87DF8F8F827527D5227F8F8F8FFFF7DFD04F87D +%FD0BFF52F8F827A8FD0BFF27FD04F8FD04FF27F8F827A8FD07FF52F8F8F8 +%A8FD04FF52F8F8F8FFFFFF52F8F8F87D52FD0BF852F8F8F8FD05FF27F8F8 +%27FFFFFF27F8F8F8A8FFFF7DF8F82752FD0BF87DFFFF52F8F8F8527DA87D +%A87DA87DA87DFFFF52F8F852FFA8A87DA87DA87DA87DA87D27F8F8F87DFD +%04FF7DF8F8F87DFD07FF7DF8F8F8FD05FF52F8F827FFFFFF7DF8F8F8A852 +%F8F8277D7D527D7D7D52A852F8F827FD05FF52F8F827FFFFA8F8F8F852FF +%FFFFA8F8F8277DF8F8F87D7D7D527D527D52FD05FFFD0CF87DFFA87D52A8 +%FF7DFD0CF827FD06FFA8FD04F87DFFFFFF7DF8FF7DF8F8F852FFFFFFA827 +%F8F827FFFFFF52F8F8F87D52F8F8F8FD08FF7DF8F8F87DFFFFFFA8F8F8F8 +%52FFFFF8F8F827FD04FF7DF8F82752F8F8F8A8FD0BFFA8FD0CF8A8FFFF7D +%A8FFFF7DFD0CF852FD07FF52FD04F8525252F8F827A8FD04F852A87D27F8 +%F8F87DFFFFFF7DF8F8F8A8A8FD04F8A87D2727FFFFFFA827F8F8F87DA87D +%FD04F87DFF52F8F8F827FD04527DF8F8F8FFFD04F852A85227FD07FFA8F8 +%F852A87DA8A8A87DA87DA8FFFF27F8F87DFFFF7DA8A8A87DA8A8A87DA827 +%F827FD08FF27FD09F852A8FD09F852FD04FF52F8F8F87DFF27FD07F852FF +%FFFF7DFD09F827FFA8FD08F8277DF8F8F8FF7DFD07F852FD06FFA8F8F87D +%FD0AFF7DFD04F8FD0CFF52F827FD09FF52FD07F852FFFFA8FD07F852FD05 +%FF7DF8F8F8A8FFFF52FD06F852FD04FF7DFD07F852FFFF27FD08F852A8F8 +%F8F8FFFF7DFD07F8FD07FFF8F87DFFFFFF527DA8FD05FFF8F8F827FD06FF +%7D527DFFFFFF27F827FD0AFFA852272727527DFD05FF5227F827277DFD06 +%FF52F8F8F8A8FFFFFF7D52F827277DFD06FFA852272727527DFFFFA8527D +%527D527D527D52FFA8522752FFFFFFA85227F82752FD07FFA8F8F87DFFFF +%F8F8F827A8FD04FFA82727A8FD05FF7DF8F8F852FFFF52F827FD21FFA8FD +%04F8FD39FFF8F87DFF7DFD04F87DFD0DFF52FD04F8FFFF27F827FD20FF7D +%FD04F87DFD38FFA8F8F87DFF7DFD04F87DFD0DFF27FD04F8FFFF27F852FD +%1FFF27FD04F827FD3AFFF8F87DFFFF52F8F852FD0FFF27F8F8A8FFFF27F8 +%27FD1EFF7DFD04F827A8FD39FFA8F8F87DFFFFFFA8A8FD11FF7DA8FFFFFF +%27F852FD1EFFA8F8F8F87DFD3BFFA8F8F87DFD1BFF27F827FD1EFFA8527D +%FD3DFFA8F8F8275252275252522752525227525252275252522752525227 +%5252522727F827FD5FFFFD20F852FD5FFFA827FD04F82727F8F8272727F8 +%272727F8272727FD04F82727F8F8F82752FD62FF27F852FFFFFF27F852FD +%0BFF27F852FFFFFFF8F87DFD63FF27F852FFFFA827F87DFD0BFF27F87DFF +%FFA8F8F87DFD63FF27F8F8272727F8F852FD0BFF27F8F8272727F8F87DFD +%63FF7DFD07F8A8FD0BFF7DFD07F8FD65FFA8FD0552A8FD0DFF7DFD0552FD +%85FFFF +%%EndData + +endstream endobj 57 0 obj <</Length 65536>>stream +%AI12_CompressedDatax��i�Ǖ���f�w>����L�o���1˵F=�Ŵt�����R$Z ��Ej����y�#nܛ7P�Hu5�"ED���p?~������������>Kg���O��._�ݾ����/�~�����o^q�'���.Գ�^�?�>�=��ݫ���_�l�Yhwo��O��ۧ_߽�]ݿ�}���O~ʝ�=��N�^�q�����v��>�;�}����z�����O��$q�M?�e��_���˿ܾ~���CӔ�xq����/����?�}w��8F ��?���?�s���_8a�KR�ea��p6�B�)�ɏ8�5琇1�vu���Ww/�����ӻׯ/�_ܿz����7�/w���Bwnw�{�������O�������7��/�������ݳ�g�����|~��ŝ����7��<��?���_<��ۯ�x�Y���z�ܣ��k G#�}�~��t�wo�h&�O�o��b�-�������Ͻ�Z�����ɯ����՟�5�6�]�����g5L�������Vҳbgi�J��T��Yy����}�\�xV�Y�0��W�!���r�s�p6�K-e*3��x��Ƕn�?s�rwy~�ן�~y��O���7�m������~�7o_ܽ����,��ks��_�?�{�_�q��������=~w�ꋻ7"��o�x�L�[���r������Z��z��7������_�v���7?���?���w/w���I�%mĠ�S� ʎY#8��e�$�����aivS��m# �����_��{�|�������>�L����[���;�y�P�Eпz�\�3v�ٴ!�1O������g{��.�1����$60�a��^�������\��'2y��ZW:~~��ͦ�~�[>Msqy��ڜj�N��w��==��ן~�o�~��'�������z⋻�<>����_�4�ӓ뷯�(æ�o_�=��(���v���5���_�~��?yv��w��������_i;�����x"N������o_>{�ۧ���_>�B|��~q��7O~u�Uڳ������n_�Y_��_ڭ?���7O�^>�}�哻��o��1=���a��^�~|��ٽD�D�.����=�{�/~�{���ۧ��1?y��ի��O��_�'|u�绗����d��������g�z������|�R?�������/��<��{�䕹�~���W�O��U���k S����'o�z���&����'o�|uw������7wO�z� ���ڳ�Z?��ݳ�/^��I��/4��n_?}��#�&n����������j��_�D�O�Mz�y{��f5�����_�<9�~rه���?r��)כ�_���y������o��|�s���'����_�����W�����W��z����_|��W�_@�_>���ǿ�������n����W��;Iӗ"��Onۋo��������v}ȭ������e:��������?֣���=o���^�7�x����t�l/�o��1�o~p��{��/Ϲ�&�m�������y���v��'��������>��k ̍�LM$]�|z�.����{=�@e��'�;O6��������&�<k��Wo�~��@n�Oo�����w�/�����_�x��������?���O?�I�W��=�n�|W������z�����ϟ���U))�_��=����<������wy��{* ZJdzݯ������~����B_�|�%V^-߯������������Ю^�����7n�>䉿~q����:i�*I��V��$����=S<�kM��r�(�����A��}�xI�����_�#�kڵy��$�v��_>��x�������߿X�~�����=��D��|����_��f{�ע��O_���I�[U��W/����ï��?@ +r�ͷ����W�ޤ��+�E�3s���������oYYڅ�#��}~��[q�y���lT��O�_>Ӹ��������k���~y���w����G�0���g�h!�.^n���+t��o~&�-WS����O��{�ל�.��v�l�g%NsL��y��ƹ�D��8�R�L�)�%�yL�X��.�e�b*2�C�c��0OC�c(ㄑ�w���ū��>~���~�/�=x����w�Y�Ȇƀ����8���?����Ǜ��~�����������='Z��#��o_}���?�~����w���+�LeR�˜���3�RC(CNal�u�S�y�S��<��}uR�Tc���ѻz�U�6v��Cm�7����������tσ�0_�]��,�<2�Y�iާ��j��tc��8i��Po���'u�����+� x�yL��i�0�F��\�]�5��L�����b�*!ߨ]�K5 5�Y��#rR�y�C�I�jW�RM���4�դ�I��OH��4��k��x�v�v��q�U�A��GGM����nµڕڅ&�B����U�1��~�p�v=\�]�\mv��F7-to����O�o���7��!�}�5,��z��?�P���R��T;���?��������e�HjL �Q�V�T���|�@9Y�L;���F�J�s�FG�Dda +����7jW��K����ğ��'��q*,��K��M���^�K��B�>W��ϤW��B8���/�u��x��'��k�F�����t���g��B��g��y�)�D������<QM�2kI�� �Ey�Z�D����: ��i�LW"'�,~�����e(If��*����������F3��o'���2hW�Z�s�Ѝ�+i��8�լ��J'��$J�<�:��DQL����E{A[0k��w��������I���3]�_]\]]��N麸��U������J�����b�,���Hg��ش���]yu/D�ρ� �,�*�4}�� �;�A�W&G�=����ɶ@'�����|�ɸ0�_�]ް��>��C6S��*/�N��E��+m�O��y��҅��[o�F�x�7煷*���-��eç>��R+�f���4��Ӯv}ysy����i�Z�K�B���\1�W���������zyX M�ebP��b���`�*n�.���'�Ɵ�l�S-l���� �����SĀ�����"b21�L5'Aq�MzeZ��p�� ��f�ou�|�ǘ�Pf�f���CAH����b~\�p`<��Ѕ���ӵ?�Qޖ�D}bn��m����4�P���p�D3VS�hrK��W��+Enir��-]v�\VG�p)�8�#ٰ��5�z��hM]�X.Ee�z��O5�Y� ,l1]���&Z�l�,T��6ʹ�Im⤫!���%䲫!�����H5[�sM�d�Q4��c�Z��a�ph�a�H��08���Ƹ*(���uWLλZ2Z-�~UP�PI�D�VI���d+$�)$R5PH.�:�2R�*��4����Վ�U��U�+mw�)��90ʎ��ݑ�{�::6w�8�荻j�c&ُ4�f��//A�K�qg`D�I��|A��\�;�F6��$Y9���gyc�Ċ��f����?������[�\������g�/�%h���u=�,�ע�EiWE<�Ұ��?:֥dZV����U�VM�̅6������_�Ē���qE�,Յ$nF��g��ea#Q���-�����zQ^��奩.�ڲUY��tA� �y��U@�1u!����DMT4a��E]��^l,.Z�f���"J��������lZ8�D��AK'[~���f!�Xm��'>vo�ۚ����iz��������X�A<%�f[�ʵ���8K��B��m�Us�K)7b�I��h#�""��\&٦�V��(w��x�:|a5����q�b�3��Xѕ��(�����}�J�Ū�6u�)��*�QcmH�G]tE�joLuEvQeSWe�\j��.mި��]��]��j����5+��j�� ���^�-���V4sG{�k��۴oz��-���'��Ƿm����'~��}<�}e�O&�9�<Ba��\��HG?)�"'mAIk���A�J��2Yk��6���� ?�A�)�яs���l�ʹ�e7����JZ�Js�� \�4[�r���+oiܥi@{�͞ˬ��8J=0��U?Z��Cs�i8Nӣ��!�9�@'�����J�� ��r�w��y������>>�z����Jr˶�Fs����e%�qg���m�s��іKiL��ɢ��4��]�zS���8zӢ9�2����ul�� �K�whPl��F�������ZY� �Ixcנ�(>����f�������-V[�rc?�=��s5���ڝ��O�B������1�=������%���lm�&������r�Z@��˱v��#M�?W'��鶏K�lѱ�m�C���A��>���'~p�����p������ �zSn�M��������E[0\�\]�Dp(�W�*ڑ|uya�h�q����l�z���1�b�Ÿ�������il.�� ����pwK�X\������s��O�u��xq7'qs7Gqs7g�E�aOv�4n���b��Q��C�i/Q��پ�3�����=��:֝;�!Ҥ�9 ���&��ek-n���,*մ6�v�~����)߷�i�� ��'���ni��lW�W�.?����w։�'~p��}�xs�|�(9�G��}=�#G��Q>r����{b�(+8����4£j�Ny�u�l@���4�`��P�������C��ګ�9�i".4�B�����4��)��?Ҩ� +����.$��x�:���_h��3R�"�]�gc�`;���� U.QC�R��'w�?��c������!�]�bu#-2s��B�������`j���ј���W6����o����j}R ��}��j�S b���`�$`]�B�ڈ7UQ���#$������z������eD PT#p�i��F#%e�s�ԏ٣�Ks(�U�G3 ڟY:F��x4M��Fc�s_��F��ӏ�j�hT�=0��O3+]?bVЭ��+�D�������h�j����0A��zih����A88`�q L�nà�!��W�uzȳ���+�V����C�2 ����U;P���;r7��_;~�aǯq�2�`OeE�7�xs�߬(�?Ĉ�� į�J��o8�)�:R��->��B���?�4����\j]��N�嵕��0�mz�f=�aη� �p�]�h���x���c�1�d^_��b����}��������� l9u~���0Z�r4���F��B1t�����`�أ}� ��3&��WYެ�ұs���+�|������p����UV�i�oh`��t��<xN���j� +��0:�㼇,�E\�,�bL��=T��(����*��DWH�-�f��Mms<���\.�Fq�%/fɍY�c��8`YseZ�ֶ�|t�����ϖ����sn9hX��ڧ�\�-?��{ڨ'���67=���w���MO��^ߦ��~Ⓒ6|ߎ��CG�so.�ѩ���ߖm���\�<�}��sl��Y6�c�wS�M +��>��2�|�5�攋r�l�7�=)}��Ay�\����<tL>pJ�o�.�S���۱r�~�:�n��܌G��m�[��\~�`��|��ģ+a��VO5��[O7��}�����B"�����x�� =���f�v��7׃T�+g�ز�l����oZ���3��V������~� ��f�J��K����Ji��)�)7��=]���K��q��dX+cP���?�����u���EGVΝ��"Ր���Z����2Ʌbτ��:lm1��a�h����V�� .vڴ�i�Q+G��=1�h����̱?�����}�ɇ�����MO��^ߦ�{~��q��� i��FNOڤ�9d�,d��f�������l���@�T<[-�C!��T��qm~u��f,�;�y��Z��<:���-$�@�[��V��i���sW�u����g�5�a�&�l����/nX��ZZ-�}�Z�c-ر�=���T�����w�[�۷�T�Cp�A��u��t�S�t���&�Ş�����!mIl �oѮ������yg�:nz�k߭}|�i�&(�8�d�4cH��P&�R2�����K�K*�@s^�C�"�����&7?9�_z��TLTW�Pd|$1[�wDZ����9����5����QR�65�"6��kb�ar�a�В�x�&4o��.������d�ɈkbPX������^�����*.��xb�i��t>�f[��I��t��>+��Ha\/���ѥȺ�o���>��k�(�KQ�k��:�FO٧�=�����Ǥ��Vt�yʣ=A����T)�A +��s��`�K ���ݛ]���_�P]�+iV�͵l�I��� �S�7�`z�!pԦ�>h���x�<xh ��0���"6���Z�\w5�{`/�2����B��W�����J!Rc�n��ԋ݄U l*��|W��W���8��xM�[Թ�Uy;��֔�5�p��,���>Dž}Z��R�g^�������%\8n���R7��R�n�T/%u��[�qsk����C��x�զp!���yM�TԥCo7�DT+5>�f@F��rm�aNc�τY�w +����m�9��AG�>Nq���eՏS>,,���m�Xu��0�� �@K�Q�-�,Ҿ����4�Wf�es�j@=�z�p���Z�#����F��H��XY��>�t�pӃ�W{� "_ôa��7�c8��5(��ge��� +��~�V�b��-�V�bk�-��)�mo�m�9./7�[��k���$�^(4�S�o��co��F7}�z�t]��Q��?�"uӺV�����)ɶ��Hk[��M+���m�)��30�dK�|G��/���ߡ�'�0��}MtVo�\tp�t�hl�v��/�n��fӍg���a�ᇽ������e9����5�)�;u�+��6�$�e��F�| ]�r���iU�Z�f���:�*�9�"͢��YCCGùJ���j�:(�Z�֖�Ɇ�t�҆����O��~���R�ds�6��t�k��le>@�\���{٠�x")�Wk���tЬݡMMB�IP�)T]��ܕ7{�M+�W�l���M�}-�L��^d����ºWK�L�Ыf�B K�|φ_��v�l�m͇54�ZI3�i��Q��rDj�C����q�-_?����q�I���H�2#�� {_��XsEه�;��Y�&�}'��<Һ=�=��č�kV�$r�#����ƛ�������[�|��B��O?�ۢ����_�hY��_4��/��v�b��t�Vk��}���go�k�KӦ�S�^C��V{��m1D���P�A��8�vh�?�-�����~y0]��T�=�����{ݸ�⇷(au�}�譇���wh<qX�O�-�p�.}܃7켁�OԆ��M]ʥ6ܸ�6���z��}�����t��PiE;��R��A���R=,�}��8.��U:.�}���N�q1�<x\P�$��v>(���M7�i��Z��G���&����m�x[]�]4[��ނ�oP5���������!�P5����~�~T��X�(�����vX�������rcpX��é�:������ �#��mH�rӶQ�ퟭ.��xXo�R�a��C{\��~�j��n�m; +{���@I:p�j�*��n�����?�*p��p�ook��.���u����x�Q��e�]��+?\I�[��G <���}���_�f��`:_7G���S=��>,���2��/#|�b�������X����4��n�|�������=�g!�<��|k���WF�l��p.8^���Pf��������o_Ia=�;�����C�Pa�z~I"Wf6��K̓�v�#;����U����]<�[�����b<:��#|A��i�/��y�M�V^p��j�`/1�m��6�.[�����ta��yp(h��-i��AaÖ/t�1l��{n�$O�^�{���s/̶�e��7�X����{��@V�ր{ �7���4r��� xy������_q��[N�Q�"ΞR��C��p�YT�2ʲ�r�b;�@��A��0�ƕ�n���d�i���DN���vxH��B %��W�{�c��<�{�����3;�63|��7�B�K��ц�]�O: pJ>x"o�ONJ�c��J�H��&2����Ђn~,&���x̘XL�n2�F�blK�#a1���?� +t��Z��!����K�IZ��#��"J ك��b�)5Tϕ���E�`(`�^�y8�g� qD`�"ؔ@����=���P�A\�R���ށ�yW������%C���o�}�ki_����F�$`mӯ��6g5nOk\ҭ�D+������U����j����)QK�Ӓ���,���H���hA;���S/ۮ�!C>�E?�Ɏ����$p��vu��v�y����^7��>�d�����3�竟�f-1PNXQCپ���3�Gⅎ�B�!�8\l�{��m�m�7=q<h��6��m�z���q���;�&cXO�<a9_%�˽%|XG~���l��_� 娧{K��m�_�����-�j���r|��W��i]S�4��xǽQzc?���B=Q�=���W�Ƈ�ZH�STK#I��&\��'��u���)Q��8*�O��|���*N�:�L�"1Og��ǭA��|M�'�LMa-I�-ՙ0�ؐ������Q��r�r��1J����1 ��.�( +�s/Z3�Kk�b���ʽ����+7cȳ���á��g�,{`���m_:��V1sY�Sl5} +tT$8��^tz^�@�7s- ������j��I%{D�������封��#�v��*?8h��1��1�6���o�t�蘋} �M���8@'֖7��������*�VIث E��ON�閳H��oZX�<8}��\������9�{L���y����k���G�AAKe�����Qq��o�cݖ��z�[?K���x��&�����@��:�c�X;�l��l�F�.y�I�Ѽe���[}�f�W��fؽZ�� ���6Ļ�nü����yHI��o7J�^�ܟp{�=���� +V{ݘ�ɶ�#{O��X�������-UR���Z�?N�T�P֞�64��D?6d��3�F�E?$iP��(�0��M�=8{{ �o���W�����:me���j����+�L&�r\dXwy[��Y׳�Yv��AP~k(l���:\���%H����/ZV`�_.η� _.Ɔ�k�>!{��902n�n���A'�y�(�8p����}=\'���;��s����u9N��=O�H������C�:@��ǡ����VK�JzM�M�y�O:}/��a��r�u��gi4��Ե9Bv�)��ڒ"[.̖7k8��u1R��*���H�ڄ&�<�ao��k�z���fFsL��u�������۳����O��f��ko���;~�ko���Χk[�g�{B`o���si��l��س�bs�t����pf1l�{��F�罋�=@ >��{��A4�R�!�ߖ"�7��+�]��*n�q��۵ܮ&n���n��vM7�z�˷뺮��hج�v}��~߮�v�����Yʰf�^��s��>]��1Ȅk�Hv,��]���o�~����]�V�k��-<��R�]�����=l)bO���\c�#*�<g�k-�&Q��o��A�FI�in��YT-Y i=��hE��+�[b�B&MɔC�f� Y�pf9��0����0=���<�;;Ng%���ۡ� �!M�m��ڋ_�P���E�զ�yG�_w�CZ�'��C�1o�1;����u���A\OiL��e�H�+��� ���F���F�ݪ�S/�z�粍l?��f�Y\GW֓$k�68���خ������c���7���yW��NZߑF��~t���G��I��z����:��^7r�D��ñmGw8��jO�v��~�syC���qnGz8ְd�>����\%s1��,�9)�7�:j&Z���N ep��u��c��4�g9 t���`N�Y|p;Ŋ��]yi=�J��KXy��]8�!�ju%���؇is{�ܡKn�;,�L����3���o2,N�w��"���.Q3gIi��8k���)�6��G|���n��F�8eq�^l\��f�ٗohdaԃb���Ϋ�օ����O�=��]$��i��R�z9Qx# rv�.������27���.\��uL3����rs��9G�9�~�I��:m��h�X����=e��|��t����6[g���V&��&�n)�']��T�������m�;p��n�ߒ&N27\� 2����K�e�r�?��/(b +:��u���P��i�ؑ����-]�&ƞ��X`h8���q|P���p< ������q��?l�hbO7[�9�_ҁ�؟����h��@S��ԭ'^q���͓g��r�^Q������Q�G�\����X�vFzr�7�_�<t�B��R�����Gl��O0��'eu��[F�gd��ށ{T����с�с��G��Hi�#M��&�}9p<���I�5dG<�|��;��v�`Z��l�������_�ɏL֭ѲʮJ�7jJˁ�҉�=}е�?�>���]_����W����=_������տ�k�/����:'�I��g�ho����j�kn�s�"�`��Ku @��<�t��Q�������|�����]��}�g����?�E?�E?�E?�E?�E?�E?�E?�E?�E?�;>��>��G��H����~Q]����/����7�_~��g[��Χ���k�K�ޯo�{��g��\�������8��܅XΨ}/�I�초gy�@�"�<�r���L����+y��?��zj��Ծ��߿����������ֿ~�������MW��i��b�o�u�=�Կ��O;��w_�������n��_N����~�K����՛��O�<�y�����ihO.��_�~r��0�_?{������O�����w�_�}����o~�������_'&���?�mO�j�I<�Y*�SĀ��4̣�夭]��g1Kѝ�x�$%t)2W��� L�7.jN�Y��ʸ��uH��䙩4%���Y�gQlH�J�S7�h�8�b!e'�t&;~��tp��n����0Ly��Ӏ�<V��{��0hي�a-U�@t!E}?g1�N�O#�'���Sԗ$�A�<��K��i��0es%4�Y�5�Q�}���Ut�8�<gͣa�9�v�LK)׃��F9��g�*�3�g���ɜ�c<�DH�Q��ܜ��7z���ګĵ�b��8D=p7�3q��??˲'-��v���,�������I��n5���x�d[�!Z���қ��.kg7�g�ܧR���$鴛*lp�K'�{�Q��4j�2OI��Zv̪��j^��{I��gc�b0Y+_��n�ъ�gc��i��!n�i����6pS��MI~�FHl,)UB���o�Cuy�� +��,�ݙ���R>�B Z!��R"�ꓢrC�����_C�U�.�Q(J�$8�-��<���Z���N@ +C�vI�ξS�=�)��Fm�ʃ$��8�0�����(>Uʎ�N��dT4VO�Ht +�(�EE�d*�uC�7h@5�}�~N�����u��6��njz��!���=��� ��<i{�9ML� ��F�˩a� |����<��ֈҔ"o*z#e�Ρ��q�^^���t�ѵn�U����@� :��zq:�@-�F����cL�Ц�˛�69� ���܍���v�>��g�1�C9�������Y�u*��z�����.rw��Y^f[�':�'~���r�M�Ko+�$'��6�@%�֭�pʹv=���O�P =�� ڱ��\P�O�'��C#~*�@Ռ�Sd�k����i�;��Y�� � �#�+�K�J�1ŕ*�Hʬȶ.%,X��i�HQԍ</7�u��D��6aY�?rm7Wg���`b��!�g��!�è�ٚ�1m���^���$��v��'&7����L���E�eq��e���d\��%Ҕ��Ϛ'����'>7&�[�X��XB�]uy�v�� #a�ˮ���uьD�. +̍�t7�cEJ���36y����fv��dZ�G�hވ� �M��ͯ�Јz̈�1�A8�3�D[��"%^%2��2��=Dbg<$�8L�,�N +qD� !U4�@RH���J�讈f^5o�J<uI����l=d���Z��=�}����ԫ����z��`����,������D�#[W�����h�����m��8c�/�غnj�4���Czq�*��Rń*����n�>� ��2i�������,ViA�l�IU�O��j����s=t�8U���ָ-���覭o7y����=~��b�!37�El��e���w�a�-D�C���!������mР��G������|ܥ8AZM�hEN�r�=ٙ�����l�x�(-��@� ���*h��.H6Tz�a���8�i����cE�Pe���)"�= ���d�v���*����7�6�A���V��U Oi�"C�=t�FR�o���]1Q�Y���K�*���ї�BH)9�U���BL�aI���*�����lEz<#H2��^��sS� ��4��) �ϕ��ڑ"4J�D�h���&&����4���h�4P����o�f�%,\I{CK�n%ɦڅ�bQ^�Y��������Ҿl�����S��P`Fϰ���ݰy���4T�S7��|3SaIѴ�=D��Ac����^�>�=��Y��/?w��tM�Ĩ�<�y������ Z�� 3�¡Ҙ�/��j�DNV�����P7HЕxĎ�a�hR��hЂzd���az RR$ȱ��h�qDO��#�%N�'G�*��*Iu�q�<���b�UOX���3}��2�>�}�O�m܊���$Ɩ7h?5��n0ұQ��dJ��U;����o�q�jt�T�e*J�zT�̲A����H�}��˪��i R����/��FS7��d�aa�f���-%�r%N��%���%��"e�V�����N��ړ�)�o�zI�C�ԓ��;uh3CٔeG�FrF�q��v�b,��R��dsR�˞,$rX҈����>�52�� ���U�*R� +��T�(=�ѫI-�#k�Ȏ�SC�v#K���'X���hz�Z <ir�Wj��Uz|����5@y#������I~^�B:�Q}~Lu�$���엄b,Φ�`�Hw�#��m�gȀ��(�rr�8�Avy���������I^�M� �C�����@�`�n����&I�Ÿ�1<�P�U1.Z�� mOM�������[Ц��|�̙`b��5Qe|�Ғ4���z/��2K*����6���n�)=��#%Ʀ�Η�{A=���=��(��4,:�X�?�W�Pу4Ą��� ����"̻DNe��BK��@<�vZ���g�E�p41�Wi�E� �`�����<����ڭ����)`g&O�D&F�P�8�5�)?��L�$��Y�:j���+�g�ŀ��@2�̜�(/�@�$������ݴ �N,h�jjfGVӮ4����$�j��"Ҕ�y!V�-W̠�2e���;��a��fw��Q�+���>�G+�N��ϕ�0#Y���5B�sF��o(}V":���,~�W���&�o�߀!(�]o@w���ey�������eeR�3aN�C�HU�G�!P�!12�ϣTĬ�����جð�Ų�����0�����׆*~�t��~��Հ���n=��ф3۱�h�"]2��W�6�H���Tr�_'�����C>��d�_�h9����A�� ++��-7c3��sc�:��٬�P��H�崊r:�/����L��/� �C�̡�=]&Nz�V��S)�c�<ѕ��Oj!���K��A���0�#*T�T��b��vC�DC�&g� �� +�nO +�7��e��e��Դ)�z�/to4��<5��Ȟ���!�k��&<�䱡`�Gb��G�^P��F��������4�)͝�d��z>bGq6#��n>HL�X��1���0�jJā�&���Kͤ�a1B��<"e��y����B�-��5�`�W|���u�N0 ��s��L֛���Q"���;b�Og�����2z�=��J�H�G�W�I����.�>��$�"&�N���uu_VXnϟ+��<�\�*Oc{<G'� �����J�Hp�B�VA5��)w�y��P��e�I����<e��1��c�!���ï���������ab������O��-��0L}e&�h,�ũ\�M�3-[�2�M�כ�'�o��� %XN����k|\�$�织�\�P=DI�x4���5�^R(m�2��HU�!i<C�����+��0�b�SҍKN�=Xs}�h�=�n�5�F� !��>,����Nw���������E/���iۏ6vG;��b�1R�p"�#�(v�u&�#�s��~��7��>�S�/��.-ud�qӣ0�����-|��d�7�qsc]fX��T�(���G��[�@#��@���6�1�����X��'���D;!�t��o^=���'�O����7�on��0�w�f�BI+B�Zd�.�����`:}�%�p/�u��Z�6J�P�N��X��_���6�G<�����f��hah�W/{<�8������}l�¹��CG�R���n�h�]�uQ�d�Y�����w�G������~�p�?� N���BG�����`��OLv`����W�M���If��A���m��Ωy�$��v5-��k��/����KL�B���^JB���Ñ�-�řA���>��V1�>��c�Pv���i�>e;1%ܦ%l�ڂ�P/�bHo7"�>�N��<���1\ ��1QL���5��p�6%Q������,b�M ��}�⊯ ۳�f-�1� +sq�Uϐ��#���#���t.%@�T�x�~/n�4pnı��XG��:q�E"G'��e*�Yb0ęZ���\��NN��*��������?q�)�b}��� 3O�^LMˏ��c+�KE��g��|P���V�O#_��e���� Vq���S�c;��ޡ���>��Aܶ��}�����v�{�&�M +��Nv�(���]�����F�&�!����>)�t���j���f�Y�D�I�C��&�E&�Н@a��D��~c�7�>�XZ^����d�8:�*���NjEvj � a�-��׀���d'�-F�����D$���jJ��'o���ņ�r2��p �/֘0�q��3R��> �Xma��c���꾄��ϱ��20d��a�`6o�`��nH�c9J���9����7��z����:װۜ��o�,u#�&3X:�Z�Ee��wTT6�ݡج`�b�5Œ�����nĈ妍%���nRセ%�<u�O~P���*��! $�C��z��F��(BǴ��[�|Ĝ�&B�,����,�W�H(��$�����Wv����~�f��� �2$۲�^� ��0�Ϫ��(�����3�l������6��V�#�F��f�J ��RK\: �3�'� +���;)Q Id/ پ��,%��E/d���Ӥ����p�V�������)`ϋ&eO�&-x�GIx��lJ1,���h�q +��\J��#"y2=D[��oÌ!��{2�4y�,� �t�V2�'�T�%���[�f0�[,�D�o�h�,��j��tr ����"N�X�[C��<HZ ��L<�g�(\q�X1�>J���{d��E7��v�0`����)0*�>X�[�F��r�)��D�D\4>M8O�/b[��l����U�,P-0ެ��W�(��F\�C�F�iQVYDi���Q�;p��p;S���`�ca&`��/�p��Q��M����x5&[���MD��(n ˔��Oq'��p y�K���әY�&P����ܭ�n��qD�����Z�{���1Ȇ��u�E�"���ݢec����_��.�wXJ���������'廥�>��\fɼh@a`�F,d�N�g���N�h�M�j\X,R�1��.�-0�<ܳ2�w܀�O8x��yD���纇v�f"��{P3��:-h��j��7��k�(D( � �J ���@�8�uI�+���ih�[ �����v��z4w��t�d�Ǫ֨ +d�z5/��n��M�ܭ��t�8&46g��~������#����W-61;8��������vY&s��70 ���v9�FP D:�������:����r@T��KG����D�34=��`����ЖANg�� g��ONj�B��hr���% �O�8O�(� �V�H�k�B/6��,.�p4c�C/���QMb�b$_��y��߱`4�œ�p��V��gB���9�U�'��e�Y�B���*D�Fi��j�c�y�"�̟�%���i\�@!���zh!*0�T黩 �M��r�{j�Ɯ ��J�C���)4fm�Bh8&u�H��(���ӂ�N�9�� c����Q��C�R����� +��yFJ�ʱZ�I`U���,���B���������h���J^�:͛Dp�~�ˤ:"YS��fwyN �B�h=DB^�1�C�it�Ȃ�hR뀻�5V7�T�3���ü /�u!�Yp3�+��&��M�Nz��U/�8�Ѕ��� OS�r�Q������$6����� E��p�%7U�)�CZp�e�m��2�}U5���GrD'�D +A��}2�2����Jiv#�c���'٥���X�x�F�v��#"�#�X���6 ���\���{ΰ+8�FPc��Z&���SLBɇ�G�I9b�k�J:�kwS�}�qь�@��.��c�4� ��?f&�Wӈ�k���R��S��������������y/�����վ@S_ ��=��?g� ��nd� f�m���K�I�>˄����0C�! f$�b��3������C�S����* ���3G8��8�d�c����N QL����2hCG����X^V��B���S^V�d�Դ;ML]=p������#�"+� �>9���G4p{��V胣x%w|>:&�`�H�>�f�(��PB���kS�dF��\ބ�>��d*�������Ox4���Dh4����(�Z��Xe��8�j�^�ǟ&����DI��ꩩ�# /��f�� +bM"�F6��0\ �?t ��.SXB��5��@�M�����s4MX�cA�ҡ�[�Ϯ�٢J�_ �!��f� ��!x������7{�8��%[��J*����3@Y`�⻝I S�����^�O��'���6Tb6�ĩ�����"h�)�(_��Fc�VLF/>��GL�0,Nq�Y�H��55���1&X�_5�W-� ��h�'�*��X����������V�>��`�>q�$}��� �G<H��"w�-cC�(�آ���=d?Q�0�h��i��\Tb�}��0�,�*�e���5_|Gpj�l�?`���3fѭ�Տ��e��`(�#���A�!���H�c�[{�s�ᠦ�NT����#��BL$K�Ž���h\��Ȭ(C7�k�"#<���h� ������z�K���7�i"�1��6E�H�]�@M/�Ku�����ѓ���)3=�/�'@?m�RzL�بcΨS����nlX�r� +�����C�G�|�@��|!�����L{�C����CTKe�Z�sʕ�wԜ�H@�.&�?��;� Ql�Yb�D'6Q�a +� +�☩�%���x���I>z����� ��Z����CI2�17l�&nDGw�d�� �V��7�h�@"�J��<�n#�'�S�Pg�"��Pd1~eHhb����6V�*������ڣ���ZȞpsG�����`��P�W'�f�L�p2�'�t���G��e,��Q���E$,�@��]r^i�;� +�2�Xb0���K5�IZ�>`Z;�(5 �y�_rjQ�j 1 �%S�M�Y�AK���\;����E�j��2���H��v���<G4��R�K�с>��8E�pi1G�� �m �tǫ�� +���5�qK�"Y�XH��dT��f��A���a��#���u|.AQ-�-�Ԅ����W��K��l����`�ɈSQ���dj0��A ���?��L>~Ugz��� /'cجT�̘Z��Z���r�z��7b=��������p����ǔ���hcʯ��,��a88��i����z }Aa�~���3��Ęݣ�sL'���k���ɻ��ѝ�CC�<DGĜ�l4"�5i��qh�78�P�y|6�3�����Y%���me��.�R�z�������iL��٧`1�)�:49�5�µC�GZ΄+\fn^���sk"3dF'$FlɌv��H#'�L�fA�OI�|IF���q���>��G`�2O*���!��c�=�e�d�w-��1xst���Y�.e�w�ᘭ�pB��Jr�\��L����U�H�w�S�Jj�.����c�B�n�E�������ԌQH�ڵ8Q��()%�xܚ<,�M��U%��D�v���@;��$�������A��6)�|�CV��u��~�6�v�dGS�(xa�V3�'mG�ց�W���wpqN���y�#榗�w� �tCFBrF�10�y�hX_r%���!��ib�>y�$PIa����i~�\T ϯ�DͶ{H��IJC��3<�:�%��YQ���#@��z`�͜��6{�*����$X�48��j�f�$+"h�]}��-_����3"�����c���g&ژLл͕>��J7�Ӄ3<����J���;��Q4�r�QA�r�I�h� ��: ��/��)�Ό#��ڳ�_E$/��u��9���Lj!=��Ra������O�UdB��_�@����%�#hBGYW{�#�k�}��#3��V��9��]�6Ȋa���'gT��+}�<��GQ6��S���G[Ӏ5��:�Z�s&5p�6(����X�����sB`!K�}qM�OD}Q�� moȌ}E�yp��J�B�P!�*�#������I1,��t���$���H���ێ���M��)8�/�G�bV��v�SUc������d^M��l��6�gϣn� ���a�S����.�������e1F�:����dH09�d�Rr���H,��ZV��+�RTC�o�K-��pA��4��٩����.������+����Ț���ؠ.6Rqc�K�� q�g�%=Z&(����X�YM��zX�5ҸҺ� +�a �����H:�ħ��4:���%�|d�9�5,�u��!�-�ƕ%X[d�O�O����*�������d%BD�~�Di���PX(q�ԑ#B h����VL�jj1~m_�ۛ'���!��.lI�a��O� H�WY�Y�{K�SuPt)R�i�q[���dT�ev��)�pj��-]�RPy�j�6R=�4��I⨘8N� �o�G���R���2 E +:D[�������+uU��� 5�n8�w�+�u6�]���Q G�A1z}�����]�B3�����-�vH3��8 +M���Zb����� +Sn�.�Js˦��s���1�.��tH�J�H�"��l�����J�ԋ��-�]�]<C�}2S��쏩 [�<�L*�c,"�?s�2�s?]\�N~���np�>߹cv�Cg�Q�3V���[�Oe�D; �r��p����2�5�U�6�sjA��C�HK1��� >gj�hb(���3?CwA��/}bX*�0�� v�e����ܡ�'�A��! ��R d���R>��켼����5Bo��Q�`3�5��S#�b�t�z<���6�B `!A��ả���+� + +'4r[Ă5ׯxJ��%�C_<��/-�32��&'�F���$�n�{ҏ�Tc�847�q\n�x����y��9<�-�6c0� {�] �6Ɍm,a�����[���z,!�f�I����_֢w�آ�6|��pU�X�-� ��m;��Jf�V�f�0�@n8�7�_���o���7��Q��Y�w��}�v�4xI�R*n�@,���W[�?L@��j3Ao���(�Ѱ.�'�{Tj�Tj��#�G&m\u2�x\���R�,P��������ܠ��E&����u5�ndVs �:�lT� qހ���g��G[��i��1?ZDK�Q%{�+�o�SZ�}�����t��"�;�L1�F,Y糣����,��q(M��7`G�6�Oj��;�(�6�BS�ȡԦQ� �2=�q�ˏ ��>@$h�bK�)��4�3��z��-�����gzbL-�M{�IU6�Uh�����2�~6BG�0#�*P��TH�I�(�p���O���p0���V�h��E��sȦ�� I:�1�E�nnQ �g�ގF�����|9�f�ejF�$�EH���?,#�ٟL��EY�(�QJ�o��S����)�O�P-lZ̢��'�G��YԗsZݔG���W1�:���z ��������{��3�^�v�9�Z2.�{���&�����,v���&�91߁A[��"^�#nE85��Z��D�*����"�L�*�wr)�� �Q�WL���u@8+��xY�����^�}�~ȣ}2F D#l�X��Ԭ!���QS,�i�H��8b�{��d�@���u�q�/LF,��)��e�L² C��[}RJ[����Y"���gtl�F�6�,�]k�����q�bb(4�Ed�Y�&�uu;7�cl�����p�3b/�Y_�����{�ʊ�W�d����L� +�\ +R$�-� �X��"��&)�.uRѸ�LA�h�HCDI?p�����`4�u�Ic�bo�&�%^b��p��=O`]-����ɑ�+IQ�#�w>�MفܿF9�=j�Ǧ��]P�G�|OV��Њ���*^�m:;$4�L�S���?�[���˩k×Į^Dl��1H������Z� �Y��5��B�w �jl)2Zd�4��[�q�$=��)\rε֏{\{����o0����l̔v&@z�A&�$Z]�����d�y͑v��B�$�� ��n�J n*�&��a��%����,)�t�-��!ekkD��yɣhi|����E�4��_ �:0�2�1�V�1���v���X�����=�������4F2�����~�e>0"��I��lL���㇖�/E��^Yi�ʚ8Kq�t+W���V��ܵ��H�"��6 Q�s�a�$������g77=�zd˧�|v;+f�p�A艘,��+d��F���H�_oҦ�)d +A�y������'t���C1���j�촯������.�K-�4�{DF:�i,+�q�fwf_�"�z��f�9cC�Qߊ�A�s�)� ��xU�H��U$9��?���ju��M0NLũEe�s����\�q��Zj� �� ��q����y�^d��ivh����j �z����J�"�nҺ�GCAPc)�q�.��l���ęFcp�x�3C_��\.�4�$��NQr!P\H��bk����N�ᄮ�P#f�p^T4M���O؇��"�ܐ�I�QJF>{_4q�\�<~�3���f�V�sI�n���Wˊ�Y+���^H!���Ŏ�V����0I �#j�ю<v� ���4����'��ʬMH�"/`u��oo�����͘&�r�EQ��Z2���j��F!���\}������hy�k�4�z\1���$?�sVQj�O�d��{������H���x��{�� ?��'��Q��������wŗ��:���w*S&����A�ǺR�5���mA�Wњ�C����a�-�z�C���'Z��]Ռ�2��h��,�L��oo��_(2+�P, #�� �f�GG��Ʀ�R�Ø�Ԍ�I�p�MP�����r����p��jKr��! ��"�/�-&{IJ������r�����2$�a��ګLҧ�b�Έ�N�0�9�9�3�0�r�l��+5`&��̭�S~���<vi�xU�_Lv�gj3�����C���,��E=�W�3eY�T�!a���s&<�VFD:h����� �?���G��Y6s�A4����.�]{�Iݙ8Kj"/B˙iR���� ��Y�C�Z�H65�B!�/�k��X]D�oN��:�Ѳ@�`�`���R�w��H�VD9���r�žjJ����Z g�I"}�� k"7���Lf�2L�;H� �L�9͖�ϼz��볰Г]}R�(�ŜdR�'^,�b�oP�oX�819І�awE���Ow�urq����0�ɇ��-�:Q���+�e�K�-��'y�����L��3v�7�٤���u��.���O>NdXK:�F�HK +�v}��"�>-�� ��{���X87�s�&!$����:�Om�,0%35�AS�p�<�&�ȅ�y���C+��k5�l�<4(Pgm�}����V��ȭ["�?q&H,i���-� �Z=Fi�l�����=�^�(��~ҟ�t�S1w�%l�z:h5�HD��[X��]h���.��P�"I���H�/Ҝ��!�5��6o'tQa���{�`w�##���ۄU�ֱ�i��"�Bb&�:�Fi��L��>v���ύ�u�����$8Ʌ�F�T#�Z�������D�h���S�5:� I�O=�BBR(Ĩn=���\Ӎ����$�PڍSk�%�k���J�9S;�A��^�j�Q�.fhzo&��o����(D��{�D#��K�J�w��3���/ ��%~�B� ^���I]ʐ�H�`��]N�[��lu�ĸ��9�W=P��왩�R�i�T�B[�P5EOČ�o�z䉓{��A"0�o���q�����I���3Q#�>�z���a����ɥ��K�0 sm�z��9����&]v!��@�{����ʑB��v���R��<� ��*�hU��ɵ��Q|�҉��}s����<��Lؙ�dU�3V|s�O�����ё�'��ꚙ�wH��j���8�� )�~�n��A&��(��&��WE�%�i�R��S�5�v#�b�2RG)���s*8�M[!d�9�&l�����G����c«�hGm��ϥ����$m�8{�j�@�J����%[S�B3��,��n�|�b��e����i�nۦıB�,�����] +܌�jr각> ������sCpֱ�rIT�Y��Q�;��5Mw���5�����Z��9v�=\8Xt�ܣ݂\w����=8x.�m��(R,<&�|k�Y$I +��ե��S��8:�#mۓ��D�u4.�5�հ��S*j��ւ��!L�_��U��E����?��J �A10� ���\�Lی�P�M���ɕAJ�aI����#��^\*BC�ǧ\��/����JBh���Դ�HAt(TiP(t +v�c��¾3��UѢSˬo2�� � ��� �P���7"�P���R�ø��:7�� +��Zy������1�/=�Z\Ψx���!d���%:�{9�]���2�����u�[������&-A�z��Q�K�"��y�t0�y����x2pO��z�z�8�:LHעK�RAA��F�O�%��:��nR�\ț�,�>k?����R�c&kxi����Д�z�������Ծݖb���05Y��g�@B%Sy�J��Sz=��W���[6zDKA��f3N��9��[>&�z��||�����x�H�*�l�`.����Z�`����#����� +�s+�`��z��X��#ƈ�%Gr�Os]^O�9��f�!:V�����g�er�7 6�@��^.]Lf����N/�u�ڧ���� +�j�[RڝX��Z�FS����7&�� Q��w����N�z�������|F�8�F��ҍ�6�k�JP7$�l(��S���"��`h�Бp ���1 �z$�hͷ;B�%c�`S���`�\�9B��H���>��w|>2�U�깳wXh������w��R�yhT��*�G�\;0�ߐ +�!� �(����T�:8?��K&�p��8��}�b�i)�͇`���x65�V�@fF�6�`�Qs�]�0����� +47O�����0�A��r/L����B���!��JX��3��3:��N�n�7��+���?�邔sԊ*'&�:��Wbn@��}�6$C�P \ ����D)iTFX�TV֪$T�$&��)�ݍ-�aب�4���Lʲ��L�y"����:�e ���l�W.,a\�1$b��w}�F�(<�^f�c�5..�N�� �� 9���a%�{r�� �����gm1Z�A�]���z T�[�H{����0)�c1Qo� N<�s�v���ź�t8��v���\�2��@l����j�t\;z���D^�7*�p��X��Ch�x�C�>����2�4��J�S+Kj���QJ|l'K��q���ew�e7r������ �y�A��T"[�Um�-n8�;6�������@eԞ.: +�P�(� +�O�r�%�S�0�T���Re��uH�ZZ^:ّ� &u�\�s6�tW����\{�8U��� Jk\�!ts�aR�V5��I"��~U��»i���[Ò�uq������5�p�/��%�*���� �Y��y̸54�ar ���e��,�U��>��@� ���8P��2���S��:�n&%jE��"��@7Q] f���р�N �g�����m�J��2�c������4� y� ��4� �y�Zg�Z��ƣ���.�Kn��57�`�9�\�[Z�O� ��R t<�N�uL7# +�Q,��0�O�ܔAP,��*:J��Dm}v���4��h��^7[�E�6n 8Wt���;'JeC+]%�8y�V�l�n�H���&ҧZL�G����4��o��73f����q��G{&�p���m���������A5Tj���2@�)��q��AD,�c��t�>���<L!�+P��;ལ�Y�"����-�3������×�����h.�[�������o_�b�邭�����'�F�2��"8�\�A���L7\`�<[��� ��LL���=3��ɱ�±>G=�25�'�p*�ʯ�����.�WW[�ϐݣ�Ӧ�M�CM�e��UY�D�B�<?�|8κ���>d�NG*�a�fN6������"�����O������>0�'<���O��j��?D~� u4Nc�),]�=C�L�s�m ��h)�+�M�LU�H�+x-G+�� ��#D9w�&� ,�VmB\;��q.J���|E��)����Js�ĩ��O�T� e�����-�,4�^C��9�7Q"з��w@l `R��zJ&"PY42nL�#���[9 �4�#l<��u��-��O� +���=��T���翹�����ݳ������q�����_����|��?��������O~������ڿ�T�C�rNB Q�����m�v� ɰ�r�L�)���d����մc�(}J�/��ʋ�C�8���T# ԕ\���h�4?��I����9YjW]^��(M�*�k*�V�|y��#'�R���n�D��w��"sRm{e\�����⯖� ����h�d���i?���kp&�� +�%�N-��Z�\��P�Zׇ�qB�4�' � X*@�8������<�a]+��W��6�x$��/��%�|r�)Z��oj�9�m��WQ�g�e(O�j��ر�>e8 +��!�KgO4'0рE}�J�C-8և8�s���r�aϾKF�Yz�KʶA#c׳N-�A|�!0E:�ըg-�αq��ܼ�#t�p��((�y��&����Z�ct�������;��t�q�>O4��ɛhZ�=&���,K�h�q�-�=�t��ع!IF����,����lo���ם%n���j E6�D}Y�1���`6�n�5�҂@-��f8B�>�7(Ko��RT|yB�4�����W-���jP���z�% +�3�GwhU�k��8��5�r;qs��<��,�%Gc1I�&���K=��(�h=�r�NQt������K#��U���`L~���ęZ�Z«�Lt,VSq2�m@Һ|��Z�g1ޥA�l��<��&�����U�)����٘v�����ݢ�� gSZ�\�gB�S19h�~NL�1����R�����91-I1��N�A]����9Ji&Q�Bc��]C�:[���6��l�2�.! p��ϓO�1p���y�a)�K���9��a��]�M���]�}f*�D$���0����L�� +Z�&��ŪA#�,$5q+ Ȗ1%ңA�����a�a���[Y�̛ju��X:��r�H�"�=���RގLbg&Kj%��%�R3����,A�ǥ�D�%�a�K���c����-t�c N��G���6,� 5���$m����Y�i���!l�d-�$;�$p������D�eV�m��;�bʅ8��Z0�R\�f;d����Kx+E����N@z�h��4 t!��������������}��G�ы� xx��pw +}VB�,�`i"��$���}�Kӧ�h���r|���Af�f�3��*���R����)����=����d7|dFH���ߚ|�F?�T9���0|:m� I"Z�qWsR�O^��o95_���ԣy���{�}N�wqQg +���� K j�ְ��ӓ�2�0Z�;=���+^��b��$�-O��s���� �gs�Zn=Z�F�y}@��Þ�ЉO��-�p-gk�5� ơ{���I�Շ�:翷���r�6{v�ٕl���_����M���q(Y��r$���v|�DV5=𬢈9h�6@n=���%j�=%Uj�Z���0W8kjO�Ʃ"J��zB$߄V�e�\`�R� �(llp��k�c� "D#�TV]�4��R��8hX��%J?��9Vh�\�a�&J��7G�����!�2�p@�D���TZ� v��;��$��qW���<!2�]����v��7�0�}@� �_���baDž©��Z0���I�hgcg��.��lJ�:,ъ�~�:�>�X�8���x9e�� �� +�T�J$�q�0��)j#ŲH�qMz� �t�{�kZ�[�/D#����O-�ߐ}��<�`�H��')�+W��t$�H�U@� ����>��^N���*}V��O=�_�!x.�4:�Hޮ+\�%`�rCB�Dq����3I�d���V�*D�f���1���K��� ^<!%�����us3��4�r���4o��́~ �klZaD7��V�N�x��`C��p=�2���������ޯ�����i��J��AG�\�O�V�v<�C��~r��U��znm�%��>��٩�<H��f�P:���Dp� �~����aP,`>�x�c�B� +�R��9�x/tI��,&��w�Iu���B�����_>O��' ��O[`5� y?��H�UX��}#�}�Ш�����"T8E0�<gU֊��6+bĿ�U +�o������1D5�h�c�'8A@� �`+���tUJ) >�N�s3��D�RA�Q�u�^�֠�d�?X�p�Ϲ�*8�Wx1gg�$��Pv$mOh�hD �@m����>"٩��k +�Q~�Ţ'$�s��Жh�;k ����cK֎xiXz�߁��e�3B>h�l-�x��Q��S���ng�T�� �A=�;���Q/ ������= C���Э'������0�͏�{� ��秗���Eq�0l��wSl� �<����0�m�(_x�w���V0�����|�����L�������*��v&��g~���,!eW�{ ܬ��� �Su5 "`'�<���C���� H`j�a�NP���@��?#Æ4���\��Y����T�Y)�(t�a�!�@[@����b��O�^];Lo�U{z��Giʾ�K����yB��B�<��ã�xJ���܌I�Ӥ�i���V������a\��M�۩����J5�������<�iD�%�c�<�/E�@Z4����P �<K�������_`*�w��c�b�92��� ��&�"t%��C������'��b���Ϗ�9������@��� �cv�F]�e� � w�yF�<�G���(�t�@����99��h]9*�mnM#����&k�-Qీ���z�����6Ks�B���&U�1�j^Z�(�+q���K���DyF5t��\�V,�S�����du����6o�g��@Hr�Am�w�SD3ej���Z�8]X������.`$[�y��LB���E�f�_{_V��EL~� iG����ٚ�$4��]��V-/ +k߲s��lǖظ)���i%cC��������?��,lTF!��sr�/�w��U��KQv��u�������W���[HK�h�����-A�{��E%�j|PU�!�#.���~e���q��k�ŏ�,���:U>��WTo2�џO���&�v����g�4�������0����������?�����'�rΙ8�K���j�JCy嶕9�@Q$��5��%��`�'�K4��Z�M�T��j�q~��p�Q�q|�/�")���H��@��㻢���r|���<�� vK�Mpv�<;+᳁�E�ԅe�>�l�-=i�,�lp���<z�*�Ų��F7�;P��E]��<˯��i�`^�B�"�=�ݠH�h���I�"���s��&�Q�S�䌐ݧ���Hü,���+7���n,?�\���L�x�ɧ�SW����ۆ�c�+aq�����%����� Q�SE*��b� +l�u�i�OӔaJ��<�Z������L2=���Ct��l���F�] +Ƥ@V��������0RD��gT:*˖gQ�#��;��3qR��� YL+�ET�ϲ�o��:��f��!19��ƚI�<���kӒ�%����KA����x1����yf2ÿ�2�O�3�(wTk�6�����5jL"[B��}7��>8� ���p��V��B=r��9�|�052���j�}Q^�, o�LG�Ъ�-�� ��3�\�;�fM� +^>�S��F�k@G��C������()>~��\0��5�,_b/�j�]��e�_�]����U�Y�則KP�b1���/|����t&B5`�3�����9'D�v����u�T+\��r(W&��W�U�;W�R�!3�a-� +sy]G[} ui� +��$�0m_¼��@!d.9�h�=���b0�_*uy�<�(�/�>)� +Ҙ�B���Y'�<F�D�6�5&�7]�O,=��jYW�0��g~�H�H�s艈�e��������^S��1g�d+��.��r����xPK�Xh��*�{��{���)^??�kʅ��E˧�W��:���:��m�|P����"��Qԉ�ҩcQ�\���X�N���D��R����cw��������."ϵuAs͗���7Gk��p��� +-�!s��L��\fk����u"_�*�9BL���%��Eu����%w�a�X�8�JX�ŝ�o���1�*�\��Qԙ��o�\r7lo�kV�GÖv���K���[�BJ�����x��Q]���.�\=7��z/�ݬ{*:[�) + [0w��E�k���:A*�E�N�}/��A��aS��~~y�HK�}�p�zjlG �w�����aXo���ې�˿��0{��TB�M��&�iᡣ���'4j�Ҕ#�/x=�) �'Ʀ�I�#�*! ��B��q����wX�������#yIs�� �k�?T����N�F�y��b��*��XFύ��V�{t�y]=#`K�.���64�����.W�;��+7�wJ����Fc��⼚���ԮA��鉥�����g&� +������wLh?� +�������;�qד�]���%~V��"�t +��Y��b/�����>W�${�g���nuv�:���2��^|���|6L�Ǚ��beg��9�.����<�NH2/wE�W�ݑ�$��������s�����_V��ѐ�F�o�!���mW��\?�dd��i��z"M}cqT�Jb?��lT]I��b�8�ƃW��V�2�ڱ��.Rg��@��@�툀����W��Z�w����1��J]�)�K����а� +��7�qe��� ���F�Y)Z� 6��k�)��ۉ�f0����!�Ů[���݅���#Z���M��y�x�R�BzV`74�g�.�]�^RP�$�e'����f�@�!C:�Vu���g�(d#�Z��g�˽u��U�C _���Y����N����GӠ������l��u�up��c��<�wz��SaXB�W ���6r]Ѵ�e�����k[z!�>"g������ �XԞ�l���ˏj'xP��f�~A�3���Ϡ �#��[B)ƭ����x�cXFD�6V����BAW��|��XG��؝MB`:(F�%B?`��EC� �3��_��iw%�"x ���q��u�L'nA�L�)�+�K�m��+�W0���Z<�_�c��e<��ıD�@&��&���ȋLw`��<j�2�7G4}d����(vLv=�X�X��x��W4��Tl-U�p�j���b�ze�O��ÿ�m��XGE��Q<������7�(c���&sѐ{fD�:���e� He C^L��w[�I�>��Ԝ���>�����ORI�w�s(�����!��\ӟf����;���BѲ�W`:Z��)Ѐ����fW)V����)l�aԅ4L��ɀ�3e`IF4��夏�g�[С�m���N���BYR�2�O�o1@h�����̟�u�V4R�'`�ECG^T�����{���(��GEȂ�Y�(S!��fئ|!>u��(��`����+�.�M��So�ʣ���g�Z�NPm�k������q�К�V8��\g�|��i�ww#H�:8�!�E�1R$N���7i +Ě�k��5����00-����Pܿz=�dE�\�pUU�IE<Tp��3W�]�4�5�m>+�M}^��-��fx�2B�+t�� h�E��U�Y���^���ȷ�MV����jx +�� +�$Bi�^O�V������`��$�#[M���"�~�yִA�c3�#�Ç�C�f'/\�{ +)�E'p=q���L�m拀��Q�<$Vn�lCGDy���H���P�q����"'���t�,?v$��v_�Z��R� /��3�@A�vF�&g��N�iH\�}��C�f�yV���n+���w��D�Y�O�A�'��l���lS^Ěv�Ԅ� ��L # + +����1Q���@�qF])#p����I�!.�-� ��sm�g �2b �wf����q� �s)�ň$z�9�Խ�-�,�V���sx3v=�w@j����嚭��R�� �m��zwZ���VT�So,����b`NQ��{�C�Q2@�вE���ϩ��g�U�AU�m\i����t��c!JH�*:�����4�8N��Q���j��s<��a�J4=�$��/l��9����S��I��%kM��{�|�9E<L�&+��/���p�L*�)?BP����~�~|��{�I�Y.UL�����QTo �+$�!�Dd`F�d>�A�������� �K�_�1e"�o���{V-0������ȪD�-Uo�E�A��~�>HlΑ��.��=�^h�!���$�o�}���bQ��4��oK[�I�姆!A�ƍX��?�� ffi��;'I�d����![��#��4��ZT�����n�ER�7<D).�(���B�bk�w�?������6-9�T �yi��#Y`�R�����;�5#����^��'���&���&����2�D3�-�1(�O�0{4�'4(Z�PK��cD�{J�?g ��I{��?�z|}��3'<�h;�hK��� ~�|$ N8����fe�uԵ*Ю�0`W��������3yK_�N�\��h�3�~�TG�ev���Z� S��_��N,��yE#%���%�[{MQۋ�� h� ��nD�"��$���1:��O���JZ��;R�I� �$�P�=�uޝ��E��p�6�� �4�Xx�@�Ii��������i�eF����V0�8 ����?#�9��ٟe�d/-Н)�m�T��`"�U�����Nfg��_��l��&�S����@5�g ���E%�M�����e�Zf*�PCfj��֑�`-@�T���L �9�j ��"��D_���Yўc��n����踀�C}W���k�� +�z�?�C�ӝz57��c�M(���h���X���-D��F��oK���ᔳ�ι�y(B �0x7xܸ3�?6.�x�+���&��8��X�q^h����J�$w���V��!n�g�r�e*�jLZ��]G�G!�'��yӔp��<ÎI +�Y���?����-�_: ��g��NgW��)�,��=�"�/�+�m�ژ��iaUl3̗���EYM ��5���X/T�^}����+��.-n�˦�i5 �yA�"ƅ����p����f��T�FΔިޫ����#Z�ӝXQ 7\I��!�]�Z;!_b5�ݜ�vO8-����d4aϧiZkKW ����L�Ay��M%l�y��I��e ����@�#v��p�(�U��l(�-T��a�Ԣ2�1�k���������V��(_�0��;�E� + �$����5��fhB�Q�߰R_��٤ +0od|�������ս �VP��_~�/Gh���ư� ���h)]��<D��C����7���t�x�d7��m105Wzv�af���<99���{���4+��>����XK�\�KQQ�+V�}s�;C�ܝET<���3��W�(�����WҢ����Q�BK���p��\"��X(QAQ0 1P^|��Z��F��ld��v�����C�^2���&㰋��c���Ȏ7e K��㤊�)�]�q`,�BA�L��,W|�Х�Z}#�T���/D��{�K��k*����"�x\�Im�0��A�0�(>���A,MY�Z0 �~� b�6����zŤ�#&(t�(��ڥS Q�Ne�U��>�'*g����D�v�,�em����z#�˕�@�u� ��<c�E�^w.ֳ^�)�R�E��#@�U��~��D�t��˟$���$��I��9dd2����[K�z�9>�W�,���ʢ3N��$��z��N���KlA�9�8=�bT���{V%��� +P����|7�f�m�I��L^��� Ig�<t�����V3Дx+�S��쬸� ��Rn-(���� C�^C��O +���1 "ʘ�� ����2V0ʺ�����A�Z�'f���YΈ���3�5`Ra���Y�v%��^v�7��uMC�F����-�Ub%�U�����bY� ���̍⾊(�\���$�SY`ш9�jHu�|�o��y����� %�ޞb�*��;,��aD��z+@��H"�!#�d��I�i!ا���%b��?�frA��� ቮ�]3���u���V{#J��5������^�^jh#�V�*��L^d����P�A���I�w1�v��~�-�P�69N �^Р�43���c�*\Df�?��_�߫�3���0!���g�s��:a| /�97;� +pƢ��� ����6��_M�ϔ� n��yr5�?9x�aw��K�l���c;B����?��+���W��u[�Ǿ�.�}����QyĐt�S� Y�W'��sA�t��|I�=8�s�5����U��1��L��j��(��J�j�At|��\<�k�=8o��W`��¤=8��z�y<qȈ��� ���J}$�/F�����+Lg�L0�� �U���B�Dp��Zc���6�1�Kf5y� ��k�]?W�u0/�ƭ�6��ޱ��M+����;!���~��r�x�55BX�2�Qҷ܁COV��#�[V��%^~�(������(��G�B�:,��/�*+&� �W|�����-�D +���u~\Xs�uQ���FG���t���X1�K�{��zԁi�2� ���Vg�q�_�DW���R(Բ����Dq{-Yϒj!fp�\�6�B��K()9���G�D��wd�[]�ɊpL +����S�]:l�`���- ��4��L�Eҗ42���o�A�OkS�����R�#kar���ѿU����{eȮ6$TGc�ͩ��>4$��@�6�� ����#���`�9K�֭�U��!��d�Ʌ��pk�Ǽ]1,�g�Lw���+̄�5e �C��j� �'w=�7Q�o!��{*�7i��_�)��[c^�s ��D�L.IE�nj�Ni*��\fd����*��=���b�)Ηo)W������u@1P�㠞@�.(�g�'���L��.;sx�_J��<ksl�I +�9����Z���5�88EP��*5��T�_w�M� ɏ���� +�f*�t���\�W�ux�8��u�P���N����̙�v�߹�B����� �ԭ��hp�eǥ��KwWC]ͭ̎��s�����l��@�'M��I�/�bn�V��5Nf;L[T������N����b�����A�S~�u�7��=����L'U�۷݀�ѫ�wYg�\���p��t�|ʽ���� ���O#�f])N\���G�wa��e>R�I��f$~�=���Q]E*[�j��?1�'�r��}]��~���, ���W�(w�Mt��D�y�^a���Kx�����{(4~!�&�,� +|��L����w)R�����^L���Ki�����A�����{���x�rw���KwU(��V�M|}�4r�g�.��lo�� ߄��7�w<%[\ +QIFE�8���fؼ����z�ǖ�x�M���] Rc�k��H1�r�Q�!46�މW�6����y&��Z�h�:�|�!L�0��8d�1qW�4|<�̴ ��)C��L�Le(pɀ��xfv{�#l� �q�d)����ФϨ�D�3�G�Jt:b_�M�-@>'(�z���~�-�Yϑe�MQ&�N��y,HF_�����E��iG��+�����_�x�Bx&�������� �6��!���� ӆ�#����DݡPrt/�Wڑ�Ҏ��Yp���l\���������)n%]!6]$�7|0��(���d�')M�3u��U��(��]pƫ�D�y3ha���rL3̈́d�*Fm �3���Z?&�T!4]�ڒ#�-��Iqר��u̜�J� -��-�@]��a����n�6��5A�CF�-�q�)�؍O"Q�X�8t�a#�a',��D�ww&p+���4�`�S����ԙ�K����2Q�Ta��xJ}�F�c�����#h71�" d�e�X�nr�Ĉ3BR�#�_��њn2>#OW�7���G�ls� +�b�ɬ�L�����!��59�P��E������ǘ�p��jP��\����/@���xi�)d��t����m�j"5�D��~��BQ�T�š�%D��T����n�\I�$����� ����A��Y�9��I��;Q�)B�ѯ��Т�x���/L��S-7n�L)(�~~��߰&�Q��O-0�j����|v��>%�=���MLc�!Q�œk�Kn��_c�g�Q��@��C�╇9�l����2L�� �<C�Zl l4,������m��-�[,�{H~�Ū#N 3���R(��'�T�Q��jߞ����y��5bQ�xs��<*��ة����u�*�Q��7���|m��>�c��vl��؞�+����BRB�v���mťB9}��VG�W�3h�#�gXS\�-h��]��{�,��e�" t�ZP�l�p� � +\J��(��hTu��w�M�����!I:�'� ��:���{�@SƠ|�=fDI2�����q)q�$�[zTn���M_}L{�̶^�h�T�;�9�JYQ�\��gcb`�C�7p�*�e%K�����p�X �|ã�i�} +�#ۻ�r���1'�Ś="�U�����4��W�w�jV~%�#��{E�gS���>�;��A�G�l���9���#@71J�ց��r�a��K_����b����Rpp>f߉d����lX +p�zw�c�(e��!u:-;�k��6'ˀ]�[��\ԲQ���4�S� +]�xY�`��-J�8�MMm�7U�F�D���$h|����qfZ?���h��_��F �� +xf�9�� )��su����ݝ��X��(,E�)�J�r��`��<K�B�7�O}�rR�1���uP���Bn�����!/,��y�bt� ���U�f��6�[�X�҈�G�C��6lO�=�v}͘��ݎS�6M84����a!�:�D��$5 U��u+���:��/"��u +b0�G&��oz�"�PSy�B��G�k���Y��Ώ6�#�EL�x�����7!�����Be��� �`���P&�q�"�0c�ݨ�)���Mp�b�������*��H4/�� #«�}|p����h/�a\B�|�ˠ�O��B$W�>xA����� +�t@�h˷���a�OQm^b癬Q| 5m�RQvJ����Y.M�������;q�Z:U���^�.<tr��%��X�W9�=�y�u�K���_���俿v�\#��� R��-��A���-\ �FK�}�zᰶ9zX���J�1�@=�C�(uD�ȁ�Q���v��>�O�匌��bHvӷm':i0�iԸ?p�u j�����q��;1}��� ��d,�P<MV� {K���O7��*DF��$��Ō.��M�)����"34���?R�ډaҧa�i���J��RO*X v[�ϼ��4}�4Q�3�]6�H9�.?�Q��k@�<+�4�roŔT��(�$x�%|�����^Jo� v�%���x-�h0���#Lkp[�;с%��SJ >�������#� �,W�{����d���w)z4.�"����������-��,�/�rSqD+F�P�i�n!=��R�&����%�6G��,�w��e��e�Y� X����S�^$c�� +G*���4{�+v{q%$������Ҽ +p����@��*��p@Ϯ�tR�G�� - S +ϠZ�i�EG��<�T�M̨���v���rpP���/�P�GU)��M�� ��,�A��ρ;����V���'AIּ�,���х���G�t���f�9���n 5�Bu<a��g�GR㾈���E5_ԗ4����p)?�\o�t�%mR�c��Z�`��.�k�M��.Џ�z9��x�,\N�}}�Ag�,��Ɯ�$`���Q��@~����J"����Q�a���2��]<J�S�/CY���tXW\G� V��CL�ar�P���)2���}�`f�����x���ů䅫]n(s��ZB��Ԉh�*5DX������B�Mk�� S�]h]� �L#h�.�`'cу�-�7�UK�F��I$�������+��w0 �e0�f�u���yc�$� K�'�����#q�e�(s4�b���f�E)Ȱ�B1�c�z��:ʸoR�ps��P�<k{1��Ж�_��K���#�uҀN��Abd�xnOpuJ�}+�َv(_� U�6����G�.k��s�����w+;��B^�(��y:19��%�����PZxG�E��~�_�2����#���J����am,.H ��` f��@� <hv�glN�ȍ����r�����̾�y�k�}f �`�t��^���=%�թ�P����t�n��Q��Li�YH�F�9��ۃ�Ŵ�L̐u5�N*���6Qb�L��#�n�5DŽ�_�auVB=�}��v%X��/n�V����]/4��5�T�OVc��B�h��eV�>(7�;�� �έ��9۪��S}��h��LC��_��_��H�P3q�y߲�@^c�5�6���[Iɟ��F�0�����>"�㸺��[�hEص�9G�N��տ=������ �a#@}���94G��m�MP�{ ͚��i��2\V]X�I����nF^R�1�'O�<�F��F�ج��H�ϼ[WK�����;�#�ђ��3�5�3MAc �̡π��%onG D�ѐ�s�nƪG��J(�����Wd +�Kyٳ� �ݠ;]x�½W>��_�-����u������S5ZWr�A��_m����&Qt<i� +Z�8o� +۽�0�`�vʝc 9cۅ8�<#��p��8���U�O�=������*� 4��;������9��=Lŷ]��j�S<��Ok�f��1\Zx�����z{]��ƾ����|�H1?ϋ��9�*1BL����ȸRAkq�"/����:�5�(G���v��� ���20$���^��s[��͂����`����r��h��4��84%�����J '��� SH96�X(�BZB�PN�8�3t`�ݖ҄�IS�h��Pd�瀦_�X@2ZbʉO�ϸtP��^������'"�/�-4Z{���µ�p�J<�*u-W��h�B��aO�\돈�sj�ۆ]5��y�Z�;�ҕ��)�2�����p ��͎�dU�s�P�@j�_�3Av�9\�� g3��<�)Y�G +M�41s�s��b�y�䢌��������`P={r �{x@JhP���&�)#���]%S��������%5���pD)�a��J:c +I�|��x�F�Oa�P��]� ������:-�����R` ��'�.������f�B]��7|���h��bP����U����P�SA�b�Z�Ф1�2��E��B,��W�ܨ,�8(���p?`�����L��hHZ�C#�5�4 Q�$�}��e��6�PX9��^Ӭ��L�I���zԁ9�PƘg+�!钭�ϸu���m{��(�M�[v�Hy@@I���t�`Z^�(�izP����%�lXV��zv8�Wr�e��E�)Cq�OI��A���������h�a�Z�U�lAi�Y(���F'D�ݭ�ݭ��σqͨku��J�I�'�+��%�q���v;�i�ˬ�1��~�r���S��Hѡ��b'/F������qp�&�>_�¼�e���aB�h{ێB��]dH.�o�Y�@�a�f���� +�{�����~�^�Ѓ6U���q�ŐX3�O��}��~��?��N���(VA����u��f=�"y/��C��I�k�H�O�@l�;ܸ,P��`�"-)I\�$j���{��S=�q�U�;7��;8�x������P�o��`��{�b���^0�/�\�[��i+��6����@�d�-���Fm������������|wt���Ԥ���#lE�:������O��Bx�b���+�R8�/�����H��3�!�oA~���A*�HP�X�~N.��*�+� + ���3��S�PE�_�t4VH�� �+0��"���?\�y,�!� +��l�\�iŵCQ�#i�֧>GU���-�w�,�B]�;���.2�E2���yOֳ'ž˸ƣAs2����4. +��zZθz��I�����g�L83��Р�����.r�B����F���ܩk��s��yd��F=Qÿ'�\�w�@r.��CQ�XY��� @��iI1�N�Ͽ���O?�1\�S�D� +ᛃl &p֊�;���W�!9GCVkR�4έS��yz8R�B��(;[����Yx���T�O�;]�$B�� +Q�jP0;K���CX�x�#T�E��#� +lq����;ST�6�*욠�����2j��f�"��nρ��R�D��X�2L���ىM�`��C���T�r�@�4Mg R�p�3��'���l6t���9B��4�K��c���"v�ohn�Vg��1�.R����B��M4a�S�=?{Fn2e�ncF���{'b)�< +G��0�.�f4GK 獁(�h~�x�{��gE9t1ϧ#�!2�D�ME��X���(xG�P�5.�Ar���!W���<q�Z��4͡AS�/�G!J�lAY+Pq�"�k�Ks��A����1Um �]:w��^����.�I�[P�$�tr��f���r$�u_ɦ���`�����|�X�D���dǃ}���� "s3���f��؞����aL'�p������O֎2�y(-��q@��� +�{�P�] +�x"���]5@4�J�w_��sP�D�o�����^2�2��_��_^��� �Jδ���D�S@J���֖QBD�z5��|��jo�Oa��Rv� T�-�3�������'l��Pi����,=\��N�CI��?Ŋs���Y����/4�8^j�O ��p�����K�)��K`?� ��R�g����eؑhPo<5JNL�/�(�(L��8�O#�l�N�"��5ơ\�]�P��xWH�����:-3a�gi��S���%C�|3�TO�^¦%�J�wY��/,�AI�.>?���R�*-�ll%�'5ʾ$��\1N�qW�|U��;�.n����-���"�Ĉ^� ./��� ���UAj����`��ؽ��#�JOT�j7���z�,� +P���b�ܦyG�1��ci�Z{��=�E��A�*a�ݺ|J�)/�!���/r��C�E"E���| ���z@$+��Yh��8`3�w%u��<+}:����Z��H�@���9`P�$��H���Y��H�3[��S��L�s��~�5�*���h���#�Z*��"V� +�t�ie����WR#�P`:����K��ҜQ�����C����Q����]�J Y�:a%�pLd�aB� ����`���P>翸&��;;�M�/ +�9��t���"`�-�t!�9��^[����#試م +�{7<)��U"�d�.|�Uj��)9&���}c��Ѱ�D� ��CT�Lh5~gK��W�� +4<@� M��|��$ː��3�$��,¿���M���Ð�����GⳔW8����ET�+�\ +,��B�QlqD<��/�[}�K�.��ppW*a�*�� o�m�s4�����w�O}uUB3��+�g�TR��$ ��J�s⮽�5�A��;6���C���!��*^=�5ꬵ��ĄN 2�^�C�_��xP�Ӱ���2�����t\Z�<��v�=;��<��:Ob��+�5�~�����Y���KU6/D��e�1N���Ѕ:__�r�������?�NL��1���'@�:���x��r� +�|a� I5`_T�D%��z�،^x�QU�{���ww��2'�}�����)�s;�Q��E� �B��mC*��;��i�qN����2Rŕ��X(htp�W���c��&�Ҧ'1I�?�g�S=��%����S��k?xKRGH�'I rr +9��x�bs�h���H���a�8�c�� ������R�S%6��E��,�����ʸ�C�&zn�T��?���O�b:�W�X��i1�P'�`�Ӝ:�`aEL��:��כqS�$���*.S��f�T�>8}�f��(�j�"��:�tj#�$���A)�)gX� iT�F`0!�U_�z��-Ҁl�k͓���]ό�@�5E����^���'��h��d�a���Bze�mf��]�4r�S>��̈$�Vb�QrCRV�9\�E�������!���9��%Փ��z����㋺�=�jPW"Y�)�5E�(�ሆ[/�"�}F�b���ӎ@�:8#h��=MׂEB��U�i]�3�{�5�E��$�[�.��y���ސ� ¡����: + ���ɺ�/0��_r�� �,Юc�ћ2+_�@�7��XrKh�V��,O�T�"� +#��[��f�jv��i�P�뷆�o ���M̠�'.��sZ��T6��@����>��}���V�Y�)Q� �y{�;V���@��0c�3� �@�U +�*}DwGP_ܒ`�$g���Fr"t��_��hYC��b��(㞴o B�# �V`"7ڷ�S��A��H@+��:1���H���&�)G�]'z���������m���l9\p�P;L����gG7�����_�>��>B�E�hE��?�wX\��x��$�g�A��Ӝ +�&� :�� +���)�Urvha���1��(���.\Ik��:M�a���б�B>3^�b���t*�=<�%��`$h�T��X��!����$����1�>s�ɝ�j03��.1lb�) l�( +oͻ*����y�i� �&ן��@�<r�����C�s�j�Z(�,�Jʄ ? �>`*��F����n�+Kh�! +�=�Ib�F����'��C����q6�z��Z̘v����ֻЫ&c+��i��L#t�.�v��^��<#��b�v0::� +��HT�~�s����f��rJ��K�e�Tղ�a�k�i8@��L�b�ӌ�:�q�w��0%�,N�[���g����5˫t��4�YE2{��̸O���֠�ͺ��2��:�w��T�θ�e�u��;�q t�U�������t�j��a�>�J�\}u��S��1fJR�J4�a!D�^�����j9^c�*���&���$f��<Ω��P����w���xp*Lg\{Pg��I*Έ"�� +Z��.SL���\�����à��G^H5x�9�g���D��f�oY=�]_ڦm�����a� �a�������]�sb��U `��rR�(`0��l��� +�Z_�~&����ܛ�p�.��a�Vt���\�� ��N���'�������ش��ϖ����4y�b��ffg;EIBƈ#*,dh�� �j��p̈́u_��.�@��������S���0!_�wM7��qP�����!>O;Bq�hQ��_��_F�eͭ4��'����� ���s�hZ�i�-#�~���a��23��\�X7�#��? ��`JUe)6�D!�ę�q!��Z��wi��k{�6�8�@�fD(2����$��l�B���' A�C;�Ũ����X�V��Ļ#4��틽W +c� +�d��?(�굆Z�݁jh�&��;_��c�n�<%����y��~`E.A��:y��q��k":��.I/k��J�@k-�G����,Nx2V82!�`K�� ��l�Dc�W:oD��������p��B�'~��nn��L���������-S�ft\`4@Pp������6��������m�q,���׀�s�h�A������Կ�-S, +�������k�����7����� �w%�T�߽�o�����lH��iE��qY��sk���M���_�j�yf ��(5X���oQg�Ҧ�Xտ9�c��S'pam�u�B��Jމ�[�oV����{6��Q +��H&�XDA�T��n��H�Io�މ��i��\������Q����m)���\�$�E#BA���D�)�u[��6?��{�#]_Z + ���� +Y�Q�>����&�`�@��$EzVp�0�:#�\ť"S���Y|n�nT�+�9��~&!��D���9G� D�Cg�|b�1j�Q�`z��f$��� ��R Y�O�P�q- �3�����������Df=���o�-�Lc���-�E-p��7Hs�W ��\���ݰl��9O ����6aj�� ������� R�@�H?Bo�3�k���n��^� �� ��%��1��Ic��J7Bh!�}v:�0+�:|�(i2<$]|�2�2])2�pN,t���Pc���L����la�Q"-��3�_F �Zw�%����<�d��2�q�Aw/�/P�O�����ޕ֏��]����Z�{I}�5��ζֶ8{�lv�Qړ�W.�T� ������,P�q3�M�֊����<��\[xcb�'|��LΒ(�`���X�C���)��O�z���J������H�"V�ОE�/b/� ��Fyd�#@k��"�K��t��MD�AQ$��˽Tj^�z����M�/��֢���`�l�B�4B8�Š�p%�Qʱ�C �� ��>��K���?����2����:lrtI9�4f�M,�#T<(�@�t���p�<,bK^���J��IO�j��X��{����G"�x� .R��ݪT�X��R#�F� w(�B��Uu�,{��� (� �ň��X��=o(�����%�e���?���Y_M|�Yt��B)l������釚��(6T�&�sh�ޜG�kˡ�b9���I9�x���j>�U{֪�v��S휰���р\ӈ]X�'�G !��|)�Eh�S�?��:?m�W�&~�0���p���Y�W���{XiG̻�{X���s +�� �&/sN('�B�p�, B8ĕ}[���`�1��M�O*%��a|�|(�,V`�t 8����� })���5hߙ)�Ru���Uo��ʝ�{��]-�;I��l�Iɀd����j7�*r�j&���,Q{}W�gw�����^�����7#PKNb̦#�ٌDOG�k���w6$1_gkv-�z���.��rlD_<��AU�ؗ�>��xߦ���Cg��v����`]�G��h'K�WeI�d[��vOT�@G��A�=�� �Ւs�ea�xG� 2��[�K�>r�����T +dY��#�Kq|��<y�o�� VN�i�b�dq�;Q�@��M��R��Xo�>��J��=厨1B�����Y�U�iBK! �w�x��+�6�iK�o��؞X�gY��1K���9m�"c�a���? +7o�"��%�K�ݨ�¶�ج��yS��w9�B�'N"�a~-=��+���_`�m`P]��Tlu��d��{ajNy�L��6��ŕ���p���.�E���X,~� +z��U�'��X�V���)A��4z@L���9��}��gˑor�,�)�O4W�~��y�L4���Oؚ�(�kr�7�Fk�)m�O�☦@��$�E����^.��z�0��eԬe�^���맑]����Sk�D���r�n�����ϢoCa���S�j1C?#[�����σ����̪�"��*�� ��[���hθ����N��D3�NU]�E +�E���|��_Tq;�!�<�(Z��3�:H���P��*܆�Vz�tb�y��兊'��'$�>��ئ� +��t�̚\�����7|l��A�,�&��v/����fp��Z!15�͠��Ϧ�n6wbF!�'t|9X7,� �b^̍��`۱��q��A���q���`C���G��0nӆ&"�|qs�g�cJ��[�'� J�����aP/��Q�R�t� ]�?�� �nx��F��Q6`���P�����ǰcC�*��-����N��W� a��]��(/-�� � ��r3�Lx_���j7v^_K�����Os���s[DqX]��'ve~�ʄC2��m� >%Z�}F%��ֺ��,F��C�{(��i�`�O,u ��l�S�����p�ʖ���7D�^�1:-�!J�+�*�Φ���q�+����%�z}s�},~�m�C�s�����A{t�e�3��K�g+��-�@�_|�r<MgҼ>;������0��q�BVX�< +�gѢ�P����iA���߂(YT}�3>�R�7�@�OM�Q���mt�< ����a����v��Úbћdq��ѠYp9P���r^���x���̒�eĩ��_P�[�.[�������H��;g�T���e�L9�vN��Ip�Æ'&��y�߅b%{q��7'�CC����d�}����4�O�4'����)ܙ�q���8q +���0�����wdBβ����I���bFu裡0Z(� ��8���t�E0G"������j؉�=�P�jGp$�ֵ](��X���%;�jH�2��S�f�f]�T��t�/""����'}>�&al�x +� �Fr_u�,�w��7��PM@)N#Aׅc�a������;Au�s3D?姴����r�`uWK�ov�3'V�2��8I��P�ip�j���vY'�r ���~�^4�9�I�U�D{����1�� ����v�'�(/{#�`��K������M��o�dA$l��K�̚����\�T��x�_F���T �^�����0�9�y������~���l���y���G˖��/nb� +�.o����U��qa�8|��WX�O��q�zV� ����>5�B/{sM����֊7����#���Q}�<��d@��hd���f�ko�E�LG ��CA/.��~� -����K!,0)�$�3���y�#�Y�n�fz�x���{I�E���9Ut��w�"�/�?hr�����dO:o�Zo[^�x`F(��P�@3H^� �y�D][���-� m������� �W���2�#�K��Ħ�>9��c�d�،���X9w|�cb�ƃ�* |�>�8q�=BH�b +(��X�bD��9��]F�J]�K�Y�R�R�g %�}�)�7Æ���+�$!�=����\�q��vq�����ӡ!a��OUz�:�x�,4uQ�;}J'�d4m�HD~(����h>Ln���+�e$������ܪ]���� �h�j��C���N:�ф�����)!<�#����UJ��T��%_�ˮ6����Hexy����{ �q�/���I|�B�%{��[�ФS��tW1����-I��k��������s��H��Ş�����-6���}�0Z2+�çp��� +�����(%�S�f4���|���k��>���D7tqҎ茱T�u%�Ǎ� �i�1��l�&�l3[<��y,oaT�^���8�#�Y4���<v�D��ri�C j�9O�Xԩc\E�\b���a����l�@y���:��}��߀�L��0�J����}�ܓJ�'kB���D)�>"pf_8�hJ��G�jD���Qc�6�:�,1U�OK���a$��1��?�X&+Or'>�����OG�N�~�ׯW&�E�3̀��-�7MߤF�N��-Ɋ�(DV`�)@}�_�&yyċ{}oeݷB��#���z�y�FcX��Aڙ�W2;xLO{��m�U6�|fG�i:���d��)���=F�P�K��#�s7_b#�P�B�<.݀����9x��Iz�ؗ W @E�lY���n-"j�0�����b��$�X��e���-aǵ�,-�$������[�ya�$v��z:����,��#;m�3A�� �h�B�� i�R�1�d'��d�x����q�r#KB�k�c��g_�І4��L�ũ��)���p��p��L$ƊY�H����j�����yt��}�1TD� +�O �mW���4 �X#Qx�c�ݍ����@�ۖ�״*C]�su�� ��J��/��5n���1;�p���M7��P��3Y~��x�g�����d��T����Ҋ�Fގs�xF^�#�#�ݞ�3N�C �����ߠ��rQ(���"Fm*�"�_��6�e6�t�z�z�60`+�-'��i}vT,��~���'�� +FU�* +�pjK�o\+�j���r0���^`�@�Z*����f���|�Ǻ$��o�AsA��L��6� ��Ģ����e��w�����_fhq.Y=)DPax��c� D�z��o�Т�ۉ����J���r���@MÄ�����b�^��&�%�'�tTZB�84�.�Ң.r��:=���#�P�S� *y�0��� ��I��QR��P�l���CR��A����E��/�'��}o�]���ЦF� +<zFCk���9����9"z>h�>� +j.Iq#m�o����T#�D���k���@� ɉ��6�܌���5�냅�w&�[M��c����fJ{����o�q:�MQ��>�x�u��xc#�nm<�M�e������0���yy���)?���d؝0�����S��G�����4� �T�hA�u��n�P�V�n�Q�nH$��B"|0��B%�4��Ϥ�=p��Y���� l��㢓���8�̠K��x��}S��T������ +BBӹ�U�<H��yo={ �bض�_\,�"��@}֪�g�ym�;�<�@2�։���M4��\�Uɥ��D&Y(�p�5J�����h-ଈ���:���F�\G��s����%)�g������t���������N�&���|��G ?��/�[H +a�B�'�������~�����)�3Y�;]�8�V���l�TH�L@R=�Ή�3�@�"d.R�$6����G.���Kݝ5�ɖx^�_K7�����1��a�Ě�P��P1���X?�)~j�?�.� +RK��G��E��ۅW�눬�<7` ~�*�s���^��c���v�f�����R��8V�ݴhv_�}RL̳�`�$a��Ѷ�\�S�w6�M&L����5�F��(="�q����E�=p��:�����JR�n���lC���qB�9 +�%\O�l��A�4��ؾ��c�%w��ޞϖ�#��٘�n���ПF��D4�J +Xz������R�#Y��̠D�mPu�@���R��v�����D��ҫ^���V�����O�|_�+��t"�{�;%�J�+H�l� o>jJ'���hfn�N�W����xW���9"}F<V���#�=��95ק�U��6����T��l���-���Q�Z�e�c[��R��4�=����T��Z�f��g�Z���5KG��J߬2�;�(*�y|ޑ$K��.5��gX���VM!\�U�_�|� �XmӃy��'jv*��f��L�p�J�"l��L1Be�3�T��������d0�3��3Uφ��K�; a�*_�� �tX#�;K��d��#cycYI��5��V��%��#ZM�[憻-��9�em"�PH��� f��V%�w��Qn3��vTl9k�����|�ktG�/<l���M�EA��umw���ݰh�}1 ��M��Qu`Nn\/�H@�%5��c;@��;ҽ����ϕ�VgS�Y��� �HCy.'��b�)�f����s �16(����8�HD��ێ�gA�aF�AoBؿ����ST���A�m�2D�vо�:��̙��R��Y��`�Q��*�&��;K��GE��4�'����:��1lij�3t]��� ���d�]����a���S�nY�#�R����؉��ǎ�Sf0:�ݔPLvB]H��B~nqZy=S��a�C�������dQ鼵$)q��8%v��k��+���"��j.f��RU�rr����O��MEd�:�$�Q� ��4�8B�N�/R1�eV��?�un�����X��u�������!�"+�����b��~������ z3�Q���1�������淪֣�1ճ��![G��&d���VU�<kgd�&6�R%�(�D�G���������hG]/���)2.�� ɿ^z��dDgtw�3`�NW��U>wo��Α���B�E���!�R�*����a�4Ϥ��a��%�wDVF�X���&m?;���?b*��hK²]Vo�|�����ҟ +R��|-@�� +2 �tDEC��sIRU;�/#!���Ov���G{hw�a ��4M�z��FG���ᗃg� ��a��k7F��=�=����Ī�#-��M�u�RcF��fF,�9<RIΐ�����3z��v�Q�@ќ�N~@]� �3%��+w��ё�SL��T^㤃I� e��:�_�.{̄C�F�eD���=g��^Q/=d��b7��c���w8���D�@���Ab�\���H\��^�]6lT�%ɨ�JY>+ ;��-F�|ZVK�:����&G}Dν��i� �z�m�V���SJ��x!�Q8����5�3�**j'K�����$a����r<*=�M��zn 8ȳ���uG"�6a~�оKz���m/�㉢��@a�oJQ_���:8[= &[��v -�5^k,�B)���TVA@����uA�^yG(r�ޮ�p�A�]x���8���Ӡ {�Dab�xՂBڎ]q*X�����{Mމ>I~ �N"�I�)T{.N���Iy���|K��"��.�E���EY*>�w@��)�P�/��?�QZ���% �n���}X� ��I����C��B�� �Y�H_����B�8�PH7`�ǁZ�7E��)���*�.@x5���-A@j���qs�t����f��4"��3j<v�4e��A���0����Q�lӵ�%�Dh�G�J 5p���� +��X3`��5q|meGh4�%oCn�BH�H�4�X�;Hi$#]������"��W��.��W��2d��X�����g�)hB#hB��ϣ*Q���^K� �=�-�/ѽ)I|���d��� +m�(&C���$`���MW�0��;��+j�@M��x��ojJ�.�;Q2� J�s���E���Hk@�b)LGX�Wc�yۢ?Ou<���$�bD� +��e�C4?��g�x��Τ������K�Q���R(�U��|k'�'/GU��]��)�6��Ԁ�Ӄ鏛�U��lo��j�l�Ů: h��n�:� �sN;"�=�S����·1��6��9�ʅ�\ ��rv�א��qO�Ihgf�;����b���I�m��H�OY�šWa��i�v��R܌�>��p%� +�v�Q�+��l4��W�z��jU�BK���AR 6��� �JY:ˬAǞ�ʆ���s��-@ �P���[���ON�$�0��2.��[h���Z@��4kE)$-�����c!U�E�`��Y1%T8��s���y7��;JPQ��Fz��6��8x){�vU�PWAZ��� f/�eX�Y�N�9+�Є�34a��@���)_u�)����ł�v�)/h��M8N~^l���#�ރ��ypϦ�t3�pC�n�i������i�Uvd��2�K�{`�Ш3�H�e�a\gb�Z.���p%��e�N�09�Cٙvj�:ne,���R��&����}�J�j]���j���w#��Q��]A���?NJ|Ҭ;��P���� �V����GL�N:���Q��h�V�z�gv��'q%�"K��L�#��V("!3,��m�?I�N�F� +��m��>_م��d +������J��MJ)]�t��W[� +l�=˻�A��R�J+�"���,�nj��%lt��L�s7,�I�t��� g#6ǀ$,M�2��5�J���HT�P�WA��1��é�Q� +�-</�C�R��=wժ���ɉ��D&��P�3BN��mx�0B Xc��Cf�����s�8�j>�ThV�>�Eԃ�>��3N�҈���}uQ�&���!?������ޑ����bH/�7�K���\��7H +.�)�h�"����A�w���>d�Zub��)U>����`Z�ZJB��DȨO]��#�1hlv0�%�Y�"���������F�؝-����X<,�bl��b��'�Z� �f��w��N�[��x���F�h�4���e8"�PCɒ����O��>QeMiZ9�x�>��� � �L��� +?���ji���9Ҋ�H�O�4�|g.����G�� �L��X6ň� ���R�<k��'\�yζ�bp��FK�O��[�����A��"���i��w���ʛ@t����Vt�ck�Yx��y��\;PnKuY#; ��V�{�C4Ʈ�>@�)b���q�-,Q�=O�S�5a*�I�]5���6��|��o�3�} xE��eZ��������f̝��/W��9� ���tM��G�qE23�飙�C����S�9,'��`���(\0j�\��<�wg��9�V�k������?J�s����"��R��� +l<���v��ı�� �{��H����z&�n�c��\l嚆�Z�O�`�A��o���%�>k�"Is���x��Y��hgK��4U�zlj$�H�3���ٕ��$��ɖz�}Bm�`�3�Eð:��<ּ�=w �5���6p�]#���y|e����0�Dz�� �#��e�$����W����s�T��YuZ�M��I0[(��|t�t�@� �:��uђ����0������C�9�^�34DC�0���;�M91�)�B������0�Np����2��D�0p�*�������Jx�Z�cs����FPG[�R9*PQ���{Ja����P�����z8_η�r�3ϸW�Mh]}Ĵ5�Ea[d�xh���(M������7��{#X�3�=3������bߨ��F��ih�E#f�Q�B����+z��=t�ǣ��\"�^SڧJ���ϕf�㊮���ᛆ�8e����1����N�k�{nѻX$��P���_�H?ޠ"~3zY2Q�!4�߳�I�j��C���v* +9�#�H�7Û4k$j�Vv�h���jh�gD� 04�O� +X�l�~�9;�����1@9�3�o�Ay���ىo���{�Į�a��Z��s0�#�ٜ)�d��Xvf��A��{)ᇮ��C�3 +mPF%��)y�2�)m}H��qR�)���,���c� +��_^5�ATy���{��t;�#� �N��w���w�m��5gI��H�^���0�aC�mZ�(����d�F����:��A�,�9���EG�k��'������*o�F����T[���{��s+~���`���w�m�+��鸶���v�g9��p���j��kJ���%{jA��t�ӹ =fzY���1��e;���w��$��2 �����},;�-�Uy'��:p����� zvjR/����h�.W�]�!�-��;�l��l��1����%3�*�\V�(f� ���{Rh[��"d�2�'�FH������1�����Ģw#X�;1�7���^6t?�}�H�s�:F�>�6���pn^�tn/�{�W^O��y����9!5-/D��C�]�f<���>B="2UE/�v@c9|��f��! +�m(ZM�C$X�_��0U��WT'�bP��Rp�w���S�U����LL����rS�5`F� �4FV�!�%L �|N>��`�!W�V��l���{+ؗ�0��mVKAm�C0�c��³��PK��;�Fh�Lx;^�:��ؑF(cqpN��:N����'<��B��LkXS?YSj|���F�����/b{G@>��i���#Τၩ䙙��:�P�b���8��8�����2,CZ�gj~dIJY�k��a��� ��!���]��%� ,*,wT=�qS�o�Wz����^ 1X�b�����x�>�� +]Bc�^����=�Gpp�;P��3ڀ'��z�#h��o | +�� �?0�6z��Z��MW��������bۑ�B\vB\͊p�e�e��-��x5�I�3b�zFh��W ���Y�'bn�g�Q���z'��V����,���(x5��#8[�~�D��|Ц��#�cD�OW0��̤�{��Q���t���i�!@�(=��L)��p��PZ N +�,oV-�çt}�P��=��F�T�r0cK38!U�;2F���ޯ�]W���ur�g`�#^�1-��<�O���{+9��6`S���|TX�)�m�Ø��xy�\�`����8X�E��d���HBg�:�8=�eG�x�Y���To�W�Z��[���j�U^��RP-`�j�� 7�a#(�7�o�����q6M��4i��������/���W�r���5p�<�?)�,���0�p�Md��Df��4����_�T)��� |`�~I}�����̃��w����0��9�,�i`���u���!����җ�P-w��ns�l�T8$e�995w��"�B��ۆ���9���F���5u�v@*Y 3:�4��?1���:2V�Y�(�S���~~��B�Q��A��!�,Q c��W�%�@s9�8�ɭ���OXe��aȆ���P���Vj����P^=F(xZ�"��H�Ȩ#Tz>vG����С�b�%�ފ�Z�(�hJ�TR��MUZ�#��%��Tqf��W�`�<0"'o/���4wc�F�Z��ֱ�$`c����� \�u���>$�[�x��243g�d� x"����&X��t�*4M"0���W�)}�!,�P�[�0����'�K� z�:RA�� ��R,wy&�ޚ�y9�Bu�":�TAПz6�D�'bTZF�[��L�iU�� p`\�[4�ԑ����E%jKt*�\=̪���^�S���0�O�n�C�1� I�ND.�Z��I��1;�`B0Vl�x�Ā��O��TU74K|���8Es(�@��aa��������g�|�f�����#���J&L$5o�U����ϥ6Ic�@d��{SJ�D��6�,^���H�ٟ0�vX�B��RE"��+h�T �fQ����h�P���jv0�!��ߤ�~=�;���8��*����0������륇��O��6���ta�F�H诫z�Y5�ۢLv++*2Ű���o��Is%�"�� �g�!����X��3c4Y�K�D�J ?ƆE��+���SE�b�e�`$�71?8��Ψgynh����&��:5�(�j�gz�E��P<O�uw�Af#�p?9�*/j�R�H�`��ӳ����z:L/���S`E��0 r���^(� z-�'!�����6$�!I#[�sq����+ـ�F�k� +��OVV�8�w (fS���)d���G���V`5ۦ"�,;,W� �{e8~����&����[�yp��UZG^�\�Y�S�ު�@ӫ�� +�nF����F�;��j��4u���ɾ.�մ�U������3������R_���A�������O7{A�I��+Z8j��.�^��M�r�B<������k�u�ء���T��aQF̶�$�_m��X[�!@��aH'2l�m����Eg �(4���`�i!�En�R��NIg1�R�<�aߺgvjq�;��F�hA낊T�Խ�� ����F%=����&V���u3� +!l�~ĸu�4��۳���F5���$7쁾;4ܢ ++RF�gv�G��H���8b1&}z�~�]?��_�J+T ����g��!��ۀ��#s�q�t:�t�%1yh�LF�m:㕐��P��ԍ��M#�Y�%���=�Iѷ�>��he���9�����{�8�X +Q�#��Re���^A���O]4�fp*T 4X6hF^d�YWU����^�-ԨNNӾ���h��v��/4C��w�Q^1y�v�B5��I�����ϟ�C�י&�PԹh��xg7�������z�և}Ɠo��Pd� ��t�U+�:��gB2�� +�EK�P'�͍A���u]����?���mG�D:-�d�t(d��>�g�xT�$q��K����4�zZ�0��DtR���IEݔ��3%����M7��-+�>�g#ps�!ﴬ@�PD������Q_@C7�ٟg9=��ܢUK��[�=%b�.k���pB8,�;���аNk��<��G��7���N|�--����#�j®�K��f�4w�S��?�|��] +��C��Ԋ� ++aEB}�G\���0�,݂q�_�XI�@���Q=��Z���ZR~h5�4�wGJ�ޯU�5���f�ݖ#9�,�{��p#������1�bQ��J�/JӒ���@Hb��(�(����[�#2q*dQ$*F�,d���#��k�����/5����v@5� +-�1]�z >kM��6�Y�jmY�ܧF}*�1�Զ�� �)y��k� +����U[�y��Т�%eq��D��'�Hi\�JU��p�F����Ma�a�`�i��Pޤ ���$���ٳ��#\�i��:��8���{��v�������2�� +�Xv���I����q�� /kF�g,F8�B*�H�J���J�@YT���\R�'��)bo�m]5��S%@܁�����A:Crbj���96̌�5��jvȣLe�'M@X6V0��1,��gG��>(�+���%j��u�b�+^n�Dm�`�W��R@����^�1b��0�lj���ˆ� +��e˿�3c"f�M�FI�=h\I� +�_�W(�^�I�]J;��⻍>��:�ų���U4d��8\.j��OM��ɨ�H&�Ѥ�ap�./ۜ�NZXr: � M����d����R��g�U����$�N��C���?H���%�J���w���0|���MH��M�����\PB5�>�`Q�7[7��|x�JI�6�c�� � �|Ȗg�Dڮ��4Ћ"U���͜�H�Ғ�- +��7��:�=�N_�gA�b�b=OAV��4�a�Ɔ���IH����F^�n�ā�1QW��V�G�ك�bP�:a��k0��l�p� �(Uf�L��0�o�4������͚VZ'z���ظ�!փ@*���V�u�8 +��p�F�@l�T�-�r"���� + �5�͌~3�*�l�I6S���N���Fx�fCl'�Ñ ��h��+: +}{����l��#�f_�՚���k�x + ũa�H(�c5�@�;p �~�����ьc��Zۅ��HD\�I�B�$��Ҭ[�{�pq$�'��:x�A�ݤV�����`jױ�n�F�S"5+i��TO� ��^�r�����T&`� ��-N��=2�Oq驤 ��$���5&�8�\K����, +UV�T��b��B��Pt6b���r��z�Ygp���)m�� ��.����78�r��`H�� �C8��<(4p�~�&@ ����w�)�f-T�"�V� ��X���Q��o��䡃�s�d2�!�AhE_�2�̜�a�"5�H�f�O��D�u +d�\M�Ji�~�dV��f��+���Y���P3k���]Xq�"U�����T'z���[�@`$�,��A?ȤO�Úd]3���Q-�t��;�I .e5��/���be �h'�З.��7\��x�� ����l�����%30�t���w��J��WZp3�I��w��jS'�o������ې�1(�n�I(�g�K �Iɇ���L-�>�a� �|^�cB�O.�5$)WQ�3�#F�T���֣�(|Y�|-� I���tP��(8�d"�����ECr���-E�%�`�ju�!Ax���BJK�Ls��Ry��B��xT���T��Q`Ϯ��7*/IZ$�j�k��΅Q~��Mi����l�����h׀�0~�ǁQV�b{���b�D��}_YJ��4m$BH����=A�^K:Ie�_Q��+���61 ]8x�TԢw�uOfF^S|�'��d ���Ncޭ�.�o��T��v +��a�N���s��xB/�<�C��Ij�����G�X%b!�w����-��ۉ%�E<Ռ~Ҍ�t��u�A��j_��B?���ƭ�>O�yp��狸�+>v������Ѻ�2I(��ƮU +�}_G����z��"��S�w�4�dG����8�<+��D�Bʼn��z��%����0`����뵥;�7�}�I����A�(�ʂ�G3e�,���rhj^��2�T�I��� �TQ�$���`��~*�*<����ƀ����Z��m�No������J�� �E�(B�� 3�+� ��Ё�9�/<^DU7RR���Bp�s�uʆj��0�Q�x��~2���F8 +d���IJƵwE� :X���:�dD�����#Z7Ք��b����{�Ea�!����PF��5� Ұ7.�? F��״��Ht�(;/� @a�W��~���=��a�(3?�$�����D�y���xҨ����牝En��V�9�*���RT*N�`��;��;v���%���/np�2GtZFD���`^Ȋ�'S��h.`�����Ӝt�Eƻx�}#,�Q�Ⱥ�d.b�f��b�pV-P����RD��Rv�>j�c�����t�_�#Oڑ�|�H�Кw�� +wp��I��p�0C�8�X� +l�TN�0~���ZL1���x���8a +�a�G:���q�%�A;?�`�k�RQNU��P���M��뭍"W�M�"���c���Y���#ʫ�F�Jp����EokpD�/����,�-5씴�"���U�p�*�����e�ړ��� �%�Bz��7�<�ܷ�h���"�/��2�Ũ�,y��LB2��M�T�)`�,N,ˀ�i!�R�7�<+�& T��Wٓ]� �2���J��;D�)jFCODJiL����Z��J������P+��`e���Ԣ�@ +�3�AN\h[�o� @�y(ApL3�dTt��FQ�<X���ڧ=�X�X}�)R�#�ᶰk1TD>i� +�a��Z'���~8U4e��4��d���1f@�'��C[�`e��WӉ7R�/0��n�/F�J�0MՊ��� �@%O�[Čv��֢<���cV�~�,8N��\��d(7T��u!qs_Ui�W��<�m��@�/B@�M���!JƉ1S�7��G~@t�ܭ����=UI�.63%>U�4*��ʘ!}�B"RY�P�z��8�مI��e�P��P�V�A���;��X3�%��K{�3K{�[ �O)�T�)� �B�5�:��uBÀ��A2�Ў0�7�"K ,�d ���t��1��A٦�� ��e[��j��F[~�UŖt~�%>�B!��$��i�>�j">5ETvB %�n������h�g��$�y)�e&)�n +���[�j��x��w���ϔ��6w�^7�l�Ź(����W���af!�A2��7��m�ʡ�OX�����Rϒ��BE�ۼtZa�Ȑ\̡B ��&h�r����x��+��KUW�$I� +:�T�y�pEq�1��H��>Lt`b���Z�����r�K6I�+��9�ZR"Af5ܨJ,g�Ty�;a����X,}��1�b.���\*6��{AET�~O���!IJQ;���q�a���&Y�TV���%�hf/�Re\н`���R%ڪ��^��U��Wv�Br����el"ѣK�D��"ez~�\*�בSm%|��Иh�(���f��h6*�D8�i�gj�*�Z��D4 �)�}��Uc���)�"�e��`'�(�(��I��,�=a֍����S$xM�\�R�n��a�s.^�սR+'�dh�_Gx��t���8c�8�@��1H���**.���IXQ�(�z�B��;�e1���聕� +X(�����*�#3�B1(��5`t� ߑqhc3��g N^� �͚�Qz� �e�����W��8��y�З��0�n{�V��Y�X�:� +cng��$�g`�`��+�zn��NĊ(�$iB��jҙfpȢ7O���@�'פfJPf����I��� ��,�N�5��H�O?8�=��V�)���cS��#d���R�.R�rU$3o�ȤP ]U'HQ�Z"��f�/k�I"жg������/:�1�Аg8 �NTv1#Іg�ݖR��K�Q=�)b/��(�d��p/(*�ڑ�={9���ǴDǽI���"2٣�c���0�*8�F15s#��v6N�<3g[$����i:4�ū)��*��& �ʤ�`�2{�Y��@}Q�MT ٣��8���2-�xGJ�Cn��L��k�̹c�����PI.�vS�lwBR�^�Q�=2[Jg�>����.��L�Pu����0� >y&~�����F�F�uk�c�̽Ћ5�h;;zn5 +4CK�k�WKWdD:�s/��yz�a� �Ңw�k@g)��B��T!Pe]��W� ��l"т���KTq� �&3C�F�~��dU���x�~:�=��q&/k���0K[!� �C+����t[uP����9$LQ�,H�1/�rˀc������B#������&���jT���"���< +�a��aZ�h��d͌+��$� + =��9Ec'>M�ؙƥ�P��-� HURta�����`�c��9H��t;DϬfBZX3(��x��NA&9�.En��A�,��e ,�k�~Ŝ�DI�츭�����b����"�J�%6k�p�7NR�7���(C�"�8Ѩ|P����{�XB���asUQ��̶��RN2)B��bD4���d�Y�����O`�R��$LE&<ur��T��:1�ub�P���Y+�^����!�̐�����ޙ��z)M�C�l�M57���7S���U��@#`+� ��*0&_��Q��IAz�3�Iz ��4�0�6 �Q28�I���(�Ѕ�ᓗ�-Fd�Q~h�2,�SIm���d���B���RVRm +J�ځ�I0\p)�^���R���6;Y�i*(�j�XG�b� ��;���M�q��Z�ܘr+�#�?l���3�� +�^Dh�+Q!�7I�'��?@�ԇV�yQ����:���E��*/3��!�X�&7��C�h,��#���?�w���RS}4�vP��aq�����o�>5�Fx���?����|ޤ����l�&�,3�w)�k��Z�Y���J�jq���N��u"�lh��њ���:qP�#E�H���8 +\����uP����،���\�zV�:s�u�|�z���,� �z�Dq�t��%���#Խ���*a����6��\�~��RkBp��lU��w�8*�(�yPN�ŹS�~�ꀋ�=�T��1��A �A��$�� ����Io�%� /���N�B���t!l�%Ъ�d�U|�4B�!�t2�荑Z߫�C<9����{�(�2K�lB ]�P���E��",f��qZ���.if��q��b�(W�o�t�6�4�s���_su-dI^�ӌz� +e�,�X��u�����CB�Q��#FG{�AD��d='���!o���[d���K���K�-D�c͐����o�K��Fdk:^�g]�dI�ɒ�%}��K�f�7Q���=2�H�Xj����z1�z�����o�#/r��h[�V-X�x<��^�����Db׃`W�MV� `E��>��ڲK%����V�߹beXe��{'�L�&��'��EH�ß�T��<�N5��������J.=41m%��& j*"�HY��8��8��CIJ*�j0ʳ��_u"�y��h0i���ROe����p�ԟXTT 54���X��X Ҏ���~*�����_��:<3���� +Ey���S���dhN��-� +����k��I����3��_!�!8< v?��D(+O�m�P��3�g p�Xܒ���'d�^h��4 .�@8Q����E l[22�����d8�hYQ��d��!n�XS�uTyr�E�X���Y��>�'m�ɣʀBh�.�+��_�m�R�+Ho�+��v��R�-Һ���!`�H����ψ �M�워\���B� l���w�[(������y^*/t%���lq�y����0���[�ʇɾ��4�8XHFBB�2 ��b�`��>����c��K�Zd��d��2��rQٱ������7ŹI� +�l�.ѽR�T�PB'�g��fq���j���$�H� ��H�;���C ����PR��c��^F�z[���y`ި�_�iHs���BMb>�+��P��I'��Mˢ�fd�ȥ"S���*�* �:�:ݎ +hQ�����R������.��@A��i�ų�b�ϢLN�5A�+��d0��r�6B�g��葃�a��7��0��F&D<EŧQ ����E��<A�H_���3�e��V�I6]�ɐ�J���Ή�r�"4�Y�E�)��8� �����t/�R�j��t�~� z�2��D_�e�5�z'l��2�x'-��n�@LU��� ʋ��V�5҇'�<H3P�.<B��I��ӕD}��9��q=�8���:U�]� j���IJ�1A�~^�����Go����]k��ɀ�~��߉y���"��4z�Y[n57#��Z������ +cq�T�cIS�倍X���VY6�ǘ�^���[0��D����SC[����R1Ȣa4BL�܌#D$Y� I7�Xf1s�!�3�N{vo�h��+�=�v���7eֽ��{��Iߙ��@�� r</�}� �Ԉ��� ^3ͥ�BLk���$�Q�K�n����x�_�4 +�½��ļ��a��p �����̬|*��1(�����x7`��T`�d�]��R�If��G)^,�Ma�ztl����!�$��+Z3qw0��s�� [%�=Jo��sN����\��.�����2�!���}A?6����r���ŴD�>פ*�0��ܶ6I >���ه@, +4J��7��z�=ym�Z[�[J�2|B����,ǂjj�µ��)�H��(�b�J�Q"�Yu������讬���|_�A�Am3�@��*�BC��F#��3��j��2���9%B�N���-��(�^������C1h4�FW��-t��j:�E�ө�9c���"�H����&H@a$�,��x��H��y��u�+��4Uh +j��b0�l�!�c�cpY��v��g�$�˶B�d�0�{��DD�y.I�ڶW�!ȓ35=|�Q��p�m�Y)S�~/N y�����)1(����"�%�z�pT��H��/%%���ceX�6W�1����1�Tmݵ���W��؍���l�8U�T�3�B���&���(�T����{�W=P�(�!b�A��$�`S �ۨ�x%i =Q)%�)yF��A��TL����^�!KT��!#/ؗV?����Q�fm�ֱ@R�Z%:�F��j ;AB)�'�ى����T�`<�P\�/xjcSۨ����;wg����7����wɻ���WyC]{A4�0���X�?��N~��X�7Sг�Dɍ�H���/�D���X�Q}�]n%��u����KE'��l��8֜B�Hщ�`W���[@��LD��.%��K����GD�D���E/�(:-b��{RH�7�|��(�~/C�[aV�{q>쩊�b���2����P�$�1�����ړn�̀���C&�Rsʤ�"�T2D�:�p�G/�C�|wP�@l;�%&�B$�jB7�qH3y]zlv�XEf�&�/�� +��~p4�g�H��>";�'dhcUףUQJ�g�bb�b� +?3��Di3E)�N�!�>EG�L:�"G���z���bO�+���$!�rb�赎F�7I��f$�]g��\�^�Q�W,7ڤH�W�Oi5 d Cj{L���ܭ�1(�٭�.�lu.G'+�rv���UL(�]�� DjiD�I�k��@N��UA���c�� p;G` +D�]�\8��l��~���/���2�D���x��Bj�"�E�*9U��T� i~�\� �������E����$6�)�J���0��Y���.�q��;Z�z��U�T)�V0ѻ.5�ɨ �,~�kނ� �������I%�@ǜ�_K�z\# ?ow�Z#m=��D.&�<Ɵ+�5M��b� �Eβ����;TQ��35%B%�t�WPMZ�~�(A�ZF��N����b�Om�,9$ܲ�0�F��$Ht����6�� +NFt]0Q��X%�i��W=0+��v�"� +!�ڻ*|G`!��Ցd u����e+m��QY���YNf�Z;��b�ԨL��%����j�w�g����FK�>-�e�Na)Qnӧ5�4�P�%A���sSK'gS@G���o*�b�0�B���2A� q��J0��a�8�1m��s��-��K��H%��b`��$����X���(6U%+;����P����<�ɑ�'�kK����:�I�R� I��N��$��@��H %%_ռ��%E�V7� 0<�Q��S��^N?�k��y+v% �RA��<H�y�@��R��!Yܥ�*��������a��1n��C��A�a�����|D +I���M?U����M5q|F�Ŭ�3�kBt�����ԃw�K�Mh�0#,�a8R�x�x@Gs�p(��-��`a#����2$����z'�B.K�TG+[�FG҃���A,Pe�؈5�0J$H�C�/�պ�lS�j� ��-�lv�gZ0C���t��r���Q�_#�����+��GH6J��"��CyVUaĢ{�\R������ Р�+*Q3+�v�?��AH��4j�P�5�:WZ���v�!� V�`�zT) +endstream endobj 58 0 obj <</Length 64512>>stream +����o�t�|�>Jj���Z���XE�1�G��x��(6"�r�N��gDFa뛭��բ�|��R�Ҹ�ՠ������X�)�L�/x=�Ҫ�1�.��3P)"�"(�-�G�g����/dK�'� �����jC:�g"�pk�J��kH:1���͔�Bk�u3�5�+�צ��;|��L�|({'x��H���)f���>��ե��ۙ�����Z�(=a����1��:�C�"��U4"�He(���4th��t��@�bѵeF<��j�,v��b`��R�~���J�v��Ç��h'��d��,�ϹH�Ƽ$��Q-<��j�H��:SO(/�Zk�pI������fǺej�� !�ɍ�싎�%�`t�q���17�MʷH�ӥa��--�"�;4"�㛄�סZ���`4�f�k�)JT�� �3�XE�N@�ٜ���۱w��غ\�n���I��NO^ +`A7[I��fa�Z�6J�:��� +铖��e� ��(O��O�!��z\�$�d���]m�� ����#�$�+e�)@foQ�a�|y%��+{MRKJ�-��F{REy�)�zOW�5�Svg ���1��X�ڧ��G�Y���r���w627�Q�NG���*h!KpV3���3�SF=�P�^U@�''_r��MT<��Q#9�ɚ!B����b�(j �h��q��8[�>(���O4^�)��X�m"=�t�� Z`�o�l�dA-����쑒s����Bf�a�_��V��@�%;��0���tb��tb6O]٫���;Y����ޅr��X�d�&D�1BV�$�d�w�qw�^� [���}�yNr��%;p���t��p��)Dx��V�!l�+P��ޅ��]���yݫ�����NJ?A�u�ɦ����_&����O�{�ҐG���(?�:�wcUeO�!�'��I!�Q!��9�!9!T�+�%IA�ޱ�� R��Bi���b�n=��Z��b�CP�l[B3cO~�E���~�Pm嘨 �=>�_Fz ���+%������IK4J��lY����D�;�;���\�a��5,��4���~�*E��A���I"6(F@*Q!Z�<:( A��ӚKb�����j��ڪ_��1P�ep�(e�����p���F�~U�S���o��Q�Dئk�YH�'�y=�$�!͠<�-�#������b���wh�QBb��=���{���#�G�q�{��Ĩ�m`��J �1�D�*�}'��1�y��i|bg�i����DF+a�K�UN �aQ54��H�[LN��b߉wZ8~(��M;�WB����>Ӫ�dj�� �#��sZ�Ʃ���>�(Q���ݗ%%=�4b���15�X�iT�'���J+=d"ԲXw�t��%��2���~�5 +L�؏0q��+������a�Ԕg|zq0�T'�u�9�s�ʙ:���C#>��p��P� +�:���C���)�PѡR6&{� +~m�N�[]�0x]�6W�������+ STȷ������9�-Cw�o�V���RI��ı!�,�[�פfy��z�A�T��g�R�����?<�;hyգ���z�v3W�7*<R]$����0W���bA��A�T ��Y� +0qm�i)kM`�A� [{����K�"��^,Ŵ�������jӡsPY�S�+�EB������:RJ����q���9���ųLzL���2U�S�3�z���dJ`�S���Y%>��q����>���"�uVe������P��t��,��� +�� /8���Ў�a��Y�@z�D���:$ +Oɴ�~���#Pt��'A��k�nO& ��?ra�s��AŸC�������'�l�~%j-�̋)y�PzP��P�� ����{�½���MT�@,�q3"G����8�*�ù���sə,��im�7˱&�A�2K��P� ��櫨}��}G8�U� cTk`]��ka��)|�s�^"� Q�i�b�Ya��Lvd�ĂX�Ad�IQ|a��{T���ږ�Xgq���/�/V�����|�*{JKp���z_�5{@�v�ў�L�b���3�N��� +��I��ː����y)�Ng/����䋋�~D��� ��{�x2�O���GP�� {��䒂o�n#��H��*.�3�H�9�EI`���Q��`# +>F�=-(4���J�e �aÕ���~n����!0Hd��zـi,x�%�?<��ɴ���$�[��.�N���ňd�n�e���� %4�w��Ћӧ�D���]xZ��D ��C.��t����.���mAۖ$�lQG+��@���y���@[�؉wo./(Y�+�J1�t>��#�����`8���`�J�V�z�m8�5��1H��fp[E�I ��7!�5�X�G��Ja��;z-�j����ô��yX��ٌi����.cI�_��!����m-�� P|�����������e�Ց�׃�6�+hgo,!���>iz�ǜƫ�S��-�J6㘊�p���� �@�,,��e!i�ni�>A�F���7Kތ����n�Pr�F�%|� +���;u�� +���'� ++ +��?"�ǐ`��|�8WJD>TÅ��'-T0VEf죪G���<�J-9;��v���,���c�Y�<Z$�>k� r���7M�!d=r�Ѩ�PʙI���N+�`(�AF�Wf��(�19��5���S�SE�%�@�R��0��� 07��U������Hfd��Z�Z%# �V��v�&��y�L�^�73 t�~D�%������D�h��#��%-dMU]Wf`I��6�Wa���*�д�qX�C��'��;�ؕإ�g ؑ +���,�'�^�q�i͜:58Ne�����19~�0:��81M��(E��=hߩ�4 p�q�_� kkP�AT^������ED���p���$��Lu�،U|Q�:�<���� e��7G�j�[�pQ�.�SE Ex8�I�C�2i���icJ,��$[5mf�έ�I��*s�:�dY�brY:�̂��ϕb�l�V�g��^�F��_��;Um�Sd�?1 �$p?�mD���!��)�*7�`�P�H�(>`\LN��Z�)�ks� F�W���!#HP�U��B�v-EQiA��Mq�قx &�Q�� +#E�O��C>J{a�0�"�F +Y�z�<��tB��<ɲDqŠԂ���@tez')�G���*b��}RE�@:E-�G�a�� �>��b�R� +���Y@�*�Aj5�z@ 1~�x; ��S�]QR�ъ�Q�eX��c�r_�,z�@-p~3��`�J��K��M��U�<�6���U���~�j���S�=��Ma ��ޤ�� ���:�:؍[�5�*��E����뭶�EaJ�3���IjϤkh$���m[�j��cř$PoΤĉ������ꭒA���婙�I��A!�*Q��$��z�nZ�]�JI����y2<�*N�(�" +��B�t��X����+O�{U3�q�hX�m.�"V�L�� K�'c�y!�xK����8�ك�� ��fh�'XZ!�S����X�d(@l&Z[<�*�P�B1)+[��� ���+QML0�m�B�6�$��c;>D�<� ��ZB��zQ �p���v�ֶ�}�lo�r +�E�q�j=��%x��d�0�D�Z����j�nk@��_@��ZH�LJ�Ц�\0(X>�Ěζ7u�o�x^�EN�Z�P�_镬@��ᥩ +�x� +�FPM��Lʤ���KcJ���.��C@��D�6b�@숃;�>���a�{�B' +�h���G� +��K�VuV�T�sU���9K�����zcm�b�<��"��� �� z�~�A�2)�`����xbې��[��2��B�\��Y�� ��M�$�0�R_���U�m'��IAlg��G���ɷ7J4���\�$PJ2́f+��,� �W钐u���8�& 6����\���ȭ��̎h��$��G +��� +�!�b � �r�n�#1�1�Fү.eъ�RߑƘLdXT\O���20x�)Pv��Z8j]��,��Q�P�76�tz[k� +B��*�h\�F����Eű�p���H���4�h/�b���7g���&�j��Pd��D�*O-������� E(�2�Ͻ�l���,��.0��-:�5��ܒ�g�T�C�MD��MK�IH�ɣ*�z��N��d����d�'9��G��Z9� hTo�� �+� �n{>��x�E�:�f&(ܒ��$wTt�����g���+�%ۺ���Q��XZ@���*��^�{�f�Q_b��b�\!&��⸀�yʩ�?P����"H� �D������p*�I$(y��D��Q��^ЧØ�A������·�k<�.2�Bl���z��Fg.u{�j����O"^h�����%!�C[{{Jӳs��"�:[(��G�\�.�bhQ���(oB0�v�4`�e_%��#��;� Knͬ�adt�-�,<��d����c������ +r-'�w}O;��5���i�kait��q��B��"�1�7���+�r_j����� D���X�6��m���["zB +�oy>q�ɟ�J�%A����֢#��+�5�zb�(x6�B�*�{�Cj?W_�H�U5~b'#�=�䦗�����(֜CY�G�s�W�z�@7Z��`�D���b�u��;�ݪO�>���ϔZ�i-����.�8�P:���ڛ�Iib�v���.��B欚Gg�ē�,K�|TL��1Q���w +�I���ɋ<(W/�������Rv�H��`i�O����řx���f.��1���K��Y%�5�����UȽɖ%�*�7�N����IR >^��)z����R�չ��p�H�'�&���F�49q�ؔ���1�cR����ix��(�*���%�+Q\ܪ�A�B�3įXH��y�xb�� �$'�UnRr�_ ���[��(G�&W�%����D��f��46Pt���^�(�E4�`Xt8Z&��*w��.�c� +n����蜇=��aI� +���פ�B�0��*�L�wCp,��[1n3W�w��#8(CŖ�>z��d!GsJ!&=�N�V ?E�äĉ<`��Jݩ2Z$*�a�dSl+C�-TC�$���T��*�K>nUk��&ai|yEȄ�D���\�H�Q��/���vE+��=�,9+v �[xd�H8��H�C���]��"�{����Z��E (NoOt{z�f �+�D4�Q*a�~�d�q)�L��H]%\�ɤ��5�~Αy����漈�h�̚T(���dZ�0'ˁin�N�F5P��b�B�]��)�)���?����7�Q06���J���J���DT�(�ͅ��l�"�Wy�{r܇R�0���!IJ��-�2xG���y�@��&�]�����jٽ�::�"�.U� +�H�.vYk�<O�I`e3,��k�G����#��&M��z�0���$�+����;�������*�)�>KF���vR�^���/9F�����F瘖b�z0c�S� 2@�ɀ7��:I��^ד�)���~��!�Ň��b18T/8v�OEj� ���h/H�]�&#�`�P�`�t���Γ`ə@��䋒 +�rD�kP�,�$��_H�(�%�{=Wa:yo��E�>]�I�@��Sp&���O6,b��W���^�^��=卭��U0��:/��2H���v�eO�)F�t�f�_H� +8_����!�]T���7ʔ��rv����t�*��po�FP�T5��@��2Nl�xm�8/J�(�T%KL��hN����A��J]����%�5��rtc�0�/n�46Z@�1�C�,G�ր����X"�]o��?�_ �9�|i�>�! ����HBPNk& at���Ys�2 �g�0�a$�MM�!(zL0z1 + h��3L����3�K�D�sZ�rM-��S��;�:��#�U��p�J妻m�5cw��mj^U�<��sL.{�C +�*|#�Q'���2�5���V5���vt�Z'����J�� +?�dd��(���E.v�*beˈ"V~" +m�f��{�K��U C%��:G��.��A+�t�K�֊+�+� 﨑�<H��ey�L�s�~���e�B <��u^q� +%��E�+ȕ� ��6�5�{���ڞeKqA��le픮vn,l� ��t�f S�D�*TK֙� +"��/��Kf8���"�-=���v�^��މ� �U���N�����5�)k�EN@���xȣ��EqD�[#{k���h��܈��ٿE��$h��W盉>���$��Y-��E�W� U�U���S�����=� +��R����Lk��x-`̈́+ fI��Ke�m��q\�8��"���<l�b���J���!�K�U'x����,�T��[u�̺N����[xj.H #�Z%�_<q����ё+-]�n�u����r�J�U�S^C3�@QO���3#����x@~�~ٛS�J�B� +�e�Z����4�Z�*)H"�� ���K�(b���bG���H�1�D���ve�R$���$���!'K�pA�QջQ��cCCiL�r�(�f;��j�"3gx�}�k��w.��{� f����U�[@�d; �a�2@�:�^� +B�k�1r<Aap�X3 �� +�@{ �� rdM-)Ł�<<�P�T=d�OC���Ê�2P��Z5nr�.�P��Հ5��_iԅ%88!%�j�2Z��$�:�"�Cj��)s�J[y�SUJS�U���פ2}%�̨ u"6�"������:)������N�����xA�|rN!icn��p�D��NjI�ඁ���Z�䜂I,.o%(4y�2�� '�ϲٕD;�����F�@ +��쁎8//T��q�&�16@�J�@0�"��'OQ�P-'�H��$�5��<���Q�fk48P�s"t�`���� �$sz���)����u +Y�m��ʲ���R� ���tCuV|���'�V1�G��E����榜�Ӊ��U\oG)znC.���F�⪩cO��M�<��T[�*�zT�N�b�olv%9:��U-�+�R��e��-s���(��v�A|F��~�Wz�ջ�a��w�e^�� _�*�B]uÀ�'�i���x���TQ0����ٖ�g��o��[V� .�^��Zt���& �x�d/�����V �ح:�-xII�fj��������? + +���;Cu�r��+��X��j�J����6�)]GMrgQ%�FA1n�ȭ�،՜�CT�dC�F���Rj��Et�O>\06�����Q��6ȤHk"���c`�Z�@u�!�9�Pb�W��<WOB|b��t윀��n��v��$�CAD +��OE�z�̑��"���e)N��72�� K�|�x&��U~,�!�2�vM7nĺ�j��NK���KDN�.)��f��MI��f�nM���U����&T\U�Y����)A+8�%�5�2W�Q::'�p�� +�|��}FX�I�u�(���8���~d'��&�2d�{�~�sz�g�Xr�����)tLu�V\x �m��وK$�y���X��T��$���.8 ��m����P&�#q�E������3Lέ�W�%�:g�e�B�@�h����_�tl�[E��EZ�65����S� j!��K/PB����U����{ji�����F2:��죱m�k#s���M�t�pJ�rZ[�$�{hbZ�@4k�B��Ae�>|p��� ɜ.5^d�t� �X&z���9R�T&֊�Y+Vk���V"����2�r|��dВ��^�.�h3��oS��aB(�ֆ7JZ����k�z���R���T�X�l��]4�E�n�;�`Js�%�c�.�ܲ��L�S�Dܩ�N��1���M�V��-}�^���a���Sm��Dp۹���Pz��=V�� HAH�H)�Q���~yVc��#!������%-F&#��N�Nz�,���b�%�D���}vW��D�;skK ^Y��|���zAv�qkKd�5�+��zh^�F�j'cd$ ,/p�6��> +�H�xk\�@x1c�ʦ��F�'��%`��D�����K\M��N�(��(��i��]O$j'�!�F�"p��@�,L��W����'�"-���$V_}f�&�U�Cr�܍ +���k�{h�6���x|�{y�!��[���������_��TT0|獀6F� �[R�{������q���|rz�������]������.oi����?N���;}}w/Z�_���#'ǯ��_�?�����o/��������-�h���n4��*����������/7����:��j�?��ة���8?Z�v w� ���㋣�˵� +�����������ٿw_���e;��(|���Ͼ�Q~i}�}���;{�k�|��~�o���������s����k�����>�$���G���ͧ�Ľ�~��!��ħ�i�?��ǽ��������K;�����}�CD�rF��a������}�_��ʶ�ѯy�ᖫ�g���n +�N��Y$*����0u?P�r(���P$�Al�,|ӭ���,��:ff/����������[��z6�����n?�8\���ۯ���h��U�խ'�~���h��;��~��� +����W?�/mۨ�:~7�q�q�>����ޝG����:q�W�}H��(U����˯ә�x�u��07Ob��SJ��0���H���Ư�� +I��!�������� +;��l˕qMlouZ���p�ݶ_�n;��rQ���#$n����avڼ�~]��;nx� r� �_� ����\WQഺaJK�|�O�n�����pG�<�����k�a2|��_��g��M?���{�OWo�Ư�o����\��7~m'���_;��Q�%��� G=��������?��������W�/��5��^w��x���[>0�{��_��7~���;j����7i�n�L}��|2���-�2u�x�����[�զrzz�lň�����V�y�(�='�w��j�ռ�ސ%��`u}u�5�6�������B;ջ��Z���~C�ea���殶��1�?}�x�f��a�^ktzǠ�W^��n���O?� ����Of����f�"0�o�뭐`V��mT-�p����t�[�u���bO��@mӍ��nou�\��$P��%�uw7Z�yw=�����%�uw�[�zw�xn#um9�憭~�����N�O��?��p��ֱ���߹Y��O�������oON�T�~���o�'��������c�}5��~��/�|uzf?�� ^�|����������z���ON_^{p)5����\N.�������._��9{i�xq�����_�N����Z?���oڑߪO����ۏas�!v�W��G��g���g�?|�uܸ�'/�Bxwu�F�է����������m�w�G�2nڭ��SW�L��N�sG���-B�i��_ET7��S[`/�\|������x�'�o�|�K=J��ƽ:{��G���8�b�X?��f�A(w���ǿ�8��7�·Xg��X]=;�����螕t���՜��/��A��U���ݼ8~��t�%kj��uW��zp�9�n��yåg����:���:9�gA�b�������Ɲ:�������bx��}u�����w�?|r������=������O.��_��f�Xm|����{�Z��'���9]��'���tם�o/ͽ:�������n���{�ys�N�t�N�t�N����x��xj/��q|����/�|N�����<��l=���֎�lۼ���g�K1���s=qw����_���Pmnܯ�X�����={��[��;|�����ً{������G��-�֗���nѣ-������o5�ve)<����Ǘ�O��_*�����"�������7�������<<��e�<�ь��uw���ώߥ��#���X����O�/������Q_1S~:�"Xޚ?VW7�9�~s�����WG�[u��Q�v�b����=���Om�69��������#:�q�N�F�f�lӧ���i�|y~rv��V��{w�U�a�h��.`�Y�1O"��ֵl�O�}{�4�S[@6����m��h�X�o�=���D���(�D��y�WzѓG[�Uĭj��|W6�Ë���__n������!#)�s����}q�eO~�7�Զ�w��������\w���zJ~/�������H��>???}qq|�_�'E�>�m��n�Uc|����y��ۮ������/O�l��N�뽿<9=�"������D/nޣ��V>�io��]�||������OϿ�|�>Բ&�����V�R���{�����=?t��[6�{���e����������Lz���#�w��cs�}���B��;���۵n����<I��y,����ΎO�:>=>��e�y�c���6OӼsoo�X��z��tnY���9[�);{���7�����6�ڎmk�>y������������{[؛��w��x�ύ_���¼����8ݑU�ա�ns��.���l�ܹsK~��Y0?����ʧ�Xn�vd�ga��6z�ܢ�y��Ӣ��f��A'�=9=� +#z�x/{�9������~l��k�=V����6��GGo^���p��k�<V'�=��z�u�/o�X� +�w����{�����鏇?m�9�!./��R�����ű��ͧ�˗'�'��f��G<VOOΎ7�c::<=���%'kG<ڪ��x���w���篶����Q��ó�W��[���n��M�r��;�G���E�v,���ȥm�͎̤g�\ڂ%sw�K�2���]�.=_��]۱=n�.-إ�z�t�K��7��]�fM���348��/vi���ض���K��.m3NwdUy�إ��]ڢk;�`>��6/hGV���t�|�K[tm����B�E(�6/x�E�1_� +�;����z�+��ν��z3O�F�#��g����E6����gO�"h���=5^�������;�V-��;,�uY[�6˲�,�˲�<���\�7����Ǽ�eQ\�eQ�lQ\L��o*.��(.��F��z���-��xm��I<PN|���L{��/3��o�'�̴e��?�J�+�U��i���!�e�}���_�������ß�"�/�'g/��=9�WP� +�����_oC��v�c����W��Q��(Ն���E�q?��U܂�i!�ZȨ2�����?@G�qw��*��_����7�������e?�}����s�ށ��Yk�Yc��;����s��B��:����T�gW +��[�v<q��ۑ������O.������a��\G>���ˋ�����ZC�}4�t�ݓۻң�=��u^�Q|D�e�m�[��7�w��we+>�8������v�.n��{����A(b��� �w{Ệ[*_�l�]�`���X6K��%��d�l���_��K6�.�u��_�w;�����0o����L�%��K�݈-�%���NՒ��4�����S�r�c�ß�OO�ܸ��'�}i ��` �{4�`s����o>����,ȳ-V�>�Ͳ�.���[3R��W�ڍ�tG6�6����m�>%�%���Q�mv�%��S��E�~ -.��%��><�_}wq||�+�f�ef��w��������.�_������>��s|t�-�Dž���՛�{�`�L����u���ڧ�b�k�<r���'rܿ��{h!�9K_4�r�'��C���Gf�]l��y��Y�[w�7���l�w�����3H�qӟS q���ltm�1O��-�K$j�D-��[��D��H��:_"Q�.��N�ja)��H��9�K$�"Q�g�=vv�c��}����`{�u�Ϝr�]�K����?uR��x汌��{�#�3[��!���3��GB:����Ѹ����t�'?�=y!�{�{�B����w�}�I��[�\��%/$p[�ɻ����e/p?�f���<G������_����}����-�O��x.����gA���㍾-z��ڸ���|ڕ����o__2}.�_n�����G��#�U~�+������>X�b����^.��n���x�Q:��/6���#x1�ͻ����m����N��-<�Gt0b�����x+���~ �bx���y&��s ��.x�E�����Y�7���?���S{]K�f �,��]�\n��{�Ȁ�� +rz ��ã���?��lQ��oڽ�bO����ͫ?����6����<V���T^��>�����9>;��v�c�����˓ˣ{��W!4����6���A��գ�#�Ɲ�E����_�BVv�jzD��-Vօ�l�~>��gIU�0z]����.>>�W8�\*��|��|7��o/�_m����F�� ����� +�����7oNm;~�ԅi'k<�quv+��N��K�y�8�=�Z����b� �[�v0�-`p���\p�w���/74w4��9�iwsaI~����M~0-�;�k�N����ӭ���.��⟮�������;�������g�ۜ,ew=����8����8����8����8����m��A�����]n�0<y�t?>?��<[�t���#�6o�#�P������B�r�7��;�cB�υGf!ްG�̓!ٵu�|��] ��qB�������_��oN����=����ã�˟��6��ח?�n�h�kh���v�m�w�e����Y�RK��I����a�m�Ԗ��"���9/��~������1C��Xc���8%xg �7X�ֻz������o��~~����>��+N������^������x��{���O�Nm+B�k���Hx�b���=���Wo�ɓ�<�K��S��ڧ�Rk�<V��=:�����~}��십�}��>�Gk�Ͳ�8��I }{��摏f�m�L7���p~v�.�]�؋ѹ�o�J�)��7��M�3���-ԋ����b�}�쫶�<mA��p��]��e�~r�9�"�����{����mknѣ{�Wz��?ݼG�4�ң��h�=�em@ޙ�������W��������q��'�_���Z��'�'o��/{���ю��[��ٓ���Z��'�/o�s-[��ޒw1L�h���!֜�{I��fvy��[,~76�g��ȓ.�wvww �6%�}��yРŽ��w�_�7�L��Š����xݕ=�ա�nsv�]�gG������J�~���|ګ�s6E?*�]n�����??����]�]���PѷG���V�1��'���lw�T�ʹ���++ +i��?��g�y��+�1n!پ����KܼpwG��s����&��o�/~{r�dB@O�����SH��ߜ��-C�Wz����x�1��\�~����O�� +�{ao��c$�n�Gb\���2_<���3H3�|qx���-�r���x�B�%��$">�d���)Y�K��-�L���NO���zj�������7�n��T�~�ٿ���o�^��z�����8?���"b�������N�����?������W?�����n�����{_{������>�$���G������?� *�ן��?���g���������� {/�|�?v�������tuL�ž�;}��ޑ5��_�7������:ݕ�\�Y�|��'/��>�/��5��_�x/���8|yb��^2f?�CJ{�+C�3ٓ8�!�=��/�w� ��]Lq�}�O�7�ݯc �/��,{}M� ������ܷ�7���/;Y��X��۽�+%��؝v]?�MC���}���6!ԚR��Z��웒K�Ѝ)�:T�k�u�}*��p`�Xk�����[����gƮ�G�����G�9/bo���O���}pL���5ݟ�_?��՟�������o)M#��ݠ��?}G}h�ը�V�����z���Z����S^=���|�w�����'��ח�~R���_���������g�ٯ=���:���tk7��=���^\�Zy�+��j���<��Yo�:͙f�gg�'�����C[)R<��!����XR=����C�^��>�6��~��N�`m퍯���w�dL���v��Օ�[�h��^�� �X��`c}�G�p�W�p��ZUV�,��M'����ܶ����6�b��q_�ޮbg�1��%Jo+EN)$]�v��CI�ϡ6%j<H9ٗ�M�>3[ʁM�ds?�P��8���c�]�ښS��n�lI��_�ҶT��ۉ��K����Ao'�Z��4lz5[�l�1���Q}�AL���~�{q�!���A���ԅ.�U���B:ʘs_�]Q}���0��pe��1�o�5��V����?sl-�v���;{�|�e��2��Z_m�7W�;͓���O�m��5{堷W��@��%[���R�[ !Y�#�M��i۟�W��u�FV/a��:X��A��d�a[�%��:�0p�W��)�����tn���l�Ǟo�%�����x���l��M���e?u�6�=�ݒF�5���t�F���yS���Z��A��kkQ����m-2˧4�� t{_9��mܧT��wT�B?����c�mĮP�a�Ja�3��0�0���x���RWƱ��Z��-�{k�s�/����l�Hl��7�Z6�)��$�W�w61�=�l+��Fk��ۋ훍��c�q���Z��m/�/����_�xy����p�cě��{��?��x����~��w�3�p���f+ħ�v��d��n�r��}����Q�v6���uq<�kW{}dI˚Q� t6�mQ�G����\[Oz��ɶ��&[�凙�v��^g��s�1�vvoܒm;>��M�6��6�����/���G�)�kJ�qm�2����g�>��mol�5Gd��gl;`߅\�>W�Zƃ.[o총�(�sM���.�1ˡ鲍�Pzw�}cK�m����\�щ]s�YtY��=��ܒj�q6�V����g��j��3�ʶq��2��������օR�S���Z�V��ֳ<�tݲ�g���}s^���df���疙[�.�/6�_83��0:���f��R7n����q���w���Gl���>���_��~h�`<�P���y��ǭ���A���ߘ�<�����gF� �={P�7�Y��m,S�bT/�ͷ�.o|�2���������W�\��K_�j�o����(4�ì�9���gGGo^���r��7� ��k��������ʧ������j�p����v�j_�q�p�m��Ι�>�}��ڿ6/ T��m54��L�!뛐1�R���f~e4���8ϻÛ��zE� ��?�Kl���h�x;?��8��o}�u +��w�?��U�����?�#�;~O/0� G���i��mn����p��j:1�Z4���������};ϝ]�{�|q~~*3�|y����/�/�=>�����8<{yz|�e����O�V�q����������R�2��ύ��f����˖~������t�����=���{4.��j ��OLJ�^��WN1~uz���*wq���4����o��s��L��m��h��ے ����h�#,y�%���>To�J<t�����#Ȇ���tB�7M'�2�`S��%;3s=�n�ҞBǜ�.�>X��=��m�)�7�m-���9�]f��{6������� ���v�N0Wy�=�U:�C��Ń��� �3?vȫtBL��ĥ�t��ӧ��>�<�pu���薬��'�Cdl�|��B�%��w��U(�%��7�*��� +�~Y�m�u�0��k�r�Uq1���s�/�Hx�m��c!�3��C(�"�2�݇��n4��)�?a�G�;�-�n8�eİ��j�)�'әW��SN���@]�r +�g/�g�(ة:[��Y�(�HW���ޖR�=�RKJaI),)���R�xv�nJ�7�;Et����c��p�f���z�a���+�G3=r���Ð�n���b�D��k�f�����`���F;���Y�{J�ȯf�� +g[� 2/���YA�:b�"�tJL�싾�Afc�v�A�c��M ��u���G��:���흱����2/!�(�0��mᲝ�WU�nn +1�;�J�M�W̵l*�uXA�]�Xd����>%�F{ +�MR�e:�#�l��{�Wd�����{��bG߳�4��k�/�^��˙�pH6�L�=�r"�c7JŞQ.��[�ޖ>c���̎&�{{�2�;� +�i��3z^E�5�ޓd +<�6��v��6S��`kQ�,���la�YO���������)3G�T��l��l+���JI$�d��lյ�%l��'j�]����]٪��] ���rZ6���l�WW����!ga�(d�J�W����W"P9S�c�u�S4��}�|��Kd�}�kU���W��>��LZ��0�����6�#; +�oG�O��4��,g��g}�iݷ@��avp͵L�\/�(�K!`�7�I�ƶ6���3A��:�NK�-�}�%+tLr�$f��,�gc�f��u_���|2��+ ��XX�b ��I����K���\�S�OI��u��R� �x~���fZX�l���1d�=+V�2�B%:�Y�z^ݑ��54�2���m��,;�5�Z�ۣ�n��eώ��Uw<C[�́�1��-����nL��W���������7�p�U�3�$��� ���%_�䫖|Ւ��@�*����8N�x�&n��9*y�k9��q�j��9�>wcŌ��8�,.�j�p3��ߚ��}['�<N1�+�+%/=��M�~��TsƊY緔��q�������~NQ �u�RT�k/�k��2s�^�OQ D���� ��JQ�?clmx��yi��y��RwΜ[�Ro�;��2S��R�ʹ�?������R�i�x_Zj���#-e}��1���|ȝ��<}c���1w�����f^�Ac~�*15�$-6U��z�& f��8�J�HLu�yb���91��P]>D�^<h�%u�^�j���n�.������k��{�I�d����G���tr�nb�C�<�;Va�;�^�o!ۊ�D��`����m�v��|o�KJ��j�D�¶�+G:���8�Ny�L�k�*���:�=q{Q��)<jfPG�{�t�Մ#VA�ƺe#���#���;u7 +��6��I����Ζ|ٵ���*�u �v����̋��V-%���+Wn����Y�P�vf�$��{7z����~Pv�YKʟ�=�n���Sv�����*�}Σ��{�ڨ#1�Q���Ls�����]ڬ�Ƕ}*\sϮG��ث�^%λ���0ڨJf�f��;�<t�w$x���+���b�]Y4����� �f"y\Ŧ��m�Z�Lo�<��Ԥ����o��|�`61���V�v�t�<3��n����-��<[9#أ&Wydz%�l��w�%�F��ai��R���e��?�!�;��t�w�w�ywc0+H77��7w�Q�_}#�{u� j+�>��h+�䨤\,!�O����r��\.�}+'�'0Лɡ�b�O �kK6ꖅ��V����}Ϙ6�k��k_��j_}�aa��L���A$-c�CoM| +l�'��A��A�����`�y��}�z���5h��j�� in_���- g?���c ��[�"OW��H"�3��֫P�í`�ӏ<�J��,�˴\i�1��� +f��-�-{}�ts��l6-�%y5�����9��,$�ݖ���>�7��Z>��՟׳�|w����3?駞�z�YJ�*�9[a���\}{g�2Q�1�H���^�e+��UzQ����li_O]k�K?,�]Mb�w�kG�_?���%�o����^�mνX��MW�RuD�p��S>�[�v�]I��Vپ�xV^?��ג��^�κ��ar�������w`ջ�Y�Ճ�͕3_K��(��Ǿֱ�����͇�<�;dR�[*��ҥ.�>�Ղs�|�[����?�fY��דF��'���z�u��)���V�L�VM�|��Q�:�2��{�7�y��=�`��f� =�Q�J�'�^YKSzn��mN�>v��Sy����-�*��X��Zv,v��pT���Ζ�D�l��yvH�N�nN���!r%��{��A{F6�Kf��%`��;�!��o��h�]��o�]I�n1ٮfh7�n�%��N�U�v�)����曩�>_K�v�jE�yq�T���y�η�y�z$��B��uJ��RUX�eoc�YU(���ލ����mJ4� �'8��ټߵ'���kۖR���Y�Z�s� ��'Q�� +�ݓuI8%8��~�n.oz5%o� V3C�� +mI�okL��k/�kSY��<�9uK>�.���ۜnI�����8ki�y]Z�4�w��M�j��6��E�����A��IN�I��z� ��J��s�rM�j�I]}Z��5?(��X��6�ퟠ�PKC�`c���Ґ�+��s-�ُ�!�9�ٛK��j��̜N��<mw�|��`}�Ք��A 1es;|N1�ձ�1���`����PR?����\�i7��ε+y�-f������ۍ��=3n���t����n4�e3�-�K�Mto� ���y��a'Z�����\�{+��r[��f."�5 �������RWRd�,$-�H�d�)����e� +&�;�6?�&�H�l}��uZ�|-=S�k�b�L�\HUW<�+�u�Whq���\?%���� +���^�;�����I�Q�ՠ���c���]������/���U���cn~[/���M�0F� �ez�ɕ��/ϗ����k��Z�]�E�h�5Zt�]�E�h�5Zt�?]��-�^K��z}$�F�x��)t�n�t���*XJ�4�B{�aP��f�ZU��FH�J(����T��`䧀 N�����X7/[�N��m��"h��4H������gE��%��+!!�m�?�6W��x�h�����I�l�X-���.���:<��9b\]��;Ud�]I�[$:�w�y�fί[\a�)�Jd �ơ�˔��~���T�l����B�&��#<i�)�����X�?�M������ `�ub&�y4��;����:~/���0�� +��E���C+���L�5Í(V�����cX+�<!ă��x����n�C���Aa>P��"͛?'/�8R1����'�ϱ9���"����7U�8}e�m����2}^]h����t��N���h���X�@{���k#M�1�2X"fP'�jH��D�����S�K������@������lnh�����:�jy�ɖ��[�l�Mq�&�]i4���1Hk=k�&u����M)݀ +!����.%Q�6j�jk����9�7;}^�����k.q���ml�n��?��^쓻c���{m�Y��)��:4so�þYU[C�9�U�5^KoQ�ҝ5���eE��)C�`��������i�w����h����{��fӴ�4��( �F+ov�Z�W����`�%T�N�m��b����Q����8S���^�d�-�h��~�nk+3�iZ�������e���Þ�;=J��.�����,��nP#�N�[j�����E+S�vk����k��?��=��:e_.�<�����¨۱ F�߉�S�e��*�._��2�Nk_�,��3���G���;ͨ(��{�uWoMO��n%{���'��|֏�۶��ѫ��Ĉ���A�1�(SS_�-�����*��8�}��|�eMQ�]��+ݐ��w���/�-����1Q��rh�{l��<f!�66���o�jO#l��*�:��h�b�j�W�M'�o�z��Zw�4�^M���������I8�j�������& *�Eh^��c!�-�}��]��X�&�;϶(=U4ϙ0WgsW��)��γ֯����s�n���ʀ��0_e��SMJ�$�|��絾L_��KE�3�[U7ޯ��&��z��}��|�ޏ+�'�|�����C?=�����I���,D� ��p�q�����#2�3�?����۔>�|��5��0���7���'ݨ�V?>��|o�-�&�R-%�=����0d9�k4�����%灛�\;�O`�D�|���J��v=����/�M.��:���ۋ��D�j�=�̙�u��fn�?~r�aj�n���;�ֳ�wή%u�������_R�o/�{��}j Y����e�I�m܃u/J6���lc� � �j�Q�:��ir�h�n����+�����/PG�Lڪ��C���C��s��Z�#ã�����%w�]���*��- ����B�+,�q���R�8�ߤ +*�UX�m�����^��i�;�=#S�'y���) uG2�D�Fnm�����M��μ����)�w�u��e�������� �u��[{3��8�W�/���"��8�]�Uvşf��]_^}��v-�]Ki�Rڵ;�彥�k)�ZJ��Ү%>�ć�������Rڵ�v-�]�^��V��v����wl�ݜ���1ia��ǵJ� +�=���] * +o��0�T�a�m*n%���FQ���g{>u�7��h�m&���쬲l�Vj�́=�����~Y���5�n�����m"$��D���Bٯ96�<� {l��HO�����C�_�8�J�Ȏ�!r��y1""���Ff��v����TV@���OC�N�w��dn[���~�-.b�8���4�0���A���:R����ډ�Z�Ǎ���T�f6�jm$D�U��Q��6�5^�`��X�o������{��D�%�p��9�X$B@�Ď��@�k�@�b���0_2/�623?1���Jmw��{��m�*3#322��H�E�Yr&�x +?�ZE5}�na��dz�Af���&���y@;�xrxI�S�)�A�`w��x�E� +ps��U�,��#�TQ�g�k����+\ܸ�a�^�f ^�~<r/�˄��D��R���V�U��#�k��+�G��ɼ�a+<�0�"*]��<Yj��xl��-�h>�@�Dk�2x��U�ŋr%�5������x�1�p' =�k�3ęD�o�}�D��8��0:!�s��P�AN!���3�nU�9t�HԶ�0�kS��0����C��� +9���2=�'��G:�� +�8r顂�vp�քG���eLHR2i�9 ��a� +���"�$o����\K���z�3���ÉY� +�p��4e����*�E+�gAp��Wu]P�ga%7� +�,�=m����~�0֞p�SÐ����[�����P(~txQ�"�3���+��P�@r��3���r�\9��ɦW��%��3:����2� �l�j ��O�:}8#��`���j �5^�ͣ4T-���ro�����#�*�[̼�-D\q<9�Ff���[�Ь�R��H��cY�6��@.��,#�<�<'���_�1�:�&��$KfA�*9�fr"��m"�X�%0<� �@�c=�~4Af%�8�eH-`a"9l�sxg��Ƙ:kH-����C�ȐZ85��� �%c0I�.�� r��H-�+P���Сό��� +1���0M�]��!����E:�O�!n�^��QP�u/�pDj ��G��s��7�2}������O�!��;����C��q�b��B�DE�j�\:HL�(9�ΙB���{`�`�K +���2qJ�C4��͢��^���`���Ar +����d�tÅ�W�˖�B���@<�Ȋ��Ez [Qh��^�^*����-} 2��h��:1/��k �X���3�����?y2��+B�����?H���n{������Ewۋ��m/��^t���n{������Ewۋ��m/��^t��������>g4���������~�$���*��B�sҷ���pݱ/�_y���?�d��d���:��8֟�䚸շw�ގ���_|� w��A#?J䇑�/4����۶�}�+���n/.�a����������m��s~Y�tT��t��םn��[�n�/r���Cn��%��j��F�<��oL#C�ෝFLC�t8� �f�����<��� ���Cn<�G�C�<�&K@`B9<�����ul��ǃe��!7,7���|����g�k�r�_DN��Ϻm^H���mgݸg�lo0�� v�m��sg݄/�u�>;���p�,,5^�-4�_��N��i Á�J+aO���u'�"k�K��D�$�= ��ȃA����>�d�KU�SE��B#�`�ix�oH(�x�%Y��#����������LG0<Gfx�љ�.m/��x����n�+�8��pE���=�=��?��˫�}���w�aD�u"�P#}�L�G d�/�#���|�x,�[�����rڿD�����4N���?E� +3�!��gE��~��̭��Q1̑{���ha@�����|��!��1�|��W��C�K�0�Jn=�m� +�C˝����G�p���Y�y�� R�ti���b����*� +�s<�z�ְ��^���.Ʈ����q�"[�fMG{x�F%'� - $�A�$�qRPU��|[ +�*t��2���3"���V�$!L�Ӛ��"k�}IK�ĜҜ*�{t�;�S{���39B��u�Q��Ѱ�427�x�� %��'�d�e?ٔ�i��M�d�2ddx�$�d��g?�fȪ�Y�D<�h��v� ؤ��l�N#4'V�D$��FG�8��<���������c�N���A�a�T����R#~�n�9����-��6Z_<���_�Eإ�쒲�d� oٸ�JRz�Tθ�Ɛ7�-oxS�P��������?��P��Oɼt����G�?�i�G�< %��vX�/�A���<���y�A��d#�!o��ƉR��^�E�F<N6����]0Btκ%�f'@�*���7:�����LR4�})�x"�̆�0�F[⩄ �vqr��l��o�Ѭk0.�`��X*^D�T�l��T��g5D��Z�(�3�0�2��b?�:F���9�+�Ѿ��!���>i�ȑ���vm$Ǯ8s>��m,�D� ���X���c�� 0�K�юz��ds� ,�f<�u9����~��-U(K�Ѫ��m�_mc���SUI�x؛�u�q�m� u/�Ƌ���,^�͆�͆�͆�͆�͆�͆�͆�͆�����P�A�m�x� ��eC�nXb�*�+P�O�M��'�D��fE����5}��e�d#T�2��}0�]��Q7TQ�[��Rf���pɴ* zGVE��e�J ����զ�6�����ae���tzU��vZ��������`�q%#�zHi�O�3�lp���T[$&����"�;�Z)�:Y�^��"�6H���B��'Ysɮd(�����z��na +]Pjq %"I�,3��ʡ�Y6AB��xv�5_���F�uy�ns��a-���S����������+�K��0�5s��"���D;���YY�ƆE��X�ȭ>�=:�&��;,g���p�H#�gL�>���H�3��,��C��pr�(��/�Em<��/�|����#w��0� �FnF���dO�$Q+fB�L�%T�@@�B5@$�����xR�|t�� A\�.���㑐e4i�Ҡ�����hcB�0!�n��8$G�M6�`B[U�XEXI�`�c@�f����}�$��F���U���:/a&c %�Y���oH@JN�SU@5wa�P�0k�y�xB��m�sE��.���y�U�d��D�/�ؑC% +�+]Q�E���@-+9�w�����f��A�ę�L0�ǫ S0{3�{8����E��a�a���|��i�)FBj�L�?��f7C )�Irb�"���2(9��G�: �qB��*�����y� ��^8{d��@���D�fp(�U8*[E�C1ȉy�-�r(��$Q7|B$�dO}��}ܔ��H3.+F�ͥaSl8�{���W�K�_���m�w�݆���/ .��&t��E���e��#�ğ���_>"����_Y�UP�e�:F+H��J`�,�6EGA:�<���1Z�c������4�"I`F��`A����rtt 4#��VnIN�@g��rK�CKס��/(E0u�����:�����W���k�G� +v�#�v嬈�n^;�#�����|��/ſ3拄��c��b��g1_�ĩ`P�Y�ax��,�xtUei?==+��a�]0�(� +S�;�+�HEX����g9���K��\0��U0��u.����+Ɩ��c#1_0�1�-�Fc�<�^�� �n��a)��>�z���|��c�_]\��!_� +��F��v��$O��ʢ�<��/^��,h|�/|1��y���_ ��$�����$�� +���U�&�K.��$�/���6-*xk�BZyiS����yM�����{E̅Ě�F�p/G��4�$S"WW��������z1����h�8�1:b�`�����GDϛ�%�&z�����f�W%���,�Ш��^�V�qu��,7����z6 d�J�� H�$^�"��X�/�Tk��xP�3&�.$��:��"N`�V(�ު@lI\�����'[;��f<�)`��{�:`�gzOf�����"b&X3��=Z���<�K'Y��!�x"�z�uՌ��" �4���4a�j�N!�:`3#g���qdK�L� c�v�~a%�j��2�\ V'C�f �3r&����A`�ۓ�NA"C�@*.:cXr9���2�udS�t3��A�/��#����"GLp�9�Y9?�m�h2Z���r>TƝ� �B�{Ir~����G�B�Uz3��\���_�TsX�]��l�v�i�M���>|��E�f�^�bc��4��5m�ŻFӰ�m��rY�.��| �MU���mj�{��� +���^�Lۘ���MZ�Y1������|���(G�0J��z��>�\a�0[�x�s��s�$�w�ŸH@����_���Sŗ�迧���N��K� +E�D�Kj@������ +d[C��O� \���f �W".S������_(�F\�/o� �A�qǺlY�Z��߿k�\0��������O�����y�� �K���E���M��� y5'>@���Pq ��QT��o .���z����������M#9�e��%����n}�d�b�ӃA�d�Zg�E���~F�T?"םI�itE#թ����F��'im�i8Z�3Y���]�Un�&�4@��&��^oFT��8���]�NT�M4��Zt����\%:�u��)�@��Fi�S��iN/��j��L:�Ս@ �g�?ۙ�z�o���ژ1�0�˿{�Aj��aa� k8�"Y�効��/��1��1T[�(�M�����`�j̍6����tO4��v6NM��gc��m��X?�̓��Yg���7�C����ñ��_M��/���lR�G06�u�Knq3�}6Q��1�V_��h��u�P'��1��Џ��Ւ�F÷���W�~�� +������*���;۶���m�[��V�n��V�m��V��l�훷Wm���/��H���Mf��m+ڶ�m+�~6�F�6����a�9��8� ���e���V�m�V�m��h?x�D�V�m�l�J����!��s���>���j�V +k��j�b�ԟ�Ʀ\<��ӯ�q�l�%Ħ�$�D�U�="�B�r��(.�rn+s}���sP����cdw�@�L��t�1�(��`uLʃ�O�:t�ȹ6$��z�tæ����0i��0��J�~ͩ��2� K8���,/02�{�P��%N`X�3$�4钨(/r���2��Y�I�r�6��{�L�Y8^�����Yݤ�5���� +�Ä�hsl��>�a`��1��@�@����H���*���=�2CHT��VTY&ۀ�UAPE�cT�>���v}�d_y���1�����t���a�����b͵g��͓k��xLG x�s�knؚL�{�|��u�߰���d��+ӌ�Ȓ7�Oc�5�R��i�0n����������,��N��],��;����-��D�ڡ�, ��#�`���?�[w��M��/��?��w�q�3t�5��'�m?��_�&�,}���}p,�'�����]h!��UU0�y���/cx��"��UU�A�^���X���U��$,�?�2����Umk��[���?Jw�3��˘�X�(�;8��W��mԿ��'���7�ތ��H&��6��^�_�1uʼn�������[f�R-������a�u�7�aӘ�s/��5V2�Zd��&W�?# �wZo Ǻ�ZO~"/����������i\��������6��7pF`X��yA0�'ƾX�c��Q�D��� s9�0�,;*��/�L��9Dˉ[��6<���,^�Қ�2�I�QxQ�%�i ] ?&,XyG�z�BS�hvs|珒�6�jF_%�W���m��GD_�dy�gMXV�F^�D�u"2��$S,g��� �r�sj����s���Q��O<� Wo�[ �ͮ+ݛ�s������myAP�eY%�f�U�uE��U��K���L�g2�͋�řG�[�<�@"�Ϣ�56�R�EF����gTb!�x#�*J2+H<IO +��d���8�JH�x�����.�X�̥0�7`����,�=M��Xr�8�-`Ce��[5}��"�Jt���p�����HP)�W�RREaD@��%��X�Y���V�=���wR�p�X���B�Γ�z\�a���*q����� ��+���7h`��㕈uщK���g�Ħ�=q�C웿mB��D��ϔ��Rπp4s�0��&j��.K� ��#���������_NWʏe�?��8qKZ?)i���)�/!��~����[\�^���ON�C���l���B��*��^��}���[+����*�:�s�$װ�M�%,���R�z�t���V��{t��fO����q�?��_��*��oڝ�n~��;�hzXUyN�p�s,u��v��B�u�7��0�p�(�2*��-����'*����Z ����W� ��D�eU�a%��\�w�Q�0���UEd�W�s`Rk��&#���)��G���o�݂������J*C�B cD��@�)f��q���:�@9��X�L������Ga'�� �io�`�Ym��s̋��2Q�`�2�x5#��dE��XGo��8&�Nz�0g6���-���r�ێh��ʻ +q����=���D�G�WE��d O�EF�=��݇���K�� ��8�8��wg'8��|�>g�9g��/L�B�S�_�� OL4�3@)<= @��V�³���A��/�Q�n����#`��*3����$���l&�1�A����l�Ra�5�",B�c��1�m�zK������;����0��^c����94"�*ԗ��N��B��Ĝc�2�Y48��(����8DAf�tb,}����J���W���?d��S��C*� ���QY]�8U���4�d|2�͢1�@�0Kȏ��$�a$^��� ��X@� J<�l�2PF`a +TY�(�]�Z�vnΏb��D��(�x����3YF� <��� r�2�V�aTV��ķ��G�ە�+�@FGDB~ +����J,4z�������r�"���a��q��.E�k8���K��E~d��d���[P�.DP":E���' }ׄ�r�F��d2X��m�&�܃�0���8.ڜ��ު@�ot"@6s'Ix�I���%�_����d���5�β�(a�^`L[12�/�fx��pl +���F��`I ����{i$�(��[�1�7H]�-�@���2d��BQ�t}��t��P�e?��*6������a��A�b�77Z��Xߪ0�s�,�#T��`����*,�8c;��˰�����5rI�����7�(� �g��}��F]��,� +�L �L�*��7�"���t;�@(� +h!r>vm���E��� DчYl��L�K� �P� eX��Z����� �)/�$,[�Ȥ��B+��ɼ�4� ������W�<P�`��ʉ���� �A2�<-�����K�� +�>���Y)���q�~-�,�����2�2���0B��H�r@�D����yC��8����b�E��Z!�s�:#��A�"B��(�O�E2�� b(������Db JΤթ��2����`y�!�c$�$��V)���'��Q�WyB�k+�_P�Y������R�<�����d'Q&(/�MiNS%ol�Y%I!��1�*�= trP��v=Q�G�M�\�(�/܂ �Z���@*H2���}ڴ�Si �|!��I���!Bv�*�d�T�b�<�j裊���E��$(��&A��Á�Rw��XV�%�)ZP��պ3�+ԝqq(���0&������ �� + �"B$^��3ө��X�l�_��$��JXl^A�y"�ʑD��.��^:��Y ̶'��D&#��$����hf�{�<�R�[� +�7w�t�k�L8������ :Q��&��n��&����1y zee��y�+H��$�(H��D +�q�J +�~mX��n�n�S��`)@��rV8�ķ�����Y�d�������Vj��������i�D9v�$ �%O��2'��0h�"'�p�@4���E�:@m&��(6�+u�E���ld�AL&��d+��yR��DA�(���6��ه����d/�!Z>����*N%�0����G��T�K)DAB4�`���_0fTL�v�=+@�Hn _��Z���-Ba<ѼLfn�F#���S9�c�w���k(�5uWm���t�R��� ��6�pe6��fy� ��/4�P�6�Mi%�¦*�/���&x����C��T9Fq��aua�I{�� ���HJ���4$p�d>I�i�(�jD�#�/�1��$��aH��c +�!o�m����&�� +�rJ�Y�D�lEFY�'G�e�i�!"��m��"pY��.E�`�2���R���u&j�d#���3T�T�I8��Ί��ݒ �A��쐲��E�L�A�b/@T���e`��n(�x�(�c`ł�E�"�֟9M�F!eK��`&����1<@8�j���"�~�� +"����-&��1���I�����@��,a�و��Q�D�D�ˁ��nOQ�� jI<:>e�^H֟y�K��@X"�$�+Tn�u���B4��2X�`4��$J���Oߘ]��JJ����%tA��0T�d�F� +����8' + �8�u2�X̕�D�G����� +�{AG��b��,Z$��P������+�բ�Х�}��R��Df�ٮP��eFy��j�r��ˎN�����||�����G���ۼ�lX��tWf����F6cA�F�6�@M �*� ^v-q�a��V�K$iE��$���sC��M���*`"��c��13���!�2�� K*ϒ�����Z���gs }�*(h�H"k� �B��p�U���u���,��=������9�JڎZ1@;,���_�##�H����Rg2��.$Y��{eޅ/����\>���&�yts�0X�~��֯{�����D��ᯮ��"�+����u���g�I�A>i� *-��t8"/z�o� T���0B�U�(0�pl��������\76��~v�Ӭ6���}��/0l���p<yq{V:6�5�c.���i��S�A�ӜPp����|'(�r�v�����y����M��g�o0y�EOb�;p�e�0j��5��Q���d�����p�K�a��7��&���O1�zgЄ�_$�LU����|a���ߓ(�<R��H�*:Z��ie|e��vB�v����l����l�&�a�'`?�D� �{��u�uJ�+�M������ߵ�'�_��p�I����a�!��6֎��/M�o? �F??��~�4IJ���e��)�B'R}x��?���V��}m�ںq���3���3���Y}8E���v�Ƹ\��)��g㆞�c.?�R���G_�jMж�Cg�?�o�p�|����+�G�Ȳ.�;��u8��ި�sn����k:���i��:Mפ� gi� +f�ס��X�u&��&��R�ڤk��%�Hk��lv�9������l:t]j��>���:�����6n�����d�Ӧ����8�,^�/nYۤ���֔aMY_�s����7��Z���<����ku`Mu���>���zv�/;%�����>�Ew���L]�fg��;����J�b�7��m��6���ieK�t��L�ڱJ̌e��p���ʱJ�]$]���I�vU��������Y� +/:@e�L�Z�_�z�xNؙ�H�33?4�D� aF�-��s�eM�TR�V�!�U�/�^mxI�ҎT��b�|fͦF ˂+����^�[b�&����<���ά��a�͌�5C#�b������H���>� +#$4u9�m��FB<�'m�Rt�1� +3W�<����}R����%m�6��tWe8�x�<�^����H�e@��@���xl�mK�,�u�w��f��\�`j���bp|L-��ݹ>eWu6~'.��U�E�З�X�:�FP��� �9{���pLH���&�����H'K����f<Ξ��R�C����ة�kKg�^��XqS��8�E�,���ñy�=���e�R7�6Cv�f�X��f����J���$�]v}тS6|2��Β8���Iq���u��/��/);�ae#vs��:V���d��f�����M��s^,^mh=s` +�$W�����M����uG��p�),'������EuSi������_&jq :I�K��\_�A#�艔u҈l)�V �w�4 2�30�,5BVV�MM`=gڸwʟZ�=>�(���*�N�bv�f�ʖ�@4(��J;K��I����[?@��\���fClvS����3�W'��:��jYUL;.P̵�� 삌� ���@wMȑ�%=~M�)t�a�jEӄ��J6� `�̫�+cIP��3��\1�M�ve<l���qƮ*����檢�.;�~�M����"6}7$�D��Y��b9�G{��o�0�Rs��O9%�&K_74%$����u��_��'�;25�)�?#�F�3����� �Ĭ"۶�\�1Q�B��2ST�[^����z&p�}��7K/d~��,�ե2��y��r��v��# K=��,�Z.�4 +ii����e.�Y\�.,�T\��ta�?Kc�ވK#�0/-�B���Yz#/�ZjYX�%��A+�31������p[��� cVdׁ�x��(��g4OQj�z@`牦M�A#1��Zt&m�SA�(�+�`u�A�pj�o�"���y���Tq���be7A ��V$Z�����J$Ȫm�����@%�t-�/i���8h������T��q�/�Q��!�;��gu�l��u�,��Yj����b��L+���k�B}L+H��= sjEuV����D+���#�<3rm)�C�Z�/��_�;����mI����FO��J��&W�nv�8"X��Iw�E2�5d��rNkp�\�⦲��,�}Q�M�k+a������I٥2K#,�o�V|��-D]M�k� ��4�%<�-V������z�,E����5����EnuI��,�47��u���O0cJ1��S�R���"p���o�5n�'��lа�D��r!c>'�Ϛ�(K���eC��3 +;".��@��9ۀh(11�n���m8����'�Ѡ��W�ڶ��zj� ���Bj�}R�����Fc���aW����˻���RQk�-��78V57��� }B>�q3<�8 >[,����(���M��p��s�W��E�u��#dGw��Q��2��-�'+��:�#k%ln�@�>|�}B�@�a�1��M��voV��>�� ��lCb�Us�}pn�>,��6QTD�W�����7=<vx�<��H�"�x-�ƚ=ܑo��8x�U�͕��oF62����8����6Xlhl�tx�${,F���RS��t�����8�M}�y8c��6=��b�{%�Ս-���6�w�}�lUV�R��|,�7�m��'�{0ؼ����?kr����qdn�� �|�U"v��`�Y7,�N�o��-=�ռ$^����Un$@2����Ee�x�g̿���&�Q���\.�L6�b� ���6�������X>M��%G'~��+9�] �lp���T��1ū��΄�-yKea�����WWw��!�� +5�5:Rf��3h ?+7v$��.����x�i��a��u +�/������;����x_w'=�Bi�'_(<�����p�7��sf�r&���ɬn�Z~���s8�ר��MslcY��'�z���-���P�-�Y�� �q*�+������Ǻ�+�-��k�X�m{~I��)��D7��K6�hzN�Y9!s�g=;l�m�������� +�:)���Ct���`���Y�i���-98�k�)��%�G����۴H��=����R�ngjŠ���X`�Fn��*b�~9g�uúOt�x9`6?YI'�z䈓 Xx �܍U�:�js#���yy�6h��6n���JH�<�Ev�-՚�Ei雁�j_��GvkY,�5*��轊>n�J?#b����?�����T:�no¡1n�?6��Q��شdNyq�u����vD�=��Q�%����_��M�p`������������ʲ�8���<BDN\��[����l��Ǣ�6�����&��H�cNN��)1��D���Q��<���Ŵۃ�W���B�}�O���^���';��qN�F�W�ęp-=�%dz���qg�.+^��d߳o�N2��O�&��)0�X�=6K�L�o��䡠W3�x�� ��ޖ`��w�P��w��}a�}J���TX��n��`B���Ya�&��ۻ0�sR_�ڎ���닇�T-�^�Y.��<�柒�I������B�`��/�Y��t#�{��m��nO3m����ȫ/�`K�ã��tz�y~{�/�G��,��!�}'U y��Zs`�w��k��L[x��vy_0}~�Lf���}���>�c����_�`�UjS�,��qg�5�y>i�{�G{�q�q�*U}8�@2v����~J���~0~����xG�#��7�l�e�&ٓ�5`N����iF;���̞���=ݓ+}:���n2S<���TS�g��7!g������C��{�H���.)!�{qZ��b��J��)d�u�İOlD;�����1����3i�0L�S�C0�?4~��Ni��A��qE��[&�H����[�h�&~k��?�ٴz�Ӣ J�O�.<�]`��K,���Ng_����H���F��}f[�ӏ����������q�%����Te�q��q<�@J~��B��}���hfa���>w�֔^x|lN��0۪��Ю&��:K�2�ɽ���p{�O���+!zvsDfI;c fp� ��ϋ��&���bS�&����l�M3'b�*0�PB����ԓ��Lg��\�M��ٿ��] y�G��ZD��R��~�(�iK���:s�����F��cVO(F,t� +�����a�5�K�4�-�˚��*Տ�i���>�gZ' +Þ֛�L�G8�y(�{R��n\������7�� �����BwWX��lx��.�w�\~L#O]U�1�|'�"(ՙΤ#�z�po��WL�����/Hdg����� ��x_wK���K�����d#��?Oh�K����-y]+j��rq`�L����(w0<��>)z?Ss��τ@JO�l���W^�K]�F��r�1��=A�l�S�wU܊���f��dM��3��;'B�}�Vj�yN$\��/w��@��%���$��s��Q}�ja�;�5�ȋX�;�D\���T� 9�t:M��Բ��ǡ�aN��d4o�Z�v��M�N�0�׃�Pe娳/$���r|v�֟�R�Ͻ��;���)%�W(��3z=z��3Gֻ���D��w��F�!5ɣT-q�5N�[2�.M�J���^r/��9D���Mւ��R�vC�o#iu?aՈ�"؝ +���J���H阱[������l0��E,a�WA%�&Ұ��<BI�~%9��Ic�("o� U�R̡s4�&6��'ca&���d�J�/�q2��y��ɸ�GҔ�`w��Ohb�m��i���j?���<�@X�d�˦�E�5F�_q:V��L���Qc��*�.,Y�c�1�0R-��6�滓�뒯P���n�6a/)��H�X21����PR5F�'�$�~ݎNl$�u$ĥ�xb7$����#�i���KIae�N�5VY������ TS��e����т�HծO�$�vLa��h��Cc�]��_���d�������cS��v:�CSX4��吠�n�J H��xcU0hN��脁����/�S|w�X �C +��(�F΅ZB���Cp�I���A�*U���`)����'�ݑis\l�B(>�>R�L�B4C�����T������@�X��2%?�\fO����H��O������F߮v��IY:aIJ�([�Ex�i�ٮ *�iZ`k�|���f[�j�Sy��:����8�y6[KkM%�㴖lB��QC�6U�g�o^2�w)k�w�@��g-�WY�l�w![m24�j��n + �h�����-�A"� +Q|���^���D:�xԘ�yT͙*]��p���9�rL����^�2�(�4���:�×��n���q �<�� ]U��i���__j�p'��j�qW�۽pl��r&�l�*X����r�f�.EbHP){>�u/9�������WnW�+& �D�Q:I_T�0���������.Ϋ��l�i~�i~�c��^aJ���mI/:'��.�M���������0���t�,��e/�(ze��].�?X&����)��{�/�F� +����@�;�(|<��>L59;���v�7^NU�w����K^�U2d���#���iG�Ɍ̴z,�<k�Fm�{��d�j/�p�qb�k�*�ڕv�=&���;�!�W/�:П��[�膵���e�l�˘�sBn^�'�|ٺ�W?]Ǝ��2~C��*�X>+�s�����r�_�8�-9�q���&(ŹIH'�l��JF��̪I�� cx�C��a'��%M��鑶���(��+d�;���(��t��@�6�����t_Nr�}��a6�!AI;�%����Z���d�6�l��oj�u�C�?<���I�yne�`�O0����>*���!yK��q��ڙdž/_�J5�|G;�f�mղ� ��f)1�z�5*���ex3�v��]U�<��_�j�$�G5���CrRg��e�)�yVZ0�7�87��ʧx覴j��U�%֎,B�}��7w�㨡�p�f)�>z����;�f��j;������R��۰D.v�<����M�^JD�w��He�g�#sEe�b���)m6��E�CYF���gt���e56�S� +�|t���E�L���,��n���x�g��Z�c�@��L'~6IF�t$�2��#Km�Ly#v�b㲒n����?{� L����䨤?槆�lLd��T���Z�7� GG�(I�}�)�bk-}���p��}A"?��#��y���M��v���� +#>�ߧ �\Fia������&z�R���=G2GE�ݒ��2h�DY�����J���L� t�d����AM�܌��j7���d��M^�}f�Y[傆�T 48�Yj�i��n�01�0Q�7`|+���ݽ�IZ��\���/�����Z� �n�̓�й����� :Ha�"��^�ۈ���<��LS�wl�5~z��6���\����_��ܘ���k[t,Y+�A�o�|��m�'�l}����^LJ�To�!>��A��`�<y̞�F��]TC���磩K�9�7~��ϧiiw$f�Zow��*���%2�p���AG��J:<�U��If�?����,عWXI�`��G���?@ P�&?����B��C,�/�Sj��ܛ�VΪ�ݑ�|�FK��{�^��v�l��Sr՛I����a(X K� +�d~�R9~y�y�)�����'�'�)�"����=�X����`��4h�V���4Ѱ>M ��}�i�i�귌���?���ժ���n�I��������@r��'$�Ith)y� �ۇ�MH��~�@�H�K#�#1˘�6��8�tr���Wq��c��_�4�(5[y�iAu�4!ًG/~襪�Q����yK�=ʻC�J�>��i��?���E���ή�e#���~gr,݇.����ٮ�^+(G�ѕ9k�����T4ui�����'�j�����Z���A�Cf[���I��oa�;�}��9��XQ��^`"��?@/�[B�0����m�7�ia�Sr��N��� +��p��~�$����4{���1�Z���TO��)7��&����kK��[C�{�H}������>�d�'�)S|(.,s4��4j����,������x+6�$���vH\��L�dŭ?����tϿ�y0��7��ɾ}V1�\�>0�AI����7Tٛ�HJ)L����v��n=�ӓ���~��'�Z����8�cD��˾�VǺ*X_�����S(���k�=���٘vC�u2�V��A�p��s�Z�&�&�:��bb&��7eYƴ��t��ef���T%9��Mf�yo�$}��e��Ѻ��N�!�9=w�*�,�&)R��_ͣ��RJ(�A�I�p0��ʽ\{=�䳳 o^�����3���@�;j�B�o�쪳Z��B9���'-��&f���(P��6�w���^��G��4����R��)톺\�v�|�4~� ��'���~ �.q\�{��i-�5ط&��,Ɓ���^i|q| +�0�ӏ4��R�.�S��C�Ҍ���:��~��/.�'��-<b��V�H��nI�.4nFJ�������)HM+��O+�U�f��s��>��$�[ +�r���Y)�5�?8��_��������|����[;��1te��V#��~L"�e��}��y�B�6+��h�g6 +��Ѝ��{���q߲����� gO�^� �7��5�M�-�;2^�=>��T��|�Or2���j�,�&�����;� +�OŒ����<(������~�j/1[�Qi�B���\�W(��Na�O����ΛT��s9w(i�ڎ�v3��c +�4���p��Yf'4 "_tg�Y0�0��t������w�o�˒��_���W球ñ˺t��0�km}����u�q��5ѧx����k[�&&�qi�*qi|m�/4}�]W�$�=��oÙkԃJÁKov��?�6��ux�������p0b ��!'�5WO� ӭj�Q�Ӡ�'�F�Wdɱ6� +m��\3�ݰe��L\�Aw0�uތK�;�4�wF��9�v����S �g��\T ��7e��bJ�U{^��ƀ��'l�V+ڛ^�|��,Jr'���Ŭ-[w����+e��dz��1���@�v��m�'� +_~rn�,|��-t���K����+����\��p�d�I�R��m�+���8�Xt9�23ڈ���X�V07�:���x�׳����K�W�&���V��M<�Y�S#����u�g�q�E"�q*V��w��q�æ�C�p���dm�ת3NΙ^L��ə +U����o��g_��Tc<�kӒ��>�t��K���U:���I���0��Vg����M�Z{֯�No�Y!����y�dXC��]Ǣ�D� XK$U��� �c��k��r�n�Ϊ{�|"xL�7�����Qrܚ�M�c���a��1��K�E�Hvh���:o�η K\<�D�(}��&B\λ�6��5g�=Q�J1M1Ts���ʪ�#G_?ňc������C[�f�]���n�E�0��_=�5��,C�Fqm��")�6Cژ�T��Y=�oc�_P�����9��|��8X���¼�s���6����#���gNZX��T���r{��[�T�?4Y�öP�v+cY�����oUz灎�wS`�hc��ǃ��<�f���}u�|�xl��v�fj�$��K$�l�|�����8���μ%>v�v�o�O8�LF�ɩ�ɟ=����fm�+�������k�������F��R�����qs��E��;c|��䧷�ؽ��<J!���G�6��O���Gs��� >��c�WbG�X��k��(>6�cJ��G�����SJ��q|Dwea/�:��},�,�v�y�up��s�Τ�G�U1�M�G�%_�}���W�ʽ&>��C��T1͵�c�HG�B�$�o�gZO�ߥ{i���k�'����|�h�OGB�T�c��ϥ�9���)W߉>�g�t�?�|���3Ly�m.[�ϸ��C�y�f/��7�'�<7�DМ���#�Sx�2�p�{O_:��;^�:�B^buxC�;}��ݎY��)*�����a�M��z����a�����L]6�|�\�+���o��l������������F�ɏ�N�AQv�e�7lف����;�f��|�,I� <�x ��J,�ؐ��R�\�wf���tON���t,�����q�䭉���c"�q89w�ʧI�#r� + +r���Z��Y�89.����,uz�m�|��!���(�xv�ǧ{�n}�x����sq�K�Tu�n�9�UH��U����G>�>;K,N�1��b��� �!�7��=��w�;{#��3n���{�1&,���q�o?��Qu�;�](b�^�>y�����.݄z��$���������n�A�ܽ���]V�/^�MI�(Sp��z�@�:t������'�>�~�v�s��p=pG�:q7ӯ\�ى��y�t��Ϯ$��;<qK�g�̾��J�w�y���r?�c�N�;݉�I�}ts'lН��gݙ�;���xw��.�G^�ih�r�����Q0�������긫�3�}��^��g���� ��c���x{%��/z��ךx�__V���ю��L����6uw}̱���p����q��p�wQ�y����Ǘ��<���'�9b<��9�b�=���=�(�{~O,:x�$��COr|��ɴ/�����)>{���q�Sn� �����s5��y�h�1��x^��O��[�"��\A}���3�(��L��$��:������7Щ�xCU����w�W��A���&���X˛�|��f�O���*���n�qo��B����!�7��}RG�V��^�����s����;�̴�_�m�S>j��d�v�υ�;}��W����c'q:r�d����1� +�oĝ˃I|�&-�<F�+;Z����:;m�t_'��Ѵ�u�fx�c�w{^� ��w�sm�+MS���s_b7ʹ����E{��4ح����gz����~�6�;����kew�j�}�&����_�����E+�/�Iad�W��O}g�݁��;���/ +u��tߛ.>�ٛ�o +���&7��������{����^�t(����^�1q�w����g����t�뗊/{�n���^"���[�_R��?��L��|��<�_T}��G��o��J�^������'����H&X ȥR"p�< +�I��6�'�����}�$j&��S����Gp?�{��KOُ��c���������7ԟ��=�q��yz؟_����S�S�/�ر�̾2���A��9�5�d7�~���Sϥ`�/���/����I�sPnL�wO��������M�3�uC��D0$GC�P���&t�k C��#z}�9u×���� �ga�W�� �^�o�ץÝ�vzu�z� ]^�#J�+F2���H9:�#�W'� G1�Qy�3~�᯼]�H���ɴ�e�߲7L����fw�~��y �ƫ�6[Ԙ3�j(sl����q����8.���\�;�<�q���z��}��{| [�x�3��_��'������Ko��)��a!2�����N��vg*�w;a��L�`w*�7�G,d2��U��7F�8ؗ���������R>�J���T��{҇z��IVMr���|z+_'�����I��Y�F9<>)�����'b�J�4��z�IN��ӊ��]�ԋ\�P}�w`�+�����E4����}�wz{���Y��9� cB���e�{�X-�T�5oN�bS��9d�^�0�y�Vڍ⡦<?Z�����]&��o��Z���9��ND>qP8'���S��t��x�?CH�:#�Q(��%��OG�Q�r���G㑦&#�B$����dտ�N6��Q����M��C'�k�n�nZ��=���;쾧ՋY?}:b���t���A�����L�+%2���$Ӫ��;��fV.�O�'�p8�t�NeG�g�\ė����~ w��N�:�������$���������I� �bHy.����8+|�cF=�g+���m;�8���ފ��D1����Z�f��IB�O����I�ZO���������)�.*0�δ�W�w�����Jս�~�}��~`��g�N:sV��pg���<(���SR���F�������Y>V�>3\��3;(�{��y+ţ�Y�e�<�p?�fJ~�(��]�s� +J�K��\����9��_�T#��Z�\֫������<kJ��V��˵�i�~�߸�^�N�W����ո�^��q����8�n�r�7�tU�07����ͽ����[�������nߺg����|�}���==pʽ[�����}� :�����5�8�ߞ����c �p?fv;����Q����^O��h���Zz�z�I�����ܑ��^�WW�����_���k@(�^3����0mh;���v�����6+V.��J�~ݼ�����ˆr>�#$��}hO�ZS:x{o^4�q��ЅF�+������.[��G�U������$��s|�\���u'Cw���ڕH������1�\\E:��*��R�Q|�>�b���z��u6%w'�#�w��Pzw3V�{n��~���?s����_�����A#�ćrx:<9�o��z�p�1e�R}y ����&ď������>N����/�ra�m����%��!����~��Wb+��1�ܠi���C%oY�%��u����������j?�_���u=�D�g��Q{��/N8���և���j�t�����˸�m1w �+�_Jm0�;�P��c{�]����n������U��*�}(�.T���`�_O��O +ɢ����Y.xV�ɞ�U�k��L�c��V��n��e22y�C�ѧʙ����cG�N��j��l��5���)y �3��7ioT����ߏ��(�/�7�-U��xr��w����.��I�2MP/_ܙ`�;����� s��f=Ʉ�/� W�l����u�v�Y���d<�Mj����"�~'J_��D�O���!XMK�P&�"lw��L�qefL7931��#���T���C}?�=^��Z���h�9`�S��;祵P��iaw5�C�<aw�P\a�_u�wpZUl�����j�B�1xȽ�ܬ.�]��j�+����ӧ�5P%��`�/@%`(�g&�:���Zp�ؓ��J��c����}��J�@�ˣ���ڛ��,QB������=6�P���>������G�R0`Q쿌�A}?��5P��$�wؕP��^q��`���=��z�~�x���j��@�c�_����m�z���b{��>Y^ U��c�*s��'�����e�+�.�zʯ�*yw����:�S8x������(� �I��~�n%��ރ#�]ȿ��s!n`8����A�'iIJr�E��K�=ևҥ���<Zk��^[U���f�ن�`�p�9�RWC-~D����˕P��=~-T�s�Wyf�pBL�%�Y ��X?��WB����Pqn�W���uP����p5��{�O�WAŹ��x��������Zfn�N����%r/�OO*�Y�S�[\��Nl��@}T��I/� +*��x��G����+��R �B�V��5Pﮘ\�B�J[��!�;������♽�/�:XX<����O�r{ �� ��pK��~4���B������N���uz\��Q{���K߱�y�x0�\%�5�̡�!s���Tt�H�{��"�F�x0�_ `~'�9���3k�Be�:N�C��O܋�]|�R�C�&z^@�g��֨�յi�W_���ѵ_�.����W�X۠����Uo#���|�y�3������2��������,�m��گr�}\�U��/_MXY��=ﭭ��|���_K����Ձ4(P/�bk��=���ʱ���jB���>�e�];���b=хW���`���l�;^��f�q[H[U�1������,���>�����!�{ͥ/�V�w��u_������+�9�����A�ZZ������~ͥ�����N�#��z����k���L.�o�:�--��`�brdȄ��^�)�W��r�F�0ͽ��i������T��H�E��(=���_��Mw�\�w�D�C����]�}����_7���@�2����n/^ L!#Lxy\�'}�F�r��ș2�c"���Y���-��H'^�{?�ɍg����uB%��������P��{�i�R�*��wv-Tb���2����̍���P�q@U��UԦ�絡����/`m���V�� 7p�*`8έ�Jl������m������z�a=T� �z��d� ګ��Û������� cP4�BEE�67���_�wvŭC�~?k��Лǽ���K -�B��������ْl˲�f欬Efl����E����'�c�'�wJ���U�����Wv�<�/�T��H�(X�~6�~�q�?F�@{�3gf��Y��/s +��LO�?��?�8z��x�f�><&]��>f���?l3������2 �dx�?�<$�Ln?�P �)Ȋ�3��>>�&�� +p���fi(��'k��%�B�%fU^s��äv�u�|;o�1��J�����,�k�67��!��0�k�Ĝn���9]���}�'�Y���b�@�-Fx����f�鏘>��5+�a4�TV��T��w�{H���@�����^{�|��m�C-D��U���ᶫ@�Jx��*= S�VϞ�)H��_�CZ�IO(��^8����$��&��r��<:_�n�#� wd�l�Y�a��3.TL��� �5�!f�<���Y�X�g�g�<e>�'O���.��]��d���+\�3{��]�8�gusX�"23�Y'&�4Qg]7�ư@��/c��ݒ� P��pId�I�H�QF��c�J�E����G�rpd�C�$�1���:��_cJ�y���Y�j@��THgz��x��/W,�>�@�廣�R�&�I�s:!�8r��=��˛��J���;� X����h����dZ�ܰ��U�܀W/E˜3o^ک���d[&��r�Z%��\H��yFt�J�t���d�:��k�i���&�L� +������M�^�rm ��RA��)���z��(��Ξ�N�9%��Nz&;XG��F���F�E������0Y ����]�0b��}��{v�[V�tE^�Z��9 �V��5Y��s/���ń��I��s���L1?R̲$&]�9�5��2�^8��_��$�[O����zG�GO���i��a�]����a�trzZ)�f^I]ixe4��j�����yaV�2A7��̤�hg�h�4���Y,��\<+3����' +d��5�y��5y:ofS�D����+C���:!�r��}(�l�"���$:B��]$f6u�U4��J�@m����P Τe9�f� +(_�H��8��1���A,��H���N���ݬ0���K��������$��Q0"c6�W��)]8�J�Մ�Ux%���3ݶ�ľ����Es��t��96TG�:<QC����:rL�GnV`}#�/nv�xo�}!��l�e%uG����I���WF�f=���Dw'>��$*�7�M�wPa +���_�%��qId��7U�2�KB��j���fk���rԚ�\��r1vB:��H���XK������f��Xst� �͜@���7A(�@�%�ge`+H�7Yd�=�e���KY�6�j.��H�"��DS��K�9)�օgu0���U��Zoy]��Σ/5$`=�4.Z-����Roy*l̡�x� q�;�uGYcS�ZuGMHQ�K꣎��s�^ +![MY�{K�u�j��d� ���Ѭ&��2b��'�H�N���מ���6�G +���f����H�i)w{��q����`���^,6sO��>:�w;H�[b�u���*�[�E����H�h���0 �r7Ӫ;ꌻe-i�Q�� �(�$�m7�0���Z +�nZ��-�e/GFwydq�#���W����VftQH��Vcc�.�픳ɺ��Etu�_+_��-O��q�T� �Pgt7S���% Ș�����nF�u�YV�ҋ��my�L�,�����}]����Kt���|� +'T��gSͬ�D8��EX�{�95�£��p����� 1���ǯ��ݾr��{�v�P86k�Q ��Z������y/Y�X�mW�QI�E^8j�D2=�=Օ���1 z�� /�I�S�pd<mzTM�*H�JS; +���YҀ��ȴt�H n�5���z��%�G���x�Qza��d�n���8[`���zhQkN�@k��J�*�����Z4ڍ��Ef��pt]�8��|v\ ��B!����^z�ڋ�HU�"��������3@�G�z�袎�{+� �i"��s�I��;�9U�Z�q�%p3���������^~�O����(��<�sCE|�]��O�|�X벜����%N�麜O7jZ��җ.6/�+��k��Ů���k�d�o����%�.vU�W8*��k�.6-�+��kɥ�ݔ�i�%�|q(��r��Z�8 k�����ɪzG�|���J$�ݑ�*�XV���� +3hR�VoZ��\c�h���l�J���j�Ԓ�A\ �"�t)�h��V�pIuH����g|��xo5Y��Fk���9T�T),�<�+��Ҋ��"��+�8�>�S�pNq`�6�+]tӼ~�ۑ�T�k��T� �'_u|6F�)&q����\�k�*��ݼܵ{��3P/����V~I럡��������zd1�.=[T(Wlvgjq+asQ"�c�(]�P�N��%E|R/Ǖ�T�QU�Q\��,cřR�8�r��0�P�P9�u���k�@V9��0�WI�A G��� � +O=(��mP�S��qZ�z����F5�o5 +^��]U��d|\�5r�E8���z��5P4�9]�hiMaE�}�:����*�ȯ]S>W�䠗ęR���5���1�MW���2S��Ъ*v���p�вܭ�2�ڝ���)�D�RJ�J�w꩹9W��h)%��ҽ�|�(��>n��=�}|��-��W�)������V�L*$��DHJ\��`�����..O�(ٓv� ��|�f]CMOiTiW�TB���W&��ɻ����=[Qn��h��/���%ɠ� �R ��֨R����V�>*�,Y���P�7���� ���5��?�ui?������J*�ڪ��1���p�YgZv�:'�E�p��7%sr+��j����&oFe�7F�{s���{�Ǵ��7P�Uf�I�����6�kxo/G���Ir��E=\���U�(l|ޛ�/@�p]{o���&㶫�b�Mqu�6�� ++��Vэ"��RM6�Jc�)�����$IJ�@���F�-�]�X�b��c�0�7=�u=\yV`�*E�ك�b_T ,(�Yx�Y���]U�,��,a>#�6~Ŭ�:?�mZ��u~j��n> KϪ���lV�Wl���2�����J*�`Z�yJ�G\���ʼΒaW�����̓��*��y�@~� ��V��qSu�D����g�^W��؛^T�E +�Ņ�����$�N�L�Q�[�R/�����˭�H5(H���\tRxE�LV�@͎�T���ު�zSP�K��<Ś��i�����z)�#O�둧�J��&=6��Sy#���c�R��c3�VH�Ǐ��� Tu��֦l��/��c�������(/�j�LԜ��/���T����O˦��8��&�./���gv���d�w�Ð�x���d*�Ж��:*��|w5��P�:S����"ٳ��RG=)�����dϞ4�����kVF'��5�Ⱦ�[��$k6 +=Ni��C7X>��?)�+k�-�k5:���<=y��(�'�guQ�b{0خ�����R���hTȖ�㱢1fBx3MO�_��\$5��G�T�U�M���j�3V�x����i6�#������?�r�:��g �Հ�����kuNg�>r:O�tה���I݀b��3;T������bi��my%�;_ٟ�]�k��,����K'+��K'��s�k�����cqq��I�.|y�����, �*��j��Jõ�����p���]ɲW������ �˳�_�C�� +�����ۺQ[���\�_(.����}Y4���QW��,y�Ea�/ɨjٝ{�k�}AڻѲb���|9mvԉ�����'���� +�Ӳb?������a�p�᭛_�%�~7e�~>*u���j!�����{ +�?�t+�g��O�hע;�?���ե{�U���.o'��/������U�2e>����b�v�>e�~谸Hڛ���"Vu��������k�*�`Ռ��]����F��z=��u�;]���Y�g�T㶕��Yr������Ǫ�r�3��݅Wu�J� +�=M�&�VΩ�+u_��]�nVo^k�J�*U}�0=,�K&!U�u�)(��Y �ۮg�}:������O���|�fo +�tY%R&d� +�t1��?��y�,���/ӕ����`� +�tU}�������<���^���Xz���OWէ�^����+]���Z�gtuR�W��ma_սQ=*��ͩ�����>u��+�ً¾b���}��t��.���j���Qa_/�V���к)�S��Q��Ia_��RU_��ҫia�N'}�DU��/�Ua�����O���Mܞ��Ԋo��]a_Q V���m�B�4)�Ӂ�{�{Zا[R&�U���uh#23J65��?��Μ*6�֫��]}��-�-V9:�ů����-~��\��r����H9Z��EhՠZz��6J�@֡�k��[wN +S�N�/�r��^���i5���pNq�7�*��j�M��4km�(&�3=V$6ɺ@�ی���x��7���(��/ZMOsg�������9n4��u����?��[����R)��.��M.�K��e��uQ/��@,J���2��R{���=���YA���n������fy�q��}+�~hpm_V-�(����uv�@fICRuYL�}�̐B��\ _�X��� I��������4�}QK����?_+`��{WN}5S�Z�MR��[-�|�T+tU3��<��q��bv'��� +jvT%[���>)�XG�T��)wH��u֬�������oH�5�>+��|�06Y�i�)�f���I��YVB1���b���^@���ƨ�:�+��k���V NR��b|~W=ް.pPC�o�*�l�ch�G������j�c�;ꨄB�oXG�W�5K�=���UQ��D� GE�9�}��X�Ve�gO��k�Ux=Hو����ׁ��ɽ�0Q����H����<�����/�Ž-~�V�� �SJ��S�M�[�����Ԭ����Z*O;{�Y�/�J�A7]T��=հ�[��c�]�// +1�����t�R�D�gt��:-0�y머2��t��܌Q���3�E�82SH%9�K�qzt2G�ӣ-%Fa/�ǣ2z�_H�5,������w�M����$u�z�U>/t��Z���:�Y̔�v_C��a{���2۳��]<7/�*q?����4Fah�~d%[��� Q-�<����z)����fu���#>%{sܻS��[�LȞ��^���D�j] �.�����Q��Ԏ�Oj�9�/�.���"ڌ�@?�t7�ޭ}�_���_�n6�,�N|����}�ǧ�]^gxt�rm�̼[₈y�%������4�8!u%�/�ǻ�g+{5����qAeޘZ��f$W�M[���+��v����`�7����Ô">:ţ���:�~e�LK�h5��˱��]��2�e$~NFu��K36:{������k�.��͕�龲�Rt�~Z�^T�wQ2��_8*���灓��k�ROuԽ�*��ì�Q�V�[;Ho'�O�$�m�c�V;g��2���������&�^�S��U����$ޣ��%�U"��.q�*���7��(-u}�B�y?>����*�L)�?�gmI�$�.=[l�8<��.��~�M�:s�*.���wZ*�FI����+��5K�*�C�3A[��XU/�:k��ּv�pN��Xj�VQ���S�Qu�(��nJ +g�try� +�Z>�g|K6��{ci��u5���|��/�h�S)6u���-�}��|�������z����^R�G:ͼ�.I��t�Dzf���ƪɟw��lj��MEQ����PW�� �Y�%}�ҫ\�짖tlN�u^E��A7_6f�>�2n��B%%�Ԯ�;*>���I��ĪD��m9����H{Cʏ��;ZcZe>�:�zfZ�E�u�{x;Xy�@��Ī[��tS��R�!Y�[�&��K�4��5�M�2]�����*"�����n]m�=+��\��Ps,/I�k����,I�[�X@�uK�'��G�Δ�K��#b�nJ��#��S{����3u����]�U��Ahi͕%�u��d� R��(��]R�ck�Bx�%�s|���}Ya����ؾV���������/+T�v��e�-vR_Qmc�.+T���e�:��pY�Z��]V�@���yYae��M�/ѫ�t�N�2b�����T��ɩV�u^��Zս�֩V�_xX~�a���k�j�݅�i`/N�*��q�g��0�������Ym^��0#����;/(�QN$�vX����\~�a����U��uv}�a��z'pK�����$�vq�af�r���:�𰜌�?������\xX���o;��7���eyYR�����]w|ᡄH���atԨ*��������^J3�tT�,���R�����Z�9�^xXn�e���..<TI;{ۡ�~(f���)����)綫�����BۡN�Sr���C.���C���J�`��)�hչ��΅���)�����m�J��7���f�Ԓ���e�&Wg�-=*������^x،�u|�a=U����H}�G2L�64q;��P�K��Xkr��]�j��0]_xX���.<,7�[���\Yzۡ0q���\��g?tpᡆeI�v��^xX�K�����{ +{q�ayip.ͅ�MJ�U�z�D��m�,k���<{�a��ux�ayU�� ������}no:��P;�ĺ��יZ݄�^\xX~�a+�����CeN +Z(��/<����v���ux�ay�n���{�ay�n��uy�ahjYm���������fS���r6�.{p�a�m����/<,�-v�@��hkt��2Y�s�K#a�S��ʝɞ{����ѽd�Qe�8XR����G��UN�5����l������S�`�zy~�_~�C�l�O�~4�G�oBU]���3�9z���q��:Ͽ6Vf�~�>��Nݍ�,<-�k??�<�-�0�g���|����k��;O{����i��p{���4����U���������m����O����Ϳ�_��ܥ?���6o��~8z����������O�_?�R�h�]���=]_{�5p�>��L��e��3�_����~�����gd�\Y�\0W���a���{��ߣ����������]��&E���SD���������_���h@�Nb��M����E4���#yrA&]��������`��0 +�D�����gg��t��F/GnvO�g��+ö��m��u�5նnĵ��T�5��~����{V!�?���?d�\���C֛�����(數��}�ƌ?���t�rs��]���w�Z�~7�~��1�~�~� ��.�s����տ�Gg�k~�z9|�;��S⭉ۀj+����o�?�u��=l��o~�z1�|x�F���ݿ�Or��;~f���~����WΗ۞1�F�Ù{��{< �Y92x��#�~�d_!�N��uш��^Y��C��fN,M������[�#���>Ef{&K���_��c��ߗm�>NH�.?�/������l�b=pSpjp�W�Oc`ġ�խw��� ����#y1%�x�6�Y[�M�'�ʜ�5˦�6�ܺ:�=s��y���z�H��<� Ϡ=23J�\� �䇿H}6)������þ�~��Zb��W&��_n��g7-Q{̟��g�o�a̱�д�~Z��ƀ ���h�'0"���!��N���uiJ�Y큗� h�́�i>�v=J�`��|�(s|j'�����������=�v}/��d�i���GB����ɺE�}���;�b/�=�ŧ��s����c���ӣ><����uybP�ȃ}�w�俽x����ǎ~I(pbK3����O<�7!�+i5߿�/��yO�{����?��Z�\���2�$�ؒ����1[p���o�Q���B�a��e�u�ߟz����欄#��ͳ�Pjo:����o+K�����?Y����J��˘\����D� /g���=|�h�u���������c��ma�4��LT�i���4��ՃŅ��ݱ��w�B�n'��.�����wF����ag0�{5�Q�E (X'�=g.Z|u�e�ޘ�|6GO�',Ȓ⋓���G��]���QN��ď�%��.�@��z�w���i�dM����]���drq�*y6)�X�ڛ@��pm����u��nQ���]m�flZ2s\x�#?w�b��&j���l^�_������ �����w�+��ԊE�`���f���}�� +e�R�>� +�6��RV���/h�����д��,J�]�,�S�z�~1ԧ ��� �����n�����n��;��������ټ�_B�� Y�B-v5������I#�ǯ���q���^I�=�����<߸�;|boH�|�����>�2}� ��z8�m���6�ɦB_�ɵ �d�g<ed��<yL~y"e���Db"�&H�����v��AE��;�����ޒ��-������|������k������d��m)ۛ��͉�䏵oƻ?|5+ؘb���(s$H\�̀�;�B�߬T�fW��-�.��tB�xlIs8�>;W�!- �O��c8`:��Ϊ9�e �??'@8��rټ�8N!.?|J�����B�v��˕c�X:$��������ǧ:d �Qnz 0�~�O��ワ'p8*A:�5��V�G��>��cd6�ż��y4��ų��7���z鐴�]8�ؑݳ�B�f�1v����Eyԃ#�ݛ�ʅ�J}�.>=d&��_> &*x�㻴sm������,A�ci�͕ok{*���u�i��.1���IH����KL;��ӎj0��8�]=Wc�I�B~U@S`Z)0nߺC��G��W��>��pAE��}�@�ގ��_���:D������ț\�o].�Y"��y{�h�u'U�j���}���"wpu���TH����S�I(���W��uu��5뼺�P.����Kb�z뗿�x����c����_O���ϙ��/��O����o�j�d&�w�]��Xf&'c�7�)�I���q�������n]��>��+~$����XK{���zsV_����?��� 8�C7�}�����G{���|�bt�V�Լs��nq����@��i�ŋ�j�G>�=q��z�h���@��Ļ| +kÜj�˱�κfq�}=����>r�Ǟ-J1�3�����qf}d=Pr�+��'o�5�p���B���'��l������r}�=�Ԍ�|:��ºR\���0g-�����63,����e����������4sƓK⣽t�o��ERV�<.��;>sj����;�ͩ���bC:����9S���n��<��I1�������O�s�������>³`��c��̎�Z�[ֵ;��ѿ�;�r��N�������x�8������j�ܜ�Bgpz(*���]%w��>s�`�g/Ti�85̍ՏK����]OmZ?�����߫�ԟ���L�0c��(Gf���7oڙ�17n�]gx��h��=_��~N8�ҝ9g�ܭSҗg����-��s�=<w,�I��Y|<�xu��{fgљ��(L2&au��Ǣ�s5>prbf�R�� �dQ��[�����q��ˣ5����Ê`�:�o8�u��W���ӟ����8Ai]t��ڄ�:=:�Y� +������k�u3 �kW�G���.�GbL��0�(Ӂ��B6 ��Ϗ�3[Ҁ���������x,�|tt:~<���έ����4$u�>�0_݊]�;D7�_{��f� ��5b0�܇ZM +�]���zo��v��D���=�<%�\��#ޯ3���Df����I�:&d8�1$��9�w��7eg%C#"h֛��:<����ً.̴?����������)�l>���߳�Cd/����hЏ�$���"D�䫭�d�.A#�=�DZ��<��p�}࿌�O�+��|l{���>�����Q�)Z�=0��������G��$��P��2�m]�n�۟nL�'�0�=X���w��O��ڗ��ޏ�|Xv�H!j!�>������L����!EJ��zڦY�͏�O�g���}��g��2.��?�[�������܇�#w~����� �GE����0#J&1�͂��P�Ɲ (�q�h7�FMĭ����'��S����8��,�̓2txm&����iz�͉�77�)&�A0y("�7������N��3�g"��a�X<��l�)<-z%ֹ)Ǥ!�nN�0�Ϗ���&�؊!1����/��(QoB\�6쥩� �ӈ��Yڍ�P��� +�d"�Co��J;O��SBǚ�3���3 ˲\�s,��|7�k���y�y����}��}����e�_?�<������ץ�ow7��}�}��/��롷t������G���A��S�I�"�e�MH]X�7Z�]��x���y<�*�#��O����P a��c�t���I{�K����$}=�6 [��`����x�`�{ѿ]�ٷ��>l��3�0œs�>�O�G�H�����ڤ�}��+�$�ԸS6E +s��9(,������D#���sP�G�_B{r�J�I^Ȧ�2y$��Ͷ��q�g�B ���8i6̹z0�h3�dmf���h3�&;���9�v@AS�Mq&�Ҥ"z���"��c0��xr����S)H��-�Qf� r�E�?>�~����U1$t�)w�m_��=6;��Q&C6֪�1�ck+�}.?o}L)�{��Y�v��0�_�/�\�Rd�E�Ɛ��s�u��H��ʙ'�A�/_�D���Eb�_�1�5Ю���+�b_���@�����X~�& ����v�$�J:1�OV�$�D-:q䔔��A����]�o��ӊ�N�䔟o�*���\����W�߬�-�����37�q�xF�W�/.M�c++�ۇ� �w����}��$�5'u��6�J|Q�X�~6�~���O�`��K��~����,�FYz�������+����ⷍ�������Զ�y���5Ge�9M�7jN4�No�S���F��0%�Nu>S6$�B�0YAiB/A +�@b��M"Haô�%�f�`�&�f�����&�f�����A +�@8 +�*�<�سD��,�8*ԛD��,�n"v�D����A +�@2��A +;`{ӳD��,�h�I)Dm%b�e"Haٞ�K��VӋD��,�N1M���:N)����JAjcZw� �Y ��pW� 5�jz�R+���D����%�ʔi5 A +�@j���N)�i5 A +�@ʅt�D��I�B�� �Y +��2���<�0�~�k�� ]�D�D��'��Ю#�TS�:J(M�2���n +�2�8�����v�4�)BY�ǥ��4����B�*<��'�텣� ���V�豺g����A?��Υ�_�����OB� a+���j��i����� �Xb�q��=u�J� �s�~�[)l���Ԋ��x-�g���\<-�,����Z��]�n#���F�9 +WW�Fn��֯?��A�#+�Iʵgc/�J�K7��a$���O��:h�:2����1|:�����ܞ��m��ե�vYbso�XS,�>< 6y{��oO��ӹ%�?Gf�f���#�8�w.D����P춼��(1��xN����ף���C���i�Zs��ti�P�r�Fn��7�^W��f��S�W�o�3|���Te��^<'ݾ� +T��Z5�t���Z��8T�?�Uc���2��Z5�L�d�תQ8�j')�y�|-G9�x��ܼ�=�&�������[��{�������L���A�g�a��y���ӭ��?��u�5ַuO��'��E{��u����������7͞mo�/�M���\�7��F13���j��Y/������߾�����k�q���웧?G��ƺi��ƞ���F�F�m�>�w#�5� �"�,�w��eOL��]�#Ϗ�$2-����,Ƿ��1�%u�|�_���O���,�o�����w���=�ɳB#0#ۊ|7���,Ӌ�0��(,L��N��w���M��̃�-# +L?4}�1�$0\� ����-j�����e���z ��(�\7r�l(��g۱Ǵ��5�/,+�#�:r�6�Y虚��{�x���L��|�X���=�庾�&l,30B�tm,Ƕ٤C� ��k`QG�k�����L�7q1A�L�ac���ZP-�0dM<���>�Ɔ�QE�:�k��h�/7�b� ;l���bY����<��ʨ�i8�f�D~�i��B�쑏=m?X&�I[������^�w^nh�*���=c�t-t��6;�L۷m�06�_@����hb�Ū��n�Y6v�5=��>�~�0��x�]��d�~|[�.�Qءu�����E�<�Ѥe���!351�)����u$�i��V<���zVhSE?� +B��ٳ 'p�� M[,��l��S��`M��P���8fD�c��ID4"�=���w��]���(=���-O�ЌL�"�����F�hͶ#߉��4�����|�-�������b�}�D�Xk�b"��K@���ٮ) ��ڸ�H��)�q��S�&6a(f㛁���&���( � �@�O����!7�͆1pI���-X�<h�-"�. >�|�N���ix�ZFH���,sp�u 18&���h[C�u���;L�'Z8���*g��Ba3�,�H +�52)K�B�[$��\\Ǣ�d�-d(h�1B�$�"B,��F��n�� + 8��H#O���B��519Ͽ!���D��E3,p�O3Oz��4}pK�Bٮm�?�陼�7��y�[dnX-<K��-�6h@��_ VG��Pj]~ݎ�?Pםo�[�F]w~X���<ź-��k��4��QT9T�I<�ܛ�"s�r�h�Y�?N%Y�����?������v�9�bK��1�/��6Mb-ӱ٠?��I%�:���V���2��A�$"T K4��B$?N� �q=�_�UپS��n�}aA�(�C0B�2i[x�i���`sȽm>T��cSW�,�����k���li�X~�����Xd����i�7�@�7P� �%;䒎�c6Z����uMK�-֕k��=7 M�J�7�j *d�71<4oԩ@����7��y���Ef��\W�$4M<�o�U�� +fB���#����1<�&��GK�@R���� +<Ev�d�r��_���y����'Z6�X���R&��'GH�< �d���b���O��O�C[1o ��y��ij��v�o*�m�Λ���L�hNઃ1���1z���t/��2��\�� 2�,��|(��uà��D`��1�!U߃r��7L=taV�Pa�q��( ��9����w�Wx��[�a�kF�a��76-�ֶC(�C-�E��j �X���fh�薚� ����B4!k����]�Ё�B>�6�P���3CZ�Xyc���FB2�f'a7�]�{�cOD؊_pț��v��� ,'X�������V7����`�&S����� \�h`F����;���:�� 0"ɔ�"�.�>l���֥�U�0>��Đ���`�l0��[b6� ,�bqs�v-"�]�^�f�W��XN�f@ +�A��S� ��f�a��P{!�}l�p6([B�ry�\��j�VGB�d� r2B�cd�`��ܛ�ģ�Z6��U�8X����@D��}��o�vmr���&��&~���3���M'���Khɥ_y��K{�'a����8�m���@Wt`�CL�&�#8�����v��t�iA��^�o�E8��3�Ơ��%߆�}7�$� "Gp);%Fײ��Q:}A��Ĩ����ӢY�6`i��c1!@aI�)��)� ,���a�,��Ğ3"c-��h3�D�D +xA<������n n�JAak���DZv�c��٩r`u�&z�ܘ~-`�@�X�X��p�?q8s�$��|w�G��A`~�c�� �&fQ�&.�+Hؘ�p��� vD��l�/�7���!����j�\�������4� d���+Zؤ�s�� �Y�$��!8[g��������ys������D�y1�NK/L�� +?��b�?~P����gſ +J~����}UCK���4E4��>�� A H^�'�v\ɵ"�cŁ�L�y>!;pŵ}�v�9��|�����ʣ�?��EA, S��D��0��<�V);V�g!���xXDZ�B�@'��s\�钿8"��ĊuLø�fHd�3�L� ]���c�$0��e�On��g��H��j�(t���PH�,Ƅ���ӤL��������z�����5 ��O!���l9&��!�M�L���gdr'���z��hHR+�"\/y,/"K�}���(�xa��)x�ʢ�@�t��P~]��~{�=pJh6٘Ԉ������݂t���@Q`v�e8� +6]�Y� 8 �(�Kڮ���P ��x�|�Lh�`k&ul2��#`��& U�XgĽ��6&��o@�$ �B�lҲM/�� +�P� h0j�]���G��ǚ��3�!�ajC�� + ՉCZ��P��4H��mwC� +��Rh�j���>kdCb�CB�e,٠/�r�Bʑ���!�`�G��Ԯ�Ql �tI(���[��!QI�T�X�If8#�Wj�U��,F�M�C���ӎ�?��9�%#�]�Z�t��AIwH�� ��)\����r +���VS���7Y�/:A]�����2�h�R�X�Z��`M$Yl#"��� 8H�Ecp/���UA\�H.p��+5�C��Dְ^,��`OĐLA�}@���Ҵi����1'l�͌/��d�v<�4Xa<h�I�ob�9aÆə��VP����rh����� (0 r�&������KM��`��EA!�u�`P"�����d\ +���Z`�!i��e������@( +#�Dn��@M��b�<_ׄ� �� �q��;��`�0����7�X���? ���?1��O���+H�̣5Y6tj��Ġ-���&�#E!"�\���܈2]�_�D�̾$���vpx;�pd�5�,C#`sH����Ќc0 q�������0� +��e�P.�P�Ay!�sv�P�*'̠������"���hB�l(@k�&&��aJ@�!U2ׄk�����$��k�&��!ۋ���,"k����2 �]2�M�Yh�}��(xMDX`Aj�Oa���B2�}�AaRQ8hS̕�b��6ވ���P�,"h��})�H��ԥDh1f�:�o\���xeJ=�&��K�d����L�l���kJ�2�F����.�dAE�@4:���EF��C�]����e�J��a�`GIe��("F;Ęh�$r��OI�3\uH����(p�/Ġ�3&�0�� ����^�Y�94Hsd +��E$ ��e�P}H��DН�(!s��:���F��G�� +�c�Ki¹b밵�[�) 䉧h�|�&Q5�>`��zd�p�>2�S��7#&��j��{2g+TN��d�*�C�5�."��vII�ƥ�c��dL��r��E���bm�%�lks�#a@�n0(�̇��ԅ1f�'��Ƈb���6X��|��C��y��3 Fi �i�$�8 ����ym߄<��Dz� s�,�9ۉ�RΗ�L�E"ݾ�M��W'�5�(��bV7�f�����������M�.��(m�E��@ ��c�[������ԭ�H�68�ki�ǃhr�v�-B���Ϗ 0M��������f�Ds��څM�Pd'n��$�_� L� �C�V�k��pU�W�j%��-��s�o���u���l%0��"��c����� YSxrC�������OH����[����M�����|1�P{��M�@���+���M�e������d���}!�bKhI۟�^�8�}�#1nrb�VP��?XTJA�\79tW���uE��<�IC+��-"``J|���P8(|&�\X��\#�3bL��=)�H�DŽ)t!,C��w���Ch�$bĴ,���?(^;F�g(I�=o���7�G�!FlɃ���}�,d'�?��z����:'�����~4�(/4�&�9$�(�7��2S�e�L1w�H� �$��!b�.T�$��1ș��\r�@N��AH��A�'�J/�'p���2䖱 +�k��B���P\�eG�'{pb^ ;H��?�B�+-P��b4���^1>�ϜTk3��6�H ��"������6���1��\NY���x`,��ʎ>���L@; 1�$L�s��lQύYS��rvsS )�V +n�VD�e��)�Ș�la�l����d���H`��03���ԙ���T� �~ܲԵ?n��*�\9Pre��@O��0uv���$����M�KWBL���$Ll��d81\��j��6a!��l�� �RD�0l�3����S�50##f�4H����{�+/�C���� fALfJ<�Sʣ�B����Qʿ���LL ����exD���� ^� :��&����yl%ӵ���F����C�J�� �X$�!��)�/� +�p;� ��M��c�u� 5 0��פ�A}'�:�L��4��(4Ki��U8��Bn+ǔ�Ө���ξ���y��#8#�2s���6�_#��&OF�������赭C%�i9PI�D�f��5�6!����{�"t-lRpt(K��$!�����%,#ݒ�aZ�y4 +2y-<���'����L�^<MJ������0t"�h~ �#�S9��$t�� i�J��tV��XՉD4�C`��Oyz�%v���9���L"�l6Oj"����DkKjd�ҏ�:D7^�y�ܽԤ.��b��6v�>��y�J�+Ih�0GlT.�Xb� N�pl;��P%R�V���$��E�<J�;b�+Y6d�� Lڷm�2�.��!Ͻ�3�xO��!g��r7�n�83I�B�I]h�I ��"�P"�A��=�_����('#Es�rY�p82|�<Q�eRYM�����#IF�(H�H@���N�J��r���5Ѝ�x���)k� FLJ�)t��%��"��4@�Հ�M�(0�,���&�D��R)���&'\����� ��e�Ǝ���a<�y�vCl�����R�$���������m���i�EO����#i�Y�&�R�R�IY�Ж%2��+˂(s�|T +#��))��!1j�t-țO�T�V�x#ύ"��61������D���nW��a+.!_r���t0Y�1�0�2�&���qTZ�ݖ�N�5/ +UR�:%z�5�6O{O��'�4-W�l�Q֓I)LhAIM���R>���YˡH,KZ�w���Oj䢇db�Ao&���V�xΜ�E+�d����7[$�(߈�����-jDa��KUe�(Չ��|%��^ȏ���۸,D�;8�)�N��i@tKܔ�I��ϊ�^�4 &,���-$?��" /��Ԉ���N(�}y�đK�,rErb$�9�����1L�Ա�0vD�'k�P�N�h���q�G�O��F��2`W���� )�-�Y����y�����Rd5��>��B 7J5�)V�,����,'�����S#V�.�R���t�2�i�������D�b6�e������9�H.'�}�Di���8�m���S�>J�5��_l� +�YI�X�WLf�Z��F2���&T���q�ڕch�tB�!4���m���t"P�S���d���DS���fƽR���f� ��S2W$���&ཞ�R1O�M�0 +�a�2NIr�:I@ãbvWQ�=C��:�Еt��[i�Gu��b7�䑈��G�^�@��3ۂ"?��-E������겗/;��d)��̊h'�+e)?p��m";i�IG�����'o��������M +,jC֦���lKHߧ�q�&�P��.�`���f����+A��ʐ������v¢k�.%����#m��R�n�ĸ�mo�C#J�Ȓ`�rC�'��$���ʾ�~fR�SeY���nO+El�t� a$�dR�v��l:��M�lS��]�,<p���eK(A�G"�)��㒺t-2��ɵ!�)ŵ<Ragy��|M��Q����O�g��DT�K/��ו�$%�����l,7u�A ETvYRn*�Aȵd��4��n��N� +����R���"��*y��&Br�z�5q����A*f=rA�MY y-m5���ׂ'eQ?�"O8��ԧ��'oe줻���O�����JXR��'�����)�Dh4E�2J|����t�K������Y��ِ^Y�sMi6!��2��;z��I9��ޣ�Px����������y�x9����,C�L�܃�A��Y�1��T�F)n����1$?38�xy�r��ar��"ٽ"�B�ٮd�f�H�ѥSs$狲L �Th@E5��͕�]�K�P��S�����?$W_ yh�7���>�̔���R���g%{���<�S"�,�ޏә���-*��2`�#1���g��;���Ш�Er#�:�����CC��:wv@�D��6s�8���fb�W=�O�� l�9���vV����3�� %7u�A���;~Ƌ��3�3��5\A�:��¥#��=K�K�fR,C�,i:�ȗ�Zy��O\~@B7�`��D�ѵ�* �}l �)���@��}� ��B���V�1F.��4~a��l�X&��ux�5��$�1�1y���j���՛�=�l+�d�b�T�J8�zr���s����T �0��.�鞧��{#�M�H�lt�%ئ\]�e��O��'Y^�"��Q�KI̡��E-"�B�X#�:R�R���_�t,������Q�/eYL��QE���Fn�P��)9A i�Y;�(�@�}��r�z���IXK��N�QҰB�q>:;�ε����ɡt��fr�HǴ�S��I���F4H�m@#xD��H���x����3Sp)�MK�ukp(-�qC��CA����yI�z��M��Q��{hۆ�D�Ҡ,еPy���M�ĝP�⒠PZ�1�!�LI����3&L�\��$Ը)��DC�P'�����<�Դg� M1�F�� P��c�2E�+`G�����U���J���]�C�ŷKtȊ[e�U;Y�D/"�#� +�}"��,9?,�,�(I͎�8�'��ʁt� 6�J|d7���u����iiޕ� �Q�L~�,_h*�4�PJ�E%lJ9Y8�x�ܲx�t�!+��8s�7):���p�ڸr��Xt�N�᙮F��Su �f��/ Ԁj�� ��q�<���>V�d���ф��1��>VX�� +:���=��'�{6&���J�.L +�%.S>)� 2����̙�<U0�K�F�z�nFg!gz��3���KY5ʦP���z��d����\�r�U��B3�����r��6}b��MIaHk�ux��$dYR�� P�^RIur�D8�q%�B2� Ģ�J +h�%$KNJ^���l.q�)~��A�`ؒ��c�ڂ㱂��nTLW'�R�v5d���(t^*�j��:��į�f�KY������N��9�5P-߆�5M��M�p]*!��be��-�����A���=�D��0ǻ�B��|ؒ�V#L:��b2eb�-W���2��$Fl�� I҆�('�S,8�F�E9-*ba�� �����W�(���bZi�d�����x��('{��1��{%������"#D���n�g��9�eC�`�;�[�P��MGGņ.ʉ��'��rBC�:�4J.ʉF����-���ğR���'�$ñ� m�����v�KR������gL7�|�I��6��9iJ�.����5�A��\��\2�\i#�('k#��颜����{J���:)����(�+]K&�I'(A�$%-�('w@%�q@I�r��(�L�R��j����XY�vbRD�r�xN�d��VR=��r2h(���r��Agw�<�d�Oh;�o�QN���j�QN���/i�j�S�B�r��(QN6�(�('fJڛ��٘���+��W�����7MIa�F99x�"�����3�A�~L��t^�}�~L2��KޏiQŧ�)?P��@::7Nr�2��j�3��J*��&�R_~ >�����@�b!;�}&�Ɏo�tq]���ke���$w&�71�rQ�R-�T+r�r����g+����˅�� {=5�?�U1�l�A��� :$�N��#c[t�G��磜�ON4�E9��B�P? +H�RoE~�.�`�%-�eB�Ė�MP��4�D@�%�T������e^��_��ÒT�⟗�ŤLk�Z�o�5��qJ��q��K"� ôb��c�G?����.ƙbɮq +5��>RC���2/��[��6],E�J�;����|ssp�@ke_/�n��o��x�������/�v������ߗ/���c�P18;1����B�f�@pk��/�Z��fWM�erC��?o��/����~�\����������כG����|������z�zB?J~04�������r⚬ +endstream endobj 5 0 obj <</Intent 15 0 R/Name(Layer 1)/Type/OCG/Usage 16 0 R>> endobj 24 0 obj <</Intent 33 0 R/Name(Layer 1)/Type/OCG/Usage 34 0 R>> endobj 33 0 obj [/View/Design] endobj 34 0 obj <</CreatorInfo<</Creator(Adobe Illustrator 22.1)/Subtype/Artwork>>>> endobj 15 0 obj [/View/Design] endobj 16 0 obj <</CreatorInfo<</Creator(Adobe Illustrator 22.1)/Subtype/Artwork>>>> endobj 43 0 obj [42 0 R] endobj 59 0 obj <</CreationDate(D:20200210190200+01'00')/Creator(Adobe Illustrator CC 22.1 \(Windows\))/ModDate(D:20200210204543+01'00')/Producer(Adobe PDF library 15.00)/Title(Mobile)>> endobj xref +0 60 +0000000004 65535 f +0000000016 00000 n +0000000173 00000 n +0000041997 00000 n +0000000006 00000 f +0000188597 00000 n +0000000008 00000 f +0000042048 00000 n +0000000009 00000 f +0000000010 00000 f +0000000011 00000 f +0000000012 00000 f +0000000013 00000 f +0000000014 00000 f +0000000017 00000 f +0000188854 00000 n +0000188885 00000 n +0000000018 00000 f +0000000019 00000 f +0000000020 00000 f +0000000021 00000 f +0000000022 00000 f +0000000023 00000 f +0000000000 00000 f +0000188667 00000 n +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000188738 00000 n +0000188769 00000 n +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000047861 00000 n +0000188970 00000 n +0000042443 00000 n +0000050845 00000 n +0000048161 00000 n +0000048048 00000 n +0000046826 00000 n +0000047299 00000 n +0000047347 00000 n +0000047932 00000 n +0000047963 00000 n +0000048196 00000 n +0000050919 00000 n +0000051115 00000 n +0000052557 00000 n +0000058443 00000 n +0000124032 00000 n +0000188995 00000 n +trailer +<</Size 60/Root 1 0 R/Info 59 0 R/ID[<F361282BA461F147A1F2B3811D3F3FD3><614117EE489C14408B11F817CB897719>]>> +startxref +189182 +%%EOF diff --git a/resources/images/logo-concepts.ai b/front/resources/images/logo-concepts.ai similarity index 100% rename from resources/images/logo-concepts.ai rename to front/resources/images/logo-concepts.ai diff --git a/front/resources/images/logo-superhi.png b/front/resources/images/logo-superhi.png new file mode 100755 index 0000000..066b87c Binary files /dev/null and b/front/resources/images/logo-superhi.png differ diff --git a/front/resources/images/logo-vector.svg b/front/resources/images/logo-vector.svg new file mode 100755 index 0000000..b7b5717 --- /dev/null +++ b/front/resources/images/logo-vector.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1694.89 512"><title>logo-vector</title><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><path d="M1461.78,309.88a27.83,27.83,0,0,1-2.18,10.92,27,27,0,0,1-6.1,8.85,28.51,28.51,0,0,1-9,5.8,30.63,30.63,0,0,1-22.24,0,27.42,27.42,0,0,1-9-5.83,27.11,27.11,0,0,1-6-8.82,27.49,27.49,0,0,1-2.2-10.92,27,27,0,0,1,2.21-10.86,27.5,27.5,0,0,1,6-8.73,29.22,29.22,0,0,1,31.26-5.88,29.48,29.48,0,0,1,9,5.85,26.8,26.8,0,0,1,8.28,19.62Z"/><circle cx="1566.89" cy="352" r="32"/><circle cx="1310.89" cy="352" r="32"/><path d="M1670.89,128h-8V80c0-44.8-99.2-80-224-80s-224,35.2-224,80v48h-8a24,24,0,0,0-24,24v80a24,24,0,0,0,24,24h8V416a32,32,0,0,0,32,32v32a32,32,0,0,0,32,32h48a32,32,0,0,0,32-32V448h160v32a32,32,0,0,0,32,32h48a32,32,0,0,0,32-32V448a32,32,0,0,0,32-32V256h8a24,24,0,0,0,24-24V152A24,24,0,0,0,1670.89,128Zm-344,352h-48V448h48Zm272,0h-48V448h48Zm32-384h-168a98.81,98.81,0,0,1,11.64,3.06,86.36,86.36,0,0,1,30.24,17,78.69,78.69,0,0,1,11,11.91h115.09l0,128H1488.58l-1,.74-.42.31-3.83,19.15a60.17,60.17,0,0,1,5.57,10c.26.6.49,1.2.72,1.8H1630.9V416h-384V288h130.36c.23-.58.45-1.16.7-1.74a60.19,60.19,0,0,1,7.48-12.67L1383,256H1246.88V128H1354.3l6.2-5.2a132.65,132.65,0,0,1,15.28-11,124.09,124.09,0,0,1,18.25-9.29,117.74,117.74,0,0,1,21.53-6.43l.35-.06H1246.86V80.31C1250.2,67,1314.3,32,1438.89,32s188.69,35,192,48.31Z"/><path d="M1500.26,178.76a53.19,53.19,0,0,1-11.09,34,60.53,60.53,0,0,1-10.45,10.52c-3.56,2.78-7,5.38-10.18,7.75a74.24,74.24,0,0,0-7.89,6.63,11.55,11.55,0,0,0-3.39,5.77l-4.5,22.49h-36.09l-3.51-25.68a23.19,23.19,0,0,1,1.75-14.19,35.8,35.8,0,0,1,7.7-10.28,85,85,0,0,1,10.24-8.14,90.78,90.78,0,0,0,9.68-7.56,40.77,40.77,0,0,0,7.25-8.55,18.9,18.9,0,0,0,2.63-10.27c0-4.39-1.35-7.74-4.14-10.24s-7-3.9-12.35-3.9a38,38,0,0,0-11.06,1.35,45.46,45.46,0,0,0-7.76,3.11c-2.31,1.21-4.33,2.33-6,3.31a14.3,14.3,0,0,1-7.25,2.05,13.47,13.47,0,0,1-12.27-7l-13.21-20.31,2.7-2.27a100.16,100.16,0,0,1,11.6-8.36,92.28,92.28,0,0,1,13.53-6.88,85.71,85.71,0,0,1,15.61-4.64,92.14,92.14,0,0,1,18-1.67,78.67,78.67,0,0,1,24.7,3.66,54.86,54.86,0,0,1,19.16,10.69A47.57,47.57,0,0,1,1496,157,54.12,54.12,0,0,1,1500.26,178.76Z"/><path d="M171.84,306.11a102.57,102.57,0,0,1-21.73,18,93.25,93.25,0,0,1-50,14.16,93.71,93.71,0,0,1-50-14.16,103.57,103.57,0,0,1-36.6-38.45,112.8,112.8,0,0,1,0-106.8A104.67,104.67,0,0,1,50,140.27a93.7,93.7,0,0,1,50-14.15,93.24,93.24,0,0,1,50,14.15A101.31,101.31,0,0,1,171.56,158l-32.74,33.88a56.34,56.34,0,0,0-11.87-11,47.05,47.05,0,0,0-53.75,0,60.94,60.94,0,0,0-19.59,22.3,63.51,63.51,0,0,0-7.15,29.17,62.35,62.35,0,0,0,7.29,29.16,60.91,60.91,0,0,0,19.59,22.31,46.61,46.61,0,0,0,53.47,0,56.38,56.38,0,0,0,12.3-11.58Z"/><path d="M211.88,328.27A80.83,80.83,0,0,1,181,300.11a75.84,75.84,0,0,1-4.86-71.49,77.35,77.35,0,0,1,18.45-25,84.53,84.53,0,0,1,27-16.44,90.51,90.51,0,0,1,63.33,0,81.25,81.25,0,0,1,27,16.3,78.1,78.1,0,0,1,18.44,25.16,76.43,76.43,0,0,1,.15,62.34A78.75,78.75,0,0,1,312,316.26a85,85,0,0,1-27,16.44,88.42,88.42,0,0,1-73.05-4.43Zm14.58-42.18a38.13,38.13,0,0,0,53.61,0q11.43-11,11.44-26.3a34.09,34.09,0,0,0-5.29-18.44,39.12,39.12,0,0,0-14.16-13.44,37.78,37.78,0,0,0-37.6,0,39,39,0,0,0-14.15,13.44A34,34,0,0,0,215,259.79Q215,275.09,226.46,286.09Z"/><path d="M436.91,130.69V326.27h-.29A77.75,77.75,0,0,1,433.33,345q-7.57,24.44-28,42.74a109.74,109.74,0,0,1-47.75,25,123.33,123.33,0,0,1-21.3,3V372.3c2.19-.28,4.29-.62,6.29-1,.57-.09,1.19-.19,1.86-.28H345l.43-.15a61.1,61.1,0,0,0,25.88-13.72,52.85,52.85,0,0,0,15.44-23.3,87.41,87.41,0,0,0,1.86-9.73h.14V130.69Z"/><path d="M606.47,228.77a75,75,0,0,1,6.43,30.88v1.28a10.37,10.37,0,0,1-.14,1.58l-.29,2.43H594.74v.28H496.38A35.77,35.77,0,0,0,506.82,286q11,10.88,25.73,10.87A35.18,35.18,0,0,0,558.29,286l.28-.28.43-.58.43-.42.29-.43,24.59,35.17a85.85,85.85,0,0,1-21.45,13,82.31,82.31,0,0,1-30.31,5.71A80.29,80.29,0,0,1,493,328a77.71,77.71,0,0,1-29.59-28.16,77.69,77.69,0,0,1-4.72-71,77.06,77.06,0,0,1,17.73-24.88,78.54,78.54,0,0,1,25.73-16.44,83.48,83.48,0,0,1,30.45-5.72,82.32,82.32,0,0,1,30.31,5.72,79.32,79.32,0,0,1,25.88,16.3A74.63,74.63,0,0,1,606.47,228.77Zm-73.92-5.72a35.5,35.5,0,0,0-18,4.86,42.49,42.49,0,0,0-10,8.86h56a42.46,42.46,0,0,0-10-8.86A35.53,35.53,0,0,0,532.55,223.05Z"/><path d="M787.75,260.93a71.53,71.53,0,0,1-11.58,39.32,79.82,79.82,0,0,1-30.88,28,88.44,88.44,0,0,1-73.06,4.43,81.72,81.72,0,0,1-27-16.44,79.2,79.2,0,0,1-18.59-25.16,76.07,76.07,0,0,1,.15-62.19,76.5,76.5,0,0,1,18.44-25,83.16,83.16,0,0,1,27-16.44,92.63,92.63,0,0,1,63.33,0l3.29,1.43,3.29,1.43V130l45.61.14Zm-45.61-1a33.32,33.32,0,0,0-5.29-18.3,39.18,39.18,0,0,0-14.15-13.44,37.1,37.1,0,0,0-18.73-5,37.85,37.85,0,0,0-18.87,5,39.21,39.21,0,0,0-14.16,13.44,33.4,33.4,0,0,0-5.29,18.3q0,15.3,11.44,26.31a38.13,38.13,0,0,0,53.61,0Q742.15,275.23,742.14,259.93Z"/><path d="M864.09,292.53h64.19l-11,41.32H787.46l64.62-108.09h-52.9l9.15-38.31H926.28Z"/><path d="M979.75,158.28a24.65,24.65,0,0,1-8.58,8.58,23.73,23.73,0,0,1-23.87.14,24.47,24.47,0,0,1-11.87-20.87,23.54,23.54,0,0,1,3.15-12,25.44,25.44,0,0,1,8.72-8.72,22.81,22.81,0,0,1,11.86-3.14,23.61,23.61,0,0,1,12,3.14,24.32,24.32,0,0,1,8.58,8.72,23.64,23.64,0,0,1,3.14,12A23.34,23.34,0,0,1,979.75,158.28Zm3,29.31V334.13h-45.6V187.73Z"/><path d="M1144.3,228.77a75,75,0,0,1,6.44,30.88v1.28a9.31,9.31,0,0,1-.15,1.58l-.28,2.43h-17.73v.28h-98.36A35.71,35.71,0,0,0,1044.66,286q11,10.88,25.73,10.87A35.14,35.14,0,0,0,1096.12,286l.29-.28.43-.58.43-.42.28-.43,24.59,35.17a85.63,85.63,0,0,1-21.44,13,82.35,82.35,0,0,1-30.31,5.71,80.29,80.29,0,0,1-39.6-10.15,77.81,77.81,0,0,1-29.6-28.16,77.64,77.64,0,0,1-4.71-71,77,77,0,0,1,17.72-24.88,78.69,78.69,0,0,1,25.74-16.44,83.41,83.41,0,0,1,30.45-5.72,82.36,82.36,0,0,1,30.31,5.72,79.43,79.43,0,0,1,25.88,16.3A74.74,74.74,0,0,1,1144.3,228.77Zm-73.91-5.72a35.47,35.47,0,0,0-18,4.86,42.49,42.49,0,0,0-10,8.86h56a42.49,42.49,0,0,0-10-8.86A35.5,35.5,0,0,0,1070.39,223.05Z"/></g></g></svg> \ No newline at end of file diff --git a/resources/images/logo.ai b/front/resources/images/logo.ai similarity index 100% rename from resources/images/logo.ai rename to front/resources/images/logo.ai diff --git a/front/resources/images/logo.png b/front/resources/images/logo.png new file mode 100755 index 0000000..f7b42bf Binary files /dev/null and b/front/resources/images/logo.png differ diff --git a/front/resources/manifest.json b/front/resources/manifest.json new file mode 100644 index 0000000..7e6fb1e --- /dev/null +++ b/front/resources/manifest.json @@ -0,0 +1,39 @@ +{ + "name": "Co Jedzie?", + "short_name": "Co Jedzie?", + "orientation": "portrait", + "lang": "pl-PL", + "start_url": "/", + "display": "standalone", + "background_color": "white", + "theme_color": "white", + "description": "Odpowiedź na odwieczne pytanie ludzkości - czy tramwaje jeżdżą?", + "categories": ["navigation", "transport", "travel", "utilities"], + "icons": [{ + "src": "/images/icon-256.png", + "sizes": "256x256" + },{ + "src": "/images/icon-512.png", + "sizes": "512x512" + },{ + "src": "/images/icon-64.png", + "sizes": "64x64" + },{ + "src": "/images/icon-128.png", + "sizes": "128x128" + },{ + "src": "/images/icon-192.png", + "sizes": "192x192" + },{ + "src": "/images/icon-96.png", + "sizes": "96x96" + },{ + "src": "/images/icon-maskable.png", + "sizes": "512x512", + "purpose": "any maskable" + },{ + "src": "/images/icon-monochrome.png", + "sizes": "512x512", + "purpose": "monochrome" + }] +} diff --git a/resources/svg-icon-loader.js b/front/resources/svg-icon-loader.js similarity index 100% rename from resources/svg-icon-loader.js rename to front/resources/svg-icon-loader.js diff --git a/front/resources/views/index.ejs b/front/resources/views/index.ejs new file mode 100644 index 0000000..f99ad2b --- /dev/null +++ b/front/resources/views/index.ejs @@ -0,0 +1,65 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="UTF-8"/> + <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> + <link rel="stylesheet" href="/dist/main.css"/> + <link rel="manifest" href="<%= manifest_path %>"/> + + <!-- icons --> + <link rel="icon" href="/images/favicon.png" sizes="16x16"/> + <link rel="icon" href="/images/favicon-2x.png" sizes="32x32"/> + <link rel="icon" href="/images/favicon.ico"/> + + <!-- Apple shit --> + <link rel="apple-touch-icon" href="/images/ios.png" sizes="512x512"> + <link rel="apple-touch-icon" href="/images/ios-80.png" sizes="80x80"> + <link rel="apple-touch-icon" href="/images/ios-192.png" sizes="192x192"> + + <meta name="apple-mobile-web-app-title" content="Co Jedzie?"> + <meta name="apple-mobile-web-app-capable" content="yes"> + + <meta name="theme-color" content="white"/> + + <title>Co Jedzie?</title> + + <% if (gtm_tracking) { %> + <!-- Google Tag Manager --> + <script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': + new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], + j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= + 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); + })(window,document,'script','dataLayer','<%= gtm_tracking %>');</script> + <!-- End Google Tag Manager --> + <% } %> + </head> + <body> + <noscript> + <% if (gtm_tracking) { %> + <!-- Google Tag Manager (noscript) --> + <iframe src="https://www.googletagmanager.com/ns.html?id=<%= gtm_tracking %>" + height="0" width="0" style="display:none;visibility:hidden"></iframe> + <!-- End Google Tag Manager (noscript) --> + <% } %> + <div class="container"> + <div class="alert alert-danger"> + Aplikacja wymaga do działania obsługi JavaScriptu. + </div> + </div> + </noscript> + <main id="root" class="container not-ready"> + </main> + <footer class="container"> + <span> + <img src="/images/logo.png" alt="co jedzie logo"/> + v.<%= version %> • + <a href="/api/doc">API</a> + </span> + <span class="copyright flex flex-space-left justify-content-end"> + <a href="https://kadet.net"><img src="/images/kadet-net-logo.png" alt="kadet.net logo" class="mx-1"/></a> + © <%= year %> + </span> + </footer> + <script src="/dist/main.js"></script> + </body> +</html> diff --git a/front/server/server.ts b/front/server/server.ts new file mode 100644 index 0000000..23c6d25 --- /dev/null +++ b/front/server/server.ts @@ -0,0 +1,87 @@ +import express from 'express'; +import path from "path"; +import fs from "fs"; +import request from "request"; + +const server = express(); + +const port = parseInt(process.env.APP_PORT) || 3000; +const host = process.env.APP_HOST || '0.0.0.0'; +const api = process.env.APP_API || "https://cojedzie.pl/api"; + +const gtm_tracking = process.env.APP_GTM || ''; +const version = "2020.11-dev"; + +const manifest = JSON.parse( + fs.readFileSync(path.join(__dirname, "../resources/manifest.json")).toString("utf-8") +); + +const provider_manifests = {} + +function generateProviderManifest(provider: any) { + return { + ...manifest, + start_url: `/${provider.id}`, + name: `${manifest.name} - ${provider.name}`, + short_name: `${manifest.short_name} - ${provider.shortName}`, + }; +} + +server.set("views", path.join(__dirname, "../resources/views/")); +server.set("view engine", "ejs"); + +server.use(express.static(path.join(__dirname, "../build/public/"))) + +server.get("/:provider?/manifest.json", (req, res) => { + const provider = req.params.provider; + + if (typeof provider === "undefined") { + res.send(manifest); + return; + } + + if (typeof provider_manifests[provider] !== "undefined") { + res.send(provider_manifests[provider]); + return; + } + + console.log(`No manifest entry for ${provider}, calling ${api}/providers/${provider}`); + + request.get(`${api}/v1/providers/${provider}`, (err, _, body) => { + try { + const info = JSON.parse(body); + provider_manifests[provider] = generateProviderManifest(info); + + console.info(`Generated manifest for ${provider}`, provider_manifests[provider]); + + res.send(provider_manifests[provider]); + } catch(error) { + console.error(`Problem with generating manifest for ${provider}: ${error.message}`); + res.send(manifest); + } + }) +}) + +server.get("/:provider?/*", (req, res) => { + const manifest_path = req.params.provider + ? `/${req.params.provider}/manifest.json` + : "/manifest.json"; + + const year = (new Date()).getFullYear(); + + res.render("index", { + manifest_path, + gtm_tracking, + version, + year, + }) +}) + +server.listen(port, host, () => { + console.info(`Server started at ${host}:${port}`); +}); + +process.on('SIGINT', function() { + console.info("Terminating server..."); + process.exit(); +}); diff --git a/front/server/tsconfig.json b/front/server/tsconfig.json new file mode 100644 index 0000000..390f710 --- /dev/null +++ b/front/server/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "lib": ["es2015", "es2016.array.include", "es2017.object"], + "sourceMap": true, + "esModuleInterop": true, + "target": "es6", + "module": "commonjs", + "moduleResolution": "node", + "baseUrl": "./", + "outDir": "../build/", + "skipLibCheck": true + }, + "files": ["./server.ts"], + "include": ["./**/*.ts"] +} diff --git a/resources/ts/app.ts b/front/src/app.ts similarity index 75% rename from resources/ts/app.ts rename to front/src/app.ts index 24d2987..eeec40a 100644 --- a/resources/ts/app.ts +++ b/front/src/app.ts @@ -6,10 +6,6 @@ import "leaflet/dist/leaflet.css"; import Popper from 'popper.js'; import * as $ from "jquery"; - -window['$'] = window['jQuery'] = $; -window['Popper'] = Popper; - // dependencies import Vue from "vue"; import Vuex from 'vuex'; @@ -18,46 +14,50 @@ import VueDragscroll from 'vue-dragscroll'; import { Plugin as VueFragment } from 'vue-fragment'; import { Workbox } from "workbox-window"; -import { migrate } from "./store/migrations"; import { Component } from "vue-property-decorator"; +import * as VueMoment from "vue-moment"; +import * as moment from 'moment'; +import 'moment/locale/pl' +import VueRouter from "vue-router"; + +window['$'] = window['jQuery'] = $; +window['Popper'] = Popper; Vue.use(Vuex); Vue.use(PortalVue); Vue.use(VueDragscroll); Vue.use(VueFragment); +Vue.use(VueMoment, { moment }); +Vue.use(VueRouter); declare module 'vue/types/vue' { interface Vue { $isTouch: boolean; + $hasSlot: (slot: string) => string; } } Vue.prototype.$isTouch = 'ontouchstart' in window || navigator.msMaxTouchPoints > 0; +Vue.prototype.$hasSlot = function (this: Vue, slot: string): boolean { + return !!this.$slots[slot] || !!this.$scopedSlots[slot]; +} Component.registerHooks(['removed']); // async dependencies (async function () { + const { migrate } = await import('./store/migrations'); + await migrate("vuex"); const [ components, { default: store } ] = await Promise.all([ import('./components'), import('./store'), - import('./font-awesome'), import('./filters'), import('bootstrap'), ] as const); - // here goes "public" API - window['czydojade'] = Object.assign({ - state: {} - }, window['czydojade'], { - components, - application: new components.Application({ el: '#app' }) - }); - - store.dispatch('messages/update'); - store.dispatch('load', window['czydojade'].state); + const application = new components.Application().$mount("#root") if ('serviceWorker' in navigator) { const wb = new Workbox("/service-worker.js"); diff --git a/front/src/components/application.ts b/front/src/components/application.ts new file mode 100644 index 0000000..44a71c9 --- /dev/null +++ b/front/src/components/application.ts @@ -0,0 +1,20 @@ +import Vue from "vue"; +import Component from "vue-class-component"; +import VueRouter, { RouteConfig } from "vue-router"; +import { Main, ProviderChooser } from "@/components"; +import store from "@/store"; + +const routes: RouteConfig[] = [ + { path: "/:provider", component: Main }, + { path: "/", component: ProviderChooser }, +] + +export const router = new VueRouter({ + routes, + mode: 'history', +}); + +@Component({ template: require("@templates/app.html"), router, store }) +export class Application extends Vue { + +} diff --git a/resources/ts/components/departures.ts b/front/src/components/departures.ts similarity index 77% rename from resources/ts/components/departures.ts rename to front/src/components/departures.ts index 7668877..01e35d0 100644 --- a/resources/ts/components/departures.ts +++ b/front/src/components/departures.ts @@ -1,28 +1,25 @@ import Vue from 'vue' -import { Departure, Stop } from "../model"; +import { Departure } from "@/model"; import { Component, Prop, Watch } from "vue-property-decorator"; -import { namespace } from 'vuex-class'; -import store from '../store' -import { Trip } from "../model/trip"; +import store, { Departures, DeparturesSettings } from '../store' +import { Trip } from "@/model/trip"; import urls from "../urls"; -import { Jsonified } from "../utils"; +import { Jsonified } from "@/utils"; import * as moment from "moment"; -const { State } = namespace('departures'); - -@Component({ template: require("../../components/departures.html"), store }) +@Component({ template: require("@templates/departures.html"), store }) export class DeparturesComponent extends Vue { - @State departures: Departure[]; - - @Prop(Array) - stops: Stop[]; + @Departures.State departures: Departure[]; } -@Component({ template: require("../../components/departures/departure.html") }) +@Component({ template: require("@templates/departures/departure.html"), store }) export class DepartureComponent extends Vue { @Prop(Object) departure: Departure; scheduledTrip: Trip = null; + @DeparturesSettings.State + relativeTimes: boolean; + showTrip: boolean = false; processTrip(trip: Jsonified<Trip>): Trip { @@ -46,6 +43,10 @@ export class DepartureComponent extends Vue { return this.departure.estimated || this.departure.scheduled; } + get timeLeft() { + return moment.duration(this.time.diff(moment())); + } + @Watch('showTrip') async downloadTrips() { if (this.showTrip != true || this.trip != null) { diff --git a/resources/ts/components/favourites.ts b/front/src/components/favourites.ts similarity index 72% rename from resources/ts/components/favourites.ts rename to front/src/components/favourites.ts index 5a5f5bf..73ab33b 100644 --- a/resources/ts/components/favourites.ts +++ b/front/src/components/favourites.ts @@ -1,14 +1,13 @@ import Vue from 'vue' -import { Component, Prop } from 'vue-property-decorator' -import { namespace, State, Mutation } from "vuex-class"; -import { Favourite } from "../store/favourites"; -import { SavedState } from "../store/root"; -import { Stop } from "../model"; +import { Component, Watch } from 'vue-property-decorator' +import { Mutation, State } from "vuex-class"; +import { Favourite } from "@/store/favourites"; +import { Stop } from "@/model"; import * as uuid from "uuid"; -import { Favourites } from "../store"; +import { Favourites } from "@/store"; -@Component({ template: require('../../components/favourites.html' )}) +@Component({ template: require('@templates/favourites.html' )}) export class FavouritesComponent extends Vue { @Favourites.State favourites: Favourite[]; @Favourites.Mutation remove: (fav: Favourite) => void; @@ -27,15 +26,22 @@ function createFavouriteEntry(name: string, stops: Stop[]): Favourite { } } -@Component({ template: require('../../components/favourites/save.html' )}) +@Component({ template: require('@templates/favourites/save.html' )}) export class FavouritesAdderComponent extends Vue { @State stops: Stop[]; private name = ""; private errors = { name: [] }; + private confirmation = false; + @Favourites.Mutation add: (favourite: Favourite) => void; + @Watch('name') + handleNameChange() { + this.confirmation = false; + } + async save() { const favourite: Favourite = createFavouriteEntry(this.name, this.stops); @@ -54,8 +60,9 @@ export class FavouritesAdderComponent extends Vue { errors.name.push("Musisz podać nazwę."); } - if (this.$store.state.favourites.favourites.filter(other => other.name == favourite.name).length > 0) { + if (this.$store.state.favourites.favourites.filter(other => other.name == favourite.name).length > 0 && !this.confirmation) { errors.name.push("Istnieje już zapisana grupa przystanków o takiej nazwie."); + this.confirmation = true; } this.errors = errors; diff --git a/front/src/components/history.ts b/front/src/components/history.ts new file mode 100644 index 0000000..31c392f --- /dev/null +++ b/front/src/components/history.ts @@ -0,0 +1,13 @@ +import Component from "vue-class-component"; +import Vue from "vue"; +import { History } from "@/store"; +import { HistoryEntry } from "@/store/history"; +import { Mutation } from "vuex-class"; +import { Stop } from "@/model"; + +@Component({ template: require('@templates/stop/history.html' )}) +export class StopHistory extends Vue { + @History.Getter all: HistoryEntry[]; + + @Mutation("add") select: (stops: Stop[]) => void; +} diff --git a/resources/ts/components/index.ts b/front/src/components/index.ts similarity index 54% rename from resources/ts/components/index.ts rename to front/src/components/index.ts index 78d820a..bb642b7 100644 --- a/resources/ts/components/index.ts +++ b/front/src/components/index.ts @@ -6,6 +6,13 @@ export * from './departures' export * from './stop' export * from './messages' export * from './map' -export * from './app' +export * from './main' export * from './favourites' export * from './trip' +export * from './ui' +export * from './settings' +export * from "./provider-chooser" +export * from "./application" + +export { Departures } from "../store"; +export { Messages } from "../store"; diff --git a/front/src/components/line.ts b/front/src/components/line.ts new file mode 100644 index 0000000..41648b9 --- /dev/null +++ b/front/src/components/line.ts @@ -0,0 +1,14 @@ +import Vue from 'vue' +import { Component, Prop } from 'vue-property-decorator' +import { Line } from "@/model"; + +@Component({ template: require('@templates/line.html' )}) +export class LineComponent extends Vue { + @Prop(Object) + public line: Line; + + @Prop(Boolean) + public simple: boolean; +} + +Vue.component('LineSymbol', LineComponent); diff --git a/front/src/components/main.ts b/front/src/components/main.ts new file mode 100644 index 0000000..7ef0158 --- /dev/null +++ b/front/src/components/main.ts @@ -0,0 +1,111 @@ +import Vue from 'vue' +import { Component, Watch } from "vue-property-decorator"; +import { Action, Mutation, State } from 'vuex-class' +import { Provider, Stop } from "@/model"; +import { DeparturesSettingsState } from "@/store/settings/departures"; +import { MessagesSettingsState } from "@/store/settings/messages"; +import urls from "@/urls"; + +@Component({ template: require("@templates/main.html") }) +export class Main extends Vue { + private sections = { + messages: true + }; + + private visibility = { + messages: false, + departures: false, + save: false, + picker: 'search' + }; + + private intervals = { messages: null, departures: null }; + + @State private provider: Provider; + + get messages() { + return { + count: this.$store.getters['messages/count'], + counts: this.$store.getters['messages/counts'], + state: this.$store.state.messages.state + }; + } + + get departures() { + return { + state: this.$store.state.departures.state + }; + } + + get stops() { + return this.$store.state.stops; + } + + set stops(value) { + this.$store.commit('updateStops', value); + } + + mounted() { + this.$el.classList.remove('not-ready'); + document.querySelector<HTMLLinkElement>('link[rel="manifest"]').href = urls.prepare(urls.manifest.provider, { provider: this.$route.params.provider }); + } + + async created() { + await this.$store.dispatch('loadProvider', { provider: this.$route.params.provider }); + this.$store.dispatch('messages/update'); + this.$store.dispatch('load', { }); + + this.initDeparturesRefreshInterval(); + this.initMessagesRefreshInterval(); + } + + private initDeparturesRefreshInterval() { + const departuresAutorefreshCallback = () => { + const {autorefresh, autorefreshInterval} = this.$store.state['departures-settings'] as DeparturesSettingsState; + + if (this.intervals.departures) { + clearInterval(this.intervals.departures); + } + + if (autorefresh) { + this.intervals.departures = setInterval(() => this.updateDepartures(), Math.max(5, autorefreshInterval) * 1000) + } + }; + + this.$store.watch(({"departures-settings": state}) => state.autorefresh, departuresAutorefreshCallback); + this.$store.watch(({"departures-settings": state}) => state.autorefreshInterval, departuresAutorefreshCallback); + + departuresAutorefreshCallback(); + } + + private initMessagesRefreshInterval() { + const messagesAutorefreshCallback = () => { + const {autorefresh, autorefreshInterval} = this.$store.state['messages-settings'] as MessagesSettingsState; + + if (this.intervals.messages) { + clearInterval(this.intervals.messages); + } + + if (autorefresh) { + this.intervals.messages = setInterval(() => this.updateMessages(), Math.max(5, autorefreshInterval) * 1000) + } + }; + + this.$store.watch(({"messages-settings": state}) => state.autorefresh, messagesAutorefreshCallback); + this.$store.watch(({"messages-settings": state}) => state.autorefreshInterval, messagesAutorefreshCallback); + + messagesAutorefreshCallback(); + } + + @Action('messages/update') updateMessages: () => void; + @Action('departures/update') updateDepartures: () => void; + + @Mutation add: (stops: Stop[]) => void; + @Mutation remove: (stop: Stop) => void; + @Mutation clear: () => void; + + @Watch('stops') + onStopUpdate() { + this.updateDepartures(); + } +} diff --git a/resources/ts/components/map.ts b/front/src/components/map.ts similarity index 83% rename from resources/ts/components/map.ts rename to front/src/components/map.ts index 4738985..e78e821 100644 --- a/resources/ts/components/map.ts +++ b/front/src/components/map.ts @@ -1,4 +1,4 @@ -import { LMap, LTileLayer, LMarker } from 'vue2-leaflet'; +import { LControl, LIcon, LMap, LMarker, LPopup, LTileLayer } from 'vue2-leaflet'; import Vue from 'vue'; import * as L from 'leaflet' @@ -48,5 +48,8 @@ Vue.component('LMap', LMap); Vue.component('LTileLayer', LTileLayer); Vue.component('LVectorLayer', LVectorLayer); Vue.component('LMarker', LMarker); +Vue.component('LControl', LControl); +Vue.component('LPopup', LPopup) +Vue.component('LIcon', LIcon); -export { LMap, LTileLayer, LMarker } from 'vue2-leaflet'; +export { LMap, LTileLayer, LMarker, LIcon, LControl, LPopup } from 'vue2-leaflet'; diff --git a/front/src/components/messages.ts b/front/src/components/messages.ts new file mode 100644 index 0000000..463baf2 --- /dev/null +++ b/front/src/components/messages.ts @@ -0,0 +1,35 @@ +import Vue from 'vue'; +import { Component } from "vue-property-decorator"; +import { Message } from "@/model/message"; +import store, { Messages, MessagesSettings } from '../store' + +@Component({ template: require("@templates/messages.html"), store }) +export class MessagesComponent extends Vue { + @Messages.State('messages') + public allMessages: Message[]; + + @MessagesSettings.State + public displayedEntriesCount: number; + + public showAll: boolean = false; + + get messages() { + return this.showAll + ? this.allMessages + : this.allMessages.slice(0, this.displayedEntriesCount); + } + + get nonDisplayedCount(): number { + return Math.max(this.allMessages.length - this.displayedEntriesCount, 0); + } + + public type(message: Message) { + switch (message.type) { + case "breakdown": return "danger"; + case "info": return "info"; + case "unknown": return "warning"; + } + } +} + +Vue.component('Messages', MessagesComponent); diff --git a/front/src/components/picker.ts b/front/src/components/picker.ts new file mode 100644 index 0000000..662ebff --- /dev/null +++ b/front/src/components/picker.ts @@ -0,0 +1,110 @@ +import Component from "vue-class-component"; +import Vue from "vue"; +import { Line, StopGroup, StopGroups, StopWithDestinations as Stop } from "../model"; +import { Prop, Watch } from "vue-property-decorator"; +import { FetchingState, filter, map, match, unique } from "@/utils"; +import { debounce } from "@/decorators"; +import urls from '../urls'; +import { Mutation } from "vuex-class"; +import { HistoryEntry } from "@/store/history"; +import { StopHistory } from "./history"; + +@Component({ template: require('@templates/picker/stop.html') }) +export class PickerStopComponent extends Vue { + @Prop(Object) + public stop: Stop; + + details: boolean = false; + map: boolean = false; + inMap: boolean = false; + + get showMap() { + return this.inMap || this.map; + } + + get destinations() { + const compactLines = destination => ({ + ...destination, + lines: Object.entries(groupLinesByType(destination.lines || [])).map(([type, lines]) => ({ + type: type, + symbol: joinedSymbol(lines), + night: lines.every(line => line.night), + fast: lines.every(line => line.fast), + })), + all: destination.lines + }); + + const groupLinesByType = (lines: Line[]) => lines.reduce<{ [kind: string]: Line[]}>((groups, line) => ({ + ...groups, + [line.type]: [ ...(groups[line.type] || []), line ] + }), {}); + + const joinedSymbol = match<string, [Line[]]>( + [lines => lines.length === 1, lines => lines[0].symbol], + [lines => lines.length === 2, ([first, second]) => `${first.symbol}, ${second.symbol}`], + [lines => lines.length > 2, ([first]) => `${first.symbol}…`], + ); + + return unique(this.stop.destinations || [], destination => destination.stop && destination.stop.name).map(compactLines); + } +} + +@Component({ + template: require('@templates/finder.html'), + components: { + "PickerStop": PickerStopComponent, + "StopHistory": StopHistory, + } +}) +export class FinderComponent extends Vue { + protected found?: StopGroups = {}; + + public state: FetchingState = 'ready'; + public filter: string = ""; + + @Prop({default: [], type: Array}) + public blacklist: Stop[]; + + @Mutation('history/push') pushToHistory: (entry: HistoryEntry) => void; + + get filtered(): StopGroups { + const groups = map( + this.found, + (group: StopGroup) => + group.filter(stop => !this.blacklist.some(blacklisted => blacklisted.id === stop.id)) + ) as StopGroups; + + return filter(groups, group => group.length > 0); + } + + @Watch('filter') + @debounce(400) + async fetch() { + if (this.filter.length < 3) { + return; + } + + this.state = 'fetching'; + + const response = await fetch(urls.prepare(urls.stops.grouped, { name: this.filter, 'include-destinations': true })); + + if (response.ok) { + this.found = (await response.json()).reduce((accumulator, { name, stops }) => Object.assign(accumulator, { [name]: stops }), {}); + this.state = 'ready'; + } else { + this.state = 'error'; + } + } + + private select(stop) { + this.pushToHistory({ + date: this.$moment(), + stop: stop, + }) + + this.$emit('select', stop); + } +} + +Vue.component('StopFinder', FinderComponent); +Vue.component('PickerStop', PickerStopComponent); diff --git a/front/src/components/provider-chooser.ts b/front/src/components/provider-chooser.ts new file mode 100644 index 0000000..5ea9bf8 --- /dev/null +++ b/front/src/components/provider-chooser.ts @@ -0,0 +1,31 @@ +import Vue from 'vue' +import { Component } from 'vue-property-decorator' +import { Provider } from "@/model"; +import { Jsonified } from "@/utils"; +import * as moment from 'moment'; +import urls from "@/urls"; + +@Component({ + template: require('@templates/page/providers.html'), +}) +export class ProviderChooser extends Vue { + private providers: Provider[] = []; + + mounted() { + document.querySelector<HTMLLinkElement>('link[rel="manifest"]').href = urls.manifest.main; + } + + async created() { + const response = await fetch('/api/v1/providers'); + const result = await response.json() as Jsonified<Provider>[]; + + this.providers = result.map<Provider>(provider => { + return { + ...provider, + lastUpdate: provider.lastUpdate && moment(provider.lastUpdate) + } + }); + } +} + +Vue.component('ProviderChooser', ProviderChooser); diff --git a/front/src/components/settings/departures.ts b/front/src/components/settings/departures.ts new file mode 100644 index 0000000..f4c5a43 --- /dev/null +++ b/front/src/components/settings/departures.ts @@ -0,0 +1,24 @@ +import { Component } from "vue-property-decorator"; +import store, { DeparturesSettings } from "../../store"; +import Vue from "vue"; +import { DeparturesSettingsState } from "@/store/settings/departures"; + +@Component({ template: require("@templates/settings/departures.html"), store }) +export class SettingsDepartures extends Vue { + @DeparturesSettings.State + public autorefresh: boolean; + + @DeparturesSettings.State + public relativeTimes: boolean; + + @DeparturesSettings.State + public autorefreshInterval: number; + + @DeparturesSettings.State + public displayedEntriesCount: number; + + @DeparturesSettings.Mutation + public update: (state: Partial<DeparturesSettingsState>) => void; +} + +Vue.component('SettingsDepartures', SettingsDepartures); diff --git a/front/src/components/settings/index.ts b/front/src/components/settings/index.ts new file mode 100644 index 0000000..21e734c --- /dev/null +++ b/front/src/components/settings/index.ts @@ -0,0 +1,2 @@ +export * from "./departures" +export * from "./messages" diff --git a/front/src/components/settings/messages.ts b/front/src/components/settings/messages.ts new file mode 100644 index 0000000..8f4b1e5 --- /dev/null +++ b/front/src/components/settings/messages.ts @@ -0,0 +1,21 @@ +import { Component } from "vue-property-decorator"; +import store, { MessagesSettings } from "../../store"; +import Vue from "vue"; +import { MessagesSettingsState } from "@/store/settings/messages"; + +@Component({template: require("@templates/settings/messages.html"), store}) +export class SettingsMessages extends Vue { + @MessagesSettings.State + public autorefresh: boolean; + + @MessagesSettings.State + public autorefreshInterval: number; + + @MessagesSettings.State + public displayedEntriesCount: number; + + @MessagesSettings.Mutation + public update: (state: Partial<MessagesSettingsState>) => void; +} + +Vue.component('SettingsMessages', SettingsMessages); diff --git a/resources/ts/components/stop.ts b/front/src/components/stop.ts similarity index 86% rename from resources/ts/components/stop.ts rename to front/src/components/stop.ts index 1439564..a5fdd52 100644 --- a/resources/ts/components/stop.ts +++ b/front/src/components/stop.ts @@ -3,7 +3,7 @@ import { Line, Stop, Track } from "../model"; import Vue from 'vue'; import urls from "../urls"; -@Component({ template: require('../../components/stop/details.html') }) +@Component({ template: require('@templates/stop/details.html') }) class StopDetailsComponent extends Vue { @Prop(Object) public stop: Stop; @@ -35,13 +35,13 @@ class StopDetailsComponent extends Vue { } } -@Component({ template: require('../../components/stop.html') }) +@Component({ template: require('@templates/stop.html') }) export class StopComponent extends Vue { @Prop(Object) public stop: Stop; } -@Component({ template: require('../../components/stop/map.html') }) +@Component({ template: require('@templates/stop/map.html') }) export class StopMapComponent extends Vue { @Prop(Object) public stop: Stop; diff --git a/resources/ts/components/tooltip.ts b/front/src/components/tooltip.ts similarity index 96% rename from resources/ts/components/tooltip.ts rename to front/src/components/tooltip.ts index 4bb6b9e..7639aaa 100644 --- a/resources/ts/components/tooltip.ts +++ b/front/src/components/tooltip.ts @@ -3,14 +3,14 @@ import Component from "vue-class-component"; import { Prop, Watch } from "vue-property-decorator"; type Events = { - [evnet: string]: (...any) => void, + [event: string]: (...any) => void, } type Trigger = "hover" | "focus" | "long-press"; const longPressTimeout = 1000; -@Component({ template: require('../../components/tooltip.html') }) +@Component({ template: require('@templates/tooltip.html') }) export class TooltipComponent extends Vue { @Prop({ type: String, default: "top" }) public placement: string; @Prop({ type: Number, default: 400 }) public delay: number; diff --git a/resources/ts/components/trip.ts b/front/src/components/trip.ts similarity index 86% rename from resources/ts/components/trip.ts rename to front/src/components/trip.ts index fb70e0e..24bde4e 100644 --- a/resources/ts/components/trip.ts +++ b/front/src/components/trip.ts @@ -1,13 +1,13 @@ import Vue from "vue"; import Component from "vue-class-component"; import { Prop } from "vue-property-decorator"; -import { ScheduledStop } from "../model/trip"; -import { Stop } from "../model"; +import { ScheduledStop } from "@/model/trip"; +import { Stop } from "@/model"; import * as moment from 'moment'; type ScheduledStopInfo = ScheduledStop & { visited: boolean, current: boolean }; -@Component({ template: require("../../components/trip.html") }) +@Component({ template: require("@templates/trip.html") }) export class TripComponent extends Vue { @Prop(Array) public schedule: ScheduledStop[]; @Prop(Object) public current: Stop; diff --git a/front/src/components/ui/dialog.ts b/front/src/components/ui/dialog.ts new file mode 100644 index 0000000..f15f135 --- /dev/null +++ b/front/src/components/ui/dialog.ts @@ -0,0 +1,279 @@ +import Vue from "vue"; +import { Component, Prop, Watch } from "vue-property-decorator"; +import Popper, { Placement } from "popper.js"; +import { defaultBreakpoints } from "@/filters"; + +/** + * How popup will be presented to user: + * - "modal" - modal window + * - "popup" - simple popup + */ +export type DialogBehaviour = "modal" | "popup"; + +let openModalCounter: number = 0; + +function computeZIndexOfElement(element: HTMLElement): number { + let current = element; + + while (true) { + const zIndex = window.getComputedStyle(current).zIndex; + + if (zIndex !== "auto") { + return parseInt(zIndex); + } + + if (!current.parentElement) { + break; + } + + current = current.parentElement; + } + + return 0; +} + +@Component({ + inheritAttrs: false, + template: require('@templates/ui/dialog.html'), +}) +export default class UiDialog extends Vue { + @Prop({ type: String, default: "popup" }) + private behaviour: DialogBehaviour; + + @Prop({ type: String }) + private mobileBehaviour: DialogBehaviour; + + @Prop([String, HTMLElement]) + public reference: string | HTMLElement; + + @Prop(Object) + public refs: string; + + @Prop({ type: String, default: "auto" }) + public placement: Placement; + + @Prop(Boolean) + public arrow: boolean; + + @Prop({ type: Boolean, default: true }) + public responsive: boolean; + + @Prop(String) + public title: string; + + private isMobile: boolean = false; + + /** Inherited class hack */ + private staticClass: string[] = []; + + private zIndex: number = 1000; + + private _focusOutEvent; + private _resizeEvent; + + private _popper; + + get attrs() { + return { + ...this.$attrs, + "class": this.staticClass + } + } + + get currentBehaviour(): DialogBehaviour { + if (!this.mobileBehaviour) { + return this.behaviour; + } + + return this.isMobile ? this.mobileBehaviour : this.behaviour; + } + + get hasFooter() { + return this.$hasSlot('footer') + } + + get hasHeader() { + return this.$hasSlot('header') + } + + private getReferenceElement() { + const isInWrapper = this.$parent.$options.name == 'portalTarget'; + + if (typeof this.reference === 'string') { + if (this.reference[0] === '#') { + return document.getElementById(this.reference.substr(1)); + } + + if (this.refs) { + return this.refs[this.reference]; + } + + if (isInWrapper) { + return this.$parent.$parent.$refs[this.reference]; + } + + return this.$parent.$refs[this.reference]; + } + + if (this.reference instanceof HTMLElement) { + return this.reference; + } + + return isInWrapper ? this.$parent.$el : this.$el.parentElement; + } + + focusOut(event: MouseEvent) { + if (this.$el.contains(event.target as Node)) { + return; + } + + this.$emit('leave', event); + } + + mounted() { + this.zIndex = computeZIndexOfElement(this.getReferenceElement()) + 100; + + this.handleWindowResize(); + + if (this.behaviour === 'popup') { + this.mountPopper(); + } + + this.staticClass = Array.from(this.$el.classList).filter(cls => ["ui-backdrop", "ui-popup", "ui-popup--arrow"].indexOf(cls) === -1); + + window.addEventListener('resize', this._resizeEvent = this.handleWindowResize.bind(this)); + + this._activated(); + } + + private _activated() { + if (this.behaviour === 'modal') { + this.mountModal(); + } + } + + private _deactivated() { + if (this.behaviour === 'modal') { + this.dismountModal(); + } + } + + private mountModal() { + if (openModalCounter === 0) { + document.body.style.paddingRight = `${window.screen.width - document.body.clientWidth}px` + document.body.classList.add('contains-modal'); + } + + openModalCounter++; + } + + private dismountModal() { + openModalCounter--; + + if (openModalCounter === 0) { + document.body.style.paddingRight = ""; + document.body.classList.remove('contains-modal'); + } + } + + activated() { + this._activated(); + } + + deactivated() { + this._deactivated(); + } + + private mountPopper() { + const reference = this.getReferenceElement(); + + this._popper = new Popper(reference, this.$el, { + placement: this.placement, + modifiers: { + arrow: { enabled: this.arrow, element: this.$refs['arrow'] as Element }, + responsive: { + enabled: this.responsive, + order: 890, + fn(data) { + if (window.innerWidth < 560) { + data.instance.options.placement = 'top'; + data.styles.transform = `translate3d(0, ${ data.offsets.popper.top }px, 0)`; + data.styles.right = '0'; + data.styles.left = '0'; + data.styles.width = 'auto'; + data.arrowStyles.left = `${ data.offsets.popper.left + data.offsets.arrow.left }px`; + } + + return data; + } + } + } + }); + + this.$nextTick(() => { + this._popper && this._popper.update(); + document.addEventListener('click', this._focusOutEvent = this.focusOut.bind(this), { capture: true }); + }); + } + + private removePopper() { + this._popper.destroy() + this._popper = null; + } + + updated() { + if (this._popper) { + this._popper.update(); + } + } + + beforeDestroy() { + this._focusOutEvent && document.removeEventListener('click', this._focusOutEvent, { capture: true }); + + this._deactivated() + } + + removed() { + if (this._popper) { + this.removePopper(); + } + } + + private handleBackdropClick(ev: Event) { + const target = ev.target as HTMLElement; + + if (target.classList.contains("ui-backdrop")) { + this.$emit('leave'); + } + } + + private handleCloseClick() { + this.$emit('leave'); + this.$emit('close'); + } + + private handleWindowResize() { + this.isMobile = screen.width < defaultBreakpoints.md; + } + + @Watch('currentBehaviour') + private handleBehaviourChange(newBehaviour: DialogBehaviour, oldBehaviour: DialogBehaviour) { + if (oldBehaviour === 'popup') { + this.removePopper(); + } + + if (newBehaviour === 'popup') { + this.$nextTick(() => this.mountPopper()); + } + + if (newBehaviour === 'modal') { + this.mountModal(); + } + + if (oldBehaviour === 'modal') { + this.dismountModal(); + } + } +} + +Vue.component("ui-dialog", UiDialog); diff --git a/front/src/components/ui/icon.ts b/front/src/components/ui/icon.ts new file mode 100644 index 0000000..3f656f2 --- /dev/null +++ b/front/src/components/ui/icon.ts @@ -0,0 +1,150 @@ +import Vue from 'vue' +import { Component, Prop } from 'vue-property-decorator' +import { IconDefinition, library } from "@fortawesome/fontawesome-svg-core" +import { Dictionary } from "@/utils"; +import { + faBullhorn, + faCheck, + faCheckDouble, + faChevronCircleUp, + faChevronDown, + faChevronUp, + faClock, + faCog, + faExclamationTriangle, + faHistory, + faHourglassHalf, + faInfoCircle, + faMapMarkerAlt, + faMoon, + faQuestionCircle, + faQuestionSquare, + faSearch, + faSign, + faStar, + faSync, + faTimes, + faTrashAlt +} from "@fortawesome/pro-light-svg-icons"; +import { + faClock as faClockBold, + faCodeCommit, + faMinus, + faPlus, + faSpinnerThird +} from "@fortawesome/pro-regular-svg-icons"; +import { faExclamationTriangle as faSolidExclamationTriangle, faWalking } from "@fortawesome/pro-solid-svg-icons"; +import { fac } from "@/icons"; +import { FontAwesomeIcon, FontAwesomeLayers, FontAwesomeLayersText } from "@fortawesome/vue-fontawesome"; + +type IconDescription = { icon: IconDefinition, [prop: string]: any } + +type SimpleIcon = { + type: 'simple', +} & IconDescription; + +type StackedIcon = { + type: 'stacked', + icons: IconDescription[], +} + +export type Icon = SimpleIcon | StackedIcon; + +const simple = (icon: IconDefinition, props: any = {}): SimpleIcon => ({ + icon, ...props, type: "simple" +}); + +const stack = (icons: IconDescription[]): StackedIcon => ({ type: "stacked", icons }); + +const lineTypeIcons = Object + .values(fac) + .map<[string, Icon]>(icon => [`line-${ icon.iconName }`, simple(icon)]) + .reduce((acc, [icon, definition]) => ({ ...acc, [icon]: definition }), {}) + +const messageTypeIcons: Dictionary<Icon> = { + 'message-breakdown': simple(faExclamationTriangle), + 'message-info': simple(faInfoCircle), + 'message-unknown': simple(faQuestionCircle), +}; + +const definitions = { + 'favourite': simple(faStar), + 'unknown': simple(faQuestionSquare), + 'add': simple(faCheck), + 'add-all': simple(faCheckDouble), + 'remove-stop': simple(faTimes), + 'delete': simple(faTrashAlt), + 'messages': simple(faBullhorn), + 'timetable': simple(faClock), + 'settings': simple(faCog), + 'refresh': simple(faSync), + 'chevron-down': simple(faChevronDown), + 'chevron-up': simple(faChevronUp), + 'search': simple(faSearch), + 'info': simple(faInfoCircle), + 'warning': simple(faExclamationTriangle), + 'night': simple(faMoon), + 'fast': simple(faWalking), + 'track': simple(faCodeCommit), + 'info-hide': simple(faChevronCircleUp), + 'map': simple(faMapMarkerAlt), + 'stop': simple(faSign), + 'spinner': simple(faSpinnerThird, { spin: true }), + 'increment': simple(faPlus, { "fixed-width": true }), + 'decrement': simple(faMinus, { "fixed-width": true }), + 'relative-time': simple(faHourglassHalf), + 'departure-warning': stack([ + { icon: faClockBold }, + { icon: faSolidExclamationTriangle, transform: "shrink-5 down-4 right-6" } + ]), + 'close': simple(faTimes), + 'history': simple(faHistory), + ...lineTypeIcons, + ...messageTypeIcons, +}; + +export type PredefinedIcon = keyof typeof definitions; + +const extractAllIcons = (icons: Icon[]) => icons.map(icon => { + switch (icon.type) { + case "simple": + return [icon.icon]; + case "stacked": + return icon.icons.map(stacked => stacked.icon); + } +}).reduce((acc, cur) => [...acc, ...cur]); + +library.add(...extractAllIcons(Object.values(definitions))); + +@Component({ + template: require('@templates/ui/icon.html'), + components: { + fa: FontAwesomeIcon, + faLayers: FontAwesomeLayers, + faText: FontAwesomeLayersText, + } +}) +export class UiIcon extends Vue { + @Prop({ + type: [String, Object], + validator: value => typeof value === "object" || Object.keys(definitions).includes(value), + required: true, + }) + icon: PredefinedIcon | IconDefinition; + + get definition(): Icon { + return typeof this.icon === "string" + ? definitions[this.icon] || definitions['unknown'] + : { icon: this.icon as IconDefinition, type: "simple" }; + } + + get attrs() { + return { ...this.definition, ...this.$attrs }; + } + + get type() { + return this.definition.type; + } +} + +Vue.component('UiIcon', UiIcon); diff --git a/front/src/components/ui/index.ts b/front/src/components/ui/index.ts new file mode 100644 index 0000000..1909ea7 --- /dev/null +++ b/front/src/components/ui/index.ts @@ -0,0 +1,4 @@ +export * from './switch'; +export * from './icon'; +export * from './numeric-input' +export * from './dialog' diff --git a/front/src/components/ui/numeric-input.ts b/front/src/components/ui/numeric-input.ts new file mode 100644 index 0000000..df4a0fe --- /dev/null +++ b/front/src/components/ui/numeric-input.ts @@ -0,0 +1,53 @@ +import Vue from 'vue' +import { Component, Prop } from 'vue-property-decorator' +import * as uuid from "uuid"; + +@Component({ + template: require('@templates/ui/numeric.html'), + inheritAttrs: false +}) +export class UiNumericInput extends Vue { + @Prop({ + type: String, + default: () => `uuid-${uuid.v4()}` + }) + id: string; + + @Prop(Number) + value: number; + + @Prop({ type: Number, default: 1 }) + step: number; + + @Prop({ type: Number, default: -Infinity }) + min: number; + + @Prop({ type: Number, default: Infinity }) + max: number; + + update(ev) { + this.$emit('input', this.clamp(Number.parseInt(ev.target.value))); + } + + increment() { + this.$emit('input', this.clamp(this.value + this.step)); + } + + decrement() { + this.$emit('input', this.clamp(this.value - this.step)); + } + + clamp(value: number) { + return Math.max(Math.min(value, this.max), this.min); + } + + get canIncrement(): boolean { + return this.max - this.value > Number.EPSILON * 2; + } + + get canDecrement(): boolean { + return this.value - this.min > Number.EPSILON * 2; + } +} + +Vue.component('UiNumericInput', UiNumericInput); diff --git a/front/src/components/ui/switch.ts b/front/src/components/ui/switch.ts new file mode 100644 index 0000000..46756a3 --- /dev/null +++ b/front/src/components/ui/switch.ts @@ -0,0 +1,24 @@ +import Vue from 'vue' +import { Component, Prop } from 'vue-property-decorator' +import * as uuid from "uuid"; + +@Component({ + template: require('@templates/ui/switch.html'), + inheritAttrs: false +}) +export class UiSwitch extends Vue { + @Prop({ + type: String, + default: () => `uuid-${uuid.v4()}` + }) + id: string; + + @Prop(Boolean) + value: boolean; + + update(ev) { + this.$emit('input', !this.value); + } +} + +Vue.component('UiSwitch', UiSwitch); diff --git a/front/src/components/utils.ts b/front/src/components/utils.ts new file mode 100644 index 0000000..ad59830 --- /dev/null +++ b/front/src/components/utils.ts @@ -0,0 +1,56 @@ +import Vue from 'vue'; +import { Component, Prop, Watch } from "vue-property-decorator"; + + +@Component({ template: require('@templates/fold.html') }) +export class FoldComponent extends Vue { + private observer: MutationObserver; + + @Prop(Boolean) + public visible: boolean; + + @Prop(Boolean) + public lazy: boolean; + + mounted() { + this.resize(); + + this.observer = new MutationObserver(() => this.resize()); + this.observer.observe(this.$refs['inner'] as Node, { + characterData: true, + subtree: true, + childList: true + }); + } + + beforeDestroy() { + this.observer.disconnect(); + } + + @Watch('visible') + private resize() { + const inner = this.$refs['inner'] as HTMLDivElement; + (this.$el as HTMLElement).style.height = `${(this.visible && inner) ? inner.clientHeight : 0}px`; + } +} + +@Component({ template: require("@templates/lazy.html") }) +export class LazyComponent extends Vue { + @Prop(Boolean) + public activate: boolean; + protected visible: boolean = false; + + @Watch('activate') + private onVisibilityChange(value, old) { + this.visible = value || old; + } +} + +Vue.component('Fold', FoldComponent); +Vue.component('Lazy', LazyComponent); + +// https://github.com/vuejs/vue/issues/7829 +Vue.component('Empty', { + functional: true, + render: (h, { data }) => h('template', data, '') +}); diff --git a/resources/ts/decorators.ts b/front/src/decorators.ts similarity index 100% rename from resources/ts/decorators.ts rename to front/src/decorators.ts diff --git a/resources/ts/filters.ts b/front/src/filters.ts similarity index 94% rename from resources/ts/filters.ts rename to front/src/filters.ts index 3a0e040..b3fd1e4 100644 --- a/resources/ts/filters.ts +++ b/front/src/filters.ts @@ -2,6 +2,14 @@ import { set, signed } from "./utils"; import Vue from 'vue'; import { condition } from "./decorators"; +export const defaultBreakpoints = { + 'xs': 0, + 'sm': 576, + 'md': 768, + 'lg': 1024, + 'xl': 1200, +} + Vue.filter('signed', signed); Vue.directive('hover', { @@ -61,13 +69,7 @@ Vue.directive('autofocus', { Vue.directive('responsive', { inserted(el, binding) { - const breakpoints = typeof binding.value === 'object' ? binding.value : { - 'xs': 0, - 'sm': 576, - 'md': 768, - 'lg': 1024, - 'xl': 1200, - }; + const breakpoints = typeof binding.value === 'object' ? binding.value : defaultBreakpoints; const resize = binding['resize'] = () => { const width = el.scrollWidth; diff --git a/resources/ts/icons.ts b/front/src/icons.ts similarity index 66% rename from resources/ts/icons.ts rename to front/src/icons.ts index 9dd6072..7684894 100644 --- a/resources/ts/icons.ts +++ b/front/src/icons.ts @@ -1,11 +1,11 @@ -import { IconPack, IconDefinition } from '@fortawesome/fontawesome-svg-core'; +import { IconDefinition, IconPack } from '@fortawesome/fontawesome-svg-core'; -import * as bus from "../icons/light/bus.svg"; -import * as tram from "../icons/light/tram.svg"; -import * as trolleybus from "../icons/light/trolleybus.svg"; -import * as metro from "../icons/light/metro.svg"; -import * as train from "../icons/light/train.svg"; -import * as unknown from "../icons/light/unknown.svg"; +import * as bus from "@resources/icons/light/bus.svg"; +import * as tram from "@resources/icons/light/tram.svg"; +import * as trolleybus from "@resources/icons/light/trolleybus.svg"; +import * as metro from "@resources/icons/light/metro.svg"; +import * as train from "@resources/icons/light/train.svg"; +import * as unknown from "@resources/icons/light/unknown.svg"; export const faBus: IconDefinition = <any>{ prefix: 'fac', @@ -45,4 +45,4 @@ export const faUnknown = <any>{ export const fac: IconPack = { faBus, faTram, faTrain, faTrolleybus, faMetro, faUnknown -}; \ No newline at end of file +}; diff --git a/front/src/model/common.ts b/front/src/model/common.ts new file mode 100644 index 0000000..6e7fc15 --- /dev/null +++ b/front/src/model/common.ts @@ -0,0 +1,4 @@ +export interface Location { + lat: number, + lng: number, +} diff --git a/resources/ts/model/departure.ts b/front/src/model/departure.ts similarity index 100% rename from resources/ts/model/departure.ts rename to front/src/model/departure.ts diff --git a/resources/ts/model/error.ts b/front/src/model/error.ts similarity index 100% rename from resources/ts/model/error.ts rename to front/src/model/error.ts diff --git a/resources/ts/model/identity.ts b/front/src/model/identity.ts similarity index 100% rename from resources/ts/model/identity.ts rename to front/src/model/identity.ts diff --git a/resources/ts/model/index.ts b/front/src/model/index.ts similarity index 70% rename from resources/ts/model/index.ts rename to front/src/model/index.ts index e4ca6d0..e9aaa2e 100644 --- a/resources/ts/model/index.ts +++ b/front/src/model/index.ts @@ -3,3 +3,5 @@ export * from './departure' export * from './line' export * from './error' export * from './identity' +export * from './common' +export * from './provider' diff --git a/resources/ts/model/line.ts b/front/src/model/line.ts similarity index 100% rename from resources/ts/model/line.ts rename to front/src/model/line.ts diff --git a/resources/ts/model/message.ts b/front/src/model/message.ts similarity index 100% rename from resources/ts/model/message.ts rename to front/src/model/message.ts diff --git a/front/src/model/provider.ts b/front/src/model/provider.ts new file mode 100644 index 0000000..e147218 --- /dev/null +++ b/front/src/model/provider.ts @@ -0,0 +1,11 @@ +import { Moment } from "moment"; +import { Location } from "./common"; + +export interface Provider { + id: string; + name: string; + shortName: string; + attribution?: string; + lastUpdate?: Moment; + location: Location; +} diff --git a/front/src/model/stop.ts b/front/src/model/stop.ts new file mode 100644 index 0000000..3cf1aff --- /dev/null +++ b/front/src/model/stop.ts @@ -0,0 +1,26 @@ +import { Line } from "./line"; +import { Location } from "./common"; + +export interface Stop { + id: any; + name: string; + description?: string; + location?: Location; + onDemand?: boolean; + variant?: string; +} + +export interface StopWithDestinations extends Stop{ + destinations?: Destination[]; +} + +export type Destination = { + stop: Stop; + lines: Line[] +} + +export type StopGroup = Stop[]; + +export type StopGroups = { + [name: string]: StopGroup; +} diff --git a/resources/ts/model/trip.ts b/front/src/model/trip.ts similarity index 100% rename from resources/ts/model/trip.ts rename to front/src/model/trip.ts diff --git a/resources/ts/store/common.ts b/front/src/store/common.ts similarity index 75% rename from resources/ts/store/common.ts rename to front/src/store/common.ts index 49e12c0..f87a1ac 100644 --- a/resources/ts/store/common.ts +++ b/front/src/store/common.ts @@ -1,8 +1,7 @@ -import { FetchingState } from "../utils"; -import { Moment } from "moment"; -import { Module, MutationTree } from "vuex"; -import { RootState } from "./root"; +import { FetchingState } from "@/utils"; import * as moment from "moment"; +import { Moment } from "moment"; +import { MutationTree } from "vuex"; export interface CommonState { state: FetchingState, @@ -24,4 +23,4 @@ export const mutations: MutationTree<CommonState> = { } }; -export default { state, mutations }; \ No newline at end of file +export default { state, mutations }; diff --git a/resources/ts/store/departures.ts b/front/src/store/departures.ts similarity index 84% rename from resources/ts/store/departures.ts rename to front/src/store/departures.ts index 220ac06..08ab4b4 100644 --- a/resources/ts/store/departures.ts +++ b/front/src/store/departures.ts @@ -1,19 +1,15 @@ import { Module } from "vuex"; import { RootState } from "./root"; -import { Departure, Line, Stop } from "../model"; +import { Departure, Line } from "../model"; import * as moment from 'moment' import common, { CommonState } from './common' import urls from "../urls"; -import { Jsonified } from "../utils"; +import { Jsonified } from "@/utils"; export interface DeparturesState extends CommonState { departures: Departure[], } -export interface ObtainPayload { - stops: Stop[] -} - export const departures: Module<DeparturesState, RootState> = { namespaced: true, state: { @@ -29,10 +25,15 @@ export const departures: Module<DeparturesState, RootState> = { ...common.mutations }, actions: { - async update({ commit }, { stops }: ObtainPayload) { + async update({ commit }) { + const count = this.state['departures-settings'].displayedEntriesCount; + const stops = this.state.stops; + commit('fetching'); + const response = await fetch(urls.prepare(urls.departures, { stop: stops.map(stop => stop.id), + limit: count || 8, })); if (!response.ok) { diff --git a/front/src/store/favourites.ts b/front/src/store/favourites.ts new file mode 100644 index 0000000..c0e9376 --- /dev/null +++ b/front/src/store/favourites.ts @@ -0,0 +1,37 @@ +import { RootState } from "./root"; +import { Module } from "vuex"; +import { Stop } from "@/model"; +import { except } from "@/utils"; + +export interface Favourite { + id: string; + name: string; + stops: Stop[]; +} + +export interface FavouritesState { + favourites: Favourite[]; +} + +const favourites: Module<FavouritesState, RootState> = { + namespaced: true, + state: { + favourites: [] + }, + mutations: { + add(state, favourite: Favourite) { + const existing = state.favourites.find((current: Favourite) => current.name === favourite.name); + + if (!existing) { + state.favourites.push(favourite); + } + + Object.assign(existing, except(favourite, ["id"])); + }, + remove(state, favourite: Favourite) { + state.favourites = state.favourites.filter(f => f != favourite); + } + } +}; + +export default favourites; diff --git a/front/src/store/history.ts b/front/src/store/history.ts new file mode 100644 index 0000000..b6e781c --- /dev/null +++ b/front/src/store/history.ts @@ -0,0 +1,66 @@ +import { Stop } from "@/model"; +import { Module } from "vuex"; +import { RootState } from "./root"; +import * as moment from "moment"; +import { Moment } from "moment"; +import { Jsonified } from "@/utils"; + +export interface HistoryEntry { + stop: Stop, + date: Moment, +} + +export interface HistorySettings { + maxEntries: number, +} + +export interface HistoryState { + entries: Jsonified<HistoryEntry>[], + settings: HistorySettings, +} + +export function serializeHistoryEntry(entry: HistoryEntry): Jsonified<HistoryEntry> { + return { + ...entry, + date: entry.date.toISOString(), + } +} + +export function deserializeHistoryEntry(serialized: Jsonified<HistoryEntry>): HistoryEntry { + return { + ...serialized, + date: moment(serialized.date), + } +} + +export const history: Module<HistoryState, RootState> = { + namespaced: true, + state: { + entries: [], + settings: { + maxEntries: 10, + } + }, + mutations: { + clear(state: HistoryState) { + state.entries = []; + }, + push(state: HistoryState, entry: HistoryEntry) { + state.entries = state.entries.filter(cur => cur.stop.id != entry.stop.id); + state.entries.unshift(serializeHistoryEntry(entry)); + + if (state.entries.length > state.settings.maxEntries) { + state.entries = state.entries.slice(0, state.settings.maxEntries); + } + }, + saveSettings(state: HistoryState, settings: Partial<HistorySettings>) { + Object.assign(state.settings, settings); + } + }, + getters: { + all: ({ entries, settings }) => entries.slice(0, settings.maxEntries).map(deserializeHistoryEntry), + latest: ({ entries }) => n => entries.slice(0, n).map(deserializeHistoryEntry), + } +} + +export default history; diff --git a/front/src/store/index.ts b/front/src/store/index.ts new file mode 100644 index 0000000..326c361 --- /dev/null +++ b/front/src/store/index.ts @@ -0,0 +1,55 @@ +import Vuex from 'vuex'; + +import messages, { MessagesState } from './messages'; +import departures, { DeparturesState } from './departures' +import favourites, { FavouritesState } from './favourites' +import history, { HistoryState } from "./history"; +import departureSettings, { DeparturesSettingsState } from "./settings/departures"; +import messagesSettings, { MessagesSettingsState } from "./settings/messages"; + +import { actions, mutations, RootState, state } from "./root"; +import VuexPersistence from "vuex-persist"; +import { namespace } from "vuex-class"; + +export type State = { + messages: MessagesState; + departures: DeparturesState; + favourites: FavouritesState; + "departures-settings": DeparturesSettingsState; + "messages-settings": MessagesSettingsState; + history: HistoryState; +} & RootState; + +const localStoragePersist = new VuexPersistence<State>({ + modules: ['favourites', 'departures-settings', 'messages-settings', 'history'], +}); + +const sessionStoragePersist = new VuexPersistence<State>({ + reducer: state => ({ stops: state.stops }), + storage: window.sessionStorage +}); + +const store = new Vuex.Store<RootState>({ + state, mutations, actions, + modules: { + messages, + departures, + favourites, + 'departures-settings': departureSettings, + 'messages-settings': messagesSettings, + history, + }, + plugins: [ + localStoragePersist.plugin, + sessionStoragePersist.plugin, + ] +}); + +export default store; + +export const Favourites = namespace('favourites'); +export const DeparturesSettings = namespace('departures-settings'); +export const MessagesSettings = namespace('messages-settings'); +export const Departures = namespace('departures'); +export const Messages = namespace('messages'); +export const History = namespace('history'); diff --git a/resources/ts/store/messages.ts b/front/src/store/messages.ts similarity index 94% rename from resources/ts/store/messages.ts rename to front/src/store/messages.ts index d24dae2..06ad16e 100644 --- a/resources/ts/store/messages.ts +++ b/front/src/store/messages.ts @@ -1,9 +1,9 @@ import { ActionContext, Module } from "vuex"; import { RootState } from "./root"; -import { Message, MessageType } from "../model/message"; +import { Message, MessageType } from "@/model/message"; import common, { CommonState } from "./common"; import urls from "../urls"; -import { Jsonified } from "../utils"; +import { Jsonified } from "@/utils"; import * as moment from 'moment'; export interface MessagesState extends CommonState { diff --git a/resources/ts/store/migrations.ts b/front/src/store/migrations.ts similarity index 98% rename from resources/ts/store/migrations.ts rename to front/src/store/migrations.ts index 87f3946..76f54d1 100644 --- a/resources/ts/store/migrations.ts +++ b/front/src/store/migrations.ts @@ -1,4 +1,4 @@ -import { distinct } from "../utils"; +import { distinct } from "@/utils"; import urls from "../urls"; import * as uuid from "uuid"; diff --git a/resources/ts/store/root.ts b/front/src/store/root.ts similarity index 67% rename from resources/ts/store/root.ts rename to front/src/store/root.ts index 2a108ad..c0ced46 100644 --- a/resources/ts/store/root.ts +++ b/front/src/store/root.ts @@ -1,10 +1,11 @@ -import { Stop } from "../model"; +import { Stop } from "@/model"; import { ActionTree, MutationTree } from "vuex"; import urls from "../urls"; -import { ensureArray } from "../utils"; +import { ensureArray } from "@/utils"; export interface RootState { stops: Stop[], + provider: any, } export interface SavedState { @@ -12,8 +13,13 @@ export interface SavedState { stops: string[], } +export interface LoadProviderActionPayload { + provider: string; +} + export const state: RootState = { - stops: [] + stops: [], + provider: null, }; export const mutations: MutationTree<RootState> = { @@ -21,9 +27,17 @@ export const mutations: MutationTree<RootState> = { replace: (state, stops) => state.stops = stops, remove: (state, stop) => state.stops = state.stops.filter(s => s != stop), clear: (state) => state.stops = [], + setProvider: (state, provider) => state.provider = provider, }; export const actions: ActionTree<RootState, undefined> = { + async loadProvider({ commit }, { provider }) { + const response = await fetch(urls.prepare(urls.providers.get, { provider })); + + if (response.ok) { + commit('setProvider', await response.json()); + } + }, async load({ commit }, { stops }: SavedState) { if (stops.length > 0) { const response = await fetch(urls.prepare(urls.stops.all, { id: stops })); @@ -37,4 +51,4 @@ export const actions: ActionTree<RootState, undefined> = { version: 1, stops: state.stops.map(stop => stop.id) }) -}; \ No newline at end of file +}; diff --git a/front/src/store/settings/departures.ts b/front/src/store/settings/departures.ts new file mode 100644 index 0000000..2186ec3 --- /dev/null +++ b/front/src/store/settings/departures.ts @@ -0,0 +1,26 @@ +import { ActionContext, Module } from "vuex"; +import { RootState } from "../root"; + +export type DeparturesSettingsState = { + autorefresh: boolean; + autorefreshInterval?: number; + displayedEntriesCount?: number; + relativeTimes: boolean, +} + +const departureSettings: Module<DeparturesSettingsState, RootState> = { + namespaced: true, + state: { + autorefresh: true, + relativeTimes: false, + autorefreshInterval: 10, + displayedEntriesCount: 10 + }, + mutations: { + update(state: DeparturesSettingsState, patch: Partial<DeparturesSettingsState>) { + Object.assign(state, patch); + } + } +}; + +export default departureSettings; diff --git a/front/src/store/settings/messages.ts b/front/src/store/settings/messages.ts new file mode 100644 index 0000000..116a499 --- /dev/null +++ b/front/src/store/settings/messages.ts @@ -0,0 +1,24 @@ +import { Module } from "vuex"; +import { RootState } from "../root"; + +export type MessagesSettingsState = { + autorefresh: boolean; + autorefreshInterval?: number; + displayedEntriesCount?: number; +} + +const messagesSettings: Module<MessagesSettingsState, RootState> = { + namespaced: true, + state: { + autorefresh: true, + autorefreshInterval: 60, + displayedEntriesCount: 2 + }, + mutations: { + update(state: MessagesSettingsState, patch: Partial<MessagesSettingsState>) { + Object.assign(state, patch); + } + } +}; + +export default messagesSettings; diff --git a/resources/ts/types/webpack.d.ts b/front/src/types/webpack.d.ts similarity index 100% rename from resources/ts/types/webpack.d.ts rename to front/src/types/webpack.d.ts diff --git a/resources/ts/urls.ts b/front/src/urls.ts similarity index 78% rename from resources/ts/urls.ts rename to front/src/urls.ts index e3bb5d1..9b659cf 100644 --- a/resources/ts/urls.ts +++ b/front/src/urls.ts @@ -1,3 +1,5 @@ +import store from "./store"; + export type UrlParams = { [name: string]: any } @@ -8,7 +10,11 @@ export function query(params: UrlParams = { }) { function *simplify(name: string, param: any): IterableIterator<ParamValuePair> { if (typeof param === 'string') { yield [ name, param ]; - } else if (typeof param === 'number') { + } else if (typeof param === 'boolean') { + if (param) { + yield [ name, '1' ]; + } + } else if (typeof param === 'number') { yield [ name, param.toString() ]; } else if (param instanceof Array) { for (let entry of param) { @@ -45,7 +51,7 @@ export function prepare(url: string, params: UrlParams = { }) { return Object.keys(params).length > 0 ? `${url}?${query(params)}` : url; } -const base = '/{provider}/api/v1'; +const base = '/api/v1/{provider}'; export default { departures: `${base}/departures`, @@ -56,6 +62,13 @@ export default { get: `${base}/stops/{id}`, tracks: `${base}/stops/{id}/tracks` }, + providers: { + get: `/api/v1/providers/{provider}`, + }, trip: `${base}/trips/{id}`, - prepare: (url: string, params: UrlParams = { }) => prepare(url, Object.assign({}, { provider: window['data'].provider }, params)) + manifest: { + main: '/manifest.json', + provider: '/{provider}/manifest.json', + }, + prepare: (url: string, params: UrlParams = { }) => prepare(url, Object.assign({}, { provider: store.state.provider?.id }, params)) } diff --git a/resources/ts/utils.ts b/front/src/utils.ts similarity index 63% rename from resources/ts/utils.ts rename to front/src/utils.ts index 2601a47..213ee92 100644 --- a/resources/ts/utils.ts +++ b/front/src/utils.ts @@ -38,6 +38,14 @@ export function filter<T, KT extends keyof T>(source: T, filter: (value: T[KT], return result; } +export function except<T>(source: T, keys: (keyof T)[]) { + return filter(source, (_, key) => !keys.includes(key)) +} + +export function only<T>(source: T, keys: (keyof T)[]) { + return filter(source, (_, key) => keys.includes(key)) +} + export function signed(number: number): string { return number > 0 ? `+${number}` : number.toString(); } @@ -75,3 +83,42 @@ export function time<T>(action: () => T, name?: string) { return result; } + +export const identity = a => a; + +export function unique<T, U>(array: T[], criterion: (item: T) => U = identity) { + const result: T[] = []; + const known = new Set<U>(); + + const entries = array.map(item => [ criterion(item), item ]) as [ U, T ][]; + + for (const [ key, item ] of entries) { + if (known.has(key)) { + continue; + } + + known.add(key); + result.push(item); + } + + return result; +} + +type Pattern<TResult, TArgs extends any[]> = [ + (...args: TArgs) => boolean, + ((...args: TArgs) => TResult) | TResult, +] + +export function match<TResult, TArgs extends any[]>(...patterns: Pattern<TResult, TArgs>[]): (...args: TArgs) => TResult { + return (...args: TArgs) => { + for (let [pattern, action] of patterns) { + if (pattern(...args)) { + return typeof action === "function" ? (action as (...args: TArgs) => TResult)(...args) : action; + } + } + + throw new Error(`No pattern matches args: ${JSON.stringify(args)}`); + } +} + +match.default = (...args: any[]) => true; diff --git a/resources/styles/_animations.scss b/front/styles/_animations.scss similarity index 100% rename from resources/styles/_animations.scss rename to front/styles/_animations.scss diff --git a/resources/styles/_common.scss b/front/styles/_common.scss similarity index 92% rename from resources/styles/_common.scss rename to front/styles/_common.scss index e58e558..ee625d9 100644 --- a/resources/styles/_common.scss +++ b/front/styles/_common.scss @@ -38,7 +38,6 @@ transition: height 250ms ease; will-change: height; - box-sizing: padding-box; } .flex { @@ -61,7 +60,14 @@ } } +$section-safe-margin: 0.5rem; + .section { + padding: $section-safe-margin; + margin: -$section-safe-margin; + + background: rgba(white, 0.85); + margin-bottom: 1rem; .section__title { @@ -94,10 +100,6 @@ } } -svg.svg-inline--fa { - //transform: rotate(360deg) -} - .btn-unstyled { padding: 0; margin: 0; diff --git a/front/styles/_controls.scss b/front/styles/_controls.scss new file mode 100644 index 0000000..e8879c4 --- /dev/null +++ b/front/styles/_controls.scss @@ -0,0 +1,47 @@ +.btn { + &.btn-action { + @extend .btn-link; + + color: black; + + &:hover, &:active, &:focus { + text-decoration: none; + } + + &:focus { + outline: 2px solid rgba($blue, .2); + } + } + + &.btn-xs { + font-size: 0.75rem; + font-weight: bold; + padding: 0.25rem 0.5rem; + } + + border-radius: 1.5px; + + display: inline-block; + + &.btn-outline-action { + @extend .btn-outline-dark; + } + + &.btn-primary { + background: $primary-gradient; + border-color: transparent; + + &:hover { + border: 1px $primary solid; + } + } + + &.btn-danger { + background: $danger-gradient; + border-color: transparent; + + &:hover { + border: 1px $danger solid; + } + } +} diff --git a/resources/styles/_departure.scss b/front/styles/_departure.scss similarity index 100% rename from resources/styles/_departure.scss rename to front/styles/_departure.scss diff --git a/resources/styles/_dragscroll.scss b/front/styles/_dragscroll.scss similarity index 100% rename from resources/styles/_dragscroll.scss rename to front/styles/_dragscroll.scss diff --git a/resources/styles/_favourites.scss b/front/styles/_favourites.scss similarity index 100% rename from resources/styles/_favourites.scss rename to front/styles/_favourites.scss diff --git a/front/styles/_form.scss b/front/styles/_form.scss new file mode 100644 index 0000000..14da9d3 --- /dev/null +++ b/front/styles/_form.scss @@ -0,0 +1,48 @@ +label { + font-weight: bold; + margin-bottom: 0; + margin-top: -0.2rem; + display: block; + font-size: .8rem; +} + +.label-sm { + font-size: .6rem; +} + +.form-group:last-child { + margin-bottom: 0; +} + +.form-control, .input-group-text, .btn-addon { + background: rgba($dark, .06); + border: none; + border-bottom: 2px solid $dark; + + &:focus { + background: rgba($dark, .06); + } +} + +.form-control--framed { + background: transparent; + border: 1px solid $text-muted; + + &:focus { + background-color: transparent; + } +} + +.input-group-append, +.input-group-append .btn + .btn { + margin-left: 0; +} + +.btn-addon:disabled { + opacity: 1; + color: rgba($dark, .5) +} + +.input-group-prepend { + margin-right: 0; +} diff --git a/resources/styles/_line.scss b/front/styles/_line.scss similarity index 100% rename from resources/styles/_line.scss rename to front/styles/_line.scss diff --git a/front/styles/_map.scss b/front/styles/_map.scss new file mode 100644 index 0000000..89f34fc --- /dev/null +++ b/front/styles/_map.scss @@ -0,0 +1,29 @@ +.map__label-box { + @extend .ui-popup; + + padding: .5rem; + background: white; + transform-origin: 50% 50%; + transform: translateX(-50%); + min-width: max-content; + + font-size: 9pt; + + font-weight: bold; + align-items: center; + + @include active { + transform: translateX(-50%) scale(1.1); + } + + @include flex-with-spacing(.5rem); +} + +.map__icon { + font-size: 1.5rem; +} + +img.map__icon { + width: 24px; + height: 24px; +} diff --git a/resources/styles/_stop.scss b/front/styles/_stop.scss similarity index 82% rename from resources/styles/_stop.scss rename to front/styles/_stop.scss index 3ac0d0c..b695a2c 100644 --- a/resources/styles/_stop.scss +++ b/front/styles/_stop.scss @@ -53,6 +53,16 @@ .stop__destination { @extend .favourite__stop; + align-items: center; +} + +.destination__line { + @extend .line__symbol; +} + +.destination__lines li { + display: inline-block; + @include spacing; } .finder__stop { @@ -66,8 +76,12 @@ .stop-group__header { @extend .section__title; display: flex; - padding: 0 !important; margin-bottom: 0 !important; + + .actions { + margin: -.5rem -.75rem; + margin-left: auto; + } } .stop-group__name { diff --git a/resources/styles/_trigonometry.scss b/front/styles/_trigonometry.scss similarity index 100% rename from resources/styles/_trigonometry.scss rename to front/styles/_trigonometry.scss diff --git a/resources/styles/_trip.scss b/front/styles/_trip.scss similarity index 97% rename from resources/styles/_trip.scss rename to front/styles/_trip.scss index 1f3020a..c0fc03a 100644 --- a/resources/styles/_trip.scss +++ b/front/styles/_trip.scss @@ -60,11 +60,10 @@ $trip-visited: rgba($dark, .3); display: block; height: $trip-line-width; background: $dark; - width: 50%; + width: calc(50% - #{$trip-stop-marker-size / 2}); position: absolute; top: $trip-stop-marker-spacing + ($trip-stop-marker-size) / 2; transform: translateY(-50%); - z-index: -1; } &::after { diff --git a/resources/styles/api.scss b/front/styles/api.scss similarity index 100% rename from resources/styles/api.scss rename to front/styles/api.scss diff --git a/resources/styles/main.scss b/front/styles/main.scss similarity index 68% rename from resources/styles/main.scss rename to front/styles/main.scss index 9038407..ada8ede 100644 --- a/resources/styles/main.scss +++ b/front/styles/main.scss @@ -1,11 +1,15 @@ -$border-radius: 0; +$border-radius: 0; $border-radius-lg: $border-radius; $border-radius-sm: $border-radius; +$danger: #cd2e12; + @import "~bootstrap/scss/functions"; @import "~bootstrap/scss/variables"; $primary: #005ea8; +$primary-gradient: linear-gradient(120deg, #0083c5 10%, #005ea8 90%); +$danger-gradient: linear-gradient(120deg, $danger 10%, darken($danger, 10%) 90%); $custom-control-indicator-checked-bg: $dark; $custom-control-indicator-active-bg: $dark; @@ -43,6 +47,13 @@ $grid-gutter-width: $spacer * 2; } } +@mixin spacing($spacing: .25em) { + margin-left: $spacing; + &:first-child { + margin-left: 0; + } +} + @mixin no-scrollbars { scrollbar-width: none; /* Firefox */ -ms-overflow-style: none; /* Internet Explorer 10+ */ @@ -53,22 +64,64 @@ $grid-gutter-width: $spacer * 2; } } +@mixin active { + &:hover, &:active, &:focus, #{&}--active { + @content + } +} + +@mixin flex-with-spacing($spacing) { + display: flex; + + & > *:not(:last-child) { + margin-right: $spacing; + } +} + +@mixin position($position, $top: inherit, $right: inherit, $bottom: inherit, $left: inherit) { + $right: if($right == inherit, $top, $right); + $bottom: if($bottom == inherit, $top, $bottom); + $left: if($left == inherit, $right, $left); + + position: $position; + + top: $top; + right: $right; + left: $left; + bottom: $bottom; +} + @import "common"; @import "stop"; @import "departure"; @import "line"; @import "controls"; -@import "popper"; @import "animations"; @import "form"; @import "favourites"; @import "trip"; @import "dragscroll"; +@import "map"; + +@import "ui/switch"; +@import "ui/popup"; +@import "ui/modal"; + +@import "page/provider-picker"; + +html, body { + overscroll-behavior-y: contain; +} body { min-height: 100vh; display: flex; flex-direction: column; + background: url("../images/background.png") repeat-x center bottom 63px; + + &.contains-modal { + overflow-y: hidden; + } main { flex: 1 1 auto; @@ -108,6 +161,7 @@ body { font-size: small; color: $text-muted; text-align: right; + margin-top: 0.5rem; } footer { @@ -143,6 +197,7 @@ body { @include media-breakpoint-up('md') { #app { padding-top: 4rem; + padding-top: 2rem; } body footer > * { diff --git a/front/styles/page/_provider-picker.scss b/front/styles/page/_provider-picker.scss new file mode 100644 index 0000000..939910d --- /dev/null +++ b/front/styles/page/_provider-picker.scss @@ -0,0 +1,62 @@ +.provider__name { + font-size: .9em; + color: $gray-800; +} + +.provider__short-name { + font-weight: bold; +} + +.provider-picker { + @extend .ui-popup; + padding: 1rem; + margin: 3rem; +} + +.provider-picker__heading { + font-size: 1.2rem; + font-weight: bold; + margin-bottom: 1rem; +} + +.provider-picker__providers { + list-style: none; + padding: 0; + margin: 0; +} + +.provider-picker__provider { + font-size: 1rem; + + .provider { + margin: 0 -1rem; + padding: .5rem 1rem; + + &:hover { + background: $gray-100; + } + } +} + +.provider { + @include flex-with-spacing(.5rem); + align-items: center; + + &:hover { + text-decoration: none; + } +} + +@include media-breakpoint-down('sm') { + .provider-picker { + position: absolute; + bottom: 0; + left: 0; + right: 0; + margin: 1.5rem; + } + + .provider-picker__providers { + max-height: 170px; + } +} diff --git a/front/styles/ui/_modal.scss b/front/styles/ui/_modal.scss new file mode 100644 index 0000000..242138c --- /dev/null +++ b/front/styles/ui/_modal.scss @@ -0,0 +1,79 @@ +.ui-backdrop { + @include position(fixed, 0); + background: rgba(black, .75); + padding: $spacer; + display: flex; + flex-direction: column; + align-items: center; + overflow-y: auto; + overscroll-behavior-y: contain; + z-index: 10000; + + &::after { + height: $spacer; + display: block; + content: ""; + width: 1px; + flex: 0 0 auto; + } +} + +$dialog-margin: 2rem; +$dialog-sizes: ( + medium: 480px, + small: 320px, + large: 640px, +) +; + +.ui-modal { + padding: $dialog-margin; + background: white; + margin: auto; + box-shadow: rgba(black, .7) 0 1px 3px; + border-radius: 1px; + box-sizing: content-box; + + &.ui-modal--slim { + padding: $dialog-margin / 2; + } + + @each $size, $width in $dialog-sizes { + &.ui-modal--#{$size} { + width: $width; + } + } +} + +.ui-modal__close { + margin-right: -$dialog-margin; + padding: $dialog-margin $dialog-margin 0; + margin-top: -$dialog-margin; +} + +.ui-modal__header { + flex: 1 1 auto; +} + +.ui-modal__title { + font-weight: bold; + font-size: 0.875rem; +} + +.ui-modal__top-bar { + display: flex; + margin-bottom: $dialog-margin * 0.75; +} + +@include media-breakpoint-down('sm') { + .ui-dialog { + padding: $dialog-margin / 2; + } + + @each $size, $width in $dialog-sizes { + .ui-modal.ui-modal--#{$size} { + width: 100%; + box-sizing: border-box; + } + } +} diff --git a/resources/styles/_popper.scss b/front/styles/ui/_popup.scss similarity index 90% rename from resources/styles/_popper.scss rename to front/styles/ui/_popup.scss index 07d5247..90a42d6 100644 --- a/resources/styles/_popper.scss +++ b/front/styles/ui/_popup.scss @@ -54,7 +54,7 @@ @mixin triangle-left($size, $color, $border: none) { @include triangle(left, $size, $color, $border); } @mixin triangle-right($size, $color, $border: none) { @include triangle(right, $size, $color, $border); } -.popper { +.ui-popup { $arrow-base: 8px; $arrow-color: white; $arrow-border: rgba(black, 0.2); @@ -74,20 +74,28 @@ border-radius: 2px; - .popper__arrow { + .ui-popup__arrow { position: absolute; width: 0; height: 0; } - &.popper--no-padding { + &.ui-popup--no-padding { padding: 0; } - .popper__heading { + *.ui-popup__header { + margin-bottom: 0.5rem; + } + + .ui-popup__heading { font-size: $font-size-sm; font-weight: bold; margin-bottom: .5rem; + + &:last-child { + margin-bottom: 0; + } } @mixin placement($placement) { @@ -101,7 +109,7 @@ &[x-placement*="#{$placement}"] { margin-#{map-get($opposite, $placement)}: $arrow-base; - .popper__arrow { + .ui-popup__arrow { #{map-get($opposite, $placement)}: 0; @include triangle(map-get($opposite, $placement), $arrow-base, $arrow-color, $arrow-border); } @@ -115,11 +123,11 @@ @include placement("bottom"); } - &.popper--arrow { + &.ui-popup--arrow { @include arrows; } - &.popper--tooltip { + &.ui-popup--tooltip { background: $dark; color: white; padding: .5rem .75rem; @@ -128,14 +136,14 @@ min-width: 0; box-shadow: none; - &.popper--arrow { + &.ui-popup--arrow { $arrow-color: $dark; $arrow-border: none; $arrow-base: 6px; @include arrows; - .popper__arrow::before { + .ui-popup__arrow::before { border: none; } } @@ -143,7 +151,7 @@ } @include media-breakpoint-down('sm') { - .popper { + .ui-popup { margin-left: $spacer; margin-right: $spacer; } diff --git a/front/styles/ui/_switch.scss b/front/styles/ui/_switch.scss new file mode 100644 index 0000000..7392263 --- /dev/null +++ b/front/styles/ui/_switch.scss @@ -0,0 +1,48 @@ +$ui-switch-marker-size: .7rem; +$ui-switch-spacing: 1px; +$ui-switch-duration: 150ms; +$ui-switch-width-factor: 2.25; + +.ui-switch { + padding: 3px; +} + +.ui-switch__checkbox { + display: none; +} + +.ui-switch__track { + border: 1px solid $dark; + border-radius: $ui-switch-marker-size; + padding: $ui-switch-spacing; + width: $ui-switch-width-factor * $ui-switch-marker-size; + height: $ui-switch-marker-size; + position: relative; + box-sizing: content-box; + background: white; + transition: background-color $ui-switch-duration ease-in-out; + cursor: pointer; +} + +.ui-switch__thumb { + border-radius: 100%; + width: $ui-switch-marker-size; + height: $ui-switch-marker-size; + background: $dark; + position: absolute; + transition: all $ui-switch-duration ease-in-out; + transition-property: background-color, left; + margin-left: $ui-switch-spacing; + left: 0; +} + +.ui-switch--checked { + .ui-switch__thumb { + background: white; + left: ($ui-switch-width-factor - 1) * $ui-switch-marker-size; + } + + .ui-switch__track { + background: $dark; + } +} diff --git a/front/templates/app.html b/front/templates/app.html new file mode 100644 index 0000000..4809ece --- /dev/null +++ b/front/templates/app.html @@ -0,0 +1,5 @@ +<main class="d-flex"> + <router-view /> + + <portal-target name="popups" multiple /> +</main> diff --git a/front/templates/departures.html b/front/templates/departures.html new file mode 100644 index 0000000..20a1c04 --- /dev/null +++ b/front/templates/departures.html @@ -0,0 +1,5 @@ +<div class="departures" v-responsive> + <ul class="departures__list list-underlined"> + <departure :departure="departure" :key="departure.key" v-for="departure in departures"/> + </ul> +</div> diff --git a/resources/components/departures/departure.html b/front/templates/departures/departure.html similarity index 51% rename from resources/components/departures/departure.html rename to front/templates/departures/departure.html index cef5126..5b3aae2 100644 --- a/resources/components/departures/departure.html +++ b/front/templates/departures/departure.html @@ -6,31 +6,35 @@ </div> <div class="departure__time"> - <fa-layers v-if="!departure.estimated" class="mr-1"> + <template v-if="!departure.estimated"> <tooltip placement="top-end">Czas rozkładowy, nieuwzględniający aktualnej sytuacji komunikacyjnej.</tooltip> - <fa :icon="['far', 'clock']"/> - <fa :icon="['fas', 'exclamation-triangle']" transform="shrink-5 down-4 right-6"/> - </fa-layers> + <ui-icon icon="departure-warning" class="mr-1"/> + </template> - <span :class="[ 'departure__time', 'departure__time--delayed']" v-if="timeDiffers"> - {{ departure.scheduled.format('HH:mm') }} - </span> - <span class="badge" :class="[departure.delay < 0 ? 'badge-danger' : 'badge-warning']" - v-if="departure.delay < 0 || departure.delay > 30"> + <template v-if="!relativeTimes"> + <span :class="[ 'departure__time', 'departure__time--delayed']" v-if="timeDiffers"> + {{ departure.scheduled|moment('HH:mm') }} + </span> + <span class="badge" :class="[departure.delay < 0 ? 'badge-danger' : 'badge-warning']" + v-if="departure.delay < 0 || departure.delay > 30"> {{ departure.delay|signed }}s - </span> + </span> - <span class="departure__time">{{ time.format('HH:mm') }}</span> + <span class="departure__time">{{ time|moment('HH:mm') }}</span> + </template> + <template v-else> + {{ timeLeft|duration('humanize', true) }} + </template> </div> <div class="departure__stop"> - <fa :icon="['fal', 'sign']" fixed-width class="mr-1 flex-shrink-0"/> + <ui-icon icon="stop" fixed-width class="mr-1 flex-shrink-0"/> <stop :stop="departure.stop"/> <div class="stop__actions flex-space-left"> <button class="btn btn-action" @click="showTrip = !showTrip"> <tooltip>pokaż/ukryj trasę</tooltip> - <fa :icon="['far', 'code-commit']" /> + <ui-icon icon="track" /> </button> </div> </div> @@ -38,7 +42,7 @@ <fold :visible="showTrip"> <trip :schedule="trip.schedule" :current="departure.stop" v-if="trip" :class="[ `trip--${departure.line.type}` ]"/> <div v-else class="text-center"> - <fa icon="spinner-third" pulse></fa> + <ui-icon icon="spinner"/> </div> </fold> </li> diff --git a/resources/components/favourites.html b/front/templates/favourites.html similarity index 85% rename from resources/components/favourites.html rename to front/templates/favourites.html index 0e49f25..2e4ce30 100644 --- a/resources/components/favourites.html +++ b/front/templates/favourites.html @@ -3,7 +3,7 @@ <li v-for="favourite in favourites" class="favourite"> <button @click="choose(favourite)" class="favourite__entry"> <div class="icon"> - <fa :icon="['fal', 'star']"/> + <ui-icon icon="favourite"/> </div> <div class="overflow-hidden"> <span class="text flex-grow-1">{{ favourite.name }}</span> @@ -14,12 +14,12 @@ </button> <button class="btn btn-action" @click="remove(favourite)"> <tooltip placement="left">usuń</tooltip> - <fa :icon="['fal', 'trash-alt']"></fa> + <ui-icon icon="delete"/> </button> </li> </ul> <div class="alert alert-info" v-else> - <fa :icon="['fal', 'info-circle']"></fa> + <ui-icon icon="info"/> Brak zapisanych zespołów przystanków </div> </div> diff --git a/resources/components/favourites/save.html b/front/templates/favourites/save.html similarity index 55% rename from resources/components/favourites/save.html rename to front/templates/favourites/save.html index f65d937..0347554 100644 --- a/resources/components/favourites/save.html +++ b/front/templates/favourites/save.html @@ -1,13 +1,10 @@ -<form class="favourite-add-form" @submit="save"> +<form class="favourite-add-form" @submit.prevent="save"> <div class="form-group"> <label for="favourite_add_name">Nazwa</label> <div class="input-group"> <input class="form-control form-control-sm" placeholder="np. Z pracy" :class="{ 'is-invalid': errors.name.length > 0 }" id="favourite_add_name" v-model="name" v-autofocus/> - <button class="btn btn-sm btn-dark" type="submit"> - <fa :icon="['fal', 'check']"></fa> - </button> <div v-if="errors.name.length > 0" class="invalid-feedback"> <p v-for="error in errors.name">{{ error }}</p> </div> @@ -18,4 +15,20 @@ <stop :stop="stop"/> </li> </ul> + <div class="favourite-add-form__actions"> + <template v-if="confirmation"> + <button class="btn btn-xs btn-danger" type="submit"> + nadpisz + </button> + <button class="btn btn-xs btn-action" @click="$emit('close')"> + anuluj + </button> + </template> + <template v-else> + <button class="btn btn-xs btn-primary" type="submit"> + <ui-icon icon="add" /> + zapisz + </button> + </template> + </div> </form> diff --git a/resources/components/finder.html b/front/templates/finder.html similarity index 77% rename from resources/components/finder.html rename to front/templates/finder.html index ac9798c..8e309a2 100644 --- a/resources/components/finder.html +++ b/front/templates/finder.html @@ -1,12 +1,13 @@ <div class="finder"> - <input class="form-control" :value="filter" @input="filter = $event.target.value" placeholder="Zacznij pisać nazwę aby szukać..."/> + <input class="form-control form-control--framed" :value="filter" @input="filter = $event.target.value" placeholder="Zacznij pisać nazwę aby szukać..."/> <div v-if="filter.length < 3" class="mt-2"> <favourites /> + <stop-history /> </div> <div v-if="state === 'fetching'" class="text-center p-4"> - <fa icon="spinner-third" pulse/> + <ui-icon icon="spinner"/> </div> <div class="finder__stops" v-else-if="filter.length > 2 && Object.keys(filtered).length > 0"> <div class="stop-group" v-for="(group, name) in filtered"> @@ -16,17 +17,17 @@ <div class="actions flex-space-left"> <button class="btn btn-action" @click="select(group)"> <tooltip>wybierz wszystkie</tooltip> - <fa :icon="['fal', 'check-double']"></fa> + <ui-icon icon="add-all"/> </button> </div> </div> <ul class="stop-group__stops list-underlined"> <li v-for="stop in group" :key="stop.id" class="d-flex"> - <picker-stop :stop="stop" class="flex-grow-1"> + <picker-stop :stop="stop" class="flex-grow-1 finder__stop"> <template v-slot:primary-action> - <button @click="select(stop, $event)" class="btn btn-action"> + <button @click="select(stop, $event)" class="btn btn-action stretched-link"> <tooltip>dodaj przystanek</tooltip> - <fa :icon="['fal', 'check']" /> + <ui-icon icon="add" /> </button> </template> </picker-stop> @@ -35,7 +36,7 @@ </div> </div> <div class="alert alert-warning" v-else-if="filter.length > 2"> - <fa :icon="['far', 'exclamation-triangle']"></fa> + <ui-icon icon="warning"/> Nie znaleziono więcej przystanków, spełniających te kryteria. </div> </div> diff --git a/resources/components/fold.html b/front/templates/fold.html similarity index 100% rename from resources/components/fold.html rename to front/templates/fold.html diff --git a/resources/components/lazy.html b/front/templates/lazy.html similarity index 100% rename from resources/components/lazy.html rename to front/templates/lazy.html diff --git a/front/templates/line.html b/front/templates/line.html new file mode 100644 index 0000000..517545c --- /dev/null +++ b/front/templates/line.html @@ -0,0 +1,16 @@ +<span class="line__symbol flex" :class="{ [`line--${line.type}`]: true, 'line--night': line.night, 'line--fast': line.fast }"> + <span class="flex align-items-stretch"> + <slot name="icon" v-if="!simple"> + <span class="icon"> + <ui-icon :icon="`line-${line.type}`" fixed-width/> + </span> + </slot> + <slot name="badge"> + <span class="badge badge-dark flex"> + <ui-icon icon="night" fixed-width v-if="line.night && !simple"/> + {{ line.symbol }} + <ui-icon icon="fast" v-if="line.fast"/> + </span> + </slot> + </span> +</span> diff --git a/front/templates/main.html b/front/templates/main.html new file mode 100644 index 0000000..ae6af29 --- /dev/null +++ b/front/templates/main.html @@ -0,0 +1,142 @@ +<div class="container" id="app"> + <div class="row"> + <div class="col-md-8 order-md-last"> + <section class="section messages" v-show="messages.count > 0"> + <header class="section__title flex"> + <h2> + <ui-icon icon="messages" fixed-width class="mr-2"></ui-icon> + Komunikaty <span class="ml-2 badge badge-pill badge-dark">{{ messages.count }}</span> + </h2> + <button class="btn btn-action flex-space-left" ref="settings-messages" id="settings-messages" + @click="visibility.messages = !visibility.messages"> + <tooltip>ustawienia</tooltip> + <ui-icon icon="settings" fixed-width></ui-icon> + </button> + <button class="btn btn-action" @click="updateMessages" ref="btn-messages-refresh"> + <tooltip>odśwież</tooltip> + <ui-icon icon="refresh" :spin="messages.state === 'fetching'" fixed-width></ui-icon> + </button> + <button class="btn btn-action" @click="sections.messages = !sections.messages"> + <tooltip> + {{ sections.messages ? 'zwiń' : 'rozwiń' }} + <span class="sr-only">sekcję komunikatów</span> + </tooltip> + <ui-icon :icon="sections.messages ? 'chevron-up' : 'chevron-down'" fixed-width></ui-icon> + </button> + + <portal to="popups"> + <ui-dialog reference="#settings-messages" v-if="visibility.messages" arrow placement="left-start" + @leave="visibility.messages = false"> + <settings-messages></settings-messages> + </ui-dialog> + </portal> + </header> + <fold :visible="sections.messages"> + <messages></messages> + </fold> + </section> + <section class="section"> + <header class="section__title flex"> + <h2> + <ui-icon icon="timetable" fixed-width></ui-icon> + <span class="text">Odjazdy</span> + </h2> + + <button class="btn btn-action flex-space-left" ref="settings-departures" id="settings-departures" + @click="visibility.departures = !visibility.departures"> + <tooltip>ustawienia</tooltip> + <ui-icon icon="settings" fixed-width></ui-icon> + </button> + <button class="btn btn-action" @click="updateDepartures({ stops })"> + <tooltip>odśwież</tooltip> + <ui-icon icon="refresh" :spin="departures.state === 'fetching'" fixed-width></ui-icon> + </button> + <portal to="popups"> + <ui-dialog reference="#settings-departures" v-if="visibility.departures" + @leave="visibility.departures = false" arrow placement="left-start"> + <settings-departures></settings-departures> + </ui-dialog> + </portal> + </header> + <departures :stops="stops" v-if="stops.length > 0"></departures> + <div class="alert alert-info" v-else> + <ui-icon icon="info"></ui-icon> + Wybierz przystanki korzystając z wyszukiwarki poniżej, aby zobaczyć listę odjazdów. + </div> + <div class="attribution" v-if="provider && provider.attribution"> + <ui-icon icon="info"></ui-icon> + Pochodzenie danych: <span class="attribution__attribution" v-html="provider.attribution"></span> + </div> + </section> + </div> + <div class="col-md-4 order-md-first"> + <section class="section picker" v-if="stops.length > 0"> + <header class="section__title flex"> + <h2> + <ui-icon icon="stop" fixed-width></ui-icon> + <span class="text">Przystanki</span> + </h2> + <button class="btn btn-action flex-space-left" @click="clear"> + <tooltip>usuń wszystkie</tooltip> + <ui-icon icon="delete" fixed-width></ui-icon> + </button> + </header> + + <ul class="picker__stops list-underlined"> + <li v-for="stop in stops" :key="stop.id" class="picker__stop"> + <picker-stop :stop="stop"> + <template v-slot:primary-action> + <button @click="remove(stop)" class="btn btn-action"> + <tooltip>usuń przystanek</tooltip> + <ui-icon icon="remove-stop"></ui-icon> + </button> + </template> + </picker-stop> + </li> + </ul> + + <div class="d-flex mt-2"> + <button class="btn btn-action btn-sm flex-space-left" @click="visibility.save = true" ref="save"> + <ui-icon icon="favourite" fixed-width></ui-icon> + zapisz jako... + </button> + </div> + + <ui-dialog reference="save" v-if="visibility.save" arrow placement="bottom-end" + @leave="visibility.save = false" title="Dodaj do ulubionych"> + <favourites-adder @saved="visibility.save = false"/> + </ui-dialog> + </section> + <section class="section picker"> + <header class="section__title flex"> + <template v-if="visibility.picker === 'search'"> + <h2 class="flex-grow-1"> + <ui-icon icon="search" fixed-width class="mr-1"></ui-icon> + Wybierz przystanki + </h2> + <button class="btn btn-action" @click="visibility.picker = 'favourites'"> + <tooltip>Zapisane</tooltip> + <ui-icon icon="favourite" fixed-witdth></ui-icon> + </button> + </template> + <template v-else> + <h2 class="flex-grow-1"> + <ui-icon icon="favourite" fixed-width class="mr-1"></ui-icon> + Zapisane + </h2> + <button class="btn btn-action" @click="visibility.picker = 'search'"> + <tooltip>Wybierz przystanki</tooltip> + <ui-icon icon="search" fixed-witdth></ui-icon> + </button> + </template> + </header> + <div class="transition-box"> + <transition name="fade"> + <stop-finder @select="add" :blacklist="stops" v-if="visibility.picker === 'search'"></stop-finder> + <favourites v-else-if="visibility.picker === 'favourites'"></favourites> + </transition> + </div> + </section> + </div> + </div> +</div> diff --git a/front/templates/messages.html b/front/templates/messages.html new file mode 100644 index 0000000..3ee5353 --- /dev/null +++ b/front/templates/messages.html @@ -0,0 +1,29 @@ +<div class="messages mb-2"> + <ul class="list-unstyled mb-0"> + <li class="message alert" :class="`alert-${type(message)}`" v-for="message in messages"> + <ui-icon :icon="`message-${message.type}`" fixed-width/> + {{ message.message }} + + <div class="message__info"> + <small class="message__date"> + Komunikat ważny od + {{ message.validFrom.format('HH:mm') }} + do + {{ message.validTo.format('HH:mm') }} + </small> + </div> + </li> + </ul> + <template v-if="nonDisplayedCount > 0"> + <div class="flex"> + <button class="btn btn-action btn-sm flex-space-left" @click="showAll = !showAll"> + <template v-if="showAll"> + <ui-icon icon="chevron-up"/> {{ nonDisplayedCount }} mniej + </template> + <template v-else> + <ui-icon icon="chevron-down"/> {{ nonDisplayedCount }} więcej + </template> + </button> + </div> + </template> +</div> diff --git a/front/templates/page/providers.html b/front/templates/page/providers.html new file mode 100644 index 0000000..77099ed --- /dev/null +++ b/front/templates/page/providers.html @@ -0,0 +1,38 @@ +<div style="width: 100%"> + <l-map :center="{ lat: 52.0194, lon: 19.1451 }" :zoom=7 :options="{ zoomControl: false }" class="map"> + <l-vector-layer url="https://api.maptiler.com/maps/bright/style.json?key=8GX5FRUNgk4lB83GZT8Q" + token="not-needed" + attribution='<a href="https://www.maptiler.com/copyright/" target="_blank">© MapTiler</a> <a href="https://www.openstreetmap.org/copyright" target="_blank">© OpenStreetMap contributors</a>' + /> + + <div class="provider-picker"> + <h2 class="provider-picker__heading">Wybierz lokalizację</h2> + <ul class="provider-picker__providers"> + <li v-for="provider in providers" :key="provider.id" class="provider-picker__provider"> + <a :href="`/${provider.id}`" class="provider"> + <ui-icon icon="line-bus" size="2x" /> + <div> + <div class="provider__short-name">{{ provider.shortName }}</div> + <div class="provider__name">{{ provider.name }}</div> + </div> + <tooltip v-if="provider.lastUpdate != null">Ostatnia akutalizacja: {{ provider.lastUpdate|moment('YYYY-MM-DD HH:mm') }}</tooltip> + </a> + </li> + </ul> + </div> + + <l-marker :lat-lng="provider.location" v-for="provider in providers" :options="{ keyboard: false }" :key="provider.id"> + <l-icon> + <div class="map__label-box" tabindex="0"> + <a :href="`/${provider.id}`" class="provider"> + <ui-icon icon="line-bus" class="map__icon" /> + <div> + <div class="provider__short-name">{{ provider.shortName }}</div> + <div class="provider__name">{{ provider.name }}</div> + </div> + </a> + </div> + </l-icon> + </l-marker> + </l-map> +</div> diff --git a/front/templates/picker/stop.html b/front/templates/picker/stop.html new file mode 100644 index 0000000..21d1f2d --- /dev/null +++ b/front/templates/picker/stop.html @@ -0,0 +1,49 @@ +<div> + <div class="d-flex"> + <div class="d-flex position-relative" style="min-width: 0; flex: 1 1 auto;"> + <slot name="primary-action" /> + <div class="overflow-hidden align-self-center"> + <stop :stop="stop" /> + <div class="stop__destinations" v-if="destinations && destinations.length > 0"> + <ul> + <li class="stop__destination destination" v-for="destination in destinations" :key="destination.stop.id"> + <ul class="destination__lines"> + <li v-for="line in destination.lines"> + <line-symbol :line="line" :key="line.symbol" simple/> + </li> + </ul> + <span class="destination__name ml-1">{{ destination.stop.name }}</span> + </li> + </ul> + </div> + </div> + </div> + + <div class="stop__actions"> + <slot name="actions"> + <button class="btn btn-action" ref="action-info" @click="details = !details"> + <tooltip>dodatkowe informacje</tooltip> + <ui-icon icon="info"/> + </button> + + <button class="btn btn-action" ref="action-map" v-hover:map> + <ui-icon icon="map"/> + </button> + </slot> + </div> + </div> + + <keep-alive> + <portal to="popups"> + <ui-dialog v-if="details" @leave="details = false" behaviour="modal" class="ui-modal--medium" title="Szczegóły przystanku"> + <stop-details :stop="stop"/> + </ui-dialog> + </portal> + </keep-alive> + <keep-alive> + <!-- FIXME: This should be in portal but it's not possible due to information loss, maybe in vue3 it will be better?--> + <ui-dialog reference="action-map" v-if="showMap" arrow class="ui-popup--no-padding" style="width: 500px;" placement="right-start" v-hover:inMap> + <stop-map :stop="stop" style="height: 300px"/> + </ui-dialog> + </keep-alive> +</div> diff --git a/front/templates/settings/departures.html b/front/templates/settings/departures.html new file mode 100644 index 0000000..fc4a9d8 --- /dev/null +++ b/front/templates/settings/departures.html @@ -0,0 +1,38 @@ +<fragment> + <div class="form-group"> + <div class="flex"> + <label class="text" for="departures-auto-refresh-interval"> + <ui-icon icon="refresh" fixed-width/> + autoodświeżanie + </label> + <ui-switch id="departures-auto-refresh" :value="autorefresh" @input="update({ autorefresh: $event })" class="flex-space-left"/> + </div> + <div class="flex " v-if="autorefresh"> + <label for="departures-auto-refresh-interval" class="text"> + <span class="sr-only">częstotliwość odświeżania</span> + co + </label> + <div class="input-group input-group-sm"> + <input type="text" class="form-control form-control-sm form-control-simple" id="departures-auto-refresh-interval" + :value="autorefreshInterval" @input="update({ autorefreshInterval: Number.parseInt($event.target.value) })" /> + <div class="input-group-append"> + <span class="input-group-text" aria-label="sekund">s</span> + </div> + </div> + </div> + </div> + <div class="form-group"> + <label class="text" for="departures-count"> + <ui-icon icon="line-bus" fixed-width/> + liczba wpisów + </label> + <ui-numeric-input id="departures-count" :value="displayedEntriesCount" @input="update({ displayedEntriesCount: $event })" :min="1" :max="20"/> + </div> + <div class="form-group flex"> + <label class="text" for="departures-relative-times"> + <ui-icon icon="relative-time" fixed-width/> + czas do odjazdu + </label> + <ui-switch id="departures-relative-times" :value="relativeTimes" @input="update({ relativeTimes: $event })" class="flex-space-left"/> + </div> +</fragment> diff --git a/front/templates/settings/messages.html b/front/templates/settings/messages.html new file mode 100644 index 0000000..f185340 --- /dev/null +++ b/front/templates/settings/messages.html @@ -0,0 +1,31 @@ +<fragment> + <div class="form-group"> + <div class="flex"> + <label class="text" for="departures-auto-refresh-interval"> + <ui-icon icon="refresh" fixed-width/> + autoodświeżanie + </label> + <ui-switch id="departures-auto-refresh" :value="autorefresh" @input="update({ autorefresh: $event })" class="flex-space-left"/> + </div> + <div class="flex " v-if="autorefresh"> + <label for="departures-auto-refresh-interval" class="text"> + <span class="sr-only">częstotliwość odświeżania</span> + co + </label> + <div class="input-group input-group-sm"> + <input type="text" class="form-control form-control-sm form-control-simple" id="departures-auto-refresh-interval" + :value="autorefreshInterval" @input="update({ autorefreshInterval: Number.parseInt($event.target.value) })" /> + <div class="input-group-append"> + <span class="input-group-text" aria-label="sekund">s</span> + </div> + </div> + </div> + </div> + <div class="form-group"> + <label class="text" for="departures-count"> + <ui-icon icon="messages" fixed-width/> + wyświetlanych komunikatów + </label> + <ui-numeric-input id="departures-count" :value="displayedEntriesCount" @input="update({ displayedEntriesCount: $event })" :min="1" /> + </div> +</fragment> diff --git a/resources/components/stop.html b/front/templates/stop.html similarity index 100% rename from resources/components/stop.html rename to front/templates/stop.html diff --git a/resources/components/stop/details.html b/front/templates/stop/details.html similarity index 62% rename from resources/components/stop/details.html rename to front/templates/stop/details.html index e25f061..dba5cda 100644 --- a/resources/components/stop/details.html +++ b/front/templates/stop/details.html @@ -16,21 +16,13 @@ <div class="track__description"> {{ track.description }} </div> - <span class="badge badge-pill badge-light track__order">#{{ order }}</span> + <span class="badge badge-pill badge-light track__order"> + #{{ order }} + </span> </li> </ul> </section> - - <section> - <strong>Na mapie:</strong> - <div style="height: 350px" tabindex="-1"> - <l-map :center="stop.location" :zoom=17> - <l-tile-layer url="//{s}.tile.osm.org/{z}/{x}/{y}.png" attribution='© <a href="//osm.org/copyright">OpenStreetMap</a> contributors'></l-tile-layer> - <l-marker :lat-lng="stop.location"></l-marker> - </l-map> - </div> - </section> </div> <div v-else class="text-center"> - <fa icon="spinner-third" pulse></fa> -</div> \ No newline at end of file + <ui-icon icon="spinner"/> +</div> diff --git a/front/templates/stop/history.html b/front/templates/stop/history.html new file mode 100644 index 0000000..945d672 --- /dev/null +++ b/front/templates/stop/history.html @@ -0,0 +1,11 @@ +<ul class="list-underlined history" v-if="all.length > 0"> + <li v-for="entry in all" class="history__entry"> + <picker-stop :stop="entry.stop" class="flex-grow-1 finder__stop"> + <template v-slot:primary-action> + <button @click="select(entry.stop, $event)" class="btn btn-action stretched-link"> + <ui-icon icon="history" /> + </button> + </template> + </picker-stop> + </li> +</ul> diff --git a/resources/components/stop/map.html b/front/templates/stop/map.html similarity index 100% rename from resources/components/stop/map.html rename to front/templates/stop/map.html diff --git a/resources/components/tooltip.html b/front/templates/tooltip.html similarity index 53% rename from resources/components/tooltip.html rename to front/templates/tooltip.html index 65805b0..033eeb5 100644 --- a/resources/components/tooltip.html +++ b/front/templates/tooltip.html @@ -1,9 +1,9 @@ <fragment> <portal to="popups"> <transition name="tooltip"> - <popper class="popper--tooltip" aria-hidden="true" arrow :reference="root" :placement="placement" v-if="show" :responsive="false"> + <ui-dialog class="ui-popup--tooltip" aria-hidden="true" arrow :reference="root" :placement="placement" v-if="show" :responsive="false"> <slot /> - </popper> + </ui-dialog> </transition> </portal> <span ref="root" class="sr-only"><slot /></span> diff --git a/resources/components/trip.html b/front/templates/trip.html similarity index 100% rename from resources/components/trip.html rename to front/templates/trip.html diff --git a/front/templates/ui/dialog.html b/front/templates/ui/dialog.html new file mode 100644 index 0000000..8a8f2d8 --- /dev/null +++ b/front/templates/ui/dialog.html @@ -0,0 +1,31 @@ +<div class="ui-backdrop" @click="handleBackdropClick" v-if="currentBehaviour === 'modal'" role="dialog"> + <div class="ui-modal" v-bind="attrs" v-on="$listeners"> + <div class="ui-modal__top-bar"> + <div class="ui-modal__header"> + <slot name="header"> + <div class="ui-modal__title" role="heading"><slot name="title">{{ title }}</slot></div> + </slot> + </div> + <button class="btn btn-action ui-modal__close" @click.prevent="handleCloseClick"> + <ui-icon icon="close"/> + </button> + </div> + <slot /> + <div class="ui-modal__footer" v-if="hasFooter"> + <slot name="footer" /> + </div> + </div> +</div> +<div :class="[ 'ui-popup', arrow && 'ui-popup--arrow' ]" v-bind="attrs" :style="{ zIndex: zIndex }" v-on="$listeners" role="dialog" v-else> + <div class="ui-popup__arrow" ref="arrow" v-if="arrow"></div> + <div class="ui-popup__header" v-if="hasHeader || title"> + <slot name="header"> + <div class="ui-popup__heading" role="heading"><slot name="title">{{ title }}</slot></div> + </slot> + </div> + <slot /> + <div class="ui-popup__footer" v-if="hasFooter"> + <slot name="footer" /> + </div> +</div> + diff --git a/front/templates/ui/icon.html b/front/templates/ui/icon.html new file mode 100644 index 0000000..f9f2d25 --- /dev/null +++ b/front/templates/ui/icon.html @@ -0,0 +1,4 @@ +<fa v-bind="attrs" v-if="type === 'simple'"/> +<fa-layers v-else-if="type === 'stacked'"> + <fa :icon="props.icon" v-bind="props" v-for="(props, index) in definition.icons" :key="index"/> +</fa-layers> diff --git a/front/templates/ui/numeric.html b/front/templates/ui/numeric.html new file mode 100644 index 0000000..c2cb1ce --- /dev/null +++ b/front/templates/ui/numeric.html @@ -0,0 +1,11 @@ +<div class="input-group input-group-sm"> + <input type="text" class="form-control form-control-sm" :id="id" inputmode="numeric" v-bind="$attrs" :value="value" @blur="update"/> + <div class="input-group-append"> + <button class="btn btn-addon" type="button" @click="increment" :disabled="!canIncrement"> + <ui-icon icon="increment"/> + </button> + <button class="btn btn-addon" type="button" @click="decrement" :disabled="!canDecrement"> + <ui-icon icon="decrement"/> + </button> + </div> +</div> diff --git a/front/templates/ui/switch.html b/front/templates/ui/switch.html new file mode 100644 index 0000000..6111e23 --- /dev/null +++ b/front/templates/ui/switch.html @@ -0,0 +1,4 @@ +<div class="ui-switch" :class="[ value && 'ui-switch--checked' ]" v-bind="$attrs" @click="update"> + <div class="ui-switch__track"><div class="ui-switch__thumb"></div></div> + <input type="checkbox" class="ui-switch__checkbox" :id="id" :checked="value" @input="update"/> +</div> diff --git a/front/tsconfig.json b/front/tsconfig.json new file mode 100644 index 0000000..62af5bd --- /dev/null +++ b/front/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "lib": ["dom", "es2015", "es2016.array.include", "es2017.object"], + "experimentalDecorators": true, + "target": "es5", + "module": "esnext", + "sourceMap": true, + "noImplicitThis": true, + "moduleResolution": "node", + "downlevelIteration": true, + "allowSyntheticDefaultImports": true, + "baseUrl": "./", + "paths": { + "@templates/*": ["./templates/*"], + "@resources/*": ["./resources/*"], + "@styles/*": ["./styles/*"], + "@/*": ["./src/*"] + } + }, + "files": ["src/app.ts"], + "include": ["src/**/*.ts"] +} diff --git a/webpack.config.js b/front/webpack.config.js similarity index 68% rename from webpack.config.js rename to front/webpack.config.js index 439c13d..e745e5b 100644 --- a/webpack.config.js +++ b/front/webpack.config.js @@ -1,18 +1,20 @@ const path = require('path'); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); -const BabelMinifyPlugin = require('babel-minify-webpack-plugin'); const CopyWebpackPlugin = require('copy-webpack-plugin'); const { CleanWebpackPlugin } = require('clean-webpack-plugin'); const ImageminPlugin = require('imagemin-webpack-plugin').default; const { GenerateSW } = require('workbox-webpack-plugin'); +const HtmlWebpackPlugin = require('html-webpack-plugin'); + +const output_dir = path.resolve('./build/') const config = { entry: { - main: ['./resources/ts/app.ts'], - api: ['./resources/styles/api.scss'] + main: ['./src/app.ts'], + api: ['./styles/api.scss'] }, output: { - path: path.resolve('./public/dist/'), + path: path.join(output_dir, './public/dist/'), publicPath: "/dist/", filename: "[name].js", chunkFilename: '[name].[chunkhash:8].js' @@ -21,7 +23,11 @@ const config = { extensions: ['.tsx', '.ts', '.js'], alias: { 'vue$': 'vue/dist/vue.esm.js', - 'mapbox-gl$': 'mapbox-gl/dist/mapbox-gl-unminified' + 'mapbox-gl$': 'mapbox-gl/dist/mapbox-gl-unminified', + "@templates": path.resolve(__dirname, "./templates"), + "@resources": path.resolve(__dirname, "./resources"), + "@styles": path.resolve(__dirname, "./styles"), + "@": path.resolve(__dirname, "./src"), } }, module: { @@ -37,7 +43,7 @@ const config = { test: /\.s[ac]ss$/, use: [{ loader: MiniCssExtractPlugin.loader, - }, "css-loader?sourceMap", "sass-loader?sourceMap"] + }, "css-loader?sourceMap&url=false", "sass-loader?sourceMap&url=false"] }, { test: /\.css$/, use: ["style-loader", "css-loader"] @@ -56,22 +62,27 @@ const config = { use: 'file-loader' }, { test: /\.html?$/, - use: 'raw-loader' + use: 'raw-loader', + exclude: [ + path.resolve('./resources/index.html') + ] }] }, plugins: [ - new CleanWebpackPlugin(), new MiniCssExtractPlugin({ filename: '[name].css' }), new CopyWebpackPlugin([{ from: './resources/images/', to: '../images/', ignore: ['*.ai'] }]), new ImageminPlugin({ test: /\.(jpe?g|png|gif|svg)$/i }), new GenerateSW({ navigationPreload: true, runtimeCaching: [{ - urlPattern: ({event}) => event.request.mode === 'navigate', - handler: 'NetworkFirst', + urlPattern: ({ event }) => event.request.mode === 'navigate', + handler: 'NetworkFirst', + }, { + urlPattern: /^https?:\/\/api\.maptiler\.com\//, + handler: 'CacheFirst', }], swDest: '../service-worker.js' - }) + }), ] }; diff --git a/yarn.lock b/front/yarn.lock similarity index 85% rename from yarn.lock rename to front/yarn.lock index 016780d..a9f96ac 100644 --- a/yarn.lock +++ b/front/yarn.lock @@ -3,49 +3,28 @@ "@babel/runtime@^7.0.0", "@babel/runtime@^7.3.4": - version "7.7.6" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.7.6.tgz#d18c511121aff1b4f2cd1d452f1bac9601dd830f" - integrity sha512-BWAJxpNVa0QlE5gZdWjSxXtemZyZ9RmrmVozxt3NUXeZhVIJ5ANyqmMc0JDrivBZyxUuQvFxlvH4OWWOogGfUw== + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.8.4.tgz#d79f5a2040f7caa24d53e563aad49cbc05581308" + integrity sha512-neAp3zt80trRVBI1x0azq6c57aNBqYZH8KhMm3TaB7wEI5Q4A2SHfBHE8w9gOhI/lrqxtEbXZgQIrHP+wvSGwQ== dependencies: regenerator-runtime "^0.13.2" -"@fortawesome/fontawesome-common-types@^0.2.25": - version "0.2.25" - resolved "https://npm.fontawesome.com/@fortawesome/fontawesome-common-types/-/0.2.25/fontawesome-common-types-0.2.25.tgz#6df015905081f2762e5cfddeb7a20d2e9b16c786" - integrity sha512-3RuZPDuuPELd7RXtUqTCfed14fcny9UiPOkdr2i+cYxBoTOfQgxcDoq77fHiiHcgWuo1LoBUpvGxFF1H/y7s3Q== +"@fortawesome/fontawesome-common-types@^0.2.32": + version "0.2.32" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.32.tgz#3436795d5684f22742989bfa08f46f50f516f259" + integrity sha512-ux2EDjKMpcdHBVLi/eWZynnPxs0BtFVXJkgHIxXRl+9ZFaHPvYamAfCzeeQFqHRjuJtX90wVnMRaMQAAlctz3w== "@fortawesome/fontawesome-svg-core@^1.2.4": - version "1.2.25" - resolved "https://npm.fontawesome.com/@fortawesome/fontawesome-svg-core/-/1.2.25/fontawesome-svg-core-1.2.25.tgz#24b03391d14f0c6171e8cad7057c687b74049790" - integrity sha512-MotKnn53JKqbkLQiwcZSBJVYtTgIKFbh7B8+kd05TSnfKYPFmjKKI59o2fpz5t0Hzl35vVGU6+N4twoOpZUrqA== + version "1.2.32" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.32.tgz#da092bfc7266aa274be8604de610d7115f9ba6cf" + integrity sha512-XjqyeLCsR/c/usUpdWcOdVtWFVjPbDFBTQkn2fQRrWhhUoxriQohO2RWDxLyUM8XpD+Zzg5xwJ8gqTYGDLeGaQ== dependencies: - "@fortawesome/fontawesome-common-types" "^0.2.25" - -"@fortawesome/pro-light-svg-icons@^5.3.1": - version "5.11.2" - resolved "https://npm.fontawesome.com/@fortawesome/pro-light-svg-icons/-/5.11.2/pro-light-svg-icons-5.11.2.tgz#61543170feb34e04f4d4bd1843b08bbde6682833" - integrity sha512-NzN0K+hnKQ8fw4PLsr7WjLgtlnH1QjD4/N26YVUEMzLZiTgYBiqE7NDlRL6q/xJ9ittCj6PDPNY/IQ0T8XPLiA== - dependencies: - "@fortawesome/fontawesome-common-types" "^0.2.25" - -"@fortawesome/pro-regular-svg-icons@^5.3.1": - version "5.11.2" - resolved "https://npm.fontawesome.com/@fortawesome/pro-regular-svg-icons/-/5.11.2/pro-regular-svg-icons-5.11.2.tgz#e9185f15555a16748612044211444463c005d97f" - integrity sha512-y1WLNjf/AMN+Mh+CojlOoKfk9miKPDB3P3r7cj3WP7yjxmDX09YyYHkxSWP2HOK9xJulmVN36CbNcMVS8Mrqpg== - dependencies: - "@fortawesome/fontawesome-common-types" "^0.2.25" - -"@fortawesome/pro-solid-svg-icons@^5.3.1": - version "5.11.2" - resolved "https://npm.fontawesome.com/@fortawesome/pro-solid-svg-icons/-/5.11.2/pro-solid-svg-icons-5.11.2.tgz#5d72c801b3413191a81841c606d8cc7926014b76" - integrity sha512-YYrEFhda4KIUweXed1s+RQko53O7rXGK1jEbdlGXZlHnNTX7OyrkvJDQYqhQ7H+H62HV0BxF/xtDXvSJRlyO1Q== - dependencies: - "@fortawesome/fontawesome-common-types" "^0.2.25" + "@fortawesome/fontawesome-common-types" "^0.2.32" "@fortawesome/vue-fontawesome@^0.1.1": - version "0.1.8" - resolved "https://npm.fontawesome.com/@fortawesome/vue-fontawesome/-/0.1.8/vue-fontawesome-0.1.8.tgz#615347c56d285eb634315f59fe4f4156e4eee8b4" - integrity sha512-SdFiUD+vFDA/xKuEbnQTVrK8FDxoV0eyQaiHxmCcjAc0+vQe0Kf6oGm28opNPIt8MTgKWR3+Yg3xXP455Ae4tQ== + version "0.1.10" + resolved "https://registry.yarnpkg.com/@fortawesome/vue-fontawesome/-/vue-fontawesome-0.1.10.tgz#eeeec1e4e8850bed0468f938292b06cda793bf34" + integrity sha512-b2+SLF31h32LSepVcXe+BQ63yvbq5qmTCy4KfFogCYm2bn68H5sDWUnX+U7MBqnM2aeEk9M7xSoqGnu+wSdY6w== "@hapi/address@2.x.x": version "2.1.4" @@ -58,9 +37,9 @@ integrity sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA== "@hapi/hoek@8.x.x", "@hapi/hoek@^8.3.0": - version "8.5.0" - resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-8.5.0.tgz#2f9ce301c8898e1c3248b0a8564696b24d1a9a5a" - integrity sha512-7XYT10CZfPsH7j9F1Jmg1+d0ezOux2oM2GfArAzLwWe4mE2Dr3hVjsAL6+TFY49RRJlCdJDMw3nJsLFroTc8Kw== + version "8.5.1" + resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-8.5.1.tgz#fde96064ca446dec8c55a8c2f130957b070c6e06" + integrity sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow== "@hapi/joi@^15.0.0": version "15.1.1" @@ -161,7 +140,15 @@ resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a" integrity sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA== -"@types/bootstrap@^4.1.2": +"@types/body-parser@*": + version "1.19.0" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.0.tgz#0685b3c47eb3006ffed117cdd55164b61f80538f" + integrity sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/bootstrap@^4.3.1": version "4.3.1" resolved "https://registry.yarnpkg.com/@types/bootstrap/-/bootstrap-4.3.1.tgz#15fa89a4d275b114a4eceb90909d4eb8b90d43f5" integrity sha512-n7Zv7Y+C98Yv4oqbyqGn3alCvNRCya2xMYzOdVEnmnFlu04MXQk1ntVrBhXzDkiwhZZYNkNfBZn2yhTnEh/mHQ== @@ -169,11 +156,47 @@ "@types/jquery" "*" popper.js "^1.14.1" +"@types/caseless@*": + version "0.12.2" + resolved "https://registry.yarnpkg.com/@types/caseless/-/caseless-0.12.2.tgz#f65d3d6389e01eeb458bd54dc8f52b95a9463bc8" + integrity sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w== + +"@types/connect@*": + version "3.4.33" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.33.tgz#31610c901eca573b8713c3330abc6e6b9f588546" + integrity sha512-2+FrkXY4zllzTNfJth7jOqEHC+enpLeGslEhpnTAkg21GkRrWV4SsAtqchtT4YS9/nODBU2/ZfsBY2X4J/dX7A== + dependencies: + "@types/node" "*" + +"@types/ejs@^3.0.5": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@types/ejs/-/ejs-3.0.5.tgz#95a3a1c3d9603eba80fe67ff56da1ba275ef2eda" + integrity sha512-k4ef69sS4sIqAPW9GoBnN+URAON2LeL1H0duQvL4RgdEBna19/WattYSA1qYqvbVEDRTSWzOw56tCLhC/m/IOw== + "@types/events@*": version "3.0.0" resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g== +"@types/express-serve-static-core@*": + version "4.17.13" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.13.tgz#d9af025e925fc8b089be37423b8d1eac781be084" + integrity sha512-RgDi5a4nuzam073lRGKTUIaL3eF2+H7LJvJ8eUnCI0wA6SNjXc44DCmWNiTLs/AZ7QlsFWZiw/gTG3nSQGL0fA== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + +"@types/express@^4.17.9": + version "4.17.9" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.9.tgz#f5f2df6add703ff28428add52bdec8a1091b0a78" + integrity sha512-SDzEIZInC4sivGIFY4Sz1GG6J9UObPwCInYJjko2jzOf/Imx/dlpume6Xxwj1ORL82tBbmN4cPDIDkLbWHk9hw== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "*" + "@types/qs" "*" + "@types/serve-static" "*" + "@types/geojson@*": version "7946.0.7" resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.7.tgz#c8fa532b60a0042219cdf173ca21a975ef0666ad" @@ -188,6 +211,11 @@ "@types/minimatch" "*" "@types/node" "*" +"@types/html-minifier-terser@^5.0.0": + version "5.1.1" + resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz#3c9ee980f1a10d6021ae6632ca3e79ca2ec4fb50" + integrity sha512-giAlZwstKbmvMk1OO7WXSj4OZ0keXAcl2TQq4LWHiiPH2ByaH7WeUzng+Qej8UPxxv+8lRTuouo0iaNDBuzIBA== + "@types/imagemin-gifsicle@^5.2.0": version "5.2.0" resolved "https://registry.yarnpkg.com/@types/imagemin-gifsicle/-/imagemin-gifsicle-5.2.0.tgz#349160f17412e26de8d5794e70aad504781ea7d8" @@ -225,26 +253,19 @@ "@types/node" "*" "@types/jquery@*", "@types/jquery@^3.3.6": - version "3.3.31" - resolved "https://registry.yarnpkg.com/@types/jquery/-/jquery-3.3.31.tgz#27c706e4bf488474e1cb54a71d8303f37c93451b" - integrity sha512-Lz4BAJihoFw5nRzKvg4nawXPzutkv7wmfQ5121avptaSIXlDNJCUuxZxX/G+9EVidZGuO0UBlk+YjKbwRKJigg== + version "3.3.32" + resolved "https://registry.yarnpkg.com/@types/jquery/-/jquery-3.3.32.tgz#93e27fdc45dd38ee07f2f0acf34b59c1ccee036f" + integrity sha512-UKoof2mnV/X1/Ix2g+V2Ny5sgHjV8nK/UJbiYxuo4zPwzGyFlZ/mp4KaePb2VqQrqJctmcDQNA57buU84/2uIw== dependencies: "@types/sizzle" "*" -"@types/leaflet@*": +"@types/leaflet@*", "@types/leaflet@^1.2.11": version "1.5.8" resolved "https://registry.yarnpkg.com/@types/leaflet/-/leaflet-1.5.8.tgz#1c550803672fc5866b8b2c38512009f2b5d4205d" integrity sha512-qpi5n4LmwenUFZ+VZ7ytRgHK+ZAclIvloL2zoKCmmj244WD2hBcLbUZ6Szvajfe3sIkSYEJ8WZ1p9VYl8tRsMA== dependencies: "@types/geojson" "*" -"@types/leaflet@^1.2.11": - version "1.5.6" - resolved "https://registry.yarnpkg.com/@types/leaflet/-/leaflet-1.5.6.tgz#cdad1f32328331b32ee4f63c24c59cba055c9b0c" - integrity sha512-a9gVDwmNNalKrsU124kS7Lv9eo0z95CCMJu1Fp7l+A+EQ7Vv0UJ7LFkjaxu176ebUOBDEqvjn7A2vrlq5kLtkw== - dependencies: - "@types/geojson" "*" - "@types/mapbox-gl-leaflet@^0.0.1": version "0.0.1" resolved "https://registry.yarnpkg.com/@types/mapbox-gl-leaflet/-/mapbox-gl-leaflet-0.0.1.tgz#2e091ec398ac1e7ed1e52cce7c4dfaa60e25c4a5" @@ -252,6 +273,11 @@ dependencies: "@types/leaflet" "*" +"@types/mime@*": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.3.tgz#c893b73721db73699943bfc3653b1deb7faa4a3a" + integrity sha512-Jus9s4CDbqwocc5pOAnh8ShfrnMcPHuJYzVcSUU7lrh8Ni5HuIqX3oilL86p3dlTrk0LzHRCgA/GQ7uNCw6l2Q== + "@types/minimatch@*": version "3.0.3" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" @@ -265,9 +291,9 @@ moment "*" "@types/node@*": - version "12.12.14" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.14.tgz#1c1d6e3c75dba466e0326948d56e8bd72a1903d2" - integrity sha512-u/SJDyXwuihpwjXy7hOOghagLEV1KdAST6syfnOk6QZAMzZuWZqXy5aYYZbh8Jdpd4escVFP0MvftHNDb9pruA== + version "13.7.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-13.7.0.tgz#b417deda18cf8400f278733499ad5547ed1abec4" + integrity sha512-GnZbirvmqZUzMgkFn70c74OQpTTUcCzlhQliTzYjQMqg+hVKcDnxdL19Ne3UdYzdMA/+W3eb646FWn/ZaT1NfQ== "@types/popper.js@^1.11.0": version "1.11.0" @@ -281,6 +307,34 @@ resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.2.tgz#690a1475b84f2a884fd07cd797c00f5f31356ea8" integrity sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw== +"@types/qs@*": + version "6.9.5" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.5.tgz#434711bdd49eb5ee69d90c1d67c354a9a8ecb18b" + integrity sha512-/JHkVHtx/REVG0VVToGRGH2+23hsYLHdyG+GrvoUGlGAd0ErauXDyvHtRI/7H7mzLm+tBCKA7pfcpkQ1lf58iQ== + +"@types/range-parser@*": + version "1.2.3" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c" + integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA== + +"@types/request@^2.48.5": + version "2.48.5" + resolved "https://registry.yarnpkg.com/@types/request/-/request-2.48.5.tgz#019b8536b402069f6d11bee1b2c03e7f232937a0" + integrity sha512-/LO7xRVnL3DxJ1WkPGDQrp4VTV1reX9RkC85mJ+Qzykj2Bdw+mG15aAfDahc76HtknjzE16SX/Yddn6MxVbmGQ== + dependencies: + "@types/caseless" "*" + "@types/node" "*" + "@types/tough-cookie" "*" + form-data "^2.5.0" + +"@types/serve-static@*": + version "1.13.8" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.8.tgz#851129d434433c7082148574ffec263d58309c46" + integrity sha512-MoJhSQreaVoL+/hurAZzIm8wafFR6ajiTM1m4A0kv6AGeVBl4r4pOV8bGFrjjq1sGxDTnCoF8i22o0/aE5XCyA== + dependencies: + "@types/mime" "*" + "@types/node" "*" + "@types/sizzle@*": version "2.3.2" resolved "https://registry.yarnpkg.com/@types/sizzle/-/sizzle-2.3.2.tgz#a811b8c18e2babab7d542b3365887ae2e4d9de47" @@ -297,9 +351,19 @@ integrity sha512-3MkYdqVF0yQFEUMbusfaVvQRQoC6yhOSdUU87/ZSvlJrI+E49s3XanUtJZtLThrvnqACnUryt2lC2ezpV9O/2Q== "@types/tapable@*": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.4.tgz#b4ffc7dc97b498c969b360a41eee247f82616370" - integrity sha512-78AdXtlhpCHT0K3EytMpn4JNxaf5tbqbLcbIRoQIHzpTIyjpxLQKRoxU55ujBXAtg3Nl2h/XWvfDa9dsMOd0pQ== + version "1.0.5" + resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.5.tgz#9adbc12950582aa65ead76bffdf39fe0c27a3c02" + integrity sha512-/gG2M/Imw7cQFp8PGvz/SwocNrmKFjFsm5Pb8HdbHkZ1K8pmuPzOX4VeVoiEecFCVf4CsN1r3/BRvx+6sNqwtQ== + +"@types/tapable@^1.0.5": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.6.tgz#a9ca4b70a18b270ccb2bc0aaafefd1d486b7ea74" + integrity sha512-W+bw9ds02rAQaMvaLYxAbJ6cvguW/iJXNT6lTssS1ps6QdrMKttqEAMEG/b5CR8TZl3/L7/lH0ZV5nNR1LXikA== + +"@types/tough-cookie@*": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.0.tgz#fef1904e4668b6e5ecee60c52cc6a078ffa6697d" + integrity sha512-I99sngh224D0M7XgW1s120zxCt3VYQ3IQsuw3P3jbq5GG4yc79+ZjyKznyOGIQrflfylLgcfekeZW/vk0yng6A== "@types/uglify-js@*": version "3.0.4" @@ -309,25 +373,31 @@ source-map "^0.6.1" "@types/uuid@^3.4.6": - version "3.4.6" - resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-3.4.6.tgz#d2c4c48eb85a757bf2927f75f939942d521e3016" - integrity sha512-cCdlC/1kGEZdEglzOieLDYBxHsvEOIg7kp/2FYyVR9Pxakq+Qf/inL3RKQ+PA8gOlI/NnL+fXmQH12nwcGzsHw== + version "3.4.7" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-3.4.7.tgz#51d42247473bc00e38cc8dfaf70d936842a36c03" + integrity sha512-C2j2FWgQkF1ru12SjZJyMaTPxs/f6n90+5G5qNakBxKXjTBc/YTSelHh4Pz1HUDwxFXD9WvpQhOGCDC+/Y4mIQ== + +"@types/vue-moment@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@types/vue-moment/-/vue-moment-4.0.0.tgz#a70ffd56f6834d683710a9a3499224260a4f931b" + integrity sha512-29S5LD5gmQFvkhoKCAseKE036CVOKQGij1QWHCBmTzJwCb4SXvKGbrY1QIn9cAFtnxzkM55+wyjjo/apAfrdTQ== dependencies: - "@types/node" "*" + moment ">=2.24.0" + vue ">=2.6.10" "@types/webpack-sources@*": - version "0.1.5" - resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-0.1.5.tgz#be47c10f783d3d6efe1471ff7f042611bd464a92" - integrity sha512-zfvjpp7jiafSmrzJ2/i3LqOyTYTuJ7u1KOXlKgDlvsj9Rr0x7ZiYu5lZbXwobL7lmsRNtPXlBfmaUD8eU2Hu8w== + version "0.1.6" + resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-0.1.6.tgz#3d21dfc2ec0ad0c77758e79362426a9ba7d7cbcb" + integrity sha512-FtAWR7wR5ocJ9+nP137DV81tveD/ZgB1sadnJ/axUGM3BUVfRPx8oQNMtv3JNfTeHx3VP7cXiyfR/jmtEsVHsQ== dependencies: "@types/node" "*" "@types/source-list-map" "*" source-map "^0.6.1" -"@types/webpack@^4.4.24": - version "4.41.0" - resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.0.tgz#b813a044d8b0dec7dfcd7622fdbe327bde06eb9a" - integrity sha512-tWkdf9nO0zFgAY/EumUKwrDUhraHKDqCPhwfFR/R8l0qnPdgb9le0Gzhvb7uzVpouuDGBgiE//ZdY+5jcZy2TA== +"@types/webpack@^4.4.24", "@types/webpack@^4.4.31": + version "4.41.6" + resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.6.tgz#c76afbdef59159d12e3e1332dc264b75574722a2" + integrity sha512-iWRpV5Ej+8uKrgxp6jXz3v7ZTjgtuMXY+rsxQjFNU0hYCnHkpA7vtiNffgxjuxX4feFHBbz0IF76OzX2OqDYPw== dependencies: "@types/anymatch" "*" "@types/node" "*" @@ -336,10 +406,10 @@ "@types/webpack-sources" "*" source-map "^0.6.0" -"@types/webpack@^4.4.31": - version "4.41.2" - resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.2.tgz#c6faf0111de27afdffe1158dac559e447c273516" - integrity sha512-DNMQOfEvwzWRRyp6Wy9QVCgJ3gkelZsuBE2KUD318dg95s9DKGiT5CszmmV58hq8jk89I9NClre48AEy1MWAJA== +"@types/webpack@^4.41.8": + version "4.41.24" + resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.24.tgz#75b664abe3d5bcfe54e64313ca3b43e498550422" + integrity sha512-1A0MXPwZiMOD3DPMuOKUKcpkdPo8Lq33UGggZ7xio6wJ/jV1dAu5cXDrOfGDnldUroPIRLsr/DT43/GqOA4RFQ== dependencies: "@types/anymatch" "*" "@types/node" "*" @@ -514,6 +584,14 @@ abbrev@1: resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== +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@^6.2.1: version "6.4.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.0.tgz#b659d2ffbafa24baf5db1cdbb2c94a983ecd2784" @@ -530,11 +608,21 @@ ajv-keywords@^3.1.0, ajv-keywords@^3.4.1: integrity sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ== ajv@^6.1.0, ajv@^6.10.2, ajv@^6.5.5: - version "6.10.2" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.2.tgz#d3cea04d6b017b2894ad69040fec8b623eb4bd52" - integrity sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw== + version "6.11.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.11.0.tgz#c3607cbc8ae392d8a5a536f25b21f8e5f3f87fe9" + integrity sha512-nCprB/0syFYy9fVYU1ox1l2KN8S9I+tziH8D4zdZuLT3N6RMlGSGt5FSTpAiHB/Whv8Qs1cWHma1aMKZyaHRKA== dependencies: - fast-deep-equal "^2.0.1" + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ajv@^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" @@ -636,6 +724,11 @@ array-find-index@^1.0.1: 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-union@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" @@ -707,12 +800,17 @@ async-throttle@^1.1.0: resolved "https://registry.yarnpkg.com/async-throttle/-/async-throttle-1.1.0.tgz#229e7f3fa7a2a797e86f360e6309a08224d4fa7a" integrity sha1-Ip5/P6eip5fobzYOYwmggiTU+no= +async@0.9.x: + version "0.9.2" + resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" + integrity sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0= + 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.1: +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== @@ -723,9 +821,9 @@ aws-sign2@~0.7.0: integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= aws4@^1.8.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.0.tgz#24390e6ad61386b0a747265754d2a17219de862c" - integrity sha512-Uvq6hVe90D0B2WEnUqtdgY1bATGz3mw33nH9Y+dmA+w5DHvUmBgkr5rM/KCHpCsiFNRUfokW/szpPPgMK2hm4A== + version "1.9.1" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.1.tgz#7e33d8f7d449b3f673cd72deb9abdc552dbe528e" + integrity sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug== babel-code-frame@^6.26.0: version "6.26.0" @@ -736,31 +834,6 @@ babel-code-frame@^6.26.0: esutils "^2.0.2" js-tokens "^3.0.2" -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-extract-comments@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/babel-extract-comments/-/babel-extract-comments-1.0.0.tgz#0a2aedf81417ed391b85e18b4614e693a0351a21" @@ -768,180 +841,11 @@ babel-extract-comments@^1.0.0: dependencies: babylon "^6.18.0" -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-evaluate-path@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/babel-helper-evaluate-path/-/babel-helper-evaluate-path-0.3.0.tgz#2439545e0b6eae5b7f49b790acbebd6b9a73df20" - integrity sha512-dRFlMTqUJRGzx5a2smKxmptDdNCXKSkPcXWzKLwAV72hvIZumrd/0z9RcewHkr7PmAEq+ETtpD1GK6wZ6ZUXzw== - -babel-helper-flip-expressions@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/babel-helper-flip-expressions/-/babel-helper-flip-expressions-0.3.0.tgz#f5b6394bd5219b43cf8f7b201535ed540c6e7fa2" - integrity sha512-kNGohWmtAG3b7tN1xocRQ5rsKkH/hpvZsMiGOJ1VwGJKhnwzR5KlB3rvKBaBPl5/IGHcopB2JN+r1SUEX1iMAw== - -babel-helper-is-nodes-equiv@^0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/babel-helper-is-nodes-equiv/-/babel-helper-is-nodes-equiv-0.0.1.tgz#34e9b300b1479ddd98ec77ea0bbe9342dfe39684" - integrity sha1-NOmzALFHnd2Y7HfqC76TQt/jloQ= - -babel-helper-is-void-0@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/babel-helper-is-void-0/-/babel-helper-is-void-0-0.3.0.tgz#95570d20bd27b2206f68083ae9980ee7003d8fe7" - integrity sha512-JVqdX8y7Rf/x4NwbqtUI7mdQjL9HWoDnoAEQ8Gv8oxzjvbJv+n75f7l36m9Y8C7sCUltX3V5edndrp7Hp1oSXQ== - -babel-helper-mark-eval-scopes@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/babel-helper-mark-eval-scopes/-/babel-helper-mark-eval-scopes-0.3.0.tgz#b4731314fdd7a89091271a5213b4e12d236e29e8" - integrity sha512-nrho5Dg4vl0VUgURVpGpEGiwbst5JX7efIyDHFxmkCx/ocQFnrPt8ze9Kxl6TKjR29bJ7D/XKY1NMlSxOQJRbQ== - -babel-helper-remove-or-void@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/babel-helper-remove-or-void/-/babel-helper-remove-or-void-0.3.0.tgz#f43c86147c8fcc395a9528cbb31e7ff49d7e16e3" - integrity sha512-D68W1M3ibCcbg0ysh3ww4/O0g10X1CXK720oOuR8kpfY7w0yP4tVcpK7zDmI1JecynycTQYAZ1rhLJo9aVtIKQ== - -babel-helper-to-multiple-sequence-expressions@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/babel-helper-to-multiple-sequence-expressions/-/babel-helper-to-multiple-sequence-expressions-0.3.0.tgz#8da2275ccc26995566118f7213abfd9af7214427" - integrity sha512-1uCrBD+EAaMnAYh7hc944n8Ga19y3daEnoXWPYDvFVsxMCc1l8aDjksApaCEaNSSuewq8BEcff47Cy1PbLg2Gw== - -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-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-minify-webpack-plugin@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/babel-minify-webpack-plugin/-/babel-minify-webpack-plugin-0.3.1.tgz#292aa240af190e2dcadf4f684d6d84d179b6d5a4" - integrity sha512-Johg6Ju0Gxevk2R55eutMqnyXwlyUzCtwunBpiyNzoxGnKum+x5nfNuYZYHGd5Bmc1gmhjwzb7GkxHWOtYWmtQ== - dependencies: - babel-core "^6.26.0" - babel-preset-minify "^0.3.0" - webpack-sources "^1.0.1" - -babel-plugin-minify-builtins@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/babel-plugin-minify-builtins/-/babel-plugin-minify-builtins-0.3.0.tgz#4740117a6a784063aaf8f092989cf9e4bd484860" - integrity sha512-MqhSHlxkmgURqj3144qPksbZ/qof1JWdumcbucc4tysFcf3P3V3z3munTevQgKEFNMd8F5/ECGnwb63xogLjAg== - dependencies: - babel-helper-evaluate-path "^0.3.0" - -babel-plugin-minify-constant-folding@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/babel-plugin-minify-constant-folding/-/babel-plugin-minify-constant-folding-0.3.0.tgz#687e40336bd4ddd921e0e197f0006235ac184bb9" - integrity sha512-1XeRpx+aY1BuNY6QU/cm6P+FtEi3ar3XceYbmC+4q4W+2Ewq5pL7V68oHg1hKXkBIE0Z4/FjSoHz6vosZLOe/A== - dependencies: - babel-helper-evaluate-path "^0.3.0" - -babel-plugin-minify-dead-code-elimination@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/babel-plugin-minify-dead-code-elimination/-/babel-plugin-minify-dead-code-elimination-0.3.0.tgz#a323f686c404b824186ba5583cf7996cac81719e" - integrity sha512-SjM2Fzg85YZz+q/PNJ/HU4O3W98FKFOiP9K5z3sfonlamGOzvZw3Eup2OTiEBsbbqTeY8yzNCAv3qpJRYCgGmw== - dependencies: - babel-helper-evaluate-path "^0.3.0" - babel-helper-mark-eval-scopes "^0.3.0" - babel-helper-remove-or-void "^0.3.0" - lodash.some "^4.6.0" - -babel-plugin-minify-flip-comparisons@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/babel-plugin-minify-flip-comparisons/-/babel-plugin-minify-flip-comparisons-0.3.0.tgz#6627893a409c9f30ef7f2c89e0c6eea7ee97ddc4" - integrity sha512-B8lK+ekcpSNVH7PZpWDe5nC5zxjRiiT4nTsa6h3QkF3Kk6y9qooIFLemdGlqBq6j0zALEnebvCpw8v7gAdpgnw== - dependencies: - babel-helper-is-void-0 "^0.3.0" - -babel-plugin-minify-guarded-expressions@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/babel-plugin-minify-guarded-expressions/-/babel-plugin-minify-guarded-expressions-0.3.0.tgz#2552d96189ef45d9a463f1a6b5e4fa110703ac8d" - integrity sha512-O+6CvF5/Ttsth3LMg4/BhyvVZ82GImeKMXGdVRQGK/8jFiP15EjRpdgFlxv3cnqRjqdYxLCS6r28VfLpb9C/kA== - dependencies: - babel-helper-flip-expressions "^0.3.0" - -babel-plugin-minify-infinity@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/babel-plugin-minify-infinity/-/babel-plugin-minify-infinity-0.3.0.tgz#c5ec0edd433517cf31b3af17077c202beb48bbe7" - integrity sha512-Sj8ia3/w9158DWieUxU6/VvnYVy59geeFEkVgLZYBE8EBP+sN48tHtBM/jSgz0ejEdBlcfqJ6TnvPmVXTzR2BQ== - -babel-plugin-minify-mangle-names@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/babel-plugin-minify-mangle-names/-/babel-plugin-minify-mangle-names-0.3.0.tgz#f28561bad0dd2f0380816816bb946e219b3b6135" - integrity sha512-PYTonhFWURsfAN8achDwvR5Xgy6EeTClLz+fSgGRqjAIXb0OyFm3/xfccbQviVi1qDXmlSnt6oJhBg8KE4Fn7Q== - dependencies: - babel-helper-mark-eval-scopes "^0.3.0" - -babel-plugin-minify-numeric-literals@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/babel-plugin-minify-numeric-literals/-/babel-plugin-minify-numeric-literals-0.3.0.tgz#b57734a612e8a592005407323c321119f27d4b40" - integrity sha512-TgZj6ay8zDw74AS3yiIfoQ8vRSNJisYO/Du60S8nPV7EW7JM6fDMx5Sar6yVHlVuuwNgvDUBh191K33bVrAhpg== - -babel-plugin-minify-replace@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/babel-plugin-minify-replace/-/babel-plugin-minify-replace-0.3.0.tgz#980125bbf7cbb5a637439de9d0b1b030a4693893" - integrity sha512-VR6tTg2Lt0TicHIOw04fsUtpPw7RaRP8PC8YzSFwEixnzvguZjZJoL7TgG7ZyEWQD1cJ96UezswECmFNa815bg== - -babel-plugin-minify-simplify@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/babel-plugin-minify-simplify/-/babel-plugin-minify-simplify-0.3.0.tgz#14574cc74d21c81d3060fafa041010028189f11b" - integrity sha512-2M16ytQOCqBi7bYMu4DCWn8e6KyFCA108F6+tVrBJxOmm5u2sOmTFEa8s94tR9RHRRNYmcUf+rgidfnzL3ik9Q== - dependencies: - babel-helper-flip-expressions "^0.3.0" - babel-helper-is-nodes-equiv "^0.0.1" - babel-helper-to-multiple-sequence-expressions "^0.3.0" - -babel-plugin-minify-type-constructors@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/babel-plugin-minify-type-constructors/-/babel-plugin-minify-type-constructors-0.3.0.tgz#7f5a86ef322c4746364e3c591b8514eeafea6ad4" - integrity sha512-XRXpvsUCPeVw9YEUw+9vSiugcSZfow81oIJT0yR9s8H4W7yJ6FHbImi5DJHoL8KcDUjYnL9wYASXk/fOkbyR6Q== - dependencies: - babel-helper-is-void-0 "^0.3.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-transform-inline-consecutive-adds@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-inline-consecutive-adds/-/babel-plugin-transform-inline-consecutive-adds-0.3.0.tgz#f07d93689c0002ed2b2b62969bdd99f734e03f57" - integrity sha512-iZsYAIjYLLfLK0yN5WVT7Xf7Y3wQ9Z75j9A8q/0IglQSpUt2ppTdHlwl/GeaXnxdaSmsxBu861klbTBbv2n+RA== - -babel-plugin-transform-member-expression-literals@^6.9.0: - version "6.9.4" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-member-expression-literals/-/babel-plugin-transform-member-expression-literals-6.9.4.tgz#37039c9a0c3313a39495faac2ff3a6b5b9d038bf" - integrity sha1-NwOcmgwzE6OUlfqsL/OmtbnQOL8= - -babel-plugin-transform-merge-sibling-variables@^6.9.0: - version "6.9.4" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-merge-sibling-variables/-/babel-plugin-transform-merge-sibling-variables-6.9.4.tgz#85b422fc3377b449c9d1cde44087203532401dae" - integrity sha1-hbQi/DN3tEnJ0c3kQIcgNTJAHa4= - -babel-plugin-transform-minify-booleans@^6.9.0: - version "6.9.4" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-minify-booleans/-/babel-plugin-transform-minify-booleans-6.9.4.tgz#acbb3e56a3555dd23928e4b582d285162dd2b198" - integrity sha1-rLs+VqNVXdI5KOS1gtKFFi3SsZg= - 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" @@ -950,88 +854,7 @@ babel-plugin-transform-object-rest-spread@^6.26.0: babel-plugin-syntax-object-rest-spread "^6.8.0" babel-runtime "^6.26.0" -babel-plugin-transform-property-literals@^6.9.0: - version "6.9.4" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-property-literals/-/babel-plugin-transform-property-literals-6.9.4.tgz#98c1d21e255736573f93ece54459f6ce24985d39" - integrity sha1-mMHSHiVXNlc/k+zlRFn2ziSYXTk= - dependencies: - esutils "^2.0.2" - -babel-plugin-transform-regexp-constructors@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-regexp-constructors/-/babel-plugin-transform-regexp-constructors-0.3.0.tgz#9bb2c8dd082271a5cb1b3a441a7c52e8fd07e0f5" - integrity sha512-h92YHzyl042rb0naKO8frTHntpRFwRgKkfWD8602kFHoQingjJNtbvZzvxqHncJ6XmKVyYvfrBpDOSkCTDIIxw== - -babel-plugin-transform-remove-console@^6.9.0: - version "6.9.4" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-remove-console/-/babel-plugin-transform-remove-console-6.9.4.tgz#b980360c067384e24b357a588d807d3c83527780" - integrity sha1-uYA2DAZzhOJLNXpYjYB9PINSd4A= - -babel-plugin-transform-remove-debugger@^6.9.0: - version "6.9.4" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-remove-debugger/-/babel-plugin-transform-remove-debugger-6.9.4.tgz#42b727631c97978e1eb2d199a7aec84a18339ef2" - integrity sha1-QrcnYxyXl44estGZp67IShgznvI= - -babel-plugin-transform-remove-undefined@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-remove-undefined/-/babel-plugin-transform-remove-undefined-0.3.0.tgz#03f5f0071867781e9beabbc7b77bf8095fd3f3ec" - integrity sha512-TYGQucc8iP3LJwN3kDZLEz5aa/2KuFrqpT+s8f8NnHsBU1sAgR3y8Opns0xhC+smyDYWscqFCKM1gbkWQOhhnw== - dependencies: - babel-helper-evaluate-path "^0.3.0" - -babel-plugin-transform-simplify-comparison-operators@^6.9.0: - version "6.9.4" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-simplify-comparison-operators/-/babel-plugin-transform-simplify-comparison-operators-6.9.4.tgz#f62afe096cab0e1f68a2d753fdf283888471ceb9" - integrity sha1-9ir+CWyrDh9ootdT/fKDiIRxzrk= - -babel-plugin-transform-undefined-to-void@^6.9.0: - version "6.9.4" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-undefined-to-void/-/babel-plugin-transform-undefined-to-void-6.9.4.tgz#be241ca81404030678b748717322b89d0c8fe280" - integrity sha1-viQcqBQEAwZ4t0hxcyK4nQyP4oA= - -babel-preset-minify@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/babel-preset-minify/-/babel-preset-minify-0.3.0.tgz#7db64afa75f16f6e06c0aa5f25195f6f36784d77" - integrity sha512-+VV2GWEyak3eDOmzT1DDMuqHrw3VbE9nBNkx2LLVs4pH/Me32ND8DRpVDd8IRvk1xX5p75nygyRPtkMh6GIAbQ== - dependencies: - babel-plugin-minify-builtins "^0.3.0" - babel-plugin-minify-constant-folding "^0.3.0" - babel-plugin-minify-dead-code-elimination "^0.3.0" - babel-plugin-minify-flip-comparisons "^0.3.0" - babel-plugin-minify-guarded-expressions "^0.3.0" - babel-plugin-minify-infinity "^0.3.0" - babel-plugin-minify-mangle-names "^0.3.0" - babel-plugin-minify-numeric-literals "^0.3.0" - babel-plugin-minify-replace "^0.3.0" - babel-plugin-minify-simplify "^0.3.0" - babel-plugin-minify-type-constructors "^0.3.0" - babel-plugin-transform-inline-consecutive-adds "^0.3.0" - babel-plugin-transform-member-expression-literals "^6.9.0" - babel-plugin-transform-merge-sibling-variables "^6.9.0" - babel-plugin-transform-minify-booleans "^6.9.0" - babel-plugin-transform-property-literals "^6.9.0" - babel-plugin-transform-regexp-constructors "^0.3.0" - babel-plugin-transform-remove-console "^6.9.0" - babel-plugin-transform-remove-debugger "^6.9.0" - babel-plugin-transform-remove-undefined "^0.3.0" - babel-plugin-transform-simplify-comparison-operators "^6.9.0" - babel-plugin-transform-undefined-to-void "^6.9.0" - lodash.isplainobject "^4.0.6" - -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.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: +babel-runtime@^6.18.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= @@ -1039,42 +862,6 @@ babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: core-js "^2.4.0" regenerator-runtime "^0.11.0" -babel-template@^6.24.1, babel-template@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" - 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.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.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.18.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" @@ -1168,6 +955,13 @@ binary-extensions@^1.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== +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" + bl@^1.0.0: version "1.2.2" resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.2.tgz#a160911717103c07410cef63ef51b397c025af9c" @@ -1193,12 +987,28 @@ bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== +body-parser@1.19.0: + version "1.19.0" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" + integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== + dependencies: + bytes "3.1.0" + content-type "~1.0.4" + debug "2.6.9" + depd "~1.1.2" + http-errors "1.7.2" + iconv-lite "0.4.24" + on-finished "~2.3.0" + qs "6.7.0" + raw-body "2.4.0" + type-is "~1.6.17" + boolbase@^1.0.0, 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= -bootstrap@^4.1.3: +bootstrap@^4.3.1: version "4.4.1" resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.4.1.tgz#8582960eea0c5cd2bede84d8b0baf3789c3e8b01" integrity sha512-tbx5cHubwE6e2ZG7nqM3g/FZ5PQEDMWmMGNrCUBVRPHXTJaH7CBDdsLeu3eCh3B1tzAxTnAbtmrzvWEvT2NNEA== @@ -1346,6 +1156,11 @@ builtin-status-codes@^3.0.0: resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= +bytes@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" + integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== + cacache@^10.0.4: version "10.0.4" resolved "https://registry.yarnpkg.com/cacache/-/cacache-10.0.4.tgz#6452367999eff9d4188aefd9a14e9d7c6a263460" @@ -1419,6 +1234,14 @@ call-me-maybe@^1.0.1: resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" integrity sha1-JtII6onje1y95gJQoV8DHBak1ms= +camel-case@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.1.tgz#1fc41c854f00e2f7d0139dfeba1542d6896fe547" + integrity sha512-7fa2WcG4fYFkclIvEmxBbTvmibwF2/agfEBc6q3lOpVu0A13ltLsA+Hr/8Hp6kp5f+G7hKi6t8lys6XxP+1K6Q== + dependencies: + pascal-case "^3.1.1" + tslib "^1.10.0" + camelcase-keys@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" @@ -1465,7 +1288,7 @@ caw@^2.0.0, caw@^2.0.1: tunnel-agent "^0.6.0" url-to-options "^1.0.1" -chalk@2.4.2, chalk@^2.3.0, chalk@^2.4.1: +chalk@2.4.2, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -1534,6 +1357,13 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" +clean-css@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.3.tgz#507b5de7d97b48ee53d84adb0160ff6216380f78" + integrity sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA== + dependencies: + source-map "~0.6.0" + clean-webpack-plugin@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/clean-webpack-plugin/-/clean-webpack-plugin-3.0.0.tgz#a99d8ec34c1c628a4541567aa7b457446460c62b" @@ -1622,6 +1452,11 @@ commander@^2.20.0: resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== +commander@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" + integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== + commander@~2.8.1: version "2.8.1" resolved "https://registry.yarnpkg.com/commander/-/commander-2.8.1.tgz#06be367febfda0c330aa1e2a072d3dc9762425d4" @@ -1687,19 +1522,27 @@ constants-browserify@^1.0.0: resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= -content-disposition@^0.5.2: +content-disposition@0.5.3, content-disposition@^0.5.2: version "0.5.3" resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== dependencies: safe-buffer "5.1.2" -convert-source-map@^1.5.1: - version "1.7.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" - integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== - dependencies: - safe-buffer "~5.1.1" +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== + +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.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" + integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== copy-concurrently@^1.0.0: version "1.0.5" @@ -1732,10 +1575,10 @@ copy-webpack-plugin@^4.5.2: p-limit "^1.0.0" serialize-javascript "^1.4.0" -core-js@^2.4.0, core-js@^2.5.0: - version "2.6.10" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.10.tgz#8a5b8391f8cc7013da703411ce5b585706300d7f" - integrity sha512-I39t74+4t+zau64EN1fE5v2W31Adtc/REhzWN+gWRRXg6WH5qAsZm62DHpQ1+Yhe4047T55jvzz7MUqF/dBBlA== +core-js@^2.4.0: + version "2.6.11" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.11.tgz#38831469f9922bded8ee21c9dc46985e0399308c" + integrity sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg== core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" @@ -1841,6 +1684,16 @@ css-select-base-adapter@^0.1.1: resolved "https://registry.yarnpkg.com/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz#3b2ff4972cc362ab88561507a95408a1432135d7" integrity sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w== +css-select@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" + integrity sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg= + dependencies: + boolbase "~1.0.0" + css-what "2.1" + domutils "1.5.1" + nth-check "~1.0.1" + css-select@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/css-select/-/css-select-2.1.0.tgz#6a34653356635934a81baca68d0255432105dbef" @@ -1868,6 +1721,11 @@ css-tree@1.0.0-alpha.37: mdn-data "2.0.4" source-map "^0.6.1" +css-what@2.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2" + integrity sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg== + css-what@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.2.1.tgz#f4a8f12421064621b456755e34a03a2c22df5da1" @@ -1909,20 +1767,13 @@ dashdash@^1.12.0: dependencies: assert-plus "^1.0.0" -debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: +debug@2.6.9, debug@^2.2.0, debug@^2.3.3: 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.2.6: - version "3.2.6" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" - integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== - dependencies: - ms "^2.1.1" - decamelize@^1.1.1, decamelize@^1.1.2, decamelize@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" @@ -1993,11 +1844,6 @@ decompress@^4.0.0, decompress@^4.2.0: pify "^2.3.0" strip-dirs "^2.0.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== - define-properties@^1.1.2, define-properties@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" @@ -2050,6 +1896,11 @@ delegates@^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" @@ -2058,23 +1909,16 @@ des.js@^1.0.0: 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-file@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7" integrity sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc= -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= - diffie-hellman@^5.0.0: version "5.0.3" resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" @@ -2099,6 +1943,13 @@ dir-glob@^2.0.0: dependencies: path-type "^3.0.0" +dom-converter@^0.2: + 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@0: version "0.2.2" resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51" @@ -2112,7 +1963,7 @@ domain-browser@^1.1.1: resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== -domelementtype@1: +domelementtype@1, domelementtype@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== @@ -2122,7 +1973,22 @@ domelementtype@^2.0.1: resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.0.1.tgz#1f8bdfe91f5a78063274e803b4bdcedf6e94f94d" integrity sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ== -domutils@^1.7.0: +domhandler@^2.3.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" + integrity sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA== + dependencies: + domelementtype "1" + +domutils@1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" + integrity sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8= + dependencies: + dom-serializer "0" + domelementtype "1" + +domutils@^1.5.1, domutils@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== @@ -2130,6 +1996,14 @@ domutils@^1.7.0: dom-serializer "0" domelementtype "1" +dot-case@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.3.tgz#21d3b52efaaba2ea5fda875bb1aa8124521cf4aa" + integrity sha512-7hwEmg6RiSQfm/GwPL4AAWXKy3YNNZA3oFv2Pdiey0mwkRCPZ9x6SZbkLcn8Ma5PYeVokzoD4Twv2n7LKp5WeA== + dependencies: + no-case "^3.0.3" + tslib "^1.10.0" + download@^6.2.2: version "6.2.5" resolved "https://registry.yarnpkg.com/download/-/download-6.2.5.tgz#acd6a542e4cd0bb42ca70cfc98c9e43b07039714" @@ -2180,7 +2054,7 @@ duplexify@^3.4.2, duplexify@^3.6.0: readable-stream "^2.0.0" stream-shift "^1.0.0" -earcut@^2.2.0: +earcut@^2.2.2: version "2.2.2" resolved "https://registry.yarnpkg.com/earcut/-/earcut-2.2.2.tgz#41b0bc35f63e0fe80da7cddff28511e7e2e80d11" integrity sha512-eZoZPPJcUHnfRZ0PjLvx2qBordSiO8ofC3vt+qACLM95u+4DovnbYNpQtJh0DNsWj8RnxrQytD4WA8gj5cRIaQ== @@ -2193,6 +2067,18 @@ ecc-jsbn@~0.1.1: 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= + +ejs@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.5.tgz#aed723844dc20acb4b170cd9ab1017e476a0d93b" + integrity sha512-dldq3ZfFtgVTJMLjOe+/3sROTzALlL9E34V4/sDtUd/KlBSS0s6U1/+WPE1B4sj9CXHJpL1M6rhNJnc9Wbal9w== + dependencies: + jake "^10.6.1" + elliptic@^6.0.0: version "6.5.2" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.2.tgz#05c5678d7173c049d8ca433552224a495d0e3762" @@ -2216,6 +2102,11 @@ emojis-list@^2.0.0: resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k= +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + end-of-stream@^1.0.0, end-of-stream@^1.1.0: version "1.4.4" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" @@ -2241,6 +2132,11 @@ enhanced-resolve@^4.0.0, enhanced-resolve@^4.1.0: memory-fs "^0.5.0" tapable "^1.0.0" +entities@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" + integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== + entities@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.0.tgz#68d6084cab1b079767540d80e56a39b423e4abf4" @@ -2260,21 +2156,22 @@ error-ex@^1.2.0: dependencies: is-arrayish "^0.2.1" -es-abstract@^1.12.0, es-abstract@^1.5.1: - version "1.16.3" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.16.3.tgz#52490d978f96ff9f89ec15b5cf244304a5bca161" - integrity sha512-WtY7Fx5LiOnSYgF5eg/1T+GONaGmpvpPdCpSnYij+U2gDTL0UPfWrhDw7b2IYb+9NQJsYpCA0wOQvZfsd6YwRw== +es-abstract@^1.17.0-next.1, es-abstract@^1.17.2: + version "1.17.4" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.4.tgz#e3aedf19706b20e7c2594c35fc0d57605a79e184" + integrity sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ== dependencies: es-to-primitive "^1.2.1" function-bind "^1.1.1" has "^1.0.3" has-symbols "^1.0.1" - is-callable "^1.1.4" - is-regex "^1.0.4" + is-callable "^1.1.5" + is-regex "^1.0.5" object-inspect "^1.7.0" object-keys "^1.1.1" - string.prototype.trimleft "^2.1.0" - string.prototype.trimright "^2.1.0" + object.assign "^4.1.0" + string.prototype.trimleft "^2.1.1" + string.prototype.trimright "^2.1.1" es-to-primitive@^1.2.1: version "1.2.1" @@ -2285,6 +2182,11 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" +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.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" @@ -2325,10 +2227,15 @@ esutils@^2.0.2: 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= + events@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/events/-/events-3.0.0.tgz#9a0a0dfaf62893d92b875b8f2698ca4114973e88" - integrity sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA== + version "3.1.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.1.0.tgz#84279af1b34cb75aa88bf5ff291f6d0bd9b31a59" + integrity sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg== evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: version "1.0.3" @@ -2415,6 +2322,42 @@ expand-tilde@^2.0.0, expand-tilde@^2.0.2: dependencies: homedir-polyfill "^1.0.1" +express@^4.17.1: + version "4.17.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" + integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== + dependencies: + accepts "~1.3.7" + array-flatten "1.1.1" + body-parser "1.19.0" + content-disposition "0.5.3" + content-type "~1.0.4" + cookie "0.4.0" + 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.5" + qs "6.7.0" + range-parser "~1.2.1" + safe-buffer "5.1.2" + send "0.17.1" + serve-static "1.14.1" + setprototypeof "1.1.1" + statuses "~1.5.0" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + ext-list@^2.0.0: version "2.2.2" resolved "https://registry.yarnpkg.com/ext-list/-/ext-list-2.2.2.tgz#0b98e64ed82f5acf0f2931babf69212ef52ddd37" @@ -2474,10 +2417,10 @@ extsprintf@^1.2.0: resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= -fast-deep-equal@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" - integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= +fast-deep-equal@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4" + integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA== fast-glob@^2.0.2: version "2.2.7" @@ -2492,9 +2435,9 @@ fast-glob@^2.0.2: micromatch "^3.1.10" fast-json-stable-stringify@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" - integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= + 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== fastparse@^1.1.1: version "1.1.2" @@ -2559,6 +2502,18 @@ file-type@^8.1.0: resolved "https://registry.yarnpkg.com/file-type/-/file-type-8.1.0.tgz#244f3b7ef641bbe0cca196c7276e4b332399f68c" integrity sha512-qyQ0pzAy78gVoJsmYeNgl8uH8yKhr1lVhW7JbzJmnlRi0I4R2eEDEJZVKG8agpDnLpacwNbDhLNG/LMdxHD2YQ== +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== + +filelist@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.1.tgz#f10d1a3ae86c1694808e8f20906f43d4c9132dbb" + integrity sha512-8zSK6Nu0DQIC08mUC46sWGXi+q3GGpKydAG36k+JDba6VRpkevvOWUW5a/PhShij4+vHT9M+ghgG7eM+a9JDUQ== + dependencies: + minimatch "^3.0.4" + filename-reserved-regex@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz#abf73dfab735d045440abfea2d91f389ebbfa229" @@ -2583,6 +2538,19 @@ fill-range@^4.0.0: repeat-string "^1.6.1" to-regex-range "^2.1.0" +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@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-1.0.0.tgz#9288e3e9e3cc3748717d39eade17cf71fc30ee6f" @@ -2663,6 +2631,15 @@ forever-agent@~0.6.1: resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= +form-data@^2.5.0: + version "2.5.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" + integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + 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" @@ -2672,6 +2649,11 @@ form-data@~2.3.2: combined-stream "^1.0.6" mime-types "^2.1.12" +forwarded@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" + integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= + fragment-cache@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" @@ -2679,6 +2661,11 @@ fragment-cache@^0.2.1: 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= + from2@^2.1.0, from2@^2.1.1: version "2.3.0" resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" @@ -2701,13 +2688,6 @@ fs-extra@^4.0.2: jsonfile "^4.0.0" universalify "^0.1.0" -fs-minipass@^1.2.5: - version "1.2.7" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" - integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== - dependencies: - minipass "^2.6.0" - fs-write-stream-atomic@^1.0.8: version "1.0.10" resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" @@ -2724,12 +2704,12 @@ fs.realpath@^1.0.0: integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= fsevents@^1.2.7: - version "1.2.9" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.9.tgz#3f5ed66583ccd6f400b5a00db6f7e861363e388f" - integrity sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw== + version "1.2.11" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.11.tgz#67bf57f4758f02ede88fb2a1712fef4d15358be3" + integrity sha512-+ux3lx6peh0BpvY0JebGyZoiR4D+oYzdPZMKJwkZ+sFkNJzpL7tXc/wehS49gUAxg3tmMHPHZkA8JU2rhhgDHw== dependencies: + bindings "^1.5.0" nan "^2.12.1" - node-pre-gyp "^0.12.0" fstream@^1.0.0, fstream@^1.0.12: version "1.0.12" @@ -2783,9 +2763,9 @@ get-caller-file@^2.0.1: integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== get-own-enumerable-property-symbols@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.1.tgz#6f7764f88ea11e0b514bd9bd860a132259992ca4" - integrity sha512-09/VS4iek66Dh2bctjRkowueRJbY1JDGR1L/zRxO1Qk8Uxs6PnqaNSqalpizPT+CDjre3hnEsuzvhgomz9qYrA== + version "3.0.2" + resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" + integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g== get-proxy@^2.0.0: version "2.1.0" @@ -2907,11 +2887,6 @@ global-prefix@^3.0.0: kind-of "^6.0.2" which "^1.3.1" -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@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" @@ -2949,9 +2924,9 @@ globby@^8.0.1: slash "^1.0.0" globule@^1.0.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/globule/-/globule-1.2.1.tgz#5dffb1b191f22d20797a9369b49eab4e9839696d" - integrity sha512-g7QtgWF4uYSL5/dn71WxubOrS7JVGCnFPEnoeChJmBnyR9Mw8nGoEwOgJL/RC2Te0WhbsEUCejfH8SZNJ+adYQ== + version "1.3.0" + resolved "https://registry.yarnpkg.com/globule/-/globule-1.3.0.tgz#41d0e9fb44afd4b80d93a23263714f90b3dec904" + integrity sha512-YlD4kdMqRCQHrhVdonet4TdRtv1/sZKepvoxNT4Nrhrp5HI8XFfc8kFlGlBn2myBo80aGp8Eft259mbcUJhgSg== dependencies: glob "~7.1.1" lodash "~4.17.10" @@ -3028,6 +3003,14 @@ har-validator@~5.1.0: ajv "^6.5.5" har-schema "^2.0.0" +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" @@ -3045,7 +3028,7 @@ has-symbol-support-x@^1.4.1: resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455" integrity sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw== -has-symbols@^1.0.1: +has-symbols@^1.0.0, has-symbols@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== @@ -3093,7 +3076,7 @@ has-values@^1.0.0: is-number "^3.0.0" kind-of "^4.0.0" -has@^1.0.1, has@^1.0.3: +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== @@ -3116,6 +3099,11 @@ hash.js@^1.0.0, hash.js@^1.0.3: inherits "^2.0.3" minimalistic-assert "^1.0.1" +he@^1.2.0: + 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.0: version "1.0.1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" @@ -3125,14 +3113,6 @@ hmac-drbg@^1.0.0: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.1" -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" @@ -3150,11 +3130,73 @@ html-comment-regex@^1.1.0: resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.2.tgz#97d4688aeb5c81886a364faa0cad1dda14d433a7" integrity sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ== +html-minifier-terser@^5.0.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz#922e96f1f3bb60832c2634b79884096389b1f054" + integrity sha512-ZPr5MNObqnV/T9akshPKbVgyOqLmy+Bxo7juKCfTfnjNniTAMdy4hz21YQqoofMBJD2kdREaqPPdThoR78Tgxg== + dependencies: + camel-case "^4.1.1" + clean-css "^4.2.3" + commander "^4.1.1" + he "^1.2.0" + param-case "^3.0.3" + relateurl "^0.2.7" + terser "^4.6.3" + +html-webpack-plugin@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-4.5.0.tgz#625097650886b97ea5dae331c320e3238f6c121c" + integrity sha512-MouoXEYSjTzCrjIxWwg8gxL5fE2X2WZJLmBYXlaJhQUH5K/b5OrqmV7T4dB7iu0xkmJ6JlUuV6fFVtnqbPopZw== + dependencies: + "@types/html-minifier-terser" "^5.0.0" + "@types/tapable" "^1.0.5" + "@types/webpack" "^4.41.8" + html-minifier-terser "^5.0.1" + loader-utils "^1.2.3" + lodash "^4.17.15" + pretty-error "^2.1.1" + tapable "^1.1.3" + util.promisify "1.0.0" + +htmlparser2@^3.3.0: + version "3.10.1" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f" + integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ== + 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" + http-cache-semantics@3.8.1: version "3.8.1" resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2" integrity sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w== +http-errors@1.7.2: + version "1.7.2" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" + integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + +http-errors@~1.7.2: + version "1.7.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" + integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + http-signature@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" @@ -3169,7 +3211,7 @@ https-browserify@^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.4: +iconv-lite@0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== @@ -3198,13 +3240,6 @@ iferr@^0.1.5: resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= -ignore-walk@^3.0.1: - version "3.0.3" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.3.tgz#017e2447184bfeade7c238e4aefdd1e8f95b1e37" - integrity sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw== - dependencies: - minimatch "^3.0.4" - ignore@^3.3.5: version "3.3.10" resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" @@ -3334,7 +3369,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, 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== @@ -3349,7 +3384,7 @@ inherits@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.5, ini@~1.3.0: +ini@^1.3.4, ini@^1.3.5: version "1.3.5" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== @@ -3367,13 +3402,6 @@ into-stream@^3.1.0: from2 "^2.1.1" p-is-promise "^1.1.0" -invariant@^2.2.2: - 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" @@ -3384,6 +3412,11 @@ invert-kv@^2.0.0: resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== +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-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" @@ -3415,10 +3448,10 @@ is-buffer@^1.1.5: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== -is-callable@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" - integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA== +is-callable@^1.1.4, is-callable@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab" + integrity sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q== is-data-descriptor@^0.1.4: version "0.1.4" @@ -3435,9 +3468,9 @@ is-data-descriptor@^1.0.0: kind-of "^6.0.0" is-date-object@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" - integrity sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY= + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" + integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== is-descriptor@^0.1.0: version "0.1.6" @@ -3475,11 +3508,9 @@ is-extglob@^2.1.0, is-extglob@^2.1.1: integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= is-finite@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" - integrity sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko= - dependencies: - number-is-nan "^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" @@ -3577,12 +3608,12 @@ is-png@^1.0.0: resolved "https://registry.yarnpkg.com/is-png/-/is-png-1.1.0.tgz#d574b12bf275c0350455570b0e5b57ab062077ce" integrity sha1-1XSxK/J1wDUEVVcLDltXqwYgd84= -is-regex@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" - integrity sha1-VRdIm1RwkbCTDglWVM7SXul+lJE= +is-regex@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae" + integrity sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ== dependencies: - has "^1.0.1" + has "^1.0.3" is-regexp@^1.0.0: version "1.0.0" @@ -3668,6 +3699,16 @@ isurl@^1.0.0-alpha5: has-to-string-tag-x "^1.2.0" is-object "^1.0.1" +jake@^10.6.1: + version "10.8.2" + resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.2.tgz#ebc9de8558160a66d82d0eadc6a2e58fbc500a7b" + integrity sha512-eLpKyrfG3mzvGE2Du8VoPbeSkRry093+tyNjdYaBbJS9v17knImYGNXQCUV0gLxQtF82m3E8iRb/wdSQZLoq7A== + dependencies: + async "0.9.x" + chalk "^2.4.2" + filelist "^1.0.1" + minimatch "^3.0.4" + jpegtran-bin@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/jpegtran-bin/-/jpegtran-bin-4.0.0.tgz#d00aed809fba7aa6f30817e59eee4ddf198f8f10" @@ -3687,11 +3728,6 @@ js-base64@^2.1.8: resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.5.1.tgz#1efa39ef2c5f7980bb1784ade4a8af2de3291121" integrity sha512-M7kLczedRMYX4L8Mdh4MzyAMM9O5osx+4FcOQuTvr3A9F2D9S5JXheN0ewNbrvK2UatkTRhL5ejGmGSjNMiZuw== -"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-tokens@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" @@ -3710,11 +3746,6 @@ jsbn@~0.1.0: resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= -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" @@ -3752,11 +3783,6 @@ json-stringify-safe@~5.0.1: resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= -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" @@ -3818,9 +3844,9 @@ kind-of@^5.0.0: integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== kind-of@^6.0.0, kind-of@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" - integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== + 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== lcid@^1.0.0: version "1.0.0" @@ -3887,11 +3913,6 @@ lodash._reinterpolate@^3.0.0: resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= -lodash.isplainobject@^4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" - integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs= - lodash.map@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash.map/-/lodash.map-4.6.0.tgz#771ec7839e3473d9c4cde28b19394c3562f4f6d3" @@ -3902,11 +3923,6 @@ lodash.merge@^4.6.2: resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== -lodash.some@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d" - integrity sha1-G7nzFO9ri63tE7VJFpsqlF62jk0= - lodash.template@^4.4.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab" @@ -3922,11 +3938,16 @@ lodash.templatesettings@^4.0.0: dependencies: lodash._reinterpolate "^3.0.0" -lodash@^4.0.0, lodash@^4.17.11, lodash@^4.17.15, lodash@^4.17.4, lodash@~4.17.10: +lodash@^4.0.0, lodash@^4.17.11, lodash@^4.17.15, lodash@~4.17.10: version "4.17.15" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== +lodash@^4.17.20: + version "4.17.20" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" + integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== + logalot@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/logalot/-/logalot-2.1.0.tgz#5f8e8c90d304edf12530951a5554abb8c5e3f552" @@ -3940,13 +3961,6 @@ longest@^1.0.0: resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" integrity sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc= -loose-envify@^1.0.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" @@ -3955,6 +3969,13 @@ loud-rejection@^1.0.0: currently-unhandled "^0.4.1" signal-exit "^3.0.0" +lower-case@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.1.tgz#39eeb36e396115cc05e29422eaea9e692c9408c7" + integrity sha512-LiWgfDLLb1dwbFQZsSglpRj+1ctGnayXz3Uv0/WO8n558JycT5fg6zkNcnW0G68Nn0aEldTFeEfmjCfmqry/rQ== + dependencies: + tslib "^1.10.0" + lowercase-keys@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" @@ -4040,9 +4061,9 @@ mapbox-gl-leaflet@^0.0.11: integrity sha512-3jXZbQaZf/6D3lzv2PBHZsDvlT5wWt7bdm/zDDq6aKJ3n90PGQ+hyBY6Zav0z93Fy0PBHtOsx84Y5MVBA7si5Q== mapbox-gl@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/mapbox-gl/-/mapbox-gl-1.6.1.tgz#bc9beb2d7d6464b0d281a225a3f23bd3a84d9f49" - integrity sha512-qUvu8c/WX0woSLj8M64eK8351th4RI2+grGJ0ZlFb5ELEJNTb4SqMX/4uxRkb5d1euh2U72+AML1QOZjQnUPUw== + version "1.7.0" + resolved "https://registry.yarnpkg.com/mapbox-gl/-/mapbox-gl-1.7.0.tgz#b23a223af61f0c5066c6fa8072f599209b609cc9" + integrity sha512-iVZQUdhZzeVCE8VlELo24GfGqhAzjouiJl1K4rcfk9mtyJLCbWHlzGT6H5Bs61A/3NQXsSx54GdJXAWvebtFFg== dependencies: "@mapbox/geojson-rewind" "^0.4.0" "@mapbox/geojson-types" "^1.0.2" @@ -4054,7 +4075,7 @@ mapbox-gl@^1.6.1: "@mapbox/vector-tile" "^1.3.1" "@mapbox/whoots-js" "^3.1.0" csscolorparser "~1.0.2" - earcut "^2.2.0" + earcut "^2.2.2" geojson-vt "^3.2.1" gl-matrix "^3.0.0" grid-index "^1.1.0" @@ -4082,6 +4103,11 @@ mdn-data@2.0.4: resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.4.tgz#699b3c38ac6f1d728091a64650b65d388502fd5b" integrity sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA== +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= + mem@^4.0.0: version "4.3.0" resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178" @@ -4123,11 +4149,21 @@ meow@^3.3.0, meow@^3.7.0: 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= + merge2@^1.2.3: version "1.3.0" resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.3.0.tgz#5b366ee83b2f1582c48f87e47cf1a9352103ca81" integrity sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw== +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@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" @@ -4155,17 +4191,34 @@ miller-rabin@^4.0.0: bn.js "^4.0.0" brorand "^1.0.1" -mime-db@1.42.0, mime-db@^1.28.0: - version "1.42.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.42.0.tgz#3e252907b4c7adb906597b4b65636272cf9e7bac" - integrity sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ== +mime-db@1.43.0, mime-db@^1.28.0: + version "1.43.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.43.0.tgz#0a12e0502650e473d735535050e7c8f4eb4fae58" + integrity sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ== + +mime-db@1.44.0: + version "1.44.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" + integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== mime-types@^2.1.12, mime-types@~2.1.19: - version "2.1.25" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.25.tgz#39772d46621f93e2a80a856c53b86a62156a6437" - integrity sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg== + version "2.1.26" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.26.tgz#9c921fc09b7e149a65dfdc0da4d20997200b0a06" + integrity sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ== dependencies: - mime-db "1.42.0" + mime-db "1.43.0" + +mime-types@~2.1.24: + version "2.1.27" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" + integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== + dependencies: + mime-db "1.44.0" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== mimic-fn@^2.0.0: version "2.1.0" @@ -4218,21 +4271,6 @@ minimist@1.2.0, minimist@^1.1.3, minimist@^1.2.0: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= -minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" - integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== - dependencies: - safe-buffer "^5.1.2" - yallist "^3.0.0" - -minizlib@^1.2.1: - version "1.3.3" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" - integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== - dependencies: - minipass "^2.9.0" - mississippi@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-2.0.0.tgz#3442a508fafc28500486feea99409676e4ee5a6f" @@ -4280,7 +4318,7 @@ mixin-deep@^1.2.0: dependencies: minimist "0.0.8" -moment@*, moment@^2.22.2: +moment@*, moment@>=2.24.0, moment@^2.19.2, moment@^2.22.2: version "2.24.0" resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b" integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg== @@ -4302,10 +4340,10 @@ ms@2.0.0: resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= -ms@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +ms@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== murmurhash-js@^1.0.0: version "1.0.0" @@ -4334,14 +4372,10 @@ nanomatch@^1.2.9: snapdragon "^0.8.1" to-regex "^3.0.1" -needle@^2.2.1: - version "2.4.0" - resolved "https://registry.yarnpkg.com/needle/-/needle-2.4.0.tgz#6833e74975c444642590e15a750288c5f939b57c" - integrity sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg== - dependencies: - debug "^3.2.6" - iconv-lite "^0.4.4" - sax "^1.2.4" +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.1: version "2.6.1" @@ -4353,6 +4387,14 @@ nice-try@^1.0.4: resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== +no-case@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.3.tgz#c21b434c1ffe48b39087e86cfb4d2582e9df18f8" + integrity sha512-ehY/mVQCf9BL0gKfsJBvFJen+1V//U+0HQMPrWct40ixE4jnv0bfvxDbWtAHL9EcaPEOJHVVYKoQn1TlZUB8Tw== + dependencies: + lower-case "^2.0.1" + tslib "^1.10.0" + node-gyp@^3.8.0: version "3.8.0" resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.8.0.tgz#540304261c330e80d0d5edce253a68cb3964218c" @@ -4400,26 +4442,10 @@ node-libs-browser@^2.2.1: util "^0.11.0" vm-browserify "^1.0.1" -node-pre-gyp@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz#39ba4bb1439da030295f899e3b520b7785766149" - integrity sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A== - dependencies: - detect-libc "^1.0.2" - mkdirp "^0.5.1" - needle "^2.2.1" - nopt "^4.0.1" - npm-packlist "^1.1.6" - npmlog "^4.0.2" - rc "^1.2.7" - rimraf "^2.6.1" - semver "^5.3.0" - tar "^4" - node-sass@^4.9.3: - version "4.13.0" - resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.13.0.tgz#b647288babdd6a1cb726de4545516b31f90da066" - integrity sha512-W1XBrvoJ1dy7VsvTAS5q1V45lREbTlZQqFbiHb3R3OTTCma0XBtuG6xZ6Z4506nR4lmHPTqVRwxT6KgtWC97CA== + version "4.13.1" + resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.13.1.tgz#9db5689696bb2eec2c32b98bfea4c7a2e992d0a3" + integrity sha512-TTWFx+ZhyDx1Biiez2nB0L3YrCZ/8oHagaDalbuBSlqXgUPsdkUSzJsVxeDO9LtPB49+Fh3WQl3slABo6AotNw== dependencies: async-foreach "^0.1.3" chalk "^1.1.1" @@ -4446,14 +4472,6 @@ node-sass@^4.9.3: dependencies: abbrev "1" -nopt@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" - integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00= - 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" @@ -4485,11 +4503,6 @@ normalize-url@2.0.1: query-string "^5.0.1" sort-keys "^2.0.0" -npm-bundled@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.0.tgz#2e8fdb7e69eff2df963937b696243316537c284b" - integrity sha512-ez6dcKBFNo4FvlMqscBEFUum6M2FTLW5grqm3DyBKB5XOyKVCeeWvAuoZtbmW/5Cv8EM2bQUOA6ufxa/TKVN0g== - npm-conf@^1.1.0: version "1.1.3" resolved "https://registry.yarnpkg.com/npm-conf/-/npm-conf-1.1.3.tgz#256cc47bd0e218c259c4e9550bf413bc2192aff9" @@ -4498,14 +4511,6 @@ npm-conf@^1.1.0: config-chain "^1.1.11" pify "^3.0.0" -npm-packlist@^1.1.6: - version "1.4.6" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.6.tgz#53ba3ed11f8523079f1457376dd379ee4ea42ff4" - integrity sha512-u65uQdb+qwtGvEJh/DgQgW1Xg7sqeNbmxYyrvlNznaVTjV3E5P6F/EFjM+BVHXl7JJlsdG8A64M0XI8FI/IOlg== - dependencies: - ignore-walk "^3.0.1" - npm-bundled "^1.0.1" - npm-run-path@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" @@ -4513,7 +4518,7 @@ npm-run-path@^2.0.0: dependencies: path-key "^2.0.0" -"npmlog@0 || 1 || 2 || 3 || 4", npmlog@^4.0.0, npmlog@^4.0.2: +"npmlog@0 || 1 || 2 || 3 || 4", npmlog@^4.0.0: version "4.1.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== @@ -4523,7 +4528,7 @@ npm-run-path@^2.0.0: gauge "~2.7.3" set-blocking "~2.0.0" -nth-check@^1.0.2: +nth-check@^1.0.2, nth-check@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg== @@ -4559,7 +4564,7 @@ object-inspect@^1.7.0: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67" integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw== -object-keys@^1.0.12, object-keys@^1.1.1: +object-keys@^1.0.11, 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== @@ -4571,13 +4576,23 @@ object-visit@^1.0.0: dependencies: isobject "^3.0.0" -object.getownpropertydescriptors@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16" - integrity sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY= +object.assign@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" + integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== dependencies: define-properties "^1.1.2" - es-abstract "^1.5.1" + function-bind "^1.1.1" + has-symbols "^1.0.0" + object-keys "^1.0.11" + +object.getownpropertydescriptors@^2.0.3, object.getownpropertydescriptors@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz#369bf1f9592d8ab89d712dced5cb81c7c5352649" + integrity sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.0-next.1" object.pick@^1.3.0: version "1.3.0" @@ -4587,15 +4602,22 @@ object.pick@^1.3.0: isobject "^3.0.1" object.values@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.0.tgz#bf6810ef5da3e5325790eaaa2be213ea84624da9" - integrity sha512-8mf0nKLAoFX6VlNVdhGj31SVYpaNFtUnuoOXWyFEstsWRgU837AK+JYM0iAxwkSzGRbwn8cbFmgbyxj1j4VbXg== + version "1.1.1" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.1.tgz#68a99ecde356b7e9295a3c5e0ce31dc8c953de5e" + integrity sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA== dependencies: define-properties "^1.1.3" - es-abstract "^1.12.0" + es-abstract "^1.17.0-next.1" function-bind "^1.1.1" has "^1.0.3" +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" + once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" @@ -4645,12 +4667,12 @@ os-locale@^3.1.0: lcid "^2.0.0" mem "^4.0.0" -os-tmpdir@^1.0.0, os-tmpdir@^1.0.1: +os-tmpdir@^1.0.0: 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, osenv@^0.1.4: +osenv@0: version "0.1.5" resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== @@ -4710,9 +4732,9 @@ p-limit@^1.0.0, p-limit@^1.1.0: p-try "^1.0.0" p-limit@^2.0.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.1.tgz#aa07a788cc3151c939b5131f63570f0dd2009537" - integrity sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg== + version "2.2.2" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.2.tgz#61279b67721f5287aa1c13a9a7fbbc48c9291b1e" + integrity sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ== dependencies: p-try "^2.0.0" @@ -4777,9 +4799,9 @@ p-try@^2.0.0: integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== pako@~1.0.5: - version "1.0.10" - resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.10.tgz#4328badb5086a426aa90f541977d4955da5c9732" - integrity sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw== + version "1.0.11" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" + integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== parallel-transform@^1.1.0: version "1.2.0" @@ -4790,6 +4812,14 @@ parallel-transform@^1.1.0: inherits "^2.0.3" readable-stream "^2.1.5" +param-case@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.3.tgz#4be41f8399eff621c56eebb829a5e451d9801238" + integrity sha512-VWBVyimc1+QrzappRs7waeN2YmoZFCGXWASRYX1/rGHtXqEcrGEIDm+jqIwFa2fRXNgQEwrxaYuIrX0WcAguTA== + dependencies: + dot-case "^3.0.3" + tslib "^1.10.0" + parse-asn1@^5.0.0: version "5.1.5" resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.5.tgz#003271343da58dc94cace494faef3d2147ecea0e" @@ -4814,6 +4844,19 @@ parse-passwd@^1.0.0: resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY= +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== + +pascal-case@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-3.1.1.tgz#5ac1975133ed619281e88920973d2cd1f279de5f" + integrity sha512-XIeHKqIrsquVTQL2crjq3NfJUxmdLasn3TYOU0VBM+UX2a6ztAWBlJQBePLGY7VHW8+2dRadeIPK5+KImwTxQA== + dependencies: + no-case "^3.0.3" + tslib "^1.10.0" + pascalcase@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" @@ -4841,7 +4884,7 @@ path-exists@^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: +path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= @@ -4861,6 +4904,11 @@ path-parse@^1.0.6: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== +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-type@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" @@ -4958,9 +5006,9 @@ pngquant-bin@^5.0.0: logalot "^2.0.0" popper.js@*, popper.js@^1.14.1, popper.js@^1.14.4: - version "1.16.0" - resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.0.tgz#2e1816bcbbaa518ea6c2e15a466f4cb9c6e2fbb3" - integrity sha512-+G+EkOPoE5S/zChTpmBSSDYmhXJ5PsW8eMhH8cP/CQHMFPBG/kC9Y5IIw6qNYgdJ+/COf0ddY2li28iHaZRSjw== + version "1.16.1" + resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1.tgz#2a223cb3dc7b6213d740e40372be40de43e65b1b" + integrity sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ== portal-vue@^2.1.7: version "2.1.7" @@ -5037,10 +5085,13 @@ pretty-bytes@^5.1.0: resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.3.0.tgz#f2849e27db79fb4d6cfe24764fc4134f165989f2" integrity sha512-hjGrh+P926p4R4WbaB6OckyRtO0F0/lQBiT+0gnxjV+5kjPBrfVBFCsCLbMqVQeydvIoouYTCmmEURiH3R1Bdg== -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== +pretty-error@^2.1.1: + 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" process-nextick-args@~2.0.0: version "2.0.1" @@ -5067,6 +5118,14 @@ protocol-buffers-schema@^3.3.1: resolved "https://registry.yarnpkg.com/protocol-buffers-schema/-/protocol-buffers-schema-3.4.0.tgz#2f0ea31ca96627d680bf2fefae7ebfa2b6453eae" integrity sha512-G/2kcamPF2S49W5yaMGdIpkG6+5wZF0fzBteLKgEHjbNzqjZQ85aAs1iJGto31EJaSTkNvHs5IXuHSaTLWBAiA== +proxy-addr@~2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf" + integrity sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw== + dependencies: + forwarded "~0.1.2" + 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" @@ -5078,9 +5137,14 @@ pseudomap@^1.0.2: integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= psl@^1.1.24: - version "1.6.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.6.0.tgz#60557582ee23b6c43719d9890fb4170ecd91e110" - integrity sha512-SYKKmVel98NCOYXpkwUqZqh0ahZeeKfmisiLIcEZdsb+WbLv02g/dI5BUmZnIyOe7RzZtLax81nnb2HbvC2tzA== + version "1.7.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.7.0.tgz#f1c4c47a8ef97167dea5d6bbf4816d736e884a3c" + integrity sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ== + +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" @@ -5129,7 +5193,7 @@ punycode@^1.2.4, punycode@^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.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== @@ -5139,6 +5203,11 @@ q@^1.1.2: resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= +qs@6.7.0: + version "6.7.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" + integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== + qs@~6.5.2: version "6.5.2" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" @@ -5183,21 +5252,26 @@ randomfill@^1.0.3: randombytes "^2.0.5" safe-buffer "^5.1.0" +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.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" + integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== + dependencies: + bytes "3.1.0" + http-errors "1.7.2" + iconv-lite "0.4.24" + unpipe "1.0.0" + raw-loader@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/raw-loader/-/raw-loader-0.5.1.tgz#0c3d0beaed8a01c966d9787bf778281252a979aa" integrity sha1-DD0L6u2KAclm2Xh793goElKpeao= -rc@^1.2.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" - 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" @@ -5216,9 +5290,9 @@ read-pkg@^1.0.0: path-type "^1.0.0" "readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.0, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6: - version "2.3.6" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" - integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== + 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" @@ -5228,6 +5302,15 @@ read-pkg@^1.0.0: string_decoder "~1.1.1" util-deprecate "~1.0.1" +readable-stream@^3.1.1: + 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.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" @@ -5296,11 +5379,27 @@ regjsparser@^0.1.4: dependencies: jsesc "~0.5.0" +relateurl@^0.2.7: + 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.4" + resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-2.0.4.tgz#d325e532afb28d3f8796ffee306be8ffd6fc864c" + integrity sha512-K2eXrSOJdq+HuKzlcjOlGoOarUu5SDguDEhE7+Ah4zuOWL40j8A/oHvLlLob9PSTNvVnBd+/q0Er1QfpEuem5g== + dependencies: + css-select "^1.1.0" + dom-converter "^0.2" + htmlparser2 "^3.3.0" + lodash "^4.17.20" + strip-ansi "^3.0.0" + repeat-element@^1.1.2: version "1.1.3" resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" @@ -5349,6 +5448,32 @@ request@^2.87.0, request@^2.88.0: tunnel-agent "^0.6.0" uuid "^3.3.2" +request@^2.88.2: + 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" @@ -5397,9 +5522,9 @@ resolve-url@^0.2.1: integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= resolve@^1.10.0: - version "1.13.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.13.1.tgz#be0aa4c06acd53083505abb35f4d66932ab35d16" - integrity sha512-CxqObCX8K8YtAhOBRg+lrcdn+LK+WYOS8tSjqSFbjtrI5PnS63QPhZl4+yKfrU9tdsbMu9Anr/amegT87M9Z6w== + version "1.15.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.15.1.tgz#27bdcdeffeaf2d6244b95bb0f9f4b4653451f3e8" + integrity sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w== dependencies: path-parse "^1.0.6" @@ -5415,7 +5540,7 @@ ret@~0.1.10: resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== -rimraf@2, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@^2.6.3: +rimraf@2, rimraf@^2.5.4, rimraf@^2.6.2, rimraf@^2.6.3: version "2.7.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== @@ -5485,7 +5610,7 @@ sass-loader@^7.1.0: pify "^4.0.1" semver "^6.3.0" -sax@^1.2.4, sax@~1.2.4: +sax@~1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== @@ -5549,15 +5674,44 @@ semver@~5.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" integrity sha1-myzl094C0XxgEq0yaqa00M9U+U8= +send@0.17.1: + version "0.17.1" + resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" + integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== + 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.7.2" + mime "1.6.0" + ms "2.1.1" + on-finished "~2.3.0" + range-parser "~1.2.1" + statuses "~1.5.0" + serialize-javascript@^1.4.0: version "1.9.1" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.9.1.tgz#cfc200aef77b600c47da9bb8149c943e798c2fdb" integrity sha512-0Vb/54WJ6k5v8sSWN09S0ora+Hnr+cX40r9F170nT+mSkaxltoE/7R3OrIdBSUv1OoiobH1QoWQbCnAO+e8J1A== -serialize-javascript@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-2.1.1.tgz#952907a04a3e3a75af7f73d92d15e233862048b2" - integrity sha512-MPLPRpD4FNqWq9tTIjYG5LesFouDhdyH0EPY3gVK4DRD5+g4aDqdNSzLIwceulo3Yj+PL1bPh6laE5+H6LTcrQ== +serialize-javascript@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-2.1.2.tgz#ecec53b0e0317bdc95ef76ab7074b7384785fa61" + integrity sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ== + +serve-static@1.14.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" + integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.17.1" set-blocking@^2.0.0, set-blocking@~2.0.0: version "2.0.0" @@ -5579,6 +5733,11 @@ setimmediate@^1.0.4: resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= +setprototypeof@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" + integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== + 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" @@ -5682,23 +5841,16 @@ source-list-map@^2.0.0: integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== source-map-resolve@^0.5.0: - version "0.5.2" - resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" - integrity sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA== + 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.1" + 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-support@~0.5.12: version "0.5.16" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.16.tgz#0ae069e7fe3ba7538c64c98515e35339eac5a042" @@ -5719,12 +5871,12 @@ source-map@^0.4.2: dependencies: amdefine ">=0.0.4" -source-map@^0.5.6, source-map@^0.5.7: +source-map@^0.5.6: 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.0, source-map@^0.6.1, source-map@~0.6.1: +source-map@^0.6.0, 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== @@ -5825,6 +5977,11 @@ static-extend@^0.1.1: define-property "^0.2.5" object-copy "^0.1.0" +"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= + stdout-stream@^1.4.0: version "1.4.1" resolved "https://registry.yarnpkg.com/stdout-stream/-/stdout-stream-1.4.1.tgz#5ac174cdd5cd726104aa0c0b2bd83815d8d535de" @@ -5860,9 +6017,9 @@ stream-http@^2.7.2: xtend "^4.0.0" stream-shift@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" - integrity sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI= + version "1.0.1" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" + integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== strict-uri-encode@^1.0.0: version "1.1.0" @@ -5895,23 +6052,23 @@ string-width@^3.0.0, string-width@^3.1.0: is-fullwidth-code-point "^2.0.0" strip-ansi "^5.1.0" -string.prototype.trimleft@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz#6cc47f0d7eb8d62b0f3701611715a3954591d634" - integrity sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw== +string.prototype.trimleft@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz#9bdb8ac6abd6d602b17a4ed321870d2f8dcefc74" + integrity sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag== dependencies: define-properties "^1.1.3" function-bind "^1.1.1" -string.prototype.trimright@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz#669d164be9df9b6f7559fa8e89945b168a5a6c58" - integrity sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg== +string.prototype.trimright@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz#440314b15996c866ce8a0341894d45186200c5d9" + integrity sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g== dependencies: define-properties "^1.1.3" function-bind "^1.1.1" -string_decoder@^1.0.0: +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== @@ -5989,11 +6146,6 @@ strip-indent@^1.0.1: 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= - strip-outer@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/strip-outer/-/strip-outer-1.0.1.tgz#b2fd2abf6604b9d1e6013057195df836b8a9d631" @@ -6081,19 +6233,6 @@ tar@^2.0.0: fstream "^1.0.12" inherits "2" -tar@^4: - version "4.4.13" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525" - integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA== - dependencies: - chownr "^1.1.1" - fs-minipass "^1.2.5" - minipass "^2.8.6" - minizlib "^1.2.1" - mkdirp "^0.5.0" - safe-buffer "^5.1.2" - yallist "^3.0.3" - temp-dir@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-1.0.0.tgz#0a7c0ea26d3a39afa7e0ebea9c1fc0bc4daa011d" @@ -6107,25 +6246,34 @@ tempfile@^2.0.0: temp-dir "^1.0.0" uuid "^3.0.1" -terser-webpack-plugin@^1.4.1: - version "1.4.2" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.2.tgz#e23c0d554587d1f473bd0cf68627720e733890a4" - integrity sha512-fdEb91kR2l+BVgES77N/NTXWZlpX6vX+pYPjnX5grcDYBF2CMnzJiXX4NNlna4l04lvCW39lZ+O/jSvUhHH/ew== +terser-webpack-plugin@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz#5ecaf2dbdc5fb99745fd06791f46fc9ddb1c9a7c" + integrity sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA== dependencies: cacache "^12.0.2" find-cache-dir "^2.1.0" is-wsl "^1.1.0" schema-utils "^1.0.0" - serialize-javascript "^2.1.1" + serialize-javascript "^2.1.2" source-map "^0.6.1" terser "^4.1.2" webpack-sources "^1.4.0" worker-farm "^1.7.0" terser@^4.1.2: - version "4.4.2" - resolved "https://registry.yarnpkg.com/terser/-/terser-4.4.2.tgz#448fffad0245f4c8a277ce89788b458bfd7706e8" - integrity sha512-Uufrsvhj9O1ikwgITGsZ5EZS6qPokUOkCegS7fYOdGTv+OA90vndUbU6PEjr5ePqHfNUbGyMO7xyIZv2MhsALQ== + version "4.6.3" + resolved "https://registry.yarnpkg.com/terser/-/terser-4.6.3.tgz#e33aa42461ced5238d352d2df2a67f21921f8d87" + integrity sha512-Lw+ieAXmY69d09IIc/yqeBqXpEQIpDGZqT34ui1QWXIUpR2RjbqEkT8X7Lgex19hslSqcWM5iMN2kM11eMsESQ== + dependencies: + commander "^2.20.0" + source-map "~0.6.1" + source-map-support "~0.5.12" + +terser@^4.6.3: + version "4.8.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-4.8.0.tgz#63056343d7c70bb29f3af665865a46fe03a0df17" + integrity sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw== dependencies: commander "^2.20.0" source-map "~0.6.1" @@ -6171,11 +6319,6 @@ to-buffer@^1.1.1: resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.1.1.tgz#493bd48f62d7c43fcded313a03dcadb2e1213a80" integrity sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg== -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" @@ -6201,6 +6344,11 @@ to-regex@^3.0.1, to-regex@^3.0.2: regex-not "^1.0.2" safe-regex "^1.1.0" +toidentifier@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" + integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== + tough-cookie@~2.4.3: version "2.4.3" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" @@ -6209,6 +6357,14 @@ tough-cookie@~2.4.3: psl "^1.1.24" punycode "^1.4.1" +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" + trim-newlines@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" @@ -6221,11 +6377,6 @@ trim-repeated@^1.0.0: dependencies: escape-string-regexp "^1.0.2" -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= - "true-case-path@^1.0.2": version "1.0.3" resolved "https://registry.yarnpkg.com/true-case-path/-/true-case-path-1.0.3.tgz#f813b5a8c86b40da59606722b144e3225799f47d" @@ -6244,6 +6395,11 @@ ts-loader@^4.5.0: micromatch "^3.1.4" semver "^5.0.1" +tslib@^1.10.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + tslib@^1.9.0: version "1.10.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" @@ -6266,15 +6422,23 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0: resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= +type-is@~1.6.17, 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" + typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= typescript@^3.6: - version "3.7.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.7.4.tgz#1743a5ec5fef6a1fa9f3e4708e33c81c73876c19" - integrity sha512-A25xv5XCtarLwXpcDNZzCGvW2D1S3/bACratYBx2sax8PefsFhlYmkQicKHvpYflFS8if4zne5zT5kpJ7pzuvw== + version "3.7.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.7.5.tgz#0692e21f65fd4108b9330238aac11dd2e177a1ae" + integrity sha512-/P5lkRXkWHNAbcJIiHPfRoKqyd7bsyCma1hZNUGfn20qm64T6ZBlrzprymeu918H+mB/0rIg2gGK/BXkhhYgBw== unbzip2-stream@^1.0.9: version "1.3.3" @@ -6313,6 +6477,11 @@ universalify@^0.1.0: 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= + unquote@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/unquote/-/unquote-1.1.1.tgz#8fded7324ec6e88a0ff8b905e7c098cdc086d544" @@ -6375,12 +6544,12 @@ use@^3.1.0: resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== -util-deprecate@~1.0.1: +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.promisify@^1.0.0, util.promisify@~1.0.0: +util.promisify@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" integrity sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA== @@ -6388,6 +6557,16 @@ util.promisify@^1.0.0, util.promisify@~1.0.0: define-properties "^1.1.2" object.getownpropertydescriptors "^2.0.3" +util.promisify@^1.0.0, util.promisify@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.1.tgz#6baf7774b80eeb0f7520d8b81d07982a59abbaee" + integrity sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.2" + has-symbols "^1.0.1" + object.getownpropertydescriptors "^2.1.0" + util@0.10.3: version "0.10.3" resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" @@ -6402,10 +6581,20 @@ util@^0.11.0: 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@^3.0.1, uuid@^3.3.2: - version "3.3.3" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.3.tgz#4568f0216e78760ee1dbf3a4d2cf53e224112866" - integrity sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ== + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== v8-compile-cache@2.0.3: version "2.0.3" @@ -6420,6 +6609,11 @@ validate-npm-package-license@^3.0.1: 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= + verror@1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" @@ -6458,6 +6652,13 @@ vue-fragment@^1.5.1: resolved "https://registry.yarnpkg.com/vue-fragment/-/vue-fragment-1.5.1.tgz#44c070d55ed1e9a6c698ef57a5c83f64bb06feeb" integrity sha512-ig6eES6TcMBbANW71ylB+AJgRN+Zksb3f50AxjGpAk6hMzqmeuD80qeh4LJP0jVw2dMBMjgRUfIkrvxygoRgtQ== +vue-moment@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/vue-moment/-/vue-moment-4.1.0.tgz#092a8ff723a96c6f85a0a8e23ad30f0bf320f3b0" + integrity sha512-Gzisqpg82ItlrUyiD9d0Kfru+JorW2o4mQOH06lEDZNgxci0tv/fua1Hl0bo4DozDV2JK1r52Atn/8QVCu8qQw== + dependencies: + moment "^2.19.2" + vue-property-decorator@^7.0.0: version "7.3.0" resolved "https://registry.yarnpkg.com/vue-property-decorator/-/vue-property-decorator-7.3.0.tgz#d50d67f0b0f1c814f9f2fba36d6eeccbcc62dbb6" @@ -6470,6 +6671,11 @@ vue-removed-hook-mixin@^0.1.1: resolved "https://registry.yarnpkg.com/vue-removed-hook-mixin/-/vue-removed-hook-mixin-0.1.1.tgz#df2e939c87d8ecf1707f0b3b3a21def81dedbaf5" integrity sha512-ElO0fn1QT25S7WVHUS7rSug7qBHwR/OPxBTdaH2+DdMz0A/lyw3H40c/Q08k2xvndmx7tAglsevcTk2DgKPsvw== +vue-router@^3.4.8: + version "3.4.8" + resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-3.4.8.tgz#2c06261d35d8075893470352d42d70b6287b8194" + integrity sha512-3BsR84AqarcmweXjItxw3jwQsiYNssYg090yi4rlzTnCJxmHtkyCvhNz9Z7qRSOkmiV485KkUCReTp5AjNY4wg== + vue2-leaflet@^1.0.2: version "1.2.3" resolved "https://registry.yarnpkg.com/vue2-leaflet/-/vue2-leaflet-1.2.3.tgz#00ddeb9db4fb9a5e3b8f9c09cd97a4734366415e" @@ -6478,10 +6684,10 @@ vue2-leaflet@^1.0.2: "@types/leaflet" "^1.2.11" leaflet "1.3.1" -vue@^2.5.17: - version "2.6.10" - resolved "https://registry.yarnpkg.com/vue/-/vue-2.6.10.tgz#a72b1a42a4d82a721ea438d1b6bf55e66195c637" - integrity sha512-ImThpeNU9HbdZL3utgMCq0oiMzAkt1mcgy3/E6zWC/G6AaQoeuFdsl9nDhTDU3X1R6FK7nsIUuRACVcjI+A2GQ== +vue@>=2.6.10, vue@^2.5.17: + version "2.6.11" + resolved "https://registry.yarnpkg.com/vue/-/vue-2.6.11.tgz#76594d877d4b12234406e84e35275c6d514125c5" + integrity sha512-VfPwgcGABbGAue9+sfrD4PuwFar7gPb1yl1UK1MwXoQPAw0BKSqWfoYCT/ThFrdEVWoI51dBuyCoiNU9bZDZxQ== vuex-class@^0.3.1: version "0.3.2" @@ -6527,7 +6733,7 @@ webpack-cli@^3.1.0: v8-compile-cache "2.0.3" yargs "13.2.4" -webpack-sources@^1.0.1, webpack-sources@^1.1.0, webpack-sources@^1.4.0, webpack-sources@^1.4.1: +webpack-sources@^1.1.0, webpack-sources@^1.4.0, webpack-sources@^1.4.1: version "1.4.3" resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== @@ -6536,9 +6742,9 @@ webpack-sources@^1.0.1, webpack-sources@^1.1.0, webpack-sources@^1.4.0, webpack- source-map "~0.6.1" webpack@^4.17.0: - version "4.41.2" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.41.2.tgz#c34ec76daa3a8468c9b61a50336d8e3303dce74e" - integrity sha512-Zhw69edTGfbz9/8JJoyRQ/pq8FYUoY0diOXqW0T6yhgdhCv6wr0hra5DwwWexNRns2Z2+gsnrNcbe9hbGBgk/A== + version "4.41.5" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.41.5.tgz#3210f1886bce5310e62bb97204d18c263341b77c" + integrity sha512-wp0Co4vpyumnp3KlkmpM5LWuzvZYayDwM2n17EHFr4qxBBbRokC7DJawPJC7TfSFZ9HZ6GsdH40EBj4UV0nmpw== dependencies: "@webassemblyjs/ast" "1.8.5" "@webassemblyjs/helper-module-context" "1.8.5" @@ -6560,7 +6766,7 @@ webpack@^4.17.0: node-libs-browser "^2.2.1" schema-utils "^1.0.0" tapable "^1.1.3" - terser-webpack-plugin "^1.4.1" + terser-webpack-plugin "^1.4.3" watchpack "^1.6.0" webpack-sources "^1.4.1" @@ -6586,6 +6792,13 @@ which@1, which@^1.2.14, which@^1.2.9, which@^1.3.1: dependencies: isexe "^2.0.0" +which@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + wide-align@^1.1.0: version "1.1.3" resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" @@ -6758,9 +6971,9 @@ wrappy@1: integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= xmldom@^0.1.27: - version "0.1.27" - resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.1.27.tgz#d501f97b3bdb403af8ef9ecc20573187aadac0e9" - integrity sha1-1QH5ezvbQDr4757MIFcxh6rawOk= + version "0.1.31" + resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.1.31.tgz#b76c9a1bd9f0a9737e5a72dc37231cf38375e2ff" + integrity sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ== xpath@^0.0.27: version "0.0.27" @@ -6787,7 +7000,7 @@ yallist@^2.1.2: resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= -yallist@^3.0.0, yallist@^3.0.2, yallist@^3.0.3: +yallist@^3.0.2: version "3.1.1" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== @@ -6843,6 +7056,13 @@ yargs@^7.0.0: y18n "^3.2.1" yargs-parser "^5.0.0" +yarn-add-no-save@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/yarn-add-no-save/-/yarn-add-no-save-1.0.3.tgz#03540f86802a46a86db83bc7357b248cd282315b" + integrity sha512-ngmmxwYOogvYPjFDXGjoj35r/DteDzfiyoq5BI+kKSCCXW/I2gJA3KAgbm/7yFmcDE9CGSaORpNbYfglGYuxtA== + dependencies: + which "^2.0.2" + yauzl@^2.4.2: version "2.10.0" resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" diff --git a/public/index.php b/public/index.php deleted file mode 100644 index 732f5b8..0000000 --- a/public/index.php +++ /dev/null @@ -1,40 +0,0 @@ -<?php - -use App\Kernel; -use Symfony\Component\Debug\Debug; -use Symfony\Component\Dotenv\Dotenv; -use Symfony\Component\HttpFoundation\Request; - -require __DIR__.'/../vendor/autoload.php'; - -// The check is to ensure we don't use .env in production -if (!isset($_SERVER['APP_ENV'])) { - if (!class_exists(Dotenv::class)) { - throw new \RuntimeException('APP_ENV environment variable is not defined. You need to define environment variables for configuration or add "symfony/dotenv" as a Composer dependency to load variables from a .env file.'); - } - (new Dotenv())->load(__DIR__.'/../.env'); -} - -$env = $_SERVER['APP_ENV'] ?? 'dev'; -$debug = (bool) ($_SERVER['APP_DEBUG'] ?? ('prod' !== $env)); - -if ($debug) { - umask(0000); - - Debug::enable(); -} - -if ($trustedProxies = $_SERVER['TRUSTED_PROXIES'] ?? false) { - Request::setTrustedProxies(explode(',', $trustedProxies), Request::HEADER_X_FORWARDED_ALL ^ Request::HEADER_X_FORWARDED_HOST); -} - -if ($trustedHosts = $_SERVER['TRUSTED_HOSTS'] ?? false) { - Request::setTrustedHosts(explode(',', $trustedHosts)); -} - -\Doctrine\Common\Annotations\AnnotationReader::addGlobalIgnoredName('alias'); -$kernel = new Kernel($env, $debug); -$request = Request::createFromGlobals(); -$response = $kernel->handle($request); -$response->send(); -$kernel->terminate($request, $response); diff --git a/public/manifest.json b/public/manifest.json deleted file mode 100644 index b932719..0000000 --- a/public/manifest.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "name": "Czy Dojadę?", - "short_name": "Czy Dojadę?", - "orientation": "portrait", - "lang": "pl_PL", - "start_url": ".", - "display": "standalone", - "background_color": "#005ea8", - "theme_color": "#005ea8", - "description": "Odpowiedź na odwieczne pytanie ludzkości - czy tramwaje jeżdżą?", - "icons": [{ - "src": "images/icon-256.png", - "sizes": "256x256" - },{ - "src": "images/icon-512.png", - "sizes": "512x512" - },{ - "src": "images/icon-64.png", - "sizes": "64x64" - },{ - "src": "images/icon-128.png", - "sizes": "128x128" - },{ - "src": "images/icon-192.png", - "sizes": "192x192" - },{ - "src": "images/icon-96.png", - "sizes": "96x96" - }] -} \ No newline at end of file diff --git a/resources/components/departures.html b/resources/components/departures.html deleted file mode 100644 index d8f3557..0000000 --- a/resources/components/departures.html +++ /dev/null @@ -1,9 +0,0 @@ -<div class="departures" v-responsive> - <ul class="departures__list list-underlined"> - <departure :departure="departure" :key="departure.key" v-for="departure in departures"/> - </ul> - <div class="alert alert-info" v-if="stops.length === 0"> - <fa :icon="['fal', 'info-circle']"/> - Wybierz przystanki korzystając z wyszukiwarki poniżej, aby zobaczyć listę odjazdów. - </div> -</div> diff --git a/resources/components/line.html b/resources/components/line.html deleted file mode 100644 index e8565f2..0000000 --- a/resources/components/line.html +++ /dev/null @@ -1,12 +0,0 @@ -<span class="line__symbol flex" :class="{ [`line--${line.type}`]: true, 'line--night': line.night, 'line--fast': line.fast }"> - <span class="flex align-items-stretch"> - <span class="icon"> - <fa :icon="['fac', line.type]" fixed-width/> - </span> - <span class="badge badge-dark flex"> - <fa :icon="['fas', 'walking']" fixed-width v-if="line.fast"/> - <fa :icon="['fal', 'moon']" fixed-width v-if="line.night"/> - {{ line.symbol }} - </span> - </span> -</span> \ No newline at end of file diff --git a/resources/components/messages.html b/resources/components/messages.html deleted file mode 100644 index e1af51a..0000000 --- a/resources/components/messages.html +++ /dev/null @@ -1,15 +0,0 @@ -<ul class="messages list-unstyled"> - <li class="message alert" :class="`alert-${type(message)}`" v-for="message in messages"> - <fa :icon="icon(message)" fixed-width></fa> - {{ message.message }} - - <div class="message__info"> - <small class="message__date"> - Komunikat ważny od - {{ message.validFrom.format('HH:mm') }} - do - {{ message.validTo.format('HH:mm') }} - </small> - </div> - </li> -</ul> \ No newline at end of file diff --git a/resources/components/picker/stop.html b/resources/components/picker/stop.html deleted file mode 100644 index 49eea23..0000000 --- a/resources/components/picker/stop.html +++ /dev/null @@ -1,36 +0,0 @@ -<div class="finder__stop"> - <div class="d-flex"> - <slot name="primary-action" /> - <div class="overflow-hidden align-self-center"> - <stop :stop="stop" class="my-1"/> - <div class="stop__destinations" v-if="stop.destinations && stop.destinations.length > 0"> - <fa :icon="['far', 'chevron-right']" /> - <ul class="ml-1"> - <li class="stop__destination" v-for="destination in stop.destinations" :key="destination.id">{{ destination.name }}</li> - </ul> - </div> - </div> - - <div class="stop__actions flex-space-left"> - <slot name="actions"> - <button class="btn btn-action" ref="action-info" @click="details = !details"> - <tooltip>dodatkowe informacje</tooltip> - <fa :icon="['fal', details ? 'chevron-circle-up' : 'info-circle']"/> - </button> - - <button class="btn btn-action" ref="action-map" v-hover:map> - <fa :icon="['fal', 'map-marker-alt']"/> - </button> - </slot> - </div> - </div> - <fold :visible="details" class="stop__details-fold" lazy> - <stop-details :stop="stop"/> - </fold> - - <keep-alive> - <popper reference="action-map" v-if="showMap" arrow class="popper--no-padding" style="width: 500px;" placement="right-start" v-hover:inMap> - <stop-map :stop="stop" style="height: 300px"/> - </popper> - </keep-alive> -</div> diff --git a/resources/components/popper.html b/resources/components/popper.html deleted file mode 100644 index 84c1c94..0000000 --- a/resources/components/popper.html +++ /dev/null @@ -1,4 +0,0 @@ -<div :class="[ 'popper', arrow && 'popper--arrow' ]" v-on="$listeners"> - <div class="popper__arrow" ref="arrow" v-if="arrow"></div> - <slot /> -</div> diff --git a/resources/images/logo-branded-hi.png b/resources/images/logo-branded-hi.png deleted file mode 100644 index 7a7f074..0000000 Binary files a/resources/images/logo-branded-hi.png and /dev/null differ diff --git a/resources/images/logo-branded.png b/resources/images/logo-branded.png deleted file mode 100644 index dba7f9f..0000000 Binary files a/resources/images/logo-branded.png and /dev/null differ diff --git a/resources/images/logo-hi.png b/resources/images/logo-hi.png deleted file mode 100644 index 3359d74..0000000 Binary files a/resources/images/logo-hi.png and /dev/null differ diff --git a/resources/images/logo.png b/resources/images/logo.png deleted file mode 100644 index 2ff153a..0000000 Binary files a/resources/images/logo.png and /dev/null differ diff --git a/resources/styles/_controls.scss b/resources/styles/_controls.scss deleted file mode 100644 index 818cfae..0000000 --- a/resources/styles/_controls.scss +++ /dev/null @@ -1,21 +0,0 @@ -.btn { - &.btn-action { - @extend .btn-link; - - color: black; - - &:hover, &:active, &:focus { - text-decoration: none; - } - - &:focus { - outline: 2px solid rgba($blue, .2); - } - } - - display: inline-block; - - &.btn-outline-action { - @extend .btn-outline-dark; - } -} diff --git a/resources/styles/_form.scss b/resources/styles/_form.scss deleted file mode 100644 index 501fd56..0000000 --- a/resources/styles/_form.scss +++ /dev/null @@ -1,11 +0,0 @@ -label { - font-weight: bold; - font-size: .8rem; - margin-bottom: 0; - margin-top: -0.2rem; - display: block; -} - -.form-group:last-child { - margin-bottom: 0; -} diff --git a/resources/ts/components/app.ts b/resources/ts/components/app.ts deleted file mode 100644 index 2f74e9f..0000000 --- a/resources/ts/components/app.ts +++ /dev/null @@ -1,93 +0,0 @@ -import Vue from 'vue' -import store from '../store' -import { Component, Watch } from "vue-property-decorator"; -import { Mutation, Action } from 'vuex-class' -import { ObtainPayload } from "../store/departures"; -import { Stop } from "../model"; -import { PopperComponent } from "./utils"; - -@Component({ store }) -export class Application extends Vue { - private sections = { - messages: true - }; - - private visibility = { - messages: false, - departures: false, - save: false, - picker: 'search' - }; - - private autorefresh = { - messages: { - active: true, - interval: 60 - }, - departures: { - active: true, - interval: 10 - } - }; - - private intervals = { messages: null, departures: null }; - - get messages() { - return { - count: this.$store.getters['messages/count'], - counts: this.$store.getters['messages/counts'], - state: this.$store.state.messages.state - }; - } - - get departures() { - return { - state: this.$store.state.departures.state - }; - } - - get stops() { - return this.$store.state.stops; - } - - set stops(value) { - this.$store.commit('updateStops', value); - } - - mounted() { - this.$el.classList.remove('not-ready'); - } - - @Action('messages/update') updateMessages: () => void; - @Action('departures/update') updateDepartures: (payload: ObtainPayload) => void; - - @Mutation add: (stops: Stop[]) => void; - @Mutation remove: (stop: Stop) => void; - @Mutation clear: () => void; - - @Watch('stops') - onStopUpdate(this: any, stops) { - this.updateDepartures({ stops }); - } - - @Watch('autorefresh', { immediate: true, deep: true }) - onAutorefreshUpdate(settings) { - if (this.intervals.messages) { - clearInterval(this.intervals.messages); - this.intervals.messages = null; - } - - if (this.intervals.departures) { - clearInterval(this.intervals.departures); - this.intervals.messages = null; - } - - if (settings.messages.active) { - this.intervals.messages = setInterval(() => this.updateMessages(), Math.max(5, settings.messages.interval) * 1000); - } - - if (settings.departures.active) { - this.intervals.departures = setInterval(() => this.updateDepartures({ stops: this.stops }), Math.max(5, settings.departures.interval) * 1000); - } - } -} diff --git a/resources/ts/components/line.ts b/resources/ts/components/line.ts deleted file mode 100644 index bce6353..0000000 --- a/resources/ts/components/line.ts +++ /dev/null @@ -1,11 +0,0 @@ -import Vue from 'vue' -import { Component, Prop } from 'vue-property-decorator' -import { Line } from "../model"; - -@Component({ template: require('../../components/line.html' )}) -export class LineComponent extends Vue { - @Prop(Object) - public line: Line; -} - -Vue.component('LineSymbol', LineComponent); \ No newline at end of file diff --git a/resources/ts/components/messages.ts b/resources/ts/components/messages.ts deleted file mode 100644 index e3b2d89..0000000 --- a/resources/ts/components/messages.ts +++ /dev/null @@ -1,31 +0,0 @@ -import Vue from 'vue'; -import { Component } from "vue-property-decorator"; -import { Message } from "../model/message"; -import { faInfoCircle, faExclamationTriangle, faQuestionCircle } from "@fortawesome/pro-light-svg-icons"; -import { namespace } from 'vuex-class'; -import store from '../store' - -const { State } = namespace('messages'); - -@Component({ template: require("../../components/messages.html"), store }) -export class MessagesComponent extends Vue { - @State messages: Message[]; - - public icon(message: Message) { - switch (message.type) { - case "breakdown": return faExclamationTriangle; - case "info": return faInfoCircle; - case "unknown": return faQuestionCircle; - } - } - - public type(message: Message) { - switch (message.type) { - case "breakdown": return "danger"; - case "info": return "info"; - case "unknown": return "warning"; - } - } -} - -Vue.component('Messages', MessagesComponent); \ No newline at end of file diff --git a/resources/ts/components/picker.ts b/resources/ts/components/picker.ts deleted file mode 100644 index 6ca0faa..0000000 --- a/resources/ts/components/picker.ts +++ /dev/null @@ -1,73 +0,0 @@ -import Component from "vue-class-component"; -import Vue from "vue"; -import { Stop, StopGroup, StopGroups } from "../model"; -import { Prop, Watch } from "vue-property-decorator"; -import { ensureArray, FetchingState, filter, map, time } from "../utils"; -import { debounce } from "../decorators"; -import urls from '../urls'; - -@Component({ template: require('../../components/picker/stop.html') }) -export class PickerStopComponent extends Vue { - @Prop(Object) - public stop: Stop; - - details: boolean = false; - map: boolean = false; - inMap: boolean = false; - - get showMap() { - return this.inMap || this.map; - } -} - -@Component({ - template: require('../../components/finder.html'), - components: { - "PickerStop": PickerStopComponent - } -}) -export class FinderComponent extends Vue { - protected found?: StopGroups = {}; - - public state: FetchingState = 'ready'; - public filter: string = ""; - - @Prop({default: [], type: Array}) - public blacklist: Stop[]; - - get filtered(): StopGroups { - const groups = map( - this.found, - (group: StopGroup, name: string) => - group.filter(stop => !this.blacklist.some(blacklisted => blacklisted.id === stop.id)) - ) as StopGroups; - - return filter(groups, group => group.length > 0); - } - - @Watch('filter') - @debounce(400) - async fetch() { - if (this.filter.length < 3) { - return; - } - - this.state = 'fetching'; - - const response = await fetch(urls.prepare(urls.stops.grouped, { name: this.filter })); - - if (response.ok) { - this.found = (await response.json()).reduce((accumulator, { name, stops }) => Object.assign(accumulator, { [name]: stops }), {}); - this.state = 'ready'; - } else { - this.state = 'error'; - } - } - - private select(stop) { - this.$emit('select', stop); - } -} - -Vue.component('StopFinder', FinderComponent); -Vue.component('PickerStop', PickerStopComponent); diff --git a/resources/ts/components/utils.ts b/resources/ts/components/utils.ts deleted file mode 100644 index 200e083..0000000 --- a/resources/ts/components/utils.ts +++ /dev/null @@ -1,157 +0,0 @@ -import Vue from 'vue'; -import { Component, Prop, Watch } from "vue-property-decorator"; -import Popper, { Placement } from "popper.js"; -import { Portal } from "portal-vue"; -import vueRemovedHookMixin from "vue-removed-hook-mixin"; - -@Component({ - template: require("../../components/popper.html"), - mixins: [ vueRemovedHookMixin ] -}) -export class PopperComponent extends Vue { - @Prop([ String, HTMLElement ]) - public reference: string | HTMLElement; - - @Prop(Object) - public refs: string; - - @Prop({ type: String, default: "auto" }) - public placement: Placement; - - @Prop(Boolean) - public arrow: boolean; - - @Prop({ type: Boolean, default: true }) - public responsive: boolean; - - private _event; - private _popper; - - private getReferenceElement() { - const isInPortal = this.$parent.$options.name == 'portalTarget'; - - if (typeof this.reference === 'string') { - if (this.refs) { - return this.refs[this.reference]; - } - - if (isInPortal) { - return this.$parent.$parent.$refs[this.reference]; - } - - return this.$parent.$refs[this.reference]; - } - - if (this.reference instanceof HTMLElement) { - return this.reference; - } - - return isInPortal ? this.$parent.$el : this.$el.parentElement; - } - - focusOut(event: MouseEvent) { - if (this.$el.contains(event.target as Node)) { - return; - } - - this.$emit('leave', event); - } - - mounted() { - const reference = this.getReferenceElement(); - - this._popper = new Popper(reference, this.$el, { - placement: this.placement, - modifiers: { - arrow: { enabled: this.arrow, element: this.$refs['arrow'] as Element }, - responsive: { - enabled: this.responsive, - order: 890, - fn(data) { - if (window.innerWidth < 560) { - data.instance.options.placement = 'top'; - data.styles.transform = `translate3d(0, ${data.offsets.popper.top}px, 0)`; - data.styles.right = '0'; - data.styles.left = '0'; - data.styles.width = 'auto'; - data.arrowStyles.left = `${data.offsets.popper.left + data.offsets.arrow.left}px`; - } - - return data; - } - } - } - }); - - this.$nextTick(() => { - this._popper.update(); - document.addEventListener('click', this._event = this.focusOut.bind(this), { capture: true }); - }); - } - - updated() { - this._popper.update(); - } - - @Watch('visible') - private onVisibilityUpdate() { - this._popper.update(); - window.dispatchEvent(new Event('resize')); - } - - beforeDestroy() { - this._event && document.removeEventListener('click', this._event, { capture: true }); - } - - removed() { - this._popper.destroy() - } -} - -@Component({ template: require('../../components/fold.html') }) -export class FoldComponent extends Vue { - private observer: MutationObserver; - - @Prop(Boolean) - public visible: boolean; - - @Prop(Boolean) - public lazy: boolean; - - mounted() { - this.resize(); - - this.observer = new MutationObserver(() => this.resize()); - this.observer.observe(this.$refs['inner'] as Node, { - characterData: true, - subtree: true, - childList: true - }); - } - - beforeDestroy() { - this.observer.disconnect(); - } - - @Watch('visible') - private resize() { - const inner = this.$refs['inner'] as HTMLDivElement; - (this.$el as HTMLElement).style.height = `${(this.visible && inner) ? inner.clientHeight : 0}px`; - } -} - -@Component({ template: require("../../components/lazy.html") }) -export class LazyComponent extends Vue { - @Prop(Boolean) - public activate: boolean; - protected visible: boolean = false; - - @Watch('activate') - private onVisibilityChange(value, old) { - this.visible = value || old; - } -} - -Vue.component('Popper', PopperComponent); -Vue.component('Fold', FoldComponent); -Vue.component('Lazy', LazyComponent); diff --git a/resources/ts/font-awesome.ts b/resources/ts/font-awesome.ts deleted file mode 100644 index 184cfd6..0000000 --- a/resources/ts/font-awesome.ts +++ /dev/null @@ -1,16 +0,0 @@ -import Vue from 'vue' - -import { library } from '@fortawesome/fontawesome-svg-core' - -import { far } from "@fortawesome/pro-regular-svg-icons"; -import { fas } from "@fortawesome/pro-solid-svg-icons"; -import { fal } from "@fortawesome/pro-light-svg-icons"; -import { fac } from "./icons"; - -import { FontAwesomeIcon, FontAwesomeLayers, FontAwesomeLayersText } from '@fortawesome/vue-fontawesome' - -library.add(far, fas, fal, fac); - -Vue.component('fa', FontAwesomeIcon); -Vue.component('fa-layers', FontAwesomeLayers); -Vue.component('fa-text', FontAwesomeLayersText); diff --git a/resources/ts/model/stop.ts b/resources/ts/model/stop.ts deleted file mode 100644 index fa6bc33..0000000 --- a/resources/ts/model/stop.ts +++ /dev/null @@ -1,18 +0,0 @@ -export interface Stop { - id: any; - name: string; - description?: string; - location?: { - lat: number, - lng: number, - }; - onDemand?: boolean; - variant?: string; - destinations?: Stop[]; -} - -export type StopGroup = Stop[]; - -export type StopGroups = { - [name: string]: StopGroup; -} diff --git a/resources/ts/store/favourites.ts b/resources/ts/store/favourites.ts deleted file mode 100644 index 0ba6343..0000000 --- a/resources/ts/store/favourites.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { RootState, SavedState } from "./root"; -import { Module, Plugin, Store } from "vuex"; -import * as utils from "../utils"; -import { Stop } from "../model"; - -export interface Favourite { - id: string; - name: string; - stops: Stop[]; -} - -export interface FavouritesState { - favourites: Favourite[]; -} - -const favourites: Module<FavouritesState, RootState> = { - namespaced: true, - state: { - favourites: [] - }, - mutations: { - add(state, favourite: Favourite) { - state.favourites.push(favourite); - }, - remove(state, favourite: Favourite) { - state.favourites = state.favourites.filter(f => f != favourite); - } - } -}; - -export const localStorageSaver = (path: string, key: string): Plugin<any> => (store: Store<any>) => { - utils.set(store.state, path, JSON.parse(window.localStorage.getItem(key) || '[]')); - - store.subscribe((mutation, state) => { - window.localStorage.setItem(key, JSON.stringify(utils.get(state, path))); - }) -}; - -export default favourites; diff --git a/resources/ts/store/index.ts b/resources/ts/store/index.ts deleted file mode 100644 index 0719309..0000000 --- a/resources/ts/store/index.ts +++ /dev/null @@ -1,39 +0,0 @@ -import Vuex from 'vuex'; - -import messages, { MessagesState } from './messages'; -import departures, { DeparturesState } from './departures' -import favourites, { FavouritesState, localStorageSaver } from './favourites' - -import { state, mutations, actions, RootState } from "./root"; -import VuexPersistence from "vuex-persist"; -import { namespace } from "vuex-class"; - -export type State = { - messages: MessagesState; - departures: DeparturesState; - favourites: FavouritesState; -} & RootState; - -const localStoragePersist = new VuexPersistence<State>({ - reducer: state => ({ favourites: state.favourites }) -}); - -const sessionStoragePersist = new VuexPersistence<State>({ - reducer: state => ({ stops: state.stops }), - storage: window.sessionStorage -}); - -const store = new Vuex.Store({ - state, mutations, actions, - modules: { messages, departures, favourites }, - plugins: [ - // todo: remove after some time - localStorageSaver('favourites.favourites', 'favourites'), - localStoragePersist.plugin, - sessionStoragePersist.plugin, - ] -}); - -export default store; - -export const Favourites = namespace('favourites'); diff --git a/src/Asset/ModifiedTimeVersionStrategy.php b/src/Asset/ModifiedTimeVersionStrategy.php deleted file mode 100644 index c7446d0..0000000 --- a/src/Asset/ModifiedTimeVersionStrategy.php +++ /dev/null @@ -1,32 +0,0 @@ -<?php - -namespace App\Asset; - -use Symfony\Component\Asset\VersionStrategy\VersionStrategyInterface; - -class ModifiedTimeVersionStrategy implements VersionStrategyInterface -{ - /** - * Returns the asset version for an asset. - * - * @param string $path A path - * - * @return string The version string - */ - public function getVersion($path) - { - return filemtime($path); - } - - /** - * Applies version to the supplied path. - * - * @param string $path A path - * - * @return string The versionized path - */ - public function applyVersion($path) - { - return sprintf('%s?v=%s', $path, $this->getVersion($path)); - } -} \ No newline at end of file diff --git a/src/Command/UpdateCommand.php b/src/Command/UpdateCommand.php deleted file mode 100644 index 54be5aa..0000000 --- a/src/Command/UpdateCommand.php +++ /dev/null @@ -1,30 +0,0 @@ -<?php - -namespace App\Command; - -use App\Service\DataUpdater; -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; - -class UpdateCommand extends Command -{ - /** @var DataUpdater */ - private $updater; - - /** - * UpdateCommand constructor. - * - * @param $updater - */ - public function __construct(DataUpdater $updater) - { - parent::__construct('app:update'); - $this->updater = $updater; - } - - protected function execute(InputInterface $input, OutputInterface $output) - { - $this->updater->update($output); - } -} \ No newline at end of file diff --git a/src/Controller/Api/v1/TracksController.php b/src/Controller/Api/v1/TracksController.php deleted file mode 100644 index 069a338..0000000 --- a/src/Controller/Api/v1/TracksController.php +++ /dev/null @@ -1,70 +0,0 @@ -<?php - -namespace App\Controller\Api\v1; - -use App\Controller\Controller; -use App\Model\Stop; -use App\Model\Track; -use App\Provider\TrackRepository; -use Nelmio\ApiDocBundle\Annotation\Model; -use Swagger\Annotations as SWG; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; -use Symfony\Component\Routing\Annotation\Route; -use function App\Functions\encapsulate; - -/** - * @Route("/tracks") - */ -class TracksController extends Controller -{ - /** - * @SWG\Response( - * response=200, - * description="Returns all tracks for specific provider, e.g. ZTM Gdańsk.", - * ) - * @SWG\Tag(name="Tracks") - * @Route("/", methods={"GET"}) - */ - public function index(Request $request, TrackRepository $repository) - { - switch (true) { - case $request->query->has('stop'): - return $this->byStop($request, $repository); - case $request->query->has('line'): - return $this->byLine($request, $repository); - case $request->query->has('id'): - return $this->byId($request, $repository); - default: - throw new BadRequestHttpException( - sprintf( - 'At least one parameter of %s must be set.', - implode(', ', ['stop', 'line', 'id']) - ) - ); - } - } - - private function byId(Request $request, TrackRepository $repository) - { - $id = encapsulate($request->query->get('id')); - - return $this->json($repository->getManyById($id)); - } - - private function byStop(Request $request, TrackRepository $repository) - { - $stop = $request->query->get('stop'); - $stop = array_map([Stop::class, 'reference'], encapsulate($stop)); - - return $this->json($repository->getByStop($stop)); - } - - private function byLine(Request $request, TrackRepository $repository) - { - $line = $request->query->get('line'); - $line = array_map([Stop::class, 'reference'], encapsulate($line)); - - return $this->json($repository->getByLine($line)); - } -} \ No newline at end of file diff --git a/src/Controller/MainController.php b/src/Controller/MainController.php deleted file mode 100644 index 0987eb6..0000000 --- a/src/Controller/MainController.php +++ /dev/null @@ -1,42 +0,0 @@ -<?php - -namespace App\Controller; - - -use App\Provider\Provider; -use App\Service\ProviderResolver; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\Routing\Annotation\Route; - -class MainController extends Controller -{ - /** - * @Route("/", name="choose") - */ - public function choose(ProviderResolver $resolver) - { - return $this->render('choose.html.twig', ['providers' => $resolver->all()]); - } - - /** - * @Route("/{provider}", name="app") - */ - public function app(Provider $provider, Request $request) - { - $state = json_decode($request->query->get('state', '{}'), true) ?: []; - $state = array_merge([ - 'version' => 1, - 'stops' => [], - ], $state); - - return $this->render('app.html.twig', compact('state', 'provider')); - } - - /** - * @Route("/{provider}/manifest.json", name="webapp_manifest") - */ - public function manifest(Provider $provider) - { - return $this->render('manifest.json.twig', ['provider' => $provider]); - } -} \ No newline at end of file diff --git a/src/Exception/NonExistentServiceException.php b/src/Exception/NonExistentServiceException.php deleted file mode 100644 index c2c6ba3..0000000 --- a/src/Exception/NonExistentServiceException.php +++ /dev/null @@ -1,10 +0,0 @@ -<?php - - -namespace App\Exception; - - -class NonExistentServiceException extends \Exception -{ - -} \ No newline at end of file diff --git a/src/Exception/NotSupportedException.php b/src/Exception/NotSupportedException.php deleted file mode 100644 index 4ab7b89..0000000 --- a/src/Exception/NotSupportedException.php +++ /dev/null @@ -1,7 +0,0 @@ -<?php - -namespace App\Exception; - -class NotSupportedException extends \RuntimeException -{ -} \ No newline at end of file diff --git a/src/Functions/index.php b/src/Functions/index.php deleted file mode 100644 index a0028ce..0000000 --- a/src/Functions/index.php +++ /dev/null @@ -1,3 +0,0 @@ -<?php - -require_once __DIR__ . '/helpers.php'; \ No newline at end of file diff --git a/src/Provider/Database/DatabaseRepository.php b/src/Provider/Database/DatabaseRepository.php deleted file mode 100644 index 3a97eff..0000000 --- a/src/Provider/Database/DatabaseRepository.php +++ /dev/null @@ -1,59 +0,0 @@ -<?php - -namespace App\Provider\Database; - -use App\Entity\Entity; -use App\Entity\ProviderEntity; -use App\Model\Referable; -use App\Service\Converter; -use App\Service\IdUtils; -use Doctrine\ORM\EntityManagerInterface; -use Kadet\Functional as f; - -class DatabaseRepository -{ - /** @var EntityManagerInterface */ - protected $em; - - /** @var ProviderEntity */ - protected $provider; - - /** @var IdUtils */ - protected $id; - - /** @var Converter */ - protected $converter; - - /** - * DatabaseRepository constructor. - * - * @param EntityManagerInterface $em - */ - public function __construct(EntityManagerInterface $em, IdUtils $id, Converter $converter) - { - $this->em = $em; - $this->id = $id; - $this->converter = $converter; - } - - /** @return static */ - public function withProvider(ProviderEntity $provider) - { - $result = clone $this; - $result->provider = $provider; - - return $result; - } - - protected function convert($entity) - { - return $this->converter->convert($entity); - } - - protected function reference($class, Referable $referable) - { - $id = $this->id->generate($this->provider, $referable->getId()); - - return $this->em->getReference($class, $id); - } -} diff --git a/src/Provider/Database/GenericLineRepository.php b/src/Provider/Database/GenericLineRepository.php deleted file mode 100644 index e9bab49..0000000 --- a/src/Provider/Database/GenericLineRepository.php +++ /dev/null @@ -1,36 +0,0 @@ -<?php - -namespace App\Provider\Database; - -use App\Entity\LineEntity; -use App\Model\Line; -use App\Provider\LineRepository; -use Tightenco\Collect\Support\Collection; -use Kadet\Functional as f; - -class GenericLineRepository extends DatabaseRepository implements LineRepository -{ - public function getAll(): Collection - { - $repository = $this->em->getRepository(LineEntity::class); - $lines = $repository->findAll(); - - return collect($lines)->map(f\ref([$this, 'convert'])); - } - - public function getById($id): ?Line - { - $repository = $this->em->getRepository(LineEntity::class); - return $this->convert($repository->find($id)); - } - - public function getManyById($ids): Collection - { - $ids = collect($ids)->map(f\apply(f\ref([$this->id, 'generate']), $this->provider)); - - $repository = $this->em->getRepository(LineEntity::class); - $lines = $repository->findBy(['id' => $ids->all()]); - - return collect($lines)->map(f\ref([$this, 'convert'])); - } -} \ No newline at end of file diff --git a/src/Provider/Database/GenericOperatorRepository.php b/src/Provider/Database/GenericOperatorRepository.php deleted file mode 100644 index 946eff6..0000000 --- a/src/Provider/Database/GenericOperatorRepository.php +++ /dev/null @@ -1,33 +0,0 @@ -<?php - -namespace App\Provider\Database; - -use App\Model\Operator; -use App\Provider\OperatorRepository; -use Tightenco\Collect\Support\Collection; - -class GenericOperatorRepository extends DatabaseRepository implements OperatorRepository -{ - public function getAll(): Collection - { - $repository = $this->em->getRepository(Operator::class); - $operators = $repository->findAll(); - - return collect($operators); - } - - public function getById($id): ?Operator - { - $repository = $this->em->getRepository(Operator::class); - - return $repository->find($id); - } - - public function getManyById($ids): Collection - { - $repository = $this->em->getRepository(Operator::class); - $operators = $repository->findBy(['id' => $ids]); - - return collect($operators); - } -} \ No newline at end of file diff --git a/src/Provider/Database/GenericStopRepository.php b/src/Provider/Database/GenericStopRepository.php deleted file mode 100644 index 737b11f..0000000 --- a/src/Provider/Database/GenericStopRepository.php +++ /dev/null @@ -1,74 +0,0 @@ -<?php - -namespace App\Provider\Database; - -use App\Entity\StopEntity; -use App\Entity\TrackEntity; -use App\Model\Stop; -use App\Provider\StopRepository; -use Tightenco\Collect\Support\Collection; -use Kadet\Functional as f; -use Kadet\Functional\Transforms as t; - -class GenericStopRepository extends DatabaseRepository implements StopRepository -{ - public function getAll(): Collection - { - $stops = $this->em->getRepository(StopEntity::class)->findAll(); - - return collect($stops)->map(f\ref([$this, 'convert'])); - } - - public function getById($id): ?Stop - { - $id = $this->id->generate($this->provider, $id); - $stop = $this->em->getRepository(StopEntity::class)->find($id); - - return $this->convert($stop); - } - - public function getManyById($ids): Collection - { - $ids = collect($ids)->map(f\apply(f\ref([$this->id, 'generate']), $this->provider)); - $stops = $this->em->getRepository(StopEntity::class)->findBy(['id' => $ids->all()]); - - return collect($stops)->map(f\ref([$this, 'convert'])); - } - - public function findByName(string $name): Collection - { - $query = $this->em->createQueryBuilder() - ->select('s') - ->from(StopEntity::class, 's') - ->where('s.name LIKE :name') - ->getQuery(); - - $stops = collect($query->execute([':name' => "%$name%"])); - - $destinations = collect($this->em->createQueryBuilder() - ->select('t', 'f', 'fs', 'ts') - ->from(TrackEntity::class, 't') - ->join('t.stopsInTrack', 'ts') - ->where('ts.stop IN (:stops)') - ->join('t.final', 'f') - ->join('f.stop', 'fs') - ->getQuery() - ->execute(['stops' => $stops->map(t\property('id'))->all()])) - ->reduce(function ($grouped, TrackEntity $track) { - foreach ($track->getStopsInTrack()->map(t\property('stop'))->map(t\property('id')) as $stop) { - $grouped[$stop] = ($grouped[$stop] ?? collect())->add($track); - } - - return $grouped; - }, collect()) - ->map(function (Collection $tracks) { - return $tracks->map(function (TrackEntity $track) { - return $this->convert($track->getFinal()->getStop()); - })->unique()->values(); - }); - - return collect($stops)->map(f\ref([$this, 'convert']))->each(function (Stop $stop) use ($destinations) { - $stop->setDestinations($destinations[$this->id->generate($this->provider, $stop->getId())]); - }); - } -} diff --git a/src/Provider/Database/GenericTrackRepository.php b/src/Provider/Database/GenericTrackRepository.php deleted file mode 100644 index 9a25d44..0000000 --- a/src/Provider/Database/GenericTrackRepository.php +++ /dev/null @@ -1,67 +0,0 @@ -<?php - -namespace App\Provider\Database; - -use App\Entity\LineEntity; -use App\Entity\StopEntity; -use App\Entity\StopInTrack; -use App\Entity\TrackEntity; -use function App\Functions\encapsulate; -use App\Model\Stop; -use App\Model\Track; -use App\Provider\TrackRepository; -use Tightenco\Collect\Support\Collection; -use Kadet\Functional as f; - -class GenericTrackRepository extends DatabaseRepository implements TrackRepository -{ - public function getAll(): Collection - { - $tracks = $this->em->getRepository(TrackEntity::class)->findAll(); - - return collect($tracks)->map(f\ref([$this, 'convert'])); - } - - public function getById($id): Track - { - // TODO: Implement getById() method. - } - - public function getManyById($ids): Collection - { - // TODO: Implement getManyById() method. - } - - public function getByStop($stop): Collection - { - $reference = f\apply(f\ref([$this, 'reference']), StopEntity::class); - - $tracks = $this->em->createQueryBuilder() - ->from(StopInTrack::class, 'st') - ->join('st.track', 't') - ->where('st.stop in (:stop)') - ->select(['st', 't']) - ->getQuery() - ->execute(['stop' => array_map($reference, encapsulate($stop))]); - - return collect($tracks)->map(function (StopInTrack $entity) { - return [ $this->convert($entity->getTrack()), $entity->getOrder() ]; - }); - } - - public function getByLine($line): Collection - { - $reference = f\apply(f\ref([$this, 'reference']), LineEntity::class); - - $tracks = $this->em->createQueryBuilder() - ->from(StopInTrack::class, 'st') - ->join('st.track', 't') - ->join('t.stops', 's') - ->where('st.line in (:line)') - ->select(['st', 't', 's']) - ->getQuery() - ->execute(['stop' => array_map($reference, encapsulate($line))]); - - return collect($tracks)->map(f\ref([$this, 'convert'])); - } -} \ No newline at end of file diff --git a/src/Provider/Database/GenericTripRepository.php b/src/Provider/Database/GenericTripRepository.php deleted file mode 100644 index e85f178..0000000 --- a/src/Provider/Database/GenericTripRepository.php +++ /dev/null @@ -1,28 +0,0 @@ -<?php - -namespace App\Provider\Database; - -use App\Entity\TripEntity; -use App\Model\Trip; -use App\Provider\TripRepository; - -class GenericTripRepository extends DatabaseRepository implements TripRepository -{ - public function getById(string $id): Trip - { - $id = $this->id->generate($this->provider, $id); - - $trip = $this->em - ->createQueryBuilder() - ->from(TripEntity::class, 't') - ->join('t.stops', 'ts') - ->join('ts.stop', 's') - ->select('t', 'ts') - ->where('t.id = :id') - ->getQuery() - ->setParameter('id', $id) - ->getOneOrNullResult(); - - return $this->convert($trip); - } -} diff --git a/src/Provider/DepartureRepository.php b/src/Provider/DepartureRepository.php deleted file mode 100644 index 706274c..0000000 --- a/src/Provider/DepartureRepository.php +++ /dev/null @@ -1,13 +0,0 @@ -<?php - - -namespace App\Provider; - - -use App\Model\Stop; -use Tightenco\Collect\Support\Collection; - -interface DepartureRepository extends Repository -{ - public function getForStop(Stop $stop): Collection; -} \ No newline at end of file diff --git a/src/Provider/LineRepository.php b/src/Provider/LineRepository.php deleted file mode 100644 index 81a6e3a..0000000 --- a/src/Provider/LineRepository.php +++ /dev/null @@ -1,16 +0,0 @@ -<?php - - -namespace App\Provider; - - -use App\Model\Line; -use Tightenco\Collect\Support\Collection; - -interface LineRepository extends Repository -{ - public function getAll(): Collection; - - public function getById($id): ?Line; - public function getManyById($ids): Collection; -} \ No newline at end of file diff --git a/src/Provider/OperatorRepository.php b/src/Provider/OperatorRepository.php deleted file mode 100644 index 79f8b20..0000000 --- a/src/Provider/OperatorRepository.php +++ /dev/null @@ -1,15 +0,0 @@ -<?php - - -namespace App\Provider; - - -use App\Model\Operator; -use Tightenco\Collect\Support\Collection; - -interface OperatorRepository -{ - public function getAll(): Collection; - public function getById($id): ?Operator; - public function getManyById($ids): Collection; -} \ No newline at end of file diff --git a/src/Provider/StopRepository.php b/src/Provider/StopRepository.php deleted file mode 100644 index ea87c03..0000000 --- a/src/Provider/StopRepository.php +++ /dev/null @@ -1,16 +0,0 @@ -<?php - - -namespace App\Provider; - - -use App\Model\Stop; -use Tightenco\Collect\Support\Collection; - -interface StopRepository extends Repository -{ - public function getAll(): Collection; - public function getById($id): ?Stop; - public function getManyById($ids): Collection; - public function findByName(string $name): Collection; -} diff --git a/src/Provider/TrackRepository.php b/src/Provider/TrackRepository.php deleted file mode 100644 index 708e329..0000000 --- a/src/Provider/TrackRepository.php +++ /dev/null @@ -1,17 +0,0 @@ -<?php - -namespace App\Provider; - -use App\Model\Track; -use Tightenco\Collect\Support\Collection; - -interface TrackRepository -{ - public function getAll(): Collection; - - public function getById($id): Track; - public function getManyById($ids): Collection; - - public function getByStop($stop): Collection; - public function getByLine($line): Collection; -} \ No newline at end of file diff --git a/src/Provider/TripRepository.php b/src/Provider/TripRepository.php deleted file mode 100644 index 4a82521..0000000 --- a/src/Provider/TripRepository.php +++ /dev/null @@ -1,10 +0,0 @@ -<?php - -namespace App\Provider; - -use App\Model\Trip; - -interface TripRepository -{ - public function getById(string $id): Trip; -} diff --git a/src/Provider/ZtmGdansk/ZtmGdanskDepartureRepository.php b/src/Provider/ZtmGdansk/ZtmGdanskDepartureRepository.php deleted file mode 100644 index 0e956bd..0000000 --- a/src/Provider/ZtmGdansk/ZtmGdanskDepartureRepository.php +++ /dev/null @@ -1,139 +0,0 @@ -<?php - -namespace App\Provider\ZtmGdansk; - -use App\Model\Departure; -use App\Model\Line; -use App\Model\Stop; -use App\Model\Vehicle; -use App\Provider\Database\GenericScheduleRepository; -use App\Provider\DepartureRepository; -use App\Provider\LineRepository; -use App\Provider\ScheduleRepository; -use App\Service\Proxy\ReferenceFactory; -use Carbon\Carbon; -use JMS\Serializer\Tests\Fixtures\Discriminator\Car; -use Tightenco\Collect\Support\Collection; -use Kadet\Functional\Transforms as t; - -class ZtmGdanskDepartureRepository implements DepartureRepository -{ - const ESTIMATES_URL = 'http://ckan2.multimediagdansk.pl/delays'; - - /** @var LineRepository */ - private $lines; - - /** @var ReferenceFactory */ - private $reference; - - /** @var ScheduleRepository */ - private $schedule; - - /** - * @param LineRepository $lines - */ - public function __construct(LineRepository $lines, ScheduleRepository $schedule, ReferenceFactory $reference) - { - $this->lines = $lines; - $this->reference = $reference; - $this->schedule = $schedule; - } - - public function getForStop(Stop $stop): Collection - { - $real = $this->getRealDepartures($stop); - $now = Carbon::now()->second(0); - $first = $real->map(t\getter('scheduled'))->min() ?? $now; - $scheduled = $this->getScheduledDepartures($stop, $first); - - return $this->pair($scheduled, $real)->filter(function (Departure $departure) use ($now) { - return $departure->getDeparture() > $now; - }); - } - - private function getRealDepartures(Stop $stop) - { - try { - $estimates = file_get_contents(static::ESTIMATES_URL . "?stopId=" . $stop->getId()); - $estimates = json_decode($estimates, true)['delay']; - } catch (\Error $e) { - return collect(); - } - - $estimates = collect($estimates); - - $lines = $estimates->map(function ($delay) { - return $delay['routeId']; - })->unique(); - $lines = $this->lines->getManyById($lines)->keyBy(t\property('id')); - - return collect($estimates)->map(function ($delay) use ($stop, $lines) { - $scheduled = (new Carbon($delay['theoreticalTime'], 'Europe/Warsaw'))->tz('UTC'); - $estimated = (clone $scheduled)->addSeconds($delay['delayInSeconds']); - - return Departure::createFromArray([ - 'key' => sprintf('%s::%s', $delay['routeId'], $scheduled->format('H:i')), - 'scheduled' => $scheduled, - 'estimated' => $estimated, - 'stop' => $stop, - 'display' => trim($delay['headsign']), - 'vehicle' => $this->reference->get(Vehicle::class, $delay['vehicleCode']), - 'line' => $lines->get($delay['routeId']) ?: Line::createFromArray([ - 'symbol' => $delay['routeId'], - 'type' => Line::TYPE_UNKNOWN, - ]), - ]); - })->values(); - } - - private function getScheduledDepartures(Stop $stop, Carbon $time) - { - return $this->schedule->getDeparturesForStop($stop, $time); - } - - private function pair(Collection $schedule, Collection $real) - { - $key = function (Departure $departure) { - return sprintf("%s::%s", $departure->getLine()->getSymbol(), $departure->getScheduled()->format("H:i")); - }; - - $schedule = $schedule->keyBy($key)->all(); - $real = $real->keyBy($key); - - return $real->map(function (Departure $real, $key) use (&$schedule) { - $scheduled = null; - - if (array_key_exists($key, $schedule)) { - $scheduled = $schedule[$key]; - unset($schedule[$key]); - } - - return [ $real, $scheduled ]; - })->merge(collect($schedule)->map(function (Departure $scheduled) { - return [ null, $scheduled ]; - }))->map(function ($pair) { - return $this->merge(...$pair); - })->sortBy(function (Departure $departure) { - $time = $departure->getEstimated() ?? $departure->getScheduled(); - return $time->getTimestamp(); - }); - } - - private function merge(?Departure $real, ?Departure $scheduled) - { - if (!$real) { - return $scheduled; - } - - if (!$scheduled) { - return $real; - } - - $departure = clone $real; - $departure->setDisplay($scheduled->getDisplay()); - $departure->setTrack($scheduled->getTrack()); - $departure->setTrip($scheduled->getTrip()); - - return $departure; - } -} diff --git a/src/Service/AggregateConverter.php b/src/Service/AggregateConverter.php deleted file mode 100644 index 45cc308..0000000 --- a/src/Service/AggregateConverter.php +++ /dev/null @@ -1,43 +0,0 @@ -<?php - -namespace App\Service; - -use Hoa\Iterator\Recursive\Recursive; -use Symfony\Component\DependencyInjection\ServiceLocator; -use function Kadet\Functional\Predicates\equals; -use function Kadet\Functional\Predicates\method; - -class AggregateConverter implements Converter -{ - private $converters; - - public function __construct(iterable $converters) - { - $this->converters = collect($converters)->each(function (Converter $converter) { - if ($converter instanceof RecursiveConverter) { - $converter->setParent($this); - } - }); - } - - public function convert($entity) - { - /** @var Converter $converter */ - $converter = $this->converters->first(function (Converter $converter) use ($entity) { - return $converter->supports($entity); - }); - - if ($converter == null) { - throw new \InvalidArgumentException(sprintf('Cannot convert entity of type %s.', is_object($entity) ? get_class($entity) : gettype($entity))); - } - - return $converter->convert($entity); - } - - public function supports($entity) - { - return $this->converters->some(function (Converter $converter) use ($entity) { - return $converter->supports($entity); - }); - } -} diff --git a/src/Service/ScheduledStopConverter.php b/src/Service/ScheduledStopConverter.php deleted file mode 100644 index da20f28..0000000 --- a/src/Service/ScheduledStopConverter.php +++ /dev/null @@ -1,28 +0,0 @@ -<?php - -namespace App\Service; - -use App\Entity\TripStopEntity; -use App\Model\ScheduledStop; - -class ScheduledStopConverter implements Converter, RecursiveConverter -{ - use RecursiveConverterTrait; - - public function convert($entity) - { - /** @var ScheduledStop $entity */ - - return ScheduledStop::createFromArray([ - 'arrival' => $entity->getArrival(), - 'departure' => $entity->getDeparture(), - 'stop' => $this->parent->convert($entity->getStop()), - 'order' => $entity->getOrder(), - ]); - } - - public function supports($entity) - { - return $entity instanceof TripStopEntity; - } -} diff --git a/src/Service/VersionExtension.php b/src/Service/VersionExtension.php deleted file mode 100644 index 45ae2c1..0000000 --- a/src/Service/VersionExtension.php +++ /dev/null @@ -1,18 +0,0 @@ -<?php - -namespace App\Service; - -use Twig\Extension\AbstractExtension; -use Twig\TwigFunction; - -class VersionExtension extends AbstractExtension -{ - public function getFunctions() - { - return [ - new TwigFunction('version', function () { - return substr(`git rev-parse HEAD`, 0, 8) ?: '0.2'; - }) - ]; - } -} diff --git a/templates/app.html.twig b/templates/app.html.twig deleted file mode 100644 index 464825c..0000000 --- a/templates/app.html.twig +++ /dev/null @@ -1,171 +0,0 @@ -{% extends 'base.html.twig' %} -{% block title "#{parent()} - #{provider.name}" %} -{% block manifest path('webapp_manifest', { provider: provider.identifier }) %} - -{% block body %} - <div class="row"> - <div class="col-md-8 order-md-last"> - <section class="section messages" v-show="messages.count > 0"> - <header class="section__title flex"> - <h2> - <fa :icon="['fal', 'bullhorn']" fixed-width class="mr-2"></fa> - Komunikaty <span class="ml-2 badge badge-pill badge-dark">{{ '{{ messages.count }}' }}</span> - </h2> - <button class="btn btn-action flex-space-left" ref="settings-messages" @click="visibility.messages = true"> - <tooltip>ustawienia</tooltip> - <fa :icon="['fal', 'cog']" fixed-width></fa> - </button> - <button class="btn btn-action" @click="updateMessages" ref="btn-messages-refresh"> - <tooltip>odśwież</tooltip> - <fa :icon="['fal', 'sync']" :spin="messages.state === 'fetching'" fixed-width></fa> - </button> - <button class="btn btn-action" @click="sections.messages = !sections.messages"> - <tooltip> - {{ '{{ ' }} sections.messages ? 'zwiń' : 'rozwiń' {{ '}}' }} - <span class="sr-only">sekcję komunikatów</span> - </tooltip> - <fa :icon="['fal', sections.messages ? 'chevron-up' : 'chevron-down']" fixed-width/> - </button> - - <popper reference="settings-messages" v-if="visibility.messages" arrow placement="left-start" @leave="visibility.messages = false"> - <h3 class="popper__heading flex"> - <fa :icon="['far', 'cog']"></fa> - <label class="text" for="messages-auto-refresh">autoodświeżanie</label> - <input type="checkbox" class="flex-space-left" id="messages-auto-refresh" v-model="autorefresh.messages.active"/> - </h3> - <div class="flex" v-show="autorefresh.messages.active"> - <span class="text">co</span> - <label class="sr-only" for="messages-auto-refresh-interval">częstotliwość odświeżania</label> - <input type="text" class="form-control form-control-sm" id="messages-auto-refresh-interval" v-model="autorefresh.messages.interval"/> - <span class="text">s</span> - </div> - </popper> - </header> - <fold :visible="sections.messages"> - <messages></messages> - </fold> - </section> - - <section class="section"> - <header class="section__title flex"> - <h2> - <fa :icon="['fal', 'clock']" fixed-width></fa> - <span class="text">Odjazdy</span> - </h2> - - <button class="btn btn-action flex-space-left" ref="settings-departures" @click="visibility.departures = true"> - <tooltip>ustawienia</tooltip> - <fa :icon="['fal', 'cog']" fixed-width></fa> - </button> - <button class="btn btn-action" @click="updateDepartures({ stops })"> - <tooltip>odśwież</tooltip> - <fa :icon="['fal', 'sync']" :spin="departures.state === 'fetching'" fixed-width></fa> - </button> - <portal to="popups"> - <popper reference="settings-departures" v-if="visibility.departures" arrow placement="left-start" @leave="visibility.departures = false"> - <h3 class="popper__heading flex"> - <fa :icon="['far', 'sync']" fixed-width></fa> - <label class="text" for="messages-auto-refresh">autoodświeżanie</label> - <input type="checkbox" class="flex-space-left" id="messages-auto-refresh" v-model="autorefresh.departures.active"/> - </h3> - <div class="flex" v-show="autorefresh.messages.active"> - <span class="text">co</span> - <label class="sr-only" for="messages-auto-refresh-interval">częstotliwość odświeżania</label> - <input type="text" class="form-control form-control-sm form-control-simple" id="messages-auto-refresh-interval" v-model="autorefresh.departures.interval"/> - <span class="text">s</span> - </div> - </popper> - </portal> - </header> - <departures :stops="stops"></departures> - {% if provider.attribution %} - <div class="attribution"> - <fa :icon="['fal', 'info-circle']"></fa> - Pochodzenie danych: {{ provider.attribution|raw }} - </div> - {% endif %} - </section> - </div> - <div class="col-md-4 order-md-first"> - <section class="section picker" v-if="stops.length > 0"> - <header class="section__title flex"> - <h2> - <fa :icon="['fal', 'sign']" fixed-width></fa> - <span class="text">Przystanki</span> - </h2> - <button class="btn btn-action flex-space-left" @click="clear"> - <tooltip>usuń wszystkie</tooltip> - <fa :icon="['fal', 'trash-alt']" fixed-width></fa> - </button> - </header> - - <ul class="picker__stops list-underlined"> - <li v-for="stop in stops" :key="stop.id" class="d-flex align-items-center"> - <picker-stop :stop="stop" class="flex-grow-1"> - <template v-slot:primary-action> - <button @click="remove(stop)" class="btn btn-action"> - <tooltip>usuń przystanek</tooltip> - <fa :icon="['fal', 'times']"></fa> - </button> - </template> - </picker-stop> - </li> - </ul> - - <div class="d-flex mt-2"> - <button class="btn btn-action btn-sm flex-space-left" @click="visibility.save = true" ref="save"> - <fa :icon="['fal', 'star']" fixed-width></fa> - zapisz jako... - </button> - </div> - - <popper reference="save" v-if="visibility.save" arrow tabindex="-1" @leave="visibility.save = false" placement="bottom-end"> - <favourites-adder @saved="visibility.save = false"/> - </popper> - </section> - <section class="section picker"> - <header class="section__title flex"> - <template v-if="visibility.picker === 'search'"> - <h2 class="flex-grow-1"> - <fa :icon="['fal', 'search']" fixed-width class="mr-1"></fa> - Wybierz przystanki - </h2> - <button class="btn btn-action" @click="visibility.picker = 'favourites'"> - <tooltip>Zapisane</tooltip> - <fa :icon="['fal', 'star']" fixed-witdth></fa> - </button> - </template> - <template v-else> - <h2 class="flex-grow-1"> - <fa :icon="['fal', 'star']" fixed-width class="mr-1"></fa> - Zapisane - </h2> - <button class="btn btn-action" @click="visibility.picker = 'search'"> - <tooltip>Wybierz przystanki</tooltip> - <fa :icon="['fal', 'search']" fixed-witdth></fa> - </button> - </template> - </header> - <div class="transition-box"> - <transition name="fade"> - <stop-finder @select="add" :blacklist="stops" v-if="visibility.picker === 'search'"></stop-finder> - <favourites v-else-if="visibility.picker === 'favourites'"></favourites> - </transition> - </div> - </section> - </div> - </div> - - <portal-target name="popups" multiple></portal-target> -{% endblock %} - -{% block javascripts %} - <script> - window.data = { - provider: {{ provider.identifier|json_encode|raw }} - }; - - window.czydojade = {}; - window.czydojade.state = {{ state|json_encode|raw }}; - </script> -{% endblock %} diff --git a/templates/base.html.twig b/templates/base.html.twig deleted file mode 100644 index ed9d198..0000000 --- a/templates/base.html.twig +++ /dev/null @@ -1,56 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <meta charset="UTF-8"/> - <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> - <link rel="stylesheet" href="{{ asset('dist/main.css') }}" /> - <link rel="manifest" href="{% block manifest 'manifest.json' %}" /> - - <!-- icons --> - <link rel="icon" href="images/favicon.png" sizes="16x16" /> - <link rel="icon" href="images/favicon-2x.png" sizes="32x32" /> - <link rel="icon" href="images/favicon.ico" /> - - <!-- Apple shit --> - <link rel="apple-touch-icon" href="images/ios.png" sizes="512x512"> - <link rel="apple-touch-icon" href="images/ios-80.png" sizes="80x80"> - <link rel="apple-touch-icon" href="images/ios-192.png" sizes="192x192"> - <meta name="apple-mobile-web-app-title" content="Czy Dojadę?"> - <meta name="apple-mobile-web-app-capable" content="yes"> - - <title>{% block title %}Czy dojadę?{% endblock %}</title> - - {% if ga_tracking %} - <!-- Global site tag (gtag.js) - Google Analytics --> - <script async src="https://www.googletagmanager.com/gtag/js?id={{ ga_tracking }}"></script> - <script> - window.dataLayer = window.dataLayer || []; - function gtag(){dataLayer.push(arguments);} - - gtag('js', new Date()); - gtag('config', '{{ ga_tracking }}'); - </script> - {% endif %} - </head> - <body> - <main role="main" class="container not-ready" id="app"> - {% block body %}{% endblock %} - </main> - <footer class="container"> - {% block footer %} - <span> - <img src="{{ asset('images/logo.png') }}" alt="czydojade logo"/> - v. {{ version() }} • - <a href="{{ url('app.swagger_ui') }}">API</a> - </span> - <span class="copyright flex flex-space-left justify-content-end"> - <a href="https://kadet.net"><img src="{{ asset('images/kadet-net-logo.png') }}" alt="kadet.net logo" class="mx-1"/></a> - © {{ 'now'|date('Y') }} - </span> - {% endblock %} - </footer> - - {% block javascripts %}{% endblock %} - <script src="{{ asset('dist/main.js') }}"></script> - </body> -</html> diff --git a/templates/choose.html.twig b/templates/choose.html.twig deleted file mode 100644 index 8d4a044..0000000 --- a/templates/choose.html.twig +++ /dev/null @@ -1,17 +0,0 @@ -{% extends 'base.html.twig' %} - -{% block body %} - <div class="alert alert-primary"> - <fa :icon="['fal', 'info-circle']"></fa> - Wybierz źródło danych - </div> - <ul class="list-underlined"> - {% for provider in providers %} - <li title="Aktualizacja: {{ provider.lastUpdate ? provider.lastUpdate.format('Y.m.d H:i') : 'live' }}"> - <a href="{{ path('app', { provider: provider.identifier }) }}" class="btn btn-block btn-action text-left"> - {{ provider.name }} - </a> - </li> - {% endfor %} - </ul> -{% endblock %} \ No newline at end of file diff --git a/templates/manifest.json.twig b/templates/manifest.json.twig deleted file mode 100644 index 06ade28..0000000 --- a/templates/manifest.json.twig +++ /dev/null @@ -1,30 +0,0 @@ -{ - "name": "Czy Dojadę? - {{ provider.shortName }}", - "short_name": "Czy Dojadę? - {{ provider.shortName }}", - "orientation": "portrait", - "lang": "pl_PL", - "start_url": "{{ path('app', { provider: provider.identifier }) }}", - "display": "standalone", - "background_color": "white", - "theme_color": "#005ea8", - "description": "Odpowiedź na odwieczne pytanie ludzkości - czy tramwaje jeżdżą?", - "icons": [{ - "src": "{{ asset('images/icon-256.png') }}", - "sizes": "256x256" - },{ - "src": "{{ asset('images/icon-512.png') }}", - "sizes": "512x512" - },{ - "src": "{{ asset('images/icon-64.png') }}", - "sizes": "64x64" - },{ - "src": "{{ asset('images/icon-128.png') }}", - "sizes": "128x128" - },{ - "src": "{{ asset('images/icon-192.png') }}", - "sizes": "192x192" - },{ - "src": "{{ asset('images/icon-96.png') }}", - "sizes": "96x96" - }] -} diff --git a/translations/.gitignore b/translations/.gitignore deleted file mode 100644 index e69de29..0000000 diff --git a/tsconfig.json b/tsconfig.json deleted file mode 100644 index 9f6d92c..0000000 --- a/tsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "compilerOptions": { - "lib": ["dom", "es2015", "es2016.array.include", "es2017.object"], - "experimentalDecorators": true, - "target": "es5", - "module": "esnext", - "sourceMap": true, - "noImplicitThis": true, - "moduleResolution": "node", - "downlevelIteration": true - }, - "files": ["resources/ts/app.ts"] -} \ No newline at end of file