From e635b66d362aa6df56bf92867bcd0efa2312393a Mon Sep 17 00:00:00 2001 From: Daniel Siepmann Date: Mon, 3 Jul 2023 10:08:33 +0200 Subject: [PATCH] Initialize project (#1) Provide first implementation with basic setup. --- .gitattributes | 11 ++ .github/workflows/ci.yaml | 144 ++++++++++++++++++ .gitignore | 4 + .php-cs-fixer.dist.php | 63 ++++++++ .../FormElement/FileCollectionElement.php | 97 ++++++++++++ Configuration/Form/Setup.yaml | 8 + README.md | 1 - README.rst | 62 ++++++++ Tests/Fixtures/BasicDatabase.php | 66 ++++++++ .../Fixtures/Fileadmin/Files/FirstResult.png | Bin 0 -> 42383 bytes .../Fixtures/Fileadmin/Files/SecondResult.png | Bin 0 -> 42383 bytes Tests/Fixtures/Rendering.typoscript | 5 + Tests/Fixtures/SingleFileDatabase.php | 41 +++++ Tests/Fixtures/Sites/default/config.yaml | 32 ++++ Tests/Fixtures/TwoFilesDatabase.php | 66 ++++++++ .../Configuration/Forms/Example.form.yaml | 34 +++++ .../ExampleCustomLabelAndValue.form.yaml | 36 +++++ .../Configuration/Forms/Setup.yaml | 14 ++ .../Configuration/TypoScript/Form.typoscript | 6 + .../composer.json | 16 ++ Tests/Functional/FormIntegrationTest.php | 122 +++++++++++++++ composer.json | 68 +++++++++ phpstan.neon | 6 + phpunit.xml.dist | 35 +++++ shell.nix | 91 +++++++++++ 25 files changed, 1027 insertions(+), 1 deletion(-) create mode 100644 .gitattributes create mode 100644 .github/workflows/ci.yaml create mode 100644 .gitignore create mode 100644 .php-cs-fixer.dist.php create mode 100644 Classes/Form/FormElement/FileCollectionElement.php create mode 100644 Configuration/Form/Setup.yaml delete mode 100644 README.md create mode 100644 README.rst create mode 100644 Tests/Fixtures/BasicDatabase.php create mode 100644 Tests/Fixtures/Fileadmin/Files/FirstResult.png create mode 100644 Tests/Fixtures/Fileadmin/Files/SecondResult.png create mode 100644 Tests/Fixtures/Rendering.typoscript create mode 100644 Tests/Fixtures/SingleFileDatabase.php create mode 100644 Tests/Fixtures/Sites/default/config.yaml create mode 100644 Tests/Fixtures/TwoFilesDatabase.php create mode 100644 Tests/Fixtures/form_file_collection_example/Configuration/Forms/Example.form.yaml create mode 100644 Tests/Fixtures/form_file_collection_example/Configuration/Forms/ExampleCustomLabelAndValue.form.yaml create mode 100644 Tests/Fixtures/form_file_collection_example/Configuration/Forms/Setup.yaml create mode 100644 Tests/Fixtures/form_file_collection_example/Configuration/TypoScript/Form.typoscript create mode 100644 Tests/Fixtures/form_file_collection_example/composer.json create mode 100644 Tests/Functional/FormIntegrationTest.php create mode 100644 composer.json create mode 100644 phpstan.neon create mode 100644 phpunit.xml.dist create mode 100644 shell.nix diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..2c1bae6 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,11 @@ +Tests export-ignore +.github export-ignore + +.gitattributes export-ignore +.gitignore export-ignore + +.php-cs-fixer.dist.php export-ignore +phpstan.neon export-ignore +phpunit.xml.dist export-ignore + +shell.nix export-ignore diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..eb468b6 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,144 @@ +name: CI + +on: + - pull_request + +jobs: + check-composer: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - uses: cachix/install-nix-action@v17 + with: + nix_path: nixpkgs=channel:nixos-unstable + + - name: Validate composer.json + run: nix-shell --pure --run project-validate-composer + + php-linting: + runs-on: ubuntu-latest + strategy: + matrix: + php-version: + - 8.0 + - 8.1 + - 8.2 + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Install PHP + uses: shivammathur/setup-php@v2 + with: + php-version: "${{ matrix.php-version }}" + coverage: none + tools: composer:v2 + + - name: PHP lint + run: "find *.php Classes Configuration Tests -name '*.php' -print0 | xargs -0 -n 1 -P 4 php -l" + + xml-linting: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - uses: cachix/install-nix-action@v17 + with: + nix_path: nixpkgs=channel:nixos-unstable + + - name: Validate XML + run: nix-shell --pure --run project-validate-xml + + coding-guideline: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - uses: cachix/install-nix-action@v17 + with: + nix_path: nixpkgs=channel:nixos-unstable + + - name: Check Coding Guideline + run: nix-shell --pure --run project-coding-guideline + + code-quality: + runs-on: ubuntu-latest + strategy: + matrix: + include: + - php-version: '8.0' + typo3-version: '^11.5' + - php-version: '8.1' + typo3-version: '^11.5' + - php-version: '8.2' + typo3-version: '^11.5' + - php-version: '8.1' + typo3-version: '^12.4' + - php-version: '8.2' + typo3-version: '^12.4' + steps: + - uses: actions/checkout@v3 + + - name: Install PHP + uses: shivammathur/setup-php@v2 + with: + php-version: "${{ matrix.php-version }}" + coverage: none + tools: composer:v2 + + - name: Install dependencies + run: composer req "typo3/cms-core:${{ matrix.typo3-version }}" --prefer-dist --no-progress --no-interaction + + - name: Code Quality (by PHPStan) + run: ./vendor/bin/phpstan analyse + + tests-mysql: + runs-on: ubuntu-latest + strategy: + matrix: + include: + - php-version: '8.0' + typo3-version: '^11.5' + - php-version: '8.1' + typo3-version: '^11.5' + - php-version: '8.2' + typo3-version: '^11.5' + - php-version: '8.1' + typo3-version: '^12.4' + - php-version: '8.2' + typo3-version: '^12.4' + steps: + - uses: actions/checkout@v3 + + - name: Install PHP + uses: shivammathur/setup-php@v2 + with: + php-version: "${{ matrix.php-version }}" + coverage: none + tools: composer:v2 + + - name: Setup MySQL + uses: mirromutth/mysql-action@v1.1 + with: + mysql version: '8' + mysql database: 'typo3' + mysql root password: 'root' + + - name: Wait for MySQL + run: | + while ! mysqladmin ping --host=127.0.0.1 --password=root --silent; do + sleep 1 + done + + - name: Install dependencies + run: composer req "typo3/cms-core:${{ matrix.typo3-version }}" --prefer-dist --no-progress --no-interaction + + - name: PHPUnit Tests + env: + typo3DatabaseDriver: "pdo_mysql" + typo3DatabaseName: "typo3" + typo3DatabaseHost: "127.0.0.1" + typo3DatabaseUsername: "root" + typo3DatabasePassword: "root" + run: ./vendor/bin/phpunit --testdox diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a7e2bc2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +/composer.lock +/.php-cs-fixer.cache +/.Build/ +/vendor/ diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php new file mode 100644 index 0000000..201cb6c --- /dev/null +++ b/.php-cs-fixer.dist.php @@ -0,0 +1,63 @@ +ignoreVCSIgnored(true) + ->in(realpath(__DIR__)); + +return (new \PhpCsFixer\Config()) + ->setRiskyAllowed(true) + ->setRules([ + '@DoctrineAnnotation' => true, + '@PSR2' => true, + 'array_syntax' => ['syntax' => 'short'], + 'blank_line_after_opening_tag' => true, + 'braces' => ['allow_single_line_closure' => true], + 'cast_spaces' => ['space' => 'none'], + 'compact_nullable_typehint' => true, + 'concat_space' => ['spacing' => 'one'], + 'declare_equal_normalize' => ['space' => 'none'], + 'dir_constant' => true, + 'function_to_constant' => ['functions' => ['get_called_class', 'get_class', 'get_class_this', 'php_sapi_name', 'phpversion', 'pi']], + 'function_typehint_space' => true, + 'lowercase_cast' => true, + 'method_argument_space' => ['on_multiline' => 'ensure_fully_multiline'], + 'modernize_strpos' => true, + 'modernize_types_casting' => true, + 'native_function_casing' => true, + 'new_with_braces' => true, + 'no_alias_functions' => true, + 'no_blank_lines_after_phpdoc' => true, + 'no_empty_phpdoc' => true, + 'no_empty_statement' => true, + 'no_extra_blank_lines' => true, + 'no_leading_import_slash' => true, + 'no_leading_namespace_whitespace' => true, + 'no_null_property_initialization' => true, + 'no_short_bool_cast' => true, + 'no_singleline_whitespace_before_semicolons' => true, + 'no_superfluous_elseif' => true, + 'no_trailing_comma_in_singleline_array' => true, + 'no_unneeded_control_parentheses' => true, + 'no_unused_imports' => true, + 'no_useless_else' => true, + 'no_whitespace_in_blank_line' => true, + 'ordered_imports' => true, + 'php_unit_construct' => ['assertions' => ['assertEquals', 'assertSame', 'assertNotEquals', 'assertNotSame']], + 'php_unit_mock_short_will_return' => true, + 'php_unit_test_case_static_method_calls' => ['call_type' => 'self'], + 'phpdoc_no_access' => true, + 'phpdoc_no_empty_return' => true, + 'phpdoc_no_package' => true, + 'phpdoc_scalar' => true, + 'phpdoc_trim' => true, + 'phpdoc_separation' => true, + 'phpdoc_types' => true, + 'phpdoc_types_order' => ['null_adjustment' => 'always_last', 'sort_algorithm' => 'none'], + 'return_type_declaration' => ['space_before' => 'none'], + 'single_quote' => true, + 'single_line_comment_style' => ['comment_types' => ['hash']], + 'single_trait_insert_per_statement' => true, + 'trailing_comma_in_multiline' => ['elements' => ['arrays']], + 'whitespace_after_comma_in_array' => true, + 'yoda_style' => ['equal' => false, 'identical' => false, 'less_and_greater' => false], + ]) + ->setFinder($finder); diff --git a/Classes/Form/FormElement/FileCollectionElement.php b/Classes/Form/FormElement/FileCollectionElement.php new file mode 100644 index 0000000..cff437a --- /dev/null +++ b/Classes/Form/FormElement/FileCollectionElement.php @@ -0,0 +1,97 @@ + + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +namespace WerkraumMedia\FormFileCollection\Form\FormElement; + +use TYPO3\CMS\Core\Resource\FileCollectionRepository; +use TYPO3\CMS\Core\Resource\FileInterface; +use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Form\Domain\Model\FormElements\AbstractFormElement; + +/** + * Elements are created with constructor arguments and don't have DI available. + */ +final class FileCollectionElement extends AbstractFormElement +{ + public function setProperty(string $key, $value): void + { + if ($key === 'fileCollection' && is_array($value)) { + $this->setProperty('options', $this->getOptions($value)); + return; + } + + parent::setProperty($key, $value); + } + + /** + * @param array $configuration + * + * @return array + */ + public function getOptions(array $configuration): array + { + $uid = (int)($configuration['uid'] ?? 0); + $collection = $this->getRepository()->findByUid($uid); + if ($collection === null) { + return []; + } + + if (method_exists($collection, 'loadContents')) { + $collection->loadContents(); + } + + $options = []; + foreach ($collection->getItems() as $file) { + if (!$file instanceof FileInterface) { + continue; + } + + $options = $this->addOption($configuration, $options, $file); + } + + return $options; + } + + /** + * @param array $configuration + * @param array $options + * + * @return array + */ + private function addOption( + array $configuration, + array $options, + FileInterface $file + ): array { + $value = $file->getProperty($configuration['valueProperty'] ?? 'identifier'); + $label = $file->getProperty($configuration['labelProperty'] ?? 'identifier'); + + $options[$value] = $label; + return $options; + } + + private function getRepository(): FileCollectionRepository + { + return GeneralUtility::makeInstance(FileCollectionRepository::class); + } +} diff --git a/Configuration/Form/Setup.yaml b/Configuration/Form/Setup.yaml new file mode 100644 index 0000000..efc15b5 --- /dev/null +++ b/Configuration/Form/Setup.yaml @@ -0,0 +1,8 @@ +TYPO3: + CMS: + Form: + prototypes: + standard: + formElementsDefinition: + FileCollection: + implementationClassName: WerkraumMedia\FormFileCollection\Form\FormElement\FileCollectionElement diff --git a/README.md b/README.md deleted file mode 100644 index 18ca8e8..0000000 --- a/README.md +++ /dev/null @@ -1 +0,0 @@ -# form_file_collection \ No newline at end of file diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..1d2c986 --- /dev/null +++ b/README.rst @@ -0,0 +1,62 @@ +==================================== +TYPO3 Extension Form File Collection +==================================== + +Adds new EXT:form element used to render a file collection allowing the visitor to choose files. + +Concept +======= + +The form element will fetch the configured file collection and assign proper options based on the contained files. +That allows using existing templates that allow to select a single or multiple options. + +EXT:form integration +==================== + +The provided Configuration needs to be loaded via TypoScript. +Use a free identifier: + +.. code:: plain + + plugin.tx_form.settings.yamlConfigurations { + 80 = EXT:form_file_collection/Configuration/Form/Setup.yaml + } + +This will register a new form element type ``FileCollection`` that can be used like this: + +.. code:: yaml + + - + type: FileCollection + identifier: file-collection-1 + label: 'File Collection' + properties: + fileCollection: + # UID of the sys_file_collection to use + uid: 1 + # Optional, default is identifier + # Defines the property to use as value for form element. + valueProperty: 'identifier' + # Optional, default is identifier + # Defines the property to use as label for form element. + labelProperty: 'identifier' + +No template is configured by default, choose one of the existing ones or provide your own: + +.. code:: yaml + + TYPO3: + CMS: + Form: + prototypes: + standard: + formElementsDefinition: + FileCollection: + renderingOptions: + # Allows to switch between different rendering like "Checkbox", "MultiCheckbox" or "RadioButton", etc. + templateName: 'MultiCheckbox' + +Example +------- + +A concrete example can be found within ``Tests/Fixtures/form_file_collection_example``. diff --git a/Tests/Fixtures/BasicDatabase.php b/Tests/Fixtures/BasicDatabase.php new file mode 100644 index 0000000..0c60934 --- /dev/null +++ b/Tests/Fixtures/BasicDatabase.php @@ -0,0 +1,66 @@ + [ + [ + 'uid' => 1, + 'pid' => 0, + 'slug' => '/', + 'title' => 'Page Title', + ], + [ + 'uid' => 2, + 'pid' => 1, + 'slug' => '/page-2', + 'title' => 'Page 2 Title', + ], + ], + 'tt_content' => [ + [ + 'uid' => 1, + 'pid' => 1, + 'header' => 'Form', + 'header_layout' => '0', + 'CType' => 'form_formframework', + 'pi_flexform' => ' + + + + + + EXT:form_file_collection_example/Configuration/Forms/Example.form.yaml + + + 0 + + + + + + ', + ], + [ + 'uid' => 2, + 'pid' => 2, + 'header' => 'Form', + 'header_layout' => '0', + 'CType' => 'form_formframework', + 'pi_flexform' => ' + + + + + + EXT:form_file_collection_example/Configuration/Forms/ExampleCustomLabelAndValue.form.yaml + + + 0 + + + + + + ', + ], + ], +]; diff --git a/Tests/Fixtures/Fileadmin/Files/FirstResult.png b/Tests/Fixtures/Fileadmin/Files/FirstResult.png new file mode 100644 index 0000000000000000000000000000000000000000..dc6266b898a8651b8b5bca0cee9b1033416b89bb GIT binary patch literal 42383 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 b>pVOubW>ZN3BQm)gFQ7=byZ4~tpfiG7d^pe literal 0 HcmV?d00001 diff --git a/Tests/Fixtures/Fileadmin/Files/SecondResult.png b/Tests/Fixtures/Fileadmin/Files/SecondResult.png new file mode 100644 index 0000000000000000000000000000000000000000..dc6266b898a8651b8b5bca0cee9b1033416b89bb GIT binary patch literal 42383 zcma%ibyS;8&@YrCg%;Y%hvF`U0!4xZ2`2%_oOdty9$YT?YN zRz^a?Yyn6}sLDx5kg2*jSpn=Vk&t8~l2g%DHFiGqcX~T{<)Dg(jb)HYwVV-r5)%lQ zmlemL{`yYSzBrt*>4T)?kMeEx_l8&w%;Bh5QJ;?pE!0%uy+N;%L4h(JN6>js#K^gX>7@QN}eo(%@?ay5XB=I< z(9}e@f40#dLROOKAIxiL1YkHDDoC&Cm{P*gkx+v-@tf^QN+sB(XSKUlu~cKFXA>cP zf4&<=o|c!F@4q!rhXj@Tse zsFmIkMTjVk3ztEEV<*>=S^8aZA@~!|6EkUE#im;|%&>j|^D{k;0aC1fT`6)Za3NSs zx}&qK)PVVh*^JoX345;Trl%wvTSNTGq`xya+v>KP03#dyBiUA8q&2q{W3q)<6Ql>d zmEWTdS`WV+J?pcAo{`B#VQ1|y8!w@R?U9m=VwtUP~Z#h0t8 z%!Vv~5HPBjq-P(#;431}TYczRnjU!(5FyBap4geEvcw(k=T4J4fgE7>2D}bk*Of-9 z6GjQRFr~3R`yk9RkHoh)loIJu@t-N~n2?Ilh zRt_l&nGiyY1+k#leK8#*uKKbe5c2)mK03M>GvBk=zz@!tnJB4U++$dd!C{}!(0(eg zJrfCF#|S!p{XSO={7uB-nV#6iH>~v+sGm$#sgjVWC4^*=rLem;FBN%`k}ReOYjQcZ+HIj0Y1=>pO#R z<{oWx6*E>dCv)^_QfEFQV(U=XKGe0h&O1%-o1jhYO*Dq+l{mZsguQDgU=PMNbP=M_ zZiVBJtHrCHtJ*8VE3rG;XX)Qne$YOD`}W1NZUJ%poGj;1=iuW^Hfc=?@ax6!RY~kG z{9hPPUROgrAbhe!l=O+ivLyL7>H+}flFUij7FjPzFBzJ|R|A#ns1_pp*@ns@@*RqY zwEl&~s!a5LNmP+ZH6iK}JKq05rxI4op){+^Z^*CU zS?kh%`hJ7_eOqLSd;q3Q!KaPygPzIA1mc{z*W)vF=XDZwQFUTknWgCr8r(+py654x zal7H*$T^~V-Fi#gWZR-C3%9S1^42iU9fO_zZP2#Kr2CZbWb@mpN&P3gl4+5ODE+EBt@_3K**U4X{yNg_E`bz* zcmYN?>|M9L=-u5Nv>i-$&|VhYw?GDtm{x!@P6_7mma9x$PHyd`?q*N<|5P=z-S!ovO66peIh%{y2O&=m!hk*B^C>uGr zDJ?&JpJRvP+Q!z3z`A9;uGj6iVox+6#d`Yl#qUhpL(434V@toGXV$A`@ut=AT=?4t zw>rhz^13!hR0Dp!lZp%db7=R73xqmNi+it45oQ_9FSBk*F9u5ZjJOpLl7w8r%b^bs7Z8*e-VROf#FMFg-?TNmyJG(mELH+ly^;oKt&jIi}7*# z$Xu;q)P`qi!IkLHtcGXN9Iw4PkW!^)L^T zHsZEbuBy74IvpQTKh#GhFXx+wvpD=!d~W=;^e^d3dSA=e%XtDL$t0Y~4OqSPfZ1d6 zx^zh!O&j~e_-{fYOMAb0#5ZZ>MuM{)OPbw+>qOz4jU1N~u$hAXRC-oirafcFW}k`E zEzdwt(W-bG>_Il3)3J)#fe+>v_m@Y~O|?|8o{+P1BB_@Z|Lhwejl z{OfM3@A^-eOANdk1RNF{Uo|TII2Zv|9n@0~QhQRP2yPzOuvjL2NbXo}w%AIp;kUd6 z#RKI)1A{$-1|Y(trG{HODgE99`Q^bvVF7QRgX^Z$+RHwXBj1=?_e;E^$5Y(LB5(8{ zY%ZO2?PTI##KXc@`>OjnmDxsqm1WbVER_%1l*RE=($mJpu9anF@RH>@Bwks#yrKlYW*APS_STW|2ea`8fS}j`nTBeymOLFEs~_P(yG=`?EXU zO@D@DMdjeJnqaoMbqp2l?OVnT6;(DF0a|xm>Nmg>^_!0Uhl!p155SuKlA`Mt#QC%_ zeCeX2+1J|9W04Ou@wi!FFl+#K9PL~L(Qb~kx5|MmFZnJ*53QH{5oDJ?XL{~rW@Mz| zl1Wm9$34~0TYHa`IA~{g{2m_;i_}y|v45Z&KafAH?S1~qxm#Pabu+pbx*w+e3LX2h zL-)$;xZrqWrmR~u`Eda;cXuAq+4i_g5*hc|C8H?C)3RaaFT%S;{h{y6s!HbQnjhQHrd(^Mb@vG8%f4`}2@QpHt0 z3b?UN=uWcEdTBGbrSkSlFza+GF;F0tzzNCh6d6N8cu>SGeO<+K@5Ru&gIAx?(XVf; z!!?Nai|Xi#5x@KhNd1ejkUEG1oN`Z2s@vDrma%i7OX%Mztq03go@3vmYnT-}s?_f7 z&;&k4`y&AYU)(O&N2NT4v=D%%uA8osqJX)R1Bb+B|Z zCG&8wcXSo-5T^L2hrm<)Z!;?e**{&}?1U+Fl~ln8qb8>eRrl9yc(0@Ju&ePHZ@ZTdjy8ee+PYSaBrLeNI zu(AG^>?c;CzpVnQ01r!hT}gn0rK9W97$W@KJVO8U|6i2<9`S#0>ist-Cok{+yyC$JffBE8pIBCzt4qRTIzZ1{7B>;c)MEPgkk)EIWkD>ls{RBq-rxL*RA2a~k zzXaIJf6ILQe@j`;f6H%H|CVIXe@mqQ7vcX~GSdGZGQdAROT0z$P@a|er1^ZTscNy_ z0(J3Om#muCS2xRREnCpntq;q^aDv67hs<-?+Y+Egm2K5+81U#w6k}TL^*r;%sObq}6waRu6bL0h{vfyL?iP_;9gjC+BX z0ISrg+)d6%8Ge8*W}X@$_9xvcCm+HEIwL{N__CbJ<3FngN~S)%T!ZW?>enZRWRpQ* zQ{__uSb=V3b*+jUEuuSqlq;|;KPYQu)qW<4iAY4vkxW3_WE_YLDjHZ+ek<0$(-q|;6A`5|)rsGw+_rvD;>{o1MzA1?n)BgUp>3{i-_!!(%yB|j! z)P9t*nR@@lb+2}FO1jx-PxOnKNl-_WSgOb}d|2A(>|mbO@eSGKeg>5H2xZsc)`l`R~iJ8g(nqyKH`NVk1>MUr!zBG2(A!-@A5f+RT<=&y@YL z$twXCMc&Y|2c5wguSa+mbVeGt76JUVcB#Z=p2QB(N$gZ-n`U-zOq=6L0{aV`k~bY4 z;7d1BqCbj+lCduvffvnXaMEd0qw4}K!BMD6>*!1}?g7*Lta{Fi9JP_kni`WCa%%xC zl%g|`(cYX4qK+$D>}fqNw|+Q~sJe8Po)z zuzbW=`9USUJ}RKdZyj;t^c|q*V|v2H-&r-lD@<=J!YcMn>=@?B#>| z0%bjJD!BtUnM6<52+DkAM>G!~65wHwHNojI3#he1;P&ePgZkwfo&u-45y6Skr3%0K zo`D-h|D-V<>@Km&JptbeJNCn0Q?z;(Mkz8k-hD`NYNIq_dEPk`t*-oB82FXzX>DY{ z2ODaW7rY9!i0>-*5ZFR4A~vn{1>k}FX+{sf?rt*XeDA~l&Z%pj+vwRWt46bH-^Wgl zJ%d+0E+^w~^^hki=$Yi_wLMX5Lpnr*of2T{hgSeABL;G)=!$;P!rbU{D;J1=YtPdO zYirl$5jXsEzqyVm$uSi+G7=@>8q|%?F5QwbAl!?vJgBd!9)(N>7Y-0BgT3>OScwm- zD(3b?1)A*TP&$2*u>IXj8*Kf)$oazW{&<+T>m*Ys*5mj$%6dELA1Z z%jNdM!^zvy6JTr?e6tL#Fl@fLI0l z1*li%{H7LQBvDt}0^9z5)}P&i;X!j#xiHf^K7|lF=z_jKC|?>`ue4j;LLz-o6MELg{tc+oqUxqO2+tt=q2yj^uS5ae$(H7hwH zXcsy<+&G~U$@59DzhgO#W!}Be;?WXKbKKvAltW<8jX_gSudf!hzzCS?od;YkKD(NQ z*(-bhBw?41y|d#tSlbvF=W`7-@(N)M^e*+Q@DePl?#fEmU;JUXWR{(s(SPA((aG$X zE$l@VUEgrhp2hRxnB&%_lIX@4vs=Nn2)O;|nLdN#f7Uys8WJN+y)JVdIOTZ7nz}&S zv#ZK&(JhBiaP)DWY951?FSJ^V=NRwJmVKYsIrT|O!!|L{Z^gLEoRPtif4Uj0{lSGQ zb|_|aM|?@K-+QLiorj?1C#zNNkqhy`BLQO>p-(iDq*yCD-o zg_m(vhu5uM2b`EtLGPW<)6;H>y+B;JlcO2$&x?hf&`FZ+3EZvfVs+BD zMsF04*^R8qbol^45UGUAcL}2B0myj?IpX*!~kV$Kq&M0pQ)-A`aJcTj8XlcfRmP~?4NUMW? zZRQ4nAMM5do!QD1Q;pvW-loS^PMyH+H!$w^X`2^u=W9gn*W3u7CC>_k=)x-RD*)O` zRhO2BV=K%`;kZqtk>^YAM1Pk7pUqz3P8v7EIM3bH7hh@iy@n~q=?N8x^9`1) z9qjdwYL;b+os}5rygsZ4=Ou6S;?nS2Gn}s9jc`9+F$_V_J3mIdre{D;*x-k8XXK21 zltK+8lW^B4QP9Pb-+8t9gWPQyBCxgeb_BS&P^6S`+Fi16+vfQrC_FVWSSFhOoavs+ z=b+DZ?u-&L-(Pu$e{C}eCv$=q24fvwP-WA;Sc}3-4&9|Qs{R5_JN_bRhre^;X6dye z1gkn*t?j47rl}C-g%ySN9&JAsM`A zSVX~xZ|SqlXM^cE!x6D|5YZk7f~PBFIpEf`pzJu)hf~gIKk2lsEELV%eMkQdCH&}i z89&x*bl8cq2z#W3c8Hh`nzZae>971g&9K$1VX(?-t4q%TGLgpaK7CGYEo|!#Gzo_+ z33VU@{)oKno0W=sz$v_4{_xOiv%^2S%-ydPz;%hS!BSCieL?=ViBZrY~VJE+?tyqT99GzYp zQFoDHHdmzIJJC*ANWyL2^=q;BN2n$tZE)oCNHsiRx$DC)z(ghC5DtmF3@dx^2@uBv zPIRh|w~6$s74SFO!qcZV3fU5{9;%FMx7+{DDA7|Y+Oo?z*3{0w9Y}evv{@R&`w0v^ z)6T96@h_+odvm&R(rciYEl^GFbS zh73J4O9t8MNbd!>10v^N<-NI=Gcqvy`rKMM9ffNroZB0}cR9bPJ_b*7xIpLc5E*Q8Qp*uzzGGVzy)_B%S|$L)j`V zQ;!*Oa4CnV;2b7;H&ld9d{MO?oISS@nq>8eoL3nbcaL&%BC(^$nrZ3(HD4Lu*5rd|J30AzCZi=)ZD@B9(WawdGTJ{nMV zH}ufN+ZxMKjK}A2#8^RasPwfNQ=^f{FW8&p9*#H>xhv+vK^%i0YKZ*aHQ$8MZFU*`y*Tsx#;27X?NST)CUKA1qzHYnWmGrauFk(g z@PEArfr!DM06;6w$8`R)`DgCA9fHhh)mSFCf%h}`d$V5(da_&lcobrbTRYb=ur1--U)`*V9#-&~is{-xXc*6&x|iGk+5UtP zUR?J5%mSN@dAC7-66^(AtTtSjM5^;RE4@Zt`IRIWsvHEGT`>TK9p*HSv#3Y1Wk7eM zmi^Qp1qHNMds|9E*>@|TW0}-z4^lr(aH|iC$94uT!vV*!!if>)ACDU%;4YuE{&n_a zp;H0K$G#3+!`~9nho0}rHS{%0Ij*vuTUo{Z0~6FOW>sk#Kh1z}Tvs54%YO$QIB8v8 zjRm(04s%D7^^ES@ce z5aOu&{A&24xrJ{9%?L_Q0WdU_dzxWYV`vc~M7st+zfN~>zZ!DxPU1uO#nyk~mA z%J+Qkd!+^_9IAMERg;5ix4qEu8q+LfNn*5dfAF+UzU|f8AP%U=ploB}SHd&no}&_b<*Ktn{V@>DU2_p+p@L zw?6~0c$;%L#EjCxCgf1kqn=SDyNzrCxT*jvSKgnqF*vGtu)| zGj!J4CG)){y%R7f;7_VN!mVrK5eWd4MyIvr8MHlHn8IFF}BLawrL^BKC3z0kmuRgV_V zOjw|pq{LWCRD?BKo-C%jMO9pc26(mAlI9RPJF^xSb%moz)enbx?SEr-P}b*H-xD|#P3w8Dvy!#^-!&VwxwXb$YzQ9`xJphZ0R1{;irr`49^$8KtKl^g@LjNU5KlN}>t zx2y@9H}dOiFd@xG|1d89E0kLRY~Ry(OXPcA!e-ZxI`z>p&dKAL+rd@wnH@lfIvD+H zfyuQ(ZEp7H%Mz8m%B+(IrN?s^QR6VHQTdBpx>G3)0ZMw~`=YUOT{NK&YvRCIiggJ& z#C(QkWSlbi7L!C_Bf|?xmz=|7P@jN!ptVv zbees{k>@-(!8NVbTqL;pxb$O@{k-Zo;Nc&~uyYoT3}8#*LdR~nEe;w(KX>yJFC!R= zeP&q0!N}t?Unu0%TEv@rPj!kX=Q?(;_*sOJJM9$LN|2C6c&+y7n1K2i4iyfc0!Qy3 zDi!ZHy*}be3slE|4QRhN^*h59Nx6YueKObu#P{)8RXD)ZLUEten44{!>K%VcaH14r zybhpGIC7Yfhd>{EKot{6Qo@CxOt4CbyB#c}NU?WfiI_a>ANJiq?;Sa)cdaqtZXQjs zs(tLwy|Z3|m5kiIDB%$81rH&Dt@qAf@ttRbg~QsqJN5+L`jLI6(!sjcj9z-v`PJT9 z6|wd5Ini}JpQ4wvC8c7ZuDSc995;8}=XMovMbEF7_8I4=R*jAV+&4ReA6k_uAbo7B zvnIRYR~BA(zXAg$Bi6y~X5oPWd8|d;lb^a&9=rU^@@KX9e4e7tSBn?SPWD7qT`oHn zuvlTNvk-`yE6|g*?WMOEHUWk#4%KJu=RWWpD&~%pU$(Y7K5aAlcWWA8-*+;PC>ak! z1?k(>z~H^_THq&@9VUCPr~fs#Fq^w^b@F?+x!>0%Quy)GSSEm z&l7PZU2bGq>n5V!;$98(Wm^Boo;9B8n@qv9UxxGDdwRQ|5N4gH^lXA+-#OH|8 zqNU4UWaV6~d+bA$0!jHfqQ{vRtuKMs?autNJ*4+>_BT#(Tv(+?Y6-tmtc(QKLLTZ~ z*ZhW;Cd(J-S8$^asC54EbihddjnH~!e3qn+^Sb_l#x|O_C5g{+LpGlw!9-C|8Am|# zodZJ7C@gQMH1|HVJ=u0n5g40qCo&Jm&BH~#xu5g+6{#G9CzSX6eaLHyp#1G|<<#S+VCv|pvRqI8jskeZpg7Wwb340qZ~`TBh`P(>v#guV1zk9%i?lDiSq zw&ZkvcuwP!waW&Bjpy~?ecHTMQ{;)TSnov;3e`X;wUdcS zGh_B`H*b4#Y{p3TnKaX{oRn*4Qa@era(HbnTOR4n&zwZ^(@+^IXl!^AZLyU|C~#rU zv#3XNfw-nClj~6MtA`EXLWK|5d%!{>>j40U$)dzSbv=Z=C%l)%tOpiS{XUBxL>COv za&nji)AHs-Wj`Ojky8p^^Lo2&BXPI}+s~%{<4yJyT~<(jWJ`fp$Cc$pbNO3L_&0NL z3PdqOm2ZF33g@AlMbMbrex*!e9i{@eUTedc?vgM$CMqy#4MyDIT0@NdU zKX=C8D@2Z4<=-?r>WOFO^PM;sq+SNSB~4GZC^q2Eb}Lkg-<$}9?H{STGq7H>dHjGh zvRCq(U6iqQ#C<6*_V)l_u$QdjJ(+YT+CApQ3EC~Xa-LF^>3oqrh46Xa9#4Yuc)Fgj za7Ve$(cyI;?&HkcEWtktIw`GU+&_!C%SlCVrRZpUIe&-(>25EbI>_J305Of)X&35Q zt{jgcPv1aV9}L4Yx_j-&l?tq=Z>5RrDT}*ZPu!~YnZM9)2JokF&Cd>;l!^ppu;vFP z3h$SjF^v9_n21lkqtL9;iyhMECyakylpH;x-KMW-4~Rui%1x9Ks|y-{w(+}hWR+|~ zs8X5sqB902Bv%wFZ-XR5hg^Zbe3S0+SF z%b!2IY<=&}xogWgZDlr~XuPc0F{x=_qWCe76f2>Fb;|w^mWz}KiojL1(6Q?wf!JHC zmQ5YdYS2bYBN>6`h!T5}~3?W5`S6C-_W1F)q>ARn^p z`{ly7;xoTI5}|$jfV`&%;`qAh;MUWsMi5WGZ&w`*2JmtJ3T)w-?NT<^1MW+zMbYF|=sGX+}@=Unk@kNv2Dk)kWw zlQ(B`K&C&sQX3n<6Az9@1q>V6MR5Q4^r2q>-c^6PWco537wXYSVn)Pp&lNB(0WKXUf>zsMR$TG}=wpF)E251Pw zyZ}LmXT!e)9bJ|?tdnz(D+k01)^hI~ZO2L0*+mx*8rRkZ=<>fENo)MvAap1Xu1o__ zy!c6o*VsVf$LKVjkXf5rL7C-e1L&;$=qSb3Ghp;~e@@=YQr$>7p;;5SVFFy(Jb zf;dNQlZPh#CRgi%Kc|P&)v{yJ^{6|?`sI~N^TicIr`xaoy;n#A$T0fI$dKRiNH3|_%=*& zC$7HcZgX1L?|1F+m93GR;FqGBy$-!ornLmCgJ0h@C|l0L!V7BGcRYHu>{6!Eh(SE? zJL%>*Rh*bhw_}T{f|zmam^w1 zqOZSI%KtRbn%`%4B>~V_iHIk;l4y)Cl0!O0kNIvHJtKF_ahTMfbIV5MR*eDbDpAIZDeOpo%ozGY+c;IG z;kABsG3(r$-#&La0-s!BglI0NdI-K^cMg@J+@3<{MYzwI0NXABb9RkoF|Oc`Zc7PK z*MaYigHv-x{DDURja!nGxXXr}^UP`Eh1qwA)zME?ziJC*^N$Lj#od}7m$nV$Wg`O5 zUnrm(jS^rT2`li{>SW2720~r8V6RgRs+Jjl(w6C0DVwW2uK+++v2sCk zy>-OSR~_B^QtPw4hUql%#^Q6zS@Q@@fr3Qkq99uAcc(cFa-0hS(Ofuq02;$dYg557 zk~a5g)^ymutYoaMuLV$RVR3HE;ADXH2&ZN;MI~Q>dlep=RKI3BM9wHT3oy8q=$k^p z>}DU_19~txMm-jzmgNYDBq@quBU% zYqx#x1T;xQrCF-j-F(Qay@%-LbqXh=3!9P8$E=*_$5ylLz*5-PSt z6-+luls>m)amP)yMGg4(=-NX&1gEAqh)p)@&GpHJn>oj3*fur^x{xaPyft-hAYr+{ z+_u>e0T~@Vud^`q<8G|4ZEvVhsP$xzC<~&3Bwf22k^|V$7NkbpOc)NCEq+I@oQe@ z!OD4rMn974zV}~4&!ZIH0;U<&xN`1m0 zyl>^SWEi2EfA|0&PT#jakL{X2=P&l6M?yO8g)Kip_yTAnrl zY&r#dLemJ%xhtLM1-p_+GhXiB+Nx-unv(XF+SDkIiHSWNWpRAj^wewpES zT9o5+*Iu?%*u?ehhkmtLAWK6&A2Zm&@pMykupu7I*MP@hl8-Y{K#>BR60EW*`jKG! zH!^*1@{{ja#aYuisz z@j)xoj1yG<5_xVqF}4D)j6#hnkk#q{5|@wleq2$1fG<{#;!RxXZPE56k(^8-Ophg- zyLEPKFQ?(p@6YT!xKWZCF`>S6xKhTG*cR-#>{!Z-SNX_D9WT9tdLj&LUVc7Fa@USY z<2$eTk+VQrelxl_!OAaSF{O5_^5kZi`JAl)1>hV>eytU$CHBW`k?zs*&<|5>QN}uh zStdRFU6m%(P_R$lZkpIww6g0In~IENM_Raan_&D%>yjfpl+cx11W7LA^QfROP{`!H zkiv&Qm8f|U>Y{_t885MKktgigKY?%YiaQs#)&NQ)TXLfG6me$BKT~SH#np4BC&pt@+$33yCBtO z={qyvRG7jWd~_Y*G)z0(AhPhcEci$PRcrKuHhz&`@@ z!|%&>q}R}Y;8-i@FoC5s2-qO)#9N8AJoB?E+2@@1WUQ{O8FThD7cXj?vUH)A7lX;t z{e&p$B#lLd_bLti=bB8SpTJM4`hTAPgli%F-vF=wBs}4$j&W7%o70y$K-#eLV zh{z4w&XvHvy&foPBgo5nDS>^81PSRW0oZvkVzhH@7L#RVj|qDzjoqA9zMH+P*)`WcF{|xmgP!TL8i&zdhWoQt***oX7 zZaIigjcv|JU76SfhPaFstdV9-?_2o!8~xw={N9;1e0g+D>b{^H)A#G`2uTOMZl^rquVGq%<&P_OfzkwI#| zo;{)F{vzf84|@gIJN>c<*4>{jK?$3_B$UX=f5#$wTCpc*Hd}8uBKi18AtUq?fQs}N zq6P?kg2|9W->DF39j=N0ZTX8g<2+jj-tRm6JD77;w>8&*=LeG+LBzRr*ePM(tfV@s zGWV-0Sf0>dv?=wEmHUR7C3`Qb+)g#lPi^eXjWS3bJ$)_Bvjs~;J%;GFYkh|L-Yv&? zotGY_%T*SAoCs(X>~@X9F_t!p1L4E|R4H=`W-#h2@W6ppcB5H~I^~wyG1Dn!apXsg zEoOPc8x7~lc6-Zn+ya@i^fx1eRl6gYaVmF<4jX-ku&g^D@3vF}gT>)}h+~DLHTIE| zG^osO%tT(L#lTtC)#xvX2G8zRct=l|cTy=$Nef3Fc+@iYSp}zLd(V^dd_OZUa=}Pt z8SB>ayc5CK0)igB+bQ;~%pylbDcE|~aXS3P@=)J&#>~mDbpTxr9A?5w7>m)(K!Vko zYuK)gyQM7XS(Qd2ms<*sLQmW7X)mdWJMPmKK3+keeFVDTZajFWpqYjO?HolN27t4U?Xv0Se|ix){w zGEXV-lGxMPRA1wRSL#b(^GXYHS1D3@5WuuEwM^PY#dd#G<%(6*_h+Z-{2Nx#-}zk$HrOLAoF8=7^oQ$9T$*x_JL-5h@Y5jNkq_O##{B zsW&%qiX%>jaDs}kzVn|W79IfYxm)Gyk0u?(3ybi>-6@39;8e=}ma^TE3V%km>yRk$ zYyXX&<23$KSUGGtzpcMS&gV5dMojjP4 zjJ>Fq%5*>EV7Oi2!qPRfIwEfn`k?qN4W_m9d)$K$09;pdyY6{-lRiraC(zGt0Cp%> zl`=74XDr;~Duc5%0Uwmp{Lkgy&@|$25qFr^cgRq*+Xev$WXYk8m2&$=|t zg7=J24_mf{EY?PNGX)*#FD4Qm?TNS=FX(PAc?~NUauP7lG^qTzWdL!3@Tc&0^2K;Y z^qXO&n`jLO$)cG=KVEt=RHLjb7=&Ho98@wjGVph91N_r>m+Zrx0Y|G} zF=ZJ$AZ*RA5(%A{xW#y;k1_4)UXEQ7n|+LBwXgH6fD#0z*O z?6O;LdC=`3b0VXN=*0WftWw^GMR4*#%r`oza6gYENP-inAui!$|U@V>OY8WT-dQOsGQzfh-;xYJ_rC&C5$Mh zEwr527acUU>RP;${V)pI11%e=ei$15>Crl>9>G|IGpxIlx0c3oQ}Dsft`(U=VT<-h zl&}U0a`4u09tg?^g}`>Zpu%c$g3&_eaFQMVkCpT~7A;7Kg+!+%DQ`l~45WX&4dsHM zLqe=PHaR3|OHE~$zTb=QjGOJ+DnUPZUb*-?4YQ&tgZEdxP!c$|+J}$cVvB?}Lu|he zfDS>#{^x1gae#r_Scnm5l!jR&XFFM8x@q*MjpDr!k|T*tm%;H7@)Q8Gz(- z%A`ZG3>d;o7=O;0ZExP|$=NlRt5|Z)V<+s^hvD66cCrK*7-mHHlGe!&BWgrR@kOX?O?VEU1dxaNb>*tb zY5`)pB;g^V&B=*1>2@T0W-q6Em}LCSg0`w5^xYq}AyxBUtGj7VUJrchggS5hqSq=5 z^81c0?)hAN-UHOO4{8>+_zj~WO#Cv7*q#K66<;ACLP=aES5FABIx*Chdsgf-++eB8 zN;L;#3z>KT;)1nnq4Cb}95og9=_;6gLS?R*e~7ox=$w2j!uerf7f-VwEn44Sxkg;m z32G*PZ*U=)pDwGed!Y5z!k;&fA+#%2s+rZEm!4({+Sl!#oDa0i)nzQmGe3D2De?;S zzHOdYTRp9%+2OBlHCI3kt>V;rVnxof>7j0Zv6l^lvn#e&+fAdfVNLjKKNPsl zt^S!kvHN%(h{;mMfB`%&#W3A@t!TlNLfbJ7d3^dV(>6Ca%r?(V)5m39|FRSut9yxN zBFRaLLl4a#D0%wZD_`QWgq`X$8@e5;B>n^V`WRTmx(^E=GkZ~jnDT6DWic`qwB7S- z=kj;P*IBI%NhXHM7*!2Rul(q(O0miwO25_7VR}1V2@w8n znJzhT-PQr-%gW=(1O4Q#4a&bZ#Q+>m^R&Gnm#A0;Db&{DuSFI0({3PF^+eV7sf2TZ zt}^c54_;Z+yrE|eogo<18GDe@)~4D92Z za*I5vwkgbg5c}Of{QO0`Yp$NLfqFSU#qgA*T=7TIB84`llZXe0(D+uN6c(Nc3Ox6A zWgTjL@J4xyY^eoma(}}6@i!LnrqR1W!r!aRAjLnr$j3&-MRCj zPCnS3BvfQOW8zM^_KpZ}7{PnCz!k4_2m^0tfX$BkWnDk(dey<~wGC%?{P%hC*h$u+gPZ4OY)n_)!yv+XtqcE@SC<5aPonk?$S_h{^+*qAcbk4 z8z6R?Qqav5YAN1DU$rzi)#olb37sEI*WLE}!_P>5+h(Xy$@R%ONxYZIiz0nWma%O3 zVkB7&{(#!P6mBtF1g-j3T0oN+HM_2s7fWUV#%bg0tVn4=oO z?Dfifdd-0$nEb+44~ZYuZJt{}UXa|#pJmTxxcVTUp>!b=<`$&OkFue?nOi=Rroe#j z7d?Hz2AqRV^0hxvSviD9!3gVjow)eJxHOuFBHPmx!2N%A+8RJN9Ve3`{5MZZzPm+3 zxhk_*q1+_fNh;nE^1<3B*yI1~5U(umt`dBSCs(_dMgHAzVDy{Sb$BGZQ{A(T(?6yG zTsQ(Xrs&Vmps=lhjK|5qfTutYfGx>H@S-8*E4>uw+H@?OV0^odGQZ@N;vQqw>g<5} zBUWIWO-WOH^uD14S2-6a?^eR5U;eDML=qPv3No?X>cqI467PhS$Xg|<-23&>`v&46y69|1hPRMr%Z03IN}(E+b&PSh5E!7K=Vvw&01$F9P)Qm5s!BT6?l1wF?@O8b)-MLKKl+xWCw*w#rxN;7Sh~0lWwL0OGEtnuf z?p+I!Oyo^yG?RsSTy&<>A}of(KLVW3Oj%59UErxJ2tOiSHgY|C|D8D`E75a_Hvo?b zGATLzFoD^!%g#!CR>TTaGKFB38Wcgl)vTupg24l$PTldr+2l~Sx5wY-QG8dg4a0m= zxsFhkwuv37M>wtN`6?)!{|{kr9o5zry^HpoDy5VH#jUtQApwfFxKo^<#R9?Ir7eZx zE+trT*Wm6RD8Y(*aEIXV0_S(%cw^jm$6fzHlD%Z_HP<)i{N}eOH!etM2%Bl}-pZEF zsdj{FK@BbnN3Hf^1$?95tDxm2AYf(HIaWPKUBjx}yGnQFajW)JT3YqDZ&`$kvBha@ zgMS5`<;rpbOS?CXSC>8Nr8HRZ4Cxs*@N&k^qtywiwO1{fwz1utbp0(IOG+~utJs?O zDU8L!0|e-KIinMbDIM3JgRdkc5CIFsYl24+5`}E#CjE@#I3ge9|LPRQAvj@k`M3u1 z)3&r4N0q3FU#M=APa*OlC@$lmoD3IrZW~@|s7t(<^GU=McBq~z)Mb+PNFn)`Wix0%sSlbLr53 zE<`Di>6_O>LK%&mXya0U`79eU>iBQT$bJ4(YHALCQJ1`e%vH6YOJZ9Pu65lFqNw*^L%0uH z4mmo<9hQkkmDc1Xg6Q!)+4`!I5&W5{&#n`v4dto!Hpzy6tlt~cXEdUWw419h54`7f zr!kTfY@o%dcM5-$R%H@-c20|%w)+(lXY8B3UEnPz-+E-5O0##cXy|3JL5@uX6`IaA ziKn@9d%w>}M*0^`L)GT~*-r0>6gsppT-5yvXbAr*#5An*gtdsUhMur(;1A9y+IhQc zM@Ctbb38AyyV^P2{94|cUuO5Bu;S;2z= z9Odq-FA9?^J;{|wBy(LvH!<;pb=W7LX;jjk^$5sIr6n)qhcxqQ>fQdJGFu7hCJ^We zQMuneaoBnBcaE@zr-1Iox||{M&dh?rirem;3X7A9**0TdI{d z=q0_jP219snujcJbHwPHkR1LV5I#$=lw zOM8?444SnJ^J~Z(l#|EZc{p9^F8m#p{o=-G@u_U#T{uDA8JF0c zCG;dE>hcyx7vuDXGS>N;~a6Gq{s5Io5+L^;Kp(?KCBatEKAfDr{=vdqQm1Q ziCQndsDB#;fVKAE>Z-e|%0isEN6e{J2a`x;@yGQhd~B_F2qLV)M~jD69;r!8sBl#pShA=Iuot^J zs76-~f~g(sEp>!FX~#cw{4LC&od}(OQ?x=v9%Ax8IS0yU@Hiz+pWuR(1}5?NO-4|W zv=kJJPCx_`V8Z%Q>4i^h!l~ZSnA2P_+F2Uc zbIi&A!^Gka=PORD5?RHHn{+X7)sFjr+XJIq(813Fng;C8~pxoux$QEUD| z#cdc_Yu7eQg&&kfjeNRB1^%)gf(}2;dxBs7CL+t->;1z6EzAtBUg?jEO_^DY2G1A; zQ2;b<1_L+gYi0dM2S0GU@$|1QCyr86ho0tDT7Pr!7`$e{k##{x6nyy+Tvy(F$2ayD zX0ni56_+%HIrQuWv|`4?f)P9ziTuT4{CCRAf)EI*@pY*$+U*PgMs$r{p#7gCf6?@I zId+H(vc5LDs|#vTwYB?EWnljRO^{XJ5kio(N$o0TVt?~!q|PT1{%;qf_Z`i9E6jKT z36~!bXUK$aVs(2`Fk6*)3{0(At6)rg*?6fclo&Fx+)2zLY9W)pm86}spF}&xRS)nW zpVMYD?rR20%|(HYBhHKB0+xW2giWD(6=S|4oM&BIKW|CerD6C%`@GU4g;rgtIfal zChQIk9?OWQN};Q_kW!g$=#=f&@=L$jVi!k@H>XI!ufJG-o%_<@c>kyH$%WqUX`~d{%^#-vqVoMG3`p5(0YnRsm1*A{!%1+GDicLoRUxHq=tjL z_!C3YJsxaw>+>uSD}9eSb-9Uh>GPd))r@>>AVBs*4-g|<^Q6cu12g$DClGXP$g2Nl zFv{QK26MM2DwezAbN(iXY^0XmeyYIwFNz~Z65$VG*Uo&W)uw@retl8Hti2((0S}^m zDNad6xXC*!KdE7hz0;-M#;eu{<%Ef3^vNTL-X`ApJ}qPl5-pCcCXkMEYw%rmZ}O4g zrYL9e%o^9g40k=c{3F=_kQq%?rJwR**WM4wR*_7q+@gaw-k_EPPI!%yb@C1F{I>@pk=UP1ra0qL-sIBH(>ygMONt}?Z4Satg<`#os)XXCE~qG* z9`hE_yCpc?gx#=DF^VlslMf%!e%Up=WVoKeU(dM`VF^ED@$p<~k!qG(F@6xKI50)X zhy04?z=5k3Eq#M$5n$kN%syl=MxJVMonH^iz^BKNkW z>vo30B1cE<8E#5b27!v9gN^FKTHhNAp%C-Ac^u}TpF=!Rn z+SN_1yNJZdl?6<`qJsw?oq9f-Z!5g#;c!r<>1vYdtras=HPl|+uXOA4>?u113D&O6 z5p!B76M?F-kQoisM!SIO(Et2b)Ouk$-9Id%{5efjQM_TQNK8(^6pcRai7PX8!uy5j z#e#anXcd02nZJqqv}s_ZLMQd5fYBzdyHp|Bm4<9j*hJ@YxmHD9vrL`|yegtAL=saS zGO-c5Cy#vJbWKl zUx!{VZhpRV>{ohHMLby)Go+9pWNSYfKk5MFd{gg?KIGkHP2cL(uVhqL7Zs0nRQE6O zsW24>yJY=+OBci_s;?)k9yQ(tn=Zwon#kshUZxZ6EU=lv_>`WVIF>Q(6L{%k9<)d& zqjVj(-9WECem04g;`rwRtf9G@sXcS4?rGq#8wi%yFZ@mQTC{0RE5&ui1tbKP@}k_LW^{02_rhW)X~S3O47qIb?Z7`w&WJP zB9R!FAubo#NqC%{bCg5mU{!6hp>Yb?GBlZgwId@@@>?Q5=$F!8WfNv0v4Wi9T~s!R zk+#wRdX>)hd;ceLj;Vweml}gQ`QrJ<{$nU5Ix{|2+BFa%=eYevS+8%idwPB9 zQ%%hKr{iEID=`A4K7Jb$)%peBAag#0G}o2b_>?V|I$FMq93f~`D2TA)mMg+vjw+WHObq;kuxg4LBSOrsE?@fCZQ0mecu^TF(n$;} zmZNAuk@j2Oyh3wQch|gnuG^e^mmJYB#qSzSHD8cc@>bx|`b!Rh?78gDBgEh=s!ieM zi?NEq7s$5Co#mCe>C}ramQ0jET{j4r{m^)X>&`-&M%7;zrAFN}1O2o#9c_WSQVRA^ zOW%~_1#2Adi=FQ8QT#^>C&>Pz%L&u{U38++V3P0(AS^VM;OUU0rzg83xYT*C4(byQ zJX8I4>dSu$1aCmb$VaQ@mm|UJT+;@Dvp`&)%a@sNB#PcT)5KYH$%{vzgCsN-`Pk(} z&A21u(T3V>J3_E7V z6KZM_w*8W$7=#)sJp0%BJ@%x$<#g0bPX5viUja0py?~^Z$m;}+jb1(X1b;uB4!exc zMHt$c4$VGE5a4g#j_S^uNM&gfBE1Rx02vIY#V18i`VqR=CO?CLSZy$O$m6IaHNmRO z#yOwc2{3f(n2-rU$K-~!OUwt};$51zKrcNd3M9KT8Z#JpBj`fYoxj(A1o|d~O)o8d zM|A79)3rjDD=X4N0%#K1&aVYn>$WB9rd(atqYs= z5XNrY|X;6K?O z(5e#TWuIua84=Ua3?1O{6%Wo74{T+oK2XUZgb45gy$oJ8K-HL}P&#N|?d#V?yq#6jY?~Ya0;Y{1!eFg1siFmm(SJEbTc$;fpzjzq zKR{JvwVmHbGp&RLb==wZYTzdq(!v{0_e_rK%&X|)Wr=O&UvQP0T8N+0OPnkPK$i# z7bB-_t%Zs6qs_J@CRaD8-uPX9QaM7)pEOa|*;i}=QI^S)^kHlF|yTZ5Y|ISxgcHo5hJ{u{2B)NU)TJ?WM=+1};V8@;#_ z{j_I=eQ&Ak{^JZ< z?!xSs98G8=^BAiKS3$}MHbQHCGp?=rr4&Sv)Qv01(ffmuV7@Dqdwi@bQUL3|w*z!l zwOHm9Vn^>?JQD%H-a=Quy+{Sh7?_J$Agj= zTo#z%H1;1h6laNMRK>c`sXv#4 z8TN>?=InfRu4GQKjHpvh?#dcxT|pasJIhL=W)^74)J)+o*MBhD$|pHx|J*|-wBh2D z_XtQGwYsV3BOy2ME0KcYO$F-%d{g=R1uGx4h2Zr;M}xxGS_oW?=lU1P@hI4psX#j zyW!`v9_F)?d)gunfnrJ{L+r&VXu_ZEm}S_Wr)EZ4hKPq5ns2Qs0~?K)qT`-LT+^$Q z^^?kE)j{9nXz3b2jr-L2i<`N0n|lHCg;>HspJ)l;v}$Jg8LT%UsfnN+Tu=8Jtq6&# zFi75ANT$m3^VXh%@)Ltq>|^d!<0LHi=D*r{O02eKLjsZUw)TI1Hi-yJS#yn^%dpWA z0tQ_a7h)nxS95n+A3eIJLG1kc{D*3|uORP74ARZ<%du(tuhUmc+q@t9e@&;p@0a4m zl;J163Ip;rm?}T##5%oW`sdl>fLkr0k}H|xLH&rs02DplM1$VR(xe>Bj%(9#jG#h9 z4muEop&_uI+S{XfH0nZtb`;SujmEgrtQGcRtk(+_g=TI`#~N!$>Bi4^S7MJhp`*l> zE9F|9B>R&}=GEDW{UZOg{G2%KMptyS%P(457#*J1>wyq80-ve0!nLEg|XK1DA7w4KALyDi`AMNDUZXWKkVEWf0k=nyNUAJ86gwm*17-t3a?9j&B^*fBOA0Pr{{|*GdaJ50 zy`B8{F|I(Fmfeax?6Z$MrU_G;OBU6`; zqBD>nq-P~aT!nPA2j9}WTv2LgQ=5$RE#Q(Mm^vEj8z$U<08V04_=>``XWv04V&scV z>DkW-$p&mi5`;IR#zy@vV&=_c9F5;1@p&s z&WtO8drqBD`FuG07(c2JryS&P&6UVj&|>A_614t`LspzXj@YppZ)ANMt|>beo2gK) zmaet@v|IDrpc$DeT9J*(qPkrR&E4O0{YQmvOMvn>cdrtJp1dh?$l=0j+D$X#tIR*X zcqxbgRj3lBPp9$s_lTmjTkUKZMfmap6?{nWG{0&1B@bG_<gzFIB2Li>zF?&`-FNUlr5{Yox*%TJC~kaMtN*4$`LeDB&E$#ZJOdX}4;3#wO<5-9TlS3u`n706anL96y@zZNEJ~~V z_UWhCUbMpOTaXScujFqXr%d$eB^)2{m5k-UDa>q2zPP%OduAVB;r;7vw8{lV7V&>v z@dKUgizKx<`NqBB^xb#1IRYvPi^tG+1tGz-lS6c^ioQHnJhHGrRIMp}5AeY=-aOSjYA zU?X=&Q|_8L7R^0=aR@oKFar?)N}(Mi|1Fq*wpeK&XS4V`;gP&_0zw}dCh8g=xJ?dCv9vBu{=lhoULc~T#Wd7$dMWvXV~ll>8Ir^ zTWla5Zj_Bk;i=5Nf={Uwv!19&@R7FTt0&3*&L^ldgTZ4d4~^lpS?CA@*tn$dTa582 z!fNP+wEmtPL$`Zgu^Ef2z+xyG4pdRBj2YKhRXbWvei(ky zTgSrdaO?;Jkg|z$pqVhp{p|Q^M1E$UQ5<1qV+c6=3)}^FKz1Y3R{@G&a9eUSJt-L$ zeKbMl8D2R!{)ju4^eX7{S_b5vB;O%lRos&8Q?}G{G+y6X9ig~u*H)vBca<$gIZ~%h zQYp~!+TL?*IHCKoMy)*u)`ub&?rnzM-$F>Q9KZR}SG6GrRrWZyC+^$?CBm z=HPeGWhF>*80r#gCYRT8Z7X}cLO<{~oSF9u@F^bVbiK2$KPJhr&Rb#`HX(+#OlA&| zKv*sp${V^cpXOj=zK+gYzlb=6%@%ctG~#8>s$NhPPFD4VpX-Xur(`uA42>p+E5`vY z74v8KhuD5tFefoc{qZ)mE*%na?W~^msn68VGcE9@uhnlXM$28+L#AB+lut7Zj2(`X z9RFRmWv`B3;DBdw5-UPe%)klzXUD69l64b*GB&G@oiD}N0C5S?$le{bvLs1G_lr4% zeA@b`RJK4>iqbe`02g+AR1 zTOQweCv!STGDqm40Ic#NJq!Kgi@URfv&FvL62zqkEo0ChY6c+W`LQF|PU$N5hk5dt zDEwUp&SOv(XF3vlVDHBzXj-&XuGTQ6Ib?!Tl{MjFy(B{qS&zs(Tk3n7`FiCGWKSsh zgLZ|Ond)bB@nih)o?M-NVwqB0`1b29H+N%qU4vi z^O=z?N3$3juREJVY;5^6xpL=w1L{=wgVIyuYK zlytbYQh3o#9HrpdX^bN$B{|vWbou7QtkkiFlz^8q{5u7d>&M$zqEC}{$sS30L5sWM zhp}kj+3z4Z9$&mNJA}>0iic3dG?sM?$saO%C-<7ErBwaIMoOHHhgtZ}w5KrmjhPrw zdm*_V0mH_Xmn3m^X@$+`@GP3I{ktUcjNEMT(tgI1)k{%iwBSBzhW3m^G@wk%2Z;ia z+Te+7Os66bo|SENL)oFH0tEPAlyHtF#bhF1+Ymwcei?Tx!5*FEvVHExaETu0LY@?* zra*dx;<^>zyLlN(0ZPK$o~CkgWp~{pk>|QmbKVPp)xs^HD(7^N4$~LksmD5Eamkss zVS>4z4~F>t|Bi}==;S8oj0UJW23;k8JFUW42(`Y)I$XcQ?j?Fy&jJJH}>r4LfGLHPr3HG ztP4mP@F%F-+ax93bw9AfHWJ*F95~HTH%O6LOQpB7c7xbaT(oB+u7nA-@eLp|3?iJv z35mJYXJtNz5ROYJX)+4EK5>|$E5P@k~XVO=wFF&gbm7>AZ3oNW3buz zZ{Vm*ebi{#RNAVMu-XMoL|BI2shj5%iWYqXhz5u?I5bt(@O7{oAMqjN1(M?=4*aq} zRK?S#Hl{XT((4Vg`3^F1+#KD?KJ0*2S%LG;U~{*DOV!{+@58ejSz;xL6KN+=L%sechv;%>GfiTYboDv~;w?+VLphMci&# zt5ATTQ1eHqz%~5#Wp*x1yKTSl6h{WevVatQ!3H0Kxq2O*xcvb+dAZq7*zMWoR^l;E zjha$CMKf;D{`osNWdgYVdTO&Fi|_Xq=zZyRw$l5*Bw@Vr6_UC2>#`jm*g&J=s*+dO z_Y&DtSt0JW4ha)QV`?}NIB2P@BW`oEv}C&08%OB#lYp@g+KHIS&QHhDw-9~pTSbTu znvC)#L6V{lIJ((2;|Kl;uCW8}(@ecZmx!SOYY?A*1^1p^8K}VOZW%fvU z$_5D(zm&k6NWPx=1X-9oe%P&TCVnkPXx}xO3C0}~cIAX6^2W|6Z`!U@bS20awbu|o zePwgFpJq2t3R{Qo;QmR1YA}doOBKaOr~nP={>ag)n#~Fz@~H>x$Q89P*DHgS-C18BR>nXogq@A-4Wo0{yqA||x@kL%XNr4i>ZEEtq(yZO z3$Pdz{8iCCMTMy$m_5SQtr3)OrocJJT4lWrb&6xkbML{4wj8)ERt^aN$59wYxiIbi z`qOy$mEg$FZd2vbDj`i`E|=veamc9r^mhBt4wt8L+Sj_t~(Mgt67X zsb5#gb0$veS8D8e_9_h+$kS`rhAf%q+kC=iWP-Jr^!vVU;ui2UALy(nU+z|L($1ws z?n^2D*u8Y$irrRK5?W6dxlWK%zi#u1SdSc`%(C5u@L8mv4lQh`G?>hw1>KC+$4(oY z97mh!RHJMKurD2(EbFMeXPpOxk_Pfes;juJSNVKe9`>n^m5(`(Z{%4ufcGcA_Szkl zlbO!!g}#e!S<*1McTe+OA8(xA&*xq(&OIX{+S-5Z<&U{mtcIP~9QNyK&ze|UiUdIo z%M;42Ew_9eUS}$mMT)n3wy1EX98v78aO-$$jNkI&x2Uen1cZ&=Y+tUCYCY2DyytmS zjorqIubi!*GVfycx!!F^Qg^5rGBjK{L8NbnGDU>5gN zfoGnRuWu<{3S`NL)-T0^t6Xlnc*N^;D_n>&Cc+e_iZN@Hiq@?U+kOtE%XCjRzmqCs z-?g%xy@(m%NMBzFeJ|haW1U7L zhX$WtP~M%IO@ac1Zyoh_NSS8m)6Y4@bi7$y06EJ z4wR$a=w!3z1ec>kPbbwdbLL z2K{iCUQa78C4cmyOh8`^_T4th_s*LS2Xwp7v1c7pIwzatTpqjdjx_mpd8lKsX1JlW zT|2;}WYF)Y!R!b!`j6hTM~lUg$Q)LU;I5Zp1>8w+*;&AcyyixnrJkvFBn2pq5q7#1 z_z*Dt%Bu^_)-|`Yv-`VEs>+@Cp0(E+B%i&Tw63_IPke)ZZT53RB{ z8!iz%XC|nl;lH7&*-Fgb%)1f@Y;mZNJa)Ez;9{U*u4Qlg!S90d=Hv-49psH;Tn;^) zg0knr9M_-!TUMQ!>fl9HXYePE1QoNwPP2fXM&bRxgC72YWpA*vdnw~i6U#aG56W81 zEegppwnJ96tQy$F!4n{6=N_XOc>nC*gM+djO2QeHZUI3ao}I%(2~^!>m}@xp2pkh5 zYcA+bnjy@yk<8MZ9Z5Y+E!2z^%JCnIaEK9Z&9^tIHV#0p06fg=n9zbR$Mx@I|FtIU zZSQbUjME?14Is*^{Pg5+nng8Ts=UH6|FnZisF!TE7L-QPl63bs(V68oDOu7AVA^#r z#CjipMbe^*H7DRSG>Tp>l!7e8toO;ho5VXy^7+qeAlazh@D~-W`My~jE=4ik$vDc~ z4@=sbn3Wj3BRN~jJ3vZ??5w5{%Iw3otk$Nr*_!$z@D{h$uz2bBn+%)e$-m; zuB^m+=W_;-*MFt3h=IFhhD63;&5S&R4`SGJ9q{>DzLBXO%4^Reb_58JRAx+zUeCQ@flWy_Q z%U6K3qdz5jI&dok&Jt&{HsF{=o|=q*Wa`sT={QF8aBGWxW?}Uh31~^WL0xKJZf1knB?VJCXBhkI9c9HWeFw2Vw#+IlNnue1PyHv9p0Tu-1MevreAJqsJymJuZfje57vKOFl9`S%pt9R;7C!6h{{i-uqx(xZ zb%FD+H0ZVYkJ5B+3Ln~6fXwmo@^Ztm$kl(Wtgk%(Ln8j)GlT!9oFjVsFIG`aV!O~m z)*<;PYM&tYmqsJip~BOGeoJ?m+{BB(G$P8{PW_l9qH%KchiL!Sj@>=JHV6H>IfVqp z?dGd?+Qboq?+?_l`(JV(+Fx)Yw+&i8jPCR_5txE?voW4W8)K@U_N$qTymmPaxhH5{Q&SgYxivEqMEV)+hd;QzI*jn$jvd+7UWeui zBE4VWXM(=J6%5Qql}b#pQ3kVVHFC!`$nTdfCe4+;jNVPs%_Kq0yDNwk(&>L&G}f-p z_ki|?+m@h{y8GLOp2WFKAEuJ7LPY`$M=K#TJ9S8r@n@l~f`DIvOXJMt4Ra`hkh|-$f$*2NJpoDJJcE??;Nh4I`lE5b^;NlnSh zN2rb9uPgVK?|yW|??V%t^!-eTzUUCaKEk}01E7hi*;9e< z)RZ>#l_fkH6xJ*X;BKeo(wf&MkQf(eTf*z?9%Y1cx2Dr|?A%W)jM+&g`}@m(J?4N{ zs4)?A312176|PRK*r!JP_+Zm55`&YpzVT;gO~quLI{ghVF92`aJfpgqPEaSQ8aq>{ zsxFrsIT{^7Dbi@+nSxqu&M5scAf%4;CTJ_Hz~z_y&bAsT2$I#>-}WS*Zo8NVZK;! zFzbdZP6y6^2X*TVEu54}=ovo`OgYMY`YY>8rZi-UpYUzyO;^9@s#+8nzBt*mt_~g7 z`FH5?f4kmoCabQOw3}@6#j_AVJ@1w3GBI5_^{PXA{*hp4R`@X^yn+CMek;?%gt!rn z2_waBtn1A7%k`;wOZYwo@sq#woTdqpU6GP4Ey_%}z{_Qt|-C(CsG^nfDV$IzO1;3f{&%JY&0T z?dcDeb6y%!eX`!VR!{#qFrOIK@f<`{U5UGzH`XuOJK+?WX~Tv|F_T+8L~X*ka{K{G z_PTU?ej^h6%~8JJ`B09JdmRCdg8eA;KMy_L<{V<)QDNtrt@{xg52eOTK6Nx;G@8OR zkbpVz;T`dvS%dXlq>qUbKE%iSIIM z+<^60(gXNZ9mFx=iBm5Wgw{G%LLwho! zDOH3}kJz6p7^d|bjCs7}4pca6sIG-Ua#jW~J9#pyfm*Ikt=D2al`|r-Su_Vyay7+} zDy;~tk-g#9FPDK;3pgIuPQg>n=>13@SS1Hw8JHDpi2^YwKyUeyov$ZAhZIB>n=v`n z0iE~m{N0k_o8g&P?Uf50_!nOpd!g`H0IlA5<=8Ey0v^&0%rdpTTE;j2mns8;RVlMm z(ty&@!yKf0=DL?Zl6X?)tCym%zh$hIV#2|jYgtqMLrCbA?X27eV#jcA$mLJS(0?cD zyalA%#NH`N`wFpx*s(eTuR6HVNO(hoo39Ofj%d1am{(Z8Ci5FQeFWisiQq5}$Y23< z=<^i)o;N=ERm_*!yKR4vVcpd2Q+K*zI3>td$d}Of!X*2WM~g%u*uIp_va5;ecNFZ~ z#J7E1c!!^!%(VMuQKh%t^0$Pk&YA3j6IE+Ua!=EBf3>-2mk7Js`wiQGuzEc?sR|XC zyHwAbBHE)hf?QNHWQmdy%0LS8Ir{PX&Drp;HYGdE$E0EOUQud_TsK-g(aZtf07pP< z9bejEdR15^Pfu#(l6OZch3D2RGtFEVvRNgVL4d(rXH*qBlHHxucZ;cRU6l|bOhHMs zu-CZZn@=~eF^kE76|1LxXo-hCr*f(9Z#3s{#NV~yCmY1ev)|tMRU19N#kn}7%jh6v z=td1;waRmH@MVC+83Wa&R4oHKaIRcBmf-nS2u1=wp>AwE}S)4Q$NUjc}QtL(LzO~mGF!<4jlfReYDf2LA~dzl+YnzJu9P@T1= zGu_YW-PS6vnjI8U4v(nskLA_|R=9QM)A_|g$w{+je8&?!Yqge1YIxLgA7Y1?$FE1f z`EL(}Ok!`cnA;|bD6w;1Uv3KT`toIyqrI{VC3wvQLg5EY6L8^5a6WZBqw)o?_80B52+urMLwP1+Q4vQ?hT>Cuu+Vm|e>qI{t{yIGSe&)%ri;nyJ_W&`G83fR%eZE&NcBao_v`cOMD~A zOeWSMxoE)b>e6^fsAXuLpm{(Q&&=kp+KHc|O}9?pkwAT3G#}NVfy;Y$xi?HDrn8!Xq2wMI zd2H(NLgFcWc?y`W#!lmY%8DQwkLf@=KYUNN%#tF`2b@rtcp)0u8U=~lc&b2OkFBG? z6`w^n0OxSE`xg_a?@8>=P|C%?ZEM_S>qh4_z`1a5FrvWr=5{;CdhDLmx-J17XPNCz zPR|+&#o)}8``t6)-ZkG{2EhLG%DrkZz;K8jK3it`NRWRml&>U^?^Sy3CyCjF3R%8Q zp$_&;^xXp!0uEfnGfgM{AsZcS!lD`XBSf)ouT^$I&#--NP+vGoeijz{u$qE*k|y`A zW#{+?KL4P`EFGP}ZIa0Vy))T9eOF^3j_;$I?QUwG%+XXU2m8UWFKC)Je->e&JL3^= zCk?CosOPv;$R-iLr=LD2gUlIVqLcsnQuHvR zK3&DMgX>GMYxq7 zoczvs6wl5_tyIw=^m7v|uudj9vl2FH2;#>yVb#ws@=P(d`57s4NyCL2*;g|LbBw1d zp@r`JS6pBgmo=MG2pTb$ssxiXbpN~cSZwl~+c{fs_(&w)p9c$T(-K$fp09B<&5ZT#65&`hb_}sRkE4@`c!8dv(b!uO+#{4s(Qb* z^7G{Os?|V7qk)B3>Nr?kO>~zC(z_yYPEUGR7**|3iEa~=JAU;D zU+Uc<2DcGKW;aj}K?!0o0ZrnAD2D)Na=p|cdvZ$XwY4gz5z2NimOB;(4gC3RFxleq z4T?s^i`R01KFdm4zH`z13`PQfUB!$~?z5d*O6wRSvdIo1} z^gNYxIja?e)<|-I2#mapWRK%b%dM7WV5(;5*DXy}hEYOA%2<<=nkCM%o8OCjL#zIE zQh0lhKZjC)GXWQ6Is41}FXknnKeJ0A?R&k~NJTx~xxOnkE&K~65l)$;&beq46217u zkxQ6>xMA8{y7luLjQS#eyp0e|ysb`^Z!N9Yo}7*!kwVSexwh+o=M6L0Cs`9U-88tf z>MmSB`-^FM@_tXp)YF%QwFVycWp}Ztkr7S`!{hVcv0sEb?OmVvd%#o_bbn+0BZq!5 zP5C$Yjj?07i4t}k`O?d6gw651DF~2m_w^WOLSKF^!KawWNvljI~P=bPjNPde&m z<{T%wZBX}Za^YjV%gaYko<6iDf8TBdJhK857s7;g%yI_$v-YS>{rDtxQSwz&;74pZ z&-Jzv%YORpnuw!=@}QY}s*0;?=&hK;&W9&pWiB{{bQS^#^SeeOGlT@q$mf;!T(9R`R;EU~1q< zy*|Z#ZkzSl56r8s?Wo}&V!8V{9KOLip6ZLijguOTpV4Xgn_G?Fr~e7srj<^mDL{5R zSVO2Zr}qW1y3HbqB_L30qD~fF;xwxQFIhjf7Xr3q+1D=!ou(nVG}XHYI8|Htd{1U) zXk_|F2188k`|k$Sp#-ZIgY)&7sI^c&0*-&!cyN|#-{AI38evpTnke#Mj@E+w|yCmUaM- zesG8Q{!{%}dYR8}*L1r9r>SF30X=_BQkA_9O1)Gxn%z5!AXs*N`VpF2;!;6!`1UanB)?Gnp`5K79MSS^A3mJWkt}UicQX&II#w1jrxg9WL*ZPUcXz!S>R0#;X-=oveISqht-P zrVaPqE34ptOE8X#CyUr6Z%(i1W89^KiGY9nx?SBwb?MJRZ?=n-7A2{d#c6y)01b0NEA>P zvsF5%pOy^?@?Y42-n{5Gv&d&s_+^aeWd$+4%I zasxc1>l3SGoAl#CQ+u|6sG%+nz!=keo6ire81ijd^4z{t*Zw0U=4`KburXLx)Y#EkcH%_kD3_J`bMB|G=jj8qGW9O~I#FRjdw} zeEWr+xkWWfM_t~1(9_f&=GW(%UVf%3z$$rGYUB=hJqtF{2Eq0v6-x{IGnLUZtP-4P zok=^g+aT98+3~tq(k>yW)GgBqNDYp*8)UdE^$%YcgR|FaK`>rrTR+5Jkel)6kuVxO zmwT0P{K5I>4N69pwb;l0vX5YUbQNv(XBRkVLakk*4Vo}ooiC+>$@ z|Mb&*f6JhGf3+gb^NSwZ4>alY`!dj1AF3|=TV~xwJ=2A^G|-}{nwb)c8kcYgu*w7Mm89QK#W zZv2qc|IylGc}R|)>#|q;9*o3(`yht+oAd#=)6Sg+Qo|nwfUrZEb@TBZY%z zF;khV2W* zEw#&OC);W6f9krg9ps-mfkD3$jwAkkLGp*G{`Zy2-%kJAg@4)R4`cn`7el|O`}ZRM zv@30U;+KoI`?dI``u|^L{C^Yqhv8{0@;mSUF5~z2zf=DoIsdKJe?;EI?_Y}ZK zW!bCzys=f;gL~qiZ+tGCb*ybYE}|L(Q{_5jygZvAop017;y&pG_8CLkK1MPKSNfL% z7H6&B2}!q2gn5w3<6bk?)`I%W!mi0o71>NXT_4hBXBgy!%->r9ufV2zB@;e?SlSz$ z1^{Esj%B^k=FDiDsg+9AcFjQU&O{QMkDkjzqM?QJkgIY}XpAhL;lajcYH?wvmq!;pjw3 z_^@)Gt;zh|+c6>;E7gWNvDeS=VW5P9819gIZ*vwiAcUdehK-H&8^*-#5G~IDsf#2z zB0qjvm})!x%vQ#(Xh|yf{Ts%Q`uYWiIt;WtF-V?QA{Wnj4yTtevnq55)-FSC41*zt zq1g2hjs=LQ8a@Be2-uQfhQChA|J2(rH} zQG>gyj$Lr(ktWWj))eI8N9bfTe8?(iw|rI8sKffXFGJN^3#p?Rc&lm_iqC{<0_I6E zMia!Q*SA-R?R!i3818i}9^nYQE9N+aGmnplNT)H^SdN8ha8eeXoCeUJmMQF9m9Kh94&bM;;?PcG zqLKJ+a2=%S+^=CMQrOI9X6*rN%ND{E1a38Q&M^$LOq%vEJHVNyCNsZ1t~Ek`8-1K( z2@4x39ojM~^a!0=s_Y~{2J#D z2XYNU#9d7~Uo)@+QEbVpB2_NQVgM4aF zsLEi-A6i=FCt=c1`J;5yvHoSuz)oCBjxAS%{ygg9CGGi*f_~0g2I_hgA8#xsDdk}_ zYm5t4mSxWq7bM;30N}V%+xkBqO@N5r7dC5eDUYX{{w5oKjX%sAEozM6Kj|n}I^=x% zNTK4am-e$xcI||AK))B@;+LZ@9!Xrcw>*I~IM1M}Rgh7bjvgVzhA&Z=CoA82CCt$o zgg(mdh*g;Vx$aRtX^uk7MlR9Ao51=HF$R_mHx!mUrF3L?NOtBr?=q|QREyp+qX=wT z!E`mYQe<(FG%sX$Y=Xe7K)&cB>GvpY2TzXzZm_K^YwpwcC{2f5CSt)9MjaPWW(x^? zVSaB!X&SicSgpPR28v#};NjRFr`*PG3=gS@g&5zNu0-dK>bJG@Xz;=d=%&5bo#iol zmtWhfzPeC712FUQ0pA>Z4%u=T!it0yCV;i?_peMJZ745zt{r7JT_tpLR@o2C^sx{j zpx)!5rKLo?fW=4a8BZ_k>Wqb^DzBSn&s_Nw(qEWe0$8}6d1U2r!Py&ZjFF#b9JTj( zZq>vKo9R|No8IhBuR8zcS~07+y)Z%TSn4~kl4zadvfLk+ALYSsgxPyKx}Rj+MbxTY zYKG(=H!;P+ z%~?GAIAhP$4vVuGih1J^QkN8g`BS;-p6M$8^e!``I7Iun&8!Jjxr3lC3CyNOwX1Y* zUeR?jHRfLF-&5f&EvaO}`gk4fF^s*eQ3>Hsum|dZnlOgX$#`bDg$9)utoO(_^1*VZ zFKjL1*&w0;*rG+>PU}Hl+cu>0rvw1K9Ux|)Fdg}+1f`=tVDLP9i25|gBJ}m(MaujU z?oyHD)nGoX6!A#$+#oWs;9*|U8s-%@6K|E?`H^E+JUnbojwztQeb;fGtjWgLMWzE? z?6W0@&GnqlsvEZJl!{tT8rhp21-(k_+XLrFNjaCZm8CuhRKcXxonYE^IRkvAx^rxr zJX%pIrnNE-3GgxX!tnMuHZxRR)@Ai8DdWtSCQY7!;?-gh8=yjU$&@8=gl4Z$916Cx zh}eqETUhb94Xe#r*e2TSS8?(|ZQg7_B%sdY0mN>{h51Uvgi63M23Pm3xLly62}^vQ zi&R^X)DDBd;yjDUi=n&K=5AH1_$~Jr=?=PXac!6K?U8#y_W}kSn7HXr_SK$RGA>@V z@3R}+jw?|*8}{=WzPE_$75OO}O^9d4MbRN&3*H1&R@f47y%`61b*zmxk{H@=N)W7BVk#0wivBdea@rB|23s`_hq5iqIa3*%wT8Ysc0a+4hT7gl1x7RVOFJE z>ef&`AVo%sw=&Ts>AnaA*WyIk2XVE$v+b5W3ol$U8h*3vVTJE5jwa>g035xO@mmq- z4acEbhbtaZhp_`0u$63oYeYy%h!<;dV9XP?q334IZna5Js06(oGR#w4srT046a+RM z@)4Dup80#F|eVi0kc&6@Uu|sqIUFc>oKC)yvkAAqLxLdHU znTg(~Yd|1H5u53D3ngmUpF$B@=?f^^CE#o!Q_!{daO_uwtQkioL8Rrf}* zD4+EK53po?#)Xqkc6%3hmP$EEB-?TsAV)Y7MkW}6` zMNx*9m|&zPK{J4R#yNrFJHU} zi|%PI;F}v<$M)oQroPL0bhKsSjk$#8j&nO}eucJGjQ|8)mH%q%D%{8P1T=A|j*VjT zq86r9&|g%oyOsVz9%QP?0-C%Fa`wJyJ2dVZLAAHpQ)%oIYMW(jpP;ge*Vqnu-pRHA z`=BIo$cx4QYZU4%DR7s^{S%eBBRYt0~T^3(a!1PDaYeHc50;)Ep^#s zo)FuW!)G5{J3=s+M31Mp4tN*(&Dk6UCU9HFTld!??TvTV8)TV4-&oF44oPU6<9 zXf{lmbt_L`C3(+H!8dm64sMN|nlB?D5FzMoMmK#0p4V?Fc|QIgE`8SLRVZdmR`mD4 z5*iT%%BA+WX?C(Oo0;-KUV~POLbrF#)pMs;>4c%ICK|SeadrwH+I)l{6=J#swh2~+CkwO2{(;v}t#L{@8g#(1^|TkS}PsF|7+UCU&L^|) zi3Tsf59swvE0X%52Jh}4;wHHQNk?!*pcy?|_PFObwuzf!bMjMcCFs0dE|}iDbaBV( zI=M(^I(km@Wc=nU1-4VYqp+QUfa^xOauxuU;#qYEa#2#$v!WmIks>(5<$92ExdIk$ z8ig9b9K%$LcA<*W_#IngPUMm#)twsIa&$%uQ$-Y-1Y~tk{c&-+DNa3caR~_^o&0tR zXQJokcIp7*61?#s65<%7>^A&V%d^5V9f`|v2P-5F(Npb*1@VkrH`H=p)qX_Xb3>fu zA*?}MZ`@rC?&D#9okyma>zA*p&Re7?YNZJDbyOL#vbC*Y)jdmAihgd+8|t+$aFI5T z#GqfeX^k@>Tz?sSDXQC3ioK|@KGcacD=&`fk>I-_R4nThry}d2%g0!L6(O&OaJTES z%~`%*se8{~DTl3bE678)nO5mSu@@7ClJrDGAoq$z(`|@IN`E?^ zP?A=!M?+9~f~l5hq1zNpmAGXK#N(HXE|Ib&vGHJ^hJg{Nz6npSL$yK9JAEydr!B`@ z_SGU1So~#6(R!xowHcGEGepR$g#9LKLo8wF2-f&C@?3N-^t&T?*;#4eSYgsh!;)Ai4@y;T-DYS~*9mQHJDv~;eqM=pu89FHC{=7HHE{P9 zb;4w)3nATr)H_-jZeovp&1mK>$-US$*WrW!4x7ygFmEGg3OpS)XF`+GhxUfANxguZ90GRE|?ExUP~e#l}|b#d)|H14}5 zCOtp!qe$;Op&@DDI|`Z{A^i-Hn)?)Z{m#8D51*?--SjJO1`_&Wag%Z^79^vsi_!_{ zU?QU5=x5iR*u7U;Re`&vlHcw;u`y^%0CBVjhrUE4*cW$~uNW4+tN$Ww53jvq%E!YZ zpgKYp-hcVvm_S8wa%A}le=9)^xy$1A+A|xNy#tZ_jh4Nj&}`tRQx&-@;IG?<62k<3 z&!XB(Pa_U^;Q{)$IG$miHlU!}H%Xn65oBD{TIN>JrOd9?H`5q1H`ApzfpoQ<@k5cy z1L;S*hGoxR#))fDuzQ(hqoH7%1g|yW7G;i)I3bm~NU+?c9Qq=tav`tHh-vCU*~smV zqW6>vEr7`&=myerH#eXt@UXSWrtoMrM|bx#hy98IAxp^%nzy*j&W$5nkGJ=p+j!jH z5$wmMCvX|N85+QyBKFyK?1bmyzK-=1!59o4YQ53|POC`0+mI@N;*S>%9tdLBMdBAK z8#3HjpYah9Q`OYdF}Utgb4U|hfxg8G>92`Jqy^j;>NryVBna z07(nwXOEiRdErGXAR<-z#C+p7&n@q?c@HNV-GROWiMb7OTWHF6yT!Q>r3_pF<%*}< z90>W#2=4tz?br9uUEIXkcYp6$c3QgX*)|-!?A2lsFA@ z8FbWDk`2DK?gOavJzWxq1Bqm{EG^og*cmro@?`WCdUZZPPs%fh{3sWhet^li85suq zA>#1vQi0w(BiB0lfo$IE$GywX;8~=A4J0e28cVq1N|g6*r$MJ{qQz>!Do48fO0?+#KkIslE(3!(d+3Me zq%Qo#M;EzpKpmxfa0MjXLZZXEqCXG_(oe?)6N&jE1n?I%iDY?w)Y;%hpy&}A%J@F( zgMkRLD^A>O<6>jz6!joy^W#BSC$3^Yy|gnuu+;-^Kr)e*a|_Vn(fKewR>)#dP~_w` zhxg!0(?x?Q*@N{_>N}?YT;2GY@XTUH<<`%_CVygo<-pj(=fOA1+2to7|0{O+2coQJ b>pVOubW>ZN3BQm)gFQ7=byZ4~tpfiG7d^pe literal 0 HcmV?d00001 diff --git a/Tests/Fixtures/Rendering.typoscript b/Tests/Fixtures/Rendering.typoscript new file mode 100644 index 0000000..58c0fa4 --- /dev/null +++ b/Tests/Fixtures/Rendering.typoscript @@ -0,0 +1,5 @@ + + +page > +page = PAGE +page.10 =< styles.content.get diff --git a/Tests/Fixtures/SingleFileDatabase.php b/Tests/Fixtures/SingleFileDatabase.php new file mode 100644 index 0000000..d1c60f6 --- /dev/null +++ b/Tests/Fixtures/SingleFileDatabase.php @@ -0,0 +1,41 @@ + [ + [ + 'uid' => 1, + 'pid' => 0, + 'missing' => 0, + 'storage' => 1, + 'type' => 2, + 'metadata' => 0, + 'identifier' => '/Files/FirstResult.png', + 'identifier_hash' => '29b827d0daa29658d8a0d952dfd20f559bbe3bcf', + 'folder_hash' => '86d12d536195df2100a5ec04ab80c08f9bed3d31', + 'extension' => 'png', + 'mime_type' => 'image/png', + 'name' => 'FirstResult.png', + 'sha1' => 'b13f2bbf275d592534eab659c1430c2702ce31fc', + 'size' => '42383', + ], + ], + 'sys_file_collection' => [ + [ + 'uid' => 1, + 'pid' => 1, + 'title' => 'Example for Form', + 'files' => 1, + ], + ], + 'sys_file_reference' => [ + [ + 'uid' => 1, + 'pid' => 1, + 'uid_local' => 1, + 'uid_foreign' => 1, + 'tablenames' => 'sys_file_collection', + 'fieldname' => 'files', + 'sorting_foreign' => 2, + ], + ], +]; diff --git a/Tests/Fixtures/Sites/default/config.yaml b/Tests/Fixtures/Sites/default/config.yaml new file mode 100644 index 0000000..a127453 --- /dev/null +++ b/Tests/Fixtures/Sites/default/config.yaml @@ -0,0 +1,32 @@ +base: / +languages: + - + title: English + enabled: true + base: / + typo3Language: default + locale: en_GB.UTF-8 + iso-639-1: en + websiteTitle: '' + navigationTitle: English + hreflang: en-GB + direction: '' + flag: gb + languageId: 0 + fallbackType: strict + fallbacks: '0' + - + title: Deutsch + enabled: true + base: /de + typo3Language: de + locale: de_DE.UTF-8 + iso-639-1: de + navigationTitle: Deutsch + hreflang: de-DE + direction: '' + flag: de + websiteTitle: '' + languageId: 1 +rootPageId: 1 +websiteTitle: 'Example Website' diff --git a/Tests/Fixtures/TwoFilesDatabase.php b/Tests/Fixtures/TwoFilesDatabase.php new file mode 100644 index 0000000..97823b0 --- /dev/null +++ b/Tests/Fixtures/TwoFilesDatabase.php @@ -0,0 +1,66 @@ + [ + [ + 'uid' => 1, + 'pid' => 0, + 'missing' => 0, + 'storage' => 1, + 'type' => 2, + 'metadata' => 0, + 'identifier' => '/Files/FirstResult.png', + 'identifier_hash' => '29b827d0daa29658d8a0d952dfd20f559bbe3bcf', + 'folder_hash' => '86d12d536195df2100a5ec04ab80c08f9bed3d31', + 'extension' => 'png', + 'mime_type' => 'image/png', + 'name' => 'FirstResult.png', + 'sha1' => 'b13f2bbf275d592534eab659c1430c2702ce31fc', + 'size' => '42383', + ], + [ + 'uid' => 2, + 'pid' => 0, + 'missing' => 0, + 'storage' => 1, + 'type' => 2, + 'metadata' => 0, + 'identifier' => '/Files/SecondResult.png', + 'identifier_hash' => '29b827d0daa29658d8a0d952dfd20f559bbe3bcf', + 'folder_hash' => '86d12d536195df2100a5ec04ab80c08f9bed3d31', + 'extension' => 'png', + 'mime_type' => 'image/png', + 'name' => 'SecondResult.png', + 'sha1' => 'b13f2bbf275d592534eab659c1430c2702ce31fc', + 'size' => '42383', + ], + ], + 'sys_file_collection' => [ + [ + 'uid' => 1, + 'pid' => 1, + 'title' => 'Example for Form', + 'files' => 1, + ], + ], + 'sys_file_reference' => [ + [ + 'uid' => 1, + 'pid' => 1, + 'uid_local' => 1, + 'uid_foreign' => 1, + 'tablenames' => 'sys_file_collection', + 'fieldname' => 'files', + 'sorting_foreign' => 2, + ], + [ + 'uid' => 2, + 'pid' => 1, + 'uid_local' => 2, + 'uid_foreign' => 1, + 'tablenames' => 'sys_file_collection', + 'fieldname' => 'files', + 'sorting_foreign' => 1, + ], + ], +]; diff --git a/Tests/Fixtures/form_file_collection_example/Configuration/Forms/Example.form.yaml b/Tests/Fixtures/form_file_collection_example/Configuration/Forms/Example.form.yaml new file mode 100644 index 0000000..253ea75 --- /dev/null +++ b/Tests/Fixtures/form_file_collection_example/Configuration/Forms/Example.form.yaml @@ -0,0 +1,34 @@ +renderingOptions: + submitButtonLabel: Submit +type: Form +identifier: test +label: Test +prototypeName: standard +renderables: + - + renderingOptions: + previousButtonLabel: 'Previous step' + nextButtonLabel: 'Next step' + type: Page + identifier: page-1 + label: First Step + renderables: + - + type: FileCollection + identifier: file-collection-1 + label: 'File Collection' + properties: + fileCollection: + uid: 1 + - + defaultValue: '' + type: Text + identifier: text-1 + label: 'Example text field' + - + renderingOptions: + previousButtonLabel: 'Previous step' + nextButtonLabel: 'Next step' + type: SummaryPage + identifier: summarypage-1 + label: 'Summary step' diff --git a/Tests/Fixtures/form_file_collection_example/Configuration/Forms/ExampleCustomLabelAndValue.form.yaml b/Tests/Fixtures/form_file_collection_example/Configuration/Forms/ExampleCustomLabelAndValue.form.yaml new file mode 100644 index 0000000..c0eba25 --- /dev/null +++ b/Tests/Fixtures/form_file_collection_example/Configuration/Forms/ExampleCustomLabelAndValue.form.yaml @@ -0,0 +1,36 @@ +renderingOptions: + submitButtonLabel: Submit +type: Form +identifier: test +label: Test +prototypeName: standard +renderables: + - + renderingOptions: + previousButtonLabel: 'Previous step' + nextButtonLabel: 'Next step' + type: Page + identifier: page-1 + label: First Step + renderables: + - + type: FileCollection + identifier: file-collection-1 + label: 'File Collection' + properties: + fileCollection: + uid: 1 + valueProperty: 'identifier_hash' + labelProperty: 'mime_type' + - + defaultValue: '' + type: Text + identifier: text-1 + label: 'Example text field' + - + renderingOptions: + previousButtonLabel: 'Previous step' + nextButtonLabel: 'Next step' + type: SummaryPage + identifier: summarypage-1 + label: 'Summary step' diff --git a/Tests/Fixtures/form_file_collection_example/Configuration/Forms/Setup.yaml b/Tests/Fixtures/form_file_collection_example/Configuration/Forms/Setup.yaml new file mode 100644 index 0000000..aa74a3a --- /dev/null +++ b/Tests/Fixtures/form_file_collection_example/Configuration/Forms/Setup.yaml @@ -0,0 +1,14 @@ +TYPO3: + CMS: + Form: + persistenceManager: + allowedExtensionPaths: + 10: EXT:form_file_collection_example/Configuration/Forms/ + + prototypes: + standard: + formElementsDefinition: + FileCollection: + renderingOptions: + # Allows to switch between different rendering like "Checkbox", "MultiCheckbox" or "RadioButton", etc. + templateName: 'MultiCheckbox' diff --git a/Tests/Fixtures/form_file_collection_example/Configuration/TypoScript/Form.typoscript b/Tests/Fixtures/form_file_collection_example/Configuration/TypoScript/Form.typoscript new file mode 100644 index 0000000..ee3e4b1 --- /dev/null +++ b/Tests/Fixtures/form_file_collection_example/Configuration/TypoScript/Form.typoscript @@ -0,0 +1,6 @@ + + +plugin.tx_form.settings.yamlConfigurations { + 80 = EXT:form_file_collection/Configuration/Form/Setup.yaml + 90 = EXT:form_file_collection_example/Configuration/Forms/Setup.yaml +} diff --git a/Tests/Fixtures/form_file_collection_example/composer.json b/Tests/Fixtures/form_file_collection_example/composer.json new file mode 100644 index 0000000..8bc426d --- /dev/null +++ b/Tests/Fixtures/form_file_collection_example/composer.json @@ -0,0 +1,16 @@ +{ + "name": "werkraummedia/form-file-collection-example", + "description": "Example usage of form file collection", + "type": "typo3-cms-extension", + "license": "GPL-2.0-or-later", + "require": { + "typo3/cms-core": "*", + "typo3/cms-form": "*", + "werkraummedia/form-file-collection": "*" + }, + "extra": { + "typo3/cms": { + "extension-key": "form_file_collection_example" + } + } +} diff --git a/Tests/Functional/FormIntegrationTest.php b/Tests/Functional/FormIntegrationTest.php new file mode 100644 index 0000000..56cf63d --- /dev/null +++ b/Tests/Functional/FormIntegrationTest.php @@ -0,0 +1,122 @@ + + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +namespace WerkraumMedia\FormFileCollection\Tests\Functional; + +use Codappix\Typo3PhpDatasets\TestingFramework; +use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest; +use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase; + +class FormIntegrationTest extends FunctionalTestCase +{ + use TestingFramework; + + public function setUp(): void + { + $this->coreExtensionsToLoad = [ + 'fluid_styled_content', + 'form', + ]; + $this->testExtensionsToLoad = [ + 'typo3conf/ext/form_file_collection', + 'typo3conf/ext/form_file_collection/Tests/Fixtures/form_file_collection_example', + ]; + $this->pathsToLinkInTestInstance = [ + 'typo3conf/ext/form_file_collection/Tests/Fixtures/Sites' => 'typo3conf/sites', + 'typo3conf/ext/form_file_collection/Tests/Fixtures/Fileadmin/Files' => 'fileadmin/Files', + ]; + + parent::setUp(); + + $this->importPHPDataSet(__DIR__ . '/../Fixtures/BasicDatabase.php'); + $this->setUpFrontendRootPage(1, [ + 'setup' => [ + 'EXT:form_file_collection/Tests/Fixtures/Rendering.typoscript', + 'EXT:form_file_collection_example/Configuration/TypoScript/Form.typoscript', + ], + ]); + } + + /** + * @test + */ + public function rendersFileFromSelectedCollection(): void + { + $this->importPHPDataSet(__DIR__ . '/../Fixtures/SingleFileDatabase.php'); + + $request = new InternalRequest(); + + $response = $this->executeFrontendRequest($request); + + $content = $response->getBody()->__toString(); + self::assertStringContainsString('name="tx_form_formframework[test-1][file-collection-1]"', $content); + + self::assertStringContainsString('FirstResult.png', $content); + self::assertStringContainsString('value="/Files/FirstResult.png"', $content); + self::assertStringContainsString('/Files/FirstResult.png', $content); + + self::assertStringNotContainsString('SecondResult.png', $content); + } + + /** + * @test + */ + public function providesMultipleFilesFromSelectedCollection(): void + { + $this->importPHPDataSet(__DIR__ . '/../Fixtures/TwoFilesDatabase.php'); + + $request = new InternalRequest(); + + $response = $this->executeFrontendRequest($request); + + $content = $response->getBody()->__toString(); + self::assertStringContainsString('name="tx_form_formframework[test-1][file-collection-1][]"', $content); + + self::assertStringContainsString('FirstResult.png', $content); + self::assertStringContainsString('value="/Files/FirstResult.png"', $content); + self::assertStringContainsString('/Files/FirstResult.png', $content); + + self::assertStringContainsString('SecondResult.png', $content); + self::assertStringContainsString('value="/Files/SecondResult.png"', $content); + self::assertStringContainsString('/Files/SecondResult.png', $content); + } + + /** + * @test + */ + public function rendersConfiguredLabel(): void + { + $this->importPHPDataSet(__DIR__ . '/../Fixtures/SingleFileDatabase.php'); + + $request = new InternalRequest(); + $request = $request->withPageId(2); + + $response = $this->executeFrontendRequest($request); + + $content = $response->getBody()->__toString(); + self::assertStringContainsString('name="tx_form_formframework[test-2][file-collection-1][]"', $content); + + self::assertStringContainsString('value="29b827d0daa29658d8a0d952dfd20f559bbe3bcf"', $content); + self::assertStringContainsString('image/png', $content); + } +} diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..b9440cb --- /dev/null +++ b/composer.json @@ -0,0 +1,68 @@ +{ + "name": "werkraummedia/form-file-collection", + "description": "Add a form element to render file collection to EXT:form of TYPO3", + "type": "typo3-cms-extension", + "license": "GPL-2.0-or-later", + "homepage": "https://github.com/werkraum-media/form_file_collection", + "support": { + "docs": "https://docs.typo3.org/p/werkraummedia/form_file_collection/master/en-us/", + "email": "coding@daniel-siepmann.de", + "issues": "https://github.com/werkraum-media/form_file_collection/issues", + "source": "https://github.com/werkraum-media/form_file_collection" + }, + "authors": [ + { + "name": "Daniel Siepmann", + "email": "coding@daniel-siepmann.de", + "homepage": "https://daniel-siepmann.de/", + "role": "Developer" + } + ], + "autoload": { + "psr-4": { + "WerkraumMedia\\FormFileCollection\\": "Classes/" + } + }, + "autoload-dev": { + "psr-4": { + "WerkraumMedia\\FormFileCollection\\Tests\\": "Tests/", + "WerkraumMedia\\FormFileCollectionExample\\": "Tests/Fixtures/form_file_collection_example/Classes/" + } + }, + "require": { + "php": "~8.0.0 || ~8.1.0 || ~8.2.0", + "typo3/cms-backend": "^11.5 || ^12.4", + "typo3/cms-core": "^11.5 || ^12.4", + "typo3/cms-fluid-styled-content": "^11.5 || ^12.4", + "typo3/cms-form": "^11.5 || ^12.4", + "typo3/cms-frontend": "^11.5 || ^12.4" + }, + "require-dev": { + "codappix/typo3-php-datasets": "^1.3", + "friendsofphp/php-cs-fixer": "^3.11", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.10", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^9.5", + "saschaegerer/phpstan-typo3": "^1.8", + "typo3/testing-framework": "^7.0" + }, + "config": { + "sort-packages": true, + "lock": false, + "allow-plugins": { + "typo3/cms-composer-installers": true, + "typo3/class-alias-loader": true, + "ocramius/package-versions": true, + "phpstan/extension-installer": true, + "cweagans/composer-patches": true + } + }, + "extra": { + "typo3/cms": { + "app-dir": ".Build", + "extension-key": "form_file_collection", + "web-dir": ".Build/web" + } + } +} diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..0daf72e --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,6 @@ +parameters: + level: max + paths: + - Classes + - Tests + reportUnmatchedIgnoredErrors: true diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000..bb9e07e --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,35 @@ + + + + + + Tests/Functional/ + + + + + + Classes + + + + + + + diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..c2d6126 --- /dev/null +++ b/shell.nix @@ -0,0 +1,91 @@ +{ + pkgs ? import { } +}: + +let + php = pkgs.php82.buildEnv { + extensions = { enabled, all }: enabled ++ (with all; [ + xdebug + ]); + + extraConfig = '' + xdebug.mode = debug + memory_limit = 4G + ''; + }; + inherit(php.packages) composer; + + projectInstall = pkgs.writeShellApplication { + name = "project-install"; + runtimeInputs = [ + php + composer + ]; + text = '' + rm -rf .Build/ vendor/ + composer install --prefer-dist --no-progress --working-dir="$PROJECT_ROOT" + ''; + }; + projectValidateComposer = pkgs.writeShellApplication { + name = "project-validate-composer"; + runtimeInputs = [ + php + composer + ]; + text = '' + composer validate + ''; + }; + projectValidateXml = pkgs.writeShellApplication { + name = "project-validate-xml"; + runtimeInputs = [ + pkgs.libxml2 + pkgs.wget + projectInstall + ]; + text = '' + project-install + xmllint --schema vendor/phpunit/phpunit/phpunit.xsd --noout phpunit.xml.dist + ''; + }; + projectCodingGuideline = pkgs.writeShellApplication { + name = "project-coding-guideline"; + runtimeInputs = [ + php + projectInstall + ]; + text = '' + project-install + ./vendor/bin/php-cs-fixer fix --dry-run --diff + ''; + }; + projectCodingGuidelineFix = pkgs.writeShellApplication { + name = "project-coding-guideline-fix"; + runtimeInputs = [ + php + projectInstall + ]; + text = '' + project-install + ./vendor/bin/php-cs-fixer fix + ''; + }; + +in pkgs.mkShell { + name = "TYPO3 Extension FormFileCollection"; + buildInputs = [ + projectInstall + projectValidateComposer + projectValidateXml + projectCodingGuideline + projectCodingGuidelineFix + php + composer + ]; + + shellHook = '' + export PROJECT_ROOT="$(pwd)" + + export typo3DatabaseDriver=pdo_sqlite + ''; +}