From 16cebab7438662c00b60444e7dc87e164fcdb927 Mon Sep 17 00:00:00 2001 From: Deepak Mishra Date: Thu, 5 Oct 2023 02:22:07 +0530 Subject: [PATCH 1/5] Adding topology model classes and junit annotation processing Signed-off-by: Deepak Mishra --- .../extensions/TestSetupExtension.java | 55 +++++++++++++++++- .../TestSuiteConfigurationExtension.java | 9 ++- .../annotation-processing.drawio.png | Bin 0 -> 30892 bytes .../junit/support/model/ApplicationNodes.java | 24 ++++++++ .../support/model/ConfigurationValue.java | 24 ++++++++ .../support/model/PlatformApplication.java | 32 ++++++++++ .../support/model/PlatformConfiguration.java | 27 +++++++++ .../junit/support/model/ResourceShape.java | 18 ++++++ .../junit/support/model/Topology.java | 30 ++++++++++ 9 files changed, 217 insertions(+), 2 deletions(-) create mode 100644 fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/annotation-processing.drawio.png create mode 100644 fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/ApplicationNodes.java create mode 100644 fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/ConfigurationValue.java create mode 100644 fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/PlatformApplication.java create mode 100644 fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/PlatformConfiguration.java create mode 100644 fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/ResourceShape.java create mode 100644 fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/Topology.java diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/TestSetupExtension.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/TestSetupExtension.java index 4ff797802..79d7b4c1e 100644 --- a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/TestSetupExtension.java +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/TestSetupExtension.java @@ -16,9 +16,18 @@ package com.hedera.fullstack.junit.support.extensions; +import com.hedera.fullstack.junit.support.annotations.application.ApplicationNodes; +import com.hedera.fullstack.junit.support.annotations.application.PlatformApplication; +import com.hedera.fullstack.junit.support.annotations.application.PlatformConfiguration; +import com.hedera.fullstack.junit.support.model.ConfigurationValue; +import com.hedera.fullstack.junit.support.model.ResourceShape; +import com.hedera.fullstack.junit.support.model.Topology; import org.junit.jupiter.api.extension.BeforeEachCallback; import org.junit.jupiter.api.extension.ExtensionContext; +import java.util.Arrays; +import java.util.stream.Stream; + /** * Handles the individual test setup, configuration, and resource deployment (if applicable). */ @@ -28,7 +37,51 @@ public class TestSetupExtension implements BeforeEachCallback { * * @param context the current extension context; never {@code null} * @throws Exception if an error occurs during callback execution. + * + *

*/ @Override - public void beforeEach(final ExtensionContext context) throws Exception {} + public void beforeEach(final ExtensionContext context) throws Exception { + + var testMethod = context.getTestMethod(); + + if(testMethod.isPresent()) { + //FUTURE: add support for NamedApplicationNodes + var applicationNodes = testMethod.get().getAnnotation(ApplicationNodes.class); + var platformApplication = testMethod.get().getAnnotation(PlatformApplication.class); + var platformConfigurations = testMethod.get().getAnnotation(PlatformConfiguration.class); + + // Convert the annotations to model class objects + var appNodesBuilder = new com.hedera.fullstack.junit.support.model.ApplicationNodes.Builder(); + if(applicationNodes!=null) { + appNodesBuilder + .value(applicationNodes.value()) + .shape(new ResourceShape.Builder().cpuInMillis(applicationNodes.shape().cpuInMillis()).build()); + } + + var platformAppBuilder = new com.hedera.fullstack.junit.support.model.PlatformApplication.Builder(); + if(platformApplication!=null) { + platformAppBuilder + .fileName(platformApplication.fileName()) + .parameters(Arrays.stream(platformApplication.parameters()).toList()); + } + + var platformConfigBuilder = new com.hedera.fullstack.junit.support.model.PlatformConfiguration.Builder(); + if(platformConfigurations!=null) { + Stream.of(platformConfigurations.value()).forEach(config -> { + //FUTURE: support values[] + platformConfigBuilder.addConfigurationValue(new ConfigurationValue(config.name(), config.value())); + }); + } + + // Topology holds all the information needed to provision + Topology topology = new Topology.Builder() + .applicationNodes(appNodesBuilder.build()) + .platformApplication(platformAppBuilder.build()) + .platformConfiguration(platformConfigBuilder.build()) + .build(); + // FUTURE: provision this topology using test tool kit here + } + + } } diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/TestSuiteConfigurationExtension.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/TestSuiteConfigurationExtension.java index 4f641c921..127734e9e 100644 --- a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/TestSuiteConfigurationExtension.java +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/TestSuiteConfigurationExtension.java @@ -16,11 +16,17 @@ package com.hedera.fullstack.junit.support.extensions; +import com.hedera.fullstack.junit.support.annotations.application.ApplicationNodes; +import com.hedera.fullstack.junit.support.annotations.application.PlatformApplication; +import com.hedera.fullstack.junit.support.annotations.application.PlatformConfiguration; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.api.extension.TestInstanceFactoryContext; import org.junit.jupiter.api.extension.TestInstancePostProcessor; import org.junit.jupiter.api.extension.TestInstancePreConstructCallback; +import java.util.Arrays; +import java.util.stream.Stream; + /** * Initializes the test class instance for the test suite. This initializer is responsible for reading the class level * annotations and setting up the suite configuration. Additionally, the individual test annotations will be read and @@ -37,7 +43,8 @@ public class TestSuiteConfigurationExtension implements TestInstancePreConstruct */ @Override public void preConstructTestInstance( - final TestInstanceFactoryContext factoryContext, final ExtensionContext context) throws Exception {} + final TestInstanceFactoryContext factoryContext, final ExtensionContext context) throws Exception { + } /** * Callback that is invoked after the test instance has been created and configured. diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/annotation-processing.drawio.png b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/annotation-processing.drawio.png new file mode 100644 index 0000000000000000000000000000000000000000..bce8adc13258bd8498d387b9a3eb34a783147d52 GIT binary patch literal 30892 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 literal 0 HcmV?d00001 diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/ApplicationNodes.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/ApplicationNodes.java new file mode 100644 index 000000000..1a77c21ff --- /dev/null +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/ApplicationNodes.java @@ -0,0 +1,24 @@ +package com.hedera.fullstack.junit.support.model; + +public record ApplicationNodes(int values, ResourceShape shape) { + + public static class Builder { + private int value; + private ResourceShape shape; + + public Builder value(int value) { + this.value = value; + return this; + } + + public Builder shape(ResourceShape shape) { + this.shape = shape; + return this; + } + + public ApplicationNodes build() { + return new ApplicationNodes(value, shape); + } + } + +} \ No newline at end of file diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/ConfigurationValue.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/ConfigurationValue.java new file mode 100644 index 000000000..8fc53d179 --- /dev/null +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/ConfigurationValue.java @@ -0,0 +1,24 @@ +package com.hedera.fullstack.junit.support.model; + +public record ConfigurationValue(String name, String value) { + + public static class Builder { + private String name; + private String value; + + public Builder name(String name) { + this.name = name; + return this; + } + + public Builder value(String value) { + this.value = value; + return this; + } + + public ConfigurationValue build() { + return new ConfigurationValue(name, value); + } + } + +} \ No newline at end of file diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/PlatformApplication.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/PlatformApplication.java new file mode 100644 index 000000000..92b46b57a --- /dev/null +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/PlatformApplication.java @@ -0,0 +1,32 @@ +package com.hedera.fullstack.junit.support.model; + +import java.util.ArrayList; +import java.util.List; + +public record PlatformApplication(String fileName, List parameters) { + + public static class Builder { + private String fileName; + private List parameters = new ArrayList<>(); + + public Builder fileName(String fileName) { + this.fileName = fileName; + return this; + } + + public Builder parameters(List parameters) { + this.parameters = parameters; + return this; + } + + public Builder addParameter(String parameter) { + this.parameters.add(parameter); + return this; + } + + public PlatformApplication build() { + return new PlatformApplication(fileName, parameters); + } + } + +} diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/PlatformConfiguration.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/PlatformConfiguration.java new file mode 100644 index 000000000..381d66fbb --- /dev/null +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/PlatformConfiguration.java @@ -0,0 +1,27 @@ +package com.hedera.fullstack.junit.support.model; + +import java.util.ArrayList; +import java.util.List; + +public record PlatformConfiguration(List configurationValues) { + + public static class Builder { + private List configurationValues = new ArrayList<>(); + + public Builder configurationValues(List configurationValues) { + this.configurationValues = configurationValues; + return this; + } + + public Builder addConfigurationValue(ConfigurationValue configurationValue) { + this.configurationValues.add(configurationValue); + return this; + } + + public PlatformConfiguration build() { + return new PlatformConfiguration(configurationValues); + } + } + +} + diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/ResourceShape.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/ResourceShape.java new file mode 100644 index 000000000..1008bd822 --- /dev/null +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/ResourceShape.java @@ -0,0 +1,18 @@ +package com.hedera.fullstack.junit.support.model; + +public record ResourceShape(float cpuInMillis) { + + public static class Builder { + private float cpuInMillis; + + public Builder cpuInMillis(float cpuInMillis) { + this.cpuInMillis = cpuInMillis; + return this; + } + + public ResourceShape build() { + return new ResourceShape(cpuInMillis); + } + } + +} \ No newline at end of file diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/Topology.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/Topology.java new file mode 100644 index 000000000..7dd815a45 --- /dev/null +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/Topology.java @@ -0,0 +1,30 @@ +package com.hedera.fullstack.junit.support.model; + +public record Topology(ApplicationNodes applicationNodes, PlatformConfiguration platformConfiguration, PlatformApplication platformApplication) { + + public static class Builder { + private ApplicationNodes applicationNodes; + private PlatformConfiguration platformConfiguration; + private PlatformApplication platformApplication; + + public Builder applicationNodes(ApplicationNodes applicationNodes) { + this.applicationNodes = applicationNodes; + return this; + } + + public Builder platformConfiguration(PlatformConfiguration platformConfiguration) { + this.platformConfiguration = platformConfiguration; + return this; + } + + public Builder platformApplication(PlatformApplication platformApplication) { + this.platformApplication = platformApplication; + return this; + } + + public Topology build() { + return new Topology(applicationNodes, platformConfiguration, platformApplication); + } + } + +} From a422fb47e8cdb3b8c95aa7b87512ebc4c9adf3f9 Mon Sep 17 00:00:00 2001 From: Deepak Mishra Date: Fri, 6 Oct 2023 17:05:11 +0530 Subject: [PATCH 2/5] fix javadoc compile error Signed-off-by: Deepak Mishra --- .../fullstack/junit/support/extensions/TestSetupExtension.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/TestSetupExtension.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/TestSetupExtension.java index 79d7b4c1e..68540b009 100644 --- a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/TestSetupExtension.java +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/TestSetupExtension.java @@ -38,7 +38,7 @@ public class TestSetupExtension implements BeforeEachCallback { * @param context the current extension context; never {@code null} * @throws Exception if an error occurs during callback execution. * - *

+ *

annotation processing call flow

*/ @Override public void beforeEach(final ExtensionContext context) throws Exception { From 6c3bd1f485ef8eba59e10fd0dd3e0d44d4101a0a Mon Sep 17 00:00:00 2001 From: Deepak Mishra Date: Fri, 20 Oct 2023 19:29:47 +0530 Subject: [PATCH 3/5] address review comments + spotless apply Signed-off-by: Deepak Mishra --- .../extensions/TestSetupExtension.java | 44 ++++++++-------- .../TestSuiteConfigurationExtension.java | 9 +--- .../annotation-processing.drawio.png | Bin 30892 -> 33069 bytes .../junit/support/model/ApplicationNodes.java | 19 ++++++- .../support/model/ConfigurationValue.java | 19 ++++++- .../model/NetworkDeploymentConfiguration.java | 48 ++++++++++++++++++ .../support/model/PlatformApplication.java | 17 ++++++- .../support/model/PlatformConfiguration.java | 18 ++++++- .../junit/support/model/ResourceShape.java | 19 ++++++- .../junit/support/model/Topology.java | 30 ----------- 10 files changed, 156 insertions(+), 67 deletions(-) create mode 100644 fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/NetworkDeploymentConfiguration.java delete mode 100644 fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/Topology.java diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/TestSetupExtension.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/TestSetupExtension.java index 68540b009..8ca3248c4 100644 --- a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/TestSetupExtension.java +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/TestSetupExtension.java @@ -20,13 +20,12 @@ import com.hedera.fullstack.junit.support.annotations.application.PlatformApplication; import com.hedera.fullstack.junit.support.annotations.application.PlatformConfiguration; import com.hedera.fullstack.junit.support.model.ConfigurationValue; +import com.hedera.fullstack.junit.support.model.NetworkDeploymentConfiguration; import com.hedera.fullstack.junit.support.model.ResourceShape; -import com.hedera.fullstack.junit.support.model.Topology; -import org.junit.jupiter.api.extension.BeforeEachCallback; -import org.junit.jupiter.api.extension.ExtensionContext; - import java.util.Arrays; import java.util.stream.Stream; +import org.junit.jupiter.api.extension.BeforeEachCallback; +import org.junit.jupiter.api.extension.ExtensionContext; /** * Handles the individual test setup, configuration, and resource deployment (if applicable). @@ -45,43 +44,48 @@ public void beforeEach(final ExtensionContext context) throws Exception { var testMethod = context.getTestMethod(); - if(testMethod.isPresent()) { - //FUTURE: add support for NamedApplicationNodes - var applicationNodes = testMethod.get().getAnnotation(ApplicationNodes.class); - var platformApplication = testMethod.get().getAnnotation(PlatformApplication.class); - var platformConfigurations = testMethod.get().getAnnotation(PlatformConfiguration.class); + if (testMethod.isPresent()) { + // FUTURE: add support for NamedApplicationNodes + ApplicationNodes applicationNodes = testMethod.get().getAnnotation(ApplicationNodes.class); + PlatformApplication platformApplication = testMethod.get().getAnnotation(PlatformApplication.class); + PlatformConfiguration platformConfigurations = testMethod.get().getAnnotation(PlatformConfiguration.class); // Convert the annotations to model class objects - var appNodesBuilder = new com.hedera.fullstack.junit.support.model.ApplicationNodes.Builder(); - if(applicationNodes!=null) { + com.hedera.fullstack.junit.support.model.ApplicationNodes.Builder appNodesBuilder = + new com.hedera.fullstack.junit.support.model.ApplicationNodes.Builder(); + if (applicationNodes != null) { appNodesBuilder .value(applicationNodes.value()) - .shape(new ResourceShape.Builder().cpuInMillis(applicationNodes.shape().cpuInMillis()).build()); + .shape(new ResourceShape.Builder() + .cpuInMillis(applicationNodes.shape().cpuInMillis()) + .build()); } - var platformAppBuilder = new com.hedera.fullstack.junit.support.model.PlatformApplication.Builder(); - if(platformApplication!=null) { + com.hedera.fullstack.junit.support.model.PlatformApplication.Builder platformAppBuilder = + new com.hedera.fullstack.junit.support.model.PlatformApplication.Builder(); + if (platformApplication != null) { platformAppBuilder .fileName(platformApplication.fileName()) - .parameters(Arrays.stream(platformApplication.parameters()).toList()); + .parameters( + Arrays.stream(platformApplication.parameters()).toList()); } - var platformConfigBuilder = new com.hedera.fullstack.junit.support.model.PlatformConfiguration.Builder(); - if(platformConfigurations!=null) { + com.hedera.fullstack.junit.support.model.PlatformConfiguration.Builder platformConfigBuilder = + new com.hedera.fullstack.junit.support.model.PlatformConfiguration.Builder(); + if (platformConfigurations != null) { Stream.of(platformConfigurations.value()).forEach(config -> { - //FUTURE: support values[] + // FUTURE: support values[] platformConfigBuilder.addConfigurationValue(new ConfigurationValue(config.name(), config.value())); }); } // Topology holds all the information needed to provision - Topology topology = new Topology.Builder() + NetworkDeploymentConfiguration networkDeploymentConfiguration = new NetworkDeploymentConfiguration.Builder() .applicationNodes(appNodesBuilder.build()) .platformApplication(platformAppBuilder.build()) .platformConfiguration(platformConfigBuilder.build()) .build(); // FUTURE: provision this topology using test tool kit here } - } } diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/TestSuiteConfigurationExtension.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/TestSuiteConfigurationExtension.java index 127734e9e..4f641c921 100644 --- a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/TestSuiteConfigurationExtension.java +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/TestSuiteConfigurationExtension.java @@ -16,17 +16,11 @@ package com.hedera.fullstack.junit.support.extensions; -import com.hedera.fullstack.junit.support.annotations.application.ApplicationNodes; -import com.hedera.fullstack.junit.support.annotations.application.PlatformApplication; -import com.hedera.fullstack.junit.support.annotations.application.PlatformConfiguration; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.api.extension.TestInstanceFactoryContext; import org.junit.jupiter.api.extension.TestInstancePostProcessor; import org.junit.jupiter.api.extension.TestInstancePreConstructCallback; -import java.util.Arrays; -import java.util.stream.Stream; - /** * Initializes the test class instance for the test suite. This initializer is responsible for reading the class level * annotations and setting up the suite configuration. Additionally, the individual test annotations will be read and @@ -43,8 +37,7 @@ public class TestSuiteConfigurationExtension implements TestInstancePreConstruct */ @Override public void preConstructTestInstance( - final TestInstanceFactoryContext factoryContext, final ExtensionContext context) throws Exception { - } + final TestInstanceFactoryContext factoryContext, final ExtensionContext context) throws Exception {} /** * Callback that is invoked after the test instance has been created and configured. diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/annotation-processing.drawio.png b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/annotation-processing.drawio.png index bce8adc13258bd8498d387b9a3eb34a783147d52..71aee8859da974c18d8b73a7ffbdc08b131b9986 100644 GIT binary patch literal 33069 zcmd?R1z1(zwl@qYf|NliDJoJT-Q5Dx2nYgF(rmgnrGSzu2ugQKC`e0)fPjRwG*Wxh z$fh>+&86VqbMHClJNLc!z2E(w`}hEB%{6n>9OE~~^r@<{93dVB9tH*mq5N%Wbqowl zIQS{TJp)S0Be7k;A5158IZ2GdPAVh@#^oqy869U^_lK4?W*GEbQoo+)IoT~>PR{gP z()661rjAB#mM~U(8y9m+JMa!Z+QLjNA6lB3{;I&q&dJ5f!OqIbuF1hg&n3al4}Nj5 z-{NNH*8NrA$lT2CxHq0#?4SciB_k6{J7<`a1wEG}c$c?xHnRbLK{5EPq5*#CfFBNa zLk=E8J|^%eVQ+6^rfp`dXz5JPDa*sfcZ-V`6f-K`)>OJf&nX3-Z7i+Lz#lm?6KfdM zM9RVuW(!JWIXF0Ou|xkrp@z{zBS*_Wx`5VW=4@pCYb}~wZZ;OWuD4k&C8Tw@1dQ(3 zX-WKAgR7aNlO@dVWXZR9ZgKtk;Ot><_N&y)))>$PP>4$gkkZuB$lTG$7IbfUOeiC1 z1x{&mPDOclB}Yd)4jVfuEskG(*cpL|{-m}lpcU)S(x08!y308l*;^>VOn=hH)csd2 zZZ5uG4NX0M74We0{3tkH6R&om4(9aI!Emg}MDP)=#=Q!eF4O%uk7yGP8kX>x3@9 z+R6TdufON-_*-QEc>_fScRMatN!8n2?0l@Z@2K83HL+vm{#t zn6RUV4tQa|#RIbS}Y$T0Ltj&K;`j0A{{9L>oK>vYKLt-JF$1a( z$N}cyXl7&NZ0Y)EB~EsuWBE1zUGG?HZQWI2z%qe$$EwD~aXiqmrg5Ce=t&p9CVJco zEc#fozyna;lkR^`>u1qVY5e<=`OnDVYGmVbyaak~b_qK>m@`-v%+86Plh+22Nz&L6 z%=s^Y<8^R>G~g!-S)G3BKQLtM99;HbU4T0$-@%hPRL{!A4zjH5&St>w|K#0YeR2LJ znh^KhEG(VPH0+Ija?uT#Cs6i>7+M&aShzTv$wB4P+~6D7TWtOi5lJatDNaa0|KoB8 z$>Xv3Lp#ks7BXP0oz0FJ_z%S5_$w#xu^l;PFaPnY+h11cx9zd`!y<7X*E^AdKLzP; zMBtzBTi3)*!Hw0Bhs#hM=4{2muAwb$&C2ngvmFqF{&Tj2n}-kd@!NW^f_?M1Ir;Cj zAU|iIYUXGO6xj^2OwiK)CA0F+%*CH(1t=?Ir2gwH$iK??e>TBC6y4Fx2)GmMMt>?h zG~xdxnt7sPCx-V#Q~y-WlREz`s`+b&`5XHGN4Iq+YcppP$lLip)YE@!0sqks{ZDM` zKd{FC=bCk_Mt^G7-?wc4v-ItFHh<`w2~ap^D1=Zpb9RF{T1%VR+rT_*fgzHD**&y0 zcX9l=<$?+z0Q%{V!;GyU@A!Ywe#yo8xBDg6i97U%R&t&=>wjwHiT3{2Zb12w00on)c{{MLA|JQxJe=ED(Co=i}Cc7sx z{-2TEe=nu>Fnbpenm`8U#GaTy``_wjyIVTzK!g7R4Zs^T6$ouG1J8fW1bTryF-ST8C12rK;Qw?B z{;uD9T<^cm3qKC7|4kgv&CdU8+Q;rB*NO6<$j?8B z|6j*~y#FEj{JRm`zlr|MxJ>wgd+^Vq|9?rk0Lb*yNd75a|92!w!qL$P!jVqcYY*W= zKTY)C7c`y|!8#T+&SOLM8*%)%f_bvL{Qdf1WB)aSzaXUl7^-wasXrWDsXOvuL5#94 z&H$(ZP&pvn{~w%%e<&FLx(mQ_qO8Zn{yUq^e-+#V821+n4PO2R%0FS|$sxhX`|~6;okLRaK4#yg*k)}sgsnGas`*d zlUxF`2@Cf$iJIDZRf$YDTzXWDD)E);bk`rF;1dEygG#qQ-YALxQ0+ChH@;2aWxn#| zXml^$sq2e~HV%I5hT`4=>u3gdc8;HK-IYXRVs(9z&#_n^A9=Sv>{lQQ#=Ix+IBZgxW9f@otW6B zN5#KZ$uu@QdEJM>mcotu&;=~E6q z8l6E399&dEYF?>jAr=mxX!Qv42@PqS*ftIi4sFuzTZlgS*uCy&dyGsF6F6kFcm_K76uAGzexV*lvD5(4zyr$dF$kB zM)ihdLxYrBs(U0)-YE&DFI+3~!$|TLq7Z7Xdwh|HBE2(oHQhe<$88mP+0mC={5wtT zL;|mAyc}n5u1qH(Pd%q1e-vVyBpIGP@i<@3h(>Q`#f5)k#Cyfd4$h)h!eJ#QcG{r! z<+G%upwHJv-1p~5{A&f6TR8^Qe-dJ2uuv&grGERSKIWeJhd{r2Gkcef2PqdXS#MLd zrQEz%EwEp`)iUt4>yq5iLSrD~{WPkw2v58MIW~XuT*o2KcPvt4=auCZl_iIQG8ub| zMZEI{nvjNblM96|?(SO?`_c|(Eff`GTavqTk#y)U5X0^jxAWAlS3gL$vbEgAJK zal9H4-f7y)nczDgs2J1ON^AZd-Oxc`5wNu@Mwb3eg=t4*94FQHmc-24M2l|Nn{^#> z?d`C&&Y5xV`z3Tv&zyzuj3{GLH519!Y`e+keU8q=mhHc=o)}iqZAyK!VNG6NuI6QM z#J+u2E+x4xUdrm8ET(_0nRBTo3vZyP#8&5KC_fE1cA~lMr+(`EZ;Q6<4}=x^Yyxa) zMIL3rx&ne#(ox&bBk%&^;d>%VBVf*aD!WjguJ}2gLI-v@p_weQV z3I0ms8;>^8Q>@;~%-r7)DUG!%6Vk!C`CJEDxno>8o1;QY4ccBy{dcCQkL*tEKJ`yJ z6QW(zrE;^pGkCIF`ZqjjEHLg(| zFE7|>viIKA z+?vVV(ade6V~D%i#tY{sMp@UflaT6)v`$@vdr~+H#)h$L-0IHWJgebEre->@MjMsN%iu^F|XIQ+_?zX-E0NLRx3Hs1 z7DvXBr=~`7PPMEvebUTb?#(&hO{ncw)QC);7w%pF>rl9kqoW4aLE6+I*9+FM8B3^GuVTRdmN91rQPM5lrZX%kfg1+&*B}e3Dm@YpY65YZM@=YJio*W& zZ_8>y55P>qkiBUC3F3qEZ@1YJ?ujHzahG1AdS^jkM>7$14P|*D{sxXG!_=oANc#%tHFMR5f27TnBBZ-0z+QTZSv^W^;TAm4Jwb$_ExNQ;aMxZG#LpWe-%

yt`kB-qvD+NQf{(nd#Os@Znwu; zu5QbaOWgf{d7{}mr$xQxBq>#nNha~w=OiynQv+A}s@Koe;GRaGi@r@%oQ9RxJ-_Ez z?@p9@W0WAcT3fBwyth~Vt(Sr!(R5FgtGD|lBJaaa_%*u8LByfpmhToX*exno-Hes? z9o$2rJe1l~FY`vbViC=z;imy=U71tfB66Z0knh{2(tt^4NJD2=xzp1zSYpIH3 zqe~6s7U44|`Bfea_t&*9=gALDoetVXR^gN=y$w(1fGX*wuAe%}!JZGazf_xCzy(_5sX3Fpkb;=?lQHoXULUor|mu;g*g%gORG8U zOKkL(5rf=vCLU_BW{n1>d*$=omUH~X8j*-dFPZ&tD*0RA^b2UW^ddTR-{H}nw87~w zFvB#-MY|N$e5CC2U~}7beW5jL4K zRK*fpR7CqNWT==p#deD1DzC6VH$sf8mT=gpJ$Q^i?%BlE?ye$7S51`^m|U}CePNz> zvczDqNLkqRZuS?iX;Q8(*mlZjDhXR@XeLu{+W z&ZB`7W_+~NaCtuQ{d2x&R0&6zM@pO4o0q<@6*cRN1Y1ScevH?%Abb|l4!eMu*A@`U zW9TlwW+L!F`)n>IlA8_1)~mP3QDgMC z0Pn2{_9aH|D=4Li%nenYC%nnso)7C=B);h;lLaEpG(GWB^dFIQa@LebC%4O_B-8dU zy@?Q?=p>kXFm~5p)V4gMkNz!r#5MO7FIh7Jd2$n}$SJVx{UC(5J(7vSS;nfOBsD^z zlqQDxc!KFt-*xCm1pxC!xPEt346GRhvKoO$VR-vL&>Mi zNzFSR-t?>sG@d^#rBHFZdJ@6vJuDg40N?_i+y7>#oq#5dov!TD|8eG(dvxL%I_C1X$Ct z8FVYvxSS$HN6yz6M++ty@3rL%F2)1Z}@7*I;Rq);vKxd_1Od~!lrv4O9j4Q@FZb< z+OCHP{EEGAto^!~+QY$hHB4fE&PTaLogi7{z{_&lQZn_vN$Itxcm*s8XiHud*UM28 z!tNw2O>CigB-KHpA{W1g-oIzq*Oq@J+E_q@{#vloyb53O`Yqc-WbMP7Z*ln8Ja#t( zBN8IW5qb*pmJDKeIg%6h%0Jea^zrEhz7UP?A}RY*yUh&*sg=nIvzuC+!{RDQ7=$?~N4pmGYrcFGLEJ za4k28>@QmwC}r;p-=ayn{WP-SDJjPR}rX?7BRDCPq}>|IlyKKdG4 zuy9#Q1jQtyFe1(r#WW{t^m5d3skfaLMMo+aL7;MW46&>$m8zYhv_09gq(n?O`|-(8 z9p+uZ5A|H=PWhrA*|e4~6SZcUa71T^RVpdF1YGYpEmOYp(A~RAjL_3FvJ~UPE+v95 zc+C=ZIb53iQeRZEk3jVI11znEE=Y9+>GC6afSn{|9ywUy&1B0fRm(g91RCPSknahBUS zHlfavwGs2B_Md3o?g^e{4eH>#C9Eb{)-4wM{YRN0HhTAidS=oX@J0t?kW@Hm)Rbc# zdjG5pGYXHZsY@v}Suf(CMlzYqg(-gSRupVI2E?rMec9Ly%+Vq5ZK8swwoS#{-N~m_ zM0u&Wzb>77qqm^`d@Uj~I@YH0n7VU{}SukxyX2KuWhHpHIJl} zItKw?T@LSU&jbS=K8+wHPRvY0o~4F@!TD3Vw&-uA)0gSk=JBNgN1;xM6>G~uUQIs z-^?DehSE=TNO`1?Alap+W>focEtJkWg^sPxR!9hxY`K%k zAYCmhwgiD4T>V^o=l$${%t!k6t4zELwT~713=1bm=yCCu_RL6Eo7?Z41ug;!2>RU|cjq52?XuSu9yH8yP zArOk2t77G2lF5!R_m>4=&U>!1c{ww%69h8`emem+c& z5PHG047-U1xBYe}rHIu_CzB5gp8uISJTBKyeBw?j9)jK92lK3LdoM1^Hn%oG4$|cb8i{>Us4J3+oZp^^DNF4|2WX@~6`L zvPkWl_wJ{#bq}JHm=cMx-#{bAEeziq>2&89di^w`I?eALR;PP%Xf|6??T_$lgio-x z@<1H}R`Wm~q3Nav*q1Zq)x>-8_^08wl4{-2akWgDPHBETz)8{5&=;~Exy*J(i0iqt zHi@cM{pD4sbyQQYcCAAOrdquLs56p3`=%RaUUTWqm2_?47fNoglS)1EJgPGrWu@ZvS_It24z6kCsctiQ1j@SDHQuJ~d`6E)(=o>PaN-UFM z+m-IKnlJs8Ube~%yIgCbC8 zx!+L>QO;#Rp!G~Gjs%;#z>jNu{yQ=>y9gPtF35nV^D7#AUs47Q#zideCWC4Ad$3tb zIg0bxOLu`>ebDX1J8*3dZNTGHh&o}JFnk@w1J_WPm&UY)Le{J**MTxHnCru<$U?@H zH@^q-p1uwE`~j+?-F`210`OHwLe^59q`UMtU$bBe$OOg*O4z5-1Db=K!_Z)zcdn0- zVn_d!58(r^SS1V9|WXTpQCPW8HY!XIoNwm)PtGy_Y&f@c9? z1P|}1tx*fSw|Jn&SKh}+{Vea)MU*%b;sPPH@TQ-hRi0k1;G^15mYt;5%Q8R`bRn8% zzDX?g^0Az-#0bJ%V@Eo2`h5c<$&R$LXT+xgqC%3u73kR4_<6+5O)>nmDx!{K;f1=o zKD?>jO*6l}A_3AuF1@4ip%VAK@3ZYZba?#5pb-vlVWm|2_hp96jH;)xutIl7uvl}5 zMPD8aEUbvYeEI$EU2HFpY3nIueBcGBP*(1L!}ENl#e=W>+oer18uxK_+9IfxhNK1Q z@N}dwvmc8R4pSH_#7E>qV5Uc1qeI7{<~1i>MDX&&vSv_B!`v~3Id3SIo68D%9DWy! zl6?fmiA_D79LoN+PDA%(b5s1p4JCwg^8`SfIIgG8x2-{q z_YW^1BSXMSNH;SIH5jjSyWw#ObzH$lE1Otdw(x;E(-z3hmH};aOG8ld8qhdqM98o- z&_)I`vuc_JwDG1C>cz!IcbeK>wyp&r-n=4jZiX6YL%|c~tSAJHV}g%-S_Rs;5N2ZI zXp5(;PM&dnH+2@3_+^rFv<7t2RsB$1sv4?lO^JLh3wp8sbiRi$6wImoN!S1^Lw%2i zQS%K+XOW)8LDaosn|7+1qz}s9)r4LCGOQ&@K8l&!eLdw zY{I6l_FNDak&`B|R^QJ!-fuSCU3s z0tQF`weDE<%|X<%zzV1ZXobz?Z{d3Mu+sY_a>ZU&Vq3K#kKPy33O+!v&B!28V`9V+~Pg($Jm;I4r<+14oMbRxbB>u2B0Zq-LiipyxDlZ-66^Cr{v%JGrg>jZq9t zR_zor!f@*xX4_!}pp)1y84wIDO%IOVlvmuv;`2b{Y$$H95d8|tI)1eGP%Y%?m+}wa>ybMpOXllC66zRM#Z(3aAban4^Qc}ReVge-?10Y z`tOuNSn9}?d#j7)O98Kslb~1Ei0F#ZW4Bhp4uL|0cdkyF$bBryqaC8yvNw`+$uDqm z?>Bd|-G4{bg3hJJJGxY}R2rSJm!cx%i6yEV0z{2pSviVGg!EGoHJ{|sN=H6!(jHB@ zlNgH9>Cz1r)B%kbsljZXar+a7a6GloPj5t}PlUIhhD*Jg11|S@C&5eoRj8?Figrnd zt)$6m{lWMS4!sJ~ynT6*HD6SOMnpZ&ockb1L2vbNqC8sY?PzvId$w9xYvY>NJK7?+ z4fO$mN>a=%EVv>I^YS-!h;{v4cyPRB)hEHiy&7U&61y?_s?)iH7iw48Dk`ed?{CPx zH6O;v7!8-2=F3{wX!zD|NH@2Cp_J;7XXSp~V-v+2AIpt|G=1OsmT|yCvNgQpU3>0- ztED(p`4H4b?P=t0YqlU_+wJA)19VvPw%8K0*aKq_#K7`>a z4D-Al{E+=@Db=vbPBGf{kWrG%I}E{v^YuZ!dvxK%nUR&i+?y8ab_yvlOPNd&J;*Cc zLElSNQPS}Ka3`Ipx#aq2Mc4mZ>6n1*KHCs}J znq*!@z9Jmp`ws=n?nEg!!_lQrMpKUX5%pkJZqZvP@n47AcCi7U+U>BC?>ZC zu=Vth0YeA7<#MvpIbWr-sDi8c+*a4X)`xw?JJmQ-?ai=Mh12v!m>f52(*fmGx*vGK zffnTvZXRNv3`M$v-FKpA__qt3f}h8|dSMDw(rw3>|`D;NKL&kdrm^xRD8oe_RY7`<&skFYOlz$TleZHNgG`5MDo}^9^k-T=~KzG z*5T%Dxk+!$H|-LZ6Sen6KzO1BM1`!0ntdt2=OCnzsml26Dk%YRjPp?+ISX72A^+!z z7EiF?44h>IJifr(Ze+*z^+4{R?XZkzCLQF$a0WTcK3^dX$i$Ez6gAyL2Gswq*P@~(oEt?&nMuoPC4yIUe^U|s?0Trmx^;oJm4$!3d zo;i1Iff8HTDWv}_)JR#;vQ+|Vlw*|WtfPz%XLw&uAe4-^vyI=jqvJ=SR^Lf#uYee- z?07Q(hoYhzS==}AEHr-xDkkky#?H;566xES&Wa?(aghIxkHSW4Ri|bcsfjOwk>1;- zVl5?uH~^cmC_#aw`|)od|Aw6?@-gEBd@!#vRsHn&pB-gAvwMoArO_X3Ep?I$a1x`H z4-?W8hGOXgFR;i3pY*{|!n!e|xW}w!n%@l)C}{i{fjDf)Ge~3VLGEAR0)>)^G+qVx)}c;=%xAf{~oQtRZ6}w&2IqE&w5M}dq@lr2v5~O;3Z?q+24Va(x`XOS+#mHi0r9V zvRz0JrO7JMja|fklXWs0>^-Fd1sQf}A#k=A$(ZX81*V%+{eHCNN@FT9{*D{J&qXOe z!75V)F(H0GkEb#ijoS(j8N>L1=l5v&W2!yHj43XVh?J{hZgpK|3&M)lR;I_Zko+B7 z67wZHOOg}^0s`pe6n=FQoNh`{)3{wOjhWAMGMe6U(2F1$%mN^~gH?fe#l9d;BT1=o zWL6U={vGbdRqSREr}?o0Ng9!K2~X+;v2}QyWEDN0j?&3!6IOiDkjUr*N)E7U`W-km zho)l8zSMY%6{mW_+`&&B42kElZBl_7PL^klN&ur-^pW(is?}Tl9_>FZRwtwVJ5iE+ zgti@6+)Ttuu3MLpP|{uwa{8f^@E8?cck#Y?HgSluEsh zT5eG2k<+@u4UW5!NXrJ@$F*FZVUG8PvjJWAO5-)QbW>KNAI3`P>42pNV!xbwlMR;V zIjqp$2@tOd4;$OMtu~~ExsI~UuS*a)2Wo6wiJ@Y~n}OofTZGkWfNXqO zFCwfUS_g$+({FzRJ{01ri9>Q%71Se%$#kWg?Mmt_H&Fo~erm^}&Ld)kP>hHfcNx@} za%}d^E*L5K+}Df{#%D61)%}aE5TESs&{OwAVLKtET-BKb{hlI&jzh)BD6)I0bskO( z<(-M;8CDY6P(IPY9(LhS{V3)mE6KwWA>BW7W5()JYYYn zZLcl6JFmh@q0`sF%A13dS_(%+WHKghK`XB_W%avFznDM~m`kj6y&Y*q z*GT!>SlIa=`#rV27zC##jjjTy<`;lcFxle}tR*fC$?7yg=cf^s^7pYY)t5DJxAMN* zQ4HrXsxqQAwGG#QP|puLl|IKsQFo*f3DRtBZB|8fFBzU`PsG!RE>V_mKa25 z+G_xi;dLI>xV5TfBa;`36_M*_7>WTT*i6sAHcjL-Is{9>1=LL`64}5*k=kDE27qIp z5Tv2YueDQ(EQmohKlL$ao44+QdW*+J0eou#5>G>~IZ_16uyjfhV~VDm1(@G3SCP2k z*Bigk6Ddf!l02}{A-oq50PX9ihLm>e3rn|l=~Hn-HSye)Zb+HT4Zs*m|CgrHi3=~{ zdVIdwlaxd%;bwoVgNO~Az3NKa4k*@5e6lG zp!_BhFQ7qylP+=ec1Yws?aDYomm1yQAT8NxJu$fknH%^yUk?bunWau4VVsa`uj~(v z7S8k@I~G92Z?ZqB=yR*v%|QYjQ~gYiDBWd{$z;{gPk~*g?y!~l36Hxa0Ge3qN!3X% z7Umq9`i_E>FW~jzTt>~Uk3r#D81U~byeP(qn*`FjJ^H0Io75N6 zi_&k)_=3cih#8@`{AKP~c7fDViLpVc?weXu>4|m2QQASqUHk1V2~S;SkkS$odUW{2DzY{Jij7*bKDA7K3VHoR z)MZkXrS#GvY0pJs)e6&lB+Le90Mt+^>VbqZ&Mv_T_sq}Dt-XjhzrcN2m{^8+XJd!h z#BTC)n)v9`iuyVp>U}1V#vPJHKJ2706WWq^0qPPh=~D3q%X-fEKRn|=0k`t7qBnb)UAS0}zN6uy6> z-6#%H!xgwI`x@Zlpuqnx92zFm5sOp65& zt=lRpQZvtOL7H9M_x=I{{gk4@)J(ne2o`25Ys4N%2lI*CHe-BzSb2%wiZ>AUsEpt< zNFG73yAWcC+&Zj&A-4d|vyGvIs{M1_4roDuL4ACG>S%InmTPTQ5JON~+hz}OkK5b! zV#wY6U;w2!eNaF5UNU{~hRH-W>|=?u%(YQmXP)F;+N)bIX;kaM+Ug+%Zir?PKwSO= zW}ZH}5j8@tLT7w*MiYs`5>|ZK0?z5KBDG9!D3-?Wa5Zv*47cl}H31=*D(kDZ5P5e@-b=I2pyN%&e@w+>5B4@a8%K==|>n8e0rN8P4!8am2zFl4m9E3B$ z0bW7Um$zb~cNbNOI%$x>pXcmNLw>05U%@gT=7QU1ixs=^*xs^N zg>mpZ2b4nOWnL51_esb?XbVR=aX4}@nD=Lr;lL>XT7*Dg-#aDRW@NJHG{@bQKH|YG z*vw|sR+NuFIJCY$zQtm#_I@MuiKy3k0I4()+vqx8?JUyAn2=po%TmLkI($fyrh>y_ zFlE(`jkZGHOD_XjbGJbJsC)my69KnZa=msR6*983zJp*+b>mwDP#mnQQm$(-rE&D> zCTs5Ixhefi=$Y3VHc1NKvJ%ybw&nJ(t5!;#D@ie|aKF5xSf*NsMzxZ& zV9sYClxIyjo@1hMET6FqTeM|9{m71QisAlv6`uK^H=GtVhUdkFo9moV79>%-JWaEG zcu4J_-9=|Qb;)4pD&YgfvE(<%gUy4R>>6J0U=dg-uW*UPXzTfsKS z$L^q#)Kypyp^=R6=59>{_}0jquLmwc93JCA?;}usBuNC4N4jm}Uf*scdaTFaV2XQX z@%_oUb4{%;OYHf6Ft>59JXyp!l9@h&2N>U7d`EL(?+{B#v@gcmh%L#vtH|)NqMpyx z2Ct6^vskz-$V3uUHpGYPGMCFm-ArWL`rdkf@IDC}yd)1FI5xTB=Pn{x+6qV!u)|4* zpfpUIaWj_b<|$joiG{PT4z==IMsoTN?;VyCY52;0sgxp6W(LRSbXV*zcNQMvWztx^ zK8p^rm(x<2=uc;-_`pFL=&j&DNz&%v;L=WpP87X&j+`%YkEG7Qlrn-f(U}(2x|e;P zi1df)>Ud2ENI_bgpw8M45*lQ47|K~cdN{fBBe%lGp6f_9#pZBa*k?FZ^`bw!@v7l| zyl=Vx(mi67(_+`Al-@g#qNf&D!$X{{)maO380Nk%4TtfX5`}2JX;2{p7@DwafT&1n zpU5kehk1}|Z9hMZ9mM9*LC#k&^Zqn*pWBbTbDdu2lqL?SV#^PLO7iD7VBtr6)b!Ro zCW!d~T2HH1yWkgkMr_Wn-o;7X49bqOiu{0w-X03g4s&6olHu6v7OQQ{WX)IooPAv- z=QJFzvfI>t`m>fna4s6bvh+4;<@8>~+6EO?9>_e(6CDm6WJKf^xOSxqb4b&SG?_4| zrwZ1zX&QHpm#g7KOq1WbNAz-7G#n3e%-&^NFyYW6;yY=f7O=Qk$vjs0DAK$Acqo%j z>V~hY&1r3oY^lTPABOPh+22#V#aO>!#9!que1BA=+i^&{!pEIO*;_0zRpm%_9Ueds zh(G$l8_L0^dY98zi}Q$eZix;$n>P^e0PtM0>SvSrPX<)UF!a_<1L3i)uUs`cqaFjY zj{(l!n?IN4Q}?!JT-??G|1g-G#wkQZboxTNte#r~jrkzx~x)cIXS` zY{@(W>x(@&+^JtB-P^|a4g4~(O+7=>T0@eQEv{ZIs=G6-oHOXf9dUE#()%P|a=}D= zBHshLM$s$mPa1h~M19F^TZ*KOHBSdmSP=RxTnAt=$ef`XPvr?9ZqIJ)=%vK;Z}*tm z`E-tpq{#mL0v4R-;EftM_0GxDN>K@QC$UPEG&rce2jkqq9WM?2q^iF1$#~*Tx%*V~ z1NlHQr(D%nQ+;js_8*IM ztEI`BWLzJe%Rc+VF1LVXM0lWRs+b%~Sp{)=sxAH8k$ose+jOBz$fk74xV6jr$MOmY4u-?(K1 zST`GsYbBO@i17|&O&Ad7th>l_N{*uaG~dt0B)xEC1_jCkQ2d(qJ-WjM57E(T zZypk+)t0Hty+cCCds%8;0CW9V?RzKG=%%Io)8;_0^u$n-=^-&zMuw(w&6j;wH?h%V z&%dUH1BZRK?;>hLkmMAK&{+4zPFqC1Zx07atQDC50fDBkvMu%hHv-49hBlc5F+Ha#TPY$oSPTRbqfE3 zeE$EFsoC#VhR39_$F*fIdpaMQPwHBXnuw9J41|ssz zZ)V*dP#});c1Cp>igaqjGlI*YObES$*(EX%Qo)QQG6jMGQnG4)!({~%90!jaa-wlS zUEg9^$H&wl(g)d)^4hj(px+zs+T{x}!Gms_LUjaGqIQ#M`T-Q|(mlbd1dU=@KBYon zM6`ezJIIbrfnlp<%8x*uByKrA+=EJJU0)a+C%??FXM?${mS(wq@yAC|_ZD(8w?lOk zVtQVj0o_>FDrLFt*zsss7LELg&`ET?V`ddU2uJ) zh~E0PVQCHs{6e*!i_Yo+u%#o@g>E(74uQWDqIK(CsD|)$X?ex)qBIXq_5X2T)a){RacS%k_*P z7srX9`<&jen}r~|e)b@a)@q$iOqnO^hYQ#?5KQGd-2R$1r9M~YRA^OYrYzD=lloZ- zj)Fv_1!6K6XH;EdOrifWN+A`mA zV-}!?_II%Nbx#A{u#SNEeVOimR{UPEpHKtz zJ$au6oPs@hv@y;$$t5(81SmpD^$Cigl&8JYeX75jC?H>s?s|*NHB`|RXu}3+v{ykS zSmVvo&@^^RsHHCKI7lTRKc|xMJ52S{%kSBh(M0wU)5wH4eOPQb`VOU3gA7cy8qZT8 z3*l1&QS%f`ZhkmoR(7t2^(;UmyiU-F@qB~PBGI_oz02Q=l3HHs{|rnRHEX!be0E5N z!}Ri=0B!VQyvM==sHKYKWxrOo9;%U|#&X3}G zne4rqU$rh?-l2tVejSvIf1eP9zoWTjmo*{YmE$=5nHS`33&s(?egra-F$Af5G@^Eg zmQs@Sgx+;qU#`YOv8Jcf>j3~Lj|s@;n!#q!qZ?`9>eP_%clkr|bIC8YcGu78SSW!C?AB zC{g)dD)fVTAEZy#7DzIHBZUA>z^>6wB-61>N2 zlTrBU7rz(7=Hhb(=hLZ1o{Cc2y!IFHfPfx-48XCU=ooh{;8-@JTKa_}{6I4ZR{Tpp;HC(nNroqw+`T+664r*$3WwM(;bJ4tiz&7Vb*7prd>3YC1kZt6`<5eQ@x7O z<|{?44bZp4j;3^WXF=-7N8>>sC`nWMvV+Z!!ts55yVwjZD@{8p4b%51_hVoHQ3DWS zFu2B;FigiWC+MoAUZMexfdwS)TNz^!`EJm~)r#QrMXoY+dmm*@+wxmngl+{Eq$j<5 z@)TrXo%nKJh|qo4JxYS-B0qDXm?|%M=z`3if}xUqiRAIHvHb?(=C+r^BH_9s<3^LK zNy93+DqC3a-V7T9Gv-GrxBVveS{IwouBU1vmnY)vYJH=5O^t#D(#+N@M;9eJ z)|hXikOgWA=O*u#ae^e2C!$X0KM?e;EHLnn-Uu-GF9%&x5oV}OO86v1Y1t; zu4MjdPf&>GW9!P)|J|a-?rTvw3r8sb7XCl`K340)~K;c>q*NJ$t7YWQ!{qIH0d~ z(0W(_-{n>qu{34|%i5%IPGyu4*`7ZF#XoFiz z*2=mbF@=7>LP~xRrM>n8p&V`5M}u}2DO}OTPiB7ak#?Q6k@sd}ldtcLr@-ten|=|` z!sg)<4Sv-^n!m2(rj!RLIjv-8XQ!d03IupcEG;^lI;fQm*6O5 z8L3}LQRg0$l<;}?2!cT#O3iU1kQM2QH-5rKb8q#9UxTZTkItNGUU$R1Xac*+!Hk8> zW#WG~X#!z;EBCAYK)~}u2joIYe|s2dJow3A`|G;KbLe;ywcP2aBy%%|U5Nf)3XIo~9F_lA-zgj}(EG+q>otO<}5 zs0(Sh2mh#3)x~JTmI`!ikxLf&Txm*yq6`J8;Zrk_Tx!eD4H8cIjI@ZT&Nmt5bfe|3 zkB7`qRlVcLq{7t-Wj_XKjHll0#Iy`4)iLR7-Lu5Xqt^&!R9IsksfYG@xcy499 zX%gHg50XM8hpMGL)abO8Ixkx1bAh0n;kN6msxy8x4KZ<$ zj>%QQl&rE8NSp(36N25bD6jP9-XoLh9?!0Rk;SjBOXsM@1=bG;oL`j%G2q5&!YRw< z`GSeli<}TejnNbC7x9wz49+ANQa8DdbAFfaTcv!}ItQ}#*!L(;nVL(v2UDFvUm}E; zPqsz$Q&pju^`9rZTcmZ!H|AFloJEmV8g~FlK*puyk?5>D(+Ic-4Y%Y+oB>&W4Y&t= zGu0NTVbh?=OxC*54b$w0^{$_ymO3au3IX8T=*dNt9zlH9r2Qsi7`PuSUfNa&&;oN&HU9J>$aMgH;gJ$3O(h*;SpDF0p3R0cnAS=xlE-M?#MHk%NuBhc69!R?DF7LsXa=i4GC)HbJL zcbNQpxXLeW-Hi~~MxG5A<`D6nzeni+ZcGcmeH|o}b0nzkmQ>@!Tv{JL;*N_ZDf}id zMQRsNi0}Dvh`R=#U@CDeYH!jG#iLBA)E!AE)NI?Miw8d+q>%mE_o@JIn+<}}Mp=b? z&c~#lJ4=Q5p00Yp+lgp&T;cot>cOe4z^F-F5<sHpNVkJ#b#lK7J4HsuDwtC`>EM8J^eL{% z6*WwWn^p<#=!*P6P`a zVch$KhlF25Sgyo2fjEu(FT?5=ccH}P|%<(3H{IjdSQj%ly2f#(t zV7<@d0uo}IAWagBUEdzYV~lwp-{T=Z{KtwSpM^EJlxM4~auuR537Y$Ydd^d-Q&LFb z4VCdq5)V_aLJHvLH5fNRQtjaMNHh=|;gCo(J0={;{${KuBn3c_`xDPwT-O0(wO=b# zxK1YD>CT?`teC;BHg(a=Lry0CEz8heT3svgEzK|F1)}$#fQ#6US_;glWgWCG$$_#_ zYR~4WFvCPnaN&pOED4E18v7$7{VUe)!2{%2&E8!}e1Sw3>Q}pxuiRcYW2Rr^o@YN@ zAaovewkqhf1xVMOTEqAMc78ndlHjJp>X$)}G5?=P@Q+fEnifDtECm07bE*Yo6i1Bo zl1ZLIxq=LG)l@fA3Oh|#f3PZGhDb^Bi(IBX6+B5vo zdv12A%U0M_DrAE4|0(XQqoUm6eh;XiGy>8gC>;_4LktKg(hbr`2tx}9(jX;`lyrv} zbcjfobPR%0BPBBk3^9Q8yXTzaJ@>BnuKV6~*ShQFuUSv;d7gRp-oNkX`$b;pr(9m{ zz+0IEhtm4Xtv8aAX^%0Y?&7;|pR(N~2$lDb*p4qBCTUI>I_eGP#`NP)CIsZQ_KOwv zHv$*ghMHDEln5sYm~U8CTVdb+AHkE9S#e-5sE3ve9+l5efCOEp%eA;HXgaZ#=-Z+s z((R>*8Z5|5s?VZp^q+9G&4LcK!ATyp!E>J~IOWZ3N(3-rVB8xeIzt};W4Hm+-N=(^ zcgojfzJ*pha-*;-D%J{KOb+MV;wSa}og%lYA(-#>)WRC-3qZh$yV zXJP1*n3g9mpdT0*&s_N4N}pa&ko8CBNz}VHP#jZ5vsK=OvcJus*>Aj1Q6eL}1 z9amI)Tr=03%z}i&4F?x3_N)$~sPppW2m6kcd&%KtJ1*uy=44`alP!FGjT^90 z2Oe!gT5SkgYqh*wcYB%jxy(vPsb+Jm{n?YfFBM$Vn8zWlY*J48puYX)G&Emx82&no zE2r{t9<=AXd7p8Nsvfs*GmsFujR)`C3BEQ5_{j!*gL<+51tP7L0|S%P|Jf(KXkky3Y%yQ zL^0t8I0z@XDD4qg4Tx=Z=a-Q)Z5kIUj}OmsnjqI!87|dH4OS(pI^v4%j2)5mRB>If zl92SNs##FnF?b^YCX;vDV6QZbtU3%_`zZX)R$6D^1SZOw?4mq6A`!klgmK! z7ca*3=V!X?*RI60$Exwyd`>W)R2~Q9k?XrUmydn4-&w{3Tw*=j0?C_eko;A>pmO5g zZYDS5;*xp#^zH2GZLu*}8#_?qJH0PDG%Z&`;FLJdX7#Vx07X#(#$|w_xZq^%IeF*J z^rhKfkFe(*Y$wzFa-q!9h%r~#&*>5}=>T3<2sG{R7yM$Q97|U4|C!GJUqBuZy|Nq$ zke49b>X!&NvZqnqp^uA|${5-tX?b)XMxmx_$*?{lMT%L#Yhhu%|2Jql^@e}UP){EK zAeN+Gvsy*6yazWJFWf6QzkIs=b#7s-nWXMMeA_%2*7E*jeb^a}`S>1{u?LS}pQHdd zN%Wry^CT+#7x=(FvyD@BpQ$7s048a`IzQ9>y+9LogR9oAdY$Bl!8f85 z14&R3*K?Z9LEOzJCoI7$)u|rV&F+dcpDR4P*6CfjEQ+ru5x3pGv%M`4vGUvGGum`* zsWTUPCfnkVb?KkG&P)gW{-vGm$|JRPj)EEu1(Z zNO56p^nf#asqCw{o=-gDCL?Q^yKkhS4j0jlcDCaOGjbzy?2Ozl61oa6SaGH}5o?Dx z7E*XEHcz<=(E8qdc|8v0DUglfMR`%R&6~W{Ac|N8hKog~BCN@yJ>qYZ$59EpWLo}c zIp=yq_ddG`1%uZMk3Kk&YRUyCCsLMcUg%!l?l*X`qF{t}jW`b=)NeTV2D%QVCeJo; z6LGAbM15;}MTrTT)P=lXTKh3W=K^jQBaI(PMKZe)IC z)97IfgWahO8$XYs{T>xpWNVnWFdwK=UXG;((kb%1ODKq(i}&eF(*ak`7F%V7z!*+EbV?5W4^Y zRF;(58I!o?hFD-|u&}>Qp`?nn*#}jY2x!2UTa6ymzZhO3b%9RD3)dh7@NcwzwK2Az zs{`N4QRtnBx-Po03sRbMqmCwol*UQUg#i2wJ782+!z?4@Z!!@EVAU22d*L(7t1?#r zZ}NC_GEn-d);jKsJJh}}wm-16m%phkjTfs^pB3;>^;UE4HG{^5T0F5C6fMp!og7Jd zo0+ev$=j6EysxDC>biG~uA**1w>OBIS}wa1(kf>`!Ef*mywp+*@?DuRu!3Z(1q#25 z&Wx{n+6~Hf=QxD8NfU~?VoC!JK2H6L=T%n&9H&8_q-c%t=?Cc(Y&%mVAmkwzP6+2D z=5}`T$~_OAV4@rXrqVB+a_16+0gMrZC6!|HH5s!_u#Pm=AeUjom(YO3wrg@x-?%nx zGIKMaZ=G>Nbs}u^Xqr~!v|O)Jt)*Aq#iM1aaES9 zL}c@avgUF^<(NP=2rd#Xbu7)1DGSUTrhMqq?Cq}V?erTT*LieEq9ivtLz~c17rEx; z;=7bDeM}WmDDOy)3Gp#r{*sw%v?E+Q3x;u<8K63h{V@fauNKi%`15@2{6N$f*R)6C zJodWR{?|`{*P~SzRi*sw4auB|ZdcBjqL1#O;;$V;Qyq7dzQdHrsdpz}H1Uh7hGdeB z-rwKOu^hko1nU=&@i5=7Ib6O1YRmb5YRh*Ga%6enpBP-p?)uxCTbtFr+rqvx1^&D< z9o|cB(ic{mj(<`xhgua?KejKG!V4Hq@BD_XAN~IV*1$UvI1m3%?A*0`7S-3v1qcC0 z3yhv&BJ?#?v>`_ zjR{o|P_)hBPGS662bSbaVd5cfKoy$Ne_)ICai+m_j3XFAX`E-G%pV9{qm7bh8we;oFc@M3Tx_00Q{|N0{SL2_SMgPpydP9*1%K*_Olr*mTlhh5XY z12LV&p2(R6m9q(!%r4+hTq63*8k0Veq5wX4KdhBR=L0i^qaR(957>4Xt{h)O2^!*M z#f2&z#(tM-zL4s>*zZz79|nJgy}G2kwtTxyicR>6Ap}@VRTV4yX(9@SxI?S4NHgzC z9`zXwAfIj4y%w2`1WQh;k}(r%;IK~!Z%0BtfF)&jTdYY<^U>*EsoF-^ZCC43(nPTk z@}&of0>CXE(poyqo-+s>;AfwCIQpcp6t`XN$It{rta&wUksGwxFineoED5aOH&Qq* z{Ns}4Mu3K3-6x*c!5KBI?Ct1E`gOm ztR14Fpzg;vurt$atA@B_NGm+U6hB)D9K?r8jdZ#JoXB}r$=B{5BQZwqUdUKJv}@mY z-Ug=#u(ZQMac z1)Qr%c;hdISmV+i;^4@B%Ou>P1Hc{6Y!Pr>BEP~1io!Ulx1w^i&}LY5S^g=AIhl1f1-Mo)YZy2tH6HL>Z&K5)LDt^psl<=5P}aSif$6c z2vNn|8zY--GpVM=z6?t70{QWP%9`d3I=2HL9{x80xBvC~>wm}oUR?W@fAI+5e+(|+ z%=&tFi+povB0J`1IcFPmmRuJnNAuQBq_^%z7mN_0*B)I=9g%}=9dl;|XFpP6?ZEK1 zp?h&#uB;#ytm4W=R(TE^_1iA=POC)I5@j(5$I21of!;l!JUW6x7*ISeG~2N?`l_}x zHm7Cx`}!hp8$sC#7=M4anav5ehNb7KAe3;iQjf>!ppRsNMwtRA5k7tLRXR7_IR1C< zqr92vU;6+I+HUK~mWgF2f{y5(c)FdnhH#n5;+Q<}Qi$Xh#bs9bQYe%$!;L5;T5lD` zYvyQ)E;f193k^q~iHxqneL=r}z<28}8u~&O*Nn)AP3HDBz@^^TM^`SmbZQ2hConBr z40z814e@_AYEP1?KN633>Z&eD-koo48Y}DX0}8}M(iU4Il>3AdZ937aqOJo zsUouR-^y@}Bruj2I@KywJ6Z{nHj082AkcH-3RHZgWR3;{Jh}Dx=Lb%sXXpG$%hpUdKlXh)&1rw;4N3yjqJjq9W@~H zjLWF(N~j3%$B_of5Gq%TgL16(WMJS`AlBZLks*1d)Ufz_7iKRDqdt_C;ZMzbC~$sK zG!E>97Ip6YqV%HIK(tM;yIo%dbI+^r5Ml@4V|(G}9MO8)1oLtr!_&=1n-!#ieHn)f zY8MG5KtRzr41IKI-#4Kb#8ZwttaLJ-6hDVK6oR4~<&!Uy*RY*6BgOG$G=K@&Knm3R z5rxWlc@RBRZQGs9n8r1Wd7OQY62W@S2XcIuX3pazj+V=QY>z~+-g;oMwmgxPOy2OA zdqC8QEbr|z$Ose2=#*453B{}^VhK<{h=*Fu>Df)MEI^Fec`*zvVss_{j^jBw0Abk> zFc-R*o0k3ZpKwSZBj851(S-vA`J;t+!e(dFGon{+%kB*T68BJwEO*2~KHWj2`o~(l zUU&&%c>xN@IO@@&2cUHBLHp)OLWgvQGucK*vf0%3$k&{=4A-Gar^nNPiZ_PKJx5d>U24r!=kL zReiAojesSrW45d)Lj#fiuc?GPRq`~-6of#&jP3cC@sx&SP{J!uCfrh7_b-bDZGU_k zP-u|Qh!r(YyT^VHqW~|?Q^7Jf6p$ZP397Pg?mcRO$9KY^f{MTPPgkk~hW6$NLRy#9 zIlrcYuAR4^K!Oc3t9efC&0e_#;%kktIR{H_`1kS}ZuN%eDLE`L={e0)>$7b32yM#1 zj}ZiCOv~nq?xt!SNZpN=8S6?bbnLW5m}1F%cOD2uuo1(U$q*JSW1fB9_FX!mo5OeR zz<^+~FGbB-H5wlO3AS9QwQjyNL=fpMhxC4P}<|V}*zSIZN_L9WV8D=NlNo(`G#W$e=i2jm>_vbB(9YpD}gj z@Qa69p4DkZ_-BBLDBfE56oP-&=aJV)042z*E7aKRi&}**{zSzEx37L=J{3gAl-<$& zy|oWiU6)d`2c<+!z|CfUEQz#3C%8+pH zRJ-jRJVwF`xi+Q8n?6;$Q#D{!By4yk?pa&fu8kZ~>TKV^%BP5Jjg@gGMuN(@9UnbE zQEN`}&EoMg4t5l9z^gGN7TvWUg>Dv!Zw!~s-vt`r6~ly1)5t)neYlh2#u-t)AL+fG z;IfYwdPrEP*T5JlduE+92&qloe1{Fvh+DHpvMda+mgy9o{CWe}mSr@Ez^rziGGVOX z0qP@~QP^HC+5F4W&P&N^aY_tqH;SYv;MjW6;2Xmx$Jq-^iVa{bRF|P=u~8x?P;T?g zOi)Uj4xcc{5GJby>mqwd|sn~V_Uz^)Xoyf>Cc(RWQ(qYsDBhUjU zp8r?N5txdCPk7&jOp#W{w@|(PdrQSSTJ0>o$JG--2LIML*Yt2CjS7Adu&KbyT#`D>j z?ZaGd2}^lx6%1W{{awU5QOKjDY0MDP2sslaIPTb6PyncnOT789!@-u_>C_GgVz!w% zaUD5QO8_yix&j4OUzt0n#x>WTy(E)1$7cT$o?@Aym8l453u|}N?4bT~qcyjP?KVx9 z)@R><5l5ElLruM_&k4(d&a*8P9Zq{ivH4zo69_;D^gX5-!M&K`+!jFhL4KegSS+9J zV`}u0JMwBGRm&5}{13$ZP9XKk`T|(QU4M(kHfatRu~@7K&$8VSa3bZ>HBv+iDJY^` zx$RKYXvb~BQLh>`U{8z@4=4`b{V6;7OCbd|5p|;8r(=9YCHTR~x%x9mt%CrzK!rr< zM%xg|U_rQKA+$8%6KEXT0y21UJ9utLXFWFo7ctzIguJV3Wsv z!Yw&jx}@iTKp835Y&sJ>-Mi$dbd%H9+UKzD{3>lrI$WIQ-9m7eZOX9dKV`}`UGf0Q zZ@-ydVB<>Zoj`su1TE_vS|X%{l5i$*Vf;Q){+_$ZOvRL#bcm_b*Dzp(T8lO|X|3G9 zn4{T5IluBMEw3I8k~iAH8L8_oSShSe{wa_GF$Cg;$p$Pay;m8LS#?y=AD^9H)wmFT zEu%M}Wc|Cr@#}~n+wsP|h+7@?A1!1|f7@MYD^Mv9zQ!Ec#uPUrNW7}(fDNw(Il)R< z?Y5AHWF}0%YOBX4n_Yo405gI(r>Tx1tF4H;O`4@1h*nQ}bwoy-NZUwPDpQ+>2K@_) zmU4z?{^F7WpKuMm-#_p*rU$t{{TVWq8;{}~%zV4vdEVbRTX_cVcarjJk+#4n19qA_ z7*yk1vbOHW%*V6j3;lq>pmuaiY62hxD{#vIz)CgVSBsfh1;=}{T^0}<#HY=q!6RR( zLCrIblS5&*e$IVc_dH0YL#@g0OyOrx@DDkQ(Od15 z8*@&3xxY9ssC?kwptfu89qYq9j5z6}g^%(d%H)iS)+v(5wYZ&LY~}>1rP@;U z_B@LIM#c?dRHpyv;6%Wptj%-6C~u;b3lck`fAi;VNd$dPwm96 z{^x+wyW-C;BySJ*9QjKtQ;k^I#vdGJ2&T>RHd>#BC2_bDo40-2C5_Itt`Q`EKCyj8 z^>To@bq6Xw&|0#=d3&GWaIi6ElTzbAA71i`(5wN6cMMUz!fZiuzVU+LKJQh19b%(s zi$+&bS(o=WkSueQsZiVlkL!My(TSN{0<)HdS%}1R4X*T?hatIS2Brpf$ITbl>$QIF z9N>^IN_%8Z?$m!?z8XRyW?F!zts@cLrG=UuA3xUozp4Oo$%=W;sZe)lJ z8}_bR*!c!IilCM`GcP&wKiMb=*Rdn`BC2!`7fzp5e-dP$G-7Jr_6Rw9Sg-@H+f}we z>W*;xwi{-XJ8hcjDvN7+l z_NxpPW8TD%cnUO0yp4}IxTnX;2^C^;5iIrzSLeQL*mv30KGWm7aQe=TE+Kh*{CjV> zwXz{SDVl6pHbAD-XP<5SB`2lks3ckf$zF^f7MU4&J%R<}6F01C%$pQd)P7`plpQv6 zIHdIJz97aql)@8j5mMK zkYQ+EuP`4K^15UmcoVKlB|?t+snf)+FVFe84(zh4zSIGWM)n!({%y6GlfU=Tb$0A`s-;a{($8$6FF^)F1^(9X-ke@8Pf-+!;ni0(Dgd~p3=Q4Yg zFHBei7P3Km&Bi92frptK$-XyxIs>o4m0WG@!2_0;vD?uu+V(BFSs?x$N0tH;vQbB~ zK+Sp}+h(rB zeH@b#Z@@h-q)W}c$@%#6-2hpVKq!MBNmDIL%4q-jP;O3^=C$J#&u`tU>9As#5{TWp z`p>2BWEm}SEQ85~EEw*roE$^T1`nGB;Wli0QS;YC{Y>VWHn{c6>Lq zuR49rEz4j?gbw0!ZHvXTByF}KVJ8Zd*A%7-spxA zFZbq}p=G?bLkE(K+^Eeo_ts}6u`|)%bV_NXolf=!wQdHdGkCwqta3h8;bxo%F?DYw z%LSr5CeZElPhH>mKDt#*Fv^~Bo=*IordreRbHZ7kO{TnT#)8_2DPe$;Y$^Tm95eao zN4Mw{TMf)Ax3H6CVBN*b;9~S1Ajq(F9=?}MrvA0T7*|vqRbDGNK zjFQslugm>I9Ty}Af{)%L!wAo8d_^E0+!&^_-$8PSog2@d6UtZ?T$rhUud0;a%yVKe zy6Pj3It}>dam6`bUe=yMXjg{mE&&-AhAEroMM3!9yAu84v+I*?(ChWjTb&N!oUY2v zeRneCWuK4hA*Fg13(!b8CT0h)Lnw`Tc&oJ<)p0!O5`D{?mS2wy7K@M7A=w@T@sRlguo$`1`$EJQ=}UN z1padr?%OBV^M22}p6~sy_ggOETyy4{*|Tf*{>>hORg|Q$uiUtTf`WoADg~JT1U4R2MaAF_fZDmHO|9%*9b7EwIK{xTti3DD7W@Xy;HR=W_@M*-v$Gko za~tvA0v|;k9c^LSFcWzzS2_+UZcg4ioIIeJQC>zvQGt#_9DKI5vVnnL(lApS2jnZ_ zmd*}#phb$Eo&63Q@*ikaH#RqRw)$-d_s!rvj%?NUn5yKpU-yI1KFT%<#jeZJKzCw#TIT>W-ymu@1AvZb#SnCwQ~H+MpFlS zdzk5&?9MtGJ3Bjg{AD+D2ivnXp7n7A%lI|=*@VajbyH*8b2@&Jfo#>bGIIrLfK)X; z?%#ULz^p7R&u3<5JNw4Y_`LI3gNvoHnS;k~bN%F-vx5V8Rr04si^FV@x^>Q%U++o% zgKz(!-}w)f{pT;p%fanAS;SOiIN5kvWE50n%uMZBxPC3q#ntnC!7wwh{;+I5>jkAsek>uCAVE!ZdbsbpTD4u6DL(-vWZ2 zJ$1kX+Z}H3&Cf?&3*}(=T?qKWS3|iwsd1j0+L@)XpX=!P5WfgLdkfgsnP!0x zze@@E@qf*|%Vm`Zda#c=^sAJ^u7cfA}8D-#il6S-*2F_+63yLIwVb zy!A{yP*8(7)$9xVU-27=L&V7O-#r;ZFXO9^@wl zDllg&V8}3}XF@LRA4>dpxAM>2#qVwf7%Orw{O|K1|El2s8G*kUx--legcEGWzZ*M} z;Qu9-d2V9oj`!SBe>ctZKK~KZ{I$dU1^@r6+q#Pl%+(Yb?ff6w>0f)mf3!pY6W{s| zyz&3JWu2MP@0RuVJ=^~*dpo1%H+wS$2Iq=QAzU3CK{RB6j2=L$^E2{xFtJ9)!T*bP zMoup7U&}qSKhFQ__Q(FWBGYuSvbO+Y(g0zL21sCRkU`9!0nxA6=Dfws%Kb0A=Wj94 zS+sN>4V}N?;%E#~-rpSV`70)W1ivh%zXE4ubY%r%C@W(SkN=$jiv@fyey(5=Fh^Sl zPdl*1ozDbf!(WsACCQ-qC)MYzfCIl#^FKB)v#>RGK}Og}FZV}+hI}x#wX#6w(57JN z$W8qpZ|MJe2*-K837jb^*ZK4B8^w9l{`*F8uF(HZ4EMJx>FD6-1~Lw$A31j(rbu>x zbo+m?_u%+@f%UndeizDl+rJ|e_A}4*TcGq`-KhV)82XQZS@+Bceg?Du(dZd&<*I|6 z{1+Ago{*#^s1Lx0elqrV z75b?y|1NeT>g;TcjM>g5=7>acetO-%uRA>FB0k$VIL>^}AK2hu>)QDy^7s3Lz4{jg zKWF<1_WalIpL53i7Ltl9$btniO1ZfLNCkk}fKUH_*#CbK`Zrtn-%*XfmH8Pk!_E62 z17?7z{=|!a$?Z?j{al#maQ^x8*+~hfWG5~Q1O??LimZgF1{}JYi~-k>+;5rOd7^aF z6^&YBv6lDh-lGg(;>*n)IT<&vTFR4eXCn^LC()N=X^^w)DC8_NM9?i^We_D96D&^nJU6WoWFTQ1v2_L?gXr`gjA)>`-Ax7eOk^o8lF> z{EF3!2cFwcEF$ndsv2x4R3FaFU(U1rGJaVFtk_$c($DA;G`4Gg}whtd)SFCC~Crl%jSt)Hg*?(J-~q_9fg-20{!7-hFPqY+c+ zLpJd2L2iR@=^&B5kk4^se1gH0TX>$xrZb^##j?^*u2*Ew5cL%>Cp>x9@{X^obodZQN%2#I{=NOQp6EtL$7wZe65fFz9vt@%-LcgTFs*-(ZQI>lv9+t0 z_TIEOT|x!h3{J5JLYx&Wof^Z;O)e?={?+2Wl8t~&z+}newZ3|E+i(;SJis-Yo?9T&0Cmw4i)(CrEP&|D0$nQQ8`HAt}4EI7+F`5~dt>>N_%<8B>EhU>$Cn1Lo z^jz59-D-nhIu}~XrkgA@YX^$EB$mprOPrLW5Z$PdRQd9WZ*w$`@9o~g1H0wB#w7_5 zp@XBr%hnT`g}B5#Gq2!_%kt7TVX{d3s<&c-LWl=5m1ggMr`<^^!C&A#$;*hyzR;5K zp!S8%>8D1^-AU377J?wZY%G;IGp3T|@2Q%Q)`uIxxo)j~*St<|hVsQX+niR;UaNJ; ztd<(7E1Nxa{C>13cQa$JK+{JKuV=>}qrztcQmuHx-D<&IEf{wAyew)Jk8i33mf zh4m0z*cc>AT9L6a9PhFFHL`=C^IDY)*NQJa#}zH#+t0I-Ro9{y6clt&F#1XZE%jZP zpACIxn(~oY^3zj?*QG;j)z39Yd7d5PGF5(iD5Z=Wm{VDN!+R!6eTaWsQ|5`TN;;fK zA}BRljs4_Fcov9U7)+6I$ueE6y)CNK$EVv-r4?^EA`<1Xo zE^^{3D<|pjv~JZ*tv!ETp0>Nbr}f2=L$T87BZ2j^TdbRRs~+4@Dn6tRgs&d_uxoRj zTkO9#GuKtorJ5|^ulQl&ZBU$ooBIO`VW6~H%Sye<&-deKgtzY3&Gg$g@Wte+U9}0E zv?(!!FyYnuxJWT?c63%0s$)QMJ$cJN(W%FA-@W(5nqs~6fTh!MCnx^m1S?@N8eRz+ zCZUY~jOI;9j@D-lgxRa8o78xp(oYrNDr~o}OQtQ2@m?dkQQlaw$T}DFT6F86{o&_eNXmqh}VOw zi2O%u9$dCGBq#~-#ocmR1C9|R(W-hCuiPbeM(a0GtWZO@0v*ONQq*OQ)$m!9nj%xp zA;(^bL*0SHVxzlR19L7Uo@?m)55!m^U!Jmc8|Ikrw@ztSWavr9xq0ETuIrD;@_7^H zoSf86p$eo)ZIjT`Y!y2i2>3L89pENmB^6EfKFSN>tqN9mcM0>F%67vrd+mGy+T3KW z9HRN4x&MBl0ez<*Dex_;`Y_#PMT1SnWcx4dR zgD-3|5VmD863taHiu$8ptspiGiu1gNN|cvjD`Oh_#Bp`U_@&vz=XS|~n2tfaA`Z-A zsg<|1T0x|xJoGjOQFmCg%=$-`q!bX>(tTfybJ1=^+qevN31b~B=PNureCM^41~V*T zYmDJx=CLj=rBR4$yI>fXdkUW0> zfO`wYz00?eelzM-NyA}b-&SzUSi6;^ligsjyawgNA+v4>+Nj+O{;u@#(?Y+IzOtgG z&g{qylYC&@2!5FcceIM2IR0gw?2mKY@hkHc7E-zU!u#E1Hqr2QtY|Y$s)Nl&v}So| zc_gEZdD6$Xyiv-IOY5hv5f7c+67r^~*S;yyaSSY_7*^`Q6r`z!uyi580wp9EU!Q9~ zA|HBFsCOb8A{;1W6!zxFdluDXbX0x%z~MQhr+oZ{BVmk zqce$|ERc1|!G>u`L8+rYehVGd)@x$s-@`X~ZhJ~n(EbE$y&={VYk{{V&6I6xd|Kpo z>#SBvk}dDvC-23db({+%WmJ8g-CrH$otDjjYViDSCjO^9k9W!}>k_Mmf#2K2BL+jv zFq_Hocvep-A0@bh9d=#&twu8oVew29=Vv!U)(iZh*-J0{S!S{*hq|gwR`s_Ul-}NL znF)zoxxkEQ5sn`VVZOGK3_h!FWtB7>?3thw6>dHO&a z+A_r!n%O0uIjJj;vDSJpvhoI-)7P_!y+>5&T;05`_$TV3f7-X5{bl{+*azd%OM+LRrj5=16M5nW1=l_~Px7AUXsN$acmF4@# z9K*K0v;xU_7ASAU@>?zK;K5U$93H=otzGqE@?aT?!?hM0L5?iazE?DNR=?|0T!l?k zF&@RhoXG7hH=|T^C-9>A4fI2v>})}H`h$)uxH3m=Zb7Tvu(3I>q3Sou2Mn9H-7fFW zLoD2~k>65@!)~EF(s9R#S`m)tQILNZqRve6^(M`-O03?_n*=6S-GEYYl{Icwn;Fe& zbDuJwS#>w8{!Jrc@n}?2m1?hXzh;{c-7?B@4ZyeO6)gQ&GAChWukL&&xv|BZj?b%B z1eN-7V%mT5*4Z_-z=`{TbMA<`7L>m<>$)By0XqR@*lv7a8-eaS7jm#v9Ju!7#q7|` zuxGZ@$n1DvM$%RDP}8?Y@|&e3vK6zR&~1rW9ZsXH)dPCDmvq@W!o^zSe1l!c>{lSP zGg%e>otkFi=(m=Hig7W-2VOdp3^(q6xYx;2vzBYsIBw(U_w}Lx z#>|S|Fv^V0?jx5h;&Dy>R=qq&4@JB29)q;1QA5b3EQxq$ud^U|#ziU=y(U>c3H}T}d=b2ca zkvGlq&b>~iorES&M@RBkU(Mwb#COInR{!|)Jt_`kUPSISLwMXXKUgJ}OC*b8Y5mbn zzo$X>J17lFDo>wIQ9jSFSKv{EU&_i0$hE!EUKh#vZmytsXHKF#(0K1{-N%|ifkXOC zIDZ1$s0Rj`7YXa8XqWx-yv15mdEuTcc|8Q%MT-H}iXV{rmxBn{CE?38)w=LcBmPqq&d1 z*&80d?d`6+8AXCd7s}>67duI6BuT_-b2Wb{;^P6qXZLRwFP`cSzvG?hKH#hI#cb|8 z*yr=6MXkA(1~TT%@f%JQn_fHsb#$F3<86UGwx7R~2kMPB?y6)^h;1^5wGN|fG9@^invBrS&UrINLR?@k*CCatPI|B6CIGnSjbyaM$ z6hpFNdJUO@R$nlXLeLhz9oKj1Bb!i*%IMCNP;s+OK0(~|eU-*pM_a?@JTK--UXIfH zf}A7%XntX3U3lfYCEE!0>7mr&w=QQ{oWLLUOti~6jcpE^3AwM*JNRK1gDk2TmI)ql zJgHZ|hK+*!8mnWau^$teUmJ^u#+ebk$R8DKmG9VkWZ=BRUyd#76zX>$_Nt|ItTa8V zEbeF=!?RcnCo5(f{&C?!{822HfHP+D>+#*6)VI(d3pYdeDe$_Qthh zGebdc^W-x|inc{h8~cUZ17I$=M}+?>SY!ofnZ?xrBGzGo0*Uzq>n_=ea+7rUCgn|3 zY5X)ef0TXCC{F>L$R~Hr`yvhN{;rU;{XH~7)}xX#X?a3cZc3OTTc4glz7(_%_`l4&mK)Itvs^+=w*;8xo++dl4kk*b-W`wRD4Gc)R4I7 zhc-RQ%>24neOIE{R*2SqryC5qRVJz&cRErsnU*CXX$DW`x zcS=&Q^u#^)km5qA_Y3?MnUFF~)RfyPnf%E((w_`34PN!;t&5~lShc~>Ao&fFvS1AzssM5eK!qf-(F5AqkEQZuMS$JIsot@G=h5nv3m&N89TG=Kpo$zwo*fUM?t`eS<;2k#~_LNLI9$vs{kpuVKH#K!wBKrzq_+{ z@xGXrRCSBQ)k&e|{EY&gX!IQbGizRcUPj7sb+J8|5l`bnif|p1+?9gKE0sc=Xu??? z)STR;U^kJPGn&pTpGr}_`A(YZ`wOO=qR^45E3Li<8a`U|@2C@S$gfUD!6IM4iRhy- zDN|BBrJ(c66(Wrc6aIcr^V;N;#XnS;4(+z9^ec@Tr_!wI-ImjOja~07+9oIeK7Boh z#%uBt7kouCCV!Niw0%&O{vE1I3e-2S%S*SNd0B*|!0$Ie&8vheTYkYsGO4h1j?&n;J3MFqGfHh_w^-ad=7!H+^gUB?^^_iDUEpc=X+%2_K zBe=8u-q+VB;%jT6LHFvLU!NY~a40g&T=#Zmm{Fz>D-=jogH#*$Wm@uBqJg>mW8N{+ z<(03&uheCAnu6d)CC~b@UOkWcF6qG_nug^Nv8bZJY?Ff#1ixLJDhUaxTQ$z@6(Tr3hx|C_iS7}ukTX%NJ>7#kJWoysPN1y*JV<~U~Dfg#H9AYg_t2Z{cuJ?R%sPj zBJC78a7$v2#G7*RL5+K)tob7l5q$RfI~>m{J!jrBmEJO}y)!laupo@9%_|}(PB19n z4MAlyS>0XAL;J-KpJ+bzP0!ROb?(3k6b|=#9}|m-i>us}JY1EM)d%S*|?PM zacdJlQWr$WFq8JY@*dysgF~mQ@IIe!7vTrrO=e#*uzaob^S<*yKDN1qU3u=>E4BWm zw1cbBntcqC*#tthh;1U)-~qul|gZ4H~#=yWgsc|S5l6MC{9&-77jfqTkN{SBo4ehM_>2~L5E`;_ZXQf5fs$>0k6y7 zyU|c-`JoTh0Pn0Avl{8Yja2FPcPruTG3g2va<3fca^iDGib$4(Hw5q4>Z2;NQfXMZ zFr375pe(jyT5f(IB+8;V-F0b79t(AEtZUfK<>cE~g`;yXKf1fW*X`0JKagm4EX{HH z$?iK*I<8<~!noID5JH%&C>uMJ2AY-EC)Orp{O+CG#qi_9_=JI&R}nrg(llQ`Yk|`W zwZc{kL&2*Qlh}ckezLYVPPxF5jAZ`lCzbZ=5V6v_7q#}lU4fH?YGuPq>gIQGo+xXm zXHiIfQdf^jY`y2h$@Ebl!Ng-7*kQNUR98GHxl&>XfU4U}Jd00ud2{Yvoz8=30=ONM zggM&3=%+DNweI388&0r`TTKL6CMV634%J(X((Y@XHA5f^+9sn;O#Ja6{ z!^b6LgYgQy95`<|SZuV1yCMVY%=qLYZ z?NHhAZf<^QuZt|dNmbEGuS79J z&Uj(fNUVfCzSPlu96#y%asJ^Bv-f%qS5_?2@;1P-s_DJQSDv-qO$~|}x;2;(Eq>*(z#CDU z@=qi#aDC%Ek{X=m{Go4fYD`OH%35{R(q9W~OL~zO^|bc|!0x|_HT*~v8BHzmB`Bf^ z%Es^e3xL$4>g_(idnUpCIhZSM?}-U$AtIw-rA6%mUAa6^u|J1^_=b6FB@W$|0fa}% z)cS0UU^Gz*>9?}}Hc$k{SUiYwl54w5$dXZLSTnsN_DB*zaP+T}Vz50UH1!G4y0+pI zKK>2;x+m%Q zb$J#^Lc^NuH*QG@T56F|pQKvr>N_x0SbTOQ3MOBqKeN!_bx-y!=NaulL(pQ0JX)ml zVc1=jQ*y`Wa2E%oyZn*IEg118NTbo-X9WxPj_h+1D4H{)FwOpxC}iH4^u6C$8<437 z(qk*xNm-wosOaP;VdEen_?C1&U+=--v#(&jp->UTXdMY$ZN=lpMoy1A??g)7Ow_$;@E`^56lUX0ULL;?} zWlK`b(Zev2Rkh>MoJV`ntq(C9u!Uy&6V#6|bUiLoP%_Q%`^!dj2h%`tkHlOhdF^{t0xA~Vp^ zstj#IO9grYK?w0qCsr1`Dngr|5dTdwP)+v$+xHLAW8hEsJF&1$=jKH|+9sf5Ndv3q zi>r!zPsqBz#Vak3_LNR!lj-)YfiEDRl_ywPi9vToRw#IrR8>Btk6!#*HjPGa`)6tEOjjU(xCIrN&!y`|zQ5$CmLe_U;PB$kz~{>qXx*Np3`2f$wENuIm{i zPK|nmOd$hl^qsDu;uQx)1nsCuL2)1-&1D;2f)`qL5=V6uH=W6}UD9Y(XhEP#OfhUQKS%!@{W2j&OpKjMUi(oS7Lk~$?xLiyOLXBLXrj`})1iO1EL)y0xl z#TC$y!8uE$1YUE7*aA0o3D_q`#M`kRjgUA2uVhpDhmU}lykg#T;|9`GTuwEN_74Xw zt}EmTmkLNn8wK7eIXYX`J5mX4-_Jv&)QXQ9AQM)i+9fg53?L*yNU^eK!>Zygb+ z%n;!xk>6-(>pXEChG1Tg1AX7sxm@j3wDE$c3aWEf*$<&9kySr!<(I){Bu5R=p5`lg zA%(7B)8dsX=n^%Ph3DrkkLCqL*_&@+83)Lnc_xBJ8$p5^Lb8603N9*YLDNV#L)zxLkZJhTef9_X; zL*3=5Z=J0IG&lSw>&16v6uURBnDoIiw>|kW34ygY>q`uxYwW;2S!fBNee)&nj)9so<8o$qkM+8&Y_I}y!4ysMe&PT*Gm7SLiqko}9RoM>w zd49-|9eKfzDO!qnna$ovPRo!+u>X<=4ESQJBUV~_DfEB}KaS&<3W-Bq1FS?%dPPHU z3wqc2lA_af@Z9)$q}Vtl?pUW<9KgsP8yu}Nn;Z>7z=ZsxUCkiP^3tEuZs8ySw(ELF z+zOkeRPr8{!87wX(685TK`*_-K++x+t^i7g+DN&Yjlo)Q#BJ&WZbA1<7jalr5o7N= z$!VH9QTBnEpeXf51{1PU@ITJx1K@L~vE}L@TXU!H?eTOvV65k@< z@+|`nq&Lc!`e;B6@hHJf^2^D(apxQxtx?teeiK|=T-VeJ@>b&R7H|Yl>}(cZNIbUf z)aSEtv4GM`yN-g$J#3il)+g?8iq-l;09Z*T9RCV&j>Y!uE^lt_NOa?#{H!dA=MKHX z&(W#{&XZoS>NB9S02!9OGHR>qn$aw5^vQK`@G}tbCIm%gB1s`g~ z=k`3fc$01qzrv4CM^WDkBSx(A{TJ0dz1$mqa$~TSWPvM#tSM@#8j0+WJJ%Axt>v$}N?(VafeIv(cI0Ttt z#^f5P?~-}jlI;0$Udk@G4L}PtY)Wrzx<}SGnVAWCya#8eKHMTM3PW5uXg1*%2Rj;R zgOB;dzJP5(<5XL|NYQ z_V_Guzz+_md&BFUR#(`cOz@&mLZP5aj>d9t3_YfB{5rspa*OgE^}V@32`IAa4UI{w zQt;LML&NpyI7g==xhBeq@Xr{jj|Io(s{z=Q-lN{=1j^SyS(Y?rTF^}S7irMT=WJ;sVMkbfOv^Sz!NsM6_K!^3^rwLOv_hq4 z6@K10avE2pnzpJoZfWAYAE#=3tvN|EJ%-uI4Y`vn#iH@S-Fz3KVdYK2#AO{=_$5Ug z94@>1uKOWNXH{zk(*`J%MF%fESq2yb3us;s7vCh>XIqVZOm%3!2Ut&r6{d4m)2 zLv9KHCLxlA07BjSerM&t^?BK(d%>)h;%@)|f&$Dq~^S>|{&aE!#b zUj97N1*J*Pb~7n8kK5~O!t|fKT_&FW-pgu_hb$ggdUz)b6tl`j4AhSveeJHNp8kQk zlE`^uoc=TS>Smo8{t2b*N5!tF7OzJ?>^!jg)Ca5WkF#ERtX`X?{SYsA)f}PFEE)6w(laLJtjU zn5MG0$$u!wRQ@eI*D(L{OxC_?g%(Zo>`VpGHN4mg#1Hx0dz4CdQbRdy{IrfM;KrpP z;e%N9B;z?JIO^sB*2*V35hpXsR22oXYKWwbEHjb>UnhpZMFB?kBQFXzdyGSetNGXz@Da_M<(h;=fh zMo$`B=tRA0aIxQkoaJ^)4%1Rh6eu%3`ua??S!xyN@mtS{>l`mSSiI7DzBD>)aK}f$ z7YW@zJs^s=dcAZbMEm{ZtpPS+K)JGfxSSaNTaaLUTJ|nuL?H;cx^!C?9TdO+H9Z)kh@YT+h$0-19xg znF(K$ScP&t8|GEsT)OLosX)3oBnT?59l=RHM0o3Fk#usMBtoL#V?{8WPBOLeldiaZ z&>$#g^<9j?#|t)5Dn3yyESJR_rRx~xK5{Gb+BHowJiQuzdKiCL&@8Wxr&C{!U;JYw zl98i0OwQpH{~OPuHn*EaII+#-F4o-sX3le+qDU(x-7g{EXUURuYp(mk(E6z^L7*J5 z3>og8>vzkQbeBKnXrR-LNtWT?Nzzac?H3pe)bkK79N3@@vHxrlg#Yf_g~WaxInDgX z__5ZxGR!~gKIf@)F8)>FC)n8^q*`V8Ai;#jp7g>w;^KD%-X*7r`_~>EMd$h~d|_gW zz_2}Eo_NH?FZobxOa(Wc)K>hX`xhsqOrgWf6JUlbhB3*XK z+geCz1W~r_5PLtu+pYymaR70J1`09f07ipE3?+WN7XJq7Nkhac72ub~vwz^c&-8;&h9KxIj*iab#hbJ9*RBD z#fSDr6KG^Sr45nMV9sFf$+(;+VGL@eL}o3dP1Xn3Gfqs4KQuNHc-O)8gSA>!r>*Zg zwzd{$Y!6XI;=8CSE_d9BH;8_54S3;8udT#&#RbY7nZTuljM?0$Ormq2PqS4K+m(oSBP@d98rKzJD1KX8O8IeZKpqy z$|5&NG5gwREqCjduG)@g%;mhIjCc5=+zx`T7nBU&tX`t+?2?ZSkRIbRiL6@5muCy1@kiGSz98$hZU^!9vK}kY@sER;TP6 z8(Ug#^TzcK6FN=gBY91-=<-j%n2-FbZWd4u$Uo~!5PET|LH1Z9z+?|!r=BQ5=$>qF z8e#BdNfCg|+D=23H6YIB6|!;N0H3^A&O^Wa&@SMknr;e5GXvep4mCG1o(mq`woX$q z28qIl*vF^2>r1Qk6*+uNXA;?R z<#6GgZ0bTH&(D_zY=ZOgj{0td(lW|$nfrc|ulBZn5Qa~5%etC5H$bkPSJ`buPGP{y zEDUnPB+&C%c_cPSRXDmN6h03&a_OdOh1JnMsw?>Add%};iMQ4`lt9^bOu>yuP1_8b zyHT1p$lE8}s}|72sL89{a$Pl$#V!8W!k4u#TchF=Ok_Woe6P~b1zZWHdA+IaY#_Z^ zx{EWrD+SU;4*$3<{NjuRJ7U&t0b|M9l-+0I0EHko>gk<9Vxp|PLc?Lj0g=-uxAZ#_0Q2=nTA}zR;gX`)l1Exyr`J(SV7mL!-)-=960I3 zQ*snc!ZV~feE@XS^Y#b%w>$VWQex4~1M=|U%Mo$W{tuDa;)ej`We>z z_<8aS%n_sa0sb3shTnM!j?mBt6xbcS^}zoe1%M{`!fyvXy7baRj zWy0twd9624i>k^~Y#}dXyY#GV!+GCdsZDpCtjPIzWWb%<`nSr{*jq5H}(C#Iz$z`DvYhWtvvNBs?h4nmY}Jx}Bm?03>60Uk5C?u{t~;+P@2Q;Gr?Qpa*1SC7E&@ z<-dpI?vXz+A($}#Ie<2jc3u1@4*X^VI^4nxu5HQpEfKvDJM2<4&=qh_ zk>Az^fA|6&;F!D@8&pv0hF4_HuoM27-;xD2XG6C3mZq3{LlM# zu!?U=8M>os|Vb_m1k)m&*sw56L_>SU$9A4Mzp1`DYYy{?-)9Z`R2mv@4 z-ouh=;mc!Tbpfa^-Sy9iBRZT=w_%XKAE_8IneJr3Tb=r-s82o7adQzL^oEIL6pD0wOYkC zn+4||_FPdS04q~`LsF<-*qq-O*nn{bR-I4sI|NZdWR4(Y9j}VJ#E&e_K~-5De>E`E?>2)E3h191 zzMW+3{ha6Fg@S#E^**4-C&E{#PG*p}!r7Se>r*@VPA@`Mmc_RYG{9SsHrN~lYj@e# zsxH)tg0gUNJ+a#mttYb|Ud&r^nh}HWL=}>INzms(iPegq%F(ABmF4i$hA+G*i@{EO zJIAg~l*8$l!8I1N_dn`BaG59T~xDt;w zMuU3z75wq6CaH9dT@{%4$S$1xB`=OP4Q{TxgZH7GhV`&`Im4I7(j?tteMQ_LgMqvR z)kS#Fx|6mJnbxxk84WVnBeIM|fA+lNnD5Lo!Bx3SP2>{+ph^=NK}W!;#ro|4f&dDR zvLV$gS*vflBf%ZZ(}s=>W^K${PO5yhOBh7IqaVXMppc!5iVGDKoQPM*1V0~o4vJ-N znIp?;tT!+iRkMgod(|SyUGTDO`rb-F2Oel%FEO8k`Ll8>mLU%j&7XujG$g>=@5<(D z-xHfTh~}$2@aS7QK>yL9*;HLgC6dEF*$4`3UeQ6Dt9IohUN{nAr;>-*rkU3gj7J#vhw;>A61!t&Hu(>j|XzTmiJH9rxsTqgF1eiy$v2Zo?&@V>2+(9 z;3&E%NqjdPH}`ol`B+9a%NgvU>EoV=AoRz~(LT;yda~n1?8LBdyl>&aB+%Js{p6bu z*%Y`N`xlUhww(Xfm-N6wPXyX2%YZxXoxr%LcV7`f8*+;TRKx^MW=b>^8$@`$p*V56 zq=(=m5~h%PkpHIrI;J+jG~vUE}7BCpLn4 zRfNm<2gc^8-D(sMFIoj}^3_{`I}98;l9G^KH7|uz0;^5-A;C>ua9_1B1i%*CZ<>oJ zsOm#(EW*bi(B4zz{nh$)Vc2Vv`jhbqUcVD;%mrme)u@v_KLMPcBc8l&y}BR59sPC> zxf{LG7k2L9xtL+>bx{-w+iV{)FcOT31Z(@&Rp0Q8n9-c#4ImmrMj0s33VJB0%FxE$ z!p@|sfe|LRp7?`%y0)pCThB0dk2lpkc z2D+9gxS8kpW3XFwAAoHDRa;5r9q6s|`c5_eFmzN)kMe78UEFh4p74XgaB!6udD}8* zqMo$>?pPuXb;j{Valb}t5b%x9GbU(QnW0f;Gujmpo-xA1mB&$S%)8cQ_@cKA8E#9R z0~c?D=0Q1&Ovv5Gd8_O16L{CPX6Uod025G@HEjvNiCyWI=0fH^i}Zb5i9&%CwY~X; zd;nembp89MUWrx^ukfdobP4GY6q`S8$$wqK-MFsl^Zf;8lbv$?)7kn5;l!-Uk1vPJ zQw#io2{flL*{w-Dm=o2o^Wdd5zB%*U!O?uxLT**0)PS+EpS_OWTajQBS-r*D7y1&u2<;^Jzk20KyvFHu|ENe`hM^4 zbSo#edz2>~mo=clP$}zDpnqH|LgfKvd-S-kM}3yofh43A3kT|! zNx6xb+8NX&f`BKCg?qw1Gh2`R7$dQ)docl&i%h#GX9TLGnmTNAg0$5@@jW!V$!1H< zpx*V0w(^?#Y_z4uz|N~O-&ND{OI1gql|A-DBz!d|B;=>NEnWtpaZhY)=%DzEdfS?N zR%$lGu}M5-2h6RPu)tvtNGWs;xAVSe&}kTq)#2m$`Q}s3l!m{xZ+iS~XX4a3Nc#(_ zY5!sOW|q-Z@2C2nsggkz@YexW4%D(y*PmP-zNdcarVzg<9kYxpooe^+t~@BQJinj> z0LmgJUGePZ@E=?Rnxng7;I?P$Q#)qIxmH}4&oOP8;9|VSD{32w@tix4Z*fv!d|-f_ z^ijKB=U0}b1La1A!qH9my0}qghs3N30m{J~pfZoT>~KAhkzx#m;e~Jd03uPbRrs6SoBJcQie` z7(G3`_>|r_Q3s#dfJGbBRshh>?*Rc!k~nojJD&2WtKZ-9ZWp<&%PpZ;DI3Yn7+m*}l`M2B_E!~^X*_XfzDxV7 zZBX#{L^7lxD|o0QX0|`b=f&<#yy796QBY6!TyuvpQg08kDzigJ8spUJK|@2=zNACf zTzhsG75~bu4>H-(tUtDM@D)h|X$!zD;p<0rq?t=H*50GM!kVOkQJ$91A!v7IiHg2* zJ#eWhouE%`U+-#X9X|Tlt$i>owOJatFcdHW!t$3>o}%rBQ~)C9=%hDgYAxGgQt77t8?8GyWXkJ66yHVFTXWvz6& zDVpRkW zW8=7ib%_}~KVVg{AanG1dWKM}(L+mNF%F9&wkaDQSteeORFK>d;wC3+6-=+FXHs%% z;WuqA>4butm@AS|tKUG-Cf_|#WkuG!Y{bxhWU;lT;q+8q&lz;no6!0dSz92FF+x{fiZI)Ev$1e(@3{@L=4q&o#Lat!HOx{E?33D?y@g^F zhR2F0Vq+0%ICL0zSJ`G=d;R9uHurhha5D7MK-BBjOFsW!Y1bW2<@^5=>C-?6WmL8j z$BOLACL@xpLllv{M@1jmBczTktCVpvGmgl}IGnOKIaXxPGJo%<`dq(n-{1F-?{)qD zIe$FY<8eREec$i<{aOM{Yro1w?vNYjLUY!d&a8?4`D_$C+lz41YAuXEZt`g*ZEK)r zNa%QJG{9qse_jC>FDu(L(`TkfX|KyogHMf`OgC)Fn~cYh*m=b(?>~S5N?+(56_#iO z3*g1q2vljeCropgJk6h6UTJD_dLMgrDGsd2tu6h1W?}?UZ$lRTv)oK-QN;zZwF8|b zF=2onjdjS=GzR{hOo6;17-nO$xv)Gyh%>rz5Or{BN(?18_I@GFCRfp#F<*OSo_C}c**{I{LKRE*A_(>|J(4yLvl`xhlNIJM*K`5#tK%u6-nHocgrKgol zG_RdS=gk^Nv|fdZ>FfQ7=vu21O>eT5XX)V8MO9k*Ad^JuRXC9Owxxx7Q_wYvW8Cw- z(mm*oBn+T|qBrcR=&FVzjDy&Jy*!c5^FPr3^h*UM_iUP2e(56SC?nj)1eeL(&8L_i zd}W)tugo+QT9iT-0$M3uDLb6%L6}z(4*S*5kc7ilEVBQToh=;V5xwRal60iI?Q$*x zr`#|Z#}`DKH2=-J_DLe~jt7I&J`OD#1QSXh^EW_1qB)Xv&HeodT7KP6j_uO_5VbC@E^rT-Roa^HubNzzIhFx+9% z0A$kUe7k$`P%knIgs+Icpo53q81F+Jx{K(}Dyi;X7KC>UITV43@;w5JvCNlt$n`G} zlB`KJsP9L%)JOksFs=vZL3JV)mghh31EqHV_{2Zo%v0ZgK+pfx+nz{<+ZXv=Qb^<< zZ?IShd0r(GU=uli|D`^TZEAxl`oPsSfjGsk=_=EJtz)CgD%B6*Ee3lw0+@b8m657> zdt26d>^phtQuLv$eY9qykM_}iNs1aZP91$=PjggEfbr^n4z1fTSJ>Fc4j9l}{3%J2 zBl&Jo$WBom2yicZaZ&gKz}hZ?Jqquc)Ay9+FXh#Vu_S7W>V=U>DeVqn+}|f$`$z;5 z&XD*adsy8ykrk8uWoalyVU> zmBS$1sr35T>vjznHYaQFsZnhM`Oyu2p^QhzQF7(sic@mF9RU&*(y*4DgF<5=+lyMs z=|rL^7;Iqc%C-!%Wq<+hrmw-J9pqAF=uxXP_4r7;^tMD%5dtD$iok~5K3k7h9!|^k zXRW?~t z0sat7{*KbOxVNcW$R%%vlkJy6Fswt0>2YswB_i|$v&qROsKZe>1;Zn9AOrVL9j}uh z9LEBBBzME$Fq`znaX7kMr97OZ=yMQd;$w4S=jMACyS>G|V`XN$ zd_+B?4C9YGe=YcG&p2t?o2>1DrDkn!HG|BCaVv#QZ0L7r3K*AChZa$MJ!)HES$o;y zvQ|+#=KXf#n|tWsL&QgxucDOm;M>C@536&K(p3+DWmP7NaJJ6g21~i7VT5_8&(Xui4+}2C*j&(la7% zt%Q@V!Ldfe6{i3defxT+CIl1r%%yw9ugZbAfpxTKWlPxPZ>|UZ=Vvoxc34HzEoxr0 zsJM^!!1>kOnM38_HM;5l*X-u3I!M6M1~N<>i0`nG;9dLAF=VQ}&17Qo(ENQde8a3w z#Gc`tWGfJAUkP^so*0lc=)C-(U1r_W_!Wn8$$FdaLRTy%yp=p$sZ2s$_c5Kj3-|i{ z3+=?Y!Jlaszd^uSvNJMfvg?GC{(y1PQIs%C87t^6`>O<3gjG5#jc(TKyyZe8{m$HH z&0Ebab=?~&f%4C4R9{-x4}))yt~eRJ=BG0cQ%^^rkd_-Mw$yI7%G(n>E`VR{x0vQ} zw61l!#S@v*q6eImdy6EU*LzJym4n0o?))=%OgWd-c(8bxNnMeBB|1K~-YU=(2y&O^tLtLl>rZv;LvTq~`<{8|Ph^}=maNnzj?<~(>u=dJFFMLpq5eu8im6zNo z8ZDth%Ll%js;R{vgh;iF$D(4{yaz?c>I%e_%kP&6yz_5${l&OQASabLxm7MSBHJh^ zW*h~fjf3OBVLAnsP7W2uveS(a3lRuF9$j0q@C{;n#GV}S2W{3yqp8iFg8-Nd^-|Vi zce&e%<{=#Dcb{$sf7c1T-pQTm_3GfYstr?sn}lX$*Wc(e9TB#@S!if~$J}kp@Hd=A zv9PZAFCg4zUfaa2PM=jeBw%jS-EHZdVMTuY{OaQJM_HZCY##NHxMw+@j{RDeCKB=H z%1}a+%39-yT}w$n7MD?uYJWeHmliTE0RVp+uXiN@nlPP*+6aO*f)gxt+ic_`7F%t1 zC|5GtQfKjQiLtVC9s=Acv`cQGAkt2D`(7iX)-86d?_u4xrJ+SBY0i5$dI-$<*56ys^jP|dRuE|iT%o^4Kv7zLdXk4 z^-OoVRdE?SA7p&~CT12coM?4KT)s&^+F;Bs)i=p5Og{#wsVT~Z^_ou02fp5o))UI- zJZk)(HY%4z%&^SMfz|Rx+hcjUGIlJalU*{nVnn$VeYOx%+x$QRrV~u7T^_b~NZ;zU zKRpVZPcA9tS2=GoZ`#FM%W02*-?T0hyrEZW-EP>P5A*N`&ZKz$J5`B>4?5Re#cHR& z0kPUv$eauSAnpUij2WO=BFmjx!HpJ>v0=%8(l_6-oVf(rp4{fh<6L0SSm#U^=f8|> zgJKdoxbaF3eN=Sg#Nx*3YP>AMdt9ELan-%<2ogIaD&o|ses6&d>!~90bwY1Hgd!<5cj52$`{Dm+M<9bN`w-KG3h5B9C%7xn66 zNpotR&Pp}Wh*S-5_W9=SO3GFGa4E$1`OHPL^+=z%7ox6trsvdzJmEQ!G zZ;(FluH+>TW;MhL8Moy8r2T}8LA zg=92hD6IB_xG6}woL7nCSxPwDaheAzBR}X=>`^A~%9<%-lm)#(jWSWl)O2pkCL(s5 zl$ZU2jG~~UVycI@pU{>AVy+jqVn{>r)ny;EpsNT`l}lM>f`$C0=DDoad-M?iL$oWI z&v&?;CxDaQiPCbN2zGnaR6hT8%{(r&(A_w%qtjgsB$vCO7-5GuqW5klLi;iy)jiuJ z4hKBKsL@w6w2FtNJ#M)C5@{FQ`qjiwfXBqcV zs~+s=V1S8@ZS%1n9o*4TE=GMa@aTu^!=Kb;;X}_PWdby+R;i-LU;Rqn3csai$hB5z zvv3=mAOET2+)NvLL8v##emX^UwZ|Qm?I#`Sv6Qdwv7TB&`?EZuf` z5=_jrM0J!9p={Fy#*<CVvh^P^u8H>IBZJuyUxhS0O%~_WYlg!uK$y-m-e7&FZQ(ea$-w!%hQ%rD)O4BH6(O2W0PjdCpgi|o?Gvx5Uha{-K58V26)V%IYA`q{XVW$ z{B*m1&WE+MVJtFfSWMkRk>zNgRp*uBm5;w2_|~sn`+|C~M)k~7R!tYW`vn&i?Ms^C zJrJP3cqnGJ@`U$&F^MO;8c98_UTbW{q>8_(LL>1a-9Ao9oKj9Km8ZTzNmg`{a7n92 z6C0ZCYBymy+V<^ju}F}lLM=MprMO{*r}p+p@cLj-QrFz9T-&!+^};%#;)@}d)?Av8 z-44z5Zyu*_H&6yM?=&CKFBTTQP(P!8m*$p%u}7GR}FtVHq=b@?+6 z0p#*ZF(&!gE5eIrbo{!HCJT8Pxapm3a$}et1!01sJf*WbAcdg67qXb%yjiyQ%uIkOc8iqtW-N<1Dn}p+BQL;*j{g}Jo0bRxzFOB}e+=gQ zX6t4$%&Ad*&sEni#h48%_<)<9ekoeGAtz~~*y1LtarZGzeG}#Kq%+R#{`Q-YU3nZJ ze6sS}f|`fk{FVLJ6wslmNLpi-ZSB{F>s#HkQibc>T^eZ1)Zk0b$SFcAKAj1s@=z%; zfE9`OYr5PIzF@FhHw#LLvs@fc7I3Xu`q7Gay3f_|5HjX;E3!g8;!Zbfzi!yVvwCk$ z@QX$8#2prYtL>JCX??&+6IJdBRNUOS#@Dy>p20~77Y=1Fy)J82J)dBgz+pBUyB1G_ zTABa8?AbW9bIi%zgp!D~p!NoD-&?(XTJCl`H(QmCp}(a=(`?QY-b ziaMBemYpSmd%f65C$lvv=!sO8=n%#HkBe-(-^nez`2$SiF1d!OqKVH;Bqt%gi)EY> zZD!ffHu75e?%bkx7i$zvaIVk0cl`o-s;0G~kgajK{n?5tPM*2tn?^yvb(x|#iK?6q z?>(Rdyj@;(72-t0=F_7My>NR6^9GGbV_b8Ao-(Y%-w%k>2f1yA@yc||@`|ly<()1K zYB_2wj&LR2V|o^^;_QN`j(FXB={@NzctC%6CC(tc^BS9F_ihfQYs}NfoQFQ#H@$7Q zq}^ewE-CkNoqukd30w*4b9y|lj_O%G;FfP3_jtNGPNsatPyS?s&knO?59;#zN)hA6 zg9d9!HnzS{8tmuEi$$gdo5l8V%UOM6j^8my3X1r29HVonEA9QfG;^&h&{4r|+9X>mMtyBf$S;2=LB90=H8>Mz@rXsZ|x>-g<9^ zJriTY(yiz|b&7WUlL>0P-0hzc5tD(pgy5IIB`#`rciVYy^5H!VBxM+FijxLQ-re^s z?|(F`eU-~qbp_~br`xKchnR97cN%5vA%1$%Ade<|>!fh?_|4-gpCcvu3Mp13@oN3g zFqwB|P+M`P7E3~*ak%SzO+1s0cp+Pl6&I^}Za1u4z294=>cc)F@E&63p3!_`3PvjE zuv3voTp%wshQmWS&5y(K_)8?{8{8pT8y{|4pZ5mp|7wySXBB1|AFV6b=@lI_IAt}_ zqj77t(O8M>`b&ANiHy0YyE*|+vlLw`KubvReT7Y_PsVLFE}TcHWZG|mntV)4h$_@@ zxu8(MmTq0DV7uRJT=ztKjyd=!ps7+9baf@Fb~R=jupHmf1Zw_BqR+ zc<1`3Hai56m#7fqL9aUo$v>YP**+Y->Tto#C!gsVCatht$I)f!{91CtwIlWTtmO2e z<0wDGBjtCo+0+7Lk`NjRAgCflA3NC{2*EgeR;bwnRJT;L6$XYuVUs_Bkn=x(*U3K- z7{G1*4ZQK;g(pf>@cwyU7;e=IM478IC(Q>GmV`?7?n<+xhDKm8LlupY|NQN|=H z5)G!A*>$9IXXQ7egoq~QrdtmETK^6t!EX5P0FiV5=ZlD??BaW&=uAi{@(eAZ57^g( zJ1o}}485bq<2glRFrPK{*$IIUl)$Wxw2?-2%psW2i_x{FH38@a5^7XszhXt0I#}fs leR3EF{EK9m9_<~Je!&@x^4z`x|9*I%ih_oG-WAio{|EEZ%4Prn diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/ApplicationNodes.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/ApplicationNodes.java index 1a77c21ff..766a4ef1e 100644 --- a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/ApplicationNodes.java +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/ApplicationNodes.java @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.hedera.fullstack.junit.support.model; public record ApplicationNodes(int values, ResourceShape shape) { @@ -20,5 +36,4 @@ public ApplicationNodes build() { return new ApplicationNodes(value, shape); } } - -} \ No newline at end of file +} diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/ConfigurationValue.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/ConfigurationValue.java index 8fc53d179..fcb1ff869 100644 --- a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/ConfigurationValue.java +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/ConfigurationValue.java @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.hedera.fullstack.junit.support.model; public record ConfigurationValue(String name, String value) { @@ -20,5 +36,4 @@ public ConfigurationValue build() { return new ConfigurationValue(name, value); } } - -} \ No newline at end of file +} diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/NetworkDeploymentConfiguration.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/NetworkDeploymentConfiguration.java new file mode 100644 index 000000000..cb83e7959 --- /dev/null +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/NetworkDeploymentConfiguration.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hedera.fullstack.junit.support.model; + +public record NetworkDeploymentConfiguration( + ApplicationNodes applicationNodes, + PlatformConfiguration platformConfiguration, + PlatformApplication platformApplication) { + + public static class Builder { + private ApplicationNodes applicationNodes; + private PlatformConfiguration platformConfiguration; + private PlatformApplication platformApplication; + + public Builder applicationNodes(ApplicationNodes applicationNodes) { + this.applicationNodes = applicationNodes; + return this; + } + + public Builder platformConfiguration(PlatformConfiguration platformConfiguration) { + this.platformConfiguration = platformConfiguration; + return this; + } + + public Builder platformApplication(PlatformApplication platformApplication) { + this.platformApplication = platformApplication; + return this; + } + + public NetworkDeploymentConfiguration build() { + return new NetworkDeploymentConfiguration(applicationNodes, platformConfiguration, platformApplication); + } + } +} diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/PlatformApplication.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/PlatformApplication.java index 92b46b57a..028232ce0 100644 --- a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/PlatformApplication.java +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/PlatformApplication.java @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.hedera.fullstack.junit.support.model; import java.util.ArrayList; @@ -28,5 +44,4 @@ public PlatformApplication build() { return new PlatformApplication(fileName, parameters); } } - } diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/PlatformConfiguration.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/PlatformConfiguration.java index 381d66fbb..8cf770d91 100644 --- a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/PlatformConfiguration.java +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/PlatformConfiguration.java @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.hedera.fullstack.junit.support.model; import java.util.ArrayList; @@ -22,6 +38,4 @@ public PlatformConfiguration build() { return new PlatformConfiguration(configurationValues); } } - } - diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/ResourceShape.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/ResourceShape.java index 1008bd822..041183ba0 100644 --- a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/ResourceShape.java +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/ResourceShape.java @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.hedera.fullstack.junit.support.model; public record ResourceShape(float cpuInMillis) { @@ -14,5 +30,4 @@ public ResourceShape build() { return new ResourceShape(cpuInMillis); } } - -} \ No newline at end of file +} diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/Topology.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/Topology.java deleted file mode 100644 index 7dd815a45..000000000 --- a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/model/Topology.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.hedera.fullstack.junit.support.model; - -public record Topology(ApplicationNodes applicationNodes, PlatformConfiguration platformConfiguration, PlatformApplication platformApplication) { - - public static class Builder { - private ApplicationNodes applicationNodes; - private PlatformConfiguration platformConfiguration; - private PlatformApplication platformApplication; - - public Builder applicationNodes(ApplicationNodes applicationNodes) { - this.applicationNodes = applicationNodes; - return this; - } - - public Builder platformConfiguration(PlatformConfiguration platformConfiguration) { - this.platformConfiguration = platformConfiguration; - return this; - } - - public Builder platformApplication(PlatformApplication platformApplication) { - this.platformApplication = platformApplication; - return this; - } - - public Topology build() { - return new Topology(applicationNodes, platformConfiguration, platformApplication); - } - } - -} From e4723e8507c155abbc5bbbc8b7dbbdb80c84c64b Mon Sep 17 00:00:00 2001 From: Deepak Mishra Date: Sat, 21 Oct 2023 00:16:48 +0530 Subject: [PATCH 4/5] missed changing a var to full type Signed-off-by: Deepak Mishra --- .../junit/support/extensions/TestSetupExtension.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/TestSetupExtension.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/TestSetupExtension.java index 8ca3248c4..8669052c1 100644 --- a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/TestSetupExtension.java +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/TestSetupExtension.java @@ -22,7 +22,9 @@ import com.hedera.fullstack.junit.support.model.ConfigurationValue; import com.hedera.fullstack.junit.support.model.NetworkDeploymentConfiguration; import com.hedera.fullstack.junit.support.model.ResourceShape; +import java.lang.reflect.Method; import java.util.Arrays; +import java.util.Optional; import java.util.stream.Stream; import org.junit.jupiter.api.extension.BeforeEachCallback; import org.junit.jupiter.api.extension.ExtensionContext; @@ -42,7 +44,7 @@ public class TestSetupExtension implements BeforeEachCallback { @Override public void beforeEach(final ExtensionContext context) throws Exception { - var testMethod = context.getTestMethod(); + Optional testMethod = context.getTestMethod(); if (testMethod.isPresent()) { // FUTURE: add support for NamedApplicationNodes From 40806382c3afa64d4068e34cfa555af0206a47ad Mon Sep 17 00:00:00 2001 From: Deepak Mishra Date: Mon, 23 Oct 2023 18:49:29 +0530 Subject: [PATCH 5/5] sonar comments + spotlessapply Signed-off-by: Deepak Mishra --- .../junit/support/extensions/TestSetupExtension.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/TestSetupExtension.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/TestSetupExtension.java index 8669052c1..137b9ff39 100644 --- a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/TestSetupExtension.java +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/TestSetupExtension.java @@ -75,10 +75,11 @@ public void beforeEach(final ExtensionContext context) throws Exception { com.hedera.fullstack.junit.support.model.PlatformConfiguration.Builder platformConfigBuilder = new com.hedera.fullstack.junit.support.model.PlatformConfiguration.Builder(); if (platformConfigurations != null) { - Stream.of(platformConfigurations.value()).forEach(config -> { - // FUTURE: support values[] - platformConfigBuilder.addConfigurationValue(new ConfigurationValue(config.name(), config.value())); - }); + Stream.of(platformConfigurations.value()) + .forEach(config -> + // FUTURE: support values[] + platformConfigBuilder.addConfigurationValue( + new ConfigurationValue(config.name(), config.value()))); } // Topology holds all the information needed to provision