From 2eca9c55af0a7d5ab0b20e6cf3db16b1b8b1cb3a Mon Sep 17 00:00:00 2001 From: Magnus Hissingby Date: Fri, 8 Aug 2025 16:01:59 +0200 Subject: [PATCH 01/10] diagrams and domain-model --- .../java/com/booleanuk/core/class-diagram | 0 .../java/com/booleanuk/core/domain-model.md | 32 +++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 src/main/java/com/booleanuk/core/class-diagram create mode 100644 src/main/java/com/booleanuk/core/domain-model.md diff --git a/src/main/java/com/booleanuk/core/class-diagram b/src/main/java/com/booleanuk/core/class-diagram new file mode 100644 index 000000000..e69de29bb diff --git a/src/main/java/com/booleanuk/core/domain-model.md b/src/main/java/com/booleanuk/core/domain-model.md new file mode 100644 index 000000000..d31bfb0fb --- /dev/null +++ b/src/main/java/com/booleanuk/core/domain-model.md @@ -0,0 +1,32 @@ +| Class | Method | Scenario | Output | +|-----------|--------------------------------------------|--------------------------|--------| +| Member | boolean addItem(Item item) | If basket is full | false | +| | | If space in basket | true | +| | | | | +| Member | boolean removeItem(Item item) | If item doesn't exist | false | +| | | If item exists | true | +| | | | | +| Basket | boolean isFull() | If basket is full | true | +| | | If basket is not full | false | +| | | | | +| Manager | boolean changeBasketCapacity(int capacity) | If capacity is the same | false | +| | | If capacity is changed | true | +| | | | | +| Inventory | boolean doesItemExist(Bagel bagel) | If item doesn't exist | false | +| | | If item exists | true | +| | | | | +| Customer | void totalCost() | If no items in basket | 0 | +| | | If items in basket | sum | +| | | | | +| Customer | int getPriceOfBagel(Bagel bagel) | If bagel doesn't exist | null | +| | | If bagel exists | price | +| | | | | +| Customer | boolean chooseFilling(Filling filling) | If filling doesn't exist | false | +| | | If filling exists | true | +| | | | | +| Customer | int getPriceOfFilling(Filling filling) | If filling doesn't exist | null | +| | | If filling exists | price | +| | | | | +| Inventory | boolean doesItemExist(Item item) | If item doesn't exist | false | +| | | If item exists | true | + From d4921888bbf9189502fbe79045bd7a742282c390 Mon Sep 17 00:00:00 2001 From: Magnus Hissingby Date: Sun, 10 Aug 2025 18:36:47 +0200 Subject: [PATCH 02/10] First tests and created all classes --- .../java/com/booleanuk/core/Bagel/Bagel.java | 15 ++++ .../com/booleanuk/core/Bagel/BagelType.java | 8 ++ src/main/java/com/booleanuk/core/Basket.java | 4 + .../com/booleanuk/core/Coffee/Coffee.java | 5 ++ .../com/booleanuk/core/Coffee/CoffeeType.java | 8 ++ .../java/com/booleanuk/core/Customer.java | 4 + .../com/booleanuk/core/Filling/Filling.java | 5 ++ .../booleanuk/core/Filling/FillingType.java | 10 +++ .../java/com/booleanuk/core/Inventory.java | 4 + src/main/java/com/booleanuk/core/Item.java | 4 + src/main/java/com/booleanuk/core/Manager.java | 4 + src/main/java/com/booleanuk/core/Member.java | 4 + src/main/java/com/booleanuk/core/Person.java | 4 + .../java/com/booleanuk/core/domain-model.md | 25 +++--- .../com/booleanuk/core/BobsBagelTests.java | 76 +++++++++++++++++++ 15 files changed, 166 insertions(+), 14 deletions(-) create mode 100644 src/main/java/com/booleanuk/core/Bagel/Bagel.java create mode 100644 src/main/java/com/booleanuk/core/Bagel/BagelType.java create mode 100644 src/main/java/com/booleanuk/core/Basket.java create mode 100644 src/main/java/com/booleanuk/core/Coffee/Coffee.java create mode 100644 src/main/java/com/booleanuk/core/Coffee/CoffeeType.java create mode 100644 src/main/java/com/booleanuk/core/Customer.java create mode 100644 src/main/java/com/booleanuk/core/Filling/Filling.java create mode 100644 src/main/java/com/booleanuk/core/Filling/FillingType.java create mode 100644 src/main/java/com/booleanuk/core/Inventory.java create mode 100644 src/main/java/com/booleanuk/core/Item.java create mode 100644 src/main/java/com/booleanuk/core/Manager.java create mode 100644 src/main/java/com/booleanuk/core/Member.java create mode 100644 src/main/java/com/booleanuk/core/Person.java create mode 100644 src/test/java/com/booleanuk/core/BobsBagelTests.java diff --git a/src/main/java/com/booleanuk/core/Bagel/Bagel.java b/src/main/java/com/booleanuk/core/Bagel/Bagel.java new file mode 100644 index 000000000..36c9b096f --- /dev/null +++ b/src/main/java/com/booleanuk/core/Bagel/Bagel.java @@ -0,0 +1,15 @@ +package com.booleanuk.core.Bagel; + +public class Bagel { + BagelType type; + double price; + + public Bagel(BagelType type){ + this.type = type; + this.price = type.equals(BagelType.PLAIN)? 0.39 : 0.49; + } + + public double getPrice(){ + return this.price; + } +} diff --git a/src/main/java/com/booleanuk/core/Bagel/BagelType.java b/src/main/java/com/booleanuk/core/Bagel/BagelType.java new file mode 100644 index 000000000..dde8f409b --- /dev/null +++ b/src/main/java/com/booleanuk/core/Bagel/BagelType.java @@ -0,0 +1,8 @@ +package com.booleanuk.core.Bagel; + +public enum BagelType{ + ONION, + PLAIN, + EVERYTHING, + SESAME +} diff --git a/src/main/java/com/booleanuk/core/Basket.java b/src/main/java/com/booleanuk/core/Basket.java new file mode 100644 index 000000000..4aab45ed7 --- /dev/null +++ b/src/main/java/com/booleanuk/core/Basket.java @@ -0,0 +1,4 @@ +package com.booleanuk.core; + +public class Basket { +} diff --git a/src/main/java/com/booleanuk/core/Coffee/Coffee.java b/src/main/java/com/booleanuk/core/Coffee/Coffee.java new file mode 100644 index 000000000..85862d86a --- /dev/null +++ b/src/main/java/com/booleanuk/core/Coffee/Coffee.java @@ -0,0 +1,5 @@ +package com.booleanuk.core.Coffee; + + +public class Coffee { +} diff --git a/src/main/java/com/booleanuk/core/Coffee/CoffeeType.java b/src/main/java/com/booleanuk/core/Coffee/CoffeeType.java new file mode 100644 index 000000000..502618055 --- /dev/null +++ b/src/main/java/com/booleanuk/core/Coffee/CoffeeType.java @@ -0,0 +1,8 @@ +package com.booleanuk.core.Coffee; + +public enum CoffeeType{ + BLACK, + WHITE, + CAPPUCCINO, + LATTE +} diff --git a/src/main/java/com/booleanuk/core/Customer.java b/src/main/java/com/booleanuk/core/Customer.java new file mode 100644 index 000000000..6f3a664d5 --- /dev/null +++ b/src/main/java/com/booleanuk/core/Customer.java @@ -0,0 +1,4 @@ +package com.booleanuk.core; + +public class Customer { +} diff --git a/src/main/java/com/booleanuk/core/Filling/Filling.java b/src/main/java/com/booleanuk/core/Filling/Filling.java new file mode 100644 index 000000000..78929472f --- /dev/null +++ b/src/main/java/com/booleanuk/core/Filling/Filling.java @@ -0,0 +1,5 @@ +package com.booleanuk.core.Filling; + +public class Filling { + +} diff --git a/src/main/java/com/booleanuk/core/Filling/FillingType.java b/src/main/java/com/booleanuk/core/Filling/FillingType.java new file mode 100644 index 000000000..f8bcdf871 --- /dev/null +++ b/src/main/java/com/booleanuk/core/Filling/FillingType.java @@ -0,0 +1,10 @@ +package com.booleanuk.core.Filling; + +public enum FillingType{ + BACON, + EGG, + CHEESE, + CREAM_CHEESE, + SMOKED_SALMON, + HAM +} diff --git a/src/main/java/com/booleanuk/core/Inventory.java b/src/main/java/com/booleanuk/core/Inventory.java new file mode 100644 index 000000000..375cdb479 --- /dev/null +++ b/src/main/java/com/booleanuk/core/Inventory.java @@ -0,0 +1,4 @@ +package com.booleanuk.core; + +public class Inventory { +} diff --git a/src/main/java/com/booleanuk/core/Item.java b/src/main/java/com/booleanuk/core/Item.java new file mode 100644 index 000000000..b85344c21 --- /dev/null +++ b/src/main/java/com/booleanuk/core/Item.java @@ -0,0 +1,4 @@ +package com.booleanuk.core; + +public class Item { +} diff --git a/src/main/java/com/booleanuk/core/Manager.java b/src/main/java/com/booleanuk/core/Manager.java new file mode 100644 index 000000000..690d54d8f --- /dev/null +++ b/src/main/java/com/booleanuk/core/Manager.java @@ -0,0 +1,4 @@ +package com.booleanuk.core; + +public class Manager { +} diff --git a/src/main/java/com/booleanuk/core/Member.java b/src/main/java/com/booleanuk/core/Member.java new file mode 100644 index 000000000..5cf2f696d --- /dev/null +++ b/src/main/java/com/booleanuk/core/Member.java @@ -0,0 +1,4 @@ +package com.booleanuk.core; + +public class Member { +} diff --git a/src/main/java/com/booleanuk/core/Person.java b/src/main/java/com/booleanuk/core/Person.java new file mode 100644 index 000000000..23f16b599 --- /dev/null +++ b/src/main/java/com/booleanuk/core/Person.java @@ -0,0 +1,4 @@ +package com.booleanuk.core; + +public class Person { +} diff --git a/src/main/java/com/booleanuk/core/domain-model.md b/src/main/java/com/booleanuk/core/domain-model.md index d31bfb0fb..108031d32 100644 --- a/src/main/java/com/booleanuk/core/domain-model.md +++ b/src/main/java/com/booleanuk/core/domain-model.md @@ -1,10 +1,10 @@ | Class | Method | Scenario | Output | |-----------|--------------------------------------------|--------------------------|--------| -| Member | boolean addItem(Item item) | If basket is full | false | -| | | If space in basket | true | +| Member | boolean addItemFromBasket(Item item) | If basket is full | false | +| Basket | boolean add(Item item) | If space in basket | true | | | | | | -| Member | boolean removeItem(Item item) | If item doesn't exist | false | -| | | If item exists | true | +| Member | boolean removeItemFromBasket(Item item) | If item doesn't exist | false | +| Basket | boolean remove(Item item) | If item exists | true | | | | | | | Basket | boolean isFull() | If basket is full | true | | | | If basket is not full | false | @@ -12,20 +12,17 @@ | Manager | boolean changeBasketCapacity(int capacity) | If capacity is the same | false | | | | If capacity is changed | true | | | | | | -| Inventory | boolean doesItemExist(Bagel bagel) | If item doesn't exist | false | -| | | If item exists | true | -| | | | | -| Customer | void totalCost() | If no items in basket | 0 | -| | | If items in basket | sum | +| Customer | double totalCostInBasket() | If no items in basket | 0 | +| Basket | double totalCost() | If items in basket | sum | | | | | | -| Customer | int getPriceOfBagel(Bagel bagel) | If bagel doesn't exist | null | -| | | If bagel exists | price | +| Customer | double getPriceOfBagel(Bagel bagel) | If bagel doesn't exist | null | +| Bagel | double getPrice() | If bagel exists | price | | | | | | | Customer | boolean chooseFilling(Filling filling) | If filling doesn't exist | false | -| | | If filling exists | true | +| Bagel | boolean addFilling(Filling filling) | If filling exists | true | | | | | | -| Customer | int getPriceOfFilling(Filling filling) | If filling doesn't exist | null | -| | | If filling exists | price | +| Customer | double getPriceOfFilling(Filling filling) | If filling doesn't exist | null | +| Filling | double getPrice() | If filling exists | price | | | | | | | Inventory | boolean doesItemExist(Item item) | If item doesn't exist | false | | | | If item exists | true | diff --git a/src/test/java/com/booleanuk/core/BobsBagelTests.java b/src/test/java/com/booleanuk/core/BobsBagelTests.java new file mode 100644 index 000000000..eaa03ac4b --- /dev/null +++ b/src/test/java/com/booleanuk/core/BobsBagelTests.java @@ -0,0 +1,76 @@ +package com.booleanuk.core; + +import com.booleanuk.core.Bagel.Bagel; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import static com.booleanuk.core.Bagel.BagelType.*; + +public class BobsBagelTests { + + @Test + public void testBagel(){ + Bagel bagelOnion = new Bagel(ONION); + Bagel bagelPlain = new Bagel(PLAIN); + Bagel bagelEverything = new Bagel(EVERYTHING); + Bagel bagelSesame = new Bagel(SESAME); + + // test getPrice methods + + double onionPrice = bagelOnion.getPrice(); + double plainPrice = bagelPlain.getPrice(); + double everythingPrice = bagelEverything.getPrice(); + double sesamePrice = bagelSesame.getPrice(); + + Assertions.assertEquals(0.49, onionPrice); + Assertions.assertEquals(0.39, plainPrice); + Assertions.assertEquals(0.49, everythingPrice); + Assertions.assertEquals(0.49, sesamePrice); + + } + + @Test + public void testFilling(){ + + } + + @Test + public void testCoffee(){ + + } + + @Test + public void testItem(){ + + } + + @Test + public void testBasket(){ + + } + + @Test + public void testPerson(){ + + } + + @Test + public void testMember(){ + + } + + @Test + public void testCustomer(){ + + } + + @Test + public void testManager(){ + + } + + @Test + public void testInventory(){ + + } +} From 8c9b25ce9fd8b79132b46f58785990e4bfae105f Mon Sep 17 00:00:00 2001 From: Magnus Hissingby Date: Sun, 10 Aug 2025 18:59:42 +0200 Subject: [PATCH 03/10] Tests and code for item-subclasses Coffee, Bagel and Filling --- .../com/booleanuk/core/Coffee/Coffee.java | 15 ++++++ .../com/booleanuk/core/Filling/Filling.java | 11 +++++ .../com/booleanuk/core/BobsBagelTests.java | 46 ++++++++++++++++++- 3 files changed, 71 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/booleanuk/core/Coffee/Coffee.java b/src/main/java/com/booleanuk/core/Coffee/Coffee.java index 85862d86a..5349f5af0 100644 --- a/src/main/java/com/booleanuk/core/Coffee/Coffee.java +++ b/src/main/java/com/booleanuk/core/Coffee/Coffee.java @@ -2,4 +2,19 @@ public class Coffee { + CoffeeType type; + double price; + + public Coffee(CoffeeType type){ + this.type = type; + this.price = switch(type){ + case BLACK -> 0.99; + case WHITE -> 1.19; + default -> 1.29; + }; + } + + public double getPrice(){ + return this.price; + } } diff --git a/src/main/java/com/booleanuk/core/Filling/Filling.java b/src/main/java/com/booleanuk/core/Filling/Filling.java index 78929472f..01caa9966 100644 --- a/src/main/java/com/booleanuk/core/Filling/Filling.java +++ b/src/main/java/com/booleanuk/core/Filling/Filling.java @@ -1,5 +1,16 @@ package com.booleanuk.core.Filling; public class Filling { + FillingType type; + double price; + + public Filling(FillingType type){ + this.type = type; + this.price = 0.12; + } + + public double getPrice(){ + return this.price; + } } diff --git a/src/test/java/com/booleanuk/core/BobsBagelTests.java b/src/test/java/com/booleanuk/core/BobsBagelTests.java index eaa03ac4b..61aec1eb4 100644 --- a/src/test/java/com/booleanuk/core/BobsBagelTests.java +++ b/src/test/java/com/booleanuk/core/BobsBagelTests.java @@ -1,10 +1,14 @@ package com.booleanuk.core; import com.booleanuk.core.Bagel.Bagel; +import com.booleanuk.core.Coffee.Coffee; +import com.booleanuk.core.Filling.Filling; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import static com.booleanuk.core.Bagel.BagelType.*; +import static com.booleanuk.core.Coffee.CoffeeType.*; +import static com.booleanuk.core.Filling.FillingType.*; public class BobsBagelTests { @@ -26,17 +30,57 @@ public void testBagel(){ Assertions.assertEquals(0.39, plainPrice); Assertions.assertEquals(0.49, everythingPrice); Assertions.assertEquals(0.49, sesamePrice); - } @Test public void testFilling(){ + Filling fillingBacon = new Filling(BACON); + Filling fillingEgg = new Filling(EGG); + Filling fillingCheese = new Filling(CHEESE); + Filling fillingCreamCheese = new Filling(CREAM_CHEESE); + Filling fillingSmokedSalmon = new Filling(SMOKED_SALMON); + Filling fillingHam = new Filling(HAM); + + // test getPrice methods + + double baconPrice = fillingBacon.getPrice(); + double eggPrice = fillingEgg.getPrice(); + double cheesePrice = fillingCheese.getPrice(); + double creamCheesePrice = fillingCreamCheese.getPrice(); + double smokedSalmonPrice = fillingSmokedSalmon.getPrice(); + double hamPrice = fillingHam.getPrice(); + + + Assertions.assertEquals(0.12, baconPrice); + Assertions.assertEquals(0.12, eggPrice); + Assertions.assertEquals(0.12, cheesePrice); + Assertions.assertEquals(0.12, creamCheesePrice); + Assertions.assertEquals(0.12, smokedSalmonPrice); + Assertions.assertEquals(0.12, hamPrice); } @Test public void testCoffee(){ + Coffee coffeeBlack = new Coffee(BLACK); + Coffee coffeeWhite = new Coffee(WHITE); + Coffee coffeeCappuccino = new Coffee(CAPPUCCINO); + Coffee coffeeLatte = new Coffee(LATTE); + + // test getPrice methods + + double blackPrice = coffeeBlack.getPrice(); + double whitePrice = coffeeWhite.getPrice(); + double cappuccinoPrice = coffeeCappuccino.getPrice(); + double lattePrice = coffeeLatte.getPrice(); + + + Assertions.assertEquals(0.99, blackPrice); + Assertions.assertEquals(1.19, whitePrice); + Assertions.assertEquals(1.29, cappuccinoPrice); + Assertions.assertEquals(1.29, lattePrice); + } @Test From 21c20d9096cda43f8a65483f979a8153e44b90ff Mon Sep 17 00:00:00 2001 From: Magnus Hissingby Date: Sun, 10 Aug 2025 19:07:55 +0200 Subject: [PATCH 04/10] added filling to bagel and methods to add and get fillings --- .../java/com/booleanuk/core/Bagel/Bagel.java | 16 ++++++++++++++++ .../java/com/booleanuk/core/BobsBagelTests.java | 13 ++++++++++--- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/booleanuk/core/Bagel/Bagel.java b/src/main/java/com/booleanuk/core/Bagel/Bagel.java index 36c9b096f..9bc98f872 100644 --- a/src/main/java/com/booleanuk/core/Bagel/Bagel.java +++ b/src/main/java/com/booleanuk/core/Bagel/Bagel.java @@ -1,15 +1,31 @@ package com.booleanuk.core.Bagel; +import com.booleanuk.core.Filling.Filling; + +import java.util.ArrayList; +import java.util.List; + public class Bagel { + List filling; BagelType type; double price; public Bagel(BagelType type){ this.type = type; this.price = type.equals(BagelType.PLAIN)? 0.39 : 0.49; + filling = new ArrayList<>(); } public double getPrice(){ return this.price; } + + public List getFilling(){ + return this.filling; + } + + public void addFilling(Filling filling){ + this.filling.add(filling); + } + } diff --git a/src/test/java/com/booleanuk/core/BobsBagelTests.java b/src/test/java/com/booleanuk/core/BobsBagelTests.java index 61aec1eb4..12246710d 100644 --- a/src/test/java/com/booleanuk/core/BobsBagelTests.java +++ b/src/test/java/com/booleanuk/core/BobsBagelTests.java @@ -19,17 +19,24 @@ public void testBagel(){ Bagel bagelEverything = new Bagel(EVERYTHING); Bagel bagelSesame = new Bagel(SESAME); - // test getPrice methods + Filling hamFilling = new Filling(HAM); + + // test getPrice method and addFilling double onionPrice = bagelOnion.getPrice(); double plainPrice = bagelPlain.getPrice(); double everythingPrice = bagelEverything.getPrice(); double sesamePrice = bagelSesame.getPrice(); + bagelOnion.addFilling(hamFilling); + Assertions.assertEquals(0.49, onionPrice); Assertions.assertEquals(0.39, plainPrice); Assertions.assertEquals(0.49, everythingPrice); Assertions.assertEquals(0.49, sesamePrice); + + + Assertions.assertEquals(hamFilling, bagelOnion.getFilling().getFirst()); } @Test @@ -42,7 +49,7 @@ public void testFilling(){ Filling fillingSmokedSalmon = new Filling(SMOKED_SALMON); Filling fillingHam = new Filling(HAM); - // test getPrice methods + // test getPrice method double baconPrice = fillingBacon.getPrice(); double eggPrice = fillingEgg.getPrice(); @@ -68,7 +75,7 @@ public void testCoffee(){ Coffee coffeeCappuccino = new Coffee(CAPPUCCINO); Coffee coffeeLatte = new Coffee(LATTE); - // test getPrice methods + // test getPrice method double blackPrice = coffeeBlack.getPrice(); double whitePrice = coffeeWhite.getPrice(); From 98b956f23dfcf13a32bffb7e75e396098c37caa5 Mon Sep 17 00:00:00 2001 From: Magnus Hissingby Date: Mon, 11 Aug 2025 14:24:28 +0200 Subject: [PATCH 05/10] Item, Basket and inventory --- src/main/java/com/booleanuk/core/Basket.java | 39 ++++++++++ .../com/booleanuk/core/Filling/Filling.java | 16 ---- .../java/com/booleanuk/core/Inventory.java | 20 +++++ src/main/java/com/booleanuk/core/Item.java | 4 - .../core/{ => Item}/Bagel/Bagel.java | 20 +++-- .../core/{ => Item}/Bagel/BagelType.java | 2 +- .../core/{ => Item}/Coffee/Coffee.java | 17 ++-- .../core/{ => Item}/Coffee/CoffeeType.java | 2 +- .../booleanuk/core/Item/Filling/Filling.java | 22 ++++++ .../core/{ => Item}/Filling/FillingType.java | 2 +- .../java/com/booleanuk/core/Item/Item.java | 6 ++ src/main/java/com/booleanuk/core/Manager.java | 4 - src/main/java/com/booleanuk/core/Member.java | 4 - src/main/java/com/booleanuk/core/Person.java | 4 - .../com/booleanuk/core/Person/Manager.java | 4 + .../com/booleanuk/core/Person/Member.java | 4 + .../com/booleanuk/core/Person/Person.java | 4 + .../com/booleanuk/core/BobsBagelTests.java | 77 ++++++++++++++++--- 18 files changed, 193 insertions(+), 58 deletions(-) delete mode 100644 src/main/java/com/booleanuk/core/Filling/Filling.java delete mode 100644 src/main/java/com/booleanuk/core/Item.java rename src/main/java/com/booleanuk/core/{ => Item}/Bagel/Bagel.java (55%) rename src/main/java/com/booleanuk/core/{ => Item}/Bagel/BagelType.java (65%) rename src/main/java/com/booleanuk/core/{ => Item}/Coffee/Coffee.java (50%) rename src/main/java/com/booleanuk/core/{ => Item}/Coffee/CoffeeType.java (65%) create mode 100644 src/main/java/com/booleanuk/core/Item/Filling/Filling.java rename src/main/java/com/booleanuk/core/{ => Item}/Filling/FillingType.java (71%) create mode 100644 src/main/java/com/booleanuk/core/Item/Item.java delete mode 100644 src/main/java/com/booleanuk/core/Manager.java delete mode 100644 src/main/java/com/booleanuk/core/Member.java delete mode 100644 src/main/java/com/booleanuk/core/Person.java create mode 100644 src/main/java/com/booleanuk/core/Person/Manager.java create mode 100644 src/main/java/com/booleanuk/core/Person/Member.java create mode 100644 src/main/java/com/booleanuk/core/Person/Person.java diff --git a/src/main/java/com/booleanuk/core/Basket.java b/src/main/java/com/booleanuk/core/Basket.java index 4aab45ed7..b2170159a 100644 --- a/src/main/java/com/booleanuk/core/Basket.java +++ b/src/main/java/com/booleanuk/core/Basket.java @@ -1,4 +1,43 @@ package com.booleanuk.core; +import com.booleanuk.core.Item.Item; + +import java.util.ArrayList; +import java.util.List; + public class Basket { + private final int capacity; + private final List items; + private final Inventory inventory; + + public Basket(int capacity, Inventory inventory){ + this.capacity = capacity; + this.items = new ArrayList<>(); + this.inventory = inventory; + } + + public boolean add(Item item){ + if (inventory.exists(item)){ + items.add(item); + return true; + } else { return false; } + } + + public boolean remove(Item item){ + if (items.contains(item)){ + items.remove(item); + return true; + } else { return false; } + } + + public boolean isFull() { + return items.size() == capacity; + + } + + public double total(){ + return items.stream().map(Item::getPrice).reduce(0.0, Double::sum); + } + + } diff --git a/src/main/java/com/booleanuk/core/Filling/Filling.java b/src/main/java/com/booleanuk/core/Filling/Filling.java deleted file mode 100644 index 01caa9966..000000000 --- a/src/main/java/com/booleanuk/core/Filling/Filling.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.booleanuk.core.Filling; - -public class Filling { - FillingType type; - double price; - - public Filling(FillingType type){ - this.type = type; - this.price = 0.12; - } - - public double getPrice(){ - return this.price; - } - -} diff --git a/src/main/java/com/booleanuk/core/Inventory.java b/src/main/java/com/booleanuk/core/Inventory.java index 375cdb479..11be8eb22 100644 --- a/src/main/java/com/booleanuk/core/Inventory.java +++ b/src/main/java/com/booleanuk/core/Inventory.java @@ -1,4 +1,24 @@ package com.booleanuk.core; +import com.booleanuk.core.Item.Bagel.BagelType; +import com.booleanuk.core.Item.Coffee.CoffeeType; +import com.booleanuk.core.Item.Filling.FillingType; +import com.booleanuk.core.Item.Item; + +import java.util.List; + public class Inventory { + List listOfBagels; + List listOfFillings; + List listOfCoffees; + + public Inventory(List bagels, List fillings, List coffees){ + this.listOfBagels = bagels; + this.listOfFillings = fillings; + this.listOfCoffees = coffees; + } + + public boolean exists(Item item){ + return listOfBagels.contains(item.getType()) || listOfFillings.contains(item.getType()) || listOfCoffees.contains(item.getType()); + } } diff --git a/src/main/java/com/booleanuk/core/Item.java b/src/main/java/com/booleanuk/core/Item.java deleted file mode 100644 index b85344c21..000000000 --- a/src/main/java/com/booleanuk/core/Item.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.booleanuk.core; - -public class Item { -} diff --git a/src/main/java/com/booleanuk/core/Bagel/Bagel.java b/src/main/java/com/booleanuk/core/Item/Bagel/Bagel.java similarity index 55% rename from src/main/java/com/booleanuk/core/Bagel/Bagel.java rename to src/main/java/com/booleanuk/core/Item/Bagel/Bagel.java index 9bc98f872..134184b30 100644 --- a/src/main/java/com/booleanuk/core/Bagel/Bagel.java +++ b/src/main/java/com/booleanuk/core/Item/Bagel/Bagel.java @@ -1,25 +1,31 @@ -package com.booleanuk.core.Bagel; +package com.booleanuk.core.Item.Bagel; -import com.booleanuk.core.Filling.Filling; +import com.booleanuk.core.Item.Filling.Filling; +import com.booleanuk.core.Item.Item; import java.util.ArrayList; import java.util.List; -public class Bagel { - List filling; - BagelType type; - double price; +public class Bagel implements Item { + private final List filling; + private final double price; + private final BagelType type; public Bagel(BagelType type){ - this.type = type; this.price = type.equals(BagelType.PLAIN)? 0.39 : 0.49; filling = new ArrayList<>(); + this.type = type; } public double getPrice(){ return this.price; } + @Override + public BagelType getType(){ + return this.type; + } + public List getFilling(){ return this.filling; } diff --git a/src/main/java/com/booleanuk/core/Bagel/BagelType.java b/src/main/java/com/booleanuk/core/Item/Bagel/BagelType.java similarity index 65% rename from src/main/java/com/booleanuk/core/Bagel/BagelType.java rename to src/main/java/com/booleanuk/core/Item/Bagel/BagelType.java index dde8f409b..5fd4f3d48 100644 --- a/src/main/java/com/booleanuk/core/Bagel/BagelType.java +++ b/src/main/java/com/booleanuk/core/Item/Bagel/BagelType.java @@ -1,4 +1,4 @@ -package com.booleanuk.core.Bagel; +package com.booleanuk.core.Item.Bagel; public enum BagelType{ ONION, diff --git a/src/main/java/com/booleanuk/core/Coffee/Coffee.java b/src/main/java/com/booleanuk/core/Item/Coffee/Coffee.java similarity index 50% rename from src/main/java/com/booleanuk/core/Coffee/Coffee.java rename to src/main/java/com/booleanuk/core/Item/Coffee/Coffee.java index 5349f5af0..52614bdd8 100644 --- a/src/main/java/com/booleanuk/core/Coffee/Coffee.java +++ b/src/main/java/com/booleanuk/core/Item/Coffee/Coffee.java @@ -1,20 +1,27 @@ -package com.booleanuk.core.Coffee; +package com.booleanuk.core.Item.Coffee; -public class Coffee { - CoffeeType type; - double price; +import com.booleanuk.core.Item.Item; + +public class Coffee implements Item { + private final double price; + private final CoffeeType type; public Coffee(CoffeeType type){ - this.type = type; this.price = switch(type){ case BLACK -> 0.99; case WHITE -> 1.19; default -> 1.29; }; + this.type = type; } public double getPrice(){ return this.price; } + + @Override + public CoffeeType getType(){ + return this.type; + } } diff --git a/src/main/java/com/booleanuk/core/Coffee/CoffeeType.java b/src/main/java/com/booleanuk/core/Item/Coffee/CoffeeType.java similarity index 65% rename from src/main/java/com/booleanuk/core/Coffee/CoffeeType.java rename to src/main/java/com/booleanuk/core/Item/Coffee/CoffeeType.java index 502618055..fb3e89967 100644 --- a/src/main/java/com/booleanuk/core/Coffee/CoffeeType.java +++ b/src/main/java/com/booleanuk/core/Item/Coffee/CoffeeType.java @@ -1,4 +1,4 @@ -package com.booleanuk.core.Coffee; +package com.booleanuk.core.Item.Coffee; public enum CoffeeType{ BLACK, diff --git a/src/main/java/com/booleanuk/core/Item/Filling/Filling.java b/src/main/java/com/booleanuk/core/Item/Filling/Filling.java new file mode 100644 index 000000000..7417a7376 --- /dev/null +++ b/src/main/java/com/booleanuk/core/Item/Filling/Filling.java @@ -0,0 +1,22 @@ +package com.booleanuk.core.Item.Filling; + +import com.booleanuk.core.Item.Item; + +public class Filling implements Item { + private final double price; + private final FillingType type; + + public Filling(FillingType type){ + this.price = 0.12; + this.type = type; + } + + public double getPrice(){ + return this.price; + } + + @Override + public FillingType getType(){ + return this.type; + } +} diff --git a/src/main/java/com/booleanuk/core/Filling/FillingType.java b/src/main/java/com/booleanuk/core/Item/Filling/FillingType.java similarity index 71% rename from src/main/java/com/booleanuk/core/Filling/FillingType.java rename to src/main/java/com/booleanuk/core/Item/Filling/FillingType.java index f8bcdf871..37230d8ed 100644 --- a/src/main/java/com/booleanuk/core/Filling/FillingType.java +++ b/src/main/java/com/booleanuk/core/Item/Filling/FillingType.java @@ -1,4 +1,4 @@ -package com.booleanuk.core.Filling; +package com.booleanuk.core.Item.Filling; public enum FillingType{ BACON, diff --git a/src/main/java/com/booleanuk/core/Item/Item.java b/src/main/java/com/booleanuk/core/Item/Item.java new file mode 100644 index 000000000..e5961e899 --- /dev/null +++ b/src/main/java/com/booleanuk/core/Item/Item.java @@ -0,0 +1,6 @@ +package com.booleanuk.core.Item; + +public interface Item { + double getPrice(); + T getType(); +} diff --git a/src/main/java/com/booleanuk/core/Manager.java b/src/main/java/com/booleanuk/core/Manager.java deleted file mode 100644 index 690d54d8f..000000000 --- a/src/main/java/com/booleanuk/core/Manager.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.booleanuk.core; - -public class Manager { -} diff --git a/src/main/java/com/booleanuk/core/Member.java b/src/main/java/com/booleanuk/core/Member.java deleted file mode 100644 index 5cf2f696d..000000000 --- a/src/main/java/com/booleanuk/core/Member.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.booleanuk.core; - -public class Member { -} diff --git a/src/main/java/com/booleanuk/core/Person.java b/src/main/java/com/booleanuk/core/Person.java deleted file mode 100644 index 23f16b599..000000000 --- a/src/main/java/com/booleanuk/core/Person.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.booleanuk.core; - -public class Person { -} diff --git a/src/main/java/com/booleanuk/core/Person/Manager.java b/src/main/java/com/booleanuk/core/Person/Manager.java new file mode 100644 index 000000000..7673caa46 --- /dev/null +++ b/src/main/java/com/booleanuk/core/Person/Manager.java @@ -0,0 +1,4 @@ +package com.booleanuk.core.Person; + +public class Manager { +} diff --git a/src/main/java/com/booleanuk/core/Person/Member.java b/src/main/java/com/booleanuk/core/Person/Member.java new file mode 100644 index 000000000..80161800a --- /dev/null +++ b/src/main/java/com/booleanuk/core/Person/Member.java @@ -0,0 +1,4 @@ +package com.booleanuk.core.Person; + +public class Member { +} diff --git a/src/main/java/com/booleanuk/core/Person/Person.java b/src/main/java/com/booleanuk/core/Person/Person.java new file mode 100644 index 000000000..60a742325 --- /dev/null +++ b/src/main/java/com/booleanuk/core/Person/Person.java @@ -0,0 +1,4 @@ +package com.booleanuk.core.Person; + +public class Person { +} diff --git a/src/test/java/com/booleanuk/core/BobsBagelTests.java b/src/test/java/com/booleanuk/core/BobsBagelTests.java index 12246710d..e5f3fc042 100644 --- a/src/test/java/com/booleanuk/core/BobsBagelTests.java +++ b/src/test/java/com/booleanuk/core/BobsBagelTests.java @@ -1,14 +1,18 @@ package com.booleanuk.core; -import com.booleanuk.core.Bagel.Bagel; -import com.booleanuk.core.Coffee.Coffee; -import com.booleanuk.core.Filling.Filling; +import com.booleanuk.core.Item.Bagel.*; +import com.booleanuk.core.Item.Filling.*; +import com.booleanuk.core.Item.Coffee.*; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import static com.booleanuk.core.Bagel.BagelType.*; -import static com.booleanuk.core.Coffee.CoffeeType.*; -import static com.booleanuk.core.Filling.FillingType.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static com.booleanuk.core.Item.Bagel.BagelType.*; +import static com.booleanuk.core.Item.Filling.FillingType.*; +import static com.booleanuk.core.Item.Coffee.CoffeeType.*; public class BobsBagelTests { @@ -93,11 +97,67 @@ public void testCoffee(){ @Test public void testItem(){ + // Testing the Item interface + + Bagel itemBagel = new Bagel(ONION); + Filling itemFilling = new Filling(HAM); + + itemBagel.addFilling(itemFilling); + + Assertions.assertEquals(0.49, itemBagel.getPrice()); + Assertions.assertEquals(itemFilling, itemBagel.getFilling().getFirst()); + + } + + @Test + public void testInventory(){ + + List listOfBagels = new ArrayList<>(Arrays.asList(PLAIN, ONION, EVERYTHING, SESAME)); + List listOfFillings = new ArrayList<>(Arrays.asList(BACON, EGG, CHEESE, CREAM_CHEESE, SMOKED_SALMON, HAM)); + List listOfCoffees = new ArrayList<>(Arrays.asList(BLACK, WHITE, CAPPUCCINO, LATTE)); + + Inventory inventory = new Inventory(listOfBagels, listOfFillings, listOfCoffees); + + Bagel bagel = new Bagel(PLAIN); + Filling filling = new Filling(HAM); + Coffee coffee = new Coffee(WHITE); + + Assertions.assertTrue(inventory.exists(bagel)); + Assertions.assertTrue(inventory.exists(filling)); + Assertions.assertTrue(inventory.exists(coffee)); } @Test public void testBasket(){ + List listOfBagels = new ArrayList<>(Arrays.asList(PLAIN, ONION, EVERYTHING, SESAME)); + List listOfFillings = new ArrayList<>(Arrays.asList(BACON, EGG, CHEESE, CREAM_CHEESE, SMOKED_SALMON, HAM)); + List listOfCoffees = new ArrayList<>(Arrays.asList(BLACK, WHITE, CAPPUCCINO, LATTE)); + + Inventory inventory = new Inventory(listOfBagels, listOfFillings, listOfCoffees); + + Basket basket = new Basket(10, inventory); + + Bagel bagelOnion = new Bagel(ONION); + Bagel bagelPlain = new Bagel(PLAIN); + Filling fillingCheese = new Filling(CHEESE); + Filling fillingHam = new Filling(HAM); + + basket.add(bagelPlain); + basket.add(bagelOnion); + basket.add(fillingCheese); + basket.add(fillingHam); + + double expectedSum = bagelPlain.getPrice() + bagelOnion.getPrice() + fillingCheese.getPrice() + fillingHam.getPrice(); + + Assertions.assertFalse(basket.isFull()); + Assertions.assertEquals(expectedSum, basket.total()); + Assertions.assertTrue(basket.add(bagelOnion)); + + basket.remove(bagelPlain); + + Assertions.assertFalse(basket.remove(bagelPlain)); + } @Test @@ -119,9 +179,4 @@ public void testCustomer(){ public void testManager(){ } - - @Test - public void testInventory(){ - - } } From 0c6acea832caa1210ee870c4f767c74480e00eae Mon Sep 17 00:00:00 2001 From: Magnus Hissingby Date: Mon, 11 Aug 2025 15:44:28 +0200 Subject: [PATCH 06/10] Person, Member, Manager and Customer with tests --- src/main/java/com/booleanuk/core/Basket.java | 4 +- .../com/booleanuk/core/BasketCapacity.java | 22 +++++++ .../java/com/booleanuk/core/Customer.java | 4 -- .../com/booleanuk/core/Person/Customer.java | 15 +++++ .../com/booleanuk/core/Person/Manager.java | 12 +++- .../com/booleanuk/core/Person/Member.java | 25 ++++++- .../com/booleanuk/core/Person/Person.java | 9 +++ .../com/booleanuk/core/BobsBagelTests.java | 66 ++++++++++++++++++- 8 files changed, 148 insertions(+), 9 deletions(-) create mode 100644 src/main/java/com/booleanuk/core/BasketCapacity.java delete mode 100644 src/main/java/com/booleanuk/core/Customer.java create mode 100644 src/main/java/com/booleanuk/core/Person/Customer.java diff --git a/src/main/java/com/booleanuk/core/Basket.java b/src/main/java/com/booleanuk/core/Basket.java index b2170159a..7696a18aa 100644 --- a/src/main/java/com/booleanuk/core/Basket.java +++ b/src/main/java/com/booleanuk/core/Basket.java @@ -7,7 +7,7 @@ public class Basket { private final int capacity; - private final List items; + private final List> items; private final Inventory inventory; public Basket(int capacity, Inventory inventory){ @@ -17,7 +17,7 @@ public Basket(int capacity, Inventory inventory){ } public boolean add(Item item){ - if (inventory.exists(item)){ + if (inventory.exists(item) && !isFull()){ items.add(item); return true; } else { return false; } diff --git a/src/main/java/com/booleanuk/core/BasketCapacity.java b/src/main/java/com/booleanuk/core/BasketCapacity.java new file mode 100644 index 000000000..8c691901f --- /dev/null +++ b/src/main/java/com/booleanuk/core/BasketCapacity.java @@ -0,0 +1,22 @@ +package com.booleanuk.core; + +public class BasketCapacity { + public int basketCapacity; + + public BasketCapacity(int capacity){ + this.basketCapacity = capacity; + } + + public int getCapacity(){ + return this.basketCapacity; + } + + public boolean setCapacity(int capacity){ + if (capacity != this.basketCapacity){ + this.basketCapacity = capacity; + return true; + } else { + return false; + } + } +} diff --git a/src/main/java/com/booleanuk/core/Customer.java b/src/main/java/com/booleanuk/core/Customer.java deleted file mode 100644 index 6f3a664d5..000000000 --- a/src/main/java/com/booleanuk/core/Customer.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.booleanuk.core; - -public class Customer { -} diff --git a/src/main/java/com/booleanuk/core/Person/Customer.java b/src/main/java/com/booleanuk/core/Person/Customer.java new file mode 100644 index 000000000..223a134ac --- /dev/null +++ b/src/main/java/com/booleanuk/core/Person/Customer.java @@ -0,0 +1,15 @@ +package com.booleanuk.core.Person; + +import com.booleanuk.core.Basket; + +public class Customer extends Member{ + private final int customerId; + public Customer(String name, int id, Basket basket, int customerId) { + super(name, id, basket); + this.customerId = customerId; + } + + public int getCustomerId(){ + return this.customerId; + } +} diff --git a/src/main/java/com/booleanuk/core/Person/Manager.java b/src/main/java/com/booleanuk/core/Person/Manager.java index 7673caa46..4b939f593 100644 --- a/src/main/java/com/booleanuk/core/Person/Manager.java +++ b/src/main/java/com/booleanuk/core/Person/Manager.java @@ -1,4 +1,14 @@ package com.booleanuk.core.Person; -public class Manager { +import com.booleanuk.core.BasketCapacity; + +public class Manager extends Person{ + + public Manager(String name) { + super(name); + } + + public boolean changeBasketCapacity(BasketCapacity basketCapacity, int capacity){ + return basketCapacity.setCapacity(capacity); + } } diff --git a/src/main/java/com/booleanuk/core/Person/Member.java b/src/main/java/com/booleanuk/core/Person/Member.java index 80161800a..61761844e 100644 --- a/src/main/java/com/booleanuk/core/Person/Member.java +++ b/src/main/java/com/booleanuk/core/Person/Member.java @@ -1,4 +1,27 @@ package com.booleanuk.core.Person; -public class Member { +import com.booleanuk.core.Basket; +import com.booleanuk.core.Item.Item; + +public class Member extends Person{ + private final int id; + private final Basket basket; + + public Member(String name, int id, Basket basket) { + super(name); + this.id = id; + this.basket = basket; + } + + public int getMemberId(){ + return this.id; + } + + public boolean addItemToBasket(Item item){ + return basket.add(item); + } + + public boolean removeItemFromBasket(Item item){ + return basket.remove(item); + } } diff --git a/src/main/java/com/booleanuk/core/Person/Person.java b/src/main/java/com/booleanuk/core/Person/Person.java index 60a742325..c26ff2ee2 100644 --- a/src/main/java/com/booleanuk/core/Person/Person.java +++ b/src/main/java/com/booleanuk/core/Person/Person.java @@ -1,4 +1,13 @@ package com.booleanuk.core.Person; public class Person { + private final String name; + + public Person(String name){ + this.name = name; + } + + public String getName(){ + return this.name; + } } diff --git a/src/test/java/com/booleanuk/core/BobsBagelTests.java b/src/test/java/com/booleanuk/core/BobsBagelTests.java index e5f3fc042..15b9a9429 100644 --- a/src/test/java/com/booleanuk/core/BobsBagelTests.java +++ b/src/test/java/com/booleanuk/core/BobsBagelTests.java @@ -3,6 +3,10 @@ import com.booleanuk.core.Item.Bagel.*; import com.booleanuk.core.Item.Filling.*; import com.booleanuk.core.Item.Coffee.*; +import com.booleanuk.core.Person.Customer; +import com.booleanuk.core.Person.Manager; +import com.booleanuk.core.Person.Member; +import com.booleanuk.core.Person.Person; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -136,7 +140,9 @@ public void testBasket(){ Inventory inventory = new Inventory(listOfBagels, listOfFillings, listOfCoffees); - Basket basket = new Basket(10, inventory); + BasketCapacity basketCapacity = new BasketCapacity(10); + + Basket basket = new Basket(basketCapacity.getCapacity(), inventory); Bagel bagelOnion = new Bagel(ONION); Bagel bagelPlain = new Bagel(PLAIN); @@ -163,20 +169,78 @@ public void testBasket(){ @Test public void testPerson(){ + Person person1 = new Person("Odd"); + Person person2 = new Person("Jimmy"); + + Assertions.assertEquals("Odd", person1.getName()); + Assertions.assertNotEquals("jim", person2.getName()); } @Test public void testMember(){ + List listOfBagels = new ArrayList<>(Arrays.asList(PLAIN, ONION, EVERYTHING, SESAME)); + List listOfFillings = new ArrayList<>(Arrays.asList(BACON, EGG, CHEESE, CREAM_CHEESE, SMOKED_SALMON, HAM)); + List listOfCoffees = new ArrayList<>(Arrays.asList(BLACK, WHITE, CAPPUCCINO, LATTE)); + + Inventory inventory = new Inventory(listOfBagels, listOfFillings, listOfCoffees); + + BasketCapacity basketCapacity = new BasketCapacity(1); + + Basket basket = new Basket(basketCapacity.getCapacity(), inventory); + Basket basket2 = new Basket(basketCapacity.getCapacity(), inventory); + + Member member1 = new Member("Cody", 5, basket); + Member member2 = new Member("Bob", 6, basket2); + + Bagel bagel = new Bagel(ONION); + + Assertions.assertTrue(member1.addItemToBasket(bagel)); + Assertions.assertFalse(member1.addItemToBasket(bagel)); + Assertions.assertTrue(member2.addItemToBasket(bagel)); + Assertions.assertTrue(member2.removeItemFromBasket(bagel)); + Assertions.assertEquals("Cody", member1.getName()); + Assertions.assertEquals(5, member1.getMemberId()); } @Test public void testCustomer(){ + List listOfBagels = new ArrayList<>(Arrays.asList(PLAIN, ONION, EVERYTHING, SESAME)); + List listOfFillings = new ArrayList<>(Arrays.asList(BACON, EGG, CHEESE, CREAM_CHEESE, SMOKED_SALMON, HAM)); + List listOfCoffees = new ArrayList<>(Arrays.asList(BLACK, WHITE, CAPPUCCINO, LATTE)); + + Inventory inventory = new Inventory(listOfBagels, listOfFillings, listOfCoffees); + + BasketCapacity basketCapacity = new BasketCapacity(1); + + Basket basket = new Basket(basketCapacity.getCapacity(), inventory); + Basket basket2 = new Basket(basketCapacity.getCapacity(), inventory); + + Customer customer1 = new Customer("Ray", 10, basket, 19); + Customer customer2 = new Customer("Bob", 5, basket2, 21); + + Bagel bagel = new Bagel(ONION); + + Assertions.assertTrue(customer1.addItemToBasket(bagel)); + Assertions.assertFalse(customer1.addItemToBasket(bagel)); + Assertions.assertTrue(customer2.addItemToBasket(bagel)); + Assertions.assertTrue(customer2.removeItemFromBasket(bagel)); + Assertions.assertEquals("Ray", customer1.getName()); + Assertions.assertEquals(10, customer1.getMemberId()); + Assertions.assertEquals(21, customer2.getCustomerId()); } @Test public void testManager(){ + Manager manager = new Manager("Johnny"); + BasketCapacity basketCapacity = new BasketCapacity(10); + + manager.changeBasketCapacity(basketCapacity, 12); + + Assertions.assertEquals(12, basketCapacity.basketCapacity); + Assertions.assertFalse(manager.changeBasketCapacity(basketCapacity, 12)); + } } From b75119b34c18ab7a84c4fef9fc6b88cd6326d682 Mon Sep 17 00:00:00 2001 From: Magnus Hissingby Date: Tue, 12 Aug 2025 11:50:59 +0200 Subject: [PATCH 07/10] Minor changes to Inventory and tests --- src/main/java/com/booleanuk/core/Basket.java | 6 +- .../java/com/booleanuk/core/Inventory.java | 40 +++++++--- .../com/booleanuk/core/Item/Bagel/Bagel.java | 8 +- .../booleanuk/core/Item/Coffee/Coffee.java | 8 +- .../booleanuk/core/Item/Filling/Filling.java | 8 +- .../java/com/booleanuk/core/Item/Item.java | 4 +- .../com/booleanuk/core/Person/Customer.java | 1 + .../com/booleanuk/core/BobsBagelTests.java | 76 +++++++++++++------ 8 files changed, 100 insertions(+), 51 deletions(-) diff --git a/src/main/java/com/booleanuk/core/Basket.java b/src/main/java/com/booleanuk/core/Basket.java index 7696a18aa..8fd9749ba 100644 --- a/src/main/java/com/booleanuk/core/Basket.java +++ b/src/main/java/com/booleanuk/core/Basket.java @@ -7,7 +7,7 @@ public class Basket { private final int capacity; - private final List> items; + private final List items; private final Inventory inventory; public Basket(int capacity, Inventory inventory){ @@ -19,6 +19,7 @@ public Basket(int capacity, Inventory inventory){ public boolean add(Item item){ if (inventory.exists(item) && !isFull()){ items.add(item); + inventory.reduceCount(item); return true; } else { return false; } } @@ -26,6 +27,7 @@ public boolean add(Item item){ public boolean remove(Item item){ if (items.contains(item)){ items.remove(item); + inventory.increaseCount(item); return true; } else { return false; } } @@ -38,6 +40,4 @@ public boolean isFull() { public double total(){ return items.stream().map(Item::getPrice).reduce(0.0, Double::sum); } - - } diff --git a/src/main/java/com/booleanuk/core/Inventory.java b/src/main/java/com/booleanuk/core/Inventory.java index 11be8eb22..66e4e8f24 100644 --- a/src/main/java/com/booleanuk/core/Inventory.java +++ b/src/main/java/com/booleanuk/core/Inventory.java @@ -1,24 +1,40 @@ package com.booleanuk.core; -import com.booleanuk.core.Item.Bagel.BagelType; -import com.booleanuk.core.Item.Coffee.CoffeeType; -import com.booleanuk.core.Item.Filling.FillingType; import com.booleanuk.core.Item.Item; -import java.util.List; +import java.util.HashMap; public class Inventory { - List listOfBagels; - List listOfFillings; - List listOfCoffees; + HashMap mapOfItems; - public Inventory(List bagels, List fillings, List coffees){ - this.listOfBagels = bagels; - this.listOfFillings = fillings; - this.listOfCoffees = coffees; + public Inventory(HashMap mapOfItems){ + this.mapOfItems = mapOfItems; + } + + public void increaseCount(Item item){ + if (!mapOfItems.containsKey(item.getType())){ + mapOfItems.put(item.getType(), 1); + } + else { + this.mapOfItems.compute(item.getType(), (k, currCount) -> currCount + 1); + } + } + + public boolean reduceCount(Item item){ + if (!mapOfItems.containsKey(item.getType())){ + return false; + } else { + if (mapOfItems.get(item.getType()) < 1) { + return false; + } + else { + this.mapOfItems.compute(item.getType(), (k, currCount) -> currCount - 1); + return true; + } + } } public boolean exists(Item item){ - return listOfBagels.contains(item.getType()) || listOfFillings.contains(item.getType()) || listOfCoffees.contains(item.getType()); + return mapOfItems.containsKey(item.getType()) && mapOfItems.get(item.getType()) > 0; } } diff --git a/src/main/java/com/booleanuk/core/Item/Bagel/Bagel.java b/src/main/java/com/booleanuk/core/Item/Bagel/Bagel.java index 134184b30..dfb2ee926 100644 --- a/src/main/java/com/booleanuk/core/Item/Bagel/Bagel.java +++ b/src/main/java/com/booleanuk/core/Item/Bagel/Bagel.java @@ -6,15 +6,15 @@ import java.util.ArrayList; import java.util.List; -public class Bagel implements Item { +public class Bagel implements Item { private final List filling; private final double price; - private final BagelType type; + private final String type; public Bagel(BagelType type){ this.price = type.equals(BagelType.PLAIN)? 0.39 : 0.49; filling = new ArrayList<>(); - this.type = type; + this.type = type.toString(); } public double getPrice(){ @@ -22,7 +22,7 @@ public double getPrice(){ } @Override - public BagelType getType(){ + public String getType(){ return this.type; } diff --git a/src/main/java/com/booleanuk/core/Item/Coffee/Coffee.java b/src/main/java/com/booleanuk/core/Item/Coffee/Coffee.java index 52614bdd8..1e7386aab 100644 --- a/src/main/java/com/booleanuk/core/Item/Coffee/Coffee.java +++ b/src/main/java/com/booleanuk/core/Item/Coffee/Coffee.java @@ -3,9 +3,9 @@ import com.booleanuk.core.Item.Item; -public class Coffee implements Item { +public class Coffee implements Item { private final double price; - private final CoffeeType type; + private final String type; public Coffee(CoffeeType type){ this.price = switch(type){ @@ -13,7 +13,7 @@ public Coffee(CoffeeType type){ case WHITE -> 1.19; default -> 1.29; }; - this.type = type; + this.type = type.toString(); } public double getPrice(){ @@ -21,7 +21,7 @@ public double getPrice(){ } @Override - public CoffeeType getType(){ + public String getType(){ return this.type; } } diff --git a/src/main/java/com/booleanuk/core/Item/Filling/Filling.java b/src/main/java/com/booleanuk/core/Item/Filling/Filling.java index 7417a7376..7872b107e 100644 --- a/src/main/java/com/booleanuk/core/Item/Filling/Filling.java +++ b/src/main/java/com/booleanuk/core/Item/Filling/Filling.java @@ -2,13 +2,13 @@ import com.booleanuk.core.Item.Item; -public class Filling implements Item { +public class Filling implements Item { private final double price; - private final FillingType type; + private final String type; public Filling(FillingType type){ this.price = 0.12; - this.type = type; + this.type = type.toString(); } public double getPrice(){ @@ -16,7 +16,7 @@ public double getPrice(){ } @Override - public FillingType getType(){ + public String getType(){ return this.type; } } diff --git a/src/main/java/com/booleanuk/core/Item/Item.java b/src/main/java/com/booleanuk/core/Item/Item.java index e5961e899..07b0f87fd 100644 --- a/src/main/java/com/booleanuk/core/Item/Item.java +++ b/src/main/java/com/booleanuk/core/Item/Item.java @@ -1,6 +1,6 @@ package com.booleanuk.core.Item; -public interface Item { +public interface Item { double getPrice(); - T getType(); + String getType(); } diff --git a/src/main/java/com/booleanuk/core/Person/Customer.java b/src/main/java/com/booleanuk/core/Person/Customer.java index 223a134ac..07fa28779 100644 --- a/src/main/java/com/booleanuk/core/Person/Customer.java +++ b/src/main/java/com/booleanuk/core/Person/Customer.java @@ -4,6 +4,7 @@ public class Customer extends Member{ private final int customerId; + public Customer(String name, int id, Basket basket, int customerId) { super(name, id, basket); this.customerId = customerId; diff --git a/src/test/java/com/booleanuk/core/BobsBagelTests.java b/src/test/java/com/booleanuk/core/BobsBagelTests.java index 15b9a9429..dc7f5bbbd 100644 --- a/src/test/java/com/booleanuk/core/BobsBagelTests.java +++ b/src/test/java/com/booleanuk/core/BobsBagelTests.java @@ -10,9 +10,7 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; +import java.util.HashMap; import static com.booleanuk.core.Item.Bagel.BagelType.*; import static com.booleanuk.core.Item.Filling.FillingType.*; @@ -116,17 +114,28 @@ public void testItem(){ @Test public void testInventory(){ - List listOfBagels = new ArrayList<>(Arrays.asList(PLAIN, ONION, EVERYTHING, SESAME)); - List listOfFillings = new ArrayList<>(Arrays.asList(BACON, EGG, CHEESE, CREAM_CHEESE, SMOKED_SALMON, HAM)); - List listOfCoffees = new ArrayList<>(Arrays.asList(BLACK, WHITE, CAPPUCCINO, LATTE)); + HashMap mapOfItems = new HashMap<>(){{ + put(PLAIN.toString(), 5); + put(ONION.toString(), 5); + put(EVERYTHING.toString(), 4); + put(BACON.toString(), 7); + put(CHEESE.toString(), 1); + put(WHITE.toString(), 3); + put(LATTE.toString(), 2); + put(HAM.toString(), 4); + }}; - Inventory inventory = new Inventory(listOfBagels, listOfFillings, listOfCoffees); + Bagel bagel1 = new Bagel(SESAME); - Bagel bagel = new Bagel(PLAIN); + Inventory inventory = new Inventory(mapOfItems); + + Bagel bagel2 = new Bagel(PLAIN); Filling filling = new Filling(HAM); Coffee coffee = new Coffee(WHITE); - Assertions.assertTrue(inventory.exists(bagel)); + Assertions.assertTrue(inventory.exists(bagel2)); + Assertions.assertFalse(inventory.reduceCount(bagel1)); + Assertions.assertEquals(5, inventory.mapOfItems.get(PLAIN.toString())); Assertions.assertTrue(inventory.exists(filling)); Assertions.assertTrue(inventory.exists(coffee)); } @@ -134,11 +143,18 @@ public void testInventory(){ @Test public void testBasket(){ - List listOfBagels = new ArrayList<>(Arrays.asList(PLAIN, ONION, EVERYTHING, SESAME)); - List listOfFillings = new ArrayList<>(Arrays.asList(BACON, EGG, CHEESE, CREAM_CHEESE, SMOKED_SALMON, HAM)); - List listOfCoffees = new ArrayList<>(Arrays.asList(BLACK, WHITE, CAPPUCCINO, LATTE)); + HashMap mapOfItems = new HashMap<>(){{ + put(PLAIN.toString(), 5); + put(ONION.toString(), 5); + put(EVERYTHING.toString(), 4); + put(BACON.toString(), 7); + put(HAM.toString(), 3); + put(CHEESE.toString(), 1); + put(WHITE.toString(), 3); + put(LATTE.toString(), 2); + }}; - Inventory inventory = new Inventory(listOfBagels, listOfFillings, listOfCoffees); + Inventory inventory = new Inventory(mapOfItems); BasketCapacity basketCapacity = new BasketCapacity(10); @@ -159,9 +175,11 @@ public void testBasket(){ Assertions.assertFalse(basket.isFull()); Assertions.assertEquals(expectedSum, basket.total()); Assertions.assertTrue(basket.add(bagelOnion)); + Assertions.assertEquals(4, inventory.mapOfItems.get(PLAIN.toString())); basket.remove(bagelPlain); + Assertions.assertEquals(5, inventory.mapOfItems.get(PLAIN.toString())); Assertions.assertFalse(basket.remove(bagelPlain)); } @@ -179,11 +197,18 @@ public void testPerson(){ @Test public void testMember(){ - List listOfBagels = new ArrayList<>(Arrays.asList(PLAIN, ONION, EVERYTHING, SESAME)); - List listOfFillings = new ArrayList<>(Arrays.asList(BACON, EGG, CHEESE, CREAM_CHEESE, SMOKED_SALMON, HAM)); - List listOfCoffees = new ArrayList<>(Arrays.asList(BLACK, WHITE, CAPPUCCINO, LATTE)); + HashMap mapOfItems = new HashMap<>(){{ + put(PLAIN.toString(), 5); + put(ONION.toString(), 5); + put(EVERYTHING.toString(), 4); + put(BACON.toString(), 7); + put(HAM.toString(), 3); + put(CHEESE.toString(), 1); + put(WHITE.toString(), 3); + put(LATTE.toString(), 2); + }}; - Inventory inventory = new Inventory(listOfBagels, listOfFillings, listOfCoffees); + Inventory inventory = new Inventory(mapOfItems); BasketCapacity basketCapacity = new BasketCapacity(1); @@ -206,11 +231,18 @@ public void testMember(){ @Test public void testCustomer(){ - List listOfBagels = new ArrayList<>(Arrays.asList(PLAIN, ONION, EVERYTHING, SESAME)); - List listOfFillings = new ArrayList<>(Arrays.asList(BACON, EGG, CHEESE, CREAM_CHEESE, SMOKED_SALMON, HAM)); - List listOfCoffees = new ArrayList<>(Arrays.asList(BLACK, WHITE, CAPPUCCINO, LATTE)); - - Inventory inventory = new Inventory(listOfBagels, listOfFillings, listOfCoffees); + HashMap mapOfItems = new HashMap<>(){{ + put(PLAIN.toString(), 5); + put(ONION.toString(), 5); + put(EVERYTHING.toString(), 4); + put(BACON.toString(), 7); + put(HAM.toString(), 3); + put(CHEESE.toString(), 1); + put(WHITE.toString(), 3); + put(LATTE.toString(), 2); + }}; + + Inventory inventory = new Inventory(mapOfItems); BasketCapacity basketCapacity = new BasketCapacity(1); From 700539f91a76c2e9b2104c455e7c4f9950d1efc1 Mon Sep 17 00:00:00 2001 From: Magnus Hissingby Date: Tue, 12 Aug 2025 15:54:35 +0200 Subject: [PATCH 08/10] Extension 1 and 2 (currently in the core folder) --- src/main/java/com/booleanuk/core/Basket.java | 65 +++++++++- .../java/com/booleanuk/core/Inventory.java | 9 +- .../com/booleanuk/core/Item/Bagel/Bagel.java | 11 ++ .../booleanuk/core/Item/Coffee/Coffee.java | 11 ++ .../booleanuk/core/Item/Filling/Filling.java | 13 ++ .../java/com/booleanuk/core/Item/Item.java | 1 + .../com/booleanuk/core/Person/Member.java | 18 +++ .../java/com/booleanuk/core/domain-model.md | 63 +++++----- .../com/booleanuk/core/BobsBagelTests.java | 113 ++++++++++++++++++ 9 files changed, 265 insertions(+), 39 deletions(-) diff --git a/src/main/java/com/booleanuk/core/Basket.java b/src/main/java/com/booleanuk/core/Basket.java index 8fd9749ba..453195b14 100644 --- a/src/main/java/com/booleanuk/core/Basket.java +++ b/src/main/java/com/booleanuk/core/Basket.java @@ -2,7 +2,9 @@ import com.booleanuk.core.Item.Item; +import java.time.LocalDateTime; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; public class Basket { @@ -17,11 +19,17 @@ public Basket(int capacity, Inventory inventory){ } public boolean add(Item item){ - if (inventory.exists(item) && !isFull()){ + if (!inventory.exists(item)){ + System.out.println("The item is out of stock!"); + return false; + } else if (isFull()){ + System.out.println("The basket is full!"); + return false; + } else { items.add(item); inventory.reduceCount(item); return true; - } else { return false; } + } } public boolean remove(Item item){ @@ -29,7 +37,10 @@ public boolean remove(Item item){ items.remove(item); inventory.increaseCount(item); return true; - } else { return false; } + } else { + System.out.println("This item does not exist in your basket!"); + return false; + } } public boolean isFull() { @@ -38,6 +49,52 @@ public boolean isFull() { } public double total(){ - return items.stream().map(Item::getPrice).reduce(0.0, Double::sum); + + return items.stream().map(Item::getPrice).reduce(0.0, Double::sum) - findDiscount(); + } + + public double findDiscount(){ + double totalDiscount = 0.0; + + int bagelsPlainCount = Math.toIntExact(items.stream().filter(item -> item.getSku().equals("BGLP")).count()); + int bagelsNotPlainCount = Math.toIntExact(items.stream().filter(item -> !item.getSku().equals("BGLP")).count()); + int coffeeBlackCoffeeCount = Math.toIntExact(items.stream().filter(item -> item.getSku().equals("COFB")).count()); + if (bagelsPlainCount >= 12) { + // adding the difference between normal price of 6 plain bagels vs discounted price + totalDiscount += 0.69; + } + if (bagelsNotPlainCount >= 6){ + totalDiscount += 0.45; + } + if (bagelsPlainCount > 0 && coffeeBlackCoffeeCount > 0){ + totalDiscount += 0.13; + } else if (bagelsNotPlainCount > 0 && coffeeBlackCoffeeCount > 0){ + totalDiscount += 0.23; + } + return totalDiscount; + } + + public void printReceipt(){ + HashMap res = new HashMap<>(); + for (Item item : items){ + res.put(item.getType(), res.getOrDefault(item.getType(), 0) + 1); + } + LocalDateTime currentDateTime = LocalDateTime.now(); + + String firstPart = + "\n\n ~~~ Bob's Bagels ~~~\n\n " + currentDateTime + "\n\n" + + "-------------------------------------" + "\n"; + + System.out.println(firstPart); + res.forEach((key,val) -> { + double price = items.stream().filter(itm -> itm.getType().equals(key)).toList().getFirst().getPrice()*val; + System.out.println(key + " " + " " + val + " £" + price); + }); + String lastPart = + "-------------------------------------" + "\n" + + "Total £" + String.format("%.2f", total()) + "\n\n" + + " Thank you \n for your order!\n\n"; + + System.out.println(lastPart); } } diff --git a/src/main/java/com/booleanuk/core/Inventory.java b/src/main/java/com/booleanuk/core/Inventory.java index 66e4e8f24..1b4252e10 100644 --- a/src/main/java/com/booleanuk/core/Inventory.java +++ b/src/main/java/com/booleanuk/core/Inventory.java @@ -12,12 +12,7 @@ public Inventory(HashMap mapOfItems){ } public void increaseCount(Item item){ - if (!mapOfItems.containsKey(item.getType())){ - mapOfItems.put(item.getType(), 1); - } - else { - this.mapOfItems.compute(item.getType(), (k, currCount) -> currCount + 1); - } + mapOfItems.put(item.getType(), mapOfItems.getOrDefault(item.getType(), 0) + 1); } public boolean reduceCount(Item item){ @@ -28,7 +23,7 @@ public boolean reduceCount(Item item){ return false; } else { - this.mapOfItems.compute(item.getType(), (k, currCount) -> currCount - 1); + mapOfItems.put(item.getType(), mapOfItems.getOrDefault(item.getType(), 0) - 1); return true; } } diff --git a/src/main/java/com/booleanuk/core/Item/Bagel/Bagel.java b/src/main/java/com/booleanuk/core/Item/Bagel/Bagel.java index dfb2ee926..57eb1df2f 100644 --- a/src/main/java/com/booleanuk/core/Item/Bagel/Bagel.java +++ b/src/main/java/com/booleanuk/core/Item/Bagel/Bagel.java @@ -10,11 +10,22 @@ public class Bagel implements Item { private final List filling; private final double price; private final String type; + private final String sku; public Bagel(BagelType type){ this.price = type.equals(BagelType.PLAIN)? 0.39 : 0.49; filling = new ArrayList<>(); this.type = type.toString(); + this.sku = switch(type){ + case PLAIN -> "BGLP"; + case ONION -> "BGLO"; + case EVERYTHING -> "BGLE"; + case SESAME -> "BGLS"; + }; + } + + public String getSku(){ + return this.sku; } public double getPrice(){ diff --git a/src/main/java/com/booleanuk/core/Item/Coffee/Coffee.java b/src/main/java/com/booleanuk/core/Item/Coffee/Coffee.java index 1e7386aab..9a95b8349 100644 --- a/src/main/java/com/booleanuk/core/Item/Coffee/Coffee.java +++ b/src/main/java/com/booleanuk/core/Item/Coffee/Coffee.java @@ -6,6 +6,7 @@ public class Coffee implements Item { private final double price; private final String type; + private final String sku; public Coffee(CoffeeType type){ this.price = switch(type){ @@ -14,6 +15,16 @@ public Coffee(CoffeeType type){ default -> 1.29; }; this.type = type.toString(); + this.sku = switch(type){ + case BLACK -> "COFB"; + case WHITE -> "COFW"; + case CAPPUCCINO -> "COFC"; + case LATTE -> "COFL"; + }; + } + + public String getSku(){ + return this.sku; } public double getPrice(){ diff --git a/src/main/java/com/booleanuk/core/Item/Filling/Filling.java b/src/main/java/com/booleanuk/core/Item/Filling/Filling.java index 7872b107e..77d98b5f2 100644 --- a/src/main/java/com/booleanuk/core/Item/Filling/Filling.java +++ b/src/main/java/com/booleanuk/core/Item/Filling/Filling.java @@ -5,10 +5,23 @@ public class Filling implements Item { private final double price; private final String type; + private final String sku; public Filling(FillingType type){ this.price = 0.12; this.type = type.toString(); + this.sku = switch(type){ + case BACON -> "FILB"; + case EGG -> "FILE"; + case CHEESE -> "FILC"; + case CREAM_CHEESE -> "FILX"; + case SMOKED_SALMON -> "FILS"; + case HAM -> "FILH"; + }; + } + + public String getSku(){ + return this.sku; } public double getPrice(){ diff --git a/src/main/java/com/booleanuk/core/Item/Item.java b/src/main/java/com/booleanuk/core/Item/Item.java index 07b0f87fd..144e879ee 100644 --- a/src/main/java/com/booleanuk/core/Item/Item.java +++ b/src/main/java/com/booleanuk/core/Item/Item.java @@ -3,4 +3,5 @@ public interface Item { double getPrice(); String getType(); + String getSku(); } diff --git a/src/main/java/com/booleanuk/core/Person/Member.java b/src/main/java/com/booleanuk/core/Person/Member.java index 61761844e..7728258b4 100644 --- a/src/main/java/com/booleanuk/core/Person/Member.java +++ b/src/main/java/com/booleanuk/core/Person/Member.java @@ -1,6 +1,8 @@ package com.booleanuk.core.Person; import com.booleanuk.core.Basket; +import com.booleanuk.core.Item.Bagel.Bagel; +import com.booleanuk.core.Item.Filling.Filling; import com.booleanuk.core.Item.Item; public class Member extends Person{ @@ -24,4 +26,20 @@ public boolean addItemToBasket(Item item){ public boolean removeItemFromBasket(Item item){ return basket.remove(item); } + + public double totalCost(){ + return basket.total(); + } + + public double getPriceOfItem(Item item){ + return item.getPrice(); + } + + public void chooseFillingForBagel(Bagel bagel, Filling filling){ + bagel.addFilling(filling); + } + + public void printReceiptFromBasket(){ + basket.printReceipt(); + } } diff --git a/src/main/java/com/booleanuk/core/domain-model.md b/src/main/java/com/booleanuk/core/domain-model.md index 108031d32..7201c2517 100644 --- a/src/main/java/com/booleanuk/core/domain-model.md +++ b/src/main/java/com/booleanuk/core/domain-model.md @@ -1,29 +1,36 @@ -| Class | Method | Scenario | Output | -|-----------|--------------------------------------------|--------------------------|--------| -| Member | boolean addItemFromBasket(Item item) | If basket is full | false | -| Basket | boolean add(Item item) | If space in basket | true | -| | | | | -| Member | boolean removeItemFromBasket(Item item) | If item doesn't exist | false | -| Basket | boolean remove(Item item) | If item exists | true | -| | | | | -| Basket | boolean isFull() | If basket is full | true | -| | | If basket is not full | false | -| | | | | -| Manager | boolean changeBasketCapacity(int capacity) | If capacity is the same | false | -| | | If capacity is changed | true | -| | | | | -| Customer | double totalCostInBasket() | If no items in basket | 0 | -| Basket | double totalCost() | If items in basket | sum | -| | | | | -| Customer | double getPriceOfBagel(Bagel bagel) | If bagel doesn't exist | null | -| Bagel | double getPrice() | If bagel exists | price | -| | | | | -| Customer | boolean chooseFilling(Filling filling) | If filling doesn't exist | false | -| Bagel | boolean addFilling(Filling filling) | If filling exists | true | -| | | | | -| Customer | double getPriceOfFilling(Filling filling) | If filling doesn't exist | null | -| Filling | double getPrice() | If filling exists | price | -| | | | | -| Inventory | boolean doesItemExist(Item item) | If item doesn't exist | false | -| | | If item exists | true | +| Class | Method | Scenario | Output | +|-----------|--------------------------------------------|-------------------------------|----------------| +| Member | boolean addItemFromBasket(Item item) | If basket is full | false | +| Basket | boolean add(Item item) | If space in basket | true | +| | | | | +| Member | boolean removeItemFromBasket(Item item) | If item doesn't exist | false | +| Basket | boolean remove(Item item) | If item exists | true | +| | | | | +| Basket | boolean isFull() | If basket is full | true | +| | | If basket is not full | false | +| | | | | +| Manager | boolean changeBasketCapacity(int capacity) | If capacity is the same | false | +| | | If capacity is changed | true | +| | | | | +| Customer | double totalCostInBasket() | If no items in basket | 0 | +| Basket | double totalCost() | If items in basket | sum | +| | | | | +| Customer | double getPriceOfBagel(Bagel bagel) | If bagel doesn't exist | null | +| Bagel | double getPrice() | If bagel exists | price | +| | | | | +| Customer | boolean chooseFilling(Filling filling) | If filling doesn't exist | false | +| Bagel | boolean addFilling(Filling filling) | If filling exists | true | +| | | | | +| Customer | double getPriceOfFilling(Filling filling) | If filling doesn't exist | null | +| Filling | double getPrice() | If filling exists | price | +| | | | | +| Inventory | boolean doesItemExist(Item item) | If item doesn't exist | false | +| | | If item exists | true | +| | | | | +| Basket | //updated// double totalCost() | If no discounts are available | total | +| | | If discounts are available | total-discount | +| | | | | +| Basket | double findDiscount() | If discount is found | discount | +| | | If no discount is found | 0.0 | +| | | | | diff --git a/src/test/java/com/booleanuk/core/BobsBagelTests.java b/src/test/java/com/booleanuk/core/BobsBagelTests.java index dc7f5bbbd..8c79bd73e 100644 --- a/src/test/java/com/booleanuk/core/BobsBagelTests.java +++ b/src/test/java/com/booleanuk/core/BobsBagelTests.java @@ -253,8 +253,15 @@ public void testCustomer(){ Customer customer2 = new Customer("Bob", 5, basket2, 21); Bagel bagel = new Bagel(ONION); + Filling filling = new Filling(HAM); + + customer1.chooseFillingForBagel(bagel, filling); + + Assertions.assertEquals(1, bagel.getFilling().size()); Assertions.assertTrue(customer1.addItemToBasket(bagel)); + Assertions.assertEquals(0.49, customer1.getPriceOfItem(bagel)); + Assertions.assertEquals(0.49, customer1.totalCost()); Assertions.assertFalse(customer1.addItemToBasket(bagel)); Assertions.assertTrue(customer2.addItemToBasket(bagel)); Assertions.assertTrue(customer2.removeItemFromBasket(bagel)); @@ -275,4 +282,110 @@ public void testManager(){ Assertions.assertFalse(manager.changeBasketCapacity(basketCapacity, 12)); } + + @Test + public void testDiscount(){ + + HashMap mapOfItems = new HashMap<>(){{ + put(PLAIN.toString(), 15); + put(ONION.toString(), 20); + put(EVERYTHING.toString(), 20); + put(BACON.toString(), 20); + put(HAM.toString(), 20); + put(CHEESE.toString(), 20); + put(BLACK.toString(), 20); + put(WHITE.toString(), 20); + put(LATTE.toString(), 20); + }}; + + Inventory inventory = new Inventory(mapOfItems); + + BasketCapacity basketCapacity = new BasketCapacity(15); + Basket basket = new Basket(basketCapacity.getCapacity(), inventory); + Customer customer = new Customer("Ray", 10, basket, 19); + + Bagel bagelPlain = new Bagel(PLAIN); + Coffee coffeeBlack = new Coffee(BLACK); + Filling filling = new Filling(HAM); + + for (int i=0; i < 12; i++){ + customer.addItemToBasket(bagelPlain); + } + + double totalWithoutDiscount = bagelPlain.getPrice()*12; + double totalWithDiscount = customer.totalCost(); + + Basket basket2 = new Basket(5, inventory); + + Customer customer2 = new Customer("Bella", 11, basket2, 4); + + customer2.addItemToBasket(bagelPlain); + customer2.addItemToBasket(filling); + customer2.addItemToBasket(coffeeBlack); + + double totalWithoutDiscount2 = bagelPlain.getPrice() + filling.getPrice() + coffeeBlack.getPrice(); + double totalWithDiscount2 = customer2.totalCost(); + + Basket basket3 = new Basket(9, inventory); + Customer customer3 = new Customer("Sara", 24, basket3, 91); + + Bagel bagelOnion = new Bagel(ONION); + + for (int i=0;i<6;i++){ + customer3.addItemToBasket(bagelOnion); + } + customer3.addItemToBasket(bagelOnion); + + double totalWithoutDiscount3 = bagelOnion.getPrice()*7; + double totalWithDiscount3 = customer3.totalCost(); + + Assertions.assertNotEquals(totalWithDiscount, totalWithoutDiscount, 0.0); + Assertions.assertEquals(0.39*12, totalWithoutDiscount); + Assertions.assertEquals(Math.round(3.99), Math.round(totalWithDiscount)); + + Assertions.assertNotEquals(totalWithDiscount2, totalWithoutDiscount2); + Assertions.assertEquals(0.12+1.25, totalWithDiscount2); + + Assertions.assertNotEquals(totalWithDiscount3, totalWithoutDiscount3); + Assertions.assertEquals(2.49+bagelOnion.getPrice(), totalWithDiscount3); + } + + @Test + public void testReceipt(){ + HashMap mapOfItems = new HashMap<>(){{ + put(PLAIN.toString(), 15); + put(ONION.toString(), 20); + put(EVERYTHING.toString(), 20); + put(BACON.toString(), 20); + put(HAM.toString(), 20); + put(CHEESE.toString(), 20); + put(BLACK.toString(), 20); + put(WHITE.toString(), 20); + put(LATTE.toString(), 20); + }}; + + Inventory inventory = new Inventory(mapOfItems); + + BasketCapacity basketCapacity = new BasketCapacity(15); + Basket basket = new Basket(basketCapacity.getCapacity(), inventory); + Customer customer = new Customer("Ray", 10, basket, 19); + + Bagel bagel1 = new Bagel(ONION); + Bagel bagel2 = new Bagel(PLAIN); + Filling filling1 = new Filling(HAM); + Filling filling2 = new Filling(CHEESE); + Coffee coffee1 = new Coffee(BLACK); + Coffee coffee2 = new Coffee(WHITE); + + customer.addItemToBasket(bagel1); + customer.addItemToBasket(bagel2); + customer.addItemToBasket(filling1); + customer.addItemToBasket(filling2); + customer.addItemToBasket(coffee1); + customer.addItemToBasket(coffee2); + customer.addItemToBasket(coffee2); + customer.addItemToBasket(bagel1); + + customer.printReceiptFromBasket(); + } } From ce95327f0d6bb2e09faa392761a262ab819031b4 Mon Sep 17 00:00:00 2001 From: Magnus Hissingby Date: Tue, 12 Aug 2025 21:51:33 +0200 Subject: [PATCH 09/10] Extension 3 --- src/main/java/com/booleanuk/core/Basket.java | 18 ++- .../com/booleanuk/core/BasketCapacity.java | 5 + .../java/com/booleanuk/core/Inventory.java | 2 - .../com/booleanuk/core/Item/Bagel/Bagel.java | 4 - .../booleanuk/core/Item/Coffee/Coffee.java | 2 - .../booleanuk/core/Item/Filling/Filling.java | 1 - .../com/booleanuk/core/Person/Customer.java | 1 - .../com/booleanuk/core/Person/Manager.java | 1 - .../com/booleanuk/core/Person/Member.java | 1 - .../java/com/booleanuk/core/domain-model.md | 77 ++++++----- .../com/booleanuk/core/BobsBagelTests.java | 106 --------------- .../extension/BobsBagelExtensionTest.java | 128 ++++++++++++++++++ 12 files changed, 186 insertions(+), 160 deletions(-) create mode 100644 src/test/java/com/booleanuk/extension/BobsBagelExtensionTest.java diff --git a/src/main/java/com/booleanuk/core/Basket.java b/src/main/java/com/booleanuk/core/Basket.java index 453195b14..e580c5d25 100644 --- a/src/main/java/com/booleanuk/core/Basket.java +++ b/src/main/java/com/booleanuk/core/Basket.java @@ -1,7 +1,5 @@ package com.booleanuk.core; - import com.booleanuk.core.Item.Item; - import java.time.LocalDateTime; import java.util.ArrayList; import java.util.HashMap; @@ -44,12 +42,10 @@ public boolean remove(Item item){ } public boolean isFull() { - return items.size() == capacity; - + return items.size() >= capacity; } public double total(){ - return items.stream().map(Item::getPrice).reduce(0.0, Double::sum) - findDiscount(); } @@ -75,6 +71,11 @@ public double findDiscount(){ } public void printReceipt(){ + // A little bit messy, but I didn't want to rewrite the other parts of the code + // to be able to simplify this one, but it works. + // There is definitely a better way to structure the print-statements, + // but I figured that weren't the main objective of the task anyway. + HashMap res = new HashMap<>(); for (Item item : items){ res.put(item.getType(), res.getOrDefault(item.getType(), 0) + 1); @@ -92,8 +93,11 @@ public void printReceipt(){ }); String lastPart = "-------------------------------------" + "\n" + - "Total £" + String.format("%.2f", total()) + "\n\n" + - " Thank you \n for your order!\n\n"; + "Sum £" + String.format("%.2f", total()+findDiscount()) + "\n" + + "Discount (-£" + String.format("%.2f", findDiscount()) + ")\n" + + "Total £" + String.format("%.2f", total()) + + "\n\nYou saved a total of: £" + String.format("%.2f", findDiscount()) + + "\n\n Thank you \n for your order!\n\n"; System.out.println(lastPart); } diff --git a/src/main/java/com/booleanuk/core/BasketCapacity.java b/src/main/java/com/booleanuk/core/BasketCapacity.java index 8c691901f..3b1fe1653 100644 --- a/src/main/java/com/booleanuk/core/BasketCapacity.java +++ b/src/main/java/com/booleanuk/core/BasketCapacity.java @@ -1,5 +1,10 @@ package com.booleanuk.core; +// Basically the class I used as a "global" variable to be used as the capacity +// values of baskets once they're created. The logic is that every basket that is already +// in use by the time this value changes, will remain at the previous capacity-value, +// while new baskets will receive the updated capacity-value, which made sense to me. + public class BasketCapacity { public int basketCapacity; diff --git a/src/main/java/com/booleanuk/core/Inventory.java b/src/main/java/com/booleanuk/core/Inventory.java index 1b4252e10..fc7827aea 100644 --- a/src/main/java/com/booleanuk/core/Inventory.java +++ b/src/main/java/com/booleanuk/core/Inventory.java @@ -1,7 +1,5 @@ package com.booleanuk.core; - import com.booleanuk.core.Item.Item; - import java.util.HashMap; public class Inventory { diff --git a/src/main/java/com/booleanuk/core/Item/Bagel/Bagel.java b/src/main/java/com/booleanuk/core/Item/Bagel/Bagel.java index 57eb1df2f..3b57ec8bc 100644 --- a/src/main/java/com/booleanuk/core/Item/Bagel/Bagel.java +++ b/src/main/java/com/booleanuk/core/Item/Bagel/Bagel.java @@ -1,8 +1,6 @@ package com.booleanuk.core.Item.Bagel; - import com.booleanuk.core.Item.Filling.Filling; import com.booleanuk.core.Item.Item; - import java.util.ArrayList; import java.util.List; @@ -32,7 +30,6 @@ public double getPrice(){ return this.price; } - @Override public String getType(){ return this.type; } @@ -44,5 +41,4 @@ public List getFilling(){ public void addFilling(Filling filling){ this.filling.add(filling); } - } diff --git a/src/main/java/com/booleanuk/core/Item/Coffee/Coffee.java b/src/main/java/com/booleanuk/core/Item/Coffee/Coffee.java index 9a95b8349..b6035ac79 100644 --- a/src/main/java/com/booleanuk/core/Item/Coffee/Coffee.java +++ b/src/main/java/com/booleanuk/core/Item/Coffee/Coffee.java @@ -1,6 +1,4 @@ package com.booleanuk.core.Item.Coffee; - - import com.booleanuk.core.Item.Item; public class Coffee implements Item { diff --git a/src/main/java/com/booleanuk/core/Item/Filling/Filling.java b/src/main/java/com/booleanuk/core/Item/Filling/Filling.java index 77d98b5f2..93393039d 100644 --- a/src/main/java/com/booleanuk/core/Item/Filling/Filling.java +++ b/src/main/java/com/booleanuk/core/Item/Filling/Filling.java @@ -1,5 +1,4 @@ package com.booleanuk.core.Item.Filling; - import com.booleanuk.core.Item.Item; public class Filling implements Item { diff --git a/src/main/java/com/booleanuk/core/Person/Customer.java b/src/main/java/com/booleanuk/core/Person/Customer.java index 07fa28779..b93443dc4 100644 --- a/src/main/java/com/booleanuk/core/Person/Customer.java +++ b/src/main/java/com/booleanuk/core/Person/Customer.java @@ -1,5 +1,4 @@ package com.booleanuk.core.Person; - import com.booleanuk.core.Basket; public class Customer extends Member{ diff --git a/src/main/java/com/booleanuk/core/Person/Manager.java b/src/main/java/com/booleanuk/core/Person/Manager.java index 4b939f593..5cf53ee35 100644 --- a/src/main/java/com/booleanuk/core/Person/Manager.java +++ b/src/main/java/com/booleanuk/core/Person/Manager.java @@ -1,5 +1,4 @@ package com.booleanuk.core.Person; - import com.booleanuk.core.BasketCapacity; public class Manager extends Person{ diff --git a/src/main/java/com/booleanuk/core/Person/Member.java b/src/main/java/com/booleanuk/core/Person/Member.java index 7728258b4..d21efaa63 100644 --- a/src/main/java/com/booleanuk/core/Person/Member.java +++ b/src/main/java/com/booleanuk/core/Person/Member.java @@ -1,5 +1,4 @@ package com.booleanuk.core.Person; - import com.booleanuk.core.Basket; import com.booleanuk.core.Item.Bagel.Bagel; import com.booleanuk.core.Item.Filling.Filling; diff --git a/src/main/java/com/booleanuk/core/domain-model.md b/src/main/java/com/booleanuk/core/domain-model.md index 7201c2517..d93971d0b 100644 --- a/src/main/java/com/booleanuk/core/domain-model.md +++ b/src/main/java/com/booleanuk/core/domain-model.md @@ -1,36 +1,43 @@ -| Class | Method | Scenario | Output | -|-----------|--------------------------------------------|-------------------------------|----------------| -| Member | boolean addItemFromBasket(Item item) | If basket is full | false | -| Basket | boolean add(Item item) | If space in basket | true | -| | | | | -| Member | boolean removeItemFromBasket(Item item) | If item doesn't exist | false | -| Basket | boolean remove(Item item) | If item exists | true | -| | | | | -| Basket | boolean isFull() | If basket is full | true | -| | | If basket is not full | false | -| | | | | -| Manager | boolean changeBasketCapacity(int capacity) | If capacity is the same | false | -| | | If capacity is changed | true | -| | | | | -| Customer | double totalCostInBasket() | If no items in basket | 0 | -| Basket | double totalCost() | If items in basket | sum | -| | | | | -| Customer | double getPriceOfBagel(Bagel bagel) | If bagel doesn't exist | null | -| Bagel | double getPrice() | If bagel exists | price | -| | | | | -| Customer | boolean chooseFilling(Filling filling) | If filling doesn't exist | false | -| Bagel | boolean addFilling(Filling filling) | If filling exists | true | -| | | | | -| Customer | double getPriceOfFilling(Filling filling) | If filling doesn't exist | null | -| Filling | double getPrice() | If filling exists | price | -| | | | | -| Inventory | boolean doesItemExist(Item item) | If item doesn't exist | false | -| | | If item exists | true | -| | | | | -| Basket | //updated// double totalCost() | If no discounts are available | total | -| | | If discounts are available | total-discount | -| | | | | -| Basket | double findDiscount() | If discount is found | discount | -| | | If no discount is found | 0.0 | -| | | | | +| Class | Method | Scenario | Output | +|-----------|--------------------------------------------|----------------------------------|----------------| +| Member | boolean addItemFromBasket(Item item) | If basket is full | false | +| Basket | boolean add(Item item) | If space in basket | true | +| | | | | +| Member | boolean removeItemFromBasket(Item item) | If item doesn't exist | false | +| Basket | boolean remove(Item item) | If item exists | true | +| | | | | +| Basket | boolean isFull() | If basket is full | true | +| | | If basket is not full | false | +| | | | | +| Manager | boolean changeBasketCapacity(int capacity) | If capacity is the same | false | +| | | If capacity is changed | true | +| | | | | +| Customer | double totalCostInBasket() | If no items in basket | 0 | +| Basket | double totalCost() | If items in basket | sum | +| | | | | +| Customer | double getPriceOfBagel(Bagel bagel) | If bagel doesn't exist | null | +| Bagel | double getPrice() | If bagel exists | price | +| | | | | +| Customer | boolean chooseFilling(Filling filling) | If filling doesn't exist | false | +| Bagel | boolean addFilling(Filling filling) | If filling exists | true | +| | | | | +| Customer | double getPriceOfFilling(Filling filling) | If filling doesn't exist | null | +| Filling | double getPrice() | If filling exists | price | +| | | | | +| Inventory | boolean doesItemExist(Item item) | If item doesn't exist | false | +| | | If item exists | true | +| | | | | +| Basket | //updated// double totalCost() | If no discounts are available | total | +| | | If discounts are available | total-discount | +| | | | | +| Basket | double findDiscount() | If discount is found | discount | +| | | If no discount is found | 0.0 | +| | | | | +| Basket | void printReceipt() | no scenario affects return value | void | +| | | | | +| | | | | +| | | | | + +Some methods and classes in the code are not included here, as they weren't needed based on the +user stories. \ No newline at end of file diff --git a/src/test/java/com/booleanuk/core/BobsBagelTests.java b/src/test/java/com/booleanuk/core/BobsBagelTests.java index 8c79bd73e..ba1db53e4 100644 --- a/src/test/java/com/booleanuk/core/BobsBagelTests.java +++ b/src/test/java/com/booleanuk/core/BobsBagelTests.java @@ -282,110 +282,4 @@ public void testManager(){ Assertions.assertFalse(manager.changeBasketCapacity(basketCapacity, 12)); } - - @Test - public void testDiscount(){ - - HashMap mapOfItems = new HashMap<>(){{ - put(PLAIN.toString(), 15); - put(ONION.toString(), 20); - put(EVERYTHING.toString(), 20); - put(BACON.toString(), 20); - put(HAM.toString(), 20); - put(CHEESE.toString(), 20); - put(BLACK.toString(), 20); - put(WHITE.toString(), 20); - put(LATTE.toString(), 20); - }}; - - Inventory inventory = new Inventory(mapOfItems); - - BasketCapacity basketCapacity = new BasketCapacity(15); - Basket basket = new Basket(basketCapacity.getCapacity(), inventory); - Customer customer = new Customer("Ray", 10, basket, 19); - - Bagel bagelPlain = new Bagel(PLAIN); - Coffee coffeeBlack = new Coffee(BLACK); - Filling filling = new Filling(HAM); - - for (int i=0; i < 12; i++){ - customer.addItemToBasket(bagelPlain); - } - - double totalWithoutDiscount = bagelPlain.getPrice()*12; - double totalWithDiscount = customer.totalCost(); - - Basket basket2 = new Basket(5, inventory); - - Customer customer2 = new Customer("Bella", 11, basket2, 4); - - customer2.addItemToBasket(bagelPlain); - customer2.addItemToBasket(filling); - customer2.addItemToBasket(coffeeBlack); - - double totalWithoutDiscount2 = bagelPlain.getPrice() + filling.getPrice() + coffeeBlack.getPrice(); - double totalWithDiscount2 = customer2.totalCost(); - - Basket basket3 = new Basket(9, inventory); - Customer customer3 = new Customer("Sara", 24, basket3, 91); - - Bagel bagelOnion = new Bagel(ONION); - - for (int i=0;i<6;i++){ - customer3.addItemToBasket(bagelOnion); - } - customer3.addItemToBasket(bagelOnion); - - double totalWithoutDiscount3 = bagelOnion.getPrice()*7; - double totalWithDiscount3 = customer3.totalCost(); - - Assertions.assertNotEquals(totalWithDiscount, totalWithoutDiscount, 0.0); - Assertions.assertEquals(0.39*12, totalWithoutDiscount); - Assertions.assertEquals(Math.round(3.99), Math.round(totalWithDiscount)); - - Assertions.assertNotEquals(totalWithDiscount2, totalWithoutDiscount2); - Assertions.assertEquals(0.12+1.25, totalWithDiscount2); - - Assertions.assertNotEquals(totalWithDiscount3, totalWithoutDiscount3); - Assertions.assertEquals(2.49+bagelOnion.getPrice(), totalWithDiscount3); - } - - @Test - public void testReceipt(){ - HashMap mapOfItems = new HashMap<>(){{ - put(PLAIN.toString(), 15); - put(ONION.toString(), 20); - put(EVERYTHING.toString(), 20); - put(BACON.toString(), 20); - put(HAM.toString(), 20); - put(CHEESE.toString(), 20); - put(BLACK.toString(), 20); - put(WHITE.toString(), 20); - put(LATTE.toString(), 20); - }}; - - Inventory inventory = new Inventory(mapOfItems); - - BasketCapacity basketCapacity = new BasketCapacity(15); - Basket basket = new Basket(basketCapacity.getCapacity(), inventory); - Customer customer = new Customer("Ray", 10, basket, 19); - - Bagel bagel1 = new Bagel(ONION); - Bagel bagel2 = new Bagel(PLAIN); - Filling filling1 = new Filling(HAM); - Filling filling2 = new Filling(CHEESE); - Coffee coffee1 = new Coffee(BLACK); - Coffee coffee2 = new Coffee(WHITE); - - customer.addItemToBasket(bagel1); - customer.addItemToBasket(bagel2); - customer.addItemToBasket(filling1); - customer.addItemToBasket(filling2); - customer.addItemToBasket(coffee1); - customer.addItemToBasket(coffee2); - customer.addItemToBasket(coffee2); - customer.addItemToBasket(bagel1); - - customer.printReceiptFromBasket(); - } } diff --git a/src/test/java/com/booleanuk/extension/BobsBagelExtensionTest.java b/src/test/java/com/booleanuk/extension/BobsBagelExtensionTest.java new file mode 100644 index 000000000..81f933aef --- /dev/null +++ b/src/test/java/com/booleanuk/extension/BobsBagelExtensionTest.java @@ -0,0 +1,128 @@ +package com.booleanuk.extension; + +import com.booleanuk.core.Basket; +import com.booleanuk.core.BasketCapacity; +import com.booleanuk.core.Inventory; +import com.booleanuk.core.Item.Bagel.Bagel; +import com.booleanuk.core.Item.Coffee.Coffee; +import com.booleanuk.core.Item.Filling.Filling; +import com.booleanuk.core.Person.Customer; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.util.HashMap; + +import static com.booleanuk.core.Item.Bagel.BagelType.EVERYTHING; +import static com.booleanuk.core.Item.Bagel.BagelType.ONION; +import static com.booleanuk.core.Item.Bagel.BagelType.PLAIN; +import static com.booleanuk.core.Item.Coffee.CoffeeType.*; +import static com.booleanuk.core.Item.Coffee.CoffeeType.WHITE; +import static com.booleanuk.core.Item.Filling.FillingType.*; + +public class BobsBagelExtensionTest { + @Test + public void testDiscount(){ + + HashMap mapOfItems = new HashMap<>(){{ + put(PLAIN.toString(), 15); + put(ONION.toString(), 20); + put(EVERYTHING.toString(), 20); + put(BACON.toString(), 20); + put(HAM.toString(), 20); + put(CHEESE.toString(), 20); + put(BLACK.toString(), 20); + put(WHITE.toString(), 20); + put(LATTE.toString(), 20); + }}; + + Inventory inventory = new Inventory(mapOfItems); + + BasketCapacity basketCapacity = new BasketCapacity(15); + Basket basket = new Basket(basketCapacity.getCapacity(), inventory); + Customer customer = new Customer("Ray", 10, basket, 19); + + Bagel bagelPlain = new Bagel(PLAIN); + Coffee coffeeBlack = new Coffee(BLACK); + Filling filling = new Filling(HAM); + + for (int i=0; i < 12; i++){ + customer.addItemToBasket(bagelPlain); + } + + double totalWithoutDiscount = bagelPlain.getPrice()*12; + double totalWithDiscount = customer.totalCost(); + + Basket basket2 = new Basket(5, inventory); + + Customer customer2 = new Customer("Bella", 11, basket2, 4); + + customer2.addItemToBasket(bagelPlain); + customer2.addItemToBasket(filling); + customer2.addItemToBasket(coffeeBlack); + + double totalWithoutDiscount2 = bagelPlain.getPrice() + filling.getPrice() + coffeeBlack.getPrice(); + double totalWithDiscount2 = customer2.totalCost(); + + Basket basket3 = new Basket(9, inventory); + Customer customer3 = new Customer("Sara", 24, basket3, 91); + + Bagel bagelOnion = new Bagel(ONION); + + for (int i=0;i<6;i++){ + customer3.addItemToBasket(bagelOnion); + } + customer3.addItemToBasket(bagelOnion); + + double totalWithoutDiscount3 = bagelOnion.getPrice()*7; + double totalWithDiscount3 = customer3.totalCost(); + + Assertions.assertNotEquals(totalWithDiscount, totalWithoutDiscount, 0.0); + Assertions.assertEquals(0.39*12, totalWithoutDiscount); + Assertions.assertEquals(Math.round(3.99), Math.round(totalWithDiscount)); + + Assertions.assertNotEquals(totalWithDiscount2, totalWithoutDiscount2); + Assertions.assertEquals(0.12+1.25, totalWithDiscount2); + + Assertions.assertNotEquals(totalWithDiscount3, totalWithoutDiscount3); + Assertions.assertEquals(2.49+bagelOnion.getPrice(), totalWithDiscount3); + } + + @Test + public void testReceipt(){ + HashMap mapOfItems = new HashMap<>(){{ + put(PLAIN.toString(), 15); + put(ONION.toString(), 20); + put(EVERYTHING.toString(), 20); + put(BACON.toString(), 20); + put(HAM.toString(), 20); + put(CHEESE.toString(), 20); + put(BLACK.toString(), 20); + put(WHITE.toString(), 20); + put(LATTE.toString(), 20); + }}; + + Inventory inventory = new Inventory(mapOfItems); + + BasketCapacity basketCapacity = new BasketCapacity(15); + Basket basket = new Basket(basketCapacity.getCapacity(), inventory); + Customer customer = new Customer("Ray", 10, basket, 19); + + Bagel bagel1 = new Bagel(ONION); + Bagel bagel2 = new Bagel(PLAIN); + Filling filling1 = new Filling(HAM); + Filling filling2 = new Filling(CHEESE); + Coffee coffee1 = new Coffee(BLACK); + Coffee coffee2 = new Coffee(WHITE); + + customer.addItemToBasket(bagel1); + customer.addItemToBasket(bagel2); + customer.addItemToBasket(filling1); + customer.addItemToBasket(filling2); + customer.addItemToBasket(coffee1); + customer.addItemToBasket(coffee2); + customer.addItemToBasket(coffee2); + customer.addItemToBasket(bagel1); + + customer.printReceiptFromBasket(); + } +} From 6dd4fe6b72f643ee0635fff3d47950a6daef2f34 Mon Sep 17 00:00:00 2001 From: Magnus Hissingby Date: Tue, 12 Aug 2025 22:28:36 +0200 Subject: [PATCH 10/10] included updated class-diagram in core --- .../java/com/booleanuk/core/ClassDiagram.png | Bin 0 -> 81103 bytes src/main/java/com/booleanuk/core/class-diagram | 0 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/main/java/com/booleanuk/core/ClassDiagram.png delete mode 100644 src/main/java/com/booleanuk/core/class-diagram diff --git a/src/main/java/com/booleanuk/core/ClassDiagram.png b/src/main/java/com/booleanuk/core/ClassDiagram.png new file mode 100644 index 0000000000000000000000000000000000000000..1f009a157582038941be55acfbc8a46f38d2ba96 GIT binary patch literal 81103 zcmb@ubyQXT)&{ya-AH%1=@3M^K|oNXTS`j0q>+|JK$H@YR0##78#dhnBHazrAR&2w z8_zlK`=0On?)~TPF&qxJYp?aIIp;H<`OFoesw|I-MTrH0KyV)_$f`pi$eIuc(l7=Z z_=X@yCIb8gby1hU4=MUay#fA#Vkxa84S|%zVqch`f`4N=Dd@RCAf!x)KhTHjjC&Bs z^~Z;@(wd$|TQgps#2dccXO8v_Rx(y{3P|PjQVN`=#-Vb3@Gs*yOBP$s-}a}4_TApR zU3zh^vm};?yJU%|Gv;mT692d8r8ct{V!X63k^`ZkCdO?sklRo~j4aimVJ3WN$vLtwE9D;Z}sKkKevdZHu*sWjnQs^AZpYF@7ymZ5|bCul3Yy z)ZJ>a)E52{6%lSlj6y4Or_@)&uw@ihB(Bem}lauUd&oxF0mL5lk zs*th;K+C;x_)f@AXHDoDD@Q^!M%ZUradmY#7Wc^u;-cE7=|vA^Cgv1+S1?ErLpOy8 z8RVM|@RRVGqGHfCEy@{u8KK9Nvd;}1_TZ~`=Lr}!LJoy`BAvuuY=lDnjo&k3tttuj zO~pMTF&csQ=-qRu+Q_r|Ug)nZE6bS|9v;qIwN$0)`Wt5*%_&d4y{3*b@;g)gR|T*U z6W$&Wsp2^)zk+aOI@L6er83(zs||kD5s_*ucH19u)OY69Y2rH8+wi8CxzLpXCd>B%3S{H0LO*B$J2f;F7mH^ zz%AwV7d!7IU{84^bf5qE-;N7`mg;sP#{Ap>ULGZ@dE$o%Pm8xyVLZkoa$Gq0t2QIp`>w@^=&fFP?l^Q;HGp?Zpf zhfa|XwM_)&VuPLK;LQVLRf3^qQfCHD$t4UeUELl6_9>;~lU)TlQ-{~@e=kiK#~>a= z@Q;IJAuV^iIjE=Bb@88yczC!vyrpkT9a zevc5Gm}_Dni9nbsm<~V9>6YWv;Gn(zZ7ky*?wRZQGvKT(#}6w9BAS2fH>V9@zu;pPuL~9d@rfqHF1V|j%xq#7 z^D0{S-t)KB4{xqu#`b%Gk1UE!BF3-MoHB9GXkxu3v8MEh>*h|xp`M9NclSmLx%k|v zPMe)?3=NO&H8CoqY{Z@|nxFe*tjZl1dbTI<5i}aKfGre)6sV6ALjV&m6XS!3L1?{S zcWh^=`G@vMCw6%BGn%<^$)~L$nCUA6|6>)?S7MnN(pMb+zO};lNthG+;`dbOo-_ES zU_88gcjiv^7qyoK(9f2=gSbym_(|qO=H=@3rQGUbjMENV10YG9^S0;p)svYf7N3M` z-D;#;o8BKY2tScBnOyfcxS7>2CvZq)<=%$Q8DPz0?|M4bDTNvHI^}D(?i@glwNaju zOF41wuUTH?*^KNj5~3?C&@(3Gb~ z=QRS~M-gvvy3+f@`H-q$^B-ZTww8)cJxB#l`g=C&25MAavoB~?h|H@++-wePpPU^F zlUByUP-LI^{M_TipF_RBJ|EG%3efyTEM^D`&nSnFKZ-+ij6$GA?F;g zi(FLmjwpo~Qm36FGzjaXq`@C%^UCL~WrR5><}8ub2F0yJcQZO$_%M0!pky}uo=9l- zmgK-sSRH>1eiuDhn=Hi86<55kULNpvWKw2qZApZCJmyirx!s5JPxraQv&ki_SlLU7a)x51(HC{qH(w`4qI;7jdE+AV?* zo1*hQuVU%+blv!s#waMO?p~$i!O^Tys6GPuiAhS4r_7qbI#K>&5oj%oiM;Lk<)_fwWt0!(-P2a|(e1WEqPYH51I|e>`YA;aIMwyT z>&B2ybF}b;ETEkZ`MN1wN0OuYqLcy_y)VzMA6P>i_9ojQ>AgCG zxtCqxWFKT-?9rYreD*mB$33QM66m%OvZKMlQce_2 zxCi!KoXkoMdF%I~_J_peXsS<&Z?ipFH?DePLjqP%$VsMsw;1KDO#UTKZ@beJr=KkO6r#x? znWiC$L6IeeH#$L>v@J6ivdFCLP5VB&!$Thd@3z6Mpb;^uBbJJt7&I86d&0YrZm@xkdog+_NCD7! zr;m~1W18kH;ks$e3kn}2{qO8I=i(ZQ;cqEc;R6hyre1h^(uCB^0+%wI#0BdUBgEKi zAnJhGC2}EB@7~Wk*J-<<*GZhP4z^##Q&bWVywi`-s=m7ZRlnXfND5B0#$3(!GbJt1K#%Z<7V;q#C@ zO}-6z%{1+iI2tGhmD)Z(6klPVt>2P&&kmN8k)e&bI@__m|Jszg+JGR@rS65e(dE5~C2&CFec!&tDqao(J z_SEH+EMdT;GIH*&mFKo8gtlp@$pIKepAf+iUS_9bX6t#tEm*cmt^Y1q1U}4)Uz9>m zJ}wR_x#_Y*?4jW>R-@YW#1Sm>rRNf#RR`? zGWgE8;pgRMXro#-Rlf)dw0iQXgrJ1mp4kHQQc^R2@v!OSsfrgQ^|?8xLc(2MW%zYj zbA+SVMkp)9BKldNb{az~TWTzC{Go@IU034%1i!Kn6O`9f&d0R`nb(x=vZ}!k`FB1H z*aZ*Xe8_#&0kUMd5*_}%rVQsJGS9Ug8xR)uT41R9hiI`<;=(EqOj3fci`!zkw~rT} zUm~;HfTfAdGs|-~JX&DMeNh<2hC=!w{Io9j6LhKCSDyVZ_=3P%`&+xRG&1}K&1N2c zPZs5^4VQhJD?eY;8GeB?VOt%NkEgKYe0UPp~$el@=l!w~nL)$~PUkXe57jVlV&wWWuE;YbvJx)E zj-BTu*UsN0Kbc}d*!5lcT&YgSP0@j0H)?7dpn#RC$VRK~bNVm5wESJh_1^RC<>kM? zBglaSe=umu<~08k%tcod0H_W=+50X38(R9;f2x@x><4`K9*OnRg`f-^SpIjkF8+j^ zaizpzQ>ST5q&EJ%7d|KXzN_paTIz4u85;z8Qq9qiM2@9R{{LE8fV*u(_G+po)#m=d zKRl?vA$4nz4a)y7;I_jo?*`$8KZropO749{R^po##InZb#1T|M0RdiP@vR(Q->aon zM#L(V62)d=nR#`?uI%0uDT$+*zDKI{LBpF?EfF_v9{6_ZTp_*LG#B}pf^J$>Z7N@% zj+qmnm;VjVeor@=-XK5jBvk8a7eV#$Yj_Lth<~g_0gpF`ivLdWPOp{E_uC9m^)O+K z1fIoW0VBY>lfds_ukTTYyI>+PSRDtnzP<%o17a0PK9 z-8gf4wny-ci_w>cI>?X!klt-^;m?uHKI=psE-x^XJ8z`!@$OT~{?4UZT%FTT2LkvBJKCcZxc47oq~cxDIB8au++% zGd+>&3@~O4LU{4i1eU+M(DlORF(bA|Nw*3yPK{sGdmg3H9cr{mcRr*D^`f$xuf25x zb=$x?AboVB#GBD{UaUMD%x21jra(E<*-VTM22~s%Rz#Ac@7>P|0>I%*D#OCL=(MMR zF%;r@j{7BzX@M@?WeI^Ut;f_RvYXkk#}irf>2@SQ0O(0|^|6Zxq6xt=-*0BApuaK4 zp#>gIjp^%(?}4L6ht-Ac)`X2NU1X#zMe{uW(}0xQcr>%btW_M|glD^AD$SrNYun;q z-gc;-jub}DE>)6usfy`6I?JPT;T-5a4#9fX5pg<%nNeXquKny$mva2xXY3P+x7fps z03SQ>#oGDaj|QjJ;4jPF8I)n=+eqO5$=dV!bt>cH(RX;bq!8ddmMi<;?uYbqEi)+s ztlCT_AWG-G5ta32;LZNFm__0m)Jm5 zwr3?m>F%WL<0+Qk2I*lbkA?1o1e4%@T2-fQ@Xx4rF20lX(?^#)xXb&@9`NOs%p3cvx;E z12T+da;RElfO~8ptDIEs0Q>|mwTw7uAc_$wzhreu&~5YO*K z_BiuE90r+ye?@21nBt|?2G7|*ns=6Vt7}zw=>yyXG-8XcllKk$vv)FU4LiBN{Z<<` z$-Jx7(ob5Zs+)fM_9z>mi#TyOQd}>ltR+FN_3IS(VxOwP>V&-Ok>{TL-U=G-HAt72 zt)OI^I#D*@wj#T0p-fGvzcYcJ`Cv0zV7@Z_$s}(<5F^{CKk z%8SvmOq_wbxAwExbdWm2JC_@>Gb?;IHthJ+m_ zgKiV?f|SNBSkT+Ynee(Jc1G=`;+`{)AZy@+T;QG(=G&Wi>7 zXeOBH>;dFWHmc9HmmpydDs|yK?u7js{%=={y*SMA}3IGoG zd6q!b)IuDalQ$GCdJ}Lsw_WRA{4crq-*!wSjbU+%!k+%q{Q^(!w{*%X0I7lUY ztgDjRi3!v)!YQ*R-A2Ob5`O8DX<%?ZPT2EMQ9|x;K9AA-%T4~@q!|KdH5KiXq6yx3 z_k8;72YH@2TBrY;HwWg)%n5 z#Ts$sOi$%Lp;W znW9cJQqy$rX#gS)@Nvs+X8;%YbwpqM2)m{sP-6u5cxpS_iX9f_%z@PSbs}O7n`D{! zA^4HOxPYT;doNj(;b|W``rW5E>N?N)O z5D}&%Gn|GcKi(!B6;-ivn-%7tg2BL_ zdelS$fTSxb-;on*5ID@g>YXP7-2dmb zOWoJ7ELOuH75|)DEh=|@l}w~v z|7Wz_Ai;w}K%n`cLUewT)#;e;>Gcsgl2s}$0HC{4BH6S;o)cSOVZgmCZlJFEojiz& z@#sPF^a{!Gr}ICkjO-V_cat-{52ZoH(xmxAB9uK9(#XkbHG8TT8r(F#((IA$mQ&Ly z_DfW)zy^|?F+;Lx}_Mdu$v-Q;QL<5Q-NMAZv%Wdd+k5-=&DabKfiYZPftR=y6 z!1EyvdQxFyQfZ1(TAyPaw*-xejc0z|FPD)ztzG=NqpubNTc+!ImfX-`Dj+T6gV9M?hTUy%<;wL)Ppf&Q8==rY#(@vM4dZbf( z&Ark7xH$4VPxaGZCA=d9z+6Z@f6-XcXU`f9;M*>k>S*TeC(x7^I6vIi$45?XYs?hM z5TbIXTkm)l3vMD3{jkrPZky3GOk4`1wt_b zT~n=wolg0lpaUEY$5%OZ$~Ei+$q%S~7&Q^Yr*x22k4k(OZo?=Yd6#4X?f_l_={X@2 z@E6q48wZr9vjlY0cqW4quA5@0;PL(!54Ztav)KxTXq)#SraOh+Af%sTdP(gyDB-79 ztA~Q>Z*aD~0_maTU(S8xS;iM&Y_!L~{jlv<-g#~t?sTX7c|asH4bupvjp)&puPB7i zm4Y>YRCVY>&W!ETT76l)95gLt?SaHBD)`VNTuU21z(aZ-)zhgZHdhvCH(c-M(5&JI zG)pWqJ;cA9_WEIoeRj70_N^avzGexdVGEcXIM=6F&UEUgD8L1Roc?rDg1bn-O81>L zX$o&H=F2nn_}fb!I!K6Bl1YmBV0FmR^B1TIvCiRs0%}!}>xU@`BTfK#Ofeq_7IWp}2c!JH{-(`gLNpQ7($bjSz76H``+7 z(g&Q@dfX3GtM;(lI^);ODSyGyWL^u36)k(s7WcXY=ZXp))JctwQpP=2c9{Plhwbh?YzVO}@GF zv{Jtvv7cq_j|f7p)^L3NxiJEsB~PLI`by1NPQn}G`E7vnKxP|45<#o~L{|}g{~HA9 z>fE@Op#~Q*?$jBtW_=KS5o`R+!)T8*q9*M?@IG)sViG#dR3H7Otw#4t+9QQ=i;G!> z)jyhg%|)=tLdQL3((u0T@XWtPowgp^f4L-a5gV<{sSxM%;Zgg~iF+3Xf#kUXZ$v2% zG-NNz+hWO*SUrpHx3@H!r2%v(u-1iPh4#d|Kc6;3f3vMb{~1%IL(D6Gp)DEvT)(;U zSM}xu*C&)L2BnZ(90U77#7%Q`gq(BqT3_k9q$t`a#oREr^AdY30Oa(YV zY@ekzbrewMUPNoN{-Z((C?`*)-{&AgPkOsuoMj6$ZU06>mAtc`^E8ytitcQOpTz&` zO#7_@>Wg1HxHJr*fn{y+{FtEY94oBKMEc4@3N-FVA zM2W>Z)k41Z>xgyJyN6|&e7^JD8<%Nh^-6mLw@nxoj6RN(1!uCeLnuIRSZ=GyAtson z?xX4cV@w1Zh9cXpb_r>Jgh^`Mk4Jtj=Mp&+YDZydTYjbXl>?Wua;5w9yThRz;0TJO zWBt!!1lC=CZW-c64fkC(9J%BcY0w>%F$sMv?X-lmVS8SO{`M+o(s>{yczrc;2))?1 zLC>ZMV8rk|ETvQF({gIilUL3jpG(ToVh12bmTlE88iXBSrl2NQ{XO%@v2)08=P|MJ zZ>qo7Ye+TCehsy+YK8*mSm<@{YP+0nZD+Eo?0RWLnemrzc;zwW>HfovBd(>@>n9sh zw#CAd{>~}EyVUn2pUS`dU-*zEEmbAdX5aHFJYB!p$_W56h^{8?O_XH*y-YNX{`h`o z9H_pTjk*$SmYQ#I>Db@-1exz-@jV@dayPocMHlEiEuuvt@AYY%HX2cqyYT>iO$K{s zN~S+%fE1S99fLYTZdf$77kz1Tu_Bs&RYs+xg>X%u#f>gTXt`rflz49#t4Q;|;X6>_ z2cIFYv@qk)Y>?wPj3H3i2G;@Qz+=}F_=>y9 zv$VEN)d{hcK`FBh;!hv$%)y~XqEi&)Pc8PV5C zf&<=3m%y@6qFw}2MJqu_4I`Hl1Oq*d3@;DbmLdgLKJpy zN^J-I&$$|NRuPP<9+QH@C%~3B9_FK1@$iQVaXvPJaK` zJHPKaI6M>GNjnv;a@m|)@_gmVujAvz3gc_S^OFY4OCrR|XMb%EV#i4^5{YeBOoWMx zBNrCl8C`wo*gxqeLnv zePuOl$tda$DfMvh%#2LADKkmi+rEjvp9n{`LZZt@J+2)CEX*tHm2E}MyjA&ie z?q=~dWfU2=oV-5%BV{^i_2>6Siwt95y?VT9$Rf*H$$dZV?=l{s59r(^FW@Gv8=THr zGFJZ0!>inuQRG5@`%y5cSJysi?E%=ZDJxq@r{jp3rsg3`dCW>zP#@F}_-RBIXOIAO z?tE2*HUj||)e3EI)Iu`Sg(R&IL|>#t3x&IozK3^rr+yTgjc`&F-~rIi!>uR#{8a#8 zY3e$q;$fM?mI%&1Z~F(Rg3B8Rq6slRHLi)Q={CJSyV@$J<0cWF*MwAYf?_KDHzq`S z4D$cVH4flcBmr=M1Qa{EWc6Ck@8YLeQk;dYO*?TQrQK5<`m*%C6k=qw03HEIrg1m^ zfJFm}2sM~1q}cdi39z8R$0DWh@DqC>Ht; zB?yoUJox$3W@vgkI0&gM87ZLc!v{7GYOTSaBewgq=^oCnfPz(;tD8HFjR*729gVWgp02L8$b`>(#*&wM5UFRYoMM-K?mtFG7WcC7 zZ(*Q(@xL$oOBHCREO13Y&@jmiLw`dv(wi-shjNUK_wa2_@&g=_bA<5^GmmJxh#)^2IRe6w zZVf^l=NDoHU$a88J$H9Q8aJr{S2dl*E$L~jdv*XaHckbSp&w@S$yVe6mdU?C4Ri!q zf{;~H;%ZUxbY0$9)>e_%Z$INY#$)!k`0>un%i7u}n})fsv_6mGoLwg;lZ%xcJ(QJ` zUz+ilePCwRn&}S94*M^TiSO@x5Z5J#YFoS$31gIt?u10%Bf~% zFFGjWs|+OVtH%XZfbeet<=+;my+kV|+VS-PrBF~?{M`*>PjR*T7Po&t3z@1k%zx{R z;8S|vlyKJeKKvrbt6RfeL7PqU!>nrakuoP|d$$;YLo1=*`e*aPuP*otzw>VLF?fB2rceUVU`>}^iXubeV1 zb6Y1NuCA*fb1p|fi*Bfn1ueXA9MSy)&sy|b)py^B+S{%y+2(Y96=P3W1KM{AR5pU%{Fz6RTIa$Fx(S*Z;s6p~;1S?6^|(=9L!vz=+NWo}NX zpRXts6chqDh}Y_w0184j3bVn;>S}PwrPSdvZhfm_Um>7W-CgU;(Nm0=wWnPxv$?tX zlTD812UE(38OL2g;N z_krLKAw3n+Z<0TtWeZka){Zxp@%6WZ`vNI zm7FR#FnJ-h6emjgPXr`CIR~ca^lRP3XPJRc{;?gWxgM}XHyu+}gV`x6iBi2H*?{yd z6k@I?Hul-_R`&MIC1&V6FSJQX?{Jk05UGV5)_US46&uJZx)7cPp$$yb%Lvqryu zxiawZU}g(lw0eiV6(v9{xct@rlKg_Jh}u^tR6LqV+_2U_rPL}wX`0;sEf&W9A8q8n z^`0K58Aj&VDvsO+TD4eQ%K4U##{8pgEp$q}`=5L< zZZc8jL4~NPsVOKcQ>gLC5$$#yVfFR%`;Sl6ZnKex2F~p6l+H$nhXaM+-th47%e*|R zO;gIOqfJ2wPJkQ6eQZ6@kaX9|Hq?HMS|OsTuFa6MbK8==t*UvgzE_$>5J4R`$%gX#*d(j5Zzi=3WWVmPS$}@QnG-hXp1nbeqKWyMS7>XK+AUCRiw}(=i$?#MJ8R~ zOZ-mi1l9EQUmjNq{1}~W2X`2)BP1ZeF4$W^|54rB-Q8|RC17&hc%o|PJ2m-O z)=bmbIIPP5niNGE?lL9$>LLVnv~G}5quPpRRI-xb{J8OD!};;ks~{iRwFk1lZcU4Z z5;V=>lgZ~Y%Oc_{2td>lzn}#L?1lY6e~_feJwK1WYlaw6gZCX2lMhL9ADt2s5~3~B zX98>MJkSk;fd@k~lO}m^;U_um0Cqb2!^i$MBK?du;LO$ZyoSN37zRfsA}-HoWn2`A z(x)1c_4FpdsEA+3#|JSfMgfffMM+lnM;NLWxf(LGT31ym?*~xxm~Ormayt-m&??D; zQAV2q?6h4q*Yb+Odc1rCQ&#@4?}Nrfhf;fW>&ACkS$vQJyh1^ORvQ3TVhFgly;Gto zr=LG~l&={mp-pqKOP#UVg%u>9$G$94T)-4Wxh16mcmUfTE;%1I++1claa&jzwOzk* zp>02>+U;`>7&mEuztVWqu6THMxMjxqE#Tb0cx17CDJy%KltB;k#vs)+VZ4O_?*>X< zMwZ-c&t4*-=cn{L)A_(>t7Q}vJldK&p+$Jxqn{O{&mti_JSBVH4WsR{vfzBw=N0s9 zR*u_syy7Ev^g=?H^rUlh1D9ood(`|QR8C53TV3po6Lf5>cn51Mw;rBfiC_b&>hM3S zM5=lFb$WUrE|uWYU^8;s_xpTO54#^uH~L}^*v|!mpu}pQ(3V$DD0jFUp*#8WK>nEU z;3yIfZE0sAr>$`U#7{H~eW~cE$72&XbPgZ;{gP77#g=Fqs7($J2UEk(7(kEK=xgaY zJEEH3*lwRF%Pmxr)p!5`I0BZYM$vVq3F`rSg#^%J47$zy`)5kSo_)&XljUC6HoLQO z6C)g>%-Iijz2$@-DZhtns7OYEv>WWDpK>k{lvW1pffU$-;3Df$Ibt+(y^c>x?W_$x zm|9v1;G&10w|Lh zg}u7A)D;IcDKfpA=4HF~kbhx42#=?I1{!J1<#EyXu=o38YX47$-+ev8*l4R86rF`PR% zJ{Z7~;T?KTLCK#qg&WPH3fdd+5mVU|Xk)|PBRy8yJ>5{HO0kC{v_vBad6IZgZprN{25ZfZnJ%R62sD{F@i;59B_ zkIg=@V#U%i!Mq_^4KInZTbsA1wDP{x$MmOGJxOJKHS$Aq=|^|Yc`B_zBptbwbSij?>6nR>5iXr|#JwLrc zHW==!v(-j{XQAF8hBuE+2Uh!bKHGg!hcNDtC{q1YG>YBng~j6vc~%$2M=?17*i5DS znCj+yT)G{9S;29#c`jZ(+GZBk6`w#qpE{NOC8{&{+!C=O|Lz$H+ZV-|2+UOi`Xvy? z#(H|4HnkHfBCJ{(jz(?Qx3`CaS6*5E zv^Dh3C^Mj$N}=E=nvkQ(=Y0zQjeQW893KpV5;(jaS{omu@)}-{0dKK}e-GgC+bxcJ zCijQ=!jS|!HA}pYp169rE%dCY19w!-TIY?LkRVu6bLuQajdznJOa#x(x1xairn_y@ z%2;p6O*iP9*~2K`0?MuWi92e0dn^OHjn9C<18{GKR>ZvpJ=G)gnFYA;Y{$ey5wWeR zYHac`A3M0SGZ;59nPkj(wa}ltze3zy{ zvV?du__=9_HKD+2*LX4mgW$%HF(y#<1NHX2wx^9BEIU(vSG=1v)MRgxN8`sL(+$)0 z?Y$^spp}sawnC@P=i>$!LLl~nn37Wp+O|Lu@5{S8O9|0jcJDa!ckd}krvxWOQp=DU z8*{oZ@P76*pd*lr3EL&;)~?4J`B7;#L9dN$$u$nS2b~ zO){wIoVE)~f)d=p8>Wk;u<6tNZ>$KF0-)pelG?d0mP1$(5?a#!yO!$9OcAGR_;n>N zaY0SKJt1`4uUf9pO$4v(8i+!yVWSq^x*7bg&JSeywDzcclJDXmBViY?^=`PDZr2`x zEQwV_WD+=H{E_e9UjfwJ`ICQBRkgYcEYdTePd|-{R>nYb`dJw{#)alo{U`(q7&57P z{dMlzBL0nVcMMOMO0%d1yDLrd4yoE`p7aPr2^}Qb@tU?k4*VnsNP-ysUg8r`XQiAy z>r;>cfHO^`dnw<_Q)F^#zZpQTiBb|o$|yh-9fe&%d3E7I3uOO5x`t?+0g9Q^v!7Xi zNnyY$OAkY5?gEMB{eP5!Fm&nC!>xL54tWs!y*}gDvE$X&LS6^ez<6Ho>^S)BHJ`KU z>V{9(cmexxE(2BY>$2A9SJp5aQMbP-i=o^kY`UWQK^mmJE_R)3|Q8fBfX?nTL-oBZ-(qHdQYEF6T{QH61xrlqK3%&%!vcGjz+KF*T~0E z-v?l`@7-Gq+a0Ot#^XJ2ocimlsbo<>e6Pb*{Ztm5s$%gDhOx~fQ;@xaWuQIglXRGi zI6S(fHL(2-RKxczm@rOPEB70&sOFlEF)aS$5T7eB8tk<+63E;_`C?c_o2&d@N<$+D zK&Z5W0t8SofA)>i9l`(0X5HA)m|MDlc+lgF^ruF@PR7+xki=F49*3IDzXaGM?F|B+ zg2OB;OB{-bTcE3efQ5yHY=eTLex3VB6rA|*=&06%6%K$Iz(t=^I;cM*pBI^cA$cFeemW5z?TkljUgjCxz!7+DtvsJF*wQbwR zWl@h81u zl#8Wfq5tCvCk^7erV|Gw3XdLD@_W#O;E0nj1sGQGy1C}E0Y8lW;osQny1_0ET3Sp9 zpp3{i5Cw--wT0vNLiJy{aoe!ZV+{Y&3UT32Vls%ap)xTsnSrhObN)YtgG@}wd-;}t z13PV%DWZMtKFC3m=O41MS^>Z+D=)v)_m0q(Na?wfQuK{`18@(JGXP2;T2&W8Kc)YDI2o8+g+;tE-BOfR$HCwIz1XCCVH1P+C}U9qU!5Wb;}VR$7Dx8OgzsDh*Zr} zh`8rDQfpM0vtI~-Mm0|pB90X`yQYIa!c914yX|hKLcF=+{ix z=N36d5WBdH8?EfKA1>}KoB)^>1irjExqPU5MTJ_P{?=Ckjbst810g=GijT>N0?wcbNFaq)VriKH9n4?r|o z?nzLr*4KCmSc*M)Lac~?$&yk}?$O3d%M!C8$|qZWmoxf~roBu01Vlt;|C+L*gT6k; z?A4{d=jz0^!sExK0{9VA9*c&>tew9PllFcMtH78AMkmFxs(o3$$x_QyfKWG#4cd{M za^yNUMA;D)`kQty@3I*FGA2(=gW z3=-%s=z0@SynVEoprj0R777{6nKxyOGYDkPYcv|Py?|PaCXFiN{4W|3(23}z0H;bq z^2~|Xh(=%J(KP#8vr{iY!QB?)vJJIQDk^YLhHyS;bG9W48UGkX<^&+Q-T2q`W7Ei% zDKde&y@qWEACtodl{1oe_hK{)PLHLzzm4VzdFXTkMU#;6XX&^AR`kJDo;@2EzrYS`Yg7$~hE6$#j!-V_afNTmk^(xvY$DA(bs z-8!Rt2@d8^4oDUlfZko`V6`8d2snWMzyrcS2F!Y=Av^>do5$BX2)OO(t4(OV8&kmL z*e(f6tqHssdPf`$^k7JoDl`utlJL20VpzSrqK1Gj&BYZGybrS2>+9zgQ)lGbK#~eN ztwChW0ev6}A8i^GC1>tBg070^AQJ;k74i)GTP}1h?|<58>daLN#Pv^3K5<^3hko(5 zW5B{91AyPD@D*Lz5>Cf?xHr3ZLy2x4q{hov z*j^6_xkmB_ah`&T{o$MbScgqB6fa~nAiW${%bYhY3d*NT36&y}E+(9r!WlswOUUpV+~Z z-2c|+OPz&96l&tsLl>>!?TxnjtzQOHzi@|jS z#>vZL1?$!}DZ8}3KGbUEVAJxcUmrm-$r5KF0y%Q4!~|>z`HoRNv4`!>JXmI1qUe_g zwibEC#jOP+w)BzHZh&fwiJs`*nbd;pa2zj z0wU)IoXA43*|YQ60DT3BL}@?+*%INt1XRE49t1%?In0XPgdjCZ1nM9={}7?4}^T>sueo+*C3^q3UrF3DZv z0NOxv=>Q%6TbsmRbHxI-WHBc&VSLD*o27J{t6l$U5`e&ghH?oMi-C6T#FF2g3iJ3{KLe&jmvY;OI{+W^sW^x8>;Y0^n$kpYi zArUu+G+eMsPLC`W^S@ASa3m|z7lRtgiVFU`qDBjQ7(}p0Co?;nno5u)Ha{8W{hHg( zec{E_%xTMNbH*>wJNzfv2zQ5+V#M=Xg=+`YGlCXUWJ!?)c~FD}O*`MlY=DlHV3$;N zrf7+5?E<{2Vxf5M@R&?PhT_ztNr()gO9U+f7YmQj8;{DVA~7zO2y}5 z2WFu9htI8v=>B8ierL=dZe_D%#Pt|>6eUJI0r}i-X~LLu@QfY|uo2Fyk1+-8xgNN> zmILOh@7NfB9tiQanrOcY9KDr=&iKvWe;-;^grYiRN6HTYqI+*7wDLyj(!Y|N`fAOZ z6Z+V@d%KZqv*!yy$R#Bucvt)pyssKPgW8&LGl`sup6Nk=BEjGa|GbxHRYdqF6ktIF z;27eVTdpnkS*Je|&nqc`hT+k|0Y?(|`ZeJ8DFM{sqpre>C)XwF71o-!s*CHs{>D`|0*0UCh(+hxS+; zy`8R#Le~yRmUCx0Dj(GPLH4Haqw<=f`s{usoAa5A65U=BHGBigZ5Z1$)RdU$j`dgU z{|10Y0&ydCyY(UK$>es^r_~i~+2s`#i!bqyP4$Kz^`*bHw`cx&QrJqXS^kxkemKn& zYCO?5U<0cSWBEuP^uDI}@=Qyt$`^gwq3VWjngmo0L{&p0dZ}}+^LShI?j4C)?xk)i*nH6QmMt=Zm(&B@dxzpoK|AFOJVp&_v&HGwPEjU!w z32QX2@o2;XCd$@cy|_uJ;=)i#)KGeibs>6*&KrxUw!`rrAf7&sitT*!QSOg(AwX0L zP!<-@e-lPmC43&8|2fiYWt9g?z+|UOw-ksPx}kP?W^df ze)@pDHjtImKm*RaKEm&ZKZw4;ejqI~uS-iaU}R!h`jMY+sA49&^tKSTSu}>kKQnTdD4Ie zvd4fi(fR2j4JrF=Lu&Eo7^wmz3=WfgH~w@e8G&Ka4&<}$xjYj=gwJl`l(VtP$skan zeY*6?^uvb_PY|g>cn2zYM+*{!69h}(zFC{JpV_Cl*4EWIFLyz|=$2rWJ?jUFK1d9s zsSqw&AOTSH1*wmdaV+>Hr ziz54`pV~4zloPh#TJ!afpO25vU|*OTs4kJPwQJY=!`*Z#QJ#+l9qHWzkcaAb{u_{e zT0J5ZYg`!MKg1P+CJ%R%;h)zZucA)8JMY!GMiwSl^npr zCi5`#Pm00Zk4}DVXaMFDp4eH1B(VA<>t> z2UOO=u{ctW`O`ZjKmh{Ys-Qai!9*_Yc8k@p=?^y z=d67F&H}w>B_5w106i+SCIXh?4PL2(c621q;+sdlw&n#hzu_@h|Bpo21BP8tiiW$Z zgZ3qAH^=tm>dxe8Yj)8@Dj6|&xj}39?#9p1&P^cdDy^`V-CB2a^uV7KokZ}iK~~Co zr3@$1|0$J!pQhk}8L_(Rl1YBo#V!Eh!sNl1fHN*+|C7Mq(v+NeKnI^zIP{bp4w|(< zBhiNrED++H6p%j2WA1%MtMx?#t*)T=pNGS!E$PH_UvSExdbkKkYT8nhkUeeEgKVQI zK}b0*?xo4w=DW+F4F^}1h-tLMgkUL8YnOnoS-Ny`gL)j!JZ+0dr`8d4qFBU0P72=X zu)asG5KS_;!GG7bHoR6D`3=TnkJQb{@3!;m??LE`;MPzvI*Mol2#dr_U#U~%qdGC_0s!|hF!3QQkID|yW8Ij^)ZhV?)ha@6M4tQ0!&$LHt%*O z=xT$3z5xWd_F2wKsT+Y$|R4C_&*3}%U=nCVFJPU5?$;m+Lwj- zARD<*J=JYaz{1oj(@?pXTZuS*P?y^`0P=ThtDi$dEBt%EkPiKHD0jH?D!(P{f8#$y zZvd?@7b(Kt$3QXt!6E*|{d3Ce+R>?S&YFms7{MTSK){@V9i=Er2X3A?ziQ30~av&!h$5;*>>jTC2_H zb=EFT)IjstA|EEOYS5R@J54yW+;Q_Nu}F@ZoP~^-|A(=+4y$T?;=Vyd1SKUz2?+&B z=>{c5T0lTLr9(lwl#-GVNlB$cKsuFFS`?5D=?DATM4tU^#(!2jG!(JlcS5p_lN7cZ59s1Mzhstw zOP!(#BJXxUTOCvUU#XKS1|jB7$5oM+oiD=w$YjFAQJ;53f$~w~G-$iuvMY;d5J=kU}2mHz{< zl-wC4De<@f>D_N;A-7{e?HxIV$c=K9Zvu@(wU}1RtXnCJVKU>Y#}d6__kh*-xEvAO z*?V0PioN=JpauqW0guj30V5fFGehfC9}BrlCM`kbJ*hNwN{!zxVHYIM`iht>Nos;* zu@0j@4vtLexu;RbhKY^A860>RKmWTojOBR>bt-{b(S{d9;g13c^U_@$dRJvg)6U z$Myb>F*GVudDYSlBGFDg4V1fP!L^&Ymmy+oPq?NBEu5ga+UXWW2l9owkfxt5msG)> z71LG)HmOWdSzrN(6R8r;O=3g@Re#dT&v~$M zO1GNxF=brAc*8l#+UJLT`nU`ry!;V+lJ#qGgnIln9%#CUI1j>(@R_tAB9IS*`vV#h zA_49knSRD>I*FXnYLeHGMe1L#5pI|0c00Gt&iUxL-XpsnbBc$37%|F{AQM$>}281)!2A6#Q%Dnow8a{GftHo zqmt{O!6pYwSnJyA4^$VV39~?(Q-OZ-hZPGHjSdcP6<_>+c17>(l8Qh)qs}FB1_jPB z;KFZ0xaDPXenG~tER=+p@5(9QW0a5P8g^J>dSC<0M?_GcIO(zet$!J4rc6J*2P@(v zD%Chd_!5cXFg#=U? z@N?GRjOe&IQm7}>6kf1OH0nXFS(xC@PcdR=RgIk>U zgBeCehvct@U>obDE)TkaE^>6NDSGA!HXtM3xJ(Gx%jFWlY0d4IJ#gP-*vr|_Bw~urX zl+pPqousSyc&9gO-)>Dez4-%UN?zq-J73Sy?na&Z?5CGD2XYpP{>+d4)#^<4kUd%6 z-JXFonom@EGWo$k_;3_(7`9}~m=NOA^<%;UlWo|h^)2Bs9j56VclR<+*elyr!=cMJ z;IQ1TK&;gBcgSERpLQ9?rk?CN5DRxy^k%8i1*vqFz>W7X*|jw6hwwY43- zYTP3NO1|_cAl(FRg1Ah9H!S(zI{2lWv&q?VEiJ?XYlTfX!=^o;2R`XGmU&Kj+xFbR z3mO`exkvgyYdf8B0M2x{U-y_R(QSjYv9U4Ol_lc0i(PLmvj&(+3{BWHiUgbkwP>YY;~04lZLm<6mG|gen3H(r<(Ogb@7tpl8Bu zV@WIKUM(U^a&llR4%R>UguUW^m5%d27Wr2#E%jXXD#d2LI zb6VLCanQ;BR^Esl!#k zf>J?r3c^)TU{%Zw+7J231yCLA#bO9AsqI+Br$E_CnxxKekI!}~3Dn~=WTf$rj1G(o zci-sI|5CmSZUu>XWc%2NOf`eReQ4(6&Ic0`XeB`O_vhmMk0yEV{*vBMy7^Xwd_&MT zjr?8+>_<@S1IX{4jC<2q`S&tsT|lc2?;;6r2Fi`K*~M2-*jfL~j(%))m`3SI`zyUE zIAmvG(Gw$&u*OyIxotMTj1(63|Qgm&^NV|TV|N1z0@k=C=w8EZsh(Tc(3G5kXcWmwL9aUmMdS16Sm)8; zv7LIH6H2#Xw8M3i2hq_Rh?Sl%W2y&*_s8oZ!ZpL*^!_MirxLRJkOI(-7AY!rn1r61 z1_~pPHveXEGC3ex8BHsG;ac(cAI*t!Oh#OX-TPHRQ-J^GEO-oFjXVRx(qMokaZk5` z{#^f~?50{51dm?kda!_?4B@XibKe!)?YJBlj?tjho>0ZMY`u5lZU9x%RD6zbhZ7CN zB~`|#v@HREKDmYGRm^qiQsvfuVi26ufvFkh^@*6gh<4n7&ILSJHvp+2?UUDy%IoQ z1T~YNQ?%DFOylm(=3QC<0JJL9lpR^soJnkroKV6Bcg}O?5H5>`@s^`5I*N>dZvvE{P7g`mFCc?bjrx|9h1;LqlLd~0pb*yeQ=Rs_mhdgPfX`kI* z=lJYTAk%;fO74D;n0#E;Dh>Z8GF5hglz|#mv3h4{I)~N z5FV&E^8~fkEy&FmuK9p^v3_3Q(!`-^PwZ8)j9;*?@MwLH}2bRYsKaE+YqfPbfXh zKY2IOJJ*R>n0#oZrxJ&T4aXbFiBLNR*#%+O2p0`_Cx~yJ zo3bzSiYhir$mu~aO&h>-qV>?S?=H5)S2xITI#9-Y<2~ z;!uHb4G8J5OElx4ID|cYKuQ2y?c|iUoA1ORs0Q-G$hH=c6SeaDCse(U1!r5bWl3>9 zl2Hk$yh(*Og*O3y+&z;|aBWl^Iv;+RklX00V&py5<*FN|EGMn6U1a!d&@qcdf?ZuZ zg(jiFkk0U9A=h|D-8sUQRCl3_>-*Ip`m7${^0th~qeU-p0`Bi=UtNbGF{|fpJ_+A5 z6YruNS&2sl-T>HE!oi1Z&|_`Y^&rK)Ds)CGjaU;~O80Ch_5*ttVLEKO zQ^vX2e{m!&@5|gSD9b(vk?Ocn$?hdh4$bB_{MgZ#w~l7H@8H9d{S@&NBLM3n{*io> z@1W}uDzImZ2qa{m6X11wm$Ag_ZapcTxt_VmdE-&s!0}$9koJ;p7gXcXZX`ul)8dQp zO}Di3ZaRa9-{0q^xhG!MRnJ+rTiK6|G_;-Yx8A>8-jUZBukAMnv1jjDkO%QZa@GKa zOlYb(DbI0oeitjQ@&^WSav=S9FC&?H7}S?ryihsX_O#AJXLnl4P(2_6!I6Zj#5Lu8 z*ni734hYw49eB0VCOg_ZjOgy{6g$Xo2GyLQkMKgzBA`WuY=B@ z>$|>cTyGz~1WNT@GJb+L#n!>$Oa$eF)l8>{iBCkdjOC3N*W-PchHIA*ZhxZ{QC+Pb zG2N{=ee0HHYqXDSGmD1fF1WN<^)p)2waWr)Y^Mef-5K-xp@9U_QoCq3_2ahcvofB$ zxTApvlxHgsm&rZH{A+kLZEAYM&3DRRk^uhuwRCwWxj&mWZpg5lP-(6Ub)}~B(7mgS zet5BpUaxy!IlLo0A$*DF+S5PhyGL+psM@~&b|sA=ZgtrS3KI(TUVYn-i-Zfx2HOps zAte@6GU&elq>7y1erj}6D2#ffuI@yAicuG`A7V5jfqK@|t8A5HQVBkBtSohP6@6lK zpUB-E1x32Nj&5S1?NXYwSby5gVH(1m4WU72rzl+de}O`L<1GK-*<{)Y$(&-re0Go^`R7| zL@z^wq(839Fl-}A-G!Sv5oc9-MBHk!y&OmYU>HCE zK42~Fl@fv%f!qX)8u)!eOJBVar5^1ia(}uW!f}#C&K;FaBjPsp_8+bTk0!8V>WWtB z6>SUq5+2?iHMO3K!>KuL!~mL;XZdIEV0=OHJ9)9Pv5W7H=Hl=DTz;U{DiZ zAY;cwGo|)g{5fS#GqdE9+g6MIntT9Z$EQmU5D1p5@RSp{f7#p)m%t(HQpKAk02p!I z-V2_2fCWPJL)0NYw1bZw>MnX>rNhV7@{2<+A+g{KNC9fT!364yS~gqmn2c~+Htx{f zcflSuCqEc|x$Ta6URcsRc-PT`=&);IUDMq2mL1GtfTL8KpB;gp_t5bz=z(I0JF}ga zs^PDR4@{o-mv4X=yN+zAf;_L_YpmU5vhGG1oN(T6uH2%Vycpy9nxQ*s^Veb7F8jWi zUH-0)4KlaET=-{+q*eER?{y)UIyTa%J~Oa>iX-U=PdXnJ-CVkae~vG}QKWnftxR{# z*?l>c5|+49zm^-AfM=G^L4LrLA35@;3GY+}-)%qqSbw-|i>}L>=*5=nfU%O-FoILO ziu6n$;qWAO)NLQVU15B(-#5NEvz%iRbvQDsMSnZWHhb{kI1Z;6g>ryo(ZdgpbePNJ zk%whIt>>T1ViTLE?V@)MDdvI%o4D=oH;J1e29>Mzw)S>StJH~3M{u&RN-DE z#!3m{dw9$y|K_ErJ}^1G9&8!|A#@6(rDMwGpPahdER~dhcT8QC!~}L88UzKkrTs%9 zcS+6PPsMwfk$$`MY?$`Z>)FTg-jqpO6K$GW1CByKGf#6Bl6|p05Zc#oZk`(e0pZc~ zm+`6QYdN?bYHJhdG$MWrCykr235O>L6miU*K5vZkLxTwG>)p?|)s&Cc^3`4imK0+k zU^0C;C4C)9oyFT6oKX-g#0I&~RHA?m)b(x9IcVL=Z{C9H!o;1D<1627BchoMB+`R% ztuvu;GeVLL&m*Lk5oSPlM>nwo?(f{EZb-@;u&njrEaK0gs+EbIBznR{MX37^wie$( zvPtxX7mrNG)Q1mWoh(~yJ@Z0U=@stWQpNziz(30_zp{Fob?#`07{Pk*on04pKctRZ z<)MjB5CpIPOg48i;am{CNC~nh18xDfRk{17(7mwMLTu5nxLmAJifAr(Nyt94jR77uNw(~IX@v)n0jAFu!N%#Z)jCdxGkIh^QSu#96>Bf>O zWw}P3iu#)M_^Vo-IkfP{xvY*Ah3u=zmGH2(b`Ar#fWGL-_wR(iddxxA^GEdiORxiF zd$A~nH~@JZrDF_2!U3?)WaTNTFopq`e!N7e2(t;O9WY)1IfJ}s9=G}Fs`OB*!Os%? z*r5W=l~DyLd;ts&;BJ8Iy#4$F!W!@h^r0!^gs_=OK2mYSIytMQ9_o}w3w9*pN(f4l z50e^NY~fAyAEclKo`nDqa!DjGq(Je8m?$(esd4i`77Ir(vY$7DA5nLXp|6b zO89y})?*-!h@%3s6@t}swT-5mY^-0*cOu7J-YzcGY|gu$I^*&1^K%+NAikD?%`gT1 z4hT8-PB2ndf$ER$&}`G!GuVtA9X8hhnf6C+0!VA)B^Yq?Lk1OSiQ(hi9IQO1J7v8d z;I!yvU3W}L@q1J_wnpPDX=K<{92SmJrNjxdpm+=D6-a5oNvnIABRVNxX?@06r0Bxc zgKzwF&zJ+5Ih~Qf4#lc z01lpdJp~-IL%cV{E>bx#hp2v8ly^E(cKObCgW%X`qs!&_WgmF0gs<=Ls#+a+ z%K4)vnal4F0j$*{@N^Q^_iN9f_Hb*G2NRlzs^6|c5xYi5DRkzgNv=jQbOwXg4Fq-n zgctx&sf3XyfpuxWCFj-c0QR7~J{>4!f8#ljxZp?fll-5C@+hD1nvsO}rEz3l6!zG2 zg}t>rG#$4^uM-Yx0AeSLm}u&edNy=2-GwgsYh*YWzp}ik(tfaJw!CD&RkMHW4yMGt zaa`#5M}FdD5$o#T`wZn|k`l1;h@kn0ns>VE;*rJ@(nb_O-v}?k&*;TWdY(}O00;OZ zCgeB%4VWT-KIkb(dF?8+)^?HkM(`s?3}Ob5RFGicu83K$2trd>5vb{u0^AngVh}M` z0$?kXZ~atl5#J|h(WkyB1@hzG`6peoC16*mMd8_iLOKjhfaxofbvCw>FhZ)YN+=94 zr_{=#1~2riDiutsfv#=VU35}0Jot1|eCrCLRWBRDE`a(o?A@1tdXr>Ix%K~~V;9Ds zoIyFkTW9D&$}vG4|Em>0@#|sT1Hs$C>ju+Df7^A-y}v7b9Z*ZR+F(wM_m4*_y1LZV zr%pe&*-<_^gOkYnw^nJS!dR^!xhmsw5SH4vxXXyv+S2b_4BnTCyK1pOo+&tKeb(vcikCnw?e7%DG)TJvy2=ET8cz|VitlitK|T(`q?s{^ zh?816cdhc#&JiNa{A0nRLHOG^{kWlb$O7?PkpmEP`kE0$q)9*x_rmOIcII+-VGa|x zC-%P~&-4~wl%U}S8afYF?x0kCI%PWdIh@dab&CJ0N|pVkxNIwQ#Ady8a~vAH>TJTK2-`2CKo0iL zc~afv2?poQh5fBQ?E1@2JK`6l#gC^j%=|QNpn7f0k$TzQp1C7^3MjH#*`{P}s@u;+xdQz08; z!uBTKY3Lk0k+Gp9r%EFY&O0kqn@-n}*=#95VQ2>hLt0r`3nI>epAS&Qx^aQLYgTdu5bVjy+MkDR$P=|Y7^L&iR>{FuSU9)xdk_XEDHuWyHnu+@BVwOo z2L^cU9USgMECoMG7Y*QTwOB|_-|}jiDnyjM@XHvmmwuCz=_$p<4S%lYJX{UoWghHT zPT*lP@FT8>a*UyGNn`w`WhDv)ZZ0V|Ag@Dt41%=p*J3Hh z7&+cZ9UVF$^G=}rvttyF2G0H+w}|4e&}}#nv10mhU&iQy*I>JfLaXY;Vx zS{o2s4`mJ%sQ2z_K`%m>cygg8Qk#G(VYR1N6VwYKMOg(?7N76hX1H4p8RQlboOXMp z`NCm6X6^8wmY>CQ4^zy#tRih?dAS5OTMupVKSRDogobL}3xlPaUX{8wz5kn73vH@b zFzeMuH&d%WG6|kBU*WnEbW>&Q3NSqbW^~XBw71eyrI8Y4KP&oLmlPCe`UpAQXRRa!#)#Du=6taAk!r8b$QwfkN_yMCA=$2aSfTV^AQILNK!*f_&J>CTx+9nq4n!MuZR97H@AO{y?lWSl5jj z%i=-XfagfULktucrgU>%3msZ#Ad1W$gaILiXu6}59|rl@Ph?+lbRVERVS7*-2<>i& zI{HNn1_|$|m-m(#HGo`|H-L2rapDPKpYeM)&-7}P+{`lukV+s;d(ej>c+w{U)dA>4 z8sG1#0unXUsU#rP+p=jy*cCVSx3|J-$Lm>ExvyZVtqUv+QJ6YDSt8ewQ_q4dF2{`mG*u! zOes4n6sC>*qk|M?Y<^I=Yd{dE8JCCPMl82~bvQH?0BG>d$Y=mFbkS4zK&Tn`ECd|| zKn5q8E3nhDV3iH8f4pvLZe4`Lb<@IFv&f7Lx8V|DvJWy`yl zKg#?62(+Ug?524`3)w$U^V2WtZbZlNqhVwJ_;VmX1G}UGs5o#=FaC3_0C{VF(;4Hv z$NwALIsxp67#Vqa@0Q-6#6*e{9|wIR7tdu&UtzYoW^S?i$K3=JCdZvNdEFsSesbPk zTfd5v+x`NY5+H^2S0{vVInjHUXnkiD9277~JDWe`5%jTO&CNpY=dCAn(TA(SB@hNf zm&G%sG)+&KdHeo}Il*m(F62C*5F&eB`q?mNQ0l=OvA}eb{`v(C zF%n%Gc-ALjL?G7Z=54!Y0ZYw`uw4=!I@VR43yNlHYLA_Ndbt@NbcO%9UmTErMI>Tv zbFBva!<4cF&R;cm!gT5Xoac8^D<*+@^dqiI&_#mao54g4Z6eT01cR;*BX=+1sAlgp zMB#`FoJJbZAUcFz#ea1VB>x7`v#2d_F~wbfPlalug{3#m1aM;&s1pt(768ik5Ly>e zQIN(UmL%^wkvU{W%yH4McfSl;YrqBY&Xe+0V9rbm?b9X2{96u=iygUuOD%a5%?N+z z`6Ca|_uNk`Tx(kV-@ShgNz;@+${0kp>xbcg1-oX2r~V!QDD$}^b?OT_wysl4@3G?< zWcJffEoJKR^$##p(H3~7ma{3KwHg`7u|6Do^NCf-lr!bJ|`SbwT! z0@dE&ANchBM`!ZewlZD${#bEPHXST;vF(j+Ro8iR1;N)vLrJL0Nr9?MDk%YSa9-v@ zhG}(tM)7cd{~W4#z5D4undKv)t-Pu3<<5Ao-(frpzS029P?A2eiV6QZ*jx2oIV9|1 z;^b_*5~CkehA|Jt8^CG|x?poU#;4scd38p9tOuFz$S-*2OKnTe>gSYze?c{KaWT)U zlhjw&rN^h;PDMG*36XRw7An0(_YLSvgaS#4B)OmW(GzKc4$ZYOk4IraAQI7oivcZ= z|IoCgwssyuE%=}ga~v1A(cp|0dM|5k<1%1Rk=c_l(8#XP+UcwBFB0Xnd+!_!J#FI0 z&UqjME1L$W-g7~O&|qL!dk>lQv$|?K1y!o@k@SYYCarjUs+oG3yGYP}Jpn0KUlF(^ z{`kqR!-RE9&65R~@$)ovj9)eH{S7ZD1cS&;rDPsyUKcJMAd|3IxjbE|n4=FsQv^5r z!bucn)*K*e@ej<~fN!u4|NA^RWq1DTO(dBItqafq{Q{>rCXW93{b(el zGQK_c11VNR?*Mx>u{XTyzfy@l<^-{kQ6ZYZg+hYFXD}M+WH{Y}fw~9sF;aPLzs97H zj5&?9833J&3Seo}Y;0^m%)3Pt1i3%y9Ei!0Q9(m|9%(vhMDmNG;+z^_u8fL`9w|C+ z`Z=(j1joK8VAZY(2w*TXcYyHb1cn2G*A93;QND^tc88L_zhC(+82u~l3y>aJYZZ9q zKk5`XiLC*99p_^(HF?8O@>0Iqi(h)IfL2N1E@f3aZ`v*2kNxxa0g&_%EuXC|o7Mi_ z5&t|l*V3Xl)AqmP&#tcFs-uW>)CkVZZ^VOM7Au3XluHHai>8?cVt33LjHF9Pt%d=C zL?ORI$>eySB;$e8Bdc zfEWxP0xuYm5Cgy&#fy~Va~LpDu4c%quigX?@ z*?6b*yV{ONjv+WKzS3 zuY}B5lVG}EeVT+d(SK~U3^_W5491l#+HQQe1MO}jAV=PsEc4%P;49+=pM*Ck;O9AL zk7e_qGvPD}lWy%GBG=7D*`1lpQ{EfOgLKU~0q$~6JPu$f?<0{cdZXAC!nP`@VisA<+(r&}a$5QVv z9@)GFdC61suY?>tHWWr0GnfpB2oOMI5_j(sJby(Eyf0!EWyPMNY2HWar-5IG1S6^V zj5YT7y%}^!d<%%hEVI3>(}-U0>eU%(c!L1RML>Z7^$eB@WaY?|^z?kdX8^!Vtw5_3 zSvBl7-*XQTSUE8HkjEht$Ys|p0dmIc`jhki{kW6+E4Bx?iPYMBVvD|fWUYHp;Empz zt*@(>m}AQ)@>(O(cb6*-HxLSGxfTnPW-S(ue}fANkX60lJ4FMtGQFt)w+Q47N6G9nu493!)|F#9|@);VgR_}G!@dX zH^-kiut%GkmX_y81rtFbC!qh5Srb)>(78t!l>d)GD;!EL@C1~N8@k66fC|Ytf>0kyX@RnqfY<_C55;!AYWdq*qrS`)bVfa=h;Erj>;0bsm6?UYvaPm!3=IEefvnIsxLfi zXZQsK)`owQw|2a;s5u7-TiEhnSOr{JUNUKiKBZhTR+13sl+Mf!?9EU}`Thk{Hl7>% zGPkuP;7@;8!}kXUK+hFEK4vj5Xt# zWj3fk5^xijPGdg}d5>pUk5})*ymd5^G9kV4x}ulUHbXi(>?NI5@r$4RKCk5lUr$sN zpQ6$`6+`|sWSgk%C6C5SBbg%Nwg^cmyUjjN3x5;N8DV86xuLb%Z=pl=D72GnjI=BE z(W}*mK=vX^t(sRQq)s_U7~SoQh-@=aP08LGtF;X zM^%8r;6zsBER_$Qv>X8g+iSDljh)80lBL0tr?5CuHpD0YkJ?OH^s3)g0Rex_{^90u zny97G8jipIP})q0=YUT|)aS`9Zud2utSmDv*X6*u4$-sWH(p|oxn)ESa_?$fpn0I3 z)wx%ZCg6YPEL-izR6;gd!{LCGNlyTcovx}xJfY6&^kFyce}6}f7ox#uG+r2dzY2fl z)U06S8p)i0e)mGOQB&aM*4Fm#C2G1U6&2V2x~y9S40a!hS+p95E7Ud@D0viB9jO2O zPc=c(4H7Z9t>rO084CUD6aMk^vD%-wHc7;7DDF}ZU1nU#zkk7EU@Uavod5e9sY&GS z6KlT5p$`uJ-18&TQb*|{6ry`o*jtBDRGtQ$tzmWH(ZRpBfm~^Mgkn<|{F8;-LrMxG zUS!y(Yj&z~Q7zT%{uayAJ4UXCO(Uun8?2P43zz1YMFV<%Rv7D8)4%XpxJxK|H#RmU zm7$x$en7)eVwIg~+WArlIZnp?$bDLR%&)C7&E@#(!AY$@uW4$LZqP}Jo0~HvsTUI$ zbhR*E)|p)T);y=(%q&H*5hj&DDZkaPsO3Y%;Xt7?m*N)JoF*gWwq7YCa|Zsc-_-s- z@;=;s7U|5!fcuqO_h&k5;zVjU*rgb7PwqZG2Kg=j3?6j89wUyPg0&xCg^#9c36D09 z2v?G9*1AP;kDWcSM0AoqD2POT7}-2u>mL7{vOrJ|%LPwc=@C;rUzhMw`k4{Qu3Nd`Ze6(g4gH5Er&^2WACcC}s>wx|6 zcabu5%=FE8PVTsqNd@dqaoY~smJ{juZIKhikVCnQMJ-xW63ik5F zs}BUoYB%nBZ9k9Ajd`;@2a94c=jWL;OUcsu z`P<;B%`FdCJ!=21Gkz!FwC&CTds6NOPav%6crVfYQ#clP>^(|_8uJHbG_lw2(B&M2 zR2v2Ve%_0kq9_>fNh0YU*bXf(uI;*2AAAn_($^=xO6`M3EsxVTB%74`@Q~@18g6`q zEGAW>ahT7Y#;-7fL<5kylpf{JMyebokw+UJ1EW)2@P`SB=k6UZk$bIfu(0K15sJ^s z%nl7Y{dj)a=sgy`@_X7SqGEfjYZV!cbt!M%{N(NW))aJOuVcwzaUS>) z)JP*{WU}b|aiDkr{`c+u3jMEgghWJ}&6f*o^^R*{J-t?_-*`T*iT+`{Qe8Dv@OgJL zN~iCIR*XN-3+IYU&tJH*FkoIlEY3w7jTh8@zrOK<%R>WI+ccI#ChHMzWD^tcYuYj| zF1WvxxZdpNPwZ5lrJf-)x7Pmh3NGu`4a1^OotJ{%PQSIR3^i+TZIQcEtXkAdc=x<- zpO;u*N;k3n&f8B$BV zJc{YQ%-TFj-*^0pvK<_}!lAo0c0WS!xodWIGJUHU1I?{mm_%OuhXjb}!X^yF6JeQ)8KXUioECPxs0-Rbyo? zON>x1jn~dmi4@tfqzsoCKEOha>pksYE_UF5f}^87k(YKY_WCC;&;53j`II}=GOH;O zU{haz{BN5&N$UCbCtzrcEc$Uexw-GwnzHp~bOnq~7o8{O5hY-tB9H)Q_V~6a*9PKA z|2S5^gJ*1vSFidKFhs!SO^%jG$^R`QNw*1=um`F>Zp;Ve97$SIy!IzH= zo+pmcskv_WXQHrn%Zj$Zx=Rgwq`ZmAy)72BOAO$fBI`V>lug$+lwCt)ENZB$U=IiJ9nIZk(yRXn4`i z@oSvh)DPk%eNQnTJep}%HMs~d*_aWE|28{548NaAns1|eH(C>gs(3XVQXkZQ)$*3FIqimL^!_Yj{}=RUZvfW)+BBsENm$#4^^nx1}7- z%po!1$?|h;{M5GHqr%RJQz4T~Asd1rt}~>$EEIyfL2m>V()2$2CQZul^`*Lns7mnX z1lki%>pBU6b2P5FB!e}4d}v?cZ#KVC%nDyZ4v9)A7^s@#4O4tXA zJ|8t!bXABy(2L(v#KiZ+Nn+l%I}DznBc8C05ps3hv~&=jje6D-&)RmliT$#xd$(Yj zDnBtb+@Suz>{3g-71p(EH+AEO`E3)+X(n4qIPZqkRm{nNJls%OAOJ?tgY5wMI1PhIO&imc@3%hC>Z zc*DOq8)}Ukg=gRfUQ=tGsm)-lR$GN4e>`q?x;>VI)g>Agf-&(_EiF-p@2ylYH$dWO zOH_wnS5jMZiz3>(iRqPy_5xK$+S{ByY7U8c>ATdJs;;dmDI-*La#W5_0{gwv9$10p zo9TH&abER(x1Ll;(-%yv*{3*T?mTDFXjK&Q*WtMhTT!NOS1cr(!xH$ea5u}m)Y(AH ztDVr-pV%cPDrF;SNK~-0kzCUdNXEpQ$aJrUpA8BU2r>%Q3 zbyGXOiiDfS2-24{5H3ULaHgGz$KFELjzqi$b86 zFN>LI4y*efTP*Ikk*|85H6^=1q@&ioN=Y?pce5=vA-sWSZ2ooW@@J1e;%N)Fg-f_P zF7NN2!MyV7f$d(kSRBUDUI_~lrNlkL>9Tx$ zAuHfLLH2y4DwxJq3XXZKh9o9-r-_>}-(neLG8R?7XbP5zv}fIm_dI-^^vnaj_sP>A z#Ph;eO+>leBR=WY^)-!+Eu;y34_i^)8Fjryao_aD`<%7!%`7kF`paDt{Rz=Ls(9M{ zRS#X8BYbI9K3b@~`go3L#Zj4d^wk@Rm(wjr+P4Y+c6RI5tIsa9d@FV(iM(b~Y-Gk~ zcHx@%>Zu}nUp!1gSEaz4SL%OSRb|@nHa$U~Zco%cMe~+k!X)rR!u3mWSS7QTp@|N4 z2PBb-T<-+jv^;k)zgD%#63>`v@rX?s<;dw&emaNoL3WE_*dQy$P~CUFcc|@4ku;bbuA98z!Hrj}1?X=hkUWC8V*bZX8iEgqYP{U%;?f zjkbc83cC{vHK{{Ph6#N_po$RQ9$xmA4=(M69gC}Yeb(FID3#Yedf38~pSZ@p=Vd>-| zx<_n|M2Q6>-*qre83gZI+m4*aF39iho4yv16J-DRi@MvoFG`gK^Gbrn4adN~N4YX~ zl^rQ<_B$=G3{g`Q7FJpE8u`thR_E43)T$!*V+lk9Cc-Fw9kfo|LyF>M*PlzN6&11Q z=h|Y~3{AQo&!-SjEA4G7e*KbQu$njm(5AO~`h3@qf<0zK+Llu;nYE=`FkSEdcHe4a z{1mS10#o7$U#TB1kxBM2SO0heL!`j$rFW;v5ve@mdLb2RT~p~_%WgP7l-#m5 z{9N11osNy$zHR$Gx8u=%^XMtumUzpBA##eC)fBGr;E(=acg`tX30=20w9k-Cp}}u8ziCl;3fzI8mb*E6tI#_msXrr48oBjvtE1 zC;=@VMf~gw-DRA0`1kRFN0@Tn=c`~UI6kZup}U$3mJ+%awQr%6M?dz~R=LjYc~ znNT{@=VIgc;P9l3@c8_qcQ>a7NiT_%w{+DNDCqCK_EtN-pHQImB5S?Nac_5hkML;! zJz=dw&hy0w^Dm~eb6GEY5L|0?;^3p<*n@x<&pblbfyfTPWD;$|fGqK~y_p0bpvTYpK z%-1?X#OPFlHb#7~Xj2G2B9Y2tEqPJZZ)b5fR@r(Gx3x(;MiiwuazFdg7#D?n>3~r> zeZu0yoeal4R*%gQ2M>nJ%pZv1h_kLcB(@|X)Gq5OOFD$9ny`v{He67?WYCh|x@f-q zo6U5t7&h@YGpyssWl7hc5+0Drstr)tq<#|GG-^$PU?@EJCGp%+R*BO>2aCtMtF0f2 z<5fo_J{-HdV;yfuiyYfmCB;Un-XoeHzMC2;qBLF0{?uk{W~yaTdB=10r*dM(`T#qw z$f3%~$x`f`P)|zZjlZK%NPei>v6ev|0YWMNJHh0i#kh{Np9!gqRWx+1+z-bPReyiRigoFNq)cRtFhx>}!N^h*D!a2gw1^kqXWe~=ok|2GZ8 zQ?{w!OxmO)$Aa5-Ri8l=_$wZqYF+eikbRZBHud8=ILiizxkLOLjNULDtm%lvW?>Cw zj~Hc@G1D>sIXq(2291DLxa{hZq%y#JM=#J(vZNxd&chJcfictP2c{7 z#o}x3Bok3x%6W@aC+9>-L;qe5)?&SgJCCzJ5G>%zX(Bma zzsKYNMdT90{Z|MFo_!0{3$@ez&?;i72J2ZY@$#KvTvMid= zi+Li=aO~-^cyK;}7f!8;7_L9X-G8Z%7cK9S*(@@jQb}+d0wmG1Y%|QC`gdA}4iV>oF|)nQ z#;<6zURK~Z(L5~PAwbeFJp zXCLJJenoH{ze+}t#tTB z{G84lb8P;jnd*+hYe5l~QAJwJdkVgDX-sN{s^Oj4)UT#F?C-UIcDD8QFVf1((6fX` z7K6k|{r;8XM4x~+$KUQF#|=@{4sJLNRqxovyn5O$eV3?P#g=T3u=^dke;B$PIZhs` z=$@uzjACz`1RprmE*q*qJ6X;@+9y zs5_f~KM11w{d_icWonZ522RK)l%3?v=H6li27N!TDeKkT6y$CX0Z5 zgwKuW$BJ9^&oD8uDlvUOBtZb@REWPft}!47Z#ZJu$KJRqHxY8DZ1zWKj{T9Lg{eBD z>a{2Bu+@T>`BZ+V@_r?FiPVq-rm^K!mF;#82`AnBFdN>BtnTSTk zuUu1EY>Qw_+1teaasK#@MsWJ-sIc!MZAzv6Gqu6P?X~Jz3i<*9?ChiUQ+|FcI zCdA@U#YrgKmoiq6y#^#@4B9L_r;EjvUS-)N3Kbbq>`GcB~ z1$(B@n4-4UWt^imgT$pg>-KCq^{YCqW%7rg*Ayj0XXSf#I>|lmwO=~$xdsWLPij4S z%89Eig-63jYcX=^J^>i>e-5OOIfqoM>6T(1!{^<|hq$-e-e)i#6jIARj{7v}hArX! zii=pkP5+xc`H;6`XzUA<9L`b!qu2E6IPdKFnLhR3u;LxHKBZzRgD1>A**3Q55^?O;J^+fn9BL`h{zZ z59WoMq#M#3RFyfihxq2^}vueXYI{Lrz9y=f*&WEq(cqhe(WD-JMMHeXWx%Qg;QXu&VPzx8A~O zqNMz{KVEz+t`dFcQ1NW2X#P^y%K7lv)UE6CE~O1AD+!u8Qb^`N)a$d0^$tXqw2?I# zavpD&Kf7jPUCU~3w_Vi`pJ9ast|(|9&lnPAN=Ua;4V4^tY`S89)@Ow8UftjY1Es{~ zqIrJEF?*n0+aGD13Aq#bwb+4MO@s6CK*H)nb*<#c$aFZ?=x7IzK==xOG6{z(b({g5 zC0^qq%gRo;KBFC?{Md9h9;qqy$fhMG?8}I8IbHA}_#;CBIZj%R7n-BC)!GN|8>{4z zL|u)hb~~08&le4cpOFO^pPc6&d+{rYYGt3Cfpy$)zm|=yem9MTjgRg;&*16s6t~XK zPDrk5LDr*O4m`mb|1Q?`LZ;(M50XgE(B!9TYEFxp(n{%f ztSg^LDf50czrd+);un}+pU5ASzzHr5L)#br+vhcPO$Y~e2CRy@u<`?iyr$vn?*0ct z?$MM5I9OQRI8v9aAUyM7f>a)^ym~Iv7dGZ?PH=^1JehvNMu{t(t9gEVl#NCbjE1PnX4NePJ#H0en{;#~% zk+i78)i9rhqN^L&cS?U}`<-$-9xTqMmG9j|k5$0pA z75V@1M{R0dk7Q@SnDl-oI&rSX4s+R{oq~0Zt0Dy-x!iu zwr?ZCJ=Q`amC z*muOAg-Siu=6dOh|GnOugBU$hC6s3fN)Z2%%@ET2c$)1Yi$iM?(;c?Q!EYq4-y^D+ z_4<=gPG?d}<5hlB+Hp%cxv0m)#P7okOa`h89yL7T(l0;3Lza%cO3w39S~(^neJw<7 zWc3*0+hKN1I!o{T4}O6+WX^H2E2~(JSGZH%>-=nH>bO%rIyver*|mFBkKZ&hah6J#x=DpbP{yAlMl)A4lttMHI%SXT5i=*;a7nV}zQDJqtN} zq@I$s9<1!POUN2@Or4=SSIK6a(R~)leke+>El#?L5y5>uA%2HrjC)hHd-5H7` zQN{MPp3zB|qvx6`%KFv87C5;mhb?oFu;@UULf85F%?D?#W8S3wj+|oV&XG}xGg-)B z*H(3QIri^rXf7lwqrl;KDwNogv@tH^xex`&a@&EAk)?roU z?f1WhL92vP3MvB9-6(0$Aq^6O(%qp_N{WayNSAcCfFRushm>xKL-V^2j`QgAdA`5v zn)zeqnt*fm-tYTf>$TP%zEP8W@8h%q+<>WE`gxq1Q<@xTjvuIB?UoQl_(vSf7T$c& z9Lp$ImweA@(T^UxPnDML8t3JgmpFNkEC|KgRA}35HJkI_q5o?W)j!mBM{TR_xN&8t zknq7WxRB`0p0d@sM{EoWGw6EoFB@@>78Mtyy-K3$Dc~{^c)mVdq2(XFJY1(9og8RD zbaHr+y=a+hJ`u&~U>6gk7Wf))z$+%9}CiEdgN+}CEN_Ks%pP6=689Y5`P zajn@rC<-1cWsZ!4|54d(_3z7(hPe4fd6hsL^C{kS~J4sj{CN37_o+D*gkr&A)$^M;Lo(tzqmD4*vEEW0qGW=qnZ~3Ig?e4*-1H2bF%!Rhh@{bn3`k#FfZ_Ywxd^KUPPH# zw!4m1b$=(!+=#QmIa>|~ex2i}5{ePW2|n2naxFg#Nu^cQ($SE|#gBVX7|IUh^j z*hqR|l);{AVB=Us77F$j;s-U4!~~D+4pn2V^-(6IxFFbi1W**kn!W~T8 z)SY6Ow~MGWi{Tm5{_#kV?Z_|DJ?*yY^GC1Sc*GOpzma8zW5U zw|@l|_EWVmA=K2_$|X<1<(GIeEC=#D5Rn6!SZ|oR$cz;`(kSQA7L^g#ON)JyqT)wy;}#+lWwHEO!{tt$kq2wIonB`UDoxY)95bczkXomsCjH4L1g1 z?n^}cMz=9JY#*%oJb3!sbOz43gL*QR^`CG^fwygiPqRQL zi`DR0W@mEsEMKF%`KQM+NlljfHRVo>zAt$`&ZNKtZFgekCf7@J7D{B5nlHTppK)A- z6>S(i0<4uYG0);DRvwMvo_vIX(xznQKH^pOy5n*1))N9lKl<~=JlNzI;oKxDXR*W4 zm&pe#hbHR+YMrEei*6Q($w}j1R3XHk}0v*TPi4 z^u;`6c1*e37QYd8psLb3pXuV-^|)mLoxD<|+0+7;KDfM6avpAcb$)&x*~U`rl2nhg zx}Il}sXDv-tfDT5G6D=wCC6a@Od1kXn}GG*X_M-OqJYvz1B9O(savcVNaKA}Vz^c- zKdBcyg-=)T_SwI`_7UOsSenoTX0S;?l99_`cM;O6X7#Jbb{w!h_;-i6!mpuqlHu<(rZyBwV_t+56#Z0+e_kKMikw`*lrbNChHG0yk8F9YYY zD_iC)4}MPpy-ErRQ!IExr6ieAE-!T^Z>Y||f8?rJ;Z?!6_r8vD`v_rK#6NzUBkJ&% zD#jzrCoh$;l~dL?xqGNZrZPA2X^>kB!wR2W-d$Pcb6{ZHm0S}4$O2`4ps}BPx#}ZOy0J-{&)R>(fR_Ian9q+otvuRPC4mJ=fY2^UWtWDa9Qf zkx*Z}#IZ2~{j{D!u5&fmu(Q#fPHtaxvQd0HoW%^(Mpw_gS-+Z_>oL{0Y6qm(A*k8r z{BvsvTSQsXnCk4Tk(ZG9C-0YKQwK#c%q2FSFn-J;J?veM$NAJK1|Q+Th*vL*6I{&N zB?N;YC@~*o9~CyuhB!7#S}Ssu>PJ@}sQF2JmpHOiegAn{Iy9AeFiW=cnU=~5n%499 z)`2gqc*I`OD?{2uk#URE)Jpn=0h6mH4xvw;|m3uqrO;xz&zOX4dnaaTF| z>+D)rCp>Mqv8GwJP9NJWQu}08T$!_9?#yCgP_IiCaxRN7JFT0fvGaNt?ns9ZsiP>> z*!Yq~TCb=AUZH|2Jk(Ic0c?HV(&CAQ4m{Rmt!JJ*kxTv2(2rX;O!)-b9G8ow=%lIF0Zm4W)@o zU-L<6hn*|Z&S+tjdNSR;=deXho_P)qKeQnFmDxPbC(}o}=kMukmV!uTXZ9LT6kkv+ z666>%HC#u#W4;Z{r-V2zN0&qN*K9Q|nk)Z0Vr3E9a)`<7?x^*_fZ z|H2A6(Sj+mM|p%-bvDofM?)gE5)sSyLpn58cHpqoz!58buT0gM*L0c=Ne1!-19*DHmc*yQ zcmtE)63OcpV~Ufr{IL!`S$>(gjb?-vD9dUBa{9{(D^4}H{MbdpXri<@hjfF2(mKd2 z8lpZ=vW?Fv+lsV`g*Y(EqY1f@vVHpUlR%8w%iw_ciDgQqd0v2rJrUShw8ZR+Vc?hh_jWc zAIETY0pUSShE{c2H9h0>taz2}7t@T~oCh?^oJi72f_pw?a{H6y}%P!HC&FyD57&hbd5>g_Utw3zUCC2fR!B-2^}!{ z!n#|7@j5#9bQUT5Zg$h;>)rEXDpR%QkFNCg)tm3hnLxpMe@ zABo@^;zv5c&IyjmK+(S%gX&ex@o6`$g|@+iqx+#S*rX>LfH-en*d1F^tB$v@9#Y0> z(KlHiceD|GY%Q04H|&g^i|bq9OYZjX?2HtUZTFPUegdH(<8<;E$;%6N$Hk3?UgF@` zx>zRFCBjtkmXq78elnG#Y^PcA4AUa#CGyFvv_U-~kx)Vb?7Y1GR{ybOjGT>+jYG0- z?evz8G~9yNXjgl+S`$@NK6m2V>~#5@F7mopwMzQ*yE&oRJe`9^Jg)Y^pQG`Lg1O_c zYrS@^rq^SQ|UMw~*wC75r% znQ=N5j(p!@s&B&imOBx#Y9%{t^Zf7&T|{OM%ru4tjWAX&rRLe$=pXa+YFmA|*Q+dm zoSc<*-anM|XKy4)%el#*KAmN+Z$QXAsR^dN zj zQ4{W?lxH8B)D?-p(6OB-#a0BtVBP|!yKDM`%-iaQBB7HZnB-dHn+}-8k7q?0Fp^%P z9<8wVqd31Po`aUCN%|BD_iJQ-&pp4!-3Ag6SA2uHik2z`5$-Gjx2GlQX!~1x* zW5^sah15#ibLJhn_YJkRqs9LJZ0(sP=S$J?w+K?t>n2h;ts_sflUU6* z{=Kuqk;g7yETXT;f34nTyjO^l!FCm=9 zX*4S^{IJDNd`%hyjzG1-oE&Nvn>kz5B(InS(c8y=-)Hj>V_8 z6>gu>!UNXfo3wCpctG=u zo+J0$d@t|{?iY~yW&`lG&S=4)P`&6S;Zkt-Tet0Q*to*QVYAX!J)OkHWJ02jsAtC9 zTDcZ|9^|g5E6=cmFlGh&DzB1h&b)i0{wF&whd%9vbHSiiThAJ!NR#qGlq@(!e8$N% zDhB@c)kE}V{o>kF5>Eg^>trqTI(YOiPl(#bM(il%;a81OUzqSXt2N3qqk-u%!Og(+ za^+DukUK_PK*S!@4p;D}T!TB0HY!stJfrLKnNtsg(%Q`;8BY$mvWoJ)0NWrCy z;hUcaaR?O{-VFK4q0NZ`5W8-)neQEByY{(X>ni1{4}FwE@n1VP5BY37 zU`Mef-Q=ix6exYeU_1Bi|2u^Tf0(bBf{OXI=V z+U_<5n^z!`N9MQo1}6VEmjL)5WRn?MC@C&>I9*byylPa7Y~TvEms7$ciRO;u+P zN^45!k>8hv^IGLhZPtGf-GG6--3a?9n83|RWq0FA*$CwBQo#la+hB|0Q-|HPgh!7) z)qlYRQ?nn(D{M|qiCz7>&3Kd!rO!{+?dU?Ph%}jA?W=_(FaR+b+jjjNpZa?uP; z?6$V)3vG#t14N4PUhOhldP-4;f+ynqE7WR+T3x=zS9{(460K3*NAG3aOIf7(95&~XL3iX$|3x$drobz#g<%^FF#Mh=NK!Y%@`6bje=Ga{DMWO9qu(g zEh*@EHuf@omU85mN-u-o=zitSXH(s=m4`KT!n!pZ^My|gg&fyv z_HlC~`LAX^$z_FE1yGi_JL7A6T0sbF0_9X1EJPMLOYfn~h@AdbSR@uEXKWc5E+w-( zpwz=b^8F8W(M)RLI!unpXXcfCtCr_Ef6r@(Ll4|ZS%p8<8$ol4q&ba&NmF?K!JkBV zjURE>0crbV|0&+^3OC}<`&JuCP2)$p!uLeNLpp0rK;4>QN%f4|SSKs%MP=;$1zHV0 z5*92K77;8`@=4C6^u`LYYYNbAzCv7R2pFilwIv~ox6 zShe4{sM^8S(%6%BCe2}jjp|h#l@jz&*3Y%Qqp<98sJhS@!-A-|i<-tvK^Je@pkJYk z7?Vc%escZS@WhG6#R`YvGNYv{F4pmR!m^Wm)4iA$eBc|AjHxC$sV3$?LsPsc6#oc`K9u1b!N8EsBn=Y^^2N4L(IMq`_KrM@}TL?JodXP zMnE@Byxt}AXCJh3Cm|5;-l^tu`FS@DYgdMu0$AcNcz(MJ+zDjh6@F^fN};#=gvNd+a+}aB*-bOw%lMURnJKPx5Oo{y>!jT zGUZ#{b=aGlEDEA`OTg{)XB%v3lO0so&*9XJFYTpds8}`dwoFQi#Nl>Asv|j;Vpi6= zJ4`mfKKOYzb%dpTd?A%cp>@Tt3sjLIfYr@S_we;oLkoFw;XoJqk&x;Wc7{9Ir*Ku&d^!)UJfAt8TJ_1Oz_%Op&` z13o}um7gu7GhA3(KvxvOiU^3#Gvrwj@+AY93^lB}U(@!{Chw* z2!0rduWIz!)$7{slUmZdC}b&kaDxJHmDhJC=N5n+Eltv32CP!hHQ5GO=cK=nGRdP3 zoukxuD;dx^)6(2)moNg-m|E#YbFROlEK@hbi1riy7B#w1D)#L{uLZa-BA2sw8~boU z2Rhct0g?(gm&E1RJaqUm;`tuwg@qv_Y>px4r!7MoI$%*xgAvYGq4(5*Iww=AgKUnO$U+L z&d5eoB-iR_CzzHm7D%FWx+^GVXMzYIjWE)RKSBtgv=Q+O1Aqv8;9v&VV;b!)K?gR*7R%alMI{y5aW-k$7;_zY$fwnN#-B zoVGLFLIgwAghX^=fUwzoM2t2Zoivu*W}!|RL00upkl>}^4`&5@~OzW^&7xp zoKV_3A)np~{E`2AA#bsX8SN-vyg!aXTHDk~K5GJw_CDAtSt#!5DX^=EuhASJ-KfQ* z#*f7NBlE&Ox$FuIo+aJ4z{=Mi$hQji+{U=x3TmGI%2r8h4w z{s1rI7^ozCB*wV_D(93A@R@*F_->^{-HYfyR988XGk^TOL7isagH1W=gYVANyghsu zBu*dA5Zo9m9{diB`xHjMy|O~WMpn$`M%bNb{#8etv^P_nPG&Vg)t!eEvDoDkFxE{| z>E#Cp)p#yP_t9-zm;kCn@%YEqze0j2afVNI77&_)gnc&N645J6NZO5>F7DSZ8df=pHx)ot4hBOF7e!8y4qkgM5er<1pF)Wn^2JTf77SMPPBTBf4 zV3M)vQ=+Bs*jel^-Pu=l&i5kesz4ueWM~k=z@oInj~*FVoYeA#16uLSuSe!vts&c? z`uvkQCbGcZL=z?G-DN*Ve=kh?y^dz)9Dc1!4$HTz#Ag(RnS&pil3m&W-Pl z!0qL{L3>xn*^*Ej5w)f3cuRRFBbZ?NA` zDBIGkkI2gWsg;6m+r}0e6t5v)v;K|dMt7G2Lo0l15_b7rI%HPoh z$pL;496iNhgSjfyF0N3L^DsFUF|oP(`dBZ;2J46H(ad8&CRUXx9dDj>b|t+q%1xAH zyreny&iqFjNwB?~_JI=SWW^NdcJVQ!W58|XF|+YA4a0~qQR1vMRC=Bt>38R7sSoF_hQ;NxSP?f&`W*7aCAS9dDvx(1HVW8$H(yy5aEKp??7J9 zBE9S_`~psNK{FkrW;JK=4jT{ixu+;Gqy1Dc|EKd6@AbB7Z@sAs38s&qhXAf8DcSZY7 zc@G$hU|7LJgWDKx`t@-qoV3ZzXEUASE%si%cxcV9rzF_ZeXL0?Y{%q;G7TQ_;u8%Svp)@Y z=5N)@Bq8-KD?-GETC zA58Ki-Lpo8y&4WU3Lpa{&p1*w^*mgs65qZD1iM8-;|zzR5RhRHtkZ=cO-9u%;gl9m z%FnM8G^1b#u4j7k3*E$2s;`>mB;!NZxwVMl9^egE9nZZp{$4<4N;+Pow0~J4d`WS@ zc1TnPG(}N4at`%GAfy(~p#>z3_f7~DdWJ?Nu5Zf(eV)cnY~5Nb3cpgMTxPBLP8MBgXdBijlgn(h%3v7?xG&cHzy4V zknJ2sQxYbSGpJhoUSM!L9ar4Mq2Gj0PJ%}7d1-~wyoQJ7>Ls{&;#0e0?=8`{9}GKd z>FK8;HqbV;Dzd~PjEIIv!Sxbh*E-OZtqN3D><;>U^3k?Qs3d-piIMiZcr|(l{=eX z_j8^*e1WpkGTFd+)D6HiY_pE>CVN#C$D|3wN08j>i8KDxxneGxNG zZ{1dr^E~joJS}IPl%zJYD#%NADy@H3&$8Bjlc2(w^~SnCp*^aRVa_;y_pNPtgHB5E z-gAO?rVD1AX7v=$xO)l)NsKMZN@v-r}+%DqNW5@Cy|pmNN1H6XqOwmN%Us(&4_<5Bt;xBgd>@QulR>P#%#x zKyc&LMErvyfSS4d@QDOxu!c{vV?;Gv|gL?_3qF6PG70Kvzi*b!>S3c`k zOx5^QS@!b=D&t#NJ>{R7!}mk#pN^N4=;7}OK$g1!gm=qkh{~;dprRnE9=j-Wc=vN{ zplH$4p(*0?ngWi-sbzBw7ZfOA%|CJ!d(m-j33d&FA1@<~3d4d^*GDRGpI}(E*$f=$ zE_x`?-H9dQ3JC{oH!Vk}yft=j&)|kWj}Z-#5x@G%gsu<7L2F{qM<`!6h*1eVy9;6l z7@>{})clAFZPR?nv@oczE?c%a?58yTb_*PkytgkY7=3^O$^V@HnIOi%#C|ocp{_-$ z(31)*gepb5uphP|MOlWHhPhkx#U#|+>OjWN01|bA+`@b~GxGv;t%3h&R0ukU!wPE` zIFQ9R%PN${h(%-P{->w^nQi=iaGdn;Oy3j37q(Pw@{iW3cCZFimiuJO{_zgK2AIY}W+ZEOXd3o|KB|I&_L|xJ- z;&5Dj>5~hB7#+I@;u67ExK@vc$R^>F*5JeiTW5HGQy7UA1?Dvwut~kOl#m`OF-dBR z`RKS8nMX#AWMmO~Zkr)ulO_n4n{%04ET{_+yCu#(jaf83)a~6DZDK^D2d|JMp4mVF zfw1sgBtK^oI0wpN=%-B7u?4OtOeg>D=|1jvx~TaZYmEq)!!2_QYq$T0P6)!PUruSPF6Y{X%d&0X+euq8YL8rt0(a z9s}AOW;Irxl{d3O^f2KJkP+fM_U+UkfZ=e*MZn9Yw%8%W4p%rf8>UkTTj{t(!rbN( zZSY^tyS^oqr1gKSUHSFi=+I-;ckyw3bMCw%oEsSEh2`dG#U}p13@9XwNb8Xf9&oZJMzE zGNs~K_`3I^@*Mi@NahaA6A6N<)D8tuKQF~4v>I$6o#cy3uU6XjDS_Mr!|c&I_6z)bO}5GIjTEE2$_RwLD*> zU?&KI$9XNauw^$&Dh$f$Z{w{+^ZLF)lo?8Z_>KDJG>qrKzX-`p?VfPEO4&=t-b;tQ zFQs}|=_b}z>ahy3^8lx0pImu<8SS-}3KtXlK43X&{x@wAn>JXV8_Ot^$S4GdRS;LH zX~V%9nEzeo^$r7-kxsoqW(Nkt|aRiT;#$=>pR#-`(h8G9nyVF%ZJ#~8u9LnxJlSo zih>GixnCRqQQXh@*Y(JBU|{?9JIA@5S)?12VU_RSO*_6T9-naIs_rfG6oX*>k8h-H zsqi!N8VwwAI%?Ioi&AdfhhYD*CFV-$&^0sW1!+_iE|}Qqpbksplf(_XH%|GJw6@l9 z6JU$)m1pLvAv57{e7p0L7#$QtutSi@IHYOgGjM7Nvo?MX6p&R~xDi%ec1#)md7T@F ze(f7?`xs06Gwb#7+I;uoE0{-E5FjW9m~3Zn;q`?b7w3Wi_=~t0Js=3Z2pv$*b*O)O zN;ppow&hmuD7h=iJMNVW!yD7P<G_~_k7(Q9h{^}2NC>UX zx_ZPX^EcXRr52r>oUvLg;n@iYUu2jSc11X63 zX-<_=o%m@Oe0w4-F%GuqrArg;*P2quh&?JtB;zjN@RJNaI-GpWVgqaq zMWBx?N-7LZUhmJcuH$78BMci=H)QHe?)cY$0d_o;XIe0Dp3i#4AXorFpzR#?K&Z^^ zL~tIf8mueo+u?K`o%pUgvauDS=n(cRIpX7?B$9;FH>}2@kjR1=rR4>J5+s>MF41V5 z^^Y#t1xoclfL-4!>tN9uC6$kYYOoawzD>YW?_dCbK(#>CJ+A;2yZa|s@xr@Hu3@#x z)_rGs1-ERG786Uh)O7oKLW-69$Yji^V_U_GXnQ33uy5b45(M$=7=b^j$>HJPuiCGN zQ#LU6s!klk3aGsUGt2kz)1+SAi{bwxZ$gfkJ-R4DC`h`3D+mGDr*Mdry7G*SeJDtD zINtbqQzQv+l^HpJ#+c#(<1lV(nz z%Yy#v#bT2T5HPaA`cJ8Ez5IOFC; zpmEK_mZ|OtvsJ>M;yW6!J<`ZU8IXv5($qMsg$V`u9G<%Hdf-xgikD!wHfBHFeMmQt zDYDvmJVHdx9JL|`WBnB1Q;;-2m6gdzcR1-SZkVQe--b~LKa4Epl#$iMOY%%Scz`fH zK2I~(f0FlL&MBLn*|*&bC|d)jlZT7-=FE-IgPftj`DPjtV35%}9{NFyZ5@99?&{w#CZ?hu^%j7kb`H;9Cl<|OuSZr3zY|zT@ z4jQ*=x&)cpxRz8@T^`ScIZxu#|I+6=!l?fUID1^{w9JP=0fM|a+u$FN30#4Ue#saQCK*hzvv0 z*ZI~w#ICnyaa;4UrKe&uv>44(t22I_qZp~B-lK7Un+3baJq(0pQ{2JPSo=u;yyJNH z1)*v-7Zil~DCcu&f8G$=ixLmt&rHrbsUvZyvSZgCFBi4r|Nd=)DpS}j! z4T~%o3U$b$2d^IczM~Csa7Zwp` z#w&cx&Z5*!Se2k*Y!4^W+{dk3-Q5xThDx~{V$NjNg_-Pnz@!z_is~jSjATu`X!|h- z;K5?6cN!ljQw#WQ`b#k$@a1>ZLQz=FC)FBVAX5|3fC!@@|3~}Ek3Q1~<$eLC7uVp# zfi=$xKUWqXj6>a|Vm4ZRJu30A&sUfywwfxx?}MHQl|Hrf18UK;l%^FJ^j>scV7zUt z1F4dF6%Uji{>-9c+vw_(ah>RN_X9aR6c83=i3wXtf;}pS-0g{kIGO=6k)D^rM;5Lb zT%A#{Vg4B1S4NX22;>mzv-D>V2NTK2RK{arKQt=q&iXq4;Y<`T`;{9eggl1gpIYY} z%RTH>q%N;CnE3vB|>`r|524VJ$h|H{U#Ss3iD+LkT9GT&huOTn(ifjG-1qfI-Fewm9=h#evBf4 zZ#|cs18kQu5983;8Jha{@YGh+yO$Il1;PJLz+}|T{@23GDR#8ehNt9j6vw80Lox11 zU-@LDEjUL)vtSH*Caj<&26GC^Wg*qxsc%#-S_4N{<%0Vol>_1PaqdiVAjRNGyFv2U zxn}E>GN3jpCVY9(e^gGw<6h@CE{&{VLl(uJrdV)x;tav zE)_n8&pz|uC`i?9F7n(N>)v&i&yJOSQ|dwp5Y{H zV+uz{B>OzD&&MdBo?oFJLt!$G^aZvCOHjE5U+J8NwGk9sEIjpsgbbip5M!#PPf}r5 zsI&Q8+Dl5n8Tv4ADYiloZ^jkr3(=J=(m+AN_QGx6;vyQYAQfI;n@mL*d+mDNU!|x6h!XN_u@fR z&$A;(P^}A200^SU?sfX4XB&kEK})P2u4TjR z5H~ee$Nr0&adN6(_HcMs`C7_0FA4s!)scz#+fQ^9GaTEvh9|HsD^H?)QY~5|Q&C+G z^xWE=2=T>33MQ6xPmBo= z9foQ@TYPNY*Iu#1B|qj;6%;Q4lR0g}6UE(hVy9XS1id!&U*Qy~AHk@;vMMR~XVqo3 z=~rKOI|3szzF)ZVQQaZ^Hy`L|gKNv}tr%19Yv5iU98E0Kqy7X%sQ3-ZpXk0AUl>Ij zT0{^e_~1b*jHxKgq(CmLP0FdW-V>pIFn#Yd82T~9tlFE6x$}P(ok(ov&Z7m5B!()W zLFW~Z;ofMS1N3&l`Z6qun_;YbV3mk2m4QGf`$kNOpcU~SV z)XH3Pk9zRk9_Kp%0d3amp&LwUa+Fj~4zXT1>EeY?aS;A6tT)anZKzTFa=WfgEJ-q_w&@WyC zq5t61YvC9O8Cg9RJ(Y#cB;Hl;<;MEp zGv7C_nIPcC6MSp8=uCFJDTo6*#)y2vMo4-^Ncp*=Gz!v~*p5CnZjq$;_Ef@+B0*pL zzwO77z=c?E{RdT=tJa3XoAhx-X5sayuAb#fIl0oa(dk%k2=MgNz()mmh7%hkl*G7E zLB)AFytV%zp0LB!K%^EJLPzxXqiSE`|AIojtRowKc0uh&;DQVUWpQ(#O=$()K_hYz ziY;h{LHGZu#u!6`&~>=ykiqV)Us5Y451k(NGJ`5}sl?AwKQpRI2Jc=xyF zJ33aRT}MBiNr{K(*|&kf2C}rR=jY+XfkL^=(An%cif-UpnGew6iJ@`8*&=7?Y~@L! z_dLbQ6Y-`C&M4USoxR1YWTAQQPIR>83XTBgPpCG5{{w`@HmRAh)@+ORIB!_(tdy|DK*Cd0s60%|qSo~$WzfA}?y zf7z3Vz!>bp;7{$TYQ!r0>f=gu+^?dF4E0(8Nz=RG%hAZ2y;GFYC+zu0-IoC5xs=}# ze)4rhs+k<_oatp$(e;;t&3Vnf_TllH)kUyZgu z4-(Q~>WV33ODc}JjNVgpGu*(8PtDGio^o7t+JUx2``8AnALTdHbsg%&E84k`E9qEH zrK*_hr46iK$0|pAgT%4qbsbjlkdcQc2xsvn#C_}@)dRrF>{vbKgGQWZB+X4JL^YnQ z2A+XP)!E}_0ztJxVZ6<}G7eGixkIEst~#Y!@Uq5Id+3+RQw6hoRi7@Z`y7U!(Q-ZGKj>?dRyPp>(XZp}DOPwqRS7bV*6h_E0 zM@2T-pL!~P%vz7%q6UQT*^}O{-xtx#>K@(Q|LBtSl2M_R5dFQVl?Ulh%Cv-Q@a^R{ zIO1O9`48pz6X(cKEp%cuueZcSfvb3FKw zpq{chT6Ssy7K7*~r{&4Ny%>Uu+tRw&(z+QCl2&6Fz0`I0`mT_Ef4!leJ)KbYtmA&1 zkN9dz&R(RY#4u#uFqL$}SIAwZpj^p|B&EUXdA!Kev>Ke%t)Q^9wd!|AB1!WaJCj)^ z>)Ko^SPxzaVL3ydf3v#%SnziE|8)}<=->huRfUI_?lo-+z@w^4>YCe#Y%{~Jt^Q|c z5XKMtBiuHX*N~5D^g(4Vgp1%RAT|y>lkg7jBF}G!LGcUx8!nJg0dc2J&h$~>OY-x# zK#wuMjdqBl-e{AnrzJ~1Jf&VUO54Q6}+BD=LQ90RIQpcJBLx4S^YP}KfTeWS&c z3iW(UHN-?ORTLv`_(jO(_uq1V=qs|T5@Xqv*f+D+as>w(Hr5C^?3CGs>2hHBgNWW2 zU#1@pFJITYVR&lZW4^97boUng-!IN7h;I$eb3>;SnZ`JQydN!zSq^>D`-Q)?l>Z>5 zE=;%GuMJbwEoU`#0=d|Btn>p`ioU#r15}bi3BXnu2tl|Z)Y;vIkbh-qlbBXg{bBz# zr*&=y0BxY``%-8qYa7%${&`xG`oX?{TN^kaLS0!o^nDOJ0`ffSR!qI7RlU7(cq;uU zm~?DtpzbP%L#n{4ba=)#HJ)>chy3w8wgA>LJ5c)+t{3V3ynDQ;jV< z@HmGjq$3lxhgQ0JP}ulgiDfyXgF$ujQ69=>IVAg2&{IO_JAGtP4*H6UZD#_Mk?uLo z{?CZ7RFP+gJZhMiD)N9xf$H4OJkrg{&@bTrKrFD2U#&XuJmBzwg%av(esx9D4r|F& zw)JaV`e&7ZBA`>xAX0|dz;vnP`&KAN0BQwPg|so)mKD%s#iZtK(~t(7FEgN>nJ(QD zgVbY!!$?hM3{~eP<&`T3ze-TcC`^Ai?f$3_4A-Ii-wT5UGIOmCPj1=Ru;AT)N;(55E0oUm{6`Ie3O-reHa#IENoz(jZRNJNn^h}*CE95*`S)G=Y?)f(&hn&F~0zT9#~Zl`*%@jpqUDQ5am$K}lxC`~D_Yv2*>{5g}?13;vr3E)DwHE5fbeJg4=zv#!3b!6N}+J)+oHcZ zP}5Y6(o{*dV+!}2Xa8&T=c`**#NQG~mS-K%O{Q7mS$65q>&C0J^a}Vu>xcCBN;S$a z`L~KA(!ly5k_P(NWK&fOliMOjUz}NhQ15J5E2uBa(Yp%J0p&ef zA;yc5s`0L_UTi3_E!JUmXPghKvqht9A&1b0L`IL(ro7e*yR)-XayPE7GlITZ+FY#m zgA<>YWr{;tCRjqB; z;>G_c=YRyO@O7R`_+S5Q;8@FEJccrx5fuXnI`!st)WW0pq^X1U_E32$k!?E*4B5b} ze%!M=TioNmpzYf`Hb&@r%)7OvzcVshb**AP7Zcw$U(E>BtVTb}QJ};Y~eqVFoz&1Mi|vs?73{%%54^w95eTINC&}ua$J(?pGOelz>GtI0qS4+VLM$ex0$OBEWr#{I@bAAG z7NOOY$KEy}p!s6Oap(7?!vk++=X)apKv=fcImEP2$kMch=%zzwLoMn>5v3zS_R)@C za@C-YyNICEjDHyZx0)r@!>a|FzF-kcg*b+Oa+zSEZnFrvNFeB|c~|NwlTN+3UQ48i zLhq%Ti3uEus}zH3LkjP3wS~Wgrf#g&_>_f`J^m4jVSylG38P-AvjE-*5b~8!%XKD! zijG=9CNL}t$Q4(VHTBG(MH<`+sV_gxHZSjI@V3&Bq9RThMk>zD@(N2D=`S-Ibh^0>tY_;;Y@p>}XdJNW0q^)J#g6 z><9fI{HeA@8-FV_hL^L9uiJ&f%MTQ~p4|EN`M;WI#0;<%R?+7dn=wsdbjCSB5`(Hr zL~_%PDbiC}E-vUF;!GxV;wfKpS&F8JTb%~eQ@%dYF!bra%`X@QHf0bFe$S}3|(TA@j;Y8aX(8z_nfJxZIRypBEAi2 zv6y~V>o4f)84m+tuuKSK@IlE36wYXv$qU#U&wQjkiSKya5(52Yw0u zxM~?ZpCdp;w4Zw0*jmTUKyuO2GKXLL`{8^cE@-^a$X|Q+@n$s52Ds#q8(Fm!mr&S~ zFK|T`L-@Z)%;2+*sPHIqwA~dFjgW6CnSb0q3l5t$Ae)X2e-?|cAh~$+xEi3$7qqEs z;ezlf=pK9Mi12rV2K}|Y@Xq+=%Vy|{`$FHv^~===4(5HM*Wo03_$Fq#_Q*i$?FZW6K?EPUDXDdg>icB#e=9#DFQG%I@C2A1 zM!4wd*RRM}z$-^0%554F7=-}I5&dmIlt)Mq5kcp68|oz~V=guQt89ta&`;tm_#E$0 z5u~`DMly+?TIO(Zt0 zkW=>ia)xd2uAxN%|M!;13i}EL3{CQ0yn5emSJl8^_!G4pSZ{UkvBQfd;Ef`}5Mc|1@zyHzjn2 z?kufx??TUjKWklOu{8(F$U`+`i%xn6l@Ci9b6Oqc|sdqtQ&L;+(^39%bpAo zSm7+6<+yzCZ%SajV*|&b%IlUEXG}&?>7}k`P>wavObUHksU`(ngk}y7#=$GdYxny{ z&e8ugRlLaLLdq{+J%b}KKB#%%tM9tba925V=(IiRX4&TAiLtCJ*l_)GLy3En+7>-hy_ra9b!zVY-kKAxAlXP~(wDrFpmRm3%;rKM}_8>l36jl%U-F8)>*05^b+d#Ro`` zDgj(Q1WD1u@q?E`Z%K=g@2iGq<{~jTVb?D5-xko5^J)d-Leln4?!5b;98)EdX^cxR zS39ZAblY>lrKvQ5+!Y}68~v*A*c-2yT9K|9jj3gcKxo;6fAT~!yauK&$kuG`i{BDD ziW3-KPHy2hwg@LPsVH zY!BBVzt|HKLhd@*^xjwKh=K;^MqEi^m|<20y+il&>ohAbN(PE~3|cPFn-@8d3KBa> z*S^i8<P(~zZwkq|6?Qdk!`S$g_(Q3HQ7dIn zZyuE^*HJHGaZ{HbGy6aoy-#P0aAxrE5a}%Q^%kydf9HKq=*S({8CuG8hSt71;fS>j z@fMlR#TpQ%$5kisj;T-XmmE%nK5DOW#UpvjTqiMW()DM)UL(S~V%MEzU` z+WK!HrckfMe8>ITJ;|8N_{>c9y_Zb>kzcs0;e}ZZX00+w`O(BKP|4h=yZSQdhS8Hs zRC9FuMBX%iW&l&Z&dvYv7O-I>2fx?B^CT+hRE@O`I85O~l?Kk*1$n#_8aN*VuaqHo zjcdv(`~O;d%ebnxu6bD`+1)Km-l=)M}KFpwb!0&&Joubr6bU(sG%&tC3pv0!*x{sc~*YTGid^X-jO1 zv8MeAGPHVQRr)1-OlRlYpLT__A_4tRT_Mv&spN};X^s;uAXrym7sAnhk2@`ZrPJ5A z+VgL%sO<8z-U$cUja)oZP>gIoVPhacaq2aW-^!aSKNuUIY<^5T2C9BwdZ93DI1!L< zOi#|vU7ipCA%%RhX|Y$JWh4O5Ug=n2LSsWRf>x#S@sFo!>1gpEnkSAe0+o|K?FLZ( z>Y)R3O5sdh?fq?{QYSvR0M`zw-!QkhlUn7fxg{S8$NG`t>X7Ffm_J{RtU7%$Mfu9f zG9;|U%43|#qcCGrI2@O9D){7)8vcJLSF^7~en#j7ma|7~eRzLn?y#WlKQweXOjyIx#Wbk6U`A+;z`>8;k3A-MqEF zu60&wIGMkSfF|%^wn=Dxw7@TdL1$*i-zebI&HFwdfz^)Q5rg>;P=E#VpuAG4EooKu zQHe+xv=O;Syy;L#8n-Ti-asQq(aW}B zeLz?m1$ancBZ>g{gr+l|w7<93`?Y|EK$vc`e+1n~1T~i|=Huf5@BW%^PoHOj-G{37 zN~KBgpq(OBB5q8#Jau2%?`FQ$b8|lR&wTqSy4Z@6Xw~Jpn`)R3^&+0iD0}2kmXAX^ zan~2nQ!ti>WmDNJmJis^sBhnkOZXO?y8mzscctN1#R>(eR4%+#8hOm_L%;AdL!ScK z3Gbp9>t3nxv@oA0=T^-ble5EuHq>#6T6|=vz;X?!F*e@^5@cX?eux=>GH-^FCE(!& z6pb2S;xTMxI{S(KeEcShPov{L~PUrV+}2awzE zwt{ycVuWS0De#zffuQ0GBWD71qvRcCYQ2B-K_@(4{>Cf?$~P@nM>#Y=io<6mSauWd zZNRvs)kx%|WcuF8f@*bSRQ!~Zj-+|dVy_zF_B6YD-5d9J922F24m^mcgwDI%T#cmM zC*<#^$|Ex>D!?uv*{nF?y4){{^MOKqZz(L${?-!T%xz$s6(zVjkN?gYtg^6uyy zwp~H6517m74{C!E026-9(^eq!eo{8i61ZiaINP!m18W#)NdS{7pz{f|h=bvpx5+X)LFyXwREo2u-SvfEsCeeuZ47bt`b>VH1Ek5qOIM-zSi?68G|>R|Pz8DsUC>+x z$T2!~mpKYLTDyzx)qQa;K=3YlCa2kh7ScY|Nu%cb?sMNRV40vf021%+;&$#7I5_0- zY@h=T^sRw9`zl5hD=VNZZWI}J|CBxg1oY%8z4`8)EGKot4DMnxW?TU5n}5qi-iX1y zpA5v=J^BxSN&9OqGg6RuF&0mN?8Wqm0}j?Z7Q8A25{n%$**uCRTKH|dHn=tr_~sP z?yNG!PNuhFmFHk2!(hbwu@$hm1)l+p4=50lvWpQlOX@vhNyb7n7yy%;dy`Oq(CFoSW`{{224fZ5Q$dz6Ml?&G;awcA z8eLjpimEgRx(bt8Fmg-6sVH9YNMXA5zX(e5Q-7)hCK9k@CuJzEvauy+=tSKSCJAL3 zN1p&&#c30uV{Ez3)TUNrV@hKS0dJa@gxv8kt_r9(%Pam;-F9+l(E-IpFe=b%@IYhi z+iXStS97UQpvThu2WN`hDH`4dAUg?#L)x4Cx(4uPsna9q=o~ULuCP|y%qlT{9&{?nys0UP$GesKXT?ne z1&IyX?@4I2>GiqF2)jDsa$8UwJnx@tDog(fPLaOQ*n~@%5%^&qsFzeG%Oth zlmy}*fC+RMcS(tJy;SGtMn5JGT*FOj29}?6Cbx%_L@e}s#=v|Sd5?6&ybQ}A<=E*B zIUH}@6*w4sJohF(!=OX%Ipmk;=VoQK5-L$=B*s}xfME2vtm;B^WwQjxQE7z)Gq_cs zyDq0SvzQ-ouJsoO#^_R=g6V*N6kkAZTn*4;8PPS8CiY7iF(U^@1B@XoblFA$aW*hh z!=jfLi)DOW0}HZ6hB#he-%1sY!1;}7-slVqj-NrRjEh!VhWeuf#jeAb5T$(Hrv7Vs zRn4Tn1$jH_utcyAy&m1Jy^3X56Nd47U@3ruS!6%b1A9h|NRo|>4PYcuVM95l`)7c* ziVMd+T)Eme1!hMz*2yU-bjC_Llj1PuJagB8_G>PH$gf@J-C4TfpPf|J*d|>dz*zc3)ixB))qar?Lq9g<)QVTOe9-KPRv7#1LsI}g z7^7Ez@2<3mtS(h+pZzXybB1k7M}|&H8{*4q5=MM_fswSezryB^&-nznFTwGNUh~=< zYLGNF{JU|vB@wh#%)DDqL{n4Sm;<#C*Z@uM;4z^O=dq<5V0b?ZXqC%>a?+Ky-owl5oX$qq#PmLFx@^7HPfg=Qci7%P^J!!18xPpr0K} zkexPd?ejg(pa5)qA$qhssg0mj*2X5mBjcZD z{#rB}gc~3%yaj?fKx5umY~cnbJOQQ*c)^F?*k6718dQ;2lKB;tXKh;EFQx~Eq+yU< z+%*YRMAW?8F%Xb-D&}&l$|b0jTlkZ=VxN)@pIob(3=j7gV5(t?D+W`uHcRsB6(Pvm zm!`oZ$Ps8d>2RfWwLlheqv2bfUkHhs4bhKMnN9oBq!waIfe%x7_$u&q_t)94@3%UOR|_x@+4{L24C+6X>XxmF$# zUedIe3m~5QXOsM9=IfJgXaenf zn$V3mMPuazg47R`7B}1A=ES^FrUadPHi(KWe^PfHp0jiYd>)SqzRDTfSIY0 z-aerlfTauo+SF)M1Qvj~Cya4E56q*_+4%tSq-yI)El2{4woSXLh7}Ct0B#R}a5(_v z#+}V78Dk0zzXt&=ksf+$`5E))^i^NJ}W@+&r!v27w+K+ z+;Ok~!F%*ofcAL~yTB{}nYX>~)wtD%w&``MlHN0F5GeG#nNETNX^l3lthg;bp_aeo zw|`f&${1RvhB{Fnx>{Q}N8LkPhtx3x5%qqkx#7}rne&Al*HPUi=9t15u!j)h@lN#9 zlT;go-k&grd0E~Ny?-nH!8j>OyE;YgH5#xH*uPVyg2QJI+E>o}lV5iujjF@!wNv5i zciMCJtpi@Zc||GwxId!fSKFrHaea-dV96vUcfR!NJB zuDuPN75PsxGd=bpFbL;r+|bJ*?kTz)jD%EK3I`YWRyb>x=l+A0pFg9$p&$)tq62@r zR^tXPM@q@wyKLI-IoRYdg*$Ks2q86qp8YLY#S9eAZq&cs&2w^!W5N>i=R)RKM5976 zfenTiUaOcv0SaiI1)E28SC5#dirs~RNuJ)f*c~8@os&7@cFpX#NTQ6nQKBgoa~f`H zQ;^Fna@t%*K6$Fa_;VzVgj9Fc6J-n>EWAI2Bik`xc--6=w6aq1a2?vbVLdta^eBg! zSz2DU3zj)m1$f((mX&E8JJ{or<$__?B%+8Vn5bmp#ksA*!q%&ot9uvSdCr}NWmCeZ zO+a||E#$XLE(Mh5EkOS_;#+J_1Vb8-%{ai-65}(&d)Kra0j>M_9DUj}n#kkM%fcGXmz%p0iUWs|exWdUDeoAVKAw6J zsh$00u_T)RZI2|5pZUaHxq1)+DT0wCX1`4S66P_k>Cdx@OpF%3Mnq$hk2#X;4LRc_ z^BTIJqh4WNU8r@%um?1YguXRieIB@hFJfv=>bvO@TX1^8XpA4(f z!s40g*}8+px2Y1eAFRBp-pO#h+;tR}RsK^nkwgh*;3Q=2ff91S&GuC`g2}QwT{W1C z#zc04mxf(a@%w)Pon*-kPRq&o+3QLp|oAX4p*m*ES%1u<-pK<-7W=`57} zWs{Ah9iKQ2Lpgf%iS*)`uD4C1Dw8$MQIA+Y;+Ml4@36v0Z9 zpu{S$Ma+*PAl1hR3o6_#Ei6p-s6VxJbofJGybZi*e+^2{G_y~;Raj(xOV7Z-b6n)U z98di|Y97zaw<8nAH9Y3#G9beK4(n_vC(g*E0IY7FW`%OR@NN0rsDu4Ug312VEKiU< zfEFqVHg-gRR1+C2bTbtwG*kku0sWmowR-2|JU#L)@b38d`17I>4S^kv{Z)v!U8c8M zw~hq4saw)D1p`dF&*6c4WVu0r-raHkV6rOvI zoi$NgcT5YgJg}9p03Sq0zXw*r6o?+d(A2vC*s908TJM~+o`wVB@7*DBIlJ zdkO<2qMlHd`#=)8G4*H~=AP+8wWWZVca#wrI0*LqJ;(9Fd}3pbjEc(JNzs!lRWzo9 z>cslhV$I%Rlq>;P(+dR(&JQ>9AVH!cA`DyA7drccy!-SY2j*jko;8n#goX9`s`_+$ z9^Ztr?_LFy>e7AO)iRg>%g-O+cy^e7(kKRgGJON17|bL@SIEsB*d;OhumDwU7)Hp8 zgh`VKVo^}96fk~r$K~VTZa5P)EqIr2@iJN3#)|yF)pvg{m~>_C;Mkauh)B^-!>1Qo zIy&u=h4h(~r!Ro?{7k6CBuFcv^qTxh*7;fup@ z{Tb}0p9~DtTm20!tgPM|KY8$bRp%{KbUVIh=taJrs4(x35(tW9dmRR(5 zK3f_6qS&*jr$=1X{s0|#hs1bwyL}ycgc}+z&)X{Y8;B$lJ@E+%v0__wxHSsOGobRH zd|lE&6$HAw!9hU{iOnM5oaun;-u}KWJd{eIWoWMh7~JZMVO;4m64;SUSZ&$?Pa9oa zTD*PQBA1cD`m+5e)^GVw_wRv$UL$MTi`l%@1hj(wvSz$ArFnWI%0(_A%#&E)F~7LG z+mVRHb{&l5y?_DEMOd0Q>+~={5HSRi9uX1AC;VHizvcv3<2Oe!7N!fZCGBYR085ax zKHpAJYH;~&agiidyxR{-)$;6mjgn2szUHp=OCS-weFvbGY>nQPh-OXMiBkRPq@-VsesSPtP+Fex#|+LVzYDifX0H&#RYNELctzDteLF{2^p@P(-`d}EBk(s%FY6`tBBD|@ibBUxn{7I|{OP7*y&F49m>>69g1|RZ3 zMQJcPk@`|>P%D(1h~)F`ZUrc*Ieri8O-Y!cGX@lZ=Oh|IY);jI7iWhp+|;>}x=Yx^ zGjx%usQ2#zU*bK@FG_!Ni-}Sh=#<2L`cg>Ndl?8s?8TE0dp^B`P$vqfr}SQ0+S-9J z!B4M>%kS7*ZD~wHIlH<#HHR{Xc4&Rbg%Pg_&XcrmU@- zj7dm7D-`XfP%64IzQ!j-!%56f_Y9GKC&vDYycz2iJu^wj$;#xkXs4f$wo~Py97zg` zZeR8K;CZ7tL3w~ifZkHd1?Qp}!;NugcN48Q3>$^?OmKcTT!vnBI~x5UTim){pj zcaJy-BEl)*hyHt!j+VI3SdX|(xIe$qZyYSC)4Xt$uo!dL^1C1NCCsrBGg#i#zaeZ` zyv~(EM_t`ThLnA*$QoB9j7GO7df+>LtJmbTaWw}&-@WoS(=ek2hN15mvZ2}unVHN* z+H#n{bFrT(QtWCzIk6`Q5bYAX9FxCKH1G!U^Lv^21EO4IadG5@g}w5F&_}ZG-a!Gmlrty+B@EIDg^ZbN(VC0IPLY+%{Qc_Y68as&| z?jOOK>@NqFQ@g!G8Dv~pUr$aeyXP`igfz#DIv9;6%j@}3Xv9)sRL=9`V&&R<={i07 zG>NjJPb1=rijgZ@Ye1~ySj_ERC3t1AXBP~Ncw9~AC$A@M=Ejf3_}#y`3g4%vRtSBm znf^6A)!W;<;s|<1MoF1gu!AMReefdi-TZpC1@DW&A3tt^6UJ7r{w*XcH!asm>YRkQ z@!ieil7H%-ed%D*xN&^pq-tx+a1S~`Sm*Wl0V2tgV}kDVn}s>|!vvqzy*zHhFhdKI3{_u5^w z3wB`Gj+h6{G~X^-KV&-(V18R2uAU1gjAJzQ@X^D-5PZ>%)j;ymX^9*}I_9kg7oQ8q zh`Vc&Lt%RJy0*?9!>Rzsq2YvTD`dQFjTbTRO(~;pla_xiAt?7jF3VA2tKxekZwUGV z&`c@NTdUgb6-i#HMMi(nF;%6@YnQLyS;&@Ji`HtVHOIE=n^O;CO;T!EM zat}!hGv^Vn${@>hHa77h^H%oB>P?KqRH02@Y+xz}GTgy*+xIbPArA!gERX&8x8 z>Ly&QtUwt zFk{D!ck53O?8V1_s->9P^}Xc2f1*Hv$I+GiBh2F z(-z9))fJ-;4b*8*y_?Ghn-?VwBTQ@3EGhJ{P1-#!-1Tz${4e zWd}|63mlx*()@NuXB1c|mkRTxX5&{znlW*~v+&qg{xZcpQeBW9saE zeKYwr?K;oyd`Y!0%|AJ^7IP|SoG;*%DrHnGe^V+!gk}i}?7<@e3RL7nHf!bGdDao@ z`bG4N&g@Mhk1+UBk8G8q494y7FE>9QB{4CmwDi5IlP$xHN%&=L?XeicfD$PcxGI(tOS@S)M&<%pklj!p5#nuzUg@Ds zV9Va%va*{ML(*D>=UtdKqCLMe=U2Ty;In^pVA`33`$SsQtBbD2|1O9Hf(JI4qC8@e z`*E$t@_+n#O6h>6O}UReU2(C19Na?VaW52$Bmd{EYTgWo)Q)w7yp)f|QQdnUNd`uq zu@{qIz0RrJz}byY*zTUV!*O1JD{A%8>2sPuDWh22%mz3>C2!%!)9S)!QBE57dh(rp z!SMK(4W>OL2-qB3i~+m#8Xf7mvAt7-6&`P%{qV=17%Q`uI48jtlZnsiU5L?%YCYs% z!C|xBd!}FYl{!DI{o?M3@g0RebCZ=1%upQK6-PPofN7xwEE5FZY@*9p8x2en21dJ2=5e=r4 z%4`3yU>(}pJzBeS-WzbYACkA-zDqtSof8-H@Hun*b~}V?Sax}x^&^8Guao4=B1H@y zH>1TUP?0$9Z+Yfi(IA*RZ6EjXvzlCa&Rboj;1RQ7Leo4O-_Un;qb!-0YsM+*<>8+% zot&=Du98zySe*ua)se4~N90zjom)OAWVF=yJY@PQI(=}CgG|UPg?4&+7S51{=JMv* zBgdAe@1&aPE#JHEOk0o z_v`I6)tcvMWsqp52QAfHctkK8Bjf9`>3#a7-Rup4#RuIqowC?`ArEF-B`W|2B;UP{ zhK31F{Tjd@%}obMULPElRw*MI`nT(suGLvC5D^tj%z}qQXEOa4zAs6U8ost9J62d81F6zqXhg zV41lut;BJf7z3)KQhT2;OqM*hNGK_N=KNZ1cHEY3dGZtQM0pFfZ0*S?DPdj}KYs8$ zSlX8eL~ha%aXlB^#gpNIC&8A|-dmHXT5?(4;8(s6{X|7JATOUhFtE0(TGh>IiLg~X zI!PxX2#HS_A)-yEvkvX3x58C%bEQJRXXB99?uX9i#)_!m&MVQT^u3UFcK7Uy)MoAQ zGd;5XuPUX?3X_&Ow`n-cpG6M0-Jp^p29GuMd{2DM_t>`Ree zdlizDaE@8hly@ZsJ-zLWvD4j?7|hB!=F7!= z+MhcbY28oOAY3}|=(6zQDCHI?70NMryX*C2C{*-VbVMV0+YK{hm52;*h@U7AC}TC) zv2&B%RvCIN`Z!+{4T{|pVC5pHurDo^d|4kdUzsb?IKxL(u0xb(eDb`GqvYEW8}&Dg z%;KzQ^m)>wc@ZRtx0Xikz@YsJe8^*sQ&xug?HcCi#VDe=uB)LZY)90GAF6&0s_)H^ z@$k*03diIxB$6XmO&ElRd<+lmjDL_vP*Q%T_@z|UW737U6opY>ru~8>YiT73LzZ39 zU>IUcEuVRZUC9t5OfR@Fz5|8AVFvDYM~f}d)KASl?oxqeoS?xA3(4;}+ipX*h0R)z z*dJ#MPCB?ckA;aTy%4E97rT?fAX{rC;}Sn}p#PY-A8dBwMzLX6VdZ6E#7shAp4W!J z<~yh&W(sXhD7mu?kZY!sd>O!|Pz!Mtei0ZA^Omr*QNva1;XhLZ>|fHqYw^ zphr*}KNGE^Ntyh=wvIoKhXnVKK&y-GrVu@O_kBGMGwTF2S!{8{%y}WLTv1_q+qPu1 zj1aF1X-U6-omTuW$ZF2Eo`Y~#7VEWwK!Pe2`o}9{gm9js-gFDD$G9)U`|NXN- z9{iI&f+R&=DP?b|(}CY0%q4ewvYw3dLzq40iR5Q!ekTYljI!t@(e+j=S)d#F<@}m* zQQel>IIWdP*z`i-~;c5!IM?KG`YZ%%#kbH}JJrcnq=zp6wMiLCm+oqugdmzY?sKH#=sgVNl>HNK#T=%mHLjosyUkRD*kK3cMWJ);H%IY5i zg$)Z@=IoQs_i#~hdTipXw~P7sJQ`un6Gbp0CdFil7oYD-_aiB;vpAwyPLmnN&MBfW z+H;zwZx2-XHphD3Y14!3RAV;~<%o6H$heaE!S#}OeZk4x(N&@eDQ=^+*$R8$Wd?13lSxPZo-Kb=DUfRszV z-@;~?&2T)taht26qqjjL#J?VC>m&=2ih5{N*0_(*)a&60OD+=XM2dM^3OC*rjm<^4 zz^Iu5tK1Th+0j$+U9%HNh8^sn>oeZ+b8>DQtTBjx8IPhVSX8MxK z{B))p!p7<(FO|Bd>*M&nSJqShaY+LA?CwveJWAD8m(D_IKYL7UgY^CfN;FO?Go?5& zU~NLfKAzjiU|0_W+3b%D>Xov+?-f*2QKRBCLEI!~e4ts?*Y_cKL8d%Kk(65`!SP2* z!Ng2$GgqyZhzp9cqmh}^6pIFELIPk+hTK$FrHuIr7As{y8^L1>|4+ zUn~&GAXaAkuQl8|(F7*8^EvO%MZ$8PiOhhUhXPTywt$u6rDD9+L&)xnSIkqI>ELPS zkJ0fk!M<3UdZ?g~E2R*>Ls&&ybNLJWI$TN%i|#d=v&nj-s>T+|HtBRK$uZ}Sig|j7 zS|X}5PR&ADh&wD6eGf;&Wj4JD;D-Zc_fCQ25EL7lS1;r@-|^r*H@M52Z1z8 z-QO#IwpLQaSOP`lI;ezW`vNT{-2gZ{E(v`g6Ls2LaBQ*BxjiLooS(3$?6YkHrEJn7 zqW&*iTP!JtKfwDEc(`O?EhA#ZbfzI(unmsKkv??n$#RvoNT^EITPEc6ewY@Dn!vzH z>iHf)C_6f)vG>zns@Brp1uQbLnl>4tARE4SAv%=n!%l)5^en)F?fg>xyF~UjDkGX* z0}ZzwL&G%mm#(glz|yx)l@f%j%Axrm+wvX8P>gu66Q;QBa+;j&zr<;$jE~X#_7eIR z<_eQ`O5RtXsZuly4beZhsA^BO`!Wc(314JsWL&Bsm$KJ^>SGBxwVl@1qMWdKhXncC z5(FY7QFAD%CHmQom}|z=pXy`Zd;T??gJ~H1XBd#4%yO_RiJQP&) zRU+P-Ff4p@+*X2c8-M(svN(#3+XtS*3iDMEk@RB73>85#5oHOcaTg-sq^Md!wxQW) zaq{yi-~QKXS0l#fx@*2ubeYt{J!dqZ-uiw<(2EK8#|w`K*DnVp@Cv8-4Nm(5(V z@CagIt_DDmHw;;+i&mDrP1@9@^(b=E)bI1OOMGr0u2lr8q~5xj&1ubERhofuVfmUO zobsr1M=FQJLWw5ET9)O*p|f**Y9_e_iX}@KFEJxYmH40qnfo{<)e|3}ROoRC66=1u zO|>E@P2x-|yQJS}oP|Q#CiyK+svJM_7#4IKmGP7H%A7AAl_6;qL)IeNHnGNy4NfU3ncefr#v1 zpqtu9o|0DBQpVqzDf*7+^gYjXI_zPYfFHa~lhWh(Zx%G9UJ(@c>Rd^U7dU&jJlAKB@ zB_k;osSOfkQSYYux<<-gn8UR-DVMHJO z@@}3|a9o6*wB+AGV)!tylpOYS9Wq-2V`Fxkn=>gGvW_#`CqA`3_oLU4G^+aWccD+$ zE>WL)$FA`vW^~x9@Z$80f?R&+9Hvg^mF2+p@*FS)`)CQk7HuB5=NCMYv= z2){&o%7$f19+UCPygdIj4dq@syg-(3E2!~!jrap z2_HyDuf^=v+A6uwPOS$_@86k8KZ;=*R=F(C66y?TEw=OY-Cw2&rscw&JyRm#nu~c% zyp!BH{SWLNJHk0d<&u9@StzWomt&A;q_5dWhTalw>DXp|b8KLN_Q8{gsAU>wjoF)c zCl~F%>^PdNOlt_5>??Qu({J?uQ`CALihF+iT~h&n3x7ubTfGc~`rl)rorFN1E8MB) zA*;hy_x%kxaI3=3ztRs@tJI9vMUM$$i%0D%PHbcy?~l({Z@p|Rdhgx7^3N=yhWt%m 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 W(c{E_oBS5|M@T@NKbKeC_5TB^_)%m4 literal 0 HcmV?d00001 diff --git a/src/main/java/com/booleanuk/core/class-diagram b/src/main/java/com/booleanuk/core/class-diagram deleted file mode 100644 index e69de29bb..000000000