From f56b6b75820c8134afd400e4b936b5ad43dd93ee Mon Sep 17 00:00:00 2001 From: Antonio Addeo Date: Thu, 2 Mar 2023 14:03:15 +0100 Subject: [PATCH 01/15] Add crtp directory with builder for object hierarchy example Ref: #2342 --- crtp/pom.xml | 38 ++++++++++ crtp/src/main/java/crtp/App.java | 11 +++ crtp/src/main/java/crtp/Cargo.java | 5 ++ crtp/src/main/java/crtp/CargoSpaceship.java | 39 ++++++++++ crtp/src/main/java/crtp/Size.java | 8 ++ crtp/src/main/java/crtp/Spaceship.java | 74 +++++++++++++++++++ crtp/src/main/java/crtp/Speed.java | 10 +++ crtp/src/main/java/crtp/WarSpaceship.java | 39 ++++++++++ crtp/src/main/java/crtp/Weapon.java | 11 +++ crtp/src/test/java/crtp/AppTest.java | 13 ++++ .../test/java/crtp/CargoSpaceshipTest.java | 40 ++++++++++ crtp/src/test/java/crtp/WarSpaceshipTest.java | 38 ++++++++++ 12 files changed, 326 insertions(+) create mode 100644 crtp/pom.xml create mode 100644 crtp/src/main/java/crtp/App.java create mode 100644 crtp/src/main/java/crtp/Cargo.java create mode 100644 crtp/src/main/java/crtp/CargoSpaceship.java create mode 100644 crtp/src/main/java/crtp/Size.java create mode 100644 crtp/src/main/java/crtp/Spaceship.java create mode 100644 crtp/src/main/java/crtp/Speed.java create mode 100644 crtp/src/main/java/crtp/WarSpaceship.java create mode 100644 crtp/src/main/java/crtp/Weapon.java create mode 100644 crtp/src/test/java/crtp/AppTest.java create mode 100644 crtp/src/test/java/crtp/CargoSpaceshipTest.java create mode 100644 crtp/src/test/java/crtp/WarSpaceshipTest.java diff --git a/crtp/pom.xml b/crtp/pom.xml new file mode 100644 index 000000000000..492051177486 --- /dev/null +++ b/crtp/pom.xml @@ -0,0 +1,38 @@ + + + 4.0.0 + + com.iluwatar + java-design-patterns + 1.26.0-SNAPSHOT + + crtp + + + org.junit.jupiter + junit-jupiter-engine + test + + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + + + + com.iluwatar.crtp.App + + + + + + + + + diff --git a/crtp/src/main/java/crtp/App.java b/crtp/src/main/java/crtp/App.java new file mode 100644 index 000000000000..e231a2438483 --- /dev/null +++ b/crtp/src/main/java/crtp/App.java @@ -0,0 +1,11 @@ +package crtp; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class App { + + public static void main(String[] args) { + + } +} diff --git a/crtp/src/main/java/crtp/Cargo.java b/crtp/src/main/java/crtp/Cargo.java new file mode 100644 index 000000000000..b75b95b0ca38 --- /dev/null +++ b/crtp/src/main/java/crtp/Cargo.java @@ -0,0 +1,5 @@ +package crtp; + +public enum Cargo { + FOOD, FUEL, ELECTRONICS +} diff --git a/crtp/src/main/java/crtp/CargoSpaceship.java b/crtp/src/main/java/crtp/CargoSpaceship.java new file mode 100644 index 000000000000..ead200f1ac03 --- /dev/null +++ b/crtp/src/main/java/crtp/CargoSpaceship.java @@ -0,0 +1,39 @@ +package crtp; + +public final class CargoSpaceship extends Spaceship { + + private final Cargo cargo; + + private CargoSpaceship(Builder builder) { + super(builder); + this.cargo = builder.cargo; + } + + public Cargo getCargo() { + return cargo; + } + + static final class Builder extends Spaceship.Builder { + + private Cargo cargo; + + public Builder(String name, int fuelCapacity) { + super(name, fuelCapacity); + } + + @Override + protected Builder self() { + return this; + } + + Builder withCargo(Cargo cargo) { + this.cargo = cargo; + return this; + } + + CargoSpaceship build() { + return new CargoSpaceship(this); + } + } + +} diff --git a/crtp/src/main/java/crtp/Size.java b/crtp/src/main/java/crtp/Size.java new file mode 100644 index 000000000000..0c82ac77788b --- /dev/null +++ b/crtp/src/main/java/crtp/Size.java @@ -0,0 +1,8 @@ +package crtp; + +public enum Size { + SMALL, + MEDIUM, + LARGE, + XLARGE +} diff --git a/crtp/src/main/java/crtp/Spaceship.java b/crtp/src/main/java/crtp/Spaceship.java new file mode 100644 index 000000000000..792ecdeb22e8 --- /dev/null +++ b/crtp/src/main/java/crtp/Spaceship.java @@ -0,0 +1,74 @@ +package crtp; + +public sealed abstract class Spaceship permits WarSpaceship, CargoSpaceship { + + private final String name; + private final int fuelCapacity; + private final Speed speed; + private final Size size; + + protected Spaceship(Builder> builder) { + this.name = builder.name; + this.fuelCapacity = builder.fuelCapacity; + this.speed = builder.speed; + this.size = builder.size; + } + + public String getName() { + return name; + } + + public int getFuelCapacity() { + return fuelCapacity; + } + + public Speed getSpeed() { + return speed; + } + + public Size getSize() { + return size; + } + + static abstract sealed class Builder> permits WarSpaceship.Builder, + CargoSpaceship.Builder { + + private final String name; + private final int fuelCapacity; + private Speed speed; + private Size size; + + public Builder(String name, int fuelCapacity) { + if (name == null) { + throw new IllegalArgumentException("Name can't be null"); + } + if (fuelCapacity <= 0) { + throw new IllegalArgumentException("Fuel capacity can't be equal or less than zero"); + } + this.name = name; + this.fuelCapacity = fuelCapacity; + } + + // Builder withSize(Speed speed) { + T withSpeed(Speed speed) { + this.speed = speed; +// return this; + return self(); + } + + // Builder withSize(Size size) { + T withSize(Size size) { + this.size = size; +// return this; + return self(); + } + + protected abstract T self(); + +// Spaceship build() { +// return new Spaceship(this); +// } + } + + +} diff --git a/crtp/src/main/java/crtp/Speed.java b/crtp/src/main/java/crtp/Speed.java new file mode 100644 index 000000000000..504915c78597 --- /dev/null +++ b/crtp/src/main/java/crtp/Speed.java @@ -0,0 +1,10 @@ +package crtp; + +public enum Speed { + + SUBLIGHT, + QUARTER_C, + HALF_C, + THREE_QUARTERS_C, + LIGHTSPEED +} diff --git a/crtp/src/main/java/crtp/WarSpaceship.java b/crtp/src/main/java/crtp/WarSpaceship.java new file mode 100644 index 000000000000..83f6ea03fb5c --- /dev/null +++ b/crtp/src/main/java/crtp/WarSpaceship.java @@ -0,0 +1,39 @@ +package crtp; + +public final class WarSpaceship extends Spaceship { + + private final Weapon weapon; + + private WarSpaceship(Builder builder) { + super(builder); + this.weapon = builder.weapon; + } + + public Weapon getWeapon() { + return weapon; + } + + static final class Builder extends Spaceship.Builder { + + private Weapon weapon; + + public Builder(String name, int fuelCapacity) { + super(name, fuelCapacity); + } + + @Override + protected Builder self() { + return this; + } + + Builder withWeapon(Weapon weapon) { + this.weapon = weapon; + return this; + } + + WarSpaceship build() { + return new WarSpaceship(this); + } + } + +} diff --git a/crtp/src/main/java/crtp/Weapon.java b/crtp/src/main/java/crtp/Weapon.java new file mode 100644 index 000000000000..16bc0cf629ac --- /dev/null +++ b/crtp/src/main/java/crtp/Weapon.java @@ -0,0 +1,11 @@ +package crtp; + +public enum Weapon { + + GUNSHIP_AUTOCANNON, LIGHT_PULSE_CANNON, PLASMA_CANNON, RAILGUN_CANNON; + + @Override + public String toString() { + return name().toLowerCase(); + } +} diff --git a/crtp/src/test/java/crtp/AppTest.java b/crtp/src/test/java/crtp/AppTest.java new file mode 100644 index 000000000000..bb591312389c --- /dev/null +++ b/crtp/src/test/java/crtp/AppTest.java @@ -0,0 +1,13 @@ +package crtp; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + +import org.junit.jupiter.api.Test; + +class AppTest { + + @Test + void shouldExecuteApplicationWithoutException() { + assertDoesNotThrow(() -> App.main(new String[]{})); + } +} diff --git a/crtp/src/test/java/crtp/CargoSpaceshipTest.java b/crtp/src/test/java/crtp/CargoSpaceshipTest.java new file mode 100644 index 000000000000..453dea63a3a7 --- /dev/null +++ b/crtp/src/test/java/crtp/CargoSpaceshipTest.java @@ -0,0 +1,40 @@ +package crtp; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +class CargoSpaceshipTest { + + @Test + void testMissingName() { + assertThrows(IllegalArgumentException.class, () -> new CargoSpaceship.Builder(null, 100)); + } + + @Test + void testNegativeOrNullFuelCapacity() { + assertThrows(IllegalArgumentException.class, + () -> new CargoSpaceship.Builder("Planet Express", -1)); + assertThrows(IllegalArgumentException.class, + () -> new CargoSpaceship.Builder("Planet Express", 0)); + } + + @Test + void testBuildCargoShip() { + final var ship = new CargoSpaceship.Builder("Planet Express", 200) + .withSpeed(Speed.QUARTER_C) + .withCargo(Cargo.FOOD) + .withSize(Size.MEDIUM) + .build(); + + assertNotNull(ship); + assertNotNull(ship.toString()); + assertEquals(Speed.QUARTER_C, ship.getSpeed()); + assertEquals(Cargo.FOOD, ship.getCargo()); + assertEquals(Size.MEDIUM, ship.getSize()); + } + + +} \ No newline at end of file diff --git a/crtp/src/test/java/crtp/WarSpaceshipTest.java b/crtp/src/test/java/crtp/WarSpaceshipTest.java new file mode 100644 index 000000000000..8c423afc9514 --- /dev/null +++ b/crtp/src/test/java/crtp/WarSpaceshipTest.java @@ -0,0 +1,38 @@ +package crtp; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +class WarSpaceshipTest { + + @Test + void testMissingName() { + assertThrows(IllegalArgumentException.class, () -> new WarSpaceship.Builder(null, 100)); + } + + @Test + void testNegativeOrNullFuelCapacity() { + assertThrows(IllegalArgumentException.class, () -> new WarSpaceship.Builder("Gravity", -1)); + assertThrows(IllegalArgumentException.class, () -> new WarSpaceship.Builder("Gravity", 0)); + } + + @Test + void testBuildCargoShip() { + final var ship = new WarSpaceship.Builder("Gravity", 500) + .withSpeed(Speed.HALF_C) + .withWeapon(Weapon.PLASMA_CANNON) + .withSize(Size.LARGE) + .build(); + + assertNotNull(ship); + assertNotNull(ship.toString()); + assertEquals(Speed.HALF_C, ship.getSpeed()); + assertEquals(Weapon.PLASMA_CANNON, ship.getWeapon()); + assertEquals(Size.LARGE, ship.getSize()); + } + + +} \ No newline at end of file From 4536e8506162a783d95cecd247d39a84e12cbe67 Mon Sep 17 00:00:00 2001 From: Antonio Addeo Date: Fri, 3 Mar 2023 17:35:44 +0100 Subject: [PATCH 02/15] Add space package Ref: #2342 --- crtp/src/main/java/crtp/{ => space}/Cargo.java | 2 +- crtp/src/main/java/crtp/{ => space}/CargoSpaceship.java | 2 +- crtp/src/main/java/crtp/{ => space}/Size.java | 2 +- crtp/src/main/java/crtp/{ => space}/Spaceship.java | 2 +- crtp/src/main/java/crtp/{ => space}/Speed.java | 2 +- crtp/src/main/java/crtp/{ => space}/WarSpaceship.java | 2 +- crtp/src/main/java/crtp/{ => space}/Weapon.java | 2 +- crtp/src/test/java/crtp/{ => space}/CargoSpaceshipTest.java | 2 +- crtp/src/test/java/crtp/{ => space}/WarSpaceshipTest.java | 4 ++-- 9 files changed, 10 insertions(+), 10 deletions(-) rename crtp/src/main/java/crtp/{ => space}/Cargo.java (66%) rename crtp/src/main/java/crtp/{ => space}/CargoSpaceship.java (91%) rename crtp/src/main/java/crtp/{ => space}/Size.java (67%) rename crtp/src/main/java/crtp/{ => space}/Spaceship.java (94%) rename crtp/src/main/java/crtp/{ => space}/Speed.java (75%) rename crtp/src/main/java/crtp/{ => space}/WarSpaceship.java (91%) rename crtp/src/main/java/crtp/{ => space}/Weapon.java (89%) rename crtp/src/test/java/crtp/{ => space}/CargoSpaceshipTest.java (98%) rename crtp/src/test/java/crtp/{ => space}/WarSpaceshipTest.java (95%) diff --git a/crtp/src/main/java/crtp/Cargo.java b/crtp/src/main/java/crtp/space/Cargo.java similarity index 66% rename from crtp/src/main/java/crtp/Cargo.java rename to crtp/src/main/java/crtp/space/Cargo.java index b75b95b0ca38..5aa907719cee 100644 --- a/crtp/src/main/java/crtp/Cargo.java +++ b/crtp/src/main/java/crtp/space/Cargo.java @@ -1,4 +1,4 @@ -package crtp; +package crtp.space; public enum Cargo { FOOD, FUEL, ELECTRONICS diff --git a/crtp/src/main/java/crtp/CargoSpaceship.java b/crtp/src/main/java/crtp/space/CargoSpaceship.java similarity index 91% rename from crtp/src/main/java/crtp/CargoSpaceship.java rename to crtp/src/main/java/crtp/space/CargoSpaceship.java index ead200f1ac03..f4b9118315ee 100644 --- a/crtp/src/main/java/crtp/CargoSpaceship.java +++ b/crtp/src/main/java/crtp/space/CargoSpaceship.java @@ -1,4 +1,4 @@ -package crtp; +package crtp.space; public final class CargoSpaceship extends Spaceship { diff --git a/crtp/src/main/java/crtp/Size.java b/crtp/src/main/java/crtp/space/Size.java similarity index 67% rename from crtp/src/main/java/crtp/Size.java rename to crtp/src/main/java/crtp/space/Size.java index 0c82ac77788b..2bb0b22ff77c 100644 --- a/crtp/src/main/java/crtp/Size.java +++ b/crtp/src/main/java/crtp/space/Size.java @@ -1,4 +1,4 @@ -package crtp; +package crtp.space; public enum Size { SMALL, diff --git a/crtp/src/main/java/crtp/Spaceship.java b/crtp/src/main/java/crtp/space/Spaceship.java similarity index 94% rename from crtp/src/main/java/crtp/Spaceship.java rename to crtp/src/main/java/crtp/space/Spaceship.java index 792ecdeb22e8..614372860e0c 100644 --- a/crtp/src/main/java/crtp/Spaceship.java +++ b/crtp/src/main/java/crtp/space/Spaceship.java @@ -1,4 +1,4 @@ -package crtp; +package crtp.space; public sealed abstract class Spaceship permits WarSpaceship, CargoSpaceship { diff --git a/crtp/src/main/java/crtp/Speed.java b/crtp/src/main/java/crtp/space/Speed.java similarity index 75% rename from crtp/src/main/java/crtp/Speed.java rename to crtp/src/main/java/crtp/space/Speed.java index 504915c78597..36434ad7a3ce 100644 --- a/crtp/src/main/java/crtp/Speed.java +++ b/crtp/src/main/java/crtp/space/Speed.java @@ -1,4 +1,4 @@ -package crtp; +package crtp.space; public enum Speed { diff --git a/crtp/src/main/java/crtp/WarSpaceship.java b/crtp/src/main/java/crtp/space/WarSpaceship.java similarity index 91% rename from crtp/src/main/java/crtp/WarSpaceship.java rename to crtp/src/main/java/crtp/space/WarSpaceship.java index 83f6ea03fb5c..16c182f00cb8 100644 --- a/crtp/src/main/java/crtp/WarSpaceship.java +++ b/crtp/src/main/java/crtp/space/WarSpaceship.java @@ -1,4 +1,4 @@ -package crtp; +package crtp.space; public final class WarSpaceship extends Spaceship { diff --git a/crtp/src/main/java/crtp/Weapon.java b/crtp/src/main/java/crtp/space/Weapon.java similarity index 89% rename from crtp/src/main/java/crtp/Weapon.java rename to crtp/src/main/java/crtp/space/Weapon.java index 16bc0cf629ac..a18d8302efc4 100644 --- a/crtp/src/main/java/crtp/Weapon.java +++ b/crtp/src/main/java/crtp/space/Weapon.java @@ -1,4 +1,4 @@ -package crtp; +package crtp.space; public enum Weapon { diff --git a/crtp/src/test/java/crtp/CargoSpaceshipTest.java b/crtp/src/test/java/crtp/space/CargoSpaceshipTest.java similarity index 98% rename from crtp/src/test/java/crtp/CargoSpaceshipTest.java rename to crtp/src/test/java/crtp/space/CargoSpaceshipTest.java index 453dea63a3a7..f1755942f891 100644 --- a/crtp/src/test/java/crtp/CargoSpaceshipTest.java +++ b/crtp/src/test/java/crtp/space/CargoSpaceshipTest.java @@ -1,4 +1,4 @@ -package crtp; +package crtp.space; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; diff --git a/crtp/src/test/java/crtp/WarSpaceshipTest.java b/crtp/src/test/java/crtp/space/WarSpaceshipTest.java similarity index 95% rename from crtp/src/test/java/crtp/WarSpaceshipTest.java rename to crtp/src/test/java/crtp/space/WarSpaceshipTest.java index 8c423afc9514..1d76f971d61a 100644 --- a/crtp/src/test/java/crtp/WarSpaceshipTest.java +++ b/crtp/src/test/java/crtp/space/WarSpaceshipTest.java @@ -1,4 +1,4 @@ -package crtp; +package crtp.space; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -20,7 +20,7 @@ void testNegativeOrNullFuelCapacity() { } @Test - void testBuildCargoShip() { + void testBuildWarShip() { final var ship = new WarSpaceship.Builder("Gravity", 500) .withSpeed(Speed.HALF_C) .withWeapon(Weapon.PLASMA_CANNON) From 223a92fba85ac9446be2a92238d0bf3487111d89 Mon Sep 17 00:00:00 2001 From: Antonio Addeo Date: Fri, 3 Mar 2023 18:55:18 +0100 Subject: [PATCH 03/15] Add comments for checkstyle Ref: #2342 --- crtp/pom.xml | 26 +++++++++++ crtp/src/main/java/crtp/App.java | 28 ++++++++++++ crtp/src/main/java/crtp/space/Cargo.java | 27 ++++++++++++ .../main/java/crtp/space/CargoSpaceship.java | 30 +++++++++++++ crtp/src/main/java/crtp/space/Size.java | 27 ++++++++++++ crtp/src/main/java/crtp/space/Spaceship.java | 43 +++++++++++++++---- crtp/src/main/java/crtp/space/Speed.java | 27 ++++++++++++ .../main/java/crtp/space/WarSpaceship.java | 30 +++++++++++++ crtp/src/main/java/crtp/space/Weapon.java | 27 ++++++++++++ crtp/src/test/java/crtp/AppTest.java | 28 ++++++++++++ .../java/crtp/space/CargoSpaceshipTest.java | 27 ++++++++++++ .../java/crtp/space/WarSpaceshipTest.java | 27 ++++++++++++ 12 files changed, 338 insertions(+), 9 deletions(-) diff --git a/crtp/pom.xml b/crtp/pom.xml index 492051177486..1869f7b37adc 100644 --- a/crtp/pom.xml +++ b/crtp/pom.xml @@ -1,4 +1,30 @@ + diff --git a/crtp/src/main/java/crtp/App.java b/crtp/src/main/java/crtp/App.java index e231a2438483..cfd3f5ea3cb6 100644 --- a/crtp/src/main/java/crtp/App.java +++ b/crtp/src/main/java/crtp/App.java @@ -1,7 +1,35 @@ +/* + * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). + * + * The MIT License + * Copyright © 2014-2022 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package crtp; import lombok.extern.slf4j.Slf4j; +/** + * Curiously Recurring Template Pattern. + * TODO Add more info. + */ @Slf4j public class App { diff --git a/crtp/src/main/java/crtp/space/Cargo.java b/crtp/src/main/java/crtp/space/Cargo.java index 5aa907719cee..c8e85e1e913c 100644 --- a/crtp/src/main/java/crtp/space/Cargo.java +++ b/crtp/src/main/java/crtp/space/Cargo.java @@ -1,5 +1,32 @@ +/* + * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). + * + * The MIT License + * Copyright © 2014-2022 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package crtp.space; +/** + * Cargo enumeration. + */ public enum Cargo { FOOD, FUEL, ELECTRONICS } diff --git a/crtp/src/main/java/crtp/space/CargoSpaceship.java b/crtp/src/main/java/crtp/space/CargoSpaceship.java index f4b9118315ee..a03becd3dede 100644 --- a/crtp/src/main/java/crtp/space/CargoSpaceship.java +++ b/crtp/src/main/java/crtp/space/CargoSpaceship.java @@ -1,5 +1,32 @@ +/* + * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). + * + * The MIT License + * Copyright © 2014-2022 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package crtp.space; +/** + * Specialized implementation of {@link Spaceship} for cargo delivery. + */ public final class CargoSpaceship extends Spaceship { private final Cargo cargo; @@ -13,6 +40,9 @@ public Cargo getCargo() { return cargo; } + /** + * Specialized implementation of {@link Spaceship.Builder} with {@link Cargo} field. + */ static final class Builder extends Spaceship.Builder { private Cargo cargo; diff --git a/crtp/src/main/java/crtp/space/Size.java b/crtp/src/main/java/crtp/space/Size.java index 2bb0b22ff77c..bf8c40507a1a 100644 --- a/crtp/src/main/java/crtp/space/Size.java +++ b/crtp/src/main/java/crtp/space/Size.java @@ -1,5 +1,32 @@ +/* + * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). + * + * The MIT License + * Copyright © 2014-2022 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package crtp.space; +/** + * Size enumeration. + */ public enum Size { SMALL, MEDIUM, diff --git a/crtp/src/main/java/crtp/space/Spaceship.java b/crtp/src/main/java/crtp/space/Spaceship.java index 614372860e0c..106cde01e07f 100644 --- a/crtp/src/main/java/crtp/space/Spaceship.java +++ b/crtp/src/main/java/crtp/space/Spaceship.java @@ -1,6 +1,33 @@ +/* + * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). + * + * The MIT License + * Copyright © 2014-2022 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package crtp.space; -public sealed abstract class Spaceship permits WarSpaceship, CargoSpaceship { +/** + * Spaceship class. + */ +public abstract sealed class Spaceship permits WarSpaceship, CargoSpaceship { private final String name; private final int fuelCapacity; @@ -30,7 +57,12 @@ public Size getSize() { return size; } - static abstract sealed class Builder> permits WarSpaceship.Builder, + /** + * Builder class. + * + * @param Builder derived class that uses itself as type parameter. + */ + abstract static sealed class Builder> permits WarSpaceship.Builder, CargoSpaceship.Builder { private final String name; @@ -49,25 +81,18 @@ public Builder(String name, int fuelCapacity) { this.fuelCapacity = fuelCapacity; } - // Builder withSize(Speed speed) { T withSpeed(Speed speed) { this.speed = speed; -// return this; return self(); } - // Builder withSize(Size size) { T withSize(Size size) { this.size = size; -// return this; return self(); } protected abstract T self(); -// Spaceship build() { -// return new Spaceship(this); -// } } diff --git a/crtp/src/main/java/crtp/space/Speed.java b/crtp/src/main/java/crtp/space/Speed.java index 36434ad7a3ce..0eb68d971ab0 100644 --- a/crtp/src/main/java/crtp/space/Speed.java +++ b/crtp/src/main/java/crtp/space/Speed.java @@ -1,5 +1,32 @@ +/* + * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). + * + * The MIT License + * Copyright © 2014-2022 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package crtp.space; +/** + * Speed enumeration. + */ public enum Speed { SUBLIGHT, diff --git a/crtp/src/main/java/crtp/space/WarSpaceship.java b/crtp/src/main/java/crtp/space/WarSpaceship.java index 16c182f00cb8..ba2c563dbc8a 100644 --- a/crtp/src/main/java/crtp/space/WarSpaceship.java +++ b/crtp/src/main/java/crtp/space/WarSpaceship.java @@ -1,5 +1,32 @@ +/* + * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). + * + * The MIT License + * Copyright © 2014-2022 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package crtp.space; +/** + * Specialized implementation of {@link Spaceship} for battles. + */ public final class WarSpaceship extends Spaceship { private final Weapon weapon; @@ -9,6 +36,9 @@ private WarSpaceship(Builder builder) { this.weapon = builder.weapon; } + /** + * Specialized implementation of {@link Spaceship.Builder} with {@link Weapon} field. + */ public Weapon getWeapon() { return weapon; } diff --git a/crtp/src/main/java/crtp/space/Weapon.java b/crtp/src/main/java/crtp/space/Weapon.java index a18d8302efc4..5c4a15842f6d 100644 --- a/crtp/src/main/java/crtp/space/Weapon.java +++ b/crtp/src/main/java/crtp/space/Weapon.java @@ -1,5 +1,32 @@ +/* + * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). + * + * The MIT License + * Copyright © 2014-2022 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package crtp.space; +/** + * Weapon enumeration. + */ public enum Weapon { GUNSHIP_AUTOCANNON, LIGHT_PULSE_CANNON, PLASMA_CANNON, RAILGUN_CANNON; diff --git a/crtp/src/test/java/crtp/AppTest.java b/crtp/src/test/java/crtp/AppTest.java index bb591312389c..727bdac8e93a 100644 --- a/crtp/src/test/java/crtp/AppTest.java +++ b/crtp/src/test/java/crtp/AppTest.java @@ -1,9 +1,37 @@ +/* + * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). + * + * The MIT License + * Copyright © 2014-2022 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package crtp; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import org.junit.jupiter.api.Test; +/** + * Curiously Recurring Template Pattern. + * TODO Add more info. + */ class AppTest { @Test diff --git a/crtp/src/test/java/crtp/space/CargoSpaceshipTest.java b/crtp/src/test/java/crtp/space/CargoSpaceshipTest.java index f1755942f891..907bf71c7f35 100644 --- a/crtp/src/test/java/crtp/space/CargoSpaceshipTest.java +++ b/crtp/src/test/java/crtp/space/CargoSpaceshipTest.java @@ -1,3 +1,27 @@ +/* + * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). + * + * The MIT License + * Copyright © 2014-2022 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package crtp.space; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -6,6 +30,9 @@ import org.junit.jupiter.api.Test; +/** + * tests {@link CargoSpaceship}. + */ class CargoSpaceshipTest { @Test diff --git a/crtp/src/test/java/crtp/space/WarSpaceshipTest.java b/crtp/src/test/java/crtp/space/WarSpaceshipTest.java index 1d76f971d61a..097aab947e7b 100644 --- a/crtp/src/test/java/crtp/space/WarSpaceshipTest.java +++ b/crtp/src/test/java/crtp/space/WarSpaceshipTest.java @@ -1,3 +1,27 @@ +/* + * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). + * + * The MIT License + * Copyright © 2014-2022 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ package crtp.space; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -6,6 +30,9 @@ import org.junit.jupiter.api.Test; +/** + * tests {@link WarSpaceship}. + */ class WarSpaceshipTest { @Test From 75883f86299cd77fb889a4e2c16c67a6b50bbb6a Mon Sep 17 00:00:00 2001 From: Antonio Addeo Date: Sat, 4 Mar 2023 16:23:13 +0100 Subject: [PATCH 04/15] Add fight package as second crtp example Ref: #2342 --- crtp/src/main/java/crtp/fight/Fighter.java | 36 ++++++++++ .../crtp/fight/MmaBantamweightFighter.java | 36 ++++++++++ crtp/src/main/java/crtp/fight/MmaFighter.java | 67 +++++++++++++++++++ .../crtp/fight/MmaHeavyweightFighter.java | 36 ++++++++++ .../crtp/fight/MmaLightweightFighter.java | 36 ++++++++++ .../src/test/java/crtp/fight/FighterTest.java | 53 +++++++++++++++ 6 files changed, 264 insertions(+) create mode 100644 crtp/src/main/java/crtp/fight/Fighter.java create mode 100644 crtp/src/main/java/crtp/fight/MmaBantamweightFighter.java create mode 100644 crtp/src/main/java/crtp/fight/MmaFighter.java create mode 100644 crtp/src/main/java/crtp/fight/MmaHeavyweightFighter.java create mode 100644 crtp/src/main/java/crtp/fight/MmaLightweightFighter.java create mode 100644 crtp/src/test/java/crtp/fight/FighterTest.java diff --git a/crtp/src/main/java/crtp/fight/Fighter.java b/crtp/src/main/java/crtp/fight/Fighter.java new file mode 100644 index 000000000000..2670db112c3d --- /dev/null +++ b/crtp/src/main/java/crtp/fight/Fighter.java @@ -0,0 +1,36 @@ +/* + * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). + * + * The MIT License + * Copyright © 2014-2022 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package crtp.fight; + +/** + * Fighter interface. + * + * @param The type of fighter. + */ +public interface Fighter { + + void fight(T t); + +} diff --git a/crtp/src/main/java/crtp/fight/MmaBantamweightFighter.java b/crtp/src/main/java/crtp/fight/MmaBantamweightFighter.java new file mode 100644 index 000000000000..9851107e8134 --- /dev/null +++ b/crtp/src/main/java/crtp/fight/MmaBantamweightFighter.java @@ -0,0 +1,36 @@ +/* + * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). + * + * The MIT License + * Copyright © 2014-2022 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package crtp.fight; + +/** + * MmaBantamweightFighter class. + */ +class MmaBantamweightFighter extends MmaFighter { + + public MmaBantamweightFighter(String name, String surname, String nickName, String speciality) { + super(name, surname, nickName, speciality); + } + +} \ No newline at end of file diff --git a/crtp/src/main/java/crtp/fight/MmaFighter.java b/crtp/src/main/java/crtp/fight/MmaFighter.java new file mode 100644 index 000000000000..65ab7dd90a11 --- /dev/null +++ b/crtp/src/main/java/crtp/fight/MmaFighter.java @@ -0,0 +1,67 @@ +/* + * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). + * + * The MIT License + * Copyright © 2014-2022 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package crtp.fight; + +import lombok.extern.slf4j.Slf4j; + +/** + * MmaFighter class. + * + * @param MmaFighter derived class that uses itself as type parameter. + */ +@Slf4j +public class MmaFighter> implements Fighter { + + private final String name; + private final String surname; + private final String nickName; + private final String speciality; + + /** + * MmaFighter constructor. + * + * @param name MmaFighter name. + * @param surname MmaFighter surname. + * @param nickName MmaFighter nickName. + * @param speciality MmaFighter speciality. + */ + public MmaFighter(String name, String surname, String nickName, String speciality) { + this.name = name; + this.surname = surname; + this.nickName = nickName; + this.speciality = speciality; + } + + @Override + public void fight(T opponent) { + LOGGER.info("{} is going to fight against {}", this, opponent); + } + + @Override + public String toString() { + return name + " \"" + nickName + "\" " + surname; + } + +} diff --git a/crtp/src/main/java/crtp/fight/MmaHeavyweightFighter.java b/crtp/src/main/java/crtp/fight/MmaHeavyweightFighter.java new file mode 100644 index 000000000000..bfee88f216a6 --- /dev/null +++ b/crtp/src/main/java/crtp/fight/MmaHeavyweightFighter.java @@ -0,0 +1,36 @@ +/* + * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). + * + * The MIT License + * Copyright © 2014-2022 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package crtp.fight; + +/** + * MmaHeavyweightFighter. + */ +public class MmaHeavyweightFighter extends MmaFighter { + + public MmaHeavyweightFighter(String name, String surname, String nickName, String speciality) { + super(name, surname, nickName, speciality); + } + +} diff --git a/crtp/src/main/java/crtp/fight/MmaLightweightFighter.java b/crtp/src/main/java/crtp/fight/MmaLightweightFighter.java new file mode 100644 index 000000000000..a968e2f3fdfb --- /dev/null +++ b/crtp/src/main/java/crtp/fight/MmaLightweightFighter.java @@ -0,0 +1,36 @@ +/* + * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). + * + * The MIT License + * Copyright © 2014-2022 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package crtp.fight; + +/** + * MmaLightweightFighter class. + */ +class MmaLightweightFighter extends MmaFighter { + + public MmaLightweightFighter(String name, String surname, String nickName, String speciality) { + super(name, surname, nickName, speciality); + } + +} diff --git a/crtp/src/test/java/crtp/fight/FighterTest.java b/crtp/src/test/java/crtp/fight/FighterTest.java new file mode 100644 index 000000000000..539d1d0718af --- /dev/null +++ b/crtp/src/test/java/crtp/fight/FighterTest.java @@ -0,0 +1,53 @@ +/* + * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). + * + * The MIT License + * Copyright © 2014-2022 Ilkka Seppälä + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package crtp.fight; + +import org.junit.jupiter.api.Test; + +/** + * Tests the {@link Fighter} fight method call on some implementations of {@link MmaFighter}. Note + * that fighters can only fight against opponents of their same weight class. + */ +class FighterTest { + + @Test + void fight() { + MmaBantamweightFighter fighter1 = new MmaBantamweightFighter("Joe", "Johnson", "The Geek", + "Muay Thai"); + MmaBantamweightFighter fighter2 = new MmaBantamweightFighter("Ed", "Edwards", + "The Problem Solver", + "Judo"); + fighter1.fight(fighter2); + + MmaHeavyweightFighter fighter3 = new MmaHeavyweightFighter("Dave", "Davidson", + "The Bug Smasher", "Kickboxing"); + MmaHeavyweightFighter fighter4 = new MmaHeavyweightFighter("Jack", "Jackson", + "The Pragmatic", "Brazilian Jiu-Jitsu"); + + fighter3.fight(fighter4); + + + } +} \ No newline at end of file From 97285ebb4143b45355ec2604e831d6baaedad670 Mon Sep 17 00:00:00 2001 From: Antonio Addeo Date: Wed, 8 Mar 2023 08:42:29 +0100 Subject: [PATCH 05/15] Add README.md Ref: #2342 --- crtp/README.md | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 crtp/README.md diff --git a/crtp/README.md b/crtp/README.md new file mode 100644 index 000000000000..8aeaa7387b5b --- /dev/null +++ b/crtp/README.md @@ -0,0 +1,59 @@ +--- +title: Curiously Recurring Template Pattern +language: en +--- + +## Name / classification + +Curiously Recurring Template Pattern + +## Also known as + +Recursive Type Bound, Recursive Generic + +## Intent + +Allow derived components to inherit certain functionalities from a base component that are compatible with the derived type. + +## Explanation + +Real-world example + +TODO: add real-world example + +In plain words + +Modify certain methods within a type to accept arguments specific to its subtypes. + +Wikipedia says + +> The curiously recurring template pattern (CRTP) is an idiom, originally in C++, in which a class X +> derives from a class template instantiation using X itself as a template argument. + +**Programmatic example** + +TODO: add programmatic example + +## Class diagram + +TODO: add class diagram + +## Applicability + +Use the Curiously Recurring Template Pattern when + +* TODO: add use cases + +## Tutorials + +* [The NuaH Blog](https://nuah.livejournal.com/328187.html) +* Yogesh Umesh Vaity answer to [What does "Recursive type bound" in Generics mean?](https://stackoverflow.com/questions/7385949/what-does-recursive-type-bound-in-generics-mean) + +## Known uses + +* [java.lang.Enum](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Enum.html) + +## Credits + +* [How do I decrypt "Enum>"?](http://www.angelikalanger.com/GenericsFAQ/FAQSections/TypeParameters.html#FAQ106) +* Chapter 5 Generics, Item 30 in [Effective Java](https://www.amazon.com/gp/product/0134685997/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0134685997&linkCode=as2&tag=javadesignpat-20&linkId=4e349f4b3ff8c50123f8147c828e53eb) From 1c412d07fe24c9cd60dc83b638b3cc16346e955a Mon Sep 17 00:00:00 2001 From: Antonio Addeo Date: Fri, 10 Mar 2023 15:18:03 +0100 Subject: [PATCH 06/15] Add use cases examples in README.md for crtp Ref: #2342 --- crtp/README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/crtp/README.md b/crtp/README.md index 8aeaa7387b5b..dff69115c5e7 100644 --- a/crtp/README.md +++ b/crtp/README.md @@ -23,7 +23,7 @@ TODO: add real-world example In plain words -Modify certain methods within a type to accept arguments specific to its subtypes. +Make certain methods within a type to accept arguments specific to its subtypes. Wikipedia says @@ -42,7 +42,9 @@ TODO: add class diagram Use the Curiously Recurring Template Pattern when -* TODO: add use cases +* You have type conflicts when chaining methods in an object hierarchy +* You want to use a parameterized class method that can accept subclasses of the class as arguments, allowing it to be applied to objects that inherit from the class +* You want certain methods to work only with instances of the same type, such as for achieving mutual comparability. ## Tutorials From 7656213f4018094167cd68ada1ec7c141ee13ab3 Mon Sep 17 00:00:00 2001 From: Antonio Addeo Date: Tue, 18 Apr 2023 17:04:52 +0200 Subject: [PATCH 07/15] Remove space package Ref: #2342 --- crtp/src/main/java/crtp/space/Cargo.java | 32 ------ .../main/java/crtp/space/CargoSpaceship.java | 69 ------------- crtp/src/main/java/crtp/space/Size.java | 35 ------- crtp/src/main/java/crtp/space/Spaceship.java | 99 ------------------- crtp/src/main/java/crtp/space/Speed.java | 37 ------- .../main/java/crtp/space/WarSpaceship.java | 69 ------------- crtp/src/main/java/crtp/space/Weapon.java | 38 ------- .../java/crtp/space/CargoSpaceshipTest.java | 67 ------------- .../java/crtp/space/WarSpaceshipTest.java | 65 ------------ 9 files changed, 511 deletions(-) delete mode 100644 crtp/src/main/java/crtp/space/Cargo.java delete mode 100644 crtp/src/main/java/crtp/space/CargoSpaceship.java delete mode 100644 crtp/src/main/java/crtp/space/Size.java delete mode 100644 crtp/src/main/java/crtp/space/Spaceship.java delete mode 100644 crtp/src/main/java/crtp/space/Speed.java delete mode 100644 crtp/src/main/java/crtp/space/WarSpaceship.java delete mode 100644 crtp/src/main/java/crtp/space/Weapon.java delete mode 100644 crtp/src/test/java/crtp/space/CargoSpaceshipTest.java delete mode 100644 crtp/src/test/java/crtp/space/WarSpaceshipTest.java diff --git a/crtp/src/main/java/crtp/space/Cargo.java b/crtp/src/main/java/crtp/space/Cargo.java deleted file mode 100644 index c8e85e1e913c..000000000000 --- a/crtp/src/main/java/crtp/space/Cargo.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package crtp.space; - -/** - * Cargo enumeration. - */ -public enum Cargo { - FOOD, FUEL, ELECTRONICS -} diff --git a/crtp/src/main/java/crtp/space/CargoSpaceship.java b/crtp/src/main/java/crtp/space/CargoSpaceship.java deleted file mode 100644 index a03becd3dede..000000000000 --- a/crtp/src/main/java/crtp/space/CargoSpaceship.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package crtp.space; - -/** - * Specialized implementation of {@link Spaceship} for cargo delivery. - */ -public final class CargoSpaceship extends Spaceship { - - private final Cargo cargo; - - private CargoSpaceship(Builder builder) { - super(builder); - this.cargo = builder.cargo; - } - - public Cargo getCargo() { - return cargo; - } - - /** - * Specialized implementation of {@link Spaceship.Builder} with {@link Cargo} field. - */ - static final class Builder extends Spaceship.Builder { - - private Cargo cargo; - - public Builder(String name, int fuelCapacity) { - super(name, fuelCapacity); - } - - @Override - protected Builder self() { - return this; - } - - Builder withCargo(Cargo cargo) { - this.cargo = cargo; - return this; - } - - CargoSpaceship build() { - return new CargoSpaceship(this); - } - } - -} diff --git a/crtp/src/main/java/crtp/space/Size.java b/crtp/src/main/java/crtp/space/Size.java deleted file mode 100644 index bf8c40507a1a..000000000000 --- a/crtp/src/main/java/crtp/space/Size.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package crtp.space; - -/** - * Size enumeration. - */ -public enum Size { - SMALL, - MEDIUM, - LARGE, - XLARGE -} diff --git a/crtp/src/main/java/crtp/space/Spaceship.java b/crtp/src/main/java/crtp/space/Spaceship.java deleted file mode 100644 index 106cde01e07f..000000000000 --- a/crtp/src/main/java/crtp/space/Spaceship.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package crtp.space; - -/** - * Spaceship class. - */ -public abstract sealed class Spaceship permits WarSpaceship, CargoSpaceship { - - private final String name; - private final int fuelCapacity; - private final Speed speed; - private final Size size; - - protected Spaceship(Builder> builder) { - this.name = builder.name; - this.fuelCapacity = builder.fuelCapacity; - this.speed = builder.speed; - this.size = builder.size; - } - - public String getName() { - return name; - } - - public int getFuelCapacity() { - return fuelCapacity; - } - - public Speed getSpeed() { - return speed; - } - - public Size getSize() { - return size; - } - - /** - * Builder class. - * - * @param Builder derived class that uses itself as type parameter. - */ - abstract static sealed class Builder> permits WarSpaceship.Builder, - CargoSpaceship.Builder { - - private final String name; - private final int fuelCapacity; - private Speed speed; - private Size size; - - public Builder(String name, int fuelCapacity) { - if (name == null) { - throw new IllegalArgumentException("Name can't be null"); - } - if (fuelCapacity <= 0) { - throw new IllegalArgumentException("Fuel capacity can't be equal or less than zero"); - } - this.name = name; - this.fuelCapacity = fuelCapacity; - } - - T withSpeed(Speed speed) { - this.speed = speed; - return self(); - } - - T withSize(Size size) { - this.size = size; - return self(); - } - - protected abstract T self(); - - } - - -} diff --git a/crtp/src/main/java/crtp/space/Speed.java b/crtp/src/main/java/crtp/space/Speed.java deleted file mode 100644 index 0eb68d971ab0..000000000000 --- a/crtp/src/main/java/crtp/space/Speed.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package crtp.space; - -/** - * Speed enumeration. - */ -public enum Speed { - - SUBLIGHT, - QUARTER_C, - HALF_C, - THREE_QUARTERS_C, - LIGHTSPEED -} diff --git a/crtp/src/main/java/crtp/space/WarSpaceship.java b/crtp/src/main/java/crtp/space/WarSpaceship.java deleted file mode 100644 index ba2c563dbc8a..000000000000 --- a/crtp/src/main/java/crtp/space/WarSpaceship.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package crtp.space; - -/** - * Specialized implementation of {@link Spaceship} for battles. - */ -public final class WarSpaceship extends Spaceship { - - private final Weapon weapon; - - private WarSpaceship(Builder builder) { - super(builder); - this.weapon = builder.weapon; - } - - /** - * Specialized implementation of {@link Spaceship.Builder} with {@link Weapon} field. - */ - public Weapon getWeapon() { - return weapon; - } - - static final class Builder extends Spaceship.Builder { - - private Weapon weapon; - - public Builder(String name, int fuelCapacity) { - super(name, fuelCapacity); - } - - @Override - protected Builder self() { - return this; - } - - Builder withWeapon(Weapon weapon) { - this.weapon = weapon; - return this; - } - - WarSpaceship build() { - return new WarSpaceship(this); - } - } - -} diff --git a/crtp/src/main/java/crtp/space/Weapon.java b/crtp/src/main/java/crtp/space/Weapon.java deleted file mode 100644 index 5c4a15842f6d..000000000000 --- a/crtp/src/main/java/crtp/space/Weapon.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package crtp.space; - -/** - * Weapon enumeration. - */ -public enum Weapon { - - GUNSHIP_AUTOCANNON, LIGHT_PULSE_CANNON, PLASMA_CANNON, RAILGUN_CANNON; - - @Override - public String toString() { - return name().toLowerCase(); - } -} diff --git a/crtp/src/test/java/crtp/space/CargoSpaceshipTest.java b/crtp/src/test/java/crtp/space/CargoSpaceshipTest.java deleted file mode 100644 index 907bf71c7f35..000000000000 --- a/crtp/src/test/java/crtp/space/CargoSpaceshipTest.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package crtp.space; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import org.junit.jupiter.api.Test; - -/** - * tests {@link CargoSpaceship}. - */ -class CargoSpaceshipTest { - - @Test - void testMissingName() { - assertThrows(IllegalArgumentException.class, () -> new CargoSpaceship.Builder(null, 100)); - } - - @Test - void testNegativeOrNullFuelCapacity() { - assertThrows(IllegalArgumentException.class, - () -> new CargoSpaceship.Builder("Planet Express", -1)); - assertThrows(IllegalArgumentException.class, - () -> new CargoSpaceship.Builder("Planet Express", 0)); - } - - @Test - void testBuildCargoShip() { - final var ship = new CargoSpaceship.Builder("Planet Express", 200) - .withSpeed(Speed.QUARTER_C) - .withCargo(Cargo.FOOD) - .withSize(Size.MEDIUM) - .build(); - - assertNotNull(ship); - assertNotNull(ship.toString()); - assertEquals(Speed.QUARTER_C, ship.getSpeed()); - assertEquals(Cargo.FOOD, ship.getCargo()); - assertEquals(Size.MEDIUM, ship.getSize()); - } - - -} \ No newline at end of file diff --git a/crtp/src/test/java/crtp/space/WarSpaceshipTest.java b/crtp/src/test/java/crtp/space/WarSpaceshipTest.java deleted file mode 100644 index 097aab947e7b..000000000000 --- a/crtp/src/test/java/crtp/space/WarSpaceshipTest.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package crtp.space; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import org.junit.jupiter.api.Test; - -/** - * tests {@link WarSpaceship}. - */ -class WarSpaceshipTest { - - @Test - void testMissingName() { - assertThrows(IllegalArgumentException.class, () -> new WarSpaceship.Builder(null, 100)); - } - - @Test - void testNegativeOrNullFuelCapacity() { - assertThrows(IllegalArgumentException.class, () -> new WarSpaceship.Builder("Gravity", -1)); - assertThrows(IllegalArgumentException.class, () -> new WarSpaceship.Builder("Gravity", 0)); - } - - @Test - void testBuildWarShip() { - final var ship = new WarSpaceship.Builder("Gravity", 500) - .withSpeed(Speed.HALF_C) - .withWeapon(Weapon.PLASMA_CANNON) - .withSize(Size.LARGE) - .build(); - - assertNotNull(ship); - assertNotNull(ship.toString()); - assertEquals(Speed.HALF_C, ship.getSpeed()); - assertEquals(Weapon.PLASMA_CANNON, ship.getWeapon()); - assertEquals(Size.LARGE, ship.getSize()); - } - - -} \ No newline at end of file From a7680bce133c4b20b17d72568298ad83a4530a28 Mon Sep 17 00:00:00 2001 From: Antonio Addeo Date: Tue, 18 Apr 2023 17:13:23 +0200 Subject: [PATCH 08/15] Move files from fight package to crtp Ref: #2342 --- crtp/src/main/java/crtp/{fight => }/Fighter.java | 2 +- .../main/java/crtp/{fight => }/MmaBantamweightFighter.java | 2 +- crtp/src/main/java/crtp/{fight => }/MmaFighter.java | 2 +- .../main/java/crtp/{fight => }/MmaHeavyweightFighter.java | 2 +- .../main/java/crtp/{fight => }/MmaLightweightFighter.java | 2 +- crtp/src/test/java/crtp/{fight => }/FighterTest.java | 6 +++++- 6 files changed, 10 insertions(+), 6 deletions(-) rename crtp/src/main/java/crtp/{fight => }/Fighter.java (96%) rename crtp/src/main/java/crtp/{fight => }/MmaBantamweightFighter.java (96%) rename crtp/src/main/java/crtp/{fight => }/MmaFighter.java (96%) rename crtp/src/main/java/crtp/{fight => }/MmaHeavyweightFighter.java (96%) rename crtp/src/main/java/crtp/{fight => }/MmaLightweightFighter.java (96%) rename crtp/src/test/java/crtp/{fight => }/FighterTest.java (91%) diff --git a/crtp/src/main/java/crtp/fight/Fighter.java b/crtp/src/main/java/crtp/Fighter.java similarity index 96% rename from crtp/src/main/java/crtp/fight/Fighter.java rename to crtp/src/main/java/crtp/Fighter.java index 2670db112c3d..675a3d97571b 100644 --- a/crtp/src/main/java/crtp/fight/Fighter.java +++ b/crtp/src/main/java/crtp/Fighter.java @@ -22,7 +22,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package crtp.fight; +package crtp; /** * Fighter interface. diff --git a/crtp/src/main/java/crtp/fight/MmaBantamweightFighter.java b/crtp/src/main/java/crtp/MmaBantamweightFighter.java similarity index 96% rename from crtp/src/main/java/crtp/fight/MmaBantamweightFighter.java rename to crtp/src/main/java/crtp/MmaBantamweightFighter.java index 9851107e8134..737dcac920da 100644 --- a/crtp/src/main/java/crtp/fight/MmaBantamweightFighter.java +++ b/crtp/src/main/java/crtp/MmaBantamweightFighter.java @@ -22,7 +22,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package crtp.fight; +package crtp; /** * MmaBantamweightFighter class. diff --git a/crtp/src/main/java/crtp/fight/MmaFighter.java b/crtp/src/main/java/crtp/MmaFighter.java similarity index 96% rename from crtp/src/main/java/crtp/fight/MmaFighter.java rename to crtp/src/main/java/crtp/MmaFighter.java index 65ab7dd90a11..437a82d847fc 100644 --- a/crtp/src/main/java/crtp/fight/MmaFighter.java +++ b/crtp/src/main/java/crtp/MmaFighter.java @@ -22,7 +22,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package crtp.fight; +package crtp; import lombok.extern.slf4j.Slf4j; diff --git a/crtp/src/main/java/crtp/fight/MmaHeavyweightFighter.java b/crtp/src/main/java/crtp/MmaHeavyweightFighter.java similarity index 96% rename from crtp/src/main/java/crtp/fight/MmaHeavyweightFighter.java rename to crtp/src/main/java/crtp/MmaHeavyweightFighter.java index bfee88f216a6..4df63ef14d9f 100644 --- a/crtp/src/main/java/crtp/fight/MmaHeavyweightFighter.java +++ b/crtp/src/main/java/crtp/MmaHeavyweightFighter.java @@ -22,7 +22,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package crtp.fight; +package crtp; /** * MmaHeavyweightFighter. diff --git a/crtp/src/main/java/crtp/fight/MmaLightweightFighter.java b/crtp/src/main/java/crtp/MmaLightweightFighter.java similarity index 96% rename from crtp/src/main/java/crtp/fight/MmaLightweightFighter.java rename to crtp/src/main/java/crtp/MmaLightweightFighter.java index a968e2f3fdfb..c9afd5481ac1 100644 --- a/crtp/src/main/java/crtp/fight/MmaLightweightFighter.java +++ b/crtp/src/main/java/crtp/MmaLightweightFighter.java @@ -22,7 +22,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package crtp.fight; +package crtp; /** * MmaLightweightFighter class. diff --git a/crtp/src/test/java/crtp/fight/FighterTest.java b/crtp/src/test/java/crtp/FighterTest.java similarity index 91% rename from crtp/src/test/java/crtp/fight/FighterTest.java rename to crtp/src/test/java/crtp/FighterTest.java index 539d1d0718af..85f9fdb2cbf8 100644 --- a/crtp/src/test/java/crtp/fight/FighterTest.java +++ b/crtp/src/test/java/crtp/FighterTest.java @@ -22,8 +22,12 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package crtp.fight; +package crtp; +import crtp.Fighter; +import crtp.MmaBantamweightFighter; +import crtp.MmaFighter; +import crtp.MmaHeavyweightFighter; import org.junit.jupiter.api.Test; /** From f957f11d6693b62498baf419e8d0fcfbbdc441f6 Mon Sep 17 00:00:00 2001 From: Antonio Addeo Date: Mon, 8 May 2023 09:14:47 +0200 Subject: [PATCH 09/15] Add real world example in README.md Ref: #2342 --- crtp/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crtp/README.md b/crtp/README.md index dff69115c5e7..1fda9759bfc0 100644 --- a/crtp/README.md +++ b/crtp/README.md @@ -19,7 +19,9 @@ Allow derived components to inherit certain functionalities from a base componen Real-world example -TODO: add real-world example +> For a mixed martial arts promotion planning an event, it's important to ensure that the fights are +> organized between athletes of the same weight class to prevent mismatches between fighters of vastly +> different sizes, such as a heavyweight facing off against a bantamweight. In plain words From 66836766f9c353f7aff42c8ceef0ae5bad209e42 Mon Sep 17 00:00:00 2001 From: Antonio Addeo Date: Wed, 30 Aug 2023 17:49:15 +0200 Subject: [PATCH 10/15] Update crtp README.md Ref: #2342 --- crtp/README.md | 83 ++++++++++++++++++++++++++++++++++++++++++---- crtp/etc/crtp.png | Bin 0 -> 122701 bytes 2 files changed, 77 insertions(+), 6 deletions(-) create mode 100644 crtp/etc/crtp.png diff --git a/crtp/README.md b/crtp/README.md index 1fda9759bfc0..8894ff485f19 100644 --- a/crtp/README.md +++ b/crtp/README.md @@ -19,13 +19,13 @@ Allow derived components to inherit certain functionalities from a base componen Real-world example -> For a mixed martial arts promotion planning an event, it's important to ensure that the fights are -> organized between athletes of the same weight class to prevent mismatches between fighters of vastly -> different sizes, such as a heavyweight facing off against a bantamweight. +> For a mixed martial arts promotion that is planning an event, ensuring that the fights are organized between athletes +> of the same weight class is crucial. This prevents mismatches between fighters of significantly different sizes, such +> as a heavyweight facing off against a bantamweight. In plain words -Make certain methods within a type to accept arguments specific to its subtypes. +> Make certain methods within a type to accept arguments specific to its subtypes. Wikipedia says @@ -34,11 +34,82 @@ Wikipedia says **Programmatic example** -TODO: add programmatic example +Let's define the generic interface Fighter + +```java +public interface Fighter { + + void fight(T t); + +} +``` + +The MMAFighter class is used to instantiate fighters distinguished by their weight class + +```java +public class MmaFighter> implements Fighter { + + private final String name; + private final String surname; + private final String nickName; + private final String speciality; + + public MmaFighter(String name, String surname, String nickName, String speciality) { + this.name = name; + this.surname = surname; + this.nickName = nickName; + this.speciality = speciality; + } + + @Override + public void fight(T opponent) { + LOGGER.info("{} is going to fight against {}", this, opponent); + } + + @Override + public String toString() { + return name + " \"" + nickName + "\" " + surname; + } +``` + +The followings are some subtypes of MmaFighter + +```java +class MmaBantamweightFighter extends MmaFighter { + + public MmaBantamweightFighter(String name, String surname, String nickName, String speciality) { + super(name, surname, nickName, speciality); + } + +} + +public class MmaHeavyweightFighter extends MmaFighter { + + public MmaHeavyweightFighter(String name, String surname, String nickName, String speciality) { + super(name, surname, nickName, speciality); + } + +} +``` + +A fighter is allowed to fight an opponent of the same weight classes, if the opponent is of a different weight class +there is an error + +```java +MmaBantamweightFighter fighter1 = new MmaBantamweightFighter("Joe", "Johnson", "The Geek", "Muay Thai"); +MmaBantamweightFighter fighter2 = new MmaBantamweightFighter("Ed", "Edwards", "The Problem Solver", "Judo"); +fighter1.fight(fighter2); // This is fine + +MmaHeavyweightFighter fighter3 = new MmaHeavyweightFighter("Dave", "Davidson", "The Bug Smasher", "Kickboxing"); +MmaHeavyweightFighter fighter4 = new MmaHeavyweightFighter("Jack", "Jackson", "The Pragmatic", "Brazilian Jiu-Jitsu"); +fighter3.fight(fighter4); // This is fine too + +fighter1.fight(fighter3); // This will raise a compilation error +``` ## Class diagram -TODO: add class diagram +![alt text](./etc/crtp.png "CRTP class diagram") ## Applicability diff --git a/crtp/etc/crtp.png b/crtp/etc/crtp.png new file mode 100644 index 0000000000000000000000000000000000000000..a348c8af6175c4c7c78e972a801eb33c6f549453 GIT binary patch literal 122701 zcmeFZdpwkD+c(~Quez;PtF%(7WV6~(5y>vuWtAkMLKH?T*$&2jFou?j5JJel2q7a3 zgE6BLvYiHFm@zZiZ)XN$X3UH+@7Sz$-^*I}?|JUu^FF`#{`}sje{{~wbzSGNIgjIe ze9!Z^qOO}7?)>i1cU!h>*=cm;(oNwX?JZlj)qML`;U`66!Nyy*JlJA%N#7z6FiYb2 zJ_n=wdCOu(xX#i+3)ACj;I4xs9htW~RBi&LsXGXd_wN7Y{)GeX?;phe#UaB${eZ)* zhaT=ft4lbzpNV<&qFhJK+ete+GcBn%ZKQZK^_Zoce`VGPhp$W8`IDdV8{AHl9zM6X zr0$X)WrBD*XdD5C=7cQ@mKl2A2&c3Dui~rp@rG@`j3Wlj}U&l-vfmosDJtOn+qvVSik;%i;VFl$ZvyZ$N%Rs{~k&^p&${fe9&w` zP`PTHD+y~xe(^z;8|ZsXTaSWk^0 z>kg8({`2eBmmtlrb=LgkK}Xcu%}*%g>Ns>ut$F2z@%5kY-H**yc8y<~oQ&_fTYVSf zf_VWqTzlR#&2=Y!Yyfw@M%a)gb3>LR1Ql88y2su({qLDxN=F_lu{bfhx-EyFk)Hlb z-JII8W{8}3f->jaCgG+GAda15r)`MHT}+Z)jjU~2pl_(jbqf;uJ|_{zy|VilK!u~b z=_1!lkc5TLms0RS?+`BDt)l6nOQ>i~%67B_Izlg!-V5@`w(f!d3>e;DtD(>Q+J|Q~ zq$kFb3^aK4GH-1BN2e#3#2rTP@f4(eWhf`EUu35e=)~LIUY-suY;kty%^5Q(Tg8*> zF7T_`&Jtb9-lE@n)RfFzw{KbD9B-FLOK`{y+<9=pUcgTLCnRbP_9@oKJ$$^A9vkM( zZ&q?vRS$JDC#k+6lalPhVF(rpB3NB|e@|3uZn_i_9L5=l`@PQ^ zPh$bg`iLfDgHQzvBj zgclU9+}0*QpsvGJBAZvs$;+z_Wf#dU*65WJ3G%l|FMR&)?Ri$_AnYMD%7&tei#cM) z%WWb*iohL@ilH?=VO3}+)NKQ*m%3jYGSew>QTo;`#dENi@*=;_{P)Z0c#}(+BM>6A ze%KAx6(6{`-cL%mKUU0+HJs4pEb`fxccEBq5&5wRS`GJiD}*T4;pUGPD#ka5CYX_> zqdcVeo+ar8OP>1I$rYnh6Ktt4cE@8zPDn5dmGDg&s>0DE>|*QQm>5q%fs*L0$Q-+# zs_A?vJv5Nky_AfdfuzbQqTBc4S-MpWk}n>8Knqc+^H`6mkcZ;#ltUjthK^;CFp6$9 z^r`Gk7CnUpkghujJykD0M5(qvWA0&rbOi7te$-g(qvUx}Rs`~R==;*Nb55Y)tl`Am zxtywp2}UKf_SceB65paenuC#CnY>&h^I@_Hoa3pqGetU%1R25oGL?(!j$?wt{B*cY zvJw&vq0>x%kEH23nF9oA-b!n8vmTj{ut=Kz8z6+&vy>LH9R}527z|I(eXaMg6yzTa zz1Uv-Fjba<3_I~Nwb$I1RO!|-@0+Iqst?1GJNYfTP~KQ9)So>croAcJ6kURpY9SNN zx{RM)g^L$c2#0AYOMgKW1jr~8c1#S#vaZ%4vTA}=WRSsAgG2a$1~@+%AD0~}=vMj& zzO1LKUE>tt0&3w7vCG1g)dR*xiH7X&Md^Xe&*hc)VUelW*sxF^8~mj^;#)~(=nC*T zzuBKcK5)QnL%~62_g#Kg%L1;npN(~%R|=pmB{TnBPK<-dGW!JBfBZf=;aN&-sk zX>dCecqa63)ux33r|Dgo(p6E0xsHg@VM!d3ox1rn&U~hZA2@#F- zo34^W7AKmGWZXNY6;Umz0~uqq{%AMZ#z`1b)7f`&_Ds7=8Qf!RZpc?-rg6JNUTWN| zZI2x^KBrP)QxJE6TaoVsiRPh}D!eeC;-gGRU#Tu-Apmdc-D7)KDjm&@mM4UP_0#F@ zEFzXn%s2#e0~VOu{ZLz}lA%Z_u@0TQ=iV4E3M)Q&^;%E(OP?vS8Hjbi=Mn^KoEl$N zY>Y1Nm7d9mfnK@cY! z=iz+hWr+UuO0LUnU_(1-mx&m8n`3-Kz)4oqWp$hh*HI3Qi!wQ#lwzi=&#C{=8EG1t z{%nSHj?K#U=Xd5C<$oo~#jZ+n{U#m}z>^SHY+C6;G_>M&L;|cyy8h?RBR3(F)*=_s zg7zR5Fh+1FzwW+R>ffXD7xi!3tfXTfLxp;G7|EeapGsR^`Lxwvf)WKK0!6H3wetcZ zT*~f`{eqpu$&2KiNSlwb(^FTS+Fpx5P zyS3lAfMy>yV%!4*_hL9-Hzh=LXd1D7&u5A5zu)oUK zFj7O&O~J(Wd`9aTLdJ{4x@~5jdI7Ai7G_*F^k=}GlRt-Sf|pKDS#37*^q=A4_WNmR zOUg!!_qnJ%V7rsKw@F&Xwud6H<^V19tI%%3ry^qD*#J5mONIy860qb%yi%dp%e#a9 zONC0EIhJs%hM`Z?&X&u1gJ?K9P(7^UZ8#)Yw9y(o2M(cg zk29Q@awabzdxR0lwK3dZD-N)<7+1#TG$HyloaRWIB)u8MnvOUm1eN@tQAq0#`OSc4QHTZsbT@|G=GU8p>Ino`++E1-LfDB%E%(1k@sT7@( z&o+Qt?FEjcr+Shh3)7>jX9&$%K@Ky;yYYHr5!Xfd%-9QE<$6Mdg^gl15fD4+wx;~;CD%Df}soGZ|%;r#~Jck@+$4j;Y|=TQJC0F+xu8? ze1;%*Heqyc+01py^F1k#*%4Zg=yIMqovRA_Qa9%Aj+l|w#jCqAUvIxtomnGg;~SQX z(!lp!3l)sxUV%pn!JD175hUBH{Y0rI3BB>RvAdKaN z%f=c#_VsfXNf{s! zYbUUP>(zHBYA1U@7sbuK7wsx}`l))SecPcF&mdmgq7*#n;1XP*L9(LBHj0>Vw(od^6LhnYxVD*rkzsWtoG04fB^~$&f?TZ94**q#tO7j?5+u zIcJ9klTa14$GAs+}G>-Y%}Rp<8qZl|&fAn&na3g$cs`z(7^a`8Ppa^6K@9q0B)hG3T86%6wnk zqjzQXGihMmY`E-){;?h#aSJna{)xw+Mhh`%>LBnms63Hk{67uugD?blJAl!zi&KB&1Ab=_1NfOp-b6` zTc6bwt(hGxJV0x)Z>Uiu(w;!BH+?wDKPIK8Yq z>Cm$QhIJaj%p{G7oZExe>F?0Od8(CcKf;8zi<@$`P#&c@!mY3>=e}5I6OH0qOfsVj zy0(4uQ2v&Z^d#LASgdGN?@8P2_reN({v-(YM#AliC-Wx{WZlP-D2*3JVp|Q`S(GOR z5OIXRsWdL_@Fof)A6L+(4H%^l-}O&dmon#VTQD#V!i`~%XBX-!A1&qoh~t{ z-<$I?cKzmDLa5H0diuK0gf|VFxND37eTg%;?;w!Fp|L)m8XK=kzYsko+fa+ zm~(EE%O&49f&prx?SG(PXgymK;+zdVoq~jf03~eZD=anJzQL2v?bHgOYI)P{z$bRt z=~khT7Uk@Bo2pk~s#-C*ewH3(g@GQ@0x1pjFU9(TL`Bt)ksYOSHz9=|s3iRM@Z9L2 zZ-CX(=hb~^{CLAMTR~HyxKg&%LCty)ewtI&lpW1`_V3H<{AX#W<5JYpGtC{L1R~L3 zjQ~CPE5k61C0`aYWX?k$AFqec?|)^v=3SIdDE`H1Mk(y9)p`c_af8GX-fds<^S@Lw zt*>vu`DedTSr6fxs+T7$8IMhYIalXO#_x;N7#GoQ+1~?`BZU8--zqT(j=z5M7NaNk zvzb)P@?^_uXu8;a=(F)AbqUw=H~W(FNJz7lO}*Oc`rjgqz^%{ zk^#Cn+r+M2$9At%t-o@aX_jyeYrs6uIucxmMvq|)lQy`r8r^#NdX1n)5&1UX*kkP3qRnAnBiabzE=QM^&I zxw$3&t*a5>Sy=d$+rGedE{#CoF{CXvVHTzfy&VPvak(qi2(aDmW9%TXIC&qL=jiMV z?K)g54zDLK(-2wCD|_*}^(E(S9$L%p~Z(md;*7 z%kR@~jfurdqKnc}Z!-5i-)ZT=ed*aVv`~yJRXV8c<*j{)Xs1(+Ubtnp|B_n+dt5|t zf6?~T3a4&T>400Wh^W%O$oFZw)7&7C7p>O-N>)(o>-B>O&QFuXtG%Umyt&I(U- zmbi?jp5ud=J7_Mo;aB`$^P1Y4jC(@0X>apT(L)83T#A*(HKgv7-tQ%);&u916C$^8 zroj#Fp3ok%blDkRSCLCII}Bv+HNi8{E2{IinyF4IUjfa2%+B@;>x?v5l5@+%*TYJx zPgQ+uw(b_twH3DIJL709xvH;PZ*dW>&2{mKU7e^`B#3s1YEayEo_+Zus!pyAn40{! zOj60}kw5`xYMb`TrfAR}ubSWMlutunf-og0byDrKu)_xxasqDqIldl4%H?9odJvcz zXZln6&Z9Xkd){M74~ukEtG(8fUB#~p!{|6c>z2L1#NM8fsVTM%u!Ipmnh?|3IUh-G zj_t}oaLZd(8kadq6zzq|9FxI)w7C{E+6yrn|D=T05L8G0q}4Q*KcojtB~>=E!rNfo zLB?0L$nJ3kK4Io~#4#==h~Jcqy(0fa^-`|D_PVXQLFGP+E~Oc0b#9o$ZJ^ci3G~a{ zykoYM-aD%Ep9xxdsF(GXaOaCni6)LzXpF%&nz z6vm`c2gb*+6=Gam!xUBLrXA||o`W79v2wv-lT#c!FuQ$h3^?A!FP0Csa$yeEifLqn z+`k7KuRN(Cw19LazzZ4WE=t~xgz#VHyHvuie(~mpsVO{F3+TyA5`XUZ9JJ&=1EH7> zc84xa;OtEF>5o}n{Go*Ilewt$#8)K@GCz`-vp}=Qm(@tNZj+R=F{6;@`ZPEh=_y)z z=Wq5kfECF7vF@H3At!G~3oEk*cG8lV55^N@RBDP8#wHR_sdSlCVrF}|X5>bbMp=qR z1G}xQjQ#c;*_Ri#PpFVe&`Q1?7CDS2tEi%1`MUadQxnF;ARmb$k#z0PXP#In+Mt&z ztvu;-Abaa~Rr$8R_vQAdSinWs+w~~pC#;{$v{}~6Ib#$)Ew;LPE-OrL>W4ZH0oT68 zjKq6W4G%)h8@P1pHd4v+=P#XpUPDXH>(iDZ7M+q|u_l!Ds>B3*m(s75xr(8YxLl zMi|jxe6j^a6z!gBOS#+rUDaBr4x{a>)P)m zq=S44-YeoS z9#karmxxdtLVCaL4ME%Z*iah<-A~fsV6-gZc=dP3?#!aJ-!+sJFZJy@?tdDDI=6_U zxh$`5gnpLYzDC&6%XO31zcH^{VbcGxQFLq>E{|p6~WK#SI~jx+sNIdQ9vP)9>#zJ`L)M z@m#^HnN$jSp==$gu;*0f(T6I@_fHx^Oe8J~VW|>JTemU$_U=o?*s-StpWddV54dD^G4T%f{AU>t%gV(a>DnWWFd5r01leN!W2J-7q2#L)5`q zDRWqp`E{%fVD(#U@i|4vP_W8H9nZs7F2+HxpPyQ;&PYANOxC&=IdR+oB3URvd$&^k zX8X7}|CUB$L1k$7P(TkfiMWGcue~pxrAVV@6&*9y6!Or_%YK+ILvmsb6W`oGdfixD zM2aKp01v!^xhiY#tSTctz#!9|I)aJPk>lxmJTlJE}p=271 z!#7_RIc?8d{BC_CFy&V;u3`v@?=-nWyQ&h;lFG9F#(Bl2ZJP}lqIm~Tbr?nj5!FVpvw-HI%zyQ}aFu*Did-4?7);8p2v73*7s*ovT@ad6AA@?12 zJ^XMKs|{g*=>|fbP6Q=Qa(|hh)C@7d1VMmnQ0KaBe7#s$zyzyu-i1Cw(pmKiA_{ryV!sxaE@z8u6Ft2bhRuo4HDXgRBO;&oRYTNtr5TPN=1+UK7WM-?@CD6$n zcBm?LhGMJZ0Y@lQH-0KSc4ErzfDUm33K(oafz|LiX_aNSy>KjFlA5)VJML@lp(g9F z?ayPDi#*y1qb5H!wTEeT8bR2K1mNJZr#1l@5IA-1`0X|E0C`}F2BTvFI=wBe#tux=)0kS*Lg=}ZWOYpiq? zM;GA-0hw-aeC?Qf2xc|dzH{!|n!tUiWhDfm11r^Y6UE|)M|z@Jvn4O;3(6bxxPgO( zg%E8|=h^uhhDbq}wx{p%e9er_)dIq+k@>%Da!KJX94a5nqT!5^$*Gc(O3$BPqcQgL z=OTwPhGs@Jgd}Rlt0g`AShbKL&sOOK1;bp_-4%{78?n*F#b$47!V^Cb8nNHf0hb_Q zFVqP!3IvXk_B&)vDP&qLX@B8!7Vt*>PVNlS?A?42QJf{=S)ZB*2S5z z-!5~JSYBJSDdml`IsiH>BfJl~_eoGU0(DGS7cj(21a4m7+)H|hh#r071k2G5EG<^2k zLt16j+Z-m0laYFwF9ZS0(?tc37<1v>5f_Pha&yp{*QbVN8(-GXPYUCgZ%nagL)u>I zwlNbBHCj=t;dR|)m*kO75}y5b?|NnRn+*5h;?a7O0fw%wKF>7r=3q-yxkHDNz}YwB zEA zblJy^Xsqxn6Cph7fS#RQEgC=&2!5OXuXL?_fIqH~aw#9bc${64T53kYhRF7wRp2M;$Oa+drpO}b+xiI~Cj2S7dvDGJFhN~;9~`Ui+Q zO({-Wtq}_y!1q%GmdiCrs?Lr=uH(ZiII)t{l~dK@8jbN`%N@C*IrglXB|U@^p*y5S z@V-E}uh5-tVx}i0cutu;wCvS5yhBMr(3zdwK&qWQB>i8gj8J+FFV;@ zTO-Wl;_WYr>okJ;uPhJKMM>2MPcH5y@d2Xay_Me1@=u=Q zGV0z~j()KLW1fyI(iNSpqpnr*u~jXnB`;jCNZ zHU3Z|$K7Z`?BT+S$5HWIt;|7G&8aNOE1T&eBe?jV5mD)pcXk&kL5JPiKkNBrb9(Me z7Oub?c@mDeX~f6lzc-SQ%d(OQuYgq?hm_#6-V%LYc{XO?E)v@_rV~?dT;D`BU4lGY zcd~ytJ}33sWPSDg{iK|T>&BVAU+d)`sQQHe+io?Cm3p>8)JLq#zBfe;*rxy(6n!nX z9JWrp%80F_7@0_IZjWXwX!W4)1@bx#x21O2epv`w1Y;4JdeCE>J*!77M@7~b`7`-w zLRf`Mm@%U#xixk58yUTIlHx(;ZapUub|vLm;~FCQY_;(Sxli!}F~0q4XL31L*KD>$ zJ1{AJVB@o(b?EZvpWSV3nbmY(J;M7SWZi|fNWB|%U>&YrJ;{3ky`BrUh<5w^_PhFH zYp%9M>h)CIZx0Sy-#Xi(eFm)Oq}28E8mB!fwl37%`$7H-)VavDT=~pwU2E?jCbTI- zymt{-PYKI_HiQ&8n(V+D-gx@23KP9B-7?#>G0hEfb&J%4-hYr=e_ihTMEAdc7rm`Xzm zZNHQrvVHZ7g@+r{+PD7Dh4qtUTR#8WjeVn~PEMsspk?h>J^jJ2Hd++$6CdSc)5?>Fu^8T|US zv*+fezN(xp|8XBh?LAZM(c?P4jlx5tt5-ae{%;5&D`70!qGsDSW^>E-<-B`GS&sBa zjXV82YmCk0u4Wzo(eKqayT1%-9B}u1TI;U(v-|tAkstncwBz>K!WzHpmH{oM^hHnR zEw+V$3BHTf@u_##57fl6NG@Cs$m!VoQ`_FuD;DwD%ge)JW>+xDX1YFKH7J3rS?odo zI?UK|W5cUi8^T$v8}*6KdSKqY5eDzAGY4BPZA69t^yOk=Vu>CGLubKat2+F&5p7rh zzoq%fdg%S&-7&_E+kk;1j{5rbZlKazIHo7po zu|(gjyYTK`J@nMNke@bU{F8OUX-oM=i2LupTvk^07%}>zBTaTy|JR287cakd?b?;ieym;}zA+T;_lP`Xz<|8 zpR4kMg>c=C`>RH5ayOa(!vWzx@RNJ@?)_9zdctryW4*^LijKG$)9J% zHC_AzZ)L;Aa@~eXNyEC?-Y=|K73Mcf&jgH4j$US$p1F4u5h2=;t&PuK$ zr(vD?P+D)U-J5w0o_ePFfI|nP1B_!j zPY*V&Wi=V4wMBm6gRn=};i+=ofwe0~*FoF~VZW;IL#MrK2j(BtuP1_ShH&Sn%FR#j ztzG#{d}HduhF<077dM`+f$N2JM7;N~uvNGDfJ*dQ*0=yzd*p-gqXZSx7250yNhUwGh}w=45*CVp@w^6q#m-2$}IGu$K?uIlqT zxN;blRzFnukk<>V&45Nvnq05C-!c>@+O6JsvXi|0smKnkFLHuE<7SM1D5pzT0CTjR6{x+suuSSC9@77={= zBlM$=x#%d7moe8r+hgDwq3(f#T2-rR17+1*$**P}io`{_lpzpwCpJpL%*SskPmXE= z2wLO2V#~n0P1Gdg$Yq9bhbe=!s-N#7CB(Ii>!j@T>1pP zE5m!eP4^!>eFS_~sgBPWDD3e$4>rJ@ZTVl;Kqy(dVjYyF?Uc z?Ak3jo=7T};Vj-f^=80}J4AFCIYdQ0J=yO9`m}wTvYexWB}c|oAP%amAAA3YCD}an zyid_xbIxRJMz3q(e{+Fxm#7H*Gk*R>Em*b?u8a zCwaXW3u+XUsSgu{8UWtfZw9z|SkZ%J6q2zQelS3ms8OA}JQz^so2T1OjfvNk=4-kmUF8q{cTpG%A=XaO2@GGjYXNd zb1zUI)W%|yKH8Uz?-d=G$?v$^6X3|s%$Gz>y`JU9rO1ulI&K^vP$*iv*tIw&sdrGB z0I@E#8$9Q@kjsK;U6dM61qjA)Vl##NMf5AiI`cH>J1K|iz|2KL$`5GBbz5X0dqN|k zJ`Fsn3CaTI*k}2EcF9A@>Fp~M2BMZSozJMJ**4A^@aJ3G;|t@Vb03C(02v2%CHBP@ zmW_oZkXO(K46g|ZtvkN3Qm1)jA;>wqHFazywhJ*~QCQJ3#F&h? zB-U_U*k2s9ZaGnT{b?4s>R@^rEc+J+`bTvr)};RKadon3}R4qz62MW&Ke-+J#{NNnM7SkD6cbnr7ZYksi7!+!1wD{EaM>#PwFaVHewELHNTZpqxZ~% zDVU7uN}?m^#A+ygp5(tg_kjcA)ryOrrlKG#eoLnb>`<@a-Z5U9$P|+m78HtK`~X+{)~SA; z{EGFZXeLb(mQB6FPp^QqJ|D8Lc4|rh7ByU%T*;#O=479HSH?%>Wlg}?J2UIq)7hG1 z7e$S<>xzwe?Cb`jz!F4xIAfP;CaE`%ZS~a>zfaZbw&=31;`Js+Y8)HMzYO_C8r#D+ z;&IcuQGeZxUQpf|tw5j#P zC5ZkRe`3BL!Jqx9qNV<&`kOGM3O}Sqs|EjD#4MJDuBWiaa7iG9rLMO237B2*k`MQL z6x5!z80OC$DOHj3+*$ZKfSJ&N1oL=gd+pg7{9BGH<55GlO^!#JPLTC2YfT`&*6(UR z1>!aIE^k3f*viQ-=(5Pf69q{yhnb8B-F;;>Kaafvf_V*fzIwjO@iDBMh*vI4wJNX__^d?Op*!| z`f+JN@9gQFq7$i4y(|xs#CJ6)qt3EjLynpm%(U6bDN!U($cm6qgaLGQ>9VU_P?t;D z>mW)*L9E?I|>SPwm>b48)fJX{~?_tPXeu#?`2w*PwUrI43Pxs88bQ`z{MJo zhL0yYR$eUjDg^DNCYxlb1{ryuSg!I0o@Mx^c;(ERKMjb`aaBrqQIBSX3an6kJy)wsJJxT1fZ%IxqE}~99;&xs#&A5<(E!vMB;qORPSq`cdsd5j%HCUBY$A(7 zR;@X!UFR+&4BN;=AkwCkR@oDp;@&bHpN9Tr|EzN}QUk zq!%C${U~8*WhE-;i|X~irEq?6j;JF`F!rePb@Df%m5&+gUb6(h8UaS^%PcB2i($!{ z5R;02Ec1W+=JWRP@Rxzjv=W^uJ(_dIOr&S9pQVPGLTQ_>*XT(Qpql^bu~wrGioBu( z0-P&%u(TO_?R>t~*8q~Xeb1Oldo?PIX4=OKgV0IZXkM)A#c4CK!p+!N0&K1fB|Z^0 zF~$k@!rodlWe^>Z@YO7R-i=$m>aSn$BThajx%LsUC1JPiOLv?hxW}v#2`~9kWBC*y z@ST?Adni`-G^s>Kji807@}A^&9J9*&e8~!|b!%L=_w<{A<=eqCSx4J_5vHe39-POa zKD^#1jMqTkedxe5$-gyxO=6N~tmnQLo&i#IM?E`*3+B~Tn@SFy-BYyR133QkBeN$g z*sP~SU8q-htq7=~jMWWu9mvQ&AoOYGdteMbq+&sN$nJXGqSrVEUt8t$ITgAfEe{N@ zC^D{=)C$v*$3wpObNS32hpt}c_Go)v{(~S*+Bn#Mf27f`t|YK!KswAY}9H0o$Y!Zmq0n52hu4z zLE#G;ruTDEJG5p10Jv2-&4Nn^*0mGV;2Zv?Kaid@^^UHL1q6PhbxSr9CY|}=?)(bY z^7e;e^IX(uaeVMi8@d!!hts=bMytx_vxJW{z>@w8=cx3Hw3n}c#@a|u)J0ANL)jQ8 z95Mzk9;{y|QW3WFs_1jeAt1>*uhV?6bg%D(TT7Q^=hy%*V_s{m&iY3T>Djzs1i3g7 zFG0=kgU_Nf0lqVz7hZ{)?g&3AfhiC}Wvi4(>$X!}u>cm*QAOo|@Q4sL5p|lW-yWxZ z5w1}ba@Cg@e!PTi+u+Y8Uo1QiS_zanihNfY`r4(89od3#4+f5mytTLHDPYNOzrlAq zBkRIw&!CmgeJj_NmTFwec%+(R$NMx;P(b!`aCtzGfoVbb`@nv9lsmQZ}H9*hGr z%*kZz8K9IyGX6%HQt=_%UDz-zb0Y1mFSGBVvu*=9<7B^&jygfB7Pc643id<8Pwz(a zAXAlD1FDXn(F5j{oDgn*%Vo$>a>}QeOOPFU^^6x1i6saDig|q_uhmZhc{(DdTd!~@_DQ^V3wmUiQ z3l!E7{oO16{4T+A)^z7Xc|mH}z!Jajq6u%sW&|dfNX|{W$QH$X8C;>PfyFCgk6o0m zC~Cjh{dY=gOMyQT69W@mKx7`G+XmC1QdvFq4f^Tx5dM9l3K&{cj4m4PTfhNYcB`gy1L}ZPL4;Extx?( zk$!y;|0kFZ?s-EfcJzdOS2XLVGBwH1+8|I{iv4qix;y9!#Lp9DDnPVlxh!yE?)xF` zDzH1#eMxw#Y)=oEaz*Yso05^keLG#{OfSqvu}92-Kq*P>6yb}4`no#WBnoe-J)L7d zyi5K?Ij|dmYwk(&n(JYX#cSH^eqO4X9NI8veHr3U?8--wr>qmWJROWSvpB+ZiFzn? z_MA_-+{}kiFf0d1sek=S6(W%9cq8l|dF@H7V~N>8FDl9Ol9;VsmOZCNgUkOwc6gs> zN(hQwDIj~3j&>@`O}fH?ZY8WHG-vIymaeHyGCQ(6i&gFH?}yyMF;Yf>F0MHLgcjD z3fiMsy0@)#{P^$t?)IT2roL%#$yv$75zNa@fx|BaF&6A3Q+XBLsBA6!ki{+umExSK z1`PHRB)PO5Ax)h%@tbjvm2t1({sbQXyerIgSaJKKrK zZl0~qnXvA;MEBWTR3ts0I!HJZ!d~o?xzRAixQ1g3#q)C0fM!QccxDkSau}xlGB+xx z`}x<5QiSgo5=Ib{353Q@JH2;mS2_mqS)4Cs8okaSQ?q9;s>k}LzCo&=_9&4IUMK|M zMr4`cgk)qq{|qk*jM71v(d};X;Yhx%Fz-I^BnK4Ckl$TCZF~;&)=M+n)c}gUvl7#E~D36lpbTqnd6gKE7JR zx$uUA5DLLG697Si!LFi4^IEUeg@ed0vUE*v>gtO#d|Cea*;)tc{9(}6-ss^)*G2=R z{?<-%|0fk&T$0=sVGWF8FU_UmSOHYv!KovWUA~tg=IU7zw`NJGzFH79vsIJyI*RfK zq)9oMrd=6?0i7iQJX6?PqZ-a7op-~4KC0Z$Q9a9eBn&GZ1PJqntiND3W$@Oj+3qe( zi|I`Hh6XYHco_^EU`bnB@u7lFJ9Gf076`RxlF?ALq_-$xmrUj;ywtf)nv@11X<+;T z^?nTfal3LbhJNQA$97H351ITl@vkhsnvh&*d&JHe#9Q}6KEy`SOkZ~AU_Tj6?qVZQ zXg>fD+Br%XuWpiHW!5Xt9s9^j)i9CtAv@O;JEzIqP;)ThwOE;(IbX}7I$nmbJu^Y} zdS#bkR%iZTQCQ(yZ$}2%0%0}JjR&l*O-98d-XlmsGz!(QJ-$=d?)mt3EZ|%$5%#^R zHD6Tsj%5NW=zAet=C ze3&1Mqggac{SvugTh(zh&B~~OKUj;sYAtVG*_~Y>J#Yb{iJ^qLsVa}awSS9<5K0k| zyZjW@p)KqgD#nL(XLx?Di|>$_`rzbnkos7~bs>`}qC`Ht9|jE?`8balH!1iE>!fT<6AiEflZ z--VcrDZRm$*$@pqPs-T_*fF4BRUC%tb!|u1LTxR^u_Jv#_);KZiUQ17cP#Ud1-*E@ zFr-*F%$J?jCyTAxz)9MDLG^g@&eF=%x7L*bxbDXuoocn-L}}0MZ7JZ* zujKP%RsCnyee*KH7sL_NsPi|nl*b1)Q#VSX=C)YtzM2Z3=D6b8$VSH{-x^tnoEUO@ z_;6i54`X|-+TDj$(6QCBM0eV>VYqr?bm69unO8c$8B;cYawxtPI!MZKTcG(%LLBZm zPJaj%a&k`OI1Kk=>8lcH1;to$2_*I)c(dC&U(=R7;R!AAm1&=$(vb^OSUwW$Y1`mE zQjOxpXU^2+Omlt$E6%3f$n95=75(Go?y^@*q5Ow1;?x9nY?>PO#lH?}i6MaEdTM!|I^zM|HZwN zq$pO3aQjAiJgA`DyLe46fc3X@o;a800;&{lw>V@w3t!bLzj~DSf%y6vqwh>*3A~jY z@o%-l z?bU6pKWKt6j0M=;ZpxLm0KG}8KvpZ-3SY?z^Z|eK;N0)wG~)=CoY_`Vn+bbhdAK3jF6;69*+9{Ivgh=WSx>F{arkw1z~Y(oD{`zu)r0?4zFM>N6=_ z>CBRWN+n#Mx{fYhVlPdMc9145wNEMo@)IEOWldd;hka9ceiGnL=|YQIkq0FoUB;DK z9?R-N0Ar*DlE!lQUVL(jc4#E_yJ&gfM5$fny<0fra~$K*i2L3beVT@|w>FJc5^iZgP^aa)s!GrA^p!3uU*Zt-WOfoJWZZwpE#{ubal4ih> z=HR=OYH1T`SvK*Z3oWs%zbWy&?~sFlcPFN-(r;qPpcyNZb{$;hw~6$={I0o@=_1Tx z^26@rWScPSN@n2gF%_!dNTRWB9WKYso0dhePGE=^0YaC$QN4YBI6Sx#$@V<|(|624 z^gDm20L??syMikDd=!;9amzVpdb@0==90lF;j68RVjU8sQQvADi;+l_hp}IeWdYMb z-k}pG7-Mp42S0yvY{pY8+1_I1t5v15efHVo8lNGThsuWzu7t8?2a`lCt6utXBa7~V zu2VCDXsn1nP-zx_Y|Jd$G<JiD+vcSRZs5BBNn8(qwDrso&Ggqc%IoYZ#J4_Csg z9XVY`t)yPZ)p1(e>VCF5VDVNj;kzi9yIWwKylAw%+xXic=xv)O7y4Yk*Sa-B%)$%o zCVGAW(V1)_;A7-kPwwBHve|`x3pj&u?s88*r;KP`l~2#C!A^rc`Y>AFxKQ%y<6yP2 zR1?6hLyE$^zQ~3Y_4{1qRQbN~z1dAom8q`cT#T%LMp)2>0vcLZ0`Bovp(WqtR@g?a>k% z{-J4}A&^~)MW0DS+tyl0y1^Pl{sNn-sIkU_g>4!4z*Z?ZvzC4W!+yWyJG{= zP@O$_lJh|rax$DkCbV*HS+UjB`0uI%I@t|+aN-Wk?rb@28=B#Li|U=)b|5d4AoJ-D z5KG1a=N-zBNu07r*e=&G`wQcZ{}*}h8P(Lf{R^|VM>$(iwj!d^R6s-o6a=KJbP!Rh zbftHsmjJOL(ve<+Ql$h00-*-!(t>md1O$Q5LTE`yLdabR-s9e9-~S!s9q)L*ykq!5 z27_d+XU*rCbNbO_6*?y%Kx@2$2nlT%9SYB5?$0!O6s-MR>&@?*rMgj z#3gr`SkLrL1!936&c$IU+1#n1BavC-OA2S;D(2VXIu}1G0YlnBNXQi3AWyHptnYpwI-SmZoAVGmB1suQ9^2Z8K#s zFL8b{>}g@@#MzR^RTkqt_L1``@+wL#L+iSlUWVrDel?d2Cu2;?8u=n8>c|7GUmEaD znvURZiNCS!roN5n)S#b=l=igVS(&pQ2O-`zk)cnip=1wp zxY@3j*r0OM@2_gVN3tSZ8rH)Ly#mMkr|t|A1`9iNG$i)Y7W%m4B5}>~Vr!E+CfcWY zY~vg8qrI48TuVes9IVA|p)a&LlPfOB5>?g}X{ zgo!%<*4JjPFCj->d|xe9vug9*wh;tt38uj}GPrZ~S}2W8byB&|0LrvjK2B|=t+Aw- z{eFNtEBkUU&+Uwf)DX_JsoJ@38M;A38~)ZKd8dww0tf+h`e6grydItI@;uftDz`j` zVPz#>2#gDXi$oJwXuG}3AB;;~T{-G4nTVxONZI^%0Uw<{Vplb|!J{KKZ&Li0s`&NE zz%?UWwqrGb(Bw&qH8pdiX9|LQenAwBew+Hzb!%1{c{Uzciq&>Z&;o@IYFu+P( z=+=(z=#B(XDfxgHvvGk^89SGgqq~{Fu$F1EzK!)3yfMR%Yps$@ZaP9tjDPLe?6DB^ z@G=Y5THaoG13)rHC%UGo9qT|~Od|t-*Li4SR8E@CFRyxq(=r-ME9_7XBU~w^O&baC zfi*e6hIN#?)D7_cTvt}GyjS;|ax5*zjMg~P0BYP@m$#ZKn{c1=)qf>ozZQA_-YAO1 zbzuUOzglhTv!0al7)qjYw<&NUi9n6?ur_P?E7)EWN^|Yy3(|+@m+rOD>PTCq#?oLT zJQ>=d1kxEnI|BK*yEAhbS7$J>2fh`USV#meLuFj2?jvGQ7`m~q-| z{1&^Zz>r zSRA#iP)&#m$3n>7(M(``8&G}z6j-I_D}xxo4`nT2KKW&Ci>cVQwwW%buC6yF^*5~5 zt2bS3dd`_t0OxtL*o>ry{8inG)kiRckyr=(y_wR;iDN;?(`#{{*!&Bpv0{9ArcSj$ z1ys{m?3)}ci-LN7j~CtF;F{={so%=_r*Otd8U+8evX9y|><*$F`@ zRU8{(O=1vw3llfttBT+i9N-KH-?4*wG z_Te2zS#771B^4i%+sj_q`gkF3YJ+v8aNiQPPok5eTn$IW*O9$^$M=mfyG79Jch`5p z&8}jBn~GLeiZ;skTQz*|rJcHXNA;~z%ykabE)YAbm;MSl}_cU%p`NiWfOBf)MkiRNjg_UGG6nf_t~Q8)iaDyZ@ycqpAid$ z^2x5Jb+xaW`XmtS{8yh;a<5mND>r@+A)AH|gia33t33L4q96Ddjw33@G7usJcU9@b zM)!sfx8 zaJl5IEM7RidN)T_Y}DA)lW+Z~3MkgZPC6Ur6Llrp+h*Ql{#kWt{4M8PJ1rAWLe;U% z0lxFKqHn17=nqu2rcrByE;U-X`211L2MG)($7@3(P<%5+f+2gF{QdoA4x}ZHCC-HY-wRU~9@YNH0O7X@~8sl9HVB2m+ z@=?GK#-pP_=5?cHVvW5@(@;3tyPzbq>T}nRO%0=^w{5wuF%Ni~J&Lgc%}z7X}42Cc!E>pOyTybi_T z7q9#P$N=elUWE+|-Um4)f|9P#-Ez6GX~=u2wgX3^iwJ=`#!-FIm-e!xNou4tW~*GKQ> z-I`}?md|0OZ?F_l0`W3;O-S$PeY@T8J}@FrwrfSIZuxA<_4-BJV0dD$iBW8Yt70U9 zGxO?@^SO(*`c(i?N!{=eyQjTC39wAkf}OEmHvT-k#f?kHsRnz~-q)dazep4D1!QZc zZC#h#)#{wd3llXvz!)C%*NE!PZ;$W3rAazfzCy&19u4^_-11e}p2f?)v-0>(3g&eC zXh^ZIdT^jZr)&M!kL*WBH|9AKLC}}77p}E)#m5m|IzNW-rTAmJ{9I}2X4OL;s>q_Q zr|#T9cF`e6CuBFc>SUze$@%I%(&(2#cp_6j@G+{&sKm?k z5x7P%a-XE_Fl})JBzd6LCHU)Cm^#eXj$}-G1KOrWUX-Bq9tY;l<b6v5~ z&Ao04I5OkX_S8vG3VkF=(?8L4`daD4bmLCI%vap7rfdPbZ=o{CK&q0fd*x7t|F``e5H9$p->j0xUu&U7 zWw3WLf$^n9$kI$hXHIfF%$86SPb0^_S~H<13btAasDNHvb8*}Hk|o<2lVIW}NBvTo z(E>)EkP~-RB#B$WFw4&UtHt@Wja#-TdyD~+AG03(mH=yf@9wza!^npcB~UfiaV)Wv zp%`*|$z~QqX)Nel)rHftQu^;TJoGPjDp%AYY}cD|V(EJs#cYM^>TH5w=gvWc48Yd* z5CO{baQkb=SL zTi18ffkEwYjHHDI8k~|yd)V-fwj{Gr88~X^u$7e9ETWT7`*-b_5@>nL+ceOb+<9-H z%Al*e;f0-6;MHfyufnVJ^#aR_hF^FMg8G9EIu{%AltH2jET_7&*UHOC$)U-B|I&rJ;5p<>}2g zH>`rrcpN+)90hc_vnCKe%oLf@l6&cF$xplC%|jCJw@GPlt2Ww-@>S@f7D?X*AJdF&r*EONP-b)J28S0BhyGAJXN z6&JP=6YEp#g#9pJotIVAx?6YCc+z?(v_B{8v^FPwLIos(>@`Pi1Y$p2^ZEitnKNcJ zG!83*w3nE3pV!|=b^5xN4etsUx*wy#6j?;={Vq#FNsi=wkS4a{A~*#fj7%9l^zyb? z%k}Yp=J=JVBAE+~o&3D3it?W=OI~dlPc2AuT3@XxlIhjSy*rvc6B_?iUH)I;a1B`V&rDaXczXz)ovqxv(3y z5PodTC#tZ2s`ZZZI!(FDeSF+~yl6rc=$KM9){4*66CkC>QX?!|!QUpKVAWnj#9S}11Kj<(p3`nt zb2oYfkS2qk2yG3)OW3AsLcl3Oi(D3*ShaE`p@tN%`96nJ)nAWJktHx|W;O0E=zd7& z*X{0LW(qKmD}9AF?!e%b;JQYU&h4wiW74~)Z30Om-xtlT&Gn+F9@At~eGSw14aW0I zNoHRHpLlLe7XNOV$djwfiJ+J`d)nmZuSHBDL;{FN?&*lyR!rT90s9UIYvLDWl~GN6 za>@94Tx$=0c|3jg->0UkF~03sHJti-n`#Ohnw7z=35@TApE)~`n2Pl zydiTdD_3P-(ka)s$6ViF!{PGi%O(&nK}@Ai*U5BfHJ5YJy6QyDVdKvI$IxX?0N;IvoMjWP1wum=3*do zSIO5Q@8?$!#z`ae5RvvU_{B=(fG@8zZmU?>eB5VRoqt2sy&Se?*9VrJ7+dY-)NkpK z&q)$W&%`uZCv+=|2=5jd;YobE{a*ef`ugRoiY*D|w|4ZrO$=f=aFd?2k=&%msZZP! zd@?y84>_}I;_*9>C{wwS#WKf}7~{!7vmuYQk(^rWpl}hD)c_fKZ)({550t!O5bR<@ zb%_V9>4gSssfnc5uBu8x_r;**H-D1eJ;5QMds0LS+<|C#{$Qo*5q#Rqge^0$|7|Zs zSJs3r`X86-4;Eu5S{vAA>LYq>cab|VGyl@U+Y}4LW8RTv3B{~|ymP$9kKCIc=%^W& zx3H8)`whlAU=m{1dbAVHiFL-L#v3|(vONlUUFWG$b;Ww*9E0@z8a;Q1)H7H|L*r7- zqUbN|A5E9&6B%vdWF_FRyu#XR@_Z8(0}sB&G3uv@j=oEP6jM4Sl5?@CvFFjKe97z3 z)oR+!JdeHy!^Yc1`W*+k6pT|_CahHK^@Y)Q6k6;#O)CCOrU!2{+^-N$DS<-wwg_em z{C%C&$_@{dMdxElG_wyFE1#m}tAZSxnB$RDLPEc)yohxYStE0Goeu(eD{~Au^K|O= z)4qcJN46`KDWLTuAv~Rl#m&FRt({1+vRq0UoQ0>|HmqAccW-*Y~(eu|!IINvpgBrw(QU&kt|Bv0Hz$s6>X0NtbBx1Hh&m|kO+}!Fy6D8Y+D{87?Xw}y>Xq8T_%Kv19CM7&;BTa!)TX$hO zZF$1qJF_1DxyaLidDNf1vpYz*vy4*PsKdVIwj>cSeR#Rs5Y;>==ndC3u2T}x35L@{ zDnA>9U$P2b5md++munI33^F1If!^#G1PGQa=FdRm=C7e>r6Xf z(mX)m8l78%?g{B)Biu0>~hyrz!!wd}%NKk+^~{PF+0kIz;HIWr!6)%4`Xxn)O|j-?#GrDY3t3 zZ-4)#;!w=1sHlKKomWQO={BI1m3p-ODId?P%MyU~dj91HQ49Pbur=>kNl8n?T?A=6 z-??ZzeDdgYIofV`U*lV!v>Bh)<3luQR$6pJu~X6Bk1-=|`(s9)Up>TD4nAPW4!6}O zuVr=P+=le&AJ1==8mMz&f5dy?OWJZ~nyn_Z`2ni*6cYIKf~}|<^p`^GETT}@P(3n~j?NeS zm&f{+a4w?v#^LiYRqQuYTS&B(_An#X3hU*}sdB9-$ey^V(sO334Jf7>XDEV_V!g|- zG;J$MLy)6pXO(Ud_wdI$MBYc%-{~yEe%WS!yT#^cLV7`>t*LsM#B^LXZcD#Re)PR3 z$W#(HbjtBJ*GbisH|*B^ zsvQteJ>R53Ly;hzHH0*{17T#m7?rZ}_}tF0{>CSmFO)=tz|iba>7d)CUoI#m{QDb~ zuXChUbdae%Uxkpgj5|CXe(awAzRn?f^jf#rVug%e!A8E8bOImdxIvLq6P!S*lYRP8 zN~dvadEow=S1Ixh8I;?4o+;2g+ zYrM@oaVLN|Q(lwRoD4zuKg+oXX8j)?z75Ra3A|9NZ5ZxfI6IeFzpRg(VF232We;}@ z2u~{KTUk>l1lOWas_0owG;W%FMQs;uzGL016ozNwgzbvUF=Mg4XB}Na9Y^P@)MzNm zt8x3AhSfVok?hE4Rz?aHyu#Fx4-2-^+TmRpnxH}z2*o@wFH0shpYDin<|!=n;8i*Y z=NRxL;K)nH>{nDw)jQRiQX4e_pcze1>W}=~t-r^edq&m>p0uzo7Xjfik57+?N9f+VDuRj*PwoBm zvVXEE$vPz@aRfH@N^Um1slMuRUi2D_;amh<;^+3e-4E#i_e?#CR-0ZvD&v4W=^^B?j?aO~G9|1GGIfU;`1`uJ6WlUIFlLQ`_Ve=&uTyAAuw`GcCRQOVP3Yio;$f2Z{;B~?{d~;AcF;G$XevA&*qGrN+gZ^uKaqK2} zq{8ag6RDX$Fd!$OaP`?l^z zQ!75hfe*5-{iZ@ZDH#3hHb(TiwKZ3{PAcCdV!f5*u>UNz}g z8;Homv;nt)C6%@9){Zu)$4Cq(^42du;tVVb5@heu80kCXU1xPubF~2cA>nld!A5o^ zg5Z73&4MX zWn=&+vwJy|+1mRO?phQeh6n%jIE$Q<-T{^A*P*3l<~HM^F=w+IYWV1nS2CXi>=!?3 z$G1KJ!rGQ%tRGDns=L4!N;q}b0x*z!R8E3WCGH~7%e^%4XkLCaJ8anDZE z`SD|1z|Wu>C+%=9Vx>7>`!#dtO?aLGJV#X4?t%; zv?^-FwdDO+9trD?2<rQg&{}fu#c!j+JrOlov=7Ph z9_9KH(^KAN;|^7g0UKQwFbVJa_H*9v4=2z5EKeD1b0jniY!{X)>YwcvFP1+R5bs|r zVmk|8T~znxy18)T9EWVDahMf0LPDNLr{!DmCb2iANabYo4oz3euWIrRj2QIGO2I2` zIOFZK#QIY!7uYXR2f4!Re}qN1trHy^7K(mJ=;tcl5C-l5Fiz((mJ#=c#9_J3{~N%J7Na zw*pL2EdSzUK&Zw#SH9{3vtD4IQIaw*l*(qONYrY9RSS2jh2#r*xTJN?cD57wC-+pbs$VAr}; zrk=;H9IcQz4~v^x|0HgzzvnAO+zqJco$}Hk>8wsp78u2ObAE5Q@W+oVv*FTf=h_=b z&;>w3+!r+vgUYNJ(Q4V^w{`JF9JU+6yLuERv5)Fbb2s#l%8J=WhW@5U^EYyx`uKq8`73D0}^v+Vj1 z9=bj091eewt~&G6*3mUdQ=Nk^n2L(0>bk%rzbgJYzWd5VXU*5FOS`a=Q*PF?0j^Is z^czsZT-Ubx;OB?5(7|@Nr{*qidkubNsev=f*u%YZf@KNb#P^rd;_dp-uJ?=Lbc(Dtf>GG>ST$6EtCOm>10{jA zD^uFGu~0%o8xV=7P#5^j?1~2ZekBwz_mPz{v zXDm%W%BUFF#1~t?mOrdo(5d}qZVQP360eu2b+~({0Aj5(?~SugDX78RVEA=}e4-}u z_U-KSPKi&>(3H^gA@M1)*%WP78+C7d*OP1)sAR>Kq96Ek?%Dab2-gd!9tXM8cp$rC zmGD(!;L2|#VPj!NeGYR^ch9r&ZejI1 zZ%T81*g~;%WX>CgF7U|@k;b~O%2l#M-4AZDryoqoot#7kF=K8wrD&g)`&7p1 z_(Tg(Cm-r;I`D?@u!UDm>5*#^r|v9X$;AcE%HMFUv&UCTQg-G0UReznL+rIbZz|Ek0Qu z;OOKHZ@|s;_NthFEaYmnfr+1pxXiPK$uPoj{$Y>5zMoHjgyDi~%PoF5;M!1S^-Tr-}xp|KzFc~%t)eB(C(2UwC(rCUFwg%)udcwgZA zD~1iR0|9L`*d(ig)M__IDDsZ)s9p`Gy;#I=b_T6stFfU(6%Dex?E05uBP?(MQ`sz5loH z0Eyr-@76H*O7jw!^TZ)+HFY^lc0aQgF}0jEK)%D}zT8R`!BwmVxlu(ir+U4HS!?n& zC-NBQi7$o2G>2LUtq@ewM)Z(+%S0rBr?bKKK8dZwXVWS8>4%uO9!-TkcNc<!#cM)VddvxTCbmeWqwW#K27&ez`C`*${x>nJ{wTOW>RHW)~EFUCHu% zhxrk}Yk4hn0(EiRhvOb^nNFxoCvWbcR_ca2`i~EcFh{qs;Ce^yV*@(Bje8J-uQZ2y z23g?8`ELSB_WB!gt%qfbZ}>si1(myRSShK3ptX(^bZ%b9YgG`a-R8TkAA|||m&G3e z>~TK9dY2pOz>gBO=F8RRr^o#fv=;V2B#B+$<8#W2;1VzsXmLcOnd>n72&LO;RrfFY_GiR# z2Nr8>=mI691$69gProbYKw3D#YIMm!wqi?KOTYAMi@g<#3BHd@cD`qTOWIa-d}Mm( zj$iUBa;9M^@tbk1)Ag$ydIRva30sqsRFtAlkPrHZb#v4Q8%M^oLVFHJ#GWc%YubV@ zE$~UxLr7W_Hg_RPE}au6fbz!{WYK0c0H#R5RH!#U(F#g(H<|SJwx`*SmRn*+(>&%VOmRhGN6i*WXf6fdLg6j_OaEEsosH@j7OpI1vM;n^PisWo zCx5S5+8eNze6m?}7w?+qLuCDzIa5UL`r1s{JxNakTStV*{Pf)3OzgLn6~pd-gAb9x zI)Ekpo%R%zbWM9(4C2shr&Y|tyfFR3u1_yOrxTq@VK2XVGiUy2TD-~7bRK(-#5DCu zbv2^ZMvI`OT6JdV?8yipewEo?T)jtE$_KDur>;jyi~I-5hjMYTK|9q%#93bIM?602@s+n_p0o#)xNU)6@+hsnPXOjwM#ym9O)?!Z3CtzGG~F9UyY-PGsP z53RJIFB&hN_TyG7FZ-bEx4v>s`S>a-c;t--wyVNUZ`xCK)B8ctVD>HN<{~VHEHVJo zILn)lW#5qS4tMOpcnbwmiswDe^=;l(Y+p7%hb$GJ?l(Vk`;CL!Uih*znd{D^;JCk* z;Q&=H1h4^ow)yidLI36$%=28n)iYfVwzPF0FVVQ@5MlF%0FZwdhDMl4z;c>qTu;Le zQw^@f^GzJ{#XzPdA7zgC-X;0_y=L7AQ1I@3G>_RpHY5k^KHJ%xZwlwmX6|weoT?cw z_1B2d=-Bz$5RL#TZ9kI*I?btpnk>I(H_WA8!k3m=(ldy`dH4%4$(rB`ekz=R>rPFxSiBzKkOR(!95Lm)g8CC`>0!YJKOs3cjmI6`CB|xHqh; z!~n^8rSaLc#0u?uf{5)JsU=OJVZuE@?}hy#dQ&gEPYnPMhbylbmCij4wpbZDB*%3kS`9?eG&gmG-e8GNwZjsVxI!9Xu(^A@PkZ{urBMMhpxxM!^|Ld{i(?#=~+O7T8L3rpHNPIkcffPAV^Dkmi&7cme{65mu`Wcs{(3$eN~TJ%-Qhw z=zIlQRjeHzxIOaIRC9aurZ*?^(-n;gv3Z;%oM8Q$7z!r`sEHeA1P2=zX@tw9cpGbf zl>C)4+Q;;ua*W0%Kz2zwj&wX;-&am)!}q1DY`a0$mDcPBtN0a24d255vkk?iP!&}s z>m?hRCPnpw82I_h@kt9`i82W-kbtjlhIZZOcZ6GkFxFlp<(;3fr_vcLFS&1m%~b~y zM=781YPIYk?{Wtg<)8Lx12|D%R^-?bx_TX+@mRgbPX>5Bfh0lI_Va9M?L^Hp{TA)C z_ZMRBXN@*BOvA~?92c`TdqDG<)n8ZxGs=bFz@&l}zs2cRuMP-!uZb1%jby>>hSv8} zqWu1${g?{Kexj6~Q@C6TNFyJvgxioTe2D??l|5|jfu^EEjK=MPK@>_XW;fXVn*Rpu zwDg|9r|djG{%;zW?o+4QF$47HSDlhLgFxPe`P_`M^{>6-`>GLElxP;D@wdOB4UQ-A zzWW6_VBh?w0zKyp2m~f_YsA?gqz028eF%K<(2_e_c7IQn$ORD0z&e_G!^e%Zrtu+x zqDgS$B>77QCvdL?GM1V~Uxo0na0bjV;W)Vj7>y9WmXYB?C>_7mkt4a@fkk`~aB0~& zf4b)^s^!BTPn`T8gksxWPhwZr96q`hx~_}|ZjKzG>2O>r!QYO31-zogY46xC1mllr zkra^*dgn0*!hDbqig{ePv@SO_kT^mTsBCBWBpyV)Yms7;_qd3?dvt>VyCx8EB9g#f z=Sp&{A74Q)3Glha&aKvAg)sr}s{D{Bf=!86F7%UvcK>l*l6 z2FT5i5@w4oXzBMbpb9MG*H*u+yjVv{OO%yf+(9j;qd-sZ*3>5e6^S?q`j>H^`~vbdaR9+txD!ja)uyLBSTo z$*+Ngy&NNSudJm0Q$wSwwO=}#eKO(V@xQ_5>mi+wl7M(>8dzU_)v6ts1qe|-Zkf`9 zg-0CVAo@2voh*E|RJF;9rehTZ?~hL%*&uiWPa;L*G%I&w+q#Q|>s@8)H)gMwZ$>4= zh7v8mdcF9y%=$+H_5g5}J_MZa1%Avw4WBE2w9gW1#OlbRBBvrR@s2_uo0*mp9zkh0 zi+LWD17{vN={{q;kX*4he|>ixk7TyRXq&XC1~$WIZHYSbLR?Gz;wA&<|NYA?&SB?M zI2s?WH0ZsRL?yUMy=fltYb);Gr>25sM}EyU`|JG|`M^K2RAqm(`#0D98pQuhZI8&0Fi-uZ zy!uCmx@@luvhE`5cz)(561b1~|3&q%-zG-jqw%kO{;x}BSqvU?q|iTLI*~4?pLE{M z_b-j|KZVt=tnxp8Gh@5Wxx?<}9~bu*PWhh~;{OjEKcMw!YirYEJjNaL6W9sAjH*cO zeR10r!Dp)#WnxXbCA<{3-4}HAhp-^qYw3lgf>;U}cqNDL!Njkh>I*;?QczF;C_`Ft zKdYd3${?g}w{O~(S1H9BzVfys8BbCf;R62|TP?8g5e<2qJAIt)Ig#}*dXGUaEVWd7 z79$_`TWirz-2eap#n#M^BhyD4)-+i7B?mgl5499}PKmY!01Cii*MHN!)oLGt^)Onx zmlMdfYURUbD3q>o^5!w|=mRr69o@dvNKrYG5R^ypV0rEvdnmy8Khpl`aC$m7A!tqk zZ4(dDi9;kI@=NQ@rm1E9I-t~aeRPiAR}o|ZDh@WsO+1@{-H3OLe4NqvJqkL*1gX*0W71erjzUYrw?M zt#FQ?hwzaDxaPA>%+K46ARJ%S#}`zS^|kcUcjFAuU6KKpvSsfEK3EGVHEtv=b1qQ7 zVn`R0t79Ev@uI)cxrSeIC05$!=Caj|nVT;@_PtTk52_6#`UmnW?7-oa3!e_{G0Pg==bgF0@I~D)L zg8rt;Y92ULZ%2lUQ3}kyLvSKQwhhGcvS2MZHAQ^;PDnwwA@SSrvyXKWdvDc+l{+j~bjyl^%IjwZ zuCZMhNGF6j&$3|sytCB+1=Q5hSQ8kn2|z$9UPy)SmBgU^=0~s~?vAvcJto=C^pts| zj~~J8QC0(m{@SMLtg%nj@M5DtJ}SZ0^eoLS@E7`er(|N8rY|qwADdxZ3$67|`F98!u;H;D!W!$`CR56my9Wjy{ zj@}k7JD!Po#YwS!;kvK?@oWkqr#y|Fd(#b|M6w2T*TuD(QbLg_qYY-mMOaoQsd8)6 zqNfjB0Fa|3^>vNe0K1}Q|s~AeH=^@ zB%JKCW)|ITjy#`wEFsx7M^+Rx(O(xG*mWN_8F|)t9UT(5)@CPsW7?$~Ck3`$R(jHx z64Fvvm`>L6>WtAt(8xz{1AXgOs{>K9w+aHD+;j3G#%RD5{|3j?I~_aBF93HVY#C1S zDg`B6bS)Ir@Ey*UA?s6(ZYL)dXY#LlcUq+G+gb$vIFIf1xA+swAtXaAwzVn2E)S=^ z2*qY`6kv`&Jj~+Si6M2j-48-Y1|nI zhwu&dVuW=w8~VlfBHi6=>Wi~#Emqm)$-&{nN0QRo5d?$h!fCbTiKCZdSM5HslZ*_- z<{kBd>boN)Y`w3!%}8XhO6w>n2GOmbRV#16hQ)Tto}WsyG?Vs;D>tUl3#ZHZU_P9l z@KX^oyDf;|kkPkfLT)NYbF!snfFwmFZ;Awb-^A-ojD!&g+h!@rpbcLqtHqwLOB!&T zCdE;Hx}_nwTW*+F$8EH7$D7QC88ITq$5A5JS#FNE=F~IvGu_vNG zlg9r;wz|arCNzzd2Q>9B?{!TP?VCl1~GOHPJ(rft4b(sQhy;#5|s*T*Y ziOQG|RDAaa@p(wRUamdzmMJh(`{qg-`|9~72D<-8so^&dErxmzUK~Kizop&%4--@5GXb#sRknNg*Vn$B^%yD* z*8UC%iGqJ8bsU7=1&0!N?KkF~=KMS$N*fT%s5@o(B9dB2d=Jtmv%uU*jz^MLw8Gxi z&mfebR=tqttYZ-uT7Hj;jAJp5d!_YFbSQm`>pRiO_?6#yXTW*1W*5HyWpQqJr!^nE z4@s1f!rW&FQkqZ9^{dw5KT4md0)*BGuxaa-hI$Kv>5<6$QRe4m`UlN29pQ_7!q*K2 zP;Am>mP2hGfa}3xZzsh%v+SkY#8=Ckz`z2Vo0sFAdSB^S)Zm;fYrSnTB~S5>>JKxT z)5X7MG{9l#eKrpu>kAG}s2ng^;fEmPQltb2767Qszx2!5>WfsOAG)9?Gs?Y79vSU@ z1K4LJz21S%;0!+G?L=1r%&Oy~*?Q^V@l?%g0tqc!HeKC`S8TZqI3p$o^5q|B#YPV6 zF{__>te;bJln(d1WJNjlYw${RX3-Lawgf|zb@Lg8i5#&-9WCa>`e6c8uE8ku=wW5h zR86VYuw!O}(4nC+rQwETfs388iQlv0CpVF1sn;hQ=mUS=+>L*@xe*zAEfyOXaV;GN zoD#%`sa2gZbITsmZBUTPD$01TE-^m7KC5`Sy&f58Oy41$a1y7dnc;%zKho`!2+$v3 zm=CwPu|Q&iye@LL=qi&*8LNpNa;^w_t@CQXWAQl_ABXBo#me` zG-srw1kCs*NQ{T}f6e$+4|LITqmp9tY=yDuX+W&?Ufmv{7AkOVf1e>A!gC*1grr`&UbF=L2pO zD0+!1^madBGnGae_iXAn7B!aNG6X!C71vP$@&)O+65byb8!KXlo;}rfI+(ZtTpr;1 z{rlws=eQ(bMRZBJo)-$ZsB<=e_r(K8XmRaUp^DntLLHaZt&=D8*kvA$jl|3g2{%x$ zWXa-R)BwhN8FLSRCEf|AA6F(6Gq(-x;1b{)i^SKxlB=6ihZzjX^9IFkWG9d_j(V)< zJvexI?~_*toaBFM58c=iI?G|oCaP_2LL$iW>Fk`_@ve0?}om;ub|z9g}vRzL150IFA!JJa40PFHAM zO?g7Ot97pP-*oj1#hMB}Ymw9EWsTD7o9PXP$3p>a!BP|SSRl*??r|hr)_x_l!=jvM zT&%?TU9<&5NSQuZZ;Nn|^-sSojAH2a!vwLjVKRS8Mqe$QDJ0$wN;SvdF z6B34Ti?SZL&U9SY`oY|NIyyFBq~Y89_p=%fJQt0!3S*E&A;d`EZ|i4ye-!Pl0EHzx z<5s6ru;%Y>v}(SXRzDmHz}J9IOZAFd8%8F*T z+|B%z%@k*!>4$*KB8nWwwkPMhpwzL5e)FLlZ_pu~Kg?yB^YP0WWzFB|*woYuWCDma zxFvz7-u}zTMXW%J4^C#Y_oMA7DPWWw7U$J>-p3QI%LGr$*m%%m;;N~0rTFwraD7qZ z>Fv{(05PNZL=mO*{#C8!6YEIXMvp8x=*Exq2zUj4+-Hweb^~*Yq43sLqu{lHKUv$L z7LH*-e>{&&`q>u!6n}&E#ov9K`{M75KUgGc6`N}=3<=g?!}9m=%Ib|`{NtCAnZ3O` zsr0q0RlBhhfFpTJ_@=EC(cCq2$7abZzo9puAnC#QG>3=o(*{pmQ9WgK{q^Shc;zV<^TFCc@?(TTo%-n$W7crELj$bsXL0oifSAI5LT-ZN&Q;Z>4-P(r3 zW?BwtrXOX72>^FYJ~7Q2>vUhdZd0_#5olHl&Zo9yO|b(@>~xgZkY%0_5W>rApKZnp z;GgGvu7F%z>^1eg^nxB#wdG{I=R034Zd<}FAUnREC_jJQc{JV*H-d<`A?NyIk`>_Y z01SN>MII@FgtyK{jZi8(;x_tKI^}ons?Ltshb#3wIyu$d?UM#2L;sBBF=mj~+U8veK#n+X$Ksj6ZyOm%|9BsTgb|9B_yQj$@@}Z`uUzy+aJ^ z?Ar>G`RloDSAV0s_`~}}^=RiEe@vc-;g*U*<0>!p9Ub}$0| zabsHhcarAQnMc`=rZG^(`+JeJM>PO{)CYgyC#Bs{YLZ0j^dhnH6Dnyd6B3%SrqXXR z`2!)inYG^s2k`Oa7k}i=Z9QPr%d4kmGUJkdq7kOB{LL{ay*d`a0M5Dk_LZN>ZFRMU;h0lv%$pK+-F$L7)Iz)Qe!s<)u*Z7s4(+W6QiCjXCFV< zI2|$e)NqgMIA%5QVhMwU4`zw=_oAQOz)C1VcgeU12-gc9&gfwKS@Vs`>a5ITbf4?) z#5(&)zfrzo{t+z1uuirq%^WvPzMx;0bnvz{x;qj3Ea@MjC`yf2w=1=63cKwY7{hv{ zOyB8p)c}s`Ixc=+q6e?)!4r}Mi-&wVk5B-aWgBhsc z#;|);9~Teo8Xg zvfB3)B888x=*E^ilK=P@+u%<1f;f*e$SlR4I< z`eQo(uaR(89ifkDq&aD70=tSGfWein{lXHS_^6gesi${OQci9$|J#G)YqY+a_wV&e z&ynL@qxFDJXP3||I3M7k7IjmZRX!|&GKk#mh@FAG%y+y+-AQ*nLmGXhTqQrx%vCK{ z3HG0sbm_0S(5CEaFN$|s#4ByDEzx_p;- zZu%qh{a;@o9_Ut4-iH86?3ZOX9`pkD&Xg!{l12S?ff9*BA(Q(plE97EW)Jx7GjS;h zmg_XVV))thlTLd!3*T!{#{y#2t6OX4s;J3ZP1TK`$)kP8HR53&EtWk=?`^~&JA3m( zGup;>n30XW*K6$YG2*4pR*L<+TgROgpLYct{Mv{C-wH8&v&Ov?7FsK&F7&PG!mH3j zrOMyppNxlvg~2P>huGb~9&HT`?lrUVm|nl!;Z8SqgV$knzghI~V!|{mN8J3UBPQ~? zP7QAktZZ|(hPZQF`7P1{Z1SqpHLI6pylN|Jp{yTj25fk(JqyP4n_~% z_g~@s&yx=n2taQ&_`6B04ozk&D*|RP_U>sAsX7PlQ@p)JsTT^4uL(#_<73urZb%@o z1TPu_Zgjyz)QWg#DXbW0<7Cp;pKqgn}PP`F^RT;t*`Yp>3^+8|I8qTVh zj?QuLHdcf-1xU5LyZNjykDV^<-+zmq6q$U5Ky=AQKT82_yosg`Qs=?&QJ6)!W6O9X zaksPtXkJKUBU0Yvv3qWH4%A(jNWL1ENn-ZggKiQc%9c9#SXP8EI_crNJc(!U4WuDRhtO8%Hx(tN3@ zZ&Op^@)~~6*#&5zw3{#+9NDYvTD4J9QV2&s^$5XuO~-^7PQ!D%Npr20z;B4mD`YnS z8uSs>atMch|9o{nr+NNhKMH&i{2_lA@c_EbdczsA#L29hsp%9A_1#rl4gR#SAki|R zbE6`P&`pLpuFQC1Kxw{fFIO%TX)iv3l{-7i657)L__aQTG*s;>oW2!tk=)K0?Ziqp zH0F3?%^c_BaE0=VvGTvYe)uA8dmGl)+PXeOkrgJK4S73kij+bKrBXN2(DIot+H7De z(i@#Lw?ny#ij=)cCQnM}tjALuT!Et3UcHgyTN5?Ana^63VAP(5kAK5bMKSOSPN^aL zZNW=VU%BMk3eBy%d06i@r+pWBu6JhN%(Vsy25+$t|#Fr*=Y0Y)GYh z))ZU%!tZ0rW_~Sh&X!JGXp`ir0>>P7FE&ZGwP|8#H&D6%Z!3Df8$KeOuva^`(_CGx z>VqzCBL-j43z1pMgS7iylUR_7iCw74n7n}S6mOci-TP(_F1lQEO9-UbTSYzIIo8+e zEoU{Tx$yZGWl!G6&cC6_YpJ6UT~JD1(z@Q7IL9008>lr~EcN1Xk2o~D?%bry6TW{L zCqBa2mN0|ei;_H^4fY;>E1_cDA-`MqZNO6Ec;Nkl>&8sXqdBL{W}h0z$QBw>I%M+j zXTU5gb8TwjQ}+|eYSe+RiS?L1i*T0vNK;Tj*Fw)RN3MUKB}+gv8P{^xhXso%)uea% zC>fWzEbLY5h77L;i`x!yo2P=_E<(;xwwqoBl)!_!AU={_+cfL~SLG+{k^-O!{v>=51ihkuC*5O#7-0e-$! zBA1Qw<}8qy|Kb)*ix~do#Z~P!EiS_+6;7+Ul&5gl0NPT0GhxtpESNW1%#YoGh$0uGzWMHEt_S zAG|j%J~a$GA5+0+-RG_0DV)=MUfPdgFqKz zGA&hx?d8$O%@rR7doM+M>7jlHo_9vO*O7H|0=<`#p;Cf3>YK>Ls&1SNY5v)yK?blw z8vr!v&hZ}u2LcumU;k=>JTFaeJDwm5X0s`ES3%+;u>MfG_ai+g{AAWR!#g{Eje7+i zKK4s(oCTM-`i6;h`-C&QVAZlK@Z#57cOZeZ1^*p#bw(pT>|&!J~f2TuOY16p@CQw_CD>p5AqQZ6UmxrxFj6*kH>c8&!@PSP#T zmFSpp#%mkNaO3EY@?;+_O?B5W@DdrE6jf?d-F(>u=bMIxu^5eg6QMk-opj+QYd&mRElz+a#CUAJjLe;zzI*NLig1Pj~4sNw^K>=8VlrY8#Ap@X864X4@Ij z&Y`qlQiS-$%ulyKnWb4fn2o-HK({Sz@{ZulgBlNADnz^6L()X1+qjwf;Kx+ZD!`Niyq#5b+C*i9JWlQexqC0 zeOQ7Sn=)S{Z_T7g-nuQ2Y?)KFse*T<%mn4B;XKci{UrXf)_^0(tKWYt`NlJ3Z+YT8 zX!#-{pHziYaxzzh$|M=wYkS*|5GoG+xR&dWqu^lB)(xo3WX`lP*|Pd7-clLM>)zKV zp;{gL&QhY}VuYotqJ23}zmq2N9l@QiJ!{Z49=9A_HrmhUSAp~9x&MI$A%h?o$W`dxVG~qUJG6Dg#y-k zpF^>|+)UOH4?95z!!j=ghjLwT7X#hhUzI!Lw(NnqSAZPIK=a)pa!NyGWqtc?PWtUV zR7@O-8mGbiKLQ$4XUt?pBUmQh8ol`@-d@*#PV5avj!LWRsmcmS*JY4j2Zc+l8k4s# zM~UQqsw&AMBu?Ib%{-_TEVbX#D61v0Y*Uv%eqOyenok}{Ud#B|KH`5D5^&6(v&Mzp zBe_TUHM2g=5Ci39`2{)siZo0szB#|QQkoM%4Y0Ij)pM4aznQPkHM>~PP@0aJUowv?Sq|RI9_Vke zBo|=E+R2H|Df(vmUNFbS>Uv&>UzjX>R8zo?c4YPwoRUrOSmcDG^W!=_bs>RjWLG6E zs4AJJ*!(q>lxi={5{7i zY{+w-ek6PBOofOf3W1s0Zs-a+5l5rf>%psb%KD%G=EVqZS|~f8p`3~CHP2yT8B9<@ z{Nqd|Um#mu684{`Ii8(p7bCt|^Pl`~Otl&Hg_JQNa6PPKb{avEOYn9GtoTe{Md_}CiRBP?bFEiK%heKPdy=DA-mxpLO@ zxyl3j3%nJ`37ClIYR6EEu|@)q+-unpOBX{c{I_G1n?toNq%BOb+5Ph)C581E3FQb& zCBKbDp%(4Z+G~^KA+VR^a8AP;PQo#wb~@n3e~h$rSUJoc0~K+X?7gt@CWl)h(PxuF zs+N&VZGgNOtwo79g13b94eLv*BUIy>nVI9JZL$Ib;e#;Wbf0Wniq6`rna0eV;?WnF z7l}YQbLSiTnvsT?YBjT>$kdPH-GeWezjhWjD<0ik81$BwIB&qv#=z--`T@v%kp(ui zF@Om>C2J;9v))+Pu=Af?5uk<~mCE-^$e9Xu8b2kUyYXl^1ZA#9rdRkX=lT`Ab5Cvc z=n&A`kABR?g?nVjXq(>}!MN}+lD@D^FmK&Pk$$EB)kS$0C(LJkPSjzFU-F#tpkNyM z@ryP4>ovFiR#K4;s_n4vKHhTToe0{Qs_2AWYwmZ@;Vx?s4CL4Ne3@aIWwvU-vogvO zEipddD(K?39N@>5N^k6q7$)n5yGKtT(#D!8{d2o4hn;Z*5BaJsqw5AqRZoXkgZSYu zJjZ;9T?*4p1v({_fHA_lX)yz7dS66$r)X6nPD$Q)OfCGRyUt_*Tn8n9?Q=EeomM2y zC)V7QXEL?*MB|Cgd_7mnS%z*AjE#0(Dt zGJENc;c3a$cZY2b8%`~vARWH6Xu zY?hP&S?^6l@qyPeY03FQh!GisiJ zWz`)G)bb-kW!G;lkp;65Tecd{e(Ic)xvgw^Yqkj|whV0YND$-y$Ttax1lf%iej2>R z&Tg--QcG%&;G}yUWf|4$IX*K#`=WG3B#LpfaKm`EB<~t|ah6L;0cxS2yGkhR6-bj2 zmct`w=G43N86O3Weo6jZ_V#hfC34F7@MB<6M@dFd<)ox=21ldnk9r|l;21I1+p$#f z<}!wcPF|1;aK2xLlKq zP;QPWN3<0Bo5mdqiO3BPZi$sg>1U=xrzE(Td4=@F zIunHiNEaZcx(rQD(gj0+Lt6-6q2RPLiBXp| zRzP&;-p_*`>wh2gq!gi23yADsVZzoG2qB7`@1gRhyhlRTgfukqwQQElX5gA96FD?V zHRKWlYHRG}RKZn!(t-|94m0r8I2Dx@9X;<0wUUQy#YgU9A({11Gu>Q6iDeINyocmD zvJ5up(bW)Do@kl978P8ffg9%y=yJdNIqP%wqS2w(VJ4zV{UVSaXn=8H;TaBkT=IlPKpO)0s!**9? z4XeG7IP>(->4DXo0Jn!-ULzvnomL|HK`vAHjQ#zLX z$n*xTfd4`wM@cWBv;d#K8(f*ugIuV2DI1JnB2^ir$rRVAAeDe4$#40c?BqAStkT?Y zZAN2j-~=Lz*#1x$GQZg2(1}o6s@ZnzhR@G~&eVe}JY7|jj>@k;Q;%@fBEyxS<<*z1 z@UxN<0qRHS#<(ZVd~)197}*9eA~7K~iU=D!zcfqlHNwem%)+hCpIz&VI`@SyAQ3xu z?}s!L!cAB)YUf1B#8n@43PcLV0+o@!TQ}Gf;<^Z(wqV`arQb6B*+3erS1TtJQ5Cm( zDeo=~RBn-A<+egKmXGjj1tr(6q()i#sZAz!GLhL`O|@^;#;%YqNS>#A`-FDtU6@8# zn8}TYq%oX zQAeA#^sTd2^Tisqfs;s(P2&l3MUu~zl<9x(=nqtBmdO~pUuPBgB-zh{~(=9RoSc z;HH-0#L5HcQH`3CP&49CSYIgUwZEAK!T%i4v%;^2r;tA6#b^wd(gAj!!T%VfZy$C`i&e(R-xTq(Gfp&@b9vr$e$ za~OvDOeqFmy>2bJu%=tH{s@RyQnM}a*PGQFnFA3l)Wd6Y9O~tPvV}0$J95LPoDK6Qq;Pi(wOWl1l5wK7Zcs2xckKY~r*s$pl>=x--8PaW=E2~WJw zmh60XQ~{lfK0`aBxlceC@j*Er@$rln(DUy~`{WDej|%?dH29V-qyKpZ6xc(`Ul%De zB#Cuc&opR{85X~U;LYA-xb>eSU1B_M=WvfS|7a&%KyU7{)2F95WVE-oL2+lk1QmM^ z_cJ(rwzS>w?S|JGd@uB>{;qF&d$nq%HXY5br>Z`>(s_>jhC`TOV#A4i1pDSSRQaWw z&Bi2NlFUg@=Xi~EFcX9f$cm}A5jU?GAr^1Nu~m0tKrw~v4wyY!DQjj5JwFDm#adP2 z@tTENKvVg)2|&-fGe^qEHl1rEHs8gOrv8xp^UjkY1@Ir){tnRFv%y9q?T6}AP<=b~ za_bfUfeyO$^V~nuZs57^ZRe9g**)YTK2>Zqrl01`)bP&dMuFEX{We=lv}3W6EB$=t zo0)~%ukJ||*%{biiz<4lO`nFa)4yXkEz_l%^$f@Psae(!<{wixt}D?QyV8@bG6yaN z@>=cu`jqbNn+%bQd4`4xy60ogOT?>3U3R^z+7mBOz#k|hW4Oi#8~u>L2_X8VBCNu` z)PtWzNB4(00O(Vm1z#muB@KCB0AtYY_f$GS&D!~o`b(PH4w_8OtO!bj3>f$Yhn%oovY&qLrEoxVA1e*9 z)fjp=YGErE;3Q^o8ac3LaXP$+^Y9|yPuB<)Len{r@^p!_ys$(Em*PN4x)D__tTm;w zxKe?;Bhgp#Sypa3rb8b$FXz33&;3$T(oW*4;qsn#qA~m&QKbXBg^hfk5cX-Wy&YW= zy|1+7vfOL?v;t^ojirPmu=+^t-ZsJ9%L-wmA44BvV|7ZobPFpn=^(kcuLOR`Bz`K0 zY!x~4b1(;ouO;r2nL)7Nl*aSq3v_g5zbKbmB2S&{6d6*(l96Hoi!oEWEw_vH-{S1kIT5#$|~WresLwq za20@y10vj80~OS+7~l~-piy3u3hRPG2-u2;IXu^P==pY=o3+hby07Amv}Mzr-I0CL z&t!9@Ta#k*M6wM}IFzUlg5&9_PK66qK-em>>E%-ijJw|{$cgHWB0hfFj=0LEHkEgO zEoiGP1_MvPS~V zr{Ud5s7)z48xDR&D%=FsnAN!MD~|g=S!1-QCykv-Gza=d&f)DQ`G+c(?o;&GI+SD2 z7RG#Wo+>9^@ZWhx$oXw@bMS#ntzO{tHL1d*G4V?rb4_0gI8AnJF&|_JP21fIpH{SH zfmr0rD1{k0>*~o)R>s=Vwu4KI%oG$1tphe5BjjGFX$@9pit38$lK2CK`|hY*1K#R5 z#OiyREZcN-bkf4tLZGLl5VliU6~D@v(SJyy{|3ieg<9$(ZLko3zJvW8qsf~O36$YM)2i^9enI(wHpsr}KZ)Ee@>kgA2MU%gc(4Hhv-t3# z7iKs3Jm(Qt@!o^kN&cvbIadc-8a-R7=T@{I<)u~TD2o(Zw7g@S?{1qDT&(~zl$vy3 zDyh_`YJo?(g4TWGGi2MgxJ@-@C>3(Ed;g$-3MY9ACU8AYh{NoXbFoCO5cJ3r8GyqHNg8(f&W8H9ieh0? z!i?P{epEzC2Ktb}kg@{Vdg99|5a2C8B`|3+Qm)$A9f=WoP~8pBaKn+jM05MVs^Du) z3$$U53ke@i9)ZyJYE+%j;+j5nggtzUIeH_-EIjn&>QLp1m+Ot9OCQ)}2O#onqm43! zZhB^Hu=KVX=*}4a?(p5c^y0V`)s`)9k-iDB*J{As6JIl1EzEZ|;%7!vdDb|GKV94R zhVCr>{ZIg@FEA7*de;cYHM|U-YD!fS+OU5ty#43(|ud(elUe6b0U#L!g$gY zCKu?WYZJiSuoVyUArxc0t`q3V1>(>xF9oA-TZ5+mvL1qHv(hTDaeRBGz?6tl^1oxf zRr#!W>WLQ1(jtorOVnu_ZCsIjxf1tktEG z3gU)#uEg>J3wHrPFzcGab!cBuxY>7im<(>kn)&7r`gDzwDr_YPa(seE!J-*Tf(Js? zV>S+QqZF8bF8=h&3eMs7%D|LVix$01ri1=K8oD@Fchl=u%fA939#ffq^Rx`uo|MyT z7WFpiPY=6I8F`rZyFC3=K{~28OzpZ0^cSLKlsD7mReEV-&8x}Rto(E*SDP2Upn_Za z`LL(fVr-gyZg;8#Y-d$>EIcfOckv=o{)=4%rL$lQJ|^nuEa#g&yS*lRQ1*$=H9dxR z$PV69<~Z9Ls0FG*2)Kowl-hz}wK7Iw&R9e(#m(Vk(7ETUB+Sh zt?SW+yB2+iVVOysX8eN3tep$?A_#ysWz$DmR@ia-`rU_P|B+G#g!u~|4bOD&UGM%} zc`LPT*lr+a4{s29AaNP`vi-|$#!cWWV&C{i&bjGV7`j*o7-~TZeSns+zkE}82~n2v ze$;v3bqSr<)hzw2R?j*;9V4^hlk1rv9qn>2elnxGRrP!w7%`yJG2{|>rfDWNxSMxOw-wp3(Om58qSl?n;D*t z8kcD#7{83}k^H3NQZF#j-^o#o1HG=Ndd4Jg)Lj95bb6uAkPY$?4o(fAAtmQDVl}F!qs&6d%&c0&fY|l)_8KrP`dIp*yy*d3JlfEqGl+i8Gv*;uA z&jr&=Y0MLCmEQQ;%s)N>Pu<=`E$b$RS>Wl2}G^yk3*(_6LmK7J0MQ zOBQ%DU#7gVecK4tppC4M6?1$sMIU&YYz`$9b*X}-DSF%me6C=q3?Zv|3k7uwuw99_ zx!;TnPyk>PV^s9G&-A9B=CH=E2O5;){-ZqqFE~kta8}U!6oCN@;_rr6h2iW6Fs}!u zgK1jf8rSoQQD=FjY&0V0CD{of3m{$4GP7DtbP}x6PQ9%fEIspEV#LHCoOu$Tc`?Pu zH$OI`b8pG^`(5JZz$z73PCHMeIRzYdXRz%nk&bqG@tW#iozOaYA$B=t`up)A7$Y9i z`a=A$Rnv9Ob{F4A5*XUjZ`3nucDqeV7 z^WX~cCwzYs3f^^-08tH?U_W&=W5#7b-3KTqMgB~X+-E>Kz%C>L84zDGjt}{L^vX9k z&VVT;=ZblP)3iHpzs#w^=z2@3K=tgzIxsNpkhTw$hpXUgmFxr?MpoATy4YOGW5mOd!{ z9FjC7RqoJN^3X>k<3ecsF#2bQqLRDT!?&WH0Wyrd- z^bE?qT&%gI{LVp^{kQDfem-JNwIo8VjIF%^g&)X79y&V`=h-&_xfL~%6NzG%S$Izk zOe2^SDPuQe+FKNT_&|jLCuUCw3`}(0E#XC8EA%Xp2cV%$x77eX`7I-$I~v5n_M^jn zZ?XO?9Ji`uRAZ#^BwBhvmeU7P!DAtc-E269lQlwWZ>5Sk`c_fpPN1^rqus6i$f-lS z_Q*jprL~xYtY#vJBY{enc-u~`WwFE^t`$cbt*ipkhiKm+M}LE78dEW%Oj?bIqAz^+ z#vGNCjjS^ARoG~3^l%#T8wWGLVhm`y;@J@bBe||(mi?zpO`Wjf1!zv}$aM+vGd?MW zVK#;8X8_KP?jL3Y{E67bY$Fpu5Dp!XvwKxd4pIVGl>JlA!q4fHS;hnNdxb39$ZWAEvz_*&S8a+>s`9rNRUqy3}Z zB@Y_fZtLsX30zC*Y(FYrlkD}ZE!Xb4ReD*;bS=WQgk1GytTP=q+jDW@h8#F-aSV== z$Q9(J@Dx?t77-P8-}B!aS^SD90hv8<8O>g}ztbeDgBZwjM=_blxs#f@tQi^AzIKCmu(V#`&s52dW|#^4D!%hI)d%TAdO- ztwQPyx-=o4C2IHrFd2`3(uf3HT=*(^dG4zw*g$o!D>E<()>jA4T3AEB_DCLx_*R%22#(@(^ z_3ftvNJTiB^#F7H3U& zfX@w=xio#D1G+Az$}UA@MEt>l&i3lsz7NqIQweaMy*LLkPTfnx+p<52trP&U$)9pl z(4z|ZFkLe?87rVM(b1jx3l+4l#pxFGZ)en|?ttBa0U?)u0lx*Z6&fbN@Z`38byr0t zqIVkPRaJD!z@&;8Sv;eRhE>b?EJ`UOEN-`+a`0#^fUdXMb~i>1 zbsP|T><;E1K!+bdrl>HQ&UA2Il)w+_PJm`{_m}sUrE7!V2Gh#e_8+$h zm^3g4C@y}ZnCMo>&#k?w$2O~QTEtwdEhKxLZ8-bAWmNl=17y<39lEmiQpW5womh8v z7XH?1$|%hDI@a1jGpg{K(4+`I2g^^RXP>Q0kqH85sJplBRC|!gJWxTC1sNF4-9gnN zwKt8ONZtMq5C~w)2dh)17&+G2NAo7$NzBx)LWez~5s78><#6x4x?tFXVF3v0sT654 zG%Q)%wOIru!{}Fo=zqEEZubTQ-wJQGv3c2&dg#U7#mR49L$zh&3`Hu9149a`b;5Yp zC;d_KP*1s^(&Ygu{ujechM>(@B@>m|Ywi8{$_^)~oDaD0g^`bc6xs2*O6KXuo-B|z z)b8kzH<1%=voqw_fg4K!bRPw&*l!FrCLicUAsVib-fzmTJARW((>6Gu`5nCq);m8_ z&Qy?mU3j}?OaIWizz@<6-IaQ%7CZ9=xHSAMGwGzKcRSNcB<5rBbjt>O{7vi~j2i=s z35R|fI^~%0kD9)RzwYzhf1%5O7Fb5@vpE%jK&|_JdyRsM_FD(w+vr6h<_2!n zA!XrbLHdE3_Gdd+unCZ%URmVui2&0oaW3bmYRt95KV&s;2EXa`UU8e56FR4SZBVxbIAtq+*ByD8Y1aTxycdSh)V9;FV=zk{o=nDKWvwGst?4(Ij&=KzckAbO`Ha4gcDYCRuyIYpSMWFf%esT5ny|JtEJ3H#d9jok~!8F0=hwn%733guZCbe&VC~?FRMane%C_f`gFkbZ6Lc~qYCTmBQZ8SEakgd>y*kRuu>3mE3WDOxp z$8$V$-6UR(&Udg;`R4W9&0S)@9NIp4_oE3+MAI}1BQgK}2Ol>C9AN4Lbq~!6YIs#3ut5U+r-p!u6$0&MD02ru3V|w`Rdgyk=uiR zqVode70mmq$b2a1|6RT65%Zh>^ z4r2oocuG76hmY&tQs``Q8d`gZ5ja(6H3b~oJnBpWC{>ovJ1@^>uZZn%vSS~2E!jHX z^PZT-S#TZp^IVXIC!OFwW*rz_HuN)8{Evmb&x$>fD)B>PlR}@7g%rsdkDqRu4xZna z$?oq)$otPR+NX(s-&Nl+JS`W(2ZXFK8{u@nXTav zdr{_0I)?^Y$}87EE42YpZydOTuVzp9Pz2qBjL-UYs7bXMN*|^)a5>4dB(p)Kuv5z% z!0JK-*OjL&mV5d{$TcL4!BVfAgQL_ zl?ug(i+R^$n2sxYo49c!rn)arjy*+EJZf$%vty_t1Z~> z@}1sc(~lhPeBUnteFmbVpDjedWQv%FqdLwCMVo`2=Y2CRc2KI*e^2NAnT;O`>o!ep z1_s)*jb?MXYwDcHZ0G%mT}FcPW&K_Bg+Fx3ggGZ6-(#3>%DkX)m6s4Cwn*YvVP@pi z084fjJ1MD!H?ghEtZ?ws$A=}CYrJ&ua)nC|rZ#DAD}j!%7--J z3Fu4r`myDIQ`+D1fu4W0(+*QCHR~}IH9u=HfMK&SCD6Lz_6Je-{q7E>;Q-NPlC?nC z09bPmVkt39hdiVf);iAA<6so z`EjbETbjxxm+|jo%^!;7>0j% zd0IFBY-5%PNBi`VXE(9s%Tx58oEkfMSdW2DhXA7dAO;_F=vMHAe{w#`vbNKD1~-# zaFF^RU=}h6^z8wxJB4`!57Bro+TS_T&9|Z&g^h6NSL(=9`)oyQ6Htowk&i5eIWl`@ zZw)LMxp4+t4gWulCuHQN!(x9g&(vyNJ`}w3WYFn>(|p}Rf|gdv3OVK!o@}GC$wQ3k zTJ+N;i-kKBUS~mu(XPItXl7SX)0(R=_Z5|1mF$qb{H+^q0&GA}CLzSPxq~{yo}6MP z^IdHHyXDgc+>knObM{i+S4x_iCl^rA86^?15^3V*cW=->ClgqyVBGrFHe4gb#c5fn6joB1=-=U@f!Qi$u+fUCwvbJ6D&tHr1)c6bMm zTBp2q$sT!uhlU#&>tqwJjbBWIak3b9F8hE(zPqW##^y$a!aW(A~4y7A(+8+%2HBG!+3)<`3XlJ|Mg* zc>ew>g#_rNEDc&e(<83^8oUS4FZce0pWX_)uy&Im^%FH`k_98OA8;^d?|hFh*^S7; zwK`BqTLZOc2SPz~xR&x_&ffGsw#cLb%|hurNl~e$yo?@RHMdWZa;hpb>+DrO9pM$w z4wzOADdTgnW0U&H2Cn=s8wlk9dbxBsP#T6TWHwUQz$>zwBW7M^!)gAP=)M6_I?g0n z3sS^3_nVyB7SOqC8EV}q6<@7W05ZHOCS#cml%WD2+TRhTb(L41?1TTLZD-Hs1MKob8Ecx~nl(KBA2&f3;JjRx08~Q# zzcl)zbS1ScrJMA*Z~UxEiI|T+`KC#kqjtw@0bc2h-|k!uftkd^T(4M>V^5odNQYkpSW@GR4Dl@d(Wa(lJ{G(5Zzme$V4 z5*rp0bJ!{~P-|PL(Nf7Qd8+;Jo#$3F2=p7DEFSp!vG+S2`D-Ec2G0Fp$6 zDD4;RxZ43rowzrm$-MdPCv~E{mOl2n9XGsxHmemPCGK zxiv84pif$HPD5J`AD$cw`P6)f@9<3a@b%Qu$*{WYF>Yo)J`23|>AQ7Nw>nSq;Roy5 z1Nz77#E1GT!x#jw3lF|hcLT1{2xxlo(aU~TXJLx+C7-MMlV_Q}SU_1fTo46aXIZi~ zWk6WIwrY-agm|1n8=4%rrhroTze8eyh+`u-QcMkl%bR|Hm|t30PLpRY>A&246VqXX zODeCQLxW0C#jf+ODoBtVubnY_ycnuaqNdNQxT)IbME+Id*5CjVFS4l+A37S6ZGGxG zPU;Ufv5|bfadsOBN1;zccy7;g0(6Rv37fi@KFC3bVHRY6$2!!Phb=U@ws+6e8|f*f zB@PjMq@J^|q!w)B$x6oJ<;3{dN8P=x?7ul1JUt9A4K;tVfbKb`Zc+-CjAi-qf*V`V zv~`Hv)7Z;{YEaol^09HGn?|U>G3GeM!ht+6|7Vk7$+{39eJJ-l_my;+ z%aw~Q2G=_heSC6r8}*~jOiXYCL*l#E!s}0L0la#Dr9b!EXW;&Ph5^0nhTrTT)A}q0 zvreaK5Uv5$ySz(z2DOfZ(G@#4t|ph}SewkOY>T)lQ5f`S3=!a^kDdBXs&W5Ojy?e4qI2x@g;` z_c~oUn1XetR{+ES&>XBfU)fDw9rSq7n4(nJpD8-X{iCMye`g>RF|8tso_kC{orh(K zwGx}~{K*IKXqVtt?tAxwgu2A>)L3=EjZDtjD{izuC6^N_zF|(Gzl3&aiplA1Qw5G{yG!`u&=~#gD2o_&?kP17i@v6X z_r+aiOI|MHx>K)|pi+6UNp;fzC3hd!8?xf8?*2)4EYW{D%QN@n2P38Xg?9`;oOPl9 za){^e7|TQqNSq@ge`A-}X&vn^ShP-4vHCtXz+~EoBJe$(QwpN#WwP{@r^pOL!Hc!8 z*z|?U^(tZtzx(`D&e;CDSfLoW=pvQ;6{Vg@MCr#y0sg?Ob46`TOq!(sXLE&=cX4Gx%JdF z+WAW2m@_2Wu@Rog%m0O5nwL4W@RV6rY4srJReXl!t$J&-c?2SmbR+L0yI4;R^OB-a zgOix={lvZX(DH+hQi_jG?9-Mmczda;S8Y>%>!g~+THMpnRNF((h2CFHocFFA4U8!S z;aEWN^cX)mKlHU(%yXu{6u8l@5?cSO7Ww3JGtHl{r#L|y(9bk3Ub26WJSEI^tt@;` z54fH8jw5Xdd>;0D@2hw_KzCW3jB;Nfkn}}DUZjMvD9*=!?nEuRKLv`h-I3h#TOXMZ z{3trQgZk4>9z`h5kv5r>1oWR!+HZljUun%mxAn6KoVU+PjurN6{EM_O540@nW=p9s0a})6czcU5G{2dcXyNpKxG~Fjd5#DM>VDHI zGCSTrU3v>)r`x*rR}2%-kL~`9VSWQMb;DJ9IN4{7*1xeEEOmDDrwEF2e3v^#SK|@s zh;?SW05?2=@#7RcZQ?cPc}r+Y$oJ<|J`jOH51_61T;sVNoM<238@}gI_u*jpW^dMh{sSR|2x6A zczPKhx%yR(8OZB1Wc^dS{U0ME{$mDkkhyOvmrtV{=7uJncMk2ay-)!(Igys!B&&@a zy`ibztA|F!RsKPbKKkc3sR6({c%~4e`A~!Wg8UG)hq+?%-kP^JU>LnT_TsAX#2|fE zWJ`UD$vgHA^vyFm9qS)hmyMBog$AoRcI7Ai9H*Z*C`7goq+K&pGi|XkkiMZ@P;oom zclH^&3>&$#-Zhpr_oC6IMrs+PTq0a(bHm+p2@)lb+AUO%q(b7-MR`Q2QF~`gV*Z75 z0eV`$n}RL+>fY~@VU;O6?JM&z0$WL$C&0Qbl&5;8 zTF72gpSp-R9E`Yc*16L>UMiAWE_C`h<`P?_OUv{vhijg5&$?sc086^jYynBprdtc@ zhL_w|0a4t)Gg|t5l;&>vQaD${w>Hh^vA3Wy<4vdzW1u%uZ zr@5^?q|oGoH1LhSPwl756Vm#PVrS>L+;W+Wf4`8F#LyPdBlC2${aKv&@@sQtv#xJ$ zlfIox_f@0&%Uvr*mMhMXcci~n4R@P9$trAk((~rh0Jmz1sp*cBPw!6G7v^sGd+*Jd zO{JyP37*WTl=`PO3&z}pTtCfA8}+fQ7g5;hKk1%w@CnTx2qot2tE0|coNrgvTofAo-#m?)vAv9Qy9L(|Ce?!axRV%#V z(}f!wd);&Utu@M?k;zU?iNWxWy@ZK5LyW_m5^Oo zvyF8IW2qD&)Y!6zkUb1zm>~&`H9Iqm?CZ=}XE2uM;;zr<{yd-i`#X+jIiBNrp83Pk zF-P;Bd7tm=y3X@_ov-tCR%^?OwkJ=fUCbxFG0fml0aFD?Jn~-OZ%>m|vV};kq=E}K zGYx@2PkA=KZ>NffrESP1{C$s==tU6MB$TZaO;G4 z{ORtl`!6nT7LWwCk;+~h;fc;F&@tC;uX@p#n9J|2+B*ZSI}GMY-bdLa0PP`NSd5?|E|)-PwK7RT>{9ES*85P4n9FNQSSE^^Jm-5SR&*hGP9;qY|rsU)Q2F{lt+pXzi z<+vr91r3+akx*Yg6v`2Xujht1v}6@q2|@v4M7{d zdmdI=rE*PA9x}eQXOz2X+UMBiU=7&P*VP^sE7sjFcs<`%E(8=>fV_3`8%2-OnY$>D zva{2#*>VM%?21$wH%CUOA+$866^enoYntGvscd@uxic+Rg=JbUOcu7d9XZs@n)|2P|r{`0p3 zf1302?B~1s$5|fL-lE#ojsxsjw81G(;ufGW6ion69JZ&$`XJ zvmVTp_L^1-*eFCd%h?+o+zbyiR(o4}#Z64=->dTB{-3_%J`mP=7(bSdV>rQ$5p=IJ z-)%~rVm_D@Um0Erd7B#-SKZpg5R`*A1@ZE9%~m(!j|8yt`klnw6FaAxJT_s+o7(vC zt_W@lup65`zD~h7Af2j53Giq3l6jmwwKTKU0-so=RgSY4=7s3VFoVKacT8rI*}6nq zxEZ5|=-X{8_axSEQYGGFBV}W+v~)Cnb9-vQ_W?9SJ=;2EwPPYKe_(=iBc|$6BayfC z%UYZC!KIN733b`yya^8iO15OpHi&=NIGWI-ZK;+?w-CCTjnva@LQmVz)g^qeznuTo zXRlFGat@!IY8UrbW}!pbEi+t+=$~sI){{g>Op8q*&v`CFc0F~ODnW0IFT2x$(O@&K zQj(|hP*_u-BHyAkyjAP&%PIJX{z=}MNRcBnW(tK18QSbYCVFjLCCjPJsx}_ocqx!R z+xV8iG1$$qG_eI3jrDVPx2DdHOLT`);-@p`?&nUx`aLj41E!=W5sXQvf;_@%|62^Z z@{s-~q9d4N4-%f;2&d^MTmGsBsG4d<-T}gy@n(V7nOD}!Z6U8-pR{4#7L;t;Oy|uG zsG^e?T7FxOS<+HkVrkj{!{tS32h*Z%N_tz41B!CKKX*BeN{VcoW9CsnY)|R$uU@$X zm8Pr*&9AyOY`IJ>`2RWDAK<@0U#^d~nPpK~2@I&dx~)>7C{zL)a&zBoE9MKOb zrrXN?4pQ&ljP-YTt74>>wOKiPhlo5}=!j(S6Omkcl zTum@VTlr*PkNe|&=}Jp6$}(3IE4s{+-~=C6k*25zPLR*JUWX^{4#y6bN-6~CmKcqz zE6m2USXJM>kBtX?kA-q4jGu@jPP9_1X3i^51+Q^QtbVHI zSzaF0)s0WG?i^6-%cNbqZar>{vRM|*Pd-J)5TjB`zn&(aV@Y70s9G`GG@~KkRAeQ6 zaN~^MmOWF?T(xp|BLH{lvb03P7?NRXwUtu*{9fq01Tx3hAMh$ZU+<=7#2d@n^~62& zrzf{9^qdPc5>*Jt+SYBOz# z$#$lfo%D@+y>~rZr_7;lR-|V2QWj*h5hKdg=_8(9+5qq-BM{%wxmToVSNqn0*2^&+ zI)r-u?%@h{cS=Qit%k;BShkEkt@nt(KpTZiqexEH=hGMNex19M{XPz>?O(fW8Z+2K zXk%Dht#q|Mq6XVJ!DqFu7X6|ik580#_*_DnT(^%Kic;c@80*E0oL>iu;5p@g7PoS* z*f%P4=m}W+;Z)>~CwT~l(0r@}G>YKmbC%&&zGH<^(_5bYE&3)J8$0@ROiyk9`Kef_ zPBh&;KeiC$a2i%5~9c!_&h+#D$yrTv(Kp1S78@+C~3{cGuV;`NGto>O)a$af*^T?1K-?)~+PQ@Fys-3Kb~7lXr$~ zYz>BHMU*<_x0DHyy6$4Eifo~)wi(x!%GZG2z&0gYL1)hAhA#EhyDMIqQpNj{96P6( zM`+m*GbJPXGzvwZ_%%9&mZ-HkgK8LLU(!y9SPiPo(hXkXc~H-vg~Yqza%s2V<1TG; zuWDQ}Z}gvqdZr6(eXt0?(cimHTQ3Y)hwP|cW7ZX;mtc}XBW+fCgumMPZFfj7pAP-R zl0SeHp47- z8BH0+>-pWBy7_DL!yiE>LeY=sNilO`_H&mJUSmb^l$VOt*~2UivO$Rp9`Bvr+Cp8u zXPlpGtl!fIgG2GtZQ5OS2c_*hy~aD{Tl9IzusM8KiX^_fLFj7+g8901tg)lqR|e;+-gsk^7&Q`HN@K&PS!pk1Nz`L-PCHyy_JvNHgb_Uci}zujszjp z|8S##SJq~+Afd^rx}Xf60vi_?d?GB@xL@ae*~&7Rq47YDREa<4=Fx5om2EOw&4F1u z6&w5dToELQ$`{OK$PL^Bf(Q@I;IQjrrBdz5tM*;X%Jfrjfl)UL%Ucu}%w0DT(ZlTLAi?P@Cqxj8 zT}U|iQl9xA>_xj03?u)%>%TPJoub#g9}QCRsRL4<=S+Fvn9_*v-s$PMFblt;Z=XSL z3YS%=uy=9Q6VNO*8dDXgp zXCsh~n=|R{eli*qGLckvLA`bTWBSgCrJl0dU+f>dikYxGKVh~veB|-C=YZo9cSHiW zGLKxf11(3E;FjGm>I9!Xn*Zm=^Sf>G|F{#^Y$2DeWOK=b9M7J9f@FnKmbz-vc(*Tm z-)%k;@HTcvVc&^d+7UyjD=KSf4f6P_zd8E2krtT8;r?SthnI}M#SQN!I9NiRHpHK2 zq{62r22*SJ_O1V}&pyr@rmd26TG1pg)DR{}s4TKzPglxb?b|u5JwkP)4PvY5fv!Ge zjaxwOHTi%C;RmdxGm?KRn4>4kA9y_V0ACa9AEt0}Xzf1M`o8Ys0JHN3rXLA!eh61B z-XC`+%2r!!*+PAtrkcF;-dMWLwx0T*H`i;L>Tl0tQ@=wOmvGc7uE8!k7-B%Y@%QbmJpu^{mkp@5opmP% z-JPxncS}%EHyfPmTW~s%=szz=(jXW8U&PMu?k-tE=QxVhN08KMHmT_EQb0OQ;7S37`@{i6|^s!s&Qy##@cN3R?TAS*s2$d3t)f=9X*jWPu z!YN7h5!2niSikGwfuajGT&{{O;@v`pES$dg$GdDqJhpC3SE{LUyBkJRMdXZ%6wI5D zS~vuwPdkp#+8wQE{e12M{pPI&_KMO{%A4-4cFVU7tmgnHF(^eFgry3Gj-iA!=(9g0 zhjq!fyZA;x7rt3ve!Ux?zKUHx;qGxlc~Mz5xvK@ysl&kt(w88VI9BFuu~PlJ{_O1# z59T)_)MkzN^$S$#C(#-pe>$waY>Q?qO!K!;9Xn&*KXJLJ(okL=4uzR6#{>a!ZD$S+ z(FC%GuFrk*&b9(`*jgdH%dg#FGrD}2H~aMbKZHEU_GELJcgf=uRfk@dsUu~-8NDkX z2fG(6hcpwf=oXGNN}%-b4xQBQV>* zgF`8}3BiX=Y=fS8s!xtt91h%HXf{`Uae2C{+`G4{E5l^pTbe!1U_X3G*Tbzc7*q`x znvA5P53tKOQcrRI zb>GI=phl>yBetY)rinr*R6Hp6axwbco81c1JyRt@6Tw`>-RWanS?TZ6b?}9flkM8T zD~a#;Ch$5V0BD{W>dJ&;zX>*haT@--hj=cYL|Ku1zFL;{9i!Xz8v8EobJGl=MXiMRG#70WlKp4 z9nR!oGn>k3L)+6q-;({|QkqF+VZp|y%5zsP|Fx0$?KXdJC%w*l9?#9pMoUzIFN_4I z2ccsbQ8%n-^~4BGeK2dOE0Z;Gu5Kgp_{iquR0)BsgpVNvyNgcY4)bH8ehq>S`66bFwSdo24MSWoi+$%KKDscv_Av#}e=y`qb>n^p~Wm|AXQ#ov3t zbM=k8Nxw0DCj3XVp!Ko|+|L#PuViW)cSUxc7)}Q@Q2%?n5uMo&g7r$Kg zQVe?;=8cwo#2$M+Mm)B@OUDY4GrpE0FntGfzQgWWdEN3V7_yM9hkQr6pGc4+k{dgO z2$!5>;iEj#&Z5M7p$O zP+<1~;9ijuQ2Jd@xf*<`pxH*Z`}}TV|Je}TW!skUsEP<$$i(MSb@0nWKh~!!W2(J{ z&bsI}-vhF@u`ppKrmE`y2%10yneAuYf8ppKA6H1fflLwiP*#)N|8^ecf)3Z^ywpyl zKmV}Qy*yB*qO`V9a9wAv(EJaWagwKk{N~u4o?5ebNxLa3`4n!9(9OGLe-p%%{b)14 z_osg_#@1`TbPrflTNZx(!Vk8E-!a4O+S`+k&z3Uus+W^xyTEgQ75BKRTyr4TWWGfR zZ=F?=+MZy87-WR*{Y(!&%hx%5VM=EkFN{BdXpae;dGE3BgxS&mK$oo45IGjwy`2Mb zVf3`%YcAQJA9s_U>z~CZYh^)MN#)X>qZ@*Bdm!!{tA-R`BiC9Czo1aMNt@y=9;K|M zVflz~vr47x>1d7r@!?G51N*2Gs=fZ-Zqn-vtO5bitN24 z$lbTpUAw2raKSSFj+mlv{+WMnzs*X$-i(#jtE`pY-nP7rY|=i@!Uo4oB<*D?)Utkb zWAbH_9PdEN!4!uJ@*eh{^Iu8(3vWrgVR|?`hVE|>Q`;owob3w>z;vyhLx<@vz)k-( z?Ezal#yx=ibnvW0Q}a<3`$?uFU{3gx8Se7JM18Ij2&wDqxDMiZ=;rq4PluqpQD&Y8 zUJU{C%NQjd1Tl!NP-#88Qx-$-oAsq${6&JjSV@o{@x$E*vjw|ALT^qx% z&(nouwk!FVJaG=X4a^PJ+OqEw<0}*u*3KkS4jiNJH(V5VSrWKWGto*3NUA*OsJVL8 z$P6fjgAto4MD3pvc!uCu5!2ED(LX1Dx?(k~AzUem+eC@^@Eozq!!0#vz%2v2OL_j( zBfv=>?-&0`vwy!$Z8HQk`=fu+?3c=(!WLc*;@5^BY$>*Xy&ZV3r`7lX(xF&!Mi${F zw)DWA1sn%i?g(*xx=kF)?Mo+k@YrB?d4xn5(7T<-v=ZJUCd`ck2F*&dY^G9?3xi5# zqpy_C)?iB^cxqsLOtHsD{sd{3Q!^q<&4r9E*S|k35Okg4{@c$q$%d;uSzu()Q9zHw zIJjd>1_MSetkd@bDwqGN)4=a8)JW$Yn*Af4HR_#-?H?Z}tI-6NKZokt9*;d;5+cMw z-;duyd?^uUUhEzd@H^Gc^HeUJpQ{m~4N>xuU3V$D(FsPsHm0Ma#pwl<)^JWUJrsT7 zCxPfMuLWFKM-7nc2MfyH1Rzg-o(VXr1@p2X zL}4K&@mkhJzw4gb&4rQ)#Vmu}9;A^gp)%H)cn(+H9&e3BM;Mv-%HYDH+Na4rR#o!v zO!mqAL2Ltl;K=$2JS$Gb6K0HsZBBe{->FQm63s5i zD`;*@UfYOmmWX)RIQw0E6_fRoxAc!jC1r(?ZUtc5#S3mt{sA1yV;M5vi3`!&+PRwn z-!wrq!P&%k2D3(5->87Zx0G#Qb@g*sE zXW7A{Wdzj|sj&Wv=`XZ}$^22e=nS{r7bz~XR+IzE3n3U?85n_aXotVdYT+Ws6_+L3 zo%HKaK${G;B?J}5IJSg2>ZSQ@<{`f<9aH49SqvW#%Z1M@BU?>y3!@9)JZD!u2cKzZ zK0gIPwrtI_;5xw2;vs{t6IN{jIy@#ykR5lTKeJa2{2NH>rM)K--$mKc`jAFu*v_6 zgI{wR2h04_AQbup2(boCL|z~ye1lv=!O!>6KYI97EJQ*?5Ut&`2pQ2h!cxy{5)Ffn z{ZtWY3GrR~e9X#cZn$S_D<`?6bn|c*F=72wKEbALpo&Crb}}mO%XM&Wg`I5&;$=1u zVul{*5n(7Fm}qwYli+lv(8+H&XKOmv%k$&JSaxyxq#bjnVbohS4U3OTnRg`$rCKY&B}R$Qr{8MF`ObgYSX5>Y;1dSOU!tWvZF1mPEZUvS0Ku@dIvLG z({*AT>Y2JVv#Oo(bYm^tO;PG7(8cW$Q7@A-eQ+Ox*ko*E*15^yOEQ+0`y+jCz@z${ zTz?GoM~;k77ib{dW8^$P*n2)+pI+T;f3_vcA(8UYP>et%!d%?f@!#gJQnN{slZ8X4 zS$h3+;Iw@fTUu&TCoY+tO1SIfwJ|+!PR*9Kkr?8R^HEqcH#h185X`Rs(E}99PnQ7W zS;6yHBz1`(>g@FJGC`-XUY;f$3Cq0ev=v+~vV+ZN+tya-F_`Vr;H~tk^^!9nw2E9) z0c3o60vCsjQGVDqcD&~$_PtkG^LK+>h@41Ef62Na!&o!+eMQqZim%vyINQqj*v;_p z=$5)9*7Qa)Ys)?1H5OzIhsJTl z=poy*GJ)bIFz8k+d@ni*4~LXb9Ig0h=0AmM%i`H1jE}p;C8?s*U<6%W$CixNiwzZB zwDK8yVQ;-JTKqfX_G`HnURpExv4Byd0v9E4`wz!tek2EzePHTG`}0@<(*KBgSI#O; z5p|O}(I!(^(BvJQ&B%fuzsaW1iN?{{DUZMuouI`147U&-%q@rN4-ao3YK^dJ9) zpMoK`pQgB1ky(27DQGQi-3MwRO402Ip9+r=ucmB5|HKWWLG^XyF=CVwZU53p+gh}k zVqg?rA7(U(8N5$Kd(3&wu0HG*)PGRKk<59Fd|>}%>OBDrV>z+yh>Z9>l#o$UYoM<{ z%gY6!;rLTIJg;QbWF#s(G@#)7|QY z@N2CMoQeyeK`NZe`1qNI)S-Gd8RF>$}qn-RO zRQp(43kNxP4GyXE@i`EfLppNNYw^yw!_D*kvPphtoKn_5DvSDAQ7L{a=S_bt*CYS1 zT#1~`#$dUIIk|`{sC`?x)5> zZd$*Z1~SasBD4G5lh<8m+tCR-E4Gg0xnd1**s&8YC}9hu7UEs)9CgeBHQZ9lnNSC7r5rc5wT~+21Mgc=#Xi>v}L>*C3%)G&T_KZ7o<>IL*z$ zhpt>a>cd9Nfk1u{kQ#SV*S`k=gK6!gG(~bY@->Z=m_$oPlcv7ChDz~c(x6%8?n|GP z?s;(V6ixasf=I6|mn#jOod6l51r&tngjtN#6djkqgZ%4!I8j zzoPtGK!@7nG+$mg-dz0vQW7brM%` zCc=G&R8wI}MXH#xUtwNz8vfcuD2>1W2aDh0O>9t7EJ5nffgP#d-q^!RI=o#{QielB zBkxa2eGexOMjbcV_5mpE%IAT$vP4B4FIUr-y0R^W2hOmnyXq~pAF*Pt9B#eZ)$qkW zn07ts@K;3);=`TFVspac0mU8h1JE+@PwOxF`!1^RV{6_7$N{~*gA&s7B%Sy(_X%(6 z3i$0a3*~M0vXTJCZ5LhZS1^DcPE5XUN+P!bI(}$U9N5ni(^te-(nmTvwH)`DJhz3= zme1>&HO0U>G-r0OIGbqc^(;kTc+0@iG@r+!?2hv7-x)PBlsu2UP z!oQmuZK~d8+XW552@Dv;|9Jun93zht#X$@bKE_qbZF&Kf#O88`zpJkO4G4yIcxD*nNyAEkaQn32)H91J{FXtkG7K(+AfYqd|EO0J8Hu6RHm)tyQ2FN<@=Af&u=#Pi#Dp9 zN&a;H#-o7Xw{sDy7K~=3(0&goRiR~w?-OmNAdEi8Y5p^#nhqi4YpZ0n43J1uk;926W zYuRuai+vLe;53!9hpbb$?|4>P=FAXfC9IWmhNcq+-R;`Jz9zHkrU<^Ky?)l&Nb%LO zNsyj^Q9F%tL5PsEqyrjNIQxfHt}lI_PV{jbqjy&}%F%+hF9(q0E`~Bato_RTZGt6I zgCgs~m@1R16kfzzU$E&dP2%KC0Z&rK`-9lT=q=C5H1IavZ-l$|q1~M?>49vYIdItvDW5 z5s)QBf_(W@l!bE&nuODVR}?OGjR)2U7x^u{)X|mG+rew$j?>Z3DRNtuj2~eYB$m>Y zfx(NJRbkKWetUOw@i+69H+fb;PFIq>SMR(#iMVjdbMx_bSSlo|z8g22nJGaQ`EDOR z50f(k%HRnnQ%-YNV+Eu)ynZ2}GezBum!;3gK&d`l6Z= zyZ(Rx1q|o%6#}z?Uz@+p{cxt!qP@Y)#0u%~J;4Xl8e#`g_Y356Qp=6z!wV*e7k<|@ zeB9=dkUy(Gi(w+&LAF|=Y-~7mWAvjY*Oja-HhvdZw<+=}87vUnoC_W<48<%UkCIJ@ z)Y~KJznV05Yu(lj;oL@L4*lgtCqEMewb$8%a(ia}oX}()j2iMub%XVB2 z(}$!CP_emEIj(^-VqH9O2EdX8;vObXasH&j%t_kjG(G~(9{;%M%8gH>GhaLL(?T|A z1(clKPanGj{_bAq3|UMPP|}IwTTRsTU$ z*nR&AXtQB@YW4s4m7tA zOiXzKKh3v8*4eedZN|Fff2DorW3=6LYZ z)}M!9Q!9X?@n(~R=z)`t?825+MD94Zy4h|CP%EMXz;gFPJLt~OPXkKIQ~cs3A-dK1 zW#Yz0q;<*YAbbT{o%E($WC9SG%QY*H$J|7U*Kju|RC+5^vguZ=0Okeq^*$p7L=?M% zY^8gX!5+{-`PUV9>5n^?eu@IMs6qgf>(~5fx@!xHQLQPnw|1tGzmo(9y&Z=Sj^8LO zW4d5-UeeeEGS^aRWgv-{1(|k1w|}M=JAmNstz9L60wK#gvFbzAL^{L#E^$))$E%t% z;Jd5tG05taV+EQ+R)@E4jZ?3nOnWqeD1iMCU_SNhrljKpIFSV{e#2%y9HtLrOF2nC z{QbRM+knoUNtwe-x3XDp%s<%P_7WA|hTh0@4J|FRc_6$ksD^0D%k~Lkn$I+#wjc&f z7-^L>>mmb$%(KLeHa0!Ko)NkLhw9H=@V8TqpO>7?Jjf$^5@kS2V+*QO8V>2rGLa9L zZ#a4RakG4?4;Xchuq2{Wa=tph{3!Dzbc6R;Eq>L%Or-k# zk0H2G9-r}GN%MsxOjR5`h(#VyY-|Y&!wZbA?b|8+7s&}F{Bq{I^=n|_4sB#RsZERv z@Pc|vic!~0kza9-U#h&gPN+*a2xXNQih3;hrAmHfF!=-V33Xe-nH*uT@1j5uztQ-> z=0sRVlQIt+-=3V^ncch{-K|XZQ7`LW)&{Z@zV127e0Br#k7AbmFQ>oUB0fbfY?_hx z6^*uTKZ?UORnqOsw-d0PN$3HyV@xEUksBSuE{-kuPy8IiKYhl$;lGafNK2I5(LXi> zRfZUp%3YoTY3K!{w_AeetkI$VhN!!eC9Uu7J^6EJZ;;kVMh&~l5_?OgtG~UQpsqDP z^i~=!kDC|rQo54acf8&!OIX^9PK*U6-*#HDD^#7hw4!oA=;<+&aXdHY0jBAvKaJG; zlT!wKpJf{Ex6l=<^X`of;m18=9m+xuD_^MEq$wv+La+WvZt5=Rg?dhMy9m=a=_+OY znOG7R3{ea5KQ%}WX8)?NgIzy}!Nv`)oZ}NLEM5S)tQ8>aPn^bO-Q>MYy?-AwWEH3p z6`MS=VlB}A#w<737;FzS=pXJH3{iXbwY8!DO?;84D zppJTI4X+{e)tWeeI>bwFL-D{9UPmYFr6VLRC>9#(R1?J?2Z#*RQ+kkZ-13H;UXx6p z*7=k0j%X{QBdkR&#Z_0fPbxaMsvmbf9lGo_C*xI6F_&kYdvRDTj-M;3aYQdcxu)Ag zRWo&{{mtxo*LODI+&{PJ509Tti|L6_9MC^e^Kkcv$82faehT#7^GV`0<@Qmz?)qZ1XOO{eHhY?T6XO z?**GdxC;Y)EhUiT4=g7W{DyIhCSxc3seJa~ItNJ$p=-F!_21i*we+PYFw5it9f?gx zy%l4Ap?wA3g)QQj8QOj}ZVk$YyKHqXpw(`+ERfH?%MmhJc`-0cri>AeGd(=;H!k^O zHqjJ}ox6$reX#G>ACm^EC2tpBRE$#bzKzjbNvpK35U%XX!I;2IC@0Xd@OmdJ5&T4B zPFM~iI1nd=hgx?3Y zbrJ%ibeLY&$%$EbZz`z@hIBFK>!jgUlW08|3V`)Uv{$+8NZp8rsLyUq$zRFGUb*~; zwV8{o9%wgP1& zY0MVWxsOrWQz#fM9dxjIuE4jQGcSHn1kz!Ec93AaM2>X(w3~Y4ihgL=_m?>P(RI}p zu0iGkGlM}wky7MuGp;|(o=ld+5FR?`=NsqEr@2|!d!7A-4@CSczyt^qlC|tbJINQV z=xrG*7Fv_8YO(y|s$R^=4M90Msrw5x%#UvZRopjk4CFb;oSPcCLa$;eWpOE^AmhG; zJR7Hwq#;5VwI85q0`d-$wW8ikw9a%JD#cPVscr7ggQ9P#ng3{O%mAbh_|`Lj7bm;B zkapdN_R`^-&e$K?5q4$mvM>__3UClb;tIkL=LdXCK1}I&Qd^;t1xdwfh*b9mb!Qn7!UeNN;AZepS+@ z^ga=q8%F#3zR<#qpE(XQrcAweV%sReO}O23qBV5pUYU;Xc&G=zx*DQ2(+|u)A22EU z7SHr4jlaM6CzE-3;GdbyRuZYn7)z?sN8<{EEAZw5a3tL+*wP-y4mO?DStd7T+}S?= z^VSM~g*>+vLsfTJ%rDwa_2)9ZtyI>6PaYpiXRb>uM>wjiKJygb<)kJYB}d-@iknH5 zsSyO+lL=&^mGVi_709t2UUUCFDUR^wR_HhEd5KMgUe^R{2^Wbu05A|cl$@(r`9n3N zJIW?UB|T4g*(t<71>j{;2ScL5VM}z1FJ{ z(_1Cyq%RbWosI=m6#tarP{937ecjn8=o9WbJMiNQ)zazu)Vw%gmnx5GE%Q7U6#6^= zm;3iU=F#e^^ypd*lU{PjGVH$zz)te*L8)WSaWgyH@U??R4meyg8V{PuRUGyEfN0YA zgT-p7YBBm>%l+px!`=%1&mFev8 z>Vr(VkXUY?%+tmR`X{&EyZw!Q>sELraX=|2L5Lvj1$~i@(`y1s{uN(Fz4R`;28&#&?-m&uMk|J!==Yvhd4Ss4O9%PoXVb$$e^RuN?}$y)mdVIu zd@k4`r`24FT(3~d*1{WF*mxrn%w)G0$|ZmZI@!r2jr})vfWqxY!FkI6@+E-9eNe0i z5KVB&n(&|OFLA?3Y@LYqoqT_a97cQ4peyJCc9sKCBA11<{qgK@QT0w_ z*5ARS%ua8TSisGoRQ#TsH%a;wxO=j1a!J1~;WaC6ad`|cb#K z3#~##S@_c}<%$-G?UitXq(W}>(b!)P0CcABuA(z!eopd%Hdi;$(FRsCS{+%22i#Q6 z0a3kAr|uA<^@or<2w>AKeG`uA7M=~wn?DHt-gFe+sQ8-_ z#h?ko^if)bqIy}EOqBBB zwzcAtkv8-%g>NeY9@d`7@z~)dN5C4jD*=qMizmOD0PZoEI@bFb0AH_PpK{x*Yxa#W z8El(F6d1592^dJ?Tu~f6^pmn$-s`o4q*DJjk&s~Rt^-=JDKDfei&{rkbBm-SU(uw> zlHv{tJw4nSl`uNQ&xBP)_DgqVjJY4vD8Z)Z$FE< zKwybT2x&SfsAzBPL@n?o#1GlZ-S+zx4DS8+29BV;=wK}~dr5ERLJJFLv4@&?R^zhd8|5*8imCEM zR&fGC|Jpqi2%k7cN>rl7Ttnu&!lo6pI?m!%YbpLd77t1?2HBa zwc%0qSTy21_Q}xL-AKtT5vDU<{|$v`f+Y{Q;wKOM-gO4L=W+PEY}_W|X2*B}ZIk3r zjwle9SzvU4UZ6rBj&fRli8ZOjR_EJ&1dJbhgOqQf8#pfeoJNl2y|aVryKb64+9=%1 z^zh(Mv;GaG1k|n^kgC1w%y3+Jk%hsGZe_(dY*AyKdE5De;hQDZW})}Zwu)6+lx z`zwK7)?aKwMH3 z-=QKPDSZI{#^SuZ^`N(mTW?Zx=2A~QEL~a$0GV$De{SagzoTpaFM~+`4`PG=)32ZG zPFD(QH?F8D6PKO^jMJ*nl)6{2Qvm!r@bgIf8imb5OLG6j5Z_rl z0GfMk+h%v+)(BSR_W*8h-#TVq%W8V^N)r6*4%Z$-g{e&#FL;-RGBM5LKqX`6Lw^VM zx@;xQi?6iceK`+q%BpOC=%4eXn`{!HLi`0G@^)w;N{7Tt>Jjy_-{Gfc=Vqqo6dp|X zi1O7x7f(`Zyxm|OtIfIRDe9-(`QNYmzXlAA5&QurWsIKut6v3w0fl~mvfQ_3ss9Wic)3$`WLTik4L#25BL zNTus(xA2S3U*EZ1U!yoBXnwtaTdM1!p_66V@+ooQ+bum%EO}brP)VSdYgKNjP9=Lf z`A7BgmlNM!B~)XxH05uYg1I=7HjZVqnUId?lv8nf>j_0}#Fk-4+PMveQ>e@EOmesO zfj!tKyS(D4wh-r0MGv_9;SML4JEESL8LqsqM0cA zdW@qQZ@*%FDSjClOFS66*4BH6>!S}j4c03osMVsJLoXX9n%`xKQKyj((QfnvxtM~* zg>s}r?sO6xZvbQJ0Z#DhG6i>vvL;A%pUkIl?VVR`AD_cq%0#)>PAb?3P~rkySYiI% z$;qifjagp@mt?~G4&PYnQ5LA?vU3$5?!19)iQC8O5$!e6yBP-vEdRT0@qYqn6qiis zL|Ud#KfOP(RvF$D?{l;GQh%GU5e35)`nX}~bS z(+N`|a`sT>H*6re^1GjnP*ZV&*{U3Jj8=n+^784!8yt>TU~Q=_{|(9mVFG>gBG6x? z9oO>qH!8A44x_!T5-6pxSdTFj7t?a}20*SS(bnT8*0TR); z`iF!^1-2b^#^SHA-Q{aYVf~a|2N5S(Pq*G|gmKFasY$NqiduDwhe(P2h`kC$QJt0A zOZM?xl3Fk59b8mmTBkAlKqU|ZlvE4Xv)i?my!#Its4l80$pnv@w1tQE77U%fOfbK% za!5;C|4eUeH8t%hdC*R>WhFRvPqo#=s6=f6b~&z=*J{81BXx4jx>hvBS?&r##yqa& z)#yZ_G@>{(Mt}RMwUTUOd~L=h^!D?#K|E#$uTm=+fE#6kC_V zmGB+d+MU6z(M8?P(M+%@(+O^F`_>_M$BQwk$CkK#CH(>< z;k$ap)1qk(lBk>XCN3gRUR&6+K{95B+}l7phYuXFh_s9B9hwL=ayy?!1Dn7rvx!Zpn~;5v6P7wLDt&Xf1A=fUc_IXr*0jcx#rkVru?_Dpg`J!->D^s6;CqHY2O}`c}K6Ao7q6+-mo4 zo054Rd;lN9R6;*unpacPzE;1tBz0s7%IL(N$_t)kdPwB&CwbmeAE&HPml95FpMG=2 zNCA?f)Gz0*7EBgoZcS1WHch7F9O6Bt%r(r)Gkq%gou7iAzx(^`#+OY(IVVDCv@(;^ zNq$mNSH2^1=woZMat&P(nTm|(neVc=SmGtaw9cciY`J@WqIbnf$5O-ZC@1+`_>@2W zt9H3V+uB{`yIAD^HCT3Ydv0(ul6@sGr~6^MA^i`VceRHOUAS=g!iCST zR-c|q-go49%KV-iH;?eKDWBOhcFnw-J<6u{V`(XZO2Wz6%hCl&8fCB&G&0Pq@8;SX zEl&DS%d~W7?S<(lRg=0aB6d@hPMcztWj~cVA`~)kDSe<|b7`#VDu2OhKBRGtKuXc7 zM$~-P_INoFtz){{=6Zm>xOG4mnw*6Aln&Lz8c1?OG33@QIU?JWPtd}fp1zf{n?Ch9 zj1UgL_8;veUTZRAZFxMjfz@YaS-uQP6{<@qV*JcC)6~oG+Tli-hGfILj8kVk!&u~a=McuHmA*4R zE4eX-9w>ge-swwh8Xu@Bb<~ZhbbX=kmE+()R*=n6H39>}PSYc^hWwulK5qRXsfbuEH#%-2^EnRx>w8)zYjf3?qF2_WZRa?>6{Kx1FY z%C5zhI<6i$qDGm{UC>J;A_^bd>v+Xhr8K9gI9s-^^s1?)Aq1;!2VN?YbzO0(VV=xY z*Ge$KbO-{6Ju>*(YVc)_Pd>_<5WbjQ#=azZ*)(y$nO?~~X{tpmoy~IO8nQE3{Qg2X zax~UtRXo6lfw3)IDk?1{IT$GtLJLyX#?rfchhTZwxFJ&K-UW@+H9Y6I+}f7+dRp0x zVp|`{)QcS|MMzlx(W;@~=FKn(Hp||QA9-C`DeBb{)CPJhf&E@S)@cagpz+N556=bD zhX&U=VuC0}3YDd_o}BTB54S+)aAnrTg)vSs@Rk1bI;&%n*s291oLX8a1n1L+dG+ag z@nQy`>Oi1I%K7W9NfDF+%f{U#@7rIktREG#fu37_r@bm7L2}>$v^`8tl{sBylsVl# zN15o_BGYb`4$SnivF|1VU8PU5rXr}(cDUKHN8^VZZOr+yIwbTnkscJZ|v z$B;`gHkOndB*;(uP3(AMLH&=={qr?{?3IUAveolEcIZT;5r@@{7T= z5Ya9Dwftg;O0*ccF(n?8RkGpTpN>yTS(mi6b$rKI9rK{JOl{uM-wt(Bftukyi0E?8 z5t)mz!bvg|6;BksQ&>8;Q1UphgD;=L3RK62o?=%{?_8uVbp=|=9TP6txJI@uoK%GB zrr~ObD0wS2A-9ZFK6c3~_Ub}MnY&W2*G84S6z#dPG9tHaX@w*od?p7mWt9S!OSZRvn752}Wj;kWiZe@FEXf)qDA5-sf zWngg`(x|vZ-mY7&oHTWYy@5iky>6sv@yPqTEY$QUaoj{?u#V%F6?h*av2JVYw`>|2 z^Wd=Phu{njIBi)k4O}}KbG^t#ovIdX3uWX8<5`|ouq*Kj!o+>2GSEYkY92z~`Y>Z> zSs8+2>^Q5htk>8^U0q#UO8FT=<>=a?sdrFHm5kTqw^ggc#Me%{dbCdu?G^~0Rz#j6 zm&V4cUL+7NKf1o$JC%%=%#jjoH?{Cbq0gY+)uy?%;1V$HFY=5u5!1TU^C3yAj=Dv!=gMR?isDgZ&f+psNc$w+!(wYPCAK2 zmIicpT&79TM-Qi=rVoOWL7)o5WznemQ~jd(>zT`Q&KT5Z(wwu^8cNW!=S{UqWTMtP zSJNkyFa?_g-Z`y36w-;4RS8znDy`u6FG=+hRN}-1VtmV(9c`I&fsyM`qH9o!Vsyn0 z846P2PSw(NeUVlA<&$5LJl*I$pIl+dR`~Ot?n8$7BT(K5rIH>O2LHrVmz|wjsbElX zve)*?0kG49Sp(&6b+rxue6kU~wp!KODfM8C=BL{;#?HQ^02yJIxxIrOsex~rz-h9# z$sr4|o1q`?rJ^))ipvcnW5L#yb6#0m!ade{YqiU=7T{hJIUd(nm^rV8W)Q(^=7zaq z_#D-79mtI1X#VFssy_@Vc)ieFv0wg13FB-tF~b{942_2e*eA!9m5t<|LxDRZNTFtdCEWOur9! z?RmwML)i6?8qIfWU(qgCJeMn*GkdP$ev~hFMNedYZDmayDy)BOyk26K)Gj8k;gQkVj;qJ$(4Wk{f)1Lc}98;<*a zOFa`ZQ>2CXzlY9bUqyPmf@8_`8U}Is;>kF8!GjCoMBft24lEO6s694pPYz7sf?qD$ zCaVjE_$j%U=yv;kDwb$XqzsY`V&(9_5l%C$R))!&pkflEf!$07LXHdF;E zp1=R7s6qF9meC>|!6iL}V%uHtV7`jHra3V{7{_7r^gDeP9Qt98%{%5TIWWHCU*jV+ zk`y++r)Kf^+b#sv3c;_hv{g@WBflc1`M1&G6p0J4WfnDgSe-{>!cb%$22xj(jB_-s zAdT=aHc*!{Jr@)%F!z%@eYFEhm%m#}EZ_AcTgl4AH08C z05Op-C408@xwIpxpz8?Q2ZuQhSx;ZQc6luti_;a$!k0i^{{%H)*wU$}Tc5MaoFKSX zkd{9#G@pi<1NJzMrd|dF3YMRF@ICGh#Bo&Y3+!=o6rN)PA5I-1LG2)Qtet^1<4Qvc zt7fN1Tx%PeSh|a1J4k?nU3Uh?RL^ z#mAqfp#%?KcwI%%J9k8uPd9nCcTl&Lz-TFfrT1n{jtW2!C{p5zB@PYtkn6(r8u>-j z=lG{$bgFs~#hc50y(<14l=+kleS)-SW)6j*cza9czb=4<`{!gV?{+LFX$mn434Iy{ zLO2km+Z#6eqUP^5lh5XaWS4%I+3!p0NH_!Yh|zb>&P1V0cl;QXlAke){nI`DL4tR~ zhC?L)ZwgR_AX!@VNRNyJyyyD2+QQPQ6asaqK+ZzJi?o0a3{?5gP93VF+%+5rHu`g9 zJ<*E;o(mYeCyJ~5;#*LAqkG3l9Q7~ZDR+I;3?dWaJwKF|uJqeQ`fXwepom7tdrSZW!tmVlyeHum_J1xK2$&Cs9t8_nQ|ua)m~R6%+3{dT5`G z6m$4qbFB@8eeGNRD_vFw)qzaHFBvx*V!;or-%+Ql(X`L^1&m~iH#Au&T4%46w!jTl zcs7y+q!2!_euNN zSI#KV$MmTIeF)pTYq4I%o=D7+QV$*UU9UZU(^P4tT{mKt@QK_V3z1Hydd<w}!#Nw!U!{UQyWS+j@6ULMi6hREzJ@*UlKM%;4t~nDTfUnXrk zUEe7HtUA2fu5wh~zVrH%EFguve{8KryxKZUjpczSpj(oE{#!@^5itd>Xaq!x3%CNBP4cuypo|QD7T(K>kYZi4ofdb_bEvO(LiFVn zZV&M1^{wXSS8?;&z1#hmZV3#_(~FXu4y5xtW90ogMqc_qogdil{J0%Y`JX#Pyd+)ptI01DJ4c~d*joJ4dGj_;S-!ObY44w77q{E#NH*>tCY0sw(BqZS z#;+j_FYgfUl1s~rg)EK$sTbF90X?WO`&FxDEu)kvTw@}WTVE`9GWX+34aE#3!0~D9 ze-Q*~|tok3M?Bjw+6J7TzVEA8{0Wt!z} zZNIU&-O3G2H(z+nM-ZxlwNR6dQ6x zaT1m$^>6omIdugV0QmeKlWdG+xxbkHw%N`OHt&m-WZgm8R*yCM`G3FUG9n6;c+vXf zfM1mZltCgA%=ezM>^R6qWwZQsE}wfuHm-SZ?XTUvb5!VfjWqkS%N-))>HHXm!II$FL5BgQa zDG8>bsyFG_di9GfZ{x9jrzOAPgH%2la`7)ul4aTq1 zo!OEFypAs1D3MvL8JM&A9lMT4WkSsIFx%tAX{XNW5&k7 z=XI7>zV5zd`YJX*=Y4i4DRoR+SCzcg=D<#y7kt;|dIHSb1=1~{K;AVw6%~4W94S+w z;f5U7Wj=X>zVjp~v|zI_2Fz&A3b?jX9U^+L#BVCVlX%te;pLv3Pe%#bUpr8t)5&c~ zX;hV=!+yHkbA7FtD*v?2vrfCm#7}X>J>AgJ8tl6Ayaj0a0VLGZK5=6)*cb)p*zNIV zx}dGvnGM~>O9lQxv%*A`p~Ou~;Bj6hnUaF?e7EK<87Z)HS7~Dw`_mCX zGL5oD3(98-CLJz_4ar#2;t}eg+zlBf<3CyPR362**tFrFRwI^xZ;oFEx{Nk`LoWdLeH0f#ERuos3TQ{W3OHu(Sz& zsmr=>k(PM^XkoEoE2P}}GZs+p35+mba z;wiTUE4)ffZGXCW5BMTsZNGeCR3^(T^JQb3KK{0o%k>e`jha9!U(Rmn(TgeIi?&={ z1CsLcksE%%cOUKa1Fjp~Hqos({jUa%fG-l(47%a>lmGmr0gN9w(L*7e`;G3<)pP%T z&~NOcb+;XE)#hi5iG$P}>qFjv9G}qu2*#4Ob&1R0$)focR}$8qkeP`1K>?V{BfXn| z4&HdO<&fSi(%66FJuq?@Dgk)w_~osM9WQm*km4ifqn#fC%?mIGT$b;qR^n?9410SV z#ybz@f&{{$Ju!}VfdMl$>4=O+Zb)n-00O7Bhp~k;e}8N*l1X(YZWG2G7~1R9AI0Yk z6e0}Eb||pZU^wsvA9;tQKxM#jSb!KXo2TD-Yk~1Sw;0&<62QTag}%FgfBBmrzlGtq zBK$^%|BX1KSyYKalD$F(0FI9cK;TI8R zlD)mAf7kDMb&=OzvgXQ_!0IZ@-uFi}T3hhy3-c`t>i44>QRS7M#n30j%h|2Vko<>eCA2e9Qsz@M|q z{09L?^KQTV)2oV57VWb_0Brt#^fv{5Q{XoRepBE#1%6ZDHwFGLp+KEyLR?U(`8pmm;`{f#yHC!t}D&7V@XQa}(cvxPkEJrH?f1R2;m-mt-qhwsj^(64Q^tQb}D_L;m z2cAu$s?dXQorR?yf zM1KkU9CpGVeVl`@X$xd}UE!IV8MmU~dd$%r3Q@3fJy%w`u^vo9GiXE+jmVe4=hemX zBU-U678+6|ahsiofKQ_lnv4oCv*!5raXM(8j3&!Ag4UU{<-1ybWWYeWL8J%-4wmuz11_U|fc`jHI$a>vF67_zOk29vyOjp-kXb{~fx zV7_!G@aqr3*V?9=WKQV z^6iVJ2VJ?e4G2jPmRBzOci;QK}b zM>HJxzU@m~E!3897)cX1VUsv{@@UvLC8SMj{PX77`(E=G0i1uh z!>rl2hWcuSUc&8Dkm~ov)u^-H9b5tTRnv2WXi17}t zj#A2vl2KU|&kJ^{GnvMlES&i3g^(#W)SRva(NQD+wC3rXlF+%VO0p3B@$g8Xs{~d< z!Psun-oJS9%nWWodI>VWpV)XflHQUKs&f93>#xbMzbiZ~f&aG8aP1R}Ba!@=O-SLe z$5NeTjkrR2$ZGntigke;LuIm1cd1&b<@sb8_R?=>&9~JjJbIM9@4-@#eQKg8{xy5~ z32N`<3>|S_e~Mb$Aym1UM-0sJ&&yni!VVw4Sx0Tl{H2+hzLlI$%Z5&iL^LfhW@v+F z&=RI0T|kjDdh(D??4xMU<#IK$r=P2?8idPj)&&+Yj=N3O5(K)kKRteKx`b~I6g?;> zw{p+c?rZNK5#w}1GXztXEu0s8oa^vCoXcqS59;EWz-1NMp8WSp&;o9JuM8M`{UZM> zD=A`QwQwjcQJO1K>*M4vMBo!MyDaFwWCj(yGQ(A|4p2bVn{BA`j`8M~8J>P+Pq+T` z{!3ig#2^EUw>v!EbGJ8+3-T?9W?;iP6=c7Ed)m#7H8mUs3;KGNX7OL{)lJ^vKYJ-* zM?LR7uDK2wp)(MLM4?1~qLIzRt5HrP(`tev6^&vUXO^(#&sgI;TKNgA-%Bzhe6@|7 zRXbnq;>aJWf)d_9WrzWs)FX_^`aS_yO{XK(8|E@Zg)(M6WJGi#kKXBhiO0twsE6!XgjZ;E;MM{d0+S!SVUgG;W0!87SYU zFrm7nMw%;>*Tf%38>_2%aUMU@XuOkk?P^75l=WFeILSLQPfsE*wNkl89fUd1K zOUp^#m9A}SIdcAC{JVa*<^2PhU_9m|_^h_t-}eG0zXpyPXqG4+NHDPSkT9W+w$T$Q zGpJ|5V7Q+*-TGj_BToCP&IN_FRtU-$LG9-mM^|(Uz^G5I{a=kMonwr;@=al6i-~*X z!dzL`ej+id{%&VYaElkau`lqi;g32{erNYZn>gF%x3Z8@lzc+Q@SD(Am$%V1j&KC> zEnympU^@gu$=80$n zm+)D6{epY5Z$dlY|HNLCu~W7qwNI)_6bsJVj<_#HUYwbER|4qRBdnnhUQj*S_v6X2 zSKGK{DO<;1G&VmOg%gWQPRa}8C>4|MMyx-Wi%hn^uOPp#t*Or3TEaZObJF@AB(Jgc zqu_sx{+!L60rJyg%d2=SEw_YD?IwPwIZmlvM)(ev(;{(j6r+~QDvIsMi@6~FeKIiv zKKr9`4+;6x=-o#fVXBt`uoI)_kA6B-8>}l-p?URnbEQv{geG$R%YDT&rQ>`p&?3k9 z&VR9D&s}s_L2r#r0p%o9w&=2X{L#&~#WqtIM?IDr)iZ@F)+>|%+&r^Zl|DsilWJ5s zf2nobh?*cY*MjVOTL9hCnV!tXzb1HPd(V8{{A%)07oz5p5)!c`d`Fu z9#gCv5eu2o5|W|cXOj7C9URmYE*?7P-)gMjviki7U1)(!OfX*BC1LHeJgf_gtmh}9 z-7jr~Sw>4g_9V7xW@3}B`&lch{Jpya+D)95UF*w?gBa6hXJN%eOn2qu$sfx%e<%dd zB6bnM(-^mv+0udyY_hi%g!mkB$n*F&##=%^US35b8ME3qVc6q1usJ$f*U>;CD@YgQ z86{nB;#iKyQQ26Ri_`d{G^E36O2I<(l2%JY@-cZ&`lzmM{$N#az`|fH6)A3`k$ZS| z4!E(vWuemwN#yZZ-$);(;hbWiQQE<@%b5x&!$Qn7F_yL9UIl#*hHF zh2osJf}x7ly9{7`)`v2)Fgem7y&-zFiELq$G4Q5dCyS84jn7w4QbR7tdeEDJ8wv5{ zjNxyS<26x@{{Zy~vkqefEV5$#)5Vnw>n~YYOcw9nzNrN-UcuIgqkC(DRSnmj*rbt* zW-AKbV!oQWDb|bP3UAJJiraj$lZ6DTb+3}F6P~N^8KxubvQr#accd;zGiA$yRhDPV zSmb!PUXGg-A@xHuxP(F`N!NAM7l;I#iP3$^7fWQiRj)Qpd&=&;ens%5>e3~Y_QjhG zlQLyt*O2Gad8aGY`Am=44YAVWl=QH&zMQ@aXTkUYt^?+v;ejm2vf8LS;9R zI&Lr@{9z1N<(vXhw`x3}Mm-Kj5Pi&qk)(n<;+nN#3fDLL2+f{ku!O$naCKe>v}Y0| z6MT3#R#4&^hhl*Xp{uSIG}utA#_6UMdocMkD=}BXH9dL0Qod{gnkf@^0-XO-AUZ<2-JsAyi z$M{?M^~pGuwRG1>B%uskvTJt%o8$>>=D}C~k*k9lBs-s_^!(&J5y$!-dAj{${l+K1 zJfHB_g);{YiS69<$|MPxv9ApqgI1>k2vP}*1NpbdQfVn5M<(_owJK3;;j$I$MezoN zsGthON-Vf21F6z+M6SKM(_dY>GaRso%s`>psfL~dxR<^%x(iGci$R^>cT8Dk@0+$F zWz_lWOYrq4mZscuR(J*gHm8+*bv-gWSFWGrQLExk>6 z5Jd4kU`H@MET77rTYinN!%#H&oae{DELwu?F8=F34R2IoVdC1T1m|C)NdHU`@Lu%N z+>ot7wAU;$phP}l%FZ}In(kHhX7hX{<0R!zVXLLzP|@d3d(~Dsx51bQcGpR$TVkI>P9RvCi;dOqu6Oa|aPs%=pqaCIrTC z`Q<8XQeg5L`7@P*u@}g-RvO0!F^nH0oNyB~X#Jc^W_)P_l{~mxjhQZ-HwB^?qw+HfOT^$6?D!tu4{Ks#7^<4C5EpRtY8GfP$po^F(fm$C1lDd}=U z{^ZcZ6etp6vOe9Jvda&WG>uv83Y>m_;DAvd<~&6h#-*AcYYCMY5EzKA1omIa`FIV{ zkrBygubD|~jmiR8w%p7xCTgxFZbMvtz3$7GBn@oPR5`K5^L`R#6hGVw=v@a&EsP2Z z61^Hqw&()@qD4Y3-)@6aEdxSv()m}1=L*CFoPpc?$oIis4i5jb%%Y)KaByTCVlmLz z_b!`|`;s}}O}s@cjsVtmy06W%pw#`IX0CDjgB}mOtshiMy?VQw|3p1b64(-OVh4@- z_=|@4HlD?_JLUt@sz0})2whT{RVc}fY3BLH6-2Vld12Q}FeNol?N`*@1xH;e7*JrX z&Ls$`V4S_Ydwvv@b|GS~6i#lrA6@{UPx1)%{0s6F#6SkT+#c1-9EZE`oGa9t2DqNn zr;-~7Xr_%zGl|5KTTDn+SWV57*!4!3i8gY%X}VN&QJCC5$R7C4UUx&@ywbX zvH~p_C%h9~o;DN!3mUyYD?YVQ{-C$^TO4chD-iz^dUA8yp0S}b`<~D6M+}O|(bv*B zWn=3zL;`JGyB7$N=v+xB+Mslv<&b@2l<3|`^Z;BUuO?`GnTq52is|?vN9+^Ut<7l;&YHM`1SK)wnK7kwu}x%9#ri|UqB@KTfPjr1PaO*rN84xURDMj! zCsavyZ2-12ROLF_j<4;3jLUY`Kq4pp3m`n_4-mAcC!gd&yyq362IZ#XDX0X|5k3#u zy-!HV5&h33JSEN+W2@%{gm_FA{2BSz6!{PIY%IlpE=XtJtmvM!z5vPd+8J!gGxo$C zhb{#BD!sBcdjaquIlJ%!x{R?`V&FKPV6GSZA+}$g5*y>r#Z41C_Br_3=q^<+!a0u6 zqmsH2W?kc6m*&F+%(5y_3=@A}!juqNQnuWho|bCUhqi-7h5~0=v~r|s=O0?p@N>6s zS^dgt)(n^;b_M84XGVM@_7%zMzOqtRCY1Y#(1D&=eGGLttGS0rbMq`0vQ0+#E~@R3 zIam+|qE81_F@_Uja&+qDN>j)%-Gc#6mWztyVquhgZGcnRB#)olIug|19xwOhgH2m9 zHcdkBEoEe`NvM~zkcmtgd9sITzT^q`cYcKG6loKpz%hXF+8Eo!?muYMF9Xs!y1V*) z95u~nqO)G_?nQ@2`X}!)pUwEAr(tgX_xV%5kHQ36;oiUxhe1Mq3b!7+xo_> zM1}*zp}BCU!CQR=>Q3vdj~EYa-}@_#WvTFx4SfAQ4`Pw>q$)$)|E-vB??)A;-4sgr z!i_%H{lEefCe$1d0pGEc-A4kT)}KU8IyOygKJm-$1YccRWhV^#N42#nLH3(*q$dvF z7_OF_(%*Y-uXbnhEU{`Z{(uRrx>$#G81Z&cHK#Au|#ids^lW za`^B20J%GIIoCGa%S=~ebLp%Y_I;>A^un=#D`2mK8gwcv%nBleGuoIh>FzGV91*w& zom{_RHl#41AaBxiK*01bq=evL#bb}rK)K}4XzQg#3DjpP#CqCy{F04-UN8uRC?6Mz z$ni5($?}dnvlv?9=nL9#AQVfqc$YXy(#oS@@Pl+~XpgJaezAtSxKYq!Idk01t!ihH zT%8~U_wJ-X%(5S~)=K57VZIQDG$b5ndic7OC64sl`vsAkX9LMS?2 zD`mW*q+kPt8q+T1BPvtBS0cnF{WUnRmv zMFjAXSncLURr+dz)qVU7)-&`J-%!N;Hx;2-4si)mouxq9$o*mr^L@H;Z2eAN(o&ks z@mnmyOIsU#f}ef1j!|B8mk)5FL}ku|q@b3xY97{C;qnqA2F2z4y%{wlqI+(VTQ&C6 zYG}pS7GAnmbA~x^b$JHBZjO5VG3oG)ymWS7$r|{s_TxJ_-S~B_PlxQNSQ?k@*V}@) zA10Dw8{JCle;@*sTt-MW&9WP-#V)MFQGI*{3a~mNB`0S?qJ2 z&}lugqgJf3m!AbgvEn>}Ok zCY^nyI@0P$kFDQiXHre&v=%W9K620iQRNB3bSH6QOJ6y))fSbK-L#aFyswb7qn1zi zyy9s+Lb{gg97c`(mc}0Oz-6LfxLDYzI_3T(K13|!e#R`kh#%$UJ@eZGloX+a3 z2lLKhQY{pIw^W4^R}!uIPkHrAdzpV`KD+ICkU-b-CF5&qZLdA@*{@y}GHvVUF1LkysV zLwY9ucGaP1Q5cGE?ya9qeT5pQm(ueOesippIR3H#Tg}gx&iXzx9Uh6RoMOHCqjcq# ze;rN)aeG2(9i$;7wz<9%$cAk|pZ@y-|EBh=nhGM%80mjXRznGN%+F?O;CwK5uAEzG zVYMi$E|1WKmZrdmDpHRcrI)$vXXKBf3KYB)9$wQ%J&(jkgXGIsCg4?4QG~g}#QH4v zkDUJM=_$W*`^~<5D+LWLps21b6|(_UY*|EI(YV9A<3W#`dio##6W4fyNz0KIr7<~1 zIUN1&t1C4%fQ~t9)r7oqL9Xa~pRKTgQd(k`f~Sb(MqV+jkOC}&y{<9WM|Sp%vYy>= zQWU^Lie-H-pl5VI&yI~?|FC)eGq>q$;9nw{JNtY>=u|dJWReVv1brTUU~__ZqdID= zLuSZEpKQ5V?Iip#oY(O(<O$9nbsMca|$3c;0$bb ze{)rpUBUpk9_5v*HKfKfYf|)*D~>{?JaQTS(O<0+yHJ@7URE87s)=GVp@q=`!E^p5B_Z>0ZgTt_Cy?RvL?PE-$~wI8h(h&Uf)1)zvChs9zrAx+t-<52UHHro=gcBsHKVA7J?|zU!vVSN3p9 zchjD+>H?9?#@9FUAiSU4hT4E#_MuEMAHuEGoNu}Zm9-zf?Kde|9tl2*{eicbf8?Nh ziqSbQFtuO9_*!9hp#^p!jKY8t@=7T(>g(T@H{TpQ;5TwyuZs9+1h(PX!jDL5Ar1*C zo^T-#XP*z&kqfsGEeAj+`GR^MN|o^D{4uMAoSt@vkV{(pp0pFNm? zlqDHdN_cdH-JN|Z4*^8}d!aG?!byvE=h=Dx9r+g~ib55yXpw^K=}QlXUi(!kLe<#^ zn*IXLnF~)lobP~4yTH5YU4?@vTwA}h}e*QXe`4v*9d^Rq(VeXt=I!pQBJ&}Fbq0&?z= znanb1S2(Xv^91rZgROB}c^n3PRM?CM+z%`X?5$kyH&~x0 zHijFlFTNSSH5LH`H%$uxwz%}OfYEC;bbv%=93uT}RdUB$9eF|11;S&BWBvep-!^*( zYNjFI6i6wkAcu+PZ-D4H?}Z(nP;FJ|vBq=1u1nEwS+=LMWIViJf2Aj_^mHREY@ZLw z*TAbTsx%)}QML(qs-Lf@sGIxR)oFSZJc4e)d)v>&hI9H_>-#1qrNO6czlv}lGw@oJ zX)Dgt0LLRXqDfY)lPHo5<TDLk;>m4f@6! z;IuxHM-#25rp9o9?hzEB(Zy=gMsFVbcrZ!|C)8vsp3k6!CWb_IStUF0Uk|>yk}<}y z%=VtqnESz%+5i*UKyOZ_-i~iaQE!>CItm4x$+lC07X@>>RkLQV>`OJP&^rsm-dLQPP53F3xGuIOYG-b#@MFC%F44X1ve@^M) zd~alMa*}kf6Bpg2|G3^peN0UaoJcsQU-s_!yA_vJo?{~26?!&e4#V#f(lRchOGp0! zee0iY=GzkYJi|_Mq?xzON;y0xHe_fcseFjwWm6wpAd6%;Q;W#~Wuy08o;_zS9gSo} z8EV{Y>V8RS2o6m&6hR_bRVijjwb}};A_$|Y7@>%eZ@A|DC zfIGEy3vfT@C-$F7c~;9@Q-Q9AQ>)46HwC`N4ZWhJdY-shxcsHGM$NYm>9!8dvTYJH z`1?Zdijr9%2io^E!}#qbKz5B@M%cNi<`?M}{=YJeJ<68{{22x@SyAe(QxV(rG>|zH z7h%>>n5_1nb}MM*&Zy_U%>#4Q<_ z4gR7?KWhmF@Rv*V9YtuVPK`9tOh1)fZ<}){FrGg`S?Go5 zkfGsb*0{ko3SKQC;|FUr;S2h&z0Nb{$LAlh>z*Rb7y0R~VDa)R^rf0OtybbOomYDV zB$8Vgh?O1@4PQ4|a1dTzZy8!UqN97POux6b0Oa%8_pf78Vto{PpCS~DFRKzYnRw-9 zZ7dORI7UIHwMq_IZh=gE0`UfcGLE9AU&I>4Gh!#=1+-{P-az|t=L3Qj`NlVXF zfFFfNB?v!qLJfd)=Sk_+SJGQ~LSaI{bzJ&msZMkGt+i5Re2$yojD?Y=P06oixvCSg zt&Za5gKwfk0pPQrcz!6DWSh$bK9%Ns0Sh!Jtb6!deOH@;Tv?%mPW*hLdlI}4QU=j64$7V)s2Ne;&P0UjGLg6x~}x~V`K zh|7HK>qn^=+O=mB^ITBC%+>N{e6-U|G2AcHn}ZL9sD2^~8mDEv;SjSn zbRTx1v)!d=i?2Go1ErN0>a2qtj5UbYpi}f(I2d#7fu83rwfsi?^i`}wLZ^-9SD%aZpnC?(T2o5`Nu$9epCF)cc>04)B!eehbbgK{~* zo#zOv`$yfl(d(L>2+PX@`0(v7%(DsRRO9h-n0F$>Wn$BFzE7rL% zz!<8rEtny<#&ACu-p3QM|EtsBIJai>e(A@0m#e%d9;!PLH(T4Wk$}cj=jLTDySf9} znsOHeks=*dc|Aje_zt-2YSMvK+{kY+?3p1l|F)31aMw%Vh_xZl;k9=%2dikUA;m)e zE-Oz)CYGBAsxh154RcW8l9Nt5rKl~Z%E*gaB?>MFzHr1NkRq909 z;331&SJv6zLBUmW0llGI2lFf&^Ic(wuep#X*Vt%0APjwtR+F*dTj5EFV1v1fl#FM4 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 EKlDO2k^lez literal 0 HcmV?d00001 From 033c28390cb25eee1ffd5f04780347b0f946ab0f Mon Sep 17 00:00:00 2001 From: Antonio Addeo Date: Wed, 30 Aug 2023 18:17:13 +0200 Subject: [PATCH 11/15] Delete FighterTest Ref: #2342 --- crtp/src/test/java/crtp/FighterTest.java | 57 ------------------------ 1 file changed, 57 deletions(-) delete mode 100644 crtp/src/test/java/crtp/FighterTest.java diff --git a/crtp/src/test/java/crtp/FighterTest.java b/crtp/src/test/java/crtp/FighterTest.java deleted file mode 100644 index 85f9fdb2cbf8..000000000000 --- a/crtp/src/test/java/crtp/FighterTest.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). - * - * The MIT License - * Copyright © 2014-2022 Ilkka Seppälä - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package crtp; - -import crtp.Fighter; -import crtp.MmaBantamweightFighter; -import crtp.MmaFighter; -import crtp.MmaHeavyweightFighter; -import org.junit.jupiter.api.Test; - -/** - * Tests the {@link Fighter} fight method call on some implementations of {@link MmaFighter}. Note - * that fighters can only fight against opponents of their same weight class. - */ -class FighterTest { - - @Test - void fight() { - MmaBantamweightFighter fighter1 = new MmaBantamweightFighter("Joe", "Johnson", "The Geek", - "Muay Thai"); - MmaBantamweightFighter fighter2 = new MmaBantamweightFighter("Ed", "Edwards", - "The Problem Solver", - "Judo"); - fighter1.fight(fighter2); - - MmaHeavyweightFighter fighter3 = new MmaHeavyweightFighter("Dave", "Davidson", - "The Bug Smasher", "Kickboxing"); - MmaHeavyweightFighter fighter4 = new MmaHeavyweightFighter("Jack", "Jackson", - "The Pragmatic", "Brazilian Jiu-Jitsu"); - - fighter3.fight(fighter4); - - - } -} \ No newline at end of file From b3413d7743a0eab0e99d388a7a5dca44fcbc8d85 Mon Sep 17 00:00:00 2001 From: Antonio Addeo Date: Wed, 30 Aug 2023 18:59:57 +0200 Subject: [PATCH 12/15] Update App and AppTest in crtp Ref: #2342 --- crtp/src/main/java/crtp/App.java | 17 +++++++++++++++-- crtp/src/test/java/crtp/AppTest.java | 3 +-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/crtp/src/main/java/crtp/App.java b/crtp/src/main/java/crtp/App.java index cfd3f5ea3cb6..8fd0c21f82e1 100644 --- a/crtp/src/main/java/crtp/App.java +++ b/crtp/src/main/java/crtp/App.java @@ -27,13 +27,26 @@ import lombok.extern.slf4j.Slf4j; /** - * Curiously Recurring Template Pattern. - * TODO Add more info. + * Shows the {@link Fighter} fight method call on some implementations of {@link MmaFighter}. Note + * that fighters can only fight against opponents of their same weight class. */ @Slf4j public class App { + /** + * Program entry point. + * + * @param args command line args + */ public static void main(String[] args) { + MmaBantamweightFighter fighter1 = new MmaBantamweightFighter("Joe", "Johnson", "The Geek", "Muay Thai"); + MmaBantamweightFighter fighter2 = new MmaBantamweightFighter("Ed", "Edwards", "The Problem Solver", "Judo"); + fighter1.fight(fighter2); + + MmaHeavyweightFighter fighter3 = new MmaHeavyweightFighter("Dave", "Davidson", "The Bug Smasher", "Kickboxing"); + MmaHeavyweightFighter fighter4 = new MmaHeavyweightFighter("Jack", "Jackson", "The Pragmatic", "Brazilian Jiu-Jitsu"); + + fighter3.fight(fighter4); } } diff --git a/crtp/src/test/java/crtp/AppTest.java b/crtp/src/test/java/crtp/AppTest.java index 727bdac8e93a..ee3e7978612b 100644 --- a/crtp/src/test/java/crtp/AppTest.java +++ b/crtp/src/test/java/crtp/AppTest.java @@ -29,8 +29,7 @@ import org.junit.jupiter.api.Test; /** - * Curiously Recurring Template Pattern. - * TODO Add more info. + * Application test */ class AppTest { From 1fe6ddece220d246cc39467465ff88242b49eeae Mon Sep 17 00:00:00 2001 From: Antonio Addeo Date: Tue, 26 Sep 2023 17:17:18 +0200 Subject: [PATCH 13/15] Add category and tag in README.md frontmatter Ref: #2342 --- crtp/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/crtp/README.md b/crtp/README.md index 8894ff485f19..89f0720a8ebe 100644 --- a/crtp/README.md +++ b/crtp/README.md @@ -1,6 +1,10 @@ --- title: Curiously Recurring Template Pattern language: en +category: Structural +tag: +- Extensibility +- Instantiation --- ## Name / classification From cae87c49f1c9fc5b34c56f1a2e050af9b0f33414 Mon Sep 17 00:00:00 2001 From: Antonio Addeo Date: Tue, 26 Sep 2023 17:18:00 +0200 Subject: [PATCH 14/15] Add @Data annotation and remove constructor and toString in MmaFighter Ref: #2342 --- crtp/src/main/java/crtp/MmaFighter.java | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/crtp/src/main/java/crtp/MmaFighter.java b/crtp/src/main/java/crtp/MmaFighter.java index 437a82d847fc..98f37a673756 100644 --- a/crtp/src/main/java/crtp/MmaFighter.java +++ b/crtp/src/main/java/crtp/MmaFighter.java @@ -24,6 +24,7 @@ */ package crtp; +import lombok.Data; import lombok.extern.slf4j.Slf4j; /** @@ -32,6 +33,7 @@ * @param MmaFighter derived class that uses itself as type parameter. */ @Slf4j +@Data public class MmaFighter> implements Fighter { private final String name; @@ -39,29 +41,9 @@ public class MmaFighter> implements Fighter { private final String nickName; private final String speciality; - /** - * MmaFighter constructor. - * - * @param name MmaFighter name. - * @param surname MmaFighter surname. - * @param nickName MmaFighter nickName. - * @param speciality MmaFighter speciality. - */ - public MmaFighter(String name, String surname, String nickName, String speciality) { - this.name = name; - this.surname = surname; - this.nickName = nickName; - this.speciality = speciality; - } - @Override public void fight(T opponent) { LOGGER.info("{} is going to fight against {}", this, opponent); } - @Override - public String toString() { - return name + " \"" + nickName + "\" " + surname; - } - } From f6a9cda51e0c42a2f5d556ed5aece919fd3b79cd Mon Sep 17 00:00:00 2001 From: Antonio Addeo Date: Tue, 26 Sep 2023 17:20:22 +0200 Subject: [PATCH 15/15] Add FightTest Ref: #2342 --- crtp/src/main/java/crtp/App.java | 2 +- crtp/src/test/java/crtp/FightTest.java | 50 ++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 crtp/src/test/java/crtp/FightTest.java diff --git a/crtp/src/main/java/crtp/App.java b/crtp/src/main/java/crtp/App.java index 8fd0c21f82e1..0013ef1c066b 100644 --- a/crtp/src/main/java/crtp/App.java +++ b/crtp/src/main/java/crtp/App.java @@ -39,13 +39,13 @@ public class App { * @param args command line args */ public static void main(String[] args) { + MmaBantamweightFighter fighter1 = new MmaBantamweightFighter("Joe", "Johnson", "The Geek", "Muay Thai"); MmaBantamweightFighter fighter2 = new MmaBantamweightFighter("Ed", "Edwards", "The Problem Solver", "Judo"); fighter1.fight(fighter2); MmaHeavyweightFighter fighter3 = new MmaHeavyweightFighter("Dave", "Davidson", "The Bug Smasher", "Kickboxing"); MmaHeavyweightFighter fighter4 = new MmaHeavyweightFighter("Jack", "Jackson", "The Pragmatic", "Brazilian Jiu-Jitsu"); - fighter3.fight(fighter4); } diff --git a/crtp/src/test/java/crtp/FightTest.java b/crtp/src/test/java/crtp/FightTest.java new file mode 100644 index 000000000000..b1d699e33385 --- /dev/null +++ b/crtp/src/test/java/crtp/FightTest.java @@ -0,0 +1,50 @@ +package crtp; + +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +@Slf4j +public class FightTest { + + /** + * A fighter has signed a contract with a promotion, and he will face some other fighters. A list of opponents is ready + * but for some reason not all of them belong to the same weight class. Let's ensure that the fighter will only face + * opponents in the same weight class. + */ + @Test + void testFighterCanFightOnlyAgainstSameWeightOpponents() { + MmaBantamweightFighter fighter = new MmaBantamweightFighter("Joe", "Johnson", "The Geek", "Muay Thai"); + List> opponents = getOpponents(); + List> challenged = new ArrayList<>(); + + opponents.forEach(challenger -> { + try { + ((MmaBantamweightFighter) challenger).fight(fighter); + challenged.add(challenger); + } catch (ClassCastException e) { + LOGGER.error(e.getMessage()); + } + }); + + assertFalse(challenged.isEmpty()); + assertTrue(challenged.stream().allMatch(c -> c instanceof MmaBantamweightFighter)); + } + + private static List> getOpponents() { + return List.of( + new MmaBantamweightFighter("Ed", "Edwards", "The Problem Solver", "Judo"), + new MmaLightweightFighter("Evan", "Evans", "Clean Coder", "Sambo"), + new MmaHeavyweightFighter("Dave", "Davidson", "The Bug Smasher", "Kickboxing"), + new MmaBantamweightFighter("Ray", "Raymond", "Scrum Master", "Karate"), + new MmaHeavyweightFighter("Jack", "Jackson", "The Pragmatic", "Brazilian Jiu-Jitsu") + ); + } + + +}