From e1517ecd9d53b4cfde5e21d57ac2b3534288d183 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Fri, 13 Mar 2020 11:17:16 +0000 Subject: [PATCH 01/77] Initial commit --- .github/workflows/lint.yml | 29 + .gitignore | 1 + README.md | 1337 +++++++++++++++++ docs/images/1.png | Bin 0 -> 182978 bytes docs/images/2.png | Bin 0 -> 190562 bytes docs/images/3.png | Bin 0 -> 243702 bytes package-lock.json | 12 + package.json | 5 + prettier.config.js | 18 + step1-first-test/my_module.info.yml | 5 + .../tests/src/Functional/MyModuleTest.php | 19 + .../my_module.info.yml | 5 + .../tests/src/Functional/MyModuleTest.php | 39 + step3-building-a-blog-page/my_module.info.yml | 5 + .../my_module.routing.yml | 7 + .../src/Controller/BlogPageController.php | 17 + .../tests/src/Functional/BlogPageTest.php | 28 + .../tests/src/Functional/MyModuleTest.php | 19 + .../my_module.info.yml | 5 + .../my_module.routing.yml | 7 + .../my_module.services.yml | 6 + .../src/Controller/BlogPageController.php | 45 + .../src/Repository/ArticleRepository.php | 33 + .../tests/src/Functional/BlogPageTest.php | 27 + .../tests/src/Functional/MyModuleTest.php | 19 + .../src/Kernel/ArticleRepositoryTest.php | 75 + .../my_module.info.yml | 5 + .../my_module.routing.yml | 7 + .../my_module.services.yml | 6 + .../src/Controller/BlogPageController.php | 45 + .../src/Repository/ArticleRepository.php | 33 + .../src/Wrapper/ArticleWrapper.php | 40 + .../tests/src/Functional/BlogPageTest.php | 27 + .../tests/src/Functional/MyModuleTest.php | 19 + .../src/Kernel/ArticleRepositoryTest.php | 75 + .../src/Unit/Wrapper/ArticleWrapperTest.php | 73 + 36 files changed, 2093 insertions(+) create mode 100644 .github/workflows/lint.yml create mode 100644 .gitignore create mode 100644 README.md create mode 100644 docs/images/1.png create mode 100644 docs/images/2.png create mode 100644 docs/images/3.png create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 prettier.config.js create mode 100644 step1-first-test/my_module.info.yml create mode 100644 step1-first-test/tests/src/Functional/MyModuleTest.php create mode 100644 step2-adding-more-test-methods/my_module.info.yml create mode 100644 step2-adding-more-test-methods/tests/src/Functional/MyModuleTest.php create mode 100644 step3-building-a-blog-page/my_module.info.yml create mode 100644 step3-building-a-blog-page/my_module.routing.yml create mode 100644 step3-building-a-blog-page/src/Controller/BlogPageController.php create mode 100644 step3-building-a-blog-page/tests/src/Functional/BlogPageTest.php create mode 100644 step3-building-a-blog-page/tests/src/Functional/MyModuleTest.php create mode 100644 step4-adding-the-blog-repository/my_module.info.yml create mode 100644 step4-adding-the-blog-repository/my_module.routing.yml create mode 100644 step4-adding-the-blog-repository/my_module.services.yml create mode 100644 step4-adding-the-blog-repository/src/Controller/BlogPageController.php create mode 100644 step4-adding-the-blog-repository/src/Repository/ArticleRepository.php create mode 100644 step4-adding-the-blog-repository/tests/src/Functional/BlogPageTest.php create mode 100644 step4-adding-the-blog-repository/tests/src/Functional/MyModuleTest.php create mode 100644 step4-adding-the-blog-repository/tests/src/Kernel/ArticleRepositoryTest.php create mode 100644 step5-wrapping-up-with-unit-tests/my_module.info.yml create mode 100644 step5-wrapping-up-with-unit-tests/my_module.routing.yml create mode 100644 step5-wrapping-up-with-unit-tests/my_module.services.yml create mode 100644 step5-wrapping-up-with-unit-tests/src/Controller/BlogPageController.php create mode 100644 step5-wrapping-up-with-unit-tests/src/Repository/ArticleRepository.php create mode 100644 step5-wrapping-up-with-unit-tests/src/Wrapper/ArticleWrapper.php create mode 100644 step5-wrapping-up-with-unit-tests/tests/src/Functional/BlogPageTest.php create mode 100644 step5-wrapping-up-with-unit-tests/tests/src/Functional/MyModuleTest.php create mode 100644 step5-wrapping-up-with-unit-tests/tests/src/Kernel/ArticleRepositoryTest.php create mode 100644 step5-wrapping-up-with-unit-tests/tests/src/Unit/Wrapper/ArticleWrapperTest.php diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..ac78494 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,29 @@ +name: Lint README.md + +on: + push: + +jobs: + lint: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@master + + - name: Run prettier + run: | + npm install + npx prettier README.md --write + + - name: Commit changes + run: | + if [ -n "$(git status --short README.md)" ]; then + git config --local user.name "Oliver Davies" + git config --local user.email "339813+opdavies@users.noreply.github.com" + git commit -a -m "Run prettier" + fi + + - name: Push changes + uses: ad-m/github-push-action@master + with: + github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..096746c --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/node_modules/ \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..b1169f7 --- /dev/null +++ b/README.md @@ -0,0 +1,1337 @@ +# Workshop: Automated Testing and Test Driven Development in Drupal 8 + +## Table of Contents + +- [Introduction](#introduction) +- [Creating a new Drupal project with Composer](#creating-a-new-drupal-project-with-composer) +- [Using the Symfony web server for local development](#using-the-symfony-web-server-for-local-development) +- [The different types of available tests](#the-different-types-of-available-tests) +- [Different approaches to testing](#different-approaches-to-testing) +- [A structure of a test](#a-structure-of-a-test) +- [What is Test Driven Development?](#what-is-test-driven-development) +- [Acceptance criteria](#acceptance-criteria) +- [Step 0: Preparation](#step-0-preparation) +- [Step 1: Writing your first test](#step-1-writing-your-first-test) + - [1a. Create the module directory](#1a-create-the-module-directory) + - [1b. Create an .info.yml file for the module](#1b-create-an-infoyml-file-for-the-module) + - [1c. Create the directory structure for tests](#1c-create-the-directory-structure-for-tests) + - [1d. Create your first test case](#1d-create-your-first-test-case) + - [1e. Preparing PHPUnit](#1e-preparing-phpunit) + - [1f. Running the tests](#1f-running-the-tests) + - [1g. (Optional) Running tests via a Composer script](#1g-optional-running-tests-via-a-composer-script) +- [Step 2: Adding more test methods](#step-2-adding-more-test-methods) + - [2a. Ensure that anonymous users cannot access admin pages](#2a-ensure-that-anonymous-users-cannot-access-admin-pages) + - [2b. Ensure that administrators can access admin pages](#2b-ensure-that-administrators-can-access-admin-pages) +- [Step 3: Building a blog](#step-3-building-a-blog) + - [3a. Anonymous users should be able to view the blog page](#3a-anonymous-users-should-be-able-to-view-the-blog-page) + - [3b. Add a route for the blog page](#3b-add-a-route-for-the-blog-page) + - [3c. Fix permission error](#3c-fix-permission-error) + - [3d. Add the BlogPageController](#3d-add-the-blogpagecontroller) + - [3e. Refactor, add more assertions](#3e-refactor-add-more-assertions) +- [Step 4: Getting blog posts](#step-4-getting-blog-posts) + - [4a Creating our first kernel test](#4a-creating-our-first-kernel-test) + - [4b. Starting with an assertion](#4b-starting-with-an-assertion) + - [4c. Trying to use the ArticleRepository](#4c-trying-to-use-the-articlerepository) + - [4d. Creating an article repository](#4d-creating-an-article-repository) + - [4e. Adding the getAll() method](#4e-adding-the-getall-method) + - [4f. Building up the ArticleRepository](#4f-building-up-the-articlerepository) + - [4g. Adding articles](#4g-adding-articles) + - [4h. Making this test less brittle](#4h-making-this-test-less-brittle) + - [4i. Ensuring that only published articles are returned](#4i-ensuring-that-only-published-articles-are-returned) + - [4j. Ensuring that articles are returned in the correct order](#4j-ensuring-that-articles-are-returned-in-the-correct-order) + - [4k. Linking up the repository to the BlogPageController](#4k-linking-up-the-repository-to-the-blogpagecontroller) +- [Step 5: Wrapping up with unit tests](#step-5-wrapping-up-with-unit-tests) + - [5a. Creating an ArticleWrapper](#5a-creating-an-articlewrapper) + - [5b. Ensure that we’re only wrapping articles](#5b-ensure-that-were-only-wrapping-articles) + - [5c. Determine if articles are publishable](#5c-determine-if-articles-are-publishable) + +## Introduction + +## Creating a new Drupal project with Composer + +If don’t have Composer, visit for +instructions on how to install it on your computer. + +This assumes that Composer is installed globally and is available by running the +`composer` command. Alternatively, you can download the phar file and run +`php composer.phar` instead. + +```bash +# Create a new Drupal project +composer create-project drupal/recommended-project my-project + +cd my-project + +# Add testing dependencies +composer require --dev drupal/core-dev +``` + +You should now have files present including `web/index.php` and +`vendor/bin/phpunit`. Now you can start serving this site locally. + +**Note:** Development dependencies, including PHPUnit, should only be installed +locally and should not be present on public servers. Doing so would present a +security risk to your application. + +## Using the Symfony web server for local development + +https://symfony.com/doc/current/setup/symfony_server.html + +- Part of the Symfony CLI. +- Download from . +- Docker provides the integration with MySQL. +- Faster performance compared to mounting files within Docker volumes. +- Need `docker-compose.yml` to provide the database service, `.php-version` to + set the version of PHP +- +- - blog post + +## The different types of available tests + +- **Functional** (web, feature) - tests behaviour and functionality, makes HTTP + requests to the webserver and has access to the database and other services + via the service container. Slower to run. +- **FunctionalJavascript** - functional tests, but access to JavaScript. +- **Kernel** (integration) - no browser capabilities, has access to the database + and other services but requires more configuration. +- **Unit** - no access to the database or service container, all dependencies + need to be mocked. Fast to run. + +## Different approaches to testing + +- Inside-out (testing pyramid) - mostly unit tests, some integration tests, few + functional tests. +- Outside-in (testing trophy) - mostly functional tests, some integration tests, + few unit tests. More flexible, easier to refactor. + +## Structure of a test + +- **Arrange** - set up the environment. Create users, nodes, set up dependencies +- **Act** - perform an action +- **Assert** - verify that something happened + +## What is Test Driven Development? + +- Writing tests first +- Red, green, refactor loop + - Writing failing test first + - Write code to make the test pass + - Refactor when tests pass +- Three (simplified) rules of TDD: + - Write production code only to make a failing unit test pass. + - Write only enough of a unit test to fail. + - Write only enough production code to make the failing unit test pass. + - + +## Acceptance criteria + +This module will be used to demonstrate how to take a test-driven approach to +develop a module to the following acceptance criteria: + +- As a site visitor +- I want to see a list of all published articles at `/blog` +- Ordered by post date, with the newest posts first + +## Step 0: Preparation + +To begin with, we need the site to be running. If using the Symfony server, run +these commands: + +```bash +# Start the service containers +docker-compose up -d + +# Start the local web server +symfony serve -d +``` + +You don’t need to install Drupal, it just needs to be able to connect to the +database. + +## Step 1: Writing your first test + +### 1a. Create the module directory + +Create a directory for the new module: + +``` +mkdir -p web/modules/my_module +``` + +### 1b. Create an `.info.yml` file for the module + +In order to install the module, it needs an info.yml file that matches the name +of the module (e.g. `my_module.info.yml`). + +Within the `my_module` directory, create the file and paste in the following +content: + +```yaml +name: My Module +type: module +core: 8.x +core_version_requirement: ^8 || ^9 +package: Custom +``` + +### 1c. Create the directory structure for tests + +```bash +mkdir -p tests/src/Functional +``` + +### 1d. Create your first test case + +```php +// MyModuleTest.php + +namespace Drupal\Tests\my_module\Functional; + +use Drupal\Tests\BrowserTestBase; +use Symfony\Component\HttpFoundation\Response; + +class MyModuleTest extends BrowserTestBase { + + protected $defaultTheme = 'stark'; + + protected static $modules = ['my_module']; + + /** @test */ + public function the_front_page_loads_for_anonymous_users() { + $this->drupalGet(''); + + $this->assertResponse(Response::HTTP_OK); + } + +} +``` + +Some things to note: + +- The name of the class must match the filename. +- The filename must end with `Test.php`. +- The namespace is `Drupal\Tests\{module_name}`, followed by any additional + directories (e.g. `Functional`). +- Test methods must start with `test`, or use the `@test` annotation. + +### 1e. Preparing PHPUnit + +Firstly, we need to create a `phpunit.xml` file to configure PHPUnit. Core has a +`phpunit.xml.dist` file that we can duplicate and edit. + +```bash +cp web/core/phpunit.xml.dist web/core/phpunit.xml +``` + +Update the `SIMPLETEST_BASE_URL` value to be the address that the website is +currently running on. This needs to be correct so that functional tests return +the correct response codes, so ensure that any port numbers are correct and also +that the site is correctly marked as HTTP or HTTPS. + +We also need to configure the database for Drupal to connect to and use when +running functional and kernel tests. This could be your project’s MySQL or +PostgreSQL database with a table prefix, but in this case, we’ll use a separate +SQLite database. + +```diff +- ++ + +- ++ +``` + +### 1f. Running the tests + +```bash +# Make sure you’re in the right place +cd web + +# Run the tests +../vendor/bin/phpunit -c core modules/my_module +``` + +You should see a summary of the number of tests and assertions that were run. +This is the expected output if all of the tests pass: + +> OK (1 test, 2 assertions) + +If a test failed, the output would show the class and method name for the +failing test, and give a summary of the failure. + +> Drupal\Tests\my_module\Functional\MyModuleTest::testThatTheFrontPageLoads +> Behat\Mink\Exception\ExpectationException: Current response status code is +> 404, but 200 expected. + +Other useful options include `--stop-on-failure`, `--filter` and `--testdox`. + +### 1g. (Optional) Running tests via a Composer script + +To simplify running tests, the command could be simplified by [adding a +script][composer scripts] to `composer.json`: + +```json +"scripts": { + "test:phpunit": "cd web && ../vendor/bin/phpunit -c core --verbose --testdox", + "test": [ + "@test:phpunit" + ] +} +``` + +This means that you can run just `symfony composer test:phpunit` or +`symfony composer test` and it will automatically move into the right directory +and execute the test command. + +This approach can be useful if you want to run other commands in addition to +PHPUnit such as PHPStan, PHP Code Sniffer or Drupal Check. Each command can be +added to the script and they will each be executed. + +If needed, you can still pass additional arguments and options to the command by +appending `--` followed by the arguments. + +```bash +symfony composer test:phpunit -- modules/my_module \ + --stop-on-failure \ + --filter=the_front_page_loads_for_anonymous_users +``` + +Locally, make sure that the command is prefixed with `symfony` if you are using +the Symfony web server to ensure that the correct PHP version etc is used. + +[composer scripts]: + https://getcomposer.org/doc/articles/scripts.md#writing-custom-commands + +## Step 2: Adding more test methods + +### 2a. Ensure that anonymous users cannot access admin pages + +Now that we’re sure that the front page loads correctly, lets also check +anonymous users cannot access the administration area. This test is very similar +to the previous one, though instead we’re making a GET request to `/admin` and +ensuring that the response code is 403 (forbidden). + +As this functionality is provided by Drupal core by default, this should pass +automatically. + +```php +/** @test */ +public function the_admin_page_is_not_accessible_to_anonymous_users() { + $this->drupalGet('admin'); + + $this->assertResponse(Response::HTTP_FORBIDDEN); +} +``` + +### 2b. Ensure that administrators can access admin pages + +Now let’s check that an administrator user _can_ access the admin pages. + +This introduces some new concepts. We need to create a user to begin with, and +assign it some permissions. Because tests may be included within Drupal core a +contributed module, permissions need to be added to users directly as modules +won’t know about roles that are specific to your site. + +The `BrowserTestBase` class gives access to a number of helper methods, +including ones for creating and logging-in users (`createUser` and `drupalLogin` +respectively). When creating a user, the first argument is an array of +permission names to add. In this case, we can make the user an admin user by +adding the `access administration pages` permission. + +```php +/** @test */ +public function the_admin_page_is_accessible_by_admin_users() { + $adminUser = $this->createUser([ + 'access administration pages', + ]); + + $this->drupalLogin($adminUser); + + $this->drupalGet('admin'); + + $this->assertResponse(Response::HTTP_OK); +} +``` + +Again, as this functionality is provided by Drupal core by default, this should +pass. However, we can be confident that the test is doing what’s needed by +making it fail by removing or changing the assigned permissions, or not logging +in the user before accessing the page. + +## Step 3: Building a blog + +### 3a. Anonymous users should be able to view the blog page + +Let’s start by building a blog page. This will look very similar to the admin +page tests, but instead we’ll be testing the `/blog` page. + +```php +// tests/src/Functional/BlogPageTest.php + +namespace Drupal\my_module\Functional; + +use Drupal\Tests\BrowserTestBase; +use Symfony\Component\HttpFoundation\Response; + +class BlogPageTest extends BrowserTestBase { + + protected $defaultTheme = 'stark'; + + protected static $modules = [ + 'my_module', + ]; + + /** @test */ + public function the_blog_page_loads_for_anonymous_users_and_contains_the_right_text() { + $this->drupalGet('blog'); + + $session = $this->assertSession(); + + $session->statusCodeEquals(Response::HTTP_OK); + } + +} + +``` + +This test will fail as there’s no route for `/blog` and no View that generates +that page. Because of this, the response code will be a 404 instead of the 200 +that we want. + +> Current response status code is 404, but 200 expected. + +### 3b: Add a route for the blog page + +We’ll create a blog page using a custom route in the module. You could also do +this with the Views module by creating a View with a page on that path, and +exporting the configuration into the module’s `config/install` directory. + +To add a route, we need to create a `my_module.routing.yml` file. + +```yaml +# my_module.routing.yml + +blog.page: + path: /blog + defaults: + _controller: Drupal\my_module\Controller\BlogPageController + _title: Blog + requirements: + _permission: access content +``` + +We set our path to `/blog`, specify the Controller to use and which permission +the needs to have to access the page. + +If we run the tests now, we get an access denied error (403 response). + +> Current response status code is 403, but 200 expected. + +### 3c: Fix permission error + +Because we need to node module to be able to access the `access content` +permission, we need to enable it within our tests. + +We can do this by adding it to the `$modules` array within the test. + +```diff + protected static $modules = [ ++ 'node', + 'my_module', + ]; +``` + +Now the error has changed, and is now returning a 500 response because we’ve +specified a Controller that doesn’t exist. + +> Current response status code is 500, but 200 expected. + +### 3d: Add the BlogPageController + +Let’s create the `BlogPageController`. + +``` +mkdir src/Controller +``` + +Let’s start by creating a minimal controller, that returns an empty render +array. Because we didn’t specify a method to use within the route file, we use +PHP’s `__invoke()` method. + +```php +// src/Controller/BlogPageController + +namespace Drupal\my_module\Controller; + +class BlogPageController { + + public function __invoke(): array { + return []; + } + +} +``` + +This is enough for the test to pass. Though it just returns an empty page, it +now returns the correct 200 response code. + +> OK (1 test, 3 assertions) + +This is how the page looks in a browser: + +![](docs/images/1.png) + +### 3e: Refactor, add more assertions + +Now that the test is passing, we can do some refactoring and make the test more +robust by ensuring that the correct text is displayed. + +```diff + public function the_blog_page_loads_for_anonymous_users_and_contains_the_right_text() { + $this->drupalGet('/blog'); + + $session = $this->assertSession(); + + $session->statusCodeEquals(Response::HTTP_OK); ++ $session->responseContains('

Blog

'); ++ $session->pageTextContains('Welcome to my blog!'); + } +``` + +The page title is created by the `_title` value within the routing file, but no +page text has been added yet so this will cause the test to fail. + +> Behat\Mink\Exception\ResponseTextException: The text "Welcome to my blog!" was +> not found anywhere in the text of the current page. + +To fix this, we can return some text from the BlogPageController rather than an +empty render array. + +```diff + namespace Drupal\my_module\Controller; + ++ use Drupal\Core\StringTranslation\StringTranslationTrait; + + class BlogPageController { + ++ use StringTranslationTrait; + + public function __invoke(): array { +- return []; ++ return [ ++ '#markup' => $this->t('Welcome to my blog!'), ++ ]; + } + + } +``` + +Now the tests will pass because we’re returning the correct text. + +> OK (1 test, 3 assertions) + +![](docs/images/2.png) + +## Step 4. Getting blog posts + +### 4a Creating our first kernel test + +We’ll be using an ArticleRepository class to get the blog posts from the +database, and this is also a good time to switch to writing kernel tests as we +don’t need to check any responses from the browser. + +Within the tests directory, create a new `Kernel` directory. + +``` +mkdir tests/src/Kernel +``` + +And an `ArticleRepositoryTest` class. + +```php +// tests/src/Kernel/ArticleRepositoryTest.php + +namespace Drupal\Tests\my_module\Kernel; + +use Drupal\KernelTests\Core\Entity\EntityKernelTestBase; + +class ArticleRepositoryTest extends EntityKernelTestBase { + + /** @test */ + public function nodes_that_are_not_articles_are_not_returned() { + + } + +} +``` + +This test looks very similar to the functional ones that we’ve already written, +except it extends a different base class. + +This test is extending `EntityKernelTestBase` as we’re working with entities and +this performs some useful setup steps for us. There are different base classes +that can be used though based on what you need - including `KernelTestBase` and +`ConfigFormTestBase`. + +### 4b. Starting with an assertion + +Let’s write this test 'backwards' and start with the 'assert' phase. + +We know that the end objective for this test is to have 3 article nodes +returned, so let’s add that assertion first. + +```diff + /** @test */ + public function nodes_that_are_not_articles_are_not_returned() { ++ $this->assertCount(3, $articles); + } +``` + +As we aren’t yet returning any articles, or even creating that variable, the +test is going to fail, but we can move on to getting articles. + +> Undefined variable: articles + +### 4c. Trying to use the ArticleRepository + +As the test name suggests, we’re going to be retrieving the articles from an +`ArticleRepository` service - though this doesn’t exist yet, but let’s let the +tests tell us that. + +```diff + /** @test */ + public function nodes_that_are_not_articles_are_not_returned() { ++ $repository = $this->container->get(ArticleRepository::class); ++ + $this->assertCount(3, $articles); + } +``` + +Because this is a kernel test, we have access to the container, and we can use +it to retrieve our repository service. + +Running the test now gives us a different error, and tells us what the next step +is: + +> Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException : You +> have requested a non-existent service +> "Drupal\Tests\my_module\Kernel\ArticleRepository". + +### 4d. Creating an article repository + +```bash +mkdir src/Repository +``` + +To begin with, let’s create a basic `ArticleRepository` class. + +```php +// my_module/src/Repository/ArticleRepository + +namespace Drupal\my_module\Repository; + +class ArticleRepository { + +} +``` + +We also need to create a `my_module.services.yml` file that we can use to +register the `ArticleRepository` as a service. + +```yaml +# my_module.services.yml + +services: + Drupal\my_module\Repository\ArticleRepository: ~ +``` + +Within `ArticleRepositoryTest`, we need to add the import statement for the +`ArticleRepository` as well enabling the module. + +```diff ++ use Drupal\my_module\Repository\ArticleRepository; + ++ public static $modules = [ ++ 'my_module', ++ ]; +``` + +We’ve fixed the missing repository, though we still haven’t created the +`$articles` variable or given it a value yet. + +> Undefined variable: articles + +### 4e. Adding the `getAll()` method + +We’ll use a `getAll()` method on the repository to retrieve the articles from +the database, and use the value of this for the `$articles` variable: + +```diff + $repository = $this->container->get(ArticleRepository::class); ++ $articles = $repository->getAll(); + + $this->assertCount(3, $articles); +``` + +This method doesn’t exist on the repository yet, so the test will fail. + +> Error : Call to undefined method +> Drupal\my_module\Repository\ArticleRepository::getAll() + +Let’s fix that by adding the `getAll()` method. For now, have it return an empty +array. + +```php +// my_module/Repository/ArticleRepository.php + +public function getAll(): array { + return []; +} +``` + +Now we’ve got everything in place, and the test failure is because we aren’t +returning the correct number of articles. + +> Failed asserting that actual size 0 matches expected size 3. + +We can fix this by building up the `ArticleRepository` class. + +### 4f. Building up the ArticleRepository + +The `ArticleRepository` needs to return some articles. We can do this by +injecting the `EntityTypeManager` and using it to return nodes from the +`getAll()` method rather than the empty array. + +```diff ++ /** ++ * @var \Drupal\Core\Entity\EntityStorageInterface ++ */ ++ private $nodeStorage; + ++ public function __construct(EntityTypeManagerInterface $entityTypeManager) { ++ $this->nodeStorage = $entityTypeManager->getStorage('node'); ++ } + + public function getAll(): array { +- return []; ++ return $this->nodeStorage->loadMultiple(); + } +``` + +Within our services file, we now need to add the `EntityTypeManager` as an +argument so that it’s used to create the `ArticleRepository`. Currently we don’t +have enough arguments. + +> ArgumentCountError : Too few arguments to function +> Drupal\my_module\Repository\ArticleRepository::\_\_construct(), 0 passed and +> exactly 1 expected + +The quickest way to do that is to enable autowiring for the ArticleRepository +within `my_module.services.yml`. This will automatically inject services rather +than needing to specify each argument individually. + +```diff +- Drupal\my_module\Repository\ArticleRepository: ~ ++ Drupal\my_module\Repository\ArticleRepository: ++ autowire: true +``` + +> Drupal\Component\Plugin\Exception\PluginNotFoundException : The "node" entity +> type does not exist. + +As we did previously, we need to enable the `node` module. + +```diff + public static $modules = [ ++ 'node', + 'my_module', + ]; +``` + +The `ArticleRepository` is now working, but is still returning no articles - +though this is because we haven’t created any inside the test. + +> Failed asserting that actual size 0 matches expected size 3. + +### 4g. Adding articles + +To test the ArticleRepository, we need articles to be created so that they can +be returned. + +Within the `ArticleRepositoryTest` we can make use of one of a number of traits +that are provided. + +Within the class, enable the trait: + +```diff ++ use NodeCreationTrait +``` + +Include the import statement at the top of the file if it hasn’t been added +automatically. + +```diff ++ use Drupal\Tests\node\Traits\NodeCreationTrait; +``` + +This gives us a `createNode` method that we can use to create nodes by passing +an array of values. + +As we need 3 articles, let’s create them. + +```diff ++ $this->createNode(['type' => 'article'])->save(); ++ $this->createNode(['type' => 'article'])->save(); ++ $this->createNode(['type' => 'article'])->save(); +``` + +The next error is a little cryptic: + +> Error : Call to a member function id() on bool + +Looking at the stack trace, this error is within `filter.module`, where it’s +trying to call an `id()` method on a filter format. + +```php +// filter.module + +$formats = filter_formats($account); +$format = reset($formats); +return $format->id(); +``` + +As kernel tests don’t install configuration by default, we need to install the +missing filter configuration. + +As we’ll need this for all test methods in this case, we can use the `setUp()` +method that will run before each test. + +```diff ++ protected function setUp() { ++ parent::setUp(); ++ ++ $this->installConfig([ ++ 'filter', ++ ]); ++ } +``` + +We also need to create the `node_access` table as indicated by the next error: + +> Drupal\Core\Entity\EntityStorageException : SQLSTATE[HY000]: General error: 1 +> no such table: test90927710.node_access: DELETE FROM {node_access} + +```diff + protected function setUp() { + parent::setUp(); ++ ++ $this->installSchema('node', ['node_access']); ++ + $this->installConfig([ + 'filter', + ]); + } +``` + +We’ve successfully returned our three articles and this test now passes. + +> OK (1 test, 6 assertions) + +### 4h. Making this test less brittle + +The test is passing, but it currently returns _all_ nodes and not just articles. + +If we create some page nodes too, these will also be returned and the assertion +will now fail. + +```diff + $this->createNode(['type' => 'article'])->save(); ++ $this->createNode(['type' => 'page'])->save(); + $this->createNode(['type' => 'article'])->save(); ++ $this->createNode(['type' => 'page'])->save(); + $this->createNode(['type' => 'article'])->save(); +``` + +> Failed asserting that actual size 5 matches expected size 3. + +We can make a change to the `ArticleRepository` to fix this, and ensure that +we’re only loading and returning article nodes. + +```diff +- return $this->nodeStorage->loadMultiple(); ++ return $this->nodeStorage->loadByProperties([ ++ 'type' => 'article', ++ ]); +``` + +### 4i. Ensuring that only published articles are returned + +We now know that only article nodes are returned, but _all_ articles are being +returned. On our blog, we only want to published articles to be displayed. + +Let’s create another test for this. + +```diff ++ /** @test */ ++ public function only_published_articles_are_returned() { ++ $repository = $this->container->get(ArticleRepository::class); ++ $articles = $repository->getAll(); + ++ $this->assertCount(3, $articles); ++ } +``` + +We already know that only articles are returned, so in this test we can focus on +the published status. We can create a number of articles, some which are +published and some which are unpublished. + +```diff + /** @test */ + public function only_published_articles_are_returned() { ++ $this->createNode(['type' => 'article', 'status' => Node::PUBLISHED])->save(); ++ $this->createNode(['type' => 'article', 'status' => Node::NOT_PUBLISHED])->save(); ++ $this->createNode(['type' => 'article', 'status' => Node::PUBLISHED])->save(); ++ $this->createNode(['type' => 'article', 'status' => Node::NOT_PUBLISHED])->save(); ++ $this->createNode(['type' => 'article', 'status' => Node::PUBLISHED])->save(); + + $repository = $this->container->get(ArticleRepository::class); + $articles = $repository->getAll(); + + $this->assertCount(3, $articles); + } +``` + +Because we have no filter on the published state, all the articles are returned +including the unpublished ones. + +> Failed asserting that actual size 5 matches expected size 3. + +We can again update the `ArticleRepository` to add this extra condition to +filter out any unpublished articles. + +```diff ++ use Drupal\node\Entity\Node; + + public function getAll(): array { + return $this->nodeStorage->loadByProperties([ ++ 'status' => Node::PUBLISHED, + 'type' => 'article', + ]); + } +``` + +With this added, the test passes again. + +> OK (1 test, 6 assertions) + +### 4j. Ensuring that articles are returned in the correct order + +As per our acceptance criteria, we need the articles to be returned based on +their created date, so let’s create another test. + +In this test, let’s ensure assert that some article node IDs are returned within +a specific order. + +```diff ++ /** @test */ ++ public function nodes_are_ordered_by_date_and_newest_first() { ++ $this->assertSame([3, 1, 2, 5, 4], $nodeIds); ++ } +``` + +We can use the same `getAll()` method, and get the node IDs from the array keys. + +```diff + /** @test */ + public function nodes_are_ordered_by_date_and_returned_newest_first() { ++ $repository = $this->container->get(ArticleRepository::class); ++ $nodes = $repository->getAll(); ++ $nodeIds = array_keys($nodes); + + $this->assertSame([3, 1, 2, 5, 4], $nodeIds); + } +``` + +Use `createNode()` again to create some article nodes, each with a different +`created` date to match our assertion. This is to ensure that the test doesn’t +pass by default. + +```diff + /** @test */ + public function nodes_are_ordered_by_date_and_returned_newest_first() { ++ $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-2 days'))->getTimestamp()]); ++ $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-1 week'))->getTimestamp()]); ++ $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-1 hour'))->getTimestamp()]); ++ $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-1 year'))->getTimestamp()]); ++ $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-1 month'))->getTimestamp()]); + + $repository = $this->container->get(ArticleRepository::class); + $nodes = $repository->getAll(); + $nodeIds = array_keys($nodes); + + $this->assertSame([3, 1, 2, 5, 4], $nodeIds); + } +``` + +This test fails as expected, as the nodes are returned in their default order, +by node ID. + +> Failed asserting that two arrays are identical. --- Expected +++ Actual @@ @@ +> Array &0 ( +> +> - 0 => 3 +> - 1 => 1 +> - 2 => 2 +> - 3 => 5 +> - 4 => 4 +> +> * 0 => 1 +> * 1 => 2 +> * 2 => 3 +> * 3 => 4 +> * 4 => 5 ) + +To order the articles by their created date, we can update the `getAll()` method +within the `ArticleRepository`. + +```diff + public function getAll(): array { +- return $this->nodeStorage->loadByProperties([ ++ $articles = $this->nodeStorage->loadByProperties([ + 'status' => Node::PUBLISHED, + 'type' => 'article', + ]); ++ ++ // Sort the articles by their created date. ++ uasort($articles, function (NodeInterface $a, NodeInterface $b): bool { ++ return $a->getCreatedTime() < $b->getCreatedTime(); ++ }); ++ ++ return $articles; + } +``` + +The nodes are now ordered by their created date, and in the correct order to +match the assertion. + +> OK (1 test, 6 assertions) + +### 4k. Linking up the repository to the BlogPageController + +Now that our `ArticleRepository` tests are passing, we can use it within +`BlogPageController` so that articles are displayed on the page. + +Let’s add `BlogPageController` as a service and enable autowiring. + +```diff + # my_module.services.yml + + services: ++ Drupal\my_module\Controller\BlogPageController: ++ autowire: true + + Drupal\my_module\Repository\ArticleRepository: + autowire: true +``` + +Now we can inject the `ArticleRepository` and use it to load and render the +articles on the page. + +```diff + +namespace Drupal\my_module\Controller; + +use Drupal\Core\Entity\EntityTypeManagerInterface; +use Drupal\Core\StringTranslation\StringTranslationTrait; +use Drupal\my_module\Repository\ArticleRepository; + +class BlogPageController { + + use StringTranslationTrait; + ++ /** ++ * @var \Drupal\my_module\Repository\ArticleRepository ++ */ ++ private $articleRepository; ++ ++ /** ++ * @var \Drupal\Core\Entity\EntityViewBuilderInterface ++ */ ++ private $nodeViewBuilder; ++ ++ public function __construct( ++ EntityTypeManagerInterface $entityTypeManager, ++ ArticleRepository $articleRepository ++ ) { ++ $this->nodeViewBuilder = $entityTypeManager->getViewBuilder('node'); ++ $this->articleRepository = $articleRepository; ++ } + + public function __invoke(): array { +- return []; ++ $build = []; ++ ++ $articles = $this->articleRepository->getAll(); + ++ foreach ($articles as $article) { ++ $build[] = $this->nodeViewBuilder->view($article, 'teaser'); ++ } ++ ++ return [ ++ '#markup' => render($build), ++ ]; + } + +} +``` + +In the browser, we should see our list of articles. + +![](docs/images/3.png) + +## Step 5: Wrapping up with unit tests + +### 5a: Creating an ArticleWrapper + +The final thing that we’re going to do is create a wrapper class for articles so +that we can add additional methods. + +```bash +mkdir -p tests/src/Unit/Wrapper +``` + +```php +// tests/src/Unit/Wrapper/ArticleWrapperTest + +namespace Drupal\Tests\my_module\Unit\Wrapper; + +use Drupal\Tests\UnitTestCase; + +class ArticleWrapperTest extends UnitTestCase { +} +``` + +The first thing that we’re going to check is that we can wrap an article node +and then retrieve it again. + +```php +/** @test */ +public function it_can_return_the_article() { + $articleWrapper = new ArticleWrapper($article); + + $this->assertInstanceOf(NodeInterface::class, $articleWrapper->getOriginal()); + $this->assertSame(5, $articleWrapper->getOriginal()->id()); + $this->assertSame('article', $articleWrapper->getOriginal()->bundle()); +} +``` + +Lets create the `ArticleWrapper`: + +```php +// src/Wrapper/ArticleWrapper + +namespace Drupal\my_module\Wrapper; + +use Drupal\node\NodeInterface; + +class ArticleWrapper { + + private $article; + + public function __construct(NodeInterface $node) { + $this->article = $node; + } + + public function getOriginal(): NodeInterface { + return $this->article; + } + +} +``` + +In the `ArticleWrapperTest`, add the import statement for the wrapper. + +```diff ++ use Drupal\my_module\Wrapper\ArticleWrapper; + use Drupal\Tests\UnitTestCase; +``` + +Currently, we don’t yet have an article to wrap. + +> Undefined variable: article + +Because this is a unit test which has no access to the database, we can’t use +the `createNode()` method or `Node::create()` so we need to create a mock node. + +```diff ++ use Drupal\node\NodeInterface; + +$article = $this->createMock(NodeInterface::class); +``` + +This satisfies the instance assertion, but the other assertions are failing. + +> Failed asserting that null is identical to 5. + +In order for this to pass, we need to specify what value each method will method +will return (e.g. which node ID and which bundle type) so that these values are +populated when used within the production code. + +```diff + $article = $this->createMock(NodeInterface::class); ++ $article->method('id')->willReturn(5); ++ $article->method('bundle')->willReturn('article'); +``` + +> OK (1 test, 3 assertions) + +### 5b. Ensure that we’re only wrapping articles + +The ArticleWrapper is only supposed to be used for wrapping articles, so we want +to throw an Exception if a different type of node is used. + +Let’s create a page node and assert that an Exception should be thrown. + +```php +/** @test */ +public function it_throws_an_exception_if_the_node_is_not_an_article() { + $this->expectException(\InvalidArgumentException::class); + + $page = $this->createMock(NodeInterface::class); + $page->method('bundle')->willReturn('page'); + + new ArticleWrapper($page); +} +``` + +Because we’re currently not throwing an Exception, the assertion fails. + +> Failed asserting that exception of type "InvalidArgumentException" is thrown. + +Within `ArticleWrapper`, add a check using the `bundle()` method and throw an +Exception if it is not an article. + +```diff + public function __construct(NodeInterface $node) { ++ $this->verifyNodeType($node); + + $this->article = $node; + } + ++ private function verifyNodeType(NodeInterface $node): void { ++ if ($node->bundle() != 'article') { ++ throw new \InvalidArgumentException(sprintf( ++ '%s is not an article', ++ $node->bundle() ++ )); ++ } ++ } +``` + +If the Exception is thrown, the test will pass. + +### 5c. Determine if articles are publishable + +Let’s imagine that there is a rule that articles less than 3 days old are not +eligible to be published and we want to add an `isPublishable()` method that +will contain this logic and determine whether or not an article is publishable. + +We need access to the `Time` class to get the system time, so this is added as +an argument to the constructor and used within `isPublishable()` to compare the +created time of the article to the current time. + +```diff + ++ use Drupal\Component\Datetime\TimeInterface; + use Drupal\node\NodeInterface; + + class ArticleWrapper { + + private $article; + +- public function __construct(NodeInterface $node) { ++ public function __construct(TimeInterface $time, NodeInterface $node) { + $this->verifyNodeType($node); + ++ $this->time = $time; + $this->article = $node; + } + ++ public function isPublishable(): bool { ++ $created = $this->article->getCreatedTime(); ++ ++ $difference = $this->time->getRequestTime() - $created; ++ ++ return $difference >= 60 * 60 * 24 * 3; ++ } + + } +``` + +In the test, this argument also needs to be mocked. As this will need to be +added to each test, this can be done within the `setUp()` method again. + +```php +protected function setUp() { + $this->time = $this->createMock(TimeInterface::class); +} +``` + +We want to compare against a number of dates to ensure that this is working as +expected. Rather than writing separate tests, we can use a data provider. This +is a method that returns data to be passed to the tests as parameters. + +```php +public function articleCreatedDateProvider() { + return [ + ['-1 day', FALSE], + ['-2 days 59 minutes', FALSE], + ['-3 days', TRUE], + ['-1 week', TRUE], + ]; +} +``` + +Use the `@dataProvider` annotation for the test to specify the method to use, +and add the parameters to the test. + +```php +/** + * @test + * @dataProvider articleCreatedDateProvider + */ +public function articles_created_less_than_3_days_ago_are_not_publishable( + string $offset, + bool $expected +) { + $this->time->method('getRequestTime')->willReturn( + (new \DateTime())->getTimestamp() + ); + + $article = $this->createMock(NodeInterface::class); + $article->method('bundle')->willReturn('article'); + + $article->method('getCreatedTime')->willReturn( + (new \DateTime())->modify($offset)->getTimestamp() + ); + + $articleWrapper = new ArticleWrapper($this->time, $article); + + $this->assertSame($expected, $articleWrapper->isPublishable()); +} +``` + +We can use `$offset` value to modify the returned date from `getCreatedTime()`, +and use `$expected` to make the assertion against `isPublishable()`. + +The test is run, is then run against each set of data and passes or fails +accordingly. + +> - Articles created less than 3 days ago are not publishable with data set #0 +> [23.76 ms] +> - Articles created less than 3 days ago are not publishable with data set #1 +> [0.32 ms] +> - Articles created less than 3 days ago are not publishable with data set #2 +> [0.25 ms] +> - Articles created less than 3 days ago are not publishable with data set #3 +> [0.37 ms] diff --git a/docs/images/1.png b/docs/images/1.png new file mode 100644 index 0000000000000000000000000000000000000000..be24c98593269951d59848381d0ade86d66a2a36 GIT binary patch literal 182978 zcmeAS@N?(olHy`uVBq!ia0y~y05RDdIM^5%7`CpFKES}h*(pLe_;SP&cLv6i8#N8)@e3vtK6amvBp_n)3M&ER~xY4)k> z_P_tHmf&#ZVr1};dE&FsX##(xJVQmNgPJ}|!-=-4+b>&xDVPI$=WnC`(<*?DUtw`-hcn z;s+_7+3e?z)v_=CdwSl785bNY9CmoUP`NWlOLJnq=;?|JoPXQ1jnDltO1{JR>&qeM z4-7A4tB%dwAz5(v_<>4`3V}H{xwCfO+7Y^Q^FQBt&XP5O#cO4c&TR^63vAN#i|@Zu zdhx5&r$wt?O#gcE$Sli{(02jnuYWGyzhbk%y~X>s9T7{a-gxXwbvB_xIlZ3%t$Fs0SL&$x>v)Qjiga6h#%y|CqlBf*pf$cI{oBv<>n9FGK zL4x7f?ENL%^dCOn$kX5~&gxY;(XD;89?K823(fvhG&itpJHVOtgmF)!JqKH2f=mZ% zr-GjQ2ZBy-s98*LYG%CH z1I8D)?={r1IC^l%CMqoJ5KZdep(Mv4&FOMzLWYW*r>oI~9G5PQi8oJ}d$4X|ifqqu zdNpDGMCKEQPjoId-f?-SeD{R+6XvdkCRaGNI>=rK)R2CzMZU+&^CZ@jQ#w!8s4SJ}7_S z5aztu^0LLqNi|VB(f*-I&8%G<`5i7wlV5mzY4lIlGHkc#-Z5jxydB*YQ*Jocc)U@b z=&?*CJcvPa+7WfpNvAxrJ*_?6J*IoaE-6ou-6VRmS;o&#+54pG6R%HvpAtW*eiAOS zcb%W)|8en=pq42!r!1YKJ4NgitC#rF`B@I7OV|R0S6W_Sy`q)H{8i;E-`A;qeSN)s z>(8;scAl%5t2OtoReH(0*L#*rUW&psO&&TyIHg{bgu|6n&{XN#bal_#t%Z{=rn;CEnLLtwDiJF2H|0v+mF%1hn`0I?E7}UTepGzyr*^C);nR%DGfU6d zp2}%Qg78mC>&EcApHFuqb@Z6i{cAk4ZSAW+6y*Rz3=~>gc*R5E+ zef5#jz1hb(4sqNUyd=0)dEM@dcP#Q;^S(`OIY4Yi(#_qt(#nbw&Y+r5O zJ-vF~Z?W&U7xTLJOUD}RO8w%^FV5fSzV*1M|E}~M&uz}9ofl7zIo@$BN22&}_e0Zr zudUaIt@poYcdzI@+xt9u>-jwMrRKlRQ7)6IHvHYAf6)9$`Mmdz_rKTOt81;R{`2ok z`RDUr??3!svgUEb#T&ZG@@zL)J}{fHmauJNGG?mhc*C=a?-Bb|Hd~Huykczmymf~P zpFJrkE1K87qy2>QxAr|xe-%D2=x<9}D7f(H!ncWSiJpnC54~%>-ICsZz5Tmeh3lCv z3n|Zzo~{_V%DL$Wg+IKi*!#HV*jdSPr7p3l0$cT7Id1XZVzVpN#;WelkExH}AGvYd zBY9SmqmF)A>YKY3$9FXCh*uL(KjOP$-Uo}il0R>LT;}X)S;=WFbWf#CMbCH7+$U3( z_+2p zww~;pobF?1eKg1G-W2EHugg9ye|J_PWl74L6F*M$KfV6xw^8Lx)0umj)+O{lm}wBP z!|R4Fm%v&9+ml=;q9%Sdu~w)~E!%G45u^ETVu9*w75yTmVzXy^&i0;?WA^CwFQdCgl{de> z|Fi%04uN=$$Q%1k6kojMI{$R*)8|@uw6(PD^u%=RzW;ske)T^2h)G+Q)UNz~iT8BJ z=_RMv>GDVIt8G2l^+=RIyf6Odj;^h%YOcP%8XP`Tapsy|&Y~?suov{9U_bpIJ}4w)pF*U+?C=wATM8@+-Kw zIr{Lj*fX)ByAS3)eRse9+>f8P=B=<@TYa-y`rFO-t8bpa5r414+65t-g{eG z|3^&5z8BRSmnP>Nf9UNvy)Tw;Z_O*N_osfYHVn63ry9Gv(DrZDbKZx&%gsOM?b{Jr zvikqGKh`bQPs_i)54&f)Km7OX&-uHp_FD7b<==b%o5I6`Z`+&N&&z4b)xOcH^{J2f zdE}Mn-QfP^?7I)|*8gYs^832a_EBa1W?@;m~m9v)qx*gAQR;hiMA5kn8(rwOgyNS_b z7QchZoy9o~XXT7|?}bKxJ(AE+RmEqzR%4Tmt;xQO4@aCU%nd%AVqys5W|;qknfdQ) zb~d}*#)J1*9%M8=t63?eWF!6O!J0+i%(Q+){bT(!xz6}S^l~o-28OQG2+uTMUj{7( z1_llW7Dg!sRt5$JMg|53J4R_Z+l^6!ff+2$#K6#=$-n|;GcfouK)?hjA3`%vYGYt$ zU|X><&B_Vi?6UXQ2>tmIipR1RclAn~SSCLx)GKayY!m1*-AUCxnQK2F? zC$HG5!d3~a!YZ%W3M8zrqySb@l5MLL;TxdfoL`ixV5(=LXP{)qrJ$f-Qp=!2sK6g_raIxAfdGB7a6 zWV-l=FfcGMfuogyS%HCpL4yHIGb=DK{tobovNvL2aA5FsaSW+od~=t*MkMt5@sE@5 zaW4G6h~tLC!M28`6*eZ;N@5`*EZSNMW&tj&N4mI@++9Ti1qC+l0jb&8+}r2m=Oj%(gsK)5nnT|DUsTOH0b#X_IGL8|v!%1_cGFs;eKr{&)pd&b1facOBkucOg1Yh%&VMYUDCWEps*3<^G!2>+SAqdZ^fpgn)0 zB@YQ^J1{WTb7Tl?D17WD#WH8-qra(>&zN?vVR+EM*zEq+-*e{n>hF2=JGu?@l;B;VM%x5XFdJv`?9Vc6I$kR6N*5~*4PVar$QcS9w z{xkW`GOM#(5&T@)eAcV_*gy4^>pH;xC!V;+F+;1to@Hz9eMMalm20#4EZ9klKbAlG z0Vy&H67n?z z6Ndo96I;@9sDrME0z(A1yp*#WN#1H;Pa5au-xpC5QCNU$iY=MrG}vfS*tma2e|P|~6LuddTgAYm!6VwQuW zW8;z~Z^UCS5s{W&?PFj(uaIm=D!6{%(!!xN8Rk;{mIG z4a{G^En1wcqNb)6(0+UeMB|FDOp=l>C(WE0`TBjcG{L}P5h&1iV7RcCw|bSQf`vtd zlu3q$6{`U+v`ARx4oZEKCQUjMa-j8UF=G`G*>*)CBU6LvKMuZqj7N?h^-M{*aC+({XIibOb&%gED0t{ca|8T6^+tI&dfcKi)UR za6`~6VfgEIwlzdSZ{56^|ICGWpbq#j*`cg#+LEP)yc_24*vSKREbhwe zK{z8*L*3J7Nt~R#Dkdf(90+sb;^w`%KmX10)rFE!L9A|p7C5j}KdFsZ+Owd*KnR-k z9;i1qH8I`Xu7A=${IL;K5MSx`PlTg`A>sK9jhC|p^zXhp>NUHABU2zOMlmlwZePyn zlM{JYzWkI~)b(fD#Haq!$G2K-;hQ>nx66r(vWJ(ZE)G~JFP`%D_WUpvYvIpNkDuMS z>07(Z&*bWTk7erDxoqd0_{+WBdyZs$%H#yjUR}N$PnU~(eVgaxY5e&1|KxQkdDY@aRJOa(`{@=TVzC3Iqxc|>}dKZI_slq{)vfmPj6PqPCv`a$jPv)nth`zIK?!+ z627s!-2ZE--+3Z}*;FkcnehPkY?DdRx3*1iOH7=)>*tX@HkB!_^(u?~la`)a{pO&v zU+1KY&yRXGS52M0t}H%l;hAb{-)VJmdliqW?Nwg-^+E<`@9H~0K3(QY{k_QN=4Pwi zn^f#9=P@ksmw3qnag!IP0K*y)adu^VQ4V(QR<{LiOby9VCX+wDjSAz;yf$sFQTcWI z&{v1=o}A9xG11WZ@twEdGJfB2&HQw#i>JSD?Hfm3Hn*7{;(b#6wG01zbCulm`tK`V z&1pLx)ax^uF-XWHxkacXY578n+7;PMEDW!22|umFld~YHxiN`xKRbhd#+`s=^4HF( z|C?NQUn&2s?f& zPI)hG`OSO34znr4jA`;J5AU*hpJ*#rF)_KKFBSs{8OC}}0fsNrO|CmatON%acH)or zgX;_r5-$dBda$Bz(u2hfp+$B3V*XrC`)PaGTygg|UFWAOZ%cX9i+Y@^SW)+26$=C2->|B?pEL>ufyVF=KZdQc!AWf}D9+_V&q}y;9R; z97W@GJ$)uco9C}g(m%S~Urtp2Z?((MCHlK3Pkp^9<<(}*Z>P0%t$X^Ww%IDJzS92s zr045RPx~uhuA9C3ZK(nqgK-h}leJ4vryOFBPC2{GC3DATZqFZ|gFpJ7*>p?er3A!1 z{j3}eRX#@>!AS@o;jmWdLo~yN#Vh}9|MB9Skm#e?ud22cg*h&q^Z#-Frk!1(4E(vG zTA$x#X-s^$ueUb!x!B1UnVz4X_pJ(@(rxzG`qR1!&b|+Ce{dCdJ$as~IVtk!$D8LD zFG^KlW#H!KRyEnzX=7NvZq0A?@MXI9RerL%UegtMdsFA@{(5JrwrAcR9v-gSkJdp7 z6sD*J+gKQ?zrE9S*57ktQ_PoVPLZ3dN*#6^SwIvZg(`ZPyI>jXA29}*+pA{YxwR~H z>z((9Zr%65SS|`iFcwo^YrIR{5lO|s8om@D5zW(h=#ZOjlz5V3p)o3ri`!eBM z@^`!Z{nBT0+Iz}|4I3u?u55MC70XCjwei{0r`}#&`C3!1C2_U&9dJ|(h-PZ&KU?SZ z=uua_oVU04dPnwC(%NPeOLSx_*{eKQAy2iG2LmA{PwTD?U;4z zFZvI^S@73!3th2_Y&qJ<#e>fxC?c~((xI9+<>aXt} zzYE!>9H7gzRh8k#AMelJcm9Wl|M>R)l+fJIOa#Mz1v66}H^VxcZyuH=TAQLy{5x}M z+Q0jMW0vj{zjHt0mYKfnj#WX+|Igi1THY8_^ZcGx>D8|XSvqsVY#*Qgx7@+(UfkA( zMa#{@gBcGjSfFr{zkgzQe5EH}{_Q(bdFwbY*KW}Cl>7Td|7YFm-wtyh-{bnE`seiX zC9wzNv@M?Ah~w3cuiv`tPTc2DpPp>LZ+7xVcD{z_l&Ia$jD_WRrY=1_?R4#T+kiZK z(~X}O^WUHT<448Js{4O8<=p%&%9r?{;r~h7?{{L~6-GXL-{2plyb-m~BZ*Nnsue)1xZm0NEc5%h zjcxR<^7mzi6{Q5Y#>Wf}sZQK>!#x`DQkDyEY zyzcgxKM#4u^k3G8;exd3Il{$0Q#>eJzYd| zKV4~_tZKGu$EoC^w0Ua`9_~-SmNQj;TcyCi&F`;=_+)SY{a@wNdi|vf796hscK zhJe*uZu-7Iy7T3iwc>occeuP*yXL{f&z7cp<762fe$O-6U{-f1_tVqq@i%8PWxagO z@Zh4mylU}to0l`@MK!0MJb5(nUP}uLC!gLwYu{M6I8!gPe7$v3Zmqq&@zaGfFV#B2 z6c(@Fd2Q9A6#>Uf-YR{5c6Q?#w|+V8`}uzk=GU3ZGR!Ht&0_g}Pw|@fujSO|2R;3* z_xkq)hJ>k+%)6RztMyI)eBM4>Oux=O?aZ8~7bEss9$(yd+MWuun zWsAm&n5pX9|4!X_n2%xK=XXMt9}dp!Q@*t&Q&*gCuLB#;3;n{v!fW5c<6;#yr`tcZ zShnWD#N>2_H6f}DFJdJ9miN59zJC1|%daBYx1wv;`Z7-zk2iAq_viC^h8?#jIe#c+ zDCpz-UuvFcmplK@{pCf^=T2Vxs_0kLYKL=kJ~n)Lbu~Etl==M{?d!4ilefNm$Ia-# z)bQ?}bdG+!!|ESvE9zH1R`7RfDEo2VF7vdh|EqKwNGKdm*R_uZPOq+NGcS^n>z^-rFNR{fQYo-j|t zcYlSC(4s?o-!0xFe3zBsZE*?L-Kp|Ao3-}j-rRIFgmKT2d#dx;7;bORSC8JFSIlxu zMs~{POM5DdPo6q8CXJNF5B|&E53aBa_P6~%?nFchfSJ0S=s7sUgX(Wh7Gm9%QjVix1W@|Z2nrG-$`GW zFZ%xR{r>8d6OqrSRld6P{ocf7zOy~{t(V#-y)WneGF6;u&6$n+f)p8EXnX!5B3pZdvNg1}3)e0GA6c|2=4vF1ewk}fqk+R>O zxq+4S=cONOq@Q+e{_VMplc{dAZlvA6()B9Ko`w93E1e3x^w^oPGDJ>EiX%F8jYvXWj1Pl#jWztY~WPxznd7Z@*s`F1F`i+n&$gW?$RZ-4?GE zy)9>}fAQ`$eGCiYe6$(#D!=Ql3}64_z2w|m-+sUEUd}eZ>b;2N=QEerZn!VJdH$5! z>UY(mHhM1)iQAO2^344It8}8i>@t1!I$t8aa>u;`zfa#czQ_6Lr24W;_hKi@?zS#} zr(*20bni0XSr+%Wqgp>apI<*wGkDplZ?e`h$F0~I)bEw;Uir?#H)>nPLkoRnW#?sg z?eE4s{x9=$cTj3%}gm_&Cw%?Y`h{bGLoztWubXS#MXJlOqyPb#bRbiG);{eM2KjwwESbhH-?giMUx}Fiy<7k6cD}h555uxw#aHi2xtr0>Wh!I!<vt7#uNE_Uy!F>EwA#LDA3rC975CM%rT$H|^JIc$tymaVJ5RNP3@o6x z9+CPQjkCl#vaauQo@n1@xGmIp=T_g-Sv#*BMr%!WFArH8qqVo^Rcwz<)dp@6L5k*iig#+BM$APv7sAoHT7_ z_|c2<7O~n4VsGy2_SRQL&vIdvz437I)-I-ojT<*EavNgq>oo_zB`%$o+IqqyWP8oc-9oamv9BubZm9hHeo>=A?)11a*O`hs*~>3af5pY{ zO7++L%CK%6)(Tzt7C7_bKiYzRZbb2EP0!&Yqq6`JB93^|v=0 z`?fPToIH6lEFp09_o-J+E-ZVze#P48-#bh7t73T*{{8(vt;=uYxA|3G`IRpgzP$Ep zL$}^UF*SxCFBWgUGq3tkr|sHWU!N0!+PbR}BYh7SG`G)*e(BYAYx-`62kqMTr~mr; z*!Szcx659|uNK<(O~Pb@dBKI7oAU45RZrHb%U&3&dg0!KUpa4HZhgP=dEV<=-wMy2 z-rLz}bmGhE?|WaIy{@XIb*Zwv^Xv9|Rncj7Up6F1N8WE|VUV>cty;RLA-?kWD(O~+ zgi`Ly_5?>S0*pZ|!m^&eNk`qwr>&TfF#ldAtea%HIg4?db9C#eJ-em6Qg-AYj=8zh z)u<|J(x08m`@O!)<{m4568lj|=Hcy+qR(b{rCttF+1&N`^Ot9TBpLqvouH_+w*PBM z##Adk`;$I%XV2AI*jexKe2V;9ugs~h7Bn^AWo2-7c7A##*ncADSGluC*7%l{nyTv2RT1AV9-rS4)+AkcbLpjJzS-ILpRe9O;p5}{ z;xAvXEo$wnjjDaSm395;{QY^GnpzIG$A>6!h;cAF@VfoGudcoJWA@X%pM8J$&6Z`@ z5;sHtwRw%Yc36$V?K2`LcAvSjyRdL$94o`ym!-wUpVzEvm|y#Cr>I!)YsY4`i0PNJ z>bBo6+`cuBo#AUM+a)pGC>`(Vy5!sheKivJ^H}zQg8m-ncQS09k&zEL11T1e_7r%dB$=j+eXJ-6sD1DJT`Q3zG>G~~N z46mx)wE6UE-{)R@nZI@Kw_C3_y;yrxO+->z`Rwo4UoQJ^-nQG%GdK6k18-MGhqq3v z1<%d2K5w&os*tp_a`|kodUx5%maD&amByd)eVn)TTJ`sLn*8TyWv;FN`qkVh^U~b3 zSFdzl7GCNs`p^75Qk3!P>nnE4XJ^&3E?aN0^X0MEsRtVVg?+W>70xUWk!Ho4u+H>c3ajarM+MI~9hE*H`|gMmpN>ef{~o zy+LSsWiU&4y8z>XR{=}?@pJ+qCDnpwpx*73=-M60)|R^io#)^CDrEfk<=WZXe=IqF za`B_3_5F`D{c0~Qe3|lem(I*zIbHs{UK?12NqsAbZ#*@-TV?I(Y4*>SRu``dfBr+8 zK|)Sc*S=g{T}bHFRg2TMCw+A1{64Q%+@U!y^N{oLcfSIPHm??QDBU|xmf^~TN&hy^ z{%o>zciG!%n%{j)71zqYxqEHXngwevwRTXY- z#m9Ls8y&`|mw6xyz!irPn?3+&iay>dtu+0`9N!N%ybLkzexs_3z}XtIj|9 zDIPcJ%a=*_AFpF{*j@C%@R!f?vm19w+E%TpdH>~}RNX~`oj;#RudRKxyzgA@uP?u! zniyZ*U^aJB)beHPd_Jo%SfsuAy6Iqx`P|um@0HEtie4V}t~@IK^v2^Sms>3Ra`m%` zLB-wDl7WHTYoG6;lDoiGUI`Hd#h*v?~6%cx?Xrr zBsA{2<_Yn=I|Ht*(fjv%$0^xMjD*Xr(=30a7;MgjFvb*wxO*BjD#ve03I6-$(R{Ph z??c!8OYdJ=dpe-<)iyRE`PZ|xS~Xv`7TxWs{q+6Zs?h(NkBi?ma^agF67Q5;8_a58 zzt^K~?!I`Va`%IR6|9pObMCkcB%yH`uD$h;()_rw;RIF~yk7YKWUOZm9tCX)Lw*Iii&s!nB zyDNSeNSd#+_^|Zykz0y}&nKtbe_S!A;t}VyWe%JSw?coG?7AQP`^)BI&tw>Eo?fY2 zx@^T)HHH%rO`d75tL```M zvNq%_SZN_48)|i6P2z#4r^8QN`TefE6x`vxep5e^@X7@CsSWYW4O-QXkK2s? zZYZ;JocHCoSY>wp(^Wp9B@Z3i*?(#?NYq~v_-XbiBA)m5MgPRGRZrgEepazodvEgO)cfC$GVT_# zUiIM+AH%x%{f;JE(ziz#hvweimb)~5|GrDRLbbC$-#g-B`TY*JjHA}|2NOS+tPoc7 znRMPxKUUSVIeB$hZO+&255Af|*?4^3gviZlCp7m~M_#==XSvzdkUycZ? z-ODR|TqEnx+)%b5=y11n*&Cf=i`?7WHg3BuDmeGPeCpf>F_D`VF+9lMpF2r#dcV%q zvsbE@pZNc;d|5{6>3Ms9Mf?W!+_>ZGuLjNya-MK|Tdw%ux~j)#T~pg4Z8;gTS`W+F z`U$<=AGg;cIMc{$(IO?;%SyrwBD1;~7!NQjurTmPY-nR3l!1Q)9eB^^Ap2*A*x8ht z-P1yM^+!gRow^hIKV&6;xq7^rg4;2kwNWSX-YqhzOm%JB?H!U?-Q5^?sVc)~>aQF7 zG@Q%!zQ0|tNS*mpID^5nE8b75EssoAtgP_~%v<(E{aTx08^qY(a&aBaSdHH!s_WsY} z`OFPbf8V#gUO$yve~-hVLx<+omH}%(7 zZ}wfKyB=@~t4AjK?%w~2so~eZ8P?A|-7lQCJ6`I^a3S=`gSyzTALqqZc4{@4#xhRO zYLY}C@fh^eK6 zQ(vVcO)Wj#rM6eum%|{+>9LmizCT->Ztl|v{3tcUzgO2-zA9pw&%V=wa+kRp)?Iz`rKZ{|IF`SK;la=6 z^Rrv;mDrq~w)g#vZ`+I*4@4jLpK^8e^$c;5 zztSu^BIrINQ!iQexBZU?&NFSE#=YKZ&)o2hVb1)=TQbwK?kzpNhl^p~{y(;vS5_=s zvSi7L&FAg%%j2IFeSUWTX|?c;?(S}3-t#-NJ=HqW{fpncW>`?`ySA(1-p=&Xg~v-b zuS&laD){-V$S0|eJKOW;mu6Hl9`Lt|ds(rp>OZK_JKM+gkV^5odxsbIpWF0Hfgxk{ z<`UljnGgJD|C3EMuWx6_wqnS*U+#MPdHk&SM-x`BlL&lds*h)i0@lg&;<^&S5YS#2 zQ8J|`^J>Vsj0p-C)y{;(oz~Hr(*I5M^c~s%r{2%JD!p#=@j{Q&0Xs_)dgffx4O*nc z=d(2PeR*8kQ<0O;r8hmj`rY`+`nf;P?Ov5@i)T92acl3&MSXw87~T}ltC6n@nR$4n zys+A5y;n-6$LN4^XuLEP1*MwzegmdZF-{q-srfP=j>%4KRr2N{B(boj7~_Jd4qZHA1u1-}-Fep}|h zKi-ns@`UFYBpao88E$RAW2xr#OYMmF_NtAS)Rdg0T3Vxae|!4$^tL%N zHz&-}o3FO~M7|`uQ{=au|02pVWVO`GJ0~o*Zu36vwlK(kodwSh`?VfrYR^vh&n`}V z%WwJVc-eoJ|1s|^clmZ)vA2qObmoWBY!>f~oWdDK_Im?1eHZbXC3*j!e6ebA^jX&b zZw!BHGe}h4`1mQgn>l#?t?T@pe3PbLpQ~{$Dji%)xu@K7aiF=@s{R&vWySCaUi4U!`Zu$zbLG_VZR=ciMrQ{T+E`0cdRT80@D0^;vgKG%IMSLzVe=*QeywpxQ>#qrv&PsPJb zUDy6w9?CHHc8B2fQ(v!(`rBu-Gwd#ZucoZG`-s(>f9z=y!LP068~=YQzNGlM-=e9{ z{N7cr+Io6Ahf*Za(LFE_Wg+guG* zbL7^)UAg@Esnh!6?DxNH{rq`bbIY!~c~S@V{9b3Ra-&5qzVhi+qtzO>j!)bAC6(dB zIcqh~$!fi+kNNFq72NYy)w{l@vN-b7yXb4%%RuE{Q+wW^PQ z=7j~@#N%rspPiYTzV>!}+Syr(%fGx!-K)Zov07%2_w(-)wWfqVJwG{lmGcCKgwhq4 z)Cn~l6aqdoF$yxQsbq6|pwC#(%HaH1`sDgp-vsRyDNm1W-fcR4y3bd8|6Ag-%TKTQ zzHds$27#TW7d{p_wLe?x7yaw5*i5_3IZxi+kIsq@HM_xhU~BgNDdO=}H!p^!q%7Hz zf8FobcYEhPlc~qwlpUMNEckR$L?x~^UJ5n{(HZ_`pL%Q>8F>^UpFalnb0gY z&aGWDx4qwgUjsC?5p`XE`+d8>bGFZOUT-KH6yNdSzeoVf)zfEWQp4|~&Y*)AypWPghvaI{sch~ci zt4~~6`8^_7<+UAe_q&^$k6WF;tiO+kAm?y{fxkxBK2KyQul;85t|q{7jnq^^fu9O(~a_Sg-xw zz{Z)s^QoG)Pv(7PMu+G}4`Ra9ZiLTFu3hTMa3Ors7s7KJEYlbm4;-kHE3Gs6$Hl-l z^TGXP@2-0W_%sVG^XIpZYLmac=*YHDaep@3J0~d}R?#!sbLQ~8pZn#X9<^RK_0Xb2 zM&GMQ0_C>4}%{w$05I-wNlkFto=N?DLsX z&|T}*x%6IkSy`WG!Di-$s)phVKJm|=J&U^h@70z4x4!(0sXuHHxxcRY>#ggI2mYnc zOLVF$kG{S|FJa${h_C&!9ar8;UE2Nd*lgG37q5a!^WSzqE0!KPdi2$*t6SC!`)jQ$ zxW4gm;-^pE=cn(OS375KP4UH~&vDxG{BGTQcJk76#skSds)y6(Ro)W3b>;h(up}OS z`wz8mq{^;xwdL#AT`uhFi@fiiKDTz>8RJ^nVxREixhp#V$u9QIRrYxrRqM-e!Lj7R zT9cd`4qaXwC%;ftiItRle$L5!*bSJu_G zFKUnyY+iYp=^qz^)}v`F$|jW`>JXauS?{Hi^X_Tuo`gSA_?+~4U9Hi-t>>Rie*b^c zj1>iye@eWs4byfA2 zUp;l`(4i-LzfU{4<#+dTy{-H^Ua!0Ddv(v`rH;+a2TyF-Qu6cX^ZBWda?2wU)qY1* zuXNlL?Ef}*)p6b_>tg%1IptQJl{8NGJT0dC~ghF6kq?~Zi{=eLTZI{pWQEw;JqKpGSjtuZ@q01uD-Rp2-LpmHIGw&du!X) zRgZ64U%GT@&G*~O=hvm>uex&Sr)9sK?X^`ID`am>m5gPsE_*)t{k~u}emRZG%F0Wd z!{w_tZ^^%ZF2XKp=Z!?$yDJ-QYuDQtzqhQ7T*NDF7P8J*)Nt#mg=TA;EDA0}Ui0*x=9adSWMZ;Q_B4U*I6t6iU4 zx#sbdyC+{>TJImG`p$WqN$wOwk#a_|Cnt5BT^%Fi2PWxIgWq9EWeyfOFCuhD$;Lm$qZhZ)$~qp<@YN~PX~s5I6wKp zyxnzs?yd{I`fAF#XxU{g^SnC|-`@FdS!HDE zgZI5>Rh_1uJHDar1J{f1KB=pJR2KJ{A7WwH8~9j;g-|nJ;R7oN1KU62Rl&+%(is9C zaz)GQ?%!?^+oXJE%CfYsa~B>cR95{6T*j4fGP7ZG(dVa2&(}|4zaN**`tRMY4bypS z7cS0F2w-+ezw>?9lGJCXl$HIbXa6dl+H^>1XVs&E9>SFw=uqu7p_r?O{B(`|i5yZ43);AKVODueM?-Xr1`W z=HwgrR)&ESivueY3xhU8()N7TKe7y0R@&FEO<%S)w`K-QYfG1i=&b+ZCqBwXpZX{} z%QM2GBgfxss=wJkT}?^LYiI9SJgHdy>;B}^`vm98|6U_(9o4x1>HR->Z{JtHN!(Qa zJWMlc_l4~ij5luonI1pk++6EO<=gv`+iO05-M;CxPv-6A=T}}j84|jA`QF%#NlSfp zrmu1@cVM`nti}gg!%(9Y0AE@4XifF?SBoF#?KrobuY~Z3$`w;ariRkDooqk;{;+0P zA!BK|^HccgxS)vrp;Jqnnw(X)tZ>-%_xHvn%foE$=1$d*I4rv*@2c0cv(>j|*_pDjo3>(tl-!uAh zs9UGOHD7Ov>FV&`a?NsrkRg3oZxAyjHCm}SFl^wnJ#(u-+fEbM|8&_W)Ik)!7nRRcU6b66Q|GM9+;hSOm_FNtFf9rSO`E^U`r1ve|wf`g30tFv_ zd)J&~`D|8T(W6dvk8ZKEs!B#dlO|1ia^C*m6n?uO0sr1#4rOm;H1A|!;<%F5cuR<3 z&Dmo;kY%&@x-Tm@K}*RO)(OOKUdGhmC71Fq{Kg-HpQ?`xCSK?e@?RMESE4e-C0?@P z&B9H#hN0hP3M9BhbeQz?PARSbqik&dBeJaSOV^eY_cRwSOw&q~0)-d@(^iiLh6LTJ z2p&;STFOmWfF(b?pm2nt<= z28XpG3Jek2^3u(2xT7BGaV?NiMM3r-K?)O?8usnc{{>3&0uBljK&8s3%ZWJzGj79o zCKiUh+aLSrvv4p}H6GK1=m-gHU`P;Uv?LtI9080>4UE4MUOn2-)YP;jaPhIykJolU z_eC&8DHs;67ZEjFTI*o1!qyHhEASB&iVh4HxJ~>%`YEWWxJa2~ytsREPAgPL9QT{s z(^XhmS>xuP?}WG$_saYR2Bt<$2L=O!`QCG7LL(w(TvdC1Y;0`ZJFkLEgrgiJYd>{w;FQ9860)^MHa<;%=TQ>Q-t`g0Bu8@dE$ zfKt=vomWl<9zA}2`iBo6tSa;Gh(MBeqt1lMla*Jl)NHhIIYzjYQh3nH!04cV!Q!ZN zqeAAL9TP1LPt2Zd3ELF5N+BR5M5VK{di4e7<&d-kAr9FlUOs1H*t#Zdx@V*P_ag@&iUsEKML0K9R#s-<%|Z~XuLOabdtVN+KH5;a>i&!w5}iFgTt^-nszD1w z4QB;yZEqtZBOiqcnvJI)BnmS@G~zZ}-~uQM{Q7vM?_lOqd)~j9Kl)eIZ+$$|&p-!xnfPF^o(NjlXl4ic+LLT=uHp#ly*IdT>7nCx1W3 ziH$}Y5Q7C)>~YA;>*Hj4=HckLPee>?rakM__btYdV8LcCT~Cr_Vx?)y18e1d)}D{D|dfQGBY5gxF#)F zkif~wIqks&0ZwktsTVdFa2nV1wTa2(yu177VroFa##Tka&1D96?7qKHZd5Y-Zyd;@ zJvlH!rM0y+DB<6WNn#P8CRKg&=?mf|?TA=>E3hKMp}8^f z;X@%wK}|tHLDBgE-F+N}j>iK&tE-r_EQr^w%G+AFLW)P{g#Lt@)fvH#xqDiz%+r_} zO5aT^a^|?g+vpU0Q(xQKd(-AkOD=@`SWHX`d!XHz5Uglmq~*0pX|d1L0}1h^udmmc zT#%5G(n@^RzwWkgI?vgOp0Kk3uAMezEn6e`?bBJEYPB^>LvPQBJTI2?va?~|@-1B{ zD>$dNwTXpa;4x>6dhRvr*Su4w&zryBSaUCa-h!~phAa%LIj7|bIvlWO{M+xGmbUEY ztJBYV<}m6|I3$>&$HS87(8n0IE&9p zXvVy%ARr^7v~lA`Mtjo@ZR<@+ME}GewdehlnzF>(&o9q(#RXNSr`#?sE#5vpYedROekRr8ifUynT{Vl_H%*y z{qjWL{aMR?UtPvpcIi?O=f9uxX3FgqxS)^_6JzV%5VoB4nu5Yvd(i&J$7ezX91iq0 zEZg_BUFg(-U5rV_gwuaRJZni+EU$6q*1ZlHj>~S%XItasGu0_qQ&aQWo2sY1Ym=Av zU0Uuh|MJF51MLeE;^OJotfQ9a+}m=q#&5n_)Qa@a%kHOMT@{+PbLXCSH`*KAnW9{c z?dk!Qg-VotIr!SMyy`mY6xVfpXEyQv>0II8`)ew{@kd2ZFp ziqh}zVn4mz{yO#MrKg+j>11+LXfI&A)zZRpaj75YoXK-@b@#sQ|EwjZz!0%f&|RUy z!IUH7;r_px&-8yD%6c(ZkBBw`X!mkKz=k8&``2$2SkU%g$@ho9HbdHMfvfv!f1g^j zY}vv67ZeXH}VX(-*x0!{pwy|=;w}tO-vhhkqypLbYu;P6@FY~2U?hOnHUw2&6 zX5yHlyx{V`clYNX`z9>sL`7khr3SC&~^ZL5~iXi!^ww6XlPEI~Q0-S?AJw2ED zUC*lDEH^Lo<;ptm(vX8~Teg%)*1xV;#TfSBNZxlQUTL!}ht{yRvOfDe=kY&>Zxy-@ z3>UJk{9G6q^I0xkx~y{hPZ<+r-yQytXuPE)khyBc(WA$HrtWz7@S%{HlvZVB<)-rY z_kuz%xA90S1;3m7X8Oh(;ycSvg+%TuS^0O8Dw7;{hUw{Jz0%!mnV&y__VHhTTx@v( zRMXD0EEHkl_~8I5#)E=`Yc2@KB3I(jvH_#`co5%M_4SdelG36meJLR!rHTJzlh4ny z4db}*vq|dDWrhS_6JCZafeCF6sjMb{t}pQve!V4UvaF_t#)=$qnfN{i#sftKH(D8( z_6c98yz~9-ZS~e=OSFj!fKyysGB4kc`nin_F8-T3X0f>2rizYE0Y~=LMUXdZkP^t;%>d>*d@geB5vU^tgQ8n$*SX{}jwN z%T=?j{x)IW-YTy(Kl`6Al;zuM_4D$b`dyrp*ZxfET@$(4@893=^NXzKTNE~(ne#JX z=kY6TbF1WCpVjl9of9hE7M;}7%Gx?<%laq$>Z*JXh-hv!s9snR=xlk~=i{xF!Ri-F zuP?j${@R*Y?dL_&)<7~Eb>nI{w}sJca6e>P6rp49Y3qrZY<4M zwvuVZW=}S+?%v*sr`=-I_Eyc!;mv%?E+1*R)j=}8^6?5$Mh9NIxi|mw9Iu^o@4e6Q zUkA4oy{mj~kyn0u+S*NZhs*n}mu4=_zOHBV=#$_gZ~t4zdhJhK_CGJk%eKqx_uk;! z_l>{RzWBQ~=4awsZpNU$=fBQ9nN6@-T(IT9hwiqMFPDGU-n+O*SL$E&!=uxm?tcF& zt?a+NUclp{!RUP-^!ret3cK@31*SjnK{yw4ai>ChH!jzDD z>ovF7sl%J)zP*@I{cf&Ob34zs7ZJY|cm?|Qr#3-Kh8HHcqHda8SjBMb=*v0zPu?DV zA2Czqd2ZtlxetsE&mT-?x+ZqxRmF|iT{3T1G%f#o{ir}fkx{yv^Kt%GJN`}VYcKz;`+oQPwdY;8&ph|ejoQA+uK3lR zoxz=%jiwyS8+Yuwmv*iq;LB&dTr1vBxs&tOZ;a;S|rUYev8zTN+Dv+Uj7<&({FZ(H=O(N=WOU0nJ8 zO0{?B-^=Oy3Lm@uJlqoVhO6F6w4mLYf9ho4lV|6ti%-A11++6FIrRAMZ@02vyIl3S z{+{u-U1?;rQ-h_Y<)m4&9@&)aU-$a^nXBQwBC%P~`|Fx*zW?FAc4<9x;jSC!?f)uV zycl?`=9{dw?87a~zpXXPycDtTSJ7J255BX_PX1?;`LTAw(fqxdcXx@h%dqp>dDs1X zdi_>;bEr%qXshOh1&%^eQbB3{v(NC~(GIH#cxG3<_+N7Vg$0b4Hl=!3PflLRcqo5= zZ2r{p@*JJyqvEwJ?CjC|bIXnhwp*|Ja3#2S&G(JT&XU^C=hx5s*`A>-EOut1W%0a; zi~FojeF>J~_;bkT>AJ`3bEK`mNp*H~O!)Jsrt;It<=WL&$MK#|z^Gnue#*&f=~`9> zYZ<=(I%J-5cGjcw4`bL@&;L6oaTUwF(rW_8*Uehj@m#{gbgfMFn~g<(OOw67{9E#K z%__Ck^4C_2=hvo%CI!Upv%zrSn()e|v9hblZ&c8QPbp=~esB z+MW?NGdN}M&o%ze4O?c3UvSbhPP0*Xdu!|D%*%2sF8Z{nOZ7^di^&#m`zf-&0z2&2J&urh3oiATXrse&bA>@Aj7+1r(`^;9o>$c69!Tdc;+NnWP?a%b= ze}~p}mYqKP_{pMfJ)O^&&fERoWAppY=hSzr-}SOEtd8E1^*8(Kq382wrnF0XD|J&i|m`qhd5o?Vm9*V$Azqx|mr{XYwiicX*YgIDi*@|Umu_WxAo z*Lya&cMAS)?K?jSv^yr_V&ASC>-N8k zvix=<+3U`%F!!2ID`#no3Fa|Xe^g_6(JhwP6tHmN!ZfpuBA)*KoxNoqzt(E_{Oqiu@#?J`(q`;_*jA{z?kM+nre8bP{JXeJ z)X3j%XT>(V@99_G%)446ENB>~DKCq--0EM_H(mBZYKoy=3ZH`dd=63*W==q zSC%t1h}9pcleDRraHj5&VRlW_-1oO$=dJh>5xq4_RXnC(-s3&7&&+eK%}V(E?(YAH z;Ok{?DrS6nQFy67_+?kl%}t^AYRfwxS5&9o*s$=@p30B;H(%u2u8I5G`sdqiwa%WN zE$7}}S-H4&g--lFr@H@t%a3PQFI`oeA$t7Y-fGKZS>IQm?qX^6ov%Q|A9PfZX?3)3b*A9Vw6n83 zC;p62OMBqMyhd`_yfn9<+*!w0@;ezGzi$YNWU^nD)(!@Tl)mY0_Kek^(W z?ojQoexbFi(zhR%pC7BFv-+}je9gy#?CotC;8Iv=`<`Qbb-myB*Xs_=FD~6PYo6G4t9i?dTU|^q zrM1i1|N9}Fy(=XVT8E=a}<{iBdw&2hnU z%ks*!c^}6;e(-;=KuHDi0|IKf!Er%BdNjo(}KHKhp$(V17`nKcm z`=4HqU%OTB^7}9UCQX|b_GnVn)SQ#MkA|xGTWtK%{!)lN8=)RnU&q(x}y8x=a7h zOh2{%S^IU<>}y^{o6;2nd3ogPemqob5X;v(`8SuC+W>*MCk$vjr}-gffZe|Gy!nddJ3XsQf1KCG z?X9}@&b3?Y^trj#r)^5!+{iv7vRClhzUlGv@^!vh_g$_(B3tB9{d()I+8+gTtvG%F*cil z>)zmHr!Fn^)~=m5&miT5z|5ljkLgRNzI^cL;q(*Fd}nJHcim3rWZ1RzW0m^?HioS~ zdd@Y>%wEQD&UpUcOMApQW-u(s{?Peh{&W7V+u9gFUBLCaGv4pG=&dK0xGMVZU-LQ3nc>1$yF0D_-~3+9t9anbmXMPx7Z&u$GL(paSe>!|ZHz3a&`zIIxa*F6 z?kbbKm|Zbj+McS-{&e#6G~IIRE&J47nAQGbUi8rB`7*_Id#ir$w-aW|{XWF4Kl4G9vIR>7`9S7bWfvT^)9E{r-Px`9(T!e;0`} zT$%6^)O)+SylesE0e`!nF5B|%K6`P#)OGpP_jh&%ugvV%R?s=b2D9=c7%}jpT8Lj8obUhX&dOhDI~ha&5{UEEz~ zYo#3x{^J(;dhOc3*}j1bpPzl6c59Bddfx4Av70t^EqA-O?X1t_KlgXl@nxEquIv*_ zv=d$}9v&lczOca&Md6-1Dzk%U%A*D}FqjyY^+CdET82uKqvK z7d2Dg*}vQIE-XIkp`p6^@-xYIa@XWAYzSQ)c5KDs()#`XcAb2}b4NVCu-w;wTQ+EL z@7K=!K2AnZy6=Fb`}n8w8M!=+udYl__I;|Ad(W=;`u9HToeumAyY3y||No!%WcB;X z-?r?3_s-k7A=o!zb>`(|ea7pBg;Ys$Mm*78%<&o`UTd&^#0dwb)i7iU{V=hYvdTOJ*J>Xs~zaqwQd9}oU6 zW%B=4SN-$LoSmO8IP>4uUprx;x+uf_+VW0K%{TkrYz~unQ{_|s+Wt-7xwEHs%+8xK zJ8##)%HWlyyesD3dTtWDY)6Wz!(ZP8j?HY-tnO7dx4ruH_eK4QcG&mA`EcuMUsey<=DRk$3}uE_ zwf(Kvt}ngCt-t5RiapO|82wA;6em6Fya%W33Ic8+Uj@$Qtzt^ahFRb2EUURJQ z>eZ?Iy_xm@a>`b0G`ha0{8g=5#n!u4M=fn$X3D?XdgSDp%b!nK`=w94l-aQQl9IBr zii*XNntMC1YfVc0{`Jh}^Brl9SzLpMSPLN$>czbMHBu^0TJbr%5VZk-YHi?CfM#k>;kRH}B5e*mS0+zyIVk z-RQHmXSQyOFTI-ax;V1-euhzZoi-5WLZAzkdwE}{OD-wn0<39pE(%!>GrLCeEh!B^qET5uio4# z(b=4Culf1;{#Sc;o_Z}P_%O|F`>~*a2!)$Br*fNy{d`oqrdf&~)Zp2}+jMo~^G8?T zUfCwF;PaRLQW2LQM5WGpUA=ryF|#RygtW9WzrBsO$%*vs`_G81-+rfPwdWIgk8ihs zpNh(o@3;B1L8j=1V&7e9^M46mHvS)X@E`BAi@VsB*!oOAtKRgl+>Dy9zOYUD)^iy}#lAiSfCu$3aV7O?swI2>5e2 zc^~K8xwYSR_GOlSt@x|>{c(TTtd*XJzbyS4Eh{DT=g=SL1@k$RGUaD2*dE1bTao;()+_#XyQ=Lz*KV;*&$`dQ30})pwthxJOhm>E9yyx;y?qrs9@lN1 zwP+fv{jU{^*StSE+0VwYjd%A2tMKLbYQOD#zP6P2*(?6Zx3=t>Q@qt-E!Xnnw{-37 z?)^DXy7TX)U&n8l->-RHvG#w)?h7q?SL0^?Th@MW_T4YGIsK0H3^mK<+@E&w!=10! z;LIBGxyof8Af*@K$R@g8R}4&8{vEjiiMfW-dFrdX@Hm|5Sf}rtRj04?^kyeD!;t3u=ddQjOz?*8QOHi&gz@(Nmq2bd`fKhzp%YkrRDbb z=7Y9`#BT2X9^)vdz3kxLJ8|YSlW&I{J8Gg}R{yVNV|GN{%`k=!8{OrDW7B?}-Tr#5 z=!F;8_C_DNzF}2KtW~M!kD9o79wH2X9=2z``}OM0&CN^m?(TY6`t?R~^n$ZZxfhSF z+uSevd!zOxp<0`&`?qefipMN54o?exvAOK)N%h4=XDr0;o?rENZq28cma7=~q`pM0 zV?4Kh->+M-pSLB)mR>bAN;?x#eq*8Y{b_%{-#;Jwd)w=|rjO6aWJpInoV2*l>YQ(L z?&~nm{6|Oh->mav{5!AYeckG31^3FYTik6f{5PlA&v@>~cjDjA$d=!k_ExHV&e^B) zs^3jlbiUW|J!GHU<_S;M?S7{fZQ`A9{b>1@q@T0Ra&Kp3Y@TR6wcqYfgmeG;cP}n` zz4}_7!LT8Bw^`M~eZE2Jv+no4X_ollRaGYu_Gt6Mf4AqI=9z0{c<)Q+?a!u@ZOi`u zJKwf&t6uE7dudyDr}RgMZ0i>Px4GCp-Z}PU+y6h+Ta$TZzpaZe-5zGUq5Avm&oygu z*fk$?{dGF%6yLhF=VIe^FQMn@8wC7dfv>N$^F)L zJhyH(PkZsd=Fg6t+cK3`Ha>ja|37CA+q$yy*QclJPfza4owNAM`z4+6tA4J1xNYO9 zth>AJFIx7%L(-@s;aQ!wiO2OLt?Y-HU(a3mexGi;j8F^1`it>CJu*KVtF3M_EZEwd zy?(dio%8a)_f@|yy!`amE=gtk)Xl!aHh+)5KctnHY+_PzRCMm2ym!~`y}n_%*g4s} z>WliNmBj&}TaN$z-uAd#a>DKRJG5`_TRyL<%Vs&xrue9c&QxyaUrRGD7e8I8KEGhK ze9ec2C41GqYFgr70zud+P@mn6v{p)qo zt~(=sWBkM$TXt-lp|?JJ=DR!7Ua#MOEi*M(@cYZl*K=oeB_F9io5I|1J+{1eM&f3D z*=394lb9RQqH?<)XH0dxeLik^&CjAd^WU3{D+;Df^bujmx&5tZW!TzTw~w!~-uLHI zL(cK7>Pg!-Uf*`~*YuY!#D8z?`x~UW>&Eo$r?)(*{Bqrtg<&yQp*-F^$-o+*pwH#f zTzBzRiP_{StaJVp)jWP2sufE z37W7WE@#DsFBPlKU%t8J)B4F>(Yxv9>Sq%x_nogdJB8I>_Y|dPM|}8V zkpAH?zr9ztnE39$Yq;)7?3K$6Wy_suoW71n+AKzAM>=cro2qrK?{a2Z7EcpfbaIy9 z`*pkDO(>hyx#_6W+_1aFKR!IH;;jtNy!Iw$;~|xcs&Nb#?En9MU;pCkqei1h`|RD@ z?ytSwo49b!L}mLa()m11Ge0slgl#yw%xd4mw(Qu03f5`Y*Ihq3N!9!A!{xrSpRHSd zYv(P?+ez1Rb$c=ton|-PK6m}sRNXS)-NnyWKRy@s!tBIj`PcSgchXn?JKuHe&5Nbk z*HLXf6aWq{;R|3KkwS# z{QHQNVX>o?bU?1x?fw5|O@2IK+uat<$4gt-mgHm>eaeiw_Pt#E)#ifvx@Irt)g6oc z)EzdtCpM?+_Vsw_2R-N4?>{$r?gBU zYV+HBb+3Cb?1)f3^i6i%hW5?6Vqa$c{9GcwVpF_EM5$x6RauVy_dBvJ-*k8~=lhx{ zJmW9AHZwir=x&7%Y0ql^GdE3mwE5SKnZM@fhQ)qawYr(BvTpyKyvdvlxBiK3*u1Lu ze*OQw+=9ofmxXS!e!a$c6YH@>w<9gitzvhpKbd@9zTg03(XW@wclo{*7Y|!%u>GhO zL)3~3cGcWVZcc*aIi`lK+3%le$=v#v)|7t!pRP@a2}8#7Y{orPwKuQ&{gZcXSJLlq zxv|lAw`5Lclb-+0-*XQ`!ka0__4j<3wEB+tyD62&x4pjdl1togOZ&X~f3D&cz4JEv ze*fduB+n1pd1Zgu`0!yN2A-u4__!7@;6)B{q8nZ%*~-_Qc>DFJc>D?OnXTMO{EwHP zetY%z#TLhH;`83WFWdaue{Yq&P<6+axa~8~=^T*YWsFKV#nfLJx$Z)C&&8FK-~L*d z`EWV!xzigzZOT16YwM>?m3_IVvmacZW?8%`UVh%6vrA-dFZ;~wE>{=g<)=TB;lb?u zeM=j+KKQk@{-SjLp18xgjt3>QGm0Pg-n|=qclZ4jm%o&ieHYh{Q&OLEK_yyo-l?hD zFMY}$-{mPP`}^rea=-ZQxEp(a`|gSlSaQs%S$$rG*S73yW>4QepWn}Yd+pwN`b&(H zkMTb=eU!a^@4;B%Z_hKg@2&oRCCTXQp>`owhTK^XHlMRHzx_IDYUZ9OFH zXL0jxzc|Ae{e;V^^XuyZ9xMx7EPUwHtbdj9u@|r9@BLbKmWAiL|IXVh#KI0ND||e8 zlWqJ2(b*@@PP>|YP2`Dz=FRdOAIdkMU6sN9_xJmsMUk(!XzOf zi;t-vyB{gP)vMi1bfs>;&8Hb(u5PI;`G2FUEblPWpN(1R;xPsLY!;~$_Sf%TF#WdXv-98Y`|{QY2IjA?y}Nn+-d|onw3`-6DeQi^?7*C(Z(fC^ zpPePhrqpk_ZK6)ZhJfWq-fG?5eODwe@9Ld1cYbTu99DmH$J2~KBK`UYMefIu8JmKZ zdOb`oOaJ?eH;QpX%8%2+)n}S|#U^cz&-?Z$&sng%~s`+fiUN(m5FG4Obv+WVHt=abb;`OR$Gt=kRZFAhiu%K1?!xZloezku9xx!D$llV-2Gwf4xL&b1;Q3YR*_I8H}^~fpTeIG6H=~ni- z!l)m`a}6GHZ_H{qsk8Cne*6D_ynlUpJ6rk1lrtMY?c!xT;IQ!!7ekas{{Fvwr^*+!8mjhUDW4E-$`+ z+-?@Te!apB4Tc+AUvEviZk#+_fB&C5p=x(FBsR-bJXrYdG#l1h-PGNF zPv?H!?^uhit7^kmaxnZ#j*7n(R*+G>t^d$GrX3pL40}HJ-QJ>gbLzXt2Flfyv&%T` zXVsmzd&|?2YmjjvVdv*{)mJ?3=*?ZnqxB{?`@akOz4H6DPpsCel)qTmzAAFXyQZwP zNo(HZm7Mfv_^{`*-h}t2DWdrs&!6>a)wN^z@sRz!WpYaY-ST*T$q!kNCPb7(J)Ra7 zcFU)8?)NDtL9u>FxoP2!St2+7GFB|{- zdaeJeWQn`_+~Y%R>-vqY$WG5*q;g7KbJAZ*Dz*pqPJz*X@?sHviM!`kdX}H9MO$ay4qF%VbQyo%f?$sD6#07{&f1>t;Q)uReZJv!J{rVC{qX4hQ=L*4~@m#gI_fAGo1>VsZZLU8Sd| zDSVjn`Q{b-pef7^d#k@r>DJ47=(6#^mDuw8lLHo5=k52kD(5@YB%e`nD(L^kzqJ|$ z4;dfXeEe|u|3q(n&bo^N&tK;7KUHU_$h-XcNL{L6ey2Et%>SDfD}&WFzE+=Hx;Ev~ zl9M0HO8aXUJX@A{xb5A)((Csn{HABCPM`n!|C-fr(vB&XZH#Zbab=fzR;lCfsZH@* zQVe%er$=2{73y7X!To2Z;)jEF|E2zIbM59n;x+5G(A-z$*JI14PSe#d>_5(Zai_Y` z{~3*2yV|#{iQgZ$+~wW#cgr71ymK(Dw<>$HU@EWnF89Z*42y$5-V)z*dDv1Rv`?CWl;!q&c;r_L}VKy97_qX>TF;l#+jA+q7TfBo#+Ci_3~iLb4h ze%s{G$8WyJkNfn8Rn670nwp`-sZTs^{q3gs<<~Pm zKR;jIsJFj*|MOp+vDdxQHVWMT`~BO5!pFx_Z{K06y_^3|&v&-z*>5}IEAx+3e|n+Z zzw5w)`ZIa6O){0f+ZWt7JKS6+ukCkrX|VYIs0FukSs4~T+;>C#Q}E4Sxr;&>|0Zwz zeI&Y{?f15=_phv+d}qr>yM!C-?_VzZbkg@uV)T|B5$Vdm4exos5IGzfEPR}sAxcnE z{$022feQ=sPyhSu)YBoO@?sYj4g;T@8ud@p-Sm{k&27 zR=4Wyy=8Cw+QIGej~{#Qtc*Cgc9Fop&69n*85YdtP;>}ZtoIJ&`G3=T?}tNTMWxUF zyk5M;Dr|k+-p}d|XX3&l-}C(a-pb~Gug-eLcbl}yTcYnqGB=!_raKk1d}P)=S4)P9 z*A9ar@QmQ7pIG!$*KJN)v@Ti?RPEb{AsJ#bMah#a&q$1N8VAY zckI7$&R(?*)N$q4kKN^Sxa#uL>o+%lz3$kZ^6-%BC5QUROY35zxBDitFu3otcRK4M z@T&U3!T*z|$5pA??7v|>S-nZ~qo||6R0ns^8D7%a`OT9xz(^ygD&a{)FlE zIQe%$7Z?&sv~K?Y`@UYvNJdi5`kSAL&W@_DS(Wd0ir-ON>OH;e@|{~;r%J^@~aTk8|t`u-T){(N!j z=kxh`)$ew;S7*GqkeGB;I=54t!RF70!%vO~`xl%)KgZI$|99hV`S<;QC!Jdsx$P-v z-}V1Rp^V4-WS_6veC+mhxzE9Rw`-XimN9YTZD%uZEpTuYv3RrLaLKRRtM4kV$(kFw zXR{Oc?Wjc$?YYn2sk$xO8uT?U`uWtZ=f7>f-Zv1*bafC4{k-|WgJ6HVhjEv-ZOr8^ z){NY=BrJ}b%l*ms($iBkb&r~QWEj6$8$aLlci1LI2k!q{cYQJX{^@T1PS33OVbNM) zs}zc#pPBsc@BGU%FE2as*Y@3ML8dJq?*FxtzAYG)ayae4s=dGSHWeM!nrWTC&gRzd z!tyHqo9gcF%H8{Sif#N9=7zA^ zH}?PQE@T?k|GQrlvp7NPa>b(_Y3rzOH|J6x5kYoAi zL~_c>NviMa7TJr5RKKwQum1J*_43&fU-$3*o+*$QcY)zS<#W@knl;~xj{pAinN!MR zj*y)7x4uxdEibEcH+Hp%seSHdby_=Xp057BA4P|>nl5Tp1~2zJou&|6$Ww3kuPmC; z!T#?@tGB<;+ugqZUhJM5bA$JEz0zR$cK>5{c0TIji%PRe-+Hiu@j&gjo9^CO?5TUE z>qNfN(my7n7n6H;*U~GiL_>aW{`Ti_|K+V+Da@9y*BIY5Gfq2mVP&U#>uvYP{U zH(r)gXOIYO|EY|Je*446|I9tsD}A!^?5xa! zWxMJu>w2>||noZ+Ths{{2UXb?G(#YrnT$W_vCscIKu zUF+d_dD+>em7mit?JoDqg1OKz754bx+bHm@Q!I@*_Q%$%J2D>?d2_ZdcZw#!GO zWh;QQ_FTJ-zauptO4|Q@(6hxhz0sRH?v@ZQ!>y1_y3wrrrxp6EeN>O~%sV&7 z^3$`~`RaF8$L+Pf$}sQwyzSqwFF$|z;kGil-)}Z=kKX=rvU~3@iyFPE<*UPjbeG0+ zF`TQ(f+%MMk3?7KHdRMEODNB)~4 z_l2n28;`HwvnhGU|Lpa=C8DBtnJ3!oem(tt-R^fnc1{ciQ<|*t=LwAlCf1MxX@*&q zFPGlz+mvxJX>Zy_jhZvd_Vnt7{mgHRn{N4LgY(_PViIrG2JaGkDv+>6DXGLOes|cd zg|*e+?c%F`J~fb$T-$QPJ^k7ygOo&F(Np0QHbprsQt&=0q8p9qaYKH1o6Avm5V!JeJNjoc{dI}RQb+w|!y)9kFH7ya+Py!j?G_jXywysV1) zGcy8%mix(mkCQU9F{s(2P`)Z;<)dZ(+g=}(e*A=ytLRPrt$mr|3|sgc1RiXg{qUT? zzs=>D!LCsp7xd3(98lhW`J3Bvk!_D7f1Gz}a80}!$=qO8y3&_9Cc-53xJ5m(Tzw{&)3olJ-0Co1FOTD4Tz@_^e?KB!XZ-89sg{EyWbdA+*2`nlZeYk$Qmzu#S0CthCddYrH5``z-keo;4u3-@08i(R<9 zV4m(rE#Y^&-`jn9$o{_Fah>2V?iH`|cbv@q|Cs-N)(S&|Te8+=lQup+w)6O3`O68X zo^8`S1=PTc$2iyd-b0e+IP;*HurDisWiT$Bh|2(otUr z+r?M)tHak{)NGj#8l4J}QNGPss=A$Ffn?}vh79kLQ*qxNp3To-xFEO5tMR=3|D)og;mSu7noK33rqHdo5Qt|QV^pwxf&eoZK-?=sazMobo*D9{44+RGr z!Vf>UF3C`zsvTbT`r3D$J(;4Wxf`>3d}qyBF_lSrSLy$Dh6UkG(FEG|4viri3D9y!x?X$(d3M6cidep7IcTMBI%yo|zvZ^dTeO$hN zQK*pnjt|Ml`QF|QUc8m-k;2|}VG-TF|FbVMh^K7K?oa(1H6?a?%!UNVZO*;Fb8^-N ze>gYW+JBa*t^PZa{r?=o&c1&#*{^IhsK2`X+YH?>(E{_iMi%!TE&nQOQnBDobp8E` z**lK^u~fOE(C@#*iXns5=goZGvcGo@)reVq?iS_x`RVk>hg&_l-~9di{r;uBzkM&c zI#1qq{h&eo)vmUa&#cSbc=ntWgGr&dZq$oag`#a2Tx}ULLSO5!ym0mx zvzu*{+QmIxw&X%%(Um~=U0-%*W?=e|&uC!R(pSPVV|IF1)Yg zw_N2D!H560?Ok7${?Ly5=gp+%SLXL?9-nHyy*|{><|B*vl~Vt-f0{iE3-(@-OrN87 z-tO}C)-O4Cdycf|?<*1g+h_ePLic=4Ld3!IT5soGd2+?z&DRgk|HZUJbGr8~H@{!w z?e-$%(Ch2@6CRsBNPl)D{Os%n@jZI`_sqS0?O%k#`Bj>~j%w-b`~T15=eytXN0upX zI~sRe>+jE}pqb(@-F3;wzh%A9`nlZn%#X=oC4Y|2t$uoH>YeEZzePJ)@BR_ee~>Q9 z_cmN)+l}8pobK-rZ3DGK|9L%qvB7D9t$opx_QKWX%N|LT)$D&F#_;7TzwVD8SAuIF z&)RZ>VS()RTd&^S+`n_um(o{n)&*-^=eCz$-IL*H_nN=XQ-onlz*5#ff6}uR_ubr_ zzWc$Fna8WXe&gZYA^ZL5boLXgLL)=Ha_g(>FP=ZTZF7B{Rhl*XYMsbME&_h43>jS; z2#nP;a4m^qT-|g%z_~%}-RDFHZKkA$`{vjGi(EgucH#9T@!iw69+KF8uc+99cb#p- z6z7I-aeu1iY*ISrl)cKlxy-sRD_5%LUrI@Y<;V23PS;nLhY2ovv2EqP`4cBDd>(47 z+P?L5h~%&RKR-Wjzi#vP!1wPv{AZO?aUkiTU`uTIhD&~f=xA|{w^rudbEh}7}e0}cPA19{A z*Qu({zjH*i{Nv@!+c}lKv**3vrX9Vlr$^E_YE}69XV=zdoZS7M@3LmA`mVoGTP*B( zKK^}QzyE~ga})0S?;6?V7OXc^(Me0b{{8K)rLC-Qf34ptyL(yI_H8-u85W2-?R?yK z`%ZS`(vzU0CGGy#G-3E zw&3{vdB2zEGF-T4qIh7A{NHn8|31GruoB&1n|7Je{_ghq%T_%9?fdB7yG^IpUHUpp zZdlKYdk|OS>COAf_w2_lq4PJds<_Ay{KjqD|Jd^TueDCyEWWxbbh5u&|D~WKj!!q= zc$<5dt$uYyx_2Tg!`rQAGVYYWw=FY&n6&?r#lIG{n@urc56|D5ynfn@jCA92Gu}_} z^=D6R^W37fs6OfCrKLqb1l@OEo$P02sIxeaKVs_s$jxa#eebRp(cAUH$#mk@L&t^g zZZx=gVWD&JoaWqo$8BYAZ>4bO9kcEWRooKacO*Kfu;)dguEKNe7dN-;xfp-^hRCjO z-r~PgFFE|ZB#__9#-Mv4MNKoZI%i-1owzf2syU#_foi8MCc!@FXuf`s=`f z#^yu%M=!qB(YUed>e7Wb`|Q%c+yBnl^JaUz^TwbX+XNU&j6Sdvnn_Mz*WO^<$`D_% zuinXY?W={ly;7`Lt_88io3rO%WD;}F zm^i)e@BFi01H$gEpBdKs=GxxqJ8x@L_h(E{F>S4bods}y+3T&D)$$i5rE{-stT>(A zZ>Oeg!eaLA@{j9^f9+yT<{PGd64@X1;C2W*!`qfM9;bH{&VN#M_iD-h7mKFdT*k32 z;eoo<;(6;oiN8Oq8?(cMxp8^w?!2tqu>}WzUfTS;{?Xe<%U;NtWOT$7x(2LBuV!a> zd+XVckI9D}7TIfZ>qb>voVNSjuEVjjznwq2d#``MBi`)VboN}@(THpAT1Lwr z-S}zimcwXl?H8!&Fzp(ngRqeqOGHS^)?)v!MIR2bpS<_`jjY_a{`>zgyh?}+U3Eyk z>w&EI#cvf0-21$e#aQMTJmmiA>Rh`&#p$?H{qKwuD<`Vuowxbilk@)Cq58YKO0P2( zmTo(Kxi&SOk0FY6ov0L(PR~)NXfux|=^NvN=3L+7T32@Vvt3Z}O_& zTV7ugO_(#FJHY#tTt=1U#nI9y_%h`UakA| zxc~BEf6K$4j!kgXYsgSt_BZKy#?$)tJs;b8{^!i8{?W{DKWSa;`qJ;ZHWsd@#czMQ z>~H*JPVwfts~?_8H$OR{++T8jZsD_=>x$+^cmDi*b-Hj&z_~+l)o)|%pWReosW|-g z`g0DATi?viemA`y_g?Gu(RUf|9~+vkc|NB$tZ&opZ?9KuOg?@RH0-+F>+ZVU@09+3 zf504d?B@}KIbysFQP$a)pB067=HJ|ux^7a;o7cB@%}o7W>b|F8_T2xEj(Xn-*%>G- zUoErRruUAt%B(B5655MFkHPWF@EihtlT4F#(Vd% zY-4p(S2y^{F0*0(oVs6`dGgw_xl(hg-`)ImdgiN}Jj?%ndNSGn*ouSm-frvtxAWDi zbL*7m&pc>XJFm~~>AUNzLW8wU=1G}1WCs7bRrowJ-eXII=(*%R%cvZ$ubDemp|RUnY;d8|1Pc0i^sPe|LZ07@AKx}qF;W5-C5KVxA@cbrHhWg{vKn$F)6T9 zEPkbaoT>e8zMHQuonG?o-R`FxLQw_z@8(n*Wt@0zxo-3MS(e^kb9FDSYWx^?-$*;w ziZ%G~v1&W}e&5+&pkVD!|T0aE0zW?Uwveq z#B!gRn>MAKOyYgyJE2|f)yuAjcdA~W&D);A@L_KGy^`xQ-bTIn z_gh}({RXSmY3FitmhILIZp!}d+|GA>PiVl!^YRDM9_)T=wpt|Wy8V+?V!s#`*k(LW zJ{p#Ed+SzZ?VeAkwAZ)&7W>lIDztXSS*x>Ca<1t(Tj?Bb+do@bC9CzcUiMuxSwH>j z#U8&I7R;^9;rOs6cys%{qS|)ri<8AOeg^D+R)#QEeF0wF@VmR~G zR_%ApuCEi1O6|D0snmPZ^7-%Ip80a8{Qcc^J~?rGNe}nS@&Adx#hR7du%ZU4eqBBLl^56X+j`$NHuKp8y!y9#-Rg|=%V(FJPI_AZ zJ-j(&T}|cMY2T-F%S0V8nR#@J#k(EJcbAFzMQ={?HQK$?A?od|-8&0rPxb7twdKCH zHhTJHmSb{v4i$!-+L?A%>fP42e`-Cy-N+SQdwa^E(pPWZ)v+duzR@}HZ8zJ&vp-aK zFL@-<8Ta~vGk;;Dd-cDc&*RU0JH5o^_Yu21QDN_CI!}3u@)n-B@mFZ=be+f`?U=CA z`SV-t*8X?V7E`;GAKm|(VbRPg<6Sxgd+Qn#^teR63M3S-O(~!E?{jzTvl zRdna(A60)-H77pj)g_nPzjL{&qIDL}2)X`x$I6&fFRM3bCW`Aut+=jg-qP;3jO)SK zyLlJ6${#P;Dz<4uLp1ANJFDQslbTDybfVk#n>%TRor&`~zKq{)eddDF)z@~-Z_^52 z8>4B)`|iMX_Lp1tt3@epD6f$F_-@IrU-5gcdwfm4=AM&gH(N3P)|ULq`|`3~lcdaY z9&pW$IF@j%XMS;v{khXSqe>lC3uSm;UUoM0`x?pTpNi(}$;*C!|K9IirLRpV>`;04 zPHftm@b&X{$Jr$xw-XoB5UcFwXNqN335Lols==zFn4E9K!7LrEV?LjfQZx z9bO5Y+dRJ?f9$BT|M{Qq_g}KhuYR&M&G+J}Q#0cK-sETfw~{NS=A&zr;rea=w9?kD zmWmW9-SOwswXCG>-2qRn-|vw&zmw^BWty&jVSfI>rq(>Ihl_s1S*8;#i{^$m-Vj*e zJNx&cZhi4i^P0D&u}?P~<|}<}Rr<egFQ54d?aOMs1&RE_T-wj{iTO=iYXg zuMD|&dFJjvNsb5o=34JISXi%fZ|(dji+jcYzZ^f-BdHp?I_&D4BT#Li~Z?!6J&$*}6JzYoZLUnSwh(qI-um`_huP@!tuyN%A`(GI$Rr7P2 zHfOKhpR?&@bM8i?yUK2R)(4B|^KA!BvzNa5dHJyB-2FcuozC^!FZ1qD zt>O4^-u}Oa(L?*m%g+b@FE!5MmHN}>GuO)0ze~34Mxs^jTUEV?lDl8cpJm?PlNYl$ zidQpiPefe#>C)=e|I$Mlay!>D?YNz{^|9Yo>Gz=BvQwvOhh@6%e-nK7*zIffX^sx7 zB{G6pZ)fLbe+=fnoxSl%$b+BHf1m7BpZ8$ihM5m@*tP~PwkzAbVs1^5@LaJUV&Vc@ zc=!E$CavpGRC%uX&655fuj;>jTk~svD5KBvqg+=^udSJ+TXuK%3Xzq{3^V-Jb`(1{ z&W&JP#qjQkyk7oW`Sk}ttBl3tYZhKkd~qT1)9w8I;-0>*uB}xTkGr9Cd*|(v)8AIl z4qEEv`SH=w!_TMbL~1p&^Lw70a_FJs&SnDR0V9-v9JCUKD#$6EoxZ0ZLQD8X}Yt!Pe>Ne(r92hsg)4#Qp0-LviRAOyX#FR z)yi+Xo45Pzs?;6lCmW>-&HgykIQ=BMd`-lX`{{8ei3G=U7)2Z!9U7C4c6Iy4XI=fZ z?Rrx1VzJAQ_2c*53GM0L=eIfS?2~-BDa5tFL5OQj%+{c56QB4wX_`3_niGf5n0tt`p2|qw*CnbY zcIxF6txzwoX&Mg?)pLvMoiQ}N+P8wm&QRS&`HIjXMg|!3rR+VZ7FYC#< zw<+@W=U;Pw%zd|GyBkBn@yzquix1d`F={{Em2=Z*?&*1x*8RWXc0k&l$UtdSTHs*F z`!IB6kZVrXy+bi;vSzg|>w5V%YHn)&$w{h~adq48W_f>)-sL%2P5o(wo+y8h^!JrE zw|*PWG|$h|;yZ5muaWD zKQ}$)`l;)gb5@OnFbmkhC30FrZR+ZfX+o-AV(+-q_swekufvj&=&+h4L-9Zbqt_mi0j6bo1v@2M0an! zaKGwM{mBzy3vxLa#60ZE+!#ePRxp{#emFH%TS#h3lid8j1lQ*Uz!&f-=yOFBtV}xU z)oS-Pe^K$4tgNNp(TR~AAeNgQd#WK$|Y)I5q&dvSLNxn$o+NB zcUDb3Dbt-hDZGIp;ZxK`RjvgG%0d#Ju9~_j@9nL(Ke%M12#q(u9nHX66u!Xc=BA*H zPDk&U-*P-Z4Vo|GYXAQFy6#3F>zasw1b6KO#!&9F)AV9*%>`x4l*4Sd(h_U+SQxmy zGvnA<0}^I)&2ZcpubFdE#Dd^*0;H8;BGZ`6o~{qo|IE1TP}SW%`}{sWI(oFJ!OV1n zZuZs-=U!c19kX=n9=YzffeRLJMSNIa^OGwmtam|A(G3Vk*T3|x#{{A zCXER#OwpwV5u4L`|3%L|axJHca7_o#4XnWnVs?HCS{Gxvab;Qesieyy(=XN6ZM-nG zmGQ0oL+$lk+iyEFaxaW}aQC71sMDwibGUNNl8*B*6nEC^3Z4HU|4qj z`N5lL1{2G52;vf8@bOYJb0V^)K~vT^8U&4Bf)o}f9&U@i{CbLoG?@|U(3q>~z)%p) z_0fjRq_kuqljKzW`jXXplO|47yt9b;Z9^Rc`vV4<2Ic|=z5|RFq;NEpWE2=8TM9jDHyF80;J54-nwKDX>pq zbVww=1&WpnHG;TOc5pRRow8!y5Fs=nx@3Xu1%5I^zJb}bfqANay^p=R-72LIfr1y8 z%oVz*x`>CosB}2NxR&7sbAuh*i_N>&uy6GE!V$&vw((nnVI(Nvs+epV*gr7H8Oa%d z;UiLl?E(9xL;N9miy03*@cANq(OQx#Op!k^aG2>%Jq9OoGY-PS? zH)>)?_`#XV)cy60KaZ`wKHxZ{xoMKNjRFY?izrZ`A6*e~dks`3w6m=Eu$3 z8qcIT)SnPxvXzkE!h1pf1%D6!EjFXsjDHn_Ild&+TrhK}Utn)wmmz&3hwV$dkK%>q zkB-C`sI+4tlfqPfQGS(eo;j0mEF;g0jY`KE?O8XtwZ^Jk*w1+F;$g3U7v-87d;fu4 zb%42oga7OcV{rP0q;e2RbV{EPR=2?G_VMj`S3lm=QZDM|BQte?3*rSG1qwV2yMEQr zx^UJ1Txr6!=9PsPo4+M6f^(x*(jjJ0K?cb>WMrNResu~w3_*+r88coq@LhAvWZ%Mk zi}5eX#XqRzzH8~gu%Tm0me2RLBR>rvfZ##WDiKKfYdrMSVd^&jjO~~IM^B8iuQY%C z!m)aR{ek8MA}Tg5?H>f>4mnq3ENztJmq39Zi7CGoc>g-Iu`-lie3IGr?Eel|b~1en z4xs=QiwSF)7WiuwORG$~$SA9`)7N@|>;=9T?4(zq4a}J*7{eJau+Q1{iZjhcN(d-Vd_3vzpyzOYv?@Ym!g)PT$R1I+6gKqdZx?`(eEB0M&EMGvhP(x3J%8e$N{jU-C!!3;!?nzlXoG{bDE5`wi@IjG#=}_@4I%D0hB3 z(A={siZQ^OA&c<#Nx&4LNvF(SRi<5 zLy6(r#%~Uw{6bdVD|zCO#(H4QshPhFcS;uSbY(xf?OLk~JNXS1ho~Zj8B7+%TyG1w z60Xf|es&=Ah^#a=!OrUga1FD1@nIO5Ega6?|P1Hy|P=P;MC-BuR$ol>NR>e++_0N?>Bwz9Vf;e-aqZ1eEsg=tE7#A^zY(tufw;lro8E|KhdGN|HLic*-N5Yje?d(xt7m~{}-pW z`g*?4s~M(WY_h`FKG^oR@}5xS{=(uN_ZdsGJqmTdY$cNwCkfPQ@-CiJ{>%pFR@hcx4eR}rY^OKysuQS-s?_3kJ z+cC=i=RBVohVH!%f6o8^_PKxJ>~pqGUQ;#ZJ!W`cV;lT0ZlBvayT<|F@AT^TPh_0` zcLn>Ut1QPqKhFKHmww9i__gxifA8OpKb8F6zpRz_`-(`u#Fq_^_s8uhob@!_XjN%N)@r?~x`UnR8NDvoE;fI2s5e;52X)`XnP{r>#X z)S?r*`t6mIZ`N9QKP_5%w|Mcs-@Z|HALF+D^?vo`Q2eWZ)mK-&*|yPMjG^Z1=9ivN zuNSc~G;=k4{ZbJu$EU?`%ka5wtZw`LZ(VEdZ*jf8>0JG$yvOmopKn;d^!bK_|0!QQ zwd<#ZG8#y1_;cW_ZdF9{a@h-f(2b*9hU0!|Cg;^rq1=br8}zMn(zM=x$DdSi1*@q&s%P0TCh*| z>S-=UO8Qe8w`6|2n^*=a@x%*W|GpTq^LsC+=kvqQzQ5N}?G`WoZMG|Y!I>GGRT9^| zxqa{LlDw}EO5aJD#LbiayVmB`vd%5nwVJloth)Rz?!$={)zel}w1>o{v*E zMlpUkzU18I`sv0`7A3#heZ8XM#q~?oM^v`Q?~R&zh^yhXdG54ZvGY2s_vkH`SK{Al zb@1)~hg)tI-3)$z{I1^H-;M^X8}{*w&-kLs7wOKQ%WO4?T~!w}fB|aD$Q^Lj&OD3K z*d^31f)8RfE_%eC#N6;bgTY|tx9EjFnm-@E)Vp=FnIWZD`}d7J&d;gN`8yr_?yT>- z{jXQQe%k8!|0CM&744gI!JuNzem16jc?-LT|K{H*UMUl{e%fvOY_11K)<6H+&&%-b z62pSI86{i~_D^3w?eFfrBH#ZcGdHX?Wth=p_wVcFG@Am(13G(~mZ-k|_t}wuH4muK zmmzI1VYiDhtc}WC(P4i;{vnBjNcZ?_mQVdD6vlAo>F3+&*R_m3+E0HirX;0Vx# zqyF@_ze{XFqvZF`zkP2Rciz3dGvLA zX&OIu-IawHcn>ssFL|`RR`{ul|es|3`i2 zzoq_9=Ds`objjb>yOQ^q)$Ot~b1UD%{Or#E+4FK!&(E5AXImnJLFb>SKU@u*Obvy7 z;`^Br&VBa&{Vis#v;5cis9C}PkLy~I+hZ+Q@S<2Do%MkJq;u_OUzbmvq7`_j^^;%a z1Kye6emAxJ-1M@)Y(nhnDdo5C{ra{1)1eviPwubno4$I>p?SKSpXp9bephGv?%z@` zk;#_l<5Z98q%QXsV3;%SO69XP3>G)vhObXco%yLix_r+9rUwl>j-QTXEJ(TY_R_p| z76wMM1A4y>_*GvJFwmRD%rakk{%kFV_z#>vSco5q)0icr;lWT4wSHUB_9|ELMZe$m zw_aLue8P_F{r>h9{E{`!!Q1ElwR|_P(Wv-ckmc_UwokWapXZg&FSy*jDdXrZnd=Yp z?f+-&TzWI`VHpd<=YzAeWPeL6zx$}+ZI;-kJgx=pW*WDewQapXy)jS&_Um=AAFSyU zz}@E$402X7pK3itq226%)r|l5HoV8%xLmSX{>QfR=#{~`93Q{_&6suP_c4~EVMUM2 zKP!KmD8Am#_{Ec7-w$rzKSkZGZgTGbs;ye5cl_3y$d&4~^KIR%%`Q^+tquOXe{L-I zUcpp*YVrBVAMa0C$4?f`zTSS`+_px)a_8%tyX5xy1TY3H=kaS>|JQ21p15rA{kMNU zZ0NjH{X?a^t}HHCt}BFLPp-qA$E9{}6Dn6+<;?rfzyGhVUiGKHIq%QU^9Wm?a;|*0 zY(H0ntMNkbO|#CQWo+ZhWz4w9C>z4KgG2nG5=rAr6OJ}!upU^t`ufQ~so610e7|s2 zPw42bzrFIl#!S2PjXuB5Ki%|QFH~pyvuQ8ub*Gi9pPjV-tA+Zzc=sroz4;cU>vJ!> znCEDe{O-|*Uw=5qQ{JHo4+~!-q4jvR>Q9KOk)PC1NU{+-7$ZDa7cbWEFZKx zidC|*y1PK@fy?jwo4Z2us{a~S7T)2v{PnXpU0$zzyM>+hnJl-syilQ`Sn2k z&UUNs@~Zj%bEZDFSa&F{r_NG~p>M{MZ?`vxE&UhOU5(nbC!<_r~i=gXh0p85IEYsLPpxk_uLOs8B@?S9QZ zcWcCl{BKQ9i%tqFKiSTzedulS@56;(%O@YdJx{0l$_f#=!%g-3|Ll!fS68>?%Z?uw zmYM%|y*qHWYOi+unK`pV>>i%vTYe(-`1|MIih~)l87@@B=nFCYdHO!J=u7PSbV+iT6bZojJZ&FZQ8Z%?)E6BmE;A$(H=s2aVdoGJf>{|AG- zq&#?nfsE;eAMU>!y`FkyF5PFlq+%n_&wu@{pFZzVt-Q9_t#wn-#+b~RYY*DY58u49 ztNeOa^R_>$v+E=GCJOI4%bdTGL83`>^W6>eZW>-Z{8jlD^V@^96PMawkZ*eb`Q?vp z-nu}K|4ZsG*}vVt{h<0)htdV$82Z2xoBGe;tsQS_P$V$Wi&-tf8yIcw*Hzf7W z`E)?KD#`Np^M%z{Ci%bH8SzkcQ|4*0l~-R%rY$)6`m237cFF!`^;Hlxos~T)@G1@sBH6LFQeTd zP$lu8F`Pl}0CUBIYUY1n1_S>drVk+2ed!O7?pMVFNUibXUV}Zf`dEM9-1+9s{CB-~ z&8==RSrZ$2YKqpvms@xucPB2^iP;&pZ|2|aZU2wG`nAl*v8>KE=GFvTZ{yV9e?BvYA zerXD`9m5On>Yw~wUlaUNzHmtCfd+$%TQ1AL;7@x2aqxtX4PYoh#1t`T}~wW2uioaC0CS51UX zB=QZ+e;QUZyxAyW_k57j?GH)JK`CFLdMH}7Kp3+X7ea6J(J*!|<^25SR5 zBReCzv{Lq85IGLf1Nx7|lm8^8u^#XV_{DZ8_d>u0M%guoL1P$X&aFB~6)7w}Hud}s zo~sWZ-CkMW@O8o6MUV*~27MdeO*OssE&m+q9f z-6$2F#Smb~Cpzw?M1WKLm4Vk7%0SH%3~FV?<~4ez-@UF1c7FUi*P@FN#i_zS8_XZe3^tyXb)Wq$ zaTTP|c+k8K{`P0%mJiHg40l#d*OQs{wdc;9J8KrV$6i=udqKX$uK?cQ{>M>&g1`(O z_At4^pAyPYB0uriz8zQlxnwig#Tu88J!*NNam!N&HxmX4mD0^j4Qrx{#BFN?`XJM! z%oPGG&EQFNa7_MwC<0!G1R47Uk%YSp8xH?<=sov$jjUAvpB+bZ!GTQ93ILFvMw90b zZW0V7Kka=}(q2eLA5OJh@uCrwmYHoD+CKz{Ce$2}f6#xY06f+H8-O99JUf_(7E!=xuuuE4^9^k8h@2noTzB9KP3NX z`p*sT^cv(|&wNZlfH zVaZ;L34y`d3|X897Nowio&9J+>6d~|bLhC}G4^Bb#d+X$T%fgF5KKyo>e6NY6kkS} zmp{y5n}+ra)+FaDM{-e zm@}V&nu%$Qr^-X}n)$lEn+;dARzbJ z&dqtP*_*|_IDi8awy5Z!_^wrF2-b zQ+~xtMu*oc|SFh%$Jtm=&nF(ud5kCkFNh4i`b`?gG2XPTr2rWJ$C9 ziqfmxQVdsi-rDN;>gS8K=Wd>*)`&~Ky#vFB0;c}dZFv)tq_3a26%=}Tx8sGxpEV(j zOb1yOakdC|JZEQYea!zrcTel~4`TNYMb|YP|ISaaDu)$KTu<1uV*fV1Td#3(XWsT# zxoxvQPx~73Ixz2Z*2--;({xtda=0d{-F zu9<)Ff5?d+hra9X%l}y0{XV+p{-fVw1lM{$nE#kvhv9|ZlwYUv?{RF93u*G6C>Lt3 zH}O{V^b?z|zD}u|`ZvYft#gW;y${p!7d4h~X`3W$nUi_=U#t(4ob=D3euI7&**$cH z+CL5fj2C>bt>wMUDsReodRLv3=GDc=e(k*Ut|$3PZ{YmX&q`OP#w}%&V$xa1+?3UO z@79N))#k^Y{VUkcKh%EA{aCw>kF=p8NMG@jpMV1^nC-^u2PS`rFQbF7;ema);7kT`RM# zW+dm?3CrphT)V3O>Zy*l<8$%&Nqt`(8n3(vEdOZo^Tp43pU$jUY4m2bF>>iFc67WPO{hT2IJqjRHfoeEm+y!GqnrB^xGPwss?`_yy$zpCbY|9D>L zGGBAitHJ){Ca%)d)R$7fBC_JAKVF!wb=&Z5=Qo#Xue&=O>KEBxod3cf)EOXpq2B~9 zz6@3edsc&{Wlk3=WQ)J2+MjARFP&7}pQZ45+PX=fK&84qL*M@l+XjE(uUB2aXLGbO3 zd8|LV*17N0eVuZ?xBlb}@qdq<>ctq|Tqs|n6Svi@yIfoB)U>1Z85|q-t-~EC4|M`2R3~qsG z|EJ$$=2TT&=*2E7FjentTNA7H4L{3|Hn#rfoA#Ew?zMhzbNl39R_PAbkO09A7rMXj zHMX!^s=ll8|NGf@+pTvSZ?@j8x!beuvFzsiZ_b3@`+o2J-n)OF+8$xD$5kaMtU zs9^ZW@Q4vvU;*bN#%wl+FukV}&S-Cu_LiIL-G3?cdGDg*`8xt$1_?0aS6AFhq2}r>bmIii^)E2fQAe!;R0@a6& z-fRwG@%QZ6A4|P$JE6R3-7G87w@X$3SGDa@IigjSsLmiZ&FW9<5#Mtx5$9(z6yN&3 z{8WG%O10Mr>1M>mK2Mh%yaubd-o@4mI zsNV7D)}cS~w)?prO-al!kCB_Jwduu|D-pk5%-o%G#r}2X)psRTRS(yP1O*;$J26Wm zXp3js?40Q-!Fv@Lk9}Ww>O;jF_AkQUIBS^f4%;8JSGIG+mOLK)tM{bKR-XE(h6bN!0nx^&vT*p0o<{%$#Z&;ET!FNa2D!#1;Y zCJ~hbkAA!h5xI7-&i>nRuaMS#hvF>PZDx}C!1aUSKkI*98wR;9{h9~-sE~xn(>=!Q zC&{21ES0XEe2d*uB_uUiTx-$x`Mak7T5442Us|*OEyv#tw!L9*t&WA~c07I;6YKU> zoi89YLPqpRiMn^dhV!3;jBI{wkh58Ss)O^V zG*soj+iv$;A<&gm)NOe{X2~XIi@h`Cy=TB`$9{#uCz=HKUEH~CCSsl>6!3-`ILLLZwWb9_F zV6Xud3@t1I@=W{>k)ob(wBK^ENjS@JqVIm&Z;RU^_m|jMh0I-|qP0x@-L6)(IrnaN z&DmDJnd?->*?*6xga4Ml1HcUCnwWFQpha^z8l62n~oNd-k@|t~JLfw}$o;-;A@??IR z)zm+_Yu7CFZTHuR{LgaIf6D*6Gv{5d=m?5Foyo9y#l8>yYz!}g!!Kga(UKe`ofFu!5^#!x+>-jN*~n4mKD8e>g; z(|i99e>wNrAN;QV<6lc5!#{@o;*UQI+Q~nJ5`Ppy)r78*oB)eM>La1!PsL?3q6=f) zee8mYDoEq}_>O%JnDg9zW}xZ#9fiBh5#Zml zp+ezhUuDkru9vsc^4g2GOg(W-v0uX5aI3zR(`B{(h1KilyA@7+IO$lr{qmr>@g$IWFG#v~IJ&RMCK1yXoxD*6MV6FMaf(?}q*KzlY~<*i^*P zl9%(>xn3uDn)VmoU#!2G_A&4`wtry%(2l2C#ph&`VjF=a0t~rb>OqWbotz8SYAl-K zK4s~gTT|s0JK9=Z-fJH3d-(T~O^1u>&qQyXyh?Y@!t-T+HvH9CnkpV88Y5K|Jjc6u ztzd92Npb^F(0pQsbkzm`QbeU*Q~{DJ-7)kJ{} zpem8^n}RANzb`R;@EKALFvxjuLRt)&ydC_Il=8vB3({in$abiKXlP&$Vggm@9~`2Z zJNVZ~GN=Z6rY*^Soa_1LwM3AkvEF>I&CC0WPnw`*XHE?JzlY){DJIi26np*-=BToe?a~L z{|ELT%zs+{H~w$^?}}bNVr^l;lfo=TIS#LV$@3(R)p69NMCY~_ZoI>y_w}~ol1ZKQ z;+K1h-2-A$cEp;c#p~Ry=`iBVG=$<3{~7hA;fz*#B&7RD8o&alne9y1~|i^ML&!IdIcUp9vCxL^Zt_ zDiD$JL(#54kMYe6kLW7Vpm^`MT7E$#seEVWRqi~0#9ndp+?PAIq}?yv{bLi?X%7J= z=4Tq(3x3@(*~H==5Le^BinEVr#>zyc2@EO>oDNLnQqNQcrqn$D|LSMLE5+i%pE5_D zZ@ZEgKG(hQsC(w28y8F7mx>2ZZ;AMPsd%UH`Yn^h*55uaS;Dg1v}2X-)-OkYF^9xN zF5SX<-Mr)f-=HJMFQy%^4`GxWq z)?fC%J@$D+{SEs!^55=(2@wfljN&n#g!~T!?f8+lH|F`|9*83xm z1mkZ%EfHZ0s#wyQtjyWhtzN9LMe{BTe6o9gdRP80r5 z%dtAKWWQD29j)_Myagqcl)V% z|BqHh%HE#$H~D|AP{Tjx|B3(0EE?=L)D>*uX8FNT!(eygEaMM`8izeS=ef%q8tPl> zTk5yWX8xlLhKpqd9>_nGe<=U<83VYQ;P{`x&ho<@1b15=us;Nbw-_1!ZS?%R*p_)g zir==@;@w@sBGGk|(&EkMruo@*Cn+C(`|H_hZpVMoyIu-}M(TXysb}BBm3j4D^0#eg z{)kU_-c+(m-^TH1;oX%gn}i>)Z??Q6_J#5F(K_ezYtIy(U@T&gW8!ZltNDB3P{9J- zsSJD%FKwUO%^$G+9Osu;d+V3fX?E`W@ORFtmA41HAre zNwUw3e3xe@sv0u?tR#=}qn#=R<*Ru4LT4<$v_REZK6iDav)r})Aq{p8@-7e9s~c=P z_TOQI^c9?cFoU5pa<>Vdsj-%tkaD0w{t;sfVfKpkt7W$xDl73dR27q3AbEND z#W&vP7Vcn6`+8~23p&D9^RJD)zj5ES-t-&sZ}PLhUB8h3!u-qbug4y5$iHF!M*7>@kctWO+oL~z z=RaWmK=uP)1^b?48HRh?f4#r`@cjcMD9LW|j1d$I&<5Z?hJOYM;J)DOByuTs;f%J#Hrgiq5|JjgW+xudyVVtq4LgDAR|H)399;ihB7gf!P4&Gh- zQqW3wtE}zE=hD(kpRAv7`Qn_UsIA&}{k{laXZd-4*3b2Q(Yo>TzN%V=%%AV5x^ZQQ z%*8;Rz{t?-%lvDWm)^AgCj9%R)Cchj?)v1v-i9}f-|T#PeDVR~2a+Fp_MgZ|oxgsg z+>dlHEdK$91k!{9!!c$*)rOm1OLu3ze173q)T@vk?RxV~+TP8yTpH;0k4wOMLa2lG z%s1)AzMqzF>q{-KroUbM=*GGbk&6pMU$kHTwPvSjrFwM#zvSAr z+~+sUzv2Ht_`}YvN7BKe##6y&lifOB{9|R;ehG$s%=a7LA1HsYTO*Oxro|q)vw_jo zaIkrByux7$Ls&zE(1NHRmXls-Y)mk}YoE<_c80~8z>fN*Q%%48-DYx1cV)s$ix~$q zW4J25zT?qj&3X9Rto@$U`BKw4oCW-%u4T)F{?%t+njW?{zv;qlsjq^s5AAbW-*}k( zR{R=^gtH7QR2+&8Zm(%MB6huRjplMb*6J50cc+7zLsG4O%BOhNt={n@zchF4WSg?I zCl_zk&V0l#IcMGWTV;D&U-iFV_Grbq5SfcR->%uc_Kp6vn`Un$e)rVoE&MlES?q`G z4gELbWsn{NNl{%=py1)lu;zJ8!?h`MuF2nu4zgafugmJ$y9Mg+clIvp%dq(AKjq8a znjb80ea>&y?pyIjSu1MIy{V4B{Y46%otmbt?-=r>>fhEmoCeA4qVCHzTpZTV&(HpJ zs47}#-j5Xd8~Jax2Yp)c^r!!e-TeOqzVTJJ?_K@qv6&eE;eUz$H`L$Q|F&DSMvm>@ z_ABqt3;b99$6m*{zajoncVSIEb3FqR>_8rf+Ony_L6KooeK6liftPhZ-#HC$)L#_YSEUTzpUk#oXYCf2zqrY>n(T2~fVq@LD&fNXd z<&9=ar%%D8e*eE4ZEyCAt*W1~-|_%J83|nnBJZd&B<= z8T%Q2H`E@md-JT}N2ecC9@%}ckUL>zsL6_-*;7DwQZ1dAhXXYz+fS8<*B}Wk)rl-pQafH zFHgGV$y)t#oA$Y-xAkYgV19c3V~4_zwfCm_sZPDx*S#$~x-X^JGC_^?lj7TJ-@<0+ zhCfLOC_NXb+zajqT zNq%Ujy@CB&{-FkF%~HW(BeMU+LHPqHPzgRB*~rk#K4~UH#?qv1HeS)~U5`zkZdv!` z&iwR%ij0n!hVb->U-RGod%VSdwZrEa&s5&O8~(0X{AB&JzHQYDx2@~r;(xy+!CQ1{ znd~~Dme7l`;urE(eoMXU{6_wpKa0U9P?f%b|B_TnLie^Q3?D#EqY2j-YCuB^pe}_b zBY2!rVJ+iF$ap0Yy^ahHxh*$%8a7^KEh+o0_3OBDc~JWfjdt6LkFOXe|GW0){E{s1 zwa-@0eOc*sZNF3t9|t{Rw{B)^Zd{$s=biUaXB5A@|&lAwS7En4`$RkN zUHFtQXSFo0+9+=NxAxxLbML2S-aE{i&N*euw4lmBJJ+YOPl67l2j#lx+`mxt#lu44 zjQDR>+Xh*3M=L?a*p?6(j#ow3+rNI@Q}38_T=(gmIoq4__I?xERr^XJ-ECHTnC9f) zX7Y9mqu+(wXl?qJYgsgDRaRE?6q`R=^F>2VLqaCFADntrB(7?b*REa_F3w!Tswet8 z6YorGHPU$<^v(I$Vbmi-?t>8#@K zT+(%pc}iLKr1+Q=3EjQVowx)KeV_CpE;ia-Rn&CK`6H|UT+%xAn#6^n6ets_+5}EvQmwo>6eBbZ)?J^Z& z?N_aj{TDP(zkYk~zFS2i|4x2u=L*u(71aM<`By^f+T!NPduuk^&Yc&(DYU%)>zmcn zrqtWw@$8^3iL($sIYBq;; zmNE<8cFZz*6*|@J^7>tq+`hl}O0UrPukH2s-E*Gs-Yt#wkhbX)~e{yn@L5Tao5budMf3L7f<+$piwoR+jPvSzW-LK0kyV*>SadS^r zzx>%d^XfdGs>GM?Lr&ckVJ@s^_PsBaZMWaPm{s+tyJhaviFbsgKEJunm>QpU?exii zFXnOkExswtHc4T%*%Oas$(ZloysRb#=S0b?^ZG3Ox!v~)PxWDI?aZU^&WNe|*FRdV zuq@7KO}pE)(`8F8pMAfU&*G2y;`#rkq$`}uKm2%l;PoRC%Wdt>)wdKpn;ie*o&KBE zsYjN7xZfx~pKZ}!X8y$Ux(`2_ec-8J`@^&5ee?$T8~jK3JLCoIBkDPrky`Qd!#`Gv zBFY2Mq)&p9+yqGmSvF-+^$+J3eR==CHwjtsi*4Hd3{Qq8Eo=2&fn-Tm}R-D|JmQA z`{jd;Qh#k)@4Hn0?A7(@ObMrtUp{s#eBxUpJFPpO_1iYa$JcAzo^sFZn$4cK>4zUr z->t}y_5FJI?@wiMJNB0z(Z1pSCb{^hcF*FY**E0h@Ru>}CT{X&|D%Qz3@4%wv)lw>(MUN`jP|IJ)pQ%g^LeKD7Rj>ZyQ zpFi3wpY&ui?z!i1pWkwS(;uc)>(*_0?H}?_a8;l0qE$zNqk3!9`QA8j=VjmFX{h4S zWn}sPFVoz1drEigyvD5lqW{sa{%o_$ox>RL$Zf&n!(WW6FWIk`UOZv$moF<9UXOdY zY4dvh`zP=2_|89>ed&ev&ArA9QnvO6OKsOyJV-igBL5@D_H2CdhN}r? zJ?{U#7wYq#@6Y(q&|YzW@BW4wh4~K0(qE{55&k8)8!;cuM3TWTMD_I*$n&;Prn z_K;oT{2%)`?u#qNx$o&iZsaM*aV)5C&}2MgpTTu_%QC-Gi&YMp?ANac6y5W)O1+_B zl^HH-@)>FTtKGkq>ajod$YzV4vdYz?V^j=}=7YXmu zgA0B9xNK@ah20aL!SEx{Sb#xQILmzc+Ij!_R%9?c{^L?y z&DQ>ZC*Nj1owHKzWPPaV){qlbQ{uy1MX!pzk`Z_1G!zt()yoOan)C7JHU7GVOK1m8=$pn+VK2-e&cUQ$ob>gW@vHTwcivkvLlULEGSdSd zH3qXQ`(}NrbY@zh!}vz1|7TYG+JkbpX8ldxdtm#qL+&@~Z+FW#fDUj*s$>>>t>FkpIE|r~QAjOa|+Id*<_v&kqzou>2rXaqq>y zGqV^kcri@ubGziowDj)ACjzc+E*CyLJp8gJ&aueVO z|KxAurhU_FZeoeGB?FPF&Uz-n7B=P3O^&?g24 zQB+~D$=LHl@KcN3!FdV(?;ZueVE@AW>!QW|>j&;1y3gd_xcorygOwjxAHiCL+ENVs z4X~zb##Dw67g*%1QW>61h+^mviBXuNtn>7WX1zJRq>h+K7_w>H7oO4lt>` zQW z+`nS?K8Kj|os;Jz_89l=T&KR~jmlN_)4Xd&0v2(wc+`CTZs?9 z6Sk~tixICVIJrS?R&B&K<+*v4|I^ohzbgOh=7g`+#`hPmKeu4Rgaq}-wYO%wda*ft zua|!iZkbo{#^}{7iN_}IAJ19%W6kn?SLR+%Ip^?upHCqc_U|n3sl7cSZJViA zd&FYRCB~d`P%ZUka;d_B$I)l_%ebst=Q0sqE6~{X&|$({h7*4^+W#=>Gu%on4ZX6n zVe|h|>$w^hAu|JGLM-Oq+RChYEb?@Dn&`B^OxLYJkG3zF4`nfA(v`JuCljV=4CYgPVQpR2!HYPm&>&+OUvUOoOhQ`u(g=$ zY8gH;b;F7~QE8Ec3e^46EK<|9t#Y?$$p{p>{L&*KWTh^Uu+~@_p%} z%-wEV4C^^+8|)6qy}8C;&+wMQhY+O&kLx4-y1 z+hPH??vC6=hcj=)MH(-z&D&9z|1J4vZSadN>wc*=is#xmmDg_B7I=))#rnIOU$1F> zGSh=e4bzH?eoNf?^dwa(RzzHF{~zABCzB?{F&D)2hp7IlE4^7(m3y<#ZR_L4*jpF5 z4)Zj$OKs^pc4_jncgJTi%s42?5N^KekMtt-v%2DYKlbgbT05Jkp;7$2M`eD+n;>&Z zhOM9H*=*>Z&C@V5_mbb2FOH|gpC9OXzES^%_>Hw<_Y=i8aNl5k!$j1o6e(f$5Eh5D z$_=%aB4_r$6*%{A`kdW!o2q%ATdwr}=f(Qr{hv28HQyXLxy^k3rcGR0nwr}L1-88A z-xLy@@-I>Ao$0*q0l(`MUe4bAbEYzbSx)WSq(hm%FNbGv=-$zeeD!MO`#JtAS1sEX z_{Ml^tx5Vtp9LanlWTX|&h-H91AjOF9^T@_t$1$2tG>3O^1H z#XX(I|L-rctx{vK`hI<_Gtbw@n|80{+!zua?tc5y=Zti>#+M)Oyqs?SdH#W?4)&K6 z7jwzJ{I|Vd%4WX2{0@(a#_R9B{E_4>b@yZae$yTGU;oX}X1r6d$G@w4iJj-iD|?-F zLW^fUsf}#i@;}8e)O?a{<>vZVUthmmZO9lfjUjJ`jnj_qxVev3)E8C1Ix1k#$!m$I>~Iw5;L+yk@pOof04Q^zxsxf($qRECX|Xcj;mq;-pE!}#_+{;2IZ$x!iX@%-Jf`^~?7dG5*l@?z%UHNmAnzfU}Gevy6uyURD8 zzxl}g^3>)k%e#LsncvPhDtC@&>7?(yF}J?H`^+93RI^1$`6T}&;QQm`;kluneOs57qE_I2gyNU>{1k2XEu0_w)y5lXF7jG6WG z*~Y&a$2#s^nQwfRwOjsIEMMR}%jupDxBH%6yeq$canmNRv;QhK|9|y&6W`LQ->;^B zU1pxvS2B|`&~n&$W2p^{Ob8-yx9NR$*k|EZ~y&qzBl>hq(s{_ zcUS(4-PUZ(@UML9x<5z%*v%;An;e`R;xBOa(Qo5Vr$s9{Ki!%;nSGW&sin#ucyTQi$2rxT6M0MlfSmVJiL|tCR?`6H~nMr z|1HuPN^Y)x?9*ZM`lWv9{P{iSv1_O>Va-?O{@$q5y^|3>_m ziZAb{X4}K_K!x!SVMRvpd>dre4MaNQOuQM69~*+0A{KIZJlmkKt3&rozP0N2axTwz z?jo9XU%vmZ`J>zKAY=bqW%`fMHFqoOowT_%ckJpp6=XSi@uZcy247A~S5}>2xZ&|j zGb7KvyzB2z0A719>=tv zS+vi6-@azfhWH%ILuVCE)zmKAlVe}M<(QI(QCr@3t7dHtvR zdcHoDQoCboQ@Y|=@$exKv7U#xoj(of#UUw6Knzx}OY?c~gdvXkesZ{O->`&m?0H1dv=L7mp* zH7qmN?2Xu+E4k=*=^Vv(>wfBli~kkQ?Uy{YV{yw2k6T~gh;EzttL)YP2k9X}sSn$G zpIY~xEM6Z|yKR!@rP+ZlZrip0{d8`Ax?Ekp{B!Bv`xeX#Rh2!%UmWRK+cs1T|o`SAjGSks`&jC#o6ql%|J1Z^!`xRtjQziLf4}=!`U&&T z1N&jH>wL@yb`*$xh0YIkxee(IAqOY?*>x)a`HWXJS@DHUO+oD4^SAyrx^|IlWs&&QQhC>{iGj=B@tf?NeUf3t_PqFO8$X<%oau94W!kLI zfdOHz&6c+pytY^^KWCLU!yjQ`hVw7)yPlMJ+V?}*n4zn#|Fr~^;oNM0|M zTlY5C-~YNmqsz^Eh3BJ<-|W1ne`~w1ghzk;s`-o;Bc_%(lhN%r>r#cT)8 zSxGY3ryY9i?Bnp|>yKHS9rcfbc2>Rq>?$Ag`=x-eqcu-QiBj{!AL9EJ9hVi=uG74o zW;8|h)1GpvGq=~Q`E9>tf-%=MiFdD;Z}(rc@$aOwWy^Q^r}Xc3o?tQ4;r5hIMa$X$ z?=0+@&C_5nea^dokM+~7sb0tIC-PpL?wqniWTyN7@3$Eb7cQOi?@GtEYT4WC-h|Kl zzP}>0nWMqqi1EYRtJS7|yZ)WG->Uuh`?TUU^IdBNr@WfEeE%)4|A~th&e?wNrUmnZ z@LlI;Zq(mfc;}_$JNFpQzZZ^eg|t1&7>QjG>(G4+v|#xs_qLd>`rESI{DqJ9S8#QS zKlNzsJgIE(Og;T^KyBsHw`bPxSkiLpw98Dt^S_1T=6Ft9!LrKhMdGVE&9e>@*FWcJ zC_2V_|NrUpFI@lcO5F11!b=^mJz*i&SFO8x`4#(DV}^6TOZQLu>F-&vxa!c?rKZdY zvx*}7T~s(5u021q-hV!WhB3pbNQ+;)OaCxbz1n2_M4H!*Tj~B@qvC~o&5u`9sWxz* zUcE9lq@uagA^d+e>))yeD*dk{&Rew}%ak`gA*6Xs;AwIG?C;u~LMg$$`LW$UuJ4+6 zGS6$uzY|YWj!rzla)2$Jp{B!_p~y4wc%p3ll#YM@?rHixZI%6A@&8n!aPQ{$KFNxA z=Yu&Dl=ocSe3!rOrn`Cn>-Q4(+QXZCZoNO)8j>owW3m1JWgG8)^?PhO1++dZ=By+` z?4PR}-pOX3y!%{wTIV;%6t2uq%*W!DD<#tyo(LUS_gOgC_*?4S<^TR!TxI-v%5M8r&z*lp z#=Pv4bpDrDZn?41sd}#C*Mkdvj(vm`*yif(I$O6c`=-8P*PKJ%n^v@JX4rP*@0<(v zGsW(h1xC&NtF!6T++Q~yxow>e8Pe%~le{9nqbKgRG1r`9mrpb7D7kGYb$V&iRHJpT z_)6mLpG=Jv&-V*{b3cU5Ve+>X{tQoe8uWEaXYIeh9(btY>YVP)q!TKeV;p#rOV-Ui#jX zsec8{1kbDZm$#o_vG}<(|Aj+Y;pWFvgP1BZ%Flk8_V$6$f&Wi=8rXgGDV?`zM>W@$21LuzLQx4_>^>9P&US3s(TgD8lo?P!e z9sB>&hY&7q!K2r|@+W?86}>toK5FF}dpn~!ySDTfc}s-+VM@<7-Sqrxf2>oiaMBz$ zo45eCblbC%456PVpP#*P{jn|S;lG`%H#|xP4G(n z?TCM#SYA;#&0XQ#;ofy5Q-bYu#&6GdIz-eLPh${snUh?cZZXk0 z#aWJN_rd-7 zTkP9d96Wo1zka?rU+q$bUig~wKO0_K*zT$jPJJ>x^O)`CaP_K^TLD(x=d0Q^I<22s z{+)C=lj`w-LRHl2<#_oY7JM1_=o-(grV%olGHcNQ$44W^v z4`1f_9-+&<@xJv86Rm3>EQM{kXKu+#``_~|^!=`xLQ9?2>q}j_>nXRA^WvWRTa(Vu zUt{mG`up61S5hIAgg*#Xa1vWPGzf!MSfAR@^5yeR;pzW-JNgzrXc5U?rfz@!__>OsHgA3h zhQ#=YK7IOa+b3})xhKMbQyi~uoV#*aZTb3n+$=w5pJI5C`1jr#=P4CePoMaD;`!{1 zd-?2ho-B7~C{g{;u}vet`txu5%WcZrdJ3#Q+y0w1twO__q1w29A%7c-!%W5i(|_;M z*DomZc~@xb!nXVRzWXn?#O#S(9ax9!|_)AWnyPR{7|sc4_! zv;A3uS*Op$=su%~)4!j-UfJ>7CsiZ(?RJ@bhv{Wo9@XV;JI!u)`@oXD&T`L1k4q|) z+t)AE%gp_MQfb$#cx{dCQ#kwCUJILjdoO+b!qMfg(}S;U-rjcNWQN?U*UO98y^|j;gkB|GhBgD7ND*pZduUmYs?W&8DZFTAc&2E1ccw(8j z|JA>*$7)|~dRX$h;;+%sTKPXcU$_%TqC{8zC* zaR>WP$GR*V$b|m3{S!(${T0Mdu>RnvVIeRM37Wh<+rixE#^7`Eu9xD?{D&EX$dS40YR;=jQ#spYL@|znt${Jd14qMy#%l7QMb7jY5_NABFxA&FHPTMATdU5wo{_BO( zn{}`KzH2K!LBaTERmYpW-4>hgUCMp=#W4L|v3o_x>$z33`-G-Qc`?+yy(L(3_U7`8 zY4grWK6kVGy>;bZ;nzQ&moCou^5QYJ#qN~ z_6N*FZ*9`$V`pIu_*bP{x8wQ!#^GP6^r3-BisN{_Mh?$H_M5f5*qgIjX9< z#=Z9sh}Cs{@@Da*d%}O0#qWFf{s?1i#=ke5-zrawvo7*^k=&g+xl?Q2)AVEeuGv}j z?ovN?>-SXsf5&I8lzVn2gDOf}V~+e5OZ)eA&--AtS+^dZeEY{$Y@@oq zt#etf{r*39%YIo;XAy0e@!xar*OSyMmUdoyO0169F8cCf&C@r&YZuR5G zUJS1%DCF0ao36bvIaB`L*8PmJw~E;gXnyHhXV;VDzL#1}>N&wJZtt=bv5$1G}pg}=p6frSt65#qx9Ut0m)mR?nMU z;ddi%{croFQFg2E8%y2qdD~SNJKtQ1A@2J*t-{^U>b`#7KJRcv;mpcC2Cv@F`FHXQ z=XA$1+kam#=jqw+^)3HxgAZYLf|kEm+N5e+Z9D$+%bx9zO|ShG{#Cw^b-QnYLhIY9 zDhyukw;~?b7Jp|o*;2hIZO`|*d+z=} z$p2Ecf17Qt4@1e^^NeamuI=qv*M9#!$Fpmur~kU|ueT;EJHMQHdhLo_bT)WwcFc_S|0@t2a&1NX$xYnLT;`&5vKM-CyjiV{2S% z;VX5+b-T*Cs=Tzgbdf2Bf(6RLKV)1S7XS2>n&2dVPHz3nZ^z2Rch=ssV1D4H$Ed^6 zaPG(Aym+fM)_adWt&Z(KZzlIFX#4BE*REfzwYt2>T5Wfk`~8BnBhfQmUazwEy=pd{ zF<`a-%=Ou)%e#->F|6mU-55FLooWB|sv}l`R)03t|5?yURTv@duXuMTE}Zz_I2%Ri_QJBIUj_|UH>hV{%&_-iTrg%(NFnNc`J`U zUuu)y_r`gBT=BML^4g3a%I|)a7G_B0OnCnFS5|yh^~BFtC-0wF^Kp;iKZkkGKC=9J znsa^v`xC}L40Q+gAKI@ZCp?oGbz9&AejJ-!E~tELuwq{DEc{K{z6%RqD7YRy5)klv zN}8PH;h7U1JTon)P8FNIGxYns4~I%tb-r}D%4u72pZ`jCnlXdfwLkSc^1JdZZ%^NM z*YE$2i?h!9^=-}SD`Y#s{Y+0e@Y1C>i7pINBpJ?rQ+{VWnK9to_IDS(S41cE&HPj~uSZqIXJ(i3%{8~U`ciNr>)PYB^DSbt``mn7 zRs1>aB|7j{q;q^I}+QB)Ed^_czc53#jTSLdWnCOU+;RY zXw0xHE`0m{>eCjx9$Z=X%KOyo?j3JFndv=zb9$k>hOp{HcKcsD_3!@t(xYH1mC7*Z z>p}gt+E+K%X}rHP+4y5+HOHsC;}Or_%vD_k;kLdb$WKpetI{Vr z8fodcd=B$W?R_@uVrxR*srqL;YxY_l&CC;IIq-aX-sKo^@g9zbbo61bLT~)(lu3JJ z&K*n9KJ}`5U(1wdK?YX?BR^&8X4R_~a6Vwo^J4fczrp-fRb6$3*4H;HRHxqgf0ON3 z#$Cmw8tbO)59EBXH?q~_<ig`8>*LgpTg8=xZ|v9M+xc(*d6}mIef;aU z$(>$WxnFL>_vQ1}&lEcF>i5#R)FREe>&m;AOlq_J*eV=%;`i0pg>TPy?6Lm#bE#Bq zUCJ!W+kd|v;QUo^R#7PZ`p24FX+ehcBF=>J*PlymcK*NUv+3{S9sj;eFJ_k%%DJlA z5PRHMiDBN?En8VOyavVOob}oD8RqNux7jG3Uv@+qyi(z5$NmI<$j+^gx{n#8nLY?q zaM-YbS0dru8Ygj#S@V0%nK^p9yKV?vwtstNjj70;@F}Gsz4?DN=daiFK5)~&NJB$s z(W+BjY$xq^>}ol5>hp>%t2Jh3-1a}}yz-kh!)@W2Hm3JG7=HW^zvi)7@VfGe%(;)| z7#D0j@Ip+_clR9c>{V~CYA`=&?lv=g_^cuPTg{)X*+&ihj@PK&Ih*)s;r8FDE=p4B zn>uzr@HP0p@A*${&1s#cX?%{StO7$Eqx+vu)VR63g)?hf)I#S!^^<=sp3b;o(XMH~ zY_XnC%^ zwe!?IIVJ5m_Y^%Ao_YS{@T&OZ&$HgTytiDOy~w6yf4kVt-;+NH{H;F2kg>qO>dD=; z?w>QXroRpSo`1~l%ZKL$ew@A4i7V6oH#awDo-e-a`+DN!w|V}{Rc{-gNLra1S@E9# zQrym2hho0vT(vvL@Z+1-{9luQYd;kgmGepe_R1yw>zfldO@vqGKd{!+jko(L* z?!wE0bp6-zbKPQv=NQkE)7MZ}WnOUZ->7{w zH{9Qj7WSTgF1w{s{Xp>h$F)C%q0s*a7~&YnuMp=iU~^Do&}y;%`Fks`M@sO&50{U; z-Ed3mRm_(DrrrEcC$>0GZm)l)?7rPv?04%n^ZBb*d1+}(NDY+U_HTu-^@<(mca~*t zWBKVP^Pr94hlDVLbY%SH=W))9_AGgA`1Sq$%hwh!+OzVoT@OdY^uM3oZ&j$Yzc<|< zU!}6>XZB2n9RUIiPZQVKJ2O4tUevQ9`Cn1pUEyTV7`w?43CmTxH~*-8TahTaHf7UI z?)y2*7j(8M z)D+3ZZ>g{M@^;uJ%uxF7{kf;RrH_|w-}tsmXwS1}*;5!V>}1(cR_pe++vrL7{8Fyo z^h4$U_1^kSmXh66vZrVY!?nKs{|wDp9Atm~%8I{sGvl~Iw#p@uyRr-7%U!4Jil_uqFdTOU!|IDPG|U1R15BdUs$kzxt_e= z=40PJ&%C2*)YG}9L5Vr3E_3O_Utc*IGIy$)xCw~tz2Y4#$-sN^ z*U@=*=>^@-uXH5;PMdJ>i+T8kV_RZg^S9_du2f;zb?3cbypJHm-WTWR)~)#Nt(#x| z`SY^p}+}DmtooF_>R3 zyuV!f#pAE-Z(rw%FgW#%mf4t}XyZgeQn~&dGsmF^<3B8!vUw?7MkI%Oc2d_*&9%0$? zchA=dIp5mH?7jP=kKSbZt#P%Qb8ya*O>)bR?#hhFdi|p2T*UVGE*sPSMbFb z)1tkS<0D>O{nJu&|95jB=L7$}llJ%er(67+Je_B8wmV1Dmd}N+_r$-P&a5tdcHTS7 z{~^1+HwDjS-?&w;>TmU}Y3EW`e|e8 z>fe=bAFlN-emQC3UDH_oU?YZqSu6Z^J&D!3|M$V7-nLKIrQ_c$S2$kQ)m<{Hc`M5Y z^R~yUzdEi&;XZDRPf84G5w+jGq}D}?Ds z_FYhBzW#MlZjXA^FYZdmxO+$ZFNnY3{&G~TdF3N#<^SB!F7N^Ne_t5(T={FmQv+H^ z-@t#s{Tk!#@BNTg*f$271JBcs97h~!b6|PJfheXMi4H*%XZ@ZNvSIQep&(6-Z68m4 z__(Uzhel&p7nhcn)~An|kB=Yn@(+s55D6`NwYp|OZl3Mu)IFVf91Y8j7y~5c>Hpnj zr|x0YWU;(_&-c@HRgb!LXBB?oX!vQCv?%-kyjxW)4%uuD?2H%QSn=<#5p`{8v(R-_ z6x390sGS_1QD89FTBB9Z#&qgAyQRXV{ym`_#(vE^Oir!RF?sOt{7OHaxUK$fEC&pI z7((u+r|mr^$zaL7_-*&!V;1`l&HR~G)Mj`6aclmzi?i+DeyqCp?po!SsjD?jRBn`N z>?%GO^(*Of;PO)6B4>t}gDeh<3(p8J^gh}4v(sC1=Un4PV{oJR=hBB2Zl5`pyq?F= z;P%NtiQ!x#(}L};sq4saA)=gPtHz#(H^}ZMGYhJIAW?FFX$1zEU{nuoVgVvni zFSLKZuWz2C-URM1O{ET^_KtEB*uOCD;2>@YyYavg(D6Q;!X2+ee+wU3`z&AmsWIb* zkfKZ{!}8GVvrM}hKprTYJ0@5q1t^5TZ}EupndA;ssq?^~U{f49cw?EYFG7F(-Q z4PX1k?YDyt@_+ba|H!B9)xT{7__KZ&2XaWn&W@xFkayP zx%&BX^MCO(HY^F3`}O&3=9laJ*DTlizpwQFyZZih^)b8iR%L!C^X?1n z^(LnnW~6HP2U=a#U|w*+`fE+h_02ENPc~T^oo(?rc|E(BRNwP;_SgUYy;}F0&0Lbf z{sCwTEXCzsZNWpe^-mQ~Y}_TuFmq3~$-eEMyi#u0ro0l^c6Xj!ZupC)xc}}mD#V{T z1;y@t&vLdVed@cvMgLjtWa~OP*Bx9G{@gi*_wVOFTfe;hRx8LN+;nC3DeEz_GRK|q+H@P|K>>DH|w6Q*aM-F1cKGRHc-r58TcXuU2A z+x%+!CK36s(Gx!Pa5Q+aIcTcO{}%86{@7@r_RKTO%VkdMFAhAfdvWUYI5r1I2AM-F z4${p>FD`BWDLJvj#WU>bhYx#X@;$b@{QCCpv+UzraW{<_PL=z7Q_r9NclWktOa5&q zUX(sx()exr75yn|65g*Vo767I7;ut7L*C4C|M&c7LILU{e%Zl(-Lk0pMg1p#-u@kYSO3(3vNBC(?RT4}KNsb_{dcm(=GhRV-ifxa zs=sJ5moeau4&T+!{_$mOXQi&6uZsPezut0w;MS$*s$5I=7cFGn;+x7a<#p&<_v>Xl zSvE{!40v8w{^^2pz1FthO}fkrrvE*8`|5A?=Kd;iq*s z_x)NE_vP1C6%4FuS1)kzwQ6(DQc? z1DW6kGUzZ9QXV`Me zdqSbyY_kwsmCj9jn>rq^t^4zM*F-NfhvnyXY&2gz;aqL$&ft1CmIE7oiawRa6iYJH zUgx)*zocy9mY*NJW2Z0QvcCR%delzy%d2ZA{e3m}>xs~$1)25#CvKBDT`F}vrp@T> zFZPnm=W5Ik61V>@czHqY%X?|J%#@GwL#toTRNZfV)<3_ts_er%`C}I>|4y3w>&}#E z*{3y@&)t8sZtu?X7R(O{XMJtlDEmr?!LoRsGV_9;KWCq2kZ=i~cXhJd^^JEY`h;DZ zyx!V!Pvu>WU2}{pcga<6?#lSI`u@vrs}zo}d~YpZ{KG3#3UNsGPz z7#><0SZj6h&~5e1Uzen}s|qn3-SzdEu9%M3^uGF^(N?pfm#tP$`|f|oytab>*YPtG zr7XL+_deHIN)#q)zxOXr3cb@1>mW!8^d zsCeL=b)d`SxQprwBwr>vuiLJ|v_S4-XwHeJIlHC%pH!*-H>{oXV)JeFtZ$cP|NZb{ zm}8zTGuK+f)%e<6?rWE(NB32lzJLF}Op(_wcl}Fl76*1alOu9hESl>+F!KFk*v&-5 zoFCF2{~ZS#uk5c?+7a*be1l+*1@jF1TPtVokK}By5j_6GMt{rf7`d&bUqdF$_ct{) z_0@YnK}wBb+A{;jf+u3fl!UT@(eu5HPAvtOPMjo)3~u~h#3-T-G7(ZAi7E;-MCa%Pg=CqdOs zyYxmcCqW=FC zpXXIR-~7f(`HK}5AJcx_&u6clwtRJs?N(bM2Hq!yHSbJk?L03o$snFeD}+FH@SA^@n}goV1MH-|KcA)c*N@;%Q6!(whcnrCQ!{IW3%L_gavl{$71k+Mc~p z-|KeXW8L1j{Nvxb#H z|N8mtHQ(NTHvho=gY^$n9ix5Y{2w;W=Z&$R?PZc>)42OBJdxo=Ys~a} zwQ{^~r>&TIsodJ=#kI=)JLk41+={o~Wxm(ouaDZsj9meGFH#>#U)^o2`)jjV_I!q& zk)P`pzAsO!k_kWc{P=IZgqc~J3v2gT_Hrh^p8Ma`v?b2Cp7Wx)X5X~GZ<&N5Wxn=3-+%Mik!5>l)zzM5&^Q+T z^MLEDh4=ns^6&j|w(P7$(fp@3W0xIjmA?Gqo&U9sVO7V(6Yn>5yk51v>B!CMb55JC zT%GyK{oHEB^nMnH=C3~%vwS#lZ!S;n_x{gyOH-|leNN{dtqm^uSYSBW^8crcQFrUU za5U`h6TkFxz3%0`@$b47s{e(yzo~qXV(44*)4IP({ntzzgH{(c$Lo_`2F_P5!K0zjD{K@5g#;*HtBOef8}s ze|20lc(!M)*zf;;zC0{>{KC$!_T;hO``;`-zW>gu?D>L)rJ8?VIn()V=ijx@GG1 z)-}I_@BNt9_jGFIl=*RL?l%`IICs4%RN6gDaNk|KLI&H4i!Vi_ba;;b3@~#4m)-jC zPw$t&b?2vlzrQO{B-Uul?$0hew&px9ob~nK`nFFe3MMmNxcyTio#9WI@jeadyp-MN zH@xM#vtn&(YvRXOCzZ`6!Z!7x(>K)~}}rJnw#F ziQ{>Ft#R6)uQ9znM_cu`%PqBjzW%bT|C#;Xzcs49FEcb*Q_X(&`O~BM+m>H`^MCEd z6W%@RXERPH{rV<-+KYSdSJ%EgxqIo6@T%XvUpGW;`d5*Ce#iXOWzF&z)L#g{;jCb) zVX-@8|Kj*_&@#3Uf}n*cc8@*_+3737&$d84YnSyn^EaUbtK?6pY%qUr8S2WAbFPrJ zVW#YQec^xWB(L_LdvSGUC&M|_KM|~VFuW)`EdAlx#y>_@`R|Oh)^4e| zBW}#%u=#agn$q2O>C0bFT6m=B)6OR!`F9&TOG}?lz3@-?Xi3ZY zw~G%=6))cO>#ywID1A)TYb}dI`D@!>r>?eD ztAE?uw)umm>8nb)<;6SSo|+Y>YF7)Sde@ zZI*y9^Q7AscQyxkyx4P3@z}gSuZrr{-N@Xt?3kx9i-T=tl@8;ZR=a8?hE>PSwdU%i zuG)5YaplsS{?I8B!UvZ;wNP`Z-WFSZGIQ?F_0Qf++-sff?a;l^_1m$ib9XdO-R55O zyF{(%UGm@Qzo&nEW!h$?d}5vVwxyTfAOEy-O_?cg%B1}YdEZ}2EPv4#c+GxiTH(3` z+uE{|W~~Mqn;7TmtlRK1o_25P$ac2Yn z=wM!1|9i?y*+2I7!M}oyt_KvnO5o}eQ?>bPFTd4BPwLv_e-?!st}n57WVv9?BKcwR z*55D1)mWy5ME;oeEH*#X*HlzYB*1oZ%o-hz_s9GD`<8re`?6@AtgGbhDy?U0Vqbqx zz3{FlX8UW-Z6QGsfoxO1NgeP1xZ_aK?8?9Q`j$^&xOTGOm~j3V=M-6C$=5TsCwbXv z^BObM<-V#6|GEFz($4jEtJ9mWt8QAqv>?s$YoaPc-SO#Lewn?WR>-C3U0d%Q&;989 z6!W@-NB)ZCOOpgX{)m>_KgH^}yA>};?dj`VJ{Q-<-K~4ipZwxbaPZt;LM%(>eXqZk z@=I1o#^>}qOMgXmOWr#yyc2(Z-0zcQwCTDh^W>NR(=v@2?j4b22!C_7Nc(*3`8dC~ zGbUs_lQ<#C@%6)}Z6E)>*qG^jwj}YD9HY0ftC*$U!M9oRzIXq9=Ur^coM3*|#+B`W zeG!|(;*YEg&wh>A@J`@tGh`4+x~T`MxF0ApML*({~Yi1F9q|D`fpd3*E<)xZ*tuK#O-(MuGtoC zbUF}PUOMMv5lcG5mC5JNJDT@nC zcJGm z*|sj>S&*Q{@GH4y?^piUH)qPtt}9zC`2ULikM8SBr&2sY~^xuN{6V=E-1k>;BX4F%Hc;LyD4Rn*Nj@%s&0n zp{#SAO|LOS-RkQ7a&{hn4U`zZB`_rfzbY1p{>Y@}I5&9`%hRBpS!hptb*ZS?JBzxp%#Dc(QzOf{aq-nHAmZtK*0PlFy6{S!<)xaH?YZ%xHx zGC!|uwZAF0P0?%D{F|E>?^$BG{}jss^ST?U*VUDo7HnnNP_~zMqyEmg^51LI{ddgY zzwJZw-{k#Ue)0eP^8dLp_~@b=e?BVwVf@1gK7vyJ4;Vf|sdpFu#iB()rq!Q6y}hM4Pi}Xb%v}2|+h0{ap8oy(?}=h- zZ!V4WFEABm0QX}(>dyc9ac$zC;`-oJ1`)Q|fdOvoYxj4H<#~Pfl+%7c|IkyD$7>&L z{HuK`r|Z(peW$`x{{MR8FKqJHig(dvf!CGUSL3Sw&3^mkS*h|&h8uTZ>UlDh#FX4S zAE2lG=j0nslSfnhc$JDcC*5$J^YgvI^nBAz%XRzXAE_}fn6vQnpPna~E(~veGNd!) zXjO+T%b0t=LT$yr?x(sP9=(MekM8$ZZ+fv&e_KFUVCyRH+Dad(8?D9+MQ;AnA20iE z$*l1GvBj79_dmP{@!jTe+_*2CS^g{>f_(5F+Z?5$B?nWUvhoi+Zku$>uS0x^8?VieWw5OIxnhlToGKT_$u0W zubA1VXa3bMu0GwJac#%GFIScx=9#}aongz`<55f&w_et%GC$ZnhcUp^e&@foTho&j z&VRZhEq~sd)1mGHf9;>mSsdUwstFmIf5mSFF&$uk!2H26iunWV+--~l`5BN-g;lTv zZRwC|WA|cnXjk-X&H7jTe9v4hri9P^`JqdyUR_shjGJS)?Bu3@mIu6lYpveUGw*Mb zGU!~V`y$e}Es9pGU%hlslhdYxm+|?(MVHp)&$DTHH&2bD`kt)uvpT=m-(;V+%e=mz z&R})#ds*Gt!g^=UhSD=Vs~`20Of}u=ldx*x-I=UgDoz_l?K5t65l!1#vnRISj&Z{z z&W0GK2-WiZ-=g2|mmf^nRs2bTi#M#fXU6)^iXHXUo47;|-Kf$_)Hx`uAjSAVgm zt7Y4lv25`CS*gabD?Z=(yQiIfZAJO7%Rd;sA`?D}Gv1TCc~sPE+LrPiA*;-*Zt83H z)g>vddi_v=p(^fw@8aJV-U_n?6z$fywmpHDG2}(WdUo+iOT)fA-M8P~_l5uVp10Xu zAsWx-#D}?_*SqUBKiB4v?)R$8SKixOm1=bU+%4zDnPANru)8i;wZZm;@2RWCi~-jB zrg$g$sN8<{((cx~xNUcR;&v7OFOvBhDPZ4v=a>5N;0lipxAGR9xttAs|6DcS?w@Df zk=Fm-f1}{SbxGH^oL;TVwest}^JYPk>2Ifgjwn0-6Li4Tv%12Et@+zQi&;*uU-P)@ z(%p66t%Mn5KMVggZ>v37`RGmj@3udR^_|QX){kYLFjg{vc61Ddb3g0o>%!P|JQvvC4WwJ;@|Vrm6g}e(5w5Ftd-W( zYtxkNwUeblE}cOpaqp9-RZ?2~Hs_PRU%K~Oee2?4_R@tH_gZV;yxKG~cG~f3txe)` z7Lh*O*JQW7T6N>1+Z}(ybCG+kw2sWXH}}!X=p-KD;>A-GKUthkOiQ#}`dNnW`IJct z9-V7qdM)=YTF|>=-m_QwYBp2Uio^DSCSWhT>zpDX>^Lz|an4I0f!9qdx;j^|KD|06 zIOyOf?d6AK)P7d$rS7t|-5+|=Kc#5zvo~>E7mY3LCRrVE3*wj@*?RBYX{}{*eU99% z(&^vC6&lGG{h+Qo`~2C${YkrH#J1N@uQ1Bp-PBjO}MLj~W`i^Bq$|LmDo`u5P}AkD3{CR4+&U*bGBZ)e5nK(#7vp*?RK z>LgG3PZW5<{8QqF_?Ko?$kB*7=S03S*d)j{*dCBu!ty{qk^ca5CU1v0Xshl6M%>47 zJ4zp7j%IUM`S+joc71C%L&vQmcUDf1R}<8DV!yK@Q0&J|eX|R%Y_&c$)LeeDbIqC_ zFE1BO*Y|xtUU2++eMPY3^iJo!)dA1*vNa#v{Z{UDy68u#K&Z<6to?1`$QSp@g+a0HJy4G8G9=z+9&bBJq&dYYcTHg1^K?@ou{PfTNz3=DT z&5U)YZ!);)9hD_5A{S*-d`_nFu1ND3t-9d3 zj~5+!QNMlu`K7MO6$cL3Y~ng?A^pJZR*}l>f37np+GJ(vhDt*K@6-h5Tn1_ta#+Jks%}Ippd_`Kw3DzGc<9y*^qx&Fr`P3C5xZxdVK-^ERQ= zwYJ#GY)E5xGME3+f0oM;iF1Chy!-UWdXY={YYq!dJyWmcmL$9-ewO95bCMGdCA0ne zc<)r~mw#G;e%FuvD4N7xxbuFHP-^|x`{|Zeci(65zq&RtZs$uIq36pi=KXw={_A~L z?x`OWZ&t6^^I9@Q{N}y)znPv4jCZw6n8EK~kV^Ipr}gZ~ohH`qVm zf9$|e^N(GQxxexFf#e5EI z=Q}x0{HXMOee;HEE}tdOAK5RS-jm67E_(9U$_Flr>CAT=e*25ud>Wj*F(5EeFfwb^ z-bv9lAr^OSDmCuf=DJKi8(#9~VAuVZFVEKnK9iohwYTf{-1DD#ww<>R_`?5LU}f3t zd+!v|Pe@j=Su>M101ny%104^)U}2GPn&HGAd9|#KQ9r-lS@?p%)$M3NfYaxcC($+M zkH-8mk1DtlbtNz=(s}-xyX#Y!b#!$XU%Di;{<;08c&)vk+CQ(zZns!J|LeELufO{* zZ!H!NF7Rb-6-^DuTwhps)wuq(<+1Pj=N$e`s8{%5{X+4JK-G)?JA}(PtXpIc@il_x zLx}6zGO$On@|8U0Y3OUc5fp87`1Gm=XK(kdweb9S^{2=jqYK9jCmT{c zH+Ks&>|AA(|2V(2{9Ee;Rw0ju76vw#1FQn&G5Z7y?;ogTmHF$E>LQ!qazIivo#i^C z?DUz1jt4}q6dr6Xbl4vl$-=_oBJ|C{Y*WdlyZ3i~|F-g7OAE`Txx23ZoI2^%?asni2zy9dpW zMA$y{|2f|NjQMlp&jU3Hc2n4&FjhLqfmXa@rxIMAHGY+5`0S8>_UnqR{71eV4R?P& zuYFm3Am96^#`!f>Hf8;ihkvWwesNKM$D3Uizkl!VZS9_(`$;n0f40nV`~MFrZVDF{ zKUI5g^~C%M+krrDao6)ZWRuQr`T3VubM4B_jhuHshYL&dS%?Vlu?k>+b->~Qqa3lQ zaocByxl#<>j9X62PIo^(=kH>}v_lij7d>U4W18wz^ZKs)le2=we;;e-^*!3ZNN_{O zE^C#!&$eg$(GL54dz$vYTn-a+hQ6K8e?{27Hr$wZr%#GOSVg#vbMad>p3>|)%cKIf z|H=Jl#8=V4P83?;CO6}6`Saydc`qwwE?F9Pxl}oJdr|eTOVY`2c5q&tu`9dS{?k96 zt6u}#&-Fk4|Lg$o?<+a{!j1Z|MX7WC^~N8Wv3p&wXtn+B%9z&y`D@pepT8e<|3QEK zyzn0@zJA{SF~dfx|Le)e#}^uCp{YiD_!c9?iw<`i#N^v1s% z7xQ&5x5=8Gm{tCHgS3#v??v~IEkE}=uw+TF&H7oNTS_b@OGJmnw@$FJ|MzOW+&*); zpB?=_XY~Kv!S~+&jQca?&l7*1s7bLil2_&bvFFHhSG)C}E0>2sq^^7ap8^>f_R<8I z4-EVypaa`JIxODFl#q2t)4DUe!1nLH?Bp{?G%wCD%8rm?(6|1Ydict#XNl%+4=U4Z zl=J@GU7z%HU4QSr!r-jn^wO2(zYSmLS7tqsKYsXQ#=q35RZm_gvGSBI;JeaTc!1f4 z7!;7sKSi4%Z%y{<*88(JR2BNfl@*tq^IgrrcQ|#4IYZp`5BDOrt=g?pej;wI{nd~2 z^8a}B#8pMFx$#-@aDj=f3KNGy0|RlyhFT$waE6?HU$%ToSu&M<_H?nl>B|}CeV&og zGxx%sxe|;1N_O%#?BDtE+l~kI>$>IRD~olacP>ksR^dC(KJ>)Y#6_4%T&)qJ|&t*pMbY~QKr_AXzqxV-!*bAQ&4;97MiaPl=a0qa5!iMtLwx?Epx;(&Pk)syV`~KgK*ijMr zKl|p7kF#xai)#Mxp6|-ttMov9|Nq%P?uhS`;6GDa^rcs7`nSTzzs(C2?!>i!d|r{l z^eWJHTbn_C#=pIlS`JC#vBg$e8h_ht|U^Gr{S{F?nt3G04J#q__5 zl)e0ZpOV#cTf0Szvpv3NsH|c5F&@#Xs4uRi?=KG!Rq zw?{MVoaDUAmieo%KdcmRU|?h+j%eH^m~p1^J!|dDNmBoVmuK(FTk?8Wj{oleza*^l zVoa8ulf3lz_qE;gq>alZ;>Z<+1Y9-2bm%iXYz`x3Anrrr+u*|JN0ASCeb+ z@k{iB!>r2w>E94p`}IclGv}Z2f2RI<^3RihLiXQRpE>{R`Df{$H~+l(C#TNL{xqb# z%DG;dP?p7@<8mYB*Y^E_8~AQ7zOK`m`8{5IZgF=ggZt8284kVZ&GqwZ4+lS9a5p{2 zH~+TT|C>)&?>c>KKldfg`u0Z^vb(;&vG|_req>4E;`X;&YksEJcl6i3niFAXZz^qO z)%NBG@6p%yXZ`y4=j)fF0Y49ZEUo#uu>R$1si%yOt1~|F@Bb*h|D*K$PnrJ|=J5Y$ z0HIa!Js%b2KY`J&Jx89aA{VaUqSip@lf!?mhLv-?*FW!j@GIy2mLIPqOcT9IeD3R3 zmS=o>f7buD`Mp11SPx(OVRnW8&r8)wv^US1(UW^jfcPm@$i+|LX#|p7vi) zIrr)RyVN}Y=S&bf%l?e{^Fl;D1rADht%b}pxb(?kD^tR^YTxzC^>!*A>ywr4&D7 z{OW?K`!uF6T6?oB{QRpKh2P~DC2wzDWLWja!TDy`oA;OHwtCk*ndSN?OA>Fq5KEB0Su`SDdTit~ed_#Khs^Q+R<%=rGLV_l$g(H^gfxko>K`|R2B zvab8%_86(xYVTwo zr@fUF4rY$o99*Q#ThuIl+pKhdXR`az?f1XlnPHH2rR{I=?VRe1wWlAy-}h;=hSWE+ zt@E4r+o#`JQt|vVU*B}wkAcy9`ll~HZuc&}eufm&^_*>j1=-5$96w{ToH25*sk~dqu!>E2{t120tdnMREC{_{0#mx?HC0G zmehT~?el>-!umRY0^+;^pO|W#j^DAoF?g|T_%c)2SpaX(ZDD$_!*zeZsr7sD#mD?Q zJSVFiTd_qdVPA;8LH<+be;007pPwTHDi*g_3MX9rQ66S>^?mE~zbkh(&%XWNT&B)p z&+8M-$)9#yJUjp9CH-~2+T3z~_3vx?>&~f93qHU7y|Rt$ht}z_;>&BktclqBIyw1n zi{#2RuR`s=9sjsu^7$)^t3vuUXKnNRXAsvL{`hLe)77tJS)fJYr$k3kcLMBVP>yc= z8GzZTXq@%5u~C$vczMa*^~djhJpSTEoLu(ubGpSxe-u7W{?o!~xN7z0JAM`N-@eAJ zmpp*vW7|A!;>eJ^CBSEt!lUGTE~x^8*n{s|lAKV`WalgP<$6O<6he{#CT3T8VK zqFeP1>{)LbpK&$xFDcF|o|}ERpn7qBuFsC2mm+5SvEDJR%i1izF8Rv~3G1qu9^d7k zWv^bH8m5GBrlWpk}E_uh{C+WFq4(CdNj&NF_? zrR|>YP)<7NHm~}_dGYmcugd>CAF=ntuZo0!mlv;Bo*T5&_tnX|Wy+R3k43^`u7<8+ zlzSpxXG(&9+io)VE@IrEFB(<3?7rE~cM)4n)b9MU-&l3b?xK0t9k<^;yDoJ#%;mVf!`@_pC5lIV-er3}?g_sY)q+x+{I zv;5R;+ujAO`SyLXc3$V_%PR}J)poX9&+9(6d;R|BNBOOuzMrnQQ|p}Ha{jnoS!dIJ zdv{G`X5T+;{*q9Je$Ukmd6}_qCrAl!%jMhrF_doo_;ibYdhP#B5yh{kZme2fyEwf) zR_OG%RqDTAS8Sd9|H|sB(Dg6>HdZcMTQvLe(da!#qls#L8}!J{D1Nm4()x?t*S3^s zuIm!K&USmT_F81Ic~ z%)hkb;@R|@H^fhemmc4`^5T2*%+|f~@rA`dOPOZ9yLJA1;v4^szwWuJ%WjSP9RKmh z@qe%RFLTv#v)lfCCjb9+ChI}xZ?~5IG-luToO`2=DSz1Xv;S*0{y)mqqF?=}Y0}Y6 zQ?pOC9pes4ethVtc2bEIpKY?*(OENpZ}W&PgXS9kxZG4)OVcvbE59BS0^1o^Cvo$&YechH<_pIlCZ+Z4v zM4MyZcWry`^P4Sd*Z)XSi8uRSvw691PyF1EyZ$h5{Fm8a{{J)o*P7VV?|b^*g>Ec* zm&nW;l^bO5>v-#a<0jpfPIkFS?pFsZKm#1iKh^#_^?}-JKN|QavG0lhRAbh zd+)I~l0OA$XCgN(6!@>`@Q3g=gsO*R3219?S-bA|{ZFsAFeQYqxm);s+pYJG#*f^- z|MqQ{mr&pT$Mfa3jz?SezW;klHS_AetC_1UCofsQ{ZGZ*pTE+V1~a~&9QH0+#{K{4 z?U$2F?bpn|f8%r6x;UZ5)9#4zzxlc4#cP?(SNp#g#GOC(?fCipO4|qDPaG4>+wqa- zJP93C2L3B2nO~bTOq=_vnJ+*($Nbl|qd#Wr_s%N}PP)5fX8#Vyb$QI2BQifs3AfRl z>-XcEhTqoRTYrb!+*?@vUdZ0>Y>RVXgKT#A@fX$k9ih8rXWe)o@HSrh%IO1>7OXt? zHeYM?H>vmEu7Aw>b^3>C-Oua?B;9yE4WgV0IBD2m-=tD z_)W^H?{EKgs&IaM*}pj(dbdfho__pCw0{5A$?2}|TQbjiOqNp#6u z{(1Db=X>?`ub;U;ul;$gCVQXheKr0Q(x2M)DCTdu`2P13^Pj$TlkbBmU%3e&#@ejp z?{(iE{!BR6d0*?<#ed$GOP}?Y+_k$co86^$;B=7i1HFsJby2tX&wIssrN4ghcJpI* zN_|V-e_8Ru?`-|m=!tcAazpe>pLVBzyrvibD*S(6|KrK4H_v@`JZpZh`s3?AOzVsp z?H(}OomhOZ<{UW4i0asaI+Fp%YYa9pC0O~TsuxPfm#>Kud;GtuvShj1foEO~xqqr& zmDwy>u6|5spP}i$v%Om{f6Mq?wNg6%_vB^XkFW0V+8HRj<$ukY^j9}5%=#+9?Nq`o z+63uJh51Yt<(g?9-tM})GcB^mdpUEQd12bGe7DULm&C^V$M(4|-mdPp{PMqbb9cFy z_|KhP_~`ci4bvL0JgvAnzpLSKps&g+M_Un=9`?rzE1IY3zjCx)(QYI4Vb=3V`KqEbG=M*94*%^%MY8hzPtw=zM+j6sZf=i>6%p1of;d2nx;x_nLVxpmXb z*1a{T%aPf0ea#Hp+@hF@oAZ-?zIr$9?fItI{HGf&Rn`l z{(9*})GmWv>2HMZ20zRBRCoLC0ZB*R&1!bS^FL}cd?v233oR8KW>+o9Vdx1t@Up&E z`9sy6McRv!ul{{{s&wz%#ZjNE%IBIHp0oV6Gxc!nMu`_&x!?DG|NHy=<5{iWb1whY z{Py_Ab6FXE+miXuW-VE7_j-5XP2O&^UGj6a-}S9~T7GoZUH-m%8-v|aYJ0Bi`o7C; z*?F1p}5MplXdwHhlSI&-P7(!CBOd_ zyk@S2ah2LzlM5%d^~T-T)UOZP^H8!s)9mh3{jRAD_CK5d_udv;F8brr|5%_omAm zn5*?m|6L%zH}B#ji;vpVr>qv_+qW_KY?nmo|Fs+QKAm}S?`7b{>laObq{S-}JA?;P zccsN)aTKG$rTgFAep$btSR1=0$Nbqld)M%&yLoS~R9-Yrdt_F5ck;2`&h`7Bw{A?h zo;ln0jVtqmL%*jTFWr7u`gGXZ&evjkeM_~k=M>p@r|o~V|Kv+cu`@H}exIAS?_%5j zgZ_U`cKvpYL|%!`^?sbGa%WoNWKTIzP6qcFtTs%RL|Nr84_ZiOWC!>gmfV z`?(jFe`$%BJL~_o=&$(_l~b%Aesup+A^pSE`kbngZ+oxqp-`;!p&DT8nlgIZb zy#JbO|M>35u=mGyf3&Ok7tH_4(UxaPz~h4z268>^umbhNzfN$GN}$ADkY<;$j$wwi z==RO8&zYW1`XYPX<@hc3q`OaI7pMQ}J9))3^zfO)`z>c5`P>VLK`zJ6KLy^j4|=Q`2y*}bVU#8!m zFzfH6>$9fo-kI-abu~ZS>T3S;RjN;4znr(R{7c`w8B+f*Dcd$3uikO~{lC8~AHwpF zMF+G0nH;c!{p$qI8S*{sb|)4)+C2r=q$gNFLzD{rY(K#j>JNO;p0NA7!GiS@@;f6Usm?euTeeUG$3=+n;$=i6)S zRAAFjsI6@<4>Vqy{QZ0V@{HuwuWo*AwkTN>E4lbmS3|7#<;>FGRg25tOvws8aPA`W zXNTS$qO1Ruu8E6U_wBlMmD8HJyWH2zHG1y2UfcKa);smTpYHe|C{J2_%E15OfLK++ z_A3lCst(3%YjAkZ{QbxZ)$Oj=KUFVUUmWtKXSUGZWVNOLFTE^@F46RRe|uwE<*$6# zn_sRQ=N*4B)57+e-#yh|ZoSzT<0_+w9FYf)+&4Z{yKv(#^ZmEp)3-RqD6i$1zV5Q7 zVs8FC_wcC9^_w%;bo@5Xp7s8hTd%$}WA*W6Z3h;8TvvQ%!-qF-;skr&O-(%VN9;Gw;t!e_pE5 z#1j|DLsAFK&M@!ZZ*R)5ENo`YN#TueyADkI&~b0;#fef(yX7Kc;>t_x1$s+YFIul{ z%2Zb3>i?gs@n}|KW#*|f+t>eyi#n(u|LJY-JkytkmtNInhr51Rw|ZT7u)y+A_Uf)s z_T%paKr=%Uwi|Owq<;L=^0={%Bj@DD;Qz<=e@xmV!t&$LpF~85f~bLEu;U$WKW)rn zJy7x>=y~ML%E)yL8PysUB_h0yN3&{IDjFR0J=>VM^*~DJzI*qIYPUVoIeYZ&-o?k& zAIN5EPxUX1m1(|W5-}%jN5+@ex?#dH=9X2`bN_0aSlKxj)?BIn*UkKO$-E!)`F||< z#jOJAPTD;={3TAOcHhbNniF6I8t=o}w*;ql1^z9*avAfOEZ%-Rz%tGC-7X<3J_`x? zKd>T>s9_0+;s9fQ&}`DXJ0-ED1&KTg+unrgMb_;F?+wBz4X8PD~qDuW-9{{Mw$>ElLfjq7c`_8eqU;k z&G_&ATw`0W`{tUf%^wf&|Cw?7Ftlu2@N2UqJp3P>*8oo+K$bFq#vY;L+lUEe=+cG- zY?TMN8kn_CIbSL@H7Pu>FklMFYYiCX9yC@}Er?+>;J>iSxH`c-SA6cRiWU7{55S`; zpi~gS67?D3m^19poUt#efVv7!t?-q*@%R1y@H5^=|2^4N(%W8TAcqJTczh9LEO;iD zVIs{C{6F3@NjkH?`;e~wOYYkhE7%`5@(VHAnaIzOf7<--Wdr{c=bsUF)B2w#gD65v zK)}vyob{x!k?p{&a;>O^8&3IKJP3H=LDGaaB<&txwpqX!@HqME#9n4TDQ?p+B1ilY zRkA~L<${gJ@7M2NufMg)?9%_3#|!v+n2BC7g0!|ILzw@~JSm3Ry4@>94Z4b_Jm0FA z`*@*T54+upYh6!4(?NGm!BO&>%O#H8T!!D+1+S#4{T7p8mAq$+^(m z6-$0v{ayd+NhqkjCc$5Gp#5mP8H$+(*oUQ{MF%n!u-ayVKjWO`FIG9Qmt8Ci+)%Ni zU+a)0|1oCy4~p`i5jdi?z3h+?g;)AfKOi%n6ZpIBISfgOx2&n`v$Pq^ zq!~7^hz&n0z=Rm4pB*+bCEQw?WO!(g#?ow?E6pDXX~AlR z>34_Z2O{2qWlT(PmA`3pyeo}n7C_}J!rt(&y zUB?{BNDiR5y&xthk->1Lx9jJDo9j3p1d48|3gBmDe0;D%gDGy`3ihuH&mZj2kkZYxt|q*_WlVVB5z4{-ZmLo$N|k&BDxcHPQGF)2O4HaDnW@{rkBACZm`60UMStFq{L^jL@J}qU^U3oJ?tbF z+>KV?QOdW$H(!RBt(zvjt=sG9;;aU3Zzle)0Xj2I@{583)d1w{pBofVhNchH5aIm` zr)&(qPmx~|ymfi;)aC!bF8x3C`J24MZ&{7ik1tO1>)Lr)?MU5bwe%(Hwlg-`-`l8@ z7rV!3-QMENnELBoC2mi@tzTXy&;M=z-r8qBEbHFd$ght7y1MSRxxe)OW9vU=|JnBX zIpd$B@gOwS=E3J3+y2+wu1T{qoKXc*1y^3&pv-v{CVfkJ2iQB z`H^xns*AE1bfo?VEsn_YkmCr;-C&#O6K<0|f9~UxpO+u)d+eUy9A@sn(UR%=`WWfy z|9;Nf@#NR;L19 z|1azMdGjCL`$1^6t^NFG`Trm&@A&=ov-Y2ff2RL=`p?sUQvYS`|EKYJ`_JmlpUaC` z50tFCy-9eh@4ETlUqpVK#9V$i#(viAXpaYnw8f6{uiv?O?WDy)W zkFTElED~({F9rv>36Hy`mRxDH3Sd9RNN8-xVXp0k9EP09s#DY78tBE9pUB(z-EVT# zja$!FZl7|1w|sp^{r*4th0iycX0pz7-0zS(xhnhLq3i#w>Ry#AT#y9Kd?naCF}DB> zDv@9%zpJ+c={cQ>vuP<(S5Zh_E_^@ALj+Ud!AZY`n@u_>M;8W&+p7VQtOXt6Y?jx z3jN@)yK+I`T80_FGJ=%P9$0zr)%Lyb*PQ&g?(lQ>^o@)4a@`l?F#Wm7TX;A2bnx7( z>-W8i`~PkIy}F_rnfX@dK}#xDo!`T>@egDnLcrRBb1=W&`0#VidG+l7zZpJn{dub< zcb{4O?Dc=`F8(e@ZmG(-$!UZ$tf{oVdFEvD<1NbHH-Cyh+kg34+4>BoKkeP?JeM=a z?cKS1mn`vRsenU*F$-vTthVTR%H3`LHQ($ue)kjpoVPPCnaTXlUM0J4lV6_>54c`+ zy5ep8RnH!GR|in5LI3P0S6k4ihr9Df@ec5eg3kfaT;GYs2me579HOd(gJHiD-f7zV z?BC}5fBnmo-TgQ6!}dHm5Sz8TzVvC>^S{5YiE=+?zkX+GUuNy=b?5#R1e?Fw{NhM3 z$xVO>VGL{XnI9Z6oLhM9G~bmMhD_42_eu|jZcI8G)jQWTcaNw53k##81CeDXR9WM% z>IH`H!?P?{#rEgn#h{d-?-(CwdehxvE|qO1%JJ*GpboW{P=fu`|AJ=U%9}1HkjeN`K+gnv&7S~uYT+1zoR;D`~5X8XP6q4OC2|MuivM2u`@LPw`WyMro`g7N9{;3j-gR>w#}>=}?7Vof^uK@3Z(Xr{*VX-h zS5EJj;Xl6E?=xua&8v+S&4K-UvTUS43oB2!*Tl4+_eWW4z4hOB$!E!*H~zd)lVfKl zKfC|zam4DQ3zuvHu8T74|1j(LQc0z+JEs~ieLeBi!?p3h=ZZ40U#)y=-FCS`r^$Pr z`|s}dDg(J63RfLIDS=w)pA_XkEyP+ZB1{Jl!a&*$x+j^LwHcoIovDhce|U8z>*v4P_oI74)s?w_3uLY={&<4Kfrblaau*mZ9#y}|`paa>Fw4MqhT55JGYw3& zvTt15ur6^vaVzv2*ee#~$<6qFP+s(}`O~E~o73%{=Kb>1-fsW@)$wb)3eTS74kW1R)jJ5Ft4sTutzBL_4fS>7&q9QQ2skVi}k>@>(O^#-Tx=T z%l7r-#K#XSR=7Xj7`5_J%~5F4ew6DTd{+m!fsJ?JndvF!&vrlJPo91`A;h?3mtXvq zgxg#V%6q@Aud2=edrLkmFu!zl{qM=I7SGXq^-%fv;g13RE7`Ip@%OktzF1)*_tV2} z)#2Zv@KydZ`_H(4{cQtT$vYdius0HA4Ol|;S?1nnnhl%TFO`}ae*2!fH6xli!HVzp z!KIa44`yABS8UnDzs>dQ`=1}f>qGZP%05#D+tqvg*`(W_8f!xKoL|2wth+M!?H|GZjg z>Ad2w$c!t^RWJUt9IP;q`=L-fA;D&b_?d3PEfdf{as&G%u7;l?2VUN}@>0C3*KvPD z?$d2-2i~q{+%WZPm=Djq{dSMHr) zKTrNisXMh9k_mCFyGQel@)`Em^O-E8S zcvJbR|Mw+Tsb04$FQb?roY2^Cc5hemzB<>nuh!)~KJf3#Y45)F$AQZ$gKSs1e~sAx zCo4v3`mv>jCy6NZHk`GcAk9#`IP6|ySbjFc8TW*g_~&c~{%E}ps{giJ=|M%vK^NN< z?M)4!)uxWN@mHFw0zkt*AuRC04{j#HWx*B${wHh)Yy@5xtz|TDUox?Ft~A5zpz?2v zXH6(LuyDqVtHd?TAq`eAdF2lCPDX>$Di;5_4j4l7c z9WVJ=?9Kk0e!GvB-<7-n?^62d-)}el-ed9Tg?a9`^g9n1az0@@5O#g`^Yzz%l!JB? zoOOQ{XuIn8uP4sXqTmlBGq~7gln;@&098!jv@Ev2!xYD0&$iDt0cH%#Dv0*SIUJ)Q}^r0KQ%r6zt-m2gylKk1jYY8U1st7{r$ju`PcG_ zAK#T-=BOPii$kZa?qGw@-T2 zXXc96|9*Jh=E~i>+gMqyWi#X??w!hf`SbO(Kh|=Z1}oja&R}!WYF_0S1!^sW$Jdrg zP2hj^xh^y=6jJV-KM&a}_T$8Jbvye{KWAcD?C{B9aR$Sg+NjE;6^Fm=JiLeLf$Q@+ zow~2x^QY^7o%`NeGfjTOPqqV3x8Ijp{y+9AgGKqhJr%blr5K9W+FW|Qh|wVaRY?6& zyPNa1G%W2z8NV)&>v}K;wh-vdbV%0}`Krx@QI@?;5DsMdY&{_;SLv z@hN-W)2{{V8CEbFOb^Une?6LUgWK2e>4gdQpnB?HVaC&%75}cx|FzoR&Qz`!R9ihE zV#H#_T=s8&F8KdqJEuC;YfFssj<46B%hg`kuuaKs2jd6L*|qzgZoj`}q9}uTok#am z)Azf7f7|i*T6EIYQ=*2&-{fBIznk>s#>d$;^HROVrcaZxEz9YVHD9>r{wCG$#}Cb3 z*FRNz+VOS8&ySzm{Z3AHuI$Tgjn89it}oj0_1Nph+sk8pW^M~Uh%=(+gr0*u0p}?$F=EG?LW+!zSoSe;?dg zxU=oGbUPzCaKx_hwtJ>*_ek09(c-F_xP!-Q&VW(OzelH^ciQ>;g6G8-{IZ=?a|F~@ zs5#MYr~k3C6P)aI!E^SnzIy#Oys+{1ueZhhb_D^+@^A2FrIw|NC-$PxI_Ob#FhaAN|)Zaz3)5 zzo>P8aDQdx&##O5Dq`*w{oT4T?dz(d>g4}6??dxDyZ3)D&%M|FKiY4+FKjp6 z-hF-h3w`tHy{+Ewcb8xIF8}B0YyTe!ziv8T=Dqqa^m|2y-R#HPH{M>&cHrOg%yoa# zcIQ35_;1OqkolhMM_W>Bq(EiAir@!E`C0s{X6S%QM^L$#c-GGUbKTM3qVL1^#DAh6x=+17YtP{+7C(#cXWaX9x?3+}oz#y-;(Imj{rk4vJpXij zOwGrmh1Vj}r_OHvu7BU|3aFsyYHVK<_;;#xYJJvY=HtqO0sXHE6RZLt17auqNiT~J zu-6zIs=2VADPh%zN3Bnp)*mb_<$7TAsqJ6Y3TX!R_5Z%_y1rL0?)R(Ge35ymHYJX z+BezuS@-@=G2d@-ZB3Nu(Z}=4?^Ry3tjf7FQ?B0i*7=Vw)63)h=`SCx~%#(M&WX#M}uYdNmZ|k<#AN`xYob8Z&{rjd(J2%{@gOqSKOMh(I!&7H_)O=gn?;H6sk=<3R z<6=Kny$bvfZknz*Zgs}}*y4{70uMmN@|+Cl)Ex8A0J|ytPjO~3=m7*PLggafiyWw& zw(4MM9)rxfSjjsK6{j?p9|@lS>&jWXtMmW=d0uh*_Pwxs`sNH`(zdU!9c7OzPx<+` z=<7c2eZgkWrry8tV18%j(!KZN{(SxMY5M+{dqrOij~{pRuYXs?+t4mwSFz{84dKPR zU;WRvb1F1@z`yUOYASQW#VtST|9{-PaohIF;?Ldn|CfJ1CjUG9!)a}Xyo#^n)AQOhZ3k^1cKtz0tSBTIdlA;|CRTD_dxga!bSnG)Hu-k=e7Yq&m5*5Stm~k7v}BEzFHQ?Xkgy;blKL0 zpdk2h?)zMs&HNQbKSlVz{y3e#U(@gZ?(NgRpVnrW_Wk|aPT}~^dp`X>%GI#E?qPIg z`Rv}}pVCMF)_-qaf7JZn=liGg_r9I0e&mkx{Jn9^4=(?fX6Uxg*>BrgcefjjM+Ligi=RQwuhGn~Me%N8Ng0VpPcy_Wj zgJ0*=!ZWMmg6#fHp7&*m#n&srr`MZ*^S{`5`*!r)=!(*O_d6Swe0Ti4@nN0qrMFqE z2iW(YbN^LQw=VASjgJL3X3q>u7wTPUt?VayxUGS`?F92q#tm64-m<4Va|{ne?X7(m z$UbHF1pbnHix=Lyw}ElPPNsx<=ex(|sb5h{67&Enf_fr0&G{gKc3kCV};z$Dd58`z~@`cpFX1>Y1DO98f>M= z6X*B+d+aA6EvH#v&ws}LZF;87l1{~3apuJ$DZJb4=SwlH{;Rp{?W&V`8r$`)o-h8m zI{wd|HO-Gi4!mB=u%q+&?JHajNB{Z8m1WD6zuEZovFQIjUzz3m_I|66xoR+d8}~kb zop`bMf6w`k#;@DIY=`%r2dw%X;`=|oEj<5f-zvs}U{Dx7d%XD~+X2Vz`CAwb?%FLg ze)KHPt_NA`PsMHdG=JfpfB%k!G3dm9T{b`e=3DclFV*+#-E;U( z<>yDa^8a#n8by8V)l8N$T$~(Q^J((@oOxUo4<=swpLJ@A=EsBlbq3G$Z|MIksn4%` zyestdV`k}f3^VdH``q@4tp9(-e7{QAx)@1myZXZUXVMP`Gd!Pvzc$ESXXju2!dsck zj~;5}{=D71>hG52wz_^+FPH3iweQ|D&4r&IKbM#2dYinzFtlpNtBI@5-LJY5fA?7P z-<8wn%kUp>Uf;DphH5>db zemWZ#?{_wv$l|!wPo_Lo{GP(9xMaPsO@52x0owfyB53XH{HWa|uh0v%}_}dR3sl|4{0z9oJ1jwxjW6+7( z-{qb6cGb41owe@*`%hXM>RkWr_qOMv>{aLcdspe_)h~$Ze7|tsnuw?Q{ad=?3SauJ zSQm9?^S!(7OJ{$ZW%Oak-Me=`Uf=(3YmUxryV|NZJ0AC){jDE!QTqF`;MdPizc|-X z8_b+o_|k88QEnFBof}UNTsaUPWA^RO&wsy{UluGElWlxibad})`*VDYFK5rV6KKXG zwp~AVm&v=G&*w#KPV+r8$I^J2-`ps(#&vJ+w>R4AytDl>JsC7<`}o@Of2(Xa*@xa< z@p!Qu7t^ukj~DDWPGNQe4K@XwXz)7XfAM_8UX zZ^Plpcg@la@1t&tm#>kDc$xR$>-zXSX)}hnnNkeqWfsqT-gL+YZ%#P=K>D|QiSMi9 zyE7yGOP0SrxIVvtIiYa=>v!)X-+y~_y!*Gj$qL4T;Pd-evK{zS6T337@cb1Pi*>IL zT1VV@{_o0+9R{W@-hd{*8B`WY^nQA_sncTy^eB*6NCy+ehQqJ>iyntG>_Z-rio#df>~aS+%xDuOC(IznpdY+qMUVIe83c z{$vN$pRL+pf7PL&M$3K$``3VuixmcPLA)m9v~ylfV1G8h&NJ$huH?!ezGc1Z&fC6f zuyKhAcTROFvUs*7@L*VFLFmv)%w^?DPrLZ~tKZQ~ZE zggk~be^VT1@ZPJi|KFC!*?~N#wBveeT}c0{KwGK)nvnkQ+RzcJGso@Duekrb^BLka z98l{ST#h2I{oD}y40M3PY9@&n0r_vY1v9As+i6(L63@Se;l{11)!uh+^OpwrxR5gg z?`;F>(ck)<^%J59tVAJ|y=7hSbr7P`!2MZS1ta5Ysx&TtD1ehFq)?EcU z6{?@D4zf{{lzQKJ#Puu>ciXE4lus#eX_pqZ(072T#%b^aM}Q%-;h#TNX8Abete#I%JD>*D+B-6K$gQbfuLo-Pc9mKIOzDV?_*+( zgnXrmggj`>`vCYXD@J(&=SM-u!nf??|7P|0c_!>j~bCV@v^RaRn@Z=KFt^Nmz)eABh&g3TTY@P$b;3FM&Jhl6qHf0PRK0-k#tvPAD+%V;3qKe4v3CCl;tfo$j}Y8e$GsUGzB=orOVuz+!c#hTtC-UF`~ zwiiV+KXB;meX^d-oMGFhdtAqGO?xxI*5mQJz}5#FEd1_`GG~c8R+Ke~{oAjCEQUAU ztT#Q9R$csRx&Ds5a8a!4a>0`iZ+yPY)nK}6_pV;%-@*F&mU4aU@mKZr!6SE>F+}b# z$T=^Uk-?DjZ{@R&oDJD}FJ>I8{4Z3#b=Nfpj{~<4KSf60N%GD5A@zear z+WXfSA~-d=E0)BCYcp)ycTa2I*Om3ZgRks=99SA6DG%GXax~s%CMk6vxL&fc;9nxj zP(Sll&aYJ;1FIHI+!nRJ_MG-5u7;{!UMLrBFE81DEV;`+vkWv;s0`{gn#j-KM~!#XJqifkg0{*9Hmn8jmU_Fd zh+*2nb~}|hA=I!k{}acixtu)=c26}M*!RxcbtQhMx2Y8WH+8`Ro2R!RO{Lvo*dZ*nDt=ELndB-Y^4N(e7zC1-4^mTQg`? zNy593^~b+juD`Kgs`0Gof3~WQ)ta}yc{~7}-C+AF?}2{U8~?A)&K!TH{COj`0lx!f(?PrFuY3>xp?|hH zl<`X9ZyDZ(r-Cc{e12`(vn9Uy{ftjEFlJ6c%Vw3|C>666v*E4+rK1X*rYKJtS#tU~@2qSxTJO9HfOVFx+Tk zKdVR5SqTaY7z22T^b6D>qtOIUG^5c3N~EK?37)q{a}%g687=fc*#Z<29HVs;heE?> z-2|;V8yJ{In-EMK3d6Gru^^1MA^-2I_mBTgy{mfc{Qh4XH$MJxakgvKMfvv~`tfDi zmHQXV+pEV_U065!uVgt%?P-SvcR8=DVk|i4Y2P85eQm1G`rqx(kDNJ~Y<~Lt=l%Os z{r-Hr`t?91+Ffg**n%ls3pv=DMn>I^BJ4pk1iP z-8T!JIa6LecoRCT~^W`f7~tWxx1_{ z{{8doU%yQ~UwHJ8s$r&2_?dY|dUCVhT@ST+nWlI2b8PMJOFN$4V_#HpF6n>Q-x5cn zkD3RCUV=g6+eM5Y{!P7Gc&Ih}==Sw{YCmM>*ZsZKT;5$@^Kfx;Qr0!;nx7v_%a3aR ze{249`@Zr!i5qji?y`9IdVjxY_BGyp(P!ox8vgtH)xU$)Sp8_E{r}>c7mu>9@7{ak zM)Iv67Qdge9}9l&Uwww*=i^z3AJUZ-n&&DZkTe|A1 zCpUtHA2=5kDU*;`HtZFUxX9bE`r5Z6jPn07H~(CpvFP{mEtl>;zVx!9`qIuC{r#zh zd;VM3=d63N{rtJfkM;*Q$JvFxf53JiMxg%tn!S%t{7pZ4Zt}4sOY8TU_x-%}{Uq+rkE z%<5w=&);AFbMgOAo24Irk&g?{6F*xkzW1%CVeO+A&)yyt->x4kdj8*&`svq?ev8z% zSBR@W@$TsKjfu<;#N+<%sCenPd)oG=^>(1$frssX{eN?peM)TTUGoR^lRVWIsx?j! zs1j$nr{G$}%b}#e^yy;t`XCjLjVYmHd)HOqD5=PiYXTq8HG3)oqnnO zJZJYYZrPokGtbPG%uAcM`P$QYo4?!re)IXwnxkt>_uu?|^ib-bZx?!#ZeL{=TYvfF z-1B>-+5dccx#x|vG*9RJcbn@r+T|L~*(T+8T>qQA-0pRoeKzXNJ#(_D%l+@O_l2*G zlRtmj^?3F53#^PxEF1y~4h;+h7$sVbe9{bOii$VhxmhkA{(bl36TV5Gr%ufYLWTn)V2-|3codsIC+ z`Ej@WIeq?H6+eGGlzT0*s_Xvc?B_>}(*G##UnkA*=kWgfz5mM(@0rSY{!Zf78`aGV zk5)^~dsF>4c;Y=%S^YViYjy7K4?nE7j%c?FbB5$HY}l!|J==Z1-2Gi|<9|-M%FAH) z@7IwVFHc>p{P`|E#;k7JeYVu)rPEi-b-Ty^Rmh)ws7cc#qMY@Bd}=iF`~UaXHoh+V za_Ps(jTc=%Gc_E~-&r*0`&84{Vb7l%Z(?|GNtLOgbh}1gN$||3{qy#uuCd)wKT~WK zQRx8`x{J9>ZZJH!`@d3u-^{hMruQ8-i&gyhJv&~*db<0+UpIF=ow>1c_Mx(axv~sC z2ak#*#9Vm1P1&qZH(YYVg6*091k)TemSsH_9A;yfU-kI#jfcnkp9OEdy{q~0um9ie zQvKGKdA{swo`@x9!x{d3oFCsivHY)kecCO%irrV)pFRKl`+S?;1r#ncvRdUZ6dZaYx$#!z_out@I~(1*X7DF?D^mN@ni3N+nM&C7v;1ba^5_ZYqnKddh(p#_fO4Q7dtC!*&IUo z4C-eVt4@b@UWR2qrGLHM-Mw(%Y`$9tWl`BLCtdz^TK#^HaNY0od-AqA{(aPWdE2S; zx2w1xnA^{hivRPk`RC?qQOoN8{9K~DD7v%Y{+7tikL%rRMc&ug=;r_a_y3)cQ-fve zf0#7{;(Eblu96oF4@wuu_g~KY9d5U?S^TYRx$IWYH9JD?S55vqzudl4cJtaM?$!U7 zu5G$J?cmFd*9-|&#}4lQ6@BO1`SMGdb9NriDtxtVwcB;Qui-y-fA}{&Ddd~y@p-R# zJG1xitgCxxPjq}#vRaie6kK~_x$)%D{v+D&>!ap8eE()oT21E9ql?SF-KqHVwew^1 z?`N#9gPQ+KZmYOc|0XT)#Qm-A3?HuYFH2ed`|nDNeYs)M64h(%Rl=k$n8(fgkZJSb zQOl3N_QynDzqd=fe50aOwfnjsflz@b+y%v;;7OQuY5L|5_Y=+Sg#XKYFT5$~w{X{% zP4_l+f7RQT-OrFvbpup9AHVbI`y;KEql_jNJ5#=wK6>CgEkEGZB%;&9Vu!124Dq)0 z$0HW`_y0V1a_ddA{r7*pH`{+aZ(~r*hSO2K?`8&CtN;7nIQ`SqFZX6xY>oSSidn34 zuepSfdd^<2DJlw3SqS$J#T_uJO%?rrc~@?5|6 znEaNfuW;Ff#uPeIn4!r%KJUkta;5MlXq>63TLZRYiI(Q7t^EdDJ*WIAea zcrLPH6+=R`&%xuD(~jPryexI$o|_wQEvVb*aemgfik!{!4a@V6+~{9+wB_XG#ns!_ zZM-8?o3!!X-PyJK+lWpfmMm7W3>%7lR&Q4!T%&=V-q@$7z;NSY`i z0t{~^Tz<8b=v1%EDm%WJ{GMk+rkHix*6x!VEEgu2{d0^xsu+ z{m-s|ce}Q@+nR_IZD%G63&VeDo0tgZwz<#ZSBa|<8-!ILtJj!o5p9)2gF_@ECZ>j~milh4@FJZM;}jPM!?dS?o`lrF3x`#~4h$Qto*!KS7a_zL%^bw1 z_0h~hY*>wE4x%f9(VAnl<{*%*0_K7mJ##FJ(@MD{VQrEHQ(3FNytsJE_EjH&0JK`% zz>ttWr}VuKq#mhR$HdeyUwePMFy88M!C{V&ScZacZzN^eu6Kj0Nk%4?S6n5puNm(b zVOX>J5uyHNl$HX+jUdbKuzFi8z=5HF@t}!1{w5E4?H%Rsz_8(~&Q}+R^I>t0w)K9UP*A;0f_K{Ls|+9J2sq~Q%E2#(3)8<8km?GWDA1! z3gItj?A$@#5xl<`()MjUr>ekkW9PHmxAC`(7OZ7uVYnR?@gL$!hQ|L~91OpfL%fRH zhif$z7;em(^$XUdogyf}pwqmVP}5K>!hxZn@#Gzt@fkB47!pq3xkIR(w3L;F!F#s` ztn094R|7-B>dCJr5QuS5Oa=SzpAJohw?IuM+pV_U__fK#J1}f`e14-jG@+~lB^)oc zLk75m0~B}{99dWxtWUU9@j}{(3x0vx%k_Od1YF5Ixq;!qA(QB1UXX;SbA^eif&1$h zNgMnTzRJ&mVZ*CsM;ai`YU~4L!NBxu)v!DW5l1)V!Dm4MhCelTY^Op(;YAA*Q^VYX zOM8vbRYIHt&t(A)3>$b0OMRijD?r_#@WYn)b#a7fDKJE=T<{x`DjAv1iU=^|s7*-& zg%~UqU@4m}=rA%KNHffY6$C3{92hnfIorZqgWYcp2hu_1U8IFF)aWfM8yFI1e|klr z_?im}%FDhx#nmAC?DRo-$@^Y0%+=Ukd%+OYoqo2bN*fyET%Z^)2;%941T7YSfz9XM z*ue0>$)>W+4-%F-F`yW~UL&cCKQLFtIxuXwm44y}#P^MS$_flO5|>?qm)H<-bVC+s zv9K_#PLkqjf;j614=BbHr|nfnR|#gP7;Ao0EfKoAg$8{JCdAFb4-iSy$$_ zNlF@rR{VUjswJ@tNNFPLMDT+1bF5Fx7v;L;ThyC<+TO#GFt&QvgYc zjjiDh3!`WD4h$PMpWX2tR`Q|; zBQz9lb8#?iTf6?=X^t~FnFe`M1hg< zK%eovk z?>D>oS}Zz8?(XjLes=jk!8MPiA8&DjS?_kVg{^6z20{4vn!Hh;h0?>{+N z{d)Dx@VH9Vu&B(XRjGP7;sEOG3)eu-RI#c1^TXoLhs8;+u4GpBx64&|)YES!u}_> z{gs{kz3gGD__1ZP^P<*2w=8~kWNLVvDYXQocX*JgTg1{4wozZbjPi#?xL?RYOZ>gUr}tJn8g z7N?~jJTS8|GV1NR=a|9kSD&n-U}#%HrFaQC^e51&r2KX%c*{+R;9jhp{i zE8>}0I7;L|?kxWM<+A_rHtD<@I~Gm#`t|j-c>JG7;*TFR^Y^W<|NHvl_Wb)|Uu$mX zZa?~N_xpQK_M(*0SWA%wysRt?(Tv~E7@zOk|M%_8B>(y!hu`|HGrPR{x>Dh_$n>M} z|9@SVFidipQ}gNL(cf0DI~fwv=T^S=ZD43T2g=(O=Wbgu-1yLWT(&%B$$72SYc6fb z+IRi_uWQ>k*?-xwBE_2Vz$6{~le`(pjEo1u82((-e|}UvY@NR8Jom?s$LAm6($<+@8`fcZ zEkgHFmf6$3EB`hgm+LmaU!$$&Q(?cW{JmVa{=SGc`~UqitogzAv+M}(`}+TX`5#^O zx9`;qUM8|Xcy{i#n^yU=wjHW|wQ_m#pC6nXpH7QD@@n<^Ya6=%SlRwwI{jG6{OO;b z>+gIbwDHZR=H$<3&AX3^MX$MN>&wcZ?mtha{^#k%AHUtsKfc6M{^$h7)5mUQuNQs2 z_WMz{S`A2^;%;tWNO&As_5E)7V|V*sfi~ao6o0;(w!Pqcm-f0De{(kGELmGu{pE#V z?C!GO@_Uu)aWx;0df3~adGBHGZu{dwGxwfP3BPV;UG_ECy}6em!BeaiZ$YgxF! zhQ@mP|8(v6|Bqez>e42=+N$H0&*#WW=WM83{OjiC^y6Qz|5v&_>BsioS6r-`9_1%h z#g7Vk>%?iC+Q0pFp3C0XB@^d;-F^S=tiMVBx^{fO_xttL_=<<$H#t9&x98KUs<&L?yWeao-d1$pP}RAo z)odTQGIjvfvD4;H?YH}-QTO}y{bLW?<>R(JT)X|=to-NEt1hz3*G%}k@#x{gHye+q z)w38b44IsC^KrkuoOJG%z>igR>cPwXa*MbV84vt?xe{-6zCf3Sg(2GUYp?mSV~Opu z*H$bS4UbX$cH?pO#-n1huiqBhQT;tGF!-|VvvYHWFE96BS$-c>%3I&Jw2ybx50$C? z68LfI`Ztr-J_w(jFJ1HRr?|-N`E|cmZhX7#w#fR+Cx1S#*U$c*5m)x%Ap24C{g(PI zKmL6F-x=(0t9wa*-Q|t%cD;7t`f!z3I5-`tNsp>AWBIH&4~qcQZ0i z>)PU#@bJf}@UlK(KMS+{KC9XKq)G#AJ|3C;v-DT$ugv9hrI^|Ix;7>sKc?6&6IAo9 z^7&lh**TjE7tYR*VEA)L{90fA-`Dpme-zv;y?%C%((CV?Nxw^q4zfN^+rQy|&|V|R zB+!CetSk((&7J%0er4oryP4)|rYFvzb7xAJshnj|N=(_!)Ye6l?w_~$?6c3Q=;SH3 z)|dUVm$I6d@-ZF=(mI8=hRetX<$Qs6H#hr>dHl|^`EY<)wc302i?>@Y`)z#Ocl-E; z#M7zT*GtbbHP$Abn{)GKR>S32cZ=Wc6hHFfV*k_B<#WrTYQClB>V{pe@t&(;(W2|!`{iVp&#$Zc`0G}7z0_%a`!yAJ zcbD(i$uT$Q=9(wvZ)d50B7DW4f8Q^6wY~HTUPu~yXK$iP7SS#6B!Jq%GZ22xbgkI-)`&U_I^s!WSDU*)Z*Xs zdb1AsKM!`ddfx|U*o1`w0t`9-OqSX+dE922ZZ%7o!RPzgna1j7_iH}CNnd?&>8_Kf zFP%3lzgL+)`D>{*3&ZOy3;YRI3Y1_I#dejxp4a+oSL(uTpC3(hm(#rcc-ibcq2KTK z$1l0cC@rVI=R=ZA{U6WDj}HzugO1!g_p5h?X|`LKnK}2B%$F+33=CE$JY5_^zIOE6 z&x_F)srYnKJS1Q%IdSjp^rPQ+nH$_?OGCC5Jv9IP z>r3~yl9H1O-)?2EuXsMU{L|~U+9$35oWYIKRiF;*PvMdWjqJzt>ppf*GB+`2n33nF zc<4*9=g!Ax&F}X-off?=X7V0ChJt-AQdp}*ut^*O3K!0Snj9?mR)^nTvs|x|!C>tL z^Tb0fn{4IF?_AvYdfoiB%ce`!|GusKd2QL{O0EO4bw3tHcH~v<(vh>R`qEeX?dEog z7Vl^t`N}5`EC2RL8h;jL2=>VPcvQT9{=YA)B9b~?yT31MxF1*jHdf}gpu3D%^}C(b z8}}6yz2D1!Om%w9r1)d!tL=I_s5zjxacUTz@`6YEepMGVLirGH_p&hyl*G42zL?bh_>x!Y=JfODwqMx$xX-$4 z_0y?UK8FP!gzw+wUO4;C-*30|x818c{bpOG;;uI;_Pfg7N-4X~lg{7&x2$gO$79k* ze?C9YeR=7GnCt6ID;@H0Y)HIWwy*eAuHm2g|83;c=bCQ%(Q}y3+Ju|s-N*a$?0@fi zKJWMAcKbah`W}o2cEA63xISF5=Z&oR$?(VCQ!`T!iSVqkewVxbt{Jz{yqVL*t9;bz zf8Vx$RKEXrY}}NvAJSGOGo4CJco^;#oz8#7D$dR8-d|^Q&i4DAL#cO)&&PhC8OK@WAl6jIjOBlm4@6ewbd55pI_)i^8;&uwKr_eFdLhEbdRgtusG2E@xW=l-8!HXfYjvcJ{}c6 zuDN{9rIgx*P7E6q9?k}*EgZS6F-uT@VNHRWn*Tf*VRgSV+t$d6?5+N;_idU}!^_Es z@?Tbbzgxa}>c@Su$;Wy$w|T1H|8;HU#=B*=U83f`KO$`Z`{?Im()lvlYc|weTlDeb z+GyX61t(Rf_slK7x3FTa-!k9X^Vt8r+yB2Yr*v=lr(LPjBCV>=l|>4C3_rTnH6$%u1uZ}MBbjxU;elv)jNozk`kKl7`~UrV{rCVg zf6k_T0g4O}6F$Jk@*oXDaAg21avT~Qwt|K>EQB*t_jc>=GvTxQao|S!{CtyFYqPKC zRSFoieoH$uLoj_#p_|R$FPD#&{eHLGU#8^3zmLbH^V6cw%SP(hf4vgCxghTG)t_Cw zUFyY~58O{*{qpZifBvISr~kKz&Mk<#m$db2Shq93t%}*LjK?-TJAS|0?H)DNK=!y? zbu{Pghq-ST))Gu`)^xYjLehKT5BY5CeOfnVO-H2(GVb-0Av?i&Bu zX1eivt2Q1LJN>WYuzbuG?p^IT(gwI=ozd99kidQ6)xA#_ocoXP*A*o4NN&oBssCGA zy86}J$1D0*Dc=dSe*3iOyo_ky7_C5O%GdW`Qt%z*V|cE zp8GrISr*6L$p7-<_@g_;`Wj}khDk1SDxb}~xHbFwo}6=YZbm-H-#)`6GpMfi5U2W) z@O_(-H`YE(ab#+^y!?DeY}rqp6*KB8>uzQG=5GwIaJ!q&cwm>*IZ)elfigD-gIRr9 zv@yeu=kuzMy|4SeTTTAo$K&$u|Ns4+y+%J|ODaRbvokXdtG>M0@%>))=bi%Gdusf=(~?Te|Zy~zt{BN$Nu^w-TM0^{{MMypZw;= z#-sl(6|MXF}eoyK3*yShXE|(oJPCs|DJ~KL_Qo(9b14F{+^sQS#0qozOc(_e8+#%1R zY45jN+Ic&lPHQ`=y8gBj!;G+>yC1emKe~PYU)khj9m^SOK5RJ5*Ij(hQvJ8{6h&Xt znfX8E|Nl5{@$<>#S#`c0r&&GtuK+Q)vs-+w>D^uR9WeVee_gc6{m)wt-9N}KFT-#1!Qte# z>~%ZSzP!4sJ+JoL%}HO+YSw(Y=)QSAr+Kbla4smE5G52WDjwgsJ;cy!aX2u6d_Z_j2wessZ^U-z4J&W)nNmrKRn_t*XH zN`0yF_tKw7-TJ-1-`6XY-Ojyk@odK8Pruq24@l?#asAf)<5={uzhBoce*EXNef9F) z@Aql%Dqp|yI}bRx9Tv<2hqv`wL54XdnL+!0#UEZ-wWFm(Q0w+|IARZq=W2*6%^5Gs}s`RV1D)l&k;qvGAnobQj;V zf9lO0>NT5+w&~vP+<1uVbo%X|W!?UEKUL;cK6`&t zKe2ww)|Zo7|F7#?I$dr;`|EAD^ISgeD=B)|dcXhcwcknG-hNo~W?uTH*WH`m)-M;m zowMhoTj9H%%H8`T^g?2)-=2SbExJB>$C+(Qck4}yExY-s^zh`ky<#VuDxY7Ec2sL+ zIB)s<&6~e%&yuUZUcJ6)D(m~R_ulevyc!mrdi&1YnN!c7+gIgEUaBeb)T`q+ImKK%Rr{(M-$ zzZ}z-yWU=!cHnwUvG3hQZqHxJe!HE&f5*>fv!$=9eqOz9*Q$%>+g3i@`Fx)A^SR}5 zi>t$8ORv7^_j5DV@@Ji$yDd^@>y;qY*CP1FHWe;dF)=lWTJ=eO&e}HV?#AA#mzS59 z=WMy?w(*$M>hx%)?>*b^RayUg|G#efc5m%pb4#y9f`+EjqQBJ5Vt*3kdVSs9O;;JR zKV6N@+yD2QTkSI4w&Q)W;X3~N7yLaWzHdVQ=i5uYr~i1WpWh{-wWfMWp@>s`X6S*` zX_0FGKD675%wA&G&MPgZKCdF?&tv)XNALgt_kG9jch%irU#fhaxb2PaThOq_*H@QZ zx98p6EXt97ACKyzt>%Q zJ=R>!XU2sWp4a25bN7Z$l{Wp6@Ayk{!%E%y=i&-J_Q}gc*}P@t>;Dvfd4GR@Na&ea zrrK>hl0ijxGNqq>F<#k>R;HoU7>(b=1sK*``1AGp{jS6O_Dc7QzHhng*L^#0w=SrD zQmek3yZ!E`_&4XckNI}r+?@S-tM6)tvX_@k-|c?CFX!oA=|^w3-(MF#U+-Gvb8gUC z>(BRR%(eWy*)A)q>gmISCT+XixlX;^`FvjC3B~p_$Gw@62_I)ve7zdp?RzO=-Ogv~ zH^1$%Kf_d6uRYD&#`Eu;!sG9y#hzc!ymPb3D00U8Yd?OTub;>IZ<$%v^sw2M4;q*k zg|CmR{P6MB>h))xCNBN$ZC?L*_U{z!?{DU}3j25d|MUE(+h0*Gy&Vtk=;ZuddT1%6 zZxXPTiK*f2{8>ee2a@}3&Gvm+TKWI|eB*S#Js*!rPYnB0{qd;y;w#&>yQcr7CG}Bz-#4<$t+@Pp&t=e{38+4P^ZbBb?<+6SCA#&& z7dBq``02F%@l)FCV^(R!i*9@<-?OCc_q*NscS2Qp>NtzqCC2`nsd>H_pwowZ2#T{jScQ?_vM;zF72k^V)*; zqZbyQe)@3xmlL;c&AjQQWh`ZD`}flJ^z(L=90sAw6k@qv_ez`VO^ZnCtXaBy%P%jh zw6n9~?$}wxF8_T=tLf#<_51%-?F;h$^)x?9R{!hlx|cGB=I^Wj{P=h?>`4Bx21e#h z8+E6D4-KAtZ|SlhZ?2?2oMBz=wKE6??+*$kFn;IE$asLOFgRhId;h)44Z5w5pS50W zr17%Ux6ehoyy}+M1u3lmVrb62_v{Msf3vTz^AJsP z=0873|G@PP`wDDxqaMdgh`+j2zR5#vX`e}3iiv*5kI00LA-6-qB#PhP>rM&xUEg*& zWX7hIbyLAp`1t$O+kh&MquXxh&1Pr1oOMLkQj3>inIY&#gkHJ1 zVd_57%;x1^_dBuQ&fi~q@+wPkZIo!?jSY#d%YK$e$rd*Anym;A+u`x>Nba_q%L*bt zS^rJ+`qkVQbbPYEog}EFTd9?bJxzia8?bO}0kw;yA1(`h%Qau*n|I>2FPbg)XZ^nM zrTanU>QAMoots#9p;hvR=;n*M64sGeKDob2qJO`Z=ooqWHHsUbYJG*qVY$wc3K%b|-gPzrdc zGaDEhw+RX`^_MLBM8?U-C z;3sH8c#^kXAp|Gtj@Z}sh7_4}$+Uj1c0GljZ!HhCO=^yk;dilR|4;uld%xW(^|G^`YgL-{<=x%io0-z_=Y#GBhJ@V))f~`ZR&Zk2@bf=c zlre)v`nfqbGMCT&l-oF4%JG&_#qYP<^H*8v=VyX@$zQ`Bt^PgX>-Bj1d6my*?sDZW z*>~RV_mTX%&$B0exB2;G^2Ud4($`i?n`VW8`tM&)T{=2J(fQLnVej?gX(*4TIW4O&36f2TS$^5=$tN)zGxvltJ2xdNI&nU%dR zvPg7a$o@xN+HO&X>$9(~d%5Y!#Y+qcQ4jN9E}gD-^LdA$@}qaV-|IzQpL1xkzn!Jt z-Y=IX`M%%zeBO=1*8Y0A9Msa8#P@U?<2;+nBAwlDHmSb%j+TDE>-D;?^B&_* zp5H*pQ$F1vGT6kz5y4o%_>Xr>8H0f>Xg;z3cHZu_Cj&vf*RHkO@9jGIYZ@Cve9gzB z5y`!#Uf*_KkE=eayZuhkrgfIBprNUl!lR<9v+e$TI1Fk`nyvc%dH(;HO?%?^*L{4k zxc`{d>ovje=Ve}A<{Fi0!1`B8PT9Th%y#~~hE(_ z3~>bqSqsluJ~y%K%CCJLt-5`O?wt#l7#?`*?-g0SeqYtX*;V(g-)wNcQ~iGL*HdCo z7Ol*!43^JKJ-Fpi!pg@J-Q_yhZo9QAFqDh&-xGEFlg$%qe}6l>UEMElW$j_*ueH}> z%Txca+ikk0$QQ{u7!Gu>1}!-f-f|q~{v5_Tf9jcY1sQyz?|_Ct}Q(TTGDZet0{B! z16JEhr|Lm-OiLy#z~8Vu@9)6y;q&J2DUck#U@|AD-FxV^5(6kJ9KXKr+g3I9jThad zk3R0Vzn4<$&D^j#{e0i7S+gen<&&{6IMy#84~k4s6$YL;o4xPPr_&ohozkAZMq9*h zu9a!o&D7}?FBZ0Qxu)(fzgPKu$D2*3pWV*C>4$&k&V?+{%!k`bWr)KX94Z+Z4}7vK z%?3H`?bhpVuePsD{_)}A$1B19rlGRBybR0u*m;}RwN;rssowUfV2 zWnuV!GkyM#v-x$wo8E7~UuO+!`GZR4zrVkO*5jCGZ9B|oePr+Vd$(8Y2`Kpc_4@ON z`wx{yb$-}(JFnZQZJu=Bv+Mi+mA={g{T^?3_w}hP499z=uRqbMkIvhfYV+sA;iJz@ zzCQttw$=RqeP92kO)K-|ZwHq4O;mP2R=)rD-KtRY`!&T&Lb+tIy8_w@LSJOLK>*x_ z`4nZ%@MG`$TK#i&zu%~_UsxZ%U&6kw=F7XgyHA=;Wnl6c#$oZEdS8~Cz@G!6WlsykutzOrq+;6ifC3fYZ z@As^ICZD>u}-N~SyPT?8D<5zUGs_V|% zem~-8{WfIN+1l@S#X*_#rPsVO5gx<>h7d|DXXkvB;E(e>T5Z z)a~~F-(O``wd!wgZay&%!RdIAn=jabx;<9=KOVcmRb5~WDdRRQU^=aDpW>Lmvg;eD zC)Wn*7SF4Gw{w#Do9*}OKCX`cyDBC2@S%SDe-?Ze4;pqn?z5H(6J5`5^Wngco9FAq zVt1G6PMd1=^UG!b&kv$k?)usKj_W(9U08V5^ty;%_kCt|zMd_)?;myR$LVChN;x;j za^vGZ>toFPHWyZ$yuSb6*BaIRZla}JK{r0^c-*%-_|m7#Z@1mn15Idqtmay``J9#R z`xA3P9)P9}Oiym{aA4Trnlt~d3d4_?t;XOSej$#Dso|~a-=8+mZ>G=hHx|3SB?k9uE2gM)+Dt={tvR$Zj*zU*&r>((n3x@leB!z(L; zlOOk*>q+K;Dw)T}r1N|7?(Vv}cj?8SuHvyGphZhkQsRLSy1?+4PWteT|v-;NF4~Muv zemKl;UR}D&_S+5ROJN5yqwk8;&9*2^+Vka-_s{2`bxX7J_w9Vio@N@Izqj5kO}?u@g9gcazh2XpJm9@rIdz z2F9r+kK@3hjw_00f#!UCG|s{bY3;IQC&K0Kq|dLNwdeWP>v7$n(SjL<$x>S-jZ!@3 zlwOPcnbq9P&VR1C$=~j03aHfVxwzQfJZt_vb=F^?EaX=Dl$MiY-)x?}cW%+n zeXp*)-E>;-=d{zYyGm9@zrjB-Z3dc{W)6vk6{KFEnm6p{OaFQ)ciGaA$6aO`o~th} z-H^!j?CYDG#rynsfCkQQB=^tF-yOtzsWv>O&~@diq?_*YwIau5iqF)9Yw6qzc%+h> z2pVZTwjuGb*A=r^lj3J*YNQ{f&#P2>x9jz~8r37qqV+4zKAj$a@6A*h@jd0`m>B>` zBtSrbLC50ZJ%=ACZ9FE-g7l9S~uuL{?e&or_S&H^Hksc`nuTJ ze^+=hHDu1d7r5BX^mSzY@7wo3P5l9C+N5pu?=`zya@pejp3h0MbGK!Fvt5~(o11&5 z;&CsiXCq-4?W@^eFUj`}Y=d$lPsW$sapY=NlZ~eU`opPtd_x}I)8?=7vnf8CvoSjdn zMIU1oj}ZVZ?YeU1ipiS165H~3cWSI3UG}qHd-Cl>b-y_h-Z~py7FWZ!Ey0p4O18aF z1#0i4uT+PoeAu4d+W`t|A51^geBSnZ%;M!srgHh)e!T)(QoVTBPf?$_R;JgY^Y=;^ zr}->i)^GF4BWL4LvEEbUTJ-?5niW*(ToeX1+je|DXDvNd-vd(M$ldrb4>Z{P#8`S; zG5+@LY0!esyyt#UzZ_r!t+5rDer&DAhIhMOPmB5cUjF|N_a(c$`hLIPZ(nvJvE3~; zru=RxX!y}YD;yd{Na+ws#Njol@jP$oJXkQMLblB3C^zmbe(rXCU99&vyX0d%FD@>2 zKe_9f*uSUx^_n}czPJ5;N7(w^j^yIq7x8YUYZT+)VA#fRRu>vQjnhDUm$SB0xjpMEAkLX6dQg_{-(5phZ&WgZyDOKzFil zTj=or-{0g#M7)17nN1^mf15WbtyzWGU0y9}nA; zPwQ^a30Viy3Uwl8)@r;aD!`Bv>%SMguAh;KWfo|E&m=cjY3@5Emwh+hulqf<<`k$# z-tp~LcJf76aox!HRR!;$y}v_Q4L+tp0#2dDM-?+M(=1WhT>nhGhpK_XG0eOX_9 zzd~01a|mdF&ODgpnrO{&<=VAle%5bAKof|Q{jL9gxeS_G>;o;ZI%x(fD*ik(-`@#p zw$7{n_tWhypWTlKJAS=dy?EKOWr1_aw3X9mj)fs;?boDe#_O_9`|JKDO$`m}Og!9n zbkk`)>C4M}yFn|Y?$vxg3(A;xmmU4w$jpAMeBbA}7Oz$;UgSMp?`V-a&X5I#^_H~_ z3<-S|wkO|l`4+A3;x0(XOj)b@<@PH*F6HAni0>h0YEAwre9JrY7mEW)ZnbiO)No;<< z*?hLniR&+~yqyhbcnFku*8I4hW629kSJ=F;1vJw3diJY{porrTPzVTeVA!D2eMn2d zqwxT!-KXX|E94Jo;Ni=Qi^`yu=Ogu8?mMf)*K0{^RK)3OkW~{{SQ!3V!?M;E&=9n> zV>J(6-?CVBHZUZp&&*g4Jz$~cA84b?e;En{ruIx+W>at&FIxUNz9lNvhvz=(k?HAYdVt2XxDtUWLbyw-@ zS+%=deb4UkUwn* znrWP!d~MAwn>W|9^shAa1!-)k{yyu)MdjLE+ZV8J7s!ZaWIV9#>s4s8AK`t}BExES z14BZqaU2Ij-iCv0qTimBF|lxL@p&*aecs9ZobwC`Q8)9C^~^M^{dJ~l;r?~8&(|KC zzK?sp$qtb-*=Lp4YR%}gEWV`G{Mjz^>cNsYi%Z7UUtbB@R)0GY&ZRTux7vqFE)Ise zdB5i2t&A8N`#|H759e?(gmJtmV`9+~%Q(-FaO$q_d^_c3zOw^mzVCTkp1n!8B0I|V zMR<*ev44=khHcx-{x5Mzc=+P(?sPG>H#2+J2Rxd6;JLB_!;haks2+qhrOwkjm|!+OOG zE~ayHERDIenU?7`{{Hs%>V}!wOm9J(?)1*cL6bL*gwp7ztiTZQFoYWscBdI0%&{zf zblHD->gpF~Z~JXeKR@s1s(MlWU&SvJ*0Nb7AKSCGJ3DLFQKjxL=fYY4$h1A0I5)z9 zVS}*$zHnIU3%hj=(qIp1Aw0B}sX_D0^h5QUEHk#9e|vTHbtm~5-tUcSe|>pmy;LB9 zi`j}}%k&0@glf-fJ_2#l4vLe{NP(rx)R4J!kH6i_Nx7e+C$m1uQd;}x`cm)dUB{z% zWzWpDHjn27C4<{yJIsE4e?NPFylKx_2`f(a_!7^_pBf%-I;}T1H#a7@ z_pr$_J~ah~8wb^{yhb$|-J1`J#RM4E6fm(cXtR`9Gct*CZz*FacyptCb8b<(%lmtK zL0u}*e*Mx9ps_^I3a;~ZzjNyTU5n0t`d4r3m7s}suh;Ld`{()mZRMW-|9%_h-rAB= z{dk^X$_b;lKQqq1S_0brS@LMF8M@7=nf(^1+w2s91@hG=`x!+u=?f2`d@6`YQd$#Jl2+N)F`?a3~5;o_p*bsP&uj0>-kA}t1 z&g5u6s52~hFiG^=i!!FCpcdZm75H-lLnAAw=rvgHww9GadZLDc!-Bc2QQ8a^m7k{Q z@O-bc`?Yj>oE1M~*e9*bqx(Ub%zB> zjn_CBmQDR|uckN#)MRS#*|3RY_ZsTxj54Fqyt?+J$F_{)q^fAae#BD(mBjbTC&QiRk6$2wv zDGLk3>x3;&LKrrvX1!B%SYXPk#mjK*+Bwjmg0=jm1&+;&($CM+m5by0IJfH6%A>jU z(VM#B4_{?IZ}GS%qW0_6Xq#ov?pY)s>&fAM^0D&s)9LcF*0SALyK{S%`+}RG(T-)8 z2yD7%nWd<}aD!(_kuM9w>6a^%9TwQKXz?ixId`Tbu!-MRiR6-cO-$+UhXlC*^@p*o}dTsj9s*}2N^*H9Y)@bHE*GPFT6 z)TylS92z3UQ1kce_M~rbECXM@s@Jrc9`@hc{r$bYk0*KS&3wOY|I@gCpsCSLVfAOe zx2i=CfNW>oXbR6FJF}UYg%rQDg9uJ?1u%8%!}gp z?>oEK*P7`pXpmBDvKxNiDqQdZZQ*w^z3RiTK~wT63&)n}4yud?zTd01xBFY-we9KK zN0B$y#=AO$rV1Y4OrL-Dx5fWIpObe!)rxl1&plfG<)ZuZzf0G4>hJsUsO#AEJF`Li z+CZt^RqUm-x4!Lyo!c|r(MPv%B|gYt(TZiWI3at{8@~yyP+|D-YIXjxJ3EV$KRh@H znkKzC;k@PZITf$hZvSMLx8q@3*DtL*Hd$9zRD3)t9=-Lv(|zCC>({OwvwpuvICfV_ z=hQH%Yazx@S)x=F7;Y$;nd5I1HaG}_wyGa6*&e~LVQ0`SL4^xpOuD=bezVPNkM&mT zSABUgac#-=lB0*MKOA8GYzLZ>0Btoq`gbYcD>jD9Tn(A32fkU{tA4+ChGlV@&h9st zF77U0|E*$4dWjGt;{iXTi*b`NGCMT!K`N-XDhdn{idzr`(lj;(`(G~}|9H^6vf8%sn@C0`L&2XP{7Ijl_<#No&&3#4HK*v5reWcu zBYS4IR&qc1!UW#O^!JypP&3=s^Q)St{@PvtP(Xko#^TvY4M?*ZIopKSWMPjiOf4%bD=R7}`lf&3=+UD$Z_d1V^QNOv$QqMt^7#%+mT~GY z_wrks9y=(WVL!oB=*HXVQe{#~40q5kOS=jW~0EnYD6x+!OEjq2&2 zo?Q6x)q>Ptf-gYBP}4ow@%DE)1WqU@Fw9_F9UabiAW!QShk(RVhkFbUu3alLnSFLe zh*qH1R4)C>0}~?B*u%usAbHTQOq{_+^N~3t(_*lv@6^b* zx3?Gm{q_!_jcCVy<4_~RPerK zoM&4tmic^N$x>N{%YF@&>#nblKi(~_AGLJz=FK0!yu564SY*}D4-cJJ|9f`!sncT( zwF{uZ;*}3);?Ex}U0fUtVj?08IvgwJFf<-w`oEMR;kjPJ%fs*P@0Wl5`t{6xhOF;F z%N1gRRXi$eJo?xf56EPA{o>+a_@;WPk$~w&92^X32VPwZW!Nyg%Z!P|O>=@dL&Y_B zhVA=z7JuJ&rR@8=yVv4>|IPe9dF$JKl}#;gZ`qW)GdvFrHtuL(c%b0*3x6Z9;lKhW zriNy(uP@XYZZNwUGcqX)gOcg3TYYJpC8v6+dM&*)bDg>D{n>|V-e%|JtrKO6iH`0* zdGci0=a06s(t9>;6wJTB&o#Hks|5~Zfn>)An z_V)bkWz27K-q*;vaunp}>+h@mEq3{Gush?)o#$TK3TuFh%MO3o@*!NM+#CS`1{=mn zUzal^gc<(j6tKu{+{1W4-u_=-)!%Au&~D7bdx8WEWIxZo_Ur5G>-D~-hK7QxSFhf< zZ=c-Djt3=QZ`p2$wRj_t0BTx1xO2xRX4jYS>Zo$2R#p}UZeb~0_QDc_73kn0gHJYG z49^0Cof{5Bay{W?`1h++V7}ekBdy%xNr{OMb*5h_UsJXBp4GSV%*>VP_doM6zI*fL z$ou>IAK%*AI%9^!`<-t394Vp#3}>{K*)!rVnC7S{FjUMs$MBwof!*O!D?{T#kd4b+ zbMyA~A3l5-QZ%*gI%m^7-<@N_%^bI_QN0^CZj6ZBIWhfa7RMLRNw=Pl@lTDia6AzZ zU^vrwEmDc$1}Nh;eiqOWVz_hjXHm(Ox94ZfoZ0#E<;%|zb@wgZWtr~Wz1#c#{^g4& z#QV$K_FO8jwGud?q`)x4)f;qV0W6@9Qw*%&c>y{(z<H)RkiN9Qp8 zXJBCX|KH(^z!up3)^F}cPrmYW=dp+3j@usb2`InYkmM6MRrs%$-0O|^kM=)aId93S zD7|2zUWuDK8E^75W&3`QlF(w>IkW!!m%Dex*$Zb>?)v@mwPO1ISCxxHkbtStQS;GnGS@i?0opzZ1MwO=kW$G@6eeoylK{{R1&>%UptzjN!Bl(=4u#P4sm zmgnYFzAco?n&zOgA^-mWzx8hpG%{b@qliDn2q=8eXjEru=zsL{yuC2PzjS3`7LGUT z4qRdQaB8ajF@F0$CVeuNMt*ZFHts&{SM!bCwPF3fU#~#RN5wY%etLTP@m^{3W1r94 zTldM=*FD-M=l9?{6VrkFvwsli@N>M0abVa{y!)pzYlASO?Hq>2lT5+P2dvBA_3i)v zSN^l@Eqm62ZBPCRKG6C1`@>=W=N})1oT#4v&%An``MrwLH~07FzY4ChX}r(L!BFr1 zNSaVN*z3<|Q}W^hs2!>Pe#>otgKh@=;MUgc+xyvmw!iiNd)q#){_mHH zN1f_nnYFvuO=w^!Xzfc4#UF)h8X6c19!+F{2V*w}L%Mg&?y}mL9R->D&Vz>6L2H33 zw})0V-QJ$x|9;=^ynU}$2CHv>e0=fh4clbHLmU`(ENb6OUn@?JdLn~Oi>-b`v>C{S9% zP@uG+U0A^>|cQ1O5GXB%hzJH-C3$r!k+LjYZmgmK}ZdY4iVV-@4WG+xz?We)H=x zZN6UlS6VasUhvEYh7E5NuECbuVK2`Pba8VqsLKT~SO{J?%qcKKXTuAIf^8RcdVYVq z&Heb!&i(zMy+3>Ye!HD~e_!q7^4yB1-R1B5&fEX5srmo+`{Oe+&5xbdpFgX;k9YUY z#J{X84X^8y-xKIaS8FOT%vqrekE|QL3MA@1LHu)_=^o@9($UAD>Q-KNtV&X8L@|^z;8J zW$bD)Bv)6Q(_ zU!SXg`dGxZ9?;lCo+1W8Wi&A5Dm1M^3 zE_=J3H?IEg)xu|IUOzsmKL5|#>U|0uco-QU7+u+`hCfqY3wL0!__&SfKxc!TU&Dcv z#=SfY?{#-?Ev>HkeD>#C{~N#a{(L&E|9zirpPa4L|EmW!{|BA>A;)ud6*{_c8z5{pxzqCWN>C8a0`FKAn2`)|T(i?`{8u zB33mp6s-Ichj*O@BU84z0>hk&OVx}Ijx7IJzyvCoEULfxPoAHw?r-q>>VfHcvG@Kx z*(-lc=S=jo`H>kFe|~(vJ>R3^(E4Ao&lLB3b7o~};9vTY8GkYpxY5|aP{5w?-QIE=j|##+^BfBGyQ%1@#`$FSXdfL)i(;@5Bsnv2ZkM&o^Q5+DBIx0#B?BZ z*R)v7o;GrVy`Zna@Mix+=v-iRbPfo4!dlzk*n#t7V)*}zbco+k&jO`sx& zk?}$DOyD1&JMvPhVp1H+CY_00wl!40cG$z$)Fy#$hnrUJv8J>6>|9&0oe5nx#NFmSIb z#KE|dhfbga!w#1kedvT<&a?)Gg3a&V-i57^f|v$z2qHidwzIM{?ACqr6XvA<`U(tR z{0a5R#WWQdVwNm>4vR1J_=86*Dx>kZm;i&F*-UnraG9C{!=0J4-3g2Vq9?xthgew} zxYfV5AV(1>c2T`|BZHCgf!qB1v!PRG-$1Eq`mMNb{K@gPz5+wcf9dLWi0KZU4GbHe z2wcN7A6ewUEDjEa>rW=!V}rN>HIGBY5Wxz(G%y*E1E4h%bVD%X3%A_p_N z92yuJzk;&k^Vq$x<7)#P7$Pb}v`ca*ufe8O^!fllru3M*t_|g z7bLI_v~hDVnE#P)*iIlRvT}1Ui1WO933Cj;umFRd&#~|LZF5LaXJR@qcSR*^1xf-t z6Vn0N1(mREM!4d@Cd7f^M}U+))N>p;Xuc*LK!=tkp5(^BCt{fZ;;tO9`!h#nnj$WQDP-7_J!e2jt0|Kf~L0o|0 zS(qAuI6?%eLvI7ahG!yT_!Ax^l|o`>X9I)5b|dJzA!Mr&h9WCx$zow?FkQZZQ1l~A zI>E})uyZPCj0PbFu^M|21t=>ptg&o$B@mDZ=Q-#pFq~QI1C4p?h9c+IMkz+dgtMAD zut>+}7>K?iM#hA^RO0XXxx&H0knNW!NOU|;;O1Z`)}Bn*?a*Ygz|DanqL_=o$=HY> zVrYzUV3-j-lfXzG)O3(OQzoVZvw|ZaXO$5XaZi|-4%|7Vf@B1K->eW6V7NBtkP?1X zNO3co6$mG%(X2o?IgMroB1+cLS^=r#0hNbX($#3K0I41EC8yC^0Y~CN3bfG%5=sLT zDP$0NaI}F$xM4NgKpJfzVJVSE`wB!Pi_vZ~)?ybqIgNIk2?h}((`dIDQD-A39^~3< zbOZ@k$RHBf=m-+wcJt^665)39=wK>x$%DvW$RnDg4W!Wq61Ea~bTAdmpch&e8XZhU z3lMC@&FEk%;YQ);U@EpE2(^MA9ZV(MC>$M3MNKov4INnMjSi+_E2U8@yV1c^A{vFG z3oi)P{-X^ff3M&}qnxe0&$JUYifxUV!i$AGPrMom|veFbc# zG-?}Yw6B1gW*8d(r@p_Jyj|zDeM7uV2*<|OLjf*@Ggc&6NJnqI^69`T!PC53ZwVy@ z&FtLDwI!ylX}QfYlTx>}L77w9e=%G8%r$eGe847E##S(6mXZd?i}kPXz5o5@Clh~6 z%aQiqm3Qku?4AGn-<|WHcgD&8t9ic*%kJzc+#C$kqE`~X-!_qjh2e0IlQQAhhL$S} zVjLJY-0@O{atYU39Lfp|5@{k*#BU9M%EZ+0G)xPN_fXRx%n1$>jEn~i7GEHKZ@7lI z0E5o?hn)=!2|K5H5iV(XLQEVo0axfg5)t*OuvjB8=l;C6~;+qBD z4h#m@Y)bH-S%(~CT`VjN-7`e+A2)@RIvXRHm>M=dTPRJmn*u=RcOO{-JA@0lK1X&4 zB2bP92{81S^4}#QL?N0Ql|Yy3sksv0EST27kg%rmMH^A+3FJxt`0~ncDZn-%yY{+%XT}ZS?)EOBMSovO# zBEmIbGZ*BturS@@R4zO-{J0rqR*~Pf3iB z8m%V?FFFxWa2T!Zh$@mtn;k?I$)m{$XSt2qavUtBQ;XxTB-mL1pw>04xkisBNaF{_ z1I+w32E7u7O1!dGCU18>pO^Xb)6>kGn^IpMWS95JzP4uNWt}xdcMUj1xLbG`=2bqM znfc_z#FgID^`c|WSij#h`QM-C_RDAI@3V{%*bu!vFEql?d|%nyTT`lg3tZl6H}%TF zyp5omfSWG`0;FZ{<6*Ith7ToK75}4zsBn6 zl;BnW*6(_?%B1|=owL_AY3sSX%?^+F0lhF6H8EhZ>&-i+g-i{xyUTp-|GxAOK0nV^ zdfm^^{guo2vvP|q`TF|$a=Y4JOExASU&dem<8ZIRgZ=;izSm;eQTX`SvEtpIRI)DU zWyS9<3aguq9IJS|w|lk23Wf*b`+pq$veLhH)ux)?Z?|9Oulvya<%Dv7&c(7D8xmhu z-~Sz_%wmyztjDDK+Z)|$|JLif@!oQM`?}s%e!n|GKY{v)42@PCEu0L`V*h`7S6?Z9 zpeCl~g(0;)$h;mmYODW zGxx`bhnoB4Do;*QeYtdcT-MJU-@aY_)P0Az;;ez8F;-7Njp4^q{aVerHJ?t3dhl(m z{kl5-uA1NaxV@Kr&F_Y^vW2gYoBOFer>aNJ)~Z+1c-iIb*5b3fN?!-n?JcOQyZm^~ z=5t=^a|)b9S6To4a`|$rc-#y=`#&G9tc~98mdSVL>>NwuyM@PPd$U2exJwx%I6N-? z>{(Y^$oHUBCU#fJ%3rqsemoB5Q_rhAfn#s=?0I*p zUax(*Zuh%Yde8U${`z`*rsr2nb~biCzB7l*h+NyGr#?xf?tQ_{{_7LQ~qY-akDb%GvDXcd^(vmeSgio{$~sc|K>DT zl;5u{pJkpOXZ7WR^JR7WpC_lp-=5w7N9&>SIg7mo3HT%BbtG?{aZ#$*x%ZrJARxg*l+HRe9uk3d2%X8N6eU{di z+C0}MvLfL)BF-Vq@aL(1edOL#<(KDv`X_y;_S;SMyG5sUHTS2P%U_Qv_MK&%?zeos zlubp!t~Z-bOI<%_|NqaHjEjq26&EuY>~}MNf9U%u?e!*EpTFO$`~9{zoay;>mhwG$ z=HgGo|IRBqr5XA+G(2|dvvYHASD4NBnPsBcD`B{3*R=A_(HjyRm;XL4Q|xoi>K+Nj){?)t;Z#=6APl(E4%S{^!-> z;qkSlTW3F-WtzQ8mf8B9sr~+?`>bC5A$Tn<)TfODLcdZJ)cg!65Tz!&heh;hZbSK6?*3H z2qetzD|4&^?NcKN!B$N9(Ko3b;Uw|>9p%R&CS4ZBJ~IePz}r~0y~uJzlu zuV17e>e4`Lec+i2uKTQ;A!v)=pTQMaqYVz*u|W;UJ`S?TBI%#5pk zyS3zQ>Gh?|d=?8{>`ps7EA;B#pU-B$>@hyK;@oWJhM%IlEM<1Q+_;$WK;7S8OaJV; zr|8_aM1~=!)P$X3{oZf4jz#VNGG5?tuO>(D(PP-*Dke_kzQzsFT%gJ%{E}SB z1xL|GZ@1r{_io4IKBWsWxA#_mU-gYU{)bc4?y}tF3=g(770EIl_!CoSCx4dl!1~&^ z*_lsIO}+Z{S$&xb!;EtEJ72Eu|9SQJ>aew5+F@%v{B6I6NExU3d@Vl9c;JuLqkXl% z!>%9ilbwC9;&Jb@Y1=CG7z99gd_4TQcuaw#lwD0l>Ad&nXBww>-=BK8#4==hfBnDD^D`eE z>Ad>$93R8KN8y8plL`#ZPu ztz8#i@v!yfN%i?_&YAyBKhhznx&NMp{Qkdh^QE`5GDwT~VQGGVt7u8v-I;QI|I3TJ%io(MAM1Jbsf}0q(sR4-JKZ`N5}FTjqB##&(NR_n8aLOu zxraO9-<hF^(-fTP`CNHiRGh^T9x$jHvc%5ZD;QKpE z#FE&J42^f46has_xcAGwoEDvzxkt{NTQ7E($d2PQ}mHoKb&hq)3;!B0cWv}ljd%ySlvg&s`)z?OEUsrYYL%QAPnQlMwFD`O@ z`RDWb{44J=7!1Cfm%X|1>i0DL_<8Skzu))em~{S<`~UxapBwjnHh0nc@_Uu(paS7C zyWNLIttHdTKfbp3_jP^!QqRe1OaF8|u6bhcc!Hwys?WXB=F1{Cr!8fduQ4cnf6un| z*X8+s>T^qiO7;I6=ib_~CE;MxvFB^QUezcfdOPp#R)-Y~31X+$Go3rQm64fEgwgKX zjpUb$y7g|YDeJfW<}p3Ku2RaP;6d8=S^7_|fAE`UW4ZU!Ded0V)=~^P_g1cd?0vuT z`P`CQnae}v*YErFYVEhJb$@?d*_wSF)E4VIetG5cc~Ntp-{t+hx_sM+%GbXt8$wbzk z`Fh^&ch2#(uk!2OJ(mApp?u`J48xi1Sw^W|R!=54TiH&we{!AadG+ICz1eRPZv4qv zckwfQ{!TUCg>ThpAuE|@w-mldTTSmv0lN>S{H!vRH+bVNM z+ODR;>eY(HtFC|7i`ilD_wW1q{5?Y37w1LS-~T-Cd&vFC`}Nz|!q-M^UF%-<>u>G1 zo6D=_zOVcJcKW}M{q;+Zc8iz)Ix8b!18TiH@iS2W>{i17Sw%go*A$9$;c>Xl!3> z%0#Rs7rY!8Hcah#O{{tcg$)f12@f7-^b*;;W8v5$B*2iP`q+waT80KChmHb+M1@6^ zGPd#otF>!cSQw&D?(l;eKsdOVxH%Zuv`f;-`~w;&NUcxLfo2tgF3A!Gi-Pg^!M``u4D0-fwf-S*@zP zbn&n6@7w#%x2s)kKe@SKb@+Ne{XHL?c0Fv94&t-hcDwM`%jL@rlaGa*-uG-)_N6(N z#kYD7R1q~k_C^fk#=pP5df)%|ZToiaw`;fG^AeA**(iHzoA=s1J1iM?RD66?^0?Pr z%(mu&Bm2_gbC%0j^@=c@*?lXv`t4TN>=znU4;tB5l|H|#e*38aL(X*1XmujmiwEB6 z2^cZ#$h*6%pq820^owL0@q3ukmp{dB$9OV{`R z`}$>Kf6bD@`eQwkncv>r>^)y>_#fJx5p3kdZwkP_*t*zPHBfjt7HKTl*^_vZcFJ-UaI}J1r_4eP* zyt})WD)-wM=|*l+SsS@IZS!+}iw6x?_SgUaawXV*>7LWE;1RJ^>-YSAw8*tvYk9df z!;gF4_iev*u<&S?=*w2|IE~!5v8%J|SU+52YLK?L6<#&(FVass8iv`0~mAb~^=y-t5>} z_xIPA>-+zi{(Tj`|J9C=zqY^MY+l_E^6$gu`G0l(##fiizj+z+pZ|~V#W zYAQueRN30rmFKZjce|jsmgkplCmv6!$99{#*3aIuMJdp%e67w#-f5|lSH*Z2PMu_^ z`P=&Z_Z@b{b2mSKGw=MO^BX@`oS*Y~XWqT*rF-rBUw?jH9Jjvu-OlCrfBM(|y8JZu zeO0*aw+GGq(>jIKzgf?3xGLx_6WG5r_0383`FGy``SJ0wx0bkC$BiEGxQc~mW*RS# zsd~BebIVSn`rEnN*9I4_4-Jc4nzQ%owbY+ar>{SL&iehHqWiVqufAP6J#N>V?f2`p zmgcUyZmP_9fQ3D!m{?3^36i(RfF!M6VQ+wIrS-%#Ciqi1LF^J$<#+^4_q|F83uST9+b@B1RJ z?tD!C-mjM0I|Z!ybf6GuS+vk$fu1TQ@Y(-}dVjKhw=E+wA`TJU_kV!ZUNBJ=Slx zT(%1Rax1r0c#Zdgb+$r3qVje=eYLP<->ePs#_EZO)lQWD{d#>mXbA1>%Ax~|>{Cpy zMJ(QIU!d%Gpyl-~(Yv=CcidTj_mjnSbH)SP_rA?deZTknJMneW75{H;PM>ak-e&Xt zhc}jt&ayB`nyv>#-z+qvxXZjTpv zb4#yjM*cr*em}}COGqH&d%B7Y5VV}eqG@Ot*JkAYaTGmuP6r17f00^ zT4%4@nP&O#$K%%@StXy@);_nsuUUS#G<@#;KerRxWxbkKb4zi~@SAP6*4UR}gL7gt zG5PgChgd}@8-w|cgyv1J*X=G#2n$NTEuetqm`;SN6*Be5gJKT3;O8EchxxIC} zkcjv1yFGW7XP*CkvA=GM@CUDe*SlV?TOIoIQkUt%eJz)aHvMC{KkM}^#sgLlkJhi8 zHvLrP^w_e*tcmepNS_8qOMjste{daJ*Q)@AKTJpi$Vrcc0a0MK2Rd6rSdD^gzh59Jf_*_X>~8 zewAImE8&(TXbH&Il2tBprB?#aUQuGWv2cSUF@5#~7w(=D3<*)!mzm~NFA<7m^3MFb z>)WmDa=)dlS%<Bon|{MY}MP2FGC@&0Xo zef8Q+*LSYSfBb6o`gMuBpG9bGP|f+?U;k&Z%9QC7zp6w`eY{d+`h|!?t#2nPBs29& za-IOqo0e85Fc_#kpHu9&{8FOY*7d#(`JbMg{CewIyq1`n%=G8#64SVffBHy2EX&YS zJkg?fTUl{$3(M?}K}-$Jp&>p$^bej*ogTZ*PU+y$8EISgUN-x_`~KfN+k1b!ClpVQ zEnB(!@^XLu$!fk?erLZICo(li=kF=}`6_&W)ce_6mrTt+c7P$lss86%Q^s>=DtBrz zJd67|?`QAU<1a2Q&K5nrO!v$Ax^J6rT{17eq_-pUu*~g7QH9U5Gwukb_$q9WWNPSb z@h7gNiB51~V`%rDcB&NAJUSihZyTzg8GgI^$wYUrC}w`MTL*WRS-cgV|HGy7|L^

&$vsiUs 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 F0RR+zi@5** literal 0 HcmV?d00001 diff --git a/docs/images/2.png b/docs/images/2.png new file mode 100644 index 0000000000000000000000000000000000000000..5676619977c4c54daf14cd4c0ff67eb8cad28df1 GIT binary patch literal 190562 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

ADtRPqs4>JxeE*vH^F*W#J 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 O7(8A5T-G@yGywp>$l6c< literal 0 HcmV?d00001 diff --git a/docs/images/3.png b/docs/images/3.png new file mode 100644 index 0000000000000000000000000000000000000000..fa3044cdce9a7b27abf71f5f6662929722c8d42e GIT binary patch literal 243702 zcmeAS@N?(olHy`uVBq!ia0y~y05RDdIM^5%7`CpFKES}h*(pLe_;SP&cLv6i8#N8)@e3vtK6amvBp_n)3M&ER~xY4)k> z_P_tHmf&#ZVr1};dE&FsX##(xJVQmNgPJ}|!-=-4+b>&xDVPI$=WnC`(<*?DUtw`-hcn z;s+_7+3e?z)v_=CdwSl785bNY9CmoUP`NWlOLJnq=;?|JoPXQ1jnDltO1{JR>&qeM z4-7A4tB%dwAz5(v_<>4`3V}H{xwCfO+7Y^Q^FQBt&XP5O#cO4c&TR^63vAN#i|@Zu zdhx5&r$wt?O#gcE$Sli{(02jnuYWGyzhbk%y~X>s9T7{a-gxXwbvB_xIlZ3%t$Fs0SL&$x>v)Qjiga6h#%y|CqlBf*pf$cI{oBv<>n9FGK zL4x7f?ENL%^dCOn$kX5~&gxY;(XD;89?K823(fvhG&itpJHVOtgmF)!JqKH2f=mZ% zr-GjQ2ZBy-s98*LYG%CH z1I8D)?={r1IC^l%CMqoJ5KZdep(Mv4&FOMzLWYW*r>oI~9G5PQi8oJ}d$4X|ifqqu zdNpDGMCKEQPjoId-f?-SeD{R+6XvdkCRaGNI>=rK)R2CzMZU+&^CZ@jQ#w!8s4SJ}7_S z5aztu^0LLqNi|VB(f*-I&8%G<`5i7wlV5mzY4lIlGHkc#-Z5jxydB*YQ*Jocc)U@b z=&?*CJcvPa+7WfpNvAxrJ*_?6J*IoaE-6ou-6VRmS;o&#+54pG6R%HvpAtW*eiAOS zcb%W)|8en=pq42!r!1YKJ4NgitC#rF`B@I7OV|R0S6W_Sy`q)H{8i;E-`A;qeSN)s z>(8;scAl%5t2OtoReH(0*L#*rUW&psO&&TyIHg{bgu|6n&{XN#bal_#t%Z{=rn;CEnLLtwDiJF2H|0v+mF%1hn`0I?E7}UTepGzyr*^C);nR%DGfU6d zp2}%Qg78mC>&EcApHFuqb@Z6i{cAk4ZSAW+6y*Rz3=~>gc*R5E+ zef5#jz1hb(4sqNUyd=0)dEM@dcP#Q;^S(`OIY4Yi(#_qt(#nbw&Y+r5O zJ-vF~Z?W&U7xTLJOUD}RO8w%^FV5fSzV*1M|E}~M&uz}9ofl7zIo@$BN22&}_e0Zr zudUaIt@poYcdzI@+xt9u>-jwMrRKlRQ7)6IHvHYAf6)9$`Mmdz_rKTOt81;R{`2ok z`RDUr??3!svgUEb#T&ZG@@zL)J}{fHmauJNGG?mhc*C=a?-Bb|Hd~Huykczmymf~P zpFJrkE1K87qy2>QxAr|xe-%D2=x<9}D7f(H!ncWSiJpnC54~%>-ICsZz5Tmeh3lCv z3n|Zzo~{_V%DL$Wg+IKi*!#HV*jdSPr7p3l0$cT7Id1XZVzVpN#;WelkExH}AGvYd zBY9SmqmF)A>YKY3$9FXCh*uL(KjOP$-Uo}il0R>LT;}X)S;=WFbWf#CMbCH7+$U3( z_+2p zww~;pobF?1eKg1G-W2EHugg9ye|J_PWl74L6F*M$KfV6xw^8Lx)0umj)+O{lm}wBP z!|R4Fm%v&9+ml=;q9%Sdu~w)~E!%G45u^ETVu9*w75yTmVzXy^&i0;?WA^CwFQdCgl{de> z|Fi%04uN=$$Q%1k6kojMI{$R*)8|@uw6(PD^u%=RzW;ske)T^2h)G+Q)UNz~iT8BJ z=_RMv>GDVIt8G2l^+=RIyf6Odj;^h%YOcP%8XP`Tapsy|&Y~?suov{9U_bpIJ}4w)pF*U+?C=wATM8@+-Kw zIr{Lj*fX)ByAS3)eRse9+>f8P=B=<@TYa-y`rFO-t8bpa5r414+65t-g{eG z|3^&5z8BRSmnP>Nf9UNvy)Tw;Z_O*N_osfYHVn63ry9Gv(DrZDbKZx&%gsOM?b{Jr zvikqGKh`bQPs_i)54&f)Km7OX&-uHp_FD7b<==b%o5I6`Z`+&N&&z4b)xOcH^{J2f zdE}Mn-QfP^?7I)|*8gYs^832a_EBa1W?@;m~m9v)qx*gAQR;hiMA5kn8(rwOgyNS_b z7QchZoy9o~XXT7|?}bKxJ(AE+RmEqzR%4Tmt;xQO4@aCU%nd%AVqys5W|;qknfdQ) zb~d}*#)J1*9%M8=t63?eWF!6O!J0+i%(Q+){bT(!xz6}S^l~o-28OQG2+uTMUj{7( z1_llW7Dg!sRt5$JMg|53J4R_Z+l^6!ff+2$#K6#=$-n|;GcfouK)?hjA3`%vYGYt$ zU|X><&B_Vi?6UXQ2>tmIipR1RclAn~SSCLx)GKayY!m1*-AUCxnQK2F? zC$HG5!d3~a!YZ%W3M8zrqySb@l5MLL;TxdfoL`ixV5(=LXP{)qrJ$f-Qp=!2sK6g_raIxAfdGB7a6 zWV-l=FfcGMfuogyS%HCpL4yHIGb=DK{tobovNvL2aA5FsaSW+od~=t*MkMt5@sE@5 zaW4G6h~tLC!M28`6*eZ;N@5`*EZSNMW&tj&N4mI@++9Ti1qC+l0jb&8+}r2m=Oj%(gsK)5nnT|DUsTOH0b#X_IGL8|v!%1_cGFs;eKr{&)pd&b1facOBkucOg1Yh%&VMYUDCWEps*3<^G!2>+SAqdZ^fpgn)0 zB@YQ^J1{WTb7Tl?D17WD#WH8-qra(>&zN?vVR+EM*zEq+-*e{n>hF2=JGu?@l;B;VM%x5XFdJv`?9Vc6I$kR6N*5~*4PVar$QcS9w z{xkW`GOM#(5&T@)eAcV_*gy4^>pH;xC!V;+F+;1to@Hz9eMMalm20#4EZ9klKbAlG z0Vy&H67n?z z6Ndo96I;@9sDrME0z(A1yp*#WN#1H;Pa5au-xpC5QCNU$iY=MrG}vfS*tma2e|P|~6LuddTgAYm!6VwQuW zW8;z~Z^UCS5s{W&?PFj(uaIm=D!6{%(!!xN8Rk;{mIG z4a{G^En1wcqNb)6(0+UeMB|FDOp=l>C(WE0`TBjcG{L}P5h&1iV7RcCw|bSQf`vtd zlu3q$6{`U+v`ARx4oZEKCQUjMa-j8UF=G`G*>*)CBU6LvKMuZqj7N?h^-M{*aC+({XIibOb&%gED0t{ca|8T6^+tI&dfcKi)UR za6`~6VfgEIwlzdSZ{56^|ICGWpbq#j*`cg#+LEP)yc_24*vSKREbhwe zK{z8*L*3J7Nt~R#Dkdf(90+sb;^w`%KmX10)rFE!L9A|p7C5j}KdFsZ+Owd*KnR-k z9;i1qH8I`Xu7A=${IL;K5MSx`PlTg`A>sK9jhC|p^zXhp>NUHABU2zOMlmlwZePyn zlM{JYzWkI~)b(fD#Haq!$G2K-;hQ>nx66r(vWJ(ZE)G~JFP`%D_WUpvYvIpNkDuMS z>07(Z&*bWTk7erDxoqd0_{+WBdyZs$%H#yjUR}N$PnU~(eVgaxY5e&1|KxQkdDY@aRJOa(`{@=TVzC3Iqxc|>}dKZI_slq{)vfmPj6PqPCv`a$jPv)nth`zIK?!+ z627s!-2ZE--+3Z}*;FkcnehPkY?DdRx3*1iOH7=)>*tX@HkB!_^(u?~la`)a{pO&v zU+1KY&yRXGS52M0t}H%l;hAb{-)VJmdliqW?Nwg-^+E<`@9H~0K3(QY{k_QN=4Pwi zn^f#9=P@ksmw3qnag!IP0K*y)adu^VQ4V(QR<{LiOby9VCX+wDjSAz;yf$sFQTcWI z&{v1=o}A9xG11WZ@twEdGJfB2&HQw#i>JSD?Hfm3Hn*7{;(b#6wG01zbCulm`tK`V z&1pLx)ax^uF-XWHxkacXY578n+7;PMEDW!22|umFld~YHxiN`xKRbhd#+`s=^4HF( z|C?NQUn&2s?f& zPI)hG`OSO34znr4jA`;J5AU*hpJ*#rF)_KKFBSs{8OC}}0fsNrO|CmatON%acH)or zgX;_r5-$dBda$Bz(u2hfp+$B3V*XrC`)PaGTygg|UFWAOZ%cX9i+Y@^SW)+26$=C2->|B?pEL>ufyVF=KZdQc!AWf}D9+_V&q}y;9R; z97W@GJ$)uco9C}g(m%S~Urtp2Z?((MCHlK3Pkp^9<<(}*Z>P0%t$X^Ww%IDJzS92s zr045RPx~uhuA9C3ZK(nqgK-h}leJ4vryOFBPC2{GC3DATZqFZ|gFpJ7*>p?er3A!1 z{j3}eRX#@>!AS@o;jmWdLo~yN#Vh}9|MB9Skm#e?ud22cg*h&q^Z#-Frk!1(4E(vG zTA$x#X-s^$ueUb!x!B1UnVz4X_pJ(@(rxzG`qR1!&b|+Ce{dCdJ$as~IVtk!$D8LD zFG^KlW#H!KRyEnzX=7NvZq0A?@MXI9RerL%UegtMdsFA@{(5JrwrAcR9v-gSkJdp7 z6sD*J+gKQ?zrE9S*57ktQ_PoVPLZ3dN*#6^SwIvZg(`ZPyI>jXA29}*+pA{YxwR~H z>z((9Zr%65SS|`iFcwo^YrIR{5lO|s8om@D5zW(h=#ZOjlz5V3p)o3ri`!eBM z@^`!Z{nBT0+Iz}|4I3u?u55MC70XCjwei{0r`}#&`C3!1C2_U&9dJ|(h-PZ&KU?SZ z=uua_oVU04dPnwC(%NPeOLSx_*{eKQAy2iG2LmA{PwTD?U;4z zFZvI^S@73!3th2_Y&qJ<#e>fxC?c~((xI9+<>aXt} zzYE!>9H7gzRh8k#AMelJcm9Wl|M>R)l+fJIOa#Mz1v66}H^VxcZyuH=TAQLy{5x}M z+Q0jMW0vj{zjHt0mYKfnj#WX+|Igi1THY8_^ZcGx>D8|XSvqsVY#*Qgx7@+(UfkA( zMa#{@gBcGjSfFr{zkgzQe5EH}{_Q(bdFwbY*KW}Cl>7Td|7YFm-wtyh-{bnE`seiX zC9wzNv@M?Ah~w3cuiv`tPTc2DpPp>LZ+7xVcD{z_l&Ia$jD_WRrY=1_?R4#T+kiZK z(~X}O^WUHT<448Js{4O8<=p%&%9r?{;r~h7?{{L~6-GXL-{2plyb-m~BZ*Nnsue)1xZm0NEc5%h zjcxR<^7mzi6{Q5Y#>Wf}sZQK>!#x`DQkDyEY zyzcgxKM#4u^k3G8;exd3Il{$0Q#>eJzYd| zKV4~_tZKGu$EoC^w0Ua`9_~-SmNQj;TcyCi&F`;=_+)SY{a@wNdi|vf796hscK zhJe*uZu-7Iy7T3iwc>occeuP*yXL{f&z7cp<762fe$O-6U{-f1_tVqq@i%8PWxagO z@Zh4mylU}to0l`@MK!0MJb5(nUP}uLC!gLwYu{M6I8!gPe7$v3Zmqq&@zaGfFV#B2 z6c(@Fd2Q9A6#>Uf-YR{5c6Q?#w|+V8`}uzk=GU3ZGR!Ht&0_g}Pw|@fujSO|2R;3* z_xkq)hJ>k+%)6RztMyI)eBM4>Oux=O?aZ8~7bEss9$(yd+MWuun zWsAm&n5pX9|4!X_n2%xK=XXMt9}dp!Q@*t&Q&*gCuLB#;3;n{v!fW5c<6;#yr`tcZ zShnWD#N>2_H6f}DFJdJ9miN59zJC1|%daBYx1wv;`Z7-zk2iAq_viC^h8?#jIe#c+ zDCpz-UuvFcmplK@{pCf^=T2Vxs_0kLYKL=kJ~n)Lbu~Etl==M{?d!4ilefNm$Ia-# z)bQ?}bdG+!!|ESvE9zH1R`7RfDEo2VF7vdh|EqKwNGKdm*R_uZPOq+NGcS^n>z^-rFNR{fQYo-j|t zcYlSC(4s?o-!0xFe3zBsZE*?L-Kp|Ao3-}j-rRIFgmKT2d#dx;7;bORSC8JFSIlxu zMs~{POM5DdPo6q8CXJNF5B|&E53aBa_P6~%?nFchfSJ0S=s7sUgX(Wh7Gm9%QjVix1W@|Z2nrG-$`GW zFZ%xR{r>8d6OqrSRld6P{ocf7zOy~{t(V#-y)WneGF6;u&6$n+f)p8EXnX!5B3pZdvNg1}3)e0GA6c|2=4vF1ewk}fqk+R>O zxq+4S=cONOq@Q+e{_VMplc{dAZlvA6()B9Ko`w93E1e3x^w^oPGDJ>EiX%F8jYvXWj1Pl#jWztY~WPxznd7Z@*s`F1F`i+n&$gW?$RZ-4?GE zy)9>}fAQ`$eGCiYe6$(#D!=Ql3}64_z2w|m-+sUEUd}eZ>b;2N=QEerZn!VJdH$5! z>UY(mHhM1)iQAO2^344It8}8i>@t1!I$t8aa>u;`zfa#czQ_6Lr24W;_hKi@?zS#} zr(*20bni0XSr+%Wqgp>apI<*wGkDplZ?e`h$F0~I)bEw;Uir?#H)>nPLkoRnW#?sg z?eE4s{x9=$cTj3%}gm_&Cw%?Y`h{bGLoztWubXS#MXJlOqyPb#bRbiG);{eM2KjwwESbhH-?giMUx}Fiy<7k6cD}h555uxw#aHi2xtr0>Wh!I!<vt7#uNE_Uy!F>EwA#LDA3rC975CM%rT$H|^JIc$tymaVJ5RNP3@o6x z9+CPQjkCl#vaauQo@n1@xGmIp=T_g-Sv#*BMr%!WFArH8qqVo^Rcwz<)dp@6L5k*iig#+BM$APv7sAoHT7_ z_|c2<7O~n4VsGy2_SRQL&vIdvz437I)-I-ojT<*EavNgq>oo_zB`%$o+IqqyWP8oc-9oamv9BubZm9hHeo>=A?)11a*O`hs*~>3af5pY{ zO7++L%CK%6)(Tzt7C7_bKiYzRZbb2EP0!&Yqq6`JB93^|v=0 z`?fPToIH6lEFp09_o-J+E-ZVze#P48-#bh7t73T*{{8(vt;=uYxA|3G`IRpgzP$Ep zL$}^UF*SxCFBWgUGq3tkr|sHWU!N0!+PbR}BYh7SG`G)*e(BYAYx-`62kqMTr~mr; z*!Szcx659|uNK<(O~Pb@dBKI7oAU45RZrHb%U&3&dg0!KUpa4HZhgP=dEV<=-wMy2 z-rLz}bmGhE?|WaIy{@XIb*Zwv^Xv9|Rncj7Up6F1N8WE|VUV>cty;RLA-?kWD(O~+ zgi`Ly_5?>S0*pZ|!m^&eNk`qwr>&TfF#ldAtea%HIg4?db9C#eJ-em6Qg-AYj=8zh z)u<|J(x08m`@O!)<{m4568lj|=Hcy+qR(b{rCttF+1&N`^Ot9TBpLqvouH_+w*PBM z##Adk`;$I%XV2AI*jexKe2V;9ugs~h7Bn^AWo2-7c7A##*ncADSGluC*7%l{nyTv2RT1AV9-rS4)+AkcbLpjJzS-ILpRe9O;p5}{ z;xAvXEo$wnjjDaSm395;{QY^GnpzIG$A>6!h;cAF@VfoGudcoJWA@X%pM8J$&6Z`@ z5;sHtwRw%Yc36$V?K2`LcAvSjyRdL$94o`ym!-wUpVzEvm|y#Cr>I!)YsY4`i0PNJ z>bBo6+`cuBo#AUM+a)pGC>`(Vy5!sheKivJ^H}zQg8m-ncQS09k&zEL11T1e_7r%dB$=j+eXJ-6sD1DJT`Q3zG>G~~N z46mx)wE6UE-{)R@nZI@Kw_C3_y;yrxO+->z`Rwo4UoQJ^-nQG%GdK6k18-MGhqq3v z1<%d2K5w&os*tp_a`|kodUx5%maD&amByd)eVn)TTJ`sLn*8TyWv;FN`qkVh^U~b3 zSFdzl7GCNs`p^75Qk3!P>nnE4XJ^&3E?aN0^X0MEsRtVVg?+W>70xUWk!Ho4u+H>c3ajarM+MI~9hE*H`|gMmpN>ef{~o zy+LSsWiU&4y8z>XR{=}?@pJ+qCDnpwpx*73=-M60)|R^io#)^CDrEfk<=WZXe=IqF za`B_3_5F`D{c0~Qe3|lem(I*zIbHs{UK?12NqsAbZ#*@-TV?I(Y4*>SRu``dfBr+8 zK|)Sc*S=g{T}bHFRg2TMCw+A1{64Q%+@U!y^N{oLcfSIPHm??QDBU|xmf^~TN&hy^ z{%o>zciG!%n%{j)71zqYxqEHXngwevwRTXY- z#m9Ls8y&`|mw6xyz!irPn?3+&iay>dtu+0`9N!N%ybLkzexs_3z}XtIj|9 zDIPcJ%a=*_AFpF{*j@C%@R!f?vm19w+E%TpdH>~}RNX~`oj;#RudRKxyzgA@uP?u! zniyZ*U^aJB)beHPd_Jo%SfsuAy6Iqx`P|um@0HEtie4V}t~@IK^v2^Sms>3Ra`m%` zLB-wDl7WHTYoG6;lDoiGUI`Hd#h*v?~6%cx?Xrr zBsA{2<_Yn=I|Ht*(fjv%$0^xMjD*Xr(=30a7;MgjFvb*wxO*BjD#ve03I6-$(R{Ph z??c!8OYdJ=dpe-<)iyRE`PZ|xS~Xv`7TxWs{q+6Zs?h(NkBi?ma^agF67Q5;8_a58 zzt^K~?!I`Va`%IR6|9pObMCkcB%yH`uD$h;()_rw;RIF~yk7YKWUOZm9tCX)Lw*Iii&s!nB zyDNSeNSd#+_^|Zykz0y}&nKtbe_S!A;t}VyWe%JSw?coG?7AQP`^)BI&tw>Eo?fY2 zx@^T)HHH%rO`d75tL```M zvNq%_SZN_48)|i6P2z#4r^8QN`TefE6x`vxep5e^@X7@CsSWYW4O-QXkK2s? zZYZ;JocHCoSY>wp(^Wp9B@Z3i*?(#?NYq~v_-XbiBA)m5MgPRGRZrgEepazodvEgO)cfC$GVT_# zUiIM+AH%x%{f;JE(ziz#hvweimb)~5|GrDRLbbC$-#g-B`TY*JjHA}|2NOS+tPoc7 znRMPxKUUSVIeB$hZO+&255Af|*?4^3gviZlCp7m~M_#==XSvzdkUycZ? z-ODR|TqEnx+)%b5=y11n*&Cf=i`?7WHg3BuDmeGPeCpf>F_D`VF+9lMpF2r#dcV%q zvsbE@pZNc;d|5{6>3Ms9Mf?W!+_>ZGuLjNya-MK|Tdw%ux~j)#T~pg4Z8;gTS`W+F z`U$<=AGg;cIMc{$(IO?;%SyrwBD1;~7!NQjurTmPY-nR3l!1Q)9eB^^Ap2*A*x8ht z-P1yM^+!gRow^hIKV&6;xq7^rg4;2kwNWSX-YqhzOm%JB?H!U?-Q5^?sVc)~>aQF7 zG@Q%!zQ0|tNS*mpID^5nE8b75EssoAtgP_~%v<(E{aTx08^qY(a&aBaSdHH!s_WsY} z`OFPbf8V#gUO$yve~-hVLx<+omH}%(7 zZ}wfKyB=@~t4AjK?%w~2so~eZ8P?A|-7lQCJ6`I^a3S=`gSyzTALqqZc4{@4#xhRO zYLY}C@fh^eK6 zQ(vVcO)Wj#rM6eum%|{+>9LmizCT->Ztl|v{3tcUzgO2-zA9pw&%V=wa+kRp)?Iz`rKZ{|IF`SK;la=6 z^Rrv;mDrq~w)g#vZ`+I*4@4jLpK^8e^$c;5 zztSu^BIrINQ!iQexBZU?&NFSE#=YKZ&)o2hVb1)=TQbwK?kzpNhl^p~{y(;vS5_=s zvSi7L&FAg%%j2IFeSUWTX|?c;?(S}3-t#-NJ=HqW{fpncW>`?`ySA(1-p=&Xg~v-b zuS&laD){-V$S0|eJKOW;mu6Hl9`Lt|ds(rp>OZK_JKM+gkV^5odxsbIpWF0Hfgxk{ z<`UljnGgJD|C3EMuWx6_wqnS*U+#MPdHk&SM-x`BlL&lds*h)i0@lg&;<^&S5YS#2 zQ8J|`^J>Vsj0p-C)y{;(oz~Hr(*I5M^c~s%r{2%JD!p#=@j{Q&0Xs_)dgffx4O*nc z=d(2PeR*8kQ<0O;r8hmj`rY`+`nf;P?Ov5@i)T92acl3&MSXw87~T}ltC6n@nR$4n zys+A5y;n-6$LN4^XuLEP1*MwzegmdZF-{q-srfP=j>%4KRr2N{B(boj7~_Jd4qZHA1u1-}-Fep}|h zKi-ns@`UFYBpao88E$RAW2xr#OYMmF_NtAS)Rdg0T3Vxae|!4$^tL%N zHz&-}o3FO~M7|`uQ{=au|02pVWVO`GJ0~o*Zu36vwlK(kodwSh`?VfrYR^vh&n`}V z%WwJVc-eoJ|1s|^clmZ)vA2qObmoWBY!>f~oWdDK_Im?1eHZbXC3*j!e6ebA^jX&b zZw!BHGe}h4`1mQgn>l#?t?T@pe3PbLpQ~{$Dji%)xu@K7aiF=@s{R&vWySCaUi4U!`Zu$zbLG_VZR=ciMrQ{T+E`0cdRT80@D0^;vgKG%IMSLzVe=*QeywpxQ>#qrv&PsPJb zUDy6w9?CHHc8B2fQ(v!(`rBu-Gwd#ZucoZG`-s(>f9z=y!LP068~=YQzNGlM-=e9{ z{N7cr+Io6Ahf*Za(LFE_Wg+guG* zbL7^)UAg@Esnh!6?DxNH{rq`bbIY!~c~S@V{9b3Ra-&5qzVhi+qtzO>j!)bAC6(dB zIcqh~$!fi+kNNFq72NYy)w{l@vN-b7yXb4%%RuE{Q+wW^PQ z=7j~@#N%rspPiYTzV>!}+Syr(%fGx!-K)Zov07%2_w(-)wWfqVJwG{lmGcCKgwhq4 z)Cn~l6aqdoF$yxQsbq6|pwC#(%HaH1`sDgp-vsRyDNm1W-fcR4y3bd8|6Ag-%TKTQ zzHds$27#TW7d{p_wLe?x7yaw5*i5_3IZxi+kIsq@HM_xhU~BgNDdO=}H!p^!q%7Hz zf8FobcYEhPlc~qwlpUMNEckR$L?x~^UJ5n{(HZ_`pL%Q>8F>^UpFalnb0gY z&aGWDx4qwgUjsC?5p`XE`+d8>bGFZOUT-KH6yNdSzeoVf)zfEWQp4|~&Y*)AypWPghvaI{sch~ci zt4~~6`8^_7<+UAe_q&^$k6WF;tiO+kAm?y{fxkxBK2KyQul;85t|q{7jnq^^fu9O(~a_Sg-xw zz{Z)s^QoG)Pv(7PMu+G}4`Ra9ZiLTFu3hTMa3Ors7s7KJEYlbm4;-kHE3Gs6$Hl-l z^TGXP@2-0W_%sVG^XIpZYLmac=*YHDaep@3J0~d}R?#!sbLQ~8pZn#X9<^RK_0Xb2 zM&GMQ0_C>4}%{w$05I-wNlkFto=N?DLsX z&|T}*x%6IkSy`WG!Di-$s)phVKJm|=J&U^h@70z4x4!(0sXuHHxxcRY>#ggI2mYnc zOLVF$kG{S|FJa${h_C&!9ar8;UE2Nd*lgG37q5a!^WSzqE0!KPdi2$*t6SC!`)jQ$ zxW4gm;-^pE=cn(OS375KP4UH~&vDxG{BGTQcJk76#skSds)y6(Ro)W3b>;h(up}OS z`wz8mq{^;xwdL#AT`uhFi@fiiKDTz>8RJ^nVxREixhp#V$u9QIRrYxrRqM-e!Lj7R zT9cd`4qaXwC%;ftiItRle$L5!*bSJu_G zFKUnyY+iYp=^qz^)}v`F$|jW`>JXauS?{Hi^X_Tuo`gSA_?+~4U9Hi-t>>Rie*b^c zj1>iye@eWs4byfA2 zUp;l`(4i-LzfU{4<#+dTy{-H^Ua!0Ddv(v`rH;+a2TyF-Qu6cX^ZBWda?2wU)qY1* zuXNlL?Ef}*)p6b_>tg%1IptQJl{8NGJT0dC~ghF6kq?~Zi{=eLTZI{pWQEw;JqKpGSjtuZ@q01uD-Rp2-LpmHIGw&du!X) zRgZ64U%GT@&G*~O=hvm>uex&Sr)9sK?X^`ID`am>m5gPsE_*)t{k~u}emRZG%F0Wd z!{w_tZ^^%ZF2XKp=Z!?$yDJ-QYuDQtzqhQ7T*NDF7P8J*)Nt#mg=TA;EDA0}Ui0*x=9adSWMZ;Q_B4U*I6t6iU4 zx#sbdyC+{>TJImG`p$WqN$wOwk#a_|Cnt5BT^%Fi2PWxIgWq9EWeyfOFCuhD$;Lm$qZhZ)$~qp<@YN~PX~s5I6wKp zyxnzs?yd{I`fAF#XxU{g^SnC|-`@FdS!HDE zgZI5>Rh_1uJHDar1J{f1KB=pJR2KJ{A7WwH8~9j;g-|nJ;R7oN1KU62Rl&+%(is9C zaz)GQ?%!?^+oXJE%CfYsa~B>cR95{6T*j4fGP7ZG(dVa2&(}|4zaN**`tRMY4bypS z7cS0F2w-+ezw>?9lGJCXl$HIbXa6dl+H^>1XVs&E9>SFw=uqu7p_r?O{B(`|i5yZ43);AKVODueM?-Xr1`W z=HwgrR)&ESivueY3xhU8()N7TKe7y0R@&FEO<%S)w`K-QYfG1i=&b+ZCqBwXpZX{} z%QM2GBgfxss=wJkT}?^LYiI9SJgHdy>;B}^`vm98|6U_(9o4x1>HR->Z{JtHN!(Qa zJWMlc_l4~ij5luonI1pk++6EO<=gv`+iO05-M;CxPv-6A=T}}j84|jA`QF%#NlSfp zrmu1@cVM`nti}gg!%(9Y0AE@4XifF?SBoF#?KrobuY~Z3$`w;ariRkDooqk;{;+0P zA!BK|^HccgxS)vrp;Jqnnw(X)tZ>-%_xHvn%foE$=1$d*I4rv*@2c0cv(>j|*_pDjo3>(tl-!uAh zs9UGOHD7Ov>FV&`a?NsrkRg3oZxAyjHCm}SFl^wnJ#(u-+fEbM|8&_W)Ik)!7nRRcU6b66Q|GM9+;hSOm_FNtFf9rSO`E^U`r1ve|wf`g30tFv_ zd)J&~`D|8T(W6dvk8ZKEs!B#dlO|1ia^C*m6n?uO0sr1#4rOm;H1A|!;<%F5cuR<3 z&Dmo;kY%&@x-Tm@K}*RO)(OOKUdGhmC71Fq{Kg-HpQ?`xCSK?e@?RMESE4e-C0?@P z&B9H#hN0hP3M9BhbeQz?PARSbqik&dBeJaSOV^eY_cRwSOw&q~0)-d@(^iiLh6LTJ z2p&;STFOmWfF(b?pm2nt<= z28XpG3Jek2^3u(2xT7BGaV?NiMM3r-K?)O?8usnc{{>3&0uBljK&8s3%ZWJzGj79o zCKiUh+aLSrvv4p}H6GK1=m-gHU`P;Uv?LtI9080>4UE4MUOn2-)YP;jaPhIykJolU z_eC&8DHs;67ZEjFTI*o1!qyHhEASB&iVh4HxJ~>%`YEWWxJa2~ytsREPAgPL9QT{s z(^XhmS>xuP?}WG$_saYR2Bt<$2L=O!`QCG7LL(w(TvdC1Y;0`ZJFkLEgrgiJYd>{w;FQ9860)^MHa<;%=TQ>Q-t`g0Bu8@dE$ zfKt=vomWl<9zA}2`iBo6tSa;Gh(MBeqt1lMla*Jl)NHhIIYzjYQh3nH!04cV!Q!ZN zqeAAL9TP1LPt2Zd3ELF5N+BR5M5VK{di4e7<&d-kAr9FlUOs1H*t#Zdx@V*P_ag@&iUsEKML0K9R#s-<%|Z~XuLOabdtVN+KH5;a>i&!w5}iFgTt^-nszD1w z4QB;yZEqtZBOiqcnvJI)BnmS@G~zZ}-~uQM{Q7vM?_lOqd)~j9Kl)eIZ+$$|&p-!xnfPF^o(NjlXl4ic+LLT=uHp#ly*IdT>7nCx1W3 ziH$}Y5Q7C)>~YA;>*Hj4=HckLPee>?rakM__btYdV8LcCT~Cr_Vx?)y18e1d)}D{D|dfQGBY5gxF#)F zkif~wIqks&0ZwktsTVdFa2nV1wTa2(yu177VroFa##Tka&1D96?7qKHZd5Y-Zyd;@ zJvlH!rM0y+DB<6WNn#P8CRKg&=?mf|?TA=>E3hKMp}8^f z;X@%wK}|tHLDBgE-F+N}j>iK&tE-r_EQr^w%G+AFLW)P{g#Lt@)fvH#xqDiz%+r_} zO5aT^a^|?g+vpU0Q(xQKd(-AkOD=@`SWHX`d!XHz5Uglmq~*0pX|d1L0}1h^udmmc zT#%5G(n@^RzwWkgI?vgOp0Kk3uAMezEn6e`?bBJEYPB^>LvPQBJTI2?va?~|@-1B{ zD>$dNwTXpa;4x>6dhRvr*Su4w&zryBSaUCa-h!~phAa%LIj7|bIvlWO{M+xGmbUEY ztJBYV<}m6|I3$>&$HS87(8n0IE&9p zXvVy%ARr^7v~lA`Mtjo@ZR<@+ME}GewdehlnzF>(&o9q(#RXNSr`#?sE#5vpYedROekRr8ifUynT{Vl_H%*y z{qjWL{aMR?UtPvpcIi?O=f9uxX3FgqxS)^_6JzV%5VoB4nu5Yvd(i&J$7ezX91iq0 zEZg_BUFg(-U5rV_gwuaRJZni+EU$6q*1ZlHj>~S%XItasGu0_qQ&aQWo2sY1Ym=Av zU0Uuh|MJF51MLeE;^OJotfQ9a+}m=q#&5n_)Qa@a%kHOMT@{+PbLXCSH`*KAnW9{c z?dk!Qg-VotIr!SMyy`mY6xVfpXEyQv>0II8`)ew{@kd2ZFp ziqh}zVn4mz{yO#MrKg+j>11+LXfI&A)zZRpaj75YoXK-@b@#sQ|EwjZz!0%f&|RUy z!IUH7;r_px&-8yD%6c(ZkBBw`X!mkKz=k8&``2$2SkU%g$@ho9HbdHMfvfv!f1g^j zY}vv67ZeXH}VX(-*x0!{pwy|=;w}tO-vhhkqypLbYu;P6@FY~2U?hOnHUw2&6 zX5yHlyx{V`clYNX`z9>sL`7khr3SC&~^ZL5~iXi!^ww6XlPEI~Q0-S?AJw2ED zUC*lDEH^Lo<;ptm(vX8~Teg%)*1xV;#TfSBNZxlQUTL!}ht{yRvOfDe=kY&>Zxy-@ z3>UJk{9G6q^I0xkx~y{hPZ<+r-yQytXuPE)khyBc(WA$HrtWz7@S%{HlvZVB<)-rY z_kuz%xA90S1;3m7X8Oh(;ycSvg+%TuS^0O8Dw7;{hUw{Jz0%!mnV&y__VHhTTx@v( zRMXD0EEHkl_~8I5#)E=`Yc2@KB3I(jvH_#`co5%M_4SdelG36meJLR!rHTJzlh4ny z4db}*vq|dDWrhS_6JCZafeCF6sjMb{t}pQve!V4UvaF_t#)=$qnfN{i#sftKH(D8( z_6c98yz~9-ZS~e=OSFj!fKyysGB4kc`nin_F8-T3X0f>2rizYE0Y~=LMUXdZkP^t;%>d>*d@geB5vU^tgQ8n$*SX{}jwN z%T=?j{x)IW-YTy(Kl`6Al;zuM_4D$b`dyrp*ZxfET@$(4@893=^NXzKTNE~(ne#JX z=kY6TbF1WCpVjl9of9hE7M;}7%Gx?<%laq$>Z*JXh-hv!s9snR=xlk~=i{xF!Ri-F zuP?j${@R*Y?dL_&)<7~Eb>nI{w}sJca6e>P6rp49Y3qrZY<4M zwvuVZW=}S+?%v*sr`=-I_Eyc!;mv%?E+1*R)j=}8^6?5$Mh9NIxi|mw9Iu^o@4e6Q zUkA4oy{mj~kyn0u+S*NZhs*n}mu4=_zOHBV=#$_gZ~t4zdhJhK_CGJk%eKqx_uk;! z_l>{RzWBQ~=4awsZpNU$=fBQ9nN6@-T(IT9hwiqMFPDGU-n+O*SL$E&!=uxm?tcF& zt?a+NUclp{!RUP-^!ret3cK@31*SjnK{yw4ai>ChH!jzDD z>ovF7sl%J)zP*@I{cf&Ob34zs7ZJY|cm?|Qr#3-Kh8HHcqHda8SjBMb=*v0zPu?DV zA2Czqd2ZtlxetsE&mT-?x+ZqxRmF|iT{3T1G%f#o{ir}fkx{yv^Kt%GJN`}VYcKz;`+oQPwdY;8&ph|ejoQA+uK3lR zoxz=%jiwyS8+Yuwmv*iq;LB&dTr1vBxs&tOZ;a;S|rUYev8zTN+Dv+Uj7<&({FZ(H=O(N=WOU0nJ8 zO0{?B-^=Oy3Lm@uJlqoVhO6F6w4mLYf9ho4lV|6ti%-A11++6FIrRAMZ@02vyIl3S z{+{u-U1?;rQ-h_Y<)m4&9@&)aU-$a^nXBQwBC%P~`|Fx*zW?FAc4<9x;jSC!?f)uV zycl?`=9{dw?87a~zpXXPycDtTSJ7J255BX_PX1?;`LTAw(fqxdcXx@h%dqp>dDs1X zdi_>;bEr%qXshOh1&%^eQbB3{v(NC~(GIH#cxG3<_+N7Vg$0b4Hl=!3PflLRcqo5= zZ2r{p@*JJyqvEwJ?CjC|bIXnhwp*|Ja3#2S&G(JT&XU^C=hx5s*`A>-EOut1W%0a; zi~FojeF>J~_;bkT>AJ`3bEK`mNp*H~O!)Jsrt;It<=WL&$MK#|z^Gnue#*&f=~`9> zYZ<=(I%J-5cGjcw4`bL@&;L6oaTUwF(rW_8*Uehj@m#{gbgfMFn~g<(OOw67{9E#K z%__Ck^4C_2=hvo%CI!Upv%zrSn()e|v9hblZ&c8QPbp=~esB z+MW?NGdN}M&o%ze4O?c3UvSbhPP0*Xdu!|D%*%2sF8Z{nOZ7^di^&#m`zf-&0z2&2J&urh3oiATXrse&bA>@Aj7+1r(`^;9o>$c69!Tdc;+NnWP?a%b= ze}~p}mYqKP_{pMfJ)O^&&fERoWAppY=hSzr-}SOEtd8E1^*8(Kq382wrnF0XD|J&i|m`qhd5o?Vm9*V$Azqx|mr{XYwiicX*YgIDi*@|Umu_WxAo z*Lya&cMAS)?K?jSv^yr_V&ASC>-N8k zvix=<+3U`%F!!2ID`#no3Fa|Xe^g_6(JhwP6tHmN!ZfpuBA)*KoxNoqzt(E_{Oqiu@#?J`(q`;_*jA{z?kM+nre8bP{JXeJ z)X3j%XT>(V@99_G%)446ENB>~DKCq--0EM_H(mBZYKoy=3ZH`dd=63*W==q zSC%t1h}9pcleDRraHj5&VRlW_-1oO$=dJh>5xq4_RXnC(-s3&7&&+eK%}V(E?(YAH z;Ok{?DrS6nQFy67_+?kl%}t^AYRfwxS5&9o*s$=@p30B;H(%u2u8I5G`sdqiwa%WN zE$7}}S-H4&g--lFr@H@t%a3PQFI`oeA$t7Y-fGKZS>IQm?qX^6ov%Q|A9PfZX?3)3b*A9Vw6n83 zC;p62OMBqMyhd`_yfn9<+*!w0@;ezGzi$YNWU^nD)(!@Tl)mY0_Kek^(W z?ojQoexbFi(zhR%pC7BFv-+}je9gy#?CotC;8Iv=`<`Qbb-myB*Xs_=FD~6PYo6G4t9i?dTU|^q zrM1i1|N9}Fy(=XVT8E=a}<{iBdw&2hnU z%ks*!c^}6;e(-;=KuHDi0|IKf!Er%BdNjo(}KHKhp$(V17`nKcm z`=4HqU%OTB^7}9UCQX|b_GnVn)SQ#MkA|xGTWtK%{!)lN8=)RnU&q(x}y8x=a7h zOh2{%S^IU<>}y^{o6;2nd3ogPemqob5X;v(`8SuC+W>*MCk$vjr}-gffZe|Gy!nddJ3XsQf1KCG z?X9}@&b3?Y^trj#r)^5!+{iv7vRClhzUlGv@^!vh_g$_(B3tB9{d()I+8+gTtvG%F*cil z>)zmHr!Fn^)~=m5&miT5z|5ljkLgRNzI^cL;q(*Fd}nJHcim3rWZ1RzW0m^?HioS~ zdd@Y>%wEQD&UpUcOMApQW-u(s{?Peh{&W7V+u9gFUBLCaGv4pG=&dK0xGMVZU-LQ3nc>1$yF0D_-~3+9t9anbmXMPx7Z&u$GL(paSe>!|ZHz3a&`zIIxa*F6 z?kbbKm|Zbj+McS-{&e#6G~IIRE&J47nAQGbUi8rB`7*_Id#ir$w-aW|{XWF4Kl4G9vIR>7`9S7bWfvT^)9E{r-Px`9(T!e;0`} zT$%6^)O)+SylesE0e`!nF5B|%K6`P#)OGpP_jh&%ugvV%R?s=b2D9=c7%}jpT8Lj8obUhX&dOhDI~ha&5{UEEz~ zYo#3x{^J(;dhOc3*}j1bpPzl6c59Bddfx4Av70t^EqA-O?X1t_KlgXl@nxEquIv*_ zv=d$}9v&lczOca&Md6-1Dzk%U%A*D}FqjyY^+CdET82uKqvK z7d2Dg*}vQIE-XIkp`p6^@-xYIa@XWAYzSQ)c5KDs()#`XcAb2}b4NVCu-w;wTQ+EL z@7K=!K2AnZy6=Fb`}n8w8M!=+udYl__I;|Ad(W=;`u9HToeumAyY3y||No!%WcB;X z-?r?3_s-k7A=o!zb>`(|ea7pBg;Ys$Mm*78%<&o`UTd&^#0dwb)i7iU{V=hYvdTOJ*J>Xs~zaqwQd9}oU6 zW%B=4SN-$LoSmO8IP>4uUprx;x+uf_+VW0K%{TkrYz~unQ{_|s+Wt-7xwEHs%+8xK zJ8##)%HWlyyesD3dTtWDY)6Wz!(ZP8j?HY-tnO7dx4ruH_eK4QcG&mA`EcuMUsey<=DRk$3}uE_ zwf(Kvt}ngCt-t5RiapO|82wA;6em6Fya%W33Ic8+Uj@$Qtzt^ahFRb2EUURJQ z>eZ?Iy_xm@a>`b0G`ha0{8g=5#n!u4M=fn$X3D?XdgSDp%b!nK`=w94l-aQQl9IBr zii*XNntMC1YfVc0{`Jh}^Brl9SzLpMSPLN$>czbMHBu^0TJbr%5VZk-YHi?CfM#k>;kRH}B5e*mS0+zyIVk z-RQHmXSQyOFTI-ax;V1-euhzZoi-5WLZAzkdwE}{OD-wn0<39pE(%!>GrLCeEh!B^qET5uio4# z(b=4Culf1;{#Sc;o_Z}P_%O|F`>~*a2!)$Br*fNy{d`oqrdf&~)Zp2}+jMo~^G8?T zUfCwF;PaRLQW2LQM5WGpUA=ryF|#RygtW9WzrBsO$%*vs`_G81-+rfPwdWIgk8ihs zpNh(o@3;B1L8j=1V&7e9^M46mHvS)X@E`BAi@VsB*!oOAtKRgl+>Dy9zOYUD)^iy}#lAiSfCu$3aV7O?swI2>5e2 zc^~K8xwYSR_GOlSt@x|>{c(TTtd*XJzbyS4Eh{DT=g=SL1@k$RGUaD2*dE1bTao;()+_#XyQ=Lz*KV;*&$`dQ30})pwthxJOhm>E9yyx;y?qrs9@lN1 zwP+fv{jU{^*StSE+0VwYjd%A2tMKLbYQOD#zP6P2*(?6Zx3=t>Q@qt-E!Xnnw{-37 z?)^DXy7TX)U&n8l->-RHvG#w)?h7q?SL0^?Th@MW_T4YGIsK0H3^mK<+@E&w!=10! z;LIBGxyof8Af*@K$R@g8R}4&8{vEjiiMfW-dFrdX@Hm|5Sf}rtRj04?^kyeD!;t3u=ddQjOz?*8QOHi&gz@(Nmq2bd`fKhzp%YkrRDbb z=7Y9`#BT2X9^)vdz3kxLJ8|YSlW&I{J8Gg}R{yVNV|GN{%`k=!8{OrDW7B?}-Tr#5 z=!F;8_C_DNzF}2KtW~M!kD9o79wH2X9=2z``}OM0&CN^m?(TY6`t?R~^n$ZZxfhSF z+uSevd!zOxp<0`&`?qefipMN54o?exvAOK)N%h4=XDr0;o?rENZq28cma7=~q`pM0 zV?4Kh->+M-pSLB)mR>bAN;?x#eq*8Y{b_%{-#;Jwd)w=|rjO6aWJpInoV2*l>YQ(L z?&~nm{6|Oh->mav{5!AYeckG31^3FYTik6f{5PlA&v@>~cjDjA$d=!k_ExHV&e^B) zs^3jlbiUW|J!GHU<_S;M?S7{fZQ`A9{b>1@q@T0Ra&Kp3Y@TR6wcqYfgmeG;cP}n` zz4}_7!LT8Bw^`M~eZE2Jv+no4X_ollRaGYu_Gt6Mf4AqI=9z0{c<)Q+?a!u@ZOi`u zJKwf&t6uE7dudyDr}RgMZ0i>Px4GCp-Z}PU+y6h+Ta$TZzpaZe-5zGUq5Avm&oygu z*fk$?{dGF%6yLhF=VIe^FQMn@8wC7dfv>N$^F)L zJhyH(PkZsd=Fg6t+cK3`Ha>ja|37CA+q$yy*QclJPfza4owNAM`z4+6tA4J1xNYO9 zth>AJFIx7%L(-@s;aQ!wiO2OLt?Y-HU(a3mexGi;j8F^1`it>CJu*KVtF3M_EZEwd zy?(dio%8a)_f@|yy!`amE=gtk)Xl!aHh+)5KctnHY+_PzRCMm2ym!~`y}n_%*g4s} z>WliNmBj&}TaN$z-uAd#a>DKRJG5`_TRyL<%Vs&xrue9c&QxyaUrRGD7e8I8KEGhK ze9ec2C41GqYFgr70zud+P@mn6v{p)qo zt~(=sWBkM$TXt-lp|?JJ=DR!7Ua#MOEi*M(@cYZl*K=oeB_F9io5I|1J+{1eM&f3D z*=394lb9RQqH?<)XH0dxeLik^&CjAd^WU3{D+;Df^bujmx&5tZW!TzTw~w!~-uLHI zL(cK7>Pg!-Uf*`~*YuY!#D8z?`x~UW>&Eo$r?)(*{Bqrtg<&yQp*-F^$-o+*pwH#f zTzBzRiP_{StaJVp)jWP2sufE z37W7WE@#DsFBPlKU%t8J)B4F>(Yxv9>Sq%x_nogdJB8I>_Y|dPM|}8V zkpAH?zr9ztnE39$Yq;)7?3K$6Wy_suoW71n+AKzAM>=cro2qrK?{a2Z7EcpfbaIy9 z`*pkDO(>hyx#_6W+_1aFKR!IH;;jtNy!Iw$;~|xcs&Nb#?En9MU;pCkqei1h`|RD@ z?ytSwo49b!L}mLa()m11Ge0slgl#yw%xd4mw(Qu03f5`Y*Ihq3N!9!A!{xrSpRHSd zYv(P?+ez1Rb$c=ton|-PK6m}sRNXS)-NnyWKRy@s!tBIj`PcSgchXn?JKuHe&5Nbk z*HLXf6aWq{;R|3KkwS# z{QHQNVX>o?bU?1x?fw5|O@2IK+uat<$4gt-mgHm>eaeiw_Pt#E)#ifvx@Irt)g6oc z)EzdtCpM?+_Vsw_2R-N4?>{$r?gBU zYV+HBb+3Cb?1)f3^i6i%hW5?6Vqa$c{9GcwVpF_EM5$x6RauVy_dBvJ-*k8~=lhx{ zJmW9AHZwir=x&7%Y0ql^GdE3mwE5SKnZM@fhQ)qawYr(BvTpyKyvdvlxBiK3*u1Lu ze*OQw+=9ofmxXS!e!a$c6YH@>w<9gitzvhpKbd@9zTg03(XW@wclo{*7Y|!%u>GhO zL)3~3cGcWVZcc*aIi`lK+3%le$=v#v)|7t!pRP@a2}8#7Y{orPwKuQ&{gZcXSJLlq zxv|lAw`5Lclb-+0-*XQ`!ka0__4j<3wEB+tyD62&x4pjdl1togOZ&X~f3D&cz4JEv ze*fduB+n1pd1Zgu`0!yN2A-u4__!7@;6)B{q8nZ%*~-_Qc>DFJc>D?OnXTMO{EwHP zetY%z#TLhH;`83WFWdaue{Yq&P<6+axa~8~=^T*YWsFKV#nfLJx$Z)C&&8FK-~L*d z`EWV!xzigzZOT16YwM>?m3_IVvmacZW?8%`UVh%6vrA-dFZ;~wE>{=g<)=TB;lb?u zeM=j+KKQk@{-SjLp18xgjt3>QGm0Pg-n|=qclZ4jm%o&ieHYh{Q&OLEK_yyo-l?hD zFMY}$-{mPP`}^rea=-ZQxEp(a`|gSlSaQs%S$$rG*S73yW>4QepWn}Yd+pwN`b&(H zkMTb=eU!a^@4;B%Z_hKg@2&oRCCTXQp>`owhTK^XHlMRHzx_IDYUZ9OFH zXL0jxzc|Ae{e;V^^XuyZ9xMx7EPUwHtbdj9u@|r9@BLbKmWAiL|IXVh#KI0ND||e8 zlWqJ2(b*@@PP>|YP2`Dz=FRdOAIdkMU6sN9_xJmsMUk(!XzOf zi;t-vyB{gP)vMi1bfs>;&8Hb(u5PI;`G2FUEblPWpN(1R;xPsLY!;~$_Sf%TF#WdXv-98Y`|{QY2IjA?y}Nn+-d|onw3`-6DeQi^?7*C(Z(fC^ zpPePhrqpk_ZK6)ZhJfWq-fG?5eODwe@9Ld1cYbTu99DmH$J2~KBK`UYMefIu8JmKZ zdOb`oOaJ?eH;QpX%8%2+)n}S|#U^cz&-?Z$&sng%~s`+fiUN(m5FG4Obv+WVHt=abb;`OR$Gt=kRZFAhiu%K1?!xZloezku9xx!D$llV-2Gwf4xL&b1;Q3YR*_I8H}^~fpTeIG6H=~ni- z!l)m`a}6GHZ_H{qsk8Cne*6D_ynlUpJ6rk1lrtMY?c!xT;IQ!!7ekas{{Fvwr^*+!8mjhUDW4E-$`+ z+-?@Te!apB4Tc+AUvEviZk#+_fB&C5p=x(FBsR-bJXrYdG#l1h-PGNF zPv?H!?^uhit7^kmaxnZ#j*7n(R*+G>t^d$GrX3pL40}HJ-QJ>gbLzXt2Flfyv&%T` zXVsmzd&|?2YmjjvVdv*{)mJ?3=*?ZnqxB{?`@akOz4H6DPpsCel)qTmzAAFXyQZwP zNo(HZm7Mfv_^{`*-h}t2DWdrs&!6>a)wN^z@sRz!WpYaY-ST*T$q!kNCPb7(J)Ra7 zcFU)8?)NDtL9u>FxoP2!St2+7GFB|{- zdaeJeWQn`_+~Y%R>-vqY$WG5*q;g7KbJAZ*Dz*pqPJz*X@?sHviM!`kdX}H9MO$ay4qF%VbQyo%f?$sD6#07{&f1>t;Q)uReZJv!J{rVC{qX4hQ=L*4~@m#gI_fAGo1>VsZZLU8Sd| zDSVjn`Q{b-pef7^d#k@r>DJ47=(6#^mDuw8lLHo5=k52kD(5@YB%e`nD(L^kzqJ|$ z4;dfXeEe|u|3q(n&bo^N&tK;7KUHU_$h-XcNL{L6ey2Et%>SDfD}&WFzE+=Hx;Ev~ zl9M0HO8aXUJX@A{xb5A)((Csn{HABCPM`n!|C-fr(vB&XZH#Zbab=fzR;lCfsZH@* zQVe%er$=2{73y7X!To2Z;)jEF|E2zIbM59n;x+5G(A-z$*JI14PSe#d>_5(Zai_Y` z{~3*2yV|#{iQgZ$+~wW#cgr71ymK(Dw<>$HU@EWnF89Z*42y$5-V)z*dDv1Rv`?CWl;!q&c;r_L}VKy97_qX>TF;l#+jA+q7TfBo#+Ci_3~iLb4h ze%s{G$8WyJkNfn8Rn670nwp`-sZTs^{q3gs<<~Pm zKR;jIsJFj*|MOp+vDdxQHVWMT`~BO5!pFx_Z{K06y_^3|&v&-z*>5}IEAx+3e|n+Z zzw5w)`ZIa6O){0f+ZWt7JKS6+ukCkrX|VYIs0FukSs4~T+;>C#Q}E4Sxr;&>|0Zwz zeI&Y{?f15=_phv+d}qr>yM!C-?_VzZbkg@uV)T|B5$Vdm4exos5IGzfEPR}sAxcnE z{$022feQ=sPyhSu)YBoO@?sYj4g;T@8ud@p-Sm{k&27 zR=4Wyy=8Cw+QIGej~{#Qtc*Cgc9Fop&69n*85YdtP;>}ZtoIJ&`G3=T?}tNTMWxUF zyk5M;Dr|k+-p}d|XX3&l-}C(a-pb~Gug-eLcbl}yTcYnqGB=!_raKk1d}P)=S4)P9 z*A9ar@QmQ7pIG!$*KJN)v@Ti?RPEb{AsJ#bMah#a&q$1N8VAY zckI7$&R(?*)N$q4kKN^Sxa#uL>o+%lz3$kZ^6-%BC5QUROY35zxBDitFu3otcRK4M z@T&U3!T*z|$5pA??7v|>S-nZ~qo||6R0ns^8D7%a`OT9xz(^ygD&a{)FlE zIQe%$7Z?&sv~K?Y`@UYvNJdi5`kSAL&W@_DS(Wd0ir-ON>OH;e@|{~;r%J^@~aTk8|t`u-T){(N!j z=kxh`)$ew;S7*GqkeGB;I=54t!RF70!%vO~`xl%)KgZI$|99hV`S<;QC!Jdsx$P-v z-}V1Rp^V4-WS_6veC+mhxzE9Rw`-XimN9YTZD%uZEpTuYv3RrLaLKRRtM4kV$(kFw zXR{Oc?Wjc$?YYn2sk$xO8uT?U`uWtZ=f7>f-Zv1*bafC4{k-|WgJ6HVhjEv-ZOr8^ z){NY=BrJ}b%l*ms($iBkb&r~QWEj6$8$aLlci1LI2k!q{cYQJX{^@T1PS33OVbNM) zs}zc#pPBsc@BGU%FE2as*Y@3ML8dJq?*FxtzAYG)ayae4s=dGSHWeM!nrWTC&gRzd z!tyHqo9gcF%H8{Sif#N9=7zA^ zH}?PQE@T?k|GQrlvp7NPa>b(_Y3rzOH|J6x5kYoAi zL~_c>NviMa7TJr5RKKwQum1J*_43&fU-$3*o+*$QcY)zS<#W@knl;~xj{pAinN!MR zj*y)7x4uxdEibEcH+Hp%seSHdby_=Xp057BA4P|>nl5Tp1~2zJou&|6$Ww3kuPmC; z!T#?@tGB<;+ugqZUhJM5bA$JEz0zR$cK>5{c0TIji%PRe-+Hiu@j&gjo9^CO?5TUE z>qNfN(my7n7n6H;*U~GiL_>aW{`Ti_|K+V+Da@9y*BIY5Gfq2mVP&U#>uvYP{U zH(r)gXOIYO|EY|Je*446|I9tsD}A!^?5xa! zWxMJu>w2>||noZ+Ths{{2UXb?G(#YrnT$W_vCscIKu zUF+d_dD+>em7mit?JoDqg1OKz754bx+bHm@Q!I@*_Q%$%J2D>?d2_ZdcZw#!GO zWh;QQ_FTJ-zauptO4|Q@(6hxhz0sRH?v@ZQ!>y1_y3wrrrxp6EeN>O~%sV&7 z^3$`~`RaF8$L+Pf$}sQwyzSqwFF$|z;kGil-)}Z=kKX=rvU~3@iyFPE<*UPjbeG0+ zF`TQ(f+%MMk3?7KHdRMEODNB)~4 z_l2n28;`HwvnhGU|Lpa=C8DBtnJ3!oem(tt-R^fnc1{ciQ<|*t=LwAlCf1MxX@*&q zFPGlz+mvxJX>Zy_jhZvd_Vnt7{mgHRn{N4LgY(_PViIrG2JaGkDv+>6DXGLOes|cd zg|*e+?c%F`J~fb$T-$QPJ^k7ygOo&F(Np0QHbprsQt&=0q8p9qaYKH1o6Avm5V!JeJNjoc{dI}RQb+w|!y)9kFH7ya+Py!j?G_jXywysV1) zGcy8%mix(mkCQU9F{s(2P`)Z;<)dZ(+g=}(e*A=ytLRPrt$mr|3|sgc1RiXg{qUT? zzs=>D!LCsp7xd3(98lhW`J3Bvk!_D7f1Gz}a80}!$=qO8y3&_9Cc-53xJ5m(Tzw{&)3olJ-0Co1FOTD4Tz@_^e?KB!XZ-89sg{EyWbdA+*2`nlZeYk$Qmzu#S0CthCddYrH5``z-keo;4u3-@08i(R<9 zV4m(rE#Y^&-`jn9$o{_Fah>2V?iH`|cbv@q|Cs-N)(S&|Te8+=lQup+w)6O3`O68X zo^8`S1=PTc$2iyd-b0e+IP;*HurDisWiT$Bh|2(otUr z+r?M)tHak{)NGj#8l4J}QNGPss=A$Ffn?}vh79kLQ*qxNp3To-xFEO5tMR=3|D)og;mSu7noK33rqHdo5Qt|QV^pwxf&eoZK-?=sazMobo*D9{44+RGr z!Vf>UF3C`zsvTbT`r3D$J(;4Wxf`>3d}qyBF_lSrSLy$Dh6UkG(FEG|4viri3D9y!x?X$(d3M6cidep7IcTMBI%yo|zvZ^dTeO$hN zQK*pnjt|Ml`QF|QUc8m-k;2|}VG-TF|FbVMh^K7K?oa(1H6?a?%!UNVZO*;Fb8^-N ze>gYW+JBa*t^PZa{r?=o&c1&#*{^IhsK2`X+YH?>(E{_iMi%!TE&nQOQnBDobp8E` z**lK^u~fOE(C@#*iXns5=goZGvcGo@)reVq?iS_x`RVk>hg&_l-~9di{r;uBzkM&c zI#1qq{h&eo)vmUa&#cSbc=ntWgGr&dZq$oag`#a2Tx}ULLSO5!ym0mx zvzu*{+QmIxw&X%%(Um~=U0-%*W?=e|&uC!R(pSPVV|IF1)Yg zw_N2D!H560?Ok7${?Ly5=gp+%SLXL?9-nHyy*|{><|B*vl~Vt-f0{iE3-(@-OrN87 z-tO}C)-O4Cdycf|?<*1g+h_ePLic=4Ld3!IT5soGd2+?z&DRgk|HZUJbGr8~H@{!w z?e-$%(Ch2@6CRsBNPl)D{Os%n@jZI`_sqS0?O%k#`Bj>~j%w-b`~T15=eytXN0upX zI~sRe>+jE}pqb(@-F3;wzh%A9`nlZn%#X=oC4Y|2t$uoH>YeEZzePJ)@BR_ee~>Q9 z_cmN)+l}8pobK-rZ3DGK|9L%qvB7D9t$opx_QKWX%N|LT)$D&F#_;7TzwVD8SAuIF z&)RZ>VS()RTd&^S+`n_um(o{n)&*-^=eCz$-IL*H_nN=XQ-onlz*5#ff6}uR_ubr_ zzWc$Fna8WXe&gZYA^ZL5boLXgLL)=Ha_g(>FP=ZTZF7B{Rhl*XYMsbME&_h43>jS; z2#nP;a4m^qT-|g%z_~%}-RDFHZKkA$`{vjGi(EgucH#9T@!iw69+KF8uc+99cb#p- z6z7I-aeu1iY*ISrl)cKlxy-sRD_5%LUrI@Y<;V23PS;nLhY2ovv2EqP`4cBDd>(47 z+P?L5h~%&RKR-Wjzi#vP!1wPv{AZO?aUkiTU`uTIhD&~f=xA|{w^rudbEh}7}e0}cPA19{A z*Qu({zjH*i{Nv@!+c}lKv**3vrX9Vlr$^E_YE}69XV=zdoZS7M@3LmA`mVoGTP*B( zKK^}QzyE~ga})0S?;6?V7OXc^(Me0b{{8K)rLC-Qf34ptyL(yI_H8-u85W2-?R?yK z`%ZS`(vzU0CGGy#G-3E zw&3{vdB2zEGF-T4qIh7A{NHn8|31GruoB&1n|7Je{_ghq%T_%9?fdB7yG^IpUHUpp zZdlKYdk|OS>COAf_w2_lq4PJds<_Ay{KjqD|Jd^TueDCyEWWxbbh5u&|D~WKj!!q= zc$<5dt$uYyx_2Tg!`rQAGVYYWw=FY&n6&?r#lIG{n@urc56|D5ynfn@jCA92Gu}_} z^=D6R^W37fs6OfCrKLqb1l@OEo$P02sIxeaKVs_s$jxa#eebRp(cAUH$#mk@L&t^g zZZx=gVWD&JoaWqo$8BYAZ>4bO9kcEWRooKacO*Kfu;)dguEKNe7dN-;xfp-^hRCjO z-r~PgFFE|ZB#__9#-Mv4MNKoZI%i-1owzf2syU#_foi8MCc!@FXuf`s=`f z#^yu%M=!qB(YUed>e7Wb`|Q%c+yBnl^JaUz^TwbX+XNU&j6Sdvnn_Mz*WO^<$`D_% zuinXY?W={ly;7`Lt_88io3rO%WD;}F zm^i)e@BFi01H$gEpBdKs=GxxqJ8x@L_h(E{F>S4bods}y+3T&D)$$i5rE{-stT>(A zZ>Oeg!eaLA@{j9^f9+yT<{PGd64@X1;C2W*!`qfM9;bH{&VN#M_iD-h7mKFdT*k32 z;eoo<;(6;oiN8Oq8?(cMxp8^w?!2tqu>}WzUfTS;{?Xe<%U;NtWOT$7x(2LBuV!a> zd+XVckI9D}7TIfZ>qb>voVNSjuEVjjznwq2d#``MBi`)VboN}@(THpAT1Lwr z-S}zimcwXl?H8!&Fzp(ngRqeqOGHS^)?)v!MIR2bpS<_`jjY_a{`>zgyh?}+U3Eyk z>w&EI#cvf0-21$e#aQMTJmmiA>Rh`&#p$?H{qKwuD<`Vuowxbilk@)Cq58YKO0P2( zmTo(Kxi&SOk0FY6ov0L(PR~)NXfux|=^NvN=3L+7T32@Vvt3Z}O_& zTV7ugO_(#FJHY#tTt=1U#nI9y_%h`UakA| zxc~BEf6K$4j!kgXYsgSt_BZKy#?$)tJs;b8{^!i8{?W{DKWSa;`qJ;ZHWsd@#czMQ z>~H*JPVwfts~?_8H$OR{++T8jZsD_=>x$+^cmDi*b-Hj&z_~+l)o)|%pWReosW|-g z`g0DATi?viemA`y_g?Gu(RUf|9~+vkc|NB$tZ&opZ?9KuOg?@RH0-+F>+ZVU@09+3 zf504d?B@}KIbysFQP$a)pB067=HJ|ux^7a;o7cB@%}o7W>b|F8_T2xEj(Xn-*%>G- zUoErRruUAt%B(B5655MFkHPWF@EihtlT4F#(Vd% zY-4p(S2y^{F0*0(oVs6`dGgw_xl(hg-`)ImdgiN}Jj?%ndNSGn*ouSm-frvtxAWDi zbL*7m&pc>XJFm~~>AUNzLW8wU=1G}1WCs7bRrowJ-eXII=(*%R%cvZ$ubDemp|RUnY;d8|1Pc0i^sPe|LZ07@AKx}qF;W5-C5KVxA@cbrHhWg{vKn$F)6T9 zEPkbaoT>e8zMHQuonG?o-R`FxLQw_z@8(n*Wt@0zxo-3MS(e^kb9FDSYWx^?-$*;w ziZ%G~v1&W}e&5+&pkVD!|T0aE0zW?Uwveq z#B!gRn>MAKOyYgyJE2|f)yuAjcdA~W&D);A@L_KGy^`xQ-bTIn z_gh}({RXSmY3FitmhILIZp!}d+|GA>PiVl!^YRDM9_)T=wpt|Wy8V+?V!s#`*k(LW zJ{p#Ed+SzZ?VeAkwAZ)&7W>lIDztXSS*x>Ca<1t(Tj?Bb+do@bC9CzcUiMuxSwH>j z#U8&I7R;^9;rOs6cys%{qS|)ri<8AOeg^D+R)#QEeF0wF@VmR~G zR_%ApuCEi1O6|D0snmPZ^7-%Ip80a8{Qcc^J~?rGNe}nS@&Adx#hR7du%ZU4eqBBLl^56X+j`$NHuKp8y!y9#-Rg|=%V(FJPI_AZ zJ-j(&T}|cMY2T-F%S0V8nR#@J#k(EJcbAFzMQ={?HQK$?A?od|-8&0rPxb7twdKCH zHhTJHmSb{v4i$!-+L?A%>fP42e`-Cy-N+SQdwa^E(pPWZ)v+duzR@}HZ8zJ&vp-aK zFL@-<8Ta~vGk;;Dd-cDc&*RU0JH5o^_Yu21QDN_CI!}3u@)n-B@mFZ=be+f`?U=CA z`SV-t*8X?V7E`;GAKm|(VbRPg<6Sxgd+Qn#^teR63M3S-O(~!E?{jzTvl zRdna(A60)-H77pj)g_nPzjL{&qIDL}2)X`x$I6&fFRM3bCW`Aut+=jg-qP;3jO)SK zyLlJ6${#P;Dz<4uLp1ANJFDQslbTDybfVk#n>%TRor&`~zKq{)eddDF)z@~-Z_^52 z8>4B)`|iMX_Lp1tt3@epD6f$F_-@IrU-5gcdwfm4=AM&gH(N3P)|ULq`|`3~lcdaY z9&pW$IF@j%XMS;v{khXSqe>lC3uSm;UUoM0`x?pTpNi(}$;*C!|K9IirLRpV>`;04 zPHftm@b&X{$Jr$xw-XoB5UcFwXNqN335Lols==zFn4E9K!7LrEV?LjfQZx z9bO5Y+dRJ?f9$BT|M{Qq_g}KhuYR&M&G+J}Q#0cK-sETfw~{NS=A&zr;rea=w9?kD zmWmW9-SOwswXCG>-2qRn-|vw&zmw^BWty&jVSfI>rq(>Ihl_s1S*8;#i{^$m-Vj*e zJNx&cZhi4i^P0D&u}?P~<|}<}Rr<egFQ54d?aOMs1&RE_T-wj{iTO=iYXg zuMD|&dFJjvNsb5o=34JISXi%fZ|(dji+jcYzZ^f-BdHp?I_&D4BT#Li~Z?!6J&$*}6JzYoZLUnSwh(qI-um`_huP@!tuyN%A`(GI$Rr7P2 zHfOKhpR?&@bM8i?yUK2R)(4B|^KA!BvzNa5dHJyB-2FcuozC^!FZ1qD zt>O4^-u}Oa(L?*m%g+b@FE!5MmHN}>GuO)0ze~34Mxs^jTUEV?lDl8cpJm?PlNYl$ zidQpiPefe#>C)=e|I$Mlay!>D?YNz{^|9Yo>Gz=BvQwvOhh@6%e-nK7*zIffX^sx7 zB{G6pZ)fLbe+=fnoxSl%$b+BHf1m7BpZ8$ihM5m@*tP~PwkzAbVs1^5@LaJUV&Vc@ zc=!E$CavpGRC%uX&655fuj;>jTk~svD5KBvqg+=^udSJ+TXuK%3Xzq{3^V-Jb`(1{ z&W&JP#qjQkyk7oW`Sk}ttBl3tYZhKkd~qT1)9w8I;-0>*uB}xTkGr9Cd*|(v)8AIl z4qEEv`SH=w!_TMbL~1p&^Lw70a_FJs&SnDR0V9-v9JCUKD#$6EoxZ0ZLQD8X}Yt!Pe>Ne(r92hsg)4#Qp0-LviRAOyX#FR z)yi+Xo45Pzs?;6lCmW>-&HgykIQ=BMd`-lX`{{8ei3G=U7)2Z!9U7C4c6Iy4XI=fZ z?Rrx1VzJAQ_2c*53GM0L=eIfS?2~-BDa5tFL5OQj%+{c56QB4wX_`3_niGf5n0tt`p2|qw*CnbY zcIxF6txzwoX&Mg?)pLvMoiQ}N+P8wm&QRS&`HIjXMg|!3rR+VZ7FYC#< zw<+@W=U;Pw%zd|GyBkBn@yzquix1d`F={{Em2=Z*?&*1x*8RWXc0k&l$UtdSTHs*F z`!IB6kZVrXy+bi;vSzg|>w5V%YHn)&$w{h~adq48W_f>)-sL%2P5o(wo+y8h^!JrE zw|*PWG|$h|;yZ5muaWD zKQ}$)`l;)gb5@OnFbmkhC30FrZR+ZfX+o-AV(+-q_swekufvj&=&+h4L-9Zbqt_mi0j6bo1v@2M0an! zaKGwM{mBzy3vxLa#60ZE+!#ePRxp{#emFH%TS#h3lid8j1lQ*Uz!&f-=yOFBtV}xU z)oS-Pe^K$4tgNNp(TR~AAeNgQd#WK$|Y)I5q&dvSLNxn$o+NB zcUDb3Dbt-hDZGIp;ZxK`RjvgG%0d#Ju9~_j@9nL(Ke%M12#q(u9nHX66u!Xc=BA*H zPDk&U-*P-Z4Vo|GYXAQFy6#3F>zasw1b6KO#!&9F)AV9*%>`x4l*4Sd(h_U+SQxmy zGvnA<0}^I)&2ZcpubFdE#Dd^*0;H8;BGZ`6o~{qo|IE1TP}SW%`}{sWI(oFJ!OV1n zZuZs-=U!c19kX=n9=YzffeRLJMSNIa^OGwmtam|A(G3Vk*T3|x#{{A zCXER#OwpwV5u4L`|3%L|axJHca7_o#4XnWnVs?HCS{Gxvab;Qesieyy(=XN6ZM-nG zmGQ0oL+$lk+iyEFaxaW}aQC71sMDwibGUNNl8*B*6nEC^3Z4HU|4qj z`N5lL1{2G52;vf8@bOYJb0V^)K~vT^8U&4Bf)o}f9&U@i{CbLoG?@|U(3q>~z)%p) z_0fjRq_kuqljKzW`jXXplO|47yt9b;Z9^Rc`vV4<2Ic|=z5|RFq;NEpWE2=8TM9jDHyF80;J54-nwKDX>pq zbVww=1&WpnHG;TOc5pRRow8!y5Fs=nx@3Xu1%5I^zJb}bfqANay^p=R-72LIfr1y8 z%oVz*x`>CosB}2NxR&7sbAuh*i_N>&uy6GE!V$&vw((nnVI(Nvs+epV*gr7H8Oa%d z;UiLl?E(9xL;N9miy03*@cANq(OQx#Op!k^aG2>%Jq9OoGY-PS? zH)>)?_`#XV)cy60KaZ`wKHxZ{xoMKNjRFY?izrZ`A6*e~dks`3w6m=Eu$3 z8qcIT)SnPxvXzkE!h1pf1%D6!EjFXsjDHn_Ild&+TrhK}Utn)wmmz&3hwV$dkK%>q zkB-C`sI+4tlfqPfQGS(eo;j0mEF;g0jY`KE?O8XtwZ^Jk*w1+F;$g3U7v-87d;fu4 zb%42oga7OcV{rP0q;e2RbV{EPR=2?G_VMj`S3lm=QZDM|BQte?3*rSG1qwV2yMEQr zx^UJ1Txr6!=9PsPo4+M6f^(x*(jjJ0K?cb>WMrNResu~w3_*+r88coq@LhAvWZ%Mk zi}5eX#XqRzzH8~gu%Tm0me2RLBR>rvfZ##WDiKKfYdrMSVd^&jjO~~IM^B8iuQY%C z!m)aR{ek8MA}Tg5?H>f>4mnq3ENztJmq39Zi7CGoc>g-Iu`-lie3IGr?Eel|b~1en z4xs=QiwSF)7WiuwORG$~$SA9`)7N@|>;=9T?4(zq4a}J*7{eJau+Q1{iZjhcN(d-Vd_3vzpyzOYv?@Ym!g)PT$R1I+6gKqdZx?`(eEB0M&EMGvhP(x3J%8e$N{jU-C!!3;!?nzlXoG{bDE5`wi@IjG#=}_@4I%D0hB3 z(A={siZQ^OA&c<#Nx&4LNvF(SRi<5 zLy6(r#%~Uw{6bdVD|zCO#(H4QshPhFcS;uSbY(xf?OLk~JNXS1ho~Zj8B7+%TyG1w z60Xf|es&=Ah^#a=!OrUga1FD1@nIO5Ega6?|P1Hy|P=P;MC-BuR$ol>NR>e++_0N?>Bwz9Vf;e-aqZ1eEsg=tE7#A^zY(tufw;lro8E|KhdGN|HLic*-N5Yje?d(xt7m~{}-pW z`g*?4s~M(WY_h`FKG^oR@}5xS{=(uN_ZdsGJqmTdY$cNwCkfPQ@-CiJ{>%pFR@hcx4eR}rY^OKysuQS-s?_3kJ z+cC=i=RBVohVH!%f6o8^_PKxJ>~pqGUQ;#ZJ!W`cV;lT0ZlBvayT<|F@AT^TPh_0` zcLn>Ut1QPqKhFKHmww9i__gxifA8OpKb8F6zpRz_`-(`u#Fq_^_s8uhob@!_XjN%N)@r?~x`UnR8NDvoE;fI2s5e;52X)`XnP{r>#X z)S?r*`t6mIZ`N9QKP_5%w|Mcs-@Z|HALF+D^?vo`Q2eWZ)mK-&*|yPMjG^Z1=9ivN zuNSc~G;=k4{ZbJu$EU?`%ka5wtZw`LZ(VEdZ*jf8>0JG$yvOmopKn;d^!bK_|0!QQ zwd<#ZG8#y1_;cW_ZdF9{a@h-f(2b*9hU0!|Cg;^rq1=br8}zMn(zM=x$DdSi1*@q&s%P0TCh*| z>S-=UO8Qe8w`6|2n^*=a@x%*W|GpTq^LsC+=kvqQzQ5N}?G`WoZMG|Y!I>GGRT9^| zxqa{LlDw}EO5aJD#LbiayVmB`vd%5nwVJloth)Rz?!$={)zel}w1>o{v*E zMlpUkzU18I`sv0`7A3#heZ8XM#q~?oM^v`Q?~R&zh^yhXdG54ZvGY2s_vkH`SK{Al zb@1)~hg)tI-3)$z{I1^H-;M^X8}{*w&-kLs7wOKQ%WO4?T~!w}fB|aD$Q^Lj&OD3K z*d^31f)8RfE_%eC#N6;bgTY|tx9EjFnm-@E)Vp=FnIWZD`}d7J&d;gN`8yr_?yT>- z{jXQQe%k8!|0CM&744gI!JuNzem16jc?-LT|K{H*UMUl{e%fvOY_11K)<6H+&&%-b z62pSI86{i~_D^3w?eFfrBH#ZcGdHX?Wth=p_wVcFG@Am(13G(~mZ-k|_t}wuH4muK zmmzI1VYiDhtc}WC(P4i;{vnBjNcZ?_mQVdD6vlAo>F3+&*R_m3+E0HirX;0Vx# zqyF@_ze{XFqvZF`zkP2Rciz3dGvLA zX&OIu-IawHcn>ssFL|`RR`{ul|es|3`i2 zzoq_9=Ds`objjb>yOQ^q)$Ot~b1UD%{Or#E+4FK!&(E5AXImnJLFb>SKU@u*Obvy7 z;`^Br&VBa&{Vis#v;5cis9C}PkLy~I+hZ+Q@S<2Do%MkJq;u_OUzbmvq7`_j^^;%a z1Kye6emAxJ-1M@)Y(nhnDdo5C{ra{1)1eviPwubno4$I>p?SKSpXp9bephGv?%z@` zk;#_l<5Z98q%QXsV3;%SO69XP3>G)vhObXco%yLix_r+9rUwl>j-QTXEJ(TY_R_p| z76wMM1A4y>_*GvJFwmRD%rakk{%kFV_z#>vSco5q)0icr;lWT4wSHUB_9|ELMZe$m zw_aLue8P_F{r>h9{E{`!!Q1ElwR|_P(Wv-ckmc_UwokWapXZg&FSy*jDdXrZnd=Yp z?f+-&TzWI`VHpd<=YzAeWPeL6zx$}+ZI;-kJgx=pW*WDewQapXy)jS&_Um=AAFSyU zz}@E$402X7pK3itq226%)r|l5HoV8%xLmSX{>QfR=#{~`93Q{_&6suP_c4~EVMUM2 zKP!KmD8Am#_{Ec7-w$rzKSkZGZgTGbs;ye5cl_3y$d&4~^KIR%%`Q^+tquOXe{L-I zUcpp*YVrBVAMa0C$4?f`zTSS`+_px)a_8%tyX5xy1TY3H=kaS>|JQ21p15rA{kMNU zZ0NjH{X?a^t}HHCt}BFLPp-qA$E9{}6Dn6+<;?rfzyGhVUiGKHIq%QU^9Wm?a;|*0 zY(H0ntMNkbO|#CQWo+ZhWz4w9C>z4KgG2nG5=rAr6OJ}!upU^t`ufQ~so610e7|s2 zPw42bzrFIl#!S2PjXuB5Ki%|QFH~pyvuQ8ub*Gi9pPjV-tA+Zzc=sroz4;cU>vJ!> znCEDe{O-|*Uw=5qQ{JHo4+~!-q4jvR>Q9KOk)PC1NU{+-7$ZDa7cbWEFZKx zidC|*y1PK@fy?jwo4Z2us{a~S7T)2v{PnXpU0$zzyM>+hnJl-syilQ`Sn2k z&UUNs@~Zj%bEZDFSa&F{r_NG~p>M{MZ?`vxE&UhOU5(nbC!<_r~i=gXh0p85IEYsLPpxk_uLOs8B@?S9QZ zcWcCl{BKQ9i%tqFKiSTzedulS@56;(%O@YdJx{0l$_f#=!%g-3|Ll!fS68>?%Z?uw zmYM%|y*qHWYOi+unK`pV>>i%vTYe(-`1|MIih~)l87@@B=nFCYdHO!J=u7PSbV+iT6bZojJZ&FZQ8Z%?)E6BmE;A$(H=s2aVdoGJf>{|AG- zq&#?nfsE;eAMU>!y`FkyF5PFlq+%n_&wu@{pFZzVt-Q9_t#wn-#+b~RYY*DY58u49 ztNeOa^R_>$v+E=GCJOI4%bdTGL83`>^W6>eZW>-Z{8jlD^V@^96PMawkZ*eb`Q?vp z-nu}K|4ZsG*}vVt{h<0)htdV$82Z2xoBGe;tsQS_P$V$Wi&-tf8yIcw*Hzf7W z`E)?KD#`Np^M%z{Ci%bH8SzkcQ|4*0l~-R%rY$)6`m237cFF!`^;Hlxos~T)@G1@sBH6LFQeTd zP$lu8F`Pl}0CUBIYUY1n1_S>drVk+2ed!O7?pMVFNUibXUV}Zf`dEM9-1+9s{CB-~ z&8==RSrZ$2YKqpvms@xucPB2^iP;&pZ|2|aZU2wG`nAl*v8>KE=GFvTZ{yV9e?BvYA zerXD`9m5On>Yw~wUlaUNzHmtCfd+$%TQ1AL;7@x2aqxtX4PYoh#1t`T}~wW2uioaC0CS51UX zB=QZ+e;QUZyxAyW_k57j?GH)JK`CFLdMH}7Kp3+X7ea6J(J*!|<^25SR5 zBReCzv{Lq85IGLf1Nx7|lm8^8u^#XV_{DZ8_d>u0M%guoL1P$X&aFB~6)7w}Hud}s zo~sWZ-CkMW@O8o6MUV*~27MdeO*OssE&m+q9f z-6$2F#Smb~Cpzw?M1WKLm4Vk7%0SH%3~FV?<~4ez-@UF1c7FUi*P@FN#i_zS8_XZe3^tyXb)Wq$ zaTTP|c+k8K{`P0%mJiHg40l#d*OQs{wdc;9J8KrV$6i=udqKX$uK?cQ{>M>&g1`(O z_At4^pAyPYB0uriz8zQlxnwig#Tu88J!*NNam!N&HxmX4mD0^j4Qrx{#BFN?`XJM! z%oPGG&EQFNa7_MwC<0!G1R47Uk%YSp8xH?<=sov$jjUAvpB+bZ!GTQ93ILFvMw90b zZW0V7Kka=}(q2eLA5OJh@uCrwmYHoD+CKz{Ce$2}f6#xY06f+H8-O99JUf_(7E!=xuuuE4^9^k8h@2noTzB9KP3NX z`p*sT^cv(|&wNZlfH zVaZ;L34y`d3|X897Nowio&9J+>6d~|bLhC}G4^Bb#d+X$T%fgF5KKyo>e6NY6kkS} zmp{y5n}+ra)+FaDM{-e zm@}V&nu%$Qr^-X}n)$lEn+;dARzbJ z&dqtP*_*|_IDi8awy5Z!_^wrF2-b zQ+~xtMu*oc|SFh%$Jtm=&nF(ud5kCkFNh4i`b`?gG2XPTr2rWJ$C9 ziqfmxQVdsi-rDN;>gS8K=Wd>*)`&~Ky#vFB0;c}dZFv)tq_3a26%=}Tx8sGxpEV(j zOb1yOakdC|JZEQYea!zrcTel~4`TNYMb|YP|ISaaDu)$KTu<1uV*fV1Td#3(XWsT# zxoxvQPx~73Ixz2Z*2--;({xtda=0d{-F zu9<)Ff5?d+hra9X%l}y0{XV+p{-fVw1lM{$nE#kvhv9|ZlwYUv?{RF93u*G6C>Lt3 zH}O{V^b?z|zD}u|`ZvYft#gW;y${p!7d4h~X`3W$nUi_=U#t(4ob=D3euI7&**$cH z+CL5fj2C>bt>wMUDsReodRLv3=GDc=e(k*Ut|$3PZ{YmX&q`OP#w}%&V$xa1+?3UO z@79N))#k^Y{VUkcKh%EA{aCw>kF=p8NMG@jpMV1^nC-^u2PS`rFQbF7;ema);7kT`RM# zW+dm?3CrphT)V3O>Zy*l<8$%&Nqt`(8n3(vEdOZo^Tp43pU$jUY4m2bF>>iFc67WPO{hT2IJqjRHfoeEm+y!GqnrB^xGPwss?`_yy$zpCbY|9D>L zGGBAitHJ){Ca%)d)R$7fBC_JAKVF!wb=&Z5=Qo#Xue&=O>KEBxod3cf)EOXpq2B~9 zz6@3edsc&{Wlk3=WQ)J2+MjARFP&7}pQZ45+PX=fK&84qL*M@l+XjE(uUB2aXLGbO3 zd8|LV*17N0eVuZ?xBlb}@qdq<>ctq|Tqs|n6Svi@yIfoB)U>1Z85|q-t-~EC4|M`2R3~qsG z|EJ$$=2TT&=*2E7FjentTNA7H4L{3|Hn#rfoA#Ew?zMhzbNl39R_PAbkO09A7rMXj zHMX!^s=ll8|NGf@+pTvSZ?@j8x!beuvFzsiZ_b3@`+o2J-n)OF+8$xD$5kaMtU zs9^ZW@Q4vvU;*bN#%wl+FukV}&S-Cu_LiIL-G3?cdGDg*`8xt$1_?0aS6AFhq2}r>bmIii^)E2fQAe!;R0@a6& z-fRwG@%QZ6A4|P$JE6R3-7G87w@X$3SGDa@IigjSsLmiZ&FW9<5#Mtx5$9(z6yN&3 z{8WG%O10Mr>1M>mK2Mh%yaubd-o@4mI zsNV7D)}cS~w)?prO-al!kCB_Jwduu|D-pk5%-o%G#r}2X)psRTRS(yP1O*;$J26Wm zXp3js?40Q-!Fv@Lk9}Ww>O;jF_AkQUIBS^f4%;8JSGIG+mOLK)tM{bKR-XE(h6bN!0nx^&vT*p0o<{%$#Z&;ET!FNa2D!#1;Y zCJ~hbkAA!h5xI7-&i>nRuaMS#hvF>PZDx}C!1aUSKkI*98wR;9{h9~-sE~xn(>=!Q zC&{21ES0XEe2d*uB_uUiTx-$x`Mak7T5442Us|*OEyv#tw!L9*t&WA~c07I;6YKU> zoi89YLPqpRiMn^dhV!3;jBI{wkh58Ss)O^V zG*soj+iv$;A<&gm)NOe{X2~XIi@h`Cy=TB`$9{#uCz=HKUEH~CCSsl>6!3-`ILLLZwWb9_F zV6Xud3@t1I@=W{>k)ob(wBK^ENjS@JqVIm&Z;RU^_m|jMh0I-|qP0x@-L6)(IrnaN z&DmDJnd?->*?*6xga4Ml1HcUCnwWFQpha^z8l62n~oNd-k@|t~JLfw}$o;-;A@??IR z)zm+_Yu7CFZTHuR{LgaIf6D*6Gv{5d=m?5Foyo9y#l8>yYz!}g!!Kga(UKe`ofFu!5^#!x+>-jN*~n4mKD8e>g; z(|i99e>wNrAN;QV<6lc5!#{@o;*UQI+Q~nJ5`Ppy)r78*oB)eM>La1!PsL?3q6=f) zee8mYDoEq}_>O%JnDg9zW}xZ#9fiBh5#Zml zp+ezhUuDkru9vsc^4g2GOg(W-v0uX5aI3zR(`B{(h1KilyA@7+IO$lr{qmr>@g$IWFG#v~IJ&RMCK1yXoxD*6MV6FMaf(?}q*KzlY~<*i^*P zl9%(>xn3uDn)VmoU#!2G_A&4`wtry%(2l2C#ph&`VjF=a0t~rb>OqWbotz8SYAl-K zK4s~gTT|s0JK9=Z-fJH3d-(T~O^1u>&qQyXyh?Y@!t-T+HvH9CnkpV88Y5K|Jjc6u ztzd92Npb^F(0pQsbkzm`QbeU*Q~{DJ-7)kJ{} zpem8^n}RANzb`R;@EKALFvxjuLRt)&ydC_Il=8vB3({in$abiKXlP&$Vggm@9~`2Z zJNVZ~GN=Z6rY*^Soa_1LwM3AkvEF>I&CC0WPnw`*XHE?JzlY){DJIi26np*-=BToe?a~L z{|ELT%zs+{H~w$^?}}bNVr^l;lfo=TIS#LV$@3(R)p69NMCY~_ZoI>y_w}~ol1ZKQ z;+K1h-2-A$cEp;c#p~Ry=`iBVG=$<3{~7hA;fz*#B&7RD8o&alne9y1~|i^ML&!IdIcUp9vCxL^Zt_ zDiD$JL(#54kMYe6kLW7Vpm^`MT7E$#seEVWRqi~0#9ndp+?PAIq}?yv{bLi?X%7J= z=4Tq(3x3@(*~H==5Le^BinEVr#>zyc2@EO>oDNLnQqNQcrqn$D|LSMLE5+i%pE5_D zZ@ZEgKG(hQsC(w28y8F7mx>2ZZ;AMPsd%UH`Yn^h*55uaS;Dg1v}2X-)-OkYF^9xN zF5SX<-Mr)f-=HJMFQy%^4`GxWq z)?fC%J@$D+{SEs!^55=(2@wfljN&n#g!~T!?f8+lH|F`|9*83xm z1mkZ%EfHZ0s#wyQtjyWhtzN9LMe{BTe6o9gdRP80r5 z%dtAKWWQD29j)_Myagqcl)V% z|BqHh%HE#$H~D|AP{Tjx|B3(0EE?=L)D>*uX8FNT!(eygEaMM`8izeS=ef%q8tPl> zTk5yWX8xlLhKpqd9>_nGe<=U<83VYQ;P{`x&ho<@1b15=us;Nbw-_1!ZS?%R*p_)g zir==@;@w@sBGGk|(&EkMruo@*Cn+C(`|H_hZpVMoyIu-}M(TXysb}BBm3j4D^0#eg z{)kU_-c+(m-^TH1;oX%gn}i>)Z??Q6_J#5F(K_ezYtIy(U@T&gW8!ZltNDB3P{9J- zsSJD%FKwUO%^$G+9Osu;d+V3fX?E`W@ORFtmA41HAre zNwUw3e3xe@sv0u?tR#=}qn#=R<*Ru4LT4<$v_REZK6iDav)r})Aq{p8@-7e9s~c=P z_TOQI^c9?cFoU5pa<>Vdsj-%tkaD0w{t;sfVfKpkt7W$xDl73dR27q3AbEND z#W&vP7Vcn6`+8~23p&D9^RJD)zj5ES-t-&sZ}PLhUB8h3!u-qbug4y5$iHF!M*7>@kctWO+oL~z z=RaWmK=uP)1^b?48HRh?f4#r`@cjcMD9LW|j1d$I&<5Z?hJOYM;J)DOByuTs;f%J#Hrgiq5|JjgW+xudyVVtq4LgDAR|H)399;ihB7gf!P4&Gh- zQqW3wtE}zE=hD(kpRAv7`Qn_UsIA&}{k{laXZd-4*3b2Q(Yo>TzN%V=%%AV5x^ZQQ z%*8;Rz{t?-%lvDWm)^AgCj9%R)Cchj?)v1v-i9}f-|T#PeDVR~2a+Fp_MgZ|oxgsg z+>dlHEdK$91k!{9!!c$*)rOm1OLu3ze173q)T@vk?RxV~+TP8yTpH;0k4wOMLa2lG z%s1)AzMqzF>q{-KroUbM=*GGbk&6pMU$kHTwPvSjrFwM#zvSAr z+~+sUzv2Ht_`}YvN7BKe##6y&lifOB{9|R;ehG$s%=a7LA1HsYTO*Oxro|q)vw_jo zaIkrByux7$Ls&zE(1NHRmXls-Y)mk}YoE<_c80~8z>fN*Q%%48-DYx1cV)s$ix~$q zW4J25zT?qj&3X9Rto@$U`BKw4oCW-%u4T)F{?%t+njW?{zv;qlsjq^s5AAbW-*}k( zR{R=^gtH7QR2+&8Zm(%MB6huRjplMb*6J50cc+7zLsG4O%BOhNt={n@zchF4WSg?I zCl_zk&V0l#IcMGWTV;D&U-iFV_Grbq5SfcR->%uc_Kp6vn`Un$e)rVoE&MlES?q`G z4gELbWsn{NNl{%=py1)lu;zJ8!?h`MuF2nu4zgafugmJ$y9Mg+clIvp%dq(AKjq8a znjb80ea>&y?pyIjSu1MIy{V4B{Y46%otmbt?-=r>>fhEmoCeA4qVCHzTpZTV&(HpJ zs47}#-j5Xd8~Jax2Yp)c^r!!e-TeOqzVTJJ?_K@qv6&eE;eUz$H`L$Q|F&DSMvm>@ z_ABqt3;b99$6m*{zajoncVSIEb3FqR>_8rf+Ony_L6KooeK6liftPhZ-#HC$)L#_YSEUTzpUk#oXYCf2zqrY>n(T2~fVq@LD&fNXd z<&9=ar%%D8e*eE4ZEyCAt*W1~-|_%J83|nnBJZd&B<= z8T%Q2H`E@md-JT}N2ecC9@%}ckUL>zsL6_-*;7DwQZ1dAhXXYz+fS8<*B}Wk)rl-pQafH zFHgGV$y)t#oA$Y-xAkYgV19c3V~4_zwfCm_sZPDx*S#$~x-X^JGC_^?lj7TJ-@<0+ zhCfLOC_NXb+zajqT zNq%Ujy@CB&{-FkF%~HW(BeMU+LHPqHPzgRB*~rk#K4~UH#?qv1HeS)~U5`zkZdv!` z&iwR%ij0n!hVb->U-RGod%VSdwZrEa&s5&O8~(0X{AB&JzHQYDx2@~r;(xy+!CQ1{ znd~~Dme7l`;urE(eoMXU{6_wpKa0U9P?f%b|B_TnLie^Q3?D#EqY2j-YCuB^pe}_b zBY2!rVJ+iF$ap0Yy^ahHxh*$%8a7^KEh+o0_3OBDc~JWfjdt6LkFOXe|GW0){E{s1 zwa-@0eOc*sZNF3t9|t{Rw{B)^Zd{$s=biUaXB5A@|&lAwS7En4`$RkN zUHFtQXSFo0+9+=NxAxxLbML2S-aE{i&N*euw4lmBJJ+YOPl67l2j#lx+`mxt#lu44 zjQDR>+Xh*3M=L?a*p?6(j#ow3+rNI@Q}38_T=(gmIoq4__I?xERr^XJ-ECHTnC9f) zX7Y9mqu+(wXl?qJYgsgDRaRE?6q`R=^F>2VLqaCFADntrB(7?b*REa_F3w!Tswet8 z6YorGHPU$<^v(I$Vbmi-?t>8#@K zT+(%pc}iLKr1+Q=3EjQVowx)KeV_CpE;ia-Rn&CK`6H|UT+%xAn#6^n6ets_+5}EvQmwo>6eBbZ)?J^Z& z?N_aj{TDP(zkYk~zFS2i|4x2u=L*u(71aM<`By^f+T!NPduuk^&Yc&(DYU%)>zmcn zrqtWw@$8^3iL($sIYBq;; zmNE<8cFZz*6*|@J^7>tq+`hl}O0UrPukH2s-E*Gs-Yt#wkhbX)~e{yn@L5Tao5budMf3L7f<+$piwoR+jPvSzW-LK0kyV*>SadS^r zzx>%d^XfdGs>GM?Lr&ckVJ@s^_PsBaZMWaPm{s+tyJhaviFbsgKEJunm>QpU?exii zFXnOkExswtHc4T%*%Oas$(ZloysRb#=S0b?^ZG3Ox!v~)PxWDI?aZU^&WNe|*FRdV zuq@7KO}pE)(`8F8pMAfU&*G2y;`#rkq$`}uKm2%l;PoRC%Wdt>)wdKpn;ie*o&KBE zsYjN7xZfx~pKZ}!X8y$Ux(`2_ec-8J`@^&5ee?$T8~jK3JLCoIBkDPrky`Qd!#`Gv zBFY2Mq)&p9+yqGmSvF-+^$+J3eR==CHwjtsi*4Hd3{Qq8Eo=2&fn-Tm}R-D|JmQA z`{jd;Qh#k)@4Hn0?A7(@ObMrtUp{s#eBxUpJFPpO_1iYa$JcAzo^sFZn$4cK>4zUr z->t}y_5FJI?@wiMJNB0z(Z1pSCb{^hcF*FY**E0h@Ru>}CT{X&|D%Qz3@4%wv)lw>(MUN`jP|IJ)pQ%g^LeKD7Rj>ZyQ zpFi3wpY&ui?z!i1pWkwS(;uc)>(*_0?H}?_a8;l0qE$zNqk3!9`QA8j=VjmFX{h4S zWn}sPFVoz1drEigyvD5lqW{sa{%o_$ox>RL$Zf&n!(WW6FWIk`UOZv$moF<9UXOdY zY4dvh`zP=2_|89>ed&ev&ArA9QnvO6OKsOyJV-igBL5@D_H2CdhN}r? zJ?{U#7wYq#@6Y(q&|YzW@BW4wh4~K0(qE{55&k8)8!;cuM3TWTMD_I*$n&;Prn z_K;oT{2%)`?u#qNx$o&iZsaM*aV)5C&}2MgpTTu_%QC-Gi&YMp?ANac6y5W)O1+_B zl^HH-@)>FTtKGkq>ajod$YzV4vdYz?V^j=}=7YXmu zgA0B9xNK@ah20aL!SEx{Sb#xQILmzc+Ij!_R%9?c{^L?y z&DQ>ZC*Nj1owHKzWPPaV){qlbQ{uy1MX!pzk`Z_1G!zt()yoOan)C7JHU7GVOK1m8=$pn+VK2-e&cUQ$ob>gW@vHTwcivkvLlULEGSdSd zH3qXQ`(}NrbY@zh!}vz1|7TYG+JkbpX8ldxdtm#qL+&@~Z+FW#fDUj*s$>>>t>FkpIE|r~QAjOa|+Id*<_v&kqzou>2rXaqq>y zGqV^kcri@ubGziowDj)ACjzc+E*CyLJp8gJ&aueVO z|KxAurhU_FZeoeGB?FPF&Uz-n7B=P3O^&?g24 zQB+~D$=LHl@KcN3!FdV(?;ZueVE@AW>!QW|>j&;1y3gd_xcorygOwjxAHiCL+ENVs z4X~zb##Dw67g*%1QW>61h+^mviBXuNtn>7WX1zJRq>h+K7_w>H7oO4lt>` zQW z+`nS?K8Kj|os;Jz_89l=T&KR~jmlN_)4Xd&0v2(wc+`CTZs?9 z6Sk~tixICVIJrS?R&B&K<+*v4|I^ohzbgOh=7g`+#`hPmKeu4Rgaq}-wYO%wda*ft zua|!iZkbo{#^}{7iN_}IAJ19%W6kn?SLR+%Ip^?upHCqc_U|n3sl7cSZJViA zd&FYRCB~d`P%ZUka;d_B$I)l_%ebst=Q0sqE6~{X&|$({h7*4^+W#=>Gu%on4ZX6n zVe|h|>$w^hAu|JGLM-Oq+RChYEb?@Dn&`B^OxLYJkG3zF4`nfA(v`JuCljV=4CYgPVQpR2!HYPm&>&+OUvUOoOhQ`u(g=$ zY8gH;b;F7~QE8Ec3e^46EK<|9t#Y?$$p{p>{L&*KWTh^Uu+~@_p%} z%-wEV4C^^+8|)6qy}8C;&+wMQhY+O&kLx4-y1 z+hPH??vC6=hcj=)MH(-z&D&9z|1J4vZSadN>wc*=is#xmmDg_B7I=))#rnIOU$1F> zGSh=e4bzH?eoNf?^dwa(RzzHF{~zABCzB?{F&D)2hp7IlE4^7(m3y<#ZR_L4*jpF5 z4)Zj$OKs^pc4_jncgJTi%s42?5N^KekMtt-v%2DYKlbgbT05Jkp;7$2M`eD+n;>&Z zhOM9H*=*>Z&C@V5_mbb2FOH|gpC9OXzES^%_>Hw<_Y=i8aNl5k!$j1o6e(f$5Eh5D z$_=%aB4_r$6*%{A`kdW!o2q%ATdwr}=f(Qr{hv28HQyXLxy^k3rcGR0nwr}L1-88A z-xLy@@-I>Ao$0*q0l(`MUe4bAbEYzbSx)WSq(hm%FNbGv=-$zeeD!MO`#JtAS1sEX z_{Ml^tx5Vtp9LanlWTX|&h-H91AjOF9^T@_t$1$2tG>3O^1H z#XX(I|L-rctx{vK`hI<_Gtbw@n|80{+!zua?tc5y=Zti>#+M)Oyqs?SdH#W?4)&K6 z7jwzJ{I|Vd%4WX2{0@(a#_R9B{E_4>b@yZae$yTGU;oX}X1r6d$G@w4iJj-iD|?-F zLW^fUsf}#i@;}8e)O?a{<>vZVUthmmZO9lfjUjJ`jnj_qxVev3)E8C1Ix1k#$!m$I>~Iw5;L+yk@pOof04Q^zxsxf($qRECX|Xcj;mq;-pE!}#_+{;2IZ$x!iX@%-Jf`^~?7dG5*l@?z%UHNmAnzfU}Gevy6uyURD8 zzxl}g^3>)k%e#LsncvPhDtC@&>7?(yF}J?H`^+93RI^1$`6T}&;QQm`;kluneOs57qE_I2gyNU>{1k2XEu0_w)y5lXF7jG6WG z*~Y&a$2#s^nQwfRwOjsIEMMR}%jupDxBH%6yeq$canmNRv;QhK|9|y&6W`LQ->;^B zU1pxvS2B|`&~n&$W2p^{Ob8-yx9NR$*k|EZ~y&qzBl>hq(s{_ zcUS(4-PUZ(@UML9x<5z%*v%;An;e`R;xBOa(Qo5Vr$s9{Ki!%;nSGW&sin#ucyTQi$2rxT6M0MlfSmVJiL|tCR?`6H~nMr z|1HuPN^Y)x?9*ZM`lWv9{P{iSv1_O>Va-?O{@$q5y^|3>_m ziZAb{X4}K_K!x!SVMRvpd>dre4MaNQOuQM69~*+0A{KIZJlmkKt3&rozP0N2axTwz z?jo9XU%vmZ`J>zKAY=bqW%`fMHFqoOowT_%ckJpp6=XSi@uZcy247A~S5}>2xZ&|j zGb7KvyzB2z0A719>=tv zS+vi6-@azfhWH%ILuVCE)zmKAlVe}M<(QI(QCr@3t7dHtvR zdcHoDQoCboQ@Y|=@$exKv7U#xoj(of#UUw6Knzx}OY?c~gdvXkesZ{O->`&m?0H1dv=L7mp* zH7qmN?2Xu+E4k=*=^Vv(>wfBli~kkQ?Uy{YV{yw2k6T~gh;EzttL)YP2k9X}sSn$G zpIY~xEM6Z|yKR!@rP+ZlZrip0{d8`Ax?Ekp{B!Bv`xeX#Rh2!%UmWRK+cs1T|o`SAjGSks`&jC#o6ql%|J1Z^!`xRtjQziLf4}=!`U&&T z1N&jH>wL@yb`*$xh0YIkxee(IAqOY?*>x)a`HWXJS@DHUO+oD4^SAyrx^|IlWs&&QQhC>{iGj=B@tf?NeUf3t_PqFO8$X<%oau94W!kLI zfdOHz&6c+pytY^^KWCLU!yjQ`hVw7)yPlMJ+V?}*n4zn#|Fr~^;oNM0|M zTlY5C-~YNmqsz^Eh3BJ<-|W1ne`~w1ghzk;s`-o;Bc_%(lhN%r>r#cT)8 zSxGY3ryY9i?Bnp|>yKHS9rcfbc2>Rq>?$Ag`=x-eqcu-QiBj{!AL9EJ9hVi=uG74o zW;8|h)1GpvGq=~Q`E9>tf-%=MiFdD;Z}(rc@$aOwWy^Q^r}Xc3o?tQ4;r5hIMa$X$ z?=0+@&C_5nea^dokM+~7sb0tIC-PpL?wqniWTyN7@3$Eb7cQOi?@GtEYT4WC-h|Kl zzP}>0nWMqqi1EYRtJS7|yZ)WG->Uuh`?TUU^IdBNr@WfEeE%)4|A~th&e?wNrUmnZ z@LlI;Zq(mfc;}_$JNFpQzZZ^eg|t1&7>QjG>(G4+v|#xs_qLd>`rESI{DqJ9S8#QS zKlNzsJgIE(Og;T^KyBsHw`bPxSkiLpw98Dt^S_1T=6Ft9!LrKhMdGVE&9e>@*FWcJ zC_2V_|NrUpFI@lcO5F11!b=^mJz*i&SFO8x`4#(DV}^6TOZQLu>F-&vxa!c?rKZdY zvx*}7T~s(5u021q-hV!WhB3pbNQ+;)OaCxbz1n2_M4H!*Tj~B@qvC~o&5u`9sWxz* zUcE9lq@uagA^d+e>))yeD*dk{&Rew}%ak`gA*6Xs;AwIG?C;u~LMg$$`LW$UuJ4+6 zGS6$uzY|YWj!rzla)2$Jp{B!_p~y4wc%p3ll#YM@?rHixZI%6A@&8n!aPQ{$KFNxA z=Yu&Dl=ocSe3!rOrn`Cn>-Q4(+QXZCZoNO)8j>owW3m1JWgG8)^?PhO1++dZ=By+` z?4PR}-pOX3y!%{wTIV;%6t2uq%*W!DD<#tyo(LUS_gOgC_*?4S<^TR!TxI-v%5M8r&z*lp z#=Pv4bpDrDZn?41sd}#C*Mkdvj(vm`*yif(I$O6c`=-8P*PKJ%n^v@JX4rP*@0<(v zGsW(h1xC&NtF!6T++Q~yxow>e8Pe%~le{9nqbKgRG1r`9mrpb7D7kGYb$V&iRHJpT z_)6mLpG=Jv&-V*{b3cU5Ve+>X{tQoe8uWEaXYIeh9(btY>YVP)q!TKeV;p#rOV-Ui#jX zsec8{1kbDZm$#o_vG}<(|Aj+Y;pWFvgP1BZ%Flk8_V$6$f&Wi=8rXgGDV?`zM>W@$21LuzLQx4_>^>9P&US3s(TgD8lo?P!e z9sB>&hY&7q!K2r|@+W?86}>toK5FF}dpn~!ySDTfc}s-+VM@<7-Sqrxf2>oiaMBz$ zo45eCblbC%456PVpP#*P{jn|S;lG`%H#|xP4G(n z?TCM#SYA;#&0XQ#;ofy5Q-bYu#&6GdIz-eLPh${snUh?cZZXk0 z#aWJN_rd-7 zTkP9d96Wo1zka?rU+q$bUig~wKO0_K*zT$jPJJ>x^O)`CaP_K^TLD(x=d0Q^I<22s z{+)C=lj`w-LRHl2<#_oY7JM1_=o-(grV%olGHcNQ$44W^v z4`1f_9-+&<@xJv86Rm3>EQM{kXKu+#``_~|^!=`xLQ9?2>q}j_>nXRA^WvWRTa(Vu zUt{mG`up61S5hIAgg*#Xa1vWPGzf!MSfAR@^5yeR;pzW-JNgzrXc5U?rfz@!__>OsHgA3h zhQ#=YK7IOa+b3})xhKMbQyi~uoV#*aZTb3n+$=w5pJI5C`1jr#=P4CePoMaD;`!{1 zd-?2ho-B7~C{g{;u}vet`txu5%WcZrdJ3#Q+y0w1twO__q1w29A%7c-!%W5i(|_;M z*DomZc~@xb!nXVRzWXn?#O#S(9ax9!|_)AWnyPR{7|sc4_! zv;A3uS*Op$=su%~)4!j-UfJ>7CsiZ(?RJ@bhv{Wo9@XV;JI!u)`@oXD&T`L1k4q|) z+t)AE%gp_MQfb$#cx{dCQ#kwCUJILjdoO+b!qMfg(}S;U-rjcNWQN?U*UO98y^|j;gkB|GhBgD7ND*pZduUmYs?W&8DZFTAc&2E1ccw(8j z|JA>*$7)|~dRX$h;;+%sTKPXcU$_%TqC{8zC* zaR>WP$GR*V$b|m3{S!(${T0Mdu>RnvVIeRM37Wh<+rixE#^7`Eu9xD?{D&EX$dS40YR;=jQ#spYL@|znt${Jd14qMy#%l7QMb7jY5_NABFxA&FHPTMATdU5wo{_BO( zn{}`KzH2K!LBaTERmYpW-4>hgUCMp=#W4L|v3o_x>$z33`-G-Qc`?+yy(L(3_U7`8 zY4grWK6kVGy>;bZ;nzQ&moCou^5QYJ#qN~ z_6N*FZ*9`$V`pIu_*bP{x8wQ!#^GP6^r3-BisN{_Mh?$H_M5f5*qgIjX9< z#=Z9sh}Cs{@@Da*d%}O0#qWFf{s?1i#=ke5-zrawvo7*^k=&g+xl?Q2)AVEeuGv}j z?ovN?>-SXsf5&I8lzVn2gDOf}V~+e5OZ)eA&--AtS+^dZeEY{$Y@@oq zt#etf{r*39%YIo;XAy0e@!xar*OSyMmUdoyO0169F8cCf&C@r&YZuR5G zUJS1%DCF0ao36bvIaB`L*8PmJw~E;gXnyHhXV;VDzL#1}>N&wJZtt=bv5$1G}pg}=p6frSt65#qx9Ut0m)mR?nMU z;ddi%{croFQFg2E8%y2qdD~SNJKtQ1A@2J*t-{^U>b`#7KJRcv;mpcC2Cv@F`FHXQ z=XA$1+kam#=jqw+^)3HxgAZYLf|kEm+N5e+Z9D$+%bx9zO|ShG{#Cw^b-QnYLhIY9 zDhyukw;~?b7Jp|o*;2hIZO`|*d+z=} z$p2Ecf17Qt4@1e^^NeamuI=qv*M9#!$Fpmur~kU|ueT;EJHMQHdhLo_bT)WwcFc_S|0@t2a&1NX$xYnLT;`&5vKM-CyjiV{2S% z;VX5+b-T*Cs=Tzgbdf2Bf(6RLKV)1S7XS2>n&2dVPHz3nZ^z2Rch=ssV1D4H$Ed^6 zaPG(Aym+fM)_adWt&Z(KZzlIFX#4BE*REfzwYt2>T5Wfk`~8BnBhfQmUazwEy=pd{ zF<`a-%=Ou)%e#->F|6mU-55FLooWB|sv}l`R)03t|5?yURTv@duXuMTE}Zz_I2%Ri_QJBIUj_|UH>hV{%&_-iTrg%(NFnNc`J`U zUuu)y_r`gBT=BML^4g3a%I|)a7G_B0OnCnFS5|yh^~BFtC-0wF^Kp;iKZkkGKC=9J znsa^v`xC}L40Q+gAKI@ZCp?oGbz9&AejJ-!E~tELuwq{DEc{K{z6%RqD7YRy5)klv zN}8PH;h7U1JTon)P8FNIGxYns4~I%tb-r}D%4u72pZ`jCnlXdfwLkSc^1JdZZ%^NM z*YE$2i?h!9^=-}SD`Y#s{Y+0e@Y1C>i7pINBpJ?rQ+{VWnK9to_IDS(S41cE&HPj~uSZqIXJ(i3%{8~U`ciNr>)PYB^DSbt``mn7 zRs1>aB|7j{q;q^I}+QB)Ed^_czc53#jTSLdWnCOU+;RY zXw0xHE`0m{>eCjx9$Z=X%KOyo?j3JFndv=zb9$k>hOp{HcKcsD_3!@t(xYH1mC7*Z z>p}gt+E+K%X}rHP+4y5+HOHsC;}Or_%vD_k;kLdb$WKpetI{Vr z8fodcd=B$W?R_@uVrxR*srqL;YxY_l&CC;IIq-aX-sKo^@g9zbbo61bLT~)(lu3JJ z&K*n9KJ}`5U(1wdK?YX?BR^&8X4R_~a6Vwo^J4fczrp-fRb6$3*4H;HRHxqgf0ON3 z#$Cmw8tbO)59EBXH?q~_<ig`8>*LgpTg8=xZ|v9M+xc(*d6}mIef;aU z$(>$WxnFL>_vQ1}&lEcF>i5#R)FREe>&m;AOlq_J*eV=%;`i0pg>TPy?6Lm#bE#Bq zUCJ!W+kd|v;QUo^R#7PZ`p24FX+ehcBF=>J*PlymcK*NUv+3{S9sj;eFJ_k%%DJlA z5PRHMiDBN?En8VOyavVOob}oD8RqNux7jG3Uv@+qyi(z5$NmI<$j+^gx{n#8nLY?q zaM-YbS0dru8Ygj#S@V0%nK^p9yKV?vwtstNjj70;@F}Gsz4?DN=daiFK5)~&NJB$s z(W+BjY$xq^>}ol5>hp>%t2Jh3-1a}}yz-kh!)@W2Hm3JG7=HW^zvi)7@VfGe%(;)| z7#D0j@Ip+_clR9c>{V~CYA`=&?lv=g_^cuPTg{)X*+&ihj@PK&Ih*)s;r8FDE=p4B zn>uzr@HP0p@A*${&1s#cX?%{StO7$Eqx+vu)VR63g)?hf)I#S!^^<=sp3b;o(XMH~ zY_XnC%^ zwe!?IIVJ5m_Y^%Ao_YS{@T&OZ&$HgTytiDOy~w6yf4kVt-;+NH{H;F2kg>qO>dD=; z?w>QXroRpSo`1~l%ZKL$ew@A4i7V6oH#awDo-e-a`+DN!w|V}{Rc{-gNLra1S@E9# zQrym2hho0vT(vvL@Z+1-{9luQYd;kgmGepe_R1yw>zfldO@vqGKd{!+jko(L* z?!wE0bp6-zbKPQv=NQkE)7MZ}WnOUZ->7{w zH{9Qj7WSTgF1w{s{Xp>h$F)C%q0s*a7~&YnuMp=iU~^Do&}y;%`Fks`M@sO&50{U; z-Ed3mRm_(DrrrEcC$>0GZm)l)?7rPv?04%n^ZBb*d1+}(NDY+U_HTu-^@<(mca~*t zWBKVP^Pr94hlDVLbY%SH=W))9_AGgA`1Sq$%hwh!+OzVoT@OdY^uM3oZ&j$Yzc<|< zU!}6>XZB2n9RUIiPZQVKJ2O4tUevQ9`Cn1pUEyTV7`w?43CmTxH~*-8TahTaHf7UI z?)y2*7j(8M z)D+3ZZ>g{M@^;uJ%uxF7{kf;RrH_|w-}tsmXwS1}*;5!V>}1(cR_pe++vrL7{8Fyo z^h4$U_1^kSmXh66vZrVY!?nKs{|wDp9Atm~%8I{sGvl~Iw#p@uyRr-7%U!4Jil_uqFdTOU!|IDPG|U1R15BdUs$kzxt_e= z=40PJ&%C2*)YG}9L5Vr3E_3O_Utc*IGIy$)xCw~tz2Y4#$-sN^ z*U@=*=>^@-uXH5;PMdJ>i+T8kV_RZg^S9_du2f;zb?3cbypJHm-WTWR)~)#Nt(#x| z`SY^p}+}DmtooF_>R3 zyuV!f#pAE-Z(rw%FgW#%mf4t}XyZgeQn~&dGsmF^<3B8!vUw?7MkI%Oc2d_*&9%0$? zchA=dIp5mH?7jP=kKSbZt#P%Qb8ya*O>)bR?#hhFdi|p2T*UVGE*sPSMbFb z)1tkS<0D>O{nJu&|95jB=L7$}llJ%er(67+Je_B8wmV1Dmd}N+_r$-P&a5tdcHTS7 z{~^1+HwDjS-?&w;>TmU}Y3EW`e|e8 z>fe=bAFlN-emQC3UDH_oU?YZqSu6Z^J&D!3|M$V7-nLKIrQ_c$S2$kQ)m<{Hc`M5Y z^R~yUzdEi&;XZDRPf84G5w+jGq}D}?Ds z_FYhBzW#MlZjXA^FYZdmxO+$ZFNnY3{&G~TdF3N#<^SB!F7N^Ne_t5(T={FmQv+H^ z-@t#s{Tk!#@BNTg*f$271JBcs97h~!b6|PJfheXMi4H*%XZ@ZNvSIQep&(6-Z68m4 z__(Uzhel&p7nhcn)~An|kB=Yn@(+s55D6`NwYp|OZl3Mu)IFVf91Y8j7y~5c>Hpnj zr|x0YWU;(_&-c@HRgb!LXBB?oX!vQCv?%-kyjxW)4%uuD?2H%QSn=<#5p`{8v(R-_ z6x390sGS_1QD89FTBB9Z#&qgAyQRXV{ym`_#(vE^Oir!RF?sOt{7OHaxUK$fEC&pI z7((u+r|mr^$zaL7_-*&!V;1`l&HR~G)Mj`6aclmzi?i+DeyqCp?po!SsjD?jRBn`N z>?%GO^(*Of;PO)6B4>t}gDeh<3(p8J^gh}4v(sC1=Un4PV{oJR=hBB2Zl5`pyq?F= z;P%NtiQ!x#(}L};sq4saA)=gPtHz#(H^}ZMGYhJIAW?FFX$1zEU{nuoVgVvni zFSLKZuWz2C-URM1O{ET^_KtEB*uOCD;2>@YyYavg(D6Q;!X2+ee+wU3`z&AmsWIb* zkfKZ{!}8GVvrM}hKprTYJ0@5q1t^5TZ}EupndA;ssq?^~U{f49cw?EYFG7F(-Q z4PX1k?YDyt@_+ba|H!B9)xT{7__KZ&2XaWn&W@xFkayP zx%&BX^MCO(HY^F3`}O&3=9laJ*DTlizpwQFyZZih^)b8iR%L!C^X?1n z^(LnnW~6HP2U=a#U|w*+`fE+h_02ENPc~T^oo(?rc|E(BRNwP;_SgUYy;}F0&0Lbf z{sCwTEXCzsZNWpe^-mQ~Y}_TuFmq3~$-eEMyi#u0ro0l^c6Xj!ZupC)xc}}mD#V{T z1;y@t&vLdVed@cvMgLjtWa~OP*Bx9G{@gi*_wVOFTfe;hRx8LN+;nC3DeEz_GRK|q+H@P|K>>DH|w6Q*aM-F1cKGRHc-r58TcXuU2A z+x%+!CK36s(Gx!Pa5Q+aIcTcO{}%86{@7@r_RKTO%VkdMFAhAfdvWUYI5r1I2AM-F z4${p>FD`BWDLJvj#WU>bhYx#X@;$b@{QCCpv+UzraW{<_PL=z7Q_r9NclWktOa5&q zUX(sx()exr75yn|65g*Vo767I7;ut7L*C4C|M&c7LILU{e%Zl(-Lk0pMg1p#-u@kYSO3(3vNBC(?RT4}KNsb_{dcm(=GhRV-ifxa zs=sJ5moeau4&T+!{_$mOXQi&6uZsPezut0w;MS$*s$5I=7cFGn;+x7a<#p&<_v>Xl zSvE{!40v8w{^^2pz1FthO}fkrrvE*8`|5A?=Kd;iq*s z_x)NE_vP1C6%4FuS1)kzwQ6(DQc? z1DW6kGUzZ9QXV`Me zdqSbyY_kwsmCj9jn>rq^t^4zM*F-NfhvnyXY&2gz;aqL$&ft1CmIE7oiawRa6iYJH zUgx)*zocy9mY*NJW2Z0QvcCR%delzy%d2ZA{e3m}>xs~$1)25#CvKBDT`F}vrp@T> zFZPnm=W5Ik61V>@czHqY%X?|J%#@GwL#toTRNZfV)<3_ts_er%`C}I>|4y3w>&}#E z*{3y@&)t8sZtu?X7R(O{XMJtlDEmr?!LoRsGV_9;KWCq2kZ=i~cXhJd^^JEY`h;DZ zyx!V!Pvu>WU2}{pcga<6?#lSI`u@vrs}zo}d~YpZ{KG3#3UNsGPz z7#><0SZj6h&~5e1Uzen}s|qn3-SzdEu9%M3^uGF^(N?pfm#tP$`|f|oytab>*YPtG zr7XL+_deHIN)#q)zxOXr3cb@1>mW!8^d zsCeL=b)d`SxQprwBwr>vuiLJ|v_S4-XwHeJIlHC%pH!*-H>{oXV)JeFtZ$cP|NZb{ zm}8zTGuK+f)%e<6?rWE(NB32lzJLF}Op(_wcl}Fl76*1alOu9hESl>+F!KFk*v&-5 zoFCF2{~ZS#uk5c?+7a*be1l+*1@jF1TPtVokK}By5j_6GMt{rf7`d&bUqdF$_ct{) z_0@YnK}wBb+A{;jf+u3fl!UT@(eu5HPAvtOPMjo)3~u~h#3-T-G7(ZAi7E;-MCa%Pg=CqdOs zyYxmcCqW=FC zpXXIR-~7f(`HK}5AJcx_&u6clwtRJs?N(bM2Hq!yHSbJk?L03o$snFeD}+FH@SA^@n}goV1MH-|KcA)c*N@;%Q6!(whcnrCQ!{IW3%L_gavl{$71k+Mc~p z-|KeXW8L1j{Nvxb#H z|N8mtHQ(NTHvho=gY^$n9ix5Y{2w;W=Z&$R?PZc>)42OBJdxo=Ys~a} zwQ{^~r>&TIsodJ=#kI=)JLk41+={o~Wxm(ouaDZsj9meGFH#>#U)^o2`)jjV_I!q& zk)P`pzAsO!k_kWc{P=IZgqc~J3v2gT_Hrh^p8Ma`v?b2Cp7Wx)X5X~GZ<&N5Wxn=3-+%Mik!5>l)zzM5&^Q+T z^MLEDh4=ns^6&j|w(P7$(fp@3W0xIjmA?Gqo&U9sVO7V(6Yn>5yk51v>B!CMb55JC zT%GyK{oHEB^nMnH=C3~%vwS#lZ!S;n_x{gyOH-|leNN{dtqm^uSYSBW^8crcQFrUU za5U`h6TkFxz3%0`@$b47s{e(yzo~qXV(44*)4IP({ntzzgH{(c$Lo_`2F_P5!K0zjD{K@5g#;*HtBOef8}s ze|20lc(!M)*zf;;zC0{>{KC$!_T;hO``;`-zW>gu?D>L)rJ8?VIn()V=ijx@GG1 z)-}I_@BNt9_jGFIl=*RL?l%`IICs4%RN6gDaNk|KLI&H4i!Vi_ba;;b3@~#4m)-jC zPw$t&b?2vlzrQO{B-Uul?$0hew&px9ob~nK`nFFe3MMmNxcyTio#9WI@jeadyp-MN zH@xM#vtn&(YvRXOCzZ`6!Z!7x(>K)~}}rJnw#F ziQ{>Ft#R6)uQ9znM_cu`%PqBjzW%bT|C#;Xzcs49FEcb*Q_X(&`O~BM+m>H`^MCEd z6W%@RXERPH{rV<-+KYSdSJ%EgxqIo6@T%XvUpGW;`d5*Ce#iXOWzF&z)L#g{;jCb) zVX-@8|Kj*_&@#3Uf}n*cc8@*_+3737&$d84YnSyn^EaUbtK?6pY%qUr8S2WAbFPrJ zVW#YQec^xWB(L_LdvSGUC&M|_KM|~VFuW)`EdAlx#y>_@`R|Oh)^4e| zBW}#%u=#agn$q2O>C0bFT6m=B)6OR!`F9&TOG}?lz3@-?Xi3ZY zw~G%=6))cO>#ywID1A)TYb}dI`D@!>r>?eD ztAE?uw)umm>8nb)<;6SSo|+Y>YF7)Sde@ zZI*y9^Q7AscQyxkyx4P3@z}gSuZrr{-N@Xt?3kx9i-T=tl@8;ZR=a8?hE>PSwdU%i zuG)5YaplsS{?I8B!UvZ;wNP`Z-WFSZGIQ?F_0Qf++-sff?a;l^_1m$ib9XdO-R55O zyF{(%UGm@Qzo&nEW!h$?d}5vVwxyTfAOEy-O_?cg%B1}YdEZ}2EPv4#c+GxiTH(3` z+uE{|W~~Mqn;7TmtlRK1o_25P$ac2Yn z=wM!1|9i?y*+2I7!M}oyt_KvnO5o}eQ?>bPFTd4BPwLv_e-?!st}n57WVv9?BKcwR z*55D1)mWy5ME;oeEH*#X*HlzYB*1oZ%o-hz_s9GD`<8re`?6@AtgGbhDy?U0Vqbqx zz3{FlX8UW-Z6QGsfoxO1NgeP1xZ_aK?8?9Q`j$^&xOTGOm~j3V=M-6C$=5TsCwbXv z^BObM<-V#6|GEFz($4jEtJ9mWt8QAqv>?s$YoaPc-SO#Lewn?WR>-C3U0d%Q&;989 z6!W@-NB)ZCOOpgX{)m>_KgH^}yA>};?dj`VJ{Q-<-K~4ipZwxbaPZt;LM%(>eXqZk z@=I1o#^>}qOMgXmOWr#yyc2(Z-0zcQwCTDh^W>NR(=v@2?j4b22!C_7Nc(*3`8dC~ zGbUs_lQ<#C@%6)}Z6E)>*qG^jwj}YD9HY0ftC*$U!M9oRzIXq9=Ur^coM3*|#+B`W zeG!|(;*YEg&wh>A@J`@tGh`4+x~T`MxF0ApML*({~Yi1F9q|D`fpd3*E<)xZ*tuK#O-(MuGtoC zbUF}PUOMMv5lcG5mC5JNJDT@nC zcJGm z*|sj>S&*Q{@GH4y?^piUH)qPtt}9zC`2ULikM8SBr&2sY~^xuN{6V=E-1k>;BX4F%Hc;LyD4Rn*Nj@%s&0n zp{#SAO|LOS-RkQ7a&{hn4U`zZB`_rfzbY1p{>Y@}I5&9`%hRBpS!hptb*ZS?JBzxp%#Dc(QzOf{aq-nHAmZtK*0PlFy6{S!<)xaH?YZ%xHx zGC!|uwZAF0P0?%D{F|E>?^$BG{}jss^ST?U*VUDo7HnnNP_~zMqyEmg^51LI{ddgY zzwJZw-{k#Ue)0eP^8dLp_~@b=e?BVwVf@1gK7vyJ4;Vf|sdpFu#iB()rq!Q6y}hM4Pi}Xb%v}2|+h0{ap8oy(?}=h- zZ!V4WFEABm0QX}(>dyc9ac$zC;`-oJ1`)Q|fdOvoYxj4H<#~Pfl+%7c|IkyD$7>&L z{HuK`r|Z(peW$`x{{MR8FKqJHig(dvf!CGUSL3Sw&3^mkS*h|&h8uTZ>UlDh#FX4S zAE2lG=j0nslSfnhc$JDcC*5$J^YgvI^nBAz%XRzXAE_}fn6vQnpPna~E(~veGNd!) zXjO+T%b0t=LT$yr?x(sP9=(MekM8$ZZ+fv&e_KFUVCyRH+Dad(8?D9+MQ;AnA20iE z$*l1GvBj79_dmP{@!jTe+_*2CS^g{>f_(5F+Z?5$B?nWUvhoi+Zku$>uS0x^8?VieWw5OIxnhlToGKT_$u0W zubA1VXa3bMu0GwJac#%GFIScx=9#}aongz`<55f&w_et%GC$ZnhcUp^e&@foTho&j z&VRZhEq~sd)1mGHf9;>mSsdUwstFmIf5mSFF&$uk!2H26iunWV+--~l`5BN-g;lTv zZRwC|WA|cnXjk-X&H7jTe9v4hri9P^`JqdyUR_shjGJS)?Bu3@mIu6lYpveUGw*Mb zGU!~V`y$e}Es9pGU%hlslhdYxm+|?(MVHp)&$DTHH&2bD`kt)uvpT=m-(;V+%e=mz z&R})#ds*Gt!g^=UhSD=Vs~`20Of}u=ldx*x-I=UgDoz_l?K5t65l!1#vnRISj&Z{z z&W0GK2-WiZ-=g2|mmf^nRs2bTi#M#fXU6)^iXHXUo47;|-Kf$_)Hx`uAjSAVgm zt7Y4lv25`CS*gabD?Z=(yQiIfZAJO7%Rd;sA`?D}Gv1TCc~sPE+LrPiA*;-*Zt83H z)g>vddi_v=p(^fw@8aJV-U_n?6z$fywmpHDG2}(WdUo+iOT)fA-M8P~_l5uVp10Xu zAsWx-#D}?_*SqUBKiB4v?)R$8SKixOm1=bU+%4zDnPANru)8i;wZZm;@2RWCi~-jB zrg$g$sN8<{((cx~xNUcR;&v7OFOvBhDPZ4v=a>5N;0lipxAGR9xttAs|6DcS?w@Df zk=Fm-f1}{SbxGH^oL;TVwest}^JYPk>2Ifgjwn0-6Li4Tv%12Et@+zQi&;*uU-P)@ z(%p66t%Mn5KMVggZ>v37`RGmj@3udR^_|QX){kYLFjg{vc61Ddb3g0o>%!P|JQvvC4WwJ;@|Vrm6g}e(5w5Ftd-W( zYtxkNwUeblE}cOpaqp9-RZ?2~Hs_PRU%K~Oee2?4_R@tH_gZV;yxKG~cG~f3txe)` z7Lh*O*JQW7T6N>1+Z}(ybCG+kw2sWXH}}!X=p-KD;>A-GKUthkOiQ#}`dNnW`IJct z9-V7qdM)=YTF|>=-m_QwYBp2Uio^DSCSWhT>zpDX>^Lz|an4I0f!9qdx;j^|KD|06 zIOyOf?d6AK)P7d$rS7t|-5+|=Kc#5zvo~>E7mY3LCRrVE3*wj@*?RBYX{}{*eU99% z(&^vC6&lGG{h+Qo`~2C${YkrH#J1N@uQ1Bp-PBjO}MLj~W`i^Bq$|LmDo`u5P}AkD3{CR4+&U*bGBZ)e5nK(#7vp*?RK z>LgG3PZW5<{8QqF_?Ko?$kB*7=S03S*d)j{*dCBu!ty{qk^ca5CU1v0Xshl6M%>47 zJ4zp7j%IUM`S+joc71C%L&vQmcUDf1R}<8DV!yK@Q0&J|eX|R%Y_&c$)LeeDbIqC_ zFE1BO*Y|xtUU2++eMPY3^iJo!)dA1*vNa#v{Z{UDy68u#K&Z<6to?1`$QSp@g+a0HJy4G8G9=z+9&bBJq&dYYcTHg1^K?@ou{PfTNz3=DT z&5U)YZ!);)9hD_5A{S*-d`_nFu1ND3t-9d3 zj~5+!QNMlu`K7MO6$cL3Y~ng?A^pJZR*}l>f37np+GJ(vhDt*K@6-h5Tn1_ta#+Jks%}Ippd_`Kw3DzGc<9y*^qx&Fr`P3C5xZxdVK-^ERQ= zwYJ#GY)E5xGME3+f0oM;iF1Chy!-UWdXY={YYq!dJyWmcmL$9-ewO95bCMGdCA0ne zc<)r~mw#G;e%FuvD4N7xxbuFHP-^|x`{|Zeci(65zq&RtZs$uIq36pi=KXw={_A~L z?x`OWZ&t6^^I9@Q{N}y)znPv4jCZw6n8EK~kV^Ipr}gZ~ohH`qVm zf9$|e^N(GQxxexFf#e5EI z=Q}x0{HXMOee;HEE}tdOAK5RS-jm67E_(9U$_Flr>CAT=e*25ud>Wj*F(5EeFfwb^ z-bv9lAr^OSDmCuf=DJKi8(#9~VAuVZFVEKnK9iohwYTf{-1DD#ww<>R_`?5LU}f3t zd+!v|Pe@j=Su>M101ny%104^)U}2GPn&HGAd9|#KQ9r-lS@?p%)$M3NfYaxcC($+M zkH-8mk1DtlbtNz=(s}-xyX#Y!b#!$XU%Di;{<;08c&)vk+CQ(zZns!J|LeELufO{* zZ!H!NF7Rb-6-^DuTwhps)wuq(<+1Pj=N$e`s8{%5{X+4JK-G)?JA}(PtXpIc@il_x zLx}6zGO$On@|8U0Y3OUc5fp87`1Gm=XK(kdweb9S^{2=jqYK9jCmT{c zH+Ks&>|AA(|2V(2{9Ee;Rw0ju76vw#1FQn&G5Z7y?;ogTmHF$E>LQ!qazIivo#i^C z?DUz1jt4}q6dr6Xbl4vl$-=_oBJ|C{Y*WdlyZ3i~|F-g7OAE`Txx23ZoI2^%?asni2zy9dpW zMA$y{|2f|NjQMlp&jU3Hc2n4&FjhLqfmXa@rxIMAHGY+5`0S8>_UnqR{71eV4R?P& zuYFm3Am96^#`!f>Hf8;ihkvWwesNKM$D3Uizkl!VZS9_(`$;n0f40nV`~MFrZVDF{ zKUI5g^~C%M+krrDao6)ZWRuQr`T3VubM4B_jhuHshYL&dS%?Vlu?k>+b->~Qqa3lQ zaocByxl#<>j9X62PIo^(=kH>}v_lij7d>U4W18wz^ZKs)le2=we;;e-^*!3ZNN_{O zE^C#!&$eg$(GL54dz$vYTn-a+hQ6K8e?{27Hr$wZr%#GOSVg#vbMad>p3>|)%cKIf z|H=Jl#8=V4P83?;CO6}6`Saydc`qwwE?F9Pxl}oJdr|eTOVY`2c5q&tu`9dS{?k96 zt6u}#&-Fk4|Lg$o?<+a{!j1Z|MX7WC^~N8Wv3p&wXtn+B%9z&y`D@pepT8e<|3QEK zyzn0@zJA{SF~dfx|Le)e#}^uCp{YiD_!c9?iw<`i#N^v1s% z7xQ&5x5=8Gm{tCHgS3#v??v~IEkE}=uw+TF&H7oNTS_b@OGJmnw@$FJ|MzOW+&*); zpB?=_XY~Kv!S~+&jQca?&l7*1s7bLil2_&bvFFHhSG)C}E0>2sq^^7ap8^>f_R<8I z4-EVypaa`JIxODFl#q2t)4DUe!1nLH?Bp{?G%wCD%8rm?(6|1Ydict#XNl%+4=U4Z zl=J@GU7z%HU4QSr!r-jn^wO2(zYSmLS7tqsKYsXQ#=q35RZm_gvGSBI;JeaTc!1f4 z7!;7sKSi4%Z%y{<*88(JR2BNfl@*tq^IgrrcQ|#4IYZp`5BDOrt=g?pej;wI{nd~2 z^8a}B#8pMFx$#-@aDj=f3KNGy0|RlyhFT$waE6?HU$%ToSu&M<_H?nl>B|}CeV&og zGxx%sxe|;1N_O%#?BDtE+l~kI>$>IRD~olacP>ksR^dC(KJ>)Y#6_4%T&)qJ|&t*pMbY~QKr_AXzqxV-!*bAQ&4;97MiaPl=a0qa5!iMtLwx?Epx;(&Pk)syV`~KgK*ijMr zKl|p7kF#xai)#Mxp6|-ttMov9|Nq%P?uhS`;6GDa^rcs7`nSTzzs(C2?!>i!d|r{l z^eWJHTbn_C#=pIlS`JC#vBg$e8h_ht|U^Gr{S{F?nt3G04J#q__5 zl)e0ZpOV#cTf0Szvpv3NsH|c5F&@#Xs4uRi?=KG!Rq zw?{MVoaDUAmieo%KdcmRU|?h+j%eH^m~p1^J!|dDNmBoVmuK(FTk?8Wj{oleza*^l zVoa8ulf3lz_qE;gq>alZ;>Z<+1Y9-2bm%iXYz`x3Anrrr+u*|JN0ASCeb+ z@k{iB!>r2w>E94p`}IclGv}Z2f2RI<^3RihLiXQRpE>{R`Df{$H~+l(C#TNL{xqb# z%DG;dP?p7@<8mYB*Y^E_8~AQ7zOK`m`8{5IZgF=ggZt8284kVZ&GqwZ4+lS9a5p{2 zH~+TT|C>)&?>c>KKldfg`u0Z^vb(;&vG|_req>4E;`X;&YksEJcl6i3niFAXZz^qO z)%NBG@6p%yXZ`y4=j)fF0Y49ZEUo#uu>R$1si%yOt1~|F@Bb*h|D*K$PnrJ|=J5Y$ z0HIa!Js%b2KY`J&Jx89aA{VaUqSip@lf!?mhLv-?*FW!j@GIy2mLIPqOcT9IeD3R3 zmS=o>f7buD`Mp11SPx(OVRnW8&r8)wv^US1(UW^jfcPm@$i+|LX#|p7vi) zIrr)RyVN}Y=S&bf%l?e{^Fl;D1rADht%b}pxb(?kD^tR^YTxzC^>!*A>ywr4&D7 z{OW?K`!uF6T6?oB{QRpKh2P~DC2wzDWLWja!TDy`oA;OHwtCk*ndSN?OA>Fq5KEB0Su`SDdTit~ed_#Khs^Q+R<%=rGLV_l$g(H^gfxko>K`|R2B zvab8%_86(xYVTwo zr@fUF4rY$o99*Q#ThuIl+pKhdXR`az?f1XlnPHH2rR{I=?VRe1wWlAy-}h;=hSWE+ zt@E4r+o#`JQt|vVU*B}wkAcy9`ll~HZuc&}eufm&^_*>j1=-5$96w{ToH25*sk~dqu!>E2{t120tdnMREC{_{0#mx?HC0G zmehT~?el>-!umRY0^+;^pO|W#j^DAoF?g|T_%c)2SpaX(ZDD$_!*zeZsr7sD#mD?Q zJSVFiTd_qdVPA;8LH<+be;007pPwTHDi*g_3MX9rQ66S>^?mE~zbkh(&%XWNT&B)p z&+8M-$)9#yJUjp9CH-~2+T3z~_3vx?>&~f93qHU7y|Rt$ht}z_;>&BktclqBIyw1n zi{#2RuR`s=9sjsu^7$)^t3vuUXKnNRXAsvL{`hLe)77tJS)fJYr$k3kcLMBVP>yc= z8GzZTXq@%5u~C$vczMa*^~djhJpSTEoLu(ubGpSxe-u7W{?o!~xN7z0JAM`N-@eAJ zmpp*vW7|A!;>eJ^CBSEt!lUGTE~x^8*n{s|lAKV`WalgP<$6O<6he{#CT3T8VK zqFeP1>{)LbpK&$xFDcF|o|}ERpn7qBuFsC2mm+5SvEDJR%i1izF8Rv~3G1qu9^d7k zWv^bH8m5GBrlWpk}E_uh{C+WFq4(CdNj&NF_? zrR|>YP)<7NHm~}_dGYmcugd>CAF=ntuZo0!mlv;Bo*T5&_tnX|Wy+R3k43^`u7<8+ zlzSpxXG(&9+io)VE@IrEFB(<3?7rE~cM)4n)b9MU-&l3b?xK0t9k<^;yDoJ#%;mVf!`@_pC5lIV-er3}?g_sY)q+x+{I zv;5R;+ujAO`SyLXc3$V_%PR}J)poX9&+9(6d;R|BNBOOuzMrnQQ|p}Ha{jnoS!dIJ zdv{G`X5T+;{*q9Je$Ukmd6}_qCrAl!%jMhrF_doo_;ibYdhP#B5yh{kZme2fyEwf) zR_OG%RqDTAS8Sd9|H|sB(Dg6>HdZcMTQvLe(da!#qls#L8}!J{D1Nm4()x?t*S3^s zuIm!K&USmT_F81Ic~ z%)hkb;@R|@H^fhemmc4`^5T2*%+|f~@rA`dOPOZ9yLJA1;v4^szwWuJ%WjSP9RKmh z@qe%RFLTv#v)lfCCjb9+ChI}xZ?~5IG-luToO`2=DSz1Xv;S*0{y)mqqF?=}Y0}Y6 zQ?pOC9pes4ethVtc2bEIpKY?*(OENpZ}W&PgXS9kxZG4)OVcvbE59BS0^1o^Cvo$&YechH<_pIlCZ+Z4v zM4MyZcWry`^P4Sd*Z)XSi8uRSvw691PyF1EyZ$h5{Fm8a{{J)o*P7VV?|b^*g>Ec* zm&nW;l^bO5>v-#a<0jpfPIkFS?pFsZKm#1iKh^#_^?}-JKN|QavG0lhRAbh zd+)I~l0OA$XCgN(6!@>`@Q3g=gsO*R3219?S-bA|{ZFsAFeQYqxm);s+pYJG#*f^- z|MqQ{mr&pT$Mfa3jz?SezW;klHS_AetC_1UCofsQ{ZGZ*pTE+V1~a~&9QH0+#{K{4 z?U$2F?bpn|f8%r6x;UZ5)9#4zzxlc4#cP?(SNp#g#GOC(?fCipO4|qDPaG4>+wqa- zJP93C2L3B2nO~bTOq=_vnJ+*($Nbl|qd#Wr_s%N}PP)5fX8#Vyb$QI2BQifs3AfRl z>-XcEhTqoRTYrb!+*?@vUdZ0>Y>RVXgKT#A@fX$k9ih8rXWe)o@HSrh%IO1>7OXt? zHeYM?H>vmEu7Aw>b^3>C-Oua?B;9yE4WgV0IBD2m-=tD z_)W^H?{EKgs&IaM*}pj(dbdfho__pCw0{5A$?2}|TQbjiOqNp#6u z{(1Db=X>?`ub;U;ul;$gCVQXheKr0Q(x2M)DCTdu`2P13^Pj$TlkbBmU%3e&#@ejp z?{(iE{!BR6d0*?<#ed$GOP}?Y+_k$co86^$;B=7i1HFsJby2tX&wIssrN4ghcJpI* zN_|V-e_8Ru?`-|m=!tcAazpe>pLVBzyrvibD*S(6|KrK4H_v@`JZpZh`s3?AOzVsp z?H(}OomhOZ<{UW4i0asaI+Fp%YYa9pC0O~TsuxPfm#>Kud;GtuvShj1foEO~xqqr& zmDwy>u6|5spP}i$v%Om{f6Mq?wNg6%_vB^XkFW0V+8HRj<$ukY^j9}5%=#+9?Nq`o z+63uJh51Yt<(g?9-tM})GcB^mdpUEQd12bGe7DULm&C^V$M(4|-mdPp{PMqbb9cFy z_|KhP_~`ci4bvL0JgvAnzpLSKps&g+M_Un=9`?rzE1IY3zjCx)(QYI4Vb=3V`KqEbG=M*94*%^%MY8hzPtw=zM+j6sZf=i>6%p1of;d2nx;x_nLVxpmXb z*1a{T%aPf0ea#Hp+@hF@oAZ-?zIr$9?fItI{HGf&Rn`l z{(9*})GmWv>2HMZ20zRBRCoLC0ZB*R&1!bS^FL}cd?v233oR8KW>+o9Vdx1t@Up&E z`9sy6McRv!ul{{{s&wz%#ZjNE%IBIHp0oV6Gxc!nMu`_&x!?DG|NHy=<5{iWb1whY z{Py_Ab6FXE+miXuW-VE7_j-5XP2O&^UGj6a-}S9~T7GoZUH-m%8-v|aYJ0Bi`o7C; z*?F1p}5MplXdwHhlSI&-P7(!CBOd_ zyk@S2ah2LzlM5%d^~T-T)UOZP^H8!s)9mh3{jRAD_CK5d_udv;F8brr|5%_omAm zn5*?m|6L%zH}B#ji;vpVr>qv_+qW_KY?nmo|Fs+QKAm}S?`7b{>laObq{S-}JA?;P zccsN)aTKG$rTgFAep$btSR1=0$Nbqld)M%&yLoS~R9-Yrdt_F5ck;2`&h`7Bw{A?h zo;ln0jVtqmL%*jTFWr7u`gGXZ&evjkeM_~k=M>p@r|o~V|Kv+cu`@H}exIAS?_%5j zgZ_U`cKvpYL|%!`^?sbGa%WoNWKTIzP6qcFtTs%RL|Nr84_ZiOWC!>gmfV z`?(jFe`$%BJL~_o=&$(_l~b%Aesup+A^pSE`kbngZ+oxqp-`;!p&DT8nlgIZb zy#JbO|M>35u=mGyf3&Ok7tH_4(UxaPz~h4z268>^umbhNzfN$GN}$ADkY<;$j$wwi z==RO8&zYW1`XYPX<@hc3q`OaI7pMQ}J9))3^zfO)`z>c5`P>VLK`zJ6KLy^j4|=Q`2y*}bVU#8!m zFzfH6>$9fo-kI-abu~ZS>T3S;RjN;4znr(R{7c`w8B+f*Dcd$3uikO~{lC8~AHwpF zMF+G0nH;c!{p$qI8S*{sb|)4)+C2r=q$gNFLzD{rY(K#j>JNO;p0NA7!GiS@@;f6Usm?euTeeUG$3=+n;$=i6)S zRAAFjsI6@<4>Vqy{QZ0V@{HuwuWo*AwkTN>E4lbmS3|7#<;>FGRg25tOvws8aPA`W zXNTS$qO1Ruu8E6U_wBlMmD8HJyWH2zHG1y2UfcKa);smTpYHe|C{J2_%E15OfLK++ z_A3lCst(3%YjAkZ{QbxZ)$Oj=KUFVUUmWtKXSUGZWVNOLFTE^@F46RRe|uwE<*$6# zn_sRQ=N*4B)57+e-#yh|ZoSzT<0_+w9FYf)+&4Z{yKv(#^ZmEp)3-RqD6i$1zV5Q7 zVs8FC_wcC9^_w%;bo@5Xp7s8hTd%$}WA*W6Z3h;8TvvQ%!-qF-;skr&O-(%VN9;Gw;t!e_pE5 z#1j|DLsAFK&M@!ZZ*R)5ENo`YN#TueyADkI&~b0;#fef(yX7Kc;>t_x1$s+YFIul{ z%2Zb3>i?gs@n}|KW#*|f+t>eyi#n(u|LJY-JkytkmtNInhr51Rw|ZT7u)y+A_Uf)s z_T%paKr=%Uwi|Owq<;L=^0={%Bj@DD;Qz<=e@xmV!t&$LpF~85f~bLEu;U$WKW)rn zJy7x>=y~ML%E)yL8PysUB_h0yN3&{IDjFR0J=>VM^*~DJzI*qIYPUVoIeYZ&-o?k& zAIN5EPxUX1m1(|W5-}%jN5+@ex?#dH=9X2`bN_0aSlKxj)?BIn*UkKO$-E!)`F||< z#jOJAPTD;={3TAOcHhbNniF6I8t=o}w*;ql1^z9*avAfOEZ%-Rz%tGC-7X<3J_`x? zKd>T>s9_0+;s9fQ&}`DXJ0-ED1&KTg+unrgMb_;F?+wBz4X8PD~qDuW-9{{Mw$>ElLfjq7c`_8eqU;k z&G_&ATw`0W`{tUf%^wf&|Cw?7Ftlu2@N2UqJp3P>*8oo+K$bFq#vY;L+lUEe=+cG- zY?TMN8kn_CIbSL@H7Pu>FklMFYYiCX9yC@}Er?+>;J>iSxH`c-SA6cRiWU7{55S`; zpi~gS67?D3m^19poUt#efVv7!t?-q*@%R1y@H5^=|2^4N(%W8TAcqJTczh9LEO;iD zVIs{C{6F3@NjkH?`;e~wOYYkhE7%`5@(VHAnaIzOf7<--Wdr{c=bsUF)B2w#gD65v zK)}vyob{x!k?p{&a;>O^8&3IKJP3H=LDGaaB<&txwpqX!@HqME#9n4TDQ?p+B1ilY zRkA~L<${gJ@7M2NufMg)?9%_3#|!v+n2BC7g0!|ILzw@~JSm3Ry4@>94Z4b_Jm0FA z`*@*T54+upYh6!4(?NGm!BO&>%O#H8T!!D+1+S#4{T7p8mAq$+^(m z6-$0v{ayd+NhqkjCc$5Gp#5mP8H$+(*oUQ{MF%n!u-ayVKjWO`FIG9Qmt8Ci+)%Ni zU+a)0|1oCy4~p`i5jdi?z3h+?g;)AfKOi%n6ZpIBISfgOx2&n`v$Pq^ zq!~7^hz&n0z=Rm4pB*+bCEQw?WO!(g#?ow?E6pDXX~AlR z>34_Z2O{2qWlT(PmA`3pyeo}n7C_}J!rt(&y zUB?{BNDiR5y&xthk->1Lx9jJDo9j3p1d48|3gBmDe0;D%gDGy`3ihuH&mZj2kkZYxt|q*_WlVVB5z4{-ZmLo$N|k&BDxcHPQGF)2O4HaDnW@{rkBACZm`60UMStFq{L^jL@J}qU^U3oJ?tbF z+>KV?QOdW$H(!RBt(zvjt=sG9;;aU3Zzle)0Xj2I@{583)d1w{pBofVhNchH5aIm` zr)&(qPmx~|ymfi;)aC!bF8x3C`J24MZ&{7ik1tO1>)Lr)?MU5bwe%(Hwlg-`-`l8@ z7rV!3-QMENnELBoC2mi@tzTXy&;M=z-r8qBEbHFd$ght7y1MSRxxe)OW9vU=|JnBX zIpd$B@gOwS=E3J3+y2+wu1T{qoKXc*1y^3&pv-v{CVfkJ2iQB z`H^xns*AE1bfo?VEsn_YkmCr;-C&#O6K<0|f9~UxpO+u)d+eUy9A@sn(UR%=`WWfy z|9;Nf@#NR;L19 z|1azMdGjCL`$1^6t^NFG`Trm&@A&=ov-Y2ff2RL=`p?sUQvYS`|EKYJ`_JmlpUaC` z50tFCy-9eh@4ETlUqpVK#9V$i#(viAXpaYnw8f6{uiv?O?WDy)W zkFTElED~({F9rv>36Hy`mRxDH3Sd9RNN8-xVXp0k9EP09s#DY78tBE9pUB(z-EVT# zja$!FZl7|1w|sp^{r*4th0iycX0pz7-0zS(xhnhLq3i#w>Ry#AT#y9Kd?naCF}DB> zDv@9%zpJ+c={cQ>vuP<(S5Zh_E_^@ALj+Ud!AZY`n@u_>M;8W&+p7VQtOXt6Y?jx z3jN@)yK+I`T80_FGJ=%P9$0zr)%Lyb*PQ&g?(lQ>^o@)4a@`l?F#Wm7TX;A2bnx7( z>-W8i`~PkIy}F_rnfX@dK}#xDo!`T>@egDnLcrRBb1=W&`0#VidG+l7zZpJn{dub< zcb{4O?Dc=`F8(e@ZmG(-$!UZ$tf{oVdFEvD<1NbHH-Cyh+kg34+4>BoKkeP?JeM=a z?cKS1mn`vRsenU*F$-vTthVTR%H3`LHQ($ue)kjpoVPPCnaTXlUM0J4lV6_>54c`+ zy5ep8RnH!GR|in5LI3P0S6k4ihr9Df@ec5eg3kfaT;GYs2me579HOd(gJHiD-f7zV z?BC}5fBnmo-TgQ6!}dHm5Sz8TzVvC>^S{5YiE=+?zkX+GUuNy=b?5#R1e?Fw{NhM3 z$xVO>VGL{XnI9Z6oLhM9G~bmMhD_42_eu|jZcI8G)jQWTcaNw53k##81CeDXR9WM% z>IH`H!?P?{#rEgn#h{d-?-(CwdehxvE|qO1%JJ*GpboW{P=fu`|AJ=U%9}1HkjeN`K+gnv&7S~uYT+1zoR;D`~5X8XP6q4OC2|MuivM2u`@LPw`WyMro`g7N9{;3j-gR>w#}>=}?7Vof^uK@3Z(Xr{*VX-h zS5EJj;Xl6E?=xua&8v+S&4K-UvTUS43oB2!*Tl4+_eWW4z4hOB$!E!*H~zd)lVfKl zKfC|zam4DQ3zuvHu8T74|1j(LQc0z+JEs~ieLeBi!?p3h=ZZ40U#)y=-FCS`r^$Pr z`|s}dDg(J63RfLIDS=w)pA_XkEyP+ZB1{Jl!a&*$x+j^LwHcoIovDhce|U8z>*v4P_oI74)s?w_3uLY={&<4Kfrblaau*mZ9#y}|`paa>Fw4MqhT55JGYw3& zvTt15ur6^vaVzv2*ee#~$<6qFP+s(}`O~E~o73%{=Kb>1-fsW@)$wb)3eTS74kW1R)jJ5Ft4sTutzBL_4fS>7&q9QQ2skVi}k>@>(O^#-Tx=T z%l7r-#K#XSR=7Xj7`5_J%~5F4ew6DTd{+m!fsJ?JndvF!&vrlJPo91`A;h?3mtXvq zgxg#V%6q@Aud2=edrLkmFu!zl{qM=I7SGXq^-%fv;g13RE7`Ip@%OktzF1)*_tV2} z)#2Zv@KydZ`_H(4{cQtT$vYdius0HA4Ol|;S?1nnnhl%TFO`}ae*2!fH6xli!HVzp z!KIa44`yABS8UnDzs>dQ`=1}f>qGZP%05#D+tqvg*`(W_8f!xKoL|2wth+M!?H|GZjg z>Ad2w$c!t^RWJUt9IP;q`=L-fA;D&b_?d3PEfdf{as&G%u7;l?2VUN}@>0C3*KvPD z?$d2-2i~q{+%WZPm=Djq{dSMHr) zKTrNisXMh9k_mCFyGQel@)`Em^O-E8S zcvJbR|Mw+Tsb04$FQb?roY2^Cc5hemzB<>nuh!)~KJf3#Y45)F$AQZ$gKSs1e~sAx zCo4v3`mv>jCy6NZHk`GcAk9#`IP6|ySbjFc8TW*g_~&c~{%E}ps{giJ=|M%vK^NN< z?M)4!)uxWN@mHFw0zkt*AuRC04{j#HWx*B${wHh)Yy@5xtz|TDUox?Ft~A5zpz?2v zXH6(LuyDqVtHd?TAq`eAdF2lCPDX>$Di;5_4j4l7c z9WVJ=?9Kk0e!GvB-<7-n?^62d-)}el-ed9Tg?a9`^g9n1az0@@5O#g`^Yzz%l!JB? zoOOQ{XuIn8uP4sXqTmlBGq~7gln;@&098!jv@Ev2!xYD0&$iDt0cH%#Dv0*SIUJ)Q}^r0KQ%r6zt-m2gylKk1jYY8U1st7{r$ju`PcG_ zAK#T-=BOPii$kZa?qGw@-T2 zXXc96|9*Jh=E~i>+gMqyWi#X??w!hf`SbO(Kh|=Z1}oja&R}!WYF_0S1!^sW$Jdrg zP2hj^xh^y=6jJV-KM&a}_T$8Jbvye{KWAcD?C{B9aR$Sg+NjE;6^Fm=JiLeLf$Q@+ zow~2x^QY^7o%`NeGfjTOPqqV3x8Ijp{y+9AgGKqhJr%blr5K9W+FW|Qh|wVaRY?6& zyPNa1G%W2z8NV)&>v}K;wh-vdbV%0}`Krx@QI@?;5DsMdY&{_;SLv z@hN-W)2{{V8CEbFOb^Une?6LUgWK2e>4gdQpnB?HVaC&%75}cx|FzoR&Qz`!R9ihE zV#H#_T=s8&F8KdqJEuC;YfFssj<46B%hg`kuuaKs2jd6L*|qzgZoj`}q9}uTok#am z)Azf7f7|i*T6EIYQ=*2&-{fBIznk>s#>d$;^HROVrcaZxEz9YVHD9>r{wCG$#}Cb3 z*FRNz+VOS8&ySzm{Z3AHuI$Tgjn89it}oj0_1Nph+sk8pW^M~Uh%=(+gr0*u0p}?$F=EG?LW+!zSoSe;?dg zxU=oGbUPzCaKx_hwtJ>*_ek09(c-F_xP!-Q&VW(OzelH^ciQ>;g6G8-{IZ=?a|F~@ zs5#MYr~k3C6P)aI!E^SnzIy#Oys+{1ueZhhb_D^+@^A2FrIw|NC-$PxI_Ob#FhaAN|)Zaz3)5 zzo>P8aDQdx&##O5Dq`*w{oT4T?dz(d>g4}6??dxDyZ3)D&%M|FKiY4+FKjp6 z-hF-h3w`tHy{+Ewcb8xIF8}B0YyTe!ziv8T=Dqqa^m|2y-R#HPH{M>&cHrOg%yoa# zcIQ35_;1OqkolhMM_W>Bq(EiAir@!E`C0s{X6S%QM^L$#c-GGUbKTM3qVL1^#DAh6x=+17YtP{+7C(#cXWaX9x?3+}oz#y-;(Imj{rk4vJpXij zOwGrmh1Vj}r_OHvu7BU|3aFsyYHVK<_;;#xYJJvY=HtqO0sXHE6RZLt17auqNiT~J zu-6zIs=2VADPh%zN3Bnp)*mb_<$7TAsqJ6Y3TX!R_5Z%_y1rL0?)R(Ge35ymHYJX z+BezuS@-@=G2d@-ZB3Nu(Z}=4?^Ry3tjf7FQ?B0i*7=Vw)63)h=`SCx~%#(M&WX#M}uYdNmZ|k<#AN`xYob8Z&{rjd(J2%{@gOqSKOMh(I!&7H_)O=gn?;H6sk=<3R z<6=Kny$bvfZknz*Zgs}}*y4{70uMmN@|+Cl)Ex8A0J|ytPjO~3=m7*PLggafiyWw& zw(4MM9)rxfSjjsK6{j?p9|@lS>&jWXtMmW=d0uh*_Pwxs`sNH`(zdU!9c7OzPx<+` z=<7c2eZgkWrry8tV18%j(!KZN{(SxMY5M+{dqrOij~{pRuYXs?+t4mwSFz{84dKPR zU;WRvb1F1@z`yUOYASQW#VtST|9{-PaohIF;?Ldn|CfJ1CjUG9!)a}Xyo#^n)AQOhZ3k^1cKtz0tSBTIdlA;|CRTD_dxga!bSnG)Hu-k=e7Yq&m5*5Stm~k7v}BEzFHQ?Xkgy;blKL0 zpdk2h?)zMs&HNQbKSlVz{y3e#U(@gZ?(NgRpVnrW_Wk|aPT}~^dp`X>%GI#E?qPIg z`Rv}}pVCMF)_-qaf7JZn=liGg_r9I0e&mkx{Jn9^4=(?fX6Uxg*>BrgcefjjM+Ligi=RQwuhGn~Me%N8Ng0VpPcy_Wj zgJ0*=!ZWMmg6#fHp7&*m#n&srr`MZ*^S{`5`*!r)=!(*O_d6Swe0Ti4@nN0qrMFqE z2iW(YbN^LQw=VASjgJL3X3q>u7wTPUt?VayxUGS`?F92q#tm64-m<4Va|{ne?X7(m z$UbHF1pbnHix=Lyw}ElPPNsx<=ex(|sb5h{67&Enf_fr0&G{gKc3kCV};z$Dd58`z~@`cpFX1>Y1DO98f>M= z6X*B+d+aA6EvH#v&ws}LZF;87l1{~3apuJ$DZJb4=SwlH{;Rp{?W&V`8r$`)o-h8m zI{wd|HO-Gi4!mB=u%q+&?JHajNB{Z8m1WD6zuEZovFQIjUzz3m_I|66xoR+d8}~kb zop`bMf6w`k#;@DIY=`%r2dw%X;`=|oEj<5f-zvs}U{Dx7d%XD~+X2Vz`CAwb?%FLg ze)KHPt_NA`PsMHdG=JfpfB%k!G3dm9T{b`e=3DclFV*+#-E;U( z<>yDa^8a#n8by8V)l8N$T$~(Q^J((@oOxUo4<=swpLJ@A=EsBlbq3G$Z|MIksn4%` zyestdV`k}f3^VdH``q@4tp9(-e7{QAx)@1myZXZUXVMP`Gd!Pvzc$ESXXju2!dsck zj~;5}{=D71>hG52wz_^+FPH3iweQ|D&4r&IKbM#2dYinzFtlpNtBI@5-LJY5fA?7P z-<8wn%kUp>Uf;DphH5>db zemWZ#?{_wv$l|!wPo_Lo{GP(9xMaPsO@52x0owfyB53XH{HWa|uh0v%}_}dR3sl|4{0z9oJ1jwxjW6+7( z-{qb6cGb41owe@*`%hXM>RkWr_qOMv>{aLcdspe_)h~$Ze7|tsnuw?Q{ad=?3SauJ zSQm9?^S!(7OJ{$ZW%Oak-Me=`Uf=(3YmUxryV|NZJ0AC){jDE!QTqF`;MdPizc|-X z8_b+o_|k88QEnFBof}UNTsaUPWA^RO&wsy{UluGElWlxibad})`*VDYFK5rV6KKXG zwp~AVm&v=G&*w#KPV+r8$I^J2-`ps(#&vJ+w>R4AytDl>JsC7<`}o@Of2(Xa*@xa< z@p!Qu7t^ukj~DDWPGNQe4K@XwXz)7XfAM_8UX zZ^Plpcg@la@1t&tm#>kDc$xR$>-zXSX)}hnnNkeqWfsqT-gL+YZ%#P=K>D|QiSMi9 zyE7yGOP0SrxIVvtIiYa=>v!)X-+y~_y!*Gj$qL4T;Pd-evK{zS6T337@cb1Pi*>IL zT1VV@{_o0+9R{W@-hd{*8B`WY^nQA_sncTy^eB*6NCy+ehQqJ>iyntG>_Z-rio#df>~aS+%xDuOC(IznpdY+qMUVIe83c z{$vN$pRL+pf7PL&M$3K$``3VuixmcPLA)m9v~ylfV1G8h&NJ$huH?!ezGc1Z&fC6f zuyKhAcTROFvUs*7@L*VFLFmv)%w^?DPrLZ~tKZQ~ZE zggk~be^VT1@ZPJi|KFC!*?~N#wBveeT}c0{KwGK)nvnkQ+RzcJGso@Duekrb^BLka z98l{ST#h2I{oD}y40M3PY9@&n0r_vY1v9As+i6(L63@Se;l{11)!uh+^OpwrxR5gg z?`;F>(ck)<^%J59tVAJ|y=7hSbr7P`!2MZS1ta5Ysx&TtD1ehFq)?EcU z6{?@D4zf{{lzQKJ#Puu>ciXE4lus#eX_pqZ(072T#%b^aM}Q%-;h#TNX8Abete#I%JD>*D+B-6K$gQbfuLo-Pc9mKIOzDV?_*+( zgnXrmggj`>`vCYXD@J(&=SM-u!nf??|7P|0c_!>j~bCV@v^RaRn@Z=KFt^Nmz)eABh&g3TTY@P$b;3FM&Jhl6qHf0PRK0-k#tvPAD+%V;3qKe4v3CCl;tfo$j}Y8e$GsUGzB=orOVuz+!c#hTtC-UF`~ zwiiV+KXB;meX^d-oMGFhdtAqGO?xxI*5mQJz}5#FEd1_`GG~c8R+Ke~{oAjCEQUAU ztT#Q9R$csRx&Ds5a8a!4a>0`iZ+yPY)nK}6_pV;%-@*F&mU4aU@mKZr!6SE>F+}b# z$T=^Uk-?DjZ{@R&oDJD}FJ>I8{4Z3#b=Nfpj{~<4KSf60N%GD5A@zear z+WXfSA~-d=E0)BCYcp)ycTa2I*Om3ZgRks=99SA6DG%GXax~s%CMk6vxL&fc;9nxj zP(Sll&aYJ;1FIHI+!nRJ_MG-5u7;{!UMLrBFE81DEV;`+vkWv;s0`{gn#j-KM~!#XJqifkg0{*9Hmn8jmU_Fd zh+*2nb~}|hA=I!k{}acixtu)=c26}M*!RxcbtQhMx2Y8WH+8`Ro2R!RO{Lvo*dZ*nDt=ELndB-Y^4N(e7zC1-4^mTQg`? zNy593^~b+juD`Kgs`0Gof3~WQ)ta}yc{~7}-C+AF?}2{U8~?A)&K!TH{COj`0lx!f(?PrFuY3>xp?|hH zl<`X9ZyDZ(r-Cc{e12`(vn9Uy{ftjEFlJ6c%Vw3|C>666v*E4+rK1X*rYKJtS#tU~@2qSxTJO9HfOVFx+Tk zKdVR5SqTaY7z22T^b6D>qtOIUG^5c3N~EK?37)q{a}%g687=fc*#Z<29HVs;heE?> z-2|;V8yJ{In-EMK3d6Gru^^1MA^-2I_mBTgy{mfc{Qh4XH$MJxakgvKMfvv~`tfDi zmHQXV+pEV_U065!uVgt%?P-SvcR8=DVk|i4Y2P85eQm1G`rqx(kDNJ~Y<~Lt=l%Os z{r-Hr`t?91+Ffg**n%ls3pv=DMn>I^BJ4pk1iP z-8T!JIa6LecoRCT~^W`f7~tWxx1_{ z{{8doU%yQ~UwHJ8s$r&2_?dY|dUCVhT@ST+nWlI2b8PMJOFN$4V_#HpF6n>Q-x5cn zkD3RCUV=g6+eM5Y{!P7Gc&Ih}==Sw{YCmM>*ZsZKT;5$@^Kfx;Qr0!;nx7v_%a3aR ze{249`@Zr!i5qji?y`9IdVjxY_BGyp(P!ox8vgtH)xU$)Sp8_E{r}>c7mu>9@7{ak zM)Iv67Qdge9}9l&Uwww*=i^z3AJUZ-n&&DZkTe|A1 zCpUtHA2=5kDU*;`HtZFUxX9bE`r5Z6jPn07H~(CpvFP{mEtl>;zVx!9`qIuC{r#zh zd;VM3=d63N{rtJfkM;*Q$JvFxf53JiMxg%tn!S%t{7pZ4Zt}4sOY8TU_x-%}{Uq+rkE z%<5w=&);AFbMgOAo24Irk&g?{6F*xkzW1%CVeO+A&)yyt->x4kdj8*&`svq?ev8z% zSBR@W@$TsKjfu<;#N+<%sCenPd)oG=^>(1$frssX{eN?peM)TTUGoR^lRVWIsx?j! zs1j$nr{G$}%b}#e^yy;t`XCjLjVYmHd)HOqD5=PiYXTq8HG3)oqnnO zJZJYYZrPokGtbPG%uAcM`P$QYo4?!re)IXwnxkt>_uu?|^ib-bZx?!#ZeL{=TYvfF z-1B>-+5dccx#x|vG*9RJcbn@r+T|L~*(T+8T>qQA-0pRoeKzXNJ#(_D%l+@O_l2*G zlRtmj^?3F53#^PxEF1y~4h;+h7$sVbe9{bOii$VhxmhkA{(bl36TV5Gr%ufYLWTn)V2-|3codsIC+ z`Ej@WIeq?H6+eGGlzT0*s_Xvc?B_>}(*G##UnkA*=kWgfz5mM(@0rSY{!Zf78`aGV zk5)^~dsF>4c;Y=%S^YViYjy7K4?nE7j%c?FbB5$HY}l!|J==Z1-2Gi|<9|-M%FAH) z@7IwVFHc>p{P`|E#;k7JeYVu)rPEi-b-Ty^Rmh)ws7cc#qMY@Bd}=iF`~UaXHoh+V za_Ps(jTc=%Gc_E~-&r*0`&84{Vb7l%Z(?|GNtLOgbh}1gN$||3{qy#uuCd)wKT~WK zQRx8`x{J9>ZZJH!`@d3u-^{hMruQ8-i&gyhJv&~*db<0+UpIF=ow>1c_Mx(axv~sC z2ak#*#9Vm1P1&qZH(YYVg6*091k)TemSsH_9A;yfU-kI#jfcnkp9OEdy{q~0um9ie zQvKGKdA{swo`@x9!x{d3oFCsivHY)kecCO%irrV)pFRKl`+S?;1r#ncvRdUZ6dZaYx$#!z_out@I~(1*X7DF?D^mN@ni3N+nM&C7v;1ba^5_ZYqnKddh(p#_fO4Q7dtC!*&IUo z4C-eVt4@b@UWR2qrGLHM-Mw(%Y`$9tWl`BLCtdz^TK#^HaNY0od-AqA{(aPWdE2S; zx2w1xnA^{hivRPk`RC?qQOoN8{9K~DD7v%Y{+7tikL%rRMc&ug=;r_a_y3)cQ-fve zf0#7{;(Eblu96oF4@wuu_g~KY9d5U?S^TYRx$IWYH9JD?S55vqzudl4cJtaM?$!U7 zu5G$J?cmFd*9-|&#}4lQ6@BO1`SMGdb9NriDtxtVwcB;Qui-y-fA}{&Ddd~y@p-R# zJG1xitgCxxPjq}#vRaie6kK~_x$)%D{v+D&>!ap8eE()oT21E9ql?SF-KqHVwew^1 z?`N#9gPQ+KZmYOc|0XT)#Qm-A3?HuYFH2ed`|nDNeYs)M64h(%Rl=k$n8(fgkZJSb zQOl3N_QynDzqd=fe50aOwfnjsflz@b+y%v;;7OQuY5L|5_Y=+Sg#XKYFT5$~w{X{% zP4_l+f7RQT-OrFvbpup9AHVbI`y;KEql_jNJ5#=wK6>CgEkEGZB%;&9Vu!124Dq)0 z$0HW`_y0V1a_ddA{r7*pH`{+aZ(~r*hSO2K?`8&CtN;7nIQ`SqFZX6xY>oSSidn34 zuepSfdd^<2DJlw3SqS$J#T_uJO%?rrc~@?5|6 znEaNfuW;Ff#uPeIn4!r%KJUkta;5MlXq>63TLZRYiI(Q7t^EdDJ*WIAea zcrLPH6+=R`&%xuD(~jPryexI$o|_wQEvVb*aemgfik!{!4a@V6+~{9+wB_XG#ns!_ zZM-8?o3!!X-PyJK+lWpfmMm7W3>%7lR&Q4!T%&=V-q@$7z;NSY`i z0t{~^Tz<8b=v1%EDm%WJ{GMk+rkHix*6x!VEEgu2{d0^xsu+ z{m-s|ce}Q@+nR_IZD%G63&VeDo0tgZwz<#ZSBa|<8-!ILtJj!o5p9)2gF_@ECZ>j~milh4@FJZM;}jPM!?dS?o`lrF3x`#~4h$Qto*!KS7a_zL%^bw1 z_0h~hY*>wE4x%f9(VAnl<{*%*0_K7mJ##FJ(@MD{VQrEHQ(3FNytsJE_EjH&0JK`% zz>ttWr}VuKq#mhR$HdeyUwePMFy88M!C{V&ScZacZzN^eu6Kj0Nk%4?S6n5puNm(b zVOX>J5uyHNl$HX+jUdbKuzFi8z=5HF@t}!1{w5E4?H%Rsz_8(~&Q}+R^I>t0w)K9UP*A;0f_K{Ls|+9J2sq~Q%E2#(3)8<8km?GWDA1! z3gItj?A$@#5xl<`()MjUr>ekkW9PHmxAC`(7OZ7uVYnR?@gL$!hQ|L~91OpfL%fRH zhif$z7;em(^$XUdogyf}pwqmVP}5K>!hxZn@#Gzt@fkB47!pq3xkIR(w3L;F!F#s` ztn094R|7-B>dCJr5QuS5Oa=SzpAJohw?IuM+pV_U__fK#J1}f`e14-jG@+~lB^)oc zLk75m0~B}{99dWxtWUU9@j}{(3x0vx%k_Od1YF5Ixq;!qA(QB1UXX;SbA^eif&1$h zNgMnTzRJ&mVZ*CsM;ai`YU~4L!NBxu)v!DW5l1)V!Dm4MhCelTY^Op(;YAA*Q^VYX zOM8vbRYIHt&t(A)3>$b0OMRijD?r_#@WYn)b#a7fDKJE=T<{x`DjAv1iU=^|s7*-& zg%~UqU@4m}=rA%KNHffY6$C3{92hnfIorZqgWYcp2hu_1U8IFF)aWfM8yFI1e|klr z_?im}%FDhx#nmAC?DRo-$@^Y0%+=Ukd%+OYoqo2bN*fyET%Z^)2;%941T7YSfz9XM z*ue0>$)>W+4-%F-F`yW~UL&cCKQLFtIxuXwm44y}#P^MS$_flO5|>?qm)H<-bVC+s zv9K_#PLkqjf;j614=BbHr|nfnR|#gP7;Ao0EfKoAg$8{JCdAFb4-iSy$$_ zNlF@rR{VUjswJ@tNNFPLMDT+1bF5Fx7v;L;ThyC<+TO#GFt&QvgYc zjjiDh3!`WD4h$PMpWX2tR`Q|; zBQz9lb8#?iTf6?=X^t~FnFe`M1hg< zK%eovk z?>D>oS}Zz8?(XjLes=jk!8MPiA8&DjS?_kVg{^6z20{4vn!Hh;h0?>{+N z{d)Dx@VH9Vu&B(XRjGP7;sEOG3)eu-RI#c1^TXoLhs8;+u4GpBx64&|)YES!u}_> z{gs{kz3gGD__1ZP^P<*2w=8~kWNLVvDYXQocX*JgTg1{4wozZbjPi#?xL?RYOZ>gUr}tJn8g z7N?~jJTS8|GV1NR=a|9kSD&n-U}#%HrFaQC^e51&r2KX%c*{+R;9jhp{i zE8>}0I7;L|?kxWM<+A_rHtD<@I~Gm#`t|j-c>JG7;*TFR^Y^W<|NHvl_Wb)|Uu$mX zZa?~N_xpQK_M(*0SWA%wysRt?(Tv~E7@zOk|M%_8B>(y!hu`|HGrPR{x>Dh_$n>M} z|9@SVFidipQ}gNL(cf0DI~fwv=T^S=ZD43T2g=(O=Wbgu-1yLWT(&%B$$72SYc6fb z+IRi_uWQ>k*?-xwBE_2Vz$6{~le`(pjEo1u82((-e|}UvY@NR8Jom?s$LAm6($<+@8`fcZ zEkgHFmf6$3EB`hgm+LmaU!$$&Q(?cW{JmVa{=SGc`~UqitogzAv+M}(`}+TX`5#^O zx9`;qUM8|Xcy{i#n^yU=wjHW|wQ_m#pC6nXpH7QD@@n<^Ya6=%SlRwwI{jG6{OO;b z>+gIbwDHZR=H$<3&AX3^MX$MN>&wcZ?mtha{^#k%AHUtsKfc6M{^$h7)5mUQuNQs2 z_WMz{S`A2^;%;tWNO&As_5E)7V|V*sfi~ao6o0;(w!Pqcm-f0De{(kGELmGu{pE#V z?C!GO@_Uu)aWx;0df3~adGBHGZu{dwGxwfP3BPV;UG_ECy}6em!BeaiZ$YgxF! zhQ@mP|8(v6|Bqez>e42=+N$H0&*#WW=WM83{OjiC^y6Qz|5v&_>BsioS6r-`9_1%h z#g7Vk>%?iC+Q0pFp3C0XB@^d;-F^S=tiMVBx^{fO_xttL_=<<$H#t9&x98KUs<&L?yWeao-d1$pP}RAo z)odTQGIjvfvD4;H?YH}-QTO}y{bLW?<>R(JT)X|=to-NEt1hz3*G%}k@#x{gHye+q z)w38b44IsC^KrkuoOJG%z>igR>cPwXa*MbV84vt?xe{-6zCf3Sg(2GUYp?mSV~Opu z*H$bS4UbX$cH?pO#-n1huiqBhQT;tGF!-|VvvYHWFE96BS$-c>%3I&Jw2ybx50$C? z68LfI`Ztr-J_w(jFJ1HRr?|-N`E|cmZhX7#w#fR+Cx1S#*U$c*5m)x%Ap24C{g(PI zKmL6F-x=(0t9wa*-Q|t%cD;7t`f!z3I5-`tNsp>AWBIH&4~qcQZ0i z>)PU#@bJf}@UlK(KMS+{KC9XKq)G#AJ|3C;v-DT$ugv9hrI^|Ix;7>sKc?6&6IAo9 z^7&lh**TjE7tYR*VEA)L{90fA-`Dpme-zv;y?%C%((CV?Nxw^q4zfN^+rQy|&|V|R zB+!CetSk((&7J%0er4oryP4)|rYFvzb7xAJshnj|N=(_!)Ye6l?w_~$?6c3Q=;SH3 z)|dUVm$I6d@-ZF=(mI8=hRetX<$Qs6H#hr>dHl|^`EY<)wc302i?>@Y`)z#Ocl-E; z#M7zT*GtbbHP$Abn{)GKR>S32cZ=Wc6hHFfV*k_B<#WrTYQClB>V{pe@t&(;(W2|!`{iVp&#$Zc`0G}7z0_%a`!yAJ zcbD(i$uT$Q=9(wvZ)d50B7DW4f8Q^6wY~HTUPu~yXK$iP7SS#6B!Jq%GZ22xbgkI-)`&U_I^s!WSDU*)Z*Xs zdb1AsKM!`ddfx|U*o1`w0t`9-OqSX+dE922ZZ%7o!RPzgna1j7_iH}CNnd?&>8_Kf zFP%3lzgL+)`D>{*3&ZOy3;YRI3Y1_I#dejxp4a+oSL(uTpC3(hm(#rcc-ibcq2KTK z$1l0cC@rVI=R=ZA{U6WDj}HzugO1!g_p5h?X|`LKnK}2B%$F+33=CE$JY5_^zIOE6 z&x_F)srYnKJS1Q%IdSjp^rPQ+nH$_?OGCC5Jv9IP z>r3~yl9H1O-)?2EuXsMU{L|~U+9$35oWYIKRiF;*PvMdWjqJzt>ppf*GB+`2n33nF zc<4*9=g!Ax&F}X-off?=X7V0ChJt-AQdp}*ut^*O3K!0Snj9?mR)^nTvs|x|!C>tL z^Tb0fn{4IF?_AvYdfoiB%ce`!|GusKd2QL{O0EO4bw3tHcH~v<(vh>R`qEeX?dEog z7Vl^t`N}5`EC2RL8h;jL2=>VPcvQT9{=YA)B9b~?yT31MxF1*jHdf}gpu3D%^}C(b z8}}6yz2D1!Om%w9r1)d!tL=I_s5zjxacUTz@`6YEepMGVLirGH_p&hyl*G42zL?bh_>x!Y=JfODwqMx$xX-$4 z_0y?UK8FP!gzw+wUO4;C-*30|x818c{bpOG;;uI;_Pfg7N-4X~lg{7&x2$gO$79k* ze?C9YeR=7GnCt6ID;@H0Y)HIWwy*eAuHm2g|83;c=bCQ%(Q}y3+Ju|s-N*a$?0@fi zKJWMAcKbah`W}o2cEA63xISF5=Z&oR$?(VCQ!`T!iSVqkewVxbt{Jz{yqVL*t9;bz zf8Vx$RKEXrY}}NvAJSGOGo4CJco^;#oz8#7D$dR8-d|^Q&i4DAL#cO)&&PhC8OK@WAl6jIjOBlm4@6ewbd55pI_)i^8;&uwKr_eFdLhEbdRgtusG2E@xW=l-8!HXfYjvcJ{}c6 zuDN{9rIgx*P7E6q9?k}*EgZS6F-uT@VNHRWn*Tf*VRgSV+t$d6?5+N;_idU}!^_Es z@?Tbbzgxa}>c@Su$;Wy$w|T1H|8;HU#=B*=U83f`KO$`Z`{?Im()lvlYc|weTlDeb z+GyX61t(Rf_slK7x3FTa-!k9X^Vt8r+yB2Yr*v=lr(LPjBCV>=l|>4C3_rTnH6$%u1uZ}MBbjxU;elv)jNozk`kKl7`~UrV{rCVg zf6k_T0g4O}6F$Jk@*oXDaAg21avT~Qwt|K>EQB*t_jc>=GvTxQao|S!{CtyFYqPKC zRSFoieoH$uLoj_#p_|R$FPD#&{eHLGU#8^3zmLbH^V6cw%SP(hf4vgCxghTG)t_Cw zUFyY~58O{*{qpZifBvISr~kKz&Mk<#m$db2Shq93t%}*LjK?-TJAS|0?H)DNK=!y? zbu{Pghq-ST))Gu`)^xYjLehKT5BY5CeOfnVO-H2(GVb-0Av?i&Bu zX1eivt2Q1LJN>WYuzbuG?p^IT(gwI=ozd99kidQ6)xA#_ocoXP*A*o4NN&oBssCGA zy86}J$1D0*Dc=dSe*3iOyo_ky7_C5O%GdW`Qt%z*V|cE zp8GrISr*6L$p7-<_@g_;`Wj}khDk1SDxb}~xHbFwo}6=YZbm-H-#)`6GpMfi5U2W) z@O_(-H`YE(ab#+^y!?DeY}rqp6*KB8>uzQG=5GwIaJ!q&cwm>*IZ)elfigD-gIRr9 zv@yeu=kuzMy|4SeTTTAo$K&$u|Ns4+y+%J|ODaRbvokXdtG>M0@%>))=bi%Gdusf=(~?Te|Zy~zt{BN$Nu^w-TM0^{{MMypZw;= z#-sl(6|MXF}eoyK3*yShXE|(oJPCs|DJ~KL_Qo(9b14F{+^sQS#0qozOc(_e8+#%1R zY45jN+Ic&lPHQ`=y8gBj!;G+>yC1emKe~PYU)khj9m^SOK5RJ5*Ij(hQvJ8{6h&Xt znfX8E|Nl5{@$<>#S#`c0r&&GtuK+Q)vs-+w>D^uR9WeVee_gc6{m)wt-9N}KFT-#1!Qte# z>~%ZSzP!4sJ+JoL%}HO+YSw(Y=)QSAr+Kbla4smE5G52WDjwgsJ;cy!aX2u6d_Z_j2wessZ^U-z4J&W)nNmrKRn_t*XH zN`0yF_tKw7-TJ-1-`6XY-Ojyk@odK8Pruq24@l?#asAf)<5={uzhBoce*EXNef9F) z@Aql%Dqp|yI}bRx9Tv<2hqv`wL54XdnL+!0#UEZ-wWFm(Q0w+|IARZq=W2*6%^5Gs}s`RV1D)l&k;qvGAnobQj;V zf9lO0>NT5+w&~vP+<1uVbo%X|W!?UEKUL;cK6`&t zKe2ww)|Zo7|F7#?I$dr;`|EAD^ISgeD=B)|dcXhcwcknG-hNo~W?uTH*WH`m)-M;m zowMhoTj9H%%H8`T^g?2)-=2SbExJB>$C+(Qck4}yExY-s^zh`ky<#VuDxY7Ec2sL+ zIB)s<&6~e%&yuUZUcJ6)D(m~R_ulevyc!mrdi&1YnN!c7+gIgEUaBeb)T`q+ImKK%Rr{(M-$ zzZ}z-yWU=!cHnwUvG3hQZqHxJe!HE&f5*>fv!$=9eqOz9*Q$%>+g3i@`Fx)A^SR}5 zi>t$8ORv7^_j5DV@@Ji$yDd^@>y;qY*CP1FHWe;dF)=lWTJ=eO&e}HV?#AA#mzS59 z=WMy?w(*$M>hx%)?>*b^RayUg|G#efc5m%pb4#y9f`+EjqQBJ5Vt*3kdVSs9O;;JR zKV6N@+yD2QTkSI4w&Q)W;X3~N7yLaWzHdVQ=i5uYr~i1WpWh{-wWfMWp@>s`X6S*` zX_0FGKD675%wA&G&MPgZKCdF?&tv)XNALgt_kG9jch%irU#fhaxb2PaThOq_*H@QZ zx98p6EXt97ACKyzt>%Q zJ=R>!XU2sWp4a25bN7Z$l{Wp6@Ayk{!%E%y=i&-J_Q}gc*}P@t>;Dvfd4GR@Na&ea zrrK>hl0ijxGNqq>F<#k>R;HoU7>(b=1sK*``1AGp{jS6O_Dc7QzHhng*L^#0w=SrD zQmek3yZ!E`_&4XckNI}r+?@S-tM6)tvX_@k-|c?CFX!oA=|^w3-(MF#U+-Gvb8gUC z>(BRR%(eWy*)A)q>gmISCT+XixlX;^`FvjC3B~p_$Gw@62_I)ve7zdp?RzO=-Ogv~ zH^1$%Kf_d6uRYD&#`Eu;!sG9y#hzc!ymPb3D00U8Yd?OTub;>IZ<$%v^sw2M4;q*k zg|CmR{P6MB>h))xCNBN$ZC?L*_U{z!?{DU}3j25d|MUE(+h0*Gy&Vtk=;ZuddT1%6 zZxXPTiK*f2{8>ee2a@}3&Gvm+TKWI|eB*S#Js*!rPYnB0{qd;y;w#&>yQcr7CG}Bz-#4<$t+@Pp&t=e{38+4P^ZbBb?<+6SCA#&& z7dBq``02F%@l)FCV^(R!i*9@<-?OCc_q*NscS2Qp>NtzqCC2`nsd>H_pwowZ2#T{jScQ?_vM;zF72k^V)*; zqZbyQe)@3xmlL;c&AjQQWh`ZD`}flJ^z(L=90sAw6k@qv_ez`VO^ZnCtXaBy%P%jh zw6n9~?$}wxF8_T=tLf#<_51%-?F;h$^)x?9R{!hlx|cGB=I^Wj{P=h?>`4Bx21e#h z8+E6D4-KAtZ|SlhZ?2?2oMBz=wKE6??+*$kFn;IE$asLOFgRhId;h)44Z5w5pS50W zr17%Ux6ehoyy}+M1u3lmVrb62_v{Msf3vTz^AJsP z=0873|G@PP`wDDxqaMdgh`+j2zR5#vX`e}3iiv*5kI00LA-6-qB#PhP>rM&xUEg*& zWX7hIbyLAp`1t$O+kh&MquXxh&1Pr1oOMLkQj3>inIY&#gkHJ1 zVd_57%;x1^_dBuQ&fi~q@+wPkZIo!?jSY#d%YK$e$rd*Anym;A+u`x>Nba_q%L*bt zS^rJ+`qkVQbbPYEog}EFTd9?bJxzia8?bO}0kw;yA1(`h%Qau*n|I>2FPbg)XZ^nM zrTanU>QAMoots#9p;hvR=;n*M64sGeKDob2qJO`Z=ooqWHHsUbYJG*qVY$wc3K%b|-gPzrdc zGaDEhw+RX`^_MLBM8?U-C z;3sH8c#^kXAp|Gtj@Z}sh7_4}$+Uj1c0GljZ!HhCO=^yk;dilR|4;uld%xW(^|G^`YgL-{<=x%io0-z_=Y#GBhJ@V))f~`ZR&Zk2@bf=c zlre)v`nfqbGMCT&l-oF4%JG&_#qYP<^H*8v=VyX@$zQ`Bt^PgX>-Bj1d6my*?sDZW z*>~RV_mTX%&$B0exB2;G^2Ud4($`i?n`VW8`tM&)T{=2J(fQLnVej?gX(*4TIW4O&36f2TS$^5=$tN)zGxvltJ2xdNI&nU%dR zvPg7a$o@xN+HO&X>$9(~d%5Y!#Y+qcQ4jN9E}gD-^LdA$@}qaV-|IzQpL1xkzn!Jt z-Y=IX`M%%zeBO=1*8Y0A9Msa8#P@U?<2;+nBAwlDHmSb%j+TDE>-D;?^B&_* zp5H*pQ$F1vGT6kz5y4o%_>Xr>8H0f>Xg;z3cHZu_Cj&vf*RHkO@9jGIYZ@Cve9gzB z5y`!#Uf*_KkE=eayZuhkrgfIBprNUl!lR<9v+e$TI1Fk`nyvc%dH(;HO?%?^*L{4k zxc`{d>ovje=Ve}A<{Fi0!1`B8PT9Th%y#~~hE(_ z3~>bqSqsluJ~y%K%CCJLt-5`O?wt#l7#?`*?-g0SeqYtX*;V(g-)wNcQ~iGL*HdCo z7Ol*!43^JKJ-Fpi!pg@J-Q_yhZo9QAFqDh&-xGEFlg$%qe}6l>UEMElW$j_*ueH}> z%Txca+ikk0$QQ{u7!Gu>1}!-f-f|q~{v5_Tf9jcY1sQyz?|_Ct}Q(TTGDZet0{B! z16JEhr|Lm-OiLy#z~8Vu@9)6y;q&J2DUck#U@|AD-FxV^5(6kJ9KXKr+g3I9jThad zk3R0Vzn4<$&D^j#{e0i7S+gen<&&{6IMy#84~k4s6$YL;o4xPPr_&ohozkAZMq9*h zu9a!o&D7}?FBZ0Qxu)(fzgPKu$D2*3pWV*C>4$&k&V?+{%!k`bWr)KX94Z+Z4}7vK z%?3H`?bhpVuePsD{_)}A$1B19rlGRBybR0u*m;}RwN;rssowUfV2 zWnuV!GkyM#v-x$wo8E7~UuO+!`GZR4zrVkO*5jCGZ9B|oePr+Vd$(8Y2`Kpc_4@ON z`wx{yb$-}(JFnZQZJu=Bv+Mi+mA={g{T^?3_w}hP499z=uRqbMkIvhfYV+sA;iJz@ zzCQttw$=RqeP92kO)K-|ZwHq4O;mP2R=)rD-KtRY`!&T&Lb+tIy8_w@LSJOLK>*x_ z`4nZ%@MG`$TK#i&zu%~_UsxZ%U&6kw=F7XgyHA=;Wnl6c#$oZEdS8~Cz@G!6WlsykutzOrq+;6ifC3fYZ z@As^ICZD>u}-N~SyPT?8D<5zUGs_V|% zem~-8{WfIN+1l@S#X*_#rPsVO5gx<>h7d|DXXkvB;E(e>T5Z z)a~~F-(O``wd!wgZay&%!RdIAn=jabx;<9=KOVcmRb5~WDdRRQU^=aDpW>Lmvg;eD zC)Wn*7SF4Gw{w#Do9*}OKCX`cyDBC2@S%SDe-?Ze4;pqn?z5H(6J5`5^Wngco9FAq zVt1G6PMd1=^UG!b&kv$k?)usKj_W(9U08V5^ty;%_kCt|zMd_)?;myR$LVChN;x;j za^vGZ>toFPHWyZ$yuSb6*BaIRZla}JK{r0^c-*%-_|m7#Z@1mn15Idqtmay``J9#R z`xA3P9)P9}Oiym{aA4Trnlt~d3d4_?t;XOSej$#Dso|~a-=8+mZ>G=hHx|3SB?k9uE2gM)+Dt={tvR$Zj*zU*&r>((n3x@leB!z(L; zlOOk*>q+K;Dw)T}r1N|7?(Vv}cj?8SuHvyGphZhkQsRLSy1?+4PWteT|v-;NF4~Muv zemKl;UR}D&_S+5ROJN5yqwk8;&9*2^+Vka-_s{2`bxX7J_w9Vio@N@Izqj5kO}?u@g9gcazh2XpJm9@rIdz z2F9r+kK@3hjw_00f#!UCG|s{bY3;IQC&K0Kq|dLNwdeWP>v7$n(SjL<$x>S-jZ!@3 zlwOPcnbq9P&VR1C$=~j03aHfVxwzQfJZt_vb=F^?EaX=Dl$MiY-)x?}cW%+n zeXp*)-E>;-=d{zYyGm9@zrjB-Z3dc{W)6vk6{KFEnm6p{OaFQ)ciGaA$6aO`o~th} z-H^!j?CYDG#rynsfCkQQB=^tF-yOtzsWv>O&~@diq?_*YwIau5iqF)9Yw6qzc%+h> z2pVZTwjuGb*A=r^lj3J*YNQ{f&#P2>x9jz~8r37qqV+4zKAj$a@6A*h@jd0`m>B>` zBtSrbLC50ZJ%=ACZ9FE-g7l9S~uuL{?e&or_S&H^Hksc`nuTJ ze^+=hHDu1d7r5BX^mSzY@7wo3P5l9C+N5pu?=`zya@pejp3h0MbGK!Fvt5~(o11&5 z;&CsiXCq-4?W@^eFUj`}Y=d$lPsW$sapY=NlZ~eU`opPtd_x}I)8?=7vnf8CvoSjdn zMIU1oj}ZVZ?YeU1ipiS165H~3cWSI3UG}qHd-Cl>b-y_h-Z~py7FWZ!Ey0p4O18aF z1#0i4uT+PoeAu4d+W`t|A51^geBSnZ%;M!srgHh)e!T)(QoVTBPf?$_R;JgY^Y=;^ zr}->i)^GF4BWL4LvEEbUTJ-?5niW*(ToeX1+je|DXDvNd-vd(M$ldrb4>Z{P#8`S; zG5+@LY0!esyyt#UzZ_r!t+5rDer&DAhIhMOPmB5cUjF|N_a(c$`hLIPZ(nvJvE3~; zru=RxX!y}YD;yd{Na+ws#Njol@jP$oJXkQMLblB3C^zmbe(rXCU99&vyX0d%FD@>2 zKe_9f*uSUx^_n}czPJ5;N7(w^j^yIq7x8YUYZT+)VA#fRRu>vQjnhDUm$SB0xjpMEAkLX6dQg_{-(5phZ&WgZyDOKzFil zTj=or-{0g#M7)17nN1^mf15WbtyzWGU0y9}nA; zPwQ^a30Viy3Uwl8)@r;aD!`Bv>%SMguAh;KWfo|E&m=cjY3@5Emwh+hulqf<<`k$# z-tp~LcJf76aox!HRR!;$y}v_Q4L+tp0#2dDM-?+M(=1WhT>nhGhpK_XG0eOX_9 zzd~01a|mdF&ODgpnrO{&<=VAle%5bAKof|Q{jL9gxeS_G>;o;ZI%x(fD*ik(-`@#p zw$7{n_tWhypWTlKJAS=dy?EKOWr1_aw3X9mj)fs;?boDe#_O_9`|JKDO$`m}Og!9n zbkk`)>C4M}yFn|Y?$vxg3(A;xmmU4w$jpAMeBbA}7Oz$;UgSMp?`V-a&X5I#^_H~_ z3<-S|wkO|l`4+A3;x0(XOj)b@<@PH*F6HAni0>h0YEAwre9JrY7mEW)ZnbiO)No;<< z*?hLniR&+~yqyhbcnFku*8I4hW629kSJ=F;1vJw3diJY{porrTPzVTeVA!D2eMn2d zqwxT!-KXX|E94Jo;Ni=Qi^`yu=Ogu8?mMf)*K0{^RK)3OkW~{{SQ!3V!?M;E&=9n> zV>J(6-?CVBHZUZp&&*g4Jz$~cA84b?e;En{ruIx+W>at&FIxUNz9lNvhvz=(k?HAYdVt2XxDtUWLbyw-@ zS+%=deb4UkUwn* znrWP!d~MAwn>W|9^shAa1!-)k{yyu)MdjLE+ZV8J7s!ZaWIV9#>s4s8AK`t}BExES z14BZqaU2Ij-iCv0qTimBF|lxL@p&*aecs9ZobwC`Q8)9C^~^M^{dJ~l;r?~8&(|KC zzK?sp$qtb-*=Lp4YR%}gEWV`G{Mjz^>cNsYi%Z7UUtbB@R)0GY&ZRTux7vqFE)Ise zdB5i2t&A8N`#|H759e?(gmJtmV`9+~%Q(-FaO$q_d^_c3zOw^mzVCTkp1n!8B0I|V zMR<*ev44=khHcx-{x5Mzc=+P(?sPG>H#2+J2Rxd6;JLB_!;haks2+qhrOwkjm|!+OOG zE~ayHERDIenU?7`{{Hs%>V}!wOm9J(?)1*cL6bL*gwp7ztiTZQFoYWscBdI0%&{zf zblHD->gpF~Z~JXeKR@s1s(MlWU&SvJ*0Nb7AKSCGJ3DLFQKjxL=fYY4$h1A0I5)z9 zVS}*$zHnIU3%hj=(qIp1Aw0B}sX_D0^h5QUEHk#9e|vTHbtm~5-tUcSe|>pmy;LB9 zi`j}}%k&0@glf-fJ_2#l4vLe{NP(rx)R4J!kH6i_Nx7e+C$m1uQd;}x`cm)dUB{z% zWzWpDHjn27C4<{yJIsE4e?NPFylKx_2`f(a_!7^_pBf%-I;}T1H#a7@ z_pr$_J~ah~8wb^{yhb$|-J1`J#RM4E6fm(cXtR`9Gct*CZz*FacyptCb8b<(%lmtK zL0u}*e*Mx9ps_^I3a;~ZzjNyTU5n0t`d4r3m7s}suh;Ld`{()mZRMW-|9%_h-rAB= z{dk^X$_b;lKQqq1S_0brS@LMF8M@7=nf(^1+w2s91@hG=`x!+u=?f2`d@6`YQd$#Jl2+N)F`?a3~5;o_p*bsP&uj0>-kA}t1 z&g5u6s52~hFiG^=i!!FCpcdZm75H-lLnAAw=rvgHww9GadZLDc!-Bc2QQ8a^m7k{Q z@O-bc`?Yj>oE1M~*e9*bqx(Ub%zB> zjn_CBmQDR|uckN#)MRS#*|3RY_ZsTxj54Fqyt?+J$F_{)q^fAae#BD(mBjbTC&QiRk6$2wv zDGLk3>x3;&LKrrvX1!B%SYXPk#mjK*+Bwjmg0=jm1&+;&($CM+m5by0IJfH6%A>jU z(VM#B4_{?IZ}GS%qW0_6Xq#ov?pY)s>&fAM^0D&s)9LcF*0SALyK{S%`+}RG(T-)8 z2yD7%nWd<}aD!(_kuM9w>6a^%9TwQKXz?ixId`Tbu!-MRiR6-cO-$+UhXlC*^@p*o}dTsj9s*}2N^*H9Y)@bHE*GPFT6 z)TylS92z3UQ1kce_M~rbECXM@s@Jrc9`@hc{r$bYk0*KS&3wOY|I@gCpsCSLVfAOe zx2i=CfNW>oXbR6FJF}UYg%rQDg9uJ?1u%8%!}gp z?>oEK*P7`pXpmBDvKxNiDqQdZZQ*w^z3RiTK~wT63&)n}4yud?zTd01xBFY-we9KK zN0B$y#=AO$rV1Y4OrL-Dx5fWIpObe!)rxl1&plfG<)ZuZzf0G4>hJsUsO#AEJF`Li z+CZt^RqUm-x4!Lyo!c|r(MPv%B|gYt(TZiWI3at{8@~yyP+|D-YIXjxJ3EV$KRh@H znkKzC;k@PZITf$hZvSMLx8q@3*DtL*Hd$9zRD3)t9=-Lv(|zCC>({OwvwpuvICfV_ z=hQH%Yazx@S)x=F7;Y$;nd5I1HaG}_wyGa6*&e~LVQ0`SL4^xpOuD=bezVPNkM&mT zSABUgac#-=lB0*MKOA8GYzLZ>0Btoq`gbYcD>jD9Tn(A32fkU{tA4+ChGlV@&h9st zF77U0|E*$4dWjGt;{iXTi*b`NGCMT!K`N-XDhdn{idzr`(lj;(`(G~}|9H^6vf8%sn@C0`L&2XP{7Ijl_<#No&&3#4HK*v5reWcu zBYS4IR&qc1!UW#O^!JypP&3=s^Q)St{@PvtP(Xko#^TvY4M?*ZIopKSWMPjiOf4%bD=R7}`lf&3=+UD$Z_d1V^QNOv$QqMt^7#%+mT~GY z_wrks9y=(WVL!oB=*HXVQe{#~40q5kOS=jW~0EnYD6x+!OEjq2&2 zo?Q6x)q>Ptf-gYBP}4ow@%DE)1WqU@Fw9_F9UabiAW!QShk(RVhkFbUu3alLnSFLe zh*qH1R4)C>0}~?B*u%usAbHTQOq{_+^N~3t(_*lv@6^b* zx3?Gm{q_!_jcCVy<4_~RPerK zoM&4tmic^N$x>N{%YF@&>#nblKi(~_AGLJz=FK0!yu564SY*}D4-cJJ|9f`!sncT( zwF{uZ;*}3);?Ex}U0fUtVj?08IvgwJFf<-w`oEMR;kjPJ%fs*P@0Wl5`t{6xhOF;F z%N1gRRXi$eJo?xf56EPA{o>+a_@;WPk$~w&92^X32VPwZW!Nyg%Z!P|O>=@dL&Y_B zhVA=z7JuJ&rR@8=yVv4>|IPe9dF$JKl}#;gZ`qW)GdvFrHtuL(c%b0*3x6Z9;lKhW zriNy(uP@XYZZNwUGcqX)gOcg3TYYJpC8v6+dM&*)bDg>D{n>|V-e%|JtrKO6iH`0* zdGci0=a06s(t9>;6wJTB&o#Hks|5~Zfn>)An z_V)bkWz27K-q*;vaunp}>+h@mEq3{Gush?)o#$TK3TuFh%MO3o@*!NM+#CS`1{=mn zUzal^gc<(j6tKu{+{1W4-u_=-)!%Au&~D7bdx8WEWIxZo_Ur5G>-D~-hK7QxSFhf< zZ=c-Djt3=QZ`p2$wRj_t0BTx1xO2xRX4jYS>Zo$2R#p}UZeb~0_QDc_73kn0gHJYG z49^0Cof{5Bay{W?`1h++V7}ekBdy%xNr{OMb*5h_UsJXBp4GSV%*>VP_doM6zI*fL z$ou>IAK%*AI%9^!`<-t394Vp#3}>{K*)!rVnC7S{FjUMs$MBwof!*O!D?{T#kd4b+ zbMyA~A3l5-QZ%*gI%m^7-<@N_%^bI_QN0^CZj6ZBIWhfa7RMLRNw=Pl@lTDia6AzZ zU^vrwEmDc$1}Nh;eiqOWVz_hjXHm(Ox94ZfoZ0#E<;%|zb@wgZWtr~Wz1#c#{^g4& z#QV$K_FO8jwGud?q`)x4)f;qV0W6@9Qw*%&c>y{(z<H)RkiN9Qp8 zXJBCX|KH(^z!up3)^F~z?hv{9|M*9JkM@oQ4O1GLSd$dk>Y2HB@8)*(@e&DG;^H9i z#wl>)#@)Zun-w$^6y{D+3i>twd}HMKcjw;Sm9BozdjEOlp7LjBX5PGc{n*#aKR^CX z`=Kro#&c|zY4)AiHSzm*N!;;$w%s7{kjnOo^?Sda`lAx2)WE>Rs`26P_xrn7zun~h z*e160))vWab${=NEq3G8j^36tZ(X2-dhNfT&%b>*%)HAF`O!Inm!wQqOrISb+3n!Q6rHp2p>fzUpP4<^HgkZk$slm2Mq>$+DhI=|$0vVE zFdmrG8_~$XbW`+1KEsFa_ov^Oq|NnD&RoL33tE)oKKEGRJ#dMO1g<-Pq3`YXiGO`Gq*v-IrV9)KH#+(e#geP1U zbWpg@^plriUG(;Qb-#0$?e2dR#~NV%vYkQn-|mmcq+=@#_fJUtY9E{a`|azfl|j)@ zzE7Id?=Xph@qmhungHQ@UOp*0Fc`>JSWRU}uw%58Wn}rJJK;XVf;@#aOcCp1EN_?H z&i!2Le{)}hQ-l4V56!VvFPE|k{k!~EFJi-if4^Squlk?*`{?if`1uSE>i_T_xa>~Q zi(C;63<-9QNd99LWZ=1V@b;INn{)5(Ds^O7w<>g9jOG3BTQy@7j&_MUNPZTa%f3YRbv)dvm$OBQ~e?o}F!e{%%&U)NPiB$Gc`9$}R4ny@G-9fbW;q$J+>A zM%kF8<-lMtU!RBZKn+uo6%)sk=miUy8g@-&<*wWQ^mO=+5AnTHre?prDpu84)c>mq z<|sI=tIhtlfA!PfUmq}WED=^g~xjV)hU7=#^exH2?4iEEr- zSddqDZOzVa*W*{Ot@-(B+gY>QBELRso?(yKQLu1r)Yem{rfO%GzPh4yrv2H*e~Xz| z82&HTxAB)Im@iI%l2y$iA%-*R3d@xn9QLttSuyM=duuh@wtC*$=iaM@%dXpMNr;TDC$u z$RO|BoS$a7xAM1ry%rrkSA5>a57;h)RY@RQ|935&pq?G9#44ZBu8Jso~yN1Xos&WS-5|hZ}~>u?Q3GDY(J9x|2PW= z!@uKk1@rU>Uehuml@Vm88p8~K2S0a)#v1MvZH5)n(OX~X&o+1{9=$DR=kD`uywYr< zpSPXU8soJ;AZs#OlT@_la zxcf$<(v66{Ra^i5`~7}f!9%C$jY+O=_+DLKpUo?EW&0#m?_GOj`1dbm#a4s1z%s79#z={c+3S!GL=e*B;@{}oycTd5?MGHRN6ACt1 zuhHJrc6C)Kua;2Q@~ioQ`vh#tycn4pG&48VC475x)2!}KMYwE8ghNA z_Ww3S=j}XNcCYgJn)}@R4FtnUWC|#4c)^3Iky9j;;X*x=_jEmOCsXYvg|lAKTeGJA z{dzqseC7HD&5c~YR&GkzS(FMY@4{A2(&7)>wsza9NB8+|bBI_oGBvnuKNE-1=lP*G6ym+uhcTvtWfuI1~ygFhtCW<9){pEgsFX!RCFc`}J~p+55fUXWd%1 z`d0iE1qO+whhzxlaglUJriPwH*8oq7}WOneSUU!vwZ!Zi*CJAsi3VqpPCY$-Atdq_0!YS z(KC%wV}9S0G)}wm>JRh$6?aN@$*F4uD z;nEV%ZFzTh&1lsMo2DJEw=G^kI{Vt1jq&w=P0LnJQuV$Cnp?k}&J6V?G;GlezQz(J z7KY0&3wU74G#nV28eSTPPV}GpQ|S1anZ~-Sw!YtzdHKyL?e$v>laHy)OS-$eeEYYz zx7E+K3v-ppmRxXzy6Un0e&NuCK?^T0?zh|JkZbqngR}MXImM6GS(d$txScjT_tCQ( z1X_CvUJVQhQ@D!ZNllD}gJGHb-?!WEgAN7oj+&yyu%b11na{?swNa{bgI5NrhDUC2 zYUT1gZsN#bFsaqkzky*v`$09liOyl8r~*SoPP|ke%-d$>AYaE{e0q91sQR2Fwv?M8 ztMGWA?Aw*g=XqJZzZxFDRZKTZFbRgkRw%>lqJ($5kF(x8qUQlJ0&P%S%z)^X8hY=VWS_sN++`#KK_9 zV}`%%>srgecp&Nbr2<%EYr{@X0S2G{UC&GzewSP~rpn!Zw=8UB(9%0` z%N(x1j!Qc`D;3l(S-b7lsk^~XPfg{1Vz}wyitksxyu5rjJ9x1hZ~6YGr>B>H|NV0L z{9C(9U&qXTvEsP{gF(IiYfzDYtVhx;{hSQAWLO)0-D{f8%>CU(X3)^ao>9@e0gZ1s z1Q>kY&$`aA;MV_Dyc_IAW=Nao&9N8VKKDMugWvD>=jZSHx$N(c$NgrBhgx=Izuq|8 zJU{REyWQ(S&Hk`$IX8Daepx2+L)xNX!QS8Rc7HoAU$3HjH+%iwHJO)}fodof*~>1c zr|AZ7v+c8bxO)9QBi4u0bfeR}r|Xse*SNF%!^8Lc|L1MLSG9U>?YEnHCrnFT1b_~Z zo20i`tNZP(t(!q9UG{XQl5`)J(5ktIKfir8JHOAye9oR%t5)CnZE%Ob{{N@b`pZtu{uNX6`|b9JC2zL>`EoPh=(&)G zcWxw^;V68dWsZ@M0>cbJ;cl3!#y{Kw3_kfYrZYS^)XKd!a&wxec-Vy3hq(29X7Q_k zl41z4Sd)H!-nS={{oAH@{S7PKcjQ9c<72&V=T*P!~+)A zQ?P7B2alW2x1!?0RhIemRj!TNYGkXMH&^Do?e{x7c7|AUJ&>(@ zGI1r}^10y(pQlCVdG2;&*Wdld==Igr;g_sft;=twPQS5dk5F?P*A}^|7YjF<21@hW zewiR!{bu7vXHZLvTkVzY1dBy>;}+9P0<6 z)my&4xOjNoo=>MjwkQAn^>y>^ce}LT{a6vW7*yOAUk^1k4SjT4vt_#057F|(eD~|M z&*zrE0j+7Sj(aE+YW!vOi`s|OP6nYx}vMLUB0g3 z&AnIG*S~j~y6W5VYnzSJ&zWrP4y!mT-*5kKhqZt4D!v!?@%6F0a$9Zu?S4Kf@lHCv z=w9{4X3LxvQ43c&Yc)uf&gYr~+QPL?YVkbpM**e#{N`F6UG{#*W4`bEx_nurSMja* zew1ClX2KWCOTQmJ>ek=(`Mmx8RiUe&`2}-)-}QRkX3)V$WsgEcc(k-R~$Q~N7tl+wW+_^RPh z{rs9wow<9zUMqb4<=)rB^{d`3cgUQq=KJVc=JTWC@ms#Vy?y+wwoS!hUh^YoH^PGt zYw0{;Cj;YwGixK@mERL@P$2IMVLY%dcK0r>ywzcAH)#ehn{jKJ)`92!VQZrzr|ZS~ zG%oXT%VTcH+WqT6GygHYwFXnPHZIMQ++FrI%KGh=%a0C)aV^%YnHC}I->AX5_|QUz zskb&v(~Gs5)AiTxQHOHQogIZ6|2Fg6-I!PR>*bBQI_u;b7DGRI?yPu=jaTZ(wV%@ee#bc;JaYc}?fm_@ z;;|(Y>${e6?P}|OqE}yE^XKF7iH(l+ytiSQ99wgif$1U>3&Y~r8Lp6K03!=m3@F4d zg)koYl0I{_M%k4>_sGp@XO*0b1D`)vV_0EuZ(+NfRJmlRq|cgLV%rsNRQ~__{q3I5 z=elRVyRfi1J6gt1OJhdF%eB6<&6Xv^UfJ>Y+wIuy#Q!&XB#n*g?)|F_yxrO8)~dCB z|G!@=mTt7%S}JQ-Q;`!dy?kC(R*?7O9II7-^B24ICVgMfuuOhRkL-;d3(dA?O-p?EdDl_45*~^IKl)|wIBi1 zpe*+hWe5pa?bOPp_hcKW>GJdW{Krur+rmRDeBY*v+JQz?Eo6UMn=?AJ{t$Wgxjky3 zS>Bx+^Sy3`ozPjeX;xEe>ZvJ(uf=tvo-}3rJNbNG^*UY|iwpC+a#vT)Tea!uvZ?yli@9J;!<%Q2?rtc~{^v{ZwA$nWROaG0%*b@yjNlj>EU_8JxA)*PU zN~DE>@xYg^mEeVhTY{E)9i6);=cdu`N8S2ss=vQ06g{!UvpazU1k60!-7>SURM1Bou&k;l|L>|x*f=Pp!{Ct@lg97 z-BZWi;+Pt$b{x5OWR`ah>ug_l+j+OXYHfMWAGsPwMyIUoQLmXKj2P9-nh>&(2;+W3_j4R(#v%+{Uw!k(q5rX_d^@W#8PdR9Am_ zaWQOjns0sNlWn&|R)1PxZ^X<0>-h%!fsx?GFrl0gR__LQfST&g&(#GMQdt5PL*Pa*-?-fv_mh}LI0gv)7%wYxmoX5o9%yiqxih-W2YXj zjF~)>KD?ixx>~Iq#U=D_Iy8J1qk>%rqA)|M>lW{q1|z@88}tpB_`x`Ss=H zAGkt+yg}m#w|J zI$S@`Pj_SJU8Bi{si#D;udWKc6T~VRYC5SAmOHRlS)iemou89TVJT+vy{T2;sh)tGTQ2hMdwS~^@OMdz=Hv}^7TNk_g*4FEBvrEpd=)4|ReO5%`OS^o} zDKCl0Xt0NeYiCY+Ze7*|Y;(tA9FAWez>LPQg8n z88p%295mHp|J1@n%TtfG->)lPAGylx)V}Fj_iMjgbPrqZCtH6jH(!g<;ciZnbzJCv z8SAn&Q#Aq)g%p0;cwDY{J}aw=>G$XJ>(xSM*nleiBOQY8c52I5rk#=SzWUDU)z`e6 zo0f8m?c#p&A^GGa)orKsb{|>0Dt`aI+OJo`3yblG1jiE{2L^+5tE<-*xpJHTf3dhfYPMPKqiY%NjaN4uEvPUsXWVykvby@# z1icq!*B;h>ltwKsV2uw*VRGXRD+fc~yY&X=VPkAvy`XwU-?fgpAuHFa{N0@;?148t zrr!HAF_YoL-SYcex%GA&u)i82n+w{9TfDMtQBx$S$)x#aiiMbdTu$w;FP>bfnRA%jew=pPjS+(nIn1nnX|w=8okm zqo3#P|IawoB*pb>s(!p(UT@i=s2^E&uRbsTdF12%|9{Viihp^2dwYKV-QDHim)~$h z^*q{G&aD7c=@+t>0(`RR9KE5^Y*Ks3WhI6w_wKXM{ zU0W(&^P#bR=ak##cM6(q|NVGecwBT(P=KHNz1%dW{9*=cvJPK-=o_)Gy@(s3#_m}6E-8vap^U*c?>Z+-rVy19< z#QwUyD}Oy)4(2%Fr-ksb#3a?YiG@x6UkbVOs~xtbSSE@d-IOT z*BKTZ>PkM=)46-|#l`N?XJ?rv7vC(|^X*nP=m4$Fd%xW}9asPN>y2c$+%>VguWi-- z_v3MYayzU$pA#<~$mp=OE{yv{lT09^1FMhdgVSdvY$`VJ%2*hD5@G!*wEA!6!?)Y- z=W&_3^$IGx&A4T;Tx!*|?{M4FA4d_AmSKu>JVmM>o^w z=dR*<(Vt^g_U_KjD{T?US5^dW`~UCvZ~nPk)@C*4-rm-GHoo*~=*Df^AEtyb1c=J6 z-~Db^foJ2NJ}!oRUoLrXd%y4Zvsb^krfti+YxPNH?|tp?b#qE|LJPvUm;271w(aVd zA0Ho2j*5K!(Y;S*<`;{9E?1t%=x)3!HJd;+Tg}MSu+#i853C`t;15a~n?d6k-))N7`I(Q&8mBS65?0_vUW9srFH%o6FAj+l}P1CllS()`qIuZ=DL7xk^5M zopzUt$@-|sO%I{&iH@r#*TYuRQrJXlt{k$gP#Z>aTBX zOjcWdd~N5dO*4YE<3oR5PCp^Pe16?7URkRv^Skc6yS;t=-P-SW3y*)fb$xBLdEUAE zfer!Z&&$i#ewmmZ{^mTP7XM682YXILE38fPBpOs49fIc6>03Om{uR>x(Aphxa;HW;>6d?p>-H{Y+E~afT(;;IgZ=L}o683t`21!V9Bj?}|KoB0jbFv*ZOv0( zKf0krV9YXzOMt=0^Dr!DIxI+FicVJB9lRr7wh-^Iu-ix^R%O8_v?P=hRf=kZ7g(Ns2BP_I69$qqENfmEX^h1 zTeGenab9<6X5Vk;M#rsRcn|w!JzxE8Z)a|uXvgl?>vpe6IXUUy%Z+cBdQac=T)fnO zqid#F$lHL0tABlcy*zU2=Y=a67Mu&xPPJWblzM7M_lvE;vu_=l@K`c^P9ms1Af)QG zq{bk$M?1s4RpjfAe-m0)-FUn8dR*A55Y6(8x3{(~^XljFX>-bdd}-=23@>3UYs zd-=P?7GL%Su%7+!v;FhG_pRLGQJd4w{?Y8_ayh2^p={reN8G_v9qU)jT4Z}U4dhWhUQa>+Z^b(fTBmP)MW!UNrUyEHQGvKGbfubY^Cbydj2gRb3TN9SH!6{-zd z-4pxz=8@!G%R#+9vFIGZa=%A?hcZ{`ndjWtaKu^it$F^vJFWbex2m3d>9mrm!OA~z z)8Fs+?@!Z@&%0myJvQj-(Gtg9M~>@exU>HK_5J<)9|jw1Sv^FXq>a;j?qpA2_iC|U zU)Fi)-7B^$ZkMn7ad7s@yJ<dam2@ypM< ztXX(m^hD@Vzx}@3#8&i{US8(w8_FlD^~L@4G~HN<;?--neOi8#Kx1Sn1LJ|1rj0VN zWP4&Y1LJ{;ohK)&FVFRr+HY0qzfe0=Ap63CMsBIO6^}YMdexjLs;KyWIomg_;&C3OyJqKKT+|x9{Qk>hpgHY>?D8f5f2TC?6KQ2E8&2wt5U!0Y{>P7haxV=-d z7x9TKc?|6;6eVs3O>3}f+W-6Uctv|@F&E1#(+~&UyBCVXcNm10dbRpp<%OHIN&R0#ZK8yPIvh7~-s-zWOvsY>*Ewi2voBV>MDsWmu5FeRX7#`c+fX==# zvTRawU@*wu;#&0Z>gw>@OFSq0Oy#+HFC@2c`^_|I&;->=r361m-Me2vQ>i~5_xG>% zT7F^fp`0wk*;#8MHXdrdBO>#qJ?hi4Y{A#-dvE#iFqFN#bd>e-mAbM!I||LRujzm) z(v?}WZynQWn7M9m&Xr`9bD}MaSE*~MtbEnJ%bxe`>#vgbb$eDvMeM7o1T~26+VAAm z){EP7BlO2?qmLL-ggL1$OCs;dq6KHjv^s3q4O!;lU1c*=Jn%}zWC8&zF+{Vp!J-+;I z>9;qV&$sO^yWq%v)A+oN@a^+&-BvLq*F(v;bny5 zifrf5wMMC@7Bn`jmZ<=>b3AK49AvlLw)CsNgk4QV%u#z*j`WL_nj|O7)yOVA<%$dJX}GKkN5gnrV9;G{&X3=fj~LN3$4b&u&<8s4nZWbRTG9 zY2ChGuL{hs@8@KAHmgS%-Q@^BfLR(rpcNIT&NoAgwFC8@4Ga(JUtT@;b7!BV@v%Ou zS1We3f`;Br^X^#W>D@i|bb5T=`hCB$a!z{d?@a;i3CgkGF3rMFtbL47uyutsFeF_3 z_4x(VlON=T6c~QUS8X(|SOprV*;V@b*xH<%o0i&sK4ToVE@tPBpDX4bc~#FYU$Y_m zfAp%5l`EcFo&&9-lQPSZ*#2(K=5w14HnSfmG~D07z;x7o!3|c1Zhqc!_#kA8yMnoH z+~#8Tn5{cF?i8KY{RSGIzM(e!F%0N~^@r&(6LD&Gqf< zV}^!0j*^B$Az%m7Q8k8$9saZ3;pL5h!-5KqKcCOre|xw4{jJ0N_Br$G|5Y9{Uz%0> zYq?`Ho8bA4by##@Rp{zB z%jef^a_ttod18!Ky8xH*Y@tFViuB=edTC_ERi`&B1Ms4L;Kk4VDsoLSUl7b#dLE=bY+3^gVXwrKM}LKFFQ_c4NwY|DRib{(iqd_u(Sf%6&dpAJncn zA79by`}XsU=j!j~{y1;{KcZ7eb^<_5I=WV}j2==o)xs8vhkkwSK;)9~J@iTXA zS(c4$ys|+7)6ae{-S_vKwe-Ii$?vS@T9N$6Fin#6n zLmIz79PYmpyd(R@g%j5|D$I}H^*z|p&aZIKwM_~hx4$0CtK4V0S6+L{`UGY+zM|_p zo;>Q#dB6Ajsn1`zejkyqm&ul||I>MPj_GL;8{PPQd#VNto-t}eD=#Iqsg&XD&GI)e{)nk zz9{j1-1d7yTUE@KFZd9hzc*J{-EULm=JeaQwr2Y(p0z4{eS`D3eEQbx>wRl|w|{)( zt$(}v{oeek+Tq(6x8E0ww#vMe^83Z({@i0dlG`di3VoN2T6}EVxz(kwuW8z^{&nu^ zS2y;0f02~%7h#Fd-fp{nuFv9;!R?ivlW!!e|dYSLs--$l==OZ$^uE2{eo1fqef9O0yJcI~cqY%S?wQK#boFQ|k8IWSzea_N zWJ?}2mOY!feEHtBQ?>tZ36HD2TKBiK%Xs4Yf9VaszP`G}sXi~^>gON!EKi>Avj1an z%kKA^&o|ONxBZf5kJ@T=;NSXC?eCJFzn55az=|rg!aOCifgxd9<4zlR26o6|Z2iy1 zw@X

atg>gh*U)$02!9?XWG;)%Rpt{Iz~vuDrMJeCk8p8*_ z@I*c36*hWG3^VpKB>XITdbfPa5B+^FoU$(_y|>vX)LK5v=@7r|pN?KRTeYXn*H#AK z{vta`LMYfGRPkzv^ZoO&R^^+1eSN(&>d~|3XJ_Yc|Mu$bw)_{DZf?83ukKP+ZTgoN zh27keS`Vh`F<5AG7~ZQrU%MRTTjMb%jyO}@zA+yDDr zb+sOc<%+7QZj0S`V>6Dvee&78kQY39{Oy5r|Bm!>=jnchjC@QDKWi>_AAI>ylwq?x zgU|OmEjF3Ry{w^U{yd%DIkA7C*6dX_D=+>#RW>oZjBC|~voj2fCv!8Xwf*3`QEz{H z-@$KY>n{o8NP4Kb>6ec=g(O*tgD-9n-tPoAJ`r1lg)m7+`l9C*CucMjke$KC~up;<74uMfB$~Vmt0=; zZ@E^(s!2cI6rbO1+4}C=-R(=O?{TfG{cx~-MF5zTa`u_KAld zYx`6_X#AgkJ7j$x*PPbGoLGyERZs5hEM6P_e&0L8ugTYA%QxOFyL%tS~o4tw? ztxNBoU+b9avj5fGLlbI$fBpac&Vs5}>vq4*s{i+MdF{`q)7Mokqne;=LvaFaC~e`o8OTk(~xpvlpVpF=G3KTNRR`}l3s&uiN|S)atyw?^fOw&3){Y8(;I&zWUS2 ziSH^_9Z39<;QUS|4RkOC>$X1%yP8s0&3e8)_WH-Ty}yq*l}?WpW8rC@_C;z{LiO*4 z#=Pi-C*+<0+zw|1l`wy(m)?EE~(7El_larJ0UJCZNy~)QL#nbM5?Qpw& z)_vAEskM9-2hLeOU-MzZ&-K9(M-6OtSY=GM(O9u+^|jMd&*v3ylPx&#@8LtIpMTRX zT#8^kt{J@Sm|gNi=H=WB`@Vj&{`PA1`khOArOmfxugjAc-xlH#oaoEDm#s?INV0P8 zI;JC8f$P6-JXFtB|7+o4&}OT=eNV4NBow}w+w7a@$_6iyQH$;X5hfOfZl}4&UEo6~ z8>Yuq-Mm-(zE-{P;Lqnfz3f*;#8o_W{r%uD|J{dWZ}qmP`OaPzHS1$d2t&ZZ?#j>4 zSpPfz*IymIz3+GbKgoE5h!qPCoSA8yds-_rX`$5rn$S(N43pcqO+)xsxrDBXIA}lT zahW4KL+O65u8>tBhGCV4$7geh{rP%5-pqJ~Q|Pi1$fPjUwd#6Z)$QDDmfY(9YZ<1!a{L-M%f5c! z%1e=3v!ahTDevTDNc;U)r1X8&y3fz`H@vzX(qF^xK6movIk&=I7cc!@b9Gf{an!sL z8|m*;<})m~CthWDy7_tN$|Tj>dAp+u8@DV`59koC+Yl8Rs=xEeqb2V3>Ks@0?lBA~ z54vFVy<l z@Q366JoD16R;90I{EuCEs*WpBtd*XFz?Qvm0i+i_ZDqSkHH{RE0Tf6vv^?&B=_jd-j@A#0BBZzCP z-a!#mn6RYC!G=}@926oQ*4EnpdXZfIphKB&`(!^G#mbAvB)8hgi2i9W`+fY)f4&^i z)d!Y{P2Sbl)+7*kP@ul|zSl*5hOB=J+2yxo?*IF2o#?*+i^rf=QSG-(LBFGQ+ARwm z4s{-^U47_Ua({2f*4!&fTbn~t)kE`xuC8@&>heq6efonE*R47A|8^ESu9mNpczZ3& z_qm^J?rB}^=>FN&yMhmuHQx%{s>K_6qv~(3d93K76_2amT)d;_%fYx(7c{hy-(C0r zZmhF?$^KsH_b(3Vnr2<;IQv_A)siLGeH!)ZH8M(0X{zu3);r7o$%E!MUoQK9p1$PH zw8c)ktC%XEOl-fMtSr|bdi#=R)x53Q`OlfmxX!mYuiqUP-MejiY}W4g_jGJTzW=^k zet&bgS=iKFk3Ma?w&msi(6f)ks;sk?g6`V5y?lP{v$*8<6L!zv`~BYObJpMIC~!oa zvVXEoTrcLuyyjKSKi9iYRS;QqJ?qt$%w=M0rRoA!Zn)=vJ3s!u?KY;Z`ul!t;$E!f zp?rS*{(ov=XT7>ZzP>udeZIf;-kna#e*x8Zm(Q!RTJgio?wXV7p0venymx=w8S>0{ zTm32DR-f?zx1Pm$vH$ySgiQ3CUt7N=vv`SY`5VKH=a=@`et6*Q*nO)|@6XCEBm#YVFnUYvq&+S6rHX z>uUCot66_9JlwF*S&8}aF7>;!kDYWZ`0zo&Va2L#cX!=?^Q@2ep7C*++9|jF{w&ejnP|KHc#-Br5wHSgTJHFfKL{}hkEablwX z?$;%I7j|D=AFuy%+L!H5-#&Q1sLg5fui59ogTYvcF3>WPz!jfoAR2FlZv{nz0v2T5 zuZ@1@^{iLn%*QH$R~IA-e&?=J3VOsUq7}sI*c-R~8;{oA(DK`f3<1_$5h`p|cNX>9 z^Mx&VyCwMXD&DQTKWUY330&L;+Du%SsQ>?t@p+58aaBL3?hu$#AET?C|F+Uw$7fkV zvlE}xDvgkJF*_HerrU3q|LT0udaJKb>3{3@dp2h;m6-SY%;xh)n~ERK`5*1*&?=jC z?TF?XQPD>NM12 zr2mC=yS0A$BE`QiIiTBWBcKNbLRZ^|8bw08(P2C zaowK%YrgEvwuQ5fJYV^DTdw|A+gaxQRw9yC(R+}QoB z= z8~N*>gF5`z-@oYiz%S9am%rKJ^XY@%H@m%$vwa-(W7o+C?f1?nuD;*QXLaGr+;xId z%d)N4Xf4P}TrarKKBTntzyZg+cYhZATFZ2$)A@V#)vMQcy%)Ow?DBcL?aSxa9n;S;S&`*!{crx{udD<=FoyZuW^dC`G? zzi;k5xS!vJcPm4fb^`DJ>XZN9UAVt4I`7@XYfqlVp$pM1Q}G;|O5aaZv;fpAU(o}AX> z(cA5ge9OFeh&9jd*N?{$rH4Q4&^j+$dnM43`^ws!starpx<;aFF7J4ED|?OSG(Jz_GCt4ZF<-BE>A$h73%l$F7`cW;$C&VJG#)17$sb)BimlfVV;k5{j6 z&I(aB3t2pAYm*M>W`+yP%68WNIjO#mY0fpxGYhyPjV@LgW?cVs?^xMctFodCW+DBn zryb*B)pB^;{{52>LkYjgpB2I(C046^rNeVG4>qxWyZJnRM?z4=p8WZ78w-LW6uplx za?<1ar^&Elp;yoIImOd%`+awA4BETi$ib#vH5K*cfwxz zWBv0NIIpuUS;bYB*ZAGpQ8!dR_^26gYvC26(%o;fb}KxaoxeACvYKzvaS^6HYvboH zIQ4W|-u?eJ*^3suI~i;9&^?Z+;h}0Dzt(-zySe7qPkpWb|NE5P&k|=Tl2=m(w$3O54PMp|4Zi8ZUdhGFO65d$_`Y{>5eX4 zy>?Cfhg;7~j5rydmGIg>S^EB%BXhpL)zS5HmK!Y7DoV2onHqA{&{QPkzCFi^%$9oQ zOQC8pvRgjw%}dt4A6tI+=(?=>rPk)lr2ufbBpdb-eSgV?GcMaDRsaUJ>qWR(5 zCx1B1Uv^WYkATLBtyn`+aKm`iz}^?ZfU zq+2p>ysai8OR@yF#N^(oaCSHs|NOuE|354Yq9(5{{#~XpC;aOEnwZ^3H@Gf$@|H^c z;e0!tHFQ58&#L;L$~-qR{1&=xo&U96{zHJns|^cGm$)S{81Ur0jJRwgbv$t@!h-dby-A1fa5NM2jX#0<|;&dDiScb7$D(ub)CqCE047}mOR&6e#GG9 zo12^0-p}2B{7`-+FN2mx@!!(xs-Z7GGk2_-R(kT-v}6DN&MW>Fd2Q8I#)rX$`{Qfh zmR4(X%*p)mR_U%wmwe*ypqm zyY|>;{hqF^0^w7w_Xn+x-te(~)uA@VZ?p5>ygGE|-^W9D&Z#i0*sw89nb-ct^oseD z>;GP5pJDfao-}S>^|KM8c z0i9lt5r%c!9TbuoTbcL$Pux=b<6yhl+wJ#*=7p~g)3yFSXS1*3#)2P>3;(b%_;as% zxz+B;gAbbu_a7FUJL}6~+r$;hp-WdEpI>n)MApYyxAgV(_0P8*man_ID!JeCRv+iT ziyxTPvlwFn7!SxZJ#Lq)J7RlGRXjeWntkD^BMYxPDLQWb#CzMXPA=qu^v^4o^D=iO z%$N7^+^+Z0@UYpeS^IaoZ(ooUxAutYx=RVm&&4K*3X4Vr6?i^8;x{+H;PvaPtJBTP z-U^lHNqpj(?|tW>h&9*pwOp%yUR@t=FLvt7bgh6D2@Bhr0(QUMw)%G12hBBA<{1wf z7I-BWy}mkC`#;aS@As>FxERE){XY5s&5GVHiS66U&L95&@y=)cBU+KGg6@YohHjtZ zCJ}ViYJb$?`g!thS8IM$rM;f_=Q!W?!{6J!2_N3{Q0nhItI}DTCzemV;dk4Y&A#qe z=AOI7?`!kI51!vJwK9-}q5A8)*M|zY)-B^^Xmbp|Te9kT{rSD$+0W-XOGkcxV)ifK z#?Ldx=RLSu`s9p{$<=&F+^%&s{lNadZJ&i1LN0tfxA1ThV^QnFs*?B9L@fS3?zfLA z^|OuJT{b;>^D^J9Gs|A={$R@5u~%yYSE2TqwF|wbhsPJsz3umPUjciw{KNZQB~zIW zZ(UWOet5&Aj7Q}wjx#p}4@w_nBBj1M2bknY>~bAwTe#rb?( zg`5Fs8~QS{e)xJqg$ZE}x~a?A-sW7@Dowf|WUw)Hl~X*|<&~zZ+vFuq`7?Ytr&z8M zdYC)^3jfxY(2pfLJf%P0N**r$a+}}ZHTFLLQV}fUF`IbLEJZn|fef@rzA>nJ*)ivesdEZw3 zef)4+yy?31^Rw3;+je`GGiVI3S9-hRk|*20%`r~z`}*$k`L&+nA9&W!f3-d8_p6;} zxo-Vfb@$^8L;GXX+87<|dA5K~vuS^A9>UhG`^D^#SIVp|SYoc zu;SW&_pO#jFDL!0e*0#D)QkVQYuKVh7!S;|t-kqZL2AAqW+M3AV?DC^e|1F$y8`Pqf zyT{j5nYh$5Hl|+Ks%(edr|OvOcuuWHD=)p4ZDvzp6&KF;6a67q^CB_a)6iy_*q&cG zZHND#dB4m1!maPCuB@#+yk9iy=(_42DK7T@npZ1#ls#W{VAX!he--a`K7YHo-@Y(- zCDUcAA3+zk{k_|pdwVg{i+`qD*Pg0czjxchqVz|GZ{KfyF1Jo8=gP)8&x|-3v@%v5 zSa~dS`Mjj8MmbY8zd28w=3A9HeW=V4{#g0ty!MONtM-yrlR3d8NMjK9znnkBdx$0X(%eURzl@$=VX8Z1W@)D=A z84Q*$=y5XQI-T)j;dFy58}m;uxci#*}|1Ep*vZ=O?VQ+PS=7zE^uf~V1e@|@&_5a>i@BRPTsAhFDACFUS`muJY zQs36q?Rap z?=e%B;qQCLUb%4jo8<0_j+&TydRpXl>D@=K@krW$maK?}8|s8IeE7Ry>xUJACqvJ? ztAF75`{VJAmSLwp9kyNdW+_*^)a)V#&}mkNr%R+|tz**l_kHnN!wpvhmWf{+KQ|4V{g9ex^Zic*`I00A4Y{P zUmdvEO@L`tuGp5%HNWSU-(6VG-0(Sef!E|L=E}HP3=8fb+Ps5>A-J}z=Ch9$!!tF8 z6|YiO1uYZY7WS37fwk2C9ivj+6IF(akFMfT-C`#f>ioA}v_hLf%Vp_>$!@z2LJh$QO(uOuVyK`*(Ao-{@rT!c31ZLjcUG9yFshWuh!}vdcE@`Pu&wW zh95W6=kGSCsEFM9XRk(u@2jh8rTtX@&JzilBwO@6!2JID{Cvf!c%K5H^WxBa-XGpl=N+S#br^}iX)S7xu@d8_Q!O3ziN zkDdMP7##Z0>iL_^F%P^MClve;U2%wEfqY%gogEujH;AqC|MQl;*lat)g7+5^e!pGo zJ>9R<-+tTwAHx2-#AeNUQR&SuzTwQ1&vR}EB)wr2HtX_cFj#YB`L`{rLT287xcwC0 zes$sXE6X;|wJI;X{P6XcGn>!fRG(k->e;1Q`CtDM6@nPo_s!k4gCTL1*~!lD0`JnL z7``;$u?o-K`_*>wfuvo6b?297@84bXlk4^U|KB2B7jG5bx94qYm~Mvmygbm1sP3=7 z<=a(4KfM0^zJ5cyyyUxUGQuoe{kGpEw(D-Lez#XYEH-rgemP^FkY!ad`&IYey1$Ay z@5+b!_rKpO4)5~|ysoigrw>y@{ok+CWA7&({_YAoFY?$r>3j1#zkfI~S^4d0{r}IG zS(m;^=#?_{i4od9fBx%LvsOBtwfvhaRd(I>+voH4yN~;d#`NvhEJL5qgbtH6>Tn1! zoMFqa%XO+&s8@B+`g^sx@9yl(^OZ>We7mD;_se6vqPK+B6-EDN z1RdgLK3j`n#k7_zUkOu@djTEJi)$}%6>Yz37NULU3RA=V+V6X9js66Fw>k8n@3!ZU zkH@6*Z>_nxIrj9O&*!bLx9W=Qy5J%HhFiPg>6UY`Cw>ctDP0bcVEN3q+n3eDs{Ex? z_HpZ+7Xsl^HDjJ{54PJ<`g(!Z^{U?*8E02`wKKDSIdAdj)8Q8vzg=+d-*H;5`pm^L zpAY_zE|iM8UEyGExb^PJ&$b(XUm7mHcb;os*^3)DLwPS-&W>idP=4Y0uWfa;O3~b_ zZ_Uv%S@md+o5Z|ZcbFQQ+j+L0oUFe4`zohWqmRd5E!Y*&uJC1vRuQWxLx_depFMJA zHx`ziI;sAX|K+yO!gm*syX|=U!T9e(clq0&&+mWmY~5ZnjD(b=eNP+^IW1 z?CKWR-poTG2~Ff~;1JuF{gr_P-BUcRRO`1aY?pFdfaXPb2O z+aa$5o#*Wf?bl!5`+Ht>GUM5jg%Nw@jKTwA>Ss&fDkcI!QxjaJa)=Jo0oH&+2`+1+ zw!T>=ozD@aJFRQV$J-WRD}#=PZn%6XfB)ZeZT7!rSgZ4F+A+7+zV2u0B3{|D@EomB zh5$#y(7xM6r*)IFw;E<&(|LV+{r=gP>+i^$d??cnUeQ^0GFFumpK{Gjh#cp5WH6P%ueiU*wL0 ziC^DczJ6_8?CW#ARl0W?JLKya0)uzZt0Sqsf&#x-Kn?FSZ|q?Ti&(&Ky=2fb#*!1mXn^v|}W-$-LK9Mbgwcqc4pL6ovZu8>MvqG!4 zto*t@iXq!1``VRTv4uNt-@C)qP`5kA{?F5SIUf$MUpG^NAtZFyPwr>Cmrm6R+Z466 zh;L8k#(T4W?P*(_KR?c~`_|gSvDYt!=z1Uikb1oD`fa{mshdkYCpU%dJbcHhR{nMI zydS&H&Njbad+uxO0>Q9pm&@1e%PzlLD!zNw->L5+mVuHTpM=4QWq-fT-u*<^yxjlS zKhLib51&UabPNsm;YoP4M>BZYtp(O>yS?8CZrPbzeRJtbz3C?J!ym8Sbv5jo`i5`v zhyVXx_;X=7U*X%9ueOUA*6h>&`u)wddFHd<8D17-JGaG7>&)BmCBf2Hx;~mE`4a}?`=7m;xPqrch>&6sxGX}zWn!|Ctr8{E5E7OE|asIJycz| z{Z``Z;&m4{Br?Cglj)rL_(taw?2t~dodGjeZ@xKn<=HuvwZQnRWr z5|`@_e0N{Pu;AK@kLRsE^W086F8k*F*Vk{K$JcFKKEKW^Y_0FqEg^y0GOmIQJkdh0 zcFvRCvV3jK&Pi7}wF+7p=chNHDp{qoRIz*4*H=+jSB0*PySppz-1-?SE={|PdYn)?^i#aJ7q_o=K3<~^i+BUi0XN>)}$Cll^nd?8t;^dVw z6Q2K>zH!VAR^e~u`|aOF+_uY5+?{eVN&FMf;UuejZ1ox0iYLs>0Wo-oDs*$Fjtk!^_Sn<3d7pc%j!rkFAsW4%hGMyOl3jm609(^CbV* z7c*8h%3giOQNDij^D~9(y(2t>j+>etXIQZ6)?I;?*&%NOoELjL~G zeZ7*O7h5lr|NHA(+55oU{5(bn`yHzqW@vet`EYp6&v(0bPnf^YJN@jew|>`4^WR;(%lh|AZFTeow(@6Z zBHu;KU7&S$X8N3mt5&U=bZ>_I@mWo?A3l$nYW8)PUi`j0c`tS?2ihz z@kjmFM)+HQol-Kr`1mZdy8%m0*BDhte2@(N{cXj=aFZ)ip=Z3!x2@fnn{#$o>FZ{P z4`(-am2fr47M)PMmhk)6vaZ$dSsNdH_E9lXD0+Do}hp+;A?9{%VW z@bu%!-q1);{)b@{wqf9<|6v1`vycWQIBG~#9WRe!#8zi#xqWOkVi`={!M z+pTcruT_1;?_tn+m{96BX z%f1W$+k4gahiKx~^Uz8fJ~#zihQJlvz>tub^*I7jOcye(ny^G{Z=&nU9nFH)fx5bX zv)l!j&tMYcipf~Q#h~RP_|N^{itH6{-#^XOFTOha&|_CYhA+*w4{J5HENbX(ljq^= z*X~%B(AUPK{r&#`hTi!GiZ(JoqjL?eido8Rs(f&;J?X8$;mZHp^Ix>b{xJ=_UB`N0 z#p8c>Ivsy}KGFNozuxXnSg0TWHbyP0e|Kf&<(vl#tnY+`Y&Dhr5PfA{?X{WT>i=IqwKjZp za_D33!xQo@{a$#!r)gc5aLfcoht_8yD~))=#77M>4# zeoi*Fz@X-A(d|6zJt=;S2R=Sl-|;XCU^w^@0u7&M~zb{l<%(S_3@4BWr{XF$1 z?=~(f>&q%$A}h~wND>jrC@hCS&|%10m2%?n^l^YwW6h_y3w$A=_kvg%L;t=2Ef%;t zJ9mZ0^UEtA-3WGkePF}ff(oD9Jb$~NE~|yMd=2#oSRB9KZka*bvA_H_8TM?UYp+yo ze9b%eZRdhTlbn?Q1*~wr%J%nE{lkxQm>TM4U#@;9Cw5&b==ulk=%1mye_sW}=D!dM z30N&|w?sE`*OfN*M3%eh8Ku8oF5k%&5Vge8mOpeBH*;^DgYKRQtHk#HJ2rdctB{9# z=B;0KYim|%1NZlq&kx^kzh8GeRF8XgRO{!eTD`qblEQU8iz_)9R*Am(&)Wa{O7Qs| z&n4rc_pfGuIJdajzj>qi$drSC3Xt?gg&=*7m$3{z<~hQ&_NyBKTdecgHPYyiWDiSBK;%MX4}@N<0dEj(8E z`@b_U3x${)qU`N|`0&@4w4CLz``r2XfCA5|31v5|;*MWUixqV>mJMWdxcU11vYbEX zr>|SNzfe53X5rf%hxumOxrAMR8Mi*Cert8lwYB^wH+DVtx9{D4e13(I*fYL-KgLs_ zWzQl3{xbibt6r_v)W3f9@tL{S=jU;}Q_pdJYric{dMjI4b`{Q%h$)~&RYCKQBgW)A zIM?vsdZ)*A$cVdn+kVjb_eD=n?F>6$nssG^ZnHqVpYzpiB1ZzePwjF%ecNlQ*3%NN zONFerL(aZ_zyCkyxN-=KM>ZxD<|Ms?`WJ3IA`EHXRW`CNV7 z{W;&o_2ZI?pPwyVYrLJ;seb03<7Vdkte>8pnVJ3if82Yf33UoOSBpbkPi3!v{b1FO zm9wJb+U~Xgvb$OxdC;JCe%{8TVwQ1U&sQ#8voH8Gt8PR#%i4Tl=S5uc^P7E6V;O$C>a|nl`qfDD zGc#-YJ{R@R!FBT76VT?jyrU6_))r`6nxBK{^N?O2=Un~IQZuy5{ClK-o#*P2`nqWK zj+@XSpZ}5U^DJ;Ivjc5pSR$^#FymhPV&oDoz=!q9ub`=?zVt^~^~>8IyqkG`p84#k zHAVtALRhaX`+f8IyzN?!q35ETzi*E6Fviit1s9Hu8jMU0fm&x2L3Tk$KpZxT|M+zJ z|IHK2=kZ0E{g>T+J?-qQsNLFn{ckrn9$2RF;qG_)8%sPVzuA%8uessc^4W`+zxTjf znMejf#Vol67|z`65Jm9<53Ak(N8HkupI+XW8@fL1Y~HSwtEcM6+nF85l|Ntx&)&?y zc;M{Mt50_#IeLR6w@&o7Gj$TS$F8l3%Qeluwq==b`Q}Ng-g(E)&sa|2&~%4ApdHNo z-|&SLIJi)V8!9Xu40%HO!seY&pCbDZ=3GoM`q=jW{Jq%YnW0bX8SJ~J2z4z;Qi|w^ zU2!8eyL{cQYqvIlcjvFmrq|wWbq#lPJu2qP6T%ZEQ2)L9qn(}cnFD7$&Yt=G zA!*+1=l6cweXsoYYtO!R2FT?w0f7z-8y2;j;=d^d>E@LHebBvsM-6s*60c>{j?u6p z6au5^imrLEu}b5^uh;9B%h&x-^1G!g^Y8Cl`j@Fem5Up%RVEIMj0e~(R>*b2NulanbjPZa_D=Xe4Ew!M5 zA%R&Yq~8U4@7D@_rv3kZWmkPT$bNa}^Lf#`o?Z=$)}32;OmgYh{QZB;VvEn3zI@m& zub2D!%F5tfkGiyjUSC`5eY>mm)5``{2JWev-z$#@x<3)mzP2XP>f;gN&kE_W>+Dwk zT6ucwT;w|rVX*=Aqr-xI92^YSrcW%I4-K3~Hk|;uTdQRldXE2lyZ!zpM|RmMzrMT- z4tjBOb9z+$->=@Uk2+PxGc~lHn({j)b!w=Wc=dxu_DedO&jdxSKYM7&tL0|bOLWlf zf%+2^uZ_Rd6c{4zyPf$f1mZF>u}CdAaL)Su9MIt>_K~5C2X1_PGTDFGWIroSd$oT# zTQ0i2ypi0myH=c=siF1Am7jA$4(|25dj3jaK`6dZ4t8^3C^%)Yn+xWa11v0ALJXjj z%`P#r%LKey>fSH+^3CS+dek!c+067yACJq&ze+uC``u^v`+e1!dm~o(GJI&4uk(7jN1e!X7*^6T|@f6%V{U$0iL4_Y0z_L9x# zGn03fy`447EH~=m9JAb8OFF-r*ZlZkQu5-$pZ^;Y4_}&~==|wr@#6h~i`|x%->)@y z<=B*ZdfLk9?Rl98S;gmM%r6uM9nU_$=9A~Yp2GFARwXCq=Qpy7c^IF!DQ^9}W{=SK z&-?%X)vx__GyP}nS;ONpKT8*%7mu$oe7pPozRYDa)4c5eehIGYFZ?$xIxq6ovt6&( ztu|o&a6~5SmjCBxXM=lULv@$Qc3yF zFK-o#TCpWg=ZXr0#KXO_^Y>Z0I;>qKrno7&&r)seo=>Mj-}>#X{_gjDUUi<7L4w1+ z`eTymK7tQcugl%{^V!P|<-Qep<@;*)e!V8WzJKerDDB)$C)FxHY%Ka;cy{wSD{bA) zXN<0XlU{hz_?$)Zp1N+~Z@2UJZ~6P}b~wjw(ckl`-|Z~9mAO2$I!~tjdTja9K3VH! z%KbJ*d%s-rKDzR1-7yK!@f}y+tm;&6fHKCf!NyxBc{0 zI&X&}zmAx-@*0bb3k#CAegPe>yu9q~t*5UA1#CYa5%vxana=mCHu3M*>;COBMIKpq zca=Vky@q))DxwJWDPv?jaMJG$B4Y>(&xm07@bmfn^URg5_U*D|5v^XuN5B1;6Tx7x z>Wu4!H*?GHo%Fw5^?L2)wAs1S!i!$t-k!hf$t3SjTKOA`cfZ}{%`R7wP#5!2UF#$0 zEXAK$EUcjGdiMy${Qvj&b8`2ol0ZehRc~CQYd#(gZedWr5?ArC)y75q;pS7is~Fra z=pV`otXyxyBjI?o*Zkg&Lz8V@Pb@%P|`}5{iJnH;2XUBGK z{XH9;Ob^!m{k3%Ow_Dox_a7CDUb1%EEv@x=5^2xp6#HrNl%Lk!zU1fg`SyQb$NxWd z)~#P|E+~Oq+Ph}gt5up!U9R1AVzDI`lS=oTpY?6?vsu~8zTd0XzgzLRSM-;~s}+kc zb!o4g5pJndX7lYv^2;m1{%6ChzrC5Mv>|-UidW*_qgfmme~RyUo3(oFw00%=suv4O zp3O{u)_y!fzV^$-%$G~2``Q2hQ(X1uUGU(*mF52PzdV`j|LnP|!|M-+`TbApZjYJz z_sFqMR))n{_nP_bX3UqL`lQeH+YOVuC6}lE>YfnW^0Z6ge&zGI)7wvVF@L+6K0l~p zLy^G8ZMXBhLHFF$W!SiHjF}TX`TS&myPYEEx*uz^|4GVvz|3c{KqROq`Q7gK`>yP( z{T*>8y7I-^;N^ZVPie0|vs^>(n|px1me4VgV;9SAWiA)F%FtbQh*SN^!5tj$Z9g1f z)?Btn_ty0Ix|!SVmffx~Wh!{uxNnA3#of~Dx_rLh?-cvb%H4L;>$Pd@icI_M_o}l0 z<+$!QTsL*Osoj?g&Yv@T9?#%#a!c5}r`45(>v7~_rv$^L`9AzIR|UJvF8i84z5Gw? z^+(B2jmPy{W=yj@2D+W%{Pn+zutov2+CZdw0R;n978Zu(Et|68y%C>)1vU&3cN@L+ zcBb4)Y?lrC{_bw@FBt#g_f53EQKXWX~w=#)dDzIUsR%a$+k*57MlufvoRICGtA zx0vQC_G#g_SIcm%zVpBS-{<)zuh(oAo4)#Dddp9x5{b3YibL-Go`cQo%YDu7ZrNhH zjI-}m$;G5ow+mM39f+6{5_i&I+f;jR!9_jk|G)45ZyUGb?V@hIQ`_CI?*63Nku7yc z``yA_=VyHj{<-6n=)Zlx-|haWrGM=68N=f;OTG7hyOsS@WS`)#JGI~Mdf!%7xVbuf zeU0tC^R?gaZr`##qT@rt9)4HXV=Htb?evZo+Tkq{^gu;|>T38cnT=B1Q`i~AqcRq5 zxt+Irsbty=MgGmMs@qmDSR@>1*t4HwscXb)n~w0hg-UzGZm-+*YSkX2=#BgL?27Xd zjb?e<_4jD{(^vU|72T_v<7>Z$-b$OD+jUs0KD|`E$BJa#yS8s&xOo}f2)56pssPpH? zCl_{;8Y-tv2u z>9dN@S$1EQs=a2y@Z*xV{?Zi|;agTjS$w}!{Cp~RvgNH$r}gK94v2a*;iKK@!^KbE z6`s3Wen0l%4-TfblS1A)hH>v|=#)#5#B+PU-CAw( zHQz_M_V?TE&wqCdq^u5G>vcQnIJf?ufK@9bUZ1!7os)HGiKkBA^;6nr$Id;UU%&6r zluM82CNN_y#~^vG(NjZ#!GhDU)D>K~aR?{`m^Xq-sq6Rae(TDXUJ2A}%6IMds?=V; zr)cA>`Y>?@&<@VauU4;*v-&n8xo_pRt^}EoI{)aLjjmRIJ{g2TM#OJ1+rt#@C1Di7%LfSR3V^;uF3JqpPzQr%)#c^0oqyz^Xp{hmqrpd(m= zeY&G#yESW+mq_R~bsa78nJazyq1aW%)93pigAV7cS#|s6^7;E}!e>b_9yoPf=U(Tc zuKV9^=g;p?^_d*AWznK|L*7sKs^8BoyIXoaseISlZMTC$@_Woq>ug@KVpT+J^}C(V zFKs+77kx{%@xZsYx2Ipzg_ko}7&GQDF*QsM4!;jiW2QnH{I^5-u1+lv*lBb-EIM~8 zpY4|mpPYkA84t|ZX13~vsBTlC;DpudriOFh$ynU$rMN!vaNAN)Q{?aW{r}JU_r7-D zU~nkKRUil4kTC*v14{3P@7}wN@c^iU;A*fjBak(}nb*w2`ppLC%w117_R7|Nxp-9Z zacx}H%cUzCPX~VEK05qQR&&2Y;|wf zmRW2J+Tjd6U8RDjy0tp>_x(t!dnspIwPf>oyWO{LcVtx-?#(F73;eq7Pm4kQqfYft zS`|m9oH+XL6yuqdq6|GB;sakA9Gc#5^T|W5CFk0jNVyN)zjfDN5kGG8<3Y3LDrV3T zwRcM{`yN$(IzN!paFw!{u2bFBt;gl-ZRQr8(p-Ai-|lBhYd}h7JKpB)WJd>v0;2`5 zCc&Bq3(A;Gc^SUFyKBvVU3BktH3o_2Z?@mB19e+}zO;V3C3s)lm(YKbjQc~wW4CU3 zxn#1R*XuQ#{W5J=?Q#9OXI<>>Wox(Jv+^~+Tax)~X8Jkpf38P&*k8_)VyJn$_4*~n zcA21ER~Gl%&5GKZHPzoy=IZ-JzBy8lR!j-^S-I!uv)Rj)`z(}rWh@NtZ+qA#{p_!( zc!%bc#Zn0^EWf|MpP#=j#zddi82H zJV4w)0pfOa?~Jl-8HTLy9=6NJt$8;8YA8d`+`_!Tt@_KJ_r8o@o%Q$ESMTb#Tf;N2 z@BjC8y~+DMpP#)B6g61I?54fy-Baz!FZ_L(8w|JR{^<{sv(aAPCjNWT{<62XjwZF5 zWnEcOv+IeHfOs&gyMvxnoghn(S5so-PS79+=$y5e?ecXe%0Z_Lf;vH`rfah^ytb0f zi~ZH9IbnX~vzc7mtMAu-UkWM-w#}{o_w(hw>i4>9k2{5a|8ckc{!$JXG0O{Z?@jPACEqsleH{L z0oA!)2RB+(~Vv>BWWAQ(WmU!9{E=?6r5C@?lV2M>}ExJznrZVzoMAp zo=;q@54XHtw|klX{y#?c`iE+sCT?4_`O|`gJM}CNlTO`PbSf$2`|iKrZfl1y>YUS^ zp9Web>gzkp*dhK6dIv?zBJJrwT zah1KB=!r$8FE6F;d0F3G3p!Q3s~~yH)@xC#51H&gY6v>=wo4%EqEdj=!JuAP&|oQK z4ondeV3-qhX&rpHBVg$PfBU~v%g2x`wU~JS%#*CKC5lg&diXCzOrpT zsJ8gDQIFqM?7Q4|fnX-_hbK6g!_21%uIowe=ITtJSDDtDxiH!5Ndc%a{rTPMRc?_n z*VVCQNNAm3zPDvv1YY zso|%}pB`NE_xpW&U;DpbetugaAujr05okDJZuB^hf+EyYd&&h1)OtS?jLdaER+?;nVs@cewR-EI9RB&t7lZVxicUA6?aJ z_w4^v^^_suP5;Y|@aWvFpwW;$TCqO4(z;p#$2L##FP{DW#J@Xbw{w4r9Nj1v%;LU4 z&qw)-IOA!hCFKVg*`LgFo$%@J_xt|U?{=nN^nE9!cub-jbmiCnx)zqjP7ip^?-<hWQxxizWn)o{`?n(g$^N? zyBY2$b?Z(uyPdQ7qf>e_8}F&*N7k;}ylUCO-i8R4&s_!KKX(e=vi|jA@$ub$GQx>R zIi&1`u-4#EYoOx#q6Hh%&(9NGb$M$1>Q6pg3r1e5`1c7cDg<=Jd`WQrIRnn)3f2huGi~kANqRM{Jzfp zx%&B_@woi@-_dq@Q_I~-_i_Y=@g=!M6i$yVlUzS5@#*L8ue-hk`!Mf0sW$t`t+ip;@oLrTXQ3SId@?ik{d%?9B?{C(pVQKeXE>gPhW=f@BZI|6IU;g)wU$g$ zPV%W2673%@KpNTDL&V3Ik@3LFmG5ssvneCfS1*NSk9t?tUtCmmk4-u!;O*bzCOdz> z-5$TM{^`{4bE|p7sta!Ronky-eBNer&U#mTbr1{3A4LU*AMLHG2vt|Pj)?5fUbizX z^S?8{?UY;Fa-*Zx?-98C{@u>!^L{?F{dPn7=>J(Jj0a|EShnFQpcxtk1Q@=^A==9; z79QAkJ8!mswsiaa;&YaoTE9cDgZerp-|v<`-@SgvqpmGK9(9M8XSBZkey=*;>i?h5 zpL6f-F4xx$w>SYG)x~b35hJ6+dPaB$MoZ z2og{T;NV~o6GG~f`?x&Ve!tG!{9Z-!uD{=IU;gm$u(!LrM8UI}>3X5;J+j=oTLM65 zrC*lHUK41Q=ftf(zow|_`P_1?FM%@l&*u~`>ovb;0Xo^}s2XgX9_}?%MgZdlYedU? z!8WGF?)`rG`+lZX{eHXs@&rZaOXuzX&xzWSF)?j+?zTVwL1iy!q%5km`d;PprHO~z zLaWam;?|$D?S9?wtnarSVTC`!P=tuXW8nbC4Ig`Vs;gm>#u77)YzhhtHyGG1DkG8s ztS^9F#Nn~907Fhq^1DuaV;snO7cg>gFqkzse&K*;5dw@0KUi28r0>tDPC}%5{8};? zn3x)P69jCTP=g=0Urg*684nyYe>QIhmSDkZh*Se;l1Rd(pUALfWa{;IU>J=K{FxIP zn4{4#nmdpS4Md@a$eyEx)o5XbwPZ#vVMgnY(W)F;r{FG6MyvACmKAcLfi1z%u%T=4 zlI2*>U){e(X*pYE{p@4CbZ42ZEc?G@Q}UPf$(LWm*L(ZU_L=^7eqGegwQQyG%A3EZ za+>H8+cy|lN;-S}kA%U`k6R-2zMIT$RzELi^K^lLFIoOh+a zpZe--t^aHDTdyx4%shNL?nHj^hn=&p{VY#>@*@88hddVVXuqQyKIZTLJI$>}VxqnO z>1n!~pU-5gf3fU>x8bYl@t4*oA6ug4J8Q|av$OpduHNO7%j(uAGqZKm@nvaeXDydZ z%dk<5VLWhapJtyrwx~mHGUyikTKsmiT{G*}mMbg_>i;vYTxWRj`0qZ??|TdlbdB6+mvp?E zF!_z^&nLSRU(QiK7RtZ3s6F-7o%IX}b6=|6?qq71+*>xOOoze3)3VeJTayd9x_!0W zL6D&*vyOevzQC>gAK$d!UwU?ZmFE5W7g5~Hgw0+>z1Mwa=u^(2?cUvaryWGEcTkgzju_@cOI4v)GEGsYF)+007|MTtV-SU@@-{f7lVCh@x^FNb-bpSx?z{FSGwWj-A4_)=8% zCOZD#lzq}xTDoTGx8Kyy-r_a=TV~r!Z7ZA454UUf#TWi7%RI=p_ELLuTVM6QGan}9 zPS^VS-|gF;|EHJT>pg!nYP*N6)%jV!x1D`g>b1>Ym|;z?_eY<=TBCWtx1MKP&cEr^ z*S0)~F@FBo{MGf1nXBK#&e<3_`Oy?D`}1;(^^Y=QLuT!6Sot@PAJ=^)djdxY5kMl(( zH(pw}wYHos_5R&(}K!VzNhxX*$E}}Wq+36=l9;9_T94j+daMMf7OnBUuDqya>?)1<9C1l z68~Af|4B^l<$1Qx&hNgNHgjii_nY70TW0;+_vLq$N7dWU@I>q(2XBH9-qI&-~O*jz51@wXp^t+?y7%%f8W0L>(%R-=XO5xiQQG=cXwB* z_u1K|s~^3Y@~TKazUHHA)z0hMFK6fPJ9+NE?$+GfYPx$aIQ^_PJIrJJ+hYi@87T4Ca2FBPhU1IHg{`i@aC*{%Rl+<`+o2D%g6r5Y?HspzOVZ(8s<@a z-ZuQH^XIQKj(wY3e$RJ)8e4oiTXD%8<+Jx!2B&Svn3cJ#YyZ~!JW^AB?YnAzcFx`C z8h5)N4-S91SN(qJzxlQEp3SJ;_GkCD8%fz-240L`IgJQ>zDnz&%b_yZP>NAifuM4u3K|E&Yd#1{DaG~O4%QeJGR`&^nddA z&PMm|TmF7s-*f%>JMGd_%^}k9|B|MjFFhSU-G8>uwT*`=&G&waw0g46TsucQOo^f5 zYv1W5eYw#hvoF2dzGvFI>d&W3?oIQ4V%PrfcYkrcMgCT|kZ zdzya5tHUL)l>cs0h;A?OH>)k(GDE21e02Qz=9$uEvu$O||63n@xb!^7lDpgApUQkD z#iqOe_rKpIFYWcc1vOT!%H8=?Ec0&ZHNCg5?*HFh^3C%3vX{%}+s!ThHuL3?$$p-K zEnVAAs!1>JHNUl?BsWnZ<$|9^W5en`DswA|k7|2t#73sUb>_RKD=ET4CdX-{@qFRsLANirL;Wwb|r!&*MY+TYuK>e7E%9%Z}=Mr<}V2SC)L` zp08W_|INbH%T+fSuD!#?Co{v(`tO-jvp;_o-Cgd#`|URGeKEH`uHAI_zWKef+izdC zipQU6E)<-w?$zAP>v_{kUMy_y5f@v1x>n@+>R0okw&l$9dr=u9w_^8?N%d)oy9zH` zh1;3kyLfGFbojlPL|dmd;jy*8TWei9a?jhAoxeBrrPuSXr=8Y^$JXXbnP!D#MsE~& zc%%0FO>5mvCk`E5_T|rK{U!Bx>)dB0_uc&LaJPQ`&*Yx&=CV79zfFQy&%9)MJtjOy ztM=IUwa-5ufBO9RG0(g4g$tL@|Chh(_5E`3)uMLWPt|c>)BLT=vDy4yh4I>bx3VH% zyzjO#h|LcCn%>VyiPriTsGW+^z)8?hee0Z~W&7*5x&;Od=-{%l^H1GPm z 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 literal 0 HcmV?d00001 diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..7447b5d --- /dev/null +++ b/package-lock.json @@ -0,0 +1,12 @@ +{ + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "prettier": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", + "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", + "dev": true + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..67aa861 --- /dev/null +++ b/package.json @@ -0,0 +1,5 @@ +{ + "devDependencies": { + "prettier": "^1.19.1" + } +} diff --git a/prettier.config.js b/prettier.config.js new file mode 100644 index 0000000..181b27c --- /dev/null +++ b/prettier.config.js @@ -0,0 +1,18 @@ +module.exports = { + arrowParens: 'avoid', + bracketSpacing: false, + endOfLine: 'lf', + htmlWhitespaceSensitivity: 'css', + insertPragma: false, + jsxBracketSameLine: false, + jsxSingleQuote: false, + printWidth: 80, + proseWrap: 'always', + quoteProps: 'as-needed', + requirePragma: false, + semi: false, + singleQuote: true, + tabWidth: 2, + trailingComma: 'all', + useTabs: false, +} diff --git a/step1-first-test/my_module.info.yml b/step1-first-test/my_module.info.yml new file mode 100644 index 0000000..21d262e --- /dev/null +++ b/step1-first-test/my_module.info.yml @@ -0,0 +1,5 @@ +name: My Module +type: module +core: 8.x +core_version_requirement: ^8 || ^9 +package: Custom diff --git a/step1-first-test/tests/src/Functional/MyModuleTest.php b/step1-first-test/tests/src/Functional/MyModuleTest.php new file mode 100644 index 0000000..cb34eb7 --- /dev/null +++ b/step1-first-test/tests/src/Functional/MyModuleTest.php @@ -0,0 +1,19 @@ +drupalGet(''); + + $this->assertResponse(Response::HTTP_OK); + } + +} diff --git a/step2-adding-more-test-methods/my_module.info.yml b/step2-adding-more-test-methods/my_module.info.yml new file mode 100644 index 0000000..21d262e --- /dev/null +++ b/step2-adding-more-test-methods/my_module.info.yml @@ -0,0 +1,5 @@ +name: My Module +type: module +core: 8.x +core_version_requirement: ^8 || ^9 +package: Custom diff --git a/step2-adding-more-test-methods/tests/src/Functional/MyModuleTest.php b/step2-adding-more-test-methods/tests/src/Functional/MyModuleTest.php new file mode 100644 index 0000000..7f2924e --- /dev/null +++ b/step2-adding-more-test-methods/tests/src/Functional/MyModuleTest.php @@ -0,0 +1,39 @@ +drupalGet(''); + + $this->assertResponse(Response::HTTP_OK); + } + + /** @test */ + public function the_admin_page_is_not_accessible_to_anonymous_users() { + $this->drupalGet('admin'); + + $this->assertResponse(Response::HTTP_FORBIDDEN); + } + + /** @test */ + public function the_admin_page_is_accessible_by_admin_users() { + $adminUser = $this->createUser([ + 'access administration pages', + ]); + + $this->drupalLogin($adminUser); + + $this->drupalGet('/admin'); + + $this->assertResponse(Response::HTTP_OK); + } + +} diff --git a/step3-building-a-blog-page/my_module.info.yml b/step3-building-a-blog-page/my_module.info.yml new file mode 100644 index 0000000..21d262e --- /dev/null +++ b/step3-building-a-blog-page/my_module.info.yml @@ -0,0 +1,5 @@ +name: My Module +type: module +core: 8.x +core_version_requirement: ^8 || ^9 +package: Custom diff --git a/step3-building-a-blog-page/my_module.routing.yml b/step3-building-a-blog-page/my_module.routing.yml new file mode 100644 index 0000000..9683277 --- /dev/null +++ b/step3-building-a-blog-page/my_module.routing.yml @@ -0,0 +1,7 @@ +blog.page: + path: /blog + defaults: + _controller: Drupal\my_module\Controller\BlogPageController + _title: Blog + requirements: + _permission: access content diff --git a/step3-building-a-blog-page/src/Controller/BlogPageController.php b/step3-building-a-blog-page/src/Controller/BlogPageController.php new file mode 100644 index 0000000..1f1378e --- /dev/null +++ b/step3-building-a-blog-page/src/Controller/BlogPageController.php @@ -0,0 +1,17 @@ + $this->t('Welcome to my blog!'), + ]; + } + +} diff --git a/step3-building-a-blog-page/tests/src/Functional/BlogPageTest.php b/step3-building-a-blog-page/tests/src/Functional/BlogPageTest.php new file mode 100644 index 0000000..1798947 --- /dev/null +++ b/step3-building-a-blog-page/tests/src/Functional/BlogPageTest.php @@ -0,0 +1,28 @@ +drupalGet('/blog'); + + $session = $this->assertSession(); + + $session->statusCodeEquals(Response::HTTP_OK); + $session->responseContains('

Blog

'); + $session->pageTextContains('Welcome to my blog!'); + } + +} diff --git a/step3-building-a-blog-page/tests/src/Functional/MyModuleTest.php b/step3-building-a-blog-page/tests/src/Functional/MyModuleTest.php new file mode 100644 index 0000000..cb34eb7 --- /dev/null +++ b/step3-building-a-blog-page/tests/src/Functional/MyModuleTest.php @@ -0,0 +1,19 @@ +drupalGet(''); + + $this->assertResponse(Response::HTTP_OK); + } + +} diff --git a/step4-adding-the-blog-repository/my_module.info.yml b/step4-adding-the-blog-repository/my_module.info.yml new file mode 100644 index 0000000..21d262e --- /dev/null +++ b/step4-adding-the-blog-repository/my_module.info.yml @@ -0,0 +1,5 @@ +name: My Module +type: module +core: 8.x +core_version_requirement: ^8 || ^9 +package: Custom diff --git a/step4-adding-the-blog-repository/my_module.routing.yml b/step4-adding-the-blog-repository/my_module.routing.yml new file mode 100644 index 0000000..9683277 --- /dev/null +++ b/step4-adding-the-blog-repository/my_module.routing.yml @@ -0,0 +1,7 @@ +blog.page: + path: /blog + defaults: + _controller: Drupal\my_module\Controller\BlogPageController + _title: Blog + requirements: + _permission: access content diff --git a/step4-adding-the-blog-repository/my_module.services.yml b/step4-adding-the-blog-repository/my_module.services.yml new file mode 100644 index 0000000..a97d210 --- /dev/null +++ b/step4-adding-the-blog-repository/my_module.services.yml @@ -0,0 +1,6 @@ +services: + Drupal\my_module\Controller\BlogPageController: + autowire: true + + Drupal\my_module\Repository\ArticleRepository: + autowire: true diff --git a/step4-adding-the-blog-repository/src/Controller/BlogPageController.php b/step4-adding-the-blog-repository/src/Controller/BlogPageController.php new file mode 100644 index 0000000..05e7fa3 --- /dev/null +++ b/step4-adding-the-blog-repository/src/Controller/BlogPageController.php @@ -0,0 +1,45 @@ +nodeViewBuilder = $entityTypeManager->getViewBuilder('node'); + $this->articleRepository = $articleRepository; + } + + public function __invoke(): array { + $build = []; + + $articles = $this->articleRepository->getAll(); + + foreach ($articles as $article) { + $build[] = $this->nodeViewBuilder->view($article, 'teaser'); + } + + return [ + '#markup' => render($build), + ]; + } + +} diff --git a/step4-adding-the-blog-repository/src/Repository/ArticleRepository.php b/step4-adding-the-blog-repository/src/Repository/ArticleRepository.php new file mode 100644 index 0000000..aee9127 --- /dev/null +++ b/step4-adding-the-blog-repository/src/Repository/ArticleRepository.php @@ -0,0 +1,33 @@ +nodeStorage = $entityTypeManager->getStorage('node'); + } + + public function getAll(): array { + $articles = $this->nodeStorage->loadByProperties([ + 'status' => Node::PUBLISHED, + 'type' => 'article', + ]); + + uasort($articles, function (NodeInterface $a, NodeInterface $b): bool { + return $a->getCreatedTime() < $b->getCreatedTime(); + }); + + return $articles; + } + +} diff --git a/step4-adding-the-blog-repository/tests/src/Functional/BlogPageTest.php b/step4-adding-the-blog-repository/tests/src/Functional/BlogPageTest.php new file mode 100644 index 0000000..1827604 --- /dev/null +++ b/step4-adding-the-blog-repository/tests/src/Functional/BlogPageTest.php @@ -0,0 +1,27 @@ +drupalGet('/blog'); + + $session = $this->assertSession(); + + $session->statusCodeEquals(Response::HTTP_OK); + $session->responseContains('

Blog

'); + } + +} diff --git a/step4-adding-the-blog-repository/tests/src/Functional/MyModuleTest.php b/step4-adding-the-blog-repository/tests/src/Functional/MyModuleTest.php new file mode 100644 index 0000000..cb34eb7 --- /dev/null +++ b/step4-adding-the-blog-repository/tests/src/Functional/MyModuleTest.php @@ -0,0 +1,19 @@ +drupalGet(''); + + $this->assertResponse(Response::HTTP_OK); + } + +} diff --git a/step4-adding-the-blog-repository/tests/src/Kernel/ArticleRepositoryTest.php b/step4-adding-the-blog-repository/tests/src/Kernel/ArticleRepositoryTest.php new file mode 100644 index 0000000..60d6d46 --- /dev/null +++ b/step4-adding-the-blog-repository/tests/src/Kernel/ArticleRepositoryTest.php @@ -0,0 +1,75 @@ +installSchema('node', ['node_access']); + + $this->installConfig([ + 'filter', + ]); + } + + /** @test */ + public function nodes_that_are_not_articles_are_not_returned() { + $this->createNode(['type' => 'article'])->save(); + $this->createNode(['type' => 'page'])->save(); + $this->createNode(['type' => 'article'])->save(); + $this->createNode(['type' => 'page'])->save(); + $this->createNode(['type' => 'article'])->save(); + + $this->assertCount(5, Node::loadMultiple()); + + $repository = $this->container->get(ArticleRepository::class); + $articles = $repository->getAll(); + + $this->assertCount(3, $articles); + } + + /** @test */ + public function only_published_articles_are_returned() { + $this->createNode(['type' => 'article', 'status' => Node::PUBLISHED])->save(); + $this->createNode(['type' => 'article', 'status' => Node::NOT_PUBLISHED])->save(); + $this->createNode(['type' => 'article', 'status' => Node::PUBLISHED])->save(); + $this->createNode(['type' => 'article', 'status' => Node::NOT_PUBLISHED])->save(); + $this->createNode(['type' => 'article', 'status' => Node::PUBLISHED])->save(); + + $repository = $this->container->get(ArticleRepository::class); + $articles = $repository->getAll(); + + $this->assertCount(3, $articles); + } + + /** @test */ + public function nodes_are_ordered_by_date_and_returned_newest_first() { + $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-2 days'))->getTimestamp()]); + $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-1 week'))->getTimestamp()]); + $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-1 hour'))->getTimestamp()]); + $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-1 year'))->getTimestamp()]); + $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-1 month'))->getTimestamp()]); + + $repository = $this->container->get(ArticleRepository::class); + $nodes = $repository->getAll(); + $nodeIds = array_keys($nodes); + + $this->assertSame([3, 1, 2, 5, 4], $nodeIds); + } + +} diff --git a/step5-wrapping-up-with-unit-tests/my_module.info.yml b/step5-wrapping-up-with-unit-tests/my_module.info.yml new file mode 100644 index 0000000..21d262e --- /dev/null +++ b/step5-wrapping-up-with-unit-tests/my_module.info.yml @@ -0,0 +1,5 @@ +name: My Module +type: module +core: 8.x +core_version_requirement: ^8 || ^9 +package: Custom diff --git a/step5-wrapping-up-with-unit-tests/my_module.routing.yml b/step5-wrapping-up-with-unit-tests/my_module.routing.yml new file mode 100644 index 0000000..9683277 --- /dev/null +++ b/step5-wrapping-up-with-unit-tests/my_module.routing.yml @@ -0,0 +1,7 @@ +blog.page: + path: /blog + defaults: + _controller: Drupal\my_module\Controller\BlogPageController + _title: Blog + requirements: + _permission: access content diff --git a/step5-wrapping-up-with-unit-tests/my_module.services.yml b/step5-wrapping-up-with-unit-tests/my_module.services.yml new file mode 100644 index 0000000..a97d210 --- /dev/null +++ b/step5-wrapping-up-with-unit-tests/my_module.services.yml @@ -0,0 +1,6 @@ +services: + Drupal\my_module\Controller\BlogPageController: + autowire: true + + Drupal\my_module\Repository\ArticleRepository: + autowire: true diff --git a/step5-wrapping-up-with-unit-tests/src/Controller/BlogPageController.php b/step5-wrapping-up-with-unit-tests/src/Controller/BlogPageController.php new file mode 100644 index 0000000..05e7fa3 --- /dev/null +++ b/step5-wrapping-up-with-unit-tests/src/Controller/BlogPageController.php @@ -0,0 +1,45 @@ +nodeViewBuilder = $entityTypeManager->getViewBuilder('node'); + $this->articleRepository = $articleRepository; + } + + public function __invoke(): array { + $build = []; + + $articles = $this->articleRepository->getAll(); + + foreach ($articles as $article) { + $build[] = $this->nodeViewBuilder->view($article, 'teaser'); + } + + return [ + '#markup' => render($build), + ]; + } + +} diff --git a/step5-wrapping-up-with-unit-tests/src/Repository/ArticleRepository.php b/step5-wrapping-up-with-unit-tests/src/Repository/ArticleRepository.php new file mode 100644 index 0000000..aee9127 --- /dev/null +++ b/step5-wrapping-up-with-unit-tests/src/Repository/ArticleRepository.php @@ -0,0 +1,33 @@ +nodeStorage = $entityTypeManager->getStorage('node'); + } + + public function getAll(): array { + $articles = $this->nodeStorage->loadByProperties([ + 'status' => Node::PUBLISHED, + 'type' => 'article', + ]); + + uasort($articles, function (NodeInterface $a, NodeInterface $b): bool { + return $a->getCreatedTime() < $b->getCreatedTime(); + }); + + return $articles; + } + +} diff --git a/step5-wrapping-up-with-unit-tests/src/Wrapper/ArticleWrapper.php b/step5-wrapping-up-with-unit-tests/src/Wrapper/ArticleWrapper.php new file mode 100644 index 0000000..fc6d516 --- /dev/null +++ b/step5-wrapping-up-with-unit-tests/src/Wrapper/ArticleWrapper.php @@ -0,0 +1,40 @@ +verifyNodeType($node); + + $this->time = $time; + $this->article = $node; + } + + public function getOriginal(): NodeInterface { + return $this->article; + } + + private function verifyNodeType(NodeInterface $node): void { + if ($node->bundle() != 'article') { + throw new \InvalidArgumentException(sprintf( + '%s is not an article', + $node->bundle() + )); + } + } + + public function isPublishable(): bool { + $created = $this->article->getCreatedTime(); + + $difference = $this->time->getRequestTime() - $created; + + return $difference >= 60 * 60 * 24 * 3; + } + +} diff --git a/step5-wrapping-up-with-unit-tests/tests/src/Functional/BlogPageTest.php b/step5-wrapping-up-with-unit-tests/tests/src/Functional/BlogPageTest.php new file mode 100644 index 0000000..1827604 --- /dev/null +++ b/step5-wrapping-up-with-unit-tests/tests/src/Functional/BlogPageTest.php @@ -0,0 +1,27 @@ +drupalGet('/blog'); + + $session = $this->assertSession(); + + $session->statusCodeEquals(Response::HTTP_OK); + $session->responseContains('

Blog

'); + } + +} diff --git a/step5-wrapping-up-with-unit-tests/tests/src/Functional/MyModuleTest.php b/step5-wrapping-up-with-unit-tests/tests/src/Functional/MyModuleTest.php new file mode 100644 index 0000000..cb34eb7 --- /dev/null +++ b/step5-wrapping-up-with-unit-tests/tests/src/Functional/MyModuleTest.php @@ -0,0 +1,19 @@ +drupalGet(''); + + $this->assertResponse(Response::HTTP_OK); + } + +} diff --git a/step5-wrapping-up-with-unit-tests/tests/src/Kernel/ArticleRepositoryTest.php b/step5-wrapping-up-with-unit-tests/tests/src/Kernel/ArticleRepositoryTest.php new file mode 100644 index 0000000..60d6d46 --- /dev/null +++ b/step5-wrapping-up-with-unit-tests/tests/src/Kernel/ArticleRepositoryTest.php @@ -0,0 +1,75 @@ +installSchema('node', ['node_access']); + + $this->installConfig([ + 'filter', + ]); + } + + /** @test */ + public function nodes_that_are_not_articles_are_not_returned() { + $this->createNode(['type' => 'article'])->save(); + $this->createNode(['type' => 'page'])->save(); + $this->createNode(['type' => 'article'])->save(); + $this->createNode(['type' => 'page'])->save(); + $this->createNode(['type' => 'article'])->save(); + + $this->assertCount(5, Node::loadMultiple()); + + $repository = $this->container->get(ArticleRepository::class); + $articles = $repository->getAll(); + + $this->assertCount(3, $articles); + } + + /** @test */ + public function only_published_articles_are_returned() { + $this->createNode(['type' => 'article', 'status' => Node::PUBLISHED])->save(); + $this->createNode(['type' => 'article', 'status' => Node::NOT_PUBLISHED])->save(); + $this->createNode(['type' => 'article', 'status' => Node::PUBLISHED])->save(); + $this->createNode(['type' => 'article', 'status' => Node::NOT_PUBLISHED])->save(); + $this->createNode(['type' => 'article', 'status' => Node::PUBLISHED])->save(); + + $repository = $this->container->get(ArticleRepository::class); + $articles = $repository->getAll(); + + $this->assertCount(3, $articles); + } + + /** @test */ + public function nodes_are_ordered_by_date_and_returned_newest_first() { + $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-2 days'))->getTimestamp()]); + $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-1 week'))->getTimestamp()]); + $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-1 hour'))->getTimestamp()]); + $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-1 year'))->getTimestamp()]); + $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-1 month'))->getTimestamp()]); + + $repository = $this->container->get(ArticleRepository::class); + $nodes = $repository->getAll(); + $nodeIds = array_keys($nodes); + + $this->assertSame([3, 1, 2, 5, 4], $nodeIds); + } + +} diff --git a/step5-wrapping-up-with-unit-tests/tests/src/Unit/Wrapper/ArticleWrapperTest.php b/step5-wrapping-up-with-unit-tests/tests/src/Unit/Wrapper/ArticleWrapperTest.php new file mode 100644 index 0000000..8a6537f --- /dev/null +++ b/step5-wrapping-up-with-unit-tests/tests/src/Unit/Wrapper/ArticleWrapperTest.php @@ -0,0 +1,73 @@ +time = $this->createMock(TimeInterface::class); + } + + /** @test */ + public function it_returns_the_article() { + $article = $this->createMock(NodeInterface::class); + $article->method('id')->willReturn(5); + $article->method('bundle')->willReturn('article'); + + $articleWrapper = new ArticleWrapper($this->time, $article); + + $this->assertInstanceOf(NodeInterface::class, $articleWrapper->getOriginal()); + $this->assertSame(5, $articleWrapper->getOriginal()->id()); + $this->assertSame('article', $articleWrapper->getOriginal()->bundle()); + } + + /** @test */ + public function it_throws_an_exception_if_the_node_is_not_an_article() { + $this->expectException(\InvalidArgumentException::class); + + $page = $this->createMock(NodeInterface::class); + $page->method('bundle')->willReturn('page'); + + new ArticleWrapper($this->time, $page); + } + + /** + * @test + * @dataProvider articleCreatedDateProvider + */ + public function articles_created_less_than_3_days_ago_are_not_publishable( + string $offset, + bool $expected + ) { + $this->time->method('getRequestTime')->willReturn( + (new \DateTime())->getTimestamp() + ); + + $article = $this->createMock(NodeInterface::class); + $article->method('bundle')->willReturn('article'); + + $article->method('getCreatedTime')->willReturn( + (new \DateTime())->modify($offset)->getTimestamp() + ); + + $articleWrapper = new ArticleWrapper($this->time, $article); + + $this->assertSame($expected, $articleWrapper->isPublishable()); + } + + public function articleCreatedDateProvider() { + return [ + ['-1 day', FALSE], + ['-2 days 59 minutes', FALSE], + ['-3 days', TRUE], + ['-1 week', TRUE], + ]; + } +} From c39e2a97893994ca95f0a7e8a631480f5e22dd23 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Fri, 13 Mar 2020 16:57:49 +0000 Subject: [PATCH 02/77] Add feedback and contribution links --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index b1169f7..28f0e87 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,14 @@ - [5b. Ensure that we’re only wrapping articles](#5b-ensure-that-were-only-wrapping-articles) - [5c. Determine if articles are publishable](#5c-determine-if-articles-are-publishable) +## Contribution + +Please feel free to create issue and/or submit pull requests to this repository whilst working through these instructions. Any contributions would be greatly appreciated! + +## Feedback + +Feedback would also be appreciated! You can contact me via , [@opdavies on Twitter](https://twitter.com/opdavies) or `opdavies` on Drupal Slack. + ## Introduction ## Creating a new Drupal project with Composer From 2b7874e280da9181d0dc075745d0a19d428b5bdc Mon Sep 17 00:00:00 2001 From: Oliver Davies <339813+opdavies@users.noreply.github.com> Date: Fri, 13 Mar 2020 16:58:30 +0000 Subject: [PATCH 03/77] Run prettier --- README.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 28f0e87..8a3b919 100644 --- a/README.md +++ b/README.md @@ -47,11 +47,16 @@ ## Contribution -Please feel free to create issue and/or submit pull requests to this repository whilst working through these instructions. Any contributions would be greatly appreciated! +Please feel free to create issue and/or submit pull requests to this repository +whilst working through these instructions. Any contributions would be greatly +appreciated! ## Feedback -Feedback would also be appreciated! You can contact me via , [@opdavies on Twitter](https://twitter.com/opdavies) or `opdavies` on Drupal Slack. +Feedback would also be appreciated! You can contact me via +, +[@opdavies on Twitter](https://twitter.com/opdavies) or `opdavies` on Drupal +Slack. ## Introduction From 54d4e2d87e5322eb3405bc09ab56711f9d531c44 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Fri, 13 Mar 2020 17:01:23 +0000 Subject: [PATCH 04/77] Add contribution and feedback titles --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 8a3b919..65d47ed 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,8 @@ ## Table of Contents - [Introduction](#introduction) +- [Contribution](#contribution) +- [Feedback](#feedback) - [Creating a new Drupal project with Composer](#creating-a-new-drupal-project-with-composer) - [Using the Symfony web server for local development](#using-the-symfony-web-server-for-local-development) - [The different types of available tests](#the-different-types-of-available-tests) From 44b7fb98424d697a6815767d1f87f8891eb3091e Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Sat, 14 Mar 2020 00:25:20 +0000 Subject: [PATCH 05/77] Add missing use statement Fixes #2 Co-authored-by: Andy Broomfield --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 65d47ed..3d1faea 100644 --- a/README.md +++ b/README.md @@ -718,6 +718,8 @@ injecting the `EntityTypeManager` and using it to return nodes from the `getAll()` method rather than the empty array. ```diff ++ use Drupal\Core\Entity\EntityTypeManagerInterface; ++ + /** + * @var \Drupal\Core\Entity\EntityStorageInterface + */ From 714644a18c5cf23ae383631b9c999d0b983b77b5 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Wed, 18 Mar 2020 12:24:51 +0000 Subject: [PATCH 06/77] Remove the GitHub Action job --- .github/workflows/lint.yml | 29 ----------------------------- 1 file changed, 29 deletions(-) delete mode 100644 .github/workflows/lint.yml diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml deleted file mode 100644 index ac78494..0000000 --- a/.github/workflows/lint.yml +++ /dev/null @@ -1,29 +0,0 @@ -name: Lint README.md - -on: - push: - -jobs: - lint: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@master - - - name: Run prettier - run: | - npm install - npx prettier README.md --write - - - name: Commit changes - run: | - if [ -n "$(git status --short README.md)" ]; then - git config --local user.name "Oliver Davies" - git config --local user.email "339813+opdavies@users.noreply.github.com" - git commit -a -m "Run prettier" - fi - - - name: Push changes - uses: ad-m/github-push-action@master - with: - github_token: ${{ secrets.GITHUB_TOKEN }} From 04a19ec0fabb70e4f3241903c80d87c2a48d55d4 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Wed, 18 Mar 2020 12:25:04 +0000 Subject: [PATCH 07/77] Re-format paragraph text --- README.md | 362 ++++++++++++++++-------------------------------------- 1 file changed, 107 insertions(+), 255 deletions(-) diff --git a/README.md b/README.md index 3d1faea..7411a4a 100644 --- a/README.md +++ b/README.md @@ -49,27 +49,19 @@ ## Contribution -Please feel free to create issue and/or submit pull requests to this repository -whilst working through these instructions. Any contributions would be greatly -appreciated! +Please feel free to create issue and/or submit pull requests to this repository whilst working through these instructions. Any contributions would be greatly appreciated! ## Feedback -Feedback would also be appreciated! You can contact me via -, -[@opdavies on Twitter](https://twitter.com/opdavies) or `opdavies` on Drupal -Slack. +Feedback would also be appreciated! You can contact me via , [@opdavies on Twitter](https://twitter.com/opdavies) or `opdavies` on Drupal Slack. ## Introduction ## Creating a new Drupal project with Composer -If don’t have Composer, visit for -instructions on how to install it on your computer. +If don’t have Composer, visit for instructions on how to install it on your computer. -This assumes that Composer is installed globally and is available by running the -`composer` command. Alternatively, you can download the phar file and run -`php composer.phar` instead. +This assumes that Composer is installed globally and is available by running the `composer` command. Alternatively, you can download the phar file and run `php composer.phar` instead. ```bash # Create a new Drupal project @@ -81,12 +73,9 @@ cd my-project composer require --dev drupal/core-dev ``` -You should now have files present including `web/index.php` and -`vendor/bin/phpunit`. Now you can start serving this site locally. +You should now have files present including `web/index.php` and `vendor/bin/phpunit`. Now you can start serving this site locally. -**Note:** Development dependencies, including PHPUnit, should only be installed -locally and should not be present on public servers. Doing so would present a -security risk to your application. +**Note:** Development dependencies, including PHPUnit, should only be installed locally and should not be present on public servers. Doing so would present a security risk to your application. ## Using the Symfony web server for local development @@ -96,28 +85,21 @@ https://symfony.com/doc/current/setup/symfony_server.html - Download from . - Docker provides the integration with MySQL. - Faster performance compared to mounting files within Docker volumes. -- Need `docker-compose.yml` to provide the database service, `.php-version` to - set the version of PHP +- Need `docker-compose.yml` to provide the database service, `.php-version` to set the version of PHP - - - blog post ## The different types of available tests -- **Functional** (web, feature) - tests behaviour and functionality, makes HTTP - requests to the webserver and has access to the database and other services - via the service container. Slower to run. +- **Functional** (web, feature) - tests behaviour and functionality, makes HTTP requests to the webserver and has access to the database and other services via the service container. Slower to run. - **FunctionalJavascript** - functional tests, but access to JavaScript. -- **Kernel** (integration) - no browser capabilities, has access to the database - and other services but requires more configuration. -- **Unit** - no access to the database or service container, all dependencies - need to be mocked. Fast to run. +- **Kernel** (integration) - no browser capabilities, has access to the database and other services but requires more configuration. +- **Unit** - no access to the database or service container, all dependencies need to be mocked. Fast to run. ## Different approaches to testing -- Inside-out (testing pyramid) - mostly unit tests, some integration tests, few - functional tests. -- Outside-in (testing trophy) - mostly functional tests, some integration tests, - few unit tests. More flexible, easier to refactor. +- Inside-out (testing pyramid) - mostly unit tests, some integration tests, few functional tests. +- Outside-in (testing trophy) - mostly functional tests, some integration tests, few unit tests. More flexible, easier to refactor. ## Structure of a test @@ -140,8 +122,7 @@ https://symfony.com/doc/current/setup/symfony_server.html ## Acceptance criteria -This module will be used to demonstrate how to take a test-driven approach to -develop a module to the following acceptance criteria: +This module will be used to demonstrate how to take a test-driven approach to develop a module to the following acceptance criteria: - As a site visitor - I want to see a list of all published articles at `/blog` @@ -149,8 +130,7 @@ develop a module to the following acceptance criteria: ## Step 0: Preparation -To begin with, we need the site to be running. If using the Symfony server, run -these commands: +To begin with, we need the site to be running. If using the Symfony server, run these commands: ```bash # Start the service containers @@ -160,8 +140,7 @@ docker-compose up -d symfony serve -d ``` -You don’t need to install Drupal, it just needs to be able to connect to the -database. +You don’t need to install Drupal, it just needs to be able to connect to the database. ## Step 1: Writing your first test @@ -175,11 +154,9 @@ mkdir -p web/modules/my_module ### 1b. Create an `.info.yml` file for the module -In order to install the module, it needs an info.yml file that matches the name -of the module (e.g. `my_module.info.yml`). +In order to install the module, it needs an info.yml file that matches the name of the module (e.g. `my_module.info.yml`). -Within the `my_module` directory, create the file and paste in the following -content: +Within the `my_module` directory, create the file and paste in the following content: ```yaml name: My Module @@ -225,28 +202,20 @@ Some things to note: - The name of the class must match the filename. - The filename must end with `Test.php`. -- The namespace is `Drupal\Tests\{module_name}`, followed by any additional - directories (e.g. `Functional`). +- The namespace is `Drupal\Tests\{module_name}`, followed by any additional directories (e.g. `Functional`). - Test methods must start with `test`, or use the `@test` annotation. ### 1e. Preparing PHPUnit -Firstly, we need to create a `phpunit.xml` file to configure PHPUnit. Core has a -`phpunit.xml.dist` file that we can duplicate and edit. +Firstly, we need to create a `phpunit.xml` file to configure PHPUnit. Core has a `phpunit.xml.dist` file that we can duplicate and edit. ```bash cp web/core/phpunit.xml.dist web/core/phpunit.xml ``` -Update the `SIMPLETEST_BASE_URL` value to be the address that the website is -currently running on. This needs to be correct so that functional tests return -the correct response codes, so ensure that any port numbers are correct and also -that the site is correctly marked as HTTP or HTTPS. +Update the `SIMPLETEST_BASE_URL` value to be the address that the website is currently running on. This needs to be correct so that functional tests return the correct response codes, so ensure that any port numbers are correct and also that the site is correctly marked as HTTP or HTTPS. -We also need to configure the database for Drupal to connect to and use when -running functional and kernel tests. This could be your project’s MySQL or -PostgreSQL database with a table prefix, but in this case, we’ll use a separate -SQLite database. +We also need to configure the database for Drupal to connect to and use when running functional and kernel tests. This could be your project’s MySQL or PostgreSQL database with a table prefix, but in this case, we’ll use a separate SQLite database. ```diff - @@ -266,24 +235,20 @@ cd web ../vendor/bin/phpunit -c core modules/my_module ``` -You should see a summary of the number of tests and assertions that were run. -This is the expected output if all of the tests pass: +You should see a summary of the number of tests and assertions that were run. This is the expected output if all of the tests pass: > OK (1 test, 2 assertions) -If a test failed, the output would show the class and method name for the -failing test, and give a summary of the failure. +If a test failed, the output would show the class and method name for the failing test, and give a summary of the failure. > Drupal\Tests\my_module\Functional\MyModuleTest::testThatTheFrontPageLoads -> Behat\Mink\Exception\ExpectationException: Current response status code is -> 404, but 200 expected. +> Behat\Mink\Exception\ExpectationException: Current response status code is 404, but 200 expected. Other useful options include `--stop-on-failure`, `--filter` and `--testdox`. ### 1g. (Optional) Running tests via a Composer script -To simplify running tests, the command could be simplified by [adding a -script][composer scripts] to `composer.json`: +To simplify running tests, the command could be simplified by [adding a script][composer scripts] to `composer.json`: ```json "scripts": { @@ -294,16 +259,11 @@ script][composer scripts] to `composer.json`: } ``` -This means that you can run just `symfony composer test:phpunit` or -`symfony composer test` and it will automatically move into the right directory -and execute the test command. +This means that you can run just `symfony composer test:phpunit` or `symfony composer test` and it will automatically move into the right directory and execute the test command. -This approach can be useful if you want to run other commands in addition to -PHPUnit such as PHPStan, PHP Code Sniffer or Drupal Check. Each command can be -added to the script and they will each be executed. +This approach can be useful if you want to run other commands in addition to PHPUnit such as PHPStan, PHP Code Sniffer or Drupal Check. Each command can be added to the script and they will each be executed. -If needed, you can still pass additional arguments and options to the command by -appending `--` followed by the arguments. +If needed, you can still pass additional arguments and options to the command by appending `--` followed by the arguments. ```bash symfony composer test:phpunit -- modules/my_module \ @@ -311,23 +271,17 @@ symfony composer test:phpunit -- modules/my_module \ --filter=the_front_page_loads_for_anonymous_users ``` -Locally, make sure that the command is prefixed with `symfony` if you are using -the Symfony web server to ensure that the correct PHP version etc is used. +Locally, make sure that the command is prefixed with `symfony` if you are using the Symfony web server to ensure that the correct PHP version etc is used. -[composer scripts]: - https://getcomposer.org/doc/articles/scripts.md#writing-custom-commands +[composer scripts]: https://getcomposer.org/doc/articles/scripts.md#writing-custom-commands ## Step 2: Adding more test methods ### 2a. Ensure that anonymous users cannot access admin pages -Now that we’re sure that the front page loads correctly, lets also check -anonymous users cannot access the administration area. This test is very similar -to the previous one, though instead we’re making a GET request to `/admin` and -ensuring that the response code is 403 (forbidden). +Now that we’re sure that the front page loads correctly, lets also check anonymous users cannot access the administration area. This test is very similar to the previous one, though instead we’re making a GET request to `/admin` and ensuring that the response code is 403 (forbidden). -As this functionality is provided by Drupal core by default, this should pass -automatically. +As this functionality is provided by Drupal core by default, this should pass automatically. ```php /** @test */ @@ -342,16 +296,9 @@ public function the_admin_page_is_not_accessible_to_anonymous_users() { Now let’s check that an administrator user _can_ access the admin pages. -This introduces some new concepts. We need to create a user to begin with, and -assign it some permissions. Because tests may be included within Drupal core a -contributed module, permissions need to be added to users directly as modules -won’t know about roles that are specific to your site. +This introduces some new concepts. We need to create a user to begin with, and assign it some permissions. Because tests may be included within Drupal core a contributed module, permissions need to be added to users directly as modules won’t know about roles that are specific to your site. -The `BrowserTestBase` class gives access to a number of helper methods, -including ones for creating and logging-in users (`createUser` and `drupalLogin` -respectively). When creating a user, the first argument is an array of -permission names to add. In this case, we can make the user an admin user by -adding the `access administration pages` permission. +The `BrowserTestBase` class gives access to a number of helper methods, including ones for creating and logging-in users (`createUser` and `drupalLogin` respectively). When creating a user, the first argument is an array of permission names to add. In this case, we can make the user an admin user by adding the `access administration pages` permission. ```php /** @test */ @@ -368,17 +315,13 @@ public function the_admin_page_is_accessible_by_admin_users() { } ``` -Again, as this functionality is provided by Drupal core by default, this should -pass. However, we can be confident that the test is doing what’s needed by -making it fail by removing or changing the assigned permissions, or not logging -in the user before accessing the page. +Again, as this functionality is provided by Drupal core by default, this should pass. However, we can be confident that the test is doing what’s needed by making it fail by removing or changing the assigned permissions, or not logging in the user before accessing the page. ## Step 3: Building a blog ### 3a. Anonymous users should be able to view the blog page -Let’s start by building a blog page. This will look very similar to the admin -page tests, but instead we’ll be testing the `/blog` page. +Let’s start by building a blog page. This will look very similar to the admin page tests, but instead we’ll be testing the `/blog` page. ```php // tests/src/Functional/BlogPageTest.php @@ -406,20 +349,15 @@ class BlogPageTest extends BrowserTestBase { } } - ``` -This test will fail as there’s no route for `/blog` and no View that generates -that page. Because of this, the response code will be a 404 instead of the 200 -that we want. +This test will fail as there’s no route for `/blog` and no View that generates that page. Because of this, the response code will be a 404 instead of the 200 that we want. > Current response status code is 404, but 200 expected. ### 3b: Add a route for the blog page -We’ll create a blog page using a custom route in the module. You could also do -this with the Views module by creating a View with a page on that path, and -exporting the configuration into the module’s `config/install` directory. +We’ll create a blog page using a custom route in the module. You could also do this with the Views module by creating a View with a page on that path, and exporting the configuration into the module’s `config/install` directory. To add a route, we need to create a `my_module.routing.yml` file. @@ -435,8 +373,7 @@ blog.page: _permission: access content ``` -We set our path to `/blog`, specify the Controller to use and which permission -the needs to have to access the page. +We set our path to `/blog`, specify the Controller to use and which permission the needs to have to access the page. If we run the tests now, we get an access denied error (403 response). @@ -444,8 +381,7 @@ If we run the tests now, we get an access denied error (403 response). ### 3c: Fix permission error -Because we need to node module to be able to access the `access content` -permission, we need to enable it within our tests. +Because we need to node module to be able to access the `access content` permission, we need to enable it within our tests. We can do this by adding it to the `$modules` array within the test. @@ -456,8 +392,7 @@ We can do this by adding it to the `$modules` array within the test. ]; ``` -Now the error has changed, and is now returning a 500 response because we’ve -specified a Controller that doesn’t exist. +Now the error has changed, and is now returning a 500 response because we’ve specified a Controller that doesn’t exist. > Current response status code is 500, but 200 expected. @@ -469,9 +404,7 @@ Let’s create the `BlogPageController`. mkdir src/Controller ``` -Let’s start by creating a minimal controller, that returns an empty render -array. Because we didn’t specify a method to use within the route file, we use -PHP’s `__invoke()` method. +Let’s start by creating a minimal controller, that returns an empty render array. Because we didn’t specify a method to use within the route file, we use PHP’s `__invoke()` method. ```php // src/Controller/BlogPageController @@ -487,8 +420,7 @@ class BlogPageController { } ``` -This is enough for the test to pass. Though it just returns an empty page, it -now returns the correct 200 response code. +This is enough for the test to pass. Though it just returns an empty page, it now returns the correct 200 response code. > OK (1 test, 3 assertions) @@ -498,8 +430,7 @@ This is how the page looks in a browser: ### 3e: Refactor, add more assertions -Now that the test is passing, we can do some refactoring and make the test more -robust by ensuring that the correct text is displayed. +Now that the test is passing, we can do some refactoring and make the test more robust by ensuring that the correct text is displayed. ```diff public function the_blog_page_loads_for_anonymous_users_and_contains_the_right_text() { @@ -513,14 +444,11 @@ robust by ensuring that the correct text is displayed. } ``` -The page title is created by the `_title` value within the routing file, but no -page text has been added yet so this will cause the test to fail. +The page title is created by the `_title` value within the routing file, but no page text has been added yet so this will cause the test to fail. -> Behat\Mink\Exception\ResponseTextException: The text "Welcome to my blog!" was -> not found anywhere in the text of the current page. +> Behat\Mink\Exception\ResponseTextException: The text "Welcome to my blog!" was not found anywhere in the text of the current page. -To fix this, we can return some text from the BlogPageController rather than an -empty render array. +To fix this, we can return some text from the BlogPageController rather than an empty render array. ```diff namespace Drupal\my_module\Controller; @@ -551,9 +479,7 @@ Now the tests will pass because we’re returning the correct text. ### 4a Creating our first kernel test -We’ll be using an ArticleRepository class to get the blog posts from the -database, and this is also a good time to switch to writing kernel tests as we -don’t need to check any responses from the browser. +We’ll be using an ArticleRepository class to get the blog posts from the database, and this is also a good time to switch to writing kernel tests as we don’t need to check any responses from the browser. Within the tests directory, create a new `Kernel` directory. @@ -580,20 +506,15 @@ class ArticleRepositoryTest extends EntityKernelTestBase { } ``` -This test looks very similar to the functional ones that we’ve already written, -except it extends a different base class. +This test looks very similar to the functional ones that we’ve already written, except it extends a different base class. -This test is extending `EntityKernelTestBase` as we’re working with entities and -this performs some useful setup steps for us. There are different base classes -that can be used though based on what you need - including `KernelTestBase` and -`ConfigFormTestBase`. +This test is extending `EntityKernelTestBase` as we’re working with entities and this performs some useful setup steps for us. There are different base classes that can be used though based on what you need - including `KernelTestBase` and `ConfigFormTestBase`. ### 4b. Starting with an assertion Let’s write this test 'backwards' and start with the 'assert' phase. -We know that the end objective for this test is to have 3 article nodes -returned, so let’s add that assertion first. +We know that the end objective for this test is to have 3 article nodes returned, so let’s add that assertion first. ```diff /** @test */ @@ -602,16 +523,13 @@ returned, so let’s add that assertion first. } ``` -As we aren’t yet returning any articles, or even creating that variable, the -test is going to fail, but we can move on to getting articles. +As we aren’t yet returning any articles, or even creating that variable, the test is going to fail, but we can move on to getting articles. > Undefined variable: articles ### 4c. Trying to use the ArticleRepository -As the test name suggests, we’re going to be retrieving the articles from an -`ArticleRepository` service - though this doesn’t exist yet, but let’s let the -tests tell us that. +As the test name suggests, we’re going to be retrieving the articles from an `ArticleRepository` service - though this doesn’t exist yet, but let’s let the tests tell us that. ```diff /** @test */ @@ -622,15 +540,11 @@ tests tell us that. } ``` -Because this is a kernel test, we have access to the container, and we can use -it to retrieve our repository service. +Because this is a kernel test, we have access to the container, and we can use it to retrieve our repository service. -Running the test now gives us a different error, and tells us what the next step -is: +Running the test now gives us a different error, and tells us what the next step is: -> Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException : You -> have requested a non-existent service -> "Drupal\Tests\my_module\Kernel\ArticleRepository". +> Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException : You have requested a non-existent service "Drupal\Tests\my_module\Kernel\ArticleRepository". ### 4d. Creating an article repository @@ -650,8 +564,7 @@ class ArticleRepository { } ``` -We also need to create a `my_module.services.yml` file that we can use to -register the `ArticleRepository` as a service. +We also need to create a `my_module.services.yml` file that we can use to register the `ArticleRepository` as a service. ```yaml # my_module.services.yml @@ -660,8 +573,7 @@ services: Drupal\my_module\Repository\ArticleRepository: ~ ``` -Within `ArticleRepositoryTest`, we need to add the import statement for the -`ArticleRepository` as well enabling the module. +Within `ArticleRepositoryTest`, we need to add the import statement for the `ArticleRepository` as well enabling the module. ```diff + use Drupal\my_module\Repository\ArticleRepository; @@ -671,15 +583,13 @@ Within `ArticleRepositoryTest`, we need to add the import statement for the + ]; ``` -We’ve fixed the missing repository, though we still haven’t created the -`$articles` variable or given it a value yet. +We’ve fixed the missing repository, though we still haven’t created the `$articles` variable or given it a value yet. > Undefined variable: articles ### 4e. Adding the `getAll()` method -We’ll use a `getAll()` method on the repository to retrieve the articles from -the database, and use the value of this for the `$articles` variable: +We’ll use a `getAll()` method on the repository to retrieve the articles from the database, and use the value of this for the `$articles` variable: ```diff $repository = $this->container->get(ArticleRepository::class); @@ -693,8 +603,7 @@ This method doesn’t exist on the repository yet, so the test will fail. > Error : Call to undefined method > Drupal\my_module\Repository\ArticleRepository::getAll() -Let’s fix that by adding the `getAll()` method. For now, have it return an empty -array. +Let’s fix that by adding the `getAll()` method. For now, have it return an empty array. ```php // my_module/Repository/ArticleRepository.php @@ -704,8 +613,7 @@ public function getAll(): array { } ``` -Now we’ve got everything in place, and the test failure is because we aren’t -returning the correct number of articles. +Now we’ve got everything in place, and the test failure is because we aren’t returning the correct number of articles. > Failed asserting that actual size 0 matches expected size 3. @@ -713,9 +621,7 @@ We can fix this by building up the `ArticleRepository` class. ### 4f. Building up the ArticleRepository -The `ArticleRepository` needs to return some articles. We can do this by -injecting the `EntityTypeManager` and using it to return nodes from the -`getAll()` method rather than the empty array. +The `ArticleRepository` needs to return some articles. We can do this by injecting the `EntityTypeManager` and using it to return nodes from the `getAll()` method rather than the empty array. ```diff + use Drupal\Core\Entity\EntityTypeManagerInterface; @@ -735,17 +641,11 @@ injecting the `EntityTypeManager` and using it to return nodes from the } ``` -Within our services file, we now need to add the `EntityTypeManager` as an -argument so that it’s used to create the `ArticleRepository`. Currently we don’t -have enough arguments. +Within our services file, we now need to add the `EntityTypeManager` as an argument so that it’s used to create the `ArticleRepository`. Currently we don’t have enough arguments. -> ArgumentCountError : Too few arguments to function -> Drupal\my_module\Repository\ArticleRepository::\_\_construct(), 0 passed and -> exactly 1 expected +> ArgumentCountError : Too few arguments to function Drupal\my_module\Repository\ArticleRepository::\_\_construct(), 0 passed and exactly 1 expected -The quickest way to do that is to enable autowiring for the ArticleRepository -within `my_module.services.yml`. This will automatically inject services rather -than needing to specify each argument individually. +The quickest way to do that is to enable autowiring for the ArticleRepository within `my_module.services.yml`. This will automatically inject services rather than needing to specify each argument individually. ```diff - Drupal\my_module\Repository\ArticleRepository: ~ @@ -753,8 +653,7 @@ than needing to specify each argument individually. + autowire: true ``` -> Drupal\Component\Plugin\Exception\PluginNotFoundException : The "node" entity -> type does not exist. +> Drupal\Component\Plugin\Exception\PluginNotFoundException : The "node" entity type does not exist. As we did previously, we need to enable the `node` module. @@ -765,18 +664,15 @@ As we did previously, we need to enable the `node` module. ]; ``` -The `ArticleRepository` is now working, but is still returning no articles - -though this is because we haven’t created any inside the test. +The `ArticleRepository` is now working, but is still returning no articles - though this is because we haven’t created any inside the test. > Failed asserting that actual size 0 matches expected size 3. ### 4g. Adding articles -To test the ArticleRepository, we need articles to be created so that they can -be returned. +To test the ArticleRepository, we need articles to be created so that they can be returned. -Within the `ArticleRepositoryTest` we can make use of one of a number of traits -that are provided. +Within the `ArticleRepositoryTest` we can make use of one of a number of traits that are provided. Within the class, enable the trait: @@ -784,15 +680,13 @@ Within the class, enable the trait: + use NodeCreationTrait ``` -Include the import statement at the top of the file if it hasn’t been added -automatically. +Include the import statement at the top of the file if it hasn’t been added automatically. ```diff + use Drupal\Tests\node\Traits\NodeCreationTrait; ``` -This gives us a `createNode` method that we can use to create nodes by passing -an array of values. +This gives us a `createNode` method that we can use to create nodes by passing an array of values. As we need 3 articles, let’s create them. @@ -806,8 +700,7 @@ The next error is a little cryptic: > Error : Call to a member function id() on bool -Looking at the stack trace, this error is within `filter.module`, where it’s -trying to call an `id()` method on a filter format. +Looking at the stack trace, this error is within `filter.module`, where it’s trying to call an `id()` method on a filter format. ```php // filter.module @@ -817,11 +710,9 @@ $format = reset($formats); return $format->id(); ``` -As kernel tests don’t install configuration by default, we need to install the -missing filter configuration. +As kernel tests don’t install configuration by default, we need to install the missing filter configuration. -As we’ll need this for all test methods in this case, we can use the `setUp()` -method that will run before each test. +As we’ll need this for all test methods in this case, we can use the `setUp()` method that will run before each test. ```diff + protected function setUp() { @@ -835,8 +726,7 @@ method that will run before each test. We also need to create the `node_access` table as indicated by the next error: -> Drupal\Core\Entity\EntityStorageException : SQLSTATE[HY000]: General error: 1 -> no such table: test90927710.node_access: DELETE FROM {node_access} +> Drupal\Core\Entity\EntityStorageException : SQLSTATE[HY000]: General error: 1 no such table: test90927710.node_access: DELETE FROM {node_access} ```diff protected function setUp() { @@ -858,8 +748,7 @@ We’ve successfully returned our three articles and this test now passes. The test is passing, but it currently returns _all_ nodes and not just articles. -If we create some page nodes too, these will also be returned and the assertion -will now fail. +If we create some page nodes too, these will also be returned and the assertion will now fail. ```diff $this->createNode(['type' => 'article'])->save(); @@ -871,8 +760,7 @@ will now fail. > Failed asserting that actual size 5 matches expected size 3. -We can make a change to the `ArticleRepository` to fix this, and ensure that -we’re only loading and returning article nodes. +We can make a change to the `ArticleRepository` to fix this, and ensure that we’re only loading and returning article nodes. ```diff - return $this->nodeStorage->loadMultiple(); @@ -883,8 +771,7 @@ we’re only loading and returning article nodes. ### 4i. Ensuring that only published articles are returned -We now know that only article nodes are returned, but _all_ articles are being -returned. On our blog, we only want to published articles to be displayed. +We now know that only article nodes are returned, but _all_ articles are being returned. On our blog, we only want to published articles to be displayed. Let’s create another test for this. @@ -898,9 +785,7 @@ Let’s create another test for this. + } ``` -We already know that only articles are returned, so in this test we can focus on -the published status. We can create a number of articles, some which are -published and some which are unpublished. +We already know that only articles are returned, so in this test we can focus on the published status. We can create a number of articles, some which are published and some which are unpublished. ```diff /** @test */ @@ -918,13 +803,11 @@ published and some which are unpublished. } ``` -Because we have no filter on the published state, all the articles are returned -including the unpublished ones. +Because we have no filter on the published state, all the articles are returned including the unpublished ones. > Failed asserting that actual size 5 matches expected size 3. -We can again update the `ArticleRepository` to add this extra condition to -filter out any unpublished articles. +We can again update the `ArticleRepository` to add this extra condition to filter out any unpublished articles. ```diff + use Drupal\node\Entity\Node; @@ -943,11 +826,9 @@ With this added, the test passes again. ### 4j. Ensuring that articles are returned in the correct order -As per our acceptance criteria, we need the articles to be returned based on -their created date, so let’s create another test. +As per our acceptance criteria, we need the articles to be returned based on their created date, so let’s create another test. -In this test, let’s ensure assert that some article node IDs are returned within -a specific order. +In this test, let’s ensure assert that some article node IDs are returned within a specific order. ```diff + /** @test */ @@ -969,9 +850,7 @@ We can use the same `getAll()` method, and get the node IDs from the array keys. } ``` -Use `createNode()` again to create some article nodes, each with a different -`created` date to match our assertion. This is to ensure that the test doesn’t -pass by default. +Use `createNode()` again to create some article nodes, each with a different `created` date to match our assertion. This is to ensure that the test doesn’t pass by default. ```diff /** @test */ @@ -990,8 +869,7 @@ pass by default. } ``` -This test fails as expected, as the nodes are returned in their default order, -by node ID. +This test fails as expected, as the nodes are returned in their default order, by node ID. > Failed asserting that two arrays are identical. --- Expected +++ Actual @@ @@ > Array &0 ( @@ -1008,8 +886,7 @@ by node ID. > * 3 => 4 > * 4 => 5 ) -To order the articles by their created date, we can update the `getAll()` method -within the `ArticleRepository`. +To order the articles by their created date, we can update the `getAll()` method within the `ArticleRepository`. ```diff public function getAll(): array { @@ -1028,15 +905,13 @@ within the `ArticleRepository`. } ``` -The nodes are now ordered by their created date, and in the correct order to -match the assertion. +The nodes are now ordered by their created date, and in the correct order to match the assertion. > OK (1 test, 6 assertions) ### 4k. Linking up the repository to the BlogPageController -Now that our `ArticleRepository` tests are passing, we can use it within -`BlogPageController` so that articles are displayed on the page. +Now that our `ArticleRepository` tests are passing, we can use it within `BlogPageController` so that articles are displayed on the page. Let’s add `BlogPageController` as a service and enable autowiring. @@ -1051,8 +926,7 @@ Let’s add `BlogPageController` as a service and enable autowiring. autowire: true ``` -Now we can inject the `ArticleRepository` and use it to load and render the -articles on the page. +Now we can inject the `ArticleRepository` and use it to load and render the articles on the page. ```diff @@ -1110,8 +984,7 @@ In the browser, we should see our list of articles. ### 5a: Creating an ArticleWrapper -The final thing that we’re going to do is create a wrapper class for articles so -that we can add additional methods. +The final thing that we’re going to do is create a wrapper class for articles so that we can add additional methods. ```bash mkdir -p tests/src/Unit/Wrapper @@ -1128,8 +1001,7 @@ class ArticleWrapperTest extends UnitTestCase { } ``` -The first thing that we’re going to check is that we can wrap an article node -and then retrieve it again. +The first thing that we’re going to check is that we can wrap an article node and then retrieve it again. ```php /** @test */ @@ -1177,8 +1049,7 @@ Currently, we don’t yet have an article to wrap. > Undefined variable: article -Because this is a unit test which has no access to the database, we can’t use -the `createNode()` method or `Node::create()` so we need to create a mock node. +Because this is a unit test which has no access to the database, we can’t use the `createNode()` method or `Node::create()` so we need to create a mock node. ```diff + use Drupal\node\NodeInterface; @@ -1190,9 +1061,7 @@ This satisfies the instance assertion, but the other assertions are failing. > Failed asserting that null is identical to 5. -In order for this to pass, we need to specify what value each method will method -will return (e.g. which node ID and which bundle type) so that these values are -populated when used within the production code. +In order for this to pass, we need to specify what value each method will method will return (e.g. which node ID and which bundle type) so that these values are populated when used within the production code. ```diff $article = $this->createMock(NodeInterface::class); @@ -1204,8 +1073,7 @@ populated when used within the production code. ### 5b. Ensure that we’re only wrapping articles -The ArticleWrapper is only supposed to be used for wrapping articles, so we want -to throw an Exception if a different type of node is used. +The ArticleWrapper is only supposed to be used for wrapping articles, so we want to throw an Exception if a different type of node is used. Let’s create a page node and assert that an Exception should be thrown. @@ -1225,8 +1093,7 @@ Because we’re currently not throwing an Exception, the assertion fails. > Failed asserting that exception of type "InvalidArgumentException" is thrown. -Within `ArticleWrapper`, add a check using the `bundle()` method and throw an -Exception if it is not an article. +Within `ArticleWrapper`, add a check using the `bundle()` method and throw an Exception if it is not an article. ```diff public function __construct(NodeInterface $node) { @@ -1249,16 +1116,11 @@ If the Exception is thrown, the test will pass. ### 5c. Determine if articles are publishable -Let’s imagine that there is a rule that articles less than 3 days old are not -eligible to be published and we want to add an `isPublishable()` method that -will contain this logic and determine whether or not an article is publishable. +Let’s imagine that there is a rule that articles less than 3 days old are not eligible to be published and we want to add an `isPublishable()` method that will contain this logic and determine whether or not an article is publishable. -We need access to the `Time` class to get the system time, so this is added as -an argument to the constructor and used within `isPublishable()` to compare the -created time of the article to the current time. +We need access to the `Time` class to get the system time, so this is added as an argument to the constructor and used within `isPublishable()` to compare the created time of the article to the current time. ```diff - + use Drupal\Component\Datetime\TimeInterface; use Drupal\node\NodeInterface; @@ -1285,8 +1147,7 @@ created time of the article to the current time. } ``` -In the test, this argument also needs to be mocked. As this will need to be -added to each test, this can be done within the `setUp()` method again. +In the test, this argument also needs to be mocked. As this will need to be added to each test, this can be done within the `setUp()` method again. ```php protected function setUp() { @@ -1294,9 +1155,7 @@ protected function setUp() { } ``` -We want to compare against a number of dates to ensure that this is working as -expected. Rather than writing separate tests, we can use a data provider. This -is a method that returns data to be passed to the tests as parameters. +We want to compare against a number of dates to ensure that this is working as expected. Rather than writing separate tests, we can use a data provider. This is a method that returns data to be passed to the tests as parameters. ```php public function articleCreatedDateProvider() { @@ -1309,8 +1168,7 @@ public function articleCreatedDateProvider() { } ``` -Use the `@dataProvider` annotation for the test to specify the method to use, -and add the parameters to the test. +Use the `@dataProvider` annotation for the test to specify the method to use, and add the parameters to the test. ```php /** @@ -1338,17 +1196,11 @@ public function articles_created_less_than_3_days_ago_are_not_publishable( } ``` -We can use `$offset` value to modify the returned date from `getCreatedTime()`, -and use `$expected` to make the assertion against `isPublishable()`. +We can use `$offset` value to modify the returned date from `getCreatedTime()`, and use `$expected` to make the assertion against `isPublishable()`. -The test is run, is then run against each set of data and passes or fails -accordingly. +The test is run, is then run against each set of data and passes or fails accordingly. -> - Articles created less than 3 days ago are not publishable with data set #0 -> [23.76 ms] -> - Articles created less than 3 days ago are not publishable with data set #1 -> [0.32 ms] -> - Articles created less than 3 days ago are not publishable with data set #2 -> [0.25 ms] -> - Articles created less than 3 days ago are not publishable with data set #3 -> [0.37 ms] +> - Articles created less than 3 days ago are not publishable with data set #0 [23.76 ms] +> - Articles created less than 3 days ago are not publishable with data set #1 [0.32 ms] +> - Articles created less than 3 days ago are not publishable with data set #2 [0.25 ms] +> - Articles created less than 3 days ago are not publishable with data set #3 [0.37 ms] From ee1d9beb8220e56e216503d96b2af759995c699f Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Wed, 18 Mar 2020 12:26:28 +0000 Subject: [PATCH 08/77] No need for prettier --- package-lock.json | 12 ------------ package.json | 5 ----- prettier.config.js | 18 ------------------ 3 files changed, 35 deletions(-) delete mode 100644 package-lock.json delete mode 100644 package.json delete mode 100644 prettier.config.js diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 7447b5d..0000000 --- a/package-lock.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "requires": true, - "lockfileVersion": 1, - "dependencies": { - "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", - "dev": true - } - } -} diff --git a/package.json b/package.json deleted file mode 100644 index 67aa861..0000000 --- a/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "devDependencies": { - "prettier": "^1.19.1" - } -} diff --git a/prettier.config.js b/prettier.config.js deleted file mode 100644 index 181b27c..0000000 --- a/prettier.config.js +++ /dev/null @@ -1,18 +0,0 @@ -module.exports = { - arrowParens: 'avoid', - bracketSpacing: false, - endOfLine: 'lf', - htmlWhitespaceSensitivity: 'css', - insertPragma: false, - jsxBracketSameLine: false, - jsxSingleQuote: false, - printWidth: 80, - proseWrap: 'always', - quoteProps: 'as-needed', - requirePragma: false, - semi: false, - singleQuote: true, - tabWidth: 2, - trailingComma: 'all', - useTabs: false, -} From 9e3d3fd7efab6a0fcff041c4b0e17089379031a2 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Wed, 18 Mar 2020 19:32:25 +0000 Subject: [PATCH 09/77] 4g: Make it easier to see where the lines go Fixes #4 --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 7411a4a..33d0a9b 100644 --- a/README.md +++ b/README.md @@ -694,6 +694,9 @@ As we need 3 articles, let’s create them. + $this->createNode(['type' => 'article'])->save(); + $this->createNode(['type' => 'article'])->save(); + $this->createNode(['type' => 'article'])->save(); + + $repository = $this->container->get(ArticleRepository::class); + $articles = $repository->getAll(); ``` The next error is a little cryptic: From a03ec1360bcf830d034498085b0df73ff03cd415 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Wed, 18 Mar 2020 19:38:14 +0000 Subject: [PATCH 10/77] Typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 33d0a9b..c548a6a 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ ## Contribution -Please feel free to create issue and/or submit pull requests to this repository whilst working through these instructions. Any contributions would be greatly appreciated! +Please feel free to create issues and/or submit pull requests to this repository whilst working through these instructions. Any contributions would be greatly appreciated! ## Feedback From b6507ffd0e26e675e824fc6700a19ffc3ad60331 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Thu, 19 Mar 2020 11:02:38 +0000 Subject: [PATCH 11/77] Fix title and jump link --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c548a6a..f0e2369 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ - [Using the Symfony web server for local development](#using-the-symfony-web-server-for-local-development) - [The different types of available tests](#the-different-types-of-available-tests) - [Different approaches to testing](#different-approaches-to-testing) -- [A structure of a test](#a-structure-of-a-test) +- [The structure of a test](#the-structure-of-a-test) - [What is Test Driven Development?](#what-is-test-driven-development) - [Acceptance criteria](#acceptance-criteria) - [Step 0: Preparation](#step-0-preparation) @@ -101,7 +101,7 @@ https://symfony.com/doc/current/setup/symfony_server.html - Inside-out (testing pyramid) - mostly unit tests, some integration tests, few functional tests. - Outside-in (testing trophy) - mostly functional tests, some integration tests, few unit tests. More flexible, easier to refactor. -## Structure of a test +## The structure of a test - **Arrange** - set up the environment. Create users, nodes, set up dependencies - **Act** - perform an action From 33e92bbb1f05f27fa9da04928e7d951388b4cfe9 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Thu, 19 Mar 2020 11:06:39 +0000 Subject: [PATCH 12/77] Add a note for non-Symfony server users --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index f0e2369..b3185e8 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,8 @@ https://symfony.com/doc/current/setup/symfony_server.html - - - blog post +If you’re not using the Symfony web server, then remove the `symfony` prefix from all of the commands below. + ## The different types of available tests - **Functional** (web, feature) - tests behaviour and functionality, makes HTTP requests to the webserver and has access to the database and other services via the service container. Slower to run. From f38ca67efbf7753c50622360f789e82138e3042a Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Thu, 19 Mar 2020 20:29:42 +0000 Subject: [PATCH 13/77] Place my_module within a custom directory Fixes #11 --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index b3185e8..f123b30 100644 --- a/README.md +++ b/README.md @@ -151,7 +151,7 @@ You don’t need to install Drupal, it just needs to be able to connect to the d Create a directory for the new module: ``` -mkdir -p web/modules/my_module +mkdir -p web/modules/custom/my_module ``` ### 1b. Create an `.info.yml` file for the module @@ -234,7 +234,7 @@ We also need to configure the database for Drupal to connect to and use when run cd web # Run the tests -../vendor/bin/phpunit -c core modules/my_module +../vendor/bin/phpunit -c core modules/custom/my_module ``` You should see a summary of the number of tests and assertions that were run. This is the expected output if all of the tests pass: @@ -268,7 +268,7 @@ This approach can be useful if you want to run other commands in addition to PHP If needed, you can still pass additional arguments and options to the command by appending `--` followed by the arguments. ```bash -symfony composer test:phpunit -- modules/my_module \ +symfony composer test:phpunit -- modules/custom/my_module \ --stop-on-failure \ --filter=the_front_page_loads_for_anonymous_users ``` From a1529f22d7422744d29c3e25ce1b739a65bc98da Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Thu, 19 Mar 2020 23:21:02 +0000 Subject: [PATCH 14/77] Add an alias for the entity type manager Remove deprecation warnings Fixes #12 --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index f123b30..11efd72 100644 --- a/README.md +++ b/README.md @@ -651,6 +651,9 @@ The quickest way to do that is to enable autowiring for the ArticleRepository wi ```diff - Drupal\my_module\Repository\ArticleRepository: ~ ++ Drupal\Core\Entity\EntityTypeManagerInterface: ++ alias: entity_type.manager ++ + Drupal\my_module\Repository\ArticleRepository: + autowire: true ``` From a13636a2f2837709cf8409af1c37fbe0a4d5a750 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Thu, 19 Mar 2020 23:23:41 +0000 Subject: [PATCH 15/77] Use a method for sorting articles Fixes #13 --- README.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 11efd72..1a7bf08 100644 --- a/README.md +++ b/README.md @@ -904,12 +904,15 @@ To order the articles by their created date, we can update the `getAll()` method 'type' => 'article', ]); + -+ // Sort the articles by their created date. ++ $this->sortByCreatedDate($articles); ++ ++ return $articles; ++ } ++ ++ private function sortByCreatedDate(array &$articles): void { + uasort($articles, function (NodeInterface $a, NodeInterface $b): bool { + return $a->getCreatedTime() < $b->getCreatedTime(); + }); -+ -+ return $articles; } ``` From 7cad32c9efae9a5fd5b596e0a0bf6bc54597a2ee Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Thu, 19 Mar 2020 23:39:01 +0000 Subject: [PATCH 16/77] Add 5d: Refactor unit tests Fixes #14 --- README.md | 66 ++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 1a7bf08..ba66c9a 100644 --- a/README.md +++ b/README.md @@ -1158,14 +1158,6 @@ We need access to the `Time` class to get the system time, so this is added as a } ``` -In the test, this argument also needs to be mocked. As this will need to be added to each test, this can be done within the `setUp()` method again. - -```php -protected function setUp() { - $this->time = $this->createMock(TimeInterface::class); -} -``` - We want to compare against a number of dates to ensure that this is working as expected. Rather than writing separate tests, we can use a data provider. This is a method that returns data to be passed to the tests as parameters. ```php @@ -1181,6 +1173,8 @@ public function articleCreatedDateProvider() { Use the `@dataProvider` annotation for the test to specify the method to use, and add the parameters to the test. +We also need to create a mock for `TimeInterface` so that it can be passed into the article wrapper, and so that methods on it can return certain values. + ```php /** * @test @@ -1190,7 +1184,9 @@ public function articles_created_less_than_3_days_ago_are_not_publishable( string $offset, bool $expected ) { - $this->time->method('getRequestTime')->willReturn( + $time = $this->createMock(TimeInterface::class); + + $time->method('getRequestTime')->willReturn( (new \DateTime())->getTimestamp() ); @@ -1201,7 +1197,7 @@ public function articles_created_less_than_3_days_ago_are_not_publishable( (new \DateTime())->modify($offset)->getTimestamp() ); - $articleWrapper = new ArticleWrapper($this->time, $article); + $articleWrapper = new ArticleWrapper($time, $article); $this->assertSame($expected, $articleWrapper->isPublishable()); } @@ -1215,3 +1211,53 @@ The test is run, is then run against each set of data and passes or fails accord > - Articles created less than 3 days ago are not publishable with data set #1 [0.32 ms] > - Articles created less than 3 days ago are not publishable with data set #2 [0.25 ms] > - Articles created less than 3 days ago are not publishable with data set #3 [0.37 ms] + +The other tests will also need to be updated to mock `TimeInterface` and pass it to the article wrapper. + +## 5d: Refactoring the unit tests + +With the unit tests passing, we can refactor them and simplify things by extracting a method for creating an article wrapper. + +As each test will need the mocked time, this can be moved into a `setUp` method, and we can use `$this->time` instead within the test. + +```php +private $time; + +protected function setUp() { + parent::setUp(); + + $this->time = $this->createMock(Time::class); +} +``` + +```diff +- $time->method('getRequestTime')->willReturn( ++ $this->time->method('getRequestTime')->willReturn( + (new \DateTime())->getTimestamp() + ); +``` + +To make it simpler to create an article wrapper, we can create a helper method for that. This will also be responsible for creating and injecting any dependencies. + +```php +private function createArticleWrapper(NodeInterface $article): ArticleWrapper { + return new ArticleWrapper($this->time, $article); +} +``` + +Now we can update the tests to use the new `createArticleWrapper()` method: + +```diff +- $time = $this->createMock(TimeInterface::class); +- $articleWrapper = new ArticleWrapper($time, $article); ++ $articleWrapper = $this->createArticleWrapper($article); + +- $time = $this->createMock(TimeInterface::class); +- new ArticleWrapper($time, $page); ++ $articleWrapper = $this->createArticleWrapper($page); + +- $articleWrapper = new ArticleWrapper($time, $article); ++ $articleWrapper = $this->createArticleWrapper($article); +``` + +If the refactor was successful, the tests will still pass. From 712f2805d2d24434b8af5831616f3797f28a6be7 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Fri, 13 Nov 2020 16:27:52 +0000 Subject: [PATCH 17/77] Update feedback email address --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ba66c9a..01ff7c3 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ Please feel free to create issues and/or submit pull requests to this repository ## Feedback -Feedback would also be appreciated! You can contact me via , [@opdavies on Twitter](https://twitter.com/opdavies) or `opdavies` on Drupal Slack. +Feedback would also be appreciated! You can contact me via , [@opdavies on Twitter](https://twitter.com/opdavies) or `opdavies` on Drupal Slack. ## Introduction From ccd5b423f604c876acc6170b3550ffb4f79302ea Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Fri, 13 Nov 2020 17:25:23 +0000 Subject: [PATCH 18/77] Update local development documentation Replace the Symfony web server documentation with DDEV, and PHP's local web server. This should be one less new thing for people to learn and should be more familiar to Drupal developers. --- README.md | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 01ff7c3..a4aa454 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,8 @@ - [Contribution](#contribution) - [Feedback](#feedback) - [Creating a new Drupal project with Composer](#creating-a-new-drupal-project-with-composer) -- [Using the Symfony web server for local development](#using-the-symfony-web-server-for-local-development) +- [Using DDEV for local development](#using-ddev-for-local-development) +- [Using the PHP web server for local development](#using-the-php-web-server-for-local-development) - [The different types of available tests](#the-different-types-of-available-tests) - [Different approaches to testing](#different-approaches-to-testing) - [The structure of a test](#the-structure-of-a-test) @@ -77,19 +78,31 @@ You should now have files present including `web/index.php` and `vendor/bin/phpu **Note:** Development dependencies, including PHPUnit, should only be installed locally and should not be present on public servers. Doing so would present a security risk to your application. -## Using the Symfony web server for local development +## Using DDEV for local development -https://symfony.com/doc/current/setup/symfony_server.html +- Docker based development environment for PHP applications (Drupal, WordPress, Magento etc). +- More information at . +- Documentation at . +- Installation via Homebrew on Linux and macOS, and Chocolatey on Windows. More information at . +- Example at . -- Part of the Symfony CLI. -- Download from . -- Docker provides the integration with MySQL. -- Faster performance compared to mounting files within Docker volumes. -- Need `docker-compose.yml` to provide the database service, `.php-version` to set the version of PHP -- -- - blog post +To run PHPUnit within DDEV, we can prefix the command with `ddev exec`: -If you’re not using the Symfony web server, then remove the `symfony` prefix from all of the commands below. +``` +$ ddev exec vendor/bin/phpunit +``` + +## Using the PHP web server for local development + +If you have all of [Drupal's required PHP extensions](https://www.drupal.org/docs/system-requirements/php-requirements#extensions) installed and would like better performance (particularly on macOS), you could use the PHP's local web server. + +As we're going to use SQLite to run the tests, there's no need for a connection to a MySQL database or another service. + +If you need to override any environment variables, you can do so before running the command: + +``` +$ SIMPLETEST_BASE_URL=http://localhost:8000 vendor/bin/phpunit +``` ## The different types of available tests From 646fe86d155629a94c13695ad3cb7b20737e07ad Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Fri, 13 Nov 2020 20:47:14 +0000 Subject: [PATCH 19/77] Update SIMPLETEST_BASE_URL and SIMPLETEST_DB Update the base URL to work inside DDEV, and the DB connection details to use `/dev/shm` for better performance. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a4aa454..9ad9e70 100644 --- a/README.md +++ b/README.md @@ -234,10 +234,10 @@ We also need to configure the database for Drupal to connect to and use when run ```diff - -+ ++ - -+ ++ ``` ### 1f. Running the tests From f9bf33397760e47b279869b1925b398268fc9519 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Fri, 13 Nov 2020 21:10:45 +0000 Subject: [PATCH 20/77] Replace references to symfony CLI with DDEV --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 9ad9e70..3bbf391 100644 --- a/README.md +++ b/README.md @@ -145,17 +145,17 @@ This module will be used to demonstrate how to take a test-driven approach to de ## Step 0: Preparation -To begin with, we need the site to be running. If using the Symfony server, run these commands: +To begin, we need the site to be running. ```bash -# Start the service containers -docker-compose up -d +# Using DDEV +ddev start -# Start the local web server -symfony serve -d +# Using PHP's web server +php -S localhost:8000 -t web ``` -You don’t need to install Drupal, it just needs to be able to connect to the database. +You don’t need to install Drupal. It just needs to be able to connect to the database. ## Step 1: Writing your first test @@ -274,19 +274,19 @@ To simplify running tests, the command could be simplified by [adding a script][ } ``` -This means that you can run just `symfony composer test:phpunit` or `symfony composer test` and it will automatically move into the right directory and execute the test command. +This means that you can run just `ddev composer test:phpunit` or `ddev composer test` and it will automatically move into the right directory and execute the test command. This approach can be useful if you want to run other commands in addition to PHPUnit such as PHPStan, PHP Code Sniffer or Drupal Check. Each command can be added to the script and they will each be executed. If needed, you can still pass additional arguments and options to the command by appending `--` followed by the arguments. ```bash -symfony composer test:phpunit -- modules/custom/my_module \ +ddev composer test:phpunit -- modules/custom/my_module \ --stop-on-failure \ --filter=the_front_page_loads_for_anonymous_users ``` -Locally, make sure that the command is prefixed with `symfony` if you are using the Symfony web server to ensure that the correct PHP version etc is used. +Locally, ensure that the command is prefixed with `ddev` so that it is run within the container. This ensures that the correct PHP version etc is used. [composer scripts]: https://getcomposer.org/doc/articles/scripts.md#writing-custom-commands From 077631bd3218738d0c01817fc393e9ab1f8fa0d8 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Fri, 13 Nov 2020 21:17:52 +0000 Subject: [PATCH 21/77] Remove unused keys --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 3bbf391..87be389 100644 --- a/README.md +++ b/README.md @@ -176,9 +176,7 @@ Within the `my_module` directory, create the file and paste in the following con ```yaml name: My Module type: module -core: 8.x core_version_requirement: ^8 || ^9 -package: Custom ``` ### 1c. Create the directory structure for tests From fa44d26bde9500e36a6473588c3bccf74414a786 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Fri, 13 Nov 2020 22:16:36 +0000 Subject: [PATCH 22/77] Update first test --- README.md | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 87be389..38b4591 100644 --- a/README.md +++ b/README.md @@ -188,24 +188,29 @@ mkdir -p tests/src/Functional ### 1d. Create your first test case ```php -// MyModuleTest.php +config('system.site') + ->set('page.front', '/node') + ->save(TRUE); + $this->drupalGet(''); - $this->assertResponse(Response::HTTP_OK); + $assert = $this->assertSession(); + $assert->statusCodeEquals(Response::HTTP_OK); + $assert->pageTextContains('Welcome to Drupal'); + $assert->pageTextContains('No front page content has been created yet.'); } } @@ -241,20 +246,16 @@ We also need to configure the database for Drupal to connect to and use when run ### 1f. Running the tests ```bash -# Make sure you’re in the right place -cd web - -# Run the tests -../vendor/bin/phpunit -c core modules/custom/my_module +$ vendor/bin/phpunit modules/custom/my_module ``` You should see a summary of the number of tests and assertions that were run. This is the expected output if all of the tests pass: -> OK (1 test, 2 assertions) +> OK (1 test, 3 assertions) If a test failed, the output would show the class and method name for the failing test, and give a summary of the failure. -> Drupal\Tests\my_module\Functional\MyModuleTest::testThatTheFrontPageLoads +> Drupal\Tests\my_module\Functional\FrontPageTest::the_front_page_loads_for_anonymous_users > Behat\Mink\Exception\ExpectationException: Current response status code is 404, but 200 expected. Other useful options include `--stop-on-failure`, `--filter` and `--testdox`. From a029e6223c632da37eb382e2230fa1af1b3f013e Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Fri, 13 Nov 2020 22:19:57 +0000 Subject: [PATCH 23/77] Update Composer test script --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 38b4591..44fb78f 100644 --- a/README.md +++ b/README.md @@ -266,14 +266,14 @@ To simplify running tests, the command could be simplified by [adding a script][ ```json "scripts": { - "test:phpunit": "cd web && ../vendor/bin/phpunit -c core --verbose --testdox", + "test:phpunit": "phpunit --verbose --testdox --colors=always", "test": [ "@test:phpunit" ] } ``` -This means that you can run just `ddev composer test:phpunit` or `ddev composer test` and it will automatically move into the right directory and execute the test command. +This means that you can run just `ddev composer test:phpunit` or `ddev composer test` and it will execute the `phpunit` command. This approach can be useful if you want to run other commands in addition to PHPUnit such as PHPStan, PHP Code Sniffer or Drupal Check. Each command can be added to the script and they will each be executed. From e1e137f55eae87cbf77a80a14645023e047404dc Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Fri, 13 Nov 2020 23:52:51 +0000 Subject: [PATCH 24/77] Replace instances of assertResponse --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 44fb78f..50a5287 100644 --- a/README.md +++ b/README.md @@ -302,7 +302,7 @@ As this functionality is provided by Drupal core by default, this should pass au public function the_admin_page_is_not_accessible_to_anonymous_users() { $this->drupalGet('admin'); - $this->assertResponse(Response::HTTP_FORBIDDEN); + $this->assertSession()->statusCodeEquals(Response::HTTP_FORBIDDEN); } ``` @@ -325,7 +325,7 @@ public function the_admin_page_is_accessible_by_admin_users() { $this->drupalGet('admin'); - $this->assertResponse(Response::HTTP_OK); + $this->assertSession()->statusCodeEquals(Response::HTTP_OK); } ``` From 1baead38fd73cb5499f39018e1aa1f46e1f431fa Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Fri, 13 Nov 2020 23:53:13 +0000 Subject: [PATCH 25/77] Add opening PHP tags for new examples --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 50a5287..55fd79d 100644 --- a/README.md +++ b/README.md @@ -338,6 +338,8 @@ Again, as this functionality is provided by Drupal core by default, this should Let’s start by building a blog page. This will look very similar to the admin page tests, but instead we’ll be testing the `/blog` page. ```php + Date: Fri, 13 Nov 2020 23:53:24 +0000 Subject: [PATCH 26/77] Update the assertion count --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 55fd79d..d5192ee 100644 --- a/README.md +++ b/README.md @@ -770,7 +770,7 @@ We also need to create the `node_access` table as indicated by the next error: We’ve successfully returned our three articles and this test now passes. -> OK (1 test, 6 assertions) +> OK (1 test, 11 assertions) ### 4h. Making this test less brittle @@ -938,7 +938,7 @@ To order the articles by their created date, we can update the `getAll()` method The nodes are now ordered by their created date, and in the correct order to match the assertion. -> OK (1 test, 6 assertions) +> OK (1 test, 11 assertions) ### 4k. Linking up the repository to the BlogPageController From fbf2171d252218840dff61f3307fc07fee8044ed Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Sat, 14 Nov 2020 00:39:39 +0000 Subject: [PATCH 27/77] Make the first blog test more generic --- README.md | 74 ++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 54 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index d5192ee..207efb3 100644 --- a/README.md +++ b/README.md @@ -39,10 +39,11 @@ - [4e. Adding the getAll() method](#4e-adding-the-getall-method) - [4f. Building up the ArticleRepository](#4f-building-up-the-articlerepository) - [4g. Adding articles](#4g-adding-articles) - - [4h. Making this test less brittle](#4h-making-this-test-less-brittle) - - [4i. Ensuring that only published articles are returned](#4i-ensuring-that-only-published-articles-are-returned) - - [4j. Ensuring that articles are returned in the correct order](#4j-ensuring-that-articles-are-returned-in-the-correct-order) - - [4k. Linking up the repository to the BlogPageController](#4k-linking-up-the-repository-to-the-blogpagecontroller) + - [4h. Ensuring that only articles are returned](#4h-ensuring-that-only-articles-are-returned) + - [4i. Making this test less brittle](#4i-making-this-test-less-brittle) + - [4j. Ensuring that only published articles are returned](#4j-ensuring-that-only-published-articles-are-returned) + - [4k. Ensuring that articles are returned in the correct order](#4k-ensuring-that-articles-are-returned-in-the-correct-order) + - [4l. Linking up the repository to the BlogPageController](#4l-linking-up-the-repository-to-the-blogpagecontroller) - [Step 5: Wrapping up with unit tests](#step-5-wrapping-up-with-unit-tests) - [5a. Creating an ArticleWrapper](#5a-creating-an-articlewrapper) - [5b. Ensure that we’re only wrapping articles](#5b-ensure-that-were-only-wrapping-articles) @@ -519,7 +520,7 @@ use Drupal\KernelTests\Core\Entity\EntityKernelTestBase; class ArticleRepositoryTest extends EntityKernelTestBase { /** @test */ - public function nodes_that_are_not_articles_are_not_returned() { + public function it_returns_blog_posts() { } @@ -538,8 +539,8 @@ We know that the end objective for this test is to have 3 article nodes returned ```diff /** @test */ - public function nodes_that_are_not_articles_are_not_returned() { -+ $this->assertCount(3, $articles); + public function it_returns_blog_posts() { ++ $this->assertCount(1, $articles); } ``` @@ -553,10 +554,10 @@ As the test name suggests, we’re going to be retrieving the articles from an ` ```diff /** @test */ - public function nodes_that_are_not_articles_are_not_returned() { + public function it_returns_blog_posts() { + $repository = $this->container->get(ArticleRepository::class); + - $this->assertCount(3, $articles); + $this->assertCount(1, $articles); } ``` @@ -617,7 +618,7 @@ We’ll use a `getAll()` method on the repository to retrieve the articles from $repository = $this->container->get(ArticleRepository::class); + $articles = $repository->getAll(); - $this->assertCount(3, $articles); + $this->assertCount(1, $articles); ``` This method doesn’t exist on the repository yet, so the test will fail. @@ -691,7 +692,7 @@ As we did previously, we need to enable the `node` module. The `ArticleRepository` is now working, but is still returning no articles - though this is because we haven’t created any inside the test. -> Failed asserting that actual size 0 matches expected size 3. +> Failed asserting that actual size 0 matches expected size 1. ### 4g. Adding articles @@ -713,12 +714,10 @@ Include the import statement at the top of the file if it hasn’t been added au This gives us a `createNode` method that we can use to create nodes by passing an array of values. -As we need 3 articles, let’s create them. +As we need an article to retrieve, let’s create one. ```diff -+ $this->createNode(['type' => 'article'])->save(); -+ $this->createNode(['type' => 'article'])->save(); -+ $this->createNode(['type' => 'article'])->save(); ++ $this->createNode(['type' => 'article', 'title' => 'Test post'])->save(); $repository = $this->container->get(ArticleRepository::class); $articles = $repository->getAll(); @@ -768,11 +767,46 @@ We also need to create the `node_access` table as indicated by the next error: } ``` -We’ve successfully returned our three articles and this test now passes. +We’ve successfully returned our article and this test now passes. > OK (1 test, 11 assertions) -### 4h. Making this test less brittle +Whilst the test is passing, let's add some additional assertions to check the type of object being returned and its title. + +```diff + $this->assertCount(1, $articles); ++ $this->assertIsObject($articles[1]); ++ $this->assertInstanceOf(NodeInterface::class, $articles[1]); ++ $this->assertSame('Test post', $articles[1]->label()); +``` + +> OK (1 test, 14 assertions) + +### 4h. Ensuring that only articles are returned + +Let's start with a new test, this time with three article nodes: + +```php +/** @test */ +public function nodes_that_are_not_articles_are_not_returned() { + $this->createNode(['type' => 'article'])->save(); + $this->createNode(['type' => 'article'])->save(); + $this->createNode(['type' => 'article'])->save(); + + $repository = $this->container->get(ArticleRepository::class); + $articles = $repository->getAll(); + + $this->assertCount(3, $articles); +} +``` + +Again, we can use the node creation trait to create the required content. + +As we already have the `ArticleRepository` in place, this test should pass straight away. + +> OK (1 test, 11 assertions) + +### 4i. Making this test less brittle The test is passing, but it currently returns _all_ nodes and not just articles. @@ -797,7 +831,7 @@ We can make a change to the `ArticleRepository` to fix this, and ensure that we + ]); ``` -### 4i. Ensuring that only published articles are returned +### 4j. Ensuring that only published articles are returned We now know that only article nodes are returned, but _all_ articles are being returned. On our blog, we only want to published articles to be displayed. @@ -852,7 +886,7 @@ With this added, the test passes again. > OK (1 test, 6 assertions) -### 4j. Ensuring that articles are returned in the correct order +### 4k. Ensuring that articles are returned in the correct order As per our acceptance criteria, we need the articles to be returned based on their created date, so let’s create another test. @@ -940,7 +974,7 @@ The nodes are now ordered by their created date, and in the correct order to mat > OK (1 test, 11 assertions) -### 4k. Linking up the repository to the BlogPageController +### 4l. Linking up the repository to the BlogPageController Now that our `ArticleRepository` tests are passing, we can use it within `BlogPageController` so that articles are displayed on the page. From e859418cbddc6e235e740c37fae1fc08237ec9c8 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Fri, 13 Mar 2020 22:18:55 +0000 Subject: [PATCH 28/77] Initial commit --- .ddev/config.yaml | 179 + .github/workflows/run-tests.yml | 50 + .gitignore | 17 + .idea/inspectionProfiles/Project_Default.xml | 6 + .idea/misc.xml | 6 + .idea/modules.xml | 8 + .idea/php-test-framework.xml | 14 + .idea/php.xml | 146 + .idea/vcs.xml | 6 + ...workshop-drupal-automated-testing-code.iml | 137 + README.md | 13 + composer.json | 57 + composer.lock | 8719 +++++++++++++++++ config/.gitkeep | 0 phpunit.xml.dist | 32 + web/sites/default/settings.php | 16 + workspace.yml | 11 + 17 files changed, 9417 insertions(+) create mode 100644 .ddev/config.yaml create mode 100644 .github/workflows/run-tests.yml create mode 100644 .gitignore create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/php-test-framework.xml create mode 100644 .idea/php.xml create mode 100644 .idea/vcs.xml create mode 100644 .idea/workshop-drupal-automated-testing-code.iml create mode 100644 README.md create mode 100644 composer.json create mode 100644 composer.lock create mode 100644 config/.gitkeep create mode 100644 phpunit.xml.dist create mode 100644 web/sites/default/settings.php create mode 100644 workspace.yml diff --git a/.ddev/config.yaml b/.ddev/config.yaml new file mode 100644 index 0000000..ead9756 --- /dev/null +++ b/.ddev/config.yaml @@ -0,0 +1,179 @@ +name: workshop-drupal-automated-testing +type: drupal8 +docroot: web +php_version: "7.4" +webserver_type: nginx-fpm +router_http_port: "80" +router_https_port: "443" +xdebug_enabled: false +additional_hostnames: [] +additional_fqdns: [] +mariadb_version: "10.3" +provider: default +use_dns_when_possible: true +working_dir: + web: /var/www/html + +hooks: + post-start: + - exec: | + if [ ! -f .flag-built ]; then + composer install + + vendor/bin/drush site:install -y \ + --site-name="Drupal Testing Workshop" \ + --account-pass=admin123 + + touch .flag-built + fi + +# This config.yaml was created with ddev version v1.15.3 +# webimage: drud/ddev-webserver:v1.15.3 +# dbimage: drud/ddev-dbserver-mariadb-10.2:v1.15.1 +# dbaimage: phpmyadmin/phpmyadmin:5 +# However we do not recommend explicitly wiring these images into the +# config.yaml as they may break future versions of ddev. +# You can update this config.yaml using 'ddev config'. + +# Key features of ddev's config.yaml: + +# name: # Name of the project, automatically provides +# http://projectname.ddev.site and https://projectname.ddev.site + +# type: # drupal6/7/8, backdrop, typo3, wordpress, php + +# docroot: # Relative path to the directory containing index.php. + +# php_version: "7.3" # PHP version to use, "5.6", "7.0", "7.1", "7.2", "7.3", "7.4" + +# You can explicitly specify the webimage, dbimage, dbaimage lines but this +# is not recommended, as the images are often closely tied to ddev's' behavior, +# so this can break upgrades. + +# webimage: # nginx/php docker image. +# dbimage: # mariadb docker image. +# dbaimage: + +# mariadb_version and mysql_version +# ddev can use many versions of mariadb and mysql +# However these directives are mutually exclusive +# mariadb_version: 10.2 +# mysql_version: 8.0 + +# router_http_port: # Port to be used for http (defaults to port 80) +# router_https_port: # Port for https (defaults to 443) + +# xdebug_enabled: false # Set to true to enable xdebug and "ddev start" or "ddev restart" +# Note that for most people the commands +# "ddev exec enable_xdebug" and "ddev exec disable_xdebug" work better, +# as leaving xdebug enabled all the time is a big performance hit. + +# webserver_type: nginx-fpm # Can be set to apache-fpm or apache-cgi as well + +# timezone: Europe/Berlin +# This is the timezone used in the containers and by PHP; +# it can be set to any valid timezone, +# see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones +# For example Europe/Dublin or MST7MDT + +# additional_hostnames: +# - somename +# - someothername +# would provide http and https URLs for "somename.ddev.site" +# and "someothername.ddev.site". + +# additional_fqdns: +# - example.com +# - sub1.example.com +# would provide http and https URLs for "example.com" and "sub1.example.com" +# Please take care with this because it can cause great confusion. + +# upload_dir: custom/upload/dir +# would set the destination path for ddev import-files to custom/upload/dir. + +# working_dir: +# web: /var/www/html +# db: /home +# would set the default working directory for the web and db services. +# These values specify the destination directory for ddev ssh and the +# directory in which commands passed into ddev exec are run. + +# omit_containers: [db, dba, ddev-ssh-agent] +# Currently only these containers are supported. Some containers can also be +# omitted globally in the ~/.ddev/global_config.yaml. Note that if you omit +# the "db" container, several standard features of ddev that access the +# database container will be unusable. + +# nfs_mount_enabled: false +# Great performance improvement but requires host configuration first. +# See https://ddev.readthedocs.io/en/stable/users/performance/#using-nfs-to-mount-the-project-into-the-container + +# host_https_port: "59002" +# The host port binding for https can be explicitly specified. It is +# dynamic unless otherwise specified. +# This is not used by most people, most people use the *router* instead +# of the localhost port. + +# host_webserver_port: "59001" +# The host port binding for the ddev-webserver can be explicitly specified. It is +# dynamic unless otherwise specified. +# This is not used by most people, most people use the *router* instead +# of the localhost port. + +# host_db_port: "59002" +# The host port binding for the ddev-dbserver can be explicitly specified. It is dynamic +# unless explicitly specified. + +# phpmyadmin_port: "8036" +# phpmyadmin_https_port: "8037" +# The PHPMyAdmin ports can be changed from the default 8036 and 8037 + +# mailhog_port: "8025" +# mailhog_https_port: "8026" +# The MailHog ports can be changed from the default 8025 and 8026 + +# webimage_extra_packages: [php7.3-tidy, php-bcmath] +# Extra Debian packages that are needed in the webimage can be added here + +# dbimage_extra_packages: [telnet,netcat] +# Extra Debian packages that are needed in the dbimage can be added here + +# use_dns_when_possible: true +# If the host has internet access and the domain configured can +# successfully be looked up, DNS will be used for hostname resolution +# instead of editing /etc/hosts +# Defaults to true + +# project_tld: ddev.site +# The top-level domain used for project URLs +# The default "ddev.site" allows DNS lookup via a wildcard +# If you prefer you can change this to "ddev.local" to preserve +# pre-v1.9 behavior. + +# ngrok_args: --subdomain mysite --auth username:pass +# Provide extra flags to the "ngrok http" command, see +# https://ngrok.com/docs#http or run "ngrok http -h" + +# disable_settings_management: false +# If true, ddev will not create CMS-specific settings files like +# Drupal's settings.php/settings.ddev.php or TYPO3's AdditionalSettings.php +# In this case the user must provide all such settings. + +# no_project_mount: false +# (Experimental) If true, ddev will not mount the project into the web container; +# the user is responsible for mounting it manually or via a script. +# This is to enable experimentation with alternate file mounting strategies. +# For advanced users only! + +# provider: default # Currently either "default" or "pantheon" +# +# Many ddev commands can be extended to run tasks before or after the +# ddev command is executed, for example "post-start", "post-import-db", +# "pre-composer", "post-composer" +# See https://ddev.readthedocs.io/en/stable/users/extending-commands/ for more +# information on the commands that can be extended and the tasks you can define +# for them. Example: +#hooks: +# post-import-db: +# - exec: drush cr +# - exec: drush updb diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml new file mode 100644 index 0000000..57f4c38 --- /dev/null +++ b/.github/workflows/run-tests.yml @@ -0,0 +1,50 @@ +name: Run tests + +on: push + +jobs: + tests: + runs-on: ubuntu-latest + + name: "Run ${{ matrix.test-types }} tests" + + strategy: + fail-fast: true + matrix: + test-types: + - functional + - kernel + - unit + + steps: + - name: Checkout code + uses: actions/checkout@a81bbbf + + - name: Cache dependencies + uses: actions/cache@d974700 + with: + path: | + ~/.composer/cache/files + vendor + web/core + key: dependencies-composer-${{ hashFiles('composer.json') }} + + - name: Setup PHP + uses: shivammathur/setup-php@5d27b8f + with: + php-version: 7.4 + extensions: mbstring + coverage: none + tools: composer:v1 + + - name: Install dependencies + run: composer install --prefer-dist --no-interaction --no-suggest + + - name: Start the local web server + run: php -S localhost:8000 -t web 2>&1 & + if: matrix.test-types == 'functional' + + - name: Execute tests + run: composer test -- --colors=always --testsuite=${{ matrix.test-types }} + env: + SIMPLETEST_BASE_URL: http://localhost:8000 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..32f0b75 --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ +* +!*/ +!/.ddev/** +!/.github/** +!/.gitignore +!/**/.gitkeep +!/.idea/** +!/composer.json +!/composer.lock +!/docker-compose.yaml +!/Makefile +!/php.ini +!/web/sites/default/settings.php +!/web/sites/default/settings.symfony.php +!/workspace.yml +/.idea/workspace.xml +/vendor/ diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..03d9549 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..28a804d --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..0d23deb --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/php-test-framework.xml b/.idea/php-test-framework.xml new file mode 100644 index 0000000..ac3134f --- /dev/null +++ b/.idea/php-test-framework.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/php.xml b/.idea/php.xml new file mode 100644 index 0000000..3f38e07 --- /dev/null +++ b/.idea/php.xml @@ -0,0 +1,146 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/workshop-drupal-automated-testing-code.iml b/.idea/workshop-drupal-automated-testing-code.iml new file mode 100644 index 0000000..33986f9 --- /dev/null +++ b/.idea/workshop-drupal-automated-testing-code.iml @@ -0,0 +1,137 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..4d788de --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# Drupal Automated Testing Workshop: Example Code + +## Updates + +If we need to update any of the commits, the changes should be rebased into the existing commits so that they continue to be in a linear order as per the workshop document. + +As we want GitHub Actions to run for each commit, we can’t just push the latest commit as that would only trigger a build on the final commit. To do this, we can loop over each of the commit SHAs and push each one separately: + +```bash +for sha1 in $(git rev-list HEAD --reverse); do + git push origin $sha1:main --force +done +``` diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..4a55556 --- /dev/null +++ b/composer.json @@ -0,0 +1,57 @@ +{ + "name": "opdavies/workshop-drupal-automated-testing-code", + "description": "Project template for Drupal 8 projects with a relocated document root", + "type": "project", + "license": "GPL-2.0-or-later", + "homepage": "https://www.drupal.org/project/drupal", + "support": { + "docs": "https://www.drupal.org/docs/user_guide/en/index.html", + "chat": "https://www.drupal.org/node/314178" + }, + "repositories": [ + { + "type": "composer", + "url": "https://packages.drupal.org/8" + } + ], + "require": { + "composer/installers": "^1.2", + "drupal/core-composer-scaffold": "^8.9", + "drupal/core-recommended": "^8.9", + "drush/drush": "^10" + }, + "require-dev": { + "drupal/core-dev": "^8.9" + }, + "conflict": { + "drupal/drupal": "*" + }, + "minimum-stability": "dev", + "prefer-stable": true, + "scripts": { + "phpunit": "phpunit --verbose --testdox --colors=always", + "test": [ + "@phpunit" + ] + }, + "config": { + "sort-packages": true + }, + "extra": { + "drupal-scaffold": { + "locations": { + "web-root": "web/" + } + }, + "installer-paths": { + "web/core": ["type:drupal-core"], + "web/libraries/{$name}": ["type:drupal-library"], + "web/modules/contrib/{$name}": ["type:drupal-module"], + "web/profiles/contrib/{$name}": ["type:drupal-profile"], + "web/themes/contrib/{$name}": ["type:drupal-theme"], + "drush/Commands/contrib/{$name}": ["type:drupal-drush"], + "web/modules/custom/{$name}": ["type:drupal-custom-module"], + "web/themes/custom/{$name}": ["type:drupal-custom-theme"] + } + } +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..4a0617d --- /dev/null +++ b/composer.lock @@ -0,0 +1,8719 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "0cacc6f4042304e22160df4c3d2ae048", + "packages": [ + { + "name": "asm89/stack-cors", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/asm89/stack-cors.git", + "reference": "b9c31def6a83f84b4d4a40d35996d375755f0e08" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/asm89/stack-cors/zipball/b9c31def6a83f84b4d4a40d35996d375755f0e08", + "reference": "b9c31def6a83f84b4d4a40d35996d375755f0e08", + "shasum": "" + }, + "require": { + "php": ">=5.5.9", + "symfony/http-foundation": "~2.7|~3.0|~4.0|~5.0", + "symfony/http-kernel": "~2.7|~3.0|~4.0|~5.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.0 || ^4.8.10", + "squizlabs/php_codesniffer": "^2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "psr-4": { + "Asm89\\Stack\\": "src/Asm89/Stack/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Alexander", + "email": "iam.asm89@gmail.com" + } + ], + "description": "Cross-origin resource sharing library and stack middleware", + "homepage": "https://github.com/asm89/stack-cors", + "keywords": [ + "cors", + "stack" + ], + "time": "2019-12-24T22:41:47+00:00" + }, + { + "name": "chi-teck/drupal-code-generator", + "version": "1.33.0", + "source": { + "type": "git", + "url": "https://github.com/Chi-teck/drupal-code-generator.git", + "reference": "49f4ce174ed83764e3389ddb75c4758772435243" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Chi-teck/drupal-code-generator/zipball/49f4ce174ed83764e3389ddb75c4758772435243", + "reference": "49f4ce174ed83764e3389ddb75c4758772435243", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": ">=5.5.9", + "symfony/console": "^3.4 || ^4.0", + "symfony/filesystem": "^2.7 || ^3.4 || ^4.0", + "twig/twig": "^1.41 || ^2.12" + }, + "conflict": { + "drush/drush": "< 10.3.2" + }, + "bin": [ + "bin/dcg" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "files": [ + "src/bootstrap.php" + ], + "psr-4": { + "DrupalCodeGenerator\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0-or-later" + ], + "description": "Drupal code generator", + "time": "2020-10-11T16:56:42+00:00" + }, + { + "name": "composer/installers", + "version": "v1.9.0", + "source": { + "type": "git", + "url": "https://github.com/composer/installers.git", + "reference": "b93bcf0fa1fccb0b7d176b0967d969691cd74cca" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/installers/zipball/b93bcf0fa1fccb0b7d176b0967d969691cd74cca", + "reference": "b93bcf0fa1fccb0b7d176b0967d969691cd74cca", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0 || ^2.0" + }, + "replace": { + "roundcube/plugin-installer": "*", + "shama/baton": "*" + }, + "require-dev": { + "composer/composer": "1.6.* || 2.0.*@dev", + "composer/semver": "1.0.* || 2.0.*@dev", + "phpunit/phpunit": "^4.8.36", + "sebastian/comparator": "^1.2.4", + "symfony/process": "^2.3" + }, + "type": "composer-plugin", + "extra": { + "class": "Composer\\Installers\\Plugin", + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Installers\\": "src/Composer/Installers" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kyle Robinson Young", + "email": "kyle@dontkry.com", + "homepage": "https://github.com/shama" + } + ], + "description": "A multi-framework Composer library installer", + "homepage": "https://composer.github.io/installers/", + "keywords": [ + "Craft", + "Dolibarr", + "Eliasis", + "Hurad", + "ImageCMS", + "Kanboard", + "Lan Management System", + "MODX Evo", + "MantisBT", + "Mautic", + "Maya", + "OXID", + "Plentymarkets", + "Porto", + "RadPHP", + "SMF", + "Thelia", + "Whmcs", + "WolfCMS", + "agl", + "aimeos", + "annotatecms", + "attogram", + "bitrix", + "cakephp", + "chef", + "cockpit", + "codeigniter", + "concrete5", + "croogo", + "dokuwiki", + "drupal", + "eZ Platform", + "elgg", + "expressionengine", + "fuelphp", + "grav", + "installer", + "itop", + "joomla", + "known", + "kohana", + "laravel", + "lavalite", + "lithium", + "magento", + "majima", + "mako", + "mediawiki", + "modulework", + "modx", + "moodle", + "osclass", + "phpbb", + "piwik", + "ppi", + "puppet", + "pxcms", + "reindex", + "roundcube", + "shopware", + "silverstripe", + "sydes", + "sylius", + "symfony", + "typo3", + "wordpress", + "yawik", + "zend", + "zikula" + ], + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2020-04-07T06:57:05+00:00" + }, + { + "name": "composer/semver", + "version": "1.5.1", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "c6bea70230ef4dd483e6bbcab6005f682ed3a8de" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/c6bea70230ef4dd483e6bbcab6005f682ed3a8de", + "reference": "c6bea70230ef4dd483e6bbcab6005f682ed3a8de", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.5 || ^5.0.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "time": "2020-01-13T12:06:48+00:00" + }, + { + "name": "consolidation/annotated-command", + "version": "2.12.1", + "source": { + "type": "git", + "url": "https://github.com/consolidation/annotated-command.git", + "reference": "0ee361762df2274f360c085e3239784a53f850b5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/annotated-command/zipball/0ee361762df2274f360c085e3239784a53f850b5", + "reference": "0ee361762df2274f360c085e3239784a53f850b5", + "shasum": "" + }, + "require": { + "consolidation/output-formatters": "^3.5.1", + "php": ">=5.4.5", + "psr/log": "^1", + "symfony/console": "^2.8|^3|^4", + "symfony/event-dispatcher": "^2.5|^3|^4", + "symfony/finder": "^2.5|^3|^4|^5" + }, + "require-dev": { + "g1a/composer-test-scenarios": "^3", + "php-coveralls/php-coveralls": "^1", + "phpunit/phpunit": "^6", + "squizlabs/php_codesniffer": "^2.7" + }, + "type": "library", + "extra": { + "scenarios": { + "finder5": { + "require": { + "symfony/finder": "^5" + }, + "config": { + "platform": { + "php": "7.2.5" + } + } + }, + "symfony4": { + "require": { + "symfony/console": "^4.0" + }, + "config": { + "platform": { + "php": "7.1.3" + } + } + }, + "symfony2": { + "require": { + "symfony/console": "^2.8" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.36" + }, + "remove": [ + "php-coveralls/php-coveralls" + ], + "config": { + "platform": { + "php": "5.4.8" + } + }, + "scenario-options": { + "create-lockfile": "false" + } + }, + "phpunit4": { + "require-dev": { + "phpunit/phpunit": "^4.8.36" + }, + "remove": [ + "php-coveralls/php-coveralls" + ], + "config": { + "platform": { + "php": "5.4.8" + } + } + } + }, + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Consolidation\\AnnotatedCommand\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + } + ], + "description": "Initialize Symfony Console commands from annotated command class methods.", + "time": "2020-10-11T04:30:03+00:00" + }, + { + "name": "consolidation/config", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/consolidation/config.git", + "reference": "cac1279bae7efb5c7fb2ca4c3ba4b8eb741a96c1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/config/zipball/cac1279bae7efb5c7fb2ca4c3ba4b8eb741a96c1", + "reference": "cac1279bae7efb5c7fb2ca4c3ba4b8eb741a96c1", + "shasum": "" + }, + "require": { + "dflydev/dot-access-data": "^1.1.0", + "grasmash/expander": "^1", + "php": ">=5.4.0" + }, + "require-dev": { + "g1a/composer-test-scenarios": "^3", + "php-coveralls/php-coveralls": "^1", + "phpunit/phpunit": "^5", + "squizlabs/php_codesniffer": "2.*", + "symfony/console": "^2.5|^3|^4", + "symfony/yaml": "^2.8.11|^3|^4" + }, + "suggest": { + "symfony/yaml": "Required to use Consolidation\\Config\\Loader\\YamlConfigLoader" + }, + "type": "library", + "extra": { + "scenarios": { + "symfony4": { + "require-dev": { + "symfony/console": "^4.0" + }, + "config": { + "platform": { + "php": "7.1.3" + } + } + }, + "symfony2": { + "require-dev": { + "symfony/console": "^2.8", + "symfony/event-dispatcher": "^2.8", + "phpunit/phpunit": "^4.8.36" + }, + "remove": [ + "php-coveralls/php-coveralls" + ], + "config": { + "platform": { + "php": "5.4.8" + } + } + } + }, + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Consolidation\\Config\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + } + ], + "description": "Provide configuration services for a commandline tool.", + "time": "2019-03-03T19:37:04+00:00" + }, + { + "name": "consolidation/filter-via-dot-access-data", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/consolidation/filter-via-dot-access-data.git", + "reference": "a53e96c6b9f7f042f5e085bf911f3493cea823c6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/filter-via-dot-access-data/zipball/a53e96c6b9f7f042f5e085bf911f3493cea823c6", + "reference": "a53e96c6b9f7f042f5e085bf911f3493cea823c6", + "shasum": "" + }, + "require": { + "dflydev/dot-access-data": "^1.1.0", + "php": ">=5.5.0" + }, + "require-dev": { + "consolidation/robo": "^1.2.3", + "g1a/composer-test-scenarios": "^3", + "knplabs/github-api": "^2.7", + "php-coveralls/php-coveralls": "^1", + "php-http/guzzle6-adapter": "^1.1", + "phpunit/phpunit": "^5", + "squizlabs/php_codesniffer": "^2.8", + "symfony/console": "^2.8|^3|^4" + }, + "type": "library", + "extra": { + "scenarios": { + "phpunit5": { + "require-dev": { + "phpunit/phpunit": "^5.7.27" + }, + "remove": [ + "php-coveralls/php-coveralls" + ], + "config": { + "platform": { + "php": "5.6.33" + } + } + } + }, + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Consolidation\\Filter\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + } + ], + "description": "This project uses dflydev/dot-access-data to provide simple output filtering for applications built with annotated-command / Robo.", + "time": "2019-01-18T06:05:07+00:00" + }, + { + "name": "consolidation/log", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/consolidation/log.git", + "reference": "b2e887325ee90abc96b0a8b7b474cd9e7c896e3a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/log/zipball/b2e887325ee90abc96b0a8b7b474cd9e7c896e3a", + "reference": "b2e887325ee90abc96b0a8b7b474cd9e7c896e3a", + "shasum": "" + }, + "require": { + "php": ">=5.4.5", + "psr/log": "^1.0", + "symfony/console": "^2.8|^3|^4" + }, + "require-dev": { + "g1a/composer-test-scenarios": "^3", + "php-coveralls/php-coveralls": "^1", + "phpunit/phpunit": "^6", + "squizlabs/php_codesniffer": "^2" + }, + "type": "library", + "extra": { + "scenarios": { + "symfony4": { + "require": { + "symfony/console": "^4.0" + }, + "config": { + "platform": { + "php": "7.1.3" + } + } + }, + "symfony2": { + "require": { + "symfony/console": "^2.8" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.36" + }, + "remove": [ + "php-coveralls/php-coveralls" + ], + "config": { + "platform": { + "php": "5.4.8" + } + } + }, + "phpunit4": { + "require-dev": { + "phpunit/phpunit": "^4.8.36" + }, + "remove": [ + "php-coveralls/php-coveralls" + ], + "config": { + "platform": { + "php": "5.4.8" + } + } + } + }, + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Consolidation\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + } + ], + "description": "Improved Psr-3 / Psr\\Log logger based on Symfony Console components.", + "time": "2019-01-01T17:30:51+00:00" + }, + { + "name": "consolidation/output-formatters", + "version": "3.5.1", + "source": { + "type": "git", + "url": "https://github.com/consolidation/output-formatters.git", + "reference": "0d38f13051ef05c223a2bb8e962d668e24785196" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/output-formatters/zipball/0d38f13051ef05c223a2bb8e962d668e24785196", + "reference": "0d38f13051ef05c223a2bb8e962d668e24785196", + "shasum": "" + }, + "require": { + "dflydev/dot-access-data": "^1.1.0", + "php": ">=5.4.0", + "symfony/console": "^2.8|^3|^4", + "symfony/finder": "^2.5|^3|^4|^5" + }, + "require-dev": { + "g1a/composer-test-scenarios": "^3", + "php-coveralls/php-coveralls": "^1", + "phpunit/phpunit": "^5.7.27", + "squizlabs/php_codesniffer": "^2.7", + "symfony/var-dumper": "^2.8|^3|^4", + "victorjonsson/markdowndocs": "^1.3" + }, + "suggest": { + "symfony/var-dumper": "For using the var_dump formatter" + }, + "type": "library", + "extra": { + "scenarios": { + "finder5": { + "require": { + "symfony/finder": "^5" + }, + "config": { + "platform": { + "php": "7.2.5" + } + } + }, + "symfony4": { + "require": { + "symfony/console": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^6" + }, + "config": { + "platform": { + "php": "7.1.3" + } + } + }, + "symfony3": { + "require": { + "symfony/console": "^3.4", + "symfony/finder": "^3.4", + "symfony/var-dumper": "^3.4" + }, + "config": { + "platform": { + "php": "5.6.32" + } + } + }, + "symfony2": { + "require": { + "symfony/console": "^2.8" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.36" + }, + "remove": [ + "php-coveralls/php-coveralls" + ], + "config": { + "platform": { + "php": "5.4.8" + } + }, + "scenario-options": { + "create-lockfile": "false" + } + } + }, + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Consolidation\\OutputFormatters\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + } + ], + "description": "Format text by applying transformations provided by plug-in formatters.", + "time": "2020-10-11T04:15:32+00:00" + }, + { + "name": "consolidation/robo", + "version": "1.4.13", + "source": { + "type": "git", + "url": "https://github.com/consolidation/Robo.git", + "reference": "fd28dcca1b935950ece26e63541fbdeeb09f7343" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/Robo/zipball/fd28dcca1b935950ece26e63541fbdeeb09f7343", + "reference": "fd28dcca1b935950ece26e63541fbdeeb09f7343", + "shasum": "" + }, + "require": { + "consolidation/annotated-command": "^2.12.1|^4.1", + "consolidation/config": "^1.2.1", + "consolidation/log": "^1.1.1|^2", + "consolidation/output-formatters": "^3.5.1|^4.1", + "consolidation/self-update": "^1.1.5", + "grasmash/yaml-expander": "^1.4", + "league/container": "^2.4.1", + "php": ">=5.5.0", + "symfony/console": "^2.8|^3|^4", + "symfony/event-dispatcher": "^2.5|^3|^4", + "symfony/filesystem": "^2.5|^3|^4", + "symfony/finder": "^2.5|^3|^4|^5", + "symfony/process": "^2.5|^3|^4" + }, + "replace": { + "codegyre/robo": "< 1.0" + }, + "require-dev": { + "g1a/composer-test-scenarios": "^3", + "natxet/cssmin": "3.0.4", + "patchwork/jsqueeze": "^2", + "pear/archive_tar": "^1.4.4", + "php-coveralls/php-coveralls": "^1", + "phpunit/phpunit": "^5.7.27", + "squizlabs/php_codesniffer": "^3" + }, + "suggest": { + "henrikbjorn/lurker": "For monitoring filesystem changes in taskWatch", + "natxet/CssMin": "For minifying CSS files in taskMinify", + "patchwork/jsqueeze": "For minifying JS files in taskMinify", + "pear/archive_tar": "Allows tar archives to be created and extracted in taskPack and taskExtract, respectively." + }, + "bin": [ + "robo" + ], + "type": "library", + "extra": { + "scenarios": { + "finder5": { + "require": { + "symfony/finder": "^5" + }, + "config": { + "platform": { + "php": "7.2.5" + } + } + }, + "symfony4": { + "require": { + "symfony/console": "^4" + }, + "config": { + "platform": { + "php": "7.1.3" + } + } + }, + "symfony2": { + "require": { + "symfony/console": "^2.8" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.36" + }, + "remove": [ + "php-coveralls/php-coveralls" + ], + "config": { + "platform": { + "php": "5.5.9" + } + }, + "scenario-options": { + "create-lockfile": "false" + } + } + }, + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Robo\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Davert", + "email": "davert.php@resend.cc" + } + ], + "description": "Modern task runner", + "time": "2020-10-11T04:51:34+00:00" + }, + { + "name": "consolidation/self-update", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/consolidation/self-update.git", + "reference": "dba6b2c0708f20fa3ba8008a2353b637578849b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/self-update/zipball/dba6b2c0708f20fa3ba8008a2353b637578849b4", + "reference": "dba6b2c0708f20fa3ba8008a2353b637578849b4", + "shasum": "" + }, + "require": { + "php": ">=5.5.0", + "symfony/console": "^2.8|^3|^4|^5", + "symfony/filesystem": "^2.5|^3|^4|^5" + }, + "bin": [ + "scripts/release" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "SelfUpdate\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Alexander Menk", + "email": "menk@mestrona.net" + }, + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + } + ], + "description": "Provides a self:update command for Symfony Console applications.", + "time": "2020-04-13T02:49:20+00:00" + }, + { + "name": "consolidation/site-alias", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/consolidation/site-alias.git", + "reference": "fd40a03f80f8fd4684b10bef8c8c4ec5a9a9bf26" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/site-alias/zipball/fd40a03f80f8fd4684b10bef8c8c4ec5a9a9bf26", + "reference": "fd40a03f80f8fd4684b10bef8c8c4ec5a9a9bf26", + "shasum": "" + }, + "require": { + "consolidation/config": "^1.2.1|^2", + "php": ">=5.5.0" + }, + "require-dev": { + "consolidation/robo": "^1.2.3|^2", + "g1a/composer-test-scenarios": "^3", + "knplabs/github-api": "^2.7", + "php-coveralls/php-coveralls": "^2.2", + "php-http/guzzle6-adapter": "^1.1", + "phpunit/phpunit": "^6", + "squizlabs/php_codesniffer": "^2.8", + "symfony/yaml": "~2.3|^3|^4.4|^5" + }, + "type": "library", + "extra": { + "scenarios": { + "phpunit5": { + "require-dev": { + "phpunit/phpunit": "^5.7.27" + }, + "remove": [ + "php-coveralls/php-coveralls" + ], + "config": { + "platform": { + "php": "5.6.33" + } + } + } + }, + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Consolidation\\SiteAlias\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + }, + { + "name": "Moshe Weitzman", + "email": "weitzman@tejasa.com" + } + ], + "description": "Manage alias records for local and remote sites.", + "time": "2020-05-28T00:33:41+00:00" + }, + { + "name": "consolidation/site-process", + "version": "2.1.0", + "source": { + "type": "git", + "url": "https://github.com/consolidation/site-process.git", + "reference": "f3211fa4c60671c6f068184221f06f932556e443" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/consolidation/site-process/zipball/f3211fa4c60671c6f068184221f06f932556e443", + "reference": "f3211fa4c60671c6f068184221f06f932556e443", + "shasum": "" + }, + "require": { + "consolidation/config": "^1.2.1", + "consolidation/site-alias": "^3", + "php": ">=5.6.0", + "symfony/process": "^3.4" + }, + "require-dev": { + "consolidation/robo": "^1.3", + "g1a/composer-test-scenarios": "^3", + "knplabs/github-api": "^2.7", + "php-coveralls/php-coveralls": "^1", + "php-http/guzzle6-adapter": "^1.1", + "phpunit/phpunit": "^6", + "squizlabs/php_codesniffer": "^2.8" + }, + "type": "library", + "extra": { + "scenarios": { + "phpunit5": { + "require-dev": { + "phpunit/phpunit": "^5.7.27" + }, + "remove": [ + "php-coveralls/php-coveralls" + ], + "config": { + "platform": { + "php": "5.6.33" + } + } + } + }, + "branch-alias": { + "dev-master": "0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Consolidation\\SiteProcess\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + }, + { + "name": "Moshe Weitzman", + "email": "weitzman@tejasa.com" + } + ], + "description": "A thin wrapper around the Symfony Process Component that allows applications to use the Site Alias library to specify the target for a remote call.", + "time": "2019-09-10T17:56:24+00:00" + }, + { + "name": "container-interop/container-interop", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/container-interop/container-interop.git", + "reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/container-interop/container-interop/zipball/79cbf1341c22ec75643d841642dd5d6acd83bdb8", + "reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8", + "shasum": "" + }, + "require": { + "psr/container": "^1.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Interop\\Container\\": "src/Interop/Container/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Promoting the interoperability of container objects (DIC, SL, etc.)", + "homepage": "https://github.com/container-interop/container-interop", + "abandoned": "psr/container", + "time": "2017-02-14T19:40:03+00:00" + }, + { + "name": "dflydev/dot-access-data", + "version": "v1.1.0", + "source": { + "type": "git", + "url": "https://github.com/dflydev/dflydev-dot-access-data.git", + "reference": "3fbd874921ab2c041e899d044585a2ab9795df8a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/3fbd874921ab2c041e899d044585a2ab9795df8a", + "reference": "3fbd874921ab2c041e899d044585a2ab9795df8a", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-0": { + "Dflydev\\DotAccessData": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dragonfly Development Inc.", + "email": "info@dflydev.com", + "homepage": "http://dflydev.com" + }, + { + "name": "Beau Simensen", + "email": "beau@dflydev.com", + "homepage": "http://beausimensen.com" + }, + { + "name": "Carlos Frutos", + "email": "carlos@kiwing.it", + "homepage": "https://github.com/cfrutos" + } + ], + "description": "Given a deep data structure, access data by dot notation.", + "homepage": "https://github.com/dflydev/dflydev-dot-access-data", + "keywords": [ + "access", + "data", + "dot", + "notation" + ], + "time": "2017-01-20T21:14:22+00:00" + }, + { + "name": "dnoegel/php-xdg-base-dir", + "version": "v0.1.1", + "source": { + "type": "git", + "url": "https://github.com/dnoegel/php-xdg-base-dir.git", + "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dnoegel/php-xdg-base-dir/zipball/8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd", + "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "~7.0|~6.0|~5.0|~4.8.35" + }, + "type": "library", + "autoload": { + "psr-4": { + "XdgBaseDir\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "implementation of xdg base directory specification for php", + "time": "2019-12-04T15:06:13+00:00" + }, + { + "name": "doctrine/annotations", + "version": "v1.4.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/annotations.git", + "reference": "54cacc9b81758b14e3ce750f205a393d52339e97" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/54cacc9b81758b14e3ce750f205a393d52339e97", + "reference": "54cacc9b81758b14e3ce750f205a393d52339e97", + "shasum": "" + }, + "require": { + "doctrine/lexer": "1.*", + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "doctrine/cache": "1.*", + "phpunit/phpunit": "^5.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Docblock Annotations Parser", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "annotations", + "docblock", + "parser" + ], + "time": "2017-02-24T16:22:25+00:00" + }, + { + "name": "doctrine/cache", + "version": "v1.6.2", + "source": { + "type": "git", + "url": "https://github.com/doctrine/cache.git", + "reference": "eb152c5100571c7a45470ff2a35095ab3f3b900b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/cache/zipball/eb152c5100571c7a45470ff2a35095ab3f3b900b", + "reference": "eb152c5100571c7a45470ff2a35095ab3f3b900b", + "shasum": "" + }, + "require": { + "php": "~5.5|~7.0" + }, + "conflict": { + "doctrine/common": ">2.2,<2.4" + }, + "require-dev": { + "phpunit/phpunit": "~4.8|~5.0", + "predis/predis": "~1.0", + "satooshi/php-coveralls": "~0.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Caching library offering an object-oriented API for many cache backends", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "cache", + "caching" + ], + "time": "2017-07-22T12:49:21+00:00" + }, + { + "name": "doctrine/collections", + "version": "v1.4.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/collections.git", + "reference": "1a4fb7e902202c33cce8c55989b945612943c2ba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/collections/zipball/1a4fb7e902202c33cce8c55989b945612943c2ba", + "reference": "1a4fb7e902202c33cce8c55989b945612943c2ba", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "doctrine/coding-standard": "~0.1@dev", + "phpunit/phpunit": "^5.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\Common\\Collections\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Collections Abstraction library", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "array", + "collections", + "iterator" + ], + "time": "2017-01-03T10:49:41+00:00" + }, + { + "name": "doctrine/common", + "version": "v2.7.3", + "source": { + "type": "git", + "url": "https://github.com/doctrine/common.git", + "reference": "4acb8f89626baafede6ee5475bc5844096eba8a9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/common/zipball/4acb8f89626baafede6ee5475bc5844096eba8a9", + "reference": "4acb8f89626baafede6ee5475bc5844096eba8a9", + "shasum": "" + }, + "require": { + "doctrine/annotations": "1.*", + "doctrine/cache": "1.*", + "doctrine/collections": "1.*", + "doctrine/inflector": "1.*", + "doctrine/lexer": "1.*", + "php": "~5.6|~7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.4.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\": "lib/Doctrine/Common" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Common Library for Doctrine projects", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "annotations", + "collections", + "eventmanager", + "persistence", + "spl" + ], + "time": "2017-07-22T08:35:12+00:00" + }, + { + "name": "doctrine/inflector", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/inflector.git", + "reference": "e11d84c6e018beedd929cff5220969a3c6d1d462" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/e11d84c6e018beedd929cff5220969a3c6d1d462", + "reference": "e11d84c6e018beedd929cff5220969a3c6d1d462", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\Inflector\\": "lib/Doctrine/Common/Inflector" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Common String Manipulations with regard to casing and singular/plural rules.", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "inflection", + "pluralize", + "singularize", + "string" + ], + "time": "2017-07-22T12:18:28+00:00" + }, + { + "name": "doctrine/lexer", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "1febd6c3ef84253d7c815bed85fc622ad207a9f8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/1febd6c3ef84253d7c815bed85fc622ad207a9f8", + "reference": "1febd6c3ef84253d7c815bed85fc622ad207a9f8", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "^4.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "https://www.doctrine-project.org/projects/lexer.html", + "keywords": [ + "annotations", + "docblock", + "lexer", + "parser", + "php" + ], + "time": "2019-06-08T11:03:04+00:00" + }, + { + "name": "drupal/core", + "version": "8.9.8", + "source": { + "type": "git", + "url": "https://github.com/drupal/core.git", + "reference": "e16f650e7bd7f0cfb4ff4dd8ed753625313cdfdb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/drupal/core/zipball/e16f650e7bd7f0cfb4ff4dd8ed753625313cdfdb", + "reference": "e16f650e7bd7f0cfb4ff4dd8ed753625313cdfdb", + "shasum": "" + }, + "require": { + "asm89/stack-cors": "^1.1", + "composer/semver": "^1.0", + "doctrine/annotations": "^1.4", + "doctrine/common": "^2.7", + "easyrdf/easyrdf": "^0.9", + "egulias/email-validator": "^2.0", + "ext-date": "*", + "ext-dom": "*", + "ext-filter": "*", + "ext-gd": "*", + "ext-hash": "*", + "ext-json": "*", + "ext-pcre": "*", + "ext-pdo": "*", + "ext-session": "*", + "ext-simplexml": "*", + "ext-spl": "*", + "ext-tokenizer": "*", + "ext-xml": "*", + "guzzlehttp/guzzle": "^6.3", + "laminas/laminas-diactoros": "^1.8", + "laminas/laminas-feed": "^2.12", + "masterminds/html5": "^2.1", + "pear/archive_tar": "^1.4.9", + "php": ">=7.0.8", + "psr/log": "^1.0", + "stack/builder": "^1.0", + "symfony-cmf/routing": "^1.4", + "symfony/class-loader": "~3.4.0", + "symfony/console": "~3.4.0", + "symfony/dependency-injection": "~3.4.26", + "symfony/event-dispatcher": "~3.4.0", + "symfony/http-foundation": "~3.4.35", + "symfony/http-kernel": "~3.4.14", + "symfony/polyfill-iconv": "^1.0", + "symfony/process": "~3.4.0", + "symfony/psr-http-message-bridge": "^1.1.2", + "symfony/routing": "~3.4.0", + "symfony/serializer": "~3.4.0", + "symfony/translation": "~3.4.0", + "symfony/validator": "~3.4.0", + "symfony/yaml": "~3.4.5", + "twig/twig": "^1.38.2", + "typo3/phar-stream-wrapper": "^3.1.3" + }, + "conflict": { + "drupal/pathauto": "<1.6", + "drush/drush": "<8.1.10" + }, + "replace": { + "drupal/action": "self.version", + "drupal/aggregator": "self.version", + "drupal/automated_cron": "self.version", + "drupal/ban": "self.version", + "drupal/bartik": "self.version", + "drupal/basic_auth": "self.version", + "drupal/big_pipe": "self.version", + "drupal/block": "self.version", + "drupal/block_content": "self.version", + "drupal/block_place": "self.version", + "drupal/book": "self.version", + "drupal/breakpoint": "self.version", + "drupal/ckeditor": "self.version", + "drupal/claro": "self.version", + "drupal/classy": "self.version", + "drupal/color": "self.version", + "drupal/comment": "self.version", + "drupal/config": "self.version", + "drupal/config_translation": "self.version", + "drupal/contact": "self.version", + "drupal/content_moderation": "self.version", + "drupal/content_translation": "self.version", + "drupal/contextual": "self.version", + "drupal/core-annotation": "self.version", + "drupal/core-assertion": "self.version", + "drupal/core-bridge": "self.version", + "drupal/core-class-finder": "self.version", + "drupal/core-datetime": "self.version", + "drupal/core-dependency-injection": "self.version", + "drupal/core-diff": "self.version", + "drupal/core-discovery": "self.version", + "drupal/core-event-dispatcher": "self.version", + "drupal/core-file-cache": "self.version", + "drupal/core-file-security": "self.version", + "drupal/core-filesystem": "self.version", + "drupal/core-gettext": "self.version", + "drupal/core-graph": "self.version", + "drupal/core-http-foundation": "self.version", + "drupal/core-php-storage": "self.version", + "drupal/core-plugin": "self.version", + "drupal/core-proxy-builder": "self.version", + "drupal/core-render": "self.version", + "drupal/core-serialization": "self.version", + "drupal/core-transliteration": "self.version", + "drupal/core-utility": "self.version", + "drupal/core-uuid": "self.version", + "drupal/core-version": "self.version", + "drupal/datetime": "self.version", + "drupal/datetime_range": "self.version", + "drupal/dblog": "self.version", + "drupal/dynamic_page_cache": "self.version", + "drupal/editor": "self.version", + "drupal/entity_reference": "self.version", + "drupal/field": "self.version", + "drupal/field_layout": "self.version", + "drupal/field_ui": "self.version", + "drupal/file": "self.version", + "drupal/filter": "self.version", + "drupal/forum": "self.version", + "drupal/hal": "self.version", + "drupal/help": "self.version", + "drupal/help_topics": "self.version", + "drupal/history": "self.version", + "drupal/image": "self.version", + "drupal/inline_form_errors": "self.version", + "drupal/jsonapi": "self.version", + "drupal/language": "self.version", + "drupal/layout_builder": "self.version", + "drupal/layout_discovery": "self.version", + "drupal/link": "self.version", + "drupal/locale": "self.version", + "drupal/media": "self.version", + "drupal/media_library": "self.version", + "drupal/menu_link_content": "self.version", + "drupal/menu_ui": "self.version", + "drupal/migrate": "self.version", + "drupal/migrate_drupal": "self.version", + "drupal/migrate_drupal_multilingual": "self.version", + "drupal/migrate_drupal_ui": "self.version", + "drupal/minimal": "self.version", + "drupal/node": "self.version", + "drupal/options": "self.version", + "drupal/page_cache": "self.version", + "drupal/path": "self.version", + "drupal/path_alias": "self.version", + "drupal/quickedit": "self.version", + "drupal/rdf": "self.version", + "drupal/responsive_image": "self.version", + "drupal/rest": "self.version", + "drupal/search": "self.version", + "drupal/serialization": "self.version", + "drupal/settings_tray": "self.version", + "drupal/seven": "self.version", + "drupal/shortcut": "self.version", + "drupal/simpletest": "self.version", + "drupal/standard": "self.version", + "drupal/stark": "self.version", + "drupal/statistics": "self.version", + "drupal/syslog": "self.version", + "drupal/system": "self.version", + "drupal/taxonomy": "self.version", + "drupal/telephone": "self.version", + "drupal/text": "self.version", + "drupal/toolbar": "self.version", + "drupal/tour": "self.version", + "drupal/tracker": "self.version", + "drupal/update": "self.version", + "drupal/user": "self.version", + "drupal/views": "self.version", + "drupal/views_ui": "self.version", + "drupal/workflows": "self.version", + "drupal/workspaces": "self.version" + }, + "type": "drupal-core", + "extra": { + "drupal-scaffold": { + "file-mapping": { + "[project-root]/.editorconfig": "assets/scaffold/files/editorconfig", + "[project-root]/.gitattributes": "assets/scaffold/files/gitattributes", + "[web-root]/.csslintrc": "assets/scaffold/files/csslintrc", + "[web-root]/.eslintignore": "assets/scaffold/files/eslintignore", + "[web-root]/.eslintrc.json": "assets/scaffold/files/eslintrc.json", + "[web-root]/.ht.router.php": "assets/scaffold/files/ht.router.php", + "[web-root]/.htaccess": "assets/scaffold/files/htaccess", + "[web-root]/example.gitignore": "assets/scaffold/files/example.gitignore", + "[web-root]/index.php": "assets/scaffold/files/index.php", + "[web-root]/INSTALL.txt": "assets/scaffold/files/drupal.INSTALL.txt", + "[web-root]/README.txt": "assets/scaffold/files/drupal.README.txt", + "[web-root]/robots.txt": "assets/scaffold/files/robots.txt", + "[web-root]/update.php": "assets/scaffold/files/update.php", + "[web-root]/web.config": "assets/scaffold/files/web.config", + "[web-root]/sites/README.txt": "assets/scaffold/files/sites.README.txt", + "[web-root]/sites/development.services.yml": "assets/scaffold/files/development.services.yml", + "[web-root]/sites/example.settings.local.php": "assets/scaffold/files/example.settings.local.php", + "[web-root]/sites/example.sites.php": "assets/scaffold/files/example.sites.php", + "[web-root]/sites/default/default.services.yml": "assets/scaffold/files/default.services.yml", + "[web-root]/sites/default/default.settings.php": "assets/scaffold/files/default.settings.php", + "[web-root]/modules/README.txt": "assets/scaffold/files/modules.README.txt", + "[web-root]/profiles/README.txt": "assets/scaffold/files/profiles.README.txt", + "[web-root]/themes/README.txt": "assets/scaffold/files/themes.README.txt" + } + } + }, + "autoload": { + "psr-4": { + "Drupal\\Core\\": "lib/Drupal/Core", + "Drupal\\Component\\": "lib/Drupal/Component", + "Drupal\\Driver\\": "../drivers/lib/Drupal/Driver" + }, + "classmap": [ + "lib/Drupal.php", + "lib/Drupal/Component/Utility/Timer.php", + "lib/Drupal/Component/Utility/Unicode.php", + "lib/Drupal/Core/Database/Database.php", + "lib/Drupal/Core/DrupalKernel.php", + "lib/Drupal/Core/DrupalKernelInterface.php", + "lib/Drupal/Core/Site/Settings.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0-or-later" + ], + "description": "Drupal is an open source content management platform powering millions of websites and applications.", + "time": "2020-11-05T16:34:55+00:00" + }, + { + "name": "drupal/core-composer-scaffold", + "version": "8.9.8", + "source": { + "type": "git", + "url": "https://github.com/drupal/core-composer-scaffold.git", + "reference": "c902d07cb49ef73777e2b33a39e54c2861a8c81d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/drupal/core-composer-scaffold/zipball/c902d07cb49ef73777e2b33a39e54c2861a8c81d", + "reference": "c902d07cb49ef73777e2b33a39e54c2861a8c81d", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1 || ^2", + "php": ">=7.0.8" + }, + "conflict": { + "drupal-composer/drupal-scaffold": "*" + }, + "require-dev": { + "composer/composer": "^1.8@stable" + }, + "type": "composer-plugin", + "extra": { + "class": "Drupal\\Composer\\Plugin\\Scaffold\\Plugin", + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Drupal\\Composer\\Plugin\\Scaffold\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0-or-later" + ], + "description": "A flexible Composer project scaffold builder.", + "homepage": "https://www.drupal.org/project/drupal", + "keywords": [ + "drupal" + ], + "time": "2020-08-07T22:30:30+00:00" + }, + { + "name": "drupal/core-recommended", + "version": "8.9.8", + "source": { + "type": "git", + "url": "https://github.com/drupal/core-recommended.git", + "reference": "561766436ccc17aa03362d740b004375fcc4d514" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/drupal/core-recommended/zipball/561766436ccc17aa03362d740b004375fcc4d514", + "reference": "561766436ccc17aa03362d740b004375fcc4d514", + "shasum": "" + }, + "require": { + "asm89/stack-cors": "1.3.0", + "composer/semver": "1.5.1", + "doctrine/annotations": "v1.4.0", + "doctrine/cache": "v1.6.2", + "doctrine/collections": "v1.4.0", + "doctrine/common": "v2.7.3", + "doctrine/inflector": "v1.2.0", + "doctrine/lexer": "1.0.2", + "drupal/core": "8.9.8", + "easyrdf/easyrdf": "0.9.1", + "egulias/email-validator": "2.1.17", + "guzzlehttp/guzzle": "6.5.4", + "guzzlehttp/promises": "v1.3.1", + "guzzlehttp/psr7": "1.6.1", + "laminas/laminas-diactoros": "1.8.7p2", + "laminas/laminas-escaper": "2.6.1", + "laminas/laminas-feed": "2.12.2", + "laminas/laminas-stdlib": "3.2.1", + "laminas/laminas-zendframework-bridge": "1.0.4", + "masterminds/html5": "2.3.0", + "paragonie/random_compat": "v9.99.99", + "pear/archive_tar": "1.4.9", + "pear/console_getopt": "v1.4.3", + "pear/pear-core-minimal": "v1.10.10", + "pear/pear_exception": "v1.0.1", + "psr/container": "1.0.0", + "psr/http-message": "1.0.1", + "psr/log": "1.1.3", + "ralouphie/getallheaders": "3.0.3", + "stack/builder": "v1.0.5", + "symfony-cmf/routing": "1.4.1", + "symfony/class-loader": "v3.4.41", + "symfony/console": "v3.4.41", + "symfony/debug": "v3.4.41", + "symfony/dependency-injection": "v3.4.41", + "symfony/event-dispatcher": "v3.4.41", + "symfony/http-foundation": "v3.4.41", + "symfony/http-kernel": "v3.4.44", + "symfony/polyfill-ctype": "v1.17.0", + "symfony/polyfill-iconv": "v1.17.0", + "symfony/polyfill-intl-idn": "v1.17.0", + "symfony/polyfill-mbstring": "v1.17.0", + "symfony/polyfill-php56": "v1.17.0", + "symfony/polyfill-php70": "v1.17.0", + "symfony/polyfill-php72": "v1.17.0", + "symfony/polyfill-util": "v1.17.0", + "symfony/process": "v3.4.41", + "symfony/psr-http-message-bridge": "v1.1.2", + "symfony/routing": "v3.4.41", + "symfony/serializer": "v3.4.41", + "symfony/translation": "v3.4.41", + "symfony/validator": "v3.4.41", + "symfony/yaml": "v3.4.41", + "twig/twig": "v1.42.5", + "typo3/phar-stream-wrapper": "v3.1.4" + }, + "conflict": { + "webflo/drupal-core-strict": "*" + }, + "type": "metapackage", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0-or-later" + ], + "description": "Locked core dependencies; require this project INSTEAD OF drupal/core.", + "time": "2020-11-05T16:34:55+00:00" + }, + { + "name": "drush/drush", + "version": "10.3.6", + "source": { + "type": "git", + "url": "https://github.com/drush-ops/drush.git", + "reference": "fc985a95c6010e04891a2dbcf3f39984b8c9ef0a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/drush-ops/drush/zipball/fc985a95c6010e04891a2dbcf3f39984b8c9ef0a", + "reference": "fc985a95c6010e04891a2dbcf3f39984b8c9ef0a", + "shasum": "" + }, + "require": { + "chi-teck/drupal-code-generator": "^1.32.1", + "composer/semver": "^1.4 || ^3", + "consolidation/config": "^1.2", + "consolidation/filter-via-dot-access-data": "^1", + "consolidation/robo": "^1.4.11 || ^2", + "consolidation/site-alias": "^3.0.0@stable", + "consolidation/site-process": "^2.1 || ^4", + "ext-dom": "*", + "grasmash/yaml-expander": "^1.1.1", + "guzzlehttp/guzzle": "^6.3 || ^7.0", + "league/container": "~2", + "php": ">=7.1.3", + "psr/log": "~1.0", + "psy/psysh": "~0.6", + "symfony/event-dispatcher": "^3.4 || ^4.0", + "symfony/finder": "^3.4 || ^4.0 || ^5", + "symfony/var-dumper": "^3.4 || ^4.0 || ^5.0", + "symfony/yaml": "^3.4 || ^4.0", + "webflo/drupal-finder": "^1.2", + "webmozart/path-util": "^2.1.0" + }, + "require-dev": { + "composer/installers": "^1.7", + "cweagans/composer-patches": "~1.0", + "david-garcia/phpwhois": "4.3.0", + "drupal/alinks": "1.0.0", + "drupal/core-recommended": "^8.8", + "lox/xhprof": "dev-master", + "phpunit/phpunit": "^4.8.36 || ^6.1", + "squizlabs/php_codesniffer": "^2.7 || ^3", + "vlucas/phpdotenv": "^2.4" + }, + "bin": [ + "drush" + ], + "type": "library", + "extra": { + "installer-paths": { + "sut/core": [ + "type:drupal-core" + ], + "sut/libraries/{$name}": [ + "type:drupal-library" + ], + "sut/modules/unish/{$name}": [ + "drupal/devel" + ], + "sut/themes/unish/{$name}": [ + "drupal/empty_theme" + ], + "sut/modules/contrib/{$name}": [ + "type:drupal-module" + ], + "sut/profiles/contrib/{$name}": [ + "type:drupal-profile" + ], + "sut/themes/contrib/{$name}": [ + "type:drupal-theme" + ], + "sut/drush/contrib/{$name}": [ + "type:drupal-drush" + ] + } + }, + "autoload": { + "psr-4": { + "Drush\\": "src/", + "Drush\\Internal\\": "src/internal-forks" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "Moshe Weitzman", + "email": "weitzman@tejasa.com" + }, + { + "name": "Owen Barton", + "email": "drupal@owenbarton.com" + }, + { + "name": "Greg Anderson", + "email": "greg.1.anderson@greenknowe.org" + }, + { + "name": "Jonathan Araña Cruz", + "email": "jonhattan@faita.net" + }, + { + "name": "Jonathan Hedstrom", + "email": "jhedstrom@gmail.com" + }, + { + "name": "Christopher Gervais", + "email": "chris@ergonlogic.com" + }, + { + "name": "Dave Reid", + "email": "dave@davereid.net" + }, + { + "name": "Damian Lee", + "email": "damiankloip@googlemail.com" + } + ], + "description": "Drush is a command line shell and scripting interface for Drupal, a veritable Swiss Army knife designed to make life easier for those of us who spend some of our working hours hacking away at the command prompt.", + "homepage": "http://www.drush.org", + "funding": [ + { + "url": "https://github.com/weitzman", + "type": "github" + } + ], + "time": "2020-11-11T04:36:51+00:00" + }, + { + "name": "easyrdf/easyrdf", + "version": "0.9.1", + "source": { + "type": "git", + "url": "https://github.com/easyrdf/easyrdf.git", + "reference": "acd09dfe0555fbcfa254291e433c45fdd4652566" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/easyrdf/easyrdf/zipball/acd09dfe0555fbcfa254291e433c45fdd4652566", + "reference": "acd09dfe0555fbcfa254291e433c45fdd4652566", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "ext-pcre": "*", + "php": ">=5.2.8" + }, + "require-dev": { + "phpunit/phpunit": "~3.5", + "sami/sami": "~1.4", + "squizlabs/php_codesniffer": "~1.4.3" + }, + "suggest": { + "ml/json-ld": "~1.0" + }, + "type": "library", + "autoload": { + "psr-0": { + "EasyRdf_": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nicholas Humfrey", + "email": "njh@aelius.com", + "homepage": "http://www.aelius.com/njh/", + "role": "Developer" + }, + { + "name": "Alexey Zakhlestin", + "email": "indeyets@gmail.com", + "role": "Developer" + } + ], + "description": "EasyRdf is a PHP library designed to make it easy to consume and produce RDF.", + "homepage": "http://www.easyrdf.org/", + "keywords": [ + "Linked Data", + "RDF", + "Semantic Web", + "Turtle", + "rdfa", + "sparql" + ], + "time": "2015-02-27T09:45:49+00:00" + }, + { + "name": "egulias/email-validator", + "version": "2.1.17", + "source": { + "type": "git", + "url": "https://github.com/egulias/EmailValidator.git", + "reference": "ade6887fd9bd74177769645ab5c474824f8a418a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/ade6887fd9bd74177769645ab5c474824f8a418a", + "reference": "ade6887fd9bd74177769645ab5c474824f8a418a", + "shasum": "" + }, + "require": { + "doctrine/lexer": "^1.0.1", + "php": ">=5.5", + "symfony/polyfill-intl-idn": "^1.10" + }, + "require-dev": { + "dominicsayers/isemail": "^3.0.7", + "phpunit/phpunit": "^4.8.36|^7.5.15", + "satooshi/php-coveralls": "^1.0.1" + }, + "suggest": { + "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Egulias\\EmailValidator\\": "EmailValidator" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eduardo Gulias Davis" + } + ], + "description": "A library for validating emails against several RFCs", + "homepage": "https://github.com/egulias/EmailValidator", + "keywords": [ + "email", + "emailvalidation", + "emailvalidator", + "validation", + "validator" + ], + "time": "2020-02-13T22:36:52+00:00" + }, + { + "name": "grasmash/expander", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/grasmash/expander.git", + "reference": "95d6037344a4be1dd5f8e0b0b2571a28c397578f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/grasmash/expander/zipball/95d6037344a4be1dd5f8e0b0b2571a28c397578f", + "reference": "95d6037344a4be1dd5f8e0b0b2571a28c397578f", + "shasum": "" + }, + "require": { + "dflydev/dot-access-data": "^1.1.0", + "php": ">=5.4" + }, + "require-dev": { + "greg-1-anderson/composer-test-scenarios": "^1", + "phpunit/phpunit": "^4|^5.5.4", + "satooshi/php-coveralls": "^1.0.2|dev-master", + "squizlabs/php_codesniffer": "^2.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Grasmash\\Expander\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Matthew Grasmick" + } + ], + "description": "Expands internal property references in PHP arrays file.", + "time": "2017-12-21T22:14:55+00:00" + }, + { + "name": "grasmash/yaml-expander", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/grasmash/yaml-expander.git", + "reference": "3f0f6001ae707a24f4d9733958d77d92bf9693b1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/grasmash/yaml-expander/zipball/3f0f6001ae707a24f4d9733958d77d92bf9693b1", + "reference": "3f0f6001ae707a24f4d9733958d77d92bf9693b1", + "shasum": "" + }, + "require": { + "dflydev/dot-access-data": "^1.1.0", + "php": ">=5.4", + "symfony/yaml": "^2.8.11|^3|^4" + }, + "require-dev": { + "greg-1-anderson/composer-test-scenarios": "^1", + "phpunit/phpunit": "^4.8|^5.5.4", + "satooshi/php-coveralls": "^1.0.2|dev-master", + "squizlabs/php_codesniffer": "^2.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Grasmash\\YamlExpander\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Matthew Grasmick" + } + ], + "description": "Expands internal property references in a yaml file.", + "time": "2017-12-16T16:06:03+00:00" + }, + { + "name": "guzzlehttp/guzzle", + "version": "6.5.4", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "a4a1b6930528a8f7ee03518e6442ec7a44155d9d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/a4a1b6930528a8f7ee03518e6442ec7a44155d9d", + "reference": "a4a1b6930528a8f7ee03518e6442ec7a44155d9d", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^1.0", + "guzzlehttp/psr7": "^1.6.1", + "php": ">=5.5", + "symfony/polyfill-intl-idn": "1.17.0" + }, + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0", + "psr/log": "^1.1" + }, + "suggest": { + "psr/log": "Required for using the Log middleware" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.5-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ], + "time": "2020-05-25T19:35:05+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "v1.3.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646", + "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646", + "shasum": "" + }, + "require": { + "php": ">=5.5.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "time": "2016-12-20T10:07:11+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "1.6.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "239400de7a173fe9901b9ac7c06497751f00727a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/239400de7a173fe9901b9ac7c06497751f00727a", + "reference": "239400de7a173fe9901b9ac7c06497751f00727a", + "shasum": "" + }, + "require": { + "php": ">=5.4.0", + "psr/http-message": "~1.0", + "ralouphie/getallheaders": "^2.0.5 || ^3.0.0" + }, + "provide": { + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "ext-zlib": "*", + "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8" + }, + "suggest": { + "zendframework/zend-httphandlerrunner": "Emit PSR-7 responses" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Schultze", + "homepage": "https://github.com/Tobion" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" + ], + "time": "2019-07-01T23:21:34+00:00" + }, + { + "name": "laminas/laminas-diactoros", + "version": "1.8.7p2", + "source": { + "type": "git", + "url": "https://github.com/laminas/laminas-diactoros.git", + "reference": "6991c1af7c8d2c8efee81b22ba97024781824aaa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laminas/laminas-diactoros/zipball/6991c1af7c8d2c8efee81b22ba97024781824aaa", + "reference": "6991c1af7c8d2c8efee81b22ba97024781824aaa", + "shasum": "" + }, + "require": { + "laminas/laminas-zendframework-bridge": "^1.0", + "php": "^5.6 || ^7.0", + "psr/http-message": "^1.0" + }, + "provide": { + "psr/http-message-implementation": "1.0" + }, + "replace": { + "zendframework/zend-diactoros": "~1.8.7.0" + }, + "require-dev": { + "ext-dom": "*", + "ext-libxml": "*", + "laminas/laminas-coding-standard": "~1.0", + "php-http/psr7-integration-tests": "dev-master", + "phpunit/phpunit": "^5.7.16 || ^6.0.8 || ^7.2.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-release-1.8": "1.8.x-dev" + } + }, + "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-7" + ], + "time": "2020-03-23T15:28:28+00:00" + }, + { + "name": "laminas/laminas-escaper", + "version": "2.6.1", + "source": { + "type": "git", + "url": "https://github.com/laminas/laminas-escaper.git", + "reference": "25f2a053eadfa92ddacb609dcbbc39362610da70" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laminas/laminas-escaper/zipball/25f2a053eadfa92ddacb609dcbbc39362610da70", + "reference": "25f2a053eadfa92ddacb609dcbbc39362610da70", + "shasum": "" + }, + "require": { + "laminas/laminas-zendframework-bridge": "^1.0", + "php": "^5.6 || ^7.0" + }, + "replace": { + "zendframework/zend-escaper": "self.version" + }, + "require-dev": { + "laminas/laminas-coding-standard": "~1.0.0", + "phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6.x-dev", + "dev-develop": "2.7.x-dev" + } + }, + "autoload": { + "psr-4": { + "Laminas\\Escaper\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Securely and safely escape HTML, HTML attributes, JavaScript, CSS, and URLs", + "homepage": "https://laminas.dev", + "keywords": [ + "escaper", + "laminas" + ], + "time": "2019-12-31T16:43:30+00:00" + }, + { + "name": "laminas/laminas-feed", + "version": "2.12.2", + "source": { + "type": "git", + "url": "https://github.com/laminas/laminas-feed.git", + "reference": "8a193ac96ebcb3e16b6ee754ac2a889eefacb654" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laminas/laminas-feed/zipball/8a193ac96ebcb3e16b6ee754ac2a889eefacb654", + "reference": "8a193ac96ebcb3e16b6ee754ac2a889eefacb654", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "laminas/laminas-escaper": "^2.5.2", + "laminas/laminas-stdlib": "^3.2.1", + "laminas/laminas-zendframework-bridge": "^1.0", + "php": "^5.6 || ^7.0" + }, + "replace": { + "zendframework/zend-feed": "^2.12.0" + }, + "require-dev": { + "laminas/laminas-cache": "^2.7.2", + "laminas/laminas-coding-standard": "~1.0.0", + "laminas/laminas-db": "^2.8.2", + "laminas/laminas-http": "^2.7", + "laminas/laminas-servicemanager": "^2.7.8 || ^3.3", + "laminas/laminas-validator": "^2.10.1", + "phpunit/phpunit": "^5.7.27 || ^6.5.14 || ^7.5.20", + "psr/http-message": "^1.0.1" + }, + "suggest": { + "laminas/laminas-cache": "Laminas\\Cache component, for optionally caching feeds between requests", + "laminas/laminas-db": "Laminas\\Db component, for use with PubSubHubbub", + "laminas/laminas-http": "Laminas\\Http for PubSubHubbub, and optionally for use with Laminas\\Feed\\Reader", + "laminas/laminas-servicemanager": "Laminas\\ServiceManager component, for easily extending ExtensionManager implementations", + "laminas/laminas-validator": "Laminas\\Validator component, for validating email addresses used in Atom feeds and entries when using the Writer subcomponent", + "psr/http-message": "PSR-7 ^1.0.1, if you wish to use Laminas\\Feed\\Reader\\Http\\Psr7ResponseDecorator" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.12.x-dev", + "dev-develop": "2.13.x-dev" + } + }, + "autoload": { + "psr-4": { + "Laminas\\Feed\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "provides functionality for consuming RSS and Atom feeds", + "homepage": "https://laminas.dev", + "keywords": [ + "feed", + "laminas" + ], + "time": "2020-03-29T12:36:29+00:00" + }, + { + "name": "laminas/laminas-stdlib", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/laminas/laminas-stdlib.git", + "reference": "2b18347625a2f06a1a485acfbc870f699dbe51c6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laminas/laminas-stdlib/zipball/2b18347625a2f06a1a485acfbc870f699dbe51c6", + "reference": "2b18347625a2f06a1a485acfbc870f699dbe51c6", + "shasum": "" + }, + "require": { + "laminas/laminas-zendframework-bridge": "^1.0", + "php": "^5.6 || ^7.0" + }, + "replace": { + "zendframework/zend-stdlib": "self.version" + }, + "require-dev": { + "laminas/laminas-coding-standard": "~1.0.0", + "phpbench/phpbench": "^0.13", + "phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2.x-dev", + "dev-develop": "3.3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Laminas\\Stdlib\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "SPL extensions, array utilities, error handlers, and more", + "homepage": "https://laminas.dev", + "keywords": [ + "laminas", + "stdlib" + ], + "time": "2019-12-31T17:51:15+00:00" + }, + { + "name": "laminas/laminas-zendframework-bridge", + "version": "1.0.4", + "source": { + "type": "git", + "url": "https://github.com/laminas/laminas-zendframework-bridge.git", + "reference": "fcd87520e4943d968557803919523772475e8ea3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laminas/laminas-zendframework-bridge/zipball/fcd87520e4943d968557803919523772475e8ea3", + "reference": "fcd87520e4943d968557803919523772475e8ea3", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7 || ^6.5 || ^7.5 || ^8.1", + "squizlabs/php_codesniffer": "^3.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev", + "dev-develop": "1.1.x-dev" + }, + "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" + ], + "funding": [ + { + "url": "https://funding.communitybridge.org/projects/laminas-project", + "type": "community_bridge" + } + ], + "time": "2020-05-20T16:45:56+00:00" + }, + { + "name": "league/container", + "version": "2.4.1", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/container.git", + "reference": "43f35abd03a12977a60ffd7095efd6a7808488c0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/container/zipball/43f35abd03a12977a60ffd7095efd6a7808488c0", + "reference": "43f35abd03a12977a60ffd7095efd6a7808488c0", + "shasum": "" + }, + "require": { + "container-interop/container-interop": "^1.2", + "php": "^5.4.0 || ^7.0" + }, + "provide": { + "container-interop/container-interop-implementation": "^1.2", + "psr/container-implementation": "^1.0" + }, + "replace": { + "orno/di": "~2.0" + }, + "require-dev": { + "phpunit/phpunit": "4.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-2.x": "2.x-dev", + "dev-1.x": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Container\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Phil Bennett", + "email": "philipobenito@gmail.com", + "homepage": "http://www.philipobenito.com", + "role": "Developer" + } + ], + "description": "A fast and intuitive dependency injection container.", + "homepage": "https://github.com/thephpleague/container", + "keywords": [ + "container", + "dependency", + "di", + "injection", + "league", + "provider", + "service" + ], + "time": "2017-05-10T09:20:27+00:00" + }, + { + "name": "masterminds/html5", + "version": "2.3.0", + "source": { + "type": "git", + "url": "https://github.com/Masterminds/html5-php.git", + "reference": "2c37c6c520b995b761674de3be8455a381679067" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/2c37c6c520b995b761674de3be8455a381679067", + "reference": "2c37c6c520b995b761674de3be8455a381679067", + "shasum": "" + }, + "require": { + "ext-libxml": "*", + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "4.*", + "sami/sami": "~2.0", + "satooshi/php-coveralls": "1.0.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2-dev" + } + }, + "autoload": { + "psr-4": { + "Masterminds\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Matt Butcher", + "email": "technosophos@gmail.com" + }, + { + "name": "Asmir Mustafic", + "email": "goetas@gmail.com" + }, + { + "name": "Matt Farina", + "email": "matt@mattfarina.com" + } + ], + "description": "An HTML5 parser and serializer.", + "homepage": "http://masterminds.github.io/html5-php", + "keywords": [ + "HTML5", + "dom", + "html", + "parser", + "querypath", + "serializer", + "xml" + ], + "time": "2017-09-04T12:26:28+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v4.10.2", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "658f1be311a230e0907f5dfe0213742aff0596de" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/658f1be311a230e0907f5dfe0213742aff0596de", + "reference": "658f1be311a230e0907f5dfe0213742aff0596de", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.0" + }, + "require-dev": { + "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.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" + ], + "time": "2020-09-26T10:30:38+00:00" + }, + { + "name": "paragonie/random_compat", + "version": "v9.99.99", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95", + "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95", + "shasum": "" + }, + "require": { + "php": "^7" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*", + "vimeo/psalm": "^1" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "polyfill", + "pseudorandom", + "random" + ], + "time": "2018-07-02T15:55:56+00:00" + }, + { + "name": "pear/archive_tar", + "version": "1.4.9", + "source": { + "type": "git", + "url": "https://github.com/pear/Archive_Tar.git", + "reference": "c5b00053770e1d72128252c62c2c1a12c26639f0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pear/Archive_Tar/zipball/c5b00053770e1d72128252c62c2c1a12c26639f0", + "reference": "c5b00053770e1d72128252c62c2c1a12c26639f0", + "shasum": "" + }, + "require": { + "pear/pear-core-minimal": "^1.10.0alpha2", + "php": ">=5.2.0" + }, + "require-dev": { + "phpunit/phpunit": "*" + }, + "suggest": { + "ext-bz2": "Bz2 compression support.", + "ext-xz": "Lzma2 compression support.", + "ext-zlib": "Gzip compression support." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "psr-0": { + "Archive_Tar": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "./" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Vincent Blavet", + "email": "vincent@phpconcept.net" + }, + { + "name": "Greg Beaver", + "email": "greg@chiaraquartet.net" + }, + { + "name": "Michiel Rook", + "email": "mrook@php.net" + } + ], + "description": "Tar file management class with compression support (gzip, bzip2, lzma2)", + "homepage": "https://github.com/pear/Archive_Tar", + "keywords": [ + "archive", + "tar" + ], + "time": "2019-12-04T10:17:28+00:00" + }, + { + "name": "pear/console_getopt", + "version": "v1.4.3", + "source": { + "type": "git", + "url": "https://github.com/pear/Console_Getopt.git", + "reference": "a41f8d3e668987609178c7c4a9fe48fecac53fa0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pear/Console_Getopt/zipball/a41f8d3e668987609178c7c4a9fe48fecac53fa0", + "reference": "a41f8d3e668987609178c7c4a9fe48fecac53fa0", + "shasum": "" + }, + "type": "library", + "autoload": { + "psr-0": { + "Console": "./" + } + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "./" + ], + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Andrei Zmievski", + "email": "andrei@php.net", + "role": "Lead" + }, + { + "name": "Stig Bakken", + "email": "stig@php.net", + "role": "Developer" + }, + { + "name": "Greg Beaver", + "email": "cellog@php.net", + "role": "Helper" + } + ], + "description": "More info available on: http://pear.php.net/package/Console_Getopt", + "time": "2019-11-20T18:27:48+00:00" + }, + { + "name": "pear/pear-core-minimal", + "version": "v1.10.10", + "source": { + "type": "git", + "url": "https://github.com/pear/pear-core-minimal.git", + "reference": "625a3c429d9b2c1546438679074cac1b089116a7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pear/pear-core-minimal/zipball/625a3c429d9b2c1546438679074cac1b089116a7", + "reference": "625a3c429d9b2c1546438679074cac1b089116a7", + "shasum": "" + }, + "require": { + "pear/console_getopt": "~1.4", + "pear/pear_exception": "~1.0" + }, + "replace": { + "rsky/pear-core-min": "self.version" + }, + "type": "library", + "autoload": { + "psr-0": { + "": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "src/" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Christian Weiske", + "email": "cweiske@php.net", + "role": "Lead" + } + ], + "description": "Minimal set of PEAR core files to be used as composer dependency", + "time": "2019-11-19T19:00:24+00:00" + }, + { + "name": "pear/pear_exception", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/pear/PEAR_Exception.git", + "reference": "dbb42a5a0e45f3adcf99babfb2a1ba77b8ac36a7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pear/PEAR_Exception/zipball/dbb42a5a0e45f3adcf99babfb2a1ba77b8ac36a7", + "reference": "dbb42a5a0e45f3adcf99babfb2a1ba77b8ac36a7", + "shasum": "" + }, + "require": { + "php": ">=4.4.0" + }, + "require-dev": { + "phpunit/phpunit": "*" + }, + "type": "class", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "PEAR/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "." + ], + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Helgi Thormar", + "email": "dufuz@php.net" + }, + { + "name": "Greg Beaver", + "email": "cellog@php.net" + } + ], + "description": "The PEAR Exception base class.", + "homepage": "https://github.com/pear/PEAR_Exception", + "keywords": [ + "exception" + ], + "time": "2019-12-10T10:24:42+00:00" + }, + { + "name": "psr/container", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "time": "2017-02-14T16:28:37+00:00" + }, + { + "name": "psr/http-message", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "shasum": "" + }, + "require": { + "php": ">=5.3.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 interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "time": "2016-08-06T14:39:51+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": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "time": "2020-03-23T09:12:05+00:00" + }, + { + "name": "psy/psysh", + "version": "v0.10.4", + "source": { + "type": "git", + "url": "https://github.com/bobthecow/psysh.git", + "reference": "a8aec1b2981ab66882a01cce36a49b6317dc3560" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/a8aec1b2981ab66882a01cce36a49b6317dc3560", + "reference": "a8aec1b2981ab66882a01cce36a49b6317dc3560", + "shasum": "" + }, + "require": { + "dnoegel/php-xdg-base-dir": "0.1.*", + "ext-json": "*", + "ext-tokenizer": "*", + "nikic/php-parser": "~4.0|~3.0|~2.0|~1.3", + "php": "^8.0 || ^7.0 || ^5.5.9", + "symfony/console": "~5.0|~4.0|~3.0|^2.4.2|~2.3.10", + "symfony/var-dumper": "~5.0|~4.0|~3.0|~2.7" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.2", + "hoa/console": "3.17.*" + }, + "suggest": { + "ext-pcntl": "Enabling the PCNTL extension makes PsySH a lot happier :)", + "ext-pdo-sqlite": "The doc command requires SQLite to work.", + "ext-posix": "If you have PCNTL, you'll want the POSIX extension as well.", + "ext-readline": "Enables support for arrow-key history navigation, and showing and manipulating command history.", + "hoa/console": "A pure PHP readline implementation. You'll want this if your PHP install doesn't already support readline or libedit." + }, + "bin": [ + "bin/psysh" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.10.x-dev" + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Psy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Justin Hileman", + "email": "justin@justinhileman.info", + "homepage": "http://justinhileman.com" + } + ], + "description": "An interactive shell for modern PHP.", + "homepage": "http://psysh.org", + "keywords": [ + "REPL", + "console", + "interactive", + "shell" + ], + "time": "2020-05-03T19:32:03+00:00" + }, + { + "name": "ralouphie/getallheaders", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "time": "2019-03-08T08:55:37+00:00" + }, + { + "name": "stack/builder", + "version": "v1.0.5", + "source": { + "type": "git", + "url": "https://github.com/stackphp/builder.git", + "reference": "fb3d136d04c6be41120ebf8c0cc71fe9507d750a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/stackphp/builder/zipball/fb3d136d04c6be41120ebf8c0cc71fe9507d750a", + "reference": "fb3d136d04c6be41120ebf8c0cc71fe9507d750a", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "symfony/http-foundation": "~2.1|~3.0|~4.0", + "symfony/http-kernel": "~2.1|~3.0|~4.0" + }, + "require-dev": { + "silex/silex": "~1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-0": { + "Stack": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" + } + ], + "description": "Builder for stack middlewares based on HttpKernelInterface.", + "keywords": [ + "stack" + ], + "time": "2017-11-18T14:57:29+00:00" + }, + { + "name": "symfony-cmf/routing", + "version": "1.4.1", + "source": { + "type": "git", + "url": "https://github.com/symfony-cmf/routing.git", + "reference": "fb1e7f85ff8c6866238b7e73a490a0a0243ae8ac" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony-cmf/routing/zipball/fb1e7f85ff8c6866238b7e73a490a0a0243ae8ac", + "reference": "fb1e7f85ff8c6866238b7e73a490a0a0243ae8ac", + "shasum": "" + }, + "require": { + "php": "^5.3.9|^7.0", + "psr/log": "1.*", + "symfony/http-kernel": "^2.2|3.*", + "symfony/routing": "^2.2|3.*" + }, + "require-dev": { + "friendsofsymfony/jsrouting-bundle": "^1.1", + "symfony-cmf/testing": "^1.3", + "symfony/config": "^2.2|3.*", + "symfony/dependency-injection": "^2.0.5|3.*", + "symfony/event-dispatcher": "^2.1|3.*" + }, + "suggest": { + "symfony/event-dispatcher": "DynamicRouter can optionally trigger an event at the start of matching. Minimal version (~2.1)" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Cmf\\Component\\Routing\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony CMF Community", + "homepage": "https://github.com/symfony-cmf/Routing/contributors" + } + ], + "description": "Extends the Symfony2 routing component for dynamic routes and chaining several routers", + "homepage": "http://cmf.symfony.com", + "keywords": [ + "database", + "routing" + ], + "time": "2017-05-09T08:10:41+00:00" + }, + { + "name": "symfony/class-loader", + "version": "v3.4.41", + "source": { + "type": "git", + "url": "https://github.com/symfony/class-loader.git", + "reference": "e4636a4f23f157278a19e5db160c63de0da297d8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/class-loader/zipball/e4636a4f23f157278a19e5db160c63de0da297d8", + "reference": "e4636a4f23f157278a19e5db160c63de0da297d8", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8" + }, + "require-dev": { + "symfony/finder": "~2.8|~3.0|~4.0", + "symfony/polyfill-apcu": "~1.1" + }, + "suggest": { + "symfony/polyfill-apcu": "For using ApcClassLoader on HHVM" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\ClassLoader\\": "" + }, + "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 ClassLoader Component", + "homepage": "https://symfony.com", + "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-03-15T09:38:08+00:00" + }, + { + "name": "symfony/console", + "version": "v3.4.41", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "bfe29ead7e7b1cc9ce74c6a40d06ad1f96fced13" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/bfe29ead7e7b1cc9ce74c6a40d06ad1f96fced13", + "reference": "bfe29ead7e7b1cc9ce74c6a40d06ad1f96fced13", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/debug": "~2.8|~3.0|~4.0", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/dependency-injection": "<3.4", + "symfony/process": "<3.3" + }, + "provide": { + "psr/log-implementation": "1.0" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~3.3|~4.0", + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/event-dispatcher": "~2.8|~3.0|~4.0", + "symfony/lock": "~3.4|~4.0", + "symfony/process": "~3.3|~4.0" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/lock": "", + "symfony/process": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "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 Console Component", + "homepage": "https://symfony.com", + "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-05-30T18:58:05+00:00" + }, + { + "name": "symfony/debug", + "version": "v3.4.41", + "source": { + "type": "git", + "url": "https://github.com/symfony/debug.git", + "reference": "518c6a00d0872da30bd06aee3ea59a0a5cf54d6d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/debug/zipball/518c6a00d0872da30bd06aee3ea59a0a5cf54d6d", + "reference": "518c6a00d0872da30bd06aee3ea59a0a5cf54d6d", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "psr/log": "~1.0" + }, + "conflict": { + "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2" + }, + "require-dev": { + "symfony/http-kernel": "~2.8|~3.0|~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Debug\\": "" + }, + "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 Debug Component", + "homepage": "https://symfony.com", + "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-05-22T18:25:20+00:00" + }, + { + "name": "symfony/dependency-injection", + "version": "v3.4.41", + "source": { + "type": "git", + "url": "https://github.com/symfony/dependency-injection.git", + "reference": "e39380b7104b0ec538a075ae919f00c7e5267bac" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/e39380b7104b0ec538a075ae919f00c7e5267bac", + "reference": "e39380b7104b0ec538a075ae919f00c7e5267bac", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "psr/container": "^1.0" + }, + "conflict": { + "symfony/config": "<3.3.7", + "symfony/finder": "<3.3", + "symfony/proxy-manager-bridge": "<3.4", + "symfony/yaml": "<3.4" + }, + "provide": { + "psr/container-implementation": "1.0" + }, + "require-dev": { + "symfony/config": "~3.3|~4.0", + "symfony/expression-language": "~2.8|~3.0|~4.0", + "symfony/yaml": "~3.4|~4.0" + }, + "suggest": { + "symfony/config": "", + "symfony/expression-language": "For using expressions in service container configuration", + "symfony/finder": "For using double-star glob patterns or when GLOB_BRACE portability is required", + "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them", + "symfony/yaml": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\DependencyInjection\\": "" + }, + "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 DependencyInjection Component", + "homepage": "https://symfony.com", + "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-05-30T21:06:01+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v3.4.41", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "14d978f8e8555f2de719c00eb65376be7d2e9081" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/14d978f8e8555f2de719c00eb65376be7d2e9081", + "reference": "14d978f8e8555f2de719c00eb65376be7d2e9081", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8" + }, + "conflict": { + "symfony/dependency-injection": "<3.3" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~2.8|~3.0|~4.0", + "symfony/dependency-injection": "~3.3|~4.0", + "symfony/expression-language": "~2.8|~3.0|~4.0", + "symfony/stopwatch": "~2.8|~3.0|~4.0" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "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 EventDispatcher Component", + "homepage": "https://symfony.com", + "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-05-05T15:06:23+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v3.4.46", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "e58d7841cddfed6e846829040dca2cca0ebbbbb3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/e58d7841cddfed6e846829040dca2cca0ebbbbb3", + "reference": "e58d7841cddfed6e846829040dca2cca0ebbbbb3", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/polyfill-ctype": "~1.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "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 Filesystem Component", + "homepage": "https://symfony.com", + "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-24T10:57:07+00:00" + }, + { + "name": "symfony/finder", + "version": "v3.4.46", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "4e1da3c110c52d868f8a9153b7de3ebc381fba78" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/4e1da3c110c52d868f8a9153b7de3ebc381fba78", + "reference": "4e1da3c110c52d868f8a9153b7de3ebc381fba78", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "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 Finder Component", + "homepage": "https://symfony.com", + "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-24T10:57:07+00:00" + }, + { + "name": "symfony/http-foundation", + "version": "v3.4.41", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-foundation.git", + "reference": "fbd216d2304b1a3fe38d6392b04729c8dd356359" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/fbd216d2304b1a3fe38d6392b04729c8dd356359", + "reference": "fbd216d2304b1a3fe38d6392b04729c8dd356359", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/polyfill-mbstring": "~1.1", + "symfony/polyfill-php70": "~1.6" + }, + "require-dev": { + "symfony/expression-language": "~2.8|~3.0|~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpFoundation\\": "" + }, + "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 HttpFoundation Component", + "homepage": "https://symfony.com", + "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-05-16T13:15:54+00:00" + }, + { + "name": "symfony/http-kernel", + "version": "v3.4.44", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-kernel.git", + "reference": "27dcaa8c6b18c75df9f37badeb4d3564ffaa1326" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/27dcaa8c6b18c75df9f37badeb4d3564ffaa1326", + "reference": "27dcaa8c6b18c75df9f37badeb4d3564ffaa1326", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "psr/log": "~1.0", + "symfony/debug": "^3.3.3|~4.0", + "symfony/event-dispatcher": "~2.8|~3.0|~4.0", + "symfony/http-foundation": "~3.4.12|~4.0.12|^4.1.1", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-php56": "~1.8" + }, + "conflict": { + "symfony/config": "<2.8", + "symfony/dependency-injection": "<3.4.10|<4.0.10,>=4", + "symfony/var-dumper": "<3.3", + "twig/twig": "<1.34|<2.4,>=2" + }, + "provide": { + "psr/log-implementation": "1.0" + }, + "require-dev": { + "psr/cache": "~1.0", + "symfony/browser-kit": "~2.8|~3.0|~4.0", + "symfony/class-loader": "~2.8|~3.0", + "symfony/config": "~2.8|~3.0|~4.0", + "symfony/console": "~2.8|~3.0|~4.0", + "symfony/css-selector": "~2.8|~3.0|~4.0", + "symfony/dependency-injection": "^3.4.10|^4.0.10", + "symfony/dom-crawler": "~2.8|~3.0|~4.0", + "symfony/expression-language": "~2.8|~3.0|~4.0", + "symfony/finder": "~2.8|~3.0|~4.0", + "symfony/process": "~2.8|~3.0|~4.0", + "symfony/routing": "~3.4|~4.0", + "symfony/stopwatch": "~2.8|~3.0|~4.0", + "symfony/templating": "~2.8|~3.0|~4.0", + "symfony/translation": "~2.8|~3.0|~4.0", + "symfony/var-dumper": "~3.3|~4.0" + }, + "suggest": { + "symfony/browser-kit": "", + "symfony/config": "", + "symfony/console": "", + "symfony/dependency-injection": "", + "symfony/finder": "", + "symfony/var-dumper": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpKernel\\": "" + }, + "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 HttpKernel Component", + "homepage": "https://symfony.com", + "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-31T05:53:42+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.17.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "e94c8b1bbe2bc77507a1056cdb06451c75b427f9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/e94c8b1bbe2bc77507a1056cdb06451c75b427f9", + "reference": "e94c8b1bbe2bc77507a1056cdb06451c75b427f9", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.17-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "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-05-12T16:14:59+00:00" + }, + { + "name": "symfony/polyfill-iconv", + "version": "v1.17.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-iconv.git", + "reference": "c4de7601eefbf25f9d47190abe07f79fe0a27424" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/c4de7601eefbf25f9d47190abe07f79fe0a27424", + "reference": "c4de7601eefbf25f9d47190abe07f79fe0a27424", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-iconv": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.17-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Iconv\\": "" + }, + "files": [ + "bootstrap.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": "Symfony polyfill for the Iconv extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "iconv", + "polyfill", + "portable", + "shim" + ], + "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-05-12T16:47:27+00:00" + }, + { + "name": "symfony/polyfill-intl-idn", + "version": "v1.17.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-idn.git", + "reference": "3bff59ea7047e925be6b7f2059d60af31bb46d6a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/3bff59ea7047e925be6b7f2059d60af31bb46d6a", + "reference": "3bff59ea7047e925be6b7f2059d60af31bb46d6a", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "symfony/polyfill-mbstring": "^1.3", + "symfony/polyfill-php72": "^1.10" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.17-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Intl\\Idn\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Laurent Bassin", + "email": "laurent@bassin.info" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "idn", + "intl", + "polyfill", + "portable", + "shim" + ], + "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-05-12T16:47:27+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.17.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "fa79b11539418b02fc5e1897267673ba2c19419c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fa79b11539418b02fc5e1897267673ba2c19419c", + "reference": "fa79b11539418b02fc5e1897267673ba2c19419c", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.17-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + }, + "files": [ + "bootstrap.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": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "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-05-12T16:47:27+00:00" + }, + { + "name": "symfony/polyfill-php56", + "version": "v1.17.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php56.git", + "reference": "e3c8c138280cdfe4b81488441555583aa1984e23" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php56/zipball/e3c8c138280cdfe4b81488441555583aa1984e23", + "reference": "e3c8c138280cdfe4b81488441555583aa1984e23", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "symfony/polyfill-util": "~1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.17-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php56\\": "" + }, + "files": [ + "bootstrap.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": "Symfony polyfill backporting some PHP 5.6+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "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-05-12T16:47:27+00:00" + }, + { + "name": "symfony/polyfill-php70", + "version": "v1.17.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php70.git", + "reference": "82225c2d7d23d7e70515496d249c0152679b468e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/82225c2d7d23d7e70515496d249c0152679b468e", + "reference": "82225c2d7d23d7e70515496d249c0152679b468e", + "shasum": "" + }, + "require": { + "paragonie/random_compat": "~1.0|~2.0|~9.99", + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.17-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php70\\": "" + }, + "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 backporting some PHP 7.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "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-05-12T16:47:27+00:00" + }, + { + "name": "symfony/polyfill-php72", + "version": "v1.17.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php72.git", + "reference": "f048e612a3905f34931127360bdd2def19a5e582" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/f048e612a3905f34931127360bdd2def19a5e582", + "reference": "f048e612a3905f34931127360bdd2def19a5e582", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.17-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php72\\": "" + }, + "files": [ + "bootstrap.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": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "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-05-12T16:47:27+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.20.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "e70aa8b064c5b72d3df2abd5ab1e90464ad009de" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/e70aa8b064c5b72d3df2abd5ab1e90464ad009de", + "reference": "e70aa8b064c5b72d3df2abd5ab1e90464ad009de", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.20-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" + ], + "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-23T14:02:19+00:00" + }, + { + "name": "symfony/polyfill-util", + "version": "v1.17.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-util.git", + "reference": "4afb4110fc037752cf0ce9869f9ab8162c4e20d7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-util/zipball/4afb4110fc037752cf0ce9869f9ab8162c4e20d7", + "reference": "4afb4110fc037752cf0ce9869f9ab8162c4e20d7", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.17-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Util\\": "" + } + }, + "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 utilities for portability of PHP codes", + "homepage": "https://symfony.com", + "keywords": [ + "compat", + "compatibility", + "polyfill", + "shim" + ], + "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-05-12T16:14:59+00:00" + }, + { + "name": "symfony/process", + "version": "v3.4.41", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "8a895f0c92a7c4b10db95139bcff71bdf66d4d21" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/8a895f0c92a7c4b10db95139bcff71bdf66d4d21", + "reference": "8a895f0c92a7c4b10db95139bcff71bdf66d4d21", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-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", + "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-05-23T17:05:51+00:00" + }, + { + "name": "symfony/psr-http-message-bridge", + "version": "v1.1.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/psr-http-message-bridge.git", + "reference": "a33352af16f78a5ff4f9d90811536abf210df12b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/a33352af16f78a5ff4f9d90811536abf210df12b", + "reference": "a33352af16f78a5ff4f9d90811536abf210df12b", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0", + "psr/http-message": "^1.0", + "symfony/http-foundation": "^2.3.42 || ^3.4 || ^4.0" + }, + "require-dev": { + "symfony/phpunit-bridge": "^3.4 || ^4.0" + }, + "suggest": { + "nyholm/psr7": "For a super lightweight PSR-7/17 implementation" + }, + "type": "symfony-bridge", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Bridge\\PsrHttpMessage\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "PSR HTTP message bridge", + "homepage": "http://symfony.com", + "keywords": [ + "http", + "http-message", + "psr-17", + "psr-7" + ], + "time": "2019-04-03T17:09:40+00:00" + }, + { + "name": "symfony/routing", + "version": "v3.4.41", + "source": { + "type": "git", + "url": "https://github.com/symfony/routing.git", + "reference": "e0d43b6f9417ad59ecaa8e2f799b79eef417387f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/routing/zipball/e0d43b6f9417ad59ecaa8e2f799b79eef417387f", + "reference": "e0d43b6f9417ad59ecaa8e2f799b79eef417387f", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8" + }, + "conflict": { + "symfony/config": "<3.3.1", + "symfony/dependency-injection": "<3.3", + "symfony/yaml": "<3.4" + }, + "require-dev": { + "doctrine/annotations": "~1.0", + "psr/log": "~1.0", + "symfony/config": "^3.3.1|~4.0", + "symfony/dependency-injection": "~3.3|~4.0", + "symfony/expression-language": "~2.8|~3.0|~4.0", + "symfony/http-foundation": "~2.8|~3.0|~4.0", + "symfony/yaml": "~3.4|~4.0" + }, + "suggest": { + "doctrine/annotations": "For using the annotation loader", + "symfony/config": "For using the all-in-one router or any loader", + "symfony/expression-language": "For using expression matching", + "symfony/http-foundation": "For using a Symfony Request object", + "symfony/yaml": "For using the YAML loader" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Routing\\": "" + }, + "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 Routing Component", + "homepage": "https://symfony.com", + "keywords": [ + "router", + "routing", + "uri", + "url" + ], + "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-05-30T19:50:06+00:00" + }, + { + "name": "symfony/serializer", + "version": "v3.4.41", + "source": { + "type": "git", + "url": "https://github.com/symfony/serializer.git", + "reference": "0db90db012b1b0a04fbb2d64ae9160871cad9d4f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/serializer/zipball/0db90db012b1b0a04fbb2d64ae9160871cad9d4f", + "reference": "0db90db012b1b0a04fbb2d64ae9160871cad9d4f", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/polyfill-ctype": "~1.8" + }, + "conflict": { + "phpdocumentor/type-resolver": "<0.2.1", + "symfony/dependency-injection": "<3.2", + "symfony/property-access": ">=3.0,<3.0.4|>=2.8,<2.8.4", + "symfony/property-info": "<3.1", + "symfony/yaml": "<3.4" + }, + "require-dev": { + "doctrine/annotations": "~1.0", + "doctrine/cache": "~1.0", + "phpdocumentor/reflection-docblock": "^3.0|^4.0", + "symfony/cache": "~3.1|~4.0", + "symfony/config": "~2.8|~3.0|~4.0", + "symfony/dependency-injection": "~3.2|~4.0", + "symfony/http-foundation": "~2.8|~3.0|~4.0", + "symfony/property-access": "~2.8|~3.0|~4.0", + "symfony/property-info": "^3.4.13|~4.0", + "symfony/yaml": "~3.4|~4.0" + }, + "suggest": { + "doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.", + "doctrine/cache": "For using the default cached annotation reader and metadata cache.", + "psr/cache-implementation": "For using the metadata cache.", + "symfony/config": "For using the XML mapping loader.", + "symfony/http-foundation": "For using a MIME type guesser within the DataUriNormalizer.", + "symfony/property-access": "For using the ObjectNormalizer.", + "symfony/property-info": "To deserialize relations.", + "symfony/yaml": "For using the default YAML mapping loader." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Serializer\\": "" + }, + "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 Serializer Component", + "homepage": "https://symfony.com", + "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-05-30T18:58:05+00:00" + }, + { + "name": "symfony/translation", + "version": "v3.4.41", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation.git", + "reference": "b0cd62ef0ff7ec31b67d78d7fc818e2bda4e844f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation/zipball/b0cd62ef0ff7ec31b67d78d7fc818e2bda4e844f", + "reference": "b0cd62ef0ff7ec31b67d78d7fc818e2bda4e844f", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/config": "<2.8", + "symfony/dependency-injection": "<3.4", + "symfony/yaml": "<3.4" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~2.8|~3.0|~4.0", + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/finder": "~2.8|~3.0|~4.0", + "symfony/http-kernel": "~3.4|~4.0", + "symfony/intl": "^2.8.18|^3.2.5|~4.0", + "symfony/var-dumper": "~3.4|~4.0", + "symfony/yaml": "~3.4|~4.0" + }, + "suggest": { + "psr/log-implementation": "To use logging capability in translator", + "symfony/config": "", + "symfony/yaml": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Translation\\": "" + }, + "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 Translation Component", + "homepage": "https://symfony.com", + "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-05-30T18:58:05+00:00" + }, + { + "name": "symfony/validator", + "version": "v3.4.41", + "source": { + "type": "git", + "url": "https://github.com/symfony/validator.git", + "reference": "5fb88120a11a75e17b602103a893dd8b27804529" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/validator/zipball/5fb88120a11a75e17b602103a893dd8b27804529", + "reference": "5fb88120a11a75e17b602103a893dd8b27804529", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.0", + "symfony/translation": "~2.8|~3.0|~4.0" + }, + "conflict": { + "doctrine/lexer": "<1.0.2", + "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0", + "symfony/dependency-injection": "<3.3", + "symfony/http-kernel": "<3.3.5", + "symfony/yaml": "<3.4" + }, + "require-dev": { + "doctrine/annotations": "~1.7", + "doctrine/cache": "~1.0", + "egulias/email-validator": "^2.1.10", + "symfony/cache": "~3.1|~4.0", + "symfony/config": "~2.8|~3.0|~4.0", + "symfony/dependency-injection": "~3.3|~4.0", + "symfony/expression-language": "~2.8|~3.0|~4.0", + "symfony/http-foundation": "~2.8|~3.0|~4.0", + "symfony/http-kernel": "^3.3.5|~4.0", + "symfony/intl": "^2.8.18|^3.2.5|~4.0", + "symfony/property-access": "~2.8|~3.0|~4.0", + "symfony/var-dumper": "~3.3|~4.0", + "symfony/yaml": "~3.4|~4.0" + }, + "suggest": { + "doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.", + "doctrine/cache": "For using the default cached annotation reader and metadata cache.", + "egulias/email-validator": "Strict (RFC compliant) email validation", + "psr/cache-implementation": "For using the metadata cache.", + "symfony/config": "", + "symfony/expression-language": "For using the Expression validator", + "symfony/http-foundation": "", + "symfony/intl": "", + "symfony/property-access": "For accessing properties within comparison constraints", + "symfony/yaml": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Validator\\": "" + }, + "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 Validator Component", + "homepage": "https://symfony.com", + "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-05-30T18:43:38+00:00" + }, + { + "name": "symfony/var-dumper", + "version": "v4.4.16", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-dumper.git", + "reference": "3718e18b68d955348ad860e505991802c09f5f73" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/3718e18b68d955348ad860e505991802c09f5f73", + "reference": "3718e18b68d955348ad860e505991802c09f5f73", + "shasum": "" + }, + "require": { + "php": ">=7.1.3", + "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" + }, + "require-dev": { + "ext-iconv": "*", + "symfony/console": "^3.4|^4.0|^5.0", + "symfony/process": "^4.4|^5.0", + "twig/twig": "^1.34|^2.4|^3.0" + }, + "suggest": { + "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", + "ext-intl": "To show region name in time zone dump", + "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script" + }, + "bin": [ + "Resources/bin/var-dump-server" + ], + "type": "library", + "autoload": { + "files": [ + "Resources/functions/dump.php" + ], + "psr-4": { + "Symfony\\Component\\VarDumper\\": "" + }, + "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": "Symfony mechanism for exploring and dumping PHP variables", + "homepage": "https://symfony.com", + "keywords": [ + "debug", + "dump" + ], + "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-26T20:47:51+00:00" + }, + { + "name": "symfony/yaml", + "version": "v3.4.41", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "7233ac2bfdde24d672f5305f2b3f6b5d741ef8eb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/7233ac2bfdde24d672f5305f2b3f6b5d741ef8eb", + "reference": "7233ac2bfdde24d672f5305f2b3f6b5d741ef8eb", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/polyfill-ctype": "~1.8" + }, + "conflict": { + "symfony/console": "<3.4" + }, + "require-dev": { + "symfony/console": "~3.4|~4.0" + }, + "suggest": { + "symfony/console": "For validating YAML files using the lint command" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "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 Yaml Component", + "homepage": "https://symfony.com", + "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-05-11T07:51:54+00:00" + }, + { + "name": "twig/twig", + "version": "v1.42.5", + "source": { + "type": "git", + "url": "https://github.com/twigphp/Twig.git", + "reference": "87b2ea9d8f6fd014d0621ca089bb1b3769ea3f8e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/87b2ea9d8f6fd014d0621ca089bb1b3769ea3f8e", + "reference": "87b2ea9d8f6fd014d0621ca089bb1b3769ea3f8e", + "shasum": "" + }, + "require": { + "php": ">=5.5.0", + "symfony/polyfill-ctype": "^1.8" + }, + "require-dev": { + "psr/container": "^1.0", + "symfony/phpunit-bridge": "^4.4|^5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.42-dev" + } + }, + "autoload": { + "psr-0": { + "Twig_": "lib/" + }, + "psr-4": { + "Twig\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" + }, + { + "name": "Twig Team", + "role": "Contributors" + }, + { + "name": "Armin Ronacher", + "email": "armin.ronacher@active-4.com", + "role": "Project Founder" + } + ], + "description": "Twig, the flexible, fast, and secure template language for PHP", + "homepage": "https://twig.symfony.com", + "keywords": [ + "templating" + ], + "time": "2020-02-11T05:59:23+00:00" + }, + { + "name": "typo3/phar-stream-wrapper", + "version": "v3.1.4", + "source": { + "type": "git", + "url": "https://github.com/TYPO3/phar-stream-wrapper.git", + "reference": "e0c1b495cfac064f4f5c4bcb6bf67bb7f345ed04" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/TYPO3/phar-stream-wrapper/zipball/e0c1b495cfac064f4f5c4bcb6bf67bb7f345ed04", + "reference": "e0c1b495cfac064f4f5c4bcb6bf67bb7f345ed04", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^7.0" + }, + "require-dev": { + "ext-xdebug": "*", + "phpunit/phpunit": "^6.5" + }, + "suggest": { + "ext-fileinfo": "For PHP builtin file type guessing, otherwise uses internal processing" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "v3.x-dev" + } + }, + "autoload": { + "psr-4": { + "TYPO3\\PharStreamWrapper\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Interceptors for PHP's native phar:// stream handling", + "homepage": "https://typo3.org/", + "keywords": [ + "phar", + "php", + "security", + "stream-wrapper" + ], + "time": "2019-12-10T11:53:27+00:00" + }, + { + "name": "webflo/drupal-finder", + "version": "1.2.2", + "source": { + "type": "git", + "url": "https://github.com/webflo/drupal-finder.git", + "reference": "c8e5dbe65caef285fec8057a4c718a0d4138d1ee" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webflo/drupal-finder/zipball/c8e5dbe65caef285fec8057a4c718a0d4138d1ee", + "reference": "c8e5dbe65caef285fec8057a4c718a0d4138d1ee", + "shasum": "" + }, + "require": { + "ext-json": "*" + }, + "require-dev": { + "mikey179/vfsstream": "^1.6", + "phpunit/phpunit": "^4.8" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/DrupalFinder.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "Florian Weber", + "email": "florian@webflo.org" + } + ], + "description": "Helper class to locate a Drupal installation from a given path.", + "time": "2020-10-27T09:42:17+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.9.1", + "source": { + "type": "git", + "url": "https://github.com/webmozart/assert.git", + "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389", + "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0 || ^8.0", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "phpstan/phpstan": "<0.12.20", + "vimeo/psalm": "<3.9.1" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.36 || ^7.5.13" + }, + "type": "library", + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "time": "2020-07-08T17:02:28+00:00" + }, + { + "name": "webmozart/path-util", + "version": "2.3.0", + "source": { + "type": "git", + "url": "https://github.com/webmozart/path-util.git", + "reference": "d939f7edc24c9a1bb9c0dee5cb05d8e859490725" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/path-util/zipball/d939f7edc24c9a1bb9c0dee5cb05d8e859490725", + "reference": "d939f7edc24c9a1bb9c0dee5cb05d8e859490725", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "webmozart/assert": "~1.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.6", + "sebastian/version": "^1.0.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.3-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\PathUtil\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "A robust cross-platform utility for normalizing, comparing and modifying file paths.", + "time": "2015-12-17T08:42:14+00:00" + } + ], + "packages-dev": [ + { + "name": "behat/mink", + "version": "v1.8.1", + "source": { + "type": "git", + "url": "https://github.com/minkphp/Mink.git", + "reference": "07c6a9fe3fa98c2de074b25d9ed26c22904e3887" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/minkphp/Mink/zipball/07c6a9fe3fa98c2de074b25d9ed26c22904e3887", + "reference": "07c6a9fe3fa98c2de074b25d9ed26c22904e3887", + "shasum": "" + }, + "require": { + "php": ">=5.3.1", + "symfony/css-selector": "^2.7|^3.0|^4.0|^5.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20", + "symfony/debug": "^2.7|^3.0|^4.0", + "symfony/phpunit-bridge": "^3.4.38 || ^5.0.5" + }, + "suggest": { + "behat/mink-browserkit-driver": "extremely fast headless driver for Symfony\\Kernel-based apps (Sf2, Silex)", + "behat/mink-goutte-driver": "fast headless driver for any app without JS emulation", + "behat/mink-selenium2-driver": "slow, but JS-enabled driver for any app (requires Selenium2)", + "behat/mink-zombie-driver": "fast and JS-enabled headless driver for any app (requires node.js)", + "dmore/chrome-mink-driver": "fast and JS-enabled driver for any app (requires chromium or google chrome)" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8.x-dev" + } + }, + "autoload": { + "psr-4": { + "Behat\\Mink\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + } + ], + "description": "Browser controller/emulator abstraction for PHP", + "homepage": "http://mink.behat.org/", + "keywords": [ + "browser", + "testing", + "web" + ], + "time": "2020-03-11T15:45:53+00:00" + }, + { + "name": "behat/mink-browserkit-driver", + "version": "v1.3.4", + "source": { + "type": "git", + "url": "https://github.com/minkphp/MinkBrowserKitDriver.git", + "reference": "e3b90840022ebcd544c7b394a3c9597ae242cbee" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/minkphp/MinkBrowserKitDriver/zipball/e3b90840022ebcd544c7b394a3c9597ae242cbee", + "reference": "e3b90840022ebcd544c7b394a3c9597ae242cbee", + "shasum": "" + }, + "require": { + "behat/mink": "^1.7.1@dev", + "php": ">=5.3.6", + "symfony/browser-kit": "~2.3|~3.0|~4.0", + "symfony/dom-crawler": "~2.3|~3.0|~4.0" + }, + "require-dev": { + "mink/driver-testsuite": "dev-master", + "symfony/debug": "^2.7|^3.0|^4.0", + "symfony/http-kernel": "~2.3|~3.0|~4.0" + }, + "type": "mink-driver", + "extra": { + "branch-alias": { + "dev-master": "1.3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Behat\\Mink\\Driver\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + } + ], + "description": "Symfony2 BrowserKit driver for Mink framework", + "homepage": "http://mink.behat.org/", + "keywords": [ + "Mink", + "Symfony2", + "browser", + "testing" + ], + "time": "2020-03-11T09:49:45+00:00" + }, + { + "name": "behat/mink-goutte-driver", + "version": "v1.2.1", + "source": { + "type": "git", + "url": "https://github.com/minkphp/MinkGoutteDriver.git", + "reference": "8b9ad6d2d95bc70b840d15323365f52fcdaea6ca" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/minkphp/MinkGoutteDriver/zipball/8b9ad6d2d95bc70b840d15323365f52fcdaea6ca", + "reference": "8b9ad6d2d95bc70b840d15323365f52fcdaea6ca", + "shasum": "" + }, + "require": { + "behat/mink": "~1.6@dev", + "behat/mink-browserkit-driver": "~1.2@dev", + "fabpot/goutte": "~1.0.4|~2.0|~3.1", + "php": ">=5.3.1" + }, + "require-dev": { + "symfony/phpunit-bridge": "~2.7|~3.0" + }, + "type": "mink-driver", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Behat\\Mink\\Driver\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + } + ], + "description": "Goutte driver for Mink framework", + "homepage": "http://mink.behat.org/", + "keywords": [ + "browser", + "goutte", + "headless", + "testing" + ], + "time": "2016-03-05T09:04:22+00:00" + }, + { + "name": "behat/mink-selenium2-driver", + "version": "v1.4.0", + "source": { + "type": "git", + "url": "https://github.com/minkphp/MinkSelenium2Driver.git", + "reference": "312a967dd527f28980cce40850339cd5316da092" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/minkphp/MinkSelenium2Driver/zipball/312a967dd527f28980cce40850339cd5316da092", + "reference": "312a967dd527f28980cce40850339cd5316da092", + "shasum": "" + }, + "require": { + "behat/mink": "~1.7@dev", + "instaclick/php-webdriver": "~1.1", + "php": ">=5.4" + }, + "require-dev": { + "mink/driver-testsuite": "dev-master" + }, + "type": "mink-driver", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "psr-4": { + "Behat\\Mink\\Driver\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Pete Otaqui", + "email": "pete@otaqui.com", + "homepage": "https://github.com/pete-otaqui" + }, + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + } + ], + "description": "Selenium2 (WebDriver) driver for Mink framework", + "homepage": "http://mink.behat.org/", + "keywords": [ + "ajax", + "browser", + "javascript", + "selenium", + "testing", + "webdriver" + ], + "time": "2020-03-11T14:43:21+00:00" + }, + { + "name": "composer/ca-bundle", + "version": "1.2.8", + "source": { + "type": "git", + "url": "https://github.com/composer/ca-bundle.git", + "reference": "8a7ecad675253e4654ea05505233285377405215" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/8a7ecad675253e4654ea05505233285377405215", + "reference": "8a7ecad675253e4654ea05505233285377405215", + "shasum": "" + }, + "require": { + "ext-openssl": "*", + "ext-pcre": "*", + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 8", + "psr/log": "^1.0", + "symfony/process": "^2.5 || ^3.0 || ^4.0 || ^5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\CaBundle\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle.", + "keywords": [ + "cabundle", + "cacert", + "certificate", + "ssl", + "tls" + ], + "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-08-23T12:54:47+00:00" + }, + { + "name": "composer/composer", + "version": "1.10.17", + "source": { + "type": "git", + "url": "https://github.com/composer/composer.git", + "reference": "09d42e18394d8594be24e37923031c4b7442a1cb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/composer/zipball/09d42e18394d8594be24e37923031c4b7442a1cb", + "reference": "09d42e18394d8594be24e37923031c4b7442a1cb", + "shasum": "" + }, + "require": { + "composer/ca-bundle": "^1.0", + "composer/semver": "^1.0", + "composer/spdx-licenses": "^1.2", + "composer/xdebug-handler": "^1.1", + "justinrainbow/json-schema": "^5.2.10", + "php": "^5.3.2 || ^7.0", + "psr/log": "^1.0", + "seld/jsonlint": "^1.4", + "seld/phar-utils": "^1.0", + "symfony/console": "^2.7 || ^3.0 || ^4.0 || ^5.0", + "symfony/filesystem": "^2.7 || ^3.0 || ^4.0 || ^5.0", + "symfony/finder": "^2.7 || ^3.0 || ^4.0 || ^5.0", + "symfony/process": "^2.7 || ^3.0 || ^4.0 || ^5.0" + }, + "conflict": { + "symfony/console": "2.8.38" + }, + "require-dev": { + "phpspec/prophecy": "^1.10", + "symfony/phpunit-bridge": "^4.2" + }, + "suggest": { + "ext-openssl": "Enabling the openssl extension allows you to access https URLs for repositories and packages", + "ext-zip": "Enabling the zip extension allows you to unzip archives", + "ext-zlib": "Allow gzip compression of HTTP requests" + }, + "bin": [ + "bin/composer" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\": "src/Composer" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Composer helps you declare, manage and install dependencies of PHP projects. It ensures you have the right stack everywhere.", + "homepage": "https://getcomposer.org/", + "keywords": [ + "autoload", + "dependency", + "package" + ], + "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-10-30T21:31:58+00:00" + }, + { + "name": "composer/spdx-licenses", + "version": "1.5.4", + "source": { + "type": "git", + "url": "https://github.com/composer/spdx-licenses.git", + "reference": "6946f785871e2314c60b4524851f3702ea4f2223" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/6946f785871e2314c60b4524851f3702ea4f2223", + "reference": "6946f785871e2314c60b4524851f3702ea4f2223", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Spdx\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "SPDX licenses list and validation library.", + "keywords": [ + "license", + "spdx", + "validator" + ], + "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-07-15T15:35:07+00:00" + }, + { + "name": "composer/xdebug-handler", + "version": "1.4.5", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "f28d44c286812c714741478d968104c5e604a1d4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/f28d44c286812c714741478d968104c5e604a1d4", + "reference": "f28d44c286812c714741478d968104c5e604a1d4", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0", + "psr/log": "^1.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without Xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "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-13T08:04:11+00:00" + }, + { + "name": "doctrine/instantiator", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b", + "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^8.0", + "ext-pdo": "*", + "ext-phar": "*", + "phpbench/phpbench": "^0.13 || 1.0.0-alpha2", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-phpunit": "^0.12", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "https://ocramius.github.io/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", + "keywords": [ + "constructor", + "instantiate" + ], + "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": "drupal/coder", + "version": "8.3.11", + "source": { + "type": "git", + "url": "https://git.drupalcode.org/project/coder.git", + "reference": "67c1bcf2d6860237ce4b176fd55ef4c7c014d84e" + }, + "require": { + "ext-mbstring": "*", + "php": ">=7.0.8", + "sirbrillig/phpcs-variable-analysis": "^2.8", + "squizlabs/php_codesniffer": "^3.5.6", + "symfony/yaml": ">=2.0.5" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.51", + "phpunit/phpunit": "^6.0 || ^7.0" + }, + "type": "phpcodesniffer-standard", + "autoload": { + "psr-4": { + "Drupal\\": "coder_sniffer/Drupal/", + "DrupalPractice\\": "coder_sniffer/DrupalPractice/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0-or-later" + ], + "description": "Coder is a library to review Drupal code.", + "homepage": "https://www.drupal.org/project/coder", + "keywords": [ + "code review", + "phpcs", + "standards" + ], + "time": "2020-11-04T14:55:07+00:00" + }, + { + "name": "drupal/core-dev", + "version": "8.9.8", + "source": { + "type": "git", + "url": "https://github.com/drupal/core-dev.git", + "reference": "36370b3f42911c09ffb35f08fc72853d20e6efd7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/drupal/core-dev/zipball/36370b3f42911c09ffb35f08fc72853d20e6efd7", + "reference": "36370b3f42911c09ffb35f08fc72853d20e6efd7", + "shasum": "" + }, + "require": { + "behat/mink": "^1.8", + "behat/mink-goutte-driver": "^1.2", + "behat/mink-selenium2-driver": "^1.4", + "composer/composer": "^1.9.1", + "drupal/coder": "^8.3.7", + "jcalderonzumba/gastonjs": "^1.0.2", + "jcalderonzumba/mink-phantomjs-driver": "^0.3.1", + "justinrainbow/json-schema": "^5.2", + "mikey179/vfsstream": "^1.6.8", + "phpspec/prophecy": "^1.7", + "phpunit/phpunit": "^6.5 || ^7", + "symfony/browser-kit": "^3.4.0", + "symfony/css-selector": "^3.4.0", + "symfony/debug": "^3.4.0", + "symfony/dom-crawler": "^3.4.0 !=3.4.38", + "symfony/filesystem": "~3.4.0", + "symfony/finder": "~3.4.0", + "symfony/lock": "~3.4.0", + "symfony/phpunit-bridge": "^3.4.3" + }, + "conflict": { + "webflo/drupal-core-require-dev": "*" + }, + "type": "metapackage", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0-or-later" + ], + "description": "require-dev dependencies from drupal/drupal; use in addition to drupal/core-recommended to run tests from drupal/core.", + "time": "2020-05-09T07:53:22+00:00" + }, + { + "name": "fabpot/goutte", + "version": "v3.2.3", + "source": { + "type": "git", + "url": "https://github.com/FriendsOfPHP/Goutte.git", + "reference": "3f0eaf0a40181359470651f1565b3e07e3dd31b8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/FriendsOfPHP/Goutte/zipball/3f0eaf0a40181359470651f1565b3e07e3dd31b8", + "reference": "3f0eaf0a40181359470651f1565b3e07e3dd31b8", + "shasum": "" + }, + "require": { + "guzzlehttp/guzzle": "^6.0", + "php": ">=5.5.0", + "symfony/browser-kit": "~2.1|~3.0|~4.0", + "symfony/css-selector": "~2.1|~3.0|~4.0", + "symfony/dom-crawler": "~2.1|~3.0|~4.0" + }, + "require-dev": { + "symfony/phpunit-bridge": "^3.3 || ^4" + }, + "type": "application", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "psr-4": { + "Goutte\\": "Goutte" + }, + "exclude-from-classmap": [ + "Goutte/Tests" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "A simple PHP Web Scraper", + "homepage": "https://github.com/FriendsOfPHP/Goutte", + "keywords": [ + "scraper" + ], + "time": "2018-06-29T15:13:57+00:00" + }, + { + "name": "instaclick/php-webdriver", + "version": "1.4.7", + "source": { + "type": "git", + "url": "https://github.com/instaclick/php-webdriver.git", + "reference": "b5f330e900e9b3edfc18024a5ec8c07136075712" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/instaclick/php-webdriver/zipball/b5f330e900e9b3edfc18024a5ec8c07136075712", + "reference": "b5f330e900e9b3edfc18024a5ec8c07136075712", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "^4.8", + "satooshi/php-coveralls": "^1.0||^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "psr-0": { + "WebDriver": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Justin Bishop", + "email": "jubishop@gmail.com", + "role": "Developer" + }, + { + "name": "Anthon Pang", + "email": "apang@softwaredevelopment.ca", + "role": "Fork Maintainer" + } + ], + "description": "PHP WebDriver for Selenium 2", + "homepage": "http://instaclick.com/", + "keywords": [ + "browser", + "selenium", + "webdriver", + "webtest" + ], + "time": "2019-09-25T09:05:11+00:00" + }, + { + "name": "jcalderonzumba/gastonjs", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/jcalderonzumba/gastonjs.git", + "reference": "575a9c18d8b87990c37252e8d9707b29f0a313f3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jcalderonzumba/gastonjs/zipball/575a9c18d8b87990c37252e8d9707b29f0a313f3", + "reference": "575a9c18d8b87990c37252e8d9707b29f0a313f3", + "shasum": "" + }, + "require": { + "guzzlehttp/guzzle": "~5.0|~6.0", + "php": ">=5.4" + }, + "require-dev": { + "phpunit/phpunit": "~4.6", + "silex/silex": "~1.2", + "symfony/phpunit-bridge": "~2.7", + "symfony/process": "~2.1" + }, + "type": "phantomjs-api", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Zumba\\GastonJS\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Juan Francisco Calderón Zumba", + "email": "juanfcz@gmail.com", + "homepage": "http://github.com/jcalderonzumba" + } + ], + "description": "PhantomJS API based server for webpage automation", + "homepage": "https://github.com/jcalderonzumba/gastonjs", + "keywords": [ + "api", + "automation", + "browser", + "headless", + "phantomjs" + ], + "time": "2017-03-31T07:31:47+00:00" + }, + { + "name": "jcalderonzumba/mink-phantomjs-driver", + "version": "v0.3.3", + "source": { + "type": "git", + "url": "https://github.com/jcalderonzumba/MinkPhantomJSDriver.git", + "reference": "008f43670e94acd39273d15add1e7348eb23848d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jcalderonzumba/MinkPhantomJSDriver/zipball/008f43670e94acd39273d15add1e7348eb23848d", + "reference": "008f43670e94acd39273d15add1e7348eb23848d", + "shasum": "" + }, + "require": { + "behat/mink": "~1.7", + "jcalderonzumba/gastonjs": "~1.0", + "php": ">=5.4", + "twig/twig": "~1.20|~2.0" + }, + "require-dev": { + "mink/driver-testsuite": "dev-master", + "phpunit/phpunit": "~4.6" + }, + "type": "mink-driver", + "extra": { + "branch-alias": { + "dev-master": "0.4.x-dev" + } + }, + "autoload": { + "psr-4": { + "Zumba\\Mink\\Driver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Juan Francisco Calderón Zumba", + "email": "juanfcz@gmail.com", + "homepage": "http://github.com/jcalderonzumba" + } + ], + "description": "PhantomJS driver for Mink framework", + "homepage": "http://mink.behat.org/", + "keywords": [ + "ajax", + "browser", + "headless", + "javascript", + "phantomjs", + "testing" + ], + "time": "2016-12-01T10:57:30+00:00" + }, + { + "name": "justinrainbow/json-schema", + "version": "5.2.10", + "source": { + "type": "git", + "url": "https://github.com/justinrainbow/json-schema.git", + "reference": "2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b", + "reference": "2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "~2.2.20||~2.15.1", + "json-schema/json-schema-test-suite": "1.2.0", + "phpunit/phpunit": "^4.8.35" + }, + "bin": [ + "bin/validate-json" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "JsonSchema\\": "src/JsonSchema/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bruno Prieto Reis", + "email": "bruno.p.reis@gmail.com" + }, + { + "name": "Justin Rainbow", + "email": "justin.rainbow@gmail.com" + }, + { + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" + }, + { + "name": "Robert Schönthal", + "email": "seroscho@googlemail.com" + } + ], + "description": "A library to validate a json schema.", + "homepage": "https://github.com/justinrainbow/json-schema", + "keywords": [ + "json", + "schema" + ], + "time": "2020-05-27T16:41:55+00:00" + }, + { + "name": "mikey179/vfsstream", + "version": "v1.6.8", + "source": { + "type": "git", + "url": "https://github.com/bovigo/vfsStream.git", + "reference": "231c73783ebb7dd9ec77916c10037eff5a2b6efe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/bovigo/vfsStream/zipball/231c73783ebb7dd9ec77916c10037eff5a2b6efe", + "reference": "231c73783ebb7dd9ec77916c10037eff5a2b6efe", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.5|^5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6.x-dev" + } + }, + "autoload": { + "psr-0": { + "org\\bovigo\\vfs\\": "src/main/php" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Frank Kleine", + "homepage": "http://frankkleine.de/", + "role": "Developer" + } + ], + "description": "Virtual file system to mock the real file system in unit tests.", + "homepage": "http://vfs.bovigo.org/", + "time": "2019-10-30T15:31:00+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.10.2", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220", + "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "replace": { + "myclabs/deep-copy": "self.version" + }, + "require-dev": { + "doctrine/collections": "^1.0", + "doctrine/common": "^2.6", + "phpunit/phpunit": "^7.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + }, + "files": [ + "src/DeepCopy/deep_copy.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2020-11-13T09:40:50+00:00" + }, + { + "name": "phar-io/manifest", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", + "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "phar-io/version": "^2.0", + "php": "^5.6 || ^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "time": "2018-07-08T19:23:20+00:00" + }, + { + "name": "phar-io/version", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6", + "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "time": "2018-07-08T19:19:57+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": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "time": "2020-06-27T09:03:43+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "5.2.2", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/069a785b2141f5bcf49f3e353548dc1cce6df556", + "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556", + "shasum": "" + }, + "require": { + "ext-filter": "*", + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.2", + "phpdocumentor/type-resolver": "^1.3", + "webmozart/assert": "^1.9.1" + }, + "require-dev": { + "mockery/mockery": "~1.3.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "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": "2020-09-03T19:13:55+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", + "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.0" + }, + "require-dev": { + "ext-tokenizer": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "time": "2020-09-17T18:55:26+00:00" + }, + { + "name": "phpspec/prophecy", + "version": "1.12.1", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "8ce87516be71aae9b956f81906aaf0338e0d8a2d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/8ce87516be71aae9b956f81906aaf0338e0d8a2d", + "reference": "8ce87516be71aae9b956f81906aaf0338e0d8a2d", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.2", + "php": "^7.2 || ~8.0, <8.1", + "phpdocumentor/reflection-docblock": "^5.2", + "sebastian/comparator": "^3.0 || ^4.0", + "sebastian/recursion-context": "^3.0 || ^4.0" + }, + "require-dev": { + "phpspec/phpspec": "^6.0", + "phpunit/phpunit": "^8.0 || ^9.0 <9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.11.x-dev" + } + }, + "autoload": { + "psr-4": { + "Prophecy\\": "src/Prophecy" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "time": "2020-09-29T09:10:42+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "6.1.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/807e6013b00af69b6c5d9ceb4282d0393dbb9d8d", + "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-xmlwriter": "*", + "php": "^7.1", + "phpunit/php-file-iterator": "^2.0", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-token-stream": "^3.0", + "sebastian/code-unit-reverse-lookup": "^1.0.1", + "sebastian/environment": "^3.1 || ^4.0", + "sebastian/version": "^2.0.1", + "theseer/tokenizer": "^1.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "suggest": { + "ext-xdebug": "^2.6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "time": "2018-10-31T16:06:48+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "050bedf145a257b1ff02746c31894800e5122946" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/050bedf145a257b1ff02746c31894800e5122946", + "reference": "050bedf145a257b1ff02746c31894800e5122946", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "time": "2018-09-13T20:33:42+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "time": "2015-06-21T13:50:34+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "2.1.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "1038454804406b0b5f5f520358e78c1c2f71501e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/1038454804406b0b5f5f520358e78c1c2f71501e", + "reference": "1038454804406b0b5f5f520358e78c1c2f71501e", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "time": "2019-06-07T04:22:29+00:00" + }, + { + "name": "phpunit/php-token-stream", + "version": "3.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "995192df77f63a59e47f025390d2d1fdf8f425ff" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/995192df77f63a59e47f025390d2d1fdf8f425ff", + "reference": "995192df77f63a59e47f025390d2d1fdf8f425ff", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ], + "abandoned": true, + "time": "2019-09-17T06:23:10+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "7.5.20", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "9467db479d1b0487c99733bb1e7944d32deded2c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9467db479d1b0487c99733bb1e7944d32deded2c", + "reference": "9467db479d1b0487c99733bb1e7944d32deded2c", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.1", + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "myclabs/deep-copy": "^1.7", + "phar-io/manifest": "^1.0.2", + "phar-io/version": "^2.0", + "php": "^7.1", + "phpspec/prophecy": "^1.7", + "phpunit/php-code-coverage": "^6.0.7", + "phpunit/php-file-iterator": "^2.0.1", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-timer": "^2.1", + "sebastian/comparator": "^3.0", + "sebastian/diff": "^3.0", + "sebastian/environment": "^4.0", + "sebastian/exporter": "^3.1", + "sebastian/global-state": "^2.0", + "sebastian/object-enumerator": "^3.0.3", + "sebastian/resource-operations": "^2.0", + "sebastian/version": "^2.0.1" + }, + "conflict": { + "phpunit/phpunit-mock-objects": "*" + }, + "require-dev": { + "ext-pdo": "*" + }, + "suggest": { + "ext-soap": "*", + "ext-xdebug": "*", + "phpunit/php-invoker": "^2.0" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.5-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "time": "2020-01-08T08:45:45+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "time": "2017-03-04T06:30:41+00:00" + }, + { + "name": "sebastian/comparator", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/5de4fc177adf9bce8df98d8d141a7559d7ccf6da", + "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da", + "shasum": "" + }, + "require": { + "php": "^7.1", + "sebastian/diff": "^3.0", + "sebastian/exporter": "^3.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "time": "2018-07-12T15:12:46+00:00" + }, + { + "name": "sebastian/diff", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/720fcc7e9b5cf384ea68d9d930d480907a0c1a29", + "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.5 || ^8.0", + "symfony/process": "^2 || ^3.3 || ^4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "time": "2019-02-04T06:01:07+00:00" + }, + { + "name": "sebastian/environment", + "version": "4.2.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "464c90d7bdf5ad4e8a6aea15c091fec0603d4368" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/464c90d7bdf5ad4e8a6aea15c091fec0603d4368", + "reference": "464c90d7bdf5ad4e8a6aea15c091fec0603d4368", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.5" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "time": "2019-11-20T08:46:58+00:00" + }, + { + "name": "sebastian/exporter", + "version": "3.1.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/68609e1261d215ea5b21b7987539cbfbe156ec3e", + "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e", + "shasum": "" + }, + "require": { + "php": "^7.0", + "sebastian/recursion-context": "^3.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "time": "2019-09-14T09:02:43+00:00" + }, + { + "name": "sebastian/global-state", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "time": "2017-04-27T15:39:26+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5", + "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5", + "shasum": "" + }, + "require": { + "php": "^7.0", + "sebastian/object-reflector": "^1.1.1", + "sebastian/recursion-context": "^3.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "time": "2017-08-03T12:35:26+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "773f97c67f28de00d397be301821b06708fca0be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", + "reference": "773f97c67f28de00d397be301821b06708fca0be", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "time": "2017-03-29T09:07:27+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "time": "2017-03-03T06:23:57+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/4d7a795d35b889bf80a0cc04e08d77cedfa917a9", + "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "time": "2018-10-04T04:07:39+00:00" + }, + { + "name": "sebastian/version", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "time": "2016-10-03T07:35:21+00:00" + }, + { + "name": "seld/jsonlint", + "version": "1.8.3", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/jsonlint.git", + "reference": "9ad6ce79c342fbd44df10ea95511a1b24dee5b57" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/9ad6ce79c342fbd44df10ea95511a1b24dee5b57", + "reference": "9ad6ce79c342fbd44df10ea95511a1b24dee5b57", + "shasum": "" + }, + "require": { + "php": "^5.3 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + }, + "bin": [ + "bin/jsonlint" + ], + "type": "library", + "autoload": { + "psr-4": { + "Seld\\JsonLint\\": "src/Seld/JsonLint/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "JSON Linter", + "keywords": [ + "json", + "linter", + "parser", + "validator" + ], + "funding": [ + { + "url": "https://github.com/Seldaek", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/seld/jsonlint", + "type": "tidelift" + } + ], + "time": "2020-11-11T09:19:24+00:00" + }, + { + "name": "seld/phar-utils", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/phar-utils.git", + "reference": "8674b1d84ffb47cc59a101f5d5a3b61e87d23796" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/phar-utils/zipball/8674b1d84ffb47cc59a101f5d5a3b61e87d23796", + "reference": "8674b1d84ffb47cc59a101f5d5a3b61e87d23796", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Seld\\PharUtils\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be" + } + ], + "description": "PHAR file format utilities, for when PHP phars you up", + "keywords": [ + "phar" + ], + "time": "2020-07-07T18:42:57+00:00" + }, + { + "name": "sirbrillig/phpcs-variable-analysis", + "version": "v2.9.0", + "source": { + "type": "git", + "url": "https://github.com/sirbrillig/phpcs-variable-analysis.git", + "reference": "ff54d4ec7f2bd152d526fdabfeff639aa9b8be01" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sirbrillig/phpcs-variable-analysis/zipball/ff54d4ec7f2bd152d526fdabfeff639aa9b8be01", + "reference": "ff54d4ec7f2bd152d526fdabfeff639aa9b8be01", + "shasum": "" + }, + "require": { + "php": ">=5.4.0", + "squizlabs/php_codesniffer": "^3.1" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4 || ^0.5 || ^0.6", + "limedeck/phpunit-detailed-printer": "^3.1 || ^4.0 || ^5.0", + "phpstan/phpstan": "^0.11.8", + "phpunit/phpunit": "^5.0 || ^6.5 || ^7.0 || ^8.0", + "sirbrillig/phpcs-import-detection": "^1.1" + }, + "type": "phpcodesniffer-standard", + "autoload": { + "psr-4": { + "VariableAnalysis\\": "VariableAnalysis/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Sam Graham", + "email": "php-codesniffer-variableanalysis@illusori.co.uk" + }, + { + "name": "Payton Swick", + "email": "payton@foolord.com" + } + ], + "description": "A PHPCS sniff to detect problems with variables.", + "time": "2020-10-07T23:32:29+00:00" + }, + { + "name": "squizlabs/php_codesniffer", + "version": "3.5.8", + "source": { + "type": "git", + "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", + "reference": "9d583721a7157ee997f235f327de038e7ea6dac4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/9d583721a7157ee997f235f327de038e7ea6dac4", + "reference": "9d583721a7157ee997f235f327de038e7ea6dac4", + "shasum": "" + }, + "require": { + "ext-simplexml": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" + }, + "bin": [ + "bin/phpcs", + "bin/phpcbf" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Greg Sherwood", + "role": "lead" + } + ], + "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", + "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", + "keywords": [ + "phpcs", + "standards" + ], + "time": "2020-10-23T02:01:07+00:00" + }, + { + "name": "symfony/browser-kit", + "version": "v3.4.46", + "source": { + "type": "git", + "url": "https://github.com/symfony/browser-kit.git", + "reference": "9590bd3d3f9fa2f28d34b713ed4765a8cc8ad15c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/browser-kit/zipball/9590bd3d3f9fa2f28d34b713ed4765a8cc8ad15c", + "reference": "9590bd3d3f9fa2f28d34b713ed4765a8cc8ad15c", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/dom-crawler": "~2.8|~3.0|~4.0" + }, + "require-dev": { + "symfony/css-selector": "~2.8|~3.0|~4.0", + "symfony/process": "~2.8|~3.0|~4.0" + }, + "suggest": { + "symfony/process": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\BrowserKit\\": "" + }, + "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 BrowserKit Component", + "homepage": "https://symfony.com", + "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-24T10:57:07+00:00" + }, + { + "name": "symfony/css-selector", + "version": "v3.4.46", + "source": { + "type": "git", + "url": "https://github.com/symfony/css-selector.git", + "reference": "da3d9da2ce0026771f5fe64cb332158f1bd2bc33" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/da3d9da2ce0026771f5fe64cb332158f1bd2bc33", + "reference": "da3d9da2ce0026771f5fe64cb332158f1bd2bc33", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\CssSelector\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Jean-François Simon", + "email": "jeanfrancois.simon@sensiolabs.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony CssSelector Component", + "homepage": "https://symfony.com", + "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-24T10:57:07+00:00" + }, + { + "name": "symfony/dom-crawler", + "version": "v3.4.46", + "source": { + "type": "git", + "url": "https://github.com/symfony/dom-crawler.git", + "reference": "ef97bcfbae5b384b4ca6c8d57b617722f15241a6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/ef97bcfbae5b384b4ca6c8d57b617722f15241a6", + "reference": "ef97bcfbae5b384b4ca6c8d57b617722f15241a6", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.0" + }, + "require-dev": { + "symfony/css-selector": "~2.8|~3.0|~4.0" + }, + "suggest": { + "symfony/css-selector": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\DomCrawler\\": "" + }, + "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 DomCrawler Component", + "homepage": "https://symfony.com", + "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-24T10:57:07+00:00" + }, + { + "name": "symfony/lock", + "version": "v3.4.46", + "source": { + "type": "git", + "url": "https://github.com/symfony/lock.git", + "reference": "8d451ed419a3d5d503bd491437b447fd4c549ceb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/lock/zipball/8d451ed419a3d5d503bd491437b447fd4c549ceb", + "reference": "8d451ed419a3d5d503bd491437b447fd4c549ceb", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "psr/log": "~1.0", + "symfony/polyfill-php70": "~1.0" + }, + "require-dev": { + "predis/predis": "~1.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Lock\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jérémy Derussé", + "email": "jeremy@derusse.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Lock Component", + "homepage": "https://symfony.com", + "keywords": [ + "cas", + "flock", + "locking", + "mutex", + "redlock", + "semaphore" + ], + "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-24T10:57:07+00:00" + }, + { + "name": "symfony/phpunit-bridge", + "version": "v3.4.46", + "source": { + "type": "git", + "url": "https://github.com/symfony/phpunit-bridge.git", + "reference": "8d05c61270c40f457e0fc11d47cc112c0f2e3606" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/8d05c61270c40f457e0fc11d47cc112c0f2e3606", + "reference": "8d05c61270c40f457e0fc11d47cc112c0f2e3606", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "conflict": { + "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0|<6.4,>=6.0|9.1.2" + }, + "suggest": { + "symfony/debug": "For tracking deprecated interfaces usages at runtime with DebugClassLoader" + }, + "bin": [ + "bin/simple-phpunit" + ], + "type": "symfony-bridge", + "extra": { + "thanks": { + "name": "phpunit/phpunit", + "url": "https://github.com/sebastianbergmann/phpunit" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Bridge\\PhpUnit\\": "" + }, + "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": "Symfony PHPUnit Bridge", + "homepage": "https://symfony.com", + "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-24T10:57:07+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "75a63c33a8577608444246075ea0af0d052e452a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/75a63c33a8577608444246075ea0af0d052e452a", + "reference": "75a63c33a8577608444246075ea0af0d052e452a", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2020-07-12T23:59:07+00:00" + } + ], + "aliases": [], + "minimum-stability": "dev", + "stability-flags": [], + "prefer-stable": true, + "prefer-lowest": false, + "platform": [], + "platform-dev": [], + "plugin-api-version": "1.1.0" +} diff --git a/config/.gitkeep b/config/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000..a0e7463 --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + ./web/modules/custom/**/tests/**/Functional + + + ./web/modules/custom/**/tests/**/Kernel + + + ./web/modules/custom/**/tests/**/Unit + + + diff --git a/web/sites/default/settings.php b/web/sites/default/settings.php new file mode 100644 index 0000000..051e0e4 --- /dev/null +++ b/web/sites/default/settings.php @@ -0,0 +1,16 @@ + Date: Thu, 19 Mar 2020 20:26:43 +0000 Subject: [PATCH 29/77] 1b: Add my_module.info.yml Add the my_module.info.yml file so that the module can be enabled. --- .gitignore | 1 + web/modules/custom/my_module/my_module.info.yml | 5 +++++ 2 files changed, 6 insertions(+) create mode 100644 web/modules/custom/my_module/my_module.info.yml diff --git a/.gitignore b/.gitignore index 32f0b75..66908d5 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ !/docker-compose.yaml !/Makefile !/php.ini +!/web/modules/custom/** !/web/sites/default/settings.php !/web/sites/default/settings.symfony.php !/workspace.yml diff --git a/web/modules/custom/my_module/my_module.info.yml b/web/modules/custom/my_module/my_module.info.yml new file mode 100644 index 0000000..21d262e --- /dev/null +++ b/web/modules/custom/my_module/my_module.info.yml @@ -0,0 +1,5 @@ +name: My Module +type: module +core: 8.x +core_version_requirement: ^8 || ^9 +package: Custom From fd921d3e4cb099306f91219b5011c9c425dac31e Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Thu, 19 Mar 2020 20:33:41 +0000 Subject: [PATCH 30/77] 1d: Add first functional test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ensure that anonymous users can view the site’s front page. --- .../tests/src/Functional/MyModuleTest.php | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 web/modules/custom/my_module/tests/src/Functional/MyModuleTest.php diff --git a/web/modules/custom/my_module/tests/src/Functional/MyModuleTest.php b/web/modules/custom/my_module/tests/src/Functional/MyModuleTest.php new file mode 100644 index 0000000..3158087 --- /dev/null +++ b/web/modules/custom/my_module/tests/src/Functional/MyModuleTest.php @@ -0,0 +1,21 @@ +drupalGet(''); + + $this->assertResponse(Response::HTTP_OK); + } + +} From 7e0a0c376223433983773c40d32c4ee0f49d3fcb Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Thu, 19 Mar 2020 20:39:37 +0000 Subject: [PATCH 31/77] 2a: Admin page access for anonymous users MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ensure that anonymous users cannot access the site’s administration pages. --- .../custom/my_module/tests/src/Functional/MyModuleTest.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/web/modules/custom/my_module/tests/src/Functional/MyModuleTest.php b/web/modules/custom/my_module/tests/src/Functional/MyModuleTest.php index 3158087..4173e30 100644 --- a/web/modules/custom/my_module/tests/src/Functional/MyModuleTest.php +++ b/web/modules/custom/my_module/tests/src/Functional/MyModuleTest.php @@ -18,4 +18,11 @@ class MyModuleTest extends BrowserTestBase { $this->assertResponse(Response::HTTP_OK); } + /** @test */ + public function the_admin_page_is_not_accessible_to_anonymous_users() { + $this->drupalGet('admin'); + + $this->assertResponse(Response::HTTP_FORBIDDEN); + } + } From 9df597c965661eef45438a4132246cbeea70dc3f Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Thu, 19 Mar 2020 20:41:42 +0000 Subject: [PATCH 32/77] 2b: Admin page access for admin users MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ensure that users with the `access administration pages` permission can access the site’s administration pages. --- .../my_module/tests/src/Functional/MyModuleTest.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/web/modules/custom/my_module/tests/src/Functional/MyModuleTest.php b/web/modules/custom/my_module/tests/src/Functional/MyModuleTest.php index 4173e30..b8f7ffe 100644 --- a/web/modules/custom/my_module/tests/src/Functional/MyModuleTest.php +++ b/web/modules/custom/my_module/tests/src/Functional/MyModuleTest.php @@ -25,4 +25,17 @@ class MyModuleTest extends BrowserTestBase { $this->assertResponse(Response::HTTP_FORBIDDEN); } + /** @test */ + public function the_admin_page_is_accessible_by_admin_users() { + $adminUser = $this->createUser([ + 'access administration pages', + ]); + + $this->drupalLogin($adminUser); + + $this->drupalGet('admin'); + + $this->assertResponse(Response::HTTP_OK); + } + } From 151803382ef0b065b09a5f1f87c1fa18699f88a0 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Thu, 19 Mar 2020 20:46:19 +0000 Subject: [PATCH 33/77] 3a: Add blog page functional test Add the new `BlogPageTest` functional test to ensure that anonymous users can access the `/blog` page. This fails, and returns a 404 response code rather than the expected 200 response code. --- .../tests/src/Functional/BlogPageTest.php | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 web/modules/custom/my_module/tests/src/Functional/BlogPageTest.php diff --git a/web/modules/custom/my_module/tests/src/Functional/BlogPageTest.php b/web/modules/custom/my_module/tests/src/Functional/BlogPageTest.php new file mode 100644 index 0000000..5b3e287 --- /dev/null +++ b/web/modules/custom/my_module/tests/src/Functional/BlogPageTest.php @@ -0,0 +1,25 @@ +drupalGet('blog'); + + $session = $this->assertSession(); + + $session->statusCodeEquals(Response::HTTP_OK); + } + +} From c7ef94c0d5f9bce459a9704ffb08954a8487445a Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Thu, 19 Mar 2020 20:48:28 +0000 Subject: [PATCH 34/77] 3b: Add blog page route Add a `my_module.routing.yml` file that adds the missing route for `/blog`. This fails, and returns a 403 response code rather than the expected 200 response code. --- web/modules/custom/my_module/my_module.routing.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 web/modules/custom/my_module/my_module.routing.yml diff --git a/web/modules/custom/my_module/my_module.routing.yml b/web/modules/custom/my_module/my_module.routing.yml new file mode 100644 index 0000000..9683277 --- /dev/null +++ b/web/modules/custom/my_module/my_module.routing.yml @@ -0,0 +1,7 @@ +blog.page: + path: /blog + defaults: + _controller: Drupal\my_module\Controller\BlogPageController + _title: Blog + requirements: + _permission: access content From 782648fef2285c3995a5600541aaf30be2c8d764 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Thu, 19 Mar 2020 20:51:28 +0000 Subject: [PATCH 35/77] 3c: Enable the node module Enable the node module within the test to add the `access content` permission. This fails, and returns a 500 response code rather than the expected 200 response code. --- .../custom/my_module/tests/src/Functional/BlogPageTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/web/modules/custom/my_module/tests/src/Functional/BlogPageTest.php b/web/modules/custom/my_module/tests/src/Functional/BlogPageTest.php index 5b3e287..28e0732 100644 --- a/web/modules/custom/my_module/tests/src/Functional/BlogPageTest.php +++ b/web/modules/custom/my_module/tests/src/Functional/BlogPageTest.php @@ -10,6 +10,7 @@ class BlogPageTest extends BrowserTestBase { protected $defaultTheme = 'stark'; protected static $modules = [ + 'node', 'my_module', ]; From 4583075a3ec998777ca977196d8c08c42acb298f Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Thu, 19 Mar 2020 20:53:46 +0000 Subject: [PATCH 36/77] 3d: Add BlogPageController MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the BlogPageController that is referenced within `my_module.routing.yml`. We will need to return a render array, but for now let’s return an empty array. The test now passes as we are getting the expected response code. --- .../my_module/src/Controller/BlogPageController.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 web/modules/custom/my_module/src/Controller/BlogPageController.php diff --git a/web/modules/custom/my_module/src/Controller/BlogPageController.php b/web/modules/custom/my_module/src/Controller/BlogPageController.php new file mode 100644 index 0000000..91e702c --- /dev/null +++ b/web/modules/custom/my_module/src/Controller/BlogPageController.php @@ -0,0 +1,12 @@ + Date: Thu, 19 Mar 2020 20:56:53 +0000 Subject: [PATCH 37/77] 3e: Add more assertions Add more assertions to ensure that the correct page title is returned as well as some text on the page. This fails as the expected test is not returned. --- .../custom/my_module/tests/src/Functional/BlogPageTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/web/modules/custom/my_module/tests/src/Functional/BlogPageTest.php b/web/modules/custom/my_module/tests/src/Functional/BlogPageTest.php index 28e0732..043f5db 100644 --- a/web/modules/custom/my_module/tests/src/Functional/BlogPageTest.php +++ b/web/modules/custom/my_module/tests/src/Functional/BlogPageTest.php @@ -21,6 +21,8 @@ class BlogPageTest extends BrowserTestBase { $session = $this->assertSession(); $session->statusCodeEquals(Response::HTTP_OK); + $session->responseContains('

Blog

'); + $session->pageTextContains('Welcome to my blog!'); } } From 9484d924a16e49b3e98b24cbe648bd2925dfded6 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Thu, 19 Mar 2020 21:00:51 +0000 Subject: [PATCH 38/77] 3e: Add page text Replace the empty render array with one that returns the expected text. --- .../my_module/src/Controller/BlogPageController.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/web/modules/custom/my_module/src/Controller/BlogPageController.php b/web/modules/custom/my_module/src/Controller/BlogPageController.php index 91e702c..d11eb05 100644 --- a/web/modules/custom/my_module/src/Controller/BlogPageController.php +++ b/web/modules/custom/my_module/src/Controller/BlogPageController.php @@ -2,10 +2,16 @@ namespace Drupal\my_module\Controller; +use Drupal\Core\StringTranslation\StringTranslationTrait; + class BlogPageController { + use StringTranslationTrait; + public function __invoke(): array { - return []; + return [ + '#markup' => $this->t('Welcome to my blog!'), + ]; } } From 48ab1c9209d0ea5588c67a51e6bfd909f488869f Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Sat, 14 Nov 2020 09:01:47 +0000 Subject: [PATCH 39/77] 4b: Test it returns blog posts --- .../tests/src/Kernel/ArticleRepositoryTest.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php diff --git a/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php b/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php new file mode 100644 index 0000000..790efdc --- /dev/null +++ b/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php @@ -0,0 +1,14 @@ +assertCount(1, $articles); + } + +} From 3e46173860919aa14fb115ae8efc773b0e963aeb Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Sat, 14 Nov 2020 09:02:35 +0000 Subject: [PATCH 40/77] 4c: Try to load the ArticleRepository --- .../custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php b/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php index 790efdc..47abf6d 100644 --- a/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php +++ b/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php @@ -8,6 +8,8 @@ class ArticleRepositoryTest extends EntityKernelTestBase { /** @test */ public function it_returns_blog_posts() { + $repository = $this->container->get(ArticleRepository::class); + $this->assertCount(1, $articles); } From 699122e83a1abad80815de15b40d43f7af5f1219 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Sat, 14 Nov 2020 09:04:04 +0000 Subject: [PATCH 41/77] 4d: Create the ArticleRepository --- .../custom/my_module/src/Repository/ArticleRepository.php | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 web/modules/custom/my_module/src/Repository/ArticleRepository.php diff --git a/web/modules/custom/my_module/src/Repository/ArticleRepository.php b/web/modules/custom/my_module/src/Repository/ArticleRepository.php new file mode 100644 index 0000000..23d215b --- /dev/null +++ b/web/modules/custom/my_module/src/Repository/ArticleRepository.php @@ -0,0 +1,7 @@ + Date: Sat, 14 Nov 2020 09:05:12 +0000 Subject: [PATCH 42/77] 4d: Add ArticleRepository as a service --- web/modules/custom/my_module/my_module.services.yml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 web/modules/custom/my_module/my_module.services.yml diff --git a/web/modules/custom/my_module/my_module.services.yml b/web/modules/custom/my_module/my_module.services.yml new file mode 100644 index 0000000..422db39 --- /dev/null +++ b/web/modules/custom/my_module/my_module.services.yml @@ -0,0 +1,2 @@ +services: + Drupal\my_module\Repository\ArticleRepository: ~ From f194015f3001046a37c3ea62c942ed0003dc0f21 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Sat, 14 Nov 2020 09:05:59 +0000 Subject: [PATCH 43/77] 4d: Add import and enable the module --- .../my_module/tests/src/Kernel/ArticleRepositoryTest.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php b/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php index 47abf6d..949f5e9 100644 --- a/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php +++ b/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php @@ -3,9 +3,12 @@ namespace Drupal\Tests\my_module\Kernel; use Drupal\KernelTests\Core\Entity\EntityKernelTestBase; +use Drupal\my_module\Repository\ArticleRepository; class ArticleRepositoryTest extends EntityKernelTestBase { + public static $modules = ['my_module']; + /** @test */ public function it_returns_blog_posts() { $repository = $this->container->get(ArticleRepository::class); From f38f21fdc89a45cb3403efefe3ec0d8e7b76be37 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Sat, 14 Nov 2020 09:07:23 +0000 Subject: [PATCH 44/77] 4e: Add getAll() method --- .../custom/my_module/src/Repository/ArticleRepository.php | 4 ++++ .../my_module/tests/src/Kernel/ArticleRepositoryTest.php | 1 + 2 files changed, 5 insertions(+) diff --git a/web/modules/custom/my_module/src/Repository/ArticleRepository.php b/web/modules/custom/my_module/src/Repository/ArticleRepository.php index 23d215b..8f859ec 100644 --- a/web/modules/custom/my_module/src/Repository/ArticleRepository.php +++ b/web/modules/custom/my_module/src/Repository/ArticleRepository.php @@ -4,4 +4,8 @@ namespace Drupal\my_module\Repository; class ArticleRepository { + public function getAll(): array { + return []; + } + } diff --git a/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php b/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php index 949f5e9..73965a5 100644 --- a/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php +++ b/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php @@ -12,6 +12,7 @@ class ArticleRepositoryTest extends EntityKernelTestBase { /** @test */ public function it_returns_blog_posts() { $repository = $this->container->get(ArticleRepository::class); + $articles = $repository->getAll(); $this->assertCount(1, $articles); } From 4dbb334a6f5b1fa7b657a32a4cb827d3b8f00466 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Sat, 14 Nov 2020 09:09:43 +0000 Subject: [PATCH 45/77] 4f: Use node storage within getAll() --- .../my_module/src/Repository/ArticleRepository.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/web/modules/custom/my_module/src/Repository/ArticleRepository.php b/web/modules/custom/my_module/src/Repository/ArticleRepository.php index 8f859ec..3399100 100644 --- a/web/modules/custom/my_module/src/Repository/ArticleRepository.php +++ b/web/modules/custom/my_module/src/Repository/ArticleRepository.php @@ -2,10 +2,18 @@ namespace Drupal\my_module\Repository; +use Drupal\Core\Entity\EntityTypeManagerInterface; + class ArticleRepository { + private $nodeStorage; + + public function __construct(EntityTypeManagerInterface $entityTypeManager) { + $this->nodeStorage = $entityTypeManager->getStorage('node'); + } + public function getAll(): array { - return []; + return $this->nodeStorage->loadMultiple(); } } From 80a1f88b2c0325c3912d16bf4413062071f9208b Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Sat, 14 Nov 2020 09:10:41 +0000 Subject: [PATCH 46/77] 4f: Enable autowiring for ArticleRepository --- web/modules/custom/my_module/my_module.services.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/web/modules/custom/my_module/my_module.services.yml b/web/modules/custom/my_module/my_module.services.yml index 422db39..23aee82 100644 --- a/web/modules/custom/my_module/my_module.services.yml +++ b/web/modules/custom/my_module/my_module.services.yml @@ -1,2 +1,3 @@ services: - Drupal\my_module\Repository\ArticleRepository: ~ + Drupal\my_module\Repository\ArticleRepository: + autowire: true From 9b7d9b3feb9f4dfa407bd1c1066dc08e1d9ca7b8 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Sat, 14 Nov 2020 09:11:14 +0000 Subject: [PATCH 47/77] 4f: Enable the node module --- .../custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php b/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php index 73965a5..d80b5f3 100644 --- a/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php +++ b/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php @@ -7,7 +7,7 @@ use Drupal\my_module\Repository\ArticleRepository; class ArticleRepositoryTest extends EntityKernelTestBase { - public static $modules = ['my_module']; + public static $modules = ['node', 'my_module']; /** @test */ public function it_returns_blog_posts() { From 48c27247362a2bfa5fa2959d5b879e4c6d309cf9 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Sat, 14 Nov 2020 09:12:58 +0000 Subject: [PATCH 48/77] 4g: Add an article --- .../my_module/tests/src/Kernel/ArticleRepositoryTest.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php b/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php index d80b5f3..707a9ad 100644 --- a/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php +++ b/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php @@ -4,13 +4,18 @@ namespace Drupal\Tests\my_module\Kernel; use Drupal\KernelTests\Core\Entity\EntityKernelTestBase; use Drupal\my_module\Repository\ArticleRepository; +use Drupal\Tests\node\Traits\NodeCreationTrait; class ArticleRepositoryTest extends EntityKernelTestBase { + use NodeCreationTrait; + public static $modules = ['node', 'my_module']; /** @test */ public function it_returns_blog_posts() { + $this->createNode(['type' => 'article', 'title' => 'Test post'])->save(); + $repository = $this->container->get(ArticleRepository::class); $articles = $repository->getAll(); From b53cfec4dd3774e7669ad91550c4efb9e9c0d8bb Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Sat, 14 Nov 2020 09:15:09 +0000 Subject: [PATCH 49/77] 4g: Install config for the filter module --- .../my_module/tests/src/Kernel/ArticleRepositoryTest.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php b/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php index 707a9ad..2cb8a20 100644 --- a/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php +++ b/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php @@ -22,4 +22,10 @@ class ArticleRepositoryTest extends EntityKernelTestBase { $this->assertCount(1, $articles); } + protected function setUp() { + parent::setUp(); + + $this->installConfig(['filter']); + } + } From 3723a0af0eee0b4b79a142f50f91eb4999e6e564 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Sat, 14 Nov 2020 09:16:04 +0000 Subject: [PATCH 50/77] 4g: Install node_access table --- .../custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php b/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php index 2cb8a20..cf7281a 100644 --- a/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php +++ b/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php @@ -26,6 +26,8 @@ class ArticleRepositoryTest extends EntityKernelTestBase { parent::setUp(); $this->installConfig(['filter']); + + $this->installSchema('node', ['node_access']); } } From 40228b36f4ff4c441cfd43056721c2de6b7a4433 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Sat, 14 Nov 2020 09:17:57 +0000 Subject: [PATCH 51/77] 4g: Add more assertions --- .../my_module/tests/src/Kernel/ArticleRepositoryTest.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php b/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php index cf7281a..3d44d60 100644 --- a/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php +++ b/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php @@ -4,6 +4,7 @@ namespace Drupal\Tests\my_module\Kernel; use Drupal\KernelTests\Core\Entity\EntityKernelTestBase; use Drupal\my_module\Repository\ArticleRepository; +use Drupal\node\NodeInterface; use Drupal\Tests\node\Traits\NodeCreationTrait; class ArticleRepositoryTest extends EntityKernelTestBase { @@ -20,6 +21,10 @@ class ArticleRepositoryTest extends EntityKernelTestBase { $articles = $repository->getAll(); $this->assertCount(1, $articles); + $this->assertIsObject($articles[1]); + $this->assertInstanceOf(NodeInterface::class, $articles[1]); + $this->assertSame('article', $articles[1]->bundle()); + $this->assertSame('Test post', $articles[1]->label()); } protected function setUp() { From 1be8440519a96ca3a366998ebaf696df2c304305 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Sat, 14 Nov 2020 09:35:10 +0000 Subject: [PATCH 52/77] 4h: Ensure that only articles are returned --- .../tests/src/Kernel/ArticleRepositoryTest.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php b/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php index 3d44d60..de9c7eb 100644 --- a/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php +++ b/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php @@ -27,6 +27,18 @@ class ArticleRepositoryTest extends EntityKernelTestBase { $this->assertSame('Test post', $articles[1]->label()); } + /** @test */ + public function nodes_that_are_not_articles_are_not_returned() { + $this->createNode(['type' => 'article'])->save(); + $this->createNode(['type' => 'article'])->save(); + $this->createNode(['type' => 'article'])->save(); + + $repository = $this->container->get(ArticleRepository::class); + $articles = $repository->getAll(); + + $this->assertCount(3, $articles); + } + protected function setUp() { parent::setUp(); From 910af32309286718c0f48ba1733df4fb60f99526 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Sat, 14 Nov 2020 09:35:46 +0000 Subject: [PATCH 53/77] 4i: Add page nodes too --- .../custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php b/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php index de9c7eb..3a5408d 100644 --- a/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php +++ b/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php @@ -30,7 +30,9 @@ class ArticleRepositoryTest extends EntityKernelTestBase { /** @test */ public function nodes_that_are_not_articles_are_not_returned() { $this->createNode(['type' => 'article'])->save(); + $this->createNode(['type' => 'page'])->save(); $this->createNode(['type' => 'article'])->save(); + $this->createNode(['type' => 'page'])->save(); $this->createNode(['type' => 'article'])->save(); $repository = $this->container->get(ArticleRepository::class); From 2cae42ba3a28f5c716a429cd0ce398de54d6f614 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Sat, 14 Nov 2020 09:36:28 +0000 Subject: [PATCH 54/77] 4i: Add type condition in getAll() method --- .../custom/my_module/src/Repository/ArticleRepository.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/web/modules/custom/my_module/src/Repository/ArticleRepository.php b/web/modules/custom/my_module/src/Repository/ArticleRepository.php index 3399100..83c7688 100644 --- a/web/modules/custom/my_module/src/Repository/ArticleRepository.php +++ b/web/modules/custom/my_module/src/Repository/ArticleRepository.php @@ -13,7 +13,9 @@ class ArticleRepository { } public function getAll(): array { - return $this->nodeStorage->loadMultiple(); + return $this->nodeStorage->loadByProperties([ + 'type' => 'article', + ]); } } From a540f4ad3257db01660109dbdc632f19a0f8df55 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Sat, 14 Nov 2020 09:38:57 +0000 Subject: [PATCH 55/77] 4j: Only published articles are returned --- .../tests/src/Kernel/ArticleRepositoryTest.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php b/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php index 3a5408d..2d3468b 100644 --- a/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php +++ b/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php @@ -41,6 +41,20 @@ class ArticleRepositoryTest extends EntityKernelTestBase { $this->assertCount(3, $articles); } + /** @test */ + public function only_published_articles_are_returned() { + $this->createNode(['type' => 'article', 'status' => NodeInterface::PUBLISHED])->save(); + $this->createNode(['type' => 'article', 'status' => NodeInterface::NOT_PUBLISHED])->save(); + $this->createNode(['type' => 'article', 'status' => NodeInterface::PUBLISHED])->save(); + $this->createNode(['type' => 'article', 'status' => NodeInterface::NOT_PUBLISHED])->save(); + $this->createNode(['type' => 'article', 'status' => NodeInterface::PUBLISHED])->save(); + + $repository = $this->container->get(ArticleRepository::class); + $articles = $repository->getAll(); + + $this->assertCount(3, $articles); + } + protected function setUp() { parent::setUp(); From e925409f5fa6007f3a247076c8ef49afb78a5614 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Sat, 14 Nov 2020 09:39:51 +0000 Subject: [PATCH 56/77] 4j: Add status condition to getAll() --- .../custom/my_module/src/Repository/ArticleRepository.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/web/modules/custom/my_module/src/Repository/ArticleRepository.php b/web/modules/custom/my_module/src/Repository/ArticleRepository.php index 83c7688..30bec82 100644 --- a/web/modules/custom/my_module/src/Repository/ArticleRepository.php +++ b/web/modules/custom/my_module/src/Repository/ArticleRepository.php @@ -3,6 +3,7 @@ namespace Drupal\my_module\Repository; use Drupal\Core\Entity\EntityTypeManagerInterface; +use Drupal\node\NodeInterface; class ArticleRepository { @@ -14,6 +15,7 @@ class ArticleRepository { public function getAll(): array { return $this->nodeStorage->loadByProperties([ + 'status' => NodeInterface::PUBLISHED, 'type' => 'article', ]); } From 91f7d094e79e8077789896676edecf788a420729 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Sat, 14 Nov 2020 09:41:19 +0000 Subject: [PATCH 57/77] 4k: Articles are returned in the correct order --- .../tests/src/Kernel/ArticleRepositoryTest.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php b/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php index 2d3468b..f3af15e 100644 --- a/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php +++ b/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php @@ -2,6 +2,7 @@ namespace Drupal\Tests\my_module\Kernel; +use Drupal\Core\Datetime\DrupalDateTime; use Drupal\KernelTests\Core\Entity\EntityKernelTestBase; use Drupal\my_module\Repository\ArticleRepository; use Drupal\node\NodeInterface; @@ -55,6 +56,21 @@ class ArticleRepositoryTest extends EntityKernelTestBase { $this->assertCount(3, $articles); } + /** @test */ + public function nodes_are_ordered_by_date_and_returned_newest_first() { + $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-2 days'))->getTimestamp()]); + $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-1 week'))->getTimestamp()]); + $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-1 hour'))->getTimestamp()]); + $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-1 year'))->getTimestamp()]); + $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-1 month'))->getTimestamp()]); + + $repository = $this->container->get(ArticleRepository::class); + $nodes = $repository->getAll(); + $nodeIds = array_keys($nodes); + + $this->assertSame([3, 1, 2, 5, 4], $nodeIds); + } + protected function setUp() { parent::setUp(); From 290c8fbcba222c67a9ebf2787635ed9e63433226 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Sat, 14 Nov 2020 09:44:03 +0000 Subject: [PATCH 58/77] 4k: Sort articles before returning --- .../my_module/src/Repository/ArticleRepository.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/web/modules/custom/my_module/src/Repository/ArticleRepository.php b/web/modules/custom/my_module/src/Repository/ArticleRepository.php index 30bec82..20d2e67 100644 --- a/web/modules/custom/my_module/src/Repository/ArticleRepository.php +++ b/web/modules/custom/my_module/src/Repository/ArticleRepository.php @@ -14,10 +14,20 @@ class ArticleRepository { } public function getAll(): array { - return $this->nodeStorage->loadByProperties([ + $articles = $this->nodeStorage->loadByProperties([ 'status' => NodeInterface::PUBLISHED, 'type' => 'article', ]); + + $this->sortByCreatedDate($articles); + + return $articles; + } + + private function sortByCreatedDate(array &$articles): void { + uasort($articles, function (NodeInterface $a, NodeInterface $b): bool { + return $a->getCreatedTime() < $b->getCreatedTime(); + }); } } From 9aec3279454e31bca47154ad172d613395e69408 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Sat, 14 Nov 2020 09:46:05 +0000 Subject: [PATCH 59/77] 4l: Expect a custom Post class to be returned --- web/modules/custom/my_module/src/Entity/Post.php | 5 +++++ .../my_module/tests/src/Kernel/ArticleRepositoryTest.php | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 web/modules/custom/my_module/src/Entity/Post.php diff --git a/web/modules/custom/my_module/src/Entity/Post.php b/web/modules/custom/my_module/src/Entity/Post.php new file mode 100644 index 0000000..9690518 --- /dev/null +++ b/web/modules/custom/my_module/src/Entity/Post.php @@ -0,0 +1,5 @@ +assertCount(1, $articles); $this->assertIsObject($articles[1]); - $this->assertInstanceOf(NodeInterface::class, $articles[1]); - $this->assertSame('article', $articles[1]->bundle()); - $this->assertSame('Test post', $articles[1]->label()); + $this->assertInstanceOf(Post::class, $articles[1]); + $this->assertSame('Test post', $articles[1]->getTitle()); } /** @test */ From 259f077f61b11c5e5937ec93d79314e5f9970fd0 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Sat, 14 Nov 2020 09:56:17 +0000 Subject: [PATCH 60/77] 4m: Return a Post rather than a node --- .../custom/my_module/src/Repository/ArticleRepository.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/web/modules/custom/my_module/src/Repository/ArticleRepository.php b/web/modules/custom/my_module/src/Repository/ArticleRepository.php index 20d2e67..5b8b032 100644 --- a/web/modules/custom/my_module/src/Repository/ArticleRepository.php +++ b/web/modules/custom/my_module/src/Repository/ArticleRepository.php @@ -3,6 +3,7 @@ namespace Drupal\my_module\Repository; use Drupal\Core\Entity\EntityTypeManagerInterface; +use Drupal\my_module\Entity\Post; use Drupal\node\NodeInterface; class ArticleRepository { @@ -21,7 +22,9 @@ class ArticleRepository { $this->sortByCreatedDate($articles); - return $articles; + return array_map(function (NodeInterface $node): Post { + return new Post(); + }, $articles); } private function sortByCreatedDate(array &$articles): void { From cbd0176c370fa8f979bc451f7a6c1a610a34e18e Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Sat, 14 Nov 2020 09:56:42 +0000 Subject: [PATCH 61/77] 5a: Add a unit test for the Post class --- .../custom/my_module/tests/src/Unit/Entity/PostTest.php | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 web/modules/custom/my_module/tests/src/Unit/Entity/PostTest.php diff --git a/web/modules/custom/my_module/tests/src/Unit/Entity/PostTest.php b/web/modules/custom/my_module/tests/src/Unit/Entity/PostTest.php new file mode 100644 index 0000000..0419d69 --- /dev/null +++ b/web/modules/custom/my_module/tests/src/Unit/Entity/PostTest.php @@ -0,0 +1,9 @@ + Date: Sat, 14 Nov 2020 09:57:54 +0000 Subject: [PATCH 62/77] 5b: Check that it returns the post title > Drupal\Tests\my_module\Unit\Entity\PostTest::it_returns_the_title > Error: Call to undefined method Drupal\my_module\Entity\Post::getTitle() --- .../custom/my_module/tests/src/Unit/Entity/PostTest.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/web/modules/custom/my_module/tests/src/Unit/Entity/PostTest.php b/web/modules/custom/my_module/tests/src/Unit/Entity/PostTest.php index 0419d69..254408a 100644 --- a/web/modules/custom/my_module/tests/src/Unit/Entity/PostTest.php +++ b/web/modules/custom/my_module/tests/src/Unit/Entity/PostTest.php @@ -2,8 +2,16 @@ namespace Drupal\Tests\my_module\Unit\Entity; +use Drupal\my_module\Entity\Post; use Drupal\Tests\UnitTestCase; class PostTest extends UnitTestCase { + /** @test */ + public function it_returns_the_title() { + $post = new Post(); + + $this->assertSame('Test post', $post->getTitle()); + } + } From 1fe7119b5dd9cc6132e2f5c558194a1e3ff0aff2 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Sat, 14 Nov 2020 09:59:31 +0000 Subject: [PATCH 63/77] 5b: Add getTitle() method > Failed asserting that two strings are identical --- web/modules/custom/my_module/src/Entity/Post.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/web/modules/custom/my_module/src/Entity/Post.php b/web/modules/custom/my_module/src/Entity/Post.php index 9690518..315c676 100644 --- a/web/modules/custom/my_module/src/Entity/Post.php +++ b/web/modules/custom/my_module/src/Entity/Post.php @@ -2,4 +2,10 @@ namespace Drupal\my_module\Entity; -class Post {} +class Post { + + public function getTitle(): string { + return ''; + } + +} From 61664cb2639cc819d71a678ba22fca36a3563b85 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Sat, 14 Nov 2020 10:01:36 +0000 Subject: [PATCH 64/77] 5c: Add the node as a constructor argument > Undefined variable: node --- web/modules/custom/my_module/src/Entity/Post.php | 8 ++++++++ .../custom/my_module/tests/src/Unit/Entity/PostTest.php | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/web/modules/custom/my_module/src/Entity/Post.php b/web/modules/custom/my_module/src/Entity/Post.php index 315c676..b3cc15b 100644 --- a/web/modules/custom/my_module/src/Entity/Post.php +++ b/web/modules/custom/my_module/src/Entity/Post.php @@ -2,8 +2,16 @@ namespace Drupal\my_module\Entity; +use Drupal\node\NodeInterface; + class Post { + private $node; + + public function __construct(NodeInterface $node) { + $this->node = $node; + } + public function getTitle(): string { return ''; } diff --git a/web/modules/custom/my_module/tests/src/Unit/Entity/PostTest.php b/web/modules/custom/my_module/tests/src/Unit/Entity/PostTest.php index 254408a..841dd29 100644 --- a/web/modules/custom/my_module/tests/src/Unit/Entity/PostTest.php +++ b/web/modules/custom/my_module/tests/src/Unit/Entity/PostTest.php @@ -9,7 +9,7 @@ class PostTest extends UnitTestCase { /** @test */ public function it_returns_the_title() { - $post = new Post(); + $post = new Post($node); $this->assertSame('Test post', $post->getTitle()); } From 0b4c648ac610b808ce2445ae17aaebbd52b798e1 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Sat, 14 Nov 2020 10:02:52 +0000 Subject: [PATCH 65/77] 5c: Return the node label --- web/modules/custom/my_module/src/Entity/Post.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/modules/custom/my_module/src/Entity/Post.php b/web/modules/custom/my_module/src/Entity/Post.php index b3cc15b..5cd63da 100644 --- a/web/modules/custom/my_module/src/Entity/Post.php +++ b/web/modules/custom/my_module/src/Entity/Post.php @@ -13,7 +13,7 @@ class Post { } public function getTitle(): string { - return ''; + return $this->node->label(); } } From bd68420fc10e446fd25921d8ad0eab93c88a83ae Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Sat, 14 Nov 2020 10:03:34 +0000 Subject: [PATCH 66/77] 5d: Create a mock node > TypeError: Return value of Drupal\my_module\Entity\Post::getTitle() > must be of the type string, null returned --- .../custom/my_module/tests/src/Unit/Entity/PostTest.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/web/modules/custom/my_module/tests/src/Unit/Entity/PostTest.php b/web/modules/custom/my_module/tests/src/Unit/Entity/PostTest.php index 841dd29..4ab5273 100644 --- a/web/modules/custom/my_module/tests/src/Unit/Entity/PostTest.php +++ b/web/modules/custom/my_module/tests/src/Unit/Entity/PostTest.php @@ -3,12 +3,15 @@ namespace Drupal\Tests\my_module\Unit\Entity; use Drupal\my_module\Entity\Post; +use Drupal\node\NodeInterface; use Drupal\Tests\UnitTestCase; class PostTest extends UnitTestCase { /** @test */ public function it_returns_the_title() { + $node = $this->createMock(NodeInterface::class); + $post = new Post($node); $this->assertSame('Test post', $post->getTitle()); From 8f8218260b7a2000b91b67fa16f17c40b1c4e853 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Sat, 14 Nov 2020 10:04:45 +0000 Subject: [PATCH 67/77] 5d: Ensure the label will return the title --- .../custom/my_module/tests/src/Unit/Entity/PostTest.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/web/modules/custom/my_module/tests/src/Unit/Entity/PostTest.php b/web/modules/custom/my_module/tests/src/Unit/Entity/PostTest.php index 4ab5273..11c990d 100644 --- a/web/modules/custom/my_module/tests/src/Unit/Entity/PostTest.php +++ b/web/modules/custom/my_module/tests/src/Unit/Entity/PostTest.php @@ -12,6 +12,10 @@ class PostTest extends UnitTestCase { public function it_returns_the_title() { $node = $this->createMock(NodeInterface::class); + $node->expects($this->once()) + ->method('label') + ->willReturn('Test post'); + $post = new Post($node); $this->assertSame('Test post', $post->getTitle()); From 655c854a80ff2b408c99d86ca64cad365ba704bc Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Sat, 14 Nov 2020 10:07:55 +0000 Subject: [PATCH 68/77] 5e: Fix the kernel tests --- .../custom/my_module/src/Repository/ArticleRepository.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/modules/custom/my_module/src/Repository/ArticleRepository.php b/web/modules/custom/my_module/src/Repository/ArticleRepository.php index 5b8b032..20147b6 100644 --- a/web/modules/custom/my_module/src/Repository/ArticleRepository.php +++ b/web/modules/custom/my_module/src/Repository/ArticleRepository.php @@ -23,7 +23,7 @@ class ArticleRepository { $this->sortByCreatedDate($articles); return array_map(function (NodeInterface $node): Post { - return new Post(); + return new Post($node); }, $articles); } From 4be8e022462736a69b78907b16db7e886cfab5ab Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Sat, 14 Nov 2020 12:44:42 +0000 Subject: [PATCH 69/77] Only articles should be used for Posts An Exception should be thrown if the node passed to the `Post` entity is not an article. > Drupal\Tests\my_module\Unit\Entity\PostTest::it_throws_an_exception_if_the_node_is_not_an_article > Failed asserting that exception of type "InvalidArgumentException" is thrown. --- .../my_module/tests/src/Unit/Entity/PostTest.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/web/modules/custom/my_module/tests/src/Unit/Entity/PostTest.php b/web/modules/custom/my_module/tests/src/Unit/Entity/PostTest.php index 11c990d..1bbb779 100644 --- a/web/modules/custom/my_module/tests/src/Unit/Entity/PostTest.php +++ b/web/modules/custom/my_module/tests/src/Unit/Entity/PostTest.php @@ -21,4 +21,15 @@ class PostTest extends UnitTestCase { $this->assertSame('Test post', $post->getTitle()); } + /** @test */ + public function it_throws_an_exception_if_the_node_is_not_an_article() { + $node = $this->createMock(NodeInterface::class); + + $node->method('bundle')->willReturn('page'); + + $this->expectException(\InvalidArgumentException::class); + + new Post($node); + } + } From 0c6fa6e60f5a5fa3755c7c8c0cf0868f9ed9491f Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Sat, 14 Nov 2020 12:52:22 +0000 Subject: [PATCH 70/77] Throw an Exception if it is the wrong type --- web/modules/custom/my_module/src/Entity/Post.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/web/modules/custom/my_module/src/Entity/Post.php b/web/modules/custom/my_module/src/Entity/Post.php index 5cd63da..83e9aac 100644 --- a/web/modules/custom/my_module/src/Entity/Post.php +++ b/web/modules/custom/my_module/src/Entity/Post.php @@ -9,6 +9,10 @@ class Post { private $node; public function __construct(NodeInterface $node) { + if ($node->bundle() != 'article') { + throw new \InvalidArgumentException(); + } + $this->node = $node; } From 0a1da40788f99ad9b65d9d11453c27e0bb3846ee Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Sat, 14 Nov 2020 12:52:36 +0000 Subject: [PATCH 71/77] Fix the existing test --- web/modules/custom/my_module/tests/src/Unit/Entity/PostTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/web/modules/custom/my_module/tests/src/Unit/Entity/PostTest.php b/web/modules/custom/my_module/tests/src/Unit/Entity/PostTest.php index 1bbb779..dd724f9 100644 --- a/web/modules/custom/my_module/tests/src/Unit/Entity/PostTest.php +++ b/web/modules/custom/my_module/tests/src/Unit/Entity/PostTest.php @@ -15,6 +15,7 @@ class PostTest extends UnitTestCase { $node->expects($this->once()) ->method('label') ->willReturn('Test post'); + $node->method('bundle')->willReturn('article'); $post = new Post($node); From 91aed1b171664b83a4dfd0e9d5420ce1227b314e Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Sat, 14 Nov 2020 14:47:53 +0000 Subject: [PATCH 72/77] Updates --- README.md | 367 ++++++++++++++++++++++++------------------------------ 1 file changed, 161 insertions(+), 206 deletions(-) diff --git a/README.md b/README.md index 207efb3..7a63f0e 100644 --- a/README.md +++ b/README.md @@ -44,10 +44,6 @@ - [4j. Ensuring that only published articles are returned](#4j-ensuring-that-only-published-articles-are-returned) - [4k. Ensuring that articles are returned in the correct order](#4k-ensuring-that-articles-are-returned-in-the-correct-order) - [4l. Linking up the repository to the BlogPageController](#4l-linking-up-the-repository-to-the-blogpagecontroller) -- [Step 5: Wrapping up with unit tests](#step-5-wrapping-up-with-unit-tests) - - [5a. Creating an ArticleWrapper](#5a-creating-an-articlewrapper) - - [5b. Ensure that we’re only wrapping articles](#5b-ensure-that-were-only-wrapping-articles) - - [5c. Determine if articles are publishable](#5c-determine-if-articles-are-publishable) ## Contribution @@ -1045,273 +1041,232 @@ In the browser, we should see our list of articles. ![](docs/images/3.png) -## Step 5: Wrapping up with unit tests +## Step 5: Creating a custom Post class -### 5a: Creating an ArticleWrapper +What if we wanted to return a custom `Post` class from the repository with its own data and logic rather than a generic Drupal node? As the repository is responsible for finding and returning nodes, we can make changes there and return what we want. -The final thing that we’re going to do is create a wrapper class for articles so that we can add additional methods. +Let's start by changing one of our existing tests. -```bash -mkdir -p tests/src/Unit/Wrapper +### 5a: Changing the existing test + +In `ArticleRepositoryTest` we have existing assertions as to what type of object is returned. Currently, this should be an instance of a `Node::class`. Let's change that to a new `Post::class` and also change the `label` method to a more desciriptive `getTitle()`. + +```diff + $this->assertCount(1, $articles); + $this->assertIsObject($articles[1]); +- $this->assertInstanceOf(Node::class, $articles[1]); +- $this->assertSame('Test post', $articles[1]->label()); ++ $this->assertInstanceOf(Post::class, $articles[1]); ++ $this->assertSame('Test post', $articles[1]->getTitle()); +``` +As we have no `Post` class and are still returning the original nodes from the Repository, this will cause the test to now fail. + +> 1) Drupal\Tests\my_module\Kernel\ArticleRepositoryTest::it_returns_blog_posts + PHPUnit\Framework\Exception: Argument #1 (No Value) of PHPUnit\Framework\Assert::assertInstanceOf() must be a class or interface name + +### 5b: Adding a Post class + +Create a new `Entity` directory and a new `Post.php` file inside it. + +``` +mkdir -p src/Entity ``` ```php -// tests/src/Unit/Wrapper/ArticleWrapperTest + Drupal\Tests\my_module\Kernel\ArticleRepositoryTest::it_returns_blog_posts +> Failed asserting that Drupal\node\Entity\Node Object (...) is an instance of class "Drupal\my_module\Entity\Post". + +### 5c: Returning Post classes + +To pass this failure, we need to update the Repository and return instances of `Post` rather than the standard Drupal nodes. + +We can do that in the `getAll()` method: + +```diff +- return $articles; ++ return array_map(function (NodeInterface $node) { ++ return new Post(); ++ }, $articles); +``` + +This will return an array of `Post` objects, and change the failure message as we're calling a method that we've not yet added. + +> Error: Call to undefined method +> Drupal\my_module\Entity\Post::getTitle() + +To do this, let's start by adding a Unit test. + +## Step 6: Unit testing the Post class + +### 6a: Creating a PostTest class + +Create a `Unit` directory, an `Entity` sub-directory, and a `PostTest.php` file. Typically, unit tests match the directory structure in `src` and the class name that they're testing. + +``` +mkdir -p tests/src/Unit/Entity +``` + +```php +assertInstanceOf(NodeInterface::class, $articleWrapper->getOriginal()); - $this->assertSame(5, $articleWrapper->getOriginal()->id()); - $this->assertSame('article', $articleWrapper->getOriginal()->bundle()); + $this->assertSame('Test post', $post->getTitle()); } ``` -Lets create the `ArticleWrapper`: +If we run this, we get an undefined method error: + +> Error: Call to undefined method Drupal\my_module\Entity\Post::getTitle() + +### 6b: Adding the getTitle() method + +Within the `Post` class, add a `getTitle()` method which will return a string. For now, let's return an empty string: ```php -// src/Wrapper/ArticleWrapper +public function getTitle(): string { + return ''; +} +``` -namespace Drupal\my_module\Wrapper; +> Failed asserting that two strings are identical. +> --- Expected +> +++ Actual +> @@ @@ +> -'Test post' +> +'' -use Drupal\node\NodeInterface; +This will cause a different failure as the expected title doesn't match the returned empty string. -class ArticleWrapper { +To get the real title, we'll need to pass the article node into the `Post` class so that we can reference it. - private $article; +### 6c: Returning the real title + +To get the post's title, we need to add a constructor to the `Post` class which accepts the original node, which we can then use to get its title. + +```php +class Post { + + private $node; public function __construct(NodeInterface $node) { - $this->article = $node; + $this->node = $node; } - public function getOriginal(): NodeInterface { - return $this->article; + public function getTitle(): string { + return $this->node->label(); } } ``` -In the `ArticleWrapperTest`, add the import statement for the wrapper. +This test will fail as we need to update the test to include the node: -```diff -+ use Drupal\my_module\Wrapper\ArticleWrapper; - use Drupal\Tests\UnitTestCase; +> ArgumentCountError: Too few arguments to function Drupal\my_module\Entity\Post::__construct(), 0 passed in /home/opdavies/Code/Personal/workshop-drupal-automated-testing-code/web/modules/custom/my_module/tests/src/Unit/Entity/PostTest.php on line 12 and exactly 1 expected + +### 6d: Mocking the article node + +As we are working with a unit test, we can't interact with the database in the same way that we can with functional or kernel tests. This means that using methods like `Node::create` won't work in unit tests, so we need to create our own mock node and tell it what to return. + +```php +$node = $this->createMock(NodeInterface::class); + +$node->expects($this->once()) + ->method('label') + ->willReturn('Test post'); ``` -Currently, we don’t yet have an article to wrap. +This ensures that the `label()` method will only be called once and that it will return the string `Test post`. -> Undefined variable: article +As this is the same value as our expection in the test, this test should now pass. -Because this is a unit test which has no access to the database, we can’t use the `createNode()` method or `Node::create()` so we need to create a mock node. +However, whilst the unit tests are all passing, one of the kernel tests is now failing. + +### 6e. Fixing the ArticleRepository test + +To get `ArticleRepositoryTest` passing again, we need to update the `getAll()` method and add the node as an argument to the create `Post`. ```diff -+ use Drupal\node\NodeInterface; - -$article = $this->createMock(NodeInterface::class); + return array_map(function (NodeInterface $node): Post { +- return new Post(); ++ return new Post($node); + }, $articles); ``` -This satisfies the instance assertion, but the other assertions are failing. +### 6f: Only article nodes should be used for Posts -> Failed asserting that null is identical to 5. - -In order for this to pass, we need to specify what value each method will method will return (e.g. which node ID and which bundle type) so that these values are populated when used within the production code. - -```diff - $article = $this->createMock(NodeInterface::class); -+ $article->method('id')->willReturn(5); -+ $article->method('bundle')->willReturn('article'); -``` - -> OK (1 test, 3 assertions) - -### 5b. Ensure that we’re only wrapping articles - -The ArticleWrapper is only supposed to be used for wrapping articles, so we want to throw an Exception if a different type of node is used. - -Let’s create a page node and assert that an Exception should be thrown. +Currently any node is able to be passed to the `Post` class. Let's ensure that only article nodes can be added by adding a check and throwing an Exception. ```php /** @test */ public function it_throws_an_exception_if_the_node_is_not_an_article() { + $node = $this->createMock(NodeInterface::class); + + $node->method('bundle')->willReturn('page'); + $this->expectException(\InvalidArgumentException::class); - $page = $this->createMock(NodeInterface::class); - $page->method('bundle')->willReturn('page'); - - new ArticleWrapper($page); + new Post($node); } ``` -Because we’re currently not throwing an Exception, the assertion fails. +Again, we need to mock the node, but this time, let's set the `bundle()` method to return a value that should throw an Exception. -> Failed asserting that exception of type "InvalidArgumentException" is thrown. - -Within `ArticleWrapper`, add a check using the `bundle()` method and throw an Exception if it is not an article. +### 6g: Throw an Exception for non-articles +Let's add a check to the `Post` constructor ```diff public function __construct(NodeInterface $node) { -+ $this->verifyNodeType($node); - - $this->article = $node; - } - -+ private function verifyNodeType(NodeInterface $node): void { -+ if ($node->bundle() != 'article') { -+ throw new \InvalidArgumentException(sprintf( -+ '%s is not an article', -+ $node->bundle() -+ )); ++ if ($node->bundle() != 'article') { ++ throw new \InvalidArgumentException(); + } -+ } -``` - -If the Exception is thrown, the test will pass. - -### 5c. Determine if articles are publishable - -Let’s imagine that there is a rule that articles less than 3 days old are not eligible to be published and we want to add an `isPublishable()` method that will contain this logic and determine whether or not an article is publishable. - -We need access to the `Time` class to get the system time, so this is added as an argument to the constructor and used within `isPublishable()` to compare the created time of the article to the current time. - -```diff -+ use Drupal\Component\Datetime\TimeInterface; - use Drupal\node\NodeInterface; - - class ArticleWrapper { - - private $article; - -- public function __construct(NodeInterface $node) { -+ public function __construct(TimeInterface $time, NodeInterface $node) { - $this->verifyNodeType($node); - -+ $this->time = $time; - $this->article = $node; - } - -+ public function isPublishable(): bool { -+ $created = $this->article->getCreatedTime(); + -+ $difference = $this->time->getRequestTime() - $created; -+ -+ return $difference >= 60 * 60 * 24 * 3; -+ } - + $this->node = $node; } ``` -We want to compare against a number of dates to ensure that this is working as expected. Rather than writing separate tests, we can use a data provider. This is a method that returns data to be passed to the tests as parameters. +This will result in the Exception being thrown if the node is not an article, and the test should pass. -```php -public function articleCreatedDateProvider() { - return [ - ['-1 day', FALSE], - ['-2 days 59 minutes', FALSE], - ['-3 days', TRUE], - ['-1 week', TRUE], - ]; -} -``` +### 6h: Fixing the existing unit test -Use the `@dataProvider` annotation for the test to specify the method to use, and add the parameters to the test. - -We also need to create a mock for `TimeInterface` so that it can be passed into the article wrapper, and so that methods on it can return certain values. - -```php -/** - * @test - * @dataProvider articleCreatedDateProvider - */ -public function articles_created_less_than_3_days_ago_are_not_publishable( - string $offset, - bool $expected -) { - $time = $this->createMock(TimeInterface::class); - - $time->method('getRequestTime')->willReturn( - (new \DateTime())->getTimestamp() - ); - - $article = $this->createMock(NodeInterface::class); - $article->method('bundle')->willReturn('article'); - - $article->method('getCreatedTime')->willReturn( - (new \DateTime())->modify($offset)->getTimestamp() - ); - - $articleWrapper = new ArticleWrapper($time, $article); - - $this->assertSame($expected, $articleWrapper->isPublishable()); -} -``` - -We can use `$offset` value to modify the returned date from `getCreatedTime()`, and use `$expected` to make the assertion against `isPublishable()`. - -The test is run, is then run against each set of data and passes or fails accordingly. - -> - Articles created less than 3 days ago are not publishable with data set #0 [23.76 ms] -> - Articles created less than 3 days ago are not publishable with data set #1 [0.32 ms] -> - Articles created less than 3 days ago are not publishable with data set #2 [0.25 ms] -> - Articles created less than 3 days ago are not publishable with data set #3 [0.37 ms] - -The other tests will also need to be updated to mock `TimeInterface` and pass it to the article wrapper. - -## 5d: Refactoring the unit tests - -With the unit tests passing, we can refactor them and simplify things by extracting a method for creating an article wrapper. - -As each test will need the mocked time, this can be moved into a `setUp` method, and we can use `$this->time` instead within the test. - -```php -private $time; - -protected function setUp() { - parent::setUp(); - - $this->time = $this->createMock(Time::class); -} -``` +Due to this new check, we also need to update the previous unit test so that includes a value for the bundle. ```diff -- $time->method('getRequestTime')->willReturn( -+ $this->time->method('getRequestTime')->willReturn( - (new \DateTime())->getTimestamp() - ); + $node->expects($this->once()) + ->method('label') + ->willReturn('Test post'); ++ $node->method('bundle')->willReturn('article'); ``` - -To make it simpler to create an article wrapper, we can create a helper method for that. This will also be responsible for creating and injecting any dependencies. - -```php -private function createArticleWrapper(NodeInterface $article): ArticleWrapper { - return new ArticleWrapper($this->time, $article); -} -``` - -Now we can update the tests to use the new `createArticleWrapper()` method: - -```diff -- $time = $this->createMock(TimeInterface::class); -- $articleWrapper = new ArticleWrapper($time, $article); -+ $articleWrapper = $this->createArticleWrapper($article); - -- $time = $this->createMock(TimeInterface::class); -- new ArticleWrapper($time, $page); -+ $articleWrapper = $this->createArticleWrapper($page); - -- $articleWrapper = new ArticleWrapper($time, $article); -+ $articleWrapper = $this->createArticleWrapper($article); -``` - -If the refactor was successful, the tests will still pass. From 354fbe412862600f9c6107b86411cf5155084027 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Wed, 23 Dec 2020 19:30:20 +0000 Subject: [PATCH 73/77] Switch to rst Convert README.md to README.rst. This was done automatically using https://cloudconvert.com/md-to-rst, and gives some features like the table of contents for free. It also means that I can use tools like [rst2pdf](https://rst2pdf.org) to create exportable versions and handouts. GitHub also still renders it automatically too. :) --- .gitignore | 3 +- README.md | 1272 -------------------------------- README.rst | 1308 +++++++++++++++++++++++++++++++++ {docs/images => images}/1.png | Bin {docs/images => images}/2.png | Bin {docs/images => images}/3.png | Bin 6 files changed, 1310 insertions(+), 1273 deletions(-) delete mode 100644 README.md create mode 100644 README.rst rename {docs/images => images}/1.png (100%) rename {docs/images => images}/2.png (100%) rename {docs/images => images}/3.png (100%) diff --git a/.gitignore b/.gitignore index 096746c..dc1335e 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -/node_modules/ \ No newline at end of file +/.vscode/ +/*.pdf diff --git a/README.md b/README.md deleted file mode 100644 index 7a63f0e..0000000 --- a/README.md +++ /dev/null @@ -1,1272 +0,0 @@ -# Workshop: Automated Testing and Test Driven Development in Drupal 8 - -## Table of Contents - -- [Introduction](#introduction) -- [Contribution](#contribution) -- [Feedback](#feedback) -- [Creating a new Drupal project with Composer](#creating-a-new-drupal-project-with-composer) -- [Using DDEV for local development](#using-ddev-for-local-development) -- [Using the PHP web server for local development](#using-the-php-web-server-for-local-development) -- [The different types of available tests](#the-different-types-of-available-tests) -- [Different approaches to testing](#different-approaches-to-testing) -- [The structure of a test](#the-structure-of-a-test) -- [What is Test Driven Development?](#what-is-test-driven-development) -- [Acceptance criteria](#acceptance-criteria) -- [Step 0: Preparation](#step-0-preparation) -- [Step 1: Writing your first test](#step-1-writing-your-first-test) - - [1a. Create the module directory](#1a-create-the-module-directory) - - [1b. Create an .info.yml file for the module](#1b-create-an-infoyml-file-for-the-module) - - [1c. Create the directory structure for tests](#1c-create-the-directory-structure-for-tests) - - [1d. Create your first test case](#1d-create-your-first-test-case) - - [1e. Preparing PHPUnit](#1e-preparing-phpunit) - - [1f. Running the tests](#1f-running-the-tests) - - [1g. (Optional) Running tests via a Composer script](#1g-optional-running-tests-via-a-composer-script) -- [Step 2: Adding more test methods](#step-2-adding-more-test-methods) - - [2a. Ensure that anonymous users cannot access admin pages](#2a-ensure-that-anonymous-users-cannot-access-admin-pages) - - [2b. Ensure that administrators can access admin pages](#2b-ensure-that-administrators-can-access-admin-pages) -- [Step 3: Building a blog](#step-3-building-a-blog) - - [3a. Anonymous users should be able to view the blog page](#3a-anonymous-users-should-be-able-to-view-the-blog-page) - - [3b. Add a route for the blog page](#3b-add-a-route-for-the-blog-page) - - [3c. Fix permission error](#3c-fix-permission-error) - - [3d. Add the BlogPageController](#3d-add-the-blogpagecontroller) - - [3e. Refactor, add more assertions](#3e-refactor-add-more-assertions) -- [Step 4: Getting blog posts](#step-4-getting-blog-posts) - - [4a Creating our first kernel test](#4a-creating-our-first-kernel-test) - - [4b. Starting with an assertion](#4b-starting-with-an-assertion) - - [4c. Trying to use the ArticleRepository](#4c-trying-to-use-the-articlerepository) - - [4d. Creating an article repository](#4d-creating-an-article-repository) - - [4e. Adding the getAll() method](#4e-adding-the-getall-method) - - [4f. Building up the ArticleRepository](#4f-building-up-the-articlerepository) - - [4g. Adding articles](#4g-adding-articles) - - [4h. Ensuring that only articles are returned](#4h-ensuring-that-only-articles-are-returned) - - [4i. Making this test less brittle](#4i-making-this-test-less-brittle) - - [4j. Ensuring that only published articles are returned](#4j-ensuring-that-only-published-articles-are-returned) - - [4k. Ensuring that articles are returned in the correct order](#4k-ensuring-that-articles-are-returned-in-the-correct-order) - - [4l. Linking up the repository to the BlogPageController](#4l-linking-up-the-repository-to-the-blogpagecontroller) - -## Contribution - -Please feel free to create issues and/or submit pull requests to this repository whilst working through these instructions. Any contributions would be greatly appreciated! - -## Feedback - -Feedback would also be appreciated! You can contact me via , [@opdavies on Twitter](https://twitter.com/opdavies) or `opdavies` on Drupal Slack. - -## Introduction - -## Creating a new Drupal project with Composer - -If don’t have Composer, visit for instructions on how to install it on your computer. - -This assumes that Composer is installed globally and is available by running the `composer` command. Alternatively, you can download the phar file and run `php composer.phar` instead. - -```bash -# Create a new Drupal project -composer create-project drupal/recommended-project my-project - -cd my-project - -# Add testing dependencies -composer require --dev drupal/core-dev -``` - -You should now have files present including `web/index.php` and `vendor/bin/phpunit`. Now you can start serving this site locally. - -**Note:** Development dependencies, including PHPUnit, should only be installed locally and should not be present on public servers. Doing so would present a security risk to your application. - -## Using DDEV for local development - -- Docker based development environment for PHP applications (Drupal, WordPress, Magento etc). -- More information at . -- Documentation at . -- Installation via Homebrew on Linux and macOS, and Chocolatey on Windows. More information at . -- Example at . - -To run PHPUnit within DDEV, we can prefix the command with `ddev exec`: - -``` -$ ddev exec vendor/bin/phpunit -``` - -## Using the PHP web server for local development - -If you have all of [Drupal's required PHP extensions](https://www.drupal.org/docs/system-requirements/php-requirements#extensions) installed and would like better performance (particularly on macOS), you could use the PHP's local web server. - -As we're going to use SQLite to run the tests, there's no need for a connection to a MySQL database or another service. - -If you need to override any environment variables, you can do so before running the command: - -``` -$ SIMPLETEST_BASE_URL=http://localhost:8000 vendor/bin/phpunit -``` - -## The different types of available tests - -- **Functional** (web, feature) - tests behaviour and functionality, makes HTTP requests to the webserver and has access to the database and other services via the service container. Slower to run. -- **FunctionalJavascript** - functional tests, but access to JavaScript. -- **Kernel** (integration) - no browser capabilities, has access to the database and other services but requires more configuration. -- **Unit** - no access to the database or service container, all dependencies need to be mocked. Fast to run. - -## Different approaches to testing - -- Inside-out (testing pyramid) - mostly unit tests, some integration tests, few functional tests. -- Outside-in (testing trophy) - mostly functional tests, some integration tests, few unit tests. More flexible, easier to refactor. - -## The structure of a test - -- **Arrange** - set up the environment. Create users, nodes, set up dependencies -- **Act** - perform an action -- **Assert** - verify that something happened - -## What is Test Driven Development? - -- Writing tests first -- Red, green, refactor loop - - Writing failing test first - - Write code to make the test pass - - Refactor when tests pass -- Three (simplified) rules of TDD: - - Write production code only to make a failing unit test pass. - - Write only enough of a unit test to fail. - - Write only enough production code to make the failing unit test pass. - - - -## Acceptance criteria - -This module will be used to demonstrate how to take a test-driven approach to develop a module to the following acceptance criteria: - -- As a site visitor -- I want to see a list of all published articles at `/blog` -- Ordered by post date, with the newest posts first - -## Step 0: Preparation - -To begin, we need the site to be running. - -```bash -# Using DDEV -ddev start - -# Using PHP's web server -php -S localhost:8000 -t web -``` - -You don’t need to install Drupal. It just needs to be able to connect to the database. - -## Step 1: Writing your first test - -### 1a. Create the module directory - -Create a directory for the new module: - -``` -mkdir -p web/modules/custom/my_module -``` - -### 1b. Create an `.info.yml` file for the module - -In order to install the module, it needs an info.yml file that matches the name of the module (e.g. `my_module.info.yml`). - -Within the `my_module` directory, create the file and paste in the following content: - -```yaml -name: My Module -type: module -core_version_requirement: ^8 || ^9 -``` - -### 1c. Create the directory structure for tests - -```bash -mkdir -p tests/src/Functional -``` - -### 1d. Create your first test case - -```php -config('system.site') - ->set('page.front', '/node') - ->save(TRUE); - - $this->drupalGet(''); - - $assert = $this->assertSession(); - $assert->statusCodeEquals(Response::HTTP_OK); - $assert->pageTextContains('Welcome to Drupal'); - $assert->pageTextContains('No front page content has been created yet.'); - } - -} -``` - -Some things to note: - -- The name of the class must match the filename. -- The filename must end with `Test.php`. -- The namespace is `Drupal\Tests\{module_name}`, followed by any additional directories (e.g. `Functional`). -- Test methods must start with `test`, or use the `@test` annotation. - -### 1e. Preparing PHPUnit - -Firstly, we need to create a `phpunit.xml` file to configure PHPUnit. Core has a `phpunit.xml.dist` file that we can duplicate and edit. - -```bash -cp web/core/phpunit.xml.dist web/core/phpunit.xml -``` - -Update the `SIMPLETEST_BASE_URL` value to be the address that the website is currently running on. This needs to be correct so that functional tests return the correct response codes, so ensure that any port numbers are correct and also that the site is correctly marked as HTTP or HTTPS. - -We also need to configure the database for Drupal to connect to and use when running functional and kernel tests. This could be your project’s MySQL or PostgreSQL database with a table prefix, but in this case, we’ll use a separate SQLite database. - -```diff -- -+ - -- -+ -``` - -### 1f. Running the tests - -```bash -$ vendor/bin/phpunit modules/custom/my_module -``` - -You should see a summary of the number of tests and assertions that were run. This is the expected output if all of the tests pass: - -> OK (1 test, 3 assertions) - -If a test failed, the output would show the class and method name for the failing test, and give a summary of the failure. - -> Drupal\Tests\my_module\Functional\FrontPageTest::the_front_page_loads_for_anonymous_users -> Behat\Mink\Exception\ExpectationException: Current response status code is 404, but 200 expected. - -Other useful options include `--stop-on-failure`, `--filter` and `--testdox`. - -### 1g. (Optional) Running tests via a Composer script - -To simplify running tests, the command could be simplified by [adding a script][composer scripts] to `composer.json`: - -```json -"scripts": { - "test:phpunit": "phpunit --verbose --testdox --colors=always", - "test": [ - "@test:phpunit" - ] -} -``` - -This means that you can run just `ddev composer test:phpunit` or `ddev composer test` and it will execute the `phpunit` command. - -This approach can be useful if you want to run other commands in addition to PHPUnit such as PHPStan, PHP Code Sniffer or Drupal Check. Each command can be added to the script and they will each be executed. - -If needed, you can still pass additional arguments and options to the command by appending `--` followed by the arguments. - -```bash -ddev composer test:phpunit -- modules/custom/my_module \ - --stop-on-failure \ - --filter=the_front_page_loads_for_anonymous_users -``` - -Locally, ensure that the command is prefixed with `ddev` so that it is run within the container. This ensures that the correct PHP version etc is used. - -[composer scripts]: https://getcomposer.org/doc/articles/scripts.md#writing-custom-commands - -## Step 2: Adding more test methods - -### 2a. Ensure that anonymous users cannot access admin pages - -Now that we’re sure that the front page loads correctly, lets also check anonymous users cannot access the administration area. This test is very similar to the previous one, though instead we’re making a GET request to `/admin` and ensuring that the response code is 403 (forbidden). - -As this functionality is provided by Drupal core by default, this should pass automatically. - -```php -/** @test */ -public function the_admin_page_is_not_accessible_to_anonymous_users() { - $this->drupalGet('admin'); - - $this->assertSession()->statusCodeEquals(Response::HTTP_FORBIDDEN); -} -``` - -### 2b. Ensure that administrators can access admin pages - -Now let’s check that an administrator user _can_ access the admin pages. - -This introduces some new concepts. We need to create a user to begin with, and assign it some permissions. Because tests may be included within Drupal core a contributed module, permissions need to be added to users directly as modules won’t know about roles that are specific to your site. - -The `BrowserTestBase` class gives access to a number of helper methods, including ones for creating and logging-in users (`createUser` and `drupalLogin` respectively). When creating a user, the first argument is an array of permission names to add. In this case, we can make the user an admin user by adding the `access administration pages` permission. - -```php -/** @test */ -public function the_admin_page_is_accessible_by_admin_users() { - $adminUser = $this->createUser([ - 'access administration pages', - ]); - - $this->drupalLogin($adminUser); - - $this->drupalGet('admin'); - - $this->assertSession()->statusCodeEquals(Response::HTTP_OK); -} -``` - -Again, as this functionality is provided by Drupal core by default, this should pass. However, we can be confident that the test is doing what’s needed by making it fail by removing or changing the assigned permissions, or not logging in the user before accessing the page. - -## Step 3: Building a blog - -### 3a. Anonymous users should be able to view the blog page - -Let’s start by building a blog page. This will look very similar to the admin page tests, but instead we’ll be testing the `/blog` page. - -```php -drupalGet('blog'); - - $session = $this->assertSession(); - - $session->statusCodeEquals(Response::HTTP_OK); - } - -} -``` - -This test will fail as there’s no route for `/blog` and no View that generates that page. Because of this, the response code will be a 404 instead of the 200 that we want. - -> Current response status code is 404, but 200 expected. - -### 3b: Add a route for the blog page - -We’ll create a blog page using a custom route in the module. You could also do this with the Views module by creating a View with a page on that path, and exporting the configuration into the module’s `config/install` directory. - -To add a route, we need to create a `my_module.routing.yml` file. - -```yaml -# my_module.routing.yml - -blog.page: - path: /blog - defaults: - _controller: Drupal\my_module\Controller\BlogPageController - _title: Blog - requirements: - _permission: access content -``` - -We set our path to `/blog`, specify the Controller to use and which permission the needs to have to access the page. - -If we run the tests now, we get an access denied error (403 response). - -> Current response status code is 403, but 200 expected. - -### 3c: Fix permission error - -Because we need to node module to be able to access the `access content` permission, we need to enable it within our tests. - -We can do this by adding it to the `$modules` array within the test. - -```diff - protected static $modules = [ -+ 'node', - 'my_module', - ]; -``` - -Now the error has changed, and is now returning a 500 response because we’ve specified a Controller that doesn’t exist. - -> Current response status code is 500, but 200 expected. - -### 3d: Add the BlogPageController - -Let’s create the `BlogPageController`. - -``` -mkdir src/Controller -``` - -Let’s start by creating a minimal controller, that returns an empty render array. Because we didn’t specify a method to use within the route file, we use PHP’s `__invoke()` method. - -```php - OK (1 test, 3 assertions) - -This is how the page looks in a browser: - -![](docs/images/1.png) - -### 3e: Refactor, add more assertions - -Now that the test is passing, we can do some refactoring and make the test more robust by ensuring that the correct text is displayed. - -```diff - public function the_blog_page_loads_for_anonymous_users_and_contains_the_right_text() { - $this->drupalGet('/blog'); - - $session = $this->assertSession(); - - $session->statusCodeEquals(Response::HTTP_OK); -+ $session->responseContains('

Blog

'); -+ $session->pageTextContains('Welcome to my blog!'); - } -``` - -The page title is created by the `_title` value within the routing file, but no page text has been added yet so this will cause the test to fail. - -> Behat\Mink\Exception\ResponseTextException: The text "Welcome to my blog!" was not found anywhere in the text of the current page. - -To fix this, we can return some text from the BlogPageController rather than an empty render array. - -```diff - namespace Drupal\my_module\Controller; - -+ use Drupal\Core\StringTranslation\StringTranslationTrait; - - class BlogPageController { - -+ use StringTranslationTrait; - - public function __invoke(): array { -- return []; -+ return [ -+ '#markup' => $this->t('Welcome to my blog!'), -+ ]; - } - - } -``` - -Now the tests will pass because we’re returning the correct text. - -> OK (1 test, 3 assertions) - -![](docs/images/2.png) - -## Step 4. Getting blog posts - -### 4a Creating our first kernel test - -We’ll be using an ArticleRepository class to get the blog posts from the database, and this is also a good time to switch to writing kernel tests as we don’t need to check any responses from the browser. - -Within the tests directory, create a new `Kernel` directory. - -``` -mkdir tests/src/Kernel -``` - -And an `ArticleRepositoryTest` class. - -```php -assertCount(1, $articles); - } -``` - -As we aren’t yet returning any articles, or even creating that variable, the test is going to fail, but we can move on to getting articles. - -> Undefined variable: articles - -### 4c. Trying to use the ArticleRepository - -As the test name suggests, we’re going to be retrieving the articles from an `ArticleRepository` service - though this doesn’t exist yet, but let’s let the tests tell us that. - -```diff - /** @test */ - public function it_returns_blog_posts() { -+ $repository = $this->container->get(ArticleRepository::class); -+ - $this->assertCount(1, $articles); - } -``` - -Because this is a kernel test, we have access to the container, and we can use it to retrieve our repository service. - -Running the test now gives us a different error, and tells us what the next step is: - -> Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException : You have requested a non-existent service "Drupal\Tests\my_module\Kernel\ArticleRepository". - -### 4d. Creating an article repository - -```bash -mkdir src/Repository -``` - -To begin with, let’s create a basic `ArticleRepository` class. - -```php - Undefined variable: articles - -### 4e. Adding the `getAll()` method - -We’ll use a `getAll()` method on the repository to retrieve the articles from the database, and use the value of this for the `$articles` variable: - -```diff - $repository = $this->container->get(ArticleRepository::class); -+ $articles = $repository->getAll(); - - $this->assertCount(1, $articles); -``` - -This method doesn’t exist on the repository yet, so the test will fail. - -> Error : Call to undefined method -> Drupal\my_module\Repository\ArticleRepository::getAll() - -Let’s fix that by adding the `getAll()` method. For now, have it return an empty array. - -```php -// my_module/Repository/ArticleRepository.php - -public function getAll(): array { - return []; -} -``` - -Now we’ve got everything in place, and the test failure is because we aren’t returning the correct number of articles. - -> Failed asserting that actual size 0 matches expected size 3. - -We can fix this by building up the `ArticleRepository` class. - -### 4f. Building up the ArticleRepository - -The `ArticleRepository` needs to return some articles. We can do this by injecting the `EntityTypeManager` and using it to return nodes from the `getAll()` method rather than the empty array. - -```diff -+ use Drupal\Core\Entity\EntityTypeManagerInterface; -+ -+ /** -+ * @var \Drupal\Core\Entity\EntityStorageInterface -+ */ -+ private $nodeStorage; - -+ public function __construct(EntityTypeManagerInterface $entityTypeManager) { -+ $this->nodeStorage = $entityTypeManager->getStorage('node'); -+ } - - public function getAll(): array { -- return []; -+ return $this->nodeStorage->loadMultiple(); - } -``` - -Within our services file, we now need to add the `EntityTypeManager` as an argument so that it’s used to create the `ArticleRepository`. Currently we don’t have enough arguments. - -> ArgumentCountError : Too few arguments to function Drupal\my_module\Repository\ArticleRepository::\_\_construct(), 0 passed and exactly 1 expected - -The quickest way to do that is to enable autowiring for the ArticleRepository within `my_module.services.yml`. This will automatically inject services rather than needing to specify each argument individually. - -```diff -- Drupal\my_module\Repository\ArticleRepository: ~ -+ Drupal\Core\Entity\EntityTypeManagerInterface: -+ alias: entity_type.manager -+ -+ Drupal\my_module\Repository\ArticleRepository: -+ autowire: true -``` - -> Drupal\Component\Plugin\Exception\PluginNotFoundException : The "node" entity type does not exist. - -As we did previously, we need to enable the `node` module. - -```diff - public static $modules = [ -+ 'node', - 'my_module', - ]; -``` - -The `ArticleRepository` is now working, but is still returning no articles - though this is because we haven’t created any inside the test. - -> Failed asserting that actual size 0 matches expected size 1. - -### 4g. Adding articles - -To test the ArticleRepository, we need articles to be created so that they can be returned. - -Within the `ArticleRepositoryTest` we can make use of one of a number of traits that are provided. - -Within the class, enable the trait: - -```diff -+ use NodeCreationTrait -``` - -Include the import statement at the top of the file if it hasn’t been added automatically. - -```diff -+ use Drupal\Tests\node\Traits\NodeCreationTrait; -``` - -This gives us a `createNode` method that we can use to create nodes by passing an array of values. - -As we need an article to retrieve, let’s create one. - -```diff -+ $this->createNode(['type' => 'article', 'title' => 'Test post'])->save(); - - $repository = $this->container->get(ArticleRepository::class); - $articles = $repository->getAll(); -``` - -The next error is a little cryptic: - -> Error : Call to a member function id() on bool - -Looking at the stack trace, this error is within `filter.module`, where it’s trying to call an `id()` method on a filter format. - -```php -// filter.module - -$formats = filter_formats($account); -$format = reset($formats); -return $format->id(); -``` - -As kernel tests don’t install configuration by default, we need to install the missing filter configuration. - -As we’ll need this for all test methods in this case, we can use the `setUp()` method that will run before each test. - -```diff -+ protected function setUp() { -+ parent::setUp(); -+ -+ $this->installConfig([ -+ 'filter', -+ ]); -+ } -``` - -We also need to create the `node_access` table as indicated by the next error: - -> Drupal\Core\Entity\EntityStorageException : SQLSTATE[HY000]: General error: 1 no such table: test90927710.node_access: DELETE FROM {node_access} - -```diff - protected function setUp() { - parent::setUp(); -+ -+ $this->installSchema('node', ['node_access']); -+ - $this->installConfig([ - 'filter', - ]); - } -``` - -We’ve successfully returned our article and this test now passes. - -> OK (1 test, 11 assertions) - -Whilst the test is passing, let's add some additional assertions to check the type of object being returned and its title. - -```diff - $this->assertCount(1, $articles); -+ $this->assertIsObject($articles[1]); -+ $this->assertInstanceOf(NodeInterface::class, $articles[1]); -+ $this->assertSame('Test post', $articles[1]->label()); -``` - -> OK (1 test, 14 assertions) - -### 4h. Ensuring that only articles are returned - -Let's start with a new test, this time with three article nodes: - -```php -/** @test */ -public function nodes_that_are_not_articles_are_not_returned() { - $this->createNode(['type' => 'article'])->save(); - $this->createNode(['type' => 'article'])->save(); - $this->createNode(['type' => 'article'])->save(); - - $repository = $this->container->get(ArticleRepository::class); - $articles = $repository->getAll(); - - $this->assertCount(3, $articles); -} -``` - -Again, we can use the node creation trait to create the required content. - -As we already have the `ArticleRepository` in place, this test should pass straight away. - -> OK (1 test, 11 assertions) - -### 4i. Making this test less brittle - -The test is passing, but it currently returns _all_ nodes and not just articles. - -If we create some page nodes too, these will also be returned and the assertion will now fail. - -```diff - $this->createNode(['type' => 'article'])->save(); -+ $this->createNode(['type' => 'page'])->save(); - $this->createNode(['type' => 'article'])->save(); -+ $this->createNode(['type' => 'page'])->save(); - $this->createNode(['type' => 'article'])->save(); -``` - -> Failed asserting that actual size 5 matches expected size 3. - -We can make a change to the `ArticleRepository` to fix this, and ensure that we’re only loading and returning article nodes. - -```diff -- return $this->nodeStorage->loadMultiple(); -+ return $this->nodeStorage->loadByProperties([ -+ 'type' => 'article', -+ ]); -``` - -### 4j. Ensuring that only published articles are returned - -We now know that only article nodes are returned, but _all_ articles are being returned. On our blog, we only want to published articles to be displayed. - -Let’s create another test for this. - -```diff -+ /** @test */ -+ public function only_published_articles_are_returned() { -+ $repository = $this->container->get(ArticleRepository::class); -+ $articles = $repository->getAll(); - -+ $this->assertCount(3, $articles); -+ } -``` - -We already know that only articles are returned, so in this test we can focus on the published status. We can create a number of articles, some which are published and some which are unpublished. - -```diff - /** @test */ - public function only_published_articles_are_returned() { -+ $this->createNode(['type' => 'article', 'status' => Node::PUBLISHED])->save(); -+ $this->createNode(['type' => 'article', 'status' => Node::NOT_PUBLISHED])->save(); -+ $this->createNode(['type' => 'article', 'status' => Node::PUBLISHED])->save(); -+ $this->createNode(['type' => 'article', 'status' => Node::NOT_PUBLISHED])->save(); -+ $this->createNode(['type' => 'article', 'status' => Node::PUBLISHED])->save(); - - $repository = $this->container->get(ArticleRepository::class); - $articles = $repository->getAll(); - - $this->assertCount(3, $articles); - } -``` - -Because we have no filter on the published state, all the articles are returned including the unpublished ones. - -> Failed asserting that actual size 5 matches expected size 3. - -We can again update the `ArticleRepository` to add this extra condition to filter out any unpublished articles. - -```diff -+ use Drupal\node\Entity\Node; - - public function getAll(): array { - return $this->nodeStorage->loadByProperties([ -+ 'status' => Node::PUBLISHED, - 'type' => 'article', - ]); - } -``` - -With this added, the test passes again. - -> OK (1 test, 6 assertions) - -### 4k. Ensuring that articles are returned in the correct order - -As per our acceptance criteria, we need the articles to be returned based on their created date, so let’s create another test. - -In this test, let’s ensure assert that some article node IDs are returned within a specific order. - -```diff -+ /** @test */ -+ public function nodes_are_ordered_by_date_and_newest_first() { -+ $this->assertSame([3, 1, 2, 5, 4], $nodeIds); -+ } -``` - -We can use the same `getAll()` method, and get the node IDs from the array keys. - -```diff - /** @test */ - public function nodes_are_ordered_by_date_and_returned_newest_first() { -+ $repository = $this->container->get(ArticleRepository::class); -+ $nodes = $repository->getAll(); -+ $nodeIds = array_keys($nodes); - - $this->assertSame([3, 1, 2, 5, 4], $nodeIds); - } -``` - -Use `createNode()` again to create some article nodes, each with a different `created` date to match our assertion. This is to ensure that the test doesn’t pass by default. - -```diff - /** @test */ - public function nodes_are_ordered_by_date_and_returned_newest_first() { -+ $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-2 days'))->getTimestamp()]); -+ $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-1 week'))->getTimestamp()]); -+ $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-1 hour'))->getTimestamp()]); -+ $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-1 year'))->getTimestamp()]); -+ $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-1 month'))->getTimestamp()]); - - $repository = $this->container->get(ArticleRepository::class); - $nodes = $repository->getAll(); - $nodeIds = array_keys($nodes); - - $this->assertSame([3, 1, 2, 5, 4], $nodeIds); - } -``` - -This test fails as expected, as the nodes are returned in their default order, by node ID. - -> Failed asserting that two arrays are identical. --- Expected +++ Actual @@ @@ -> Array &0 ( -> -> - 0 => 3 -> - 1 => 1 -> - 2 => 2 -> - 3 => 5 -> - 4 => 4 -> -> * 0 => 1 -> * 1 => 2 -> * 2 => 3 -> * 3 => 4 -> * 4 => 5 ) - -To order the articles by their created date, we can update the `getAll()` method within the `ArticleRepository`. - -```diff - public function getAll(): array { -- return $this->nodeStorage->loadByProperties([ -+ $articles = $this->nodeStorage->loadByProperties([ - 'status' => Node::PUBLISHED, - 'type' => 'article', - ]); -+ -+ $this->sortByCreatedDate($articles); -+ -+ return $articles; -+ } -+ -+ private function sortByCreatedDate(array &$articles): void { -+ uasort($articles, function (NodeInterface $a, NodeInterface $b): bool { -+ return $a->getCreatedTime() < $b->getCreatedTime(); -+ }); - } -``` - -The nodes are now ordered by their created date, and in the correct order to match the assertion. - -> OK (1 test, 11 assertions) - -### 4l. Linking up the repository to the BlogPageController - -Now that our `ArticleRepository` tests are passing, we can use it within `BlogPageController` so that articles are displayed on the page. - -Let’s add `BlogPageController` as a service and enable autowiring. - -```diff - # my_module.services.yml - - services: -+ Drupal\my_module\Controller\BlogPageController: -+ autowire: true - - Drupal\my_module\Repository\ArticleRepository: - autowire: true -``` - -Now we can inject the `ArticleRepository` and use it to load and render the articles on the page. - -```diff - -namespace Drupal\my_module\Controller; - -use Drupal\Core\Entity\EntityTypeManagerInterface; -use Drupal\Core\StringTranslation\StringTranslationTrait; -use Drupal\my_module\Repository\ArticleRepository; - -class BlogPageController { - - use StringTranslationTrait; - -+ /** -+ * @var \Drupal\my_module\Repository\ArticleRepository -+ */ -+ private $articleRepository; -+ -+ /** -+ * @var \Drupal\Core\Entity\EntityViewBuilderInterface -+ */ -+ private $nodeViewBuilder; -+ -+ public function __construct( -+ EntityTypeManagerInterface $entityTypeManager, -+ ArticleRepository $articleRepository -+ ) { -+ $this->nodeViewBuilder = $entityTypeManager->getViewBuilder('node'); -+ $this->articleRepository = $articleRepository; -+ } - - public function __invoke(): array { -- return []; -+ $build = []; -+ -+ $articles = $this->articleRepository->getAll(); - -+ foreach ($articles as $article) { -+ $build[] = $this->nodeViewBuilder->view($article, 'teaser'); -+ } -+ -+ return [ -+ '#markup' => render($build), -+ ]; - } - -} -``` - -In the browser, we should see our list of articles. - -![](docs/images/3.png) - -## Step 5: Creating a custom Post class - -What if we wanted to return a custom `Post` class from the repository with its own data and logic rather than a generic Drupal node? As the repository is responsible for finding and returning nodes, we can make changes there and return what we want. - -Let's start by changing one of our existing tests. - -### 5a: Changing the existing test - -In `ArticleRepositoryTest` we have existing assertions as to what type of object is returned. Currently, this should be an instance of a `Node::class`. Let's change that to a new `Post::class` and also change the `label` method to a more desciriptive `getTitle()`. - -```diff - $this->assertCount(1, $articles); - $this->assertIsObject($articles[1]); -- $this->assertInstanceOf(Node::class, $articles[1]); -- $this->assertSame('Test post', $articles[1]->label()); -+ $this->assertInstanceOf(Post::class, $articles[1]); -+ $this->assertSame('Test post', $articles[1]->getTitle()); -``` -As we have no `Post` class and are still returning the original nodes from the Repository, this will cause the test to now fail. - -> 1) Drupal\Tests\my_module\Kernel\ArticleRepositoryTest::it_returns_blog_posts - PHPUnit\Framework\Exception: Argument #1 (No Value) of PHPUnit\Framework\Assert::assertInstanceOf() must be a class or interface name - -### 5b: Adding a Post class - -Create a new `Entity` directory and a new `Post.php` file inside it. - -``` -mkdir -p src/Entity -``` - -```php - Drupal\Tests\my_module\Kernel\ArticleRepositoryTest::it_returns_blog_posts -> Failed asserting that Drupal\node\Entity\Node Object (...) is an instance of class "Drupal\my_module\Entity\Post". - -### 5c: Returning Post classes - -To pass this failure, we need to update the Repository and return instances of `Post` rather than the standard Drupal nodes. - -We can do that in the `getAll()` method: - -```diff -- return $articles; -+ return array_map(function (NodeInterface $node) { -+ return new Post(); -+ }, $articles); -``` - -This will return an array of `Post` objects, and change the failure message as we're calling a method that we've not yet added. - -> Error: Call to undefined method -> Drupal\my_module\Entity\Post::getTitle() - -To do this, let's start by adding a Unit test. - -## Step 6: Unit testing the Post class - -### 6a: Creating a PostTest class - -Create a `Unit` directory, an `Entity` sub-directory, and a `PostTest.php` file. Typically, unit tests match the directory structure in `src` and the class name that they're testing. - -``` -mkdir -p tests/src/Unit/Entity -``` - -```php -assertSame('Test post', $post->getTitle()); -} -``` - -If we run this, we get an undefined method error: - -> Error: Call to undefined method Drupal\my_module\Entity\Post::getTitle() - -### 6b: Adding the getTitle() method - -Within the `Post` class, add a `getTitle()` method which will return a string. For now, let's return an empty string: - -```php -public function getTitle(): string { - return ''; -} -``` - -> Failed asserting that two strings are identical. -> --- Expected -> +++ Actual -> @@ @@ -> -'Test post' -> +'' - -This will cause a different failure as the expected title doesn't match the returned empty string. - -To get the real title, we'll need to pass the article node into the `Post` class so that we can reference it. - -### 6c: Returning the real title - -To get the post's title, we need to add a constructor to the `Post` class which accepts the original node, which we can then use to get its title. - -```php -class Post { - - private $node; - - public function __construct(NodeInterface $node) { - $this->node = $node; - } - - public function getTitle(): string { - return $this->node->label(); - } - -} -``` - -This test will fail as we need to update the test to include the node: - -> ArgumentCountError: Too few arguments to function Drupal\my_module\Entity\Post::__construct(), 0 passed in /home/opdavies/Code/Personal/workshop-drupal-automated-testing-code/web/modules/custom/my_module/tests/src/Unit/Entity/PostTest.php on line 12 and exactly 1 expected - -### 6d: Mocking the article node - -As we are working with a unit test, we can't interact with the database in the same way that we can with functional or kernel tests. This means that using methods like `Node::create` won't work in unit tests, so we need to create our own mock node and tell it what to return. - -```php -$node = $this->createMock(NodeInterface::class); - -$node->expects($this->once()) - ->method('label') - ->willReturn('Test post'); -``` - -This ensures that the `label()` method will only be called once and that it will return the string `Test post`. - -As this is the same value as our expection in the test, this test should now pass. - -However, whilst the unit tests are all passing, one of the kernel tests is now failing. - -### 6e. Fixing the ArticleRepository test - -To get `ArticleRepositoryTest` passing again, we need to update the `getAll()` method and add the node as an argument to the create `Post`. - -```diff - return array_map(function (NodeInterface $node): Post { -- return new Post(); -+ return new Post($node); - }, $articles); -``` - -### 6f: Only article nodes should be used for Posts - -Currently any node is able to be passed to the `Post` class. Let's ensure that only article nodes can be added by adding a check and throwing an Exception. - -```php -/** @test */ -public function it_throws_an_exception_if_the_node_is_not_an_article() { - $node = $this->createMock(NodeInterface::class); - - $node->method('bundle')->willReturn('page'); - - $this->expectException(\InvalidArgumentException::class); - - new Post($node); -} -``` - -Again, we need to mock the node, but this time, let's set the `bundle()` method to return a value that should throw an Exception. - -### 6g: Throw an Exception for non-articles - -Let's add a check to the `Post` constructor -```diff - public function __construct(NodeInterface $node) { -+ if ($node->bundle() != 'article') { -+ throw new \InvalidArgumentException(); -+ } -+ - $this->node = $node; - } -``` - -This will result in the Exception being thrown if the node is not an article, and the test should pass. - -### 6h: Fixing the existing unit test - -Due to this new check, we also need to update the previous unit test so that includes a value for the bundle. - -```diff - $node->expects($this->once()) - ->method('label') - ->willReturn('Test post'); -+ $node->method('bundle')->willReturn('article'); -``` diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..a1ce694 --- /dev/null +++ b/README.rst @@ -0,0 +1,1308 @@ +Workshop: Automated Testing and Test Driven Development in Drupal 8 +=================================================================== + +.. sectnum:: + +.. contents:: + +.. raw:: pdf + + PageBreak + +Contribution +------------ + +Please feel free to create issues and/or submit pull requests to this repository whilst working through these instructions. Any contributions would be greatly appreciated! + +Feedback +-------- + +Feedback would also be appreciated! You can contact me via oliver@odwd.uk, [@opdavies on Twitter](https://twitter.com/opdavies) or ``opdavies`` on Drupal Slack. + +Introduction +------------ + +Creating a new Drupal project with Composer +------------------------------------------- + +If don’t have Composer, visit https://getcomposer.org/download for instructions on how to install it on your computer. + +This assumes that Composer is installed globally and is available by running the ``composer`` command. Alternatively, you can download the phar file and run ``php composer.phar`` instead. + +.. code:: bash + + # Create a new Drupal project + composer create-project drupal/recommended-project my-project + + cd my-project + + # Add testing dependencies + composer require --dev drupal/core-dev + +You should now have files present including ``web/index.php`` and ``vendor/bin/phpunit``. Now you can start serving this site locally. + +**Note:** Development dependencies, including PHPUnit, should only be installed locally and should not be present on public servers. Doing so would present a security risk to your application. + +Using DDEV for local development +-------------------------------- + +- Docker based development environment for PHP applications (Drupal, WordPress, Magento etc). +- More information at https://www.ddev.com. +- Documentation at https://ddev.readthedocs.io. +- Installation via Homebrew on Linux and macOS, and Chocolatey on Windows. More information at https://www.ddev.com/get-started. +- Example at https://github.com/opdavies/workshop-drupal-automated-testing-code. + +To run PHPUnit within DDEV, we can prefix the command with ``ddev exec``: + +:: + + $ ddev exec vendor/bin/phpunit + +Using the PHP web server for local development +---------------------------------------------- + +If you have all of `Drupal's required PHP extensions `__ installed and would like better performance (particularly on macOS), you could use the PHP's local web server. + +As we're going to use SQLite to run the tests, there's no need for a connection to a MySQL database or another service. + +If you need to override any environment variables, you can do so before running the command: + +:: + + $ SIMPLETEST_BASE_URL=http://localhost:8000 vendor/bin/phpunit + +The different types of available tests +-------------------------------------- + +- **Functional** (web, feature) - tests behaviour and functionality, makes HTTP requests to the webserver and has access to the database and other services via the service container. Slower to run. +- **FunctionalJavascript** - functional tests, but access to JavaScript. +- **Kernel** (integration) - no browser capabilities, has access to the database and other services but requires more configuration. +- **Unit** - no access to the database or service container, all dependencies need to be mocked. Fast to run. + +Different approaches to testing +------------------------------- + +- Inside-out (testing pyramid) - mostly unit tests, some integration tests, few functional tests. +- Outside-in (testing trophy) - mostly functional tests, some integration tests, few unit tests. More flexible, easier to refactor. + +The structure of a test +----------------------- + +- **Arrange** - set up the environment. Create users, nodes, set up dependencies +- **Act** - perform an action +- **Assert** - verify that something happened + +What is Test Driven Development? +-------------------------------- + +- Writing tests first +- Red, green, refactor loop +- Writing failing test first +- Write code to make the test pass +- Refactor when tests pass +- Three (simplified) rules of TDD: +- Write production code only to make a failing unit test pass. +- Write only enough of a unit test to fail. +- Write only enough production code to make the failing unit test pass. +- http://www.javiersaldana.com/articles/tech/refactoring-the-three-laws-of-tdd + +Acceptance criteria +------------------- + +This module will be used to demonstrate how to take a test-driven approach to develop a module to the following acceptance criteria: + +- As a site visitor +- I want to see a list of all published articles at ``/blog`` +- Ordered by post date, with the newest posts first + +Preparation +----------- + +To begin, we need the site to be running. + +.. code:: bash + + # Using DDEV + ddev start + + # Using PHP's web server + php -S localhost:8000 -t web + +You don’t need to install Drupal. It just needs to be able to connect to the database. + +Writing your first test +----------------------- + +Create the module directory +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Create a directory for the new module: + +:: + + mkdir -p web/modules/custom/my_module + +1b. Create an ``.info.yml`` file for the module +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In order to install the module, it needs an info.yml file that matches the name of the module (e.g. ``my_module.info.yml``). + +Within the ``my_module`` directory, create the file and paste in the following content: + +.. code:: yaml + + name: My Module + type: module + core_version_requirement: ^8 || ^9 + +Create the directory structure for tests +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code:: bash + + mkdir -p tests/src/Functional + +Create your first test case +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code:: php + + config('system.site') + ->set('page.front', '/node') + ->save(TRUE); + + $this->drupalGet(''); + + $assert = $this->assertSession(); + $assert->statusCodeEquals(Response::HTTP_OK); + $assert->pageTextContains('Welcome to Drupal'); + $assert->pageTextContains('No front page content has been created yet.'); + } + + } + +Some things to note: + +- The name of the class must match the filename. +- The filename must end with ``Test.php``. +- The namespace is ``Drupal\Tests\{module_name}``, followed by any additional directories (e.g. ``Functional``). +- Test methods must start with ``test``, or use the ``@test`` annotation. + +Preparing PHPUnit +~~~~~~~~~~~~~~~~~ + +Firstly, we need to create a ``phpunit.xml`` file to configure PHPUnit. Core has a ``phpunit.xml.dist`` file that we can duplicate and edit. + +.. code:: bash + + cp web/core/phpunit.xml.dist web/core/phpunit.xml + +Update the ``SIMPLETEST_BASE_URL`` value to be the address that the website is currently running on. This needs to be correct so that functional tests return the correct response codes, so ensure that any port numbers are correct and also that the site is correctly marked as HTTP or HTTPS. + +We also need to configure the database for Drupal to connect to and use when running functional and kernel tests. This could be your project’s MySQL or PostgreSQL database with a table prefix, but in this case, we’ll use a separate SQLite database. + +.. code:: diff + + - + + + + - + + + +Running the tests +~~~~~~~~~~~~~~~~~ + +.. code:: bash + + $ vendor/bin/phpunit modules/custom/my_module + +You should see a summary of the number of tests and assertions that were run. This is the expected output if all of the tests pass: + + OK (1 test, 3 assertions) + +If a test failed, the output would show the class and method name for the failing test, and give a summary of the failure. + + Drupal\ *module::the*\ front\_page\_loads\_for\_anonymous\_users + Behat: Current response status code is 404, but 200 expected. + +Other useful options include ``--stop-on-failure``, ``--filter`` and ``--testdox``. + +(Optional) Running tests via a Composer script +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To simplify running tests, the command could be simplified by `adding a script ` to ``composer.json``: + +.. code:: json + + "scripts": { + "test:phpunit": "phpunit --verbose --testdox --colors=always", + "test": [ + "@test:phpunit" + ] + } + +This means that you can run just ``ddev composer test:phpunit`` or ``ddev composer test`` and it will execute the ``phpunit`` command. + +This approach can be useful if you want to run other commands in addition to PHPUnit such as PHPStan, PHP Code Sniffer or Drupal Check. Each command can be added to the script and they will each be executed. + +If needed, you can still pass additional arguments and options to the command by appending ``--`` followed by the arguments. + +.. code:: bash + + ddev composer test:phpunit -- modules/custom/my_module \ + --stop-on-failure \ + --filter=the_front_page_loads_for_anonymous_users + +Locally, ensure that the command is prefixed with ``ddev`` so that it is run within the container. This ensures that the correct PHP version etc is used. + +Adding more test methods +------------------------ + +Ensure that anonymous users cannot access admin pages +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Now that we’re sure that the front page loads correctly, lets also check anonymous users cannot access the administration area. This test is very similar to the previous one, though instead we’re making a GET request to ``/admin`` and ensuring that the response code is 403 (forbidden). + +As this functionality is provided by Drupal core by default, this should pass automatically. + +.. code:: php + + drupalGet('admin'); + + $this->assertSession()->statusCodeEquals(Response::HTTP_FORBIDDEN); + } + +Ensure that administrators can access admin pages +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Now let’s check that an administrator user *can* access the admin pages. + +This introduces some new concepts. We need to create a user to begin with, and assign it some permissions. Because tests may be included within Drupal core a contributed module, permissions need to be added to users directly as modules won’t know about roles that are specific to your site. + +The ``BrowserTestBase`` class gives access to a number of helper methods, including ones for creating and logging-in users (``createUser`` and ``drupalLogin`` respectively). When creating a user, the first argument is an array of permission names to add. In this case, we can make the user an admin user by adding the ``access administration pages`` permission. + +.. code:: php + + createUser([ + 'access administration pages', + ]); + + $this->drupalLogin($adminUser); + + $this->drupalGet('admin'); + + $this->assertSession()->statusCodeEquals(Response::HTTP_OK); + } + +Again, as this functionality is provided by Drupal core by default, this should pass. However, we can be confident that the test is doing what’s needed by making it fail by removing or changing the assigned permissions, or not logging in the user before accessing the page. + +Building a blog +--------------- + +Anonymous users should be able to view the blog page +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Let’s start by building a blog page. This will look very similar to the admin page tests, but instead we’ll be testing the ``/blog`` page. + +.. code:: php + + drupalGet('blog'); + + $session = $this->assertSession(); + + $session->statusCodeEquals(Response::HTTP_OK); + } + + } + +This test will fail as there’s no route for ``/blog`` and no View that generates that page. Because of this, the response code will be a 404 instead of the 200 that we want. + + Current response status code is 404, but 200 expected. + +Add a route for the blog page +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +We’ll create a blog page using a custom route in the module. You could also do this with the Views module by creating a View with a page on that path, and exporting the configuration into the module’s ``config/install`` directory. + +To add a route, we need to create a ``my_module.routing.yml`` file. + +.. code:: yaml + + # my_module.routing.yml + + blog.page: + path: /blog + defaults: + _controller: Drupal\my_module\Controller\BlogPageController + _title: Blog + requirements: + _permission: access content + +We set our path to ``/blog``, specify the Controller to use and which permission the needs to have to access the page. + +If we run the tests now, we get an access denied error (403 response). + + Current response status code is 403, but 200 expected. + +Fix permission error +~~~~~~~~~~~~~~~~~~~~ + +Because we need to node module to be able to access the ``access content`` permission, we need to enable it within our tests. + +We can do this by adding it to the ``$modules`` array within the test. + +.. code:: diff + + protected static $modules = [ + + 'node', + 'my_module', + ]; + +Now the error has changed, and is now returning a 500 response because we’ve specified a Controller that doesn’t exist. + + Current response status code is 500, but 200 expected. + +Add the BlogPageController +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Let’s create the ``BlogPageController``. + +:: + + mkdir src/Controller + +Let’s start by creating a minimal controller, that returns an empty render array. Because we didn’t specify a method to use within the route file, we use PHP’s ``__invoke()`` method. + +.. code:: php + + drupalGet('/blog'); + + $session = $this->assertSession(); + + $session->statusCodeEquals(Response::HTTP_OK); + + $session->responseContains('

Blog

'); + + $session->pageTextContains('Welcome to my blog!'); + } + +The page title is created by the ``_title`` value within the routing file, but no page text has been added yet so this will cause the test to fail. + + Behat: The text "Welcome to my blog!" was not found anywhere in the + text of the current page. + +To fix this, we can return some text from the BlogPageController rather than an empty render array. + +.. code:: diff + + namespace Drupal\my_module\Controller; + + + use Drupal\Core\StringTranslation\StringTranslationTrait; + + class BlogPageController { + + + use StringTranslationTrait; + + public function __invoke(): array { + - return []; + + return [ + + '#markup' => $this->t('Welcome to my blog!'), + + ]; + } + + } + +Now the tests will pass because we’re returning the correct text. + + OK (1 test, 3 assertions) + +.. figure:: images/2.png + :alt: + +Getting blog posts +------------------ + +Creating our first kernel test +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +We’ll be using an ArticleRepository class to get the blog posts from the database, and this is also a good time to switch to writing kernel tests as we don’t need to check any responses from the browser. + +Within the tests directory, create a new ``Kernel`` directory. + +:: + + mkdir tests/src/Kernel + +And an ``ArticleRepositoryTest`` class. + +.. code:: php + + assertCount(1, $articles); + } + +As we aren’t yet returning any articles, or even creating that variable, the test is going to fail, but we can move on to getting articles. + + Undefined variable: articles + +Trying to use the ArticleRepository +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +As the test name suggests, we’re going to be retrieving the articles from an ``ArticleRepository`` service - though this doesn’t exist yet, but let’s let the tests tell us that. + +.. code:: diff + + /** @test */ + public function it_returns_blog_posts() { + + $repository = $this->container->get(ArticleRepository::class); + + + $this->assertCount(1, $articles); + } + +Because this is a kernel test, we have access to the container, and we can use it to retrieve our repository service. + +Running the test now gives us a different error, and tells us what the next step is: + + Symfony: You have requested a non-existent service "Drupal\_module". + +Creating an article repository +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code:: bash + + mkdir src/Repository + +To begin with, let’s create a basic ``ArticleRepository`` class. + +.. code:: php + + container->get(ArticleRepository::class); + + $articles = $repository->getAll(); + + $this->assertCount(1, $articles); + +This method doesn’t exist on the repository yet, so the test will fail. + + Error : Call to undefined method Drupal\_module::getAll() + +Let’s fix that by adding the ``getAll()`` method. For now, have it return an empty array. + +.. code:: php + + // my_module/Repository/ArticleRepository.php + + public function getAll(): array { + return []; + } + +Now we’ve got everything in place, and the test failure is because we aren’t returning the correct number of articles. + + Failed asserting that actual size 0 matches expected size 3. + +We can fix this by building up the ``ArticleRepository`` class. + +Building up the ArticleRepository +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ``ArticleRepository`` needs to return some articles. We can do this by injecting the ``EntityTypeManager`` and using it to return nodes from the ``getAll()`` method rather than the empty array. + +.. code:: diff + + + use Drupal\Core\Entity\EntityTypeManagerInterface; + + + + /** + + * @var \Drupal\Core\Entity\EntityStorageInterface + + */ + + private $nodeStorage; + + + public function __construct(EntityTypeManagerInterface $entityTypeManager) { + + $this->nodeStorage = $entityTypeManager->getStorage('node'); + + } + + public function getAll(): array { + - return []; + + return $this->nodeStorage->loadMultiple(); + } + +Within our services file, we now need to add the ``EntityTypeManager`` as an argument so that it’s used to create the ``ArticleRepository``. Currently we don’t have enough arguments. + + ArgumentCountError : Too few arguments to function + Drupal\_module::\_\_construct(), 0 passed and exactly 1 expected + +The quickest way to do that is to enable autowiring for the ArticleRepository within ``my_module.services.yml``. This will automatically inject services rather than needing to specify each argument individually. + +.. code:: diff + + - Drupal\my_module\Repository\ArticleRepository: ~ + + Drupal\Core\Entity\EntityTypeManagerInterface: + + alias: entity_type.manager + + + + Drupal\my_module\Repository\ArticleRepository: + + autowire: true + + Drupal: The "node" entity type does not exist. + +As we did previously, we need to enable the ``node`` module. + +.. code:: diff + + public static $modules = [ + + 'node', + 'my_module', + ]; + +The ``ArticleRepository`` is now working, but is still returning no articles - though this is because we haven’t created any inside the test. + + Failed asserting that actual size 0 matches expected size 1. + +Adding articles +~~~~~~~~~~~~~~~ + +To test the ArticleRepository, we need articles to be created so that they can be returned. + +Within the ``ArticleRepositoryTest`` we can make use of one of a number of traits that are provided. + +Within the class, enable the trait: + +.. code:: diff + + + use NodeCreationTrait + +Include the import statement at the top of the file if it hasn’t been added automatically. + +.. code:: diff + + + use Drupal\Tests\node\Traits\NodeCreationTrait; + +This gives us a ``createNode`` method that we can use to create nodes by passing an array of values. + +As we need an article to retrieve, let’s create one. + +.. code:: diff + + + $this->createNode(['type' => 'article', 'title' => 'Test post'])->save(); + + $repository = $this->container->get(ArticleRepository::class); + $articles = $repository->getAll(); + +The next error is a little cryptic: + + Error : Call to a member function id() on bool + +Looking at the stack trace, this error is within ``filter.module``, where it’s trying to call an ``id()`` method on a filter format. + +.. code:: php + + // filter.module + + $formats = filter_formats($account); + $format = reset($formats); + return $format->id(); + +As kernel tests don’t install configuration by default, we need to install the missing filter configuration. + +As we’ll need this for all test methods in this case, we can use the ``setUp()`` method that will run before each test. + +.. code:: diff + + + protected function setUp() { + + parent::setUp(); + + + + $this->installConfig([ + + 'filter', + + ]); + + } + +We also need to create the ``node_access`` table as indicated by the next error: + + Drupal: SQLSTATE[HY000]: General error: 1 no such table: + test90927710.node\_access: DELETE FROM {node\_access} + +.. code:: diff + + protected function setUp() { + parent::setUp(); + + + + $this->installSchema('node', ['node_access']); + + + $this->installConfig([ + 'filter', + ]); + } + +We’ve successfully returned our article and this test now passes. + + OK (1 test, 11 assertions) + +Whilst the test is passing, let's add some additional assertions to check the type of object being returned and its title. + +.. code:: diff + + $this->assertCount(1, $articles); + + $this->assertIsObject($articles[1]); + + $this->assertInstanceOf(NodeInterface::class, $articles[1]); + + $this->assertSame('Test post', $articles[1]->label()); + + OK (1 test, 14 assertions) + +Ensuring that only articles are returned +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Let's start with a new test, this time with three article nodes: + +.. code:: php + + createNode(['type' => 'article'])->save(); + $this->createNode(['type' => 'article'])->save(); + $this->createNode(['type' => 'article'])->save(); + + $repository = $this->container->get(ArticleRepository::class); + $articles = $repository->getAll(); + + $this->assertCount(3, $articles); + } + +Again, we can use the node creation trait to create the required content. + +As we already have the ``ArticleRepository`` in place, this test should pass straight away. + + OK (1 test, 11 assertions) + +Making this test less brittle +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The test is passing, but it currently returns *all* nodes and not just articles. + +If we create some page nodes too, these will also be returned and the assertion will now fail. + +.. code:: diff + + $this->createNode(['type' => 'article'])->save(); + + $this->createNode(['type' => 'page'])->save(); + $this->createNode(['type' => 'article'])->save(); + + $this->createNode(['type' => 'page'])->save(); + $this->createNode(['type' => 'article'])->save(); + + Failed asserting that actual size 5 matches expected size 3. + +We can make a change to the ``ArticleRepository`` to fix this, and ensure that we’re only loading and returning article nodes. + +.. code:: diff + + - return $this->nodeStorage->loadMultiple(); + + return $this->nodeStorage->loadByProperties([ + + 'type' => 'article', + + ]); + +Ensuring that only published articles are returned +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +We now know that only article nodes are returned, but *all* articles are being returned. On our blog, we only want to published articles to be displayed. + +Let’s create another test for this. + +.. code:: diff + + + /** @test */ + + public function only_published_articles_are_returned() { + + $repository = $this->container->get(ArticleRepository::class); + + $articles = $repository->getAll(); + + + $this->assertCount(3, $articles); + + } + +We already know that only articles are returned, so in this test we can focus on the published status. We can create a number of articles, some which are published and some which are unpublished. + +.. code:: diff + + /** @test */ + public function only_published_articles_are_returned() { + + $this->createNode(['type' => 'article', 'status' => Node::PUBLISHED])->save(); + + $this->createNode(['type' => 'article', 'status' => Node::NOT_PUBLISHED])->save(); + + $this->createNode(['type' => 'article', 'status' => Node::PUBLISHED])->save(); + + $this->createNode(['type' => 'article', 'status' => Node::NOT_PUBLISHED])->save(); + + $this->createNode(['type' => 'article', 'status' => Node::PUBLISHED])->save(); + + $repository = $this->container->get(ArticleRepository::class); + $articles = $repository->getAll(); + + $this->assertCount(3, $articles); + } + +Because we have no filter on the published state, all the articles are returned including the unpublished ones. + + Failed asserting that actual size 5 matches expected size 3. + +We can again update the ``ArticleRepository`` to add this extra condition to filter out any unpublished articles. + +.. code:: diff + + + use Drupal\node\Entity\Node; + + public function getAll(): array { + return $this->nodeStorage->loadByProperties([ + + 'status' => Node::PUBLISHED, + 'type' => 'article', + ]); + } + +With this added, the test passes again. + + OK (1 test, 6 assertions) + +Ensuring that articles are returned in the correct order +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +As per our acceptance criteria, we need the articles to be returned based on their created date, so let’s create another test. + +In this test, let’s ensure assert that some article node IDs are returned within a specific order. + +.. code:: diff + + + /** @test */ + + public function nodes_are_ordered_by_date_and_newest_first() { + + $this->assertSame([3, 1, 2, 5, 4], $nodeIds); + + } + +We can use the same ``getAll()`` method, and get the node IDs from the array keys. + +.. code:: diff + + /** @test */ + public function nodes_are_ordered_by_date_and_returned_newest_first() { + + $repository = $this->container->get(ArticleRepository::class); + + $nodes = $repository->getAll(); + + $nodeIds = array_keys($nodes); + + $this->assertSame([3, 1, 2, 5, 4], $nodeIds); + } + +Use ``createNode()`` again to create some article nodes, each with a different ``created`` date to match our assertion. This is to ensure that the test doesn’t pass by default. + +.. code:: diff + + /** @test */ + public function nodes_are_ordered_by_date_and_returned_newest_first() { + + $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-2 days'))->getTimestamp()]); + + $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-1 week'))->getTimestamp()]); + + $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-1 hour'))->getTimestamp()]); + + $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-1 year'))->getTimestamp()]); + + $this->createNode(['type' => 'article', 'created' => (new DrupalDateTime('-1 month'))->getTimestamp()]); + + $repository = $this->container->get(ArticleRepository::class); + $nodes = $repository->getAll(); + $nodeIds = array_keys($nodes); + + $this->assertSame([3, 1, 2, 5, 4], $nodeIds); + } + +This test fails as expected, as the nodes are returned in their default order, by node ID. + + Failed asserting that two arrays are identical. --- Expected +++ + Actual @@ @@ Array &0 ( + + - 0 => 3 + - 1 => 1 + - 2 => 2 + - 3 => 5 + - 4 => 4 + + - 0 => 1 + - 1 => 2 + - 2 => 3 + - 3 => 4 + - 4 => 5 ) + +To order the articles by their created date, we can update the ``getAll()`` method within the ``ArticleRepository``. + +.. code:: diff + + public function getAll(): array { + - return $this->nodeStorage->loadByProperties([ + + $articles = $this->nodeStorage->loadByProperties([ + 'status' => Node::PUBLISHED, + 'type' => 'article', + ]); + + + + $this->sortByCreatedDate($articles); + + + + return $articles; + + } + + + + private function sortByCreatedDate(array &$articles): void { + + uasort($articles, function (NodeInterface $a, NodeInterface $b): bool { + + return $a->getCreatedTime() < $b->getCreatedTime(); + + }); + } + +The nodes are now ordered by their created date, and in the correct order to match the assertion. + + OK (1 test, 11 assertions) + +Linking up the repository to the BlogPageController +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Now that our ``ArticleRepository`` tests are passing, we can use it within ``BlogPageController`` so that articles are displayed on the page. + +Let’s add ``BlogPageController`` as a service and enable autowiring. + +.. code:: diff + + # my_module.services.yml + + services: + + Drupal\my_module\Controller\BlogPageController: + + autowire: true + + Drupal\my_module\Repository\ArticleRepository: + autowire: true + +Now we can inject the ``ArticleRepository`` and use it to load and render the articles on the page. + +.. code:: diff + + + namespace Drupal\my_module\Controller; + + use Drupal\Core\Entity\EntityTypeManagerInterface; + use Drupal\Core\StringTranslation\StringTranslationTrait; + use Drupal\my_module\Repository\ArticleRepository; + + class BlogPageController { + + use StringTranslationTrait; + + + /** + + * @var \Drupal\my_module\Repository\ArticleRepository + + */ + + private $articleRepository; + + + + /** + + * @var \Drupal\Core\Entity\EntityViewBuilderInterface + + */ + + private $nodeViewBuilder; + + + + public function __construct( + + EntityTypeManagerInterface $entityTypeManager, + + ArticleRepository $articleRepository + + ) { + + $this->nodeViewBuilder = $entityTypeManager->getViewBuilder('node'); + + $this->articleRepository = $articleRepository; + + } + + public function __invoke(): array { + - return []; + + $build = []; + + + + $articles = $this->articleRepository->getAll(); + + + foreach ($articles as $article) { + + $build[] = $this->nodeViewBuilder->view($article, 'teaser'); + + } + + + + return [ + + '#markup' => render($build), + + ]; + } + + } + +In the browser, we should see our list of articles. + +.. figure:: images/3.png + :alt: + +Creating a custom Post class +---------------------------- + +What if we wanted to return a custom ``Post`` class from the repository with its own data and logic rather than a generic Drupal node? As the repository is responsible for finding and returning nodes, we can make changes there and return what we want. + +Let's start by changing one of our existing tests. + +Changing the existing test +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In ``ArticleRepositoryTest`` we have existing assertions as to what type of object is returned. Currently, this should be an instance of a ``Node::class``. Let's change that to a new ``Post::class`` and also change the ``label`` method to a more desciriptive ``getTitle()``. + +.. code:: diff + + $this->assertCount(1, $articles); + $this->assertIsObject($articles[1]); + - $this->assertInstanceOf(Node::class, $articles[1]); + - $this->assertSame('Test post', $articles[1]->label()); + + $this->assertInstanceOf(Post::class, $articles[1]); + + $this->assertSame('Test post', $articles[1]->getTitle()); + +As we have no ``Post`` class and are still returning the original nodes from the Repository, this will cause the test to now fail. + + 1) Drupal\ *module::it*\ returns\_blog\_posts PHPUnit: Argument #1 + (No Value) of PHPUnit::assertInstanceOf() must be a class or + interface name + +Adding a Post class +~~~~~~~~~~~~~~~~~~~ + +Create a new ``Entity`` directory and a new ``Post.php`` file inside it. + +:: + + mkdir -p src/Entity + +.. code:: php + + assertSame('Test post', $post->getTitle()); + } + +If we run this, we get an undefined method error: + + Error: Call to undefined method Drupal\_module::getTitle() + +Adding the getTitle() method +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Within the ``Post`` class, add a ``getTitle()`` method which will return a string. For now, let's return an empty string: + +.. code:: php + + node = $node; + } + + public function getTitle(): string { + return $this->node->label(); + } + + } + +This test will fail as we need to update the test to include the node: + + ArgumentCountError: Too few arguments to function Drupal\_module::\_\_construct(), 0 passed in /home/opdavies/Code/Personal/workshop-drupal-automated-testing-code/web/modules/custom/my\_module/tests/src/Unit/Entity/PostTest.php on line 12 and exactly 1 expected + +Mocking the article node +~~~~~~~~~~~~~~~~~~~~~~~~ + +As we are working with a unit test, we can't interact with the database in the same way that we can with functional or kernel tests. This means that using methods like ``Node::create`` won't work in unit tests, so we need to create our own mock node and tell it what to return. + +.. code:: php + + createMock(NodeInterface::class); + + $node->expects($this->once()) + ->method('label') + ->willReturn('Test post'); + +This ensures that the ``label()`` method will only be called once and that it will return the string ``Test post``. + +As this is the same value as our expection in the test, this test should now pass. + +However, whilst the unit tests are all passing, one of the kernel tests is now failing. + +Fixing the ArticleRepository test +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To get ``ArticleRepositoryTest`` passing again, we need to update the ``getAll()`` method and add the node as an argument to the create ``Post``. + +.. code:: diff + + return array_map(function (NodeInterface $node): Post { + - return new Post(); + + return new Post($node); + }, $articles); + +Only article nodes should be used for Posts +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Currently any node is able to be passed to the ``Post`` class. Let's ensure that only article nodes can be added by adding a check and throwing an Exception. + +.. code:: php + + createMock(NodeInterface::class); + + $node->method('bundle')->willReturn('page'); + + $this->expectException(\InvalidArgumentException::class); + + new Post($node); + } + +Again, we need to mock the node, but this time, let's set the ``bundle()`` method to return a value that should throw an Exception. + +Throw an Exception for non-articles +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Let's add a check to the ``Post`` constructor + +.. code:: diff + + public function __construct(NodeInterface $node) { + + if ($node->bundle() != 'article') { + + throw new \InvalidArgumentException(); + + } + + + $this->node = $node; + } + +This will result in the Exception being thrown if the node is not an article, and the test should pass. + +Fixing the existing unit test +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Due to this new check, we also need to update the previous unit test so that includes a value for the bundle. + +.. code:: diff + + $node->expects($this->once()) + ->method('label') + ->willReturn('Test post'); + + $node->method('bundle')->willReturn('article'); diff --git a/docs/images/1.png b/images/1.png similarity index 100% rename from docs/images/1.png rename to images/1.png diff --git a/docs/images/2.png b/images/2.png similarity index 100% rename from docs/images/2.png rename to images/2.png diff --git a/docs/images/3.png b/images/3.png similarity index 100% rename from docs/images/3.png rename to images/3.png From 39acad502c41cbd1a609d0aaaca58f0c98324fef Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Thu, 2 Oct 2025 08:13:01 +0100 Subject: [PATCH 74/77] Move all files to docs/ --- .gitignore => docs/.gitignore | 0 README.rst => docs/README.rst | 0 {images => docs/images}/1.png | Bin {images => docs/images}/2.png | Bin {images => docs/images}/3.png | Bin .../step1-first-test}/my_module.info.yml | 0 .../tests/src/Functional/MyModuleTest.php | 0 .../my_module.info.yml | 0 .../tests/src/Functional/MyModuleTest.php | 0 .../step3-building-a-blog-page}/my_module.info.yml | 0 .../my_module.routing.yml | 0 .../src/Controller/BlogPageController.php | 0 .../tests/src/Functional/BlogPageTest.php | 0 .../tests/src/Functional/MyModuleTest.php | 0 .../my_module.info.yml | 0 .../my_module.routing.yml | 0 .../my_module.services.yml | 0 .../src/Controller/BlogPageController.php | 0 .../src/Repository/ArticleRepository.php | 0 .../tests/src/Functional/BlogPageTest.php | 0 .../tests/src/Functional/MyModuleTest.php | 0 .../tests/src/Kernel/ArticleRepositoryTest.php | 0 .../my_module.info.yml | 0 .../my_module.routing.yml | 0 .../my_module.services.yml | 0 .../src/Controller/BlogPageController.php | 0 .../src/Repository/ArticleRepository.php | 0 .../src/Wrapper/ArticleWrapper.php | 0 .../tests/src/Functional/BlogPageTest.php | 0 .../tests/src/Functional/MyModuleTest.php | 0 .../tests/src/Kernel/ArticleRepositoryTest.php | 0 .../tests/src/Unit/Wrapper/ArticleWrapperTest.php | 0 32 files changed, 0 insertions(+), 0 deletions(-) rename .gitignore => docs/.gitignore (100%) rename README.rst => docs/README.rst (100%) rename {images => docs/images}/1.png (100%) rename {images => docs/images}/2.png (100%) rename {images => docs/images}/3.png (100%) rename {step1-first-test => docs/step1-first-test}/my_module.info.yml (100%) rename {step1-first-test => docs/step1-first-test}/tests/src/Functional/MyModuleTest.php (100%) rename {step2-adding-more-test-methods => docs/step2-adding-more-test-methods}/my_module.info.yml (100%) rename {step2-adding-more-test-methods => docs/step2-adding-more-test-methods}/tests/src/Functional/MyModuleTest.php (100%) rename {step3-building-a-blog-page => docs/step3-building-a-blog-page}/my_module.info.yml (100%) rename {step3-building-a-blog-page => docs/step3-building-a-blog-page}/my_module.routing.yml (100%) rename {step3-building-a-blog-page => docs/step3-building-a-blog-page}/src/Controller/BlogPageController.php (100%) rename {step3-building-a-blog-page => docs/step3-building-a-blog-page}/tests/src/Functional/BlogPageTest.php (100%) rename {step3-building-a-blog-page => docs/step3-building-a-blog-page}/tests/src/Functional/MyModuleTest.php (100%) rename {step4-adding-the-blog-repository => docs/step4-adding-the-blog-repository}/my_module.info.yml (100%) rename {step4-adding-the-blog-repository => docs/step4-adding-the-blog-repository}/my_module.routing.yml (100%) rename {step4-adding-the-blog-repository => docs/step4-adding-the-blog-repository}/my_module.services.yml (100%) rename {step4-adding-the-blog-repository => docs/step4-adding-the-blog-repository}/src/Controller/BlogPageController.php (100%) rename {step4-adding-the-blog-repository => docs/step4-adding-the-blog-repository}/src/Repository/ArticleRepository.php (100%) rename {step4-adding-the-blog-repository => docs/step4-adding-the-blog-repository}/tests/src/Functional/BlogPageTest.php (100%) rename {step4-adding-the-blog-repository => docs/step4-adding-the-blog-repository}/tests/src/Functional/MyModuleTest.php (100%) rename {step4-adding-the-blog-repository => docs/step4-adding-the-blog-repository}/tests/src/Kernel/ArticleRepositoryTest.php (100%) rename {step5-wrapping-up-with-unit-tests => docs/step5-wrapping-up-with-unit-tests}/my_module.info.yml (100%) rename {step5-wrapping-up-with-unit-tests => docs/step5-wrapping-up-with-unit-tests}/my_module.routing.yml (100%) rename {step5-wrapping-up-with-unit-tests => docs/step5-wrapping-up-with-unit-tests}/my_module.services.yml (100%) rename {step5-wrapping-up-with-unit-tests => docs/step5-wrapping-up-with-unit-tests}/src/Controller/BlogPageController.php (100%) rename {step5-wrapping-up-with-unit-tests => docs/step5-wrapping-up-with-unit-tests}/src/Repository/ArticleRepository.php (100%) rename {step5-wrapping-up-with-unit-tests => docs/step5-wrapping-up-with-unit-tests}/src/Wrapper/ArticleWrapper.php (100%) rename {step5-wrapping-up-with-unit-tests => docs/step5-wrapping-up-with-unit-tests}/tests/src/Functional/BlogPageTest.php (100%) rename {step5-wrapping-up-with-unit-tests => docs/step5-wrapping-up-with-unit-tests}/tests/src/Functional/MyModuleTest.php (100%) rename {step5-wrapping-up-with-unit-tests => docs/step5-wrapping-up-with-unit-tests}/tests/src/Kernel/ArticleRepositoryTest.php (100%) rename {step5-wrapping-up-with-unit-tests => docs/step5-wrapping-up-with-unit-tests}/tests/src/Unit/Wrapper/ArticleWrapperTest.php (100%) diff --git a/.gitignore b/docs/.gitignore similarity index 100% rename from .gitignore rename to docs/.gitignore diff --git a/README.rst b/docs/README.rst similarity index 100% rename from README.rst rename to docs/README.rst diff --git a/images/1.png b/docs/images/1.png similarity index 100% rename from images/1.png rename to docs/images/1.png diff --git a/images/2.png b/docs/images/2.png similarity index 100% rename from images/2.png rename to docs/images/2.png diff --git a/images/3.png b/docs/images/3.png similarity index 100% rename from images/3.png rename to docs/images/3.png diff --git a/step1-first-test/my_module.info.yml b/docs/step1-first-test/my_module.info.yml similarity index 100% rename from step1-first-test/my_module.info.yml rename to docs/step1-first-test/my_module.info.yml diff --git a/step1-first-test/tests/src/Functional/MyModuleTest.php b/docs/step1-first-test/tests/src/Functional/MyModuleTest.php similarity index 100% rename from step1-first-test/tests/src/Functional/MyModuleTest.php rename to docs/step1-first-test/tests/src/Functional/MyModuleTest.php diff --git a/step2-adding-more-test-methods/my_module.info.yml b/docs/step2-adding-more-test-methods/my_module.info.yml similarity index 100% rename from step2-adding-more-test-methods/my_module.info.yml rename to docs/step2-adding-more-test-methods/my_module.info.yml diff --git a/step2-adding-more-test-methods/tests/src/Functional/MyModuleTest.php b/docs/step2-adding-more-test-methods/tests/src/Functional/MyModuleTest.php similarity index 100% rename from step2-adding-more-test-methods/tests/src/Functional/MyModuleTest.php rename to docs/step2-adding-more-test-methods/tests/src/Functional/MyModuleTest.php diff --git a/step3-building-a-blog-page/my_module.info.yml b/docs/step3-building-a-blog-page/my_module.info.yml similarity index 100% rename from step3-building-a-blog-page/my_module.info.yml rename to docs/step3-building-a-blog-page/my_module.info.yml diff --git a/step3-building-a-blog-page/my_module.routing.yml b/docs/step3-building-a-blog-page/my_module.routing.yml similarity index 100% rename from step3-building-a-blog-page/my_module.routing.yml rename to docs/step3-building-a-blog-page/my_module.routing.yml diff --git a/step3-building-a-blog-page/src/Controller/BlogPageController.php b/docs/step3-building-a-blog-page/src/Controller/BlogPageController.php similarity index 100% rename from step3-building-a-blog-page/src/Controller/BlogPageController.php rename to docs/step3-building-a-blog-page/src/Controller/BlogPageController.php diff --git a/step3-building-a-blog-page/tests/src/Functional/BlogPageTest.php b/docs/step3-building-a-blog-page/tests/src/Functional/BlogPageTest.php similarity index 100% rename from step3-building-a-blog-page/tests/src/Functional/BlogPageTest.php rename to docs/step3-building-a-blog-page/tests/src/Functional/BlogPageTest.php diff --git a/step3-building-a-blog-page/tests/src/Functional/MyModuleTest.php b/docs/step3-building-a-blog-page/tests/src/Functional/MyModuleTest.php similarity index 100% rename from step3-building-a-blog-page/tests/src/Functional/MyModuleTest.php rename to docs/step3-building-a-blog-page/tests/src/Functional/MyModuleTest.php diff --git a/step4-adding-the-blog-repository/my_module.info.yml b/docs/step4-adding-the-blog-repository/my_module.info.yml similarity index 100% rename from step4-adding-the-blog-repository/my_module.info.yml rename to docs/step4-adding-the-blog-repository/my_module.info.yml diff --git a/step4-adding-the-blog-repository/my_module.routing.yml b/docs/step4-adding-the-blog-repository/my_module.routing.yml similarity index 100% rename from step4-adding-the-blog-repository/my_module.routing.yml rename to docs/step4-adding-the-blog-repository/my_module.routing.yml diff --git a/step4-adding-the-blog-repository/my_module.services.yml b/docs/step4-adding-the-blog-repository/my_module.services.yml similarity index 100% rename from step4-adding-the-blog-repository/my_module.services.yml rename to docs/step4-adding-the-blog-repository/my_module.services.yml diff --git a/step4-adding-the-blog-repository/src/Controller/BlogPageController.php b/docs/step4-adding-the-blog-repository/src/Controller/BlogPageController.php similarity index 100% rename from step4-adding-the-blog-repository/src/Controller/BlogPageController.php rename to docs/step4-adding-the-blog-repository/src/Controller/BlogPageController.php diff --git a/step4-adding-the-blog-repository/src/Repository/ArticleRepository.php b/docs/step4-adding-the-blog-repository/src/Repository/ArticleRepository.php similarity index 100% rename from step4-adding-the-blog-repository/src/Repository/ArticleRepository.php rename to docs/step4-adding-the-blog-repository/src/Repository/ArticleRepository.php diff --git a/step4-adding-the-blog-repository/tests/src/Functional/BlogPageTest.php b/docs/step4-adding-the-blog-repository/tests/src/Functional/BlogPageTest.php similarity index 100% rename from step4-adding-the-blog-repository/tests/src/Functional/BlogPageTest.php rename to docs/step4-adding-the-blog-repository/tests/src/Functional/BlogPageTest.php diff --git a/step4-adding-the-blog-repository/tests/src/Functional/MyModuleTest.php b/docs/step4-adding-the-blog-repository/tests/src/Functional/MyModuleTest.php similarity index 100% rename from step4-adding-the-blog-repository/tests/src/Functional/MyModuleTest.php rename to docs/step4-adding-the-blog-repository/tests/src/Functional/MyModuleTest.php diff --git a/step4-adding-the-blog-repository/tests/src/Kernel/ArticleRepositoryTest.php b/docs/step4-adding-the-blog-repository/tests/src/Kernel/ArticleRepositoryTest.php similarity index 100% rename from step4-adding-the-blog-repository/tests/src/Kernel/ArticleRepositoryTest.php rename to docs/step4-adding-the-blog-repository/tests/src/Kernel/ArticleRepositoryTest.php diff --git a/step5-wrapping-up-with-unit-tests/my_module.info.yml b/docs/step5-wrapping-up-with-unit-tests/my_module.info.yml similarity index 100% rename from step5-wrapping-up-with-unit-tests/my_module.info.yml rename to docs/step5-wrapping-up-with-unit-tests/my_module.info.yml diff --git a/step5-wrapping-up-with-unit-tests/my_module.routing.yml b/docs/step5-wrapping-up-with-unit-tests/my_module.routing.yml similarity index 100% rename from step5-wrapping-up-with-unit-tests/my_module.routing.yml rename to docs/step5-wrapping-up-with-unit-tests/my_module.routing.yml diff --git a/step5-wrapping-up-with-unit-tests/my_module.services.yml b/docs/step5-wrapping-up-with-unit-tests/my_module.services.yml similarity index 100% rename from step5-wrapping-up-with-unit-tests/my_module.services.yml rename to docs/step5-wrapping-up-with-unit-tests/my_module.services.yml diff --git a/step5-wrapping-up-with-unit-tests/src/Controller/BlogPageController.php b/docs/step5-wrapping-up-with-unit-tests/src/Controller/BlogPageController.php similarity index 100% rename from step5-wrapping-up-with-unit-tests/src/Controller/BlogPageController.php rename to docs/step5-wrapping-up-with-unit-tests/src/Controller/BlogPageController.php diff --git a/step5-wrapping-up-with-unit-tests/src/Repository/ArticleRepository.php b/docs/step5-wrapping-up-with-unit-tests/src/Repository/ArticleRepository.php similarity index 100% rename from step5-wrapping-up-with-unit-tests/src/Repository/ArticleRepository.php rename to docs/step5-wrapping-up-with-unit-tests/src/Repository/ArticleRepository.php diff --git a/step5-wrapping-up-with-unit-tests/src/Wrapper/ArticleWrapper.php b/docs/step5-wrapping-up-with-unit-tests/src/Wrapper/ArticleWrapper.php similarity index 100% rename from step5-wrapping-up-with-unit-tests/src/Wrapper/ArticleWrapper.php rename to docs/step5-wrapping-up-with-unit-tests/src/Wrapper/ArticleWrapper.php diff --git a/step5-wrapping-up-with-unit-tests/tests/src/Functional/BlogPageTest.php b/docs/step5-wrapping-up-with-unit-tests/tests/src/Functional/BlogPageTest.php similarity index 100% rename from step5-wrapping-up-with-unit-tests/tests/src/Functional/BlogPageTest.php rename to docs/step5-wrapping-up-with-unit-tests/tests/src/Functional/BlogPageTest.php diff --git a/step5-wrapping-up-with-unit-tests/tests/src/Functional/MyModuleTest.php b/docs/step5-wrapping-up-with-unit-tests/tests/src/Functional/MyModuleTest.php similarity index 100% rename from step5-wrapping-up-with-unit-tests/tests/src/Functional/MyModuleTest.php rename to docs/step5-wrapping-up-with-unit-tests/tests/src/Functional/MyModuleTest.php diff --git a/step5-wrapping-up-with-unit-tests/tests/src/Kernel/ArticleRepositoryTest.php b/docs/step5-wrapping-up-with-unit-tests/tests/src/Kernel/ArticleRepositoryTest.php similarity index 100% rename from step5-wrapping-up-with-unit-tests/tests/src/Kernel/ArticleRepositoryTest.php rename to docs/step5-wrapping-up-with-unit-tests/tests/src/Kernel/ArticleRepositoryTest.php diff --git a/step5-wrapping-up-with-unit-tests/tests/src/Unit/Wrapper/ArticleWrapperTest.php b/docs/step5-wrapping-up-with-unit-tests/tests/src/Unit/Wrapper/ArticleWrapperTest.php similarity index 100% rename from step5-wrapping-up-with-unit-tests/tests/src/Unit/Wrapper/ArticleWrapperTest.php rename to docs/step5-wrapping-up-with-unit-tests/tests/src/Unit/Wrapper/ArticleWrapperTest.php From 87437b684a29a44c1ca859e92b84ceca71d282bd Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Thu, 2 Oct 2025 08:13:01 +0100 Subject: [PATCH 75/77] Root commit for monorepo branch main From 8447b33ec87bd4ecf3c252a9b4b43e2adc4f14b6 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Thu, 2 Oct 2025 08:13:02 +0100 Subject: [PATCH 76/77] Move all files to code/ --- {.ddev => code/.ddev}/config.yaml | 0 {.github => code/.github}/workflows/run-tests.yml | 0 .gitignore => code/.gitignore | 0 {.idea => code/.idea}/inspectionProfiles/Project_Default.xml | 0 {.idea => code/.idea}/misc.xml | 0 {.idea => code/.idea}/modules.xml | 0 {.idea => code/.idea}/php-test-framework.xml | 0 {.idea => code/.idea}/php.xml | 0 {.idea => code/.idea}/vcs.xml | 0 {.idea => code/.idea}/workshop-drupal-automated-testing-code.iml | 0 README.md => code/README.md | 0 composer.json => code/composer.json | 0 composer.lock => code/composer.lock | 0 {config => code/config}/.gitkeep | 0 phpunit.xml.dist => code/phpunit.xml.dist | 0 {web => code/web}/modules/custom/my_module/my_module.info.yml | 0 {web => code/web}/modules/custom/my_module/my_module.routing.yml | 0 {web => code/web}/modules/custom/my_module/my_module.services.yml | 0 .../custom/my_module/src/Controller/BlogPageController.php | 0 {web => code/web}/modules/custom/my_module/src/Entity/Post.php | 0 .../modules/custom/my_module/src/Repository/ArticleRepository.php | 0 .../custom/my_module/tests/src/Functional/BlogPageTest.php | 0 .../custom/my_module/tests/src/Functional/MyModuleTest.php | 0 .../custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php | 0 .../modules/custom/my_module/tests/src/Unit/Entity/PostTest.php | 0 {web => code/web}/sites/default/settings.php | 0 workspace.yml => code/workspace.yml | 0 27 files changed, 0 insertions(+), 0 deletions(-) rename {.ddev => code/.ddev}/config.yaml (100%) rename {.github => code/.github}/workflows/run-tests.yml (100%) rename .gitignore => code/.gitignore (100%) rename {.idea => code/.idea}/inspectionProfiles/Project_Default.xml (100%) rename {.idea => code/.idea}/misc.xml (100%) rename {.idea => code/.idea}/modules.xml (100%) rename {.idea => code/.idea}/php-test-framework.xml (100%) rename {.idea => code/.idea}/php.xml (100%) rename {.idea => code/.idea}/vcs.xml (100%) rename {.idea => code/.idea}/workshop-drupal-automated-testing-code.iml (100%) rename README.md => code/README.md (100%) rename composer.json => code/composer.json (100%) rename composer.lock => code/composer.lock (100%) rename {config => code/config}/.gitkeep (100%) rename phpunit.xml.dist => code/phpunit.xml.dist (100%) rename {web => code/web}/modules/custom/my_module/my_module.info.yml (100%) rename {web => code/web}/modules/custom/my_module/my_module.routing.yml (100%) rename {web => code/web}/modules/custom/my_module/my_module.services.yml (100%) rename {web => code/web}/modules/custom/my_module/src/Controller/BlogPageController.php (100%) rename {web => code/web}/modules/custom/my_module/src/Entity/Post.php (100%) rename {web => code/web}/modules/custom/my_module/src/Repository/ArticleRepository.php (100%) rename {web => code/web}/modules/custom/my_module/tests/src/Functional/BlogPageTest.php (100%) rename {web => code/web}/modules/custom/my_module/tests/src/Functional/MyModuleTest.php (100%) rename {web => code/web}/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php (100%) rename {web => code/web}/modules/custom/my_module/tests/src/Unit/Entity/PostTest.php (100%) rename {web => code/web}/sites/default/settings.php (100%) rename workspace.yml => code/workspace.yml (100%) diff --git a/.ddev/config.yaml b/code/.ddev/config.yaml similarity index 100% rename from .ddev/config.yaml rename to code/.ddev/config.yaml diff --git a/.github/workflows/run-tests.yml b/code/.github/workflows/run-tests.yml similarity index 100% rename from .github/workflows/run-tests.yml rename to code/.github/workflows/run-tests.yml diff --git a/.gitignore b/code/.gitignore similarity index 100% rename from .gitignore rename to code/.gitignore diff --git a/.idea/inspectionProfiles/Project_Default.xml b/code/.idea/inspectionProfiles/Project_Default.xml similarity index 100% rename from .idea/inspectionProfiles/Project_Default.xml rename to code/.idea/inspectionProfiles/Project_Default.xml diff --git a/.idea/misc.xml b/code/.idea/misc.xml similarity index 100% rename from .idea/misc.xml rename to code/.idea/misc.xml diff --git a/.idea/modules.xml b/code/.idea/modules.xml similarity index 100% rename from .idea/modules.xml rename to code/.idea/modules.xml diff --git a/.idea/php-test-framework.xml b/code/.idea/php-test-framework.xml similarity index 100% rename from .idea/php-test-framework.xml rename to code/.idea/php-test-framework.xml diff --git a/.idea/php.xml b/code/.idea/php.xml similarity index 100% rename from .idea/php.xml rename to code/.idea/php.xml diff --git a/.idea/vcs.xml b/code/.idea/vcs.xml similarity index 100% rename from .idea/vcs.xml rename to code/.idea/vcs.xml diff --git a/.idea/workshop-drupal-automated-testing-code.iml b/code/.idea/workshop-drupal-automated-testing-code.iml similarity index 100% rename from .idea/workshop-drupal-automated-testing-code.iml rename to code/.idea/workshop-drupal-automated-testing-code.iml diff --git a/README.md b/code/README.md similarity index 100% rename from README.md rename to code/README.md diff --git a/composer.json b/code/composer.json similarity index 100% rename from composer.json rename to code/composer.json diff --git a/composer.lock b/code/composer.lock similarity index 100% rename from composer.lock rename to code/composer.lock diff --git a/config/.gitkeep b/code/config/.gitkeep similarity index 100% rename from config/.gitkeep rename to code/config/.gitkeep diff --git a/phpunit.xml.dist b/code/phpunit.xml.dist similarity index 100% rename from phpunit.xml.dist rename to code/phpunit.xml.dist diff --git a/web/modules/custom/my_module/my_module.info.yml b/code/web/modules/custom/my_module/my_module.info.yml similarity index 100% rename from web/modules/custom/my_module/my_module.info.yml rename to code/web/modules/custom/my_module/my_module.info.yml diff --git a/web/modules/custom/my_module/my_module.routing.yml b/code/web/modules/custom/my_module/my_module.routing.yml similarity index 100% rename from web/modules/custom/my_module/my_module.routing.yml rename to code/web/modules/custom/my_module/my_module.routing.yml diff --git a/web/modules/custom/my_module/my_module.services.yml b/code/web/modules/custom/my_module/my_module.services.yml similarity index 100% rename from web/modules/custom/my_module/my_module.services.yml rename to code/web/modules/custom/my_module/my_module.services.yml diff --git a/web/modules/custom/my_module/src/Controller/BlogPageController.php b/code/web/modules/custom/my_module/src/Controller/BlogPageController.php similarity index 100% rename from web/modules/custom/my_module/src/Controller/BlogPageController.php rename to code/web/modules/custom/my_module/src/Controller/BlogPageController.php diff --git a/web/modules/custom/my_module/src/Entity/Post.php b/code/web/modules/custom/my_module/src/Entity/Post.php similarity index 100% rename from web/modules/custom/my_module/src/Entity/Post.php rename to code/web/modules/custom/my_module/src/Entity/Post.php diff --git a/web/modules/custom/my_module/src/Repository/ArticleRepository.php b/code/web/modules/custom/my_module/src/Repository/ArticleRepository.php similarity index 100% rename from web/modules/custom/my_module/src/Repository/ArticleRepository.php rename to code/web/modules/custom/my_module/src/Repository/ArticleRepository.php diff --git a/web/modules/custom/my_module/tests/src/Functional/BlogPageTest.php b/code/web/modules/custom/my_module/tests/src/Functional/BlogPageTest.php similarity index 100% rename from web/modules/custom/my_module/tests/src/Functional/BlogPageTest.php rename to code/web/modules/custom/my_module/tests/src/Functional/BlogPageTest.php diff --git a/web/modules/custom/my_module/tests/src/Functional/MyModuleTest.php b/code/web/modules/custom/my_module/tests/src/Functional/MyModuleTest.php similarity index 100% rename from web/modules/custom/my_module/tests/src/Functional/MyModuleTest.php rename to code/web/modules/custom/my_module/tests/src/Functional/MyModuleTest.php diff --git a/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php b/code/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php similarity index 100% rename from web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php rename to code/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php diff --git a/web/modules/custom/my_module/tests/src/Unit/Entity/PostTest.php b/code/web/modules/custom/my_module/tests/src/Unit/Entity/PostTest.php similarity index 100% rename from web/modules/custom/my_module/tests/src/Unit/Entity/PostTest.php rename to code/web/modules/custom/my_module/tests/src/Unit/Entity/PostTest.php diff --git a/web/sites/default/settings.php b/code/web/sites/default/settings.php similarity index 100% rename from web/sites/default/settings.php rename to code/web/sites/default/settings.php diff --git a/workspace.yml b/code/workspace.yml similarity index 100% rename from workspace.yml rename to code/workspace.yml From 086b4a8c52647b61010730a9dd29283b14687dd9 Mon Sep 17 00:00:00 2001 From: Oliver Davies Date: Thu, 2 Oct 2025 23:52:04 +0100 Subject: [PATCH 77/77] Move all files to workshop-drupal-automated-testing/drupalcamp-london-2020/ --- .../drupalcamp-london-2020/code}/.ddev/config.yaml | 0 .../code}/.github/workflows/run-tests.yml | 0 .../drupalcamp-london-2020/code}/.gitignore | 0 .../.idea/inspectionProfiles/Project_Default.xml | 0 .../drupalcamp-london-2020/code}/.idea/misc.xml | 0 .../drupalcamp-london-2020/code}/.idea/modules.xml | 0 .../code}/.idea/php-test-framework.xml | 0 .../drupalcamp-london-2020/code}/.idea/php.xml | 0 .../drupalcamp-london-2020/code}/.idea/vcs.xml | 0 .../workshop-drupal-automated-testing-code.iml | 0 .../drupalcamp-london-2020/code}/README.md | 0 .../drupalcamp-london-2020/code}/composer.json | 0 .../drupalcamp-london-2020/code}/composer.lock | 0 .../drupalcamp-london-2020/code}/config/.gitkeep | 0 .../drupalcamp-london-2020/code}/phpunit.xml.dist | 0 .../web/modules/custom/my_module/my_module.info.yml | 0 .../modules/custom/my_module/my_module.routing.yml | 0 .../modules/custom/my_module/my_module.services.yml | 0 .../my_module/src/Controller/BlogPageController.php | 0 .../modules/custom/my_module/src/Entity/Post.php | 0 .../my_module/src/Repository/ArticleRepository.php | 0 .../my_module/tests/src/Functional/BlogPageTest.php | 0 .../my_module/tests/src/Functional/MyModuleTest.php | 0 .../tests/src/Kernel/ArticleRepositoryTest.php | 0 .../my_module/tests/src/Unit/Entity/PostTest.php | 0 .../code}/web/sites/default/settings.php | 0 .../drupalcamp-london-2020/code}/workspace.yml | 0 .../drupalcamp-london-2020/docs}/.gitignore | 0 .../drupalcamp-london-2020/docs}/README.rst | 0 .../drupalcamp-london-2020/docs}/images/1.png | Bin .../drupalcamp-london-2020/docs}/images/2.png | Bin .../drupalcamp-london-2020/docs}/images/3.png | Bin .../docs}/step1-first-test/my_module.info.yml | 0 .../tests/src/Functional/MyModuleTest.php | 0 .../my_module.info.yml | 0 .../tests/src/Functional/MyModuleTest.php | 0 .../step3-building-a-blog-page/my_module.info.yml | 0 .../my_module.routing.yml | 0 .../src/Controller/BlogPageController.php | 0 .../tests/src/Functional/BlogPageTest.php | 0 .../tests/src/Functional/MyModuleTest.php | 0 .../my_module.info.yml | 0 .../my_module.routing.yml | 0 .../my_module.services.yml | 0 .../src/Controller/BlogPageController.php | 0 .../src/Repository/ArticleRepository.php | 0 .../tests/src/Functional/BlogPageTest.php | 0 .../tests/src/Functional/MyModuleTest.php | 0 .../tests/src/Kernel/ArticleRepositoryTest.php | 0 .../my_module.info.yml | 0 .../my_module.routing.yml | 0 .../my_module.services.yml | 0 .../src/Controller/BlogPageController.php | 0 .../src/Repository/ArticleRepository.php | 0 .../src/Wrapper/ArticleWrapper.php | 0 .../tests/src/Functional/BlogPageTest.php | 0 .../tests/src/Functional/MyModuleTest.php | 0 .../tests/src/Kernel/ArticleRepositoryTest.php | 0 .../tests/src/Unit/Wrapper/ArticleWrapperTest.php | 0 59 files changed, 0 insertions(+), 0 deletions(-) rename {code => workshop-drupal-automated-testing/drupalcamp-london-2020/code}/.ddev/config.yaml (100%) rename {code => workshop-drupal-automated-testing/drupalcamp-london-2020/code}/.github/workflows/run-tests.yml (100%) rename {code => workshop-drupal-automated-testing/drupalcamp-london-2020/code}/.gitignore (100%) rename {code => workshop-drupal-automated-testing/drupalcamp-london-2020/code}/.idea/inspectionProfiles/Project_Default.xml (100%) rename {code => workshop-drupal-automated-testing/drupalcamp-london-2020/code}/.idea/misc.xml (100%) rename {code => workshop-drupal-automated-testing/drupalcamp-london-2020/code}/.idea/modules.xml (100%) rename {code => workshop-drupal-automated-testing/drupalcamp-london-2020/code}/.idea/php-test-framework.xml (100%) rename {code => workshop-drupal-automated-testing/drupalcamp-london-2020/code}/.idea/php.xml (100%) rename {code => workshop-drupal-automated-testing/drupalcamp-london-2020/code}/.idea/vcs.xml (100%) rename {code => workshop-drupal-automated-testing/drupalcamp-london-2020/code}/.idea/workshop-drupal-automated-testing-code.iml (100%) rename {code => workshop-drupal-automated-testing/drupalcamp-london-2020/code}/README.md (100%) rename {code => workshop-drupal-automated-testing/drupalcamp-london-2020/code}/composer.json (100%) rename {code => workshop-drupal-automated-testing/drupalcamp-london-2020/code}/composer.lock (100%) rename {code => workshop-drupal-automated-testing/drupalcamp-london-2020/code}/config/.gitkeep (100%) rename {code => workshop-drupal-automated-testing/drupalcamp-london-2020/code}/phpunit.xml.dist (100%) rename {code => workshop-drupal-automated-testing/drupalcamp-london-2020/code}/web/modules/custom/my_module/my_module.info.yml (100%) rename {code => workshop-drupal-automated-testing/drupalcamp-london-2020/code}/web/modules/custom/my_module/my_module.routing.yml (100%) rename {code => workshop-drupal-automated-testing/drupalcamp-london-2020/code}/web/modules/custom/my_module/my_module.services.yml (100%) rename {code => workshop-drupal-automated-testing/drupalcamp-london-2020/code}/web/modules/custom/my_module/src/Controller/BlogPageController.php (100%) rename {code => workshop-drupal-automated-testing/drupalcamp-london-2020/code}/web/modules/custom/my_module/src/Entity/Post.php (100%) rename {code => workshop-drupal-automated-testing/drupalcamp-london-2020/code}/web/modules/custom/my_module/src/Repository/ArticleRepository.php (100%) rename {code => workshop-drupal-automated-testing/drupalcamp-london-2020/code}/web/modules/custom/my_module/tests/src/Functional/BlogPageTest.php (100%) rename {code => workshop-drupal-automated-testing/drupalcamp-london-2020/code}/web/modules/custom/my_module/tests/src/Functional/MyModuleTest.php (100%) rename {code => workshop-drupal-automated-testing/drupalcamp-london-2020/code}/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php (100%) rename {code => workshop-drupal-automated-testing/drupalcamp-london-2020/code}/web/modules/custom/my_module/tests/src/Unit/Entity/PostTest.php (100%) rename {code => workshop-drupal-automated-testing/drupalcamp-london-2020/code}/web/sites/default/settings.php (100%) rename {code => workshop-drupal-automated-testing/drupalcamp-london-2020/code}/workspace.yml (100%) rename {docs => workshop-drupal-automated-testing/drupalcamp-london-2020/docs}/.gitignore (100%) rename {docs => workshop-drupal-automated-testing/drupalcamp-london-2020/docs}/README.rst (100%) rename {docs => workshop-drupal-automated-testing/drupalcamp-london-2020/docs}/images/1.png (100%) rename {docs => workshop-drupal-automated-testing/drupalcamp-london-2020/docs}/images/2.png (100%) rename {docs => workshop-drupal-automated-testing/drupalcamp-london-2020/docs}/images/3.png (100%) rename {docs => workshop-drupal-automated-testing/drupalcamp-london-2020/docs}/step1-first-test/my_module.info.yml (100%) rename {docs => workshop-drupal-automated-testing/drupalcamp-london-2020/docs}/step1-first-test/tests/src/Functional/MyModuleTest.php (100%) rename {docs => workshop-drupal-automated-testing/drupalcamp-london-2020/docs}/step2-adding-more-test-methods/my_module.info.yml (100%) rename {docs => workshop-drupal-automated-testing/drupalcamp-london-2020/docs}/step2-adding-more-test-methods/tests/src/Functional/MyModuleTest.php (100%) rename {docs => workshop-drupal-automated-testing/drupalcamp-london-2020/docs}/step3-building-a-blog-page/my_module.info.yml (100%) rename {docs => workshop-drupal-automated-testing/drupalcamp-london-2020/docs}/step3-building-a-blog-page/my_module.routing.yml (100%) rename {docs => workshop-drupal-automated-testing/drupalcamp-london-2020/docs}/step3-building-a-blog-page/src/Controller/BlogPageController.php (100%) rename {docs => workshop-drupal-automated-testing/drupalcamp-london-2020/docs}/step3-building-a-blog-page/tests/src/Functional/BlogPageTest.php (100%) rename {docs => workshop-drupal-automated-testing/drupalcamp-london-2020/docs}/step3-building-a-blog-page/tests/src/Functional/MyModuleTest.php (100%) rename {docs => workshop-drupal-automated-testing/drupalcamp-london-2020/docs}/step4-adding-the-blog-repository/my_module.info.yml (100%) rename {docs => workshop-drupal-automated-testing/drupalcamp-london-2020/docs}/step4-adding-the-blog-repository/my_module.routing.yml (100%) rename {docs => workshop-drupal-automated-testing/drupalcamp-london-2020/docs}/step4-adding-the-blog-repository/my_module.services.yml (100%) rename {docs => workshop-drupal-automated-testing/drupalcamp-london-2020/docs}/step4-adding-the-blog-repository/src/Controller/BlogPageController.php (100%) rename {docs => workshop-drupal-automated-testing/drupalcamp-london-2020/docs}/step4-adding-the-blog-repository/src/Repository/ArticleRepository.php (100%) rename {docs => workshop-drupal-automated-testing/drupalcamp-london-2020/docs}/step4-adding-the-blog-repository/tests/src/Functional/BlogPageTest.php (100%) rename {docs => workshop-drupal-automated-testing/drupalcamp-london-2020/docs}/step4-adding-the-blog-repository/tests/src/Functional/MyModuleTest.php (100%) rename {docs => workshop-drupal-automated-testing/drupalcamp-london-2020/docs}/step4-adding-the-blog-repository/tests/src/Kernel/ArticleRepositoryTest.php (100%) rename {docs => workshop-drupal-automated-testing/drupalcamp-london-2020/docs}/step5-wrapping-up-with-unit-tests/my_module.info.yml (100%) rename {docs => workshop-drupal-automated-testing/drupalcamp-london-2020/docs}/step5-wrapping-up-with-unit-tests/my_module.routing.yml (100%) rename {docs => workshop-drupal-automated-testing/drupalcamp-london-2020/docs}/step5-wrapping-up-with-unit-tests/my_module.services.yml (100%) rename {docs => workshop-drupal-automated-testing/drupalcamp-london-2020/docs}/step5-wrapping-up-with-unit-tests/src/Controller/BlogPageController.php (100%) rename {docs => workshop-drupal-automated-testing/drupalcamp-london-2020/docs}/step5-wrapping-up-with-unit-tests/src/Repository/ArticleRepository.php (100%) rename {docs => workshop-drupal-automated-testing/drupalcamp-london-2020/docs}/step5-wrapping-up-with-unit-tests/src/Wrapper/ArticleWrapper.php (100%) rename {docs => workshop-drupal-automated-testing/drupalcamp-london-2020/docs}/step5-wrapping-up-with-unit-tests/tests/src/Functional/BlogPageTest.php (100%) rename {docs => workshop-drupal-automated-testing/drupalcamp-london-2020/docs}/step5-wrapping-up-with-unit-tests/tests/src/Functional/MyModuleTest.php (100%) rename {docs => workshop-drupal-automated-testing/drupalcamp-london-2020/docs}/step5-wrapping-up-with-unit-tests/tests/src/Kernel/ArticleRepositoryTest.php (100%) rename {docs => workshop-drupal-automated-testing/drupalcamp-london-2020/docs}/step5-wrapping-up-with-unit-tests/tests/src/Unit/Wrapper/ArticleWrapperTest.php (100%) diff --git a/code/.ddev/config.yaml b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/.ddev/config.yaml similarity index 100% rename from code/.ddev/config.yaml rename to workshop-drupal-automated-testing/drupalcamp-london-2020/code/.ddev/config.yaml diff --git a/code/.github/workflows/run-tests.yml b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/.github/workflows/run-tests.yml similarity index 100% rename from code/.github/workflows/run-tests.yml rename to workshop-drupal-automated-testing/drupalcamp-london-2020/code/.github/workflows/run-tests.yml diff --git a/code/.gitignore b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/.gitignore similarity index 100% rename from code/.gitignore rename to workshop-drupal-automated-testing/drupalcamp-london-2020/code/.gitignore diff --git a/code/.idea/inspectionProfiles/Project_Default.xml b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/.idea/inspectionProfiles/Project_Default.xml similarity index 100% rename from code/.idea/inspectionProfiles/Project_Default.xml rename to workshop-drupal-automated-testing/drupalcamp-london-2020/code/.idea/inspectionProfiles/Project_Default.xml diff --git a/code/.idea/misc.xml b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/.idea/misc.xml similarity index 100% rename from code/.idea/misc.xml rename to workshop-drupal-automated-testing/drupalcamp-london-2020/code/.idea/misc.xml diff --git a/code/.idea/modules.xml b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/.idea/modules.xml similarity index 100% rename from code/.idea/modules.xml rename to workshop-drupal-automated-testing/drupalcamp-london-2020/code/.idea/modules.xml diff --git a/code/.idea/php-test-framework.xml b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/.idea/php-test-framework.xml similarity index 100% rename from code/.idea/php-test-framework.xml rename to workshop-drupal-automated-testing/drupalcamp-london-2020/code/.idea/php-test-framework.xml diff --git a/code/.idea/php.xml b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/.idea/php.xml similarity index 100% rename from code/.idea/php.xml rename to workshop-drupal-automated-testing/drupalcamp-london-2020/code/.idea/php.xml diff --git a/code/.idea/vcs.xml b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/.idea/vcs.xml similarity index 100% rename from code/.idea/vcs.xml rename to workshop-drupal-automated-testing/drupalcamp-london-2020/code/.idea/vcs.xml diff --git a/code/.idea/workshop-drupal-automated-testing-code.iml b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/.idea/workshop-drupal-automated-testing-code.iml similarity index 100% rename from code/.idea/workshop-drupal-automated-testing-code.iml rename to workshop-drupal-automated-testing/drupalcamp-london-2020/code/.idea/workshop-drupal-automated-testing-code.iml diff --git a/code/README.md b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/README.md similarity index 100% rename from code/README.md rename to workshop-drupal-automated-testing/drupalcamp-london-2020/code/README.md diff --git a/code/composer.json b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/composer.json similarity index 100% rename from code/composer.json rename to workshop-drupal-automated-testing/drupalcamp-london-2020/code/composer.json diff --git a/code/composer.lock b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/composer.lock similarity index 100% rename from code/composer.lock rename to workshop-drupal-automated-testing/drupalcamp-london-2020/code/composer.lock diff --git a/code/config/.gitkeep b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/config/.gitkeep similarity index 100% rename from code/config/.gitkeep rename to workshop-drupal-automated-testing/drupalcamp-london-2020/code/config/.gitkeep diff --git a/code/phpunit.xml.dist b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/phpunit.xml.dist similarity index 100% rename from code/phpunit.xml.dist rename to workshop-drupal-automated-testing/drupalcamp-london-2020/code/phpunit.xml.dist diff --git a/code/web/modules/custom/my_module/my_module.info.yml b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/my_module.info.yml similarity index 100% rename from code/web/modules/custom/my_module/my_module.info.yml rename to workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/my_module.info.yml diff --git a/code/web/modules/custom/my_module/my_module.routing.yml b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/my_module.routing.yml similarity index 100% rename from code/web/modules/custom/my_module/my_module.routing.yml rename to workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/my_module.routing.yml diff --git a/code/web/modules/custom/my_module/my_module.services.yml b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/my_module.services.yml similarity index 100% rename from code/web/modules/custom/my_module/my_module.services.yml rename to workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/my_module.services.yml diff --git a/code/web/modules/custom/my_module/src/Controller/BlogPageController.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/src/Controller/BlogPageController.php similarity index 100% rename from code/web/modules/custom/my_module/src/Controller/BlogPageController.php rename to workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/src/Controller/BlogPageController.php diff --git a/code/web/modules/custom/my_module/src/Entity/Post.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/src/Entity/Post.php similarity index 100% rename from code/web/modules/custom/my_module/src/Entity/Post.php rename to workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/src/Entity/Post.php diff --git a/code/web/modules/custom/my_module/src/Repository/ArticleRepository.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/src/Repository/ArticleRepository.php similarity index 100% rename from code/web/modules/custom/my_module/src/Repository/ArticleRepository.php rename to workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/src/Repository/ArticleRepository.php diff --git a/code/web/modules/custom/my_module/tests/src/Functional/BlogPageTest.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/tests/src/Functional/BlogPageTest.php similarity index 100% rename from code/web/modules/custom/my_module/tests/src/Functional/BlogPageTest.php rename to workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/tests/src/Functional/BlogPageTest.php diff --git a/code/web/modules/custom/my_module/tests/src/Functional/MyModuleTest.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/tests/src/Functional/MyModuleTest.php similarity index 100% rename from code/web/modules/custom/my_module/tests/src/Functional/MyModuleTest.php rename to workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/tests/src/Functional/MyModuleTest.php diff --git a/code/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php similarity index 100% rename from code/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php rename to workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/tests/src/Kernel/ArticleRepositoryTest.php diff --git a/code/web/modules/custom/my_module/tests/src/Unit/Entity/PostTest.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/tests/src/Unit/Entity/PostTest.php similarity index 100% rename from code/web/modules/custom/my_module/tests/src/Unit/Entity/PostTest.php rename to workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/modules/custom/my_module/tests/src/Unit/Entity/PostTest.php diff --git a/code/web/sites/default/settings.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/sites/default/settings.php similarity index 100% rename from code/web/sites/default/settings.php rename to workshop-drupal-automated-testing/drupalcamp-london-2020/code/web/sites/default/settings.php diff --git a/code/workspace.yml b/workshop-drupal-automated-testing/drupalcamp-london-2020/code/workspace.yml similarity index 100% rename from code/workspace.yml rename to workshop-drupal-automated-testing/drupalcamp-london-2020/code/workspace.yml diff --git a/docs/.gitignore b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/.gitignore similarity index 100% rename from docs/.gitignore rename to workshop-drupal-automated-testing/drupalcamp-london-2020/docs/.gitignore diff --git a/docs/README.rst b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/README.rst similarity index 100% rename from docs/README.rst rename to workshop-drupal-automated-testing/drupalcamp-london-2020/docs/README.rst diff --git a/docs/images/1.png b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/images/1.png similarity index 100% rename from docs/images/1.png rename to workshop-drupal-automated-testing/drupalcamp-london-2020/docs/images/1.png diff --git a/docs/images/2.png b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/images/2.png similarity index 100% rename from docs/images/2.png rename to workshop-drupal-automated-testing/drupalcamp-london-2020/docs/images/2.png diff --git a/docs/images/3.png b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/images/3.png similarity index 100% rename from docs/images/3.png rename to workshop-drupal-automated-testing/drupalcamp-london-2020/docs/images/3.png diff --git a/docs/step1-first-test/my_module.info.yml b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step1-first-test/my_module.info.yml similarity index 100% rename from docs/step1-first-test/my_module.info.yml rename to workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step1-first-test/my_module.info.yml diff --git a/docs/step1-first-test/tests/src/Functional/MyModuleTest.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step1-first-test/tests/src/Functional/MyModuleTest.php similarity index 100% rename from docs/step1-first-test/tests/src/Functional/MyModuleTest.php rename to workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step1-first-test/tests/src/Functional/MyModuleTest.php diff --git a/docs/step2-adding-more-test-methods/my_module.info.yml b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step2-adding-more-test-methods/my_module.info.yml similarity index 100% rename from docs/step2-adding-more-test-methods/my_module.info.yml rename to workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step2-adding-more-test-methods/my_module.info.yml diff --git a/docs/step2-adding-more-test-methods/tests/src/Functional/MyModuleTest.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step2-adding-more-test-methods/tests/src/Functional/MyModuleTest.php similarity index 100% rename from docs/step2-adding-more-test-methods/tests/src/Functional/MyModuleTest.php rename to workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step2-adding-more-test-methods/tests/src/Functional/MyModuleTest.php diff --git a/docs/step3-building-a-blog-page/my_module.info.yml b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step3-building-a-blog-page/my_module.info.yml similarity index 100% rename from docs/step3-building-a-blog-page/my_module.info.yml rename to workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step3-building-a-blog-page/my_module.info.yml diff --git a/docs/step3-building-a-blog-page/my_module.routing.yml b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step3-building-a-blog-page/my_module.routing.yml similarity index 100% rename from docs/step3-building-a-blog-page/my_module.routing.yml rename to workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step3-building-a-blog-page/my_module.routing.yml diff --git a/docs/step3-building-a-blog-page/src/Controller/BlogPageController.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step3-building-a-blog-page/src/Controller/BlogPageController.php similarity index 100% rename from docs/step3-building-a-blog-page/src/Controller/BlogPageController.php rename to workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step3-building-a-blog-page/src/Controller/BlogPageController.php diff --git a/docs/step3-building-a-blog-page/tests/src/Functional/BlogPageTest.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step3-building-a-blog-page/tests/src/Functional/BlogPageTest.php similarity index 100% rename from docs/step3-building-a-blog-page/tests/src/Functional/BlogPageTest.php rename to workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step3-building-a-blog-page/tests/src/Functional/BlogPageTest.php diff --git a/docs/step3-building-a-blog-page/tests/src/Functional/MyModuleTest.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step3-building-a-blog-page/tests/src/Functional/MyModuleTest.php similarity index 100% rename from docs/step3-building-a-blog-page/tests/src/Functional/MyModuleTest.php rename to workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step3-building-a-blog-page/tests/src/Functional/MyModuleTest.php diff --git a/docs/step4-adding-the-blog-repository/my_module.info.yml b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step4-adding-the-blog-repository/my_module.info.yml similarity index 100% rename from docs/step4-adding-the-blog-repository/my_module.info.yml rename to workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step4-adding-the-blog-repository/my_module.info.yml diff --git a/docs/step4-adding-the-blog-repository/my_module.routing.yml b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step4-adding-the-blog-repository/my_module.routing.yml similarity index 100% rename from docs/step4-adding-the-blog-repository/my_module.routing.yml rename to workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step4-adding-the-blog-repository/my_module.routing.yml diff --git a/docs/step4-adding-the-blog-repository/my_module.services.yml b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step4-adding-the-blog-repository/my_module.services.yml similarity index 100% rename from docs/step4-adding-the-blog-repository/my_module.services.yml rename to workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step4-adding-the-blog-repository/my_module.services.yml diff --git a/docs/step4-adding-the-blog-repository/src/Controller/BlogPageController.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step4-adding-the-blog-repository/src/Controller/BlogPageController.php similarity index 100% rename from docs/step4-adding-the-blog-repository/src/Controller/BlogPageController.php rename to workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step4-adding-the-blog-repository/src/Controller/BlogPageController.php diff --git a/docs/step4-adding-the-blog-repository/src/Repository/ArticleRepository.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step4-adding-the-blog-repository/src/Repository/ArticleRepository.php similarity index 100% rename from docs/step4-adding-the-blog-repository/src/Repository/ArticleRepository.php rename to workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step4-adding-the-blog-repository/src/Repository/ArticleRepository.php diff --git a/docs/step4-adding-the-blog-repository/tests/src/Functional/BlogPageTest.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step4-adding-the-blog-repository/tests/src/Functional/BlogPageTest.php similarity index 100% rename from docs/step4-adding-the-blog-repository/tests/src/Functional/BlogPageTest.php rename to workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step4-adding-the-blog-repository/tests/src/Functional/BlogPageTest.php diff --git a/docs/step4-adding-the-blog-repository/tests/src/Functional/MyModuleTest.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step4-adding-the-blog-repository/tests/src/Functional/MyModuleTest.php similarity index 100% rename from docs/step4-adding-the-blog-repository/tests/src/Functional/MyModuleTest.php rename to workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step4-adding-the-blog-repository/tests/src/Functional/MyModuleTest.php diff --git a/docs/step4-adding-the-blog-repository/tests/src/Kernel/ArticleRepositoryTest.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step4-adding-the-blog-repository/tests/src/Kernel/ArticleRepositoryTest.php similarity index 100% rename from docs/step4-adding-the-blog-repository/tests/src/Kernel/ArticleRepositoryTest.php rename to workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step4-adding-the-blog-repository/tests/src/Kernel/ArticleRepositoryTest.php diff --git a/docs/step5-wrapping-up-with-unit-tests/my_module.info.yml b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/my_module.info.yml similarity index 100% rename from docs/step5-wrapping-up-with-unit-tests/my_module.info.yml rename to workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/my_module.info.yml diff --git a/docs/step5-wrapping-up-with-unit-tests/my_module.routing.yml b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/my_module.routing.yml similarity index 100% rename from docs/step5-wrapping-up-with-unit-tests/my_module.routing.yml rename to workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/my_module.routing.yml diff --git a/docs/step5-wrapping-up-with-unit-tests/my_module.services.yml b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/my_module.services.yml similarity index 100% rename from docs/step5-wrapping-up-with-unit-tests/my_module.services.yml rename to workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/my_module.services.yml diff --git a/docs/step5-wrapping-up-with-unit-tests/src/Controller/BlogPageController.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/src/Controller/BlogPageController.php similarity index 100% rename from docs/step5-wrapping-up-with-unit-tests/src/Controller/BlogPageController.php rename to workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/src/Controller/BlogPageController.php diff --git a/docs/step5-wrapping-up-with-unit-tests/src/Repository/ArticleRepository.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/src/Repository/ArticleRepository.php similarity index 100% rename from docs/step5-wrapping-up-with-unit-tests/src/Repository/ArticleRepository.php rename to workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/src/Repository/ArticleRepository.php diff --git a/docs/step5-wrapping-up-with-unit-tests/src/Wrapper/ArticleWrapper.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/src/Wrapper/ArticleWrapper.php similarity index 100% rename from docs/step5-wrapping-up-with-unit-tests/src/Wrapper/ArticleWrapper.php rename to workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/src/Wrapper/ArticleWrapper.php diff --git a/docs/step5-wrapping-up-with-unit-tests/tests/src/Functional/BlogPageTest.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/tests/src/Functional/BlogPageTest.php similarity index 100% rename from docs/step5-wrapping-up-with-unit-tests/tests/src/Functional/BlogPageTest.php rename to workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/tests/src/Functional/BlogPageTest.php diff --git a/docs/step5-wrapping-up-with-unit-tests/tests/src/Functional/MyModuleTest.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/tests/src/Functional/MyModuleTest.php similarity index 100% rename from docs/step5-wrapping-up-with-unit-tests/tests/src/Functional/MyModuleTest.php rename to workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/tests/src/Functional/MyModuleTest.php diff --git a/docs/step5-wrapping-up-with-unit-tests/tests/src/Kernel/ArticleRepositoryTest.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/tests/src/Kernel/ArticleRepositoryTest.php similarity index 100% rename from docs/step5-wrapping-up-with-unit-tests/tests/src/Kernel/ArticleRepositoryTest.php rename to workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/tests/src/Kernel/ArticleRepositoryTest.php diff --git a/docs/step5-wrapping-up-with-unit-tests/tests/src/Unit/Wrapper/ArticleWrapperTest.php b/workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/tests/src/Unit/Wrapper/ArticleWrapperTest.php similarity index 100% rename from docs/step5-wrapping-up-with-unit-tests/tests/src/Unit/Wrapper/ArticleWrapperTest.php rename to workshop-drupal-automated-testing/drupalcamp-london-2020/docs/step5-wrapping-up-with-unit-tests/tests/src/Unit/Wrapper/ArticleWrapperTest.php