From 84a209835820238f50d84ad5be5b9badaa5283c5 Mon Sep 17 00:00:00 2001 From: Vodafone Date: Mon, 18 Mar 2019 15:08:33 +0530 Subject: [PATCH] List of Input Parameters for VSP Change-Id: Ie913ead731e120bd69349a4ebec13f4521eaac4d Issue-ID: SDC-2049 Co-authored-by: jguistwite@iconectiv.com Signed-off-by: Vodafone --- docs/configuration.rst | 23 + docs/externaltesting.rst | 95 ++++ docs/images/sdc-vtp-opnfv.png | Bin 0 -> 209345 bytes onboarding/pom.xml | 3 +- .../externaltesting-rest-services/pom.xml | 138 +++++ .../externaltesting/rest/ExternalTesting.java | 80 +++ .../rest/services/ExternalTestingImpl.java | 164 ++++++ .../externaltesting/rest/services/ApiTests.java | 197 +++++++ .../src/test/resources/logback-test.xml | 30 + .../externaltesting-rest/pom.xml | 20 + .../onboarding-rest-war/pom.xml | 5 + .../src/main/webapp/WEB-INF/beans-services.xml | 5 + openecomp-be/api/openecomp-sdc-rest-webapp/pom.xml | 1 + .../openecomp-sdc-externaltesting-api/pom.xml | 61 +++ .../api/ExternalTestingManager.java | 87 +++ .../core/externaltesting/api/TestErrorBody.java | 50 ++ .../core/externaltesting/api/TestTreeNode.java | 64 +++ .../api/VtpNameDescriptionPair.java | 38 ++ .../core/externaltesting/api/VtpTestCase.java | 42 ++ .../core/externaltesting/api/VtpTestCaseInput.java | 42 ++ .../externaltesting/api/VtpTestCaseOutput.java | 31 ++ .../api/VtpTestExecutionRequest.java | 39 ++ .../api/VtpTestExecutionResponse.java | 53 ++ .../errors/ExternalTestingException.java | 51 ++ .../ExternalTestingInitializationException.java | 33 ++ .../factory/ExternalTestingManagerFactory.java | 30 + .../src/main/resources/factoryConfiguration.json | 3 + .../src/test/data/executionrequest.json | 12 + .../src/test/data/priorexecution.json | 20 + .../src/test/data/testcase.json | 58 ++ .../src/test/data/testtree.json | 119 ++++ .../core/externaltesting/api/ErrorBodyTests.java | 42 ++ .../externaltesting/api/ExecutionRequestTests.java | 110 ++++ .../api/ExternalTestingApiTests.java | 30 + .../openecomp-sdc-externaltesting-impl/pom.xml | 114 ++++ .../externaltesting/impl/ClientConfiguration.java | 29 + .../impl/CsarMetadataVariableResolver.java | 210 +++++++ .../impl/ExternalTestingManagerImpl.java | 610 +++++++++++++++++++++ .../impl/RemoteTestingEndpointDefinition.java | 39 ++ .../externaltesting/impl/TestingAccessConfig.java | 30 + .../externaltesting/impl/VariableResolver.java | 27 + .../src/main/resources/factoryConfiguration.json | 3 + .../src/test/data/csar.zip | Bin 0 -> 14993 bytes .../src/test/data/fulldefinition.json | 26 + .../src/test/data/managertestconfiguration.yaml | 13 + .../src/test/data/notfound.json | 6 + .../src/test/data/priorexecution.json | 21 + .../src/test/data/runresult.json | 22 + .../src/test/data/scenarios.json | 10 + .../src/test/data/testcase-sriov.json | 48 ++ .../src/test/data/testcases.json | 16 + .../src/test/data/testconfiguration.yaml | 11 + .../src/test/data/testsuites.json | 6 + .../src/test/data/testtree.json | 119 ++++ .../externaltesting/impl/ConfigurationTests.java | 78 +++ .../impl/CsarMetadataVariableResolverTest.java | 88 +++ .../impl/ExternalTestingManagerImplTests.java | 283 ++++++++++ .../impl/ExternalTestingTestSuite.java | 31 ++ .../src/test/resources/logback-test.xml | 30 + .../lib/openecomp-sdc-externaltesting-lib/pom.xml | 21 + openecomp-be/lib/pom.xml | 1 + 61 files changed, 3667 insertions(+), 1 deletion(-) create mode 100644 docs/externaltesting.rst create mode 100644 docs/images/sdc-vtp-opnfv.png create mode 100644 openecomp-be/api/openecomp-sdc-rest-webapp/externaltesting-rest/externaltesting-rest-services/pom.xml create mode 100644 openecomp-be/api/openecomp-sdc-rest-webapp/externaltesting-rest/externaltesting-rest-services/src/main/java/org/openecomp/sdcrests/externaltesting/rest/ExternalTesting.java create mode 100644 openecomp-be/api/openecomp-sdc-rest-webapp/externaltesting-rest/externaltesting-rest-services/src/main/java/org/openecomp/sdcrests/externaltesting/rest/services/ExternalTestingImpl.java create mode 100644 openecomp-be/api/openecomp-sdc-rest-webapp/externaltesting-rest/externaltesting-rest-services/src/test/java/org/openecomp/sdcrests/externaltesting/rest/services/ApiTests.java create mode 100644 openecomp-be/api/openecomp-sdc-rest-webapp/externaltesting-rest/externaltesting-rest-services/src/test/resources/logback-test.xml create mode 100644 openecomp-be/api/openecomp-sdc-rest-webapp/externaltesting-rest/pom.xml create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/pom.xml create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/api/ExternalTestingManager.java create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/api/TestErrorBody.java create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/api/TestTreeNode.java create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/api/VtpNameDescriptionPair.java create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/api/VtpTestCase.java create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/api/VtpTestCaseInput.java create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/api/VtpTestCaseOutput.java create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/api/VtpTestExecutionRequest.java create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/api/VtpTestExecutionResponse.java create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/errors/ExternalTestingException.java create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/errors/ExternalTestingInitializationException.java create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/factory/ExternalTestingManagerFactory.java create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/resources/factoryConfiguration.json create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/test/data/executionrequest.json create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/test/data/priorexecution.json create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/test/data/testcase.json create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/test/data/testtree.json create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/test/java/org/openecomp/core/externaltesting/api/ErrorBodyTests.java create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/test/java/org/openecomp/core/externaltesting/api/ExecutionRequestTests.java create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/test/java/org/openecomp/core/externaltesting/api/ExternalTestingApiTests.java create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/pom.xml create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/main/java/org/openecomp/core/externaltesting/impl/ClientConfiguration.java create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/main/java/org/openecomp/core/externaltesting/impl/CsarMetadataVariableResolver.java create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/main/java/org/openecomp/core/externaltesting/impl/ExternalTestingManagerImpl.java create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/main/java/org/openecomp/core/externaltesting/impl/RemoteTestingEndpointDefinition.java create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/main/java/org/openecomp/core/externaltesting/impl/TestingAccessConfig.java create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/main/java/org/openecomp/core/externaltesting/impl/VariableResolver.java create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/main/resources/factoryConfiguration.json create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/test/data/csar.zip create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/test/data/fulldefinition.json create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/test/data/managertestconfiguration.yaml create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/test/data/notfound.json create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/test/data/priorexecution.json create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/test/data/runresult.json create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/test/data/scenarios.json create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/test/data/testcase-sriov.json create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/test/data/testcases.json create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/test/data/testconfiguration.yaml create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/test/data/testsuites.json create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/test/data/testtree.json create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/test/java/org/openecomp/core/externaltesting/impl/ConfigurationTests.java create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/test/java/org/openecomp/core/externaltesting/impl/CsarMetadataVariableResolverTest.java create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/test/java/org/openecomp/core/externaltesting/impl/ExternalTestingManagerImplTests.java create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/test/java/org/openecomp/core/externaltesting/impl/ExternalTestingTestSuite.java create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/test/resources/logback-test.xml create mode 100644 openecomp-be/lib/openecomp-sdc-externaltesting-lib/pom.xml diff --git a/docs/configuration.rst b/docs/configuration.rst index 7f4c635969..55c4751804 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -1222,6 +1222,29 @@ BE-onboarding-configuration.yaml truststorePath: /config/truststore truststorePassword: <%= @cassandra_truststore_password %> + # External Testing Configuration + externalTestingConfig: + #configuration to make available to the front end of this feature + client: + enabled: true + #array of endpoints that SDC-BE should connect with for external testing + endpoints: + // ID for endpoint + - id: vtp + // what format of post request does the endpoint accept for runs - json or multi-part form + postStyle: application/json + // is this endpoint enabled or disabled. + enabled: false + // base URL for the endpoint + url: http://ec2-34-237-35-152.compute-1.amazonaws.com:9090 + // optional api key to pass in header to endpoint + apiKey: blahblahblah + - id: certifications repository + postStyle: application/json + url: http://ec2-34-237-35-152.compute-1.amazonaws.com:9090 + enabled: true + apiKey: blahblahblah2 + vnfrepo-configuration.yaml ************************** diff --git a/docs/externaltesting.rst b/docs/externaltesting.rst new file mode 100644 index 0000000000..ffb6456f55 --- /dev/null +++ b/docs/externaltesting.rst @@ -0,0 +1,95 @@ +.. This work is licensed under a Creative Commons Attribution 4.0 International License. +.. http://creativecommons.org/licenses/by/4.0 + +======================================================= +Externalized Testing & VTP Certifications Query Feature +======================================================= + +The Certifications Query and VTP (External to SDC) testing +feature was added to Dublin to allow SDC onboarding to reach +outside of SDC for testing of VSPs being onboarded. + +These tests include queries for existing certification +results for prior versions of the VSP and testing of +CSAR or HEAT metadata via tests in or downstream of VTP. +The design includes the ability to configure (see configuration below) +multiple endpoints that SDC onboarding reaches out to for +external testing. + +This diagram presents the architecture to be achieved in Dublin +or a future release given the resources available. + +.. image:: images/sdc-vtp-opnfv.png + +New and Impacted Code +===================== + +The new code for this feature follows the software design +of the existing onboarding BE. New code is isolated into two +new subprojects contained within openecomp-be within minimal hooks +elsewhere. + +*New code*: + +Code that creates an HTTP endpoint exposed to the SDC-FE for this feature is contained +in this package: + + package: api/openecomp-sdc-rest-webapp/externaltesting-rest/externaltesting-rest-services + +Code to hold data types for the VTP API and the implemation of the interface to VTP is contained +in these packages: + +Provide the API and serialization classes for the REST API to VTP + + package: lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api + +Implementation of the interface to VTP and Registry that are available for the HTTP endpoint above. + + package: lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl + +*Updated Code*: + +To hook this new code into the web app, these additional changes were +made: + +* api/openecomp-sdc-rest-webapp/pom.xml + - Updated pom to include new module to build. +* api/openecomp-sdc-rest-webapp/onboarding-rest-war/pom.xml + - Update pom to include externaltesting libraries. +* api/openecomp-sdc-rest-webapp/onboarding-rest-war + - Update src/main/webapp/WEB-INF/beans-services.xml so that the external testing service beans are instantiated. + + + + +Configuration +============= + +Configuration was added to the onboarding backend yaml in +order to know the URLs to reach VTP and external testing sources. +The full configuration is documented in the configuration section +of this manual. For details, see the BE-onboarding-configuration.yaml +section. Here is an example of the yaml. + +:: + + # External Testing Configuration + externalTestingConfig: + #array of endpoints that SDC-BE should connect with for external testing + endpoints: + // ID for endpoint + - id: vtp + // what format of post request does the endpoint accept for runs - json or multi-part form + postStyle: application/json + // is this enpoint enabled or disabled. + enabled: false + // base URL for the endpoint + url: http://ec2-34-237-35-152.compute-1.amazonaws.com:9090 + // optional api key to pass in header to endpoint + apiKey: blahblahblah + - id: certifications repository + postStyle: application/json + url: http://ec2-34-237-35-152.compute-1.amazonaws.com:9090 + enabled: true + apiKey: blahblahblah2 + diff --git a/docs/images/sdc-vtp-opnfv.png b/docs/images/sdc-vtp-opnfv.png new file mode 100644 index 0000000000000000000000000000000000000000..bfca0c7d5a59251793066e64ed2ab5ad3af02e71 GIT binary patch literal 209345 zcmdSBWk6lsk}Zn6ySux)!^YhcBtQrj+}+)RyE}y7?(XgccX#)@zwUSXb#nUl|N9fz zd#$B4)mxvr%I6FW3d{Ax z>yj85IYMs-^g?juvSM&Deok<9cJ|X6d3{ZZyevh3#_&k9wf3uG^-_X_CT2ffc!Bp| zh2hn@!{k%uWOL)(-5#@ak$KwY07ME1x&fHHFDwfvRoB1$utWl}i)cihKKyTg`Qtk% z5ZZIQ_p(?z6tBL9z@^RKH{<-$~zH0L%%M1A|eZsb3o z1t@et|L?o43^9lJjq$&&r)>(N2%PkFxpHFXc!`6f*E9Fi<#y^H&(bAHnlpliw4k}U zk;xnW+|w4B!kAh#yaB`J9|vvtUkj>H*nD_@Lf0io9l7Ta5c>Nad?K-}>p&BJ30P!f zV++YPg&;@n`LA6mhXlQz+Wk9Jx&|m>hCi}QRUE#qgIjX`e^>OwjspqF=!{vJh%ouD zn**PEi2{P{Y2${$!a6S9Ke_wAuKn*jtB(PuOLGWVHrJ>A*EJPn4NiTYb`)CJ^s)Y2 z`O*@E#mD}~_;0W!HTLgjZU+BD5dZ5vbwSjK0%Oopd5`taE&O9YLC}ZrfWcE6oCN*H z1N{G2`OkMqf)5P(F(?h9`2Q^o{mOws_W$(4M8*el1gQSpbptT`fUYlZ^Ir_DCm@Sw zA!Xu7WhT3=W&A75SrpK@A|Ux)&bz{rl?*1c1c!!)Wz44%>9sCLzhw2_-eQR5qEJ-B z0Lr0R)bz7Uk&HVlPD)B>2G7@8ZTH7;=N1->EgpmH#8?r#Q-Z6C#JR`o*Vx$==gNkL zR4{ix|5DzY-{63CPOA{l`-qoMnXGcEyDOp%^BA^nWMt7f;SM$wN$)J);S#j!<{mU} zM=RGHoz1NAr0C8(EzHzIy?L@q9&36_;%vyaq;7Rmz)p}if8QTttL^WlzK^+AN;RWe@%0!n1yrw|EiDDvy;HCB}h3kypZ6Ss(V zcF;+x1(|AQH%H++r_C^&oSb-^jxk9izbz#c^geld>$bU~G9|;eC_c=LJTT#f<&>4d z6)R@@&s!+)eW6l%_7sYYjLdm?_X_MWq#1FD;WpDz5J{q#GL5p(Fs#=W&DL{HC*+ML zP}kCe7fRLT|IrVTB9hVN;ChTJ_;(PU1o;l`VEPAd98e4Y;^d5IOB`2`YLft8)HyEpK$~b&kBU5WFV4gBRupaw!$Q+YQ(Bm&JEPkjK)hsP5}=U< zUWkN0Lf~vk&nRZ9QR=F3z#ljje?A531G4tedbPg%fD$ITy>2~e&p!db7hY~KxvtoD zJ0r*Ae42uiF;h>8{zgSbb=3{s88pgCEn#pi}}Ge3Ro9o6yTCyKb{RW>Id0?QZ>Nd{)fd5;@pU<~X7&Ik-?Acm#t! z$H(1w)wElgrRi6fnye6R@^LVPu!XEfTrJWmmmz&}uB58RAR65h;b@+X?V!TH*CUhS zdg`c(UYM{Vx{vJhIy=9>tku=chn{j2EuI9Gl`OS5{k%-j8LiqBA@O~G2X$Rl9NKkk z>8k~RHSt)3<&)>j-OIplvOD7u5e-D0EZW_eB%^E%%Q*md7E$Sh1l7gSk-+Cl_>EWJ z>&~%Ej?G>OE2{g(cS;d~32IeP*cb87w#`u%o(Y>SxK#-0z^q$CdS6Pjxze!_+9!B^uMoYme9$unTzfz${XN|^IFJ-ePOps5e>TfE#Op(ZKvo>{Lp`FT8?8=Bd|#7awyrJ@kW;Z+S# zzhvsSZLo(TyN9r%Es&_ZVa5E+cC8&)C`dV%xe%v&q@Yg;KYZ+e1C?+@=f%QorIRzz zQo~jX!-g5jK#|Ow+3X_mzI(3}p@q9YTS+z&P32ektfM<8_p2q=x0MQPGjH$d4fOW* zHdL!kdMYoT-czm-^e8!;EVs24pS!|ktE>C%)0cP@!~@>SK~pzY$ytt^qoN^DS;L#U zgAMN&MgksN13PZ-Nr;p#xPK0wn89l1Ur4|&5mi|O5Gos`fXL%`h!Rb}8*a7oI}S-~ zYw=wh!Al?6dVFHjZ!qY{07aQG<<@QLh)RqLG{^DxCwtkXO%1m;`c}kYc4? ztMgV*5IosxQXc_avO*~Di6{ywK1~Q!P{zkW1#}96GNwx^9WCWvU4>#?3#ZLRIq6P* z2WkS3CCx~69_P67t$anueKOpgr`Hx)TDp!z*1|%=g1lli>0qAn2e3xp-rd2*BJLjt z?LM+ogc<2!cfRAT{9aMkPSJn%Lxi;pk{rDAL62kT-m}~4MHa@GKc~fJ*;~~eor9t0 z$ZTczb5a1F7N>SWOM*Z1JP@KuYag$+-46U{^qZetn$ZB)@H5 zgR$V_xVDlF^=yguHQ$~%<#=vaDD|{U-7o6MA{(JHTk}03iAl|xbc4MvxY(o!`49>0Y#D9*!Vy?FgQ@!H(q9+%!H@8 zyOWWX+7qx2je~`$bFzr1t1)CHz zIQ!6W!=it}`x}jNLHJ4FFuGB2a&c|n9;xxzr^xGcfCPW zQ9qPiMAUs;TWqp>3%<@^P^+`c1X)-tYZo(gKwy1KHjMF@DmoU65}w&g*V;@rY~US1p6-nTs*T*86N zAsCts!aZkQtK78yhN2rGl=&%6)+qgA5B(`mqwZlSQc(3a<373G$&aklG{*^8^b!Q# zc7(1RFYPcrHnEmypo1xT<9%Mq_Pl5;teingLQe>HhgwHb)_0&95m#vs(FF?J_9@EZGoNR-*^w1@FP; zJ@^q@v6B%V4z-8QysUT#V)e^8avhhZ1;NK2{11^c@$Er#ecUgWeC;UOX-nvc~rx2!fz2i;&#^jg%1&%u{A zp?)2CFsuKJ5;Y)_IIhN7cJFm}tU(~)iqh(GAv^DdI5~KM`zfivJ>KH%2rudU?cvrH z4eXsH7%GI7`@~q~#$3cR5VnBg^0xDomU#>5-!u(B9#AxxL%BC#4R(FITeLf#qXz;n z)cHX*R=mrX%l^ldq4XmJNYp|y_8J66+3V$zbaR}k@e~>?MKapGo$`s%!P4KKPw8j@ ze)G?BIT&&4Gpqgs!ICQShnKOvJTIfQu9rF7=cH-DF2B_RDlS37=(kd!zVN^e8~G`t z%;E+>h@lUuU^r?fZ;L4KI%_24kS#_F{DiE@Kp{aFp2byX(0276a73K2g%HmIVfrDT z``r^OAWK9*J)2`(T|eDqb>ptP9KYRxsJb&1jnj&Y|N6!uHa$7wsMH)HAh#fbd_bc6 z#BOJ?^Iat6o!aMmgSy>>J*&;<1GJ^Zdh#Gnfl>Y^7UtcZ6OZF1N=r-2)XGXS2eOqI zO@SaT0YTsCDT1u5Y_C^Uy5#st zog^~G8Vt<~Ah(4`J!6GOQ>SfP){JylXa>RyqF1p0%*G5}zSVDhq6)+w^QPe#-SzuG&>TLjBAPS_Y3D z0dxB++WY&(yS^(_xWyIiK(RU$IeBl>@;v1=?u_6InR*u0#c)MMdXv)$l`a!?0!M%C zei2m$pOdUBN9!7qfag-Wzpa2oCPb%_(0fXP&FkZ!FjiJBE%TTKG;DqSJdgb@3=l*> zNL7$CR?ezZO%to;Rpa#JvPeow*?qhV>b5xI_Pq=z;L1e-5)Y-MBt_j6!Tmt4Z*G#0 z2L^$%g?2DVMB1qDR`1_uLqO3t5bin8x^_hZsVVI@o(fE;#1Hi^12Q=2NFl7a2zeVP z-9ce?IK0k>9FUlAxt>v}7Q3X<{&;&U3E$*px*q#@B-`~-&(~v;f1srkayCZ~niSk6 zCMAVy$=I>l+Y=m~TntWKq5!!P3Q~VNsMg8W-BJO_s|sSizHlC&>Tuwd93`x?MtAB0 z)GN0~l?E>p6$TFrs)MC`+M z@taIpYoCGN}p>Z3n*-{2Q)%!9tEDfL8~ljQE`&$2SvPg|}6I2ipt6H4+q zlP97gi!sG?$^qR4U!JwvxzML%fTPtT=(&kE-|H5 z<(8uQJPW_#h>MH&+#LU`^bP@L`R<)7hU3K4#tvx&@^cU}iq}Fk7uvpgj%iiZP#-U2 z>iflVD^jdhK)+98C!w$3$=7%mjca#GRF1GgDr0Fjw`h}K>?koK#ifmZEE2sQyzPVAd)XyT8*Va3XLm4SJkY6V%;2p8?M@pc6PCs z`bDN0zyFa(e&AfRKL`!=vS^S`ev*Y35zFq~5;4k9U;K8`mWv-MNe&YvW?nd`T}qfx zd^?pZ-m{WU6f!CFBJgXH+vw=#DYswM)vR)kML2_{s%h3&Kx%p6ai5bn1RM;9+ zYnlJE%5;uAcNm;MNEI!cKrRfG7pS~cekcwVlY-LLz$wGJg;^K=-5rf?o-E(8_zA}R z48O})0|S(Qu<3-C9aEN;YC)oI``T_l-zg%D%|L=1od#yB9Q zh$?|qN%y!6wSU2;ve2Ayl>O%lqWKzj<>vt6*GuTf%>d-U#g!UD>`W5o7JP2&oR$_i zOiaw2*Ru5LSTinm_5gmD3tzDzHBPkbBRA$s8Yu_48-JWnpH#vIicDz2F=M3}>ZPsl z$O@iE62F^SS?S&3yM<2hzd3;!Q+Qm&5vvzCi@d7$GQkHkGiEw5P|V{`b2N)4Dk`zAv0a}uKZmzG^XWEw zLI!{bgi4UZ1C--}(wOkBOB>&%5x!!0E9$3}_UQpc-6{xQzK=+-<`hHe<_3a za$j1it5HLch`YwdIG$f#(2J8^WhR*mVN)_vBwSp$8|oVkf$B884}|u0o`QW9kTzIZ zoi%wJWWmgTIj@a;53XKqR`CC)RZ$}gJO}05d)T|bET?~Namg9BAR%MolA7I!2x zFdHy17&s$fq&@;Zj*%rm6XlYbwtnAz??Jb6cbB~VQYxK`3kB5BgHbrtO49f=jHqo| zDHU{T1F!&+6#zf6^i;84O11nnBpVtq#*U%#C7C?-waN)z>hrZuYKd`m^lANAnCEp5 z)9LjNE48q+w4w+wt%nO2cq;R?}q&Sz@)c5+1eObjBL0stBLlu9e8sz4qFGDrEx%*GKX2@9W*=KYL+aP~-+;i*;_G zLw)OBFaNXxfcjQIcyU5flBmpezd*rB6Bl~`a&U;9g9%i=5OK!Mdg^X!s;n1zE~ODp zD1eMaY0^Ml91u+i(9|&d7G9<*+d|o%8kj^Sqr5M^m$?PApU3Lz2;QxYprU|2Kd)wH zZPZDj5fopBJvnADc7Y9c&{4zIwld>?yt+#HP*+`w8UzShYV;wtUTXWyX9+h_O zZ+bCRQ;5sl?gpsNXm` zej^Y)IX=E^D*T2^B;?w(dsCaBaQn&j_E4qmEweHCRU9hJ>E+>~_aNI-vOe!Jf&WG| z04#4v(_992-F0XDo4aL2FU9-sGv~f|L(7W#D~psa_kTL4?!OTmg8me$%2`3hxdBsOU;DTN?Co~0nj^`p7Bd)GaR?>0!@7U@MRX>Zti&J5&&bgmaNMOdA0-;T^bSr zNwNa-aOFMKbWF}@0vZf9IZTrR8-c9tYa)>+?o#2fTy;@TE{s6_GE&Pl5>oouN~Yyi z_yg(3I0^_va4&CRs5kFwq3c_LPig^~l$12p%S7nSC0)>a_zG<$EjJ4bzi^20L-Oco zA=iSM3j;G!wU>KRi#L=jl*8aiD4&Z+>4XGF%6?2?#itNpzp1W>Af=(|Wj{#j-QCJS zA1eBHLjlvT@uGnv>>jolR z@-HtyER4G@)9dLpxhE%Y*r%Bw8l`V&Kbnlc&hW*)0O%v$Dnr z2m7Wk2Y;WGnEQLnS6pLf>olT*nVA{epCzov#d@PVssg`fAD|c4slcC=(YH27W^_Hw zX1fr{uDBT2wD|R2q1bIm{QPj5yvgl!;H08*7W9vx|Tf(31C)c@Y^%| zD=SNqT=s6ffR_FIsiLC=pFW;6XM85huVt2nM>PAwv{h+A|i9^x7v=_F2(y z>0#A+i2^oA6P}I|5|ZmDO`Ld7@eepe$X;L}MWxyjp}GKA42v~or_d}{-WWkd$$a

hanQ2Kj+dYybN>8GuD`lQ`5+|13%WQPDv->g8FI98neI;Pi zerGjQ<@w9Y5SINbb09jM; zJ3EIit#)=6XqEGGTM|x~76&(01A?eKWYm~qZm8k82%w_xc=tH)Rp)-dEZG+^DjiRcd= z)s2k6wcQ_^d%j)`;^5;4nKNa#CcH0*m437`V=aq$aVfn_EdZb%4`dZ8lWEl$4RtxvJTv)pkBo4h#+g&c}=; z<1Qt8_V-4U0YMk-9uL+uHVS%+TlT!H0vwS*Hi=`do?gs}jft6?n+qBhg*Y@^O)Xw$ z8{MXjOtAC=2uF<^9UZqG?QP_TF@{N>pI>Zuo)J%%ItUYb9oZYIt62p+AC-4ulj2^x zgM?}hXCu6+&{w(1$@S6EhaiAZlU+1+@Gp-;dW;B5(bn%rg!k=$N>Vd9FitoIF4%idI`yw$x4%qMl`rK}&Egn2wEIM+ zDtBCF6`L|uv`KbCR?=1WrIlbt5(EVl-63e|dx+nriH&j^iSv8&edAtR0;_hNJ?zeY zJFRy55TBi$;Y)hL2Zu@`m|sLoz8OZwS4_G;ofCv00^^0D zl_pA|Ucbsgf(uob;}@zXWu__4BMmwKO$AafB+PcschZXNm@C)A38!1TZQC8Kvc$AH zPJ&pRz280G8qu&Z+7>9jz>0-xmw>!8q~n8u9fnnyu(7rbP>(M`gp*>syhU zNAm-Nom8d!YY4)8u1JGwyPd@mCdH=_vak{MbSiZ>Jny<0G zbf>UKG5NmbV4Bz4W2~eR?ou~glrHg~M=(gY!+n)|1Bqr(^R<>BFtv)M9cLr80Hl+2 z-6q2-kDKmfQ_ZH_VBH|WQo++JE9q>Dq+wpc6%laTT9x|ZR(gcaz*CTwbeq7~Z2fMk{rk}BG}^bz_h!!C&+1122O#|(9mE6>`dM|K7>xasV`0ugPWL| z+Pys^&MnSIuzaX58gIX@t}?V#xP(cqY}tkq{QOC%wdiQa9Mogjl%a@#fV6o$|MT+M zlUDHC(T==|G){%ow{M99^I)f^ML5!2C!nM&-`a|L^{69)7XM+CmjXjE0uwy zg0#x@9K|m+|2S|Otm`~^SF5;`8fh^VW4hoWjQY11j7GMf9ntLR25+omIs z_8|xIzHOW?XRCg*#Y)`=4`CVcrSh_Yc`i;)K<EaY>u$QOvXWn zl#qwVyDYXXfC=e-km(|EK5bfG+1!lV>U`D%to}G#(maT)N@6THef8fLB@`#_qwh^K z`OZ$vn2U=|B`VbE@+6EbjeKT_jKiWatcl=)P%oiT!UIvGBm+Z=67~;>gDw{r7IJH9 z;sE26kJqGBG2y^;T?%vM_Gh;4g1|y$Ie@>R302m(4n_LJ8uP_CD2=>Zz0@@Z75hUK zV-hvDjKcVs${qn%R=cN(Kd?j*T82bVnG$>a<94OVS3L12r$i5wdbZyx8)Ud1s4=^K zW+oqHtrUhjDXK0S}T1IofZvRi?* z@B=x+ zaq@B|#$IXi!-SR9kmc9aVFU$1{v?d9GzDX(04DG+LskcXKl}84W2h{S=%O|VvN%;s zl-gDp@JMBci;;w`(03C^4XX`nyf)t3|H6rx8Kt`{tsVrG>6bo(T_uq>>VMa4-}KjB9R;lpS7F zS%%s|$WN_`&8-0FtC36d(A*6KLLbFpcxMZDy#9X5A!Zui#hs|+oA;ufxC`kypubFR zm(Ttx-^B+4jq6KYQgV7o(EwFKLPCd`+`%22UnC09c1MomhVo~~T>7J>EE4Cl5{5I0 zE>fhVfl^Y5HmG{b!6x{t27ZmJrFhE&pU#05L_;QA>=BV)JfJU|^(_SyeKS{kcG$RL10uZtr{tu7r_=KcMuQ?`JB6!m${s}mpc>B;qGEWPI|>t0ZLfjHSX zq(=J1p&9npLAtSd8v<2T5zwEgtF|hD`)8tA%78eO;{({@qoTXZ2LKWcC@U3Yf{a1s zM(sJOA<7j(B zr9+<-R8Gl@aC7J`^1_H2%uEdE7uHa|?R_KLeZEc{ZE`rMKw&^9TbUV16C1j9^LpH4 z_NIOQcf(Y71djo$tE-O8YfEqPYP;-f)eg`N4c0;9_uFoz)~ATZCyVfYw{dgj*x#3t z{(SRY5DVO(bP3jJp?wGtU{FSighfiwWPFiT(K-B3isIo< z2HFL@lTNs2ILUsn;4*;Pv_0{?pH9AG?EV^#f@SeDB?sd7TDzT}f667mp0T6|o8cjz zST~JPEmb5dZb}>}xc3Go6Q*XRxQGF?8)i51eEA3i73X7!FQk_5?dN#hGp`9nyHeY}s6u zbbd51XQezE+El{iQ!~#vo+{}!W_ha~J}(`@NJ>dcXx!djl-|{a&oxZF;{=CYhs(CT zoL}tR9?b%+QQ&K8tHAZUa)A+ezgw<8{)M}NmH{%6iD)ztu)Mrs7II&#!lql-dB;^v;vwO^MomM7LKl}V-`l=d9vO*&@@YfT%!BW z@U{u?9JB#$0sBF*g;SM#tTn*`_F7~R^l?MwElDOt87EzSZ??R8IQWF((;-!w4k=;&se8R)&No!9ybBa(AY+%*R#?{ggCRVZ(pn|YO4i9@A%YlO9!1v1b@T8<9hVijpHb3kTVC`a_(7%!Wlc$Q@ z!^Zsn29{KUprh?al$Xa3WfUsP2ILR8=Fo5>_9!tI=g^yDHL>Ned_ox^4~2vjlpBuXxC?mQ_(*=74P zX<{w#NMFhrdMnE4>5Om2^J*U|N=sp(k%up5F_Z0%p~*?9lZ9WdCo48#FO7=PQ(3Y|oq5V3@3JZKu<-31$Dkf@r7-xgm>en42V;mD3$hI=QWMTxS||?GXvJ;i z9@#~b~5KHQ`=eIQ1?o2+J1!Z}vubys&d;BI(k=7vHDNGXE>T0oF`6Fodzsep{ z%RWA5+gMuKRrLbVaFmfP5cQtLnlA@!@kNcLV zSM?bWslf66(E5fgyZ`$7<5v>d+>x(h;*`QrFfCodcP#X(G?s6$#^+*p_k&CmW6aJG z;oAi1D6eF+bF^qM!z=3SS(W9uq5Ul9@O_Xw7+mNt1QFq70??L|-TAEZOu&ZK)@FCW z;nBG$3rg4AZCw+E8y^VF)$#gT>myM8geDCK`ei8R)p7ZSg}8#{l9>(N-TADT$Lp_E zJ?&#ld8nR4dPtR{r@FgAEx+4LmORk^YA-88TXC@*j6UNJtSUK5y%{OGqWt8~Fs!Tr z&rk-Jz81Z`ZN$OJmDiRhP%Zxs9AFWF0&ZcdXo>*Fp9RrX1tvyFdOZe9&mRz<3yBz8 z8z<4<1WggEO<^VkWg-MYfL4c-6IVhjN761g!kY7mByhaRvM~Xz*{sS!~Ow zUVy+hom3|#VC>9mDUstvZJv5ukP^sdVu>yy@?j7r;$#N=Y7uktX@)<)_~HI);~2X`otEHtL)w@-Bs>@mF;<*iUPsT zh?bm`Xb9|=0*NF74M7GR#lJe3R>k2Jf;i~WhL6YM!f!~YDL2D{R8o<*s#b!8hC?bnctc=Cc^iwS; z^bv+QhWOb@ZwpY^u^&~0;Z(G8rV~_PWhMLy(pc<4he^XO9|xs8UK@jQH6M$Hti|Q* zKu>pn$sSwQ6!qJhj)Z-@91A*XCgzlsaeTTc&&0QXxiXw&0joPIt<#h7*U(TlZY(-Y z;|!R^aUGl>3^ivJaD7Ap8og1GLexTiuHK40W0INlC4pvhpmBJ<9A4)i<2JDCv}xyY zpq2P4RB$kFQk&b*fK<;pFE*7g(70@kajp>LQ?b!R+BdFFlwM@swP(LW{Bf17to7xG zd_)=>Mad26VVyIa_yN$C-8Dc3tmXsj!VOt}3Jk_kATpHdD8b>~eS)#u^L;n+m<=iZ zF<-C~$AfB(?e!?F@D&JI0({XR%iY-W%KTt%n{cT56w<~~KA2P42x`D+Ek)p!c^#hJ z#W8({Qq*O2?Bi)xGZq-?h=~ngWveh{bE@C z63U>lonK>5XN3EA@FIJ=U!YQ*Bxqd+o6KHhM!tkfT9yJZtTCIGI1Y{m4 z7|%_v`y4=bs-dGJ0w?D@E@l{eJMqtNeTzV@Q^f~t{8vO1e;NN%Yv*DF9r2O&$JhA9 z6<|oiDl%;>&6o3?>Nb>ABD)Z*HXAb>g$n_e!dkY5L2Tw%!q@m~ozE00H3%BnP3 ztZ^&~DX1a~#wi$L9kQ$r)oVt26nIBeIiRXj5E$TW=B<(tdrsd1F@zZ)Uhp_G0jgG<#?bzNcl)_cRFsjeOg1Y~)Yjo1zjwLSQ8 z3t94!`8VALC~IqLk82m+&_5OfuC7>dg0VXB)yQSPm$p=VwRT2A_8@}kPGrgxRODMwRiSiXNy4v{g*sRuBS)%e)Ejlh7Ad(wXCEOwL{ul1#PQAE-9dA;`ns@4RB-iiP2ODSyT}^j3oZAT@ zEjFa5RWE{NClJdWrwd#dr2g#FSz6{lAX%pE1qPgc$@X~%xc5{cjE#+N&MFD_UtY4j zdJE@GS1A*+J4r!-fv$FV;Ul}dqaaGf!To}*sr%rZpFcFSk+M>-+P+MCE6C#o68PQ# zXk=Cnj*OWTHc}$B(6{=Zi?)|jev#p6-y3YRLV>%=`HwcAX0R{wC${ezAQxHpKHCF4 zau*|S?~I^kv~z`yX36;WaSOiiK1qLOr^JmjB;%&&w)H^0Yt7Z|Ip8Q@0RqU)+}Qx3WG$Fb zw0(HOVG8g{^>I%E638C4&~{Pl+Ff+H#KqDSG$%O?0%-(FKgaQBPiQ4cJ-*yF)k(&5$vKZc|p8hipNG zgY95DPaLyZv~Gj04CN^B@RoG?)|CUL(R>8Us$oSn0=wGm4^CwigTcvoWvpk&TYm9y zU1OEh%|R>*GR6c^ri7H%j)cw4CL)gd%DW}cv#(9`%cj4v*Cce@P(P2ti9XCon%~L; z?X4g_Pr@IR6IpMR0|Ntw;V+&~m@&#y%w^J9N0PY*0RiHNXJ_a}=4>h~tlW1h>bQte zh$TRe7=iw5c3*WG_C2gwPPy(6LO5_0c_-xhpN=)g9wz#7re7R;_0&cdsw85ciUIGDIP z@}zGEU7x({ZfQP)Qh(AlnBzk7&iEQ4&y;So=gT#b&ASMQceWCS5oyKIKKNL@c2#Es zm|!iDK!#Iq!R2`!UVr%HU_|k}4`ilhbD}Z!p12hwBgXvNFu4Xi>)S0K2mz)K@qr36TO$wg1NJ%E6uQoyB{BB{PDM0-NICtE&PYsN){f)2sq<O-!a1p8w&D)^LMLF-r}xz%a)o1g3cUPD)C}(I^pnDg#{o%_XMtF)2`Dw zQJ?1mXP{D`MjWin=ouyS4E0r=PwtFWR8a3PR(=eJ(dxE(BknG@Ehx-#WC;5Z9ZYzU z7ICS%MpB)UtK0*NGHF_RI(kUf$|SIrWdH<$k7qW*eXF_@g@i@sBm_u1+x>D&wWi2O zgnSA5*0TxZ4$#2!$c6rozj4<3`tx7e3=URaUVhV1iCO6FP;HKLehc~I64~zc@hTx- z9dmzsOldBS}aFRQon;}EMQ_<%&mlEo=%B%qk!Yc6qNLd1AP+>98+&GlBp5@|RzEb@Tk8X~21I9X4~jTKu* zYcZ^kXB}oeWi!o0ZMUJ!`~1;*yNBz?+k@TP2%-u~v4agYa7?IiX}jP8^OKmA8|uA! za$W-o^m{W6N0@!Gg-oSRB{d~LGMXa4umB=cqcE@K#l4<0RWBj=dZ?Nl2GD~;MA$#K zOF@Z&`5;qs!sZkm*q)U|gn)$9vvXG@SUGP5_$m%QB+e%6~eT-%t_6z^1CIIKF z6CjK}BM|+-2X>X!YSqZTe7We=-@=_=or%oI$e>(QAR};Nn)%7Fh!g_o)oa1J9>jRdLgBz>h$CrRxJ^M3 z?q%nb&nD(-MI2%dHXQe(I!>g9SfCupWwA-?ol-tluKL-4QF&h8D`%y#q@w0;Ogc-^ zA`cuQS#5RzItIvEE?mAkn;`WA0Kf@I7EQ9#iOM5mHG#4F4KFWztpO8~i10%URbgV2 zj;i~+M@h8AZ5dxK5<{17u!8 zy2Pqd-&9qC(%jrU8tk)wpndsV;qEwx_4PY|wBxYIGhI>sN$fI^Lpts?>R`Vug*G0% zkSK@%z85V_%(;ccO(0Z-75D11n6Iuqq}^70-?%gl0y~axf1b#KpSB`GQ9o2bS$I75 zK6<}PNlgnFaAK7oZ#2BBF&BZkUSp>|^R7xKY0_LK$iT$JgoTSM7}yKmK3%RAb0kZu zArr4JQO0oUpC6Q=V02iz>OEu3Gf>Xb=zlY(&M>_GO~I6K5O1GMCGmUDxBSY^P^T>> z#^RX9NxQnR4yUuz0e;=uM*Hj68g@NBJw|=EJ&K~@BHNq&U#IdleI-oEa;sl!*=x=B zW(r7YvQ2b!=z)n5v~{hcuVnH7W!Zka5WUIy3=cTr7u$fUu6?-v=8+@ZaC*K984=XZ zIU77knA%14Pr{|zFwiIZbGN0FLBcF{QKYlfO(#1-fP(+_o1<)pMxU2;ve%o2(X`vSWe&tu>_cKq2@}Ucz1(NsgV_gfg(q4#ra7X3`a7C zeM=w*KYaf_IDs2WL^x{gvP9zTBbYP`XO1*qgC^GYUIU+JYb{acT_MecLKgQdaA*|h zg=(_h`W|~x*;#4h2kT~{+Qe2bad_G@%&|^UQCJ}?)bx+T^orT#E7+CX?T6m2v1T{((Y}5b8KQlL^hRP6U_%XM<9ohkumSst>!9wv3a3^%hB1{UzIDy zAT^xSEh|{u(DQa$s>i|eCHib~)G;d=2rr!^4V*sat0u5|_y7Jk3&8nJiYgT%;o{k_ zO5mU$G%`_NsamDMhab2MwK68I4jr6wmJN1d&jy~;RyLDhANCu&G6ig$Fv!nIXv)I? z3`FoWsve7RH&<O?n>Mo|#@$>1iBeADE$P@d*bJdK&-KbZGX|!H>sd>x|z)8l#qoaYjISv79o8RjW^elRgl<%!SWmRI611=i4jks_InwUdB zE;NZNqLjq#`UEd2)WF;_2IeOmZ$c{O(j-2b4CES8<7mb1Xd6hE{ zM7#`%Ea2_Yu?z3w1Amz@&`B^|bI319yCMhmpUDIYeA3)#G5o%JXhM8HYFQ=!m?7k;CxX)qY= z0qiCCV1Q51J{}Yqnz0V$#noXQQKk{vyL)-9Wu97FLrh+QgyY2CCK`_|G||H3z}(BP zW+7J53*jda1yq2)DRP5NmkcfAh96xHB1kxarx}V(s+zTs4d-~()3MqA!dk+_#mKE3 zqWe7>ai#hdGyJR+o{ljnoQKbzaH+uxU*F@56U71W>GKjrb=q}?>bHv|Mn*Zr$%#9+rD|fQlw1FYudfVl^@c-1zo0nmp@Gy1`32Z&|kN0 zZ*6ARl)kpja97&k%>zkudWa&ueWjvrYi5NCv7`8KjRWW${OI)ue65#8AM1D z4u)g6^h`-l?@rY7rW7fAMT7+Odp{u4(bFqvYcqtqF>pKkb%l=;)~sE`M%%0?35I?^ zV@|Vy>#)P@e9LaxsjtnVq5{{zOII{_R#BIO*XCM;A@0JExgRrCYK|vB6y3Le)s3yU zQZ*_RFu04=87rgG|K`i>ECvVm83na!YEc&3sGqAVh-ssngV6B{3j`~Yfh>0C)|w^z z#S+ecB4v1za1?C+Bdx4JT{ud zetek;6o{;t1F;#OSCEY(7m0un_*kKhg)X?J||S>Oo1@3yGv4LX6O2o zqqf>tA$)swH>yIQ20QHOBb3fvq%Nq}ZT-!{642o?O5)Nw(8$iUE8icv2zD33Pe0#N zt6p7~Q<#7}k5Sdiv^z{Qy`p~n0I$Y~x1bXcwXNMen2=Vm3%MdetL|3Z7bI))200`q zBxL30@*I*X!5NsNRCh*guu8hqODYcS_W<~C-P44GJWkiB zKoXN)fIG1&<9otZBOB(%W>#qfyeo0k>e?{q{+Xw~$(maEJ?^>$Zn}U@`v2e?v?GXV!*S@>ySmv0~}{ zs}+pD{nPdo44{a1IOZ(y@2`G?^yoXHhDLa!dxF~fYG$XGqkm=CG@ta~@9gZL>ZW2A zrJ}yd)OH5@LH1tN7;aDTHT#qyJZ*Lj;^3tRj1v2s;GFm`$?H}R9mTEvC@P|18tVRK zeQ_Ntbd7a+WCo#Pq*oS`gbNEL><^evrY9HE*sR?AbtHzBNeu+Nppied!^#aXx3in0 zmsFe{o?hwt961oEtWOz|leXgjo z$FHOPw4!hDVWB{vr;PRbWgC1l!=mGucok$s!Z))buq zxgY$zfDVGrKK?wo>tAM>T`u4wIBPlD|3+7r==AJ#rEmE4_AXI!N(#gUJq-=&E`o$p z9>+^iru@*+)r}}|Nz4(pzykxu_Kh%beE9$;mYj zKKX@LuV9307VBzjm=64QSTfZ(36PDPjFpF`$7YU^+RQMWd}5}LW3RX_zP6MW&|tf3 zh7pFH1`{!d=M`ZA-Ta|~CmsT@Pyzn=xCvzCt7iB<1FnF-gzxBZm%e#+^iS&^iV!YC2euVlWb~$3Xb`wBDIX zNxr>@!HXH>8Jvwm=C)@D@PQB2+{VnC<9P#zPMP3wXFMUgp09#gf|OK7IXSQ}Z?irm z)hp#}f7;3|I-<R?^Pr5WabRh0&+6&jRzJPFls}54$-F2YUK9>GN4)j&zJ74BEi%;k zE*D`A7>B~<8n~fwf_kbEVkIFN(V{tb3BUG%2yj?SNok?q`^Q=N^VLj1lTlC~54Sn> z-<@duGkysu65%;036iXLYyAz5+jfulM|OMXv_PG+C6C>TFDgi)M5_$kI_x@1@V$`y zuzqGT+Q;*W%*Gjo6g?`tvJ&-cv`sJn*DC{gadNAK&9(saq2aX(U(@d`*#v}Zn^Q|Eq^cr)aSLx~0EF_`U-r8WXALyOc0 z-x-_*w{iH7c$`x91w|#IaxS&#UZ&c1e(0EIa+y81S5ttGh(4Y#+uiJb#$q={Lb;Pi z%oq6cGdf@zd7hqprD32^AdAz(JVp3yME&utmyY1&!Cd6pnh2$G&-ZJwqT_FNh(v7a z7wk3*JlZ^GWEVJT0`BOx&5wL;PuUSnot9};jf5pXK}Oh^(gqGd|K;>i0bgCm)#&0-$g4L;!j5zGC(&~toIahT{u2;ydusf z5ki?>wiB$iTJrb$a7DZN(aXUa2ALpGECQR>?`m*V39O_RvGPfwO-Qo}`u%&#zTx3+ z#$wgNn%m8%hqn5a>&>d}6& zJ5OSjnkgwSR~hX%-Z1Vy9P@+ROP0aq#7ornfD1+;E}QxYK?Mzto)3tjC6BLH2bwvj zr&@zMvqdP;Qw$UhjjgSbt`8VBJ)yUl)w7^f;2SlwCbcgrN=h(o%e6vEQ)`R1SGnbd z3cve=H`%s6QVk3azTS?drX}dn@B1W5DKW*r2h0>qe|)KKs zevPp27c+{dH1)JnPW7h>$_aRdY`9-*J=6B&TN!AqD=%H0yKZ@z#ygg0|!FY8?g%lfeaCDT&Htz36)ZN94Pq(v2- zL5Lw@>7M_AOWMe=O6Tb((zjWqz182|4)SSs$R@LCgn_Gf<{RDVsbn)gqS2Da(e$!a z)1`8G;lXrw8%zx)7a<4n;Vpt?jFX`g8QLGc?&2ty>QB}U5GrX;qOUT%_h<=(?3=+8 zPCRKe%*6_2F9?|0-V^tNfzIUWY7U+~LaD5W&Gl$<0kUlS1qLNGt*=n4Ksb+#j15Al z<>)Ic!j+brI<1$Q z;jl+jBY;F5fq;|3O*rA_q=JZQw_GtQ=)D+naWeB67D_Ad(7?!u|EzIOU>HU_7Y!yh z7S`%OaRLqNMM%B2u+tP^G&%v~VvpY#iJq^=SlcWPCN@?an+8Qc(CAt7;K>YhM zqOsPN4=2Oi{1Z4umKJf)hU#uSOd9p5RVJgVSfTjb-Y_HfyDDk{2`!itv?ia?p!-p{ zJbmdCwZo2<-9tPQl14@S60>#Qc{Em@x2*Uhv~RoKO_dH@eukhKw2+n&qHjbYmAvF|^uu!&8zdeKTJB5Oio_LI4AO zm0V@we?V(-I=iLK<$a5Ld9YL}dZtljVz~P=PeO(OLbKsElapOhNeKYCBQCh9Xjxbo zr=ep|BrC6Fp{gRBuPr2YpTTyQK!*@nIe-lj6RNaEl(6)`ll<%-_yZv!5*s{rOB|Hhhy*+e7h(oV5vj*F z6Yj>wf#@Jw|1IP9^u^T$FToarOhLHt0@{O}oe(^P7mFHR^Dt3qeWRo#J02hIRJ`EdGg8_R=8tLW zs+KVv9CTnZ4G*NmLXec|He94&bz;Vuy&fo?!@Ta1Ps*xgQj$QFSqRovSI(^+kWb?P z!zuMf5vpjl(3Y{$x*&;UR)BE9eea27FbQZKz$fcij+(q|KL*%ocwjM;BUQr|dPa$% zcCgwFxr&|hVWoPgqlrUIVlpzyGGZ%?dJ60-1mV|0kcmV^MR}O?s$oy;?ZaQ5nT(_r z_W19ZO+Jl%k+jgQ-rG#NA^I{l;Mi(wPKr-N^yRyVO2=_D)}4BY5k9|5Nu{c>5T<5t zG;w)`AZVR0276n+SOz|@L^`ImEZF9S92o@%)CnA%#Ykz3-p$Y_%4P0*zrgtobGX4q zOcsogTj=eA0tw2?{VVKV7Pmgs3xRRX_)+dmR;mvQpVrJO=2$4~Ln{?Fxg3n7aMFBN zKIwCsXm%?imX#DKJ8pa^%PtYIE~b7}Hox;DC!TVD8~-Ut!_ma(=Z54!QHtsqX5&rk zhKJN|)`UyD3G=$NmO%R76m<19SX(>W|BL{X7WVNRkrGy6B^;llKvEsSEOKpN?E2;2 zYrEo;&k3FY;NpPz;(mEsRJEYFl=2Vg9gOl`s!aJXfwZrz;N$8f*{n&b8*th%e|mAC zP(q%a*qdOjn1F!8g2J+%44tMp*v&8RaeY~hdi=d#nh#5SF+HfS;Bh&J4UY(qs~2Am znp>v4qoRbDTmZ=}M^=BUPGZdRO>yT@f-^d&?_;}hcemK*jBeiIX<$rS!+Jnxlh^7v zk%-_e=-phSRHOS6;jLa(RTXb0MQYcPmsoJpNPw)adLjz{W zS?<+YK2RpZ-4?SU;P(=YB1+HR64_U^`LdmGTR5IiOW%_KCF>%BAg@^q#G?JQE(RBf z>Is-QT{O3Yf`W>?8;Jb&do9^k@P44jbP{=aDAMG{llSIB{}A>`JJ8ZNy19Q-sh$w= zb~V;;c3RK7Fz{Wt%Q?LyHY8?my-Mc8Pyf^B!V198wqF&)?f|PrqX^w9g!N*+q|M(I zbz%A{9T}NM!?N#+kV#rb|6p1hS4}he0h8`VKsJ*VvM|#p3P=G-;cVPb3gF|d7>!sq z%FxjCsXa>chmdXVrV$KjeG_iLQE;>=R1((MaQ2M?}P+3(uxg84N>h#o**ha++ zIj^ORg#dM`T9bS`&g&?!=iL0(w}|fzq=~;U6dzTAdS#{cPFH4bav(CDK?v2If-W00 zTO+9vKy-lfQN4qh&c$jG89v(+#pZU;ats<7CEPA*kd>bgGw*uPJ_11B4s#BEvzTNY=p}g=#fAP9vl5BHwNpY9|oH0YaF%cG{?t=P9LsUj;b57jMq)_6g^RG!9 z=AY4j&M;{x&J-?a76uY->C{-^)>_S#+?)LLAr0zk|L%b4oMg5tiS`Sq&XhvTxgdU! zA4%hs4r9k0QO{U=9qqY`Ndv#@sTqcag}GKd!5qg)Ue1f%ijx%dGG?k=52*Rv9?pzD z4(-Fb*|~JvsNMb2^;x(>IU>+=!wfnpCdMyX=pMCtF1M{`b6O`vHkFI^Wl}2*ZOOPI z7Z4a#UYiJum7*|Kz=k)jX30ev=nIvYj7BEIP)~f+7jKs zCXJ`AD>*qdjIe;=RTk1)Y%)LV4;;3U+3!g?Jow;|?t^>dJ^t8);m$njyJz_j6; zLRe7Gw#4+LxDDsi+Ld{ceaIav6x(kx|4^~JUq0!zb<*O{6^*d>XJIM6$wsLsMiKHe~*^9{)5Y&-o!Rn|4g2eTFPoH$2}c zkcGkN2OeH6=|n%=As1M;vzy5D#`VX>i^X0FP5(@yxio(NzR;KG?($IS4L2KmG>s*z z=Es{0C2QL$MTGQBakOB8c*=}vX4u+kgwigcgGxPzlbrD+?$d;RgDMyt7TEDNPK9`W z4QoH4cHc3TO{|k}-X*KCQVK3vTj^c%)O?2dkDl-LY-31}g=3Ymtx&kvfe!}+UOa>TZxY+Y!;k^ab~v}dQM@vljyV}E2eq$h$4F1S22KmI%@&)bgh(;&;q zM#aO*{!UrOT?cd4u%U@e%!Rm)?|(F=Mix-nd=~9PLcybcleU3(ca7-YGSK+x0;eW* zzLPcz9|KwVE7y*qUekO8R-KeRe-v{LlmvVUx zW;RqzXk|?%MS{}e(hG6!=!h;^?!`bIepgz(3T$nsFO@%YS)|ac@1_o6kr29Trge$~ z*+*i$8E^q#x-eG#Zm)P?nY@%gnMdA%wG6FS!cwQ!@ubFvH@fc~2n4CHr`^KX32>2LuNhsZ>;R$<=k%q2aDf=KEo2}g| zG$CfE%2$q-4Qi!~kPKka{MXF0#~RW?ZVDQLXDL%9Hb0i;5IrKQ&=@eVUkavl!q75|3}N(#l2{2Z zW5w+m>G<$|K*C&m88m83Ii2%*NuhpudaLOS{$xCHlu**kqxTN;s~CCR7p0Qi`fgF; zfW60+j$w#CmQybB=-8I|byY)>Uc>C8o>15tYxO&SW3O<>b!s_bNsU7EN}5*1;~X){ zQk$C4A?F;Dd<-#CD#qI#Pampp9k$s!vpBT7fODJc><6!a zdwn>no`Ukk3}`-EUzSwOaXn^~Jd?Dh<`$x9FXT-s4UMB!b*)o_4vE^OWH4r&GueC` zI7iu+ob8K`a$XW7ED{pfkix5_HtyOx3KunCtz~$KGJ%?0{^3M4rU|c&TaNCK zU-`|C^u;0qHXNUvZ%ireyJM8YcA+8uC8_PWjZ7*`TG|%{LZ@%vs^lI{X>Qlk3LJ~Y z1iaMu=p?AV!0ql$2y9N+>T0l)W?@8HoHLA|`vMmVi=gKJnvsK6SP^j?E3v0mT`es6 z+)E-anydyzN;Id2a8^N`RL_WxmI*xiLX2_Ah&Norv!cBHRIIyu;B)LFJ}ybnRNg_< zzNyV|vBVo0tq$HaWKN>R+6r5c>jIrDYf{O1vzgdeh`Yd$;*)*8G#`UEetYFVP|V)y zlZUGv1c--M5j3&dgD^>FsRwrtcN=Bw?a>yP>d;^IYYItwcTBkkZ&K?J*^OwMW>lrk zl^vKrQ@CZ#!v#}qB z@)F&eP+lc?w;xBG69op{X1b3=?3ZOCxpc5uC9WfR%DH7a?-0jY4qOz|%Y!hz3M4Nw~5C0V< z1C9}HfU+6*+=Z0?GME4Ha$#Ye7}DY{l9i9D-~9~ zsZj49dzmgmaW11i9Pjd^-AlKb8vqrsQMLbTNH@VSAf}T-@PJ5 zww{I+*+-r4l_YqT&<8cwIFm#{T`7dPwGD201FQ4!B7HnUQNXcf`n1_8_yRa(vPFM0_JkqS!-NCBRUP}%MgHpvsT+~Cd*@-d3b_%BJyg005Fqyf}-;HPKCTWLl&+dY#2MU3pDOPB(G zK6ivT@-5S*21r9V>ibdgUrgmkBr2@6bCE^bukhEv=kx&2To!L8^#7Yr$8ez@ zjmmuH?M`fG+2_8WBiLbvqI2O z5n6~ES=boL2Q7F)$GE-QXOvj#DC`3nBWVwxu@CM^2HgA^FtS1KhA&AWNZ`;CrBbE zOA;-X8NiK0V@FM_h&s`pe(!#1P@z5%0YM#WGdkm=KkvZ!-y3B22)NSjkIB-}fAAT} zA3qXO=wp&NzlQ%f^p#}y#BD-4BD(P-2=6SiGZ!>1o?xm`H(xq8xt4#@YNHhOkAE)8 z1N!Zk9waW%S^J+&5T=KM5EElGQS{8s!UbR&Ft__msvqp)zKhk3NFFk8a^g+&Tq^rg(X{ zzjyd+DYu}PH>Y#1Q|b|)HT4nGaK+xWn&tI>KW&U+vMjM|?sfDUO(IVET7D7p0G4=9 z2%pNQcSSA!_bjtMz}|aD0CRuax_wTUZ8EBXfE)Jr%SoVaIsJq?#%M$pwSiQQEhej0 zRWk>C0-lMq`)$U_Gno8&%oVLgrR^nv9$iv&>@7aec}cqc*W`ZlW%^ry&LgWdrT^e3 zC$g70`Vw!d%F4=q7=HH8#^Q92JDqBrI@~eR=go2J|G@Bde){UXrfc=Z9RfVO;xJ2F zjSJ*mjOE``f0nrsN${wrfY`i>^#D2a$cZU;3SiXHin0Y?r(4 z7Sh8hjBV5ca9#jF+=K{aG(#8m(e52zG|&*2z`kU;uRT3}c-nV*zAb4GE1m;87f+CD z{f~LG!-eK;CCgBV|E=G4#GrO4bp4?(vY{dve<}=8^%@~(6l*|AZ{?gvP@T~AacFaWR*XvxHf$DukaC9~%A=(~vcsV( z7)ia&Tae3Up}>>rB7HL^`8O9dW(WgKoY#DIE5cPH{s95@yLpL*H>aEGwN}aKf~l`R zAv}*GOpP(NMhYzfpHltP_~%U{e-0((DF0_o49-XhbFD*#dSi`}3}4qFV+&7!!?F6Hl-DlQAgT6Zfdbc}Y==Vf4OT zO`pF}$Ov?{b5_;Zs5xnC#OLr2ODhWj_MA^zRue<;a>mH*SHt!Mc0ZFond~2jp)dl} z(uX6#3&@{`b<0tD4|{4Ws?NU;YQGT*;UAx{Vi3P~VF$gnChh+qGiRZsSM`waodqNgL0r52WA zIaLA%(v`A*n*wlSbh|;=y6yP3&3@uU?odKcH>0CZB)QKD=$7FnqrT!;u0jE{m{%F~ zi02k-4V7VSLixPeZh@Gjmoe^Tmt}e{>uI;;;;T~5oa}78RO42rMTB5OSESs{N7JUypi9;4Wgyf;|X@Q@b<1`j*@`}sU zBv>9^K9TQ(|4?pYRdDBS;8;K3onGL!Bx}Lc+>Zcl0PaSCYks(#&x&5ZTK3U{fV=3r zNTfyZD(lzlt*gF+-~)xU17N?qLT$UTSAgWYCPR_~Qal_`lHUmegD!s{QMkD}=XS7gnZ^6F- z;DEE*t+eab@v!OtUhWM^`-WXh`0 z{LIcQNWet;v=dIY?fkNaS>1}qQy?6L=0BMd3ZYiP^`PSeVT!LgeS z)*1ck(_=wt|1d6{*!+lSE!b$rW^c!G?SP%3S1mz(Srto+ZvHGFt+LNr&{H;r15P@D zq2u9d83jK5Jn=^F=|XS7)I=Ok0rTOPYg>ftvR7S>N^aUS39@isGHRcS+c2V@7M!_{ zV7d(pERA15M&Guc^qpOP#$t;Ux6U)KP{$KfV6>>6&RD>P_=6FDZ`%$5gy2Z(O$w*w z2;Bhh6ROW?KehcvAKLxODCayybi|OI;V8v44(_pM(hAua>gwYa8nQEihyn{mbwWzBS$;=~g!{E@t>_zfI>1(B571uf7PZ+{UyDrqK%?UehSO z&wuY6Fa_ahj2&=7N;RU#K}9d0fTiYZ*0r*0+kF-`+TUj=4?Tp_u04SE4&1PH6Xk&L z6HI?go#6&ix9r^{Dk?-jr+BRm7aDu*NIA{E{{#NB$QP_v?q!TDkyFWY=&|m6tnzyM zcej0Pfb|;b-iYKi@qiy~l{#HAO3ug`X}#O%fcZB$8Z+7fZ!P^t*!8Rcq-5sE4mg_% zS{6Q)P;xMVu?x_?$S3ntXqwNb+)L8qLs$w53KCAv*G?#vE{Ah2_{HVry*`iIK5Kc2 zx)yaMn5YoT3BI2054BJqRJ|UPM7}5>B;A?~t%pY5G;eu5{G9d^U*g^>LU<4@nx zY{a+wfz;UF3P&XC4E7ur%nsNRw#_H+nyL&};5E$#63$$}lD{7kPDIPLvq`<4j23&2OB@;dcfJka_VXJ7 z22tzr%vZ$CQZFX8y4|}F;8T&%3((1GeEUH&Wlt$uLk}Ph=L{l9F}bKzNrdFv0=7-! zXWjCbOXw#@oz?ck*`v#Jd?gqOpHKPTROl`l3VIKfmX_lAu^ml_^NO2dy@#T==`462 zKGM)n^|&3?d+@EePc%EWRkqfx)Dc(#-EDrkTB#Hyzp!UHrwD92>Rm>eK9a2!VclJK#1Xp1oD4)6KxHO~0;9Rp!Kb z$izX&uY-%%h8gqgLG$YYgNLftdn;nMIA~};U=u`&DgLpBGU_pM2F~enz2#pr0Af`U z*>SCw0{kBv(e6&#zOywdaE1t6{yKLMop}NrUp}etZ|8>hDz$ldXvLWZie7%ds=>_| z^b{y4S5;PUE`m)D3zA!-R3B?7ksK|0%le5~lLr}x<;6KzLrbd|M$%qM>-}jOGZiD< zsrL51izg_-D7B0ZWqf&0#hHC`Mi4<8o^R1I8lgeF);&@wT}-ApKBBWbN& zG!Ov3sr_8YQ@b7 zh+sSiKJSzUdqJ$DVpiqQ-iRxms6ixNQ?EUy?nL6FcfWGQ)Z;y;YV!O60w6t8=Kgv; z`i((V>35+twG#Cos%U??IE%vi{hulKUVW_v^)^t(WnR=Rx@b*Dj;VyEkCykSpgdxT znR@HN6gk*mkEs*o89)I`sCm1)KUDbMCH+fz(h~3RtE~{B!E04r=}R& zGL6MgsVd1ntJ4O!O!1rHT-L9x<-KdxusEXQvad-(r!vk9XUDjstA{4CsiHwuSbV@` zttA$Byo?+-YYzrp!G6mskzqHV0gtv~Z2!)Zf&G92;+K;Z&(cq9j`n0V-(i(@68s&Fa_H{HU~l zO7bu)i`{&-Sj1R{?FIm^>ylouJMcZVjiu1>iF`+;IB_qen%+m&lQ_nG@TUf7 z;*uLA@4H`blzF38YvxTz9?a;t9u1KVQ-&p;t)3k?C>s5rnvQ*+Nc)C{ltpsDSrglu zGZX&QXR;t>0jU=k2)RS+4?SuDOFL&C2CCb#5Y%-^sj`nd`ejeqTO**@p`aTAF1k>k12C)}K6COcL5cakH>GpH)t%Y)SK_Kje6v zo*kfQrgXD(g)3{MsEvp4qM6qTC&aH?xeK8)sJ=UR%N|zmYA6&$8vds0aIa>RrdhbxmJN*m$k^JAX z#x`a4h`i34@e^!o#%+5TAlA8AxJyg{^N?TXi=*h0 zP|MThCW(U-H7$^dLE0MT4hzpRZ5HIaO~K`PVf0bxmbcb@@Z>z~f@eYs-2W>As_104 zLZmw1+@YuNYt)z3ue+_VS>|%)AHFF<4O0<0P(kte3D-rW@bdB=$~~KqhY2wdz_g#G zTM+79B;KS=FX2szZCy+P{6<;VDDliuTdWf^$m7mi8)v$)Z76B?YW*d_ z=au&cljv&w7!ZpR!dm=_JRiftUJ4n}sIz@;0KsJJTQ0da;+`xZCC0`KrHYG}yG|4q zY%_&Gf}*i?->F==;ghBB(`@V3FD~`a>>!6H6A>@y#-5h;+yB^nr>Kbj?jz0*iSYFV z;7}2M@p9X{`O__G87=+EtFd+KUK39@wk&PtR!@^N5LBzji4&jCj*9rPLD@-2Cd)!R z`fPLNnuurmw19NkZ#_szIz}%l`wo=&`-nn?5R4TT2jw&kD4vZ8Jt7d(GPo?qh1wGc& z;+OdrmFn(s1;696lD9TnkH9dSFXm`p5!Y+BLn$NR#*8WQiDE>~F-&a51PI_#@DUSMr$3ltq^nHZGV`RURln#pa%7HC33NZ5`=5WAMrRo zUQi#O*xIz0^t6((o)3ID-W%y;AFPF!wmDaWn44o&AOMo43~TG__|UT9;nhhT@X2#h zRX0DN>w2FYPIg>6qzC1QTIAf)oR1sRj~fY&8`6*6@5QS|A>9^_-4~9znq`hV*X=tG z9g16xjEq>lZk;Z?r{+iQ_8a?~gM^Er=v-G_^#r3PIsKk;=sLB!cS}|Gt+~B{I#vk1 z7Hec3-lYSbh8g_>{S|#rTN8pUyfcNc#LG+4yr$WO4H3ZRE~6Mb1ab18hS-Qd>i?3G z_*wgh-CQk~MGhY3Kh;?FKq+19|E^ZfrEWfV)KeM(;eBCSiicjY^I`fWam%X}7SMt- z`qh`%2bsTW0pwW&(@SVhZT%eTSNfKGiJ7$hwxe;==haAEdk3%k@25|e^sZK8n|iXG z=M~!1>s|^qSH^Q;wMGenj?r8MYQBjrXXI%ScV!2)eJ3)yN=wXv?R9C6ptk*hEf1J4F{DR9BmRI)A-zw@dG~wKN)Y8Nz;7&NO(THOV7LGk=R?!xEK4 zhs{5A^mYo8J?3ZoZ2S$Cjn+A#*>wKn0o{i8?Q;F$c;d;Gsa{7O()&#kC{41gZkZg3 zK1Z0#6g*iNM5;K!Ge_b55nYbDF1A zOn%FvVz4eaDkX)l#(B}Wmc(8i9fleaJe52(hN{lUr9P}WWA#RA47j7(3ejTXrzb`E z5k{7?u0Fa@Dw3$cuA4!x?TK(CKWa?lh@)Cv5_7Uwq%djgh{dlx(_i0=DUe{wh}S zMY)e7gwJ64yQtWa*isxm5*SyRG+!+yf}e` zE%_S5$cI%9{~CiWGp zu_do}2yX%!;)_2286nq^A>nKEGJOId4$_6f2V|^fe~cacoJ~S4*sb|tbbsA|6LDpi z6Mz2!(se{9;J}K+@bazOCi7D;?}>27l+gNJoj{}@@+(EP^7b?Aqb@-V zJbLJ~gYPX7Wqw@-;sZsdCtqKccPmf!JgvN1{(wGTM8I=-uDH;&!tv;;;mEEu9o5Tn zxTbdtt@;68Rq%pZ!0k|(LP_ma0sp+_>L-n=7Gf8gavjECCKT-(bPx## z8J?P66@gLD#}kBHi@^pfep_?GySGH8XArTWDKBWu@i7bL&kN{0dVfS{g{L0xnHLKGMPIKh}MDB5M1_kL@G^|ro!EChppzQi9yyfnJ1^u7 z*6%oR>aIs=I=%02-iD`?dO^CjuS#^LAKCVt4SvRBfpt3#(8tq2y)svr0w_&HI-PN@_Rtwpd|sO@q{E9};@uk`S{zvBmoc>~ z#RoBteIq3^=lZ322ajCVhGVxt$-yA=BkVd{2;U#_O&eZY?RdCbGP=|Zy4WziJtSOo@aE>`eS97`n<|rbe1a^+jly;csD?&HsISrBA|~Ne z1w&J)(rmab=mr&3;v-%9NU@;kf?J)BA@(#3NoVU*8$bIj&Invqa z%zv!!twow}{+(x}Oa1m8qplW+7#n%)#_P##xx3Ws)zO_}BJM4ar=yjBc0-<>HaQ55 zR}~Eg8;;b-{7t+R)JAlr92)y>pm0r0PQTm_LKakJdvbBb!PHJ~Y9ft1=;3_-+IsrqkZSo=f;t=@Dl5r{lovrVR7AV@v1C-xLjdNK zv#yFtURkm{{cw1S)a#*M2n+(}i-Kaub|NhJs-Ut}!7RF6hbDtdO|wwM#8D(-PZswD zShh*>g`eQUqim?A*G@ldkiiRkhd)psqmJhaRT#XiCtY<` zu_#D%rm0L@bW%R?)~z%-%e=E5ZT)1Z^CSt!T3kmLMps_YxA!dF8a5uOUfw$(^AG`* zBjDA_kB0FILqiBMaKOj(dHbVUPh+>#Ctv4U1TK>w4rv=l`utBp8|CnblYllx8no}l z#SdPPxN}nT&FXK6>aaDD@BG-|QeSjdVKh&4-`mQz!Ck$>Fx*olf2qIknomA8Canj0 zy?@=>+(?+JRrd;hZ-yoBInw`ZyZfEVuk=`so^$RJi!q@0a(w*y2GiQz$>^KDRBVvR z8Cy)!hsA;5lHnQ0X4(UV+pW6zG5DcwK{f7KTds1HcCJ^`j~@co3$jPQ9nIiU&h<&W zV~byO8J7|8bhRW5zc!xZu;CLEExpgZCio}k$`F_m0B z#sTvpyU2_Sx&x7ah>Bi@ihYkzE)Fv>yC@rm>6L=sy5IC>!2GIjZ?~_IZj!c~Xi9qM zsdBrrJ)TMsFAXi-_oZ{0jRa*9P{_st@(( z8LAGCprpp1@FN_eIK_BheZqXOooN<^8h*UCsz=^fPd9lN%vx_B47P~qjwerTTJmEj zwmq`yUbZmco64~ImBUHu&ZgVqor2EM&trVdvryqcMHFeiTqrxi&q&IDQ_jq=5SC}$Z~fi1WGyZ<_pSxiJI6T1ntSMLd~*#}kLA2|??9+!yKp`wRUHx30in zc~E93nmn*lN-wP8P6|Izq_B=4R!R#Gh9ftq2P0-uc-i=_?+z8ErS`Nm%SZk$Ry855Wm@g80*-6(J+C zzC#T~vlzb!O(BSWKV0c~eLMkH<`_KFQzl?!wNf$FrTCT1zAFH!kVthsRCuK@nzYL* zvtdTJhMYiSvl$aE2kXH^A_jlTivaT@x9~q-Gfv4w>O84F>@`MFS=!6 zE`PML)7t!`i`5!)FN1^x&rD1Yu_rgPbRk4^BU*lXZBvENVZtt8g0NRqq@bsVP&EmK zk%mJ=>_;nUUr@D+=Gg_mI1+kRXPJz47!U$bN+=Y-UCyW5T|-w+Gf#jRM*dB<7p2 zg>HXD9|M7N{RQBP;u7R4++#PLZ%OB)SS>ye#xNpTDiHC7Zgxj}xp*!+b6u*2>uF-4 z7;manth{dDO`>@wS-O$vcdB%WlhWA%x82yQ7{YMj4DdP1ug7+ptM5irPpGepy34LN z@WDlN2KKZZ4BO69bsPTJc2}PkXxar3vBe=$n%opD`7PI2$VoA2%B+i)^Gw}m(w7&c z*iEiiRBJaJNx=0CyfA&-5`96NGeEw z+txPRv2EM7?T(X<&5mu`PRDlAv2EMv*jB|!2Vd=d&UwcB{jM>Ry6;+R%{Awxcf=r6A; z=(h<_#$dBxl8wd;Clm~_xOg-~`Pgx0{MaQSIq z$^jo~Bn(F~_`&i0JWC6Mjg7Uu1n?S-g!oe$a8F?cj7=5E0}7W#wTbXDHPhv(;*s} z;%PyYdqEa_F$uOU{!pOLT2AC8uz13cLeG}AM%K7$W0vs0Z|WzMykPY6+=))6+W1t- z%xZ5eH~~llQU9I#r=NcPSk8d=5rmgO60bKN_~u92!LZ7FS@I5(FPb(7^Zfi3I`=Y^ zN*ED0xSGySZTfa&#!EM;aD*>HH5o3^THZ-yvEYl(Yj)Apy2mg`zwV5 zH+}izy3$Fr@z9G*+wMR{ge-Pcd3xY&MpeGF!K6^3uhPN2m%w+^5@G9R?IrFhOrYXU z(E1qPEHKlR7V69C9S#nQ@dsv(DejmsT$f(I&N@2iNmgI|7D!;A9F2$F`*#>vmmaJ_ zsYi{7+D6)}_%WRzqR+?XV^3RM+Zo6e|XsQ z3QcGeK`(gv$)|&4vq-}>K9qYD+GtA2fnf6``jV3%^-_bxUT<&>?OPA1vW|tt12LK#UPgJ zuuBn*8P)@x`AjUCl;}QoC37=Kp+C8Yqj|U#Q_vE{vUv>|-A02+M~OM;svo)`6B);9 zAjf?(g`9H4VaR;X54<23H04Blk4nAX04nT!vm@{{|EH%zq=hs zQ6tHy4x+4UM&(<#0}~HQiOE?ZF*pv){o+D`{#+?cc#3VqlQ* zaUqr6!zukx37VLo{js`K9&r{N4lfA|(&Y5*mYJUI_3fcC3{8~E)Az{G{UT0yrc~#G zgGUb|ihJX^{(iX!s`RCqbDd>oPN`4(nYx8_vhUlSa+ICvl>a;BhU{cPH?$EAk1q|R zNuzARG3?0FTkWt1`IPP-)+HSs&HaDc7%|X9S)ze^xDUY#{0jGj2`C{kqskpVy|L|E zG2OfF=l4XdtDWJU>#W7$K-;L>6KnJR{#jTQ?y7|)gWa#W3G@KpBiptmVrfanHVAjl zw*9}SWxf5Q3<|%|E0DHhsD8Owj=KB%iA{pUD-ej<1@wderI+_buFSiM2{(tw+~obU zqcneWJ4ToBb80!I8^oPSd&`h#9mn@OUUy^w=AA{LOn*{gDJDJ5o28?wJ>RN&7X6?p zTLy|vJMzp5PlUMl+-7&m7@_Z*--_ zLxy*4;y+f^_vRvXfALj2Y?v^+yi24vK6p)aI`N=}$BI@j#wJBs9Ufv(gCy&0nCwH6 z&{9HjFj7tRyTM1qONlNp$H?IXCl-wo^Yg;0EiaET(TiGYLHz!0z5C?BOl5~Ne&e! z(2YGfVh|i|;DNNkc9)nps{z^4`wV*B&W=)4>q$6TPPSflkXB(`N53n3pyjsh=h#W$ zHp;@^?SXB+^#R(WWHQl*<==(DmR4i=qUOu$_c7MYY>_E^sKWp7F4~J>HJ?}SvIM$$ zKR~tSy&zN;b5*;y$1~n$Bj17>?7MgWBGG5csOj@F7~^6GFu2TQxMBH)sV(4^SCs-b}FqoO%j36joQd)5DAB+A1X2!UbLbW zz6cRIHa;#UB0>UG^(C;(Fz`fum8jG z>{H{mn^x?>ViEq`cD>MzRKcAM{H*5!rfso)&tniV$^OqqVi8sS^qk~(Iq)F(RR{H5 zCFiY1K+T0P3@4|4vx9MLf7|KtYnJTY%!~4hK_PPI{cM_${1Z2}>H)6bA3JR0vkHD2 z)~>D0_%6^5r^&3J2sja1`xbRPXzk~X;D^dLjk0uT|0%CXpe-z1CRZ~g=^gJ@{0-Hx zaVB`Thvx_$4Jl_Es_J{g{yh;oRC8zESY>c|gDYjuj#OYz?`9mBpA>by)u|f&9^KJ6v&M&}CJOPUW|nlqZZ$&7@4mF{d-+$TGakKrwD9 zZ0dscq>3jYF=cM?=_cqz$_*OD4FzTf5YsP3rEqNpY-T67y*Gqnb9tiQArguzyYlWQ zQyQ(kz!}BIs0D_7mz`App#px+2LQlCMB{-+55qPN!`F_(5e>`b;iU>K^as&h;V{sv8^?bsHLO?LH_#}=Ohv=;E_`b0NQL+N{zwnujoLk+KHWw_7|cZpSjX?cIaCA@yMm6-}nG0C#HriZJ)Qk zUN7YA)n@q7xGHjGqle4Sy`wEpkksfAP=2DQ=&+D)NAk)eIaKj`Mg|cq}xfi9M(Ia%)_zV))b!! z6(%AjPR;bSU@@cpci!>&y$_R%2+5v7+-{vu^M3Gxh0RPUIE6HFjfL8b9@F0*VOwTW z;&onQ1CzZ7l7qW6URe5`Xd-K`Ib6Kl+S`K}6s#)@N&3gf{dNFPZ{JguecjV&bmD0( zs5rUt@uT8y(LsjC{qYLu#gO65ppLQ!KZgGYz&OUX3Vsc$r2H*g@i?os(9D+;f~#gL z66}UQ@Zu+BVZ}v8+h?S^!|v(dwv&CM*aI6|#JX@Y?pt#<)X(VjP{loAFWTI0U-L#! z#!rAjVy54>+HHPFk^a5UPgJPxJ-5zX^FHE6EiEgri}O0mgA?i*rlG{5_O%x?+<~HSQrlUPA@Pvi(u*45 zk@>+kx1;YdorZ+8lji`yG1#p{{LmU4qnPFoetcKgFh*yY+$mqfJ$O9G!X?!_# zHbahnOw-^kyU;)2ZTOG>;DX#a4l8_ndzfCWLf<j$f~N}CaG=K5VVO`4vX znEEp-OxA0b!f&?S0qEd8Z?`TR>DvEv>pQw~@OUv4SFo8j3qWuQ3PSU(129uTCcl!5 zlI-v|{WwYAaz$kG%?=ka^>4M<#U1NyD{vw!9xSD?{#C}Mr4Mm*%$#9>2-kFhXMi|P(< z*?)6)H*(MQuc@c6NLcH@vPH+^+6x`9ssZp@a|-X2`XT?X^Ly3S!lCqGFfK@kb zg&-lPhBhiN;`T5UQV~)dt}Bp8+5H7)j%&*jHKK|zV_;TSI_%gfm6bXxG1f^K^7 zTq+Wb2BM23kIGdwESkL>S(@zXi2lgdWwAGH{%4tr4y(PNL0EWSLGXj!Cb@$|BT$z| zwkz?v4{)GrmTk{K0+{S~!-tS)z@MbUIQgBNID;=UBz5^{_X;It3;BD#~+%es}aNYSp&RE zcHPhXmBtrD94DhHteFWl8I8*?XD5mz3p1Pwag2zI91Z}fhlWE4A3YOwb#0F7x!!Yo zft;K_U&p;>h5GVQe#eg9UD67E_p5!&bsXn;0 zF(&iUln0Z^(3r6KDM`GmTGT6VaQy#M>dmQvH$_N6U4YR4j|n8k@fCKcBQw1WW}Fw^yHci}KHAroSRnoZV@CQcP`1ATILYr+~Q zqT9LX`_JA%FW21RM-|hI?;id@M@9f6#26YH8jTPd3lo(xu%9`f=f z4Rh>S|IoLDgKuP`YM0fP17N;~l-&Ln*Ghx4%aV_5RBwbJY=qhllfI&%p;>FR<{B6n z_+?RfVbPNr-jix_Lpf*S`>K9DaO3uliPU6OV0ow?uh>8|%He^2Gixzwyx0g)i-9YS zC4Nv~q(L^nmYw~q3L5&tTiNisNd{^3spUnHF2Ik-BBg-W;{Eq_d*0>U=1Bs(N{5IU zSLl74S-1TP4+z%>Oq(J8@_PM3;4_Dh8J%9FGW@fKoxPS`Vcq1|MEbfx9ZtnRJ1Tz^b#6t|7C|W*%Qhv^TQpw)l)=`(D2K55sIgn-q3Eyn(B$N# zDoDWlN`@eJjvaT-rk{RgOWx|z5=~&@N|KryM>@A7Kal@Y=e^1Zw6zF)yx0-b_ahVy z5(6ZA`&GSL_dJf^l~Xf>Z5f z3<7Nuh1YB_mw3*BnZ$t|Z(hw;+5Lf4>REbLd>u#)w0{Cj@CYg6A}^}9uav*S7Sk9JZiCl6bQJ#O zGwCVhm)wNj<MqLd`q$-L>^01&)4 z<)qt5c`&dvcX38z;ONHYpoLIYPF$<^#RJBdM08v7DXZ#7875<`GWBATsY>qkuD%m` zdbZas5}7-IPgrMy}mE+8kYS0MJ)b)UhNHim?DGj|z zh-Gy_Kuupc{0r{H=qV`F;jaxfBcsH~o}63;3qsLITz_Ai2(6Q+h@arZ_h=)|45LPf zz?F3U7cx#wLx2?Z$&*K(#_Kpxd)Bym^R;*YptV+wN^d$ZzLA4%#!SZ946|$0+!%!s}SpTr!FEbleUec#e>6`H#t@FA8dW5}E zX(FEvF?n<8-$Lm0FbxJmq`$2N9KiB&IGimGTonRFM7A-H@e_qb{#8}(^vs&h$ zpyyN;?PD#~_e)_YF?_( z&U)9yw1^1k@P=X+6*Cs2eluC-pPv{G-agbc3`6s1RLpjFqC}x0k3mR1VLlX?9UqwSVqrjnReYI(83`2^)bOx`-yW(tedo1gh?L|( zFp`jZKQTQfn=T^NrX3bzE+0~K8a;>)<_|UX{g(>*;uxIRdbAPa-9BtJN-8cm42+{X zsBl`xg`=wQ@j=^T{cEV7;AG9H6G=@*7aqQP-Rs|Hu1c&*@f2F|%(ZQ_=^b?F z9Xj-W+qlZd-i=x|YpHcMt(eY{QO-1vt1S0objLIK=jG`uw#+q##toLR5lMKxB6cM` z3B4#wz{G^5+A=7(0c2kW=XqWviYSgbeSQ=UWV}@VsqOncZ(Q;RQ|y1-=#y}ukoP3K z@!`KO>EGtdPb#30(pS!kCB86!_23aMI)?PxjSScn0$W*X1_lX9NytzCr){vFiSth) z|D7BG8E6=A(SQ&Pab(kokOE1Def2&ojK5!2w#_Xq&CL)xj~grM_1Yhw=N5XJ^Rx=+ z62F3ov+BSCnL)`(ythC6yJwvh?>4itK)_kK6}_FFPJCwmMv^?|%mS@|zePnwDXFR= zcnGu^PGReM06gBGFKQj?^1nsG0H~P+VB$AIANp}#wwt+#$%n$$Gp!DZ#-w&WKUgfJ zA(K$|jcRKL0EMJK)K~j32|>Jr!JfQ2cUh(}lQQ+!f4p^L#d<&hIS#`(`kEqKF597Y zXI;UIS3%=4tk0X#7@)8qp?&Sb zyZw<`C;Qm0l30?$iJ5vYN7T#c|9li6Dom1(tOV`y6C6BJ=F2IsgcL@sb%O$0v}_V$ zWDaxvQbz8QC=9ktG+J);3EwbZwJ9y&< z*>HHsk@l1=CDsd8{0#0ENk}IgS$gmaov{PncZyJeKD~Cqa0(rnY|07a6jgE=(>da$ z<2INl(z5cXg)U-PVh ztMBhy-{+uCj7B)PJs_!QD6{(a1 zsPlRO>G^!SsHrMksE#HU2A#EQg(Fqewt;=NP1705HRZfpThm-xSuqBNd5ukOL{Ch7 zU;3dD4S(3QFf}zbwEOS_U&sv^1H-H?vx~V6*N`>SakBcJ*~SCY$_mfnb`55!JqJ6N z10I+(8B|QqNF!#Z23B> z&#p~Z4*d|dnEqxjAFo3-x@g?Bq@)DYGbxi?pqewQjR>m5wX~{pj84TW`zN%faj9W{ z3>84xhTq0^yBpJ==YjE#wr2>ADob}3%}Xx|Cr~D2{Z|R*f1f@8XgW%qFFoBDT$%Ly ze=jAFF!CGB^yQ_EGJ5+TG6TnOy{O{SDIZ1#&a;u}5MItKgn|MiQrVXt-@ic5Jz8{3 z%>Bc06^|~+O{YnGUEgVhHjjal+cy5Sc3ZqcX-uz8ht6(n-#yKkP7l=cOGF?Hk>At> zFP4E`uE7)%qNxl_&->j$i(N&zw1KzlU^NdO3pw(*v^kamKW1ns>2@_yC0nMhvmW8uLaNCw+ym{mZ%vkH@c6`SMaydYfL0Te^hn~-uBd7qoWEUea z%SzDMvfy%H4v)WtjBQoCvW7~#-C$UIUZM2u<=B6PNWIC2M3s6n8l>~e{<~SI!L`MJ zyQsRL==lHHM9@(Iq+G!RPTNS|2jVy)g>e*BN0!L7#)?G>Q1(a}DHwPx|6mgm1_3Vw zFxI1EJ3%U=^a#L0jV)k znwGqKZhR71>RAeL^*63?)(YBLg!E%rE5($-IOej@`}+sTxTvH(RMe{4mJ@GXU*^i+ zTu4E?nZ4eL>Uc_QjTaSVHipyZXYIvZ|L;kGyM8 zCN3#iR8teUy&upYQI8cXW%cz*8fK>KSf8*=#e-wCx5unKHQ@BX=j4lw#aD zi;->8;J{c1^qMc|P1ai1(q$Bx6GpLNVtg z>$W#IRxYzG<<{|4hIU~97iF=ztX(&&r+FmAaWD9eOx~~53_K3!D3D(+GIhaI84J=? z_OnUyQ6X~J%9lm{@3cH^hfdfu&ER#V#iZ9HK6iH2!65(CCE2>;A%}h)%e3vtO}_jU zLc+k#!&J@9qrl}7moaUQvOr8q3JUDjjBW0Zr^{Nf$m~4hb*6|UP zS5%6*s&Tv_o-#$KX#1?=;ezAP%u>~lJ8RwJYjHC@lD1En3T2zfe@Kt1_$L)*Hq)Si z@)$CE8#>?_I%e&$w;8eH7`bgY8s6wX#Knr)$i+l#WMJ>$DJRYghP&lbM#>{l#g$8u z%)LU-8Q*JYw!D$Z(N$ZB<$(JLIhx{GFE#yJ4!B#P`5$fV8o`!tLZ^w(=D{XZ8l`&m zU3vbmTx9EjcLW_Bw|Cd`R#SjWBWlxQYF4j|h~BB7#@Z~hCWo$MIXXI??)3K7&CxRg zEziv+#a93gci(j#ADVoAiw{#K;m&CNgC$Mw*gS`^g z;I(5Y(=~nW7rdH)()^*nrloG$wpPt>Zd42$cyqf|;iJ|elUF12MNmrGKJYRyGNcOS z6hk3EqxC^kGg{1~jJE|;Z7W@pIUp7#`gBUPThIb(ragMl0FqNu#H;b&jf@W3kD^p; z?x4F={@+UY&$;(A0JxQBzjfJl0CPHh)>73I7uJ=B%3V4`L&;C1xhFEO#>S+9>hOZD zF8qJQ$%n^Oc|Jk2y_#_ex6-<~&KQtCO<_eBuN?}js_?}^D?5~ta}dkKkQ0^yi%Wm) zNNc`rPK8R8GP#v5DW6ue71GnuiMh%H(^}-Ns$^`ufa{ob>xg~8tTn%7AySP_qaPDD zsHs1A?+!b0i3+FNo61r>bE>XpP{LWNOtwS1lW|X_Sv21n1v)QiG+Z}qWx#Bm6w27* z#HvC;?crBa`dZCGX_Pc=DpuL(cNZp_&`bp&v1I8B>svkPxusS3xbPMY=f`OZhor6Z*#{ zu&5ubb{L{^I50HE--*?a@OwEkj%W+cUWT(=X&=E2QrLBULdvzh7!Qd{ z1!rtrSZ6z|3k1wZ4~E~@IbK=C^xlfXD-gklFNP*C<6&bh$%rnlJ>1~VQnXhs)T*f7R@DskOt(YIK}j+V(SteO}R{mh&KM56+FOW zk?w+p^&eq&EB}U?K@KCM%UV-Pj!IEMGcG%G5h?g&IWB{mV5{7vKOMAihFZ@vNHzcg zgNuTKm>kbd&NI=>Y^9!o8(FR=lRHc}T7uXhuc!6G?3l=%XIqKEPsYOoffd^h9S)1Q zH?}v(t?UDDHY`6l**56E?>dUwNndx(-yG3GBUB1Ogo5~?%Y z3mHIU^cXA?kArFwb23ZMD@F5@QBFDFdgVQcCclGLbD+(~d)6+Yp$9@ynL`lVtOrX0 zCg>_}|F+zToiQ3UuP4~B7#aF7`Pgeh)?lXwC~b9F{j+Fc180PRm!zCPFGU_UD_FY@ z1dpxwWgoQ47XH}F73}5#R}XvnZ_uqx=)}HOJC}l-U8oxCW4)jF;F>(;drQb}1k9t5r~-$2Q+Wzds^ zO|!&FBIUKMCq!ixWPH9CCd!0@C!Ue9^ISW1j!6z&I7R>BD>*WQhCv8jwz7N>&zC#f zR!}3apgH>f2o5-NmN@asILf}h;n(Ti9&FUJ!!`^Ww&{;B8f11lMLxXQ2>$Z^gjmX{ z8rgj1BB8BEY9XpW=&p??Bb^A5DI!Zm^+b-`^G3lV3QbSP1}3RM*VoSrVtK@F{^G6B zCYf_Zt}_(v&A`@bK;QWI6(wd|wG(iDip*{BS$^!Wro8(N)(YvMaxffFRviqe&0-WS zHAZ*YLHJz(JU+9n!I$Fmont-Xd6{5UGwU;fI#@ME%oyuerc{Z_olx`mRqzp8F8TRH zjn3NvguoDUq0NUWYmbK&7HP!@ba6v5Pmm|SZtQse2XCM3S`(p4p;3X}4`huVUtc=Y z{F_Uto}lNmOG*jx$;flEtlOtq`++UlVtI;hf4^@&Pd+Eye@=5VfDPz<4frZ@j^hCX zE%&Ut_kOOJrRM>V-(xt^{DKhFxDL)SGrAcxKas|h-f9wAh|-$jd#`J(9d?R{4mwtA z!t@cgf)=eIhnolr3(a?H@~C!?Mw|csqJLvZ-CT8*UUl0PW>5zH#tL8{5_Y+e7J43V zG9su^^x7*9t;C2FmeR(_q4!2cMnNy8Duk%nNr$F-KzYjgy0(bd%F@a|CM0_WMuw&L z$t6@QSMCyuqlj#*-YHGOPB7S@+x+s=%4TP{qM`D(JWXNL5 z==6f8UxE>LT6PO~IUN=m^A#oLM!#1znmYwSw-!Zf5p@6RMZEH*?fY%ju0UV;diDNo zar~8ey$zksU60hb&0%uIP=vD6U0c|s0iBHsI+N7xadOe^@hQ%L$l2E1Ey<<=q=jsa z&A$Lb&_kL?>i6c{==J@PYr!WXqDMBT=%s;jNu*UU5TQeOq(+c#mDLvO$Z-yH$_!#xed#}sZ8x04t zrI;HWH*nwI@~qWtrX~41{DX;h)y_V#(b3VfQ|u*W?BWOoaAngVKlvQh<9>+pA%n<3 ze@|RE${wPuCXrE5S67EkO0qsZo^HzkgF+NnSH}c0BuH5Es3<8(+1Y;}=lwzUyGg-;!wK{B#kR&qNH@4qh~?5_38>rAg7^W5Yyr#P}u8WgkJ36 z1+dAWX5#*_LYMKy7FxV=>fZ(7uj(e`zC?IA9en;LS<3h!eLkI40FMI!@p8i-dmM%) z|G9G#J?daa(}q5BSW1WXcB{pgnyFUU)fGV@mp>Ayy)W!46m>{n(n!ypCKj_l_SAHnlb4QAzEol_;8}i>{VqdBhUSjD8ido)gGC7K zdkyZZe{8#GM(`-l{~bAZcqPDyUsKgrxNLBcY4%#}A12U->AbxawgZ{$*ns}k`DQ)! zx_^5%?!e=yH1TqG>Iu+Cukh6GI&Sok$%E_If!Rpg-AF~<{88P%(DyB&bqideEF>S=VJ=BAv&X(yndqpLqsDI+s16U6woE@pMLX_GB&c9_-uG z6`YQA1h?WEuNVJ5JmrfKVD9(AMHrlZ8+Ls1y&WdgC1Y6~baizl*di=TWqaL|X_YK< zB8pIU=iZZ7AN@HnWt`Gu*RH%@BhNR4Db+XVp{c)Zf5O_3HA`972NY~^!4M{1Ja}?A zXFuCZkv%Ro+-Pwdjay$AENu{?Xgt_UiXaXPtDw9Xn=l;C0q+}9y-D&rpD}43X-0;2tdUSs7vQQ@h&RN{B z4KlFm2|bUizFbV9$_M_0rPvvF@D@9s7z}Ow0nGec-__gK>A^$t)_GkCjRfd@k)Mw5N z+9;U6S(SAXt;H1?@%Cvi8BL&MH^V7c9E-n#T7-fiZX(eyor=*eTugTgOgOHXfU5Y8 zD7zf!XkKj+2SU>PvFSMfGp{6-ot3<$^)^2}!>l1<27)6$ZJ`C+Wc5sPcC%^v6LK!a zZ0@$H49>k93&_NtT&V;V*|9$l3h-btuu`6Cd;0c9TP*bCh zZHCJ)>9IwK&%_%T92!2q>j2x3bb{9nc`Q}d9v+{UatO4#MuInvmF{BPP19^uhw7nP z)_`t;0+Bs;m|{y$MCOEHGJj{%Cn#afYYp2lSUn`IYijB7p812!bqdPwB}Q3;Xo!rD zvCO?Dz*N$t4xLR3I$Bp9(Tmpv@SsiX>@DGts_!f&SeYgu8B~tkI_dY%rY$v>-Lban z+JY9B?;yOlVfu^OWwDX!*8rl%WdICC-1DKt7FvmUdF5ER5B${2vzp{XB}-%{@mts`K|PJ- zi_4MSArV&}_A(NsDm#44)me4uhBZ`|xzVF#1GcikK}h!qObD1lEu7hM3Unl`l(D8g zc2__oerd$tvw3KxT98}ZT^6t5u70tFWF#=BsEVg9&SpsxhjZu8_sx#h)+JDJCqeRhCQwZ*kY_fk;mAdpQfd z=xe_91fFT9)SKzKan>VSGM(1_KNFU@7&R3I>|kf@tjopfsd~j5YCS-8a!{ERbK0RtpnysNPZdyue9#y zWeI0TXS(zp4!vK7z-eFpBr);0ysVSI_)Hfj$>699&ektdT+oF=m83j5@L#E^Va?X7 zut0-MOV%3Go9%8OcZ+1-Y$2)<7&BHl5G0(hbj8o(?zsM zFeFT+e1};WM&R&@?pDc@G^ z4IeOmAX2^@VFHC@IC{*$t@R^hA-SZ@{HgggCn;#)z-%qUAc$6j+iBH)C^1aK2W1L!&+gih4;cq5x+%~S8lk?Rybav03{Uw9n_Ev`JWOY=sydL37qkE~Yi`wo z*&5vZfGY(>l2&3vg)F4G6#C)JY(siRRUjwg8_;GTk5JYeLcb~N(O@St9I_Q^hlm54 z^S~_?a#ZAvOlof0_;*Ql0in<2VnJ-28-G_HElQDT@-S#t(+;`i* z6TOzD9XS;WpEsE>0du85dh<46OmoZNYklg_dYP;TVzf@UxI9pbsMsf;_g;~>4rWUj zHcOh&6&nt(2hrF{jb;)ILu!G7F8xUFmef6q06O;BO=Ta^U%hs+{a>BeDspklU~WAv zbdLFVKHc7{-R=PZk5#oFmMbYJ5d*~+ClGD0k_LQva>L%diPoajbV_;2IYaX^`X4%$Fg zL0@9}wEmD%0!>d3Bngau_%LD<2F|w|-Os#U!f6nafTy@mQ}QCXoYu>pGt#S3*GD46 zDX#u04t8=;?}v(y)01+1*BAuO%fGt<5B zA%l+@XInO|j49~ZW9_(Fs&@j^^85pVE4HAe6q9SyiLMY0&FI;K#qo}UniiO@Dfq(l zL{t&Hh)uHZ#){B6sz1x_!;CG!oGxkxS3Z?UOTQ?KuBh(E3);JZJ%xDgQk57k!t6YLs;$QXbXnv*NlSo zWkRFB*#zaLfy`PiMdo0hR$0p(3D(JJ)Zgi;Nl0wvPz(M5gYA4=JNzuPwUa#uuL-5W zko)%>?%m78x%705%bK~2LX=GjaZ|I?n(XtZ#O)CE%sWEcbB=94%(So;A>XzZ&~xJJ zOz;=vOwQ5gwcck)sarONyLqhL+opOCSg)V8m;>++^oBXTzbzhlG;764VLkb@abb+xJ+N_1Aifw@07`C)sx3rBQ1herka|GWak1LwJb+Luk;x^}n@0{fcv zpt8nM4%&oXKg%N7dTjW8FGj2~gD*%xAPz+^QtAg7=pDH@cjoB?2!v0$As*V4+UTQ8OJ~|tOhHe$=^n(nqUa-w-Alk2=1u>aI2@sN8Dl;pfPY=xoywWU)Pp^ zu@0O*Y9+#QIcpc)0fJ`kf*#O`R5Iy3J0_k37Q{&AmQko{s<94_?{}_-x(~wXCgnfi z=*ETv$})9`F4EYo!^!u!l0p3(-LLu$goGjxcrS#kO;K|*1PR$7!@xMCZUH|p0F#4m z(~o$F^!lwRi)^JPUPa?4gkA0316;GJ)#(`=ph)rZgMHZA1nbHz{#?0Q?Rd57lX;=~ zHfud-d2tufba+SK9F7iNYoGSux=CVK;9KJf0y{&!Tj10}{{pVL_-_BA4dCd#cWu@E zB*Ppc-*1oXuaeFpnI{25G>;C(XdI0ly^-1Z}))r<7^=+REie3 zP(O%!EU}o%xTqL8xMLTm z2uR5AEde0L-i8`lR!@Ct>ogj7?fDn8jIV!LtL*W|MkoBovE$bBuX5Yd=Z)c|;7~_r zMupse6`tR!`#kNNw0$(d7oUCwTKz)!fyFpliKH72r((=(ahB#A}4Dl-~_|-W+oc)@vSL( zr7?<<0gX5rf}+V_Jwp;etLP1@!QpY5m#sE9z4CCL zK;~c~k07p@bcC&@wsd@ z($l&3jC`+@BD!-DL3nxE(@E=V4zpF``$R1(7_Gz&JJh;@UtBM%C*BTC6MJMlL?g{b zXrQ{=G~;pa!}kt*DNH0xeSfdx+xj1K`XBNx3y}@v06&2FW z#j`>MrzRD0G~UP$V3;^CJ=o*pkqbNn2L~f^>GPxB-hdEsUVdvYB%1LA!HqlJvAaP3 zSI0Uo`_d{1keO9wZge&lKTnyAVqSzoF{)_zI8h52ZZOmQy2AaDl0xddrZm;FCs|yI zB;shsa86)1l`e<|m}d!Cg+aTb6d-(nZQO1B+QHC#Z+&h1cvFUc#D~lt#;rfA4j-Ks z7iofw73bIoT;(Re+-4C#M=D6Trhq}+Ar%qMYc^McxPN+K!)`SPJ1n0K*BFjHpBU{QLCYYZlV7(i=T;RBN3oLkUc)$y*97Mm92lWNXeT60fRL3 zYV?SiZ}U+ieL&xD8I(#mX;odVpzkl+n4G&j(93gtIq_XR*lE>`;-mU$?7UBV>gI!wkHnx2;+h@Cw-|~XoV|bT7G8(269%s?CZ-XC45NWOII>crL==UQ4 zY_{FLTgi=`#{;SxEFfcMC;BKDj=4Ea79dWfM{fJm9SFN})eS~H9sFH~5ygd_MONW9 zqf0KDr4!Wf1ObXxCY?}?l&voY9r{4?%cN|@-R|k(a_WuPl-Vhfj+ylYyi2;9k(}B$ zsRDT9CG*wPggD1l!5A!!;{wy?taQFh_RaPC`}%_EYNH?|wwY>dXX**Hzo*tQzm$+x=SbM||_zbjYP^*rmIyyqBW z0zqe-R_)Y{Ijpx{!2J+6x3`IDX@3`!?%W=XUk_m!nrw8q^{eM>Aus*Tjct4KM8IKz zP)1GEdOX*$eR8L-kQv*yas*+Z>_Vz`UtH>2m<~_^4!3((l;SgQWcDv71{#nBhc)x) zB{y3Lu9gX45aWCAvhn4{a-o9hA;RI}cZB>vU+xqzkC+;Hs>M(0kXls%7%UwG=`5s> z{;%iip6BIjPNNZ0TG^0S%kcxIuDz#j{o8K+;KOp|k~fP}3|U{e z>$b@A9P2#SXtq6%7FBItV8f8j9K3PWps6tE=)wLn^>=UsO7HbwzW++rNCY=w7M}7f z!1RCJW!1ZSjKA88U)pWdA5ki4g<2S&X+_TKm7!LRX;r`_H{S4~^Ed&I58}4IbChu5Pm&b+SwHFo*#h=&JrV6z+zJvEz*w!(%0d^@oPEiGqUNZVk0V zZE>K`ZXzDb>Vkbmub1{OHrem;Rm)G7X5ow@vVMzs+-;PUPmJ*ADr+oAf_~2iZ|@C9 z`O3xaU4EC1ZI|OI?sl5d|5VexD?$PL3qg?Z7>QmSz5KE)R(8^rvcO9U3JPf%9m}NU zqE2r8Y3^Zev`kk~%Lx&*6n1oI=600EqT9&G$iM{)@vmCgyQX_6UvOa4=0d?Cp?B(d znVbhdlP^Wk}JzB(1t_{b_0H0i!{`C0Jt&z-M1e zNsAo>5ypN844e;N&%&vF*Zh&+1NzXR0~j7jGz?ig5A7RAX8O%zKb-`Zxa-P`V%%W- zKn|YhtBh;l`>EUYcA;~|Bwy~f<0^7qQs@mn8nlRO2^k~Iuc0`hMM!P@$P)x*hDq= zTcN1g7XdcLGJJBw;Nrro#Qj4r92XZMOt>06l8*otw+0j&4TqsAG`AgrR~ zEzkC#!!QLw#td&?=98m>AgL`v{>I#?DaC}2X`ZgG9&s|BTkU`IVzE8p#rN3c!uQDS z^A&wD40zSz(H_RZ-!gBZQE43Sipu>F0hw&M0S?rq{<@F(_kJsMRO={ho&u=ZYJEoi z31W{(GM=z@eWmYVdT`sJZsWeo#9!qmx>1pl8_P=pYJ=;GAafOepnDaZ5)dNG?ZSMI z@I2C%@pHJb(Quev*4N?Umk8feKllb5Lvht#><23f7Xi!dI#lE(4wuJ1y_7=IuM{(i zQL&_S0Hvs?D5N%ZH8XkQXiw8(3j3au3RE@ENsSa*iWnuma4bb~M4Gm$DlNGy+mOMUxY|nOZod_1hsRmiXMh;oNA`dhBe8Qxh=v>X6aq0gI7kw+m~W39hD;Rp z)aD6zlnxs;8K^HX0fNwB;8ok2}j3H&eEN-4}!N&Fao}rc@c&_}9jy7X| zih1szp2oJ1TANJDR+AX{`)om&>=pm(BV>g?CFf$jEMAxw_4Fdi^@l25pJFUM)@IzG zfHxG)Si8~tE||((AKbh@18yCTRc3v_aMPzGv z3u2?XwY%kkv2>*gsjMC}lL>PW2|=eHO)$x+n{#ESnd0Zt#(pwbJnut$EIiwBrT$&3 zE6gxbSPOB9B}J~7V82!Lm8P!~cNN2br(l;E8jz#qs3w=0(aGzGH(dR68y+tTr677} zmfL3#hLAByHltXp(v}KKnm4nR*YQ*db2V+{T;93%4)NhNbxXo<>(CdmcQwP1Kq3kx z35MD;n}I!B&52GP5;saB)u~VaO`&B+5)l$ms<4c1>_EjoGePdH2j_-Dg1x`a>>ijXfqRH}Xf<0lHd%~}7Q%}f}dqZMd~aa!F^pw;F5 zg~i(!xpkZ?*788NFDy~Dw)anTyzzO5ucwnCs)lB#4zYYU6|G<(k>3-dL64hv0(S1X zW?hxRXJ7OCE00<6LdX>os_O@g*B@PR>s&zx-Y5Al{2X-FChXS_ zx8AqX&Y7C|;tJ^Ozg{2nt|<8((q`aY?6Kn(KQ~n(O#K*EKv+~Vq4@+hd~z;&%BTR> z@xC4Ycmxb#ZT6A#_kvXXuSjzJnGyx4K6xXzeviNV)>+x-?g*@KoUw9so*;%9`F3l? zDDT$6$Ts?Ld}mBNaW+^M)c%%QL|~R87VbaS-2G#vR}+;|G@@@Lni>Gqquj!0Gm}FL zW+x&l$$L%P`)z0NHj;S@WJfDU-?X*03;Ak_^%h+n((Ll1#}P|6NPa0;C|u4le({}y z`f8aG;|TA|hUGClSQPUT2BoI1zV|E9H0bHh8Za$P4v37pRWJn8j8@~7YX z0lRRg+)Zk%a#L55_FWWfMq@V7dpBY2Q<~pP=xDlUAO4%oiFemSpGMV|GK^MEK;Tbo zF)#&21VUs!3C^yVz7r&Hy&a~^0izh4m{`bX&y((V?3?7oh@$aMiyyFz`ZHO_^AhiB zqQE;_E?yY5RRXH2D$rB0Mt_TwMi&#!#LS4S66F4d)<@&w&E6^1*pZ(G;jkWhXP2q` z#43ZH>m{oGlPTPuCRO&^YFQ+s=}g}tg+#x&AD)kRgv-`-)xoXV99FUmi7ke=V3xROfPctrss3tN&3Z4xqD!z0tG5=?VhE%ppSvL8+1|X zty^<+g3U4mRW(x|;6v2cKg79r&i$@a1U9bm0g23b%L_wx+1-FhI`99!a$;^IhxB7A zsp)*0nrn#DMHqRy0bFk?3!uYvQChnj_)~F!^pj6aUUpKs((%&!XEIBJ%8d0B-p_@K zLLflP6&eB~V})Q-#f8AiO`1j7(B(^{l#W#r8}MR#RI-L7@}K--_n`fxL`Z~|Nq5#L z)vt>Oh${k$$YE^i@QYTMB{Co*r+Z0*G7D@JQR{U`Y~{dYtI_7-pt8wO_df=7vR zv?2A~EX;D-GImJF@;2thv79%9v~Kr8k~?(m(jL|ha45Nkn2yl9u@pZrFB`Udj@-IS z;<6@#iC#vFnO46BmdB_BtW0tueJ$rx%ujhB-0K@YvuH8&xQt z&MaxL=D{1r7T=#}k!?B>Bi5{|cjaKG%cmVF1i`#tas)qo8Ttpv6pbcYtOaSMC0B&s zE;+%kr)2MiiT4tPH5AfZTrDB>uN0V#rA5CW;d2G8n^M*nTmcq6ldms%DU76~Fv2YL zBX+b=t`Ty`JFiNMb+3~caHe}YGARyJ(V4j4KseYAmz<18`!=4mHQ;fE$KkKcg$fEQ zlc8Ila8jVvd0g{!vlNE=dW!@)+UIOCnTaXzxz;^#w#^`0Is-;0v~s@j-OgHkLq!Xg zP2Oep62c8bju6LKVkh&qag0FXvRwG{aA#lTP7Sdd9PlDv#!pqwUK$c`7_`}+8bV~e z7_wN6LAid#qn6UBw@Lh}k+EqbjPelC zMmW-idmT@d()@{_jk$KZcFTL@2>5*kE3H$NNo37|Z}-yPUU-eXoq0!Csn(Vk!A3WxSxljbKok?7t`BuyfRzyeqcdQa~@f z+j8vL*gUa!RaXOEBGmI^Ke!hD0dAszCS`cUj}CSaO%C^4nNAss%!QvM$V%>LI;~Fi zQKWZkwVSgFEDrTSycn&5_^XE4dHK}$JIE)8r0SgZJR!^ptc5{4!(S_x6PTM**4cUl z3|Hsj{x22)lH7L-O~oltif%rs$W`w2Qc)u9;Ap3~%Sg79i2By z_Udt+zwLg&yzSh^@LTJAU|UO?pD+DKy%)61y=X->%CQ6t+umJg;)TpYO;mt6i~Wli z7$*Pb`a0u|Bsca_*k-De;BX~!cU(5*t((D``#xh2(Mt5CgDEG-+E+Tgb{Nf8+s>_) z7$m(!_5%%oQ9ffMm(f;wJeZu-BhkRD%Y`t~B5^OumtNa-mSzuV>xxL3_Gd=Vi46IEdKQ!A)gV=4b! zC>cKtToguQ#%j~ys(;ke*2aaJb^CmjhlQB~V3w|s$!MxEqi`i@yv8S6w@)MH&!~&2 z0`eC0#R~}x5eyjl9AOJE2$Sm?*ao7RgH5kK39~}SOD_ha9S(Qb>_Q!N$+la>`pink zyFdvOOAFu_TJhdr!ij0J#pfTZWV0W9{8{Y;^ZCgb$z+@Bse zFm`f1e)hAjm@>O5VTc$@u6%5GT9^~2;*c>ld(csoP?+}jV%)_|A4f(@mh2Y1fp;|i zxxO1?L^;8Z#S5c^jRtnBuvLbwknsd_r?$OkX8y?oiOFHx58!K8)`iA$^dEO8EZJ0q zft@2j_yP)61>ED_hJ*X|BW2NSiq%kdG$TS?&{?!Gti=xz$-3O%Bf)tRJ115d$9SZd zEqKv*Q*);tVdnw^jvlMVRoqnfce{J{hNSbXn8@+x@ogx)arSF5l0W%tI8z~GoZ5V1 zno{Kl)d#%y7%QW2m$Iprkc+mbP zO+cnhDl#biu))13fbYYTEU{D`ur0}Lr<|#W6MiOm*?VF2b0jfRUZgksCMq&1|bcX2YN2} z?2=zt{;#)+yAFkf{ST?lJU*e_OU8RIV(uk}e*>G8z@t z0w;@R0P-4{IGQRg^8QKt#`;}OqH73&AdT%9R4#Ou+rG$Z$qzx(gN_Ig*%t^tfg3;#lA|ai z?Q$@dGwXFF9Z@q1H<(~&8;oH!O+RejMcg0swxfag;PoOfSsL0pz$I}Kl-W-5sl-=q zRH&FCB8ikIO9Kb0kxR{Qpr{w^_h37`&!2@SDK_vm;6A3I?=^bP8#SGW9lbSg zIZpG`*I0?qy{pkLma5O43GVJUGuG~(<&u@-deiIu9Y#k@VRY_}qiqH~H%HAm(iIwp zYwd4@z1h_CX5DEv>cB7v0Wt3&k^}Pc>{w)erv79s(ksvE7ihCKU=?LYBGtJITSZ?j zvf1%?y=&UK*ARnHMES%kv4%FA=(KX~c{Vgv*IWlSWGFb(3?uK9=Je}1kuZi_tNug{ zOtRF7MtdUQsHM|+`?H?js1L`LUR!Vw2tt4c`83(>x$U8Z9wn zB!lnx>3Z+i)D)IoyF^l^^G^Vl_N}qJ>{zc8H|0osSP|KQRDa6FIm;o1O|JNEa?N4V zQ_AZ>td!B%?LJP*=%w)_a~}#(9Hfs9uH}_%e0b<1ON88+&b&N00wL$R0&fzjT$}&J z(9Y0bqcD-)m`|FA=E+1iDfrWnk>%>$yQy9n8qkaC;6UK&i@Wd@5Sn7U~AFM-3I zY#P=6@U2kC$f^}=!*(a(r0_b+!u}ZPZEN^`xscT$hRBCHRY5**pIi5539L4_2`?;`rig%)^RrY-lSPKe($uosBmCT zNg?9O&at?H zRx*_trWqd6>W5rj(`)9el%&a^3?#udqQC(6lvG66GlSbIazH|X3sZU z<-^ZIgwW!t5$nr0Rt#tFwULb{7zu{1Ez9SxBk)8u!+DL3!5^YHXCW!=dHuYc%W}NK z4S8Wpudck9f6~N^$MTQ|UM=6X65PX0JKzm}mdIY_Ub(EZi)L6s2^#=s`5km%NBt~~ z;|4uhG>a_MOAn!KX-+iKwldDDI`&E1X2!Pi9lppoEJcZYDFDD@vf2JX<~}L>5&3f& zQQGMNzO?+aqntoWUo%}3NNjw(q*HzBd!Xsf4k7U5RnH#paXeT_Nkv$}@dz~2V*oV9T5+`&Q!*F&At-Ox`5Eb1f?%D<7y}4o4J@imu0r@# z3_2E>#!R@!fk=n^lzr5*b*IRh=Pq%*&nEdElY#uu(7BQ3huliF@I*6Mt%~vkBeM53 zJHLPV!u))v_;M+i#xQ9C(D$Skz;{P5tlkXfMEY(jSxqpM^u(siM9hc3r{cYrs!Zl+ zOyocC1rdZ5Dkd*%N`hcu)eXAtNeQ(@jn{FW#6K)60o#5cVzZl>krqA;0m0$E@q4iY zrk}?W6Q83I^5z78%wyaVaqVU?xnP07jB*<@Kfw}A+TEf-AWp_y?eMU$?)Bp*rjfLE zjyq!^jxUh7p#7=#JBJVKgan8WoYGBpfpVz__7Lag>CHCK0>AjfJY-IljF$R)dc)6w ztiraFT{*KCy_c*U3!tQhreSbwxchcBefYJ3GCk6thSBgfTdC+ck;#B2ccWRk4qPBB zh7|%~v&D~>cf11P;|A-jO+kY>UB+6D#4!p6V|Rk~)g;%I1W0F6j5ZXB+dX}Abgl7) zphnN?$Bg-ALFw#2`vpzlxxAc57)42NJQxUm2%nvuRZ{9@%lMdTCuIfR$PRoO87dCT z!}F9wL4wVyT+8ijUz*?i^wJTzSZhUwMkW*!7Z0Uk;YO)um$sf2NiH&WcW)tvlV))i zd`v?5zW5y=Zf-bPf9U0m_^Kz_j{kY0=pPjVF@Yz7mfw|UAes9J9Kb|~6eM*x#vt1a z&(FibO6rJM?{RK@OHMd<=Vp(VC&0mt$R8wg)H~iGU!kG5UcbWCLy-;{Oh^53P`oVV z;Z2}@0?B8O978INvb~ED6NG6Vpb(r;nb`N@a_^D02k=@bMB&OqO<-pKlHn!bk5$(B zCuk01rlydEl=Th>_{=-=45GUwD_cueLh(B$@7)Q z(iwSuv?>5NISJKT!=V5-<(hMxx1(Ig_glWPl+asmk(7)X^E?(Q3!Q2Wt!j>tkdUB^ zNxK%M8O|)L_wx1yRl;_;i-lGB^k0p4o=>g%0fEiKK1Iz2w z?t9Ojd+j{>PF?%=oO_2F+oyW#*y$LU-V=svtrulJEIDG8YrOvsA`k=P99cEB{-MJG zF+NM8LhX4T-5v#OfAV3(%(r4CB^dhOd(L>rKkkUmGGEcDc*VBhx9%C=Zp?l5*7EMw zgBX(gdX%Yw3I$XUxTsv3sTr}*6~o%10YzGMl*?`Srt;1SgQP@BsdPzibLbIz1N~2# zuHcFa3Yb1^hGWTQK)DGYY2uq5Z{MBlls>PTLImFl_NM8S2I;S}b~%_?0FDWZ$`;AN zLx6ULc0y{JW&v;wtVmCvQP9X9#%TztfQMJNf^%1S>g1sS>8wx{w&EPjhhmXBrMMNq zs$APxB%wE8?KEuZYe1h_z{r7#tAg=Fxwd5z0{egsu{Q48#&wOiUZ$%GJ&;Ti+3UL( zp4S{b2gi1$JbDU-s_gp@pWM+MMXBg;rB7X29R@duOII@IfZb zn#Mq;`&DvlR)#?Id5tB%vPjt-plPotsCZFRQ;u?M0Bkw*>Wn}SC$cD|@-K?JXEox5 zY>G5xUGOQTe}&tj1=G3WrHN6%im#*=kx6sZ7DDDz9n>A-zLQByNq-&V z&K(yKQOOjIfIV}`Wp`^?VG~hp{9VLe!gx`98Ta~lIT8R`UKin+ zm5JQ8l;);4ID+x5U|u^Zx{2?5W+q5Hr0W+-(3AY;;+7NM^)bVZmIfBV--1~5h6N}%pWbX`)-Ka^&j zzsfE2riB(j+IF0f+JmpB$t>x5cUXb!)e}+bcCO+PY4L#K9|N$Q)4ZYX+Se*JyA{vt z@10CyPTd=)ph+2Gya=H0m zV)s+Lt!<0KP>8G!qha-sBQ@ zB-`@gNztKpQjoyWA(dr^7w7joj$JP91H1y$eK$l|6_8-p`THwW@4y+)mK?m7`s(g< zD|kv{0~)4z?SOZP|H=`#!hl81pP^uXM+p`3L6sVLTQG1{Kzexi<9V^9Jxt$gd>Q28 zU&o{T59vQU9EJ_m@w~H3k8zY)TEv+Xc4)KP2i_!kG$_4S@-j>zC^^(;Bo;3m&!G!d zSy?$Kh0pakA=Oy#h-1<%P&}7xRCzHaBO`;Fq4&0|aD7BL7UT|&G#N9EoSeLX9#+1F zT=iFHgjSkB!Q%PhX326k9)~T)BMuK8dVc<2y(w%2iM9;};h5P!NiS?iM$$AYl(Eaj z3ac3+=3CjejV0uz5(Z<GIfrKl&RpI*`Fifq>&0OG8C`IFaeoFB+MuC32`@yQ%cLN@{9= z2mvc<>Dk+Ucp&uNY7Rn6U0q#DRu;UmC@n258o=+3alcPAwa4EF_|rRdBJ<7r3Qa)!zpb=Ywu1ucueP#j3#uxTMoY-85m z$f^HVV5F1mYJ0Hi!Vj|e6NeNiN5cxCWcRPM!9Qej0@P`AfA9B$HUO4+o(-V=7snB| zWUF&rJdq$FEG+B~b3iiKOb`nj8wLL*vFPu706_eJ1gX0?V!N&Dd)9ZDOuxQn)X&* zgU9yuC{n8*o`O@8NxflT**8D%`}_jr;Qc+gzvcHue1Oc@!u!@v#wO77Eu(&{*8cC` z{t7q!z#}0Z01zk3l|b>F@bG9Ss|Be?2OXKD zX|r8IOtdU%Y3aXvg$wz{k|0U|%-YFMDV8%szRPvSLGxz1E}x4q8diwZZb$edTI0OG zxHm;<#YD(J`3aNCGryE7oADj_#xmhzpUy=j7n_%@*9mK7KAbKgW5TnR!UrpWS~7t# zFJp7ED`(LJ$X09MNMeBfdo+~Y#fk_r7V{6|Mqm?(F8PylC+EvJW^__M(kk$OF zyYg3t>OU_|2$bJo_vw{Y)BK-L{-aYhjR}@CPqrfNtnw*U5YK*epu;_RZ#$j|LAD0K zlja$7Li?^KNh=dK-Y7-qtY<-d#AWX2D+km-@sh>?PGJEhRpw{~FE8H0alkd&LRwxb z6z127mi4KoDU!RcOEvl;n$nIyl5f5MMY07s&7)_Aou0{d{(_n64Jlf@MYQ(uc=uoF z4e4+MIpY0L&0`VYqUbilgOV0LS;J(ug{ZiB42>)aVFO%wC{JTF*pROhGCnF7OErr4 zY?_|IGqmfA<)BB+oYf7N?D@4i|Hn`7Fo4dxqPkhs5&r-E4jL%LpufWR^FI>zsOwT?{bM`~Z(!lBCIEB=jr?UF!q4cXnO^OUd(eK&>=jeW)c$s*;q^Kmj_&Aw5xV zIzkFW<^aeGl$YqB%Vylf0^gY-;hBSw5qj zBQtoXvWp^CQAtS#%CPN;NnYB1=_P(%Wd}!L&;Qgv{}CQJ*8VFWWZA9ghWBs$&h~&Q zBfdWOKk!CVYB86mZkW(%IcV#trG%8exlV+j)E_Srzh8bJYUlUV4Lg` zkEH@j7*?xd=_Pj^H{f+L1`ZBR&^ku=%j5y!yQqHAx7-mi@z3{5e@G{pG`FPe>{0b0!ZyzDVn)Z=crBxB4Ms4o2rIj}LuXqR}miA}2p)b){P-^u<--2VVjgcL=$Yi*pf z^reSZY@wv%34t0j@qXQZoc}%b<7XJ)#CPp6PI`M(QZWEBZk&6u56(Qn%#;L`YU!8L z!vWt~3S%_jh-!rmCEg1y(;g&LLdJK%<)1<1zaaKcY(Y%KxCzz znpIPxk=ILsu_!T&0Ns^8y6MM0p%wjTX2xtdG7*D`(JVpEV#aJ#5(MDr3b$zsUrbFIXrWV~u&GIAUy|-uy(qR707@p2 zURa8X@<&C<0M$An!wZFDl0gt*>q+S7^v+7{G2z{&fx9;)z`G=pnsAkMx28cFhgPLl zfvw59B|@_o;UI=~L|bldz{sKbyVNZYY9Ob5V-( zX|p&ZzFYW^n9nRj%B!5xjfZ{=-wUM;_h_@Fb{z7FcG3(y1C5X#xZ$NVim;br2O4Z( zO(-z;bS}Ost^SjX{*!rt9X^v(S5)PS-!$MEt1Wo%g?lB{ZQFY#O^oQ(nSKP20d!b% z`ZWNoc3WIXt{$T~P#{bf^Ww{qjxsyzL6Id~?kEbUWDH$0G7FKXY z1x=zT67&w7!{f zi~=G!kuf#Q6h);x^XVQnxr5wB7K~E6p-!K5G_q5->AKT z_t)qzA4`FX5&!dh^m@gE1P=lk-RBPA(l3yU>(nE6DpE;KdW*mxWpS#W{b z1ED?j*1JFjEpeU9+$nFJcFEZw?&N4C)pE?~o#&!-s6-+?N$nm^(?!R8cz8G}J?sA7 zt*pFU*v*Z-qSD5wnZ>^3kVbKQe0th(aAbsxghcpk$BS-W(+0Sfsu&e&kw^1eIi6)? zLOMEBPEy(YG}sn(|E#gfLe{{cU>B0td1d)vi<%9k5iUuiemaUZL>Vwwdie{;;- zF4x=Mwl1q^gcdh8B)DSYguaMoU3DtnUMcwgF!#>Vset_Z&t5^j+Ha_?xx{6_F7yAC zB0sW-e^5SwsUu}4zxTTJy#VF_-v9HQ!Co8s$|~T2_`??|tJ= zm!N727fM=&qZ3g602_=!a$HkiXTed$9SD0SI8N8bDe+v5V!CghSht^3n>oGW`bVGO z{!YO#U_n#`&Qt}v8JdLqzA42mEyas9%?pI@>vp^khPpr9E355nY}Q&{nybxAtM#pQ zHmwfnsYq#poP+hioMFJh--z-uo_~L{#I}$~4+J&1eVTCS89DmqM~S)VhvdPmquRb$ z>g?Ul5sM%db$7U#*G)940GyRk^{&f;K@|&`ajdw{Q2&8ubNN^_qb$R0y#t#rkDj`rf zB_T@U;6OAnh#|S!QJ))Cs7W!N3H-3)K=VEBU!`n+Ce)@~)aH z+0@!Dhc=2e@)y!tYsrj`V|VPOxL(&#d|Ci_%2;m+M_GAJ6vO4Xz}Gd>Kd5fMT02SG z%BwXy6-wF|g9>&t%al1}zKsQxrS~(`+T4!0c&R^ZO_LF>=>DjTpKff09zQh!Q@6ZM z%gLYz%ghz%cr4WG!=2QFQG zC2Tf#N*MBKjP5xOMquqlX4uSFY{0rNDi0gdPaGbYgDQDZk#q(hbOmflqMm; z5;nN4@s@vIL=F;rp6$yH_kYgq@5=>92toYXXR~*r1NUP2MTs^_tYh=|-O9|*NnSfl zj%*y|(F{b*0NrX|c0KL+pk9u$Ho9rd)QMr1sy5mMwHL!J(l5&88M99whj-o(9aPdu z8SD2vMhUz~RFXK)o=@0~o|uv)$BO`r1-|Fgmu)y=G=GcagLXHC?j*870kVv zoUls10-!Pdz*5Q^NsXqs?cf)^I#fvxC=m$eIu4G6AKtz05BALOcPyl91c9C>V_ITs z_`x9RybEcoz}Ww&ss2kP@_^5k(F0lR>BVF+p-+pS3~6SJm`3GlWGSg$xJ2F0f}Cu( z+3fraD{u0WMXAZ{v#srDjf74$ocW8@Jp;_mwV0d{)dl`>h6wlnVgUrvWW%6WC}Ap( z_iCba_7`kE6DO9&;S+tqoP2EQG!zgTtwf7g$IF*psR$gfG)~8yM1KnSJ)K;kw)t2C zUXBR*W@}lUbS_b&9tks|+h1<^x;{TZ`AR)GBCvz2*7okG@1V6y%t0%6HFt(0Uoa$~ z5y>-_-OuLuQsF@u^iOf ze*IgDUFs3bHf1fXpg8VzlKH4mQCkULs@Fbyq5)x6D#=A;D?&+B*H}x0&yAjT>q&jP zi*{ODsjrntV&=`Dn)BT2uATv_N7YZtmr7kzRfPL_Ib5tjMR~s&&};viFt!HoiDP-Y zPqXLD=@O2Pa@dM79yan{RF%VeP{z%nkrR=FvQ@}5x4&5K7p{SJRoB^D8SW~~AwH@g z81<-!+QYGO_-%RGSPP}>IHX+KOcbO|9nFy zU~3mlyM_z8$9!d+ekRehs%N5xDV+>&rEVegvB>BHq@xA!Q+$re{IZ8|D85i@yisiVTVak=%_MD0-c=bWqwx5gc_G z$DV=lyx)FO3iCB8jY_shoM5cMd|FjcwZ}|Xt~M)|_V$-)hGwpfVDsGI0lR#rg0f{IV(huitLhMZg5}9BlKw`qQ}+? z2%T*49T)VJ&DgdyMRET6)fw5<>P`*Tyc}&$6ieZSkMStV8s;#*s`$ z=4N&fvOH7}E~QF#IdDUA4+H`cAC}8I#!~Ix)!2^jleBZOiB4DX?}=aI-0@rI$bG3^ zJE>?b&b7_NMbG>9&E!w-CHlWIh~l?0VAo5|H{#Y5XiM)}=}LPlKs+wp11-mOk-7>b z{^aUENjDs{L_*E$O^j^hoe%lY9+@zJXCZx~pj*ubrj|oB&)9zr+?6%ZpxfK6k+7Z@ z<5(|{fm@{3WmKy(8D?K2GtTl(+*Nni$Ku81SqgWvLS^%6uwhj7YJFb#3W#f=ZK(fz zO@4AqCH+M-aZF!EBwQW#KTIZa$;$b~Zp{gsnvjK>Fe z>LWeWH)^K5w9zFY%5jh;%X+|R;F(OzhNWV5u2%4a!(9_~YtO_3wEU!Z*Tb?V-kRpY+wtS^5o`bDf zUm7WcnNhEH#nzn!MRi*Cofvd^#w_PXh#BY8T zq1UN>{)W>tw*SWOzbQDd1vUcJyX3Ov`=B1iu~Z;!oAX4I0P<6lQ%aGQG`M}tNPMe& zuc2g^kpdBNh-7>}Eo&2~eBvUd5e(*3d@ovZ3|2)9rD4{3iz5#La&=~CZK>pLK9gXG z57hP)yrngGCTUtHBk8chz-574iGyLacu%Ox#1_pk7Nv7yO&1Omgy9A&^tiZ?s^M1b z)6^KVRXG~*p1wGH@NJc~l0#UPT_G(cJL zf0Oe+fe`3=$1PyZWg0PBO+K9Loy8+22h&I`Ld~$ zVl*JPaZqE~XXr)Qd`n|`KeOqXHzA}9E5MPW8td1}@(i@NNs)ZzE8*~C4}w+e>17%6 zRD$WTZXJQ<7xtdHXnFXSXl43a@1QsrFn#kgJ$K&c;rqX){y(J#@NGum=G6;`Ye7aD z;jZK@sF8SDI3f@|X=J0Fn0b*UXQQu->rYZ%PaT9L?Ax!Y-Rmm zTTUt~ghWbk1<#L=%El8a*30pGgFaBJ&&CMjVBfm~qTHd(@6YR;6I3I8C8WVnIQx%- zE(QsL--c#6pw{M!$=jl?kg|dk(uRG~)2nz_26 zBd}I$X~3>ShjDyh?xoX~hulAOArO^VziRccBV>Tckgj%qxw5t&wZq2J+xku>k2s{w zH`Zp|As~$EcfAS~?RCd#W9@`qj$#tz`-Kc);TMlP$WMNa2s1b6(bUqt zcY;yRlLi?a!LuJ@^y+hX?}I`T;!1NW*0PT;p59s=c1u2g4&B9q-E6)aTtdmYpM$`k zDuYFt>-(tvT+#mjp5pHV3B{vhFEE0bfaLEK4{w64xqEUa>qog%*gOeP5={{ZM(PTz zhJF^|$aExKfnV^hhQwlzhsS>$YDrfgLH;REkjWbx?Nb4Ku=!0}@Z-ZAmX z{xf1l_@8I2D-0O9>S=p6Lgk=^+AlVg8>zX0p@V5sQhug><6ZD{!FvidvWWSe92#31 z72`hfa0frYD{DWP4LY_lqH0ttG`J9Q>sc;muST}I6ZwozvAuw!e5I+Dq(Qv4{4n)P zz$Dsp2;V(Hf z2AHoK0u1plqBsaEfw}N)Ds_NMbxCGzo_qPqj;DnhET8n?&X^gSzHuMJB#-ovl7SJA zbpY^#`r*ndsN13>uS3s*ud`DTn=r>5e;VWbtF;Q0fO&B3B`Xab2~u?+o~#G`MGuwT0(X+$CHG5NcDtSaxzB9HLHoBZt?~^n zQFYab?)KgZ@J^k}v!%_j-RNa^CY)LejU74pVEbl4&XD_u0Xwp=U5~~QlG!!C`+5M} zoh_(`Tn=iqdi&_|4;YihH1i$GQ`+mRko-0;H3(AgPH?yHzuFR_TH_7-)6^*fg)f<^ za`Lqz8p~I>dSSM83d?#u?{>cLK`z^tLQgN-&QiFMVd&2;7W9PVthlE`3z(qzc{5=# zo`SbpSMhow$eNa#Hl0kB-e7cP>e?YqS~!(0**7uTPW6h<%aA2PG?Uw_sbQq)iK!xw{Y&vx?~-f;tzp>m*slsH7jUC#kqIvwwrxH?^+A ze6RD&f?m|A5*ET^L`vht@k-Mlj@(b|U$0SOQsF93n7f=A>C zQ$zCIVBKNT7EYxMe^kSdgrK9Cl2h7=11G_C78VSDL8YQR1H*JTs7lWA>py3x*k87b zVcqlOWqJ!?HMa>-0{zXiAS<44KW;Ije3D>0S|k zIvVS|8aF0bVX-Weja>)lt-BH;0Y223wJrsi=E4&NJK|Q6hRJENEYr_D4zF{*>~tnR z_a+$sTHBC3f3DQyrJ~a=3OAVvL~2jp*7krBCmS_(FV90Iqz6Vq+i$_Z4qhk=@-qu8ZczYrnfV)viDam;yA036$=X)T{GHivDTnsO0;in&HX5*; zsKAop$BDfAb`nCO6o(PJQT3NzTVHh&zn`LA6GwrSM7i3Y=!cm#nz&qqpAK*4XEIgO zX`vm?e61dwxoc}O+L#Q;*sLJ33hGorMMB0OkaXUULDCFZp1|3WfrEuJo={#S`nAlY z{Tr#Qz_>+`MeYE7#*q#M1B0-P6YQqUWN*dOv**m6&kPH6tx~T&SWZvLVFHP0mAl2! zWRAuh6X<^qD6SVc^{&$ReR8A`nf`+S><}~3LDI=?Ovn9>S8mgc;fIxu9{X%fy20ti zk#&*XR!H0XAy{UKZ>_LG%}KMpHz6C6zt@w&Jim*e452~Ditt8L-eQLv4c2FhKkLAk zYts_aJ>%QJv5(MNl{@$d|aR(CW&OU4O6*d3Q0*5*B=) z7l@sV=iBR<^*)J0q-N@MX18lIzO|)^gudU24tXD*9^P%&FDap#j=%SbAWiKfhH2)k zHX6Dro2Ti-`Hav$1PTTFzX;Nrp}m(@VqwPPg#QdVsf~!dUe434>N47^=QTN^AFerh zXC4kCG0E(y(TaJMD@hq2gW6~U*^0RjFYaD>eI$zdY&3s-=)Lw_go@@Zi5uF}knDc! zTVFfe9>6w?wo85w=w!Ue5-2qPp_>-~jo}y*fcS~SQ(~fBK|eS4c)3-p?U8(HEyM1o z0<2yfkpeq9c+OTDN32aHVsXvc5z&=?RD+oWJ}GR_m9fAwo-qa(lR#;TA>u|o9&H5R zK|S|_TdRHFCuZK^`*7|+L#4n2Z))Dsr!X8g=JVXGu&?O;+Kfjr6xY{zyT?STB*(6q z&qs^*s#vo9%!V8Sv;co+Z zeY(7^OlOv7eqm)on%dlnY$IaWKJT~QUx>bE)koRii%jp`yuuncdjK1ZnDZ5#y&6Ks zy0V`E7QutwL!>##!-%*c;iWM{=_nq0A0+UKSlA_&L^3}Eig4bUE;(r^4*h*YpU1 zhT0Lx(Yzo`7KW%{V8Y_j(82z_K0VcnRe}IJ0L}>$Ez*@|U9Y^Fbs^klHL3zIE8T8X z<$mfYgUVn>d>Q>%y$lt^loT^L8O(=qpa-!NRhJV9Y=LWI-6!7ugATGEgR$VN2MKpZJfpcqmtb~TfjF2zp zXA$<|+uhCGa11DTJ%=AI=E-6so1N~)m{W%i{PhNM}u$X z6piiYF+AN=lFPats-P88k3PP!MM%7|#6~3U&=LCeX1?4vJ#R#uj&^6iO@VZL0hsu$ zWoN|6!CJxLJB%;exB-tB+JSlhkFK|X%CcMfhw1KaknZkQO6l%Ky1S9?5CuV6x+gmKBff9<8;-=!C*q}kovjQT(5x<`M|;VpK5D%N&Y5JfoTA^K z8Jz>emqHo8C-Ej__EoIdPTANyDRV_WkC>sPy5a z5UzDZ&=$$~(ho8gDFW4qOxZYco@IqaZG1wHzK+utCvTn64x320tk8_PGBdc5`vo7M zj*1(=Ei=hGIFu(W?!FZkbk~E=+r|92%}8Yrq z5>U!%D3d7GP;Nbev2dpKZwK=g6%*v#UM0F*nsu<48wKij;+&64S>=$3XUJ8$Gm{QhX?y*)k`9=AOizMrs z^>F?akyAS@N+!YzLAy7)Hyzs4FzC?p``%2U>YsQ$Gy|EegcjNd4s z`1V(yZZ}yV)kEc`@7Ji@NB z=01#3UUe!O5=O7nFkzvC&7|9vY};baL5Ti4zZdR>@j7mYek&>YU30c02)-oO01VDa z!!OfoU%oUJcZqnsq*Tc`w^l6@Jn1Kf`_9&JfkTpdCr?vVy|J*;R|%ERF~)ktqorKA z_1}7SY>{hW%xKRtbW73|O`LRG$Lubli^t^1rlG#-CRrFWdP}l!(ym#spstoXvxH0W zxg;Z+;nm6nAzu-49BWE^bs(gmFH`;iJ>+bj z0ZlK$EYGOBE2M%geffN_c$z#7%DFJivV4^wI1=bJ43*Bh%?3L<-XxE)qW+G%xMedk zGr@)h?}}wG>9uMGa-F0_{TONF$9>VnI;nyKGZ~0&WkaH%fr3VC+(qd$L8MXGvCSiPjqs9!tJihVXw;=$QV^D;%L20E+UjuG`Owa zwuih6cIM{bEK<$f{d%Wx6{1z~L9x6gT^RE*E^$l}1a0K%;>X6deO3CqoKhSvhfEWr zq(VKJ-b!!8T9w&uZewl^9tSby3A2=&2fTwb#X4}r>#bSxDl}Vmn%;#S{Ya#XH+IJ$ zO&nZA1(wyr@A#L`c?^PmxZ+o!jmzh&sMYlN`At!2)9Q&aueuC!40(RWHG#d~8B-&Y z>UO;Cq2=1u2>7Iee)5yVR(iX{(eiD3t6bcU#L%v_7~z#%H~gzpIe5&+w7FY07HbQU zBmD)eF$d16k!@~remCq#3W>GcM_=;~8qmMdj5`U1_nIif&)ApKE5Ag1D5J3ZiULbl zgDIW?k1I#frkdAhL?@3v#j=bctZ-|%>^MTrk3qtX9}$uzLFXZ*AJM-HWC7$3cn%$QVIuzk6~$2 z2vhK2QsCD49;>Q>L@sCcj9n?t(_{>=^ZaR%6I-dXi&DThWEo|k!5Mex!Nr9xi&|x- z`GI|D3{tWAjp6Yk+HnIaWL4IN>y$gV06z4;tk-5y88;zuZF%ch@Mc z-2x5#b54T>#lA6>UQ zKBU3fq`F-X>eFC536G?VD2ajlsZX3W^Wljq0-<~F?gKY-aqg}b#HCoJlV96Q!J=xG-xkl*qPiB)yg#CS>#Xqkx{%*X z=p)i=aM0|!eq1s-*F*#9rYB@Je(m{-5G!O^mM9;&M+*rKKS>ctIKPzf1@?x=Wqqu= zV#10ek>W9{&V-_J_Ew#o%9@i$h@l=a2P-3z4BlxR$LkDl{35*K*5q&|KhPSD=;C#U z)DxVe#B1Tn z)ei05UMY$Q(>QyoA>JWqQH2ApEGb_mECasrY^VgcsT>JM;+efQy4W7mC^q{v%J!kD zg_?*Z*e$brzgfUq+D!3h4qbfsWiYAW6glVu3oSbccNspFR>_;M=4kddySqmQRbj(p zZ`W6fTcZvL@i45Ekx+bD!0&zebx@|?2v2CU4eAv2OLyc^v6c&#;b9l<84wV0CWyEX zB4-&^zqWMe$SuPW0nVY_omcZksBdQRO&swlKcDQQZLq*`pYO-N&m-{;P$v94{tiGHR@Zp(FgsrZ>Trq36@A5s|GW`5I1RJHkv^iplukXES2VP7MkL=nY+n)UtweRr+eo_ywv0RakMg6FGJ zTV@+V^M0G%nu(w67~6tivgi|$QBjjt5LGsdyhRP^UYUzG%KM>*2iE7zFZlZ$s-HA9mQ@GHSY+qJy+oU5QC1;ZNE zbU2&VGA}CueR~$fd#1uMc4^Z&7$WJ6|Ky~t70?t3{w3( zaBbox*XXk#K8J=baG@ORK$KwRC_KKnNVsOotB0|D38vu9ta3B2Yy*pimy$DWgL6=p z*vXhYIT0!DZq=Xn0Yf)w2AXvtKEVfyiMZB&VFg5}i*EOAU%&m>k;Y3efSQ$VcAdeF z{3J;)HeOC)u`8aLOe0=$QqVs`dAkykC_(;q8*F)cGFoc%tAT3Ydm-y6~ zx^2abW00LoFMkiZ&;C!FP1^~WESsW|Q}u_ZN4MRAyyIV=<>n?FSunltuTPSMQl^VF zz)vLD^?ny>^z}e1`s-&f`o3@g_gu*FpFjj7VXjYKX9~Mwhjz#Wpr3erVdPdykDzij zHn?IyMZy!q3XC;m!(WWvgSXN4x81y|4JXLNWhsCc{gOcPia4}_eRw9jYrFpQ@oA30 zb!x6IrtZ@!j16%s$mfzlMq;#Jtp}zR--XcJZPG^1gHBf@-mpP$`;>~0akee(@oEK=>jMT@y(o;l{YGc* zS7gGg$3K-j+UC}4TQ^~a%IkGry~B5kHmg1u^)u`wS-k3VM7b1bK;hE7L#mql4y8R_ zHVm5`A5SCQ%)I+$0N!B!JS7Dn~QhCI7%ImsMoeA{{}^YJ+xL?*4ojBUAyjE>h*Li zjDr=B-&WQ-8<7P$N2rch$Vg`Xgf!sw<710hB|oX%a`9UcAxp<{i~f35R|2kIF+IDm zuWl963{8(+udKRvOWtwoF}nIH0PqSTU+ss8uS`CE$lpPqw)N>puoZ(OTn@Vxb~Mxi zv*xc1OAyGx6Y*Gnc~DjFN!j+lo(n=xJo&+rtybU{OvhbuBXO@;f$4heiy}tyoq=Qf zRJ+;V2)lYYtHGb$>+&63G1G*Tz{QP$XuhGubtZhBt0Np7`!W?rp~HCj&RG=9vYV!s z*?SV3`0nYg^(#H9HLtMyG;rsQo4349AjqxtMDQ-Z`r}HxkUF}UyVFVCP3_NmM7yst zQJam#S0~@{h^s3M#CuusYCzmnt1Ya)`YpwC63~iYAv=xG&gnXkD{&(D(`9-w5!g(? z$t6EFL*kN>3TLC#iYw~PMoFJ9_DNEBV`zE-lt&;S)QM2_9mS;I0;^p{GHhtUMovyn zUw{8N1XHcmZ00OXeuE~qSu#ycG=3|CQB4fjBNx zf*jR3w~AeH;qUfk&C>^NohgM?wumoz&dNF#TxbBFF#5QdU~%r-mwqMH%tF-VyArqU zM!%VhbHgkOq_~~G#d+Z?EcyGh{4*!z;-Y%zJ=H;{^F8Z$9GxonGZUblsA6-o+@KQ$ z2L}cl8@t84?Fgh5{2nRs1}QW>cFi>B`YVmNad`SSYgn`J^u=UO>op-#ouel^7H=*T zJBfj{n;9-akZ=~;lJkCWP!p)M>Q6KG8~ItxCkB^cGCm_W8*Px}F#T7EQwX=CY$bc>jvYxm*9k3INRa!`3L`ym(nAn6V z#b50WLoJM8`?cMyR~J67g=U7xkkOl4k_Di7EHs@RQpj?6VteMq%~;)14^8d5Udt`m zWd8kz;Rtz?#m3#QjonPTF65Ki;V!6k;a7haL||&$K%Cw{k>)5I#LUHgqkko zE^gziGFNZ)A_haSm#T5YC*RX)usn-e90MBhyHID&n?Hg078VNVAaKC7NaVyXp#G#p z0)lR%IHz}@Pq*alCK#uOz4o(OH98js%G5@wy8egx@q>u&+IyAW0e zaIolz_GlG&d(ZsR$PD%3<|9t>E(s%NAzO&O50;o|px2YxVce}QxQ7HL{EAhRHJ0HQ zJs`L<&KJVOozgzmIn7N7pq#F1-E8cKYVute*$Zq$F&AeOklz_IknQx{OMZ~}z}HGBi{1Dp;V0%E>Dgx7ewHvnhk zgcJ#GA8zdBz_@|0-8ng2h&FMsgD9k-Y3?<7EVz*~5L$v9hqfi@m3G|ltkqwWNMC}M z!d%8LpJ^R0?dyxAsm3gzvbo~Q3UR}yN9~2wH|ON_k?awN5vwkSjbHT`trmA*D|j7+ z+*-CE=RTNK<1GOz$M0s946SEmm22L-NWAwtG>XQi`9d{2+l+FRI~VN>P>lw_4QnhE zKWUaXpFsyX(OK7>VE`EQGgd)2>4~8LMGN%`w;w^%)f6Lt_I$G0ZZ_mhYh6}e6JMz- zeZ4i&J_E;gRi>I2ooo1^X zP~dJCVBZ+bVLgzg$MvaxIspK?=QPsacLw8aWZ_mrcdG9&?FHEVhKgJ}_=|c{j~GGd z@(pB|#JJCtI4KV?nQzoMYJb_Q3R`sQ78myV0}OA$)ipM*@8qRVN%NQrS30IcTIT(S z3;*fR7(s_@09r%^6NR2`hTqD`^(Jvx)>W2@u2KP1_#t7{?Ugp#J>I+XKi!|*Yb>;1 z7DxYY&rB7V4sAY759%PZ#Ep!u8a?^P}#R>!nM$NhRv<$muz@&cKJ~en?6xnT^5cLTYq9>gkTa=CHK3 znf(q4L<2#ZB{mH3WlGO8Xmf@eNMr$r$7bvT?!pFI|6Nn-zovi@l96DAZ8anj8ZA0n z!uE`L9*OA;L+by|&wpcAzT>b?vl+Q@7+FC?p8G6=ja5|`d@lQKJL7o@>gu6QP5gs- z+@<;XA2qJu{niLL&JI8Psx5?fpC3=Xv}ViYNRr@#H?k z&(ml5&oGXZ_$Sr4Ce!>+Lrs;AFWLE=O>fG}Q$WMCIkMQ7*T3m}8TFhRG3rW_C5!&o-~HysAC+**0D8MzNH~lBIJ&=@ChT`ecD(!T7gp*j^%53& z)3b!yUV$N4@CL>QJ(s3l4D0zvAii}wU=B!He88>z0Q5JX!7=CWGz|wc0KMzKtq=Gk zGqIJi(lYz;6V^E36w9%|ookhDwEIsN4+-3S5`rLb7-Tyj+zpiP4^?5B)v6WEC zJT*1Mll_{0A_YWZ`>WC_#~#_uz#p%V+7-wNoNF0$}AU8>0=Z{GDIn% zZ=}b>cgbGaDTc$y2d(ooJnRd*w$iZObC2I}>Nv@PcTe)o&2K0yhJmebo5`0ogDI+_ zZbS9Ja(DauXXF(-pudSwb^z{W5*fnNC}#OTd%gv1om_Ss?$eb?#OKZe6^4U=uvLTW z!EBmD%$<$jg?klTtr!&BC3SrwFWhY?Y$F@*ahlAnTy#Oxmmin? z_^$?ICmm1@2ju;>4)CD9kw_oq%WPE0$^WWkFOMpHQ~J53?noE-$ z$UG2<^v2E|S8~-)D-+tNe9cG1kT*>UiXHPxpQ21bQ6fc|((oWT@0ggyV}b+ZXt5Hk zC2o|S&&kFEI>>gFVc;@q524i7G z@*2+huVooQB;>(^i99=6~^H8tr&xcuCk^>7}y;{Yg5O6 z*^?%wzI>(1KTCrz*rHAb+&r>wmx4E!4p5Nd1PW5$X5KBp`=PR^GcMgaoeD>-jrSh+ zglSt*mrmLAt?&Bfujuo8uPZOG)Rbisfc)@ec5=izT?uzr!ZsYQqr1LK$U9av2Va>* zCT2ivr_xL5R@DHm?gWWQ*UD>N!wZ*bZN`jv@aq~(*Ozr5RJIeFNHpiJrN*b6;3faz5By3_R8LvWncdE(Bc(PnA=`?baUDir6(rJkn%zrZgs+8nxL~R><~#W z?i5LqYCircr)FSXY&RDXyZqkb3)t~#RM%C^P&eXFEBUNzFVZExxUd+^i(B_QeTQoj zejlU$YB}`QN1Smb#I^kmM4`e6EKyPr)ce--hbx!(560nGHH6?IXpr+Eo zu&m#?F*{TB7L}w~HHKeij8b`8y91p#ceO-QXX#cmPS;vEEHfV~L}prE9_^i72IrY41quvjM+~u-83AtomwR|AyJJP_PpA> zoL9l6IEUEOmaI>+AEUWiIDnE06@&H1*dP1^oaiI$vLzi_Kx?{=A;yClYt9Vw6xIJzekqU!fE=XsT-vhZ#Q%8C6tFTv+2Ead9<86MJd(a-9E248 z4u6f%w-P>o0tK9S!&0^Nt-IMxJ<8J3P(8ytiX1^2Ab`gwCM8ZfEA=ivUTG@leAdRqws03Omds2KH4st9xL81sM zHYEKiD)R=KCm*-HL%tJuEiPS)--Qsw)Fv<}!}Yr41aZ8Wr{mr5h6;XgI=<$xUZgGRtSL-}gxBN*LoA>FIBpP}CzQf2>S?4hZ& zzHAF{#9IGA73R#fxQdMiAtVLPF!;q_IKqN_^UF4PH4I_&ML*z_CsvVKzpa;FE;ZU; ztKt$N_M~1dM|{2-?)-V8Fb6b~?=C{GO9UD=wV2D8u~&B1KVDuCr2Om_x;Sh;PJoQ4 zcniVKaS{BVLI7w5do9e?K>RWnUI?*vq*$yW88wsW5N^bi3WA}4n)jqOqwYU}f-Hsp zx^1cKqzUK0_uL?XeaW+|)qSlxs?rHFthyo8F+pvEizHI+ zm9!w*Ygc_14fj#OBr$>*eGYl5m)3%7|K{jKyO^%zb&ZMAtKN&1v3N<5k!n}!weH+E z;!LiQaEKs7d#aQrs_pOR$*p%Ygd;yC6PlNbl8B3b>;43w*zyk;o(DWnLVp7qJ8{6F zrJfX&%e>g;4E>(~l+zKH0^x!q+-h|O6ZLB(v!u~scEv2peP{KXdkfod_3w3VH9scc zberu=-UbVNahN?wOMv!BrWsgXYsfTVJx2Tcj_ph!;&K^p zk8LLanSyg?^rwAHi18AgVSY1udD{f$WzhM^Rf9eAnr2caysf03_cOX(j1RN}moy%l z-!j65gkEgTCMyx2W+=Pk&AzkDq^|{=v5Mvb=#n&)E)WCGQ5^SGu^jvy9{4@05tnDL z{ZHHpgz1*>Kz~cgBeq?J;&fDI#P$5Df?Ma$s^e|p3XNzR0omc#GgsSh7R=OtRyppN25Be58f%fuOay_6Bgx1FA zg~{;z7l;a3nW`TQFGxh$zN>EO>VyX(=ogPtil}hMT39&}UA+xdiA!7YQUtiB4Aipqs`{OlUPmPW_6>hSxO6)HJZ^G5Hn++@%o zRFBE+nhhA?F{VUlrb?EyvfBAc&e2@6zbe#1ZPCN_7yYo?w1Jn4(lgqw_z zG95){P^3RQZ2NRe8Iw{TmBiPpKTe@Fw3khO1Me)i3N#eWuXm~P7(}kbmTjk-TJZKi zS^a(!>Utgbpo;$!|Hb0v+g8C!9w;}D!!`c&MgFGD_cM&!|9~@e{_&+mp}T~>llCk# z6&9~-kSD8W$-pdq>fyGwL;-MyIB+Mx4Zu1MqUJNRPG%2kSDI(rgJmyI$Dk3K`4<@= z6dss8yTPoY5QXFN4yRRIs^v6n_WK!e>-@g6?tjWJ+=^`rPmCuYJ`>OkeW%e!S^4k*3f@%E;g=)pBbBzP zs{Z`n5&k5a++n^rsiwDUyvezw{Qm(xxMh7`%k<8EfB&L3zn{rShHG+3d_8D$Yc|X9 z`FuAf%^-=sat31vX#2h%BzlC@zxo@^{FCHn2&B6=U+pVE=hlfaEfdTEJtZn>B`7mq}D)rS>>X!uJ1Yu5($=&FYmE+ zC2GHJ@P+x>1e!Q1p?BP}zoJJ8g#*34<$SF@-h?yb^eLp< zTGMq3AOAfr#x^%-{WOrmthUkcV+s*5GBPH)_Eu+FPLM}-HC9xhT2$kun;we!SQq4; zC^UDLI~_{{$XVy$U{tWqdhGZ3zf%VxDEPtjkAZI+g0a4xo|p)XqDeUJht9!LD@dySDYazV6yh>)h1YZDd%wItO!7l)h?8}87{1f%Sfdbu8 z!2MiX$SGqB4|l8YW%Om2)ZXumhKz|o(BtFb*%hB#!N+9fm~vc+;+>$mU;j(?b~ewE z$lXo3^IwYF-U>tQbmey<{=kk^(9NlTx~Zqnj*nw2H_y&Nln>X>Npwk5amP(iF{Y&P z-Jc`XE@hm|UNsxU;{T2G{L$4EMZj|Myy&ekUPOgqMw5YHHdUy6eK(5XP3o+K{+Q~f zE3_t`J4vx4TsAYDj#4UeTa~R7jFRef0s4o`c2%uFv+QR`Q-~Rdu28j2* zG7#)yZKqM6%^Ak};NveW?(cpD5j6{DpEsl_B#j-3x?9B5d`9|Pi1q~=Vg%S%DfFra zI7H$%_~s{zkq`b|799T(wpatED;S)SF}#+GnH@{L4obZi_wDqdsLe1G9k`Pr^pPu? zl7gw8DLnD{ z$T9jl&8QFQHO0+eT|dKUK#_1C!mOmbp3R(NvN={twUy zC<}KUun~LcMtg?#MGm~mE8KQlbiQBP{SGX|5BJ)_FRW?bKy3s08N{}(kPlX2PwpP= z-a&Rmei2u3$xd7r$3+$!SJnJ7Q5HJ|vxKE2?C(tke~{WO3_z=S(&4ql{-c<}5^&m* zP?7}7t1Wuq_%hRLRV9q5+32qaQ%)tlJOq1dq{EeG^`IdBL{4rpsNMFxhcYV>2a?RH-L7DCMI z!ejS~a^-5>ciK@a*W7*s#jXV{^wQS8_uQYro*K-_FmBVbclcXHDqlkD*Ti5gBdAWG zg{HK$G|7AdSgmqZ_#T_KEmum12^C}PKEEDx_wHHWoh(XnRZ+pTu(agJQt9qfi>2hN zY0pO#Q50Zjw6U={K0gnvt>wDEzehnq@fGyG#ffq_z~IW7It~2mcIAa(?6N6aq5oMf zjL6Fe;Bl&qm4P`#9)XuQ3=*xMzUn98s=A}mQi(u{=~ zq0V5q8-r9T4Qf_>!T!rZ5XeA4`|pWf7ItA!1PIPaP?|lzSQBy68p>ZRP}c|NQ-?J> z4KNu$P(#ww21U)7Z*;LHi~+cF2?i4I^Q3c$wXDT=5DLBg%PZb-}&he zyTmh!XNIE|kTTQw$2EIi1-G`gZZe4Lgu`(Tdaf!%`T(-|_4 zb6qB<@`Gq1mH&bcM;3yZzFef>`NhQ~^touca+BE25Nh@rc-lRjn~UIz!M21}OdO~T zY8(cX;b(G|D7_}&$VqmkQJLBX?AOu&!*oew+<t(FmJp}-zs>Vyi=6sgYU@oSh zHbi+*KkiNT!}~PzkLK0Z3TBvJLCtIGzx^Qcvp^0EKMj<$%;g^txo?eb(fssqXE55OW7V2~_j!doo*3$nE5~g8Rjv$22%L$10@tZO zW!C3%5o#ZgrIuV~mbFwKd`j5LR|M&Bl3bXcu#6OLEKuHfNl0w$3h|s*`859S&7Pi? z;eMd_35HoEp!wFh zM*sLWdD#7V(^P|N*0x~3BvxNae+N@Mthd- z#j*$(M?kzTx%R5v7{Gm4$2@p-;KnnO04+_>CRSXSmdoO#QHk!uP#WA|w}{n)+Kx-7 z)M(r&sA^godY891*n9q0yL`b2fv~`&SEG{hW$=d2Z8>tjdBf^Qqk3tOP?~bN(ys#S z*OX+xeVP7+VeVc!Kqc`$oSn3dM#3|kowfO1d2^lRuRs8@8|e4o^&awqO1Y zF8z?u%|NCW!L4fWMj-^<@s4ZdI;8{RzeuV;@yGXmIXx!&FFHOw)3IY-@sIauX=@Pz zL7pjJzoDD=b>kCb=WCs|`X@Dc4ptSw>`sg?;)_zXnM2}@`C?Z3DXF^fUg06{ z-+cm=$@Bhbh4ZhcT+sm=Zxm3t40&1l?qEWFH#=C`1hv4DJbm$bwiX1B>4RRreO90; z;JB_Tn=XtOqR-j=g0)ws&u~We&4*JT{uI`KYuYyJv-y0L=nj4X3`SVMjN6EF!H+a% zG2gOnq>!=mZGJ7sdeO^gp5Z))E&J_kFTeAs62?8==U;KQ1RXTf=L1g?xGm}!dg0CU zdQ%86IrZo8&zBI(j>r#6e-UnFIIo!99Hsn$n>pFiOw(`8`en%H*KkV%N)R&oUH|2m z4ROB}XTNgn*Xy>ccL-*h3jgzjCh&v=e5KdR6DfKmAIQqDo#_q;AoeBog~!9uZ2v`< zdG*^F0A&5v0AECaZ*#s~ z*9Qo_sfj_5CaV8 z0VLuV82m3vnqdkT2%h&T)z)-!DPZ>kT6YLk_wcojiQ0=E0Ynmz0(dc!f$_J0@#MdL^vwcf>=Z}e z|1Y(FncN?Y02m@8S43Uop9Sr|zo%ZI26*yc#lOGY`p>IEfL@jz6jiL3@Zf*HhvRRdPo zd!@d|syJdAM@`F57mL`Ryz!MF4!lEb@B3(gv%5FDUJdgiHxS5D2|%UxMh!LpP3sIv zMyX)L5vv?&PRpp*t_ddXZiIq;4i1f)Y-akC+X4Y@2=k+h%~Fv_>D1b4Fm+81fgOGAmp zJNYt}h}60#$?v)L5LhRo>>Lr>tMav&D`Ud^8(_jT!rtaL_|wTm`9@%O-1n@0F(6yf za)7~i7*|+8aB~wi7!7rcyk!1ygpgNrK8`#0gA?F*DruWuGH+07{J+%RNzL!)n8-CP z6=A|gzH||xwWz%@n4oNP_(o?gSx>(O6lJ+a2I__}&0G4P;z_%-w0L44XAzeUy-`M~ zpp-g|F#UcNGk-R+Pg8nZp)M5w@WpfsaF^RFeM79*c0$W|IWiP0Mcn-}-w;g+ne6H!>8 z@F$yHF*9!1bm@-2nQ#^@;e4h4$cJl~Ygefhq{BE`^gA}$mBbG9d4KVVg8q*l8`O&Z zV=QF5CSA~>TOHVt4bj3zmGK`qXx@orvSyf%Rp*+Bm5={QV@uUM$YbLG4iyH0&qZre;`E;I<3 zi2dCC7M1clJtpm7=f{!O<9w8j=s39a+S{8x<6tqvf@{9(=+_a>*d-TyCpYz2yR{Zm z5L;^`tM+J{zYU_>KRgoc=8PLEmbGQ%|6}6#xXliMvFwek64}DSosp=oLmcHtHKkz9 zhb;KExcp=mE|mNRRpbhPTcdPph>7r z$EtTnT5dSy{imwN_0NarPE;;;s>G&e5aH3ot0#T@w%yTlVkp|el+vt~3IB3}+P#W;fUd_Yo5C3GWi z6dwZV0WP-lw3S>7;O0$@_ZIT8lxixIs4f#*B`YIJx8Y40NiY~04>=QIFiUkdB*zi3 zDPbe)j0;LCPUTkCjJEQ&y6#iLUaG%m8G;Pb6U4t%^8$@Aj#}}WHuvJ@gFR{j)!6Yo zd82`Hv{>iwvf7I5`=bF|Z?1*d_+$|jXU`LT8K2Ov$|;o)n$`z0W>bt7Do?OIrmh}6-H{E(Ko>Rs zv&#?v2}%^C4yq>>10SgIDBFGZU>N~4kZO}r{!NvA7d;}{AAjvfE!!-?$o?ZoH2 zD9;itb})f^s<^DJ2EjT5JH``-aMuScEkA>XRU{FPT+wQx1uH0qUk*$!_?0wLOUzMK zOUM;v2s1T&Qs%t7kjZ^k9rrC!i|0iGH(wr>sTd@a_M4Ho-G1fV1BQ)agHWA_2@a= zVW~`1A`v#+4ENBvHAx_3Mn^!Bv#_qX_(RID)ksA00xY(>Jxp+6KZ5-J2*aUf#(4Zx5pW9LKdO0S>(yJntCp#*nR$xl}tR*k^$L#ExTRfNTqzGK2 zC^22n#V6`G*&|+wqcZfiWS(5V$?eRKDx#zc@$iX0is8$-(&?by_?&mLSh|Oku&Edt zf|u6ys&PScL1n6uS>N&p_Hn&oRCf_L2r(;JjttOq zj;EROP`8ubS$q%u`Tfyq#rkzwZJn$+%jr|c_%@zd&+JzpgzGPE!+qAuN482m-q+$f z#=pFIM`K>MB7>sJ55z_EGzGX-kt1WszPD@oENp?gGHhaT0BtJrqF{igmD9jR8ffyo zA<_^IR>%UO&{IhQUz@lHRqOD*<1iKkw+S#amR%_k`vL8B*3&w3!maI^A-b zc_;gqA>~SB{KKmzThMOKW4JtuW#se;0gpw$$K1hQHM=KXQ)SmUJKRu?5 zuHgjLz9%wcztKC=5F5cT)O{_^QTVF`ZQ*Q?vjSc59W{3-5!Fb>Y0-?300AnySkw(_ z6H}oi@)=>vshz8xNSa6D%)L#F#LlM0xs(=4{$hv@$9aMU!qnP>6eSf3g zlhmalh>k{>L-we&orvwPJKew)FZQA^o_-(`b9G~}rzjnPwg_#C2F+@9(5v<-)}F+~ z1KnWW??l1{&X893k5Q6Luhyh4WT@pInVBQZXM6X&P{pbZkeU<(N^Z%xK}m z1f>lWAFYmuXh!>4j)JIeZ_uBh{jQ0AfxMOyD@ex`h$g;p?VusvOW;*J5a|mQvY0_4 zdt+w(0k@2t_pHnVSua_kK2trwnRf5AdNnFJ&tAi%2qS-!*AaX^BE7@0yKoq+Ov?QO zv_F|!?G5{o$E48yD>rb!JDyVpgU75{#!EGa#QEJk>x&;mT+9q2!Do@!Kd$S~ziota zB=g0H3-)~21Oz)h92<8HxH1$m1<^*}SW+~Xlbji{96xl2LHrBP{UvmuYOn>Om*>w^ z?iI$_uHTqjlh4T7Q0z_`>g5v?X8m0Gv@sjS^NRh48kWWPYX8?dx`ednsHk$+oeRm> zraLrTI(Eb%N+k{&tRGwFZ24PIOEL5kA$z&$%v$;^ZIuIwy~7Qi|0`|d>E zI6YbP)%9sVkyN`=*&i>S1aHrbR(2#Z9wq^5Fe_ms=O>+1Ofu}70o~Wq*S{jVpt`T-b z@yz82q?Za5jpXmg&zW*$6EBR=HiTI1*2kC5TM7XWlK~C#2K2j~TyE2+9XHtOtx&UR#wF%&&TeiXdF;Q+5M(-9AeYu$b0d=X~1 z^bTwQ21Bh#Km~?G(P3|kG@D7U?7FG9HBPu@sZ3o6bKv*TkN7s7U&AVJj6`6GN(KGB zznTl{!zA#@tsKTqc7(;cWHV3>+?1}! z#A|^z8VTtZ+luxmMzBwQn{xprR0wkJ5`drzCo%uLYJ-q}_4a%NS40bEh9ay>Y1_G1 zbeLTWRry;<71^GZS)Y(Ul~jbmrSsZDG&<095We82a6Sk&xf4q%_QfgjoOj~=bS6zL z+Qtsj4ovOvbQHQZ@v2i*YVTeb%C5Z4d=%5cBBFG9_i}A5_0&)lgPsBKpfiXeH$S;{HRV?%3xJf(dDJU=s))?sg!adjVC@JgCZ=Z|)}I=$~DGeVL}o-6W_BWIOeQ^<8X%PA{+#&FPNJxUS#h#jF%ePw%=J zqyY<6qN#B#@J|9XjhoJL1GH58-Y2D`7PNvtF&mqWoiyf-zuo)ZbKai&oqy}s-gC}1@Qi0XbB#{GPIb*z zo3Y_&2kP)DeE|t|<0smmmu>AP(CH}OSm&2j76-BwoPN-wWf~nV;_^h}3SFc)pIjn| zqwVstoG{1ZIkn{10jPNObZH?hn2W#minNiH_sICTso2UIUG)QovJWrY%FjxpVABoD zF{IH?@D%oyi~%~--DR_es_)(C=l+Y%!bH)F>l85Qv%F_bZl(1^_dW<*OlWgHO^%J$ zgP1rMVu6>4mQK0Lac!k0Rn1o(#qBd^;a|ghyTGPYV1$$+E&S*lY49yxK)Vz+k+On7 zzJKZp5Lmuqj80Y-hmch;7Wc40FE8+YK;klbGiJ=!sXAg0#%U-QSWG>+lzFB9JdL(4 zDd2i1VV^S!gk;!a@_kJ3l#|}z-OXg}az;ewR2u=pMb(_6_%+uw!Ct_?(HaGAUgnOo z?P&gI7~u)_LqFgon#IICB|ny0ZwL=gQ$nU_(c#jZ@q?EpN824s zVsEkSXZM7A(owjw@d4Kr8i)m)rtF!H zFekMG3XdIY^%?3QzfYzIZUt%bI8EhISSE1N7Z0;gkj)_mA29e#5>7(whAH&3`a==~ z(|f$b*x>nY0w!ZVxHWYT7#oxV{sX^urMHa@^61b|{+p}>6C*xo_{SqxS<$70uqp(+ zYH6!`={MRqJ&;l{c^#tB8?-@on>PQ8;=i;2tzOm&&rE2B33NL9B8w17J{T4_xV`&t z8Lj7^hEg|iJ~pE*oqZx#YlkZES->_;fblV7p*KG$DDC`E%tY77m_(!4W|>!DDdtJm zqV@3I6EY!O5K)=Sk}xtnrQM5V$=(P@8X3U_Oxkx#-c6*z)6 zr{--!qQ30P9%Y30e0qIaQMNiT{`^N#DXBjJGrt0-GHeOr_B>t5d?LlEpNp<$x-ir34=dq3 zP-D;sSusK@+$>I;(HCSb)RumpyfUP!9d%|2#_viniGYx=M5dm^Ri1+8ox-Kvs0nku zAk=y&F-=j4sB}_KJoV{NR5@J_iNA@xJ(BC!SI;YT(^Ic1t8?ZJocJ?|lo^olFBTDE z*;nHqbJ=+Pwo5OqCC4OmY>=tFxPmiQw1Re~P(HLvOTGJJ4=W{hEe~R{P#hSuVx13_++|*zp|+*Cp9C z?I0ZuP5#_)&JA{F2qQAjMfER{8Gc;|Y|-*|CYt;t+}~K_0u4oB_6pbqu4Wt!>K=Bh ze;s`cAPm%v5Vp!aODiwQy*<2lK_@gN^1+Qlc0>H50nr8EAb4$7_GY$GHFOy z)_oZuKVa_9Pw-)H&#ID5qzmJv^$}~5bC?k)a+3bExAcZt z*UIOk?PS^Og~p7!8=}i#gu(Ig4~3juc&8mV37#P_-(KX*?niFj^i<`rU^pttE>x8j zqA9kHc@GRaNBkdiu#l#Vd)7mB&3aq53?1RS4dsv(Ue@DPi-3K2syBjQ&vq16(mF#c z9NPqNSte^r&Pcf3&arI&s#ZuI<1yhG>gi~;^v%Ay8T(d~&HUcBADXru;qMOnL8K@Q zo_?a}K*-&fhn}W{f(m%S63Ei^5!%EeyQU0GAL8`4688+L#3#_K1=iob zq(+PjQfzd(f8@hIn^KrMg6LSeW&kWkneHD-*fb6bM)U5tA*N>-)JvO_T1ty? zNJ^>$aQPk{u-!rs`;wvT=5)KmQz#SEnH;lK+|*Qz#~}h^RhhUx-n(v^rS!hnp9Gks zzBkOC8gD2CZ_Vz619H~Q6_ynF%!oQLc0RkXHEY^z8G{-a z)fwG?>JILMWG>~)uSq}ZlkonCU*lld*Z?6ilTadz#kcanEk|vc-<~D{11Ol(nQ5@# zNoUrYX2MhWq8)HHVQh^TZ=%(P)w3AnoyIYZ^EG4|TJFBHT|Yb6Ac;9a->^9!NPO~@ zcU%lG-6DRgxYUl5%95I zYolTN#T{LeBwXy)P$bA{Y9XP&N#sBCG2IcpoxFr7W`(~@ZH=MZFHW5-(yRxriJ#&h z4=}}~nnO>nI08zN9Z&F$rZ6zS`Kz$x-{&fP^~PGtS#L&VK%>Xd{o!|A z9&#mPO1|?^XtzC_T$Yic#&G9A$_BZ)tjWFoy8q71t+>4jw)86>NXJCej#ruXE}IF`{p;;VSgwDoNtXrGFnob}Zf6)p*fcGS*D!8kXY-EH7i`H$ueA3E-OJ zut{rIfXC|Ca6$NwNEvGgj$2ye0jebxGR;08Ow#~n2icJdD<(Uw@3)>BmVe94ntots zS&1sgl|0x1$Hzi93-|34Z}&6wr-2jND8OknuCi0kaGM52<~C9;kbPGSU4Qhn&n3i3 zzCw+UgVGALY^V}fs&)G?rCguv+1?6 z_(mt-uCmIUz;f_04FvvK+fM9IfBI*vjZ-ddCkhW-i}>rM39(4!48{G(hYFu+iL?KJiHxKk)KIV!mq~DN~e~?*9Vh+D9LN-MHc+zj~ex- z;pAF~5%P7Ccfv5%aQKo__wiZEM7rO}7?w#E_SxD`tOliv_UD!4HZ)|22hj!?^v7H) z&}EHMeA=r9rW$yjAxL|!_U`GG>C`;a?BMoW;>>%5ejF3?`s6%z|C~A820U_^&lfbk zRv==X$QVSzVLndm%PJRvkvj!$Gj1>hkuJGE50i&bPGP^YwYKD=k>J^G8(Dac+g}I} z$?(H?UtoK&vIQs{n@xQ9-URCjYvK~NM898cjyN!7gqOXc>-QCGf)nRqBm4z-zkt02 z1PU%(C6K<}wOli97#FwN7e2X~g_Df~&z<0S{6`a8{^vIw|AlB?JVttZ)?QqSWsN9y ztgYlV#Z>rYh`ybjXVN$5Yxu5g`;R3dJoa-uc&{sQ0^h0aYuzN~rI!44oaOsgT@gx( z#Tij>=p}oPeVfZ zHiCf=viNBjprh&G@J` zeu68o*|U$Vei_oR&t^pTM{x;^j{Z%A`Xd`545o`amJbpDJ4;?elNJoT5-Eae3~e=- zbU~)_g*Zt?lk7|=;A-$h2(b`)kF$nK%}_|PVL17e6g~P{PLVWWG)f`l?i~9@XJm+i z4m2BLbCRRHtT12)_~>xNn~LrX@oFQ1ftd;U8XnSEr1Qw{4b&uG?`o zDwjxa?@uHT%TU24E0tsLe=2=8)xtTH2E`Hc%Rdm0JK+2WKV#Q|oO&waIetdt=Vd*j zCBBvXJqmS68dzD9`XfJpYf^ll;a(vN^Ot6qR1^vg>ANWEPbGisXv~<6wQ!M~dMXt# zQK*&}&@0x|PK?P6K_05yB#T1I&WQmWz_&8~a+UCMh6KhgZx`~kp#W>5advqpDF%g9 zqmiEGOgi)N>U{J=P|a~de`w%K@S^zN*4SSxb0r)|iPfhDhbdwYM-MuepL_5dzsom$ zd(isW73P_+q^Eu~Lt_KY>b-77+%t?W+QGOBt+sj45+uA7N2)Hqb=2890CJ2HcXXGs zR^3KS2>oXU*i7je!^d?g;9;z{-)M9E)sFk0|Ey&3U#q9MjH-9W4_Z(70JEk59yGX9 zbcNH(ywPP%G*`)y$J_bkT3+LvGBHS|qBj#oJ1CY~w{J(WtAnVU)b4&FD%Z>f%e#T( zGK9_a%t7TiTXJhHW3%VzLjR z)U3v8g6d`)R4GWt!ICt(!h2}i+@??V-t{;f`Lt@Lj7<4XR`Q+X()9H;R6Kwe%e)r#&Ho zn1!L+BgLd%UuLfvg(-BmI=E;29Si7S=(K`sCXK)_3yog-c9a;`WQMO3ItfzcK}Vp! z%*%*>d;Eth{MCcC5*EZwddq#+p4}1<_No}84T1JkN*IAQ3d@D_ca+!dyhY)coQh`M z9a65@OHk6$Q}6DYa}`J7xS-hx&T3;r<5=(mcnu@vmbwpHlVSeZ-Tmt?%ESb5qkO7< zk-)c#qsqxZI}C@bp{{gRjC>Ko)}ROMED z?Sr=JFhA%;?k_73wBh1SVfw$`>EA~Kd{B(=kB?6)2kF?qIcZG|ZbsoB2$u>jE#qP+`vUR)|96n((F$nTyosW)kw2fhH7yN6H~ z(myck|Gr#*SrNfd^O^^*%;}2)PSY-$77WDX^Mcg2Z#p$$8^LQ`HUgI%?lGbp}V zqOgiFquus>H~)$e4~$w-;M~Q}SC&imt$}a?L_uO(fkmD~(GoYSZlFoWgMiIuffys8 z)0iLkrK@&{ub~3oHFf(N79^%)RjABvMprDdGpA)sb< zwXO4s8Yd8_g^409Vs~G;JDG%(ZjqqjcM5uGu%zd8dT3zM^C?*g#K#@e&5r`DfaG=K z&4AdbEGzuYZ#yN#1|f>YBj^ZCS>4nDwvb5k~%+Q9ZS99(kChIk7R>aw8Ol~h6L>njBo z^k&+-$Fn1)E82#vq@qvN;63kW^Nl367X4~7iS(;L99!X28U~bQT5z`)uZB~!!#}VZ zX>2?AwX}l3bl8|emBT2TAH6au8cpCX$&qR$C0^+Sy>x5!CoLxKHIWa+cJ_@QAIugF zn%>=PX&7x}IdNJ3C&R6PlM3A&@W8#8h5tA}Ogit+Bi{ZJs78&#_)9jvW&*{N zf8(65s%{eP?aTYs6AnOeeK%4jCp=@Ai;hrGdICZ+Rp=kY5e?awKstn^?$#b?k9c*p z<_Y*d5?5PlG1=zK=?yRouF^TNYu*M9`^6$UGvJx{f!jd&xA{q+bnSqFhV`)Om3u}8 z9GopDszkOi_*OXK>VVrT>h(<>Alkfu8s@mi36`U(pAmQ}dFx~n{3EqlQ-auozg8Vj zmg;i_M~@ibPSA#Dh(K{4zDR8tN=$iE4ts0xnP+5z9Sqx<6cU8AkT#zvbFalh{jK@{ z^9ceLZJGhz!4F$+yemBB*2GnaN(F4sjeIzD(46cU0Qb=rG)6uXT;?U-MMT16TV^`$GN7q~l z6xKl*5j*#1yN*NW4(`gPQ+bCM1SB!g3FA@rXe#bbDP`$I9%G9dCXEkB0`KK?gC)s8?9;0Zk-6iig<2oKK_7VlMxMQ4wx=-c*n zMVd3_JPI|!%TbE892&st*x1JBb(-UM2GOe=*II!}XQ$`5?yQ;P1UP&jkp|d#h~rG? z&?lVZx9+xDhNt}o#*UzIxq`L~wbPX&wEZb31V&CbY!qE}c(4K)-Ky`cXj`B8>XGX8 zET8uSe%zmM15?}2&wj&GwiMpcvVSbnP6BxvUx+~D5P*iDW-PYE8Obj%vqLjpDu*R0 z2{+(3v;&!$(-yhmp6h!Jn?4p}_zWwHstMH{vMBU*$`9R>x;vEOX6GhF@?V<3={b<% zGaPWrB@$1R^@aU~OL^qqF=X44DCJ#yKzj~<4TUww*m18;?m8PnJ5xe!WoG#iuc!aI z6yEhNWdiN(;cN${Q9vsJ`%e@{VMCoA6z|0tu=SyCWmc^mQ3i2;CCwU>5+X zi!l`V+F4@nbJ|`{Xpi=)x4PM{_9=T$mqr;7OAQV zzCvf1&0Qu|kQxanZKFN~J^Tys{5Cba5G0_BOl@5|DX%ypZfoX#M%f+$meRyEvx)($ zCd0a4w5+~OGufl-m^{$;k1FBQuB^lU3LotCvZh*u1Y=&EC5q%Dv2yG!LSZY43nXb> z^F>|K>BqY9WI|QV3@6V_W$MQLDe*i*t8$b7_4ez_T`IQNz2+&+YS>wt1w2Y(EHJq0 zpTT6}cIDTtqLL)8!d+V5A#0vh@tr3gD?n!`y>U5B49L7>P;kdtxNPOszf!Tt%LM@u z#5Lca8xaJxk`(j=_eSF@z{jP%%bVC&7N>Gj))%uMC$pNsIm)^R^`~cz!Pkx}T~WVQ z@lwSB6HXiR;0FilECrm|jr4sW3Q|8^I#nU|Mvt{3N5bab_`pv!ZAIPV04TlxBW-|f zH&y`_!bzxDc2PUaJrJ_}xYCe5MfV2K1d$!*+Ms=gN~brQEgi*I1=OPF>Ep8yLc!PkLi&#C~d{jtxE0J zPX-GK+TT8o?yt`owA9WYa9Kj7ry7XOFwX~zOqa2gB`*lQ1WX@Zy*}?9&m?XlSLBbb z{D{?zY%o9wKH*_%bhQkk+es&V zN#G@LE@o75-G4xIQbc2hHOl zf$@U8z_Rp8G?n}xKuC*}Fgll}S>}d>b35|09Sy%n_4uIQ8QDh#D_M$acVSB9QN>Fl z-k8*=6gV&zFvT8%Aig6U{@|G6VidX6m1oE<=Q}=J9Q+<@M#Vw%QSoXj;v;hFf#331 zHj-%;o}jsYHMUng%H?nE;|{X;sIE}{4iZEN=;zb4_t$PXtHsZ(Kqu=tBNWU@Zwcfc z{u7+HHo%0E9D!xE(zXTN_7@BcX-v#GqEnA(-atN?y`>=F2u0Orlf72E0)U4_-sD`vhk!k7YnP6)cQ+{UR}*%jn`P%?U7)&THI zLFUwK$HZfK#j+pP_U%}4MA`o-0Joj&hY7Pr58622p|i(D{|6B0!IJ@cjE=^UWlS~= zUTGCu(m0xTX>VMg1L<96Sp!jjt=)-*G&muXdh_;iIeM^$CMUEb&@xa^S{YsNcHHW` z!u*(Ws`>kR1es&M-_maY1uH&C;@&{&V(6l8CGOyRB6La?HPBUyN9FAB|C`waL0!@O zhbpO!kLRVCbGaK_W=ao7F~zg6kHst6?N3*_aB@Z&gul(UfM6%f>hdRZ< z??>Lo5{P|m={R;ieB-WC$~wF%XeR!x?Sm&Q{?Jkjp6DZ8r9@QN6mX49pu~W&VUZLg z><lbnO0j57)Mpa($ zC4mkXq5tBcf8W8t(h@f2<&^XrpA;#^%TC$rvZ`k2?X6Slgeew0n zRC4j!WHF#U4to1UEx?yF!axQ>gM<3Xjl|>MPWM|giIhap zd?0Ls8CtCQS|)p(8#rPd&|7PlO>-hq61ZagjXyffrBR(44Yv2kH}r_lZJ zg@1xuRva~QXs;ev7JU=g8t(X#zi;J(Z(+gCm2|6XKIZQh)k;yw-N*4Os!aEEq~KRT z;k0_~0eF1(_a!e%7s-D)IMP~8&`(z|)6nV_#|^$V%5#-elTUI=t>ZzpZ)l(?o0y_8 zo@iMG{iQV2GmS1##km~8TUP)^28$?a1z9D>PoFx{RExB?R{e;pK|b z(g83;-cXST+}Y4D+s+#dpX-EovaqCxDALvp8Sy>fM_xAHUfo`1DD;~&lgNSNTrhl| zM&;SOX@cz$g|X;p==x`%1cE&;_%fXkJ9Qa0e4gpFTix(Q`bFRt$y{lIM$*$Yd9MJd zfcy6s_Je+dGI^rL^Nl8)_j^|#hGQ)6S8u?9?~@~VAW>Pgx|xMN)!VK7yUe-I%=2XC zC$V`nbWgJoN=tgF$Y3j3AZetDYU2C1E&cbQ_8WN6GO4b&BT4Iy^>Ak}Ppr{I;m=A z-_w*CBQK;G-?o;Y0b79&S5X2lu9S3iN#*b#5qF>N7EK-;AFs(ep3fPsZs(@9IDCOE z+S;FNA|K)5w`$&gwb-59eujQeGQ3F8F_iPyN0R4%BmD*miDsa-7ZVk|Gg#w=zOu3c zli_+`Z?J6`zCcEJw1lEJ^42VC#UAm z`8h}j^SFtJm%M#>j6wUm@_KJDT{i;VRiSRe0HqVL;N8JlLwEy_$C0)MK+NWgql}!K zloFcZmf_jXn5ckm4yJ(jJ_R77`}JbfOVrHK(GhUd4PeRS@`g)qgEE@zO|(bqBnPfZB!qv>+pu0r5)+Xha@g zOmhBfJAa3$T1aqXf2mN59Wr_%ew~cdfz3@f?}eR%SWoQ}iR}E#m{wJVsfugZOXWFT zwBnU7O6mbrn^-b^zNT)F3E9Z0&Mt0dfs_vOea4~cvZFWZ=dV9EU)do;Adz9kD&bQs zDLBJ_nbmYfE-o$>l{0A4i_S`?Fi7PWmQoJPBp zm1Za)zDVK)AaAiystI@y(bTt7jk}_oR^}O!HnOSafVdgtOaV-ud)gCd4F&MQI(52H z8WciGa!+V{VXU`a#CL@g_BbpHR*UD@XBMoePgjb!WYMt^Zzy+0b*TmoMRaaqK6}!u zKOY%=-iEAD`d3yoaGx)+NKq%u$!1zomGZlQLszW>*d}0+znH&ocq>j5w)xI9-#s}4 zy!g4K+ad~{=jP@{H^SOK-hC{stW-RqJ+Ii0FO^|&@JJ2o5o^{Ve@s;ktTQk;&JeF>FJEMWUM<|@Uu z6Tz0yPonv3fI#4i_Ihs4-aQxdm1T}|eIZ)nlj{!61K)>+8CY*pVx(I}N#WIzH?lqyCT#l0$0HLNHaIBcvIMm} zaa^o7^DI2J``kk*Z?DM~8;XiudNud1jUN=hFPii=`m$@N93=Fl{{}7xk}E|2a{6oB zAS3Y%xXG257^rOfajL{NPa+^~X--p&R)GuVu&AV(qOn=WRD?)90-0R?b6IC@`z=0* zcaLI6X-?rRD{k)|EX~P@Mp_m`;(Y7V{XkHu{dxQ}yA3i+7xAGIQ^P$N`dhzS*;z^} z^9n-e$cOEi2A_IN26o<}I({^z7Pr*jm%HC%g``_n^RO6T(s}NurkV` z;GOV!OmZU!&^~g#@4-C~Juv1za;_S|rlHXH0``n(DJn~}o6YkMlkK+iSqv*HGgDAr zzJ>HMTyEgvdw4kPymi^<}raxE^uj={HfE`BGeVa37vkY`D(|idzyYg{N%|byaS=)s znTgvmhcC|i*?P+i^D<(^NMsh73FY{B-v$2@nr)YAO`{B z-tv^{1#NtY_45xIxHP2HC8BlX;hFGGPUS*A=Fa6z@EYSKLz9tJ(oww%AC$W+TH7Kc z*ofK4NSX0*(N~j6uoMQp_(~x>gb>#8eHyjGqhG}B?X3eBJjjGUEOpZSs8==NHJMh> z3yVyHsNcJhfA@>PO``v#&tvPsbzQO`wW)ac3=>$zSpT|? z%4=>`ozwBw;XAQBvD=CWFPTh|4b;+}#UarfKXvKzaO~HiB(39-UpVR6L+>{S zR&EWC)E#+*w2&nDwrln6Q2W5|ZB90F5L6$2smP z(=_(~G;n?i_k6&6$*V=Hln4#2_JeX!S}h;qUiulVmR=*7QzsmB^UH5ZvwG|1`vW-| z+aRINoVQ(u_cYXN+8!u1ekfOXg7 zSuwBUi0*H{I5d-dh^^-G3LD{zicAzYX=MyNV#P6a=I5Q9deTesTva}b+n*v!F8WQzGApXvBtqyO^j)$cu z>f6p0mDl^4MdajUJ}U{F9-o&0{_1LKW6NlyVx#PRAF7@7aL!>Tk+NxGrKY+p_cScr zhVMJy=gcg`5R;Sy7>J40bZ+24pBl-|v7K$$5Y77bqn4&7h^3kqslGDaXe6Gyr#*gA zoReR1X=%Y_WuJ@I2cP zTg0Lmq%QYIZC85?11+Saz7T5U{x~F)S^`qDMB^Qod?S`d>t*u<;RpiUu`4(T5pP(^ zr8^chIAfV(0gtcCpcSg2Y4lR~$s_OHO1%N>k-*E=0(ckShPwGW*mk=0z7^%LZK8jU`ffd=+#YXMpA&hhdSf}EjF z4IjxnE!HdXQ{ZGx@%8jxpAE*6KfTNlyw*8c^K@-!mSAQ~fi|&myQ!+O<9lrhb==>m zp({9=xV$dFm&0uq_3bEE+OnnCk>qxr4*fJTsmKP)xxfczri<*(1F8SE zw706s2)im_W@fF~r6nNdW{D+eN%;4Pg_s90C3Js-^jIlyVIXt)XiAEvjb2){e@vCTXVs|C5FJ|B=x z)|PKS&G^I5x0+F6yFY|86cGagk=OghExp8p1vG^1otvzJB|NaU8?d_fYV{oF-GNQ8^6}Tw~D5nG(I?=V>4jvG?*l znI886)+`knuDkNl-7Bx~1BdD1wo?3NpT; zd7wJ~+442Thk^XeJS@O1Cmp+Ggx~~a&iD%NxAqCIy-pkB511$j%<8k`5$UQ{r0q4e zt7wbq^`)N;5-u=+q_i?AA%DhR!6APRVgvt~!X|)g%+Pc)@iPj`Ac4bxwAX!@z)|QF z-=i+pxX5=`Xho;5M~o-gp%*qYPSrvoFS!K#eADJFTT{&o`erVWU2`)bvArLH4&$&9 z41INziwUmMw9OrRxR|KLHq(&fI?YP1?%GQ(eYIbpWR3!%q51*F#bCDZUIA08xQmVQ z$+5xh#`|LvHC0u^uMg`Xot}uf_4Oz#8Y}Td?+!m}O!(@^k#%0vN^%CXJ3SQ?bi>BS z$4&6iH|xA9PEJ1AUG2Dw&BK2KPQKcxIIgF`anfN`O}l%q@f}FhBB(YiFIluQN_f zk!7A38Wtn52B%V;UrVc7tDZ>PS>}rY(-qUcpB9ZA8Lni~V~gjftB^ZRDMa*fogWEOP2Bv)i}rbv3P^n`_T(FQvak zw9}77n^(TYH)cY7Es6v`CkO^)oJ#G{GtZcH0bVbEG5DY(dY^0?>wGouN`2Vwf7l+x z>@G(pNnwGR0ao^^+O2lzK zBtpqk2A!oHQ`TxCp`G*ZD2w?L`mKwZl#Wgg_MDQ!T4T@Ju|*rcZlK;_xPQ zPI3b&v$435w78N@G{#x#6N;8EqAQdtyuYiM)r2VGeD^}N{&h;~-G|4dwT zS}wu%qx(_8Vmf^{qJULrbw?{?<(Bi(>r z$sCoM!a1`Dmq=mvd&cwq#qdwtZYl_Y*=p&Kl597R-V2ehS%XS^ z4I=5VjkEJx`i5XY{omS$AGiU3qzm9BxB<9yL({NpMYEwy7+?>7T~ZKZZQwAWwh|2^ zSu7cM`IWqt&L$|5Xi%;8ltyVSLBn)ZxcKR&dR!s&#%Kw>Lv84%z3-I`S?6jIXLm5&7wCJ!e8O)@3{5*p;jBT9zc06oQdMY7_3hf@K#t-BCSx{P+uRLmG#jc zQ`Mb#)22mQqQc}o?b_aPCSIfhRS6?O~Q4XxjqHz4h4y_-_7WWfP5 zD`$-D2Vc^v&?kdJpKQ5E0LaQ}YP<>B zT_9K=A*n_mIv+M7D019j*)wFZrwm*rg=_UG>9<>0CoEM)Q=VfpQbNMRr9RW5ftD=8 zNqCR~6!Q70X=t_)0fn6?pl0?8OyhkF<%0ny<(4B*rOPdXgnlnCUKTZ|cMX{x#dxx< z?{6fn9{b^}3>u`J7aPw-kMt!mqR#X@KiO7*+TYufGNQf#air;qv5TW9tf+sm*OlRZ z0E!GiK53U-m>-mql9Jn=83ofR4CU+Ve_Dm5UP1}o%hc$A|5#CN8Fc8B4=~K7xWU9p zL#OXN_ydm+S*dFbBdk8REprgq?Ak7B)}vMlo_>V-?yF+dTZTq|V=%wlpEwo69P*L9 zz(9xwsQ>Erexcv^YBl)Kb;*WiwzkS-&g8en%)t@z_*iSoTQCD2(jWH)D>FO0uXV00 z5e6tq5Q}fBC{7?l(XGM6k6GMNR+mUm0KjIYr6u1hovWT|d3bzlTxw`w32!P*jTto5 zx$@fc+5e8@>CK;0FL&f5=~^hA->Pj!=8CL*^4@ukasY~7wBopcXlP~=6@LKsyPc}} z{}uXw`3?;!p_T^hjG{I%T_sEKGFcF##z5i)4KmAq*}QRLpJ`(s-mR1dFn3`N+inT= zvbT+fUqD!3gsRn#Su^h7Ao3G+#xH1CbZrqwZ`bUh@RQjt)D&XL-&?e=)v+))E>@hl z>~Own>bZOe+i6lwsXbMJORpci(7c=Sk<@PkKT>jRD^&kezwsCS!k+3!s|;(P1ns(G z-r%*T{WXsYE`ug3`!aYrQLV(n#qfwZU|U@u8`wZ}WdkuNqS_!hvGSC=qtm!Af8Jq% zsSE;Y!jq;Ab^gd^e@Ppb^+D@vse;Dbh#Z>?i#=dMU|r2csSJW$h0xJ;bW)~VIez~j zsMJUb(%=Q1O?*N}LeIC~;2^J+3+unw;BSynndwJsJ+!H|G1rHIp!5j=!+Hq~D7_K3 zlKqHGj-p|4K3XLfP3HcERFULgv+UpN0tZLHul Oy$>p^AZ9pj;!j{Py$G#;|(~E(kxA*4z#8 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

p-T8NL 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⋙*RVT71t4IRUVC8>q9lu*N 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 KRUv5-{67GG`4rj! literal 0 HcmV?d00001 diff --git a/onboarding/pom.xml b/onboarding/pom.xml index c207fd2e5b..25db1ac9de 100644 --- a/onboarding/pom.xml +++ b/onboarding/pom.xml @@ -105,6 +105,7 @@ 1.18.1 4.12 1.2.3 + 1.18.2 1.10.19 1.9.13 1.5.1 @@ -131,7 +132,7 @@ org.projectlombok lombok - 1.18.2 + ${lombok.version} provided diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/externaltesting-rest/externaltesting-rest-services/pom.xml b/openecomp-be/api/openecomp-sdc-rest-webapp/externaltesting-rest/externaltesting-rest-services/pom.xml new file mode 100644 index 0000000000..9b9dfd0e21 --- /dev/null +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/externaltesting-rest/externaltesting-rest-services/pom.xml @@ -0,0 +1,138 @@ + + + + + 4.0.0 + + externaltesting-rest-services + + org.openecomp.sdc.onboarding + externaltesting-rest + 1.4.0-SNAPSHOT + + + + + org.springframework + spring-core + ${spring.framework.version} + + + org.springframework + spring-context + ${spring.framework.version} + + + org.springframework + spring-context-support + ${spring.framework.version} + + + org.springframework + spring-web + ${spring.framework.version} + + + org.springframework + spring-beans + ${spring.framework.version} + + + + + org.apache.cxf + cxf-rt-frontend-jaxrs + ${cxf.version} + + + org.apache.httpcomponents + httpclient + ${http.client.version} + + + javax.inject + javax.inject + ${javax.inject.version} + provided + + + javax.ws.rs + javax.ws.rs-api + ${ws.rs.version} + + + com.sun.jersey + jersey-core + ${jersey.core.version} + + + javax.ws.rs + jsr311-api + + + + + io.swagger + swagger-annotations + ${swagger.version} + + + com.fasterxml.jackson.core + jackson-annotations + ${jackson.annotations.version} + + + com.fasterxml.jackson.dataformat + jackson-dataformat-xml + ${jackson.dataformat.version} + + + org.codehaus.woodstox + woodstox-core-asl + ${woodstox.version} + + + org.openecomp.sdc + openecomp-sdc-vendor-software-product-manager + ${project.version} + + + com.sun.jersey.contribs + jersey-multipart + ${jersey.multipart.version} + provided + + + junit + junit + test + + + org.mockito + mockito-core + test + + + org.openecomp.sdc + openecomp-sdc-externaltesting-impl + ${project.version} + + + + diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/externaltesting-rest/externaltesting-rest-services/src/main/java/org/openecomp/sdcrests/externaltesting/rest/ExternalTesting.java b/openecomp-be/api/openecomp-sdc-rest-webapp/externaltesting-rest/externaltesting-rest-services/src/main/java/org/openecomp/sdcrests/externaltesting/rest/ExternalTesting.java new file mode 100644 index 0000000000..14c45fbdbe --- /dev/null +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/externaltesting-rest/externaltesting-rest-services/src/main/java/org/openecomp/sdcrests/externaltesting/rest/ExternalTesting.java @@ -0,0 +1,80 @@ +/* + * Copyright © 2019 iconectiv + * + * 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 org.openecomp.sdcrests.externaltesting.rest; + +import io.swagger.annotations.Api; +import org.openecomp.core.externaltesting.api.VtpTestExecutionRequest; +import org.springframework.validation.annotation.Validated; + +import javax.ws.rs.*; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.util.List; + + +@Path("/v1.0/externaltesting") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +@Api(value = "External-Testing") +@Validated + +public interface ExternalTesting { + + @GET + @Path("/config") + Response getConfig(); + + @GET + @Path("/testcasetree") + Response getTestCasesAsTree(); + + @GET + @Path("/endpoints") + Response getEndpoints(); + + @GET + @Path("/endpoints/{endpointId}/scenarios") + Response getScenarios(@PathParam("endpointId") String endpointId); + + @GET + @Path("/endpoints/{endpointId}/scenarios/{scenario}/testsuites") + Response getTestsuites(@PathParam("endpointId") String endpointId, @PathParam("scenario") String scenario); + + @GET + @Path("/endpoints/{endpointId}/scenarios/{scenario}/testcases") + Response getTestcases(@PathParam("endpointId") String endpointId, + @PathParam("scenario") String scenario); + + @GET + @Path("/endpoints/{endpointId}/scenarios/{scenario}/testsuites/{testsuite}/testcases/{testcase}") + Response getTestcase(@PathParam("endpointId") String endpointId, + @PathParam("scenario") String scenario, + @PathParam("testsuite") String testsuite, + @PathParam("testcase") String testcase); + + @POST + @Path("/endpoints/{endpointId}/executions/{executionId}") + Response getExecution(@PathParam("endpointId") String endpointId, + @PathParam("executionId") String executionId); + + + @POST + @Path("/executions") + Response execute(List req, + @QueryParam("requestId") String requestId); + +} diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/externaltesting-rest/externaltesting-rest-services/src/main/java/org/openecomp/sdcrests/externaltesting/rest/services/ExternalTestingImpl.java b/openecomp-be/api/openecomp-sdc-rest-webapp/externaltesting-rest/externaltesting-rest-services/src/main/java/org/openecomp/sdcrests/externaltesting/rest/services/ExternalTestingImpl.java new file mode 100644 index 0000000000..206eb4986b --- /dev/null +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/externaltesting-rest/externaltesting-rest-services/src/main/java/org/openecomp/sdcrests/externaltesting/rest/services/ExternalTestingImpl.java @@ -0,0 +1,164 @@ +/* + * Copyright © 2019 iconectiv + * + * 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 org.openecomp.sdcrests.externaltesting.rest.services; + + +import org.openecomp.core.externaltesting.api.*; +import org.openecomp.core.externaltesting.errors.ExternalTestingException; +import org.openecomp.sdc.logging.api.Logger; +import org.openecomp.sdc.logging.api.LoggerFactory; +import org.openecomp.sdcrests.externaltesting.rest.ExternalTesting; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Service; + +import javax.inject.Named; +import javax.ws.rs.core.Response; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +@SuppressWarnings("unused") +@Named +@Service("externaltesting") +@Scope(value = "prototype") +public class ExternalTestingImpl implements ExternalTesting { + + private ExternalTestingManager testingManager; + + private static final Logger logger = + LoggerFactory.getLogger(ExternalTestingImpl.class); + + public ExternalTestingImpl(@Autowired ExternalTestingManager testingManager) { + this.testingManager = testingManager; + } + + /** + * Return the configuration of the feature to the client. + * @return JSON response content. + */ + @Override + public Response getConfig() { + try { + return Response.ok(testingManager.getConfig()).build(); + } + catch (ExternalTestingException e) { + return convertTestingException(e); + } + } + + /** + * Return the test tree structure created by the testing manager. + * @return JSON response content. + */ + @Override + public Response getTestCasesAsTree() { + try { + return Response.ok(testingManager.getTestCasesAsTree()).build(); + } + catch (ExternalTestingException e) { + return convertTestingException(e); + } + } + + @Override + public Response getEndpoints() { + try { + return Response.ok(testingManager.getEndpoints()).build(); + } + catch (ExternalTestingException e) { + return convertTestingException(e); + } + + } + @Override + public Response getScenarios(String endpoint) { + try { + return Response.ok(testingManager.getScenarios(endpoint)).build(); + } + catch (ExternalTestingException e) { + return convertTestingException(e); + } + + } + + @Override + public Response getTestsuites(String endpoint, String scenario) { + try { + return Response.ok(testingManager.getTestSuites(endpoint, scenario)).build(); + } + catch (ExternalTestingException e) { + return convertTestingException(e); + } + } + + @Override + public Response getTestcases(String endpoint, String scenario) { + try { + return Response.ok(testingManager.getTestCases(endpoint, scenario)).build(); + } + catch (ExternalTestingException e) { + return convertTestingException(e); + } + } + + @Override + public Response getTestcase(String endpoint, String scenario, String testsuite, String testcase) { + try { + return Response.ok(testingManager.getTestCase(endpoint, scenario, testsuite, testcase)).build(); + } + catch (ExternalTestingException e) { + return convertTestingException(e); + } + } + + @Override + public Response execute(List req, String requestId) { + try { + List responses = testingManager.execute(req, requestId); + List statuses = responses.stream().map(r-> Optional.ofNullable(r.getHttpStatus()).orElse(200)).distinct().collect(Collectors.toList()); + if (statuses.size() == 1) { + // 1 status so use it... + return Response.status(statuses.get(0)).entity(responses).build(); + } + else { + return Response.status(207).entity(responses).build(); + } + } + catch (ExternalTestingException e) { + return convertTestingException(e); + } + } + + @Override + public Response getExecution(String endpoint, String executionId) { + try { + return Response.ok(testingManager.getExecution(endpoint, executionId)).build(); + } + catch (ExternalTestingException e) { + return convertTestingException(e); + } + } + + private Response convertTestingException(ExternalTestingException e) { + if (logger.isErrorEnabled()) { + logger.error("testing exception {} {} {}", e.getTitle(), e.getCode(), e.getDetail(), e); + } + TestErrorBody body = new TestErrorBody(e.getTitle(), e.getCode(), e.getDetail()); + return Response.status(e.getCode()).entity(body).build(); + } +} diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/externaltesting-rest/externaltesting-rest-services/src/test/java/org/openecomp/sdcrests/externaltesting/rest/services/ApiTests.java b/openecomp-be/api/openecomp-sdc-rest-webapp/externaltesting-rest/externaltesting-rest-services/src/test/java/org/openecomp/sdcrests/externaltesting/rest/services/ApiTests.java new file mode 100644 index 0000000000..d9da7e9006 --- /dev/null +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/externaltesting-rest/externaltesting-rest-services/src/test/java/org/openecomp/sdcrests/externaltesting/rest/services/ApiTests.java @@ -0,0 +1,197 @@ +/* + * Copyright © 2019 iconectiv + * + * 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 org.openecomp.sdcrests.externaltesting.rest.services; + +import org.junit.Assert; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.openecomp.core.externaltesting.api.*; +import org.openecomp.core.externaltesting.errors.ExternalTestingException; + +import java.util.Arrays; +import java.util.List; + +public class ApiTests { + + private static final String EP = "ep"; + private static final String EXEC = "exec"; + private static final String SC = "sc"; + private static final String TS = "ts"; + private static final String TC = "tc"; + private static final String EXPECTED = "Expected"; + + + @Mock + private ExternalTestingManager testingManager; + + /** + * At the API level, test that the code does not throw + * exceptions but there's not much to test. + */ + @Test + public void testApi() { + MockitoAnnotations.initMocks(this); + + ExternalTestingImpl testing = new ExternalTestingImpl(testingManager); + Assert.assertNotNull(testing.getConfig()); + Assert.assertNotNull(testing.getEndpoints()); + Assert.assertNotNull(testing.getExecution(EP, EXEC)); + Assert.assertNotNull(testing.getScenarios(EP)); + Assert.assertNotNull(testing.getTestcase(EP, SC, TS, TC)); + Assert.assertNotNull(testing.getTestcases(EP, SC)); + Assert.assertNotNull(testing.getTestsuites(EP, SC)); + Assert.assertNotNull(testing.getTestCasesAsTree()); + + List requests = + Arrays.asList(new VtpTestExecutionRequest(), new VtpTestExecutionRequest()); + Assert.assertNotNull(testing.execute(requests, "requestId")); + } + + class ApiTestExternalTestingManager implements ExternalTestingManager { + @Override + public String getConfig() { + throw new ExternalTestingException(EXPECTED, 500, EXPECTED); + } + + @Override + public TestTreeNode getTestCasesAsTree() { + throw new ExternalTestingException(EXPECTED, 500, EXPECTED); + } + + @Override + public List getEndpoints() { + throw new ExternalTestingException(EXPECTED, 500, EXPECTED); + } + + @Override + public List getScenarios(String endpoint) { + throw new ExternalTestingException(EXPECTED, 500, EXPECTED); + } + + @Override + public List getTestSuites(String endpoint, String scenario) { + throw new ExternalTestingException(EXPECTED, 500, EXPECTED); + } + + @Override + public List getTestCases(String endpoint, String scenario) { + throw new ExternalTestingException(EXPECTED, 500, EXPECTED); + } + + @Override + public VtpTestCase getTestCase(String endpoint, String scenario, String testSuite, String testCaseName) { + throw new ExternalTestingException(EXPECTED, 500, EXPECTED); + } + + @Override + public List execute(List requests, String requestId) { + throw new ExternalTestingException(EXPECTED, 500, EXPECTED); + } + + @Override + public VtpTestExecutionResponse getExecution(String endpoint, String executionId) { + throw new ExternalTestingException(EXPECTED, 500, EXPECTED); + } + } + + /** + * Test the exception handler logic for the cases when the + * testing manager throws an exception. + */ + @Test + public void testExceptions() { + MockitoAnnotations.initMocks(this); + + ExternalTestingManager m = new ApiTestExternalTestingManager(); + ExternalTestingImpl testingF = new ExternalTestingImpl(m); + + try { + testingF.getConfig(); + } + catch (Exception ex) { + // expected. + } + + + try { + testingF.getEndpoints(); + } + catch (ExternalTestingException e) { + // expected. + } + + try { + testingF.getExecution(EP, EXEC); + } + catch (ExternalTestingException e) { + // expected. + } + try { + testingF.getScenarios(EP); + } + catch (ExternalTestingException e) { + // expected. + } + + try { + testingF.getTestcase(EP, SC, TS, TC); + } + catch (ExternalTestingException e) { + // expected. + } + + try { + testingF.getTestcases(EP, SC); + } + catch (ExternalTestingException e) { + // expected. + } + + try { + testingF.getTestsuites(EP, SC); + } + catch (ExternalTestingException e) { + // expected. + } + + try { + testingF.getTestCasesAsTree(); + } + catch (ExternalTestingException e) { + // expected. + } + + List requestsF = + Arrays.asList(new VtpTestExecutionRequest(), new VtpTestExecutionRequest()); + + try { + testingF.execute(requestsF, null); + } + catch (ExternalTestingException e) { + // expected. + } + + + try { + testingF.execute(requestsF, null); + } + catch (ExternalTestingException e) { + // expected. + } + } +} diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/externaltesting-rest/externaltesting-rest-services/src/test/resources/logback-test.xml b/openecomp-be/api/openecomp-sdc-rest-webapp/externaltesting-rest/externaltesting-rest-services/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..e0498971dc --- /dev/null +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/externaltesting-rest/externaltesting-rest-services/src/test/resources/logback-test.xml @@ -0,0 +1,30 @@ + + + + + + + + %d{dd-MMM-yyyy HH:mm:ss:SSS} %-5level %logger{36}.%M\(%line\) - %msg%n + + + + + + + + diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/externaltesting-rest/pom.xml b/openecomp-be/api/openecomp-sdc-rest-webapp/externaltesting-rest/pom.xml new file mode 100644 index 0000000000..7a5953b47b --- /dev/null +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/externaltesting-rest/pom.xml @@ -0,0 +1,20 @@ + + + 4.0.0 + org.openecomp.sdc.onboarding + externaltesting-rest + external-testing-rest + pom + + + org.openecomp.sdc + openecomp-sdc-rest-webapp + 1.4.0-SNAPSHOT + + + + /externaltesting-rest-services + + diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/onboarding-rest-war/pom.xml b/openecomp-be/api/openecomp-sdc-rest-webapp/onboarding-rest-war/pom.xml index 18ec957acf..d0dd868a5f 100644 --- a/openecomp-be/api/openecomp-sdc-rest-webapp/onboarding-rest-war/pom.xml +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/onboarding-rest-war/pom.xml @@ -90,6 +90,11 @@ unique-type-rest-services ${project.version} + + org.openecomp.sdc.onboarding + externaltesting-rest-services + ${project.version} + javax.servlet javax.servlet-api diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/onboarding-rest-war/src/main/webapp/WEB-INF/beans-services.xml b/openecomp-be/api/openecomp-sdc-rest-webapp/onboarding-rest-war/src/main/webapp/WEB-INF/beans-services.xml index be8d7c5126..e0e979142a 100644 --- a/openecomp-be/api/openecomp-sdc-rest-webapp/onboarding-rest-war/src/main/webapp/WEB-INF/beans-services.xml +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/onboarding-rest-war/src/main/webapp/WEB-INF/beans-services.xml @@ -43,6 +43,10 @@ + + + + @@ -64,6 +68,7 @@ + diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/pom.xml b/openecomp-be/api/openecomp-sdc-rest-webapp/pom.xml index daa7a2177c..fb93d1d1c9 100644 --- a/openecomp-be/api/openecomp-sdc-rest-webapp/pom.xml +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/pom.xml @@ -29,6 +29,7 @@ notifications-rest togglz-rest unique-type-rest + externaltesting-rest diff --git a/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/pom.xml b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/pom.xml new file mode 100644 index 0000000000..63e9b38625 --- /dev/null +++ b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/pom.xml @@ -0,0 +1,61 @@ + + 4.0.0 + + openecomp-sdc-externaltesting-api + openecomp-sdc-externaltesting-api + + + + org.openecomp.sdc + openecomp-sdc-lib + 1.4.0-SNAPSHOT + ../.. + + + + + org.openecomp.sdc.core + openecomp-facade-core + ${project.version} + + + io.swagger + swagger-annotations + ${swagger.version} + + + org.openecomp.sdc + openecomp-sdc-datatypes-lib + ${project.version} + + + ch.qos.logback + logback-classic + ${logback.version} + + + org.openecomp.sdc + openecomp-sdc-logging-core + ${project.version} + runtime + + + org.openecomp.sdc + openecomp-sdc-logging-api + ${project.version} + + + junit + junit + test + + + org.projectlombok + lombok + ${lombok.version} + provided + + + diff --git a/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/api/ExternalTestingManager.java b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/api/ExternalTestingManager.java new file mode 100644 index 0000000000..dc9b09c767 --- /dev/null +++ b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/api/ExternalTestingManager.java @@ -0,0 +1,87 @@ +/* + * Copyright © 2019 iconectiv + * + * 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 org.openecomp.core.externaltesting.api; + + +import java.util.List; + +public interface ExternalTestingManager { + + /** + * Return the configuration of this feature that we want to + * expose to the client. Treated as a JSON blob for flexibility. + */ + String getConfig(); + + /** + * Build a tree of all test cases for the client including all + * defined endpoints, scenarios, and test suites. + * @return test case tree. + */ + TestTreeNode getTestCasesAsTree(); + + /** + * Get a list of testing endpoints with name and description. + */ + List getEndpoints(); + + /** + * Get a list of scenarios from and endpoint. + */ + List getScenarios(String endpoint); + + /** + * Get a list of test suites given the endpoint and scenario. + */ + List getTestSuites(String endpoint, String scenario); + + /** + * Get a list of test cases. + * @param endpoint endpoint to contact (e.g. VTP) + * @param scenario test scenario to get tests for + * @return list of test cases. + */ + List getTestCases(String endpoint, String scenario); + + /** + * Get the details about a particular test case. + * @param endpoint endpoint to contact (e.g. VTP) + * @param scenario test scenario to get tests for + * @param testSuite suite to get tests for + * @param testCaseName test case name to query. + * @return details about the test case. + */ + VtpTestCase getTestCase(String endpoint, String scenario, String testSuite, String testCaseName); + + /** + * Execute a collection of tests where the manager must distribute + * the tests to the appropriate endpoint and correlate the responses. + * @param requests collection of request items. + * @param requestId optional request ID provided from client. + * @return response from endpoint (don't bother to parse). + */ + List execute(List requests, String requestId); + + /** + * Return a previous results. + * @param endpoint endpoint to query + * @param executionId execution to query. + * @return response from endpoint. + */ + VtpTestExecutionResponse getExecution(String endpoint, String executionId); + +} diff --git a/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/api/TestErrorBody.java b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/api/TestErrorBody.java new file mode 100644 index 0000000000..79a3765596 --- /dev/null +++ b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/api/TestErrorBody.java @@ -0,0 +1,50 @@ +/* + * Copyright © 2019 iconectiv + * + * 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 org.openecomp.core.externaltesting.api; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import lombok.Data; + +import java.io.Serializable; + +/** + * Error body to return to client per IETF RFC 7807. + */ +@SuppressWarnings("unused") +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel("Body for errors such as http 500") +@Data +public class TestErrorBody implements Serializable { + + private static final long serialVersionUID = 3504501412736665763L; + + private String code; + private Integer httpStatus; + private String message; + + TestErrorBody() { + + } + + public TestErrorBody(String code, Integer httpStatus, String message) { + this(); + this.code = code; + this.httpStatus = httpStatus; + this.message = message; + } +} diff --git a/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/api/TestTreeNode.java b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/api/TestTreeNode.java new file mode 100644 index 0000000000..42fa330d33 --- /dev/null +++ b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/api/TestTreeNode.java @@ -0,0 +1,64 @@ +/* + * Copyright © 2019 iconectiv + * + * 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 org.openecomp.core.externaltesting.api; + +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.ArrayList; +import java.util.List; + +/** + * Tree structure of tests. VTP does not provide an organized + * tree of tests. Here we define a tree node with tests and + * child nodes to represent our tree. + */ +@SuppressWarnings("unused") +@JsonInclude(JsonInclude.Include.NON_EMPTY) +@Data() +@EqualsAndHashCode(callSuper=true) +public class TestTreeNode extends VtpNameDescriptionPair { + + @JsonInclude(JsonInclude.Include.NON_EMPTY) + private List tests; + + @JsonInclude(JsonInclude.Include.NON_EMPTY) + private List children; + + public TestTreeNode() { + super(); + } + + public TestTreeNode(String name, String description) { + super(name, description); + } + + public void addTest(VtpTestCase test) { + if (tests == null) { + tests = new ArrayList<>(); + } + tests.add(test); + } + + public void addChild(TestTreeNode child) { + if (children == null) { + children = new ArrayList<>(); + } + children.add(child); + } +} diff --git a/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/api/VtpNameDescriptionPair.java b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/api/VtpNameDescriptionPair.java new file mode 100644 index 0000000000..9a435de4ae --- /dev/null +++ b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/api/VtpNameDescriptionPair.java @@ -0,0 +1,38 @@ +/* + * Copyright © 2019 iconectiv + * + * 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 org.openecomp.core.externaltesting.api; + +import lombok.Data; + +/** + * Scenarios and Test Suites are simple name/description pairs. + */ +@Data +public class VtpNameDescriptionPair { + private String name; + private String description; + + VtpNameDescriptionPair() { + + } + + public VtpNameDescriptionPair(String name, String description) { + this(); + this.name = name; + this.description = description; + } +} diff --git a/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/api/VtpTestCase.java b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/api/VtpTestCase.java new file mode 100644 index 0000000000..ae39159f32 --- /dev/null +++ b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/api/VtpTestCase.java @@ -0,0 +1,42 @@ +/* + * Copyright © 2019 iconectiv + * + * 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 org.openecomp.core.externaltesting.api; + +import lombok.Data; + +import java.util.List; + + +@Data +public class VtpTestCase { + + private String scenario; + private String testCaseName; + private String testSuiteName; + private String description; + private String author; + private List inputs; + private List outputs; + + /** + * Extends VTP test case content with location where test case is defined. + * This value is populated by the SDC-BE for consumption by the front end. + * This allows the front end to tell the back end where to run the test. + */ + private String endpoint; + +} diff --git a/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/api/VtpTestCaseInput.java b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/api/VtpTestCaseInput.java new file mode 100644 index 0000000000..5c6db8eb72 --- /dev/null +++ b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/api/VtpTestCaseInput.java @@ -0,0 +1,42 @@ +/* + * Copyright © 2019 iconectiv + * + * 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 org.openecomp.core.externaltesting.api; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Map; + + +@Data +@EqualsAndHashCode(callSuper=true) +public class VtpTestCaseInput extends VtpNameDescriptionPair { + + private String type; + private String defaultValue; + private boolean isOptional; + private Map metadata; + + /** + * The VTP API has a field called isOptional, not just optional so + * we need to add getter and setter. + */ + @SuppressWarnings({"unused", "WeakerAccess"}) + public boolean getIsOptional() { + return isOptional; + } +} diff --git a/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/api/VtpTestCaseOutput.java b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/api/VtpTestCaseOutput.java new file mode 100644 index 0000000000..b7b66b7b0b --- /dev/null +++ b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/api/VtpTestCaseOutput.java @@ -0,0 +1,31 @@ +/* + * Copyright © 2019 iconectiv + * + * 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 org.openecomp.core.externaltesting.api; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@ApiModel("VtpTestSuite") +@Data +@EqualsAndHashCode(callSuper=true) +class VtpTestCaseOutput extends VtpNameDescriptionPair { + + private String type; +} diff --git a/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/api/VtpTestExecutionRequest.java b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/api/VtpTestExecutionRequest.java new file mode 100644 index 0000000000..481fd46906 --- /dev/null +++ b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/api/VtpTestExecutionRequest.java @@ -0,0 +1,39 @@ +/* + * Copyright © 2019 iconectiv + * + * 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 org.openecomp.core.externaltesting.api; + +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.Data; + +import java.util.Map; + +@Data +public class VtpTestExecutionRequest { + + private String scenario; + private String testSuiteName; + private String testCaseName; + + @JsonInclude(value = JsonInclude.Include.NON_NULL) + private String profile; + + @JsonInclude(value = JsonInclude.Include.NON_NULL) + private Map parameters; + + @JsonInclude(value = JsonInclude.Include.NON_NULL) + private String endpoint; +} diff --git a/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/api/VtpTestExecutionResponse.java b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/api/VtpTestExecutionResponse.java new file mode 100644 index 0000000000..add85210cb --- /dev/null +++ b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/api/VtpTestExecutionResponse.java @@ -0,0 +1,53 @@ +/* + * Copyright © 2019 iconectiv + * + * 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 org.openecomp.core.externaltesting.api; + +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.Data; + +import java.util.Map; + +@Data +public class VtpTestExecutionResponse { + private String scenario; + private String testCaseName; + private String testSuiteName; + private String executionId; + private Map parameters; + private Object results; + private String status; + private String startTime; // don't bother to convert various ISO8601 formats. + private String endTime; // don't bother to convert various ISO8601 formats. + + /** + * In the event on an error, code provided. + */ + @JsonInclude(value= JsonInclude.Include.NON_NULL) + private String code; + + /** + * Error message + */ + @JsonInclude(value= JsonInclude.Include.NON_NULL) + private String message; + + /** + * In the event of an unexpected status. + */ + @JsonInclude(value= JsonInclude.Include.NON_NULL) + private Integer httpStatus; +} diff --git a/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/errors/ExternalTestingException.java b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/errors/ExternalTestingException.java new file mode 100644 index 0000000000..33fa0f4477 --- /dev/null +++ b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/errors/ExternalTestingException.java @@ -0,0 +1,51 @@ +/* + * Copyright © 2019 iconectiv + * + * 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 org.openecomp.core.externaltesting.errors; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.apache.commons.lang3.builder.ToStringBuilder; + +@Data +@EqualsAndHashCode(callSuper=false) +public class ExternalTestingException extends RuntimeException { + + private static final long serialVersionUID = -4357810130868566088L; + + private final String title; + private final int code; + private final String detail; + + public ExternalTestingException(String title, int code, String detail) { + super(title); + this.title = title; + this.code = code; + this.detail = detail; + } + + public ExternalTestingException(String title, int code, String detail, Throwable parent) { + super(title, parent); + this.title = title; + this.code = code; + this.detail = detail; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } +} diff --git a/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/errors/ExternalTestingInitializationException.java b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/errors/ExternalTestingInitializationException.java new file mode 100644 index 0000000000..28f40199ca --- /dev/null +++ b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/errors/ExternalTestingInitializationException.java @@ -0,0 +1,33 @@ +/* + * Copyright © 2019 iconectiv + * + * 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 org.openecomp.core.externaltesting.errors; + +import java.io.IOException; + +@SuppressWarnings("unused") +public class ExternalTestingInitializationException extends IOException { + + private static final long serialVersionUID = -2422448175010311433L; + + public ExternalTestingInitializationException(String message) { + super(message); + } + + public ExternalTestingInitializationException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/factory/ExternalTestingManagerFactory.java b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/factory/ExternalTestingManagerFactory.java new file mode 100644 index 0000000000..e84a4c86a1 --- /dev/null +++ b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/java/org/openecomp/core/externaltesting/factory/ExternalTestingManagerFactory.java @@ -0,0 +1,30 @@ +/* + * Copyright © 2019 iconectiv + * + * 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 org.openecomp.core.externaltesting.factory; + +import org.openecomp.core.factory.api.AbstractComponentFactory; +import org.openecomp.core.factory.api.AbstractFactory; +import org.openecomp.core.externaltesting.api.ExternalTestingManager; + + +@SuppressWarnings("unused") +public abstract class ExternalTestingManagerFactory extends AbstractComponentFactory { + + public static ExternalTestingManagerFactory getInstance() { + return AbstractFactory.getInstance(ExternalTestingManagerFactory.class); + } +} diff --git a/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/resources/factoryConfiguration.json b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/resources/factoryConfiguration.json new file mode 100644 index 0000000000..10449038bf --- /dev/null +++ b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/main/resources/factoryConfiguration.json @@ -0,0 +1,3 @@ +{ + "org.openecomp.core.externaltesting.factory.ExternalTestingManagerFactory":"org.openecomp.sdc.externaltesting.impl.ExternalTestingManagerFactoryImpl" +} diff --git a/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/test/data/executionrequest.json b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/test/data/executionrequest.json new file mode 100644 index 0000000000..05750b4aed --- /dev/null +++ b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/test/data/executionrequest.json @@ -0,0 +1,12 @@ +{ + "scenario": "compliance", + "testCaseName": "sriov", + "testSuiteName": "compliancetests", + "profile": "compliance", + "parameters": { + "vspId": "VSP-ID", + "vspVersion": "VSP-VER", + "allowSriov": "true" + }, + "endpoint": "repository" +} diff --git a/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/test/data/priorexecution.json b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/test/data/priorexecution.json new file mode 100644 index 0000000000..f8e1db85df --- /dev/null +++ b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/test/data/priorexecution.json @@ -0,0 +1,20 @@ +{ + "scenario": "compliance", + "testCaseName": "computeflavors", + "testSuiteName": "compliancetests", + "executionId": "3053ed10-84e6-4f21-aa62-4ca66242d8d8", + "parameters": { + "vspId": "VSP-ID", + "vspVersion": "VSP-VER", + "allowSriov": "true", + "csp": "ZZFT", + "profilespec": "gsmafnw14", + "vnftype": "B" + }, + "results": { + "hello": "world" + }, + "status": "COMPLETED", + "startTime": 1550780567585, + "endTime": 1550780567585 +} diff --git a/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/test/data/testcase.json b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/test/data/testcase.json new file mode 100644 index 0000000000..9a6a166b51 --- /dev/null +++ b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/test/data/testcase.json @@ -0,0 +1,58 @@ +{ + "scenario": "compliance", + "testCaseName": "sriov", + "testSuiteName": "compliancetests", + "description": "SR-IOV Test", + "author": "Jim", + "endpoint": "vtp", + "outputs": [ + { + "name": "something", + "description": "is produced", + "type": "integer" + } + ], + "inputs": [ + { + "name": "vspId", + "description": "VSP ID", + "type": "text", + "defaultValue": "", + "metadata": { + "isDisabled": true, + "maxLength": "36", + "minLength": "1" + } + }, + { + "name": "vspVersion", + "description": "VSP Version", + "type": "text", + "defaultValue": "", + "metadata": { + "isDisabled": true, + "maxLength": "36", + "minLength": "1" + } + }, + { + "name": "allowSriov", + "description": "Allow SRIOV?", + "type": "select", + "defaultValue": "false", + "metadata": { + "isDisabled": true, + "choices": [ + { + "key": "true", + "label": "Yes" + }, + { + "key": "false", + "label": "No" + } + ] + } + } + ] +} \ No newline at end of file diff --git a/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/test/data/testtree.json b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/test/data/testtree.json new file mode 100644 index 0000000000..06b021077f --- /dev/null +++ b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/test/data/testtree.json @@ -0,0 +1,119 @@ +{ + "name": "root", + "description": "root", + "tests": [], + "children": [ + { + "name": "certification", + "description": "Available Certification Queries", + "children": [ + { + "name": "certificationtests", + "description": "Certification Tests", + "tests": [ + { + "scenario": "certification", + "testCaseName": "certquery", + "testSuiteName": "certificationtests", + "description": "VSP Certifications", + "author": "jguistwite@iconectiv.com", + "inputs": [ + { + "name": "vspId", + "description": "VSP ID", + "type": "text", + "defaultValue": "", + "isOptional": false, + "metadata": { + "maxLength": 36.0, + "minLength": 1.0, + "disabled": true + } + }, + { + "name": "vspVersion", + "description": "Previous VSP Version", + "type": "text", + "defaultValue": "", + "isOptional": false, + "metadata": { + "maxLength": 36.0, + "minLength": 1.0, + "disabled": true + } + } + ], + "endpoint": "opnfv" + } + ], + "children": [] + } + ] + }, + { + "name": "compliance", + "description": "Available Compliance Tests", + "tests": [], + "children": [ + { + "name": "compliancetests", + "description": "Compliance Tests", + "tests": [ + { + "scenario": "compliance", + "testCaseName": "sriov", + "testSuiteName": "compliancetests", + "description": "SR-IOV Test", + "author": "Jim", + "inputs": [ + { + "name": "vspId", + "description": "VSP ID", + "type": "text", + "isOptional": false, + "metadata": { + "isDisabled": true, + "maxLength": "36", + "minLength": "1" + } + }, + { + "name": "vspVersion", + "description": "VSP Version", + "type": "text", + "isOptional": false, + "metadata": { + "isDisabled": true, + "maxLength": "36", + "minLength": "1" + } + }, + { + "name": "allowSriov", + "description": "Allow SRIOV?", + "type": "select", + "defaultValue": "false", + "isOptional": false, + "metadata": { + "isDisabled": true, + "choices": [ + { + "key": "true", + "label": "Yes" + }, + { + "key": "false", + "label": "No" + } + ] + } + } + ], + "endpoint": "vtp" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/test/java/org/openecomp/core/externaltesting/api/ErrorBodyTests.java b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/test/java/org/openecomp/core/externaltesting/api/ErrorBodyTests.java new file mode 100644 index 0000000000..216ff3599f --- /dev/null +++ b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/test/java/org/openecomp/core/externaltesting/api/ErrorBodyTests.java @@ -0,0 +1,42 @@ +/* + * Copyright © 2019 iconectiv + * + * 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 org.openecomp.core.externaltesting.api; + +import org.junit.Assert; +import org.junit.Test; + +public class ErrorBodyTests { + + @Test + public void testErrorBody() { + TestErrorBody b = new TestErrorBody(); + b.setHttpStatus(404); + b.setMessage("message"); + b.setCode("code"); + + Assert.assertEquals("code match", new Integer(404), b.getHttpStatus()); + Assert.assertEquals("code message", "message", b.getMessage()); + Assert.assertEquals("code code", "code", b.getCode()); + + TestErrorBody b2 = new TestErrorBody("code", 404, "message"); + + Assert.assertEquals("code match", new Integer(404), b2.getHttpStatus()); + Assert.assertEquals("code message", "message", b2.getMessage()); + Assert.assertEquals("code code", "code", b2.getCode()); + + } +} diff --git a/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/test/java/org/openecomp/core/externaltesting/api/ExecutionRequestTests.java b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/test/java/org/openecomp/core/externaltesting/api/ExecutionRequestTests.java new file mode 100644 index 0000000000..b10d3079d2 --- /dev/null +++ b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/test/java/org/openecomp/core/externaltesting/api/ExecutionRequestTests.java @@ -0,0 +1,110 @@ +/* + * Copyright © 2019 iconectiv + * + * 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 org.openecomp.core.externaltesting.api; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.Assert; +import org.junit.Test; + +import java.io.File; +import java.io.IOException; +import java.util.Map; +import java.util.UUID; + +public class ExecutionRequestTests { + + @Test + public void testTestCase() throws Exception { + ObjectMapper mapper = new ObjectMapper(); + VtpTestCase req = mapper.readValue(new File("src/test/data/testcase.json"), VtpTestCase.class); + + Assert.assertEquals("Scenario must match", "compliance", req.getScenario()); + Assert.assertEquals("Suite name must match", "compliancetests", req.getTestSuiteName()); + Assert.assertEquals("Test case name must match", "sriov", req.getTestCaseName()); + Assert.assertEquals("Description must match", "SR-IOV Test", req.getDescription()); + Assert.assertEquals("Author must match", "Jim", req.getAuthor()); + Assert.assertEquals("Endpoint must match", "vtp", req.getEndpoint()); + Assert.assertEquals("Test must contain two inputs", 3, req.getInputs().size()); + Assert.assertEquals("Test must contain one outputs", 1, req.getOutputs().size()); + + VtpTestCaseInput input1 = req.getInputs().get(0); + Assert.assertEquals("Name match", "vspId", input1.getName()); + Assert.assertEquals("Description match", "VSP ID", input1.getDescription()); + Assert.assertEquals("Input type match", "text", input1.getType()); + Assert.assertEquals("Input default match", "", input1.getDefaultValue()); + Assert.assertFalse("Input optional match", input1.getIsOptional()); + + VtpTestCaseOutput output1 = req.getOutputs().get(0); + Assert.assertEquals("Name match", "something", output1.getName()); + Assert.assertEquals("Description match", "is produced", output1.getDescription()); + Assert.assertEquals("Output type match", "integer", output1.getType()); + + + Map meta = input1.getMetadata(); + Assert.assertEquals("Metadata count", 3, meta.size()); + + VtpTestCase req2 = mapper.readValue(new File("src/test/data/testcase.json"), VtpTestCase.class); + + Assert.assertEquals("test equality", req, req2); + + } + + @Test + public void testExecutionRequest() throws IOException { + ObjectMapper mapper = new ObjectMapper(); + VtpTestExecutionRequest req = mapper.readValue(new File("src/test/data/executionrequest.json"), VtpTestExecutionRequest.class); + Assert.assertEquals("compliance", req.getScenario()); + Assert.assertEquals("compliance", req.getProfile()); + Assert.assertEquals("sriov", req.getTestCaseName()); + Assert.assertEquals("compliancetests", req.getTestSuiteName()); + Assert.assertEquals("repository", req.getEndpoint()); + + Assert.assertEquals(3, req.getParameters().size()); + } + + @Test + public void testExecutionResponse() throws IOException { + ObjectMapper mapper = new ObjectMapper(); + VtpTestExecutionResponse rsp = mapper.readValue(new File("src/test/data/priorexecution.json"), VtpTestExecutionResponse.class); + Assert.assertEquals("compliance", rsp.getScenario()); + Assert.assertEquals("computeflavors", rsp.getTestCaseName()); + Assert.assertEquals("compliancetests", rsp.getTestSuiteName()); + Assert.assertTrue(UUID.fromString(rsp.getExecutionId()).getLeastSignificantBits() != 0); + Assert.assertEquals("parameters", 6, rsp.getParameters().size()); + Assert.assertNotNull(rsp.getResults()); + Assert.assertEquals("COMPLETED", rsp.getStatus()); + Assert.assertNotNull(rsp.getStartTime()); + Assert.assertNotNull(rsp.getEndTime()); + } + + @Test + public void testTree() throws IOException { + ObjectMapper mapper = new ObjectMapper(); + TestTreeNode tree = mapper.readValue(new File("src/test/data/testtree.json"), TestTreeNode.class); + + Assert.assertEquals(2, tree.getChildren().size()); + Assert.assertEquals(0, tree.getTests().size()); + + TestTreeNode manual = new TestTreeNode("root", "Root"); + + manual.addChild(new TestTreeNode("child", "child")); + manual.addTest(new VtpTestCase()); + Assert.assertEquals(1, manual.getChildren().size()); + Assert.assertEquals(1, manual.getTests().size()); + + } +} diff --git a/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/test/java/org/openecomp/core/externaltesting/api/ExternalTestingApiTests.java b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/test/java/org/openecomp/core/externaltesting/api/ExternalTestingApiTests.java new file mode 100644 index 0000000000..62b129c7c0 --- /dev/null +++ b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-api/src/test/java/org/openecomp/core/externaltesting/api/ExternalTestingApiTests.java @@ -0,0 +1,30 @@ +/* + * Copyright © 2019 iconectiv + * + * 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 org.openecomp.core.externaltesting.api; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +@RunWith(Suite.class) +@Suite.SuiteClasses({ + ExecutionRequestTests.class, + ErrorBodyTests.class +}) +public class ExternalTestingApiTests { + // nothing to do - just a placeholder. + +} diff --git a/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/pom.xml b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/pom.xml new file mode 100644 index 0000000000..7411cf5cc1 --- /dev/null +++ b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/pom.xml @@ -0,0 +1,114 @@ + + + + 4.0.0 + + openecomp-sdc-externaltesting-impl + openecomp-sdc-externaltesting-impl + + + + org.openecomp.sdc + openecomp-sdc-lib + 1.4.0-SNAPSHOT + ../.. + + + + + ch.qos.logback + logback-classic + ${logback.version} + + + org.openecomp.sdc + openecomp-sdc-logging-core + ${project.version} + runtime + + + org.openecomp.sdc + openecomp-sdc-logging-api + ${project.version} + + + junit + junit + test + + + org.openecomp.sdc.core + openecomp-utilities-lib + ${project.version} + + + org.openecomp.sdc + openecomp-sdc-externaltesting-api + ${project.version} + + + org.openecomp.sdc.core + openecomp-common-lib + ${project.version} + + + org.mockito + mockito-core + test + + + org.openecomp.sdc.core + openecomp-heat-lib + ${project.version} + + + commons-io + commons-io + ${commons.io.version} + + + org.springframework + spring-web + ${spring.framework.version} + + + org.openecomp.sdc + openecomp-sdc-vendor-software-product-manager + ${project.version} + + + org.projectlombok + lombok + ${lombok.version} + + + org.codehaus.groovy + groovy-all-minimal + ${groovy.minimal.version} + test + + + org.projectlombok + lombok + ${lombok.version} + provided + + + + diff --git a/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/main/java/org/openecomp/core/externaltesting/impl/ClientConfiguration.java b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/main/java/org/openecomp/core/externaltesting/impl/ClientConfiguration.java new file mode 100644 index 0000000000..2787e7e97f --- /dev/null +++ b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/main/java/org/openecomp/core/externaltesting/impl/ClientConfiguration.java @@ -0,0 +1,29 @@ +/* + * Copyright © 2019 iconectiv + * + * 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 org.openecomp.core.externaltesting.impl; + +import lombok.Data; + +@Data +public class ClientConfiguration { + /** + * Enable/disable state for the feature. Client can use this + * to show/hide menu items. + */ + private boolean enabled; + +} diff --git a/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/main/java/org/openecomp/core/externaltesting/impl/CsarMetadataVariableResolver.java b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/main/java/org/openecomp/core/externaltesting/impl/CsarMetadataVariableResolver.java new file mode 100644 index 0000000000..191fff0c6c --- /dev/null +++ b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/main/java/org/openecomp/core/externaltesting/impl/CsarMetadataVariableResolver.java @@ -0,0 +1,210 @@ +/* + * Copyright © 2019 iconectiv + * + * 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 org.openecomp.core.externaltesting.impl; + +import lombok.EqualsAndHashCode; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.tuple.Pair; +import org.openecomp.core.externaltesting.api.VtpTestExecutionRequest; +import org.openecomp.core.externaltesting.errors.ExternalTestingException; +import org.openecomp.sdc.vendorsoftwareproduct.OrchestrationTemplateCandidateManager; +import org.openecomp.sdc.vendorsoftwareproduct.OrchestrationTemplateCandidateManagerFactory; +import org.openecomp.sdc.vendorsoftwareproduct.VendorSoftwareProductManager; +import org.openecomp.sdc.vendorsoftwareproduct.VspManagerFactory; +import org.openecomp.sdc.versioning.VersioningManager; +import org.openecomp.sdc.versioning.VersioningManagerFactory; +import org.openecomp.sdc.versioning.dao.types.Version; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.io.ByteArrayResource; +import org.springframework.util.MultiValueMap; + +import javax.annotation.PostConstruct; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +/** + * The CSAR Metadata variable resolver is responsible for processing of + * variables in the test request. It looks for variables with the "csar:" prefix + * and extracts the contents of the uploaded CSAR file for a VSP. + */ +public class CsarMetadataVariableResolver implements VariableResolver { + + private Logger logger = LoggerFactory.getLogger(CsarMetadataVariableResolver.class); + + static final String VSP_ID = "vspId"; + static final String VSP_VERSION = "vspVersion"; + static final String CSAR_PREFIX = "csar:"; + + private VersioningManager versioningManager; + private VendorSoftwareProductManager vendorSoftwareProductManager; + private OrchestrationTemplateCandidateManager candidateManager; + + CsarMetadataVariableResolver(VersioningManager versioningManager, + VendorSoftwareProductManager vendorSoftwareProductManager, + OrchestrationTemplateCandidateManager candidateManager) { + this(); + this.versioningManager = versioningManager; + this.vendorSoftwareProductManager = vendorSoftwareProductManager; + this.candidateManager = candidateManager; + } + + CsarMetadataVariableResolver() { + + } + + @PostConstruct + public void init() { + if (versioningManager == null) { + versioningManager = VersioningManagerFactory.getInstance().createInterface(); + } + if (vendorSoftwareProductManager == null) { + vendorSoftwareProductManager = + VspManagerFactory.getInstance().createInterface(); + } + if (candidateManager == null) { + candidateManager = + OrchestrationTemplateCandidateManagerFactory.getInstance().createInterface(); + } + } + + @Override + public boolean resolvesVariablesForRequest(VtpTestExecutionRequest requestItem) { + Map params = requestItem.getParameters(); + + // no params, quickly return. + if (params == null) { + return false; + } + + // no match, quickly return + if (!params.containsKey(VSP_ID) || !params.containsKey(VSP_VERSION)) { + return false; + } + + return (params.keySet().stream().anyMatch(s -> StringUtils.startsWith(s, CSAR_PREFIX))); + } + + @Override + public void resolve(VtpTestExecutionRequest requestItem, MultiValueMap body) { + logger.debug("run {} variable resolver...", this.getClass().getSimpleName()); + Map params = requestItem.getParameters(); + String vspId = params.get(VSP_ID); + String version = params.get(VSP_VERSION); + + try { + extractMetadata(requestItem, body, vspId, version); + } + catch (IOException ex) { + logger.error("metadata extraction failed", ex); + } + } + + /** + * Extract the metadata from the VSP CSAR file. + * @param requestItem item to add metadata to for processing + * @param vspId VSP identifier + * @param version VSP version + */ + @SuppressWarnings("WeakerAccess") + protected void extractMetadata(VtpTestExecutionRequest requestItem, MultiValueMap body, String vspId, String version) throws IOException { + + Version ver = new Version(version); + logger.debug("attempt to retrieve archive for VSP {} version {}", vspId, ver.getId()); + + Optional> ozip = candidateManager.get(vspId, new Version(version)); + if (!ozip.isPresent()) { + ozip = vendorSoftwareProductManager.get(vspId, ver); + } + + if (!ozip.isPresent()) { + List versions = versioningManager.list(vspId); + String knownVersions = versions + .stream() + .map(v -> String.format("%d.%d: %s (%s)", v.getMajor(), v.getMinor(), v.getStatus(), v.getId())) + .collect(Collectors.joining("\n")); + + String detail = String.format("Unable to find archive for VSP ID %s and Version %s. Known versions are:\n%s", + vspId, version, knownVersions); + + throw new ExternalTestingException("Archive Processing Failed", 500, detail); + } + + // safe here to do get. + Pair zip = ozip.get(); + processArchive(requestItem, body, zip.getRight()); + } + + @EqualsAndHashCode(callSuper = false) + private class NamedByteArrayResource extends ByteArrayResource { + private String filename; + private NamedByteArrayResource(byte[] bytes, String filename) { + super(bytes, filename); + this.filename = filename; + } + @Override + public String getFilename() { + return this.filename; + } + + } + + @SuppressWarnings("WeakerAccess") + protected void processArchive(VtpTestExecutionRequest requestItem, MultiValueMap body, byte[] zip) { + try { + ZipInputStream zipStream = new ZipInputStream(new ByteArrayInputStream(zip)); + ZipEntry entry; + while ((entry = zipStream.getNextEntry()) != null) { + String entryName = entry.getName(); + logger.debug("csar contains entry {}", entryName); + Map params = requestItem.getParameters(); + params.forEach((key,val) -> { + if (key.startsWith(CSAR_PREFIX)) { + addToBody(requestItem, body, zipStream, entryName, key); + } + }); + } + } catch (IOException ex) { + logger.error("IO Exception parsing zip", ex); + } + } + + private void addToBody(VtpTestExecutionRequest requestItem, MultiValueMap body, ZipInputStream zipStream, String entryName, String key) { + String filename = key.substring(CSAR_PREFIX.length()); + logger.debug("match {} with {}", entryName, filename); + if (StringUtils.equals(entryName, filename)) { + try { + NamedByteArrayResource res = new NamedByteArrayResource(IOUtils.toByteArray(zipStream), filename); + body.add("file", res); + + // we've added the file to the body. need to replace the value in the request for this + // parameter to match the VTP requirement that it start with a file URL protocol handler. + requestItem.getParameters().put(key, "file://" + entryName); + + } catch (IOException ex) { + logger.error("failed to read zip entry content for {}", entryName, ex); + } + } + } +} diff --git a/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/main/java/org/openecomp/core/externaltesting/impl/ExternalTestingManagerImpl.java b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/main/java/org/openecomp/core/externaltesting/impl/ExternalTestingManagerImpl.java new file mode 100644 index 0000000000..38fb11c6ae --- /dev/null +++ b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/main/java/org/openecomp/core/externaltesting/impl/ExternalTestingManagerImpl.java @@ -0,0 +1,610 @@ +/* + * Copyright © 2019 iconectiv + * + * 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 org.openecomp.core.externaltesting.impl; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.StringUtils; +import org.onap.sdc.tosca.services.YamlUtil; +import org.openecomp.core.externaltesting.api.*; +import org.openecomp.core.externaltesting.errors.ExternalTestingException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.*; +import org.springframework.http.client.SimpleClientHttpRequestFactory; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.HttpStatusCodeException; +import org.springframework.web.client.ResourceAccessException; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.util.UriComponentsBuilder; + +import javax.annotation.PostConstruct; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.*; +import java.util.stream.Collectors; + +public class ExternalTestingManagerImpl implements ExternalTestingManager { + + private Logger logger = LoggerFactory.getLogger(ExternalTestingManagerImpl.class); + + private static final String HTTP_STATUS = "httpStatus"; + private static final String CODE = "code"; + private static final String ERROR = "error"; + private static final String MESSAGE = "message"; + private static final String DETAIL = "detail"; + private static final String PATH = "path"; + + private static final String CONFIG_FILE_PROPERTY = "configuration.yaml"; + private static final String CONFIG_SECTION = "externalTestingConfig"; + + private static final String VTP_SCENARIOS_URI = "%s/v1/vtp/scenarios"; + private static final String VTP_TESTSUITE_URI = "%s/v1/vtp/scenarios/%s/testsuites"; + private static final String VTP_TESTCASES_URI = "%s/v1/vtp/scenarios/%s/testcases"; + private static final String VTP_TESTCASE_URI = "%s/v1/vtp/scenarios/%s/testsuites/%s/testcases/%s"; + private static final String VTP_EXECUTIONS_URI = "%s/v1/vtp/executions"; + private static final String VTP_EXECUTION_URI = "%s/v1/vtp/executions/%s"; + + private static final String INVALIDATE_STATE_ERROR = "Invalid State"; + private static final String NO_ACCESS_CONFIGURATION_DEFINED = "No access configuration defined"; + + private TestingAccessConfig accessConfig; + private Map endpoints = new HashMap<>(); + + private RestTemplate restTemplate; + + private List variableResolvers; + + public ExternalTestingManagerImpl(@Autowired(required=false) List variableResolvers) { + this.variableResolvers = variableResolvers; + // nothing to do at the moment. + restTemplate = new RestTemplate(); + } + + /** + * Read the configuration from the yaml file for this bean. If we get an exception during load, + * don't force an error starting SDC but log a warning. Do no warm... + */ + @PostConstruct + public void loadConfig() { + + String file = Objects.requireNonNull(System.getProperty(CONFIG_FILE_PROPERTY), + "Config file location must be specified via system property " + CONFIG_FILE_PROPERTY); + try { + Object rawConfig = getExternalTestingAccessConfiguration(file); + if (rawConfig != null) { + accessConfig = new ObjectMapper().convertValue(rawConfig, TestingAccessConfig.class); + accessConfig.getEndpoints() + .stream() + .filter(RemoteTestingEndpointDefinition::isEnabled) + .forEach(e -> endpoints.put(e.getId(), e)); + } + } + catch (IOException ex) { + logger.warn("Unable to initialize external testing configuration. Add '" + CONFIG_SECTION + "' to configuration.yaml with url value. Feature will be hobbled with results hardcoded to empty values.", ex); + } + } + + /** + * Return the configuration of this feature that we want to + * expose to the client. Treated as a JSON blob for flexibility. + */ + @Override + public String getConfig() { + ClientConfiguration cc = null; + if (accessConfig != null) { + cc = accessConfig.getClient(); + } + if (cc == null) { + cc = new ClientConfiguration(); + cc.setEnabled(false); + } + try { + return new ObjectMapper().writeValueAsString(cc); + } catch (JsonProcessingException e) { + logger.error("failed to write client config", e); + return "{\"enabled\":false}"; + } + } + + @Override + public TestTreeNode getTestCasesAsTree() { + TestTreeNode root = new TestTreeNode("root", "root"); + + // quick out in case of non-configured SDC + if (accessConfig == null) { + return root; + } + + for (RemoteTestingEndpointDefinition ep : accessConfig.getEndpoints()) { + if (ep.isEnabled()) { + buildTreeFromEndpoint(ep, root); + } + } + return root; + } + + private void buildTreeFromEndpoint(RemoteTestingEndpointDefinition ep, TestTreeNode root) { + try { + logger.debug("process endpoint {}", ep.getId()); + getScenarios(ep.getId()).stream().filter(s -> + ((ep.getScenarioFilter() == null) || ep.getScenarioFilterPattern().matcher(s.getName()).matches())) + .forEach(s -> { + addScenarioToTree(root, s); + getTestSuites(ep.getId(), s.getName()).forEach(suite -> addSuiteToTree(root, s, suite)); + getTestCases(ep.getId(), s.getName()).forEach(tc -> { + try { + VtpTestCase details = getTestCase(ep.getId(), s.getName(), tc.getTestSuiteName(), tc.getTestCaseName()); + addTestCaseToTree(root, ep.getId(), s.getName(), tc.getTestSuiteName(), details); + } + catch (@SuppressWarnings("squid:S1166") ExternalTestingException ex) { + // Not logging stack trace on purpose. VTP was throwing exceptions for certain test cases. + logger.warn("failed to load test case {}", tc.getTestCaseName()); + } + }); + }); + } + catch (ExternalTestingException ex) { + logger.error("unable to contact testing endpoint {}", ep.getId(), ex); + } + } + + private Optional findNamedChild(TestTreeNode root, String name) { + if (root.getChildren() == null) { + return Optional.empty(); + } + return root.getChildren().stream().filter(n->n.getName().equals(name)).findFirst(); + } + + /** + * Find the place in the tree to add the test case. + * @param root root of the tree. + * @param endpointName name of the endpoint to assign to the test case. + * @param scenarioName scenario to add this case to + * @param testSuiteName suite in the scenario to add this case to + * @param tc test case to add. + */ + private void addTestCaseToTree(TestTreeNode root, String endpointName, String scenarioName, String testSuiteName, VtpTestCase tc) { + // return quickly. + if (tc == null) { + return; + } + findNamedChild(root, scenarioName) + .ifPresent(scenarioNode -> findNamedChild(scenarioNode, testSuiteName) + .ifPresent(suiteNode -> { + massageTestCaseForUI(tc, endpointName, scenarioName); + if (suiteNode.getTests() == null) { + suiteNode.setTests(new ArrayList<>()); + } + suiteNode.getTests().add(tc); + })); + } + + private void massageTestCaseForUI(VtpTestCase testcase, String endpoint, String scenario) { + testcase.setEndpoint(endpoint); + // VTP workaround. + if (testcase.getScenario() == null) { + testcase.setScenario(scenario); + } + + // if no inputs, return. + if (testcase.getInputs() == null) { + return; + } + + // to work around a VTP limitation, + // any inputs that are marked as internal should not be sent to the client. + testcase.setInputs(testcase.getInputs() + .stream() + .filter(input -> (input.getMetadata() == null) || + (!input.getMetadata().containsKey("internal")) || + !"true".equals(input.getMetadata().get("internal").toString())).collect(Collectors.toList())); + } + + /** + * Add the test suite to the tree at the appropriate place if it does not already exist in the tree. + * @param root root of the tree. + * @param scenario scenario under which this suite should be placed + * @param suite test suite to add. + */ + private void addSuiteToTree(final TestTreeNode root, final VtpNameDescriptionPair scenario, final VtpNameDescriptionPair suite) { + findNamedChild(root, scenario.getName()).ifPresent(parent -> { + if (parent.getChildren() == null) { + parent.setChildren(new ArrayList<>()); + } + if (parent.getChildren().stream().noneMatch(n -> StringUtils.equals(n.getName(), suite.getName()))) { + parent.getChildren().add(new TestTreeNode(suite.getName(), suite.getDescription())); + } + }); + } + + /** + * Add the scenario to the tree if it does not already exist. + * @param root root of the tree. + * @param s scenario to add. + */ + private void addScenarioToTree(TestTreeNode root, VtpNameDescriptionPair s) { + logger.debug("addScenario {} to {} with {}", s.getName(), root.getName(), root.getChildren()); + if (root.getChildren() == null) { + root.setChildren(new ArrayList<>()); + } + if (root.getChildren().stream().noneMatch(n->StringUtils.equals(n.getName(),s.getName()))) { + logger.debug("createScenario {} in {}", s.getName(), root.getName()); + root.getChildren().add(new TestTreeNode(s.getName(), s.getDescription())); + } + } + + /** + * Get the list of endpoints defined to the testing manager. + * @return list of endpoints or empty list if the manager is not configured. + */ + public List getEndpoints() { + if (accessConfig != null) { + return accessConfig.getEndpoints().stream() + .filter(RemoteTestingEndpointDefinition::isEnabled) + .map(e -> new VtpNameDescriptionPair(e.getId(), e.getTitle())) + .collect(Collectors.toList()); + } + else { + return new ArrayList<>(); + } + } + + /** + * Get the list of scenarios at a given endpoint. + */ + public List getScenarios(final String endpoint) { + String url = buildEndpointUrl(VTP_SCENARIOS_URI, endpoint, ArrayUtils.EMPTY_STRING_ARRAY); + ParameterizedTypeReference> t = new ParameterizedTypeReference>() {}; + List rv = proxyGetRequestToExternalTestingSite(url, t); + if (rv == null) { + rv = new ArrayList<>(); + } + return rv; + } + + /** + * Get the list of test suites for an endpoint for the given scenario. + */ + public List getTestSuites(final String endpoint, final String scenario) { + String url = buildEndpointUrl(VTP_TESTSUITE_URI, endpoint, new String[] {scenario}); + ParameterizedTypeReference> t = new ParameterizedTypeReference>() {}; + List rv = proxyGetRequestToExternalTestingSite(url, t); + if (rv == null) { + rv = new ArrayList<>(); + } + return rv; + } + + /** + * Get the list of test cases under a scenario. This is the VTP API. It would + * seem better to get the list of cases under a test suite but that is not supported. + */ + @Override + public List getTestCases(String endpoint, String scenario) { + String url = buildEndpointUrl(VTP_TESTCASES_URI, endpoint, new String[] {scenario}); + ParameterizedTypeReference> t = new ParameterizedTypeReference>() {}; + List rv = proxyGetRequestToExternalTestingSite(url, t); + if (rv == null) { + rv = new ArrayList<>(); + } + return rv; + } + + /** + * Get a test case definition. + */ + @Override + public VtpTestCase getTestCase(String endpoint, String scenario, String testSuite, String testCaseName) { + String url = buildEndpointUrl(VTP_TESTCASE_URI, endpoint, new String[] {scenario, testSuite, testCaseName}); + ParameterizedTypeReference t = new ParameterizedTypeReference() {}; + return proxyGetRequestToExternalTestingSite(url, t); + } + + /** + * Return the results of a previous test execution. + * @param endpoint endpoint to query + * @param executionId execution to query. + * @return execution response from testing endpoint. + */ + @Override + public VtpTestExecutionResponse getExecution(String endpoint,String executionId) { + String url = buildEndpointUrl(VTP_EXECUTION_URI, endpoint, new String[] {executionId}); + ParameterizedTypeReference t = new ParameterizedTypeReference() {}; + return proxyGetRequestToExternalTestingSite(url, t); + } + + /** + * Execute a set of tests at a given endpoint. + * @param endpointName name of the endpoint + * @param testsToRun set of tests to run + * @return list of execution responses. + */ + private List execute(final String endpointName, final List testsToRun, String requestId) { + if (accessConfig == null) { + throw new ExternalTestingException(INVALIDATE_STATE_ERROR, 500, NO_ACCESS_CONFIGURATION_DEFINED); + } + + RemoteTestingEndpointDefinition endpoint = accessConfig.getEndpoints().stream() + .filter(e -> StringUtils.equals(endpointName, e.getId())) + .findFirst() + .orElseThrow(() -> new ExternalTestingException("No such endpoint", 500, "No endpoint named " + endpointName + " is defined")); + + // if the endpoint requires an API key, specify it in the headers. + HttpHeaders headers = new HttpHeaders(); + if (endpoint.getApiKey() != null) { + headers.add("X-API-Key", endpoint.getApiKey()); + } + headers.setContentType(MediaType.MULTIPART_FORM_DATA); + + // build the body. + MultiValueMap body = new LinkedMultiValueMap<>(); + try { + // remove the endpoint from the test request since that is a FE/BE attribute + // add the execution profile configured for the endpoint. + testsToRun.forEach(t -> { + t.setEndpoint(null); + t.setProfile(t.getScenario()); // VTP wants a profile. Use the scenario name. + }); + + body.add("executions", new ObjectMapper().writeValueAsString(testsToRun)); + } + catch (Exception ex) { + logger.error("exception converting tests to string", ex); + VtpTestExecutionResponse err = new VtpTestExecutionResponse(); + err.setHttpStatus(500); + err.setCode("500"); + err.setMessage("Execution failed due to " + ex.getMessage()); + return Collections.singletonList(err); + } + + for(VtpTestExecutionRequest test: testsToRun) { + runVariableResolvers(test, body); + } + + + // form and send request. + HttpEntity> requestEntity = new HttpEntity<>(body, headers); + String url = buildEndpointUrl(VTP_EXECUTIONS_URI, endpointName, ArrayUtils.EMPTY_STRING_ARRAY); + UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url); + if (requestId != null) { + builder = builder.queryParam("requestId", requestId); + } + ParameterizedTypeReference> t = new ParameterizedTypeReference>() {}; + try { + return proxyRequestToExternalTestingSite(builder.toUriString(), requestEntity, t); + } + catch (ExternalTestingException ex) { + logger.error("exception caught invoking endpoint {}", endpointName, ex); + VtpTestExecutionResponse err = new VtpTestExecutionResponse(); + err.setHttpStatus(ex.getCode()); + err.setCode(""+ex.getCode()); + err.setMessage(ex.getTitle() + ": " + ex.getDetail()); + return Collections.singletonList(err); + } + } + + /** + * Execute tests splitting them across endpoints and collecting the results. + * @param testsToRun list of tests to be executed. + * @return collection of result objects. + */ + @Override + public List execute(final List testsToRun, String requestId) { + if (accessConfig == null) { + throw new ExternalTestingException(INVALIDATE_STATE_ERROR, 500, NO_ACCESS_CONFIGURATION_DEFINED); + } + + // partition the requests by endpoint. + Map> partitions = + testsToRun.stream().collect(Collectors.groupingBy(VtpTestExecutionRequest::getEndpoint)); + + // process each group and collect the results. + return partitions.entrySet().stream() + .flatMap(e -> execute(e.getKey(), e.getValue(), requestId).stream()) + .collect(Collectors.toList()); + } + + /** + * Load the external testing access configuration from the SDC onboarding yaml configuration file. + * @param file filename to retrieve data from + * @return parsed YAML object + * @throws IOException thrown if failure in reading YAML content. + */ + private Object getExternalTestingAccessConfiguration(String file) throws IOException { + Map configuration = Objects.requireNonNull(readConfigurationFile(file), "Configuration cannot be empty"); + Object testingConfig = configuration.get(CONFIG_SECTION); + if (testingConfig == null) { + logger.warn("Unable to initialize external testing access configuration. Add 'testingConfig' to configuration.yaml with url value. Feature will be hobbled with results hardcoded to empty values."); + } + + return testingConfig; + } + + /** + * Load the onboarding yaml config file. + * @param file name of file to load + * @return map containing YAML properties. + * @throws IOException thrown in the event of YAML parse or IO failure. + */ + private static Map readConfigurationFile(String file) throws IOException { + try (InputStream fileInput = new FileInputStream(file)) { + YamlUtil yamlUtil = new YamlUtil(); + return yamlUtil.yamlToMap(fileInput); + } + } + + + /** + * Return URL with endpoint url as prefix. + * @param format format string. + * @param endpointName endpoint to address + * @param args args for format. + * @return qualified url. + */ + private String buildEndpointUrl(String format, String endpointName, String[] args) { + if (accessConfig != null) { + RemoteTestingEndpointDefinition ep = endpoints.values().stream() + .filter(e -> e.getId().equals(endpointName)) + .findFirst() + .orElseThrow(() -> new ExternalTestingException("No such endpoint", 500, "No endpoint named " + endpointName + " is defined") + ); + + Object[] newArgs = ArrayUtils.add(args, 0, ep.getUrl()); + return String.format(format, newArgs); + } + throw new ExternalTestingException(INVALIDATE_STATE_ERROR, 500, NO_ACCESS_CONFIGURATION_DEFINED); + } + + /** + * Proxy a get request to a testing endpoint. + * @param url URL to invoke. + * @param responseType type of response expected. + * @param type of response expected + * @return instance of parsed from the JSON response from endpoint. + */ + private T proxyGetRequestToExternalTestingSite(String url, ParameterizedTypeReference responseType) { + return proxyRequestToExternalTestingSite(url, null, responseType); + } + + /** + * Make the actual HTTP post (using Spring RestTemplate) to an endpoint. + * @param url URL to the endpoint + * @param request optional request body to send + * @param responseType expected type + * @param extended type + * @return instance of expected type + */ + private T proxyRequestToExternalTestingSite(String url, HttpEntity request, ParameterizedTypeReference responseType) { + if (request != null) { + logger.debug("POST request to {} with {} for {}", url, request, responseType.getType().getTypeName()); + } + else { + logger.debug("GET request to {} for {}", url, responseType.getType().getTypeName()); + } + SimpleClientHttpRequestFactory rf = + (SimpleClientHttpRequestFactory) restTemplate.getRequestFactory(); + if (rf != null) { + rf.setReadTimeout(10000); + rf.setConnectTimeout(10000); + } + ResponseEntity re; + try { + if (request != null) { + re = restTemplate.exchange(url, HttpMethod.POST, request, responseType); + } else { + re = restTemplate.exchange(url, HttpMethod.GET, null, responseType); + } + } + catch (HttpStatusCodeException ex) { + // make my own exception out of this. + logger.warn("Unexpected HTTP Status from endpoint {}", ex.getRawStatusCode()); + if ((ex.getResponseHeaders().getContentType() != null) && + ((ex.getResponseHeaders().getContentType().isCompatibleWith(MediaType.APPLICATION_JSON)) || + (ex.getResponseHeaders().getContentType().isCompatibleWith(MediaType.parseMediaType("application/problem+json"))))) { + String s = ex.getResponseBodyAsString(); + logger.warn("endpoint body content is {}", s); + try { + JsonObject o = new GsonBuilder().create().fromJson(s, JsonObject.class); + throw buildTestingException(ex.getRawStatusCode(), o); + } + catch (JsonParseException e) { + logger.warn("unexpected JSON response", e); + throw new ExternalTestingException(ex.getStatusText(), ex.getStatusCode().value(), ex.getResponseBodyAsString(), ex); + } + } + else { + throw new ExternalTestingException(ex.getStatusText(), ex.getStatusCode().value(), ex.getResponseBodyAsString(), ex); + } + } + catch (ResourceAccessException ex) { + throw new ExternalTestingException("IO Error at Endpoint", 500, ex.getMessage(), ex); + } + catch (Exception ex) { + throw new ExternalTestingException(ex.getMessage(), 500, "Generic Exception", ex); + } + if (re != null) { + logger.debug("http status of {} from external testing entity {}", re.getStatusCodeValue(), url); + return re.getBody(); + } + else { + logger.error("null response from endpoint"); + return null; + } + } + + /** + * Errors from the endpoint could conform to the expected ETSI body or not. + * Here we try to handle various response body elements. + * @param statusCode http status code in response. + * @param o JSON object parsed from the http response body + * @return Testing error body that should be returned to the caller + */ + private ExternalTestingException buildTestingException(int statusCode, JsonObject o) { + String code = null; + String message = null; + + if (o.has(CODE)) { + code = o.get(CODE).getAsString(); + } + else if (o.has(ERROR)) { + code = o.get(ERROR).getAsString(); + } + else { + if (o.has(HTTP_STATUS)) { + code = o.get(HTTP_STATUS).getAsJsonPrimitive().getAsString(); + } + } + if (o.has(MESSAGE)) { + if (!o.get(MESSAGE).isJsonNull()) { + message = o.get(MESSAGE).getAsString(); + } + } + else if (o.has(DETAIL)) { + message = o.get(DETAIL).getAsString(); + } + if (o.has(PATH)) { + if (message == null) { + message = o.get(PATH).getAsString(); + } + else { + message = message + " " + o.get(PATH).getAsString(); + } + } + return new ExternalTestingException(code, statusCode, message); + } + + /** + * Resolve variables in the request calling the built-in variable resolvers. + * @param item test execution request item to be resolved. + */ + private void runVariableResolvers(final VtpTestExecutionRequest item, final MultiValueMap body) { + variableResolvers.forEach(vr -> { + if (vr.resolvesVariablesForRequest(item)) { + vr.resolve(item, body); + } + }); + } +} \ No newline at end of file diff --git a/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/main/java/org/openecomp/core/externaltesting/impl/RemoteTestingEndpointDefinition.java b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/main/java/org/openecomp/core/externaltesting/impl/RemoteTestingEndpointDefinition.java new file mode 100644 index 0000000000..205ca29680 --- /dev/null +++ b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/main/java/org/openecomp/core/externaltesting/impl/RemoteTestingEndpointDefinition.java @@ -0,0 +1,39 @@ +/* + * Copyright © 2019 iconectiv + * + * 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 org.openecomp.core.externaltesting.impl; + +import lombok.Data; + +import java.util.regex.Pattern; + +@Data +class RemoteTestingEndpointDefinition { + private boolean enabled; + private String title; + private String url; + private String id; + private String apiKey; + private String scenarioFilter; + private Pattern scenarioFilterPattern; + + Pattern getScenarioFilterPattern() { + if ((scenarioFilterPattern == null) && (scenarioFilter != null)) { + scenarioFilterPattern = Pattern.compile(scenarioFilter); + } + return scenarioFilterPattern; + } +} diff --git a/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/main/java/org/openecomp/core/externaltesting/impl/TestingAccessConfig.java b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/main/java/org/openecomp/core/externaltesting/impl/TestingAccessConfig.java new file mode 100644 index 0000000000..f9df5ac81d --- /dev/null +++ b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/main/java/org/openecomp/core/externaltesting/impl/TestingAccessConfig.java @@ -0,0 +1,30 @@ +/* + * Copyright © 2019 iconectiv + * + * 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 org.openecomp.core.externaltesting.impl; + +import lombok.Data; + +import java.util.List; + +@SuppressWarnings({"unused", "WeakerAccess"}) +@Data +public class TestingAccessConfig { + + private ClientConfiguration client; + private List endpoints; + +} diff --git a/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/main/java/org/openecomp/core/externaltesting/impl/VariableResolver.java b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/main/java/org/openecomp/core/externaltesting/impl/VariableResolver.java new file mode 100644 index 0000000000..3079898bff --- /dev/null +++ b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/main/java/org/openecomp/core/externaltesting/impl/VariableResolver.java @@ -0,0 +1,27 @@ +/* + * Copyright © 2019 iconectiv + * + * 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 org.openecomp.core.externaltesting.impl; + +import org.openecomp.core.externaltesting.api.VtpTestExecutionRequest; +import org.springframework.util.MultiValueMap; + +public interface VariableResolver { + + boolean resolvesVariablesForRequest(VtpTestExecutionRequest requestItem); + + void resolve(VtpTestExecutionRequest requestItem, MultiValueMap body); +} diff --git a/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/main/resources/factoryConfiguration.json b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/main/resources/factoryConfiguration.json new file mode 100644 index 0000000000..10449038bf --- /dev/null +++ b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/main/resources/factoryConfiguration.json @@ -0,0 +1,3 @@ +{ + "org.openecomp.core.externaltesting.factory.ExternalTestingManagerFactory":"org.openecomp.sdc.externaltesting.impl.ExternalTestingManagerFactoryImpl" +} diff --git a/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/test/data/csar.zip b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/test/data/csar.zip new file mode 100644 index 0000000000000000000000000000000000000000..52de39a93e77fa344d81d56edd619ae921d1fb78 GIT binary patch literal 14993 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 e=h(kTaQ+oK)Q=Ao06_fl()); + Assert.assertFalse("should not resolve empty parameters", resolver.resolvesVariablesForRequest(doesNotResolve)); + + + + VtpTestExecutionRequest resolves = new VtpTestExecutionRequest(); + resolves.setParameters(new HashMap<>()); + resolves.getParameters().put(CsarMetadataVariableResolver.VSP_VERSION, "1.0"); + resolves.getParameters().put(CsarMetadataVariableResolver.VSP_ID, "vspid"); + resolves.getParameters().put(CsarMetadataVariableResolver.CSAR_PREFIX + "MainServiceTemplate.yaml", ""); + Assert.assertTrue("should resolve", resolver.resolvesVariablesForRequest(resolves)); + + MultiValueMap fakeRequestBody = new LinkedMultiValueMap<>(); + + try { + resolver.resolve(resolves, fakeRequestBody); + } + catch (ExternalTestingException e) { + // exception expected. + } + + // test the metadata extraction on a know CSAR zip. + byte[] zip = IOUtils.toByteArray(new FileInputStream("src/test/data/csar.zip")); + resolver.processArchive(resolves, fakeRequestBody, zip); + Assert.assertTrue("body contains file", fakeRequestBody.containsKey("file")); + LinkedList ll = (LinkedList)fakeRequestBody.get("file"); + Assert.assertEquals("body contains one file", 1, ll.size()); + ByteArrayResource res = (ByteArrayResource)ll.get(0); + Assert.assertEquals("file should have matching name", "MainServiceTemplate.yaml", res.getFilename()); + + } +} diff --git a/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/test/java/org/openecomp/core/externaltesting/impl/ExternalTestingManagerImplTests.java b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/test/java/org/openecomp/core/externaltesting/impl/ExternalTestingManagerImplTests.java new file mode 100644 index 0000000000..be328ea73f --- /dev/null +++ b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/test/java/org/openecomp/core/externaltesting/impl/ExternalTestingManagerImplTests.java @@ -0,0 +1,283 @@ +/* + * Copyright © 2019 iconectiv + * + * 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 org.openecomp.core.externaltesting.impl; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.commons.io.FileUtils; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentMatchers; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; +import org.openecomp.core.externaltesting.api.*; +import org.openecomp.core.externaltesting.errors.ExternalTestingException; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.*; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.HttpServerErrorException; +import org.springframework.web.client.HttpStatusCodeException; +import org.springframework.web.client.ResourceAccessException; +import org.springframework.web.client.RestTemplate; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.Charset; +import java.util.*; + +@RunWith(MockitoJUnitRunner.class) +public class ExternalTestingManagerImplTests { + + @Mock + private RestTemplate restTemplate; + + static { + System.setProperty("configuration.yaml", "src/test/data/testconfiguration.yaml"); + } + + class JUnitExternalTestingManagerImpl extends ExternalTestingManagerImpl { + JUnitExternalTestingManagerImpl() { + super(Collections.singletonList( + new VariableResolver() { + + @Override + public boolean resolvesVariablesForRequest(VtpTestExecutionRequest requestItem) { + return false; + } + + @Override + public void resolve(VtpTestExecutionRequest requestItem, MultiValueMap body) { + + // unit test resolver does nothing for this case. See specific test for resolver. + } + })); + } + } + + @InjectMocks + private ExternalTestingManager mgr = new JUnitExternalTestingManagerImpl(); + + @SuppressWarnings("unchecked") + private ExternalTestingManager configTestManager(boolean loadConfig) throws IOException { + if (loadConfig) { + ((ExternalTestingManagerImpl) mgr).loadConfig(); + } + + ObjectMapper mapper = new ObjectMapper(); + + // read mock data for API calls. + + File scenarioFile = new File("src/test/data/scenarios.json"); + TypeReference> typ = new TypeReference>(){}; + List scenarios = mapper.readValue(scenarioFile, typ); + + File testSuitesFile = new File("src/test/data/testsuites.json"); + List testSuites = mapper.readValue(testSuitesFile, new TypeReference>(){}); + + File testCasesFile = new File("src/test/data/testcases.json"); + List testCases = mapper.readValue(testCasesFile, new TypeReference>(){}); + + File testCaseFile = new File("src/test/data/testcase-sriov.json"); + VtpTestCase testCase = mapper.readValue(testCaseFile, VtpTestCase.class); + + File runResultFile = new File("src/test/data/runresult.json"); + List runResults = mapper.readValue(runResultFile, new TypeReference>(){}); + + File priorExecutionFile = new File("src/test/data/priorexecution.json"); + VtpTestExecutionResponse priorExecution = mapper.readValue(priorExecutionFile, VtpTestExecutionResponse.class); + + // create an error response as well + String notFound = FileUtils.readFileToString(new File("src/test/data/notfound.json"), "UTF-8"); + + ParameterizedTypeReference> listOfPairType = new ParameterizedTypeReference>() {}; + ParameterizedTypeReference> listOfCasesType = new ParameterizedTypeReference>() {}; + ParameterizedTypeReference caseType = new ParameterizedTypeReference() {}; + + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.parseMediaType("application/problem+json")); + HttpStatusCodeException missingException = new HttpServerErrorException(HttpStatus.NOT_FOUND, "Not Found", headers, notFound.getBytes(), Charset.defaultCharset()); + + Mockito + .when(restTemplate.exchange( + ArgumentMatchers.endsWith("/scenarios"), + ArgumentMatchers.eq(HttpMethod.GET), + ArgumentMatchers.any(), + ArgumentMatchers.eq(listOfPairType))) + .thenReturn(new ResponseEntity(scenarios, HttpStatus.OK)); + + Mockito + .when(restTemplate.exchange( + ArgumentMatchers.endsWith("/testsuites"), + ArgumentMatchers.eq(HttpMethod.GET), + ArgumentMatchers.any(), + ArgumentMatchers.eq(listOfPairType))) + .thenReturn(new ResponseEntity(testSuites, HttpStatus.OK)); + + Mockito + .when(restTemplate.exchange( + ArgumentMatchers.endsWith("/testcases"), + ArgumentMatchers.eq(HttpMethod.GET), + ArgumentMatchers.any(), + ArgumentMatchers.eq(listOfCasesType))) + .thenReturn(new ResponseEntity(testCases, HttpStatus.OK)); + + Mockito + .when(restTemplate.exchange( + ArgumentMatchers.endsWith("/sriov"), + ArgumentMatchers.eq(HttpMethod.GET), + ArgumentMatchers.any(), + ArgumentMatchers.eq(caseType))) + .thenReturn(new ResponseEntity(testCase, HttpStatus.OK)); + + + // POST for execution + + Mockito + .when(restTemplate.exchange( + ArgumentMatchers.contains("executions"), + ArgumentMatchers.eq(HttpMethod.POST), + ArgumentMatchers.any(), + ArgumentMatchers.eq(new ParameterizedTypeReference>() {}))) + .thenReturn(new ResponseEntity(runResults, HttpStatus.OK)); + + + Mockito + .when(restTemplate.exchange( + ArgumentMatchers.contains("/executions/"), + ArgumentMatchers.eq(HttpMethod.GET), + ArgumentMatchers.any(), + ArgumentMatchers.eq(new ParameterizedTypeReference() {}))) + .thenReturn(new ResponseEntity(priorExecution, HttpStatus.OK)); + + Mockito + .when(restTemplate.exchange( + ArgumentMatchers.endsWith("/missing"), + ArgumentMatchers.eq(HttpMethod.GET), + ArgumentMatchers.any(), + ArgumentMatchers.eq(caseType))) + .thenThrow(missingException); + + Mockito + .when(restTemplate.exchange( + ArgumentMatchers.endsWith("/sitedown"), + ArgumentMatchers.eq(HttpMethod.GET), + ArgumentMatchers.any(), + ArgumentMatchers.eq(caseType))) + .thenThrow(new ResourceAccessException("Remote site is down")); + + return mgr; + } + + @Test + public void testManager() throws IOException { + System.setProperty("configuration.yaml", "src/test/data/managertestconfiguration.yaml"); + ExternalTestingManager m = configTestManager(true); + + String config = m.getConfig(); + Assert.assertNotNull(config); + + List endpoints = m.getEndpoints(); + Assert.assertEquals("two endpoints", 2, endpoints.size()); + + + // this will exercise the internal APIs as well. + TestTreeNode root = m.getTestCasesAsTree(); + Assert.assertEquals("two scenarios", 2, root.getChildren().size()); + + + // handle case where remote endpoint is down. + try { + m.getTestCase("repository", "scen", "suite", "sitedown"); + Assert.fail("not expected to retrieve sitedown test case"); + } + catch (ExternalTestingException e) { + // expecting this exception. + Assert.assertNotNull(e.getDetail()); + Assert.assertNotEquals(0, e.getCode()); + Assert.assertNotNull(e.getTitle()); + } + + // get a particular test case + try { + m.getTestCase("repository", "scen", "suite", "missing"); + Assert.fail("not expected to retrieve missing test case"); + } + catch (ExternalTestingException e) { + // expecting this exception. + Assert.assertNotNull(e.getDetail()); + Assert.assertNotEquals(0, e.getCode()); + Assert.assertNotNull(e.getTitle()); + } + + + // execute a test. + List requests = new ArrayList<>(); + VtpTestExecutionRequest req = new VtpTestExecutionRequest(); + req.setEndpoint("repository"); + requests.add(req); + + // send a request with the endpoint defined. + List responses = m.execute( requests, "rid"); + Assert.assertEquals(1,responses.size()); + + // send a request for a prior execution. + VtpTestExecutionResponse execRsp = m.getExecution("repository", "execId"); + Assert.assertEquals("COMPLETED", execRsp.getStatus()); + } + + @Test + public void testManagerErrorCases() throws IOException { + ExternalTestingManager m = configTestManager(false); + Map expectedEmptyConfig = new HashMap<>(); + expectedEmptyConfig.put("enabled", false); + String expected = new ObjectMapper().writeValueAsString(expectedEmptyConfig); + String emptyConfig = m.getConfig(); + Assert.assertEquals(expected, emptyConfig); + + try { + m.getEndpoints(); + Assert.assertTrue("should have exception here", true); + } + catch (ExternalTestingException e) { + // eat the exception cause this is what should happen. + } + } + + @Test + public void testExecutionDistribution() throws IOException { + System.setProperty("configuration.yaml", "src/test/data/managertestconfiguration.yaml"); + ExternalTestingManager m = configTestManager(true); + + VtpTestExecutionRequest r1 = new VtpTestExecutionRequest(); + r1.setScenario("scenario1"); + r1.setEndpoint("vtp"); + + VtpTestExecutionRequest r2 = new VtpTestExecutionRequest(); + r2.setScenario("scenario2"); + r2.setEndpoint("vtp"); + + VtpTestExecutionRequest r3 = new VtpTestExecutionRequest(); + r3.setScenario("scenario3"); + r3.setEndpoint("repository"); + + List results = m.execute(Arrays.asList(r1,r2,r3), "rid"); + Assert.assertEquals("three in two out merged", 2, results.size()); + } +} diff --git a/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/test/java/org/openecomp/core/externaltesting/impl/ExternalTestingTestSuite.java b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/test/java/org/openecomp/core/externaltesting/impl/ExternalTestingTestSuite.java new file mode 100644 index 0000000000..31346a135e --- /dev/null +++ b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/test/java/org/openecomp/core/externaltesting/impl/ExternalTestingTestSuite.java @@ -0,0 +1,31 @@ +/* + * Copyright © 2019 iconectiv + * + * 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 org.openecomp.core.externaltesting.impl; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +@RunWith(Suite.class) +@Suite.SuiteClasses({ + CsarMetadataVariableResolverTest.class, + ExternalTestingManagerImplTests.class, + ConfigurationTests.class +}) +public class ExternalTestingTestSuite { + // nothing to do - just a placeholder. + +} diff --git a/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/test/resources/logback-test.xml b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..e0498971dc --- /dev/null +++ b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/openecomp-sdc-externaltesting-impl/src/test/resources/logback-test.xml @@ -0,0 +1,30 @@ + + + + + + + + %d{dd-MMM-yyyy HH:mm:ss:SSS} %-5level %logger{36}.%M\(%line\) - %msg%n + + + + + + + + diff --git a/openecomp-be/lib/openecomp-sdc-externaltesting-lib/pom.xml b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/pom.xml new file mode 100644 index 0000000000..75ab9a54b0 --- /dev/null +++ b/openecomp-be/lib/openecomp-sdc-externaltesting-lib/pom.xml @@ -0,0 +1,21 @@ + + 4.0.0 + + openecomp-sdc-externaltesting-lib + openecomp-sdc-externaltesting-lib + + pom + + openecomp-sdc-lib + org.openecomp.sdc + 1.4.0-SNAPSHOT + + + + openecomp-sdc-externaltesting-api + openecomp-sdc-externaltesting-impl + + + diff --git a/openecomp-be/lib/pom.xml b/openecomp-be/lib/pom.xml index 86787b5bc4..a0def39002 100644 --- a/openecomp-be/lib/pom.xml +++ b/openecomp-be/lib/pom.xml @@ -23,6 +23,7 @@ openecomp-sdc-model-lib openecomp-sdc-validation-lib openecomp-sdc-datatypes-lib + openecomp-sdc-externaltesting-lib openecomp-heat-lib openecomp-tosca-lib openecomp-sdc-action-lib -- 2.16.6