From c3971fb03756899923e88cdd4614602d87e67627 Mon Sep 17 00:00:00 2001 From: cedscho Date: Mon, 16 May 2022 14:24:08 +0200 Subject: [PATCH 01/10] refactor: put Backend apiKeys and BotBackendFetchURL into .env --- Backend/.env | 7 +++++++ Backend/.gitignore | 1 - Backend/package-lock.json | 14 ++++++++++++++ Backend/package.json | 1 + Backend/server.js | 13 +++++++------ Frontend/.env | 3 ++- Frontend/.env.production | 3 ++- Frontend/src/benchi-chatbot/MessageParser.js | 2 +- Frontend/src/benchi-chatbot/TextToSpeech.js | 2 +- .../screens/Dashboard/DashboardScreen.jsx | 1 + 10 files changed, 36 insertions(+), 11 deletions(-) create mode 100644 Backend/.env diff --git a/Backend/.env b/Backend/.env new file mode 100644 index 000000000..b1fe361ee --- /dev/null +++ b/Backend/.env @@ -0,0 +1,7 @@ +#API Keys +APIKEY1 = ZSQ57OXG4YKUA0B8 #API Key Hakan; +APIKEY2 = MB6DE4CNFFYGP4M7 #API Key Steffen; +APIKEY3 = NOGQ7D1A1RHDGMU4 #API Key Cedrik +APIKEY4 = ZSQ57OXG4YKUA0B8 #API Key Hakan; #RESERVIERT FÜR MONATLICH +APIKEY5 = MB6DE4CNFFYGP4M7 #API Key Steffen; +APIKEY6 = NOGQ7D1A1RHDGMU4 #API Key Cedrik; \ No newline at end of file diff --git a/Backend/.gitignore b/Backend/.gitignore index 6a7d6d8ef..fa6a20f53 100644 --- a/Backend/.gitignore +++ b/Backend/.gitignore @@ -73,7 +73,6 @@ web_modules/ .yarn-integrity # dotenv environment variable files -.env .env.development.local .env.test.local .env.production.local diff --git a/Backend/package-lock.json b/Backend/package-lock.json index 304db1a97..7455db3f4 100644 --- a/Backend/package-lock.json +++ b/Backend/package-lock.json @@ -12,6 +12,7 @@ "axios": "^0.26.1", "body-parser": "^1.19.2", "convert-csv-to-json": "^1.3.3", + "dotenv": "^16.0.1", "express": "^4.17.3", "linebyline": "^1.3.0", "match-sorter": "^6.3.1", @@ -643,6 +644,14 @@ "node": ">=8" } }, + "node_modules/dotenv": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.1.tgz", + "integrity": "sha512-1K6hR6wtk2FviQ4kEiSjFiH5rpzEVi8WW0x96aztHVMhEspNpc4DVOUTEHtEva5VThQ8IaBX1Pe4gSzpVVUsKQ==", + "engines": { + "node": ">=12" + } + }, "node_modules/duplexer3": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", @@ -2839,6 +2848,11 @@ "is-obj": "^2.0.0" } }, + "dotenv": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.1.tgz", + "integrity": "sha512-1K6hR6wtk2FviQ4kEiSjFiH5rpzEVi8WW0x96aztHVMhEspNpc4DVOUTEHtEva5VThQ8IaBX1Pe4gSzpVVUsKQ==" + }, "duplexer3": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", diff --git a/Backend/package.json b/Backend/package.json index 3aa568541..0787c343c 100644 --- a/Backend/package.json +++ b/Backend/package.json @@ -13,6 +13,7 @@ "axios": "^0.26.1", "body-parser": "^1.19.2", "convert-csv-to-json": "^1.3.3", + "dotenv": "^16.0.1", "express": "^4.17.3", "linebyline": "^1.3.0", "match-sorter": "^6.3.1", diff --git a/Backend/server.js b/Backend/server.js index f6b467f6b..4af2afc4f 100644 --- a/Backend/server.js +++ b/Backend/server.js @@ -1,3 +1,4 @@ +require('dotenv').config(); const express = require('express'); const bodyParser = require('body-parser'); const fs = require('fs'); @@ -17,12 +18,12 @@ let accessURL = '*'; const apiKeys =[ - 'ZSQ57OXG4YKUA0B8', //API Key Hakan; - 'MB6DE4CNFFYGP4M7', //API Key Steffen; - 'NOGQ7D1A1RHDGMU4', //API Key Cedrik - 'ZSQ57OXG4YKUA0B8', //API Key Hakan; //RESERVIERT FÜR MONATLICH - 'MB6DE4CNFFYGP4M7', //API Key Steffen; - 'NOGQ7D1A1RHDGMU4' //API Key Cedrik + process.env.APIKEY1, + process.env.APIKEY2, + process.env.APIKEY3, + process.env.APIKEY4, + process.env.APIKEY5, + process.env.APIKEY6 ] let apiKeyIndex = 0; // let apiKey; diff --git a/Frontend/.env b/Frontend/.env index 665e18710..d2fe3ef3f 100644 --- a/Frontend/.env +++ b/Frontend/.env @@ -1 +1,2 @@ -REACT_APP_BASEURL = http://localhost:3001 \ No newline at end of file +REACT_APP_BASEURL = http://localhost:3001 +REACT_APP_BOTBACKENDURL = http://benchmarket.germanywestcentral.cloudapp.azure.com:1880 \ No newline at end of file diff --git a/Frontend/.env.production b/Frontend/.env.production index b0ce0d55b..78643652b 100644 --- a/Frontend/.env.production +++ b/Frontend/.env.production @@ -1 +1,2 @@ -REACT_APP_BASEURL = http://benchmarket.germanywestcentral.cloudapp.azure.com:3001 \ No newline at end of file +REACT_APP_BASEURL = http://benchmarket.germanywestcentral.cloudapp.azure.com:3001 +REACT_APP_BOTBACKENDURL = http://benchmarket.germanywestcentral.cloudapp.azure.com:1880 \ No newline at end of file diff --git a/Frontend/src/benchi-chatbot/MessageParser.js b/Frontend/src/benchi-chatbot/MessageParser.js index 13f9747a7..0417357bb 100644 --- a/Frontend/src/benchi-chatbot/MessageParser.js +++ b/Frontend/src/benchi-chatbot/MessageParser.js @@ -32,7 +32,7 @@ class MessageParser { async fetchAnswer(message) { try { - const response = await fetch(`http://benchmarket.germanywestcentral.cloudapp.azure.com:1880/interpretMessage?message=${message}`, {mode:'cors'}) + const response = await fetch(`${process.env.REACT_APP_BOTBACKENDURL}/interpretMessage?message=${message}`, {mode:'cors'}) const json = await response.json(); return json.answers; } catch (e) { diff --git a/Frontend/src/benchi-chatbot/TextToSpeech.js b/Frontend/src/benchi-chatbot/TextToSpeech.js index a148ddb71..22952a564 100644 --- a/Frontend/src/benchi-chatbot/TextToSpeech.js +++ b/Frontend/src/benchi-chatbot/TextToSpeech.js @@ -6,7 +6,7 @@ class TextToSpeech { let audio; try { - const response = await fetch(`http://benchmarket.germanywestcentral.cloudapp.azure.com:1880/textToSpeech?text=${answer}`, {mode:'cors'}) + const response = await fetch(`${process.env.REACT_APP_BOTBACKENDURL}/textToSpeech?text=${answer}`, {mode:'cors'}) const arrayBuffer = await response.arrayBuffer(); TextToSpeech.ctx.close(); TextToSpeech.ctx = new AudioContext(); diff --git a/Frontend/src/components/screens/Dashboard/DashboardScreen.jsx b/Frontend/src/components/screens/Dashboard/DashboardScreen.jsx index c954f7ae4..56c584230 100644 --- a/Frontend/src/components/screens/Dashboard/DashboardScreen.jsx +++ b/Frontend/src/components/screens/Dashboard/DashboardScreen.jsx @@ -163,6 +163,7 @@ const DashboardScreen = props => { onClick={() => dummyCash()} sx={{ margin: '1rem', + marginTop: '3rem', color: '#4eb96f', borderColor: '#4eb96f', backgroundColor: 'white', From f00bba8dcab716b37f194a2fd779deef67df75e6 Mon Sep 17 00:00:00 2001 From: cedscho Date: Wed, 18 May 2022 21:24:47 +0200 Subject: [PATCH 02/10] fix: wrong name in package.json files --- Backend/package-lock.json | 5 ++--- Backend/package.json | 3 +-- Frontend/package-lock.json | 4 ++-- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/Backend/package-lock.json b/Backend/package-lock.json index 7455db3f4..f1b1cc96a 100644 --- a/Backend/package-lock.json +++ b/Backend/package-lock.json @@ -1,13 +1,12 @@ { - "name": "package.json", + "name": "benchmarket-backend", "version": "1.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { - "name": "package.json", + "name": "benchmarket-backend", "version": "1.0.0", - "license": "ISC", "dependencies": { "axios": "^0.26.1", "body-parser": "^1.19.2", diff --git a/Backend/package.json b/Backend/package.json index 0787c343c..267622132 100644 --- a/Backend/package.json +++ b/Backend/package.json @@ -1,5 +1,5 @@ { - "name": "package.json", + "name": "benchmarket-backend", "version": "1.0.0", "description": "BenchmarketBackendServer", "main": "server.js", @@ -8,7 +8,6 @@ "start": "node server.js" }, "author": "Steffen Kruschina @fefifef", - "license": "ISC", "dependencies": { "axios": "^0.26.1", "body-parser": "^1.19.2", diff --git a/Frontend/package-lock.json b/Frontend/package-lock.json index 82ae76b04..00b2bff54 100644 --- a/Frontend/package-lock.json +++ b/Frontend/package-lock.json @@ -1,11 +1,11 @@ { - "name": "finanzen-projekt", + "name": "bench-market", "version": "0.1.0", "lockfileVersion": 2, "requires": true, "packages": { "": { - "name": "finanzen-projekt", + "name": "bench-market", "version": "0.1.0", "dependencies": { "@date-io/date-fns": "^2.13.1", From 4a526e2dfb5f1674a60ebe44ef6df7f3674dc5d3 Mon Sep 17 00:00:00 2001 From: cedscho Date: Wed, 18 May 2022 21:28:00 +0200 Subject: [PATCH 03/10] fix: changed icons and title to bench:market --- Frontend/public/favicon.ico | Bin 3870 -> 168862 bytes Frontend/public/index.html | 2 +- Frontend/public/logo192.png | Bin 5347 -> 13819 bytes Frontend/public/logo512.png | Bin 9664 -> 71941 bytes Frontend/public/manifest.json | 4 ++-- 5 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Frontend/public/favicon.ico b/Frontend/public/favicon.ico index a11777cc471a4344702741ab1c8a588998b1311a..ee93e25f3f17559bbf4eeb5ee3ff85eece6cfe2c 100644 GIT binary patch literal 168862 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 Y*Ao~+W3T4YX77*UA1?LW3IkO3|1ZmM+yDRo literal 3870 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 baj7?x%VD!5Cxk2YbYLNVeiXvvpMCWYo=by@ diff --git a/Frontend/public/index.html b/Frontend/public/index.html index aa069f27c..81bf65ebf 100644 --- a/Frontend/public/index.html +++ b/Frontend/public/index.html @@ -24,7 +24,7 @@ work correctly both with client-side routing and a non-root public URL. Learn how to configure a non-root public URL by running `npm run build`. --> - React App + Bench:market diff --git a/Frontend/public/logo192.png b/Frontend/public/logo192.png index fc44b0a3796c0e0a64c3d858ca038bd4570465d9..2ecb5d4ab806d5b29739a82a0f826fd6f4303ca8 100644 GIT binary patch literal 13819 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 literal 5347 zcmZWtbyO6NvR-oO24RV%BvuJ&=?+<7=`LvyB&A_#M7mSDYw1v6DJkiYl9XjT!%$dLEBTQ8R9|wd3008in6lFF3GV-6mLi?MoP_y~}QUnaDCHI#t z7w^m$@6DI)|C8_jrT?q=f8D?0AM?L)Z}xAo^e^W>t$*Y0KlT5=@bBjT9kxb%-KNdk zeOS1tKO#ChhG7%{ApNBzE2ZVNcxbrin#E1TiAw#BlUhXllzhN$qWez5l;h+t^q#Eav8PhR2|T}y5kkflaK`ba-eoE+Z2q@o6P$)=&` z+(8}+-McnNO>e#$Rr{32ngsZIAX>GH??tqgwUuUz6kjns|LjsB37zUEWd|(&O!)DY zQLrq%Y>)Y8G`yYbYCx&aVHi@-vZ3|ebG!f$sTQqMgi0hWRJ^Wc+Ibv!udh_r%2|U) zPi|E^PK?UE!>_4`f`1k4hqqj_$+d!EB_#IYt;f9)fBOumGNyglU(ofY`yHq4Y?B%- zp&G!MRY<~ajTgIHErMe(Z8JG*;D-PJhd@RX@QatggM7+G(Lz8eZ;73)72Hfx5KDOE zkT(m}i2;@X2AT5fW?qVp?@WgN$aT+f_6eo?IsLh;jscNRp|8H}Z9p_UBO^SJXpZew zEK8fz|0Th%(Wr|KZBGTM4yxkA5CFdAj8=QSrT$fKW#tweUFqr0TZ9D~a5lF{)%-tTGMK^2tz(y2v$i%V8XAxIywrZCp=)83p(zIk6@S5AWl|Oa2hF`~~^W zI;KeOSkw1O#TiQ8;U7OPXjZM|KrnN}9arP)m0v$c|L)lF`j_rpG(zW1Qjv$=^|p*f z>)Na{D&>n`jOWMwB^TM}slgTEcjxTlUby89j1)|6ydRfWERn3|7Zd2&e7?!K&5G$x z`5U3uFtn4~SZq|LjFVrz$3iln-+ucY4q$BC{CSm7Xe5c1J<=%Oagztj{ifpaZk_bQ z9Sb-LaQMKp-qJA*bP6DzgE3`}*i1o3GKmo2pn@dj0;He}F=BgINo};6gQF8!n0ULZ zL>kC0nPSFzlcB7p41doao2F7%6IUTi_+!L`MM4o*#Y#0v~WiO8uSeAUNp=vA2KaR&=jNR2iVwG>7t%sG2x_~yXzY)7K& zk3p+O0AFZ1eu^T3s};B%6TpJ6h-Y%B^*zT&SN7C=N;g|#dGIVMSOru3iv^SvO>h4M=t-N1GSLLDqVTcgurco6)3&XpU!FP6Hlrmj}f$ zp95;b)>M~`kxuZF3r~a!rMf4|&1=uMG$;h^g=Kl;H&Np-(pFT9FF@++MMEx3RBsK?AU0fPk-#mdR)Wdkj)`>ZMl#^<80kM87VvsI3r_c@_vX=fdQ`_9-d(xiI z4K;1y1TiPj_RPh*SpDI7U~^QQ?%0&!$Sh#?x_@;ag)P}ZkAik{_WPB4rHyW#%>|Gs zdbhyt=qQPA7`?h2_8T;-E6HI#im9K>au*(j4;kzwMSLgo6u*}-K`$_Gzgu&XE)udQ zmQ72^eZd|vzI)~!20JV-v-T|<4@7ruqrj|o4=JJPlybwMg;M$Ud7>h6g()CT@wXm` zbq=A(t;RJ^{Xxi*Ff~!|3!-l_PS{AyNAU~t{h;(N(PXMEf^R(B+ZVX3 z8y0;0A8hJYp@g+c*`>eTA|3Tgv9U8#BDTO9@a@gVMDxr(fVaEqL1tl?md{v^j8aUv zm&%PX4^|rX|?E4^CkplWWNv*OKM>DxPa z!RJ)U^0-WJMi)Ksc!^ixOtw^egoAZZ2Cg;X7(5xZG7yL_;UJ#yp*ZD-;I^Z9qkP`} zwCTs0*%rIVF1sgLervtnUo&brwz?6?PXRuOCS*JI-WL6GKy7-~yi0giTEMmDs_-UX zo=+nFrW_EfTg>oY72_4Z0*uG>MnXP=c0VpT&*|rvv1iStW;*^={rP1y?Hv+6R6bxFMkxpWkJ>m7Ba{>zc_q zEefC3jsXdyS5??Mz7IET$Kft|EMNJIv7Ny8ZOcKnzf`K5Cd)&`-fTY#W&jnV0l2vt z?Gqhic}l}mCv1yUEy$%DP}4AN;36$=7aNI^*AzV(eYGeJ(Px-j<^gSDp5dBAv2#?; zcMXv#aj>%;MiG^q^$0MSg-(uTl!xm49dH!{X0){Ew7ThWV~Gtj7h%ZD zVN-R-^7Cf0VH!8O)uUHPL2mO2tmE*cecwQv_5CzWeh)ykX8r5Hi`ehYo)d{Jnh&3p z9ndXT$OW51#H5cFKa76c<%nNkP~FU93b5h-|Cb}ScHs@4Q#|}byWg;KDMJ#|l zE=MKD*F@HDBcX@~QJH%56eh~jfPO-uKm}~t7VkHxHT;)4sd+?Wc4* z>CyR*{w@4(gnYRdFq=^(#-ytb^5ESD?x<0Skhb%Pt?npNW1m+Nv`tr9+qN<3H1f<% zZvNEqyK5FgPsQ`QIu9P0x_}wJR~^CotL|n zk?dn;tLRw9jJTur4uWoX6iMm914f0AJfB@C74a;_qRrAP4E7l890P&{v<}>_&GLrW z)klculcg`?zJO~4;BBAa=POU%aN|pmZJn2{hA!d!*lwO%YSIzv8bTJ}=nhC^n}g(ld^rn#kq9Z3)z`k9lvV>y#!F4e{5c$tnr9M{V)0m(Z< z#88vX6-AW7T2UUwW`g<;8I$Jb!R%z@rCcGT)-2k7&x9kZZT66}Ztid~6t0jKb&9mm zpa}LCb`bz`{MzpZR#E*QuBiZXI#<`5qxx=&LMr-UUf~@dRk}YI2hbMsAMWOmDzYtm zjof16D=mc`^B$+_bCG$$@R0t;e?~UkF?7<(vkb70*EQB1rfUWXh$j)R2)+dNAH5%R zEBs^?N;UMdy}V};59Gu#0$q53$}|+q7CIGg_w_WlvE}AdqoS<7DY1LWS9?TrfmcvT zaypmplwn=P4;a8-%l^e?f`OpGb}%(_mFsL&GywhyN(-VROj`4~V~9bGv%UhcA|YW% zs{;nh@aDX11y^HOFXB$a7#Sr3cEtNd4eLm@Y#fc&j)TGvbbMwze zXtekX_wJqxe4NhuW$r}cNy|L{V=t#$%SuWEW)YZTH|!iT79k#?632OFse{+BT_gau zJwQcbH{b}dzKO?^dV&3nTILYlGw{27UJ72ZN){BILd_HV_s$WfI2DC<9LIHFmtyw? zQ;?MuK7g%Ym+4e^W#5}WDLpko%jPOC=aN)3!=8)s#Rnercak&b3ESRX3z{xfKBF8L z5%CGkFmGO@x?_mPGlpEej!3!AMddChabyf~nJNZxx!D&{@xEb!TDyvqSj%Y5@A{}9 zRzoBn0?x}=krh{ok3Nn%e)#~uh;6jpezhA)ySb^b#E>73e*frBFu6IZ^D7Ii&rsiU z%jzygxT-n*joJpY4o&8UXr2s%j^Q{?e-voloX`4DQyEK+DmrZh8A$)iWL#NO9+Y@!sO2f@rI!@jN@>HOA< z?q2l{^%mY*PNx2FoX+A7X3N}(RV$B`g&N=e0uvAvEN1W^{*W?zT1i#fxuw10%~))J zjx#gxoVlXREWZf4hRkgdHx5V_S*;p-y%JtGgQ4}lnA~MBz-AFdxUxU1RIT$`sal|X zPB6sEVRjGbXIP0U+?rT|y5+ev&OMX*5C$n2SBPZr`jqzrmpVrNciR0e*Wm?fK6DY& zl(XQZ60yWXV-|Ps!A{EF;=_z(YAF=T(-MkJXUoX zI{UMQDAV2}Ya?EisdEW;@pE6dt;j0fg5oT2dxCi{wqWJ<)|SR6fxX~5CzblPGr8cb zUBVJ2CQd~3L?7yfTpLNbt)He1D>*KXI^GK%<`bq^cUq$Q@uJifG>p3LU(!H=C)aEL zenk7pVg}0{dKU}&l)Y2Y2eFMdS(JS0}oZUuVaf2+K*YFNGHB`^YGcIpnBlMhO7d4@vV zv(@N}(k#REdul8~fP+^F@ky*wt@~&|(&&meNO>rKDEnB{ykAZ}k>e@lad7to>Ao$B zz<1(L=#J*u4_LB=8w+*{KFK^u00NAmeNN7pr+Pf+N*Zl^dO{LM-hMHyP6N!~`24jd zXYP|Ze;dRXKdF2iJG$U{k=S86l@pytLx}$JFFs8e)*Vi?aVBtGJ3JZUj!~c{(rw5>vuRF$`^p!P8w1B=O!skwkO5yd4_XuG^QVF z`-r5K7(IPSiKQ2|U9+`@Js!g6sfJwAHVd|s?|mnC*q zp|B|z)(8+mxXyxQ{8Pg3F4|tdpgZZSoU4P&9I8)nHo1@)9_9u&NcT^FI)6|hsAZFk zZ+arl&@*>RXBf-OZxhZerOr&dN5LW9@gV=oGFbK*J+m#R-|e6(Loz(;g@T^*oO)0R zN`N=X46b{7yk5FZGr#5&n1!-@j@g02g|X>MOpF3#IjZ_4wg{dX+G9eqS+Es9@6nC7 zD9$NuVJI}6ZlwtUm5cCAiYv0(Yi{%eH+}t)!E^>^KxB5^L~a`4%1~5q6h>d;paC9c zTj0wTCKrhWf+F#5>EgX`sl%POl?oyCq0(w0xoL?L%)|Q7d|Hl92rUYAU#lc**I&^6p=4lNQPa0 znQ|A~i0ip@`B=FW-Q;zh?-wF;Wl5!+q3GXDu-x&}$gUO)NoO7^$BeEIrd~1Dh{Tr` z8s<(Bn@gZ(mkIGnmYh_ehXnq78QL$pNDi)|QcT*|GtS%nz1uKE+E{7jdEBp%h0}%r zD2|KmYGiPa4;md-t_m5YDz#c*oV_FqXd85d@eub?9N61QuYcb3CnVWpM(D-^|CmkL z(F}L&N7qhL2PCq)fRh}XO@U`Yn<?TNGR4L(mF7#4u29{i~@k;pLsgl({YW5`Mo+p=zZn3L*4{JU;++dG9 X@eDJUQo;Ye2mwlRs^;2BU^Y!BHwzxY1g1bAxEkN)P+Ng&vw!50lAxI=JQ++CODiUEOE;PWQR-+M3EZm=u@*002i-ML`z;Kzw^e1fZk7O*j5?Pj3@~m#(rL zpl*Wd@NI!?C#xX~05qgx!K_f;))?+8#$EsbH^cu1Le=(KIsowcT~$F=-{1V?MYW!3 zG3y6Lp%=JneDY*m%7y_IkuEX`zz9qlV@qddH_)Xw>vpUsYdJW>X)0HgQ`6No>F}cy zdbh?

^2mu02k}j>}P=tFye^q)Hck51$~3P9!W0$vt**;QDa<{9iff{P6V?zn5Pa zaP_jVvu7*lY*AmsV7zdddg5_%zS`(7FZRIyhbPG_dRTpcmxjL7<lpIq2h&K zz}v6GrDy)&IY`^zqV}=I^z(pHVE_levJ@x#=ZQcITpJVAVA^iGE_e2n27-+fM8XVt z!dU5D>)x3F7SaWu^SCnnShkuXIwlL7%O?3NtZ;kM_|KoQylJJ_2rp8Ri;|hh*N;JQ zJHYr-1+KI%OH)nyZo8paxj#U=*jp=i`m#o1&+l`e$k7yyZH-*-o=c>n@6E_YB(Sbq z)Y{tGiHmYeW%e)c&4-1d!{yiSv7u>Jh`qeNxjQEtGGfU$n3w-Zt|*bNPHme0F$gx^ zx;6>T)9kFd)G2XuxPNW=a8)%~$)b7m5Q7>NsG(LP?wqKiAn5L2-{OB-?+dj1I83PQ^?BstM?$1sF>VU-w&u^3O)rn_iwOK!LSGTDO2aDIf-@r|@k-vsoO}kPy&v3vo+3hmHAn>>ZH)@t z(kp@5%eX(QN)PddNdZ59r`#Fev+Oh?j$C)wu64tWB!rTNz)G+6M{k@HzDrxn)U#?a=>4PO1-f zG;DK7dA7tsQob5_A!thB9gSVC&u^9-$E{Ji&*KdC;=tZJXNyrd;J9{9$O*z8IpCfe z(Euvv6dzbXpY9?`9krYcuoO^7#sNq%c}B!Ltb!bzJN-Z&KX46aOsARmg8pfG<82orH1;PQ*c#*D);iaEkJ9x7RI%GR6h z_H6H@*>lwi@W|cf-zb*>>jWLYD_yMJ@8zXQh&SfNhN}A`on5nT#LkB99o7hK+z&iD zeqT@~2IB_g2;&C|^DCTx_tNmRl_ajq4Xlbjpm^{fPb;@KFKCCvy4CRwV@g^0NOJ9!sTiSN4KkbkSI8|c$R9j;nQj~o`W_PcT)T5dnbhXjh4p}Ie*bP&|ST;=Ux zf>i7QQGmFeVZ`1o9;o{%La!zXKw%0%Opl1acFaP8LJ@6)_l;Y%cLUwMRU1zgxG6~@ zVjdll5J9+Mu$f;!5iLUQxr4YNFlda!s2VOUH0Xy-hmHE+O#3|a_x2+8iAo+X;2)IB zd3Y0qudEiJ}{xW ztI$?V{f2NuY$<7%2bG2Cz6q7ME_m(T0t1rGJ`F#QhfsNss-4(I(_%jl$abfZpxEug zMm*a@P;RFg+YKu&kkFAp{5amgf)p#@PaVo3E5$YX?psDraF1NjC4+6SbT(~d8Es~_ zW95@0)q-Ot-Z6TIlZcqlDE~7mRUo671A~|=2>0U?`=kI0*{odiN<@*<_Hq8jpikQn zYEyN8{*ho%n@REod#ug9JII{zHeOsyim$!0p(tWhjhozUc%3K-7t)!MbxEIL)=@`G z8INRUlwEVI3OF!c?mEi9i6>`C&ypXs`GFldSm$T zn}q2IN8Iskez-9xyGINy9kigb{+W$OhuRi9dtm)4wC*Ne@-ApmNUAQv604~1IWBl+ zchxPn^g!%NazAJ>d*)o{#IB`L+FP-wBM&DLuGBDJvJLNx0i`^I-jCrxdEdL{#dx&+ zC;X?oNg?D6__(}4u)*^j(5+Le7Bw(os$s2gi{kTbQtV_TS4IGbr-UHHbkOI5M9*FG zoj@_gS3!|l%@6@0}^qTDl4EBzN?+|jZw8>B?Octfr zM)bRCENYjCp||AAbRbX0?t@Hsb1_==o=!VcGIU%&?| zQ>={{Ii}SJX}8`-VGn2O4b$Q5<3BJCxPl_uD!m4b7#N7{tnHW8%hzrcT!f395uBQM zxv`>-xJk5{E$rS=HvjyUQE3gBcjMk2g|Ea&ppSg;5Ki+|GSfnf!H0hJSA!SjituG( z>qVbNkR#FWmiV3q8nyMX`js$m)8Ty~YP?^KrK{X*=YI64hEDp0QW{&zW$GwUDuJZP zfwdpDKs1Dp4)^fm%<(QyuIl^a$Kutxp|SZGU5BSJjexHXRD5VXlBQxNGDJCk#QR$h zcJV=IDb|=12x;BE$Lc8OUj9tYL>0n+`uxg;GCIyKhi|%Fr;*N}P5JW`l5sTOSEQZ~ z%)Y>e?=u0wSO0J0tSX_8M4|9mQDMZQ{1cUIybG<)%UiSq!j+lm)O66cONw`22Dga^!W{%_y* z9`1h~gl#y@@e3jXYx^semYbA2+c-@zW)GpY#%gyDi=+_sGk&GkY2$h$|*&G@hT* zpScr4ni3Kt!mZ?irSqAF1%!JELZfjXc`vAQeT=^AEmz0^>r#3m8B7#iEyA6-7WuL& za%OzrJU9wzzJq2+sUU97mh%sd?u;oT0(vl|{pJ*lTd5hocjEeooyvD7KJ3IuFINrDB>cPoPZm_&YuTPPdzz~?>qA&qiINB7T;y#7x*nt#P2LP zg>jjA*MHVQu5Cs%KT!XSf`I46>J~W5bqv27U_h85%N`7ICk_a-AA8YK=x4+UA49V*S0V>??x}SVipAU-KU70^?Vs7aA|^mU z6tDvYlpA+xkbu&^2bI1(W=uUB`Em{f^T@KlJAt&D{SuTUoPgK<+%Y;MIJ+J+Nn^#qvqRXsT2!L|W= zJYbhJu!e8Vv-@{TiMmyJGEw?IXYGyY+sr=tuI(296UnWFDWmtlMFQef0bJJYVOkSg zl-@EM#0>BlDPALT#w+5&UsfGh~&B#<_O1n?9vR zT&wz+Zzf;TS1SEl^#O6&;`pVbm64ne5rP<2wKVo+f9OyZrYILqMvTqKPc)*^EF|_wtTU?&S`(Ctx}Yc)qxA5z%6or4(fm4vO7xNUXYmu zZLVqf^qs>M48x`ZJP``JbLV?}VF5rgnE*qh@qnq5Su{pj?W1Gu8858L3N4W+{iXh2 zIG%@By?mbcEKQw%xmSxzdfriGi_*G&hIGu|*q)!%&chR5NpLQI$Nmzd2t=w~iMbs7 zkGAJ)k>oG)BJLOs-@0TrCyKN=>~Akr9Qy=qWi~3qI(n&n^)%57xbl^tR)b-u^P zGE&vU7BLuMW@zn|)F1L%`qFOFT30ILtN(OR;@7Hwxa>gZDM?>viUW+mFo!*Z>oq7> zzt*-pe;?jZ)zTD5VvT6=gf^7kpS=o)s)~+J7*g-HEEF$ea%*YQe)XnT`xIts;l8tH zWkI&NV;Aj@E9gTpWO%;iM%O#pG(8XV4$Mw>z0MP9pYCrfQeDphJdBi6^(BsIoPN&x zqgm@G_K{A3gIWP_1uCEhm+ICjY?E|<2pc%ttT(Nk^^1bKoUdWVT90=wFZ7bV{QH-M z&|}$3M3I{9K_Zl-jE7A(DlKl@`QGA}+@u!Ke$$1b*HO$8{W7ZThmoZS-5HQ9Gk6XVWqppu)SLmtb;fFF-wRBYhff=8MOx3 z^Adc;3f~Oa$Tgd^U2+tgJVh8b2FfZtc{8DkZU3W|)kj9?0;d0nfKc}~9 z5kNxr{T(Ejpda`VE)HZ0G}>c0#H*Sro1eN6xzf>P2)JynUFNRyX(oE`)kYh!TRF^K z(}+3s0zU2kJauXRfU?Lwg*TIdSvx|RitMyI#0VX;kg_mySL`;ub}3R{{g6+%Q{JMss&}#04jG|^xz8XkKZu#m>BSSz~1=E@P9^3QK>Unej~00+u{dT zZOSm*y8kyJQi;bhgNFaEX^I*>M!+0Ux`mq3UC_{@M?B!On34R;^t_{I3XPh4=**^e zb;-y3s_@k}@hCV1RCQz@bA6(6vHW{-m;jGDmP`y+T7Y71`0d#IxM-lLVG(kI-C#H; zZMa$@ZZ>2np|6iWb{@zl8{pqGK%yfT<}Mjq!DYd8ig5@XXJxCIx~?5R;c7Ouoqt2+ zCG++FEV~6u*C)0vw zZkMg+8s*+4f;SSzqQ)d_fC^TR`FC93K9<;3C1z#n?}Ca^&@q==kQcR%;Oo zZSj2VDchzDDMrQzAn(gBaUr%4FFWWBIfuCc!DX3%ZG#{)v_!>cikBv)s9W}*-b?P6 zTA|r^`UyHd(R8#>0c{BcJWsi@kepJKC=oAwM3;}>NgL*L)~b$R^P3JQWeXgNa%Esa z8fNGRA%uFrDXN8EysFEjYTa}DeXnuYvxyUwk**PoEA zj>wi=XP*^rEFfN@6w_~B8sMXpEj%~lR6>9Zi>%0Zr!Y3-RSbKH^MZy4`d{|uc2Q)X z7=}gZ^^ISBEoNEP5ycp#^2vuUn!>|9Nu^udSMh9N^v`}{~ zUhsU4d;Q(tSZa|#x80+N)xvvotJ|n~<2vo-OB`6pGR$h#sM+grAkdA)`?0CgKyS(L zp7%5E1PhAbljL8>A!hn~*YIdLb`6@PR#|&pH$q2gHi|cQIR5<4VW|XnqKQxx#d3bE zbs1wbqOI!i9nZ7Fr(#Y&N3WOppSQK^;(7uPDH{CFK^Sig;Xzi4<$?QY`N6z%?&bZ; znf&?#rBFD15IZ%kUUlY5+XYIC+A(;*O?QWzQpoIoGnt3rc2SUqynBCgvM`LW7uk{E zU|F4H6mL3G5pNpHYoQ1@4)OO1MtAufaC%ua)h;H*TFWY)>&HO(CF)gI#eS7QP z2Z1*vt>TH-A!+Fu_u6HB(tbIMMw>WZ&3=Cg6rzYf7T#eSI&GNUEdQ*wK}2g$LnzjWmZ7CCPU+q?GUz|Q<6QpW9Hjhc@f(sqcqRseku=Y9e*2pROr*3O zb5-3L|4qBPP(flcD{y9AyZV59{zCgxP~6LVLiH9X3gQ-n=fwr09wG;!F~CJ4)%a1| zz>^!3mO!00m9Vnn3W!(*%z;H!J>h5#bit>b^;EWz!% zp?0Iwk}pp?5Qm&d7G0DT0*PKB`%rq)FU)uJP&s}CcXyotDUKE$t8C_|urh>op9Z@u z_VxZR)RgWB+nb1i5aOVK7OKy!d*UGj!OtuyO?$yP^@bsT+AdJ%Ic`=S-*;&rpZdfC3;=kuO0qU$i#bD@$#T+(< zWe83Njbd0}aqSmC@kY}p8hGklFPCd8;7OpvfuWM#w*YNcfHPi|!Bo|n2IcLdH4~2q zn!nkWcVFc`hY%ocI^-k;0AJa=+li}B1F9$;v*!>ysc3Vy!eGC+Y`Rm zjcx0$sxnbJHTjuo|Jn9jO)z`+?!kCVm1jP2#Bw2?inHm&A>~q30sd4Dv71^- z9UvMTAZ^|}=NEwK)FCTQ2z}1WJ0h33Boe2x64O|x!e6k{pGz)rVuv+H-w(skjq(`30g$W!j z#@-#^zdj#@8^j~UV*sFf3e>=2g9s%&^8P2%1tWaAPs*F_e{HYK<8Bb_e*gZ@Z9VS= zx3&V00u9w^7Y#X}07fEeoEuW&Ofo0JH@0)A0z=Gu5dKzXWX+`TB9OeWF7wlFc^({M z@h;3DLO$$&2$j!^kRERh8C@K9YE?4Do|t6yiBSh+jPs04J9(w-tK{vWAD#v|AN1hNieGc z4A=<_m^I&n_g5Q?zD{2diwo;)5^pIL8uH=_BX$9^C7e?+y zdtmQ(!PKUe>%~JsIv48eo!Qe|7BLc`%|;}F?^%bA4KZ*LSO7^{ z;U>I$>l9PBY&P`0nhOp0RjhD)zO6_g6b*-4YW3>aZ*OB59_pxvac)u5@PDxM@1iM>s&KbD`^-u<=#;H#cGq;S^jiT)HVSiLId84eSmpAYORy1iBF&%9qQtcD9??|6*T(LVK}N z9p^Czg{JG@3bJ~b3k2t|$D{@^U1$-8C(nCi0|Lv|s+ub*TZ=PY~hMiX$N<)^c>S!6yA*68@O6q|Khl&Dv-L0W9@y913ojoY) zE`Nu%Y(LR|008kKFaaW09?UYkI$&pPIbW~Jy=adQTwq5+&flCY7-b*Lno8u4yDbh2uZox$}c+5CW z8&AC)@0UruyB?48R_4Xys`Deqc75jdLP>*qC`?tL)$ z5<=ognIq zKV8U^JFh#^mTtE#iR&ScWB_J9FwC6`6*8M99X@tKo&cq@i+u04rqFh>*qN5+g zQl&Ac5~lnCZ&B_1&_NYeRqo>?A>)qHvQHr{I+-S|U*XFs|uUAyA@Dkk&saLa46sE#@j8wmY3tXJFXg|os`Q{BPVz{gCmPZ zNNkE1lJq%x=zv+Z%F6h+E-U>gHA5~N73aFDk4ZU*F^U!@ObmYlpL+J1_ksX-fGfQ# zzrtLns2Lvgc?fs|R~Mj&_XZRtjML!zsi-anmof(2tE1s${q9~9KWr{+xrAaNl<$6Z5ZQCdQpg) zRznP9OJ!;bM;6k6kl*S8W@(A`d0hOOY)oqn^Fzcs%KrMpa>hc(4s3#W`WqHw6RF9L zhi!gK>!phYKgzR&5X4duq^J0CQwq{?GT4v-hm97HEF}zqq}c4p7$^QX^T%Ij?a&pT zH1-b6;yu%>??D+IPB%h0E_GqUiMIfWFLln^Es7OiY!-s5#$dDxThcyqp;2Z$3MDol zk6QTMP?va#k70rFDgjO_owM#rT$N4DzJ*aYue1ZJAL7z{O&7EgIT+z;kP!~ zaGd#dwzKOGCecHx?&3(B|KKV)76fS-D%8!{m=wv#UF2vkF;>85!WJtXTADBef;vmZ zeM}MhK^~iH+J*ywY)A>ZXQPx}QQG|s(slomvu)<*bv+2K^n_(E9jrVr=Y0y6WF< z*l;*Tm~xyF{IW==;ClI!=0EoB6GcxL-yknxutr=e<~6Z+!F$f};&83+xh+Z-mcSSf z{3$B{bQASXqk?bz;#agcvG0Ww6O2!&hfCJHlrPZnhhBb04}AgepP)I$LB4wePn%Lk;d?;(%xVHQLDYER(WgP?KZQ)5BJ zX*0l^G!V8dK~04&et?fJh>vpkeTs}}rZwjwKX=lc%O=FJh0AUdmg+0Isbe+0&t0|# zr+Cb+bsox^x04uMM7rkWg5k_PlKlt0{wUOCSNrgjezS)p>e7B%?FSYmvi%8yuFqiN zB0jOfyUd6YRx@W)C2EOC;qyM3LT>dZ-jTa#>m^gkCkt)72w7zUU}w}V;Dk?X6CCkp zPxqVua_d>Z1W?+b>TlrHPfvmNaywr4=VJLW*0!GQS^U0{cNw13=bS|8}vEcH#d=x>&!Lqmvb)5&(EAPD^W~i6;1KB8_ z^xu%FG>c`VC|@KZfVj-@QJ|al?sqFE7JV27>tiB8f&o=GzDnT`0+!sWcZy^b!jWLA z*e4RUh`D21U@Cg8c~P48w<7cCnSG5UJqpq|v4q;gut^o@B;}B6sgILfWAak*4?@|D z3Cg8G)BJ^lMKidhe9sm5Kkn>JxZMCLkaBwX1@NpM7Gaspt6e5WTnnW0n-1m`C&W z-0>d$>cH=nKf9!(n>GBhMYx%R%BPrxzAn)w=$8KQOuxug%?qjs35OS`>dwRihj4S2 zhC2072Yltqzo1{;V*FHYcn#2R%8ou{{xiQX@Bk*8@-^?pBDa3?;f!08m7##e2EI7E4hV3c3+MiM2#0)Ge`yi8BfKxs+>g& zZZIAlm)3fxc*S*P#h{{sE_I|QceR~m@qMGtjmHZ8Bq;|8HqgtYzY2Wvb*KGj&F)@- z*CYeQlMu%dZAld*Y$Skc{#Ww-Q+?v|xD`XL{=fsa?tB|~=)hCg;_Nj4gt{a~w^NN^ zjnff^ieDhvc1*L-nf947BmgTUkZ9O-3rhJgqY-p27Fga<)A?n!*m2cc^p3!#QTYD9i`B2XmWfde75f@*gNvsjJl1liqk?zY#;FvN*lBh2!`akRuR4M|kHQ>XU>)vxu` zi}ZLDn3qZ6&i%5M0OVB+A$dL)71S*97qUBLWoz@i;^#v!oNAh0B(abd2(}Y&?-y+} z06>!)6S!ZtL-5W)GmoUt%7A{Biu>qMy3C&Guw^gbkz$=&4B2{%$Ry_U5pB z*%$me%&s=oR}CT={oPA*wo>LAsMMU=v~b*L%#;mvle+OcIC+ zPe7`ZEuM3q5QOcCrBrYEeP@OnqJ+M`CWkjyp}~9vpYjAkS&sdPq%5gun#X)f5M{8W zi~Gw`uyyu@v_rXzLqfuyUd8wO!D!uQ%4pzygY~3wlnPEag$7R7qk+S*G?al{^+ARlp-#hA) zB&qC0t7SVvfAToiTb66HmWO4~mVzoH&uyOBMvP*$j>gRJbTnvVYAAC%r*Kv-I!*Bb zD{((s%M#6kOobJW0us#py@E8Ks2XLX9q`#Ra~}v_J74MNvT^^ zf~}#@p-1L7N%uiD4tf;Bp4Ddc6qZ4DG{r>48DcelW%kpJdb|d*y9Rm|3$k~{Z^1M> zeDoQa8w>e$0ey*0fvSh(vg59&lO&xg(Az&;SQvTJGS?#CpBIuN7y&IPW0A@#4;H&Im-C%YoRrTb!)4=501RBr>^s)R_^`yTM!-b zw(U5sUYLzfqSl$w`TWP9LL}rqwhklK$$4x17>_>?KDI>dHehTd+%ZkuLLfoSnEP|u zS4;eSbGa2(vWFWrZrX~bhaB@9<^bthqVA5&Dwghyb%eQ{MRTTr{ju(&CyHNdlh6Cg z&*s6=2Pd}M`wbyKrIzooXRD5~!0eb6#KRIR|5uq@?i>T4K_WBt1Xw^be*PGxkY;;%=WsibIiixY?~i+ zIQl?!HmVDqg%MA@rl$J+X#BZ==y4kWtU0G&e#IS|xaQSVw(9x;G)9kn7iY-DgC}xN zRxg(KIZB(np4xzpoC3MS{b`Un;!+BCxu4*eSFgI>oD)BO)ZMw7t2x2t_}gVirUzDk zaboHX9S}9H8O>Bb(=~^zpvHulkBicZQv7&#Xuf)DzI7%HA}Rfc9VaI^i|=tZqmcW) z5r@6WymhSU%NVRUuhVf%t;itAyXB+jnz*Y7N5x2g>*Y_}kWK7g<1(KnOFYKg+4%7R zv-V#!PO3`j%-&v<%BI$Criw` zB5^|XYNv9|Unfo-O5Yu0JOrJ!It*2W5mc|0X0Y0fSwt8Ipculnw6`D#NM6LEi%~7A zP1=1bxd4%3`x3{$jx*>MiN?t(DgPG#deETR5Fv3KCw{;i&@ zs3FL;-5-vj_D;V-#zlx?osb6i22-}+-^b;oQK7`uc9XNl#zsl5WAeqL>1fnwXElzw zQn}?FGs?#~77Xg)I-E%9Ak9+ynzeCow(f&a9zI9^UOr=-s7D4&aTMCAYn zy)yW-{(xnrfZ0m7n!HcgZbi zP5gD3S8RhTP5W=5q9bc4*qqi8Fq{t%*{mF&MqFSQ&0@mze)G#LF?Gec<@W13ZE@rSd!w$yymY@B~_>yPQq77U3;#{b=R)9{pj>ibcK z<$c6FYqZCYu?JNLpN4lc{lk`|VXUzX-?oGULt-1cL5*8~#Oe?hC zF^XTp+|zy^I6))4AR!gm$p~jJ{QMV!!gy`B1mnY=;;(eR27!B&NbmuE)R7IZxgywR zETXaf^D8&njHs1JV)l4x$j5^srtVkyBA=IxBW5lrDguXanxZhq|e#;b7oEANFha;!9%RZ&pi@?O{Z6O z!K4;3Td!p@S7!P(``Q~nbbeNuyCtY8=K)06?8#XwQp>SY$*3(24`ig$eMHEBq>ykQ zrVe&Ow|&hs;_wA+tOc8!e5s*#Tb_a9Z+W`C739O~JoX`rGBOpqr_9t!rn(-QxWiii z@!?5_gik6%c%AP4sCp30Q!Mg>4%0Oas(6*{=3SLMQeU_q!1$#uzRh*SPQW1H{J%B_ z9*;UYF~l^;AFg5Tyu?38qH&FfT(j!FWu*BXrbEn@437ihEuRo zcF!fAEj;2XMuYr4o+gD1Z|tEo?9WLAV%x7ndivM5`zhH^A3}#i(Ia2q0TZRevP9~H zRR=!C$-D69H@wQ^GH1N6y17^5tu6U^m)fg{~ zSS|eb(S-}#ruk3M4O;l%hFp*wu-n&Aa;47 zVa<6*N@i4x_Cqv^ay*KmtN-4H*nY_9d$?Np>w5J1UW?lc&h3eAuVjtq#_-IWSY7jL zb(MF)BCbD_gDVt~@j`-Q7Go(q#azD`A@rFH80>TP^QIYK1`=NeTJvF=#xXB!DST~s z6-w!dF7R_7q~1T!WJ5XjX#Z?Nt@Q6=zR&Oz`_tpe$OU=CK&;g?M>=HAf2Y``!*89w zN2I)_K`7torTFW7}(?OtB8_JxrLW$pVH1i>{mDbydM;)-PdX_ko!cMq?7 zWE5fp_1}ti9=cV6Zv+XZ>M1w5q>FT`lL4$fz?cWD{oS%dSKHjz(fp^RL=Sda*BZ~% zX;zrznrI6?CoIYTew^<~I+pp>W{xNr+ZM+-%W0Q_Ji4KU_l|^UC8a;otT(Sp)ITuO zN%o`zKiKcvA0Ou)Y#(=Se6tb8HSB5dLz2)_cd2QGIXE8&O)LyAy}|z!JaZbl@cngX zN=WsFi1_$YK!Mj3tnI@)Ut=f&{=F)wBj@rZ*JCG@{w$P53507KLbw}*SoAIWz=`3o zdFbgRl2~!ufFYYDkJhNbTsA1a5=iPq2u*mFJ-Oq6ZvRcw-yJRhQCf=-L%DZ!h~uO6e5LC-ez=0Rj^2*b z!lqESX`YU17GK=nam_)KOz~a2l(ykig4?Dllh*ePoi~<5J9?n$n)1y+i`c7?FQt20#Hk|YOS5H05(S}t^)(=eM~DVIVBMmMZiLb1ory%Sc1 z4~1?Ylw(cDXrB_k)jiv})>%|b4QxY{`(AiGgHWD4NN+3a7SYDH&t1}Wl+0*^pQeB5 z^nwLHQK^E6xg#Px<|a8s?kH-02jtu*Qmu+k9AakgdX5^PwJ*lDXnV#;p*77n}bV8h_VgC$a{=uhv*Isf}n zIKBIaWfcqa1M!Juvkc-6#3r~9wf0Fzt9LSY*R2bS%+b`zZ#DGi-R6a7C1>rrVw(@O@48X2z2 zaXsc-i?!oZ$9|JYq1yxw_Li>80?s$&#;ZzQ18Qv?%I(q%4xek(-SJ8lOKp+(!vHcj z78=2bLsP;Uviqj?fPMQQXOtp}I`AZiIDL%SnT|8!YtQN%6E)_6z2czSI8b zTdUMoyB{O)ezgkA<2`8sdxPmwBslZNqD_l_Eb)ODU z7z+?V?3_~So zrv}l>{v~U-6qkM_hr$hz{)o~&f7Oo@*(p3?-RsgoZkM$~aOlfi<2sS^G$ife-z3}f z(^#70I?oq-71o>=y?T_%C>b7qWmfG`Qsxn^lRjePFsY6@1%FejTvvbRLAuM&TvVF&`uN$xYF0@01fZDFulp_4%@>3MTG z`4^USsf||@fr9}391i5Z?#d11-a=+c3L1x<*V(K*sjr+%z9jh*mIL4mcs4$uC%sW5 znQ;=YfAdR=5@k=9Z}n?(sLkSiav<#1LJt-S+h6gBT(;#3T-oWTSblX;Kos5-a4pqz zVemXDn<;Vpju0U__`{q~My__2!oO%z7~x{49V{T=z`iTS@-Yy-fUH}C*WGZ<`~deC z{3ui;2yv6wP#bbFG+SV@lU?eyk*u=`dt9;Kv0(JoGm)R$XU*mlTleoTN4LOYBwxBI zr4(G~r<_*4#Km{L^_a?Igv1Q+6aywph_n>i0{CG)m*dE8j6o*q$###;q(!ruUe{Xr%5`Hy0c3SeQbRH>!dz58XeJAv8rXq=T;+!M~_cGR#EL`5sWz26AmR*cqx7o|-4$E%)ulfXP za5=wH?fnHx>9#ybJ7feMdsUhLsoA8*e#KaiGhA@ZO8u98uD!yNN3+D0CiW#qaV?+F zLvV>GRxF^0koOLK+3BN_!fSaeZ0OqmS?cr3BvzV*2aCE_w$U%V+1l{fs+gfrk46Y& zD;4{XBrQ^~k&4@62HBRv4ZF3^a3v-S;Et+lRWMb-Cfsm}h$}+P z9<=k%;_vFkm-c@jy}H)LmphE7^2?hdzNb~y;a+!Qx3>Ul1d75Xe;k2@MJtmW8f|$s~flKVt(Zz$Ecyo zMNa`DA_DVzXz(>Esm}ivA0B1BH`4LFfApMNE$X>H2yz*_J@N}*ewMv+!bm#aZQHll zKU|D|X2w}MmdA9a-!}OTIo7_)W*WMdg3dvSHxkkAU$NtjhcECz5jkyx@CR8vR+{u- zcX!!d4oA#o`D2vJAm#LuMY+tQGxSu0ct3XO5^K;%I+5Wuk@)Jon$6FAzls9-1=rlv*}e zQL?oEAJRDSLxt;?*Gx+!bKiq!6S|i-=&+aFBQ+o0nSYYByJL zk)ZnZ4mmmIbg?xG>OP?mjP?9rLlpOXaqWsDH1+9-V#W$BGm-}oq6WWnD>TXcR*3Wc zl{DnC=uLBb4|`z<2`Ql3T^7$q4ii#$%F)W4Th;~^5311;K%_dnP|m?6?%ZPWWQ?7u z%rS|{AYYdh?7_|8>;!fpEHYbrfr)if=p-Muniyb*Q00W>6kaiSVmI{L7hZ9=%>WroA=?ngi?o zP^kR=8gkQ8`n==-B`Cr@)~;;?R8u~Mr{e5XQIo$jw=2l9Lw|U_*qnN z1S84WG*RDmQW~{D<3Q}5DN0S_-dp1lAv&K3fUW66tX+4G&q|EHjpF}fby&W0VQu-& ztFKdmvOtL(JPvFX`{j=*KRNg8Y|NnQh`x(R|35?Hdljwf2zGZIQ#Mk7*2PMNBAS^$Cf3?^2=zH=c4c#qT(F0yB5lL>#6GHO`E>g*z3s8D7#Lr=?Ycn;X6)p zmOTeA^8#G`bExCbLGK<#_|ZlKsKOSFXJk#6A`>P69uwn?h7KrEE*ppmZ(`$V6v)39 zFMr#n{w1z%ukv>e=D^|uTg7hwpXR1qwf#)U{nv+O{2pS@nW67kZ7fn1G<`myC>l+1@X;KPjR!%DGsd8W3yZG-%b{e;%;x85T6U$onu ztXVx(l=OmR@^x(f1MGbk0^leUchCm(awK%Xy(!2|06ZR24*+sH!Uj2(A>QiafzLC` z-(;ElPZcUY++16`H2)V62M3S?S;gcH%9e|hN205I3#Iyp2p3<2llcQQsuS?|aQ=`1 z<716S&!>%<_NJ-lN1F>M3pBd8js3T=>r#wz(K|j9OZqrEy4Wtm)#?A+<<-$A4P$?@ z{y$I6xkh%Zi0)Z<92EgybCJG=hH(;2V-ANj;fm5Mf|H5JwcRMAcgCY6N1^Y4z_GuJq z8&PJCA8c*u337ktJK`a%+d7t4CDMmZ=oc`1KZjWR8xH;7_Se@heY|pcYkat2>|5G1 zn;T8fm&t9vn~D5~80qJc=$B{@ACd5Nw2TdiV2wc2uw;w=p8%}piBUY<7IIHP4!jZq zJzvfI{LFLIfG;_4{_?<8v!#E2q&cAKVx^wF3^Dzmqc#00gxxdvr8@Gzq1`>H-`QmK zBV`i3+%sg*)*AR@1x~&c<^df28XDUTrZgw_M>zO5r4(m)dwuEDzueH7{>I;87zYEi z0l)qqJMBQV5&T&m#IiiW=WRGik76rx(VQ(FaG3!Gyu11;PyOL3(f! zYni8uSpR!R^6$!6oNiC8-*n$5y+m+eI8ch_jW@^@)qL95=vi^}0?P7fG$I{!JB4Dc zjGVvmxY6q^<7+OO{{fNDCd%U)-hLz$-@(5B$dUi9Qiczxipn@}z=4NO zxxTr*-CL?icn>z}Z=LpdF};I`^CMLI>qwgvDPUW=R%zEOA0NnT)mS-n*Hj>0EQR1h z-18#Yvn#9hnS<5~aG-w7|DK+%RBPEhIrlu?z6cj`64B-~JV{-Zw|SH&hu-6d@Mnm| zwFxt*&sIMdMc!qJe=ni@yY?{rdboV)@>A8z>-?tO;%6LO_=i-U+Spic`qlGg(ft)# z$1fa(e}FvxEpa@DHgZcv0D_l7+s&jm&3J6US4d4nrV+6mN5JwTi+|p8WkIJ29v^cc zI4A;ult(%ekwDdBWIE!VEJ15sN02o(TcGkp}n^s%}^ z!Z37*`dR)S%fBrP`DL#c&TVbo*szIxjKhcu-rL>VYg^^;V+rxsRM6kE@Gm0qyDV}^ z+YOq~KrOY`5XKDIqet@?J_E10_5vWCf)IEX_Ux%b_}FH@)qeZ!$=nV5n*$*LuFo8+ zN`vR{b50?CgaF_Z*t~#cQ}h}C+G@rv$J)>CbAPz5`HKcaQNxxfI;LhD`|n`$Wf-)N zyu^1)3GZfQIQ_x9m(IWVuW#Ib@n6Hh8O9;y*&kB>#1FUbTp6xjaGp<>LEc51`5lD7 zN7#J{&FPLl69e00)P{u(+UmwD#x63+(BvnCHHK+mZ2`9HM7lEoVt@wK`LE9$j7tIg zUI3uL*iFTj=Ult~zlQelOcYum*5`5Sz(1^6GkI)`1}(8(^Vj*#H}Up5lYGEJze3}A z2S)9;F2*xHY~TKi|H&M`VNCe;e@Wdi2sbICv+z9c!gBo*n}5Zug9CX9>zlB6L3;wU zouQfG)p!)B&(Qo;AAaO!TTlG=8O2`>hsB4dHm+QqZ!90E+i47A z7m%6N)vblbovR@hAF<)CHjLdOo}p@Y zX@0g(@swx(Dulo{5!AdSBF~}O9ff_(lIj8Mxi#uFptD4oPSecI^hXokRLt zFX7))*8gB>b$ji_zu3P$nfp3Iu4N~irLP}H;XI9>@|3vb_;tdcD$34${$nC_`=>S0 zd;E3I?5k)vr#Z?$p#A)kOMb8Hb}udDylT$hFuojqfria^XEjp)3di`KWBCPf{3ZPS z2WW3s(d4w9iQXAtcJ9%kP6R#$8BG<~v}u&ZQHt_ZB=>X~>&F}URBL?bzGUAD05}$| zRNb^^caqpWgF-rvqMFAp6bNV9EJn(BREWmzFv(M0OVcVLB+-FMA;usi8+gBjtpC`v zyq9tO4Grb}IP70K_AhSU<~J|(#~(Hf;|oxq!#||{LbH3P+Z|j)#QB~l`7Pr8_p$F| zG`t%uvQ-9cdT4||+vI3z?39Vm(C*FA8_w|Bgw>lz1|Qe)08ZSgR=qZj9N)KobYGsh zyg}~PPZpYzhXq8Oi2mc#a6?B>`=`(-badvpTg-Tr=nz@74Xr~1Q((LzYVm_(;6U58Y@iY*^GIDZ%E9UsE!y0~jEO)ag_ z&+Q(6!}zMa`Z^Un*x2xuwX5ZT-ltH$BOHE%==4K0#H(;bTL}DPYLsUB9wi=`Tt`07 zV*RNo@!8zRW3DnYO>ghd$$|EtYI%eF((ve1blIYaI|0Fa0*d%38bKQlDAy^R6m19A z7IqI+!P>hxy0DV&^N%6O5O3D7evMepIF{3Dlp-RPdY7+vM$`J1XcblzhVd1Fz}CwF zW&2NP&7rMjRDO(b{{uLq)7Wie8Pc%*gI(834V%89oMC z+ZN%Yp52Ma{)8X8BR49|HoZgH_+$Hq{nrDqaWWrLWnmbyr{ImALO~qE&zMCMscRXH z4>KMSqx<}|QKSKXt1v>B(I`&CM!f??{H`ZD7s_~Rx_4=NJgu)`7`p(hTR4AywHvEj zw;-}VMicx^i19bDfgfP+CA7A692V2SK(mCqPZ9ztYin532Ll~LZa)Q4_EaTS7I4JA zyDf0v34rU>*zm+haOO{;Ku)3%79tcG3T5Bller&IHC!U(M+4A@m0U*yIE&@`Xav8* z?vI9Las3zPE^qK(*=T>m*loV^PpRm9k2YK*UZs*gbQ%8+!O#1!g=dj&ASl{`GLPe_ z0*u{9^HqJ#l=>cFJ}K;;b`p^jhSlrk9(yS1xb;$maDo zj7J7S&~kcheJgY2O^V?n^te7q=y$?$h9X@yeD`b7?+^?=~*nmI7cs!t8js^y1wC-B*TFl+KAn_v+ z{tznt0$Sm%7-c(*+U>pD+4YUJ(67WjyOh^r?P273SH9$X|lIS4O^| zk^kno_3a=2+#-L&c-*K6I2YEpb64DQIh|z*zeUvlE^+)A4Obr^r0tfySI0H_jIlHB z6Hs1ArXaL*0N`=Q?qogqqt#};MQ@k@*fr$Gl;`X^9G%Ygr_cF^5TF@isiRU`wSJV0 zDtjMFcNsPR5(W9tQTUy3@!?vxe_bR0Z@fi%JD_10Pk`@yhl=)}Y;O3_zv}aFIy!kT z3Vn!(^kNWN!68G7`X2!-4g#Q#G!t}+V4;&4WyfQ$HchYZk6Qxwx&UB#gR=G6r&>Pu zbK?1g=#;-gbMX2t`2HM+q*?za_1o0IS3?bi=Aq`FUN_WtF+I{>dU$gio6a-I2M8lR zj6@d(zFfL-_Qr-q{)X}7K_FC2&2FvBu(*L%d%-)=IRZ|j8DGTiI}q?)q;Ri&kK6pj za2j9AqzC10zKKr0$T?Drh37o+aUpl2U_ZaU(Qe7lk_Z@oYHzZq1;9^VCwGe$YU^HR z1Itk;+7rxj3>iO-Ot0#N|M8*5E-^6>X_|kH9Ees?*{=xk``Gatw1SV;`rW0ta&!F` z|C8P7XBc~iS0Ms!Z*5S~yXJCwAJPABAle}U_zK$aYK&5<#WbtAdw35|#9Tq@AfJyx zVx4r3j?f^@7FbgsHac=|vZqh(+ee|Gwi_*%xdl|(qvGTk91_;KiKLIhOsE*MI{nqq zyi<~4z!Fh{g1}#fQD`0Mx^Q}|?}x60mmj}03U;NiJc#~|RAH&!ypbZQEh=$$e z-pa7-U4~)&hy#CwMt)A)F_!E4@E~pA+R!Ir;BG`~JP?ySQ{OWhea;zPo7l7fk9v$9 z9S!Ukwi}JsxBm}&`%=K3768Mrke4}4yO13Xse6TvV)HDPwUM(*hZ(zo=4Z-NO*(Rz zX%nkgwcDR5yiZh~t(WDMENrg+#lN;|{)VwvIdz%_!&+~R%i@}I;Uif2chRsvM9W@6 z+R*l`UTZS9hw;@(LI6udOf`tC*)m2re>$F5_-Kr^nNEFg-x9c|tH7ytUZu>>F~{Sm zuZaFdAH~?lGFL~13^#TORkdRRvb7tD@1T00j}+gNLQdzgcX7LW{m#*UakGnKEawel zkD^m>AAgN{gcYh3|ZR7avphl zjKv=>gPX5UwQA|WJ<6UG0LW1O<&P=vN&Wf_#vN@NuW? zT|d9Ns*%5882bbj0n<~o9fsu%FX24ewcZ)sHQdN82?AL6>8S_ z3QSZhB7yV&h((GmX}EPNB2&O4?LV+iN#eY!sLuh!STV-NQ+jC}`xhl=SRuCHg6 z^15d_izxL2iF6?f-Hbst(fEhj3!p|oF(L49Ol+wR21L@>vjn=>z>W*!rYM^Irq%;Gh}Cz)>S3~lSF!E<_e&jwbn3(Gky zPjeYRU@oq9u3p{JV-3UDpP)TUYq-5p_RGsfEYD!WM`-uwu}fzP)akwTZXUQW>skG( z+~=1v=%@~sNAUI-@^q1XHcQjpJvkO&&j|oz8rP?%8sgkMId>G9dK5Kto>=rY3wL+W zg|TBaAGH?%{{~pSgZCF4%ZHwe(|M&ldu+ILo8GdCehg#3^OLt}_;;sQZ+hvUXU`v@ z<$vTHT@;C{NW(~a>n}`!Nr10}`lX;UN>aacQz9);{msbwbEP zrZ=cMjII+LY4oqR{mmnFaH3TesrM-@tE&%zX4&0*8)qDpsy6z*V_IcLS0J*^zz&@8 z5-xAjwL5M!=+Ex;H;jGGn{QJ5i~o)W7uNe}N^j=)A)5ck*mWJ2U=7>)SVkUMiu9SW zxiG$fd$x3xbPIs5q7MAmJcNNxTfZ2*bmSGP;*dS%w)T<$Q0MPAs>ho}C7Wdr=dUv= z>74&W4X*<%_E_faS5l=NoM{TD65Yl0Dc!ZoE?;#cb*};*WWM>8t3~o$fS3@ z9G0gMPQB;7PV%Ks_@qswFcJX94$ucL>5~HM@L1CjT1OZnKq#Btd}gXaKO?<^ZO{0z zJtF{g%ETM3Bh_xm+DvX9VdqiN>nF@@cCMlWEL2))2a65R{G`oMd9ID7=(`@{x87} z+=27&>8-#c3vtiPPI?ZF&u3&?b;%F_cyV08+cu2oA~N!5h&&&q(Y`S}QvK;q_m1D) zGbi%g3^^HcBbGFS3JKN3$C06n*wxUAsF`c^aA#;fqN3_$6m8snAzq0>m$2hZ6nB0& zj7v-5_PRaY&oB-y3=wdyN*l$nSdvI*U=mKl7F@!vH5geP52TX>P5i&{kc@5Q+=*!gSa z#6Kyp+(ZSv0o8xjv3%fSd9k;-wDP@nG605Q9AJL%Lkj)gU?r1yCi?g;0{@R;XK%sG z>J;E=A4~y!MM8jrLS`Zlbz-17tRKUsV`0b(v2g9h;og}OV9yAE)&5Mi4E2uJ5&xse ze;%3F#!|adlB&{Wa%4!xgE7e~_4*3dbh4jK$8?h=UdH>6V~poYlACY+8|qruzhNAF zG#0phjkZL}rAXnN-u_E0mznt{c5f#;F-8LiRTPY3{coqRbp)$m?skZFtLcpepU8qsMTyGPUh>Wi@xPzOg{|EQFAAP6oY zQ$NQ0vt^Krt{2zr>3)WBczErfQrYTlA>uEtM~UZPA3lNsxCkq;3QM39f0^0+3QRK1 zIsA927oY>bHt!uTi1V|ReAxKeXfWUtXHN)#D<`Q!F|=?x^O5BUMCTkFR11y@3hM4y z6k`WKk!q)uHtH=%fhEuKv3GP9TP{8Qf4zM3segI3H#*WVjKcs7tGK_Q!FcX5%g>(tSb!%l05&N1{m_z_%|y`*;-jc!9VX7KuI&yg1h5$3bq)3L zIt0Ku7sKi5P%air*SAMU8HRCKX?3>ODl$Chvht(o=scpWtFXg5K~RxAni=DVN3#tH z0>C4+CDPHzd?c{UhK6rlpL+7W08dl^Xx^;1JJsNP+aXinrxr!xB64gB$*1^rdz2TqgvcXD4v}SQ0gnEiPr?_)z1kkm^=Ip7x1l84X$+_J^pDm-}UZ zmF<3i!!X9caS6H26&Ktg#HcYy?jn8M|ztop`_%!&qI<|CRj~B3YL8Q_l>eQa(Qv#pVA7*-; zvMKKy!hV*?9YIDdqHeWVua}^5S^e4>NdgEBq2O21kgqWD1xMjR+}yafymZN;f5R|- zk2De3c^V7`8!JpvZw)*H$FI`_uam?QHYG(C>0sl5QNe_yJpoNffdx3YBb3R^a_~*{ zg~-<@;_{w|0MG~j+*(+uNUSwI%Pb=Qqxkjna8eD3C8vGY>E9^Rj4$DCi$q>wsh%Gq zQ%bzuM&90(C>Mgni(Y8y*?+aZ_8p7<4a4{x^jQH{H)t!AvgFdkg6KR%z-{d6!n%}d zVn#Znk9Zb9IUO4jxr3x_rZt+J0xPUs?R$wio$+gSGXI^&3Bu17D%=aPJy<`HuS+uXvN*{Hrx zWJdZt)tY@WlL9?<0f0PkQ(Jk>MMVF?b4dg^nQ}}uWK23At4m)U7K$99(j#5P>NzUp zYB>yRr`j~Ihy56a@i6@GhZLkTSjo8jm`UDuPOiX6cbywOq1_z+gOPkc68v1cB@hAc z6ba9=@ODk9F&pX{)a=fQl+TY_+0L_ zJFJc5C1QVxXrz6-S%LGvge~V;!qRYRY0Dn-YZ%5?K*;qra~fWz7|uqLD+t)uuvP7h z-WG@$F5Po9KHSip_+%R8k03gO<9D7ZlSoYjyweDR=PCHv>M(1(|LWtv4DeV5z#I5` zH>QqMD349##vDA-;^?uzR7sxS_{yN7XI<2>Z!5n`tkBj|mQBNqm&E#S%RI6&Ah{Bi(}G>B8=a+3N>m?B0?HK%RLx z-?lL80QiMay7s~hRq6QSof`PD3V_At$*kVyT3(G)&hwn}w7_1b*pb(VPHSJ1_LLx_ z(lX`PXC*_g^^X{3n7$jb$SRgP@b9uCzJ7aaY5A#tNj+3H%QeF=z7oka|B%XB?5}wQ z7cf2-nB^*VZNT`1kR&%FPqj@;E~>&U@tiYcWXh|F|$`zV=|QlV06zAyEu zUYuIkmd@NJ%}uTF3$^jx0FO;mJvIS=tl@gr%VJd;T;XCZ5X-C-u9fyBX0xU!Gn=+D9CtTJ<< zeE=#F#)lnp)bR&6)=`3BLW(;054q%}j8*D~CJkbnw`s1q7U$=exhE}HyFW~() zn&A@C$Jlf^<8qzfLhUmQ!`Ka`D7X-His18jcL7%D4pJ8esKhc|3YgfXgU;`}qRAFb z4n}#DVv+zE6^Qx=Qm1Zg(MIUdy3FuOoNe5Wvop73e)eiyn7&L4ttEP@N^gAsvH9i4 zCjed{U)1|`pT{=Rw9BRADgrSOb0p$CMwdt79C|WC^3a%GutOp$SW5Voh!x$S-A#8> za)Fu-8TiTiU#I5O34U}?&NXDlg_6qai^E%6qoWMNFm{30sN5WOH*@YTag0}4S7nwi$xMDBbXsR(yYoTpOurx7?K643zA{^XY~uhPp8z;cS)SFJA?I1j zX_hO}<~%gAn)nO?03tv%IjpCYVLg+`nf9L`WA9y9Nu{6_ELAd1hZI#r!aQWBQ*_E5 z)W~b(;+3Lbxy`?%yCZZB!!UM=cJu#-b?R>~_g4eSjdV*O%T;FhHh} zsvV;rxdj1q1#9Ob@zUzRZ)0B?PiYv2vD@gRVtv`%ge|`W`+Ej9XbHBqpUlyLK)vti z>b*xC<&dxr*H1_u0-%a0zbQR9`fZt&4Ox&CME4ryUk{6PH7wAjFi+>p8UCp3@CTvI zABHLVFf{3GtkVUl!C+^6i!xdh?>5Obdc+Hb&=LIAj!?Jy{kOmWSS|xRashxk!KfaY zuUD!*x@l}Wg6y4#0I1)UI68>bBS8ot(oar4^#oK$DXWTP6_IhTK-%xdJp?KOP&zu^ zLVE)A@7+xY8EtG(s0EfA9Ql$XcMbye_Hd=Ju7ATY9w}S5spkV-^CIV9;dSiMW{gtC zcyLVbNCvRFek4zYav7rFl1$45Y127r zAvKZebY7~6{&T)Ap6?*7_#SC=i6Es(4?$Lm5Cv)600hEl{6I=MQl?2F zt60;^1LI2s>1vJk65N;Ws)b3~!=xWEI>(3~Qj%~F1-OhXyh5HYQ!G~Koh6&~&oGQf zN@!7^{9qaWeu*R9fc?IWvp;FZBRApXuZ0=95<7A+w&i^6(76bQA6k4qH2G4f^EIjQEvfQK zgtHgN+i-6^EQd%1){#_TAp000F20bUARJ9YZ8SPFU(4yIuRn7C{OAS1KOwgv$E!}L zf!{j~2Rx7LpFy_cN2@0rA9oL}I-^T4`fwmkK8Xm2Xy1*TzxE8kztQe<%G;!!V3T#tXlo zVr^+_tLn>TIQtv0L)Q_I+<{&1t6klL{{KGIxs1|S1VFo}i@+~Px1LpF!HwACPTWM4 zzebCQ@{h`r9Fr?@6b^rpE`&KcAExQWN5AYc{ebJtQand;hvvJa1feLask66c2#}14y5qP~kFj`MS zAc=uVg2>Z^QpXBTVUqN8R3O}!@K5W@lVy@e+Fvpn{D-Q;TiAXJ`L+}T-4rU87yr%e zE-H-)0K+gIDLM||)c=$; zvB6iQ!B?fu*JFim#GG#b=^`BflHqkqQ80J<}rPaK=sVVjDlQ13x>3Wet0hy3r!~QnWH5rAjr<$RrGO5FwJs zH|YRE2U+DSNL8$l1`z7t!L&@53bbbci8ZM}(6Ix03gdsHE&{DDIr|9F@LefEe zb-FB7x+Yb=B^j@Z=WX&lBzJcnyBT+>@Uo%@!*hx$Ut@QE@NB~IfM+Z7r%`}NdW z@VOt`4IXU|z#GI{!&Wso$R*}!ijYo14eY7l4?p-1yU!ut{m{64Q$?GM8JG+t%%QNf zH=u%mAI@J>8c;YMJ21IKkOmM=1`%q~Z@l}Lz#em@`dd>PJ@xN4PVZchczL@QH~#y7 zZBP6&4CC=K8yiJd^>;jr-VTUhM09Lh`Q%OK$o)^2dd*Zj`!(tx#v1jdAzM0-PiAE~ z>V5i0{m>q&fV^ zHp-#qQ@6eXANv3`Wqk1GqDQ2ICYK4)r2=f3Tq+o+@#TRe4n_iDGy&1*_Cl^nL z-qpgz-a2fQcKM^yJ^@ZwkHW#JHygj9hO=*DWzLaDu*}uho_lTo3ILfU zUkn>HiP;QP%{-i`3IM&{@#(DCG2`!>e6^;r%s~F$*E^sC37sYt0@cVmcrdGv1`+CD zLSGGfnLwu{jxOCrkSZ~%^4Rffu}$jUV@Cfzs(XoZ+KLiy5r->*uRF@SCL$I z{Bf(86yX4ZVBJq`XFmMbt|H!KN(bR{mu*~w+hGK zkUq6#OJ-$N7UY&3k!$gYTnb0%L%0CBZe;)4VLTu87*q}?XM%Sc5H>JYM zl<_)wb@rqK`QYr+C`L_>jpQ=~p{d>t0ADFQ1DVqpR^W{u;W&Ut_QlVws!wg@@JtPq zl-~b8hcay8M?KOmjV~e<=h&NS*}5bI?uh~w0zS<~sDlWx)H?~_{L^KEba_B~2T%!h z+<@Lrs3Kr=Bd6BXyBZ*|iy~lB4WVDU_}-h)+*e(c+Y)-++kZ`kUH>-><4Lmm4wYPy zO|K6Ja&iIY?>6jJsomu}_oJgP7#UfW0=blk^ap81zD|15o(|-@Q68tufy-*g)R?Iq8yUJ!r+dHQ~g+$G$Y;$-R9F-7-oL3MoxGQg!$qOsyJXtW{#5MjVhnQ-3xt$D?s69FG^vlkzd5{g29{ z^g+4EAB8zSBOU%24*!DG;rOe36%PMK%+j3uYw)I9FyVa|bsfm3cU9pJBvU_$?nh>S zl%5FqwKz?X=E!No+;`wXTKOQeHgD0O zN4+(y-iGbE0`7%WM<5~GcXXVrT^joqS+i@k% z#9MJbUJr}$a#)m$VS&!Yc|I3s`CMr8g|g)?m34O&k^T}K|IO$T?dxoOaQyJ9J^W#f z^h=yVMACngfqW_ep124YdjkAj{nPM~+{CH1I7*9R)~LsN<+atBN8+m=jR3e!F4Oz} z$xk`&rttGLHBkPKbVTE$LhEfx$gPx6WA0CB0HKcG%yC${#Sp1NV}SrwTa9Uc0rsfw z9>O49B2X7UcK4ID&m<`Y?VakfxOGSVR)y$Rqg!q+zh~Y5hGFatPAyWgb-UX`ptBB3 zxQxK>Hq8ART>enw8$asfPS@DAt5xUS7x=r9>Z14RZ^<;A{hZv?sdr^jE`%d=HZ1a) za^9UOXWYl3?JlHy^c!?lYP5uOlPYjGIjz9(ZonApK)wM|fp6Da5GLKPUua_Y3dk&= z*;B`QiyTh{CoTM(>Uv+VrtdzFOG{1n36G&qPwEk<0K$fL$sm~zw4hRqNXE&YD zDr)tz6vNfd%GK`w_Z<@ehGFate)2ZOTxb|#?84r!z)&tBd{Gh5hhx(rRxq7!KYeJ}s)dsA48_Tvd^V{!b0$OHTi@(w;$2 z6b=z5n-Ic}WT_*nL;%gxF2+W6aiAJz*LfrYV67Ntu0YfuXcoV18o3QcgE;vBx~o*d zG)-1DN5?7k4CvhiDh$%N0j$=DCn+1vFEAQFs67PL5L_OE)444W?vKAWU}Y^*ToM;= zdX~+8)-SOAvj-O%hG9G*e((bdm0mW;$gO%;xfZB?v!K>?U)r(}XK7iE#OrcAUJS?O zOgN4x|0ul|7Wln5#~*}_K6J-jhz+N6?(3vHIuqX-dqnw6aQ2Aub>98t=n+IFKd(0O zZc--8{fGv}5CASRSMfup@pd-Pxf!-a??~Kr9*F>OS@bbb6TWK}KSzIrc4-_gv=)w1 zx{DwQ0i9q-?a=YKES=YZ| z7<&%*WGRZgC_-(05bHPkGIeu{I$LXTI_RTyuf;`41Nmf8&cy{fD|33UK9+4hPt7!f ze+iENHlqABc=%0xXAdq>Z+FrW&oRY3sb>_Rn@&-9qt0Ug^O?a>w_`eQ*QC0h8wCi7g!#J|t_ox8<;xyv!nnRjgD)6Y` znleexCD5b;1~U}9ro0wYfthGFbUx|=J-hO{@~@b6p< zGs_>BbK7U*Y;mTXrgO1P=VQxVj7@hX*4*`2b+=;0Eyo-VKjTfLE{*QdAHrZx?$6hU z?M#w(@lR3$fAh1_zG8gBI^uieKB$Ui2fuO#BA{8zIDZs#0X&Kx0Oz`8UW#kQNVE85 zIss4xk_JC+e8k~qQa|-_0Xw90c|awT-a$}N0VOVPKnOG-0vfUKwYbVvxkin6Ya8wB zCvT?if5R}0J;%8peZTnCaIyQlczos8<&o82hlTBTi@D)@MMpl04ZZ-Ue=THApQW$& z=x@W5>mzjw_`VXBanil1Mp7NrWB}hJ%0I|3e558PaQGq}i834Yc0kTDqVMmzzuwg^ zOy|Br-sM@vF*UJ4rvPr_2UXJkLn;7JX;spFDvi-z0mWmhhX@$=2Ds6sfZ(gtgD6bO4U7GE!s6x!ac2EOXs=(A#@5wXD{e}KmKo7LqMj`n zza9j@K%GBK;Jrb7nqUtTc#~c~I~_Dq4?r3r&l)thv8tB=nl5CO=f7Lu_1oxoS5dr< z?|VvT04!^zqzC`Bake_Qaeg36Yqvn&Xmw8u6$eKHVAlHcEQh)6$P zbXFOCGGGVZpoM6#c4BKPr?+0;RiC}9U-tehh+&&laaC7yl6nB9@I#vT0Xl%;keBKg zFzFdV{%97Bvk4lCw((}oJ6UIPTa{wiKh;WOVGP4C_AIBba=1NMANGCN8aQ4a5Zx(R zHWA^Eeg3_He7c<2z5DFnp$0jUK>+BpbEc3>t&Cl*b!5Du)UZJV=!SDt zmy)aPS9bSly1Oa>PE{BD8kEW~P?H@s@H^`8W%;;#QQ*dxfwqw{3(kMQaQ>(Ow4*v}`mCV~_Krx1tO~AzXHylV#Ylo3Lvea0NQ3|Ij)1hXz?BOge#ljUqQ( z8JdCe+G2G$>P_Dzc1-{z-BL8NEL7{xyB3pcK+IH8*j~rErDM!>eJ+!%(X7&S78yVU ztU?jq<|rGnEQj6xv4oZ`rj*d6L zXaHdH1DZqH3s8-mo}<(9O!bhpGUVf~W!bLw0BpKJ?tN^*ap~;~O+>Ew$ekGv4-b%a ztK{iU$iil*42JX*>;5+kV}Ee^H0+gcbjk6m1YYJyTSz*!`S=Lq^FbaZ@2unJq)E=T zT_LSu-rm(20e4RT;Cy|v$eqNN6Yhw_CZg9}y&tQH zfMFQM-seYeg`V{LUU;22t~!=YSg_&9z>SYFzL@lsnb?SqJC1#;GOXta1ovbQ0Q^&~ zv)#8?Z(Sg#g8<$A<%|Q2&mfKa&^D1sOMQ}M4;$C;cD2lSyEC_LxBnT2v9DO|QBiW- z4nZ~|r78WlW0V3mF3swj1_2uPxSJhmh@|>V9TrySC>;*c%CeZ#tFP}t0q_>_P_jHq zY@wh#;;4=@-_=VDhk=O9b0l!~+>OE;P=D*r^}4ibxBnT2vA0A$9RQuk(i+CHLJPO{pa57U=g8-gU6YyHOk7Vr0FW^F9mW@+ zB6uW(5&Fk8DrSIO>-tC=T*S@1TJ(6uuKyc`vA_8E%I!Gx!y%R2g@@RHZCgk5zYU*I zs&~_&ZpLSzg8@gQ=5?xsIzq!XBvUJMlD~3$ao7Cz?g@YyVpo;Cy4iwnSc8?@fO}J$W_%H& zpinQP*B$c|M`^M6%2Tb)T~kfF=b*O<=jd{rnO^&!!WY-z#Qd(E=>cb)PpbO{(8X~6 zvQ>o8&4cu2%SK`M{~Ly}-+2AiMJaM0q6KFi) z8gZDyN|Su3w5D5ouLnT<5q-#Q1zt)g0BXYd*RV{F03P*Z7@x=J5`bnBvP(!O0NQkp zRV8<0Q4aazB?tjBD_91Ul+_=g?xH^bl(z8uq=r*w&-PL5y;d4nb;b^X8eKKHE zoU5~U6)I;uqUv4Ax!vgjc!S(#tmVOT6{l6l7EKiuc-8~(<&2y^ULf&w@E%e2 z75(+F73j3eD8n#}{m1FI-U>y(7{aD)!^mxr#4Rj`uxfS};OC)%v)&Pg&>y)}!Mg^; zQXQMCy{wgg|Lvb>FTjp-Z+8U1tKWoDPom7(W{>Zl;UXuWb zL?eVNor)Nx=h9DIw!@FPTC6iK~S|f$|;>AtA|2ai!2*n1iJZ1umOOEVeDh% zR_vCUlb$%*V&ZKCI0eC3m}Pq)w9CJWys8Ov4gR&-@T>YzpdIJljs<}FF7b2TK>(m& zYjF8hY|}0aeUL$NYrAu`;^1=c5$WPLxEHz(6n^NKGU6er)tHJ1eue?hjm2PU{xkbT zML5^{kvmqe9o<2TJir)#u=B7beLgL<3Zd7>VJ;}{sP7~l;Eu6{5-&^eTNoDDq)?;w z-|^{x{>1f8z^l*+&2OX7P7I0Fh!%LOvC)K=T$SVw9KCjTSNb6sirpz56s+=@oma zyKu9H^PB&?7Tmo}heR$0FdE5~QU~rchnZh0KtHmZ{%J58%skRsSHDU=5rum2?IGh^ zKXVHgD$cltH{-Ep>+h{rw6JOWp6?r;eur_e8#usj4=Hq@3a}f*)^-H8&)uN>C>F8A zNO-~U3Yqh9_oQt83^8LO{u%e_N4b!uSQmRIbjw_1v!YYe!_N2!v3)t83M1Pm%~m@7 zA;@b$lAdRQ)qlncWdWXvEJ(71+oo(lAI#k&JPuQ)**8{k^PxM?B@Nlxr;~uXn8j)*Qu_V25mFY z!aH{>U!l#ylXmHkd7O06Q7pUAfS~ZC&L`$!Rv+J{DCafDX-GOr`bvF4lGxlMfg0ZHOb@#Y4I(;M<%epqL<11>XNU z*d5FLTj}L^=}{#x4@kF(Q_|j6#oZN6q*By z+Rt*|`#*fWI|ozknKHO@?ctSF1Pr+11CU22R*C=BR^w|fYW3cG5(wZi+d>Dw`{4KV z7V*A1&Y1H`JDsUY|DJGg%Wi5j0xIzp32-qcmHZ7Zw>RZQ-ZD3({syHtyeu_%;anyC}ZCFNZVhG?eH@h+HgWk)F%nsD)%x0fU26f8wUeu9M^W zQ2frzPOL_pnwEK6cTrYr0q)=7%fwSzcKZ>a{Ik>=4aJ`UYfhKI2|p%eoX%VJ^p2XvxCD?^9rEltJV%sz`84Fa9l?i0s z|5-Dl>u));<|-X|1DNf3*PlyAsuY7%HZ?^AE&d9YkS;rfo@)dAX)rCn zmT~tXDLAWj-ZJ-$VTx;$p%S;`6Y3xk9lW9TajPF?0jd&HSsg!K-1WUSMxb*i03+gw zGSRh~p*3_t=Wat9Ue{;2GQsTsgcVtGPjA~<1tm3g-IqGp;fD7;xKNH0N(@O$>6Jm=ooq1_7}qGQ8;!YqliUSLTmVJ6^~iSudx zwTJme^o7qn*Kp-@5&)UhP@^0TiXlN)xR#zBWq0f9L+cZ~Aa^RxnPC9Ku|s!(h<|}t zv= z6Uie01IB+sE!s(*u>0@56T$xEZ+J4ER{(*wX*Tp-7Np0{03`KA%tsUD43rq_H)C@^ zCz!EE&3?=++`n>#kI>Mv6JG!P@(}A}GX(i$v9Fjg)%kH%qf~#*QM#!J&_#pcXlMsj zsNk+w6C|7f>S%j_k<-K_x|jI!FwWkBZR< z@S4qkuNI|0DQX@ z%(mPAz9>j-waE?mm~27XEN;Fgx~@Zff=~zhYXypYiSrLGtw(0_k}O+zP~}-NF*2a@ zxj_N8LI;ciX#F)I`$}(Ze3)vl_kd9QbsK*qgr+a%cgg=Bh(gq7Lu-VgoWa!!uuKIA zqK_vl4<12M7FDimtAZs8m)xVSh46sFBbkJ;?bXbUYW@G7ucASnt})Wq>gW)E2p&HR zil$7hUidJ;U-3K8A3;kJ`baFmwfNDu{q3)|#sUB`hpNa5pIx?bNzS-lHlK)AA%y03XdGr$%X(djeebU-LHNVu zQY{Zav5(lRbfLO{4+0teYY<^I`dh!;Q8Q_Qj$ogQV1?=9U1N7gJ+)nc6$Ow7Xkon*lm}w0Hwvk7nte= z;MLX|wbwL;Gn6=vD?!^z^nO0%eLfMxr178!rP^8qp-k!eD=vxc*5i9<>|s$(riGn$ z5Why~U;?Hn%XTZ?T%jD5?23Pjg50Lb{z(Jb{(`@laq3wXWbYBx$a~*nQ5eld+WN6% zn!fn6(%N{HGUb%n7rx}m)o4$}-2EcRX>kcm~ zi}1_hUX>~C+@)V72F4eG`!qB#egE4!zScVgB-7h(ul__Wn*9ubz_7dONd?=`i}9^9 zzJDufy(@aKDQ=z2q0$t@^h^-?K5s;$q^&#ZWyyIrOUk8+;mGa*xwP(tD|2ZO{E-VSbhhHTIxz$a2=Sv zhy`F2H#*fM&kS!MbU*)iM91>_X zAbT`SK6%HBqZ~3>Ea+4eCiwH29YSqM37({eV+Uq$(YVW-Sc-1lN^j`2IkU&9lNNUK z{BXogt(^lA%i?)_ChUQ*UGVM6=~-FNkorL{quJ-`AizBCFSI8Vc14Nj{EiPQ5k2ni z@xh*BC%y-C2r0tAXQ7kTC_|fa1i4rc=?zk)-sP!N5!_S;qKv`$uIjB7) zcnjXaf{~CCw;x-K4S4$OKQpffN-o2S=S8p;#4dF7n=_+z!RUp&e(kk&-s=4h*k8da z5#$HjF%!)UME~qv#Um46$`R(xUby*pz!7AJ7!cE4(@~q1)uG)&5@MmW-v)*o1^da|bF=j`F^Qus-(KV@FH^k}sln}*<_YW4}KVIq;pOM;7Nb>U$ z;TZ1$zgGe51UbU+i^u!E=Z|sr4NIT4sAa(~WuBpb+AwvbC4UTAS~U zkmh{Qg`}#=@#(Nn^sTm)=N}Wss7`XKy%SWrSUOHCM&cKTTZPx+da?87q(t<``wEu2 zsy`-w<1-zC%2l6EiWI4qr7~e90p=$BBM|A~x|k2cbTo!#EWLh*te2Kfa@Cqi5Cqr1 zdROa=lM-?-{S%!PbX)vI1+qq$FSZhX>rwjg)xwe1Y3q(0z-|Jv-1IgWB4~oR9{h=a z=*b)z>9%J{KOUYhy1ADn(%c=F6U}>+kM5{}qIx!D$WY?dbX}h^OvfnSIAC z>ucMuafHz9@I4xp&piT4z(!TFgAF190OcL+13xIjf1M!9Ja?u-G*JU!z!YmI}HQW9onbY!PcG_W7^xx%>S5Xg7zhA05!f`HTgtEjajppX<%`RK0ZU|HF*(%hidW0j8RGYr=!{-VIOc(&N2wLI09sH|l zw)El8w0SmKDP0)>KQ12tD9YhdyyW(T&HCPmrSJfP!nlF2$R&o2j0u)`cP-`fIwlJ+ z|D*~kd&OBn-HbQpCjyYH--X++1BUqmSW|O7d(;hP&-G0f;)T6Z!us*osv|?O6P`@G z^mqY=usaPGE=!5H435YMSrhlFDsn3papd8@vX-hKEL z@j6&{Bb;oRJ@MQ-7VJh(!gZ39ML|a6cNTZdKm&q}BCv>To;`E^9`&p1x&9?x?CLn&3RD$?iGuoA}KeLw| zg8#>-h{@l=kmbqLq4lUMYI!<%Zj)|?T^ylKs9iqYGXfYCc14six0F9A$>SJnuP0a;$66(){zLI4a5woAKL3!C$nS5n z!tg28k-sNlYGen|0ocO+e#GHPz8JK}Kd)nnYi?x$i_-k!Sx|rA59fz0QXnBBeX_|5 zMq*vEySix;fQ6@`O9Li5niV92cINfxm^JIMD^ki2`yF{9eRkLX+nt>nlpyq8#7pR& z()}m@y99ZGugm+-A2YGUXI0U_?nP{xE)oSS>Qp!wLUfTtnSy+0n#-~%Rvc-~b?%bR zcPuZ>6o`YB+1z#cSMFw*aUERks^G=HYzy$#CrgrXN9vf{aAJ{fZ8mZp_>TM>NbIsK z26J=^sE{K?x_@{04HfTG3ZHwPWry>#!qf17;`N$w=;gO%(fytKt@X&8nt}uOuMM1k z7)7_(9r2KE^ganDp!gnhzyZN!=DSHC!++cKz#oxKFT^@tcgQdpJL znaFw!9IyzBgxJuV#mx(#L?UVq`Z{Y)U~^cK(zv<;t^ZGj-x2)4F_&$g90xeXQ2xbR zw_4#=bhI})+=y6EIWfGU2~6{ipGx5|r(y)r{Cr;z`5tQ8cGQFGDR`?F!Ct$zk;FMm z24ZX|&qb(EP{O8Zh3CQLSwEaF={0Wu1%4beY}*|FWR=^9`7e>D;3jsGk{Wo^9-q`C z+hbZ_=%-&6iueoC8HxB{n{Be7*3!mUu#upQmpk|#>i}F*=Afq#2^O2^?kgT3U51b{ zdUTJVKkL2&YOH_7=(TqKKpQOgw@I=A~k!Pia?G#eSdWzd)0IK8Md|e>0vq2Tn zXFwqSVz14M?*Ao;EW%;33Fihc-{UtM_15>-eoOaRi3NF{ychel?<KDP!i8zQmn4(F7Dz}^G0Z={o5JPRfH@jwf@ZkZt zL*fq$M@uL7UPSqgcc2`_6(?jKfzsj?Ndl1@q^G}z`-&I^oGKj(GRhN4i2wBjD7u4j z582o{6G_|@7!nYG!Z!Hrkf2|C@HH$MO7u!zHk4JCWtSe#qFJohp@A^V57C3V0AWC` zRIPCqK8;~2&ZU_DSYXm2O7*?eTHuaVep<%Q6(yq4s^p&#f@QS(go{V8->ZT8k@uh6 z>=o*_8i#-Bkx@u+#z+dPTLd61g}UP^o`YOt^@TQH`g(^R&LHR0EY_dt*CTKfANFJ4#pGa1zujTViA`zbe& z=b7Oq4?%9cEZs`jP>c*!Tz-;Czd|@aF?{3TIQeq0Fywzi$J@D6-lv{4)03^N#Z@~2 zEo|gvs<0y~f(z@&8tjCBqyx~s=|u1Aa6;S)!9l8BWuh4EcKU_p{-%_B{U+{u|AIXI zHeL0pgNbuICV?bAF9_&CXaGhr1e-Pr82!@(pMkNtYko%_#}B!0H7@e%&D!!=x>pS( z{*wXo9-j}Z36gEWMkyqmsG%l5);d|2e#)M;x#;jHDC<6L!GD@j4bj2A09dg9S$C&V zg+Xu_=lNxNcu+Ui%=+bq%Ua@Jd>C2CXZ^Lb;%_JC0D(1uGIDk$R7U8)6aMb4vQX|K zU`sYH$7`}Llt%JKUn2w(NpjwEJ-t%>ahZ+a_ z1tsNHHwSsDWM61WpvM%_j40*dYr!@e^&^W|k#Z|X42BQ3+EgGN9i<(}$^bh{byYg^ z6C9;Ox%$MnKsH~nkas)o2rgOWENop zIYY_%`J}hpQ*n4*4AOS=Kp&I-Jmyu_XFlE=!_e(4-$U^9%2&0V*=JVp97sil$>bTf zj+?Yv#83J)71lkVgA$PZAs)%{SIO`UsUFF{GrI%lvM*pqp+*YFQXkC%lc+druAG;A zN~>Cn2|@zAGPySFJt`BVl~2OK9$%{^6CgGl0q|6%0yG@w~rstveEJnF0iC}xsC>3aY88^(2}Q&T0_B4u>VmZX)Plyx+7 zNH($PJAu1m=Sg70*7;%D4pgQla+`Lf{TNsX0|OW@TN^izYP|Y`AS%Dp(|6I)ZV{#% zU01vojUPsMEnn)CMFzdLOSinH?gNQzm7k}I@{)I=1x?11H@NOQ)8YSM(aj@B+su?@ zl1+~~@F1744M%| zS!l91O5TDjsfed<@LG8gFEDe~j{^9-IG@Y=QUi;}_dDleNmU)y@ zrWHT#Q7ZC3R7>VgjB(2G&p5*`C^YT2OU%UinPd)8>DBBe4<25O|AZ`YB6^Z1?pux8 zZSn=U7*|_kV!~qRvvv?6j}u(Zz!7)zN!bzB|K@9mLK zN-C%UM_pN>&V*$`3du=I^#mLfz%%c>hXOTq5J7kGO@Y) zWfC(H`NJ5n-J)|p|0j&(z&p-UikFabmb%4S{w5le#=rAXB1vb;P0TE<6rbauO zTqS@AE^VE7jELqhk`U1o^Eg=UUN&M&FOVv?;R-Qv>_?jt_>R|6(TmqpF4oLAgh7&h ziUpHxri5cXlDw=EHXk8Sy$qlVEO|eFZF}XR_WSs_S<|BNCyV&f{&>Rh>~Xoqf2wn{ zXE&N8ONOz;piLDE@0Cx}Xu{$eJ|G{FHf#g|GBGO@j1$DV;i=Uv>k&z~O_mXv2oXAt=5=`}w`4vz}%ZDL$3NyVv# zhR*ci{3^VnA;Um8`;^TUe0&_@Z?RXcuNx&Q-0eKox?^My}q?R(p>F=D}@|PqmANT4WFyaR(A9 zVJ;9fj-|1B8rC7BAY+p#sxagcagwQDkkehDjonpIP>s~O@EH>)z{n=9U`*ky;{5TC z+s{rj60Nbs<)Yd)1Qzet=`G2OHs>g9T40oCSjQ@Ag)6=?_eUHf3shZs*-G%xg#4Dl z)c}x@1EyTEd_I~Ztkx3|&M zzB9_UtFp$U)2T-~#zMho0`VF|Hw+S*8{KxrX+^gM{Lv#Af-1#!iVxvDdrJ<1|J~n7D@^S8fVKsX(n+$9-*KK=W_Ftq;#|ajl!6I2F~FB$r~PCefqBMjAMjAT}Ro#UK#F zu|_lUiKbvv7@x__%o9DF`zHuIjJoW2GF`gSTv6|Gw*4&f2)ODgy5@|hR=#Zy5fIdVuc&y#JFO5 z(ojY8ekO!INTWluPVoW0%J1pmWSkD(c+R8@!relSngRy6w=8gKXf{f4UXf?eYvWOu zw(>&M!aXPleJ`mgYx<3~g4l8nbt<9J9A#sUCDP-|mt+3bRc9vX0EkrQQi5B4^KVti z^?J&SpreXu+}G@fV^(?R!;xJr3#VI&NsrUM6-u2hwM3XuI%&^i0;+X2mTpJ@e;@E; z=%}1%|I_$_YM?gozG;k`MOG3~kjHRDxwAjaq>Uko6?@FiUuLAS_j253pxO=j!um8r zZ1MjHMbzEaFi8VwiTtx?SY&z4U<65rdGy2>YZB@rocq!$%I3kmP-HqC?F_ne58MEz zZ9Ht67}=@_((i2ar!;7%+%v*RZ8+}O4KPng6gE1eE90RGrei~iV<=2qr6@hf8bk;% zuF)U8DkFp>V(y+$pU)6b($O?X?xy+@57WYHR)#rj_zqdM>I;8c)aNBnc-(jGL&Pz+ zk>K$MjqL0XqD@UAKvfU-afv?%HxJs-eP;LJ?~L!fB*JELfML*meuJFwQIVYWXKN3` z;7+dZXuD7_PysgZo(Ff0dJHRn=ECA_p?E)NQY>ibh%3ex%_#4`uZk>#LEa?K9E~v? zCGJZy=TK?$vp>q$X}W$+7YghFXf}J}jt{v!rU~%^k9TqYWE-a&UVqy6%o%{Vc)0yrABtdh`F5w&-bIPz+1p^xD z9MW;NaV9DnQjmdI2&8`#00MZaMx#vH$OSV71PJSE5zyb^$f^+FT2X6^QQcucVG{VK ze-T!+_-=AI)~#5WA=#uLf!t$q^dTp%I^6Ij9yncKd?f~T&Dp&4KAb9 z?L}Y37%FXk&-3=sE-qEXDSDgTztXl1EU)aKytkq0z+_pAb!ATWCWY65f9OagH%;)`;a= zM(MitUd(8DPlLH^BpIpj3cQd_Jj9~z>mVv z12u0gpON_4?O|5JkDO=PO-9^fR#oaX*4ky%nmb0{n)m=r?ZRju@}H9CmZ!fUjX*`u zBcUB*_waW5=+o(cF--5j`6_Xs3K~HO8Tu!oQQ_!{xHj}jN}Oi39)zP9&K@XPyL43V z(gBlk2Wf;N3Ao6WHA%3iAZue4z12*4DVsyi`g1h@1^X+w{|2N8t&PXGC3~&31GlTK zR>N#j{Zq*FLa?8-`IiPIRyW83;>5)yjxeG?Bf-T)yJD2hV3Lq@D2O#L2%5Ux}NUSQ8}!cyXv)NgpHwaN2Qh2GaZ0(M|Oq09~TOnH0@L-|G&PK>JFYhuk{ehO~* zZjC*Zvp^fryiQ@;2EFAG!K$EXh*g=Y@Zx4upJ=6GFMoChbHDUv$=f8F>F^x%^ zPj+u$)0@C&P{}imOOgua3+V}f3h1V+U51RpQ{kLoA$6dV)Nd-nP(=~*6WiPh&g~?iKuCwYuyU{R&6Vm!&9w*)Ak~zHT~WGYR(TXi+5t5BKADMz3i^!TsZKKX zW$(W!c%U`rSt{tdhSDpuKa;hIyG8l<67hdfE}4hXqKjWdIoLv-+ZIQ$fZu=dDMiZa zV_r1`*FOgx#!Nk4Eqo#K)(E^sH$SbEv-^6>!k0Pc`lQf!)4 zIKO+J5Z(w|LH$rpJL!k;>Zo`x#bJS*0PFZJ9PVGc+_|?-q%P?o!VF&CyA#azs#W&hsNpaV{9>0q3EV;GCDw*3 zbwk=b5UL^1m)Pu2V$`oMf1#ggA>8U}cG}jj%6Mq$*DRH~I$CXk0cb|r&vn7}jJo}N zC`#$`*y-@F$Dui<$hAbfvfXE^zE$4W&En-{A|5e+}D^Z~GJp!Fj)@Zy=-cAw+pXN@`FW7Gv!1;t8;IV5-fn(ff$?M2PJxXs#`!DV;*9-7jU*PGf^3bH z5T<-q0^OZDJbjw{wdngetFCCzub==;ECV6&nr8g~22o@}9Hot|#!+RXHAL2fv{O0- zEYy(y2^96Th~JN}$n=QNyvn%9BGwxSWv8qiRI8SILeALu=a<%xpX$z@BK%u+Z?&M6gpqx?ve|Ngw-bt z^kk$n*oJ6cpooYNcIS!^*T)WPv9d2Jp=U^zAef7e(RNO+>#Bpe@aN}Gy2R2eZL;*&{{fOvKhMnWqZ_hdQHjYkpUSVg{|BlhFOoqH5>QishVX`-GB!UV0smrohijr)IEvyJ%{ z9>F3cQPB2Sx=R1apAwjzQhcy*pZT^J54`~aF3W7}_%RKu;zB_$OKe;yTtGlK(5$}MEw|cQ z5j&bcARLU%K4{>|`n5MC&PHuZ*?{;6E}bU!SNPup`F^*?*PPn+gazD;R3@E`=|Ml8 zf8Q@H$=fO;ty#XXG+gJv8dZ@V)~0&T0EB%&dRpR81@eE=HJvvY`o)R(wQT;qLrQX6 zpSZ75C<9+`IeJ~nEZd)K2XcqKrAtA*FG>c{1KFXz+`C%fdIB-3qUo-4^Q1T9OH>#^ z^o{uEt#W8EYT|BV0z2~OGibxdJ56|mmm zE(e4Snq`$~Pn!XKcSy7DB)!@hC|Y$`BrL1JJrl8Sj}|25b&C}iH>Pw9MW+O}pJdkP zA0~FEicHh(Q1Fp9Q?|1Lv@?;_NxNCad(DCiiZf$k@6kboGZsPj4G~stzu*aZ^XGb=)BJ-(?`ZRlJ!ago<QDII~4F{RWwZLb9fy*L+uMVeEIz5@bn51yf=y7~Fp*1neCXEjah}*oS<~*mlpP_ZnmnYxHe7CYT!O=6@ zh#xa-o=8|5?2Y5{dSHsTKTnzo3gn61$9K&lmo;N$m0VbS^}4NxSd&gD&i7QXu|>&L zq=G$&@?}xN&l_dX0-G?e0y@lj0>#^*0omVj1^0(qE$e9(V6?_%eq|nSLLj9RjDE93 z?2o6H7p+@dG`>Q_nHVBxj>hQ+TUe9LgVX_R0z$^YUq%|@&d>%G6OR&{c@lal;FWUI zZx)w0c|tff_1j6;^Smf+-M7z?6A1;kRJ?0U^4m(J?12j?a7_qc$o9jq#@2AH0N<=e zW84*+l_xj9chw+wGwP3LdROrvrmX*JY-V|7%larM>W3*D6^CSOxv4u7zFx_8asLWw zeUhQoF?-6tdZ~3nI5u!EQN+k#lV_2%x{QlGrU_`tfp{?w?06&XR}%w)yo`(Z+$`_e-v_SXkKU3QHqN5b_^yh;%7TNd`NzW z8z9rsvB9a)YTAgIdzBfR65QJoDdy`75QH~M$0pPz<#bHe! zU*O?tD*~#n9VM|^?1EqBFm-VWotaCQR~Y}KHRB4XKQl+PSkJ*gI!xKMDv8(s9`gpM zd%|c^FaYz^J&aIApjWPg5YB;60Rjpw)0=pO7YIo_qZDSfr&KAl;eMpf<$r}50v2Hd zn8K@pSF{`$>I@>&C)!+2#&!Q$nq=%BoEZ5%Y?>@`0~E0e@1LJrBQ)t!*7&2R=xgaI z1m{b!vYMpCk=nPByn(#?-;lp7)Es4s^z+)-3n9zrt7kg)Dkk<9*O_`ihOMJNjt)$H zhRA>wgfd1=|3kgwFwd;S=*f5v#YlXPkEHlF-(hc&d;dkK7eeRLf`rxLH3^Z3lVPEy zGD<$Ygb510!&xewW%I&DwW{_{Ab-VzbHHFukwgN~Y5E^=Zs23Q$L;X6e1EA0^UJF2 zklDOQAY83)^b$W}*46LrCsl1mc}8^fFzF!3YYcXKc34wpGlR1H<#K|)d;S^#nG6LP zqwIAU-39rsv$j)q!%$9U>^KK&{Td0zOZ-#AsSt%aGjipM*mg3)+a*Onx>CZ@f@8b{ zdKk;ox8(EpOtCQPo`4Z)X+*LHo~XNI`ke!fl^k!Y0(yrsuL#V;sQZ_9n?SFnL48sX z!$%?x1iQkD^+YVirn&~)`+nbp*ZiFtdut4sYuN~Hwae$%{l^}(3IKfg z-)VQmjkoBdr|I*j#X-x#Sn-C(#?Jb5$8f-3UG{Z`dp<(0#Dh23u0k=;#aOhYBx!`i z@t02;y%0cR+EvFUWs4uYCU>}j*?S@QTC6DAT3m}FJZKc7D)jIItp`&7Vk0e{ zylsMo%YGQK_D5NSCqZ2C#&(=Lf(8= z&_3}q3@_*`DE(8vk`fl3Iau2_mG{nz;x5^lC&7oLTKK0N0SaB53%zk$uagnc(UF+$ zc6dgEb=rIMH(lfJypCmFf=;icpJ?4y)$2B?YOAMv?$hz<24atyPwB~;SLSU4oHeNC z2d3)mamw*g?gS#_JfXeb*)d*>9Mj9}WpXyr3XjunqLco@`px#+ZFu=3V&8>2sts03~yAH|5hn9z#7m#(kgW%TT9N~r2H1lUy*v1h|>UUOT$1Urw3F}EGO`B`!hylbT zY2Xj|D>8ej^%s6@Ba$*2lBI*lFqATH<;Mf%{C}O5H#Gt+yiX(zzx_nKeto zuZ$j3zVswGXsa5PpLd=AE}&G3h*20Py*#eMjJv2Mg`?bWW22(41`*!%4St*^rZj3ejE@CpYr^#arTsp*+z0wn{CHlw7zTwpzRmk|#3~T|cnOXWV!>aergX=pZ4DTs+14 zTD?F`Z@AE7l)yp@+y!Z03KwlH%V@a_ZeD5Q9AnAD z;3sUfII&o-7><=nuFKQSLb|O0Ny=uvjfbb?c7_?-6Uz+!H;d1C&Yj=o7B?(aUH9w3 zjBP8xT-oI7ZV8V1aq&K9bl68UkOncx9E%_url5<>oYSfeK=Wx0?j&ei=r6q@MXNjG z_|qt?l>%hHORZUG7+tk43I~MwG~M1H|Dg0Eq=}R4HKQDzjNCQLo0*K9y=Yr2C@u|v z>e;cw+5lpt8roouf{0qh2G^~)R+0B59FjV3J9OC2F3oDoi2=!)+jyl}cNG;}Hg@!uEe*~Hru6Y(0Jqdcq+Ts#-fudI-QSNsa&U|k!fSJpWI#Ghs7L+r5EKhW%>WKe7PUJpYJ5Z(-;%WFTMP!EHy+tz%^;zdg(fu5mM;7bI zbA#OK-ndOplmn*drQBC5^v!fex`S$@=iNZo?5-l?fJRHo*tc{gU% z6NWjog25a@G|wom^-doUBqH+SKRzeWVnDxd2U$Wv1u*P}C^Y(wnU1yIVWUjeGYjj5 zRxTcX#ETIIE^|FQ9d|e7ZTutzZKFKqMz-sHTKc?mggfw%%~mIp%6Pew0*Tl|uHg?_ zH}9X(4ld>kYG1Sss2}#Ogf-9m^QxQXnSXgmxa8Q-ULN=Junrf*nXnJ_fM#%MfY7fo z^pMHzTZVr5K#jB^l=ZZV`I#H9K(mqGUPu@o;f5 z+q>x$dtGSbBESg3AL{z%F>|nQs9Co-zz8VTL}U+K+=jbOh&~dB&E1P#!bWvrIY%Q0 zf>Ah&2dExvP8p2B=-Vi7+_F(Z9|d|~rh}WLM>wy2%x<5PN=y0ZiBB|K+Y##`t>JC? zHo%n@)W0KH4c)Ew7d)OMF}AJA&qB6|+6Qq$h2rq4w4-0c3IaA{_-#Ta zSu(2YSn$Xc56PW}zE6<(WKOQlvnT}ENanonlCZ~v>7s>I)9iR;xwt?~^fNnEBzK4P zOHP#yL!II`i^Z=qo^)8daybTUfYDiGjUy3FWy;?-x$}lScuT(VL(gYp>eJVO+rY01 zCDzfL7|9gaYQeh-d}H`2^e40?Oz$zCFU|pbKg)HRc`*>&b$xq2UN&C}9cL0TN5(J> zod|pH>4^l<33!9<#o{Z0+|WM?sY_aHB%JUxD$YNgu>wp3$4%Da_|&VS^5|4$s=w1A z)7iZZbSWI&Y|L1ARl#k|{O8#3wi=XNplQ)HU=WI~!S*-D* zi#-}~y$FRA}DM5em3 z#bjr{`;#ywceW|c_TzE$hU4kx$BAECzS+6>gE4Bi z&(3P2Yvx4n)nhCQ04{h0cq9?*aj__ema#VD8MB;8!qYH}yME5{aE*v*3H4D!Y3Z_ddP{BoakFC`no7y*W`fFHBfJ=O!>-K>5|Q>n@H|VIVWazyq#uJ?;#C z*Y8s=D`HqK`YP=2XK@`11hnplTL)YtdDcA-=u>358^((fzNL5H6jQg49lMXJSfTpj z<<&Rg~0%0#%{$| ziPayStrB6`X{G#Z(p^uJFMB&5G#LTi)b8oluk)KHNxj`vJJrP)+kW5Ex+aV}p?qA> z62O>8bT(&rly7s-rsNzwcpDCLcUIMY`M3)Uc|EvWnd|-Qe>Nu8ItK1SV;{Q?m+^|O zO%Ue&)QOIw5-#48!%WEoh~A@6_e zH1-&Rdw)y4|KV^%`}{$R{|igPov;|yi1vBLuN zI%{XK<&gg~=1Sc^*MlweR)8sN6ekD$6G;rQ2uXo|$vR zn*ZF4+b0x>m?4vo2~b4Tsncaf{=}}F1p(VZRLXMv zu)t*5Q4hCxg4gJ%nUf>tBbqMUm7&s-6w6iN9w$_Z*p=hh7N^HJI@$MhcKfR@rgZuD zf)fzf-CX>B^tI8(AoVRDwl;kNmgT$=dBzy`6dO4W9dyWWI?N`i7%SRXSz~|Dl@n|P z{j_s*O@bnn;4W0LZyxvKeI|K>th`rqH1ql|{%(~n<>&4P_FdoWi~px;meq=Fl1K-n z9fVK~z^5zYhU((0*g$@A5U?FY6OmrX?ItS&_^^{n5Ev*x;&j zBp=49S^waPAEf!2`-6R1#BTg9m4=&#j@a0K11{ayoO9=$qcgav;^fb3CrdrX~a)*8fN8~ zVK>Ebb1*8@O17{b$Avkz#YHhz$C63duvT4S^%K?qK|5_HxpwlIuB%%ApTZ+sgr@os z;qhC}Wv^$>{RN+jZ~pNU{}pu2{$gK_zV=@}N3PAnwi266o12ODH|Jq^-MzTo+7>|T z0D_3^Fa{0)<29o`YSFZ8&`Ecjj`2q{O?POJ7pQ19DWU|oMDG*ypiUjElb`6A4*ggL z;S3CtF*=4o+-t3?oPDdg@`K;s7Y%X(dzWK>`)?O}+qLmHhM^Zaj|k(-D8`EGTu&Gh$q*q08#CETcg@YmWd?TIp>$Uy*mAzdRl)CY0WfoLM!Xn)sp zUm&oxJSZo=Y7??$V9&Mfe~H>ODw}jd7U?8H`)U4AMtFuRye<(ny&Cj)#bAly36yb@ zDtHHV0Q&J}Sh!#ePIlx<{lm%8|LAWecL)9>p{uX#I{^*sc7zZA&bjia8=7F2lQ85u zanF~?$(P`$o<+ewj>0^_BK_FknI7A>MHbfZ#9)gvV$;THo!Vtc3f}88^ioh&Ta8xv z`;=h(N!1Un;YQpdBR>|-e#{BqTCJ|G-u=(7?#r&o`?f^sKr%~5MtTZKX;LhIHDdeC zjO1C|?&G-Q6UI;>w^Ko=ww_Nq0A9SrVx@xUU!VIQm039_x8;mnr!l?;-MGLdZopSa zAbsjG=rbCBXK)ofIMs|g8OJ8}E@9tYDAe27_aQsJVPku{ZIXpnO;+EmWVJAEKw#VX z&JW{fP852JMH=EbnScd9!j?}N=T0!$<2d6GmJyWYUPKyYeeCGv02W5)%rv$wwosL* zxF&JDM5egFHd5Q8?Ew&o-gf{xiRZ!fz*c}elBYUMIr9SivRhCACbwiT^v5oEWc zVQIN(S%wdGOODeGn&LZZ{Hee-+zGA6hv416A)0#e%$;-#0o8HQ^>L2Y1dKrG4&%L{ zWTn?QV@zz*zNC;Y_5O=CUA>e`b|A3TT>O4??$AJgrDCQF2w%+PWJ-k!S%ovp_7y# zYo&pgyGHmb?&I58Bv-j5x6947>ec`JU+&vpNBh1+$wi9RMkbELh4?JQ>N#il8@T1q zLH^Wm6k$wsTzX#>^nmRNJQ7`-oBP#1GesZg>(l=pX~+>o|EJ}yoRs(EIA51Zo~1G` zLmSpR?K1NlkYC-s8NQZIZw(e58x`-UlXKMB;8I8P5MCXk^F0!CJap~Hy&hxs0r%{ug?Hsklt z{c-lkH{fFj0B>+V#hPv)Y|^sJ1#Fe!x%I+xAA)l*hEE%@5e-Bp>ESpcJJ3pRfAx(d zj2#eoWL|#RJ~MQ*pEl%3xx{B;W6xVBUlGI4q5PdgSwDsHIEjJ@9|* z@%z90-|Hkm`^qnEUJ&PamUI0J=EDTfRELzq|Gl=)sOLY@85wUxKpy zYgm2>=X}#T^Hs!OPbRW{TDPb2clKJ}s zqZ4+Z@N|;d3)uA>mM_EUK8%7;!a8J4I9u9q^jRnP; zJBg(8EOv>r#`;3joihC(_X`}{1Ksd)Vx7}QfhOLdxHL~ud4Wv4 z&eqiMrtQvqAh}-~@Dpzv_&lhx(5yqwLsR)y|43(W>)v2PZ%E2-P}+RwfBNBfXXz4@ z*#ThRKLY4-`7+7h{f#;e^p)FbYEu-2666zJJN1%w&GFUBey)HZUXKiNv4hc~B}Hn| zD6P{enUm9WTMoha5Aht8%mzi=f_l3jlXsNm!{q(_OMQ@qd&jtk+RxB;_v9gLPvC8* zaD0@F={L@mjKow)))RB~cDC`_f4i@r?*$&7!@u*d%44JBLncm-Mp5xBO6ZrY@Gqb| zeHkV698NibayN-WHvr>Z#{LM4nr8pvxnD4U(gC=SFS5Gmg?J};z`DctenBDD4zmUl z!Y09<&dERV0fC3c=cW%E5PR^tu-wMIeBBxPVOq#O*l4s@?);zM*mnc|{4@?!N&5ap zik?3*Qr@KEw9%?O;$Oyc9^vC*6bX3qI%j}p3Pe&1iu&kYume9GAINy}s9$BvI;Juu z(ofpuZ-&0)Zp$gY=EnI$>g7c$as&2SyZm+C>~0=EQeNi{022RA^i|(B!LFuZUPrKX z51z(N5qASO^aHZyrpwYr&RXk@IH@homs_*b7ZUmorC$364h9#sL;jU$qIxeLKQ&b- zN75tY1~`o;h|=RYc#_1NgadgBF6}sqMnB4uPTUj2Xy`M36j!e(J~P_?S>#0(DHgmx z5*YlbEjFr2Tw0Z=xFS(u)|hA=UV#pcrT;Kfo(Dhbp+5HDq8W{R);7sd>1{;*t5~@U z-G45AP9DNuakW3N*rh4p#OnBu=~ZJ%vJg5@lxsMQad? zj!GG$jA?CQUg$htWjqr3Wu1$)0#Zva>7ZE-9|Oa0RGzenZ0H*J#qrsvaY_?wcgWCN z*zqQOgLfK@)*TyNul~`m|IvYx{{vZi+&@2EY!22YxMfbm6?_(M(6^8k5PBNRoQYvW zw3WGf>7fST=km!K0Ij-ArB|ACOxEd1cSlapRXR!^x-p(X@U)7|u6x^ztDw?8zV?&p zL(vJR@Y;PlCErw!L^#8$KK5zg{j1oyf^R(oEqepk-ZWge<|Mt{Y-Y=~@z!SHgWJuk z^g>FP{2M&@o`Jm%qW)hUz8-%-E5$NVe=#;=QC2!G#+|^OK7|5&98v!iw8Rj~NFM_I zk}&jv21_hHV8XgDruWUh*Aow?Cb~5Mo=(*jTWt!XV*)f0{jW=0oF`jYArr3{6KV4n zeH@@4^WaB4)W;rNki*DjHSQ_&)Di-~H*iP4kNftfYo{MLW9R<(*Y@97|38ldTY47% zpCf&7vpm6(oHdr7cS2uBb{u!kj39o5r>`?Z`?hI8!akF(2GcZO7tx0KMQY24tjQUf zGf%r4?l8YA<9rLcbQ!^T9Z^mj8LZC2wyH7xO8Ta{bQ&5!&mx?1369ku_)9ot2K#34 zZEiU-cPPsiD3WDKTC0iaTZ^Pxy<4!2*(WZv>D%3LS_69ut>&M8U0eOerk#~dTIjQJ zJeb*J5aK_y}U_!|)Z4K-?#B)d#>v)sLM4?WO{`u!)$c z4hLXGY;jF&Vcx(IfYfNp`l?= z34%84>U2mJ5c%K2a$CmuuJrOUtMRw`kX|GYFrqj{=Noi;fhCs0146K?h*lzRmtYvj`zSvQ@`g{t(OC$ip{Na#yoVW?b)k zja$Em7~lYM&`S@?cc(_+`aKCjJ5SDj4dV4xhK3?bmU__Yh1M zFY<-y->~!552Mn?vDoxA3O$39g+kKkVJ`KNYYwBNPQ$T30cZcDupB`#IE4E@j3~Mc z1A%CtteRFez4+JS`OsDSUj%QXRM`j|YU^PCQ$+upQYgrtNm)gPt`{OTI7uS z2c7S?V_$Pm;6+_;ovyH?NSfGv3wicK%l5Bur{AuZoA3X-Z~i|P^>lyH0p!5e0Cf4! zzFn2xa&IQ7%iv-cVW)agY_uzxjxtx&);{@}fls0`liNK%C?8d*Nn^AQ-)UA(@NJsn zn>0dmRMswkIMyB8%*&-;+3}3kd#Se*sc$E!O+EDauD0qHj$s!Kmk+EGdF;IKvORoitT<*TE5*{l zP){M6ic95Vah5%Sd;2t;y)PM&=Wyr01OotPpHAXFPb1zQMcRjRbe2AgFx!_5UrzFZ zx}!z(egV?2kpJnL7~l9$BY()7NwBw#{d%^Zp&hzSE#s3L!*{@pMwtgMHCPn;`1~-^1}vBfjX0c zPou_PhtbxcsZ1FU$(kIO896Vv+!^{vM(G3B$BSI#nm+eOS?gwFuC(rJuARe21>JT3 zuQo6coBD?^Fa+}!QvtsXxxLH>;i_ML61A$mg(uHJw zw23T!Vgz~Emwch1(1_n4lWwTSwuV54fKTqyJ#2QQTEA;&U}_!v<>AZM=#vntCw`4!~#Qvr_M-6Q~}#$JSiO&Ns#JpIf0HXUT^PfA|}J*h01) z=w3ge)O48rr_|FoeCRYe^PD4o4$}7=3X#t2H3Tt?QI`C~9w=ApiXYH?%WEhV);e@w z^2yM|op;w$CKPd2XffQbR2{HWBOn-9H96sBQCXzzIn5wYUgh>%Cc6q=N|;H<1x$iCkh6<0sS&;GGQGh zFsj1=SfIEvFQ%}>R-4oM&a{4dAuY2HeD}xtGae6mKQ#-z=)!e!&cTaHuzw9l-xtF_ z#(^IjmLC_R?D{L;{+9=0sNbK*0W2w>jSdp@)uHi`thacC9i20le-SqBYbaNTP_zb7 zu8JyS`sf(x0nIlRvQD)>ETgtXN~up8bR1Ilgxr-AbX^Y9M{dl_P=yvbraCl}x3CZ7 z*{;ewuXX)5^#A#zUtQG{zt=fL2+~G5Xku>z`)g1yRWYtgVpO@TVp+;WmT<|ulWft6 zT}Y+18pUR_(pPM5WUjrQt!AU`zU=j(j~u=D0x~f;0zVxTtmj{~7ykEsyj0kGGK@^siN18YXl=#c1Gil#=PBVWegFN= zZS8=S&aGDifsMCX64&F!aVY$rd&wsw|0x0}w@PWXvYMv7h5izxxAU z{_*~f#{#m;-%S-<{CtPVA0E;gbh&o-{VVMJ^Tfy%(@O6gzLze4@3+5qpsW779Ke$D z({X=?iq-Q|eIn)*Mdq89`5Rd#Pw1ln93Fs->BDXaq|q?K)72mQ8!ue=o%-6T*%piN zzeFt=kySn`^YXOZl%sr2M);QWnnlt9e=M~-mVeJSHt{tC`2G6h9e#?YLKzfuiX%1T z$~u-MN7(|(#a)~}i~Te38y0c)nvJ5W*tC%)amz%~wrNj$y|IvH11_npA5BY9(|xdV zFQZG}>QqJg(xe%^-@y;npNRXYI;)=>?+bbsca`MF;J703K{3cPhB8kacao66-~ z!}dD%zJ`N;wkGa_sp|0hD=%JB<9`rj?B{Y2O2|VYFH@nhIyIRXa~|5`Ie6mFqCh=^ z;&MpHXjBmy=#g&e$%S;kqe9jdGp%-ngt>}jG$wVLb~ALAZpm4?L6h{M>*EP~3g=4gV^;MLWH8@8r;$$8E&l<|l29)y# z)c7VD*~GC;m$a*?iEHFcy--M-YiY4LT;_Hwt7YrW{;aUlma%U=?JmFiD&F#2jxN1~ zbT79lK(1WWjC<8wnC|1oP>E|-7R~5%pP|*&cr!W@m$^|a7hRd6sO(zW4VQa~vpzD6 z#q_&O`caw&NX!5ty8+yXK`8ZMyeo{p=(GJ^q!l(%?sDQ^eK)OtQe&FG>>WP-x>&=y zHchc{OAMTVsIUenU;z%n0*d6O?-jrXlIF{%^67Lx)6q=$hs>#;o=Qv?8>L6`#%$NgQvz%EB)1+r-=NUa>A|23HgXl(T8-DZXo) z$)<~=s-#&X zQ=jQS(zK<`9$Of0+o)Ew&CM*L9*S)el{mI#>yjRcOh2w2K&}p1=3(UF2o(A#-c1MQ z8Adh_!3nS6w-;d%Bjl;J&CwD1bVzS4Vixy73+bNclMVoW5N@}zshFrGHr|8-ut*V{ z0FKw#n5r=kP8xJS1NK2i{9L*YfCeQ_8${GmW|kp$*PyTeR1E(xwe1g^8;$wPfAja& zaq2FXo1Nz%l#qu;E+TxL9_rb!W-_LpXQAbP35Ne^L?0(ICzDV$-RXmU{&j^l-`bC8 z@Trf&)$h@oRqgUODeLl-TW}}o8XckQGQqdG50)+B4TNawF8Dgw{0;VRLGwCS%?^Gc z!jAlxVsVaKmLW8An>rhaeuv}H-ZygG&ZiJg6wrLEt zQ!8zg7254~Eh!ta(}Vk zmaAn;Q4$-MM)jUzTuj#r%*8meRLCeTMurQ}(gl-p(XlBRmI_>`9>`P=0=Rxd+>iVk zL|8kBHy=WN>2rOZb{EmV^s&V|`I;D%F0C3@|EsIh^;>;xIrjzH)VA}(P`olRR+olE zrDd_jWs2g?P{Bq=xz3*=X>s%``_S$7_J6q?1+V^^-;=WvLQ!hPR_|4cMJ}|7=7Rdc%DnFjsCRtjTh0* zqU`U2hF_=uz5sL=C?%I^wWQ8Us82&+*r|oxO>8%Dys1@{SZ|;#HK3{+xf6hJPIwbW zvS!Fsaa}FRk~&AW2B)II64wz5HnMiB6-80AVUx6IP1@RYVmWnjU(v;;leO1{2OT4&dYcxXs%E{@H>tt*Z2O2Kds z7S}SIRGOyT#(LD?7-74b^`sry0*pMqdoj&Y7(psS1Wt-Z|0vVuqp8YRV^f}}JK>vdF?=!D$Jp5UAA2;$BGx(R)) zUH-J4oL2kivUWcd33SnL1$l!%tmym#zN?b9m4tJkqY?5Zj&GmR2l+$Jun zA_lBN?bVREH5Spf2aU`Ru|SEC%Pc$&YfT0xB69{Cb>|FQr-NK)964^bBt>e}j{`-0 zVDTwh7NJze9Cyoemf&(@97?#2kj5E;cYF-?S)1W3Yg6YULM#e%qXX)cBtulMhF^_7 zj6A+d9|{E)=|@E02Lq)uGh$nZ-DVwevy9`~H(#gORST~LNM8pRtA70NRQbWWj^%$B z>u)$if0`BPYMQv)H&e6x!2z7)=kv11OU3r%e&=wx5!FYyR6H&meKlkH3dHa%Y~nGv z&P@gk6ry0(7`s#cXsYA-?*YZjf zXwr!m@kJ3)sdeWx!#m?-3!{t+Ep}NaE<%JA;d6981-Jz8C=iFD+!ye@3Tnvl>x%eg zMZB9%4uL3MQy6(tV~^-wQ`Vujb(&_q4l<--q*ePkIWIYyC;EkQSIG;O7cRf^z>xo1 zeMQ0X4uED8as*C*?;2QKr?|Wb2Vj{ayUNDuJXhKt0O#d}uEPVXdy(#K*Po#awvh{( z8!7T-6~*^9_PsBh{n*6vgJvQ(3ZvQbA71#L*0Oc44t$C|UMjX9x#%@xsW~_?o|VlL z5}R}4?3dvHJO>FohLY6-G4nkGv?jpoDDa@@?M?KD=p!?j7%4yt_rl7I$(o#!IXMey zJ1p<{S^oNY3A%n$Dh-a?OI(Ywd&*iW; zN&4lHRTQcaG?0-ciEa)xfm1Ye^8z9(hYE`NS{5@dpxPk&Y5;Xuy$vZ5)9 zkzduU- z_;=H?tM*t;hf@bYjG7qiPy>z#U36aD2;Ksm08!(wL+Pr~k74Tz6lp{Je4L&9+utuo ze!a8dw?A`#;OFAAEMM^%r(FY0{wP4A!n#DId5Q{)Y-|}?s29L3xp4355{Z_GgYkaZ3`O1s0=#LJ34nhsULvZOb$v+xurtMQ@ zm^}o>a6M5%V=}DIK{Wy^Ks(3kk7Iw=9(skX>|W8kuTOx}szb<~A>m$0Nvr-3%L*Nn z8979^bg&-;g?^Sl{BXn>s#>(>!`B1sG4--1>E^N5i}%qwsm^MCH}J0uiX~Fx*E{>~ zFF1Dpyw2kHE1%r&ySa4t-#-WBR^P9Nd%wNp_q(&!$@N@x^BOq#?AV8+>cIPHgHxn> zf;RKeo&m}pxJwTz%=`!IZ`0js*lYNe^M?2av0Q;K^md!v2bpcpylOsLzxwNc6pa5v z5FCJqY+s8%eQ_QdY)k>I`7>lft&UMXxJ$9R~n0eFo#- zlq0gLRsV97?$9{hqJF;1C0@r*%wr3f1E22p-*=GkN+18-MK>SZew0OPRFU3a0=ov- zcQusyL{b;l)*EX4ZK^5MP=+P%8n~yV)PLRF$AS6RAJD?OPJnP7>sRno-^|#(yWVKt zxl>Np*T4NgXv5dQLl7K*N8r+BO8>!Elh#J13>#=9(wJWmP7&*!r>6 z0=fcJmww7G*adv7)bah`U|SgfUTMm-Y$EbsgcEQ_Ci%7u^9+^!P`^z?fjHgIj-(=r z-wxH_3<&8Z3n|OAa#HtF? zuhd;s8R@GZ^3f0Rt5b5{#=$Glw^#6+-j{;hdiB=pE9<}cZ^9V=k3e2`6nJR(5~X9U z#dS^^cgbb%p@6=F-RhNIhc~c@g4*)N9{=6)ynE4ar}4Zx&|3B1r&a$_qe)t!DVn1( zzDxZyLmK&O%|OoX{!M|v0l_!xfHXR|<5|ou=^@wd=PVhdEbS#HC8#3p!KrA{S>4Te zrHL1Oa~OUdL30V;`a>*Nu)LE=_Flu7JM)|A28AJhADQ3)d;xfaTGecI(Kg#RBFf%1 zl)a5Idld!rE)K7u@M@LS9(g8(Z;C~${u3J3hJUmUyy92EU@ZJ7hM3NNY1oTms42eto5TBIc1ZeXlRrk4^?`k@V1%bcA57Oa9*6{o8 zGMlSx_-%6T-9{XL^j?o$eEs$B>EKv_M!yUyk!XHtE z=P73GU998CXmca|>Y?I45O{p#rW~)@c}MjLUbs7JU~yBT(h}LiB5}OV)>L6Xb-sZ7 zD!%_@@-fPA{#8El6*|93e^DLEX%%1k4t891hTafz*V>Lg-0X|zUi-y=rXywsz5t;H zU<)|1L9H4kE7oKm8liXKZodV?_zspEIJ}BQ2WCO2 zH%)8q5Y4+$y6gIQmP)+A`TYLc5=RAeSN)7YAmD{k+XISr-^~h~wJTWqC`04!29 z{$o@{^uHu$7bO&-K;UtsI>e_~7}iqd+C+)i z!lu~bDn-Q=tS_-O>(D@2tFFC$Iz0m(&_z2Y&!19yYV!4?@v6~?R_kwI>$Wins4{*V zKFd|H^#0O{U3~4uf2K2Pb`?i#X|gX+2-7jXwUm zJN(51fxu5CmqvZX;3jv~7bhZZr0dW& zcZA(larBmx^qn+oUx)FZ`}6i@F#cQ2E+_%}lY1Ab(la$SWo>j4!uDh){3XNm6pa5N zd?1qfZ4S~4b8Iw?!^1l^KDbX6w#1`qO_6cGIz zN?6A?)~f&Rw+zK55ZJ9~?RqYwP7Gw7Z6Y?ViY@D7fK`g46*BP}g6sxVj}97y)9$mK zG2u_@57k20b};`9X19Wk863VUY~I5D_l!$Ely*AvhkxUH+TgGI27xUi)BtP~(?m_j z=~9$rA3_e_A(l6U@QMM8j`kOE#zTnkr)Z6)XjUfZ zo{V7Wp#_Plrg{O|K@IL+$2mqnB%WlCH9l(ltifPQjL=X8o;e!JRd zhi$9Y`0FR*WAP<*D(e*z^C8kVVf^2~_kKIG@dq1?cgihri&#Ak^q?6FP4| z=|VI4Wm{_$2YOqnaOR9Ybkmk}Tt;y&piFE2`&t0+2SY0SlQ1v4{%y99Tz<5%O=GSrb z@)mYbH#n#x1hUOX2_(*NL<52xFX;JNo@@nO)9sZSzK=He1NepxA6Lgd?J0E!-}x%` zUdhN_<;Z@xFwi^y7ys*0jn4nekH27GO9>9ZHgXwGz)SxYq4uwovqtPvc-x5~P9Xs* z2`UB=R^SN06^EVGHunAi7B4GXioUA~yHbG2_fnfCwADW?(^0xjQ*?tyX_k6<8OFa! zI?G>PJCT2_`&zWSXYtS>f_+246b`;l8=TwNuB>;j+fw}7 z<{yCX=HLM6l)el2q8}lB7b@^A9Cs60#@J%G>}3Hw-c2k_#XIkRHjr$sV1hP{@@i&&PVz^NZ9c#yKBpInM{hxo%+Ms7FwGEhU% zcNuh_cJ*6vBsYcmO&9U&iIuloQn=nQ+5Dd;KWO0eVEnh4pyGEB_s^-=jHbs^mg8dV zX_W5g9MjWqhmYb;j2bq*NG$|J9}{%0`XYQRKY5>j9bBs@86y9t9HJ#TA@}5@+;E5Z zIuFx_(#vbUT>vhCqpnxytARjZuki`%>GEnvHkp{HAttWoV*?Zy*v6}DqZ$sjA?uwE zN}o_bkFEi_I>cA{>$3*uC-&Jyz_W}mbQ_;?)n)u+vg!46ZMX@qX^0L@d0Yl!?4JM4Gu3$gnv3U9NtH;Bvemh8L1F(Z!!t&C; ztED%--e?Z=^fqlAw;&i=;MLzQ33HK!BY4IUc6H_s_@Z>%&uD-DUP@r_>vDwF=m?De z6n#YFe2e>iqrZke9aPsJ(SO$g*g8ng31_ zY5;Z^2!WixMD5=B`88=Z?m_UbiE|JJ`4J9jBbb{wXH}n(iD)ZX^~rPJ{qv(w`X4-B z>)wi#`Bwj9vPKg!OOseeWKMc%8O}iszM!vq2m}KA7OjdG?HcGJ%F>b!5F}Z9P&9R} z1eFtEQG?&rIS($M53hUlEmYazlkkR3=(Sbsy@~a=vG+$%ZExeqwKQ(uP1>^d%K1zB z{NeL|NMK6{H2{x^mtG}Tc&(nqJ=92DRCjD@F!fEtzMG)V9vDMdwTD3DU2+u-O&@}f z&(=Bo`w{(5NtF)EJvm0VklvILzDFgqstx~eww|vauIa;lQXml6J3zX9Er52(i_}`f zB}my=Xn}6;0P|p*G1-Y6UOj!5YFdtsIhra zemd)-^A71)U=?a1>aWQux8P35H9E%c(;>PoeLP3jY-mq^e1H!46RLy)f&Ggz z^9{W1n>v?2^wB%1q&GO*Sh$@wYKxa%(GLkcMn2;%1|A2HOSANkM|wB^whdB1&j%gkJXWX}rWP7xyjldHxNk+pu)UPbN<8nvNx|?!@-lY-# zNXkZM`O}Vpc;EZ)7is_kf&EKf1JFUoA5~?dT?1{)Me&B%;tJW)tg-P58>16|!x_js z2I~cR;`vDxBtT!GQtEiy1sMICP%iId`>#@C-z_@6x7b`;`}5!b@9OkQXmYe02sHq^ zgiDZ|fAS}dWa*a&+U2y_rh=r_a3*3?h$wt&*k(U6ufJ!Vb^(w#pJI>iwclAp=l=Aq z{-sUhv`I&0(LeJ)#5ZM>XQ{%gWK9d=jrZ)d_*d^={{n%)ensWmNBYnk-tpHUKUW~C zH<0Rd!TB)3zK4L08t9Mv>pJQ|&&AT&QaYx;g|}RTE}F%`>)8E{uz3e+=4zXg+pBAK z#ZTw^V&~aH;IR_|zFmZh)sc<6trb~Xv#xrJvh?-L$e$sW{{gJD3es)J-39~=Qke^7 zH_6crb-*ozu|lZ~>S%wmDo12irs$Ro;tk3M#-CH1nj8Hu?Ypq5vHMTx0&=1qK2KkK7XDRi6U_waq4ONL*NV zwzMu$yvU}w#KzX3CbXZB^QuD6gZ}9lazD388=F-qp}WvU@5A`N>ny#KFumI}YxC8< zcWSSH_4On_Kd_q!x__6#zfH-|&}voE+9D;%H6z&%nX=amxxa#ty#vcV!^|yTiD!I0 z9?+))odJJjgz7XY^D;@dXqfNN0IgDynvhQ4ya!A0{sMtOj+%8Wi1@RtkFs_@XDMQg ztQWC;5jH;Z=Xj-&FM5H}LZVgvS48B8h(G=kLC6nNa@V3ldx7X?H5mWhOK1bIi@Ed) z$v-^Q%GOP_Rve7iGl^=JO%w8$BH)jSr3dQ~yl;lk!I_I#hxF9Z{u*>hbe6vxG)>oN zl4hlswb5V8KgsJn>-R}#JrD>SOggc=N7YDYmU2HPfK3o#XnTMRT0_SO(1-t`bp|PR zHlRP2aq@M<6+gzoAGb-~Hj%kjx5>iFds*Wze)GQ%E&X>fLHF+w^pQZVGCG>oibuup zX-nqmjOaWB^01Ih2o(m1%7sJ*Y>f`niky}^bV9DWDSns6Xn{*yhl`)EHUY|SeD~&u zLJ$ZXT(kk-$B4!UVr*MXVU6O_GSX%C;{%v=GTe5=PM_s(kmCiYlsgDSu4o&jgyn;_ zY2TS!Sy{aL;wxcH|2;s^{d)w+D9gX1Qf+ynuWjOqVkAeijGn;WvqJV6k;*aQp@F81 zmlox?y-iQJkLZ|OmqBxbDzqVy`tdr~*Zq4Q9DqO|@M#A?U)ea}s6n<+brBqZxHxB` zcsVns3FDuvA?UaRKjCdA^PUrTJ&U57Et4&*4}P@y`h`CXQ~B-@!Xtn^f=(oK>0eV? z_-d_jVkoXxELB}9b;w!D6c;in+e}8d##1~`hxjHRl^Zh7vr;ju@Y}mx{?yoidI)HAHKrtZ23(x?t|5y;>^GQ{y$rr z{ZFp7y|N1I34#N#$GCi%Wc168^eb^Cu{LQHsnB#3Hxe^i-H>C+Dj$(sbjVzniTExJ z#H$?JCi@<}KVk46Tn_{S0i_cq=z{=lTcj>Q)0k`(-oOm@yhohA!IZoS2jGfCe0wv_ zmjCpBHCU%_Uk?5I_ZYze*n_AO@K3*1PfJIdtyZm4D@0?<%jT)oIXRci(qVIhCZZ2% zptvB#Vx7o{Hr%-%{eNusg98u<1Rli4|GMIb^2v?$ST|9UK}?*H1Xy& zW2;xwXyskQ_ZG+LYU7m`!(={tnJ^B(9*19~j7qI$x;nI!q&@F$WaYnDqvF4BQv7F* zPOh03iCSl-4w%b5ZONyXZ}66_%G5d zez!H(SiT&L|GppugZqSw>dajf^TF`-%6znWs2LYdNoJmOl%0oAKPlp-Am05D>JkgZ zxTGWU_g~a2Q13sKi9le#;%oMES?>k`NOe^Q_e)8*K`e;;&72YQF7{n9!tb%GeHbP6 zd)0UQYOjCqt7`Z|mH$2$IWX4Pn22oYh-B?EFzQc`xD&+LQ4%wbo8FJp zN-*{DC(OO7flwj>f&I&;WZZiJLJ16g6Fz}f`7a;_xb28iEPK^3|0xS!f$ZN#s-t(+A^a&h*9icW z`$0h<5ZIS=WgLlC_NxvcX<&1OMegA6RYUS;*2woIwXd0GdS!h%y_@tl)j0^pf1eTJ zz5UD!V!!l@H~UJZ)iLYh6GGXuLVN~y{kRBEGs%cy>45?$VSl8>0p7pPB^(MyAh3_< z$}}uKf_q3i3_py23u{&EUO_B4!<5|;lItY=R#u>onyFcQ`}@yq#gE3H000>2NklRO( z-~(W9XbKPr><=KzdD9**(-3!!`b}M!mT=%E_PvLFZ$k8c1n=NV)@t80S>J+ryI!CD ze;*2C`R`+bmOmhzyZBDQmR5Uu`i4djc`l&TZaePQzb^^Bk6q7qCLWg1VCs85>S*Qo+7O`lp!2L4v$Rf@J!ZM#*nA*aauY$p-L<$r_x^wO%_?O6K|v4fW5OeV z1IFUt{#G`;U!zP>c$9KiC*qp8xw(HU9>I14q#12N`IJ z3*URaY?4xc7TGc5++pLgqgLE0VLr-+4?$^6qL2&Pn`E6NnzB5K@c~iyuJ9Fk5X`9E^V;up7v$ z`|+3RfIg7X4LATRkkMIe-*m*++0sYcb~oB_JUhz+>$86{-J(}?G{5k?{~!|_fWXIG z6!W#>4~D3}Flnrvwq%ZH&K+l#qd0m98fF3tWe|#`7mGF$jIh8@_&5Ry1OnSlE^lh` z@vnXKQ$+r4$l)f|5%tr&IGQnRZbM#gImb5~+ZnO-xz}el*XYu>L)X55CpZ9sPjKP8 zKa6cNEvLo)o;XX#9J?t)<```JNp^BV*i9qCm>_2F2q5$*vC#?vz1l0JJPiZ_TMUHE z%Nbr&)Fjiuzl9xD82UBrn>TFlIg*=@*N=$ZEhlz1Nu$Ns*=lvA-3;CP0uK@#fWS}X z*?;=uo>HMXl-kmvqM;K)_9T-#Do&0H(*&&k2u|xq!oz+7W zOc%!KZdke-q@-POX^<{Sfu$CZUI{6I1?iFw0qI&~7nY?P1O$U_r9?>qky`58_kZ~2 zW^QLL=A1LnocTR=|H_gYv2@}10cD#Q>je$S(<1r#Q}OG$gBsX3Jd%pqFqm8R6+BMI6ObSynVonr(A*r}4 z5AkVo*`;~u)2umQxMGk%yq9O&=)6ccwn~xezr0pnPgVAeyrX>y=;X}TZ zo-qB`WwYxrC=9ymiVAJ(%bC<$8(-%q*dV`o7L896EF5vd)whyIbt2prvTA&q!2Bv- z5%@Ve+nsLDgMw;+J35c-S-Lz!ipdy|k1Qzp`J@h3F8&(@WIX)xo9$9ya5ehYSLKZb z)PdCStcbpMRO^rNuRjo{qlBuEtnA!~<5%w&$JVgq@~bx)IQY~bi+%5^*)rO<^~(xb ztWmrZUcsqv7SI6cTwr30YD75_4rouh z80F`i#2gkl4(@S;x`|aowQXN&E@It%E=+7{mc%mVxIReA?*2WB1>M5F8B7ktw0~dI z*|ndWr0cOd$L0$fJf|93-4~A5ru@VsEgS0)$uPl9ZpogUCS2=JBK09mP;77<|mLE+tgV7-7+ z+q6jC3LNdG61R*g@KxCmXjc>Oc9g!GiV{_&438FKRb>826-5S1&9_dYYK5E{0Ra^y^c(}mk;?q{}d&PfgBprNTs(Jr6TK?2_s81moWpBa9I6e(@t%4aU7l<$c}H_ z+^rY8ZBY>1E23Gtf3D)uZOyoPE4Hji{#D?{!U_pPMPc)JimKO7k zz5hP2vcEAR*Wf-LBQRiH43$W_(z-9^oze<1tE{mKh#5IXqJ1*W3gR-}|4k<<(pQ^G zEoG)sm!VQ=JEL2Prs6Ao{eFY{C#@-`!1fUbHl{Rg4>Z>iTEVZ-T*{{6Bg1_dQ>x*7lt&dm_-gIZS9QpdShOZ!NA8 zg>}h&CWVU2YtA#Nv{}c&{3mai3*Trd5oju=It7ymrKy{zIdoBL^}Wfg+akHqxO$^T z36V#7sxBRd)?b*cq$_juAY#oq5Roi|A+VwyWRFbT4yR#$OrBJFK-oZ0$W-;*Qh~Dj zbd_FNp)%5&0K&RR8;}NT@d?{hn`J_AJT;L1ERxDLk(E8=m_1B7KN3Acp^lZlStd#2 zMUAr|8kz!sWSM9CCf%iwVLP35HcIFx$+>#n9_@(ljmu} z79sQ!^3FvaI`XdUq5*Vd&{bwmbrrd!Wa2s6DEcS@O-8DIBM>V#c@pp8)SfKJ`pyc4 z!0(90e*x3P9%X2<&-UK<7Y@c2$EYI{%$iEX{fB%S+MW0wES;C-ge`4jBblGQ@FL9n zzw9$Q(v-X=nR7~zq$8E1 zzs`-|0qe1yK-;AX_$!IIsP2>yq3n%%vd0JJ@b?4Aw%GPGwT`qih^tI|^W$WHx7P}w zpyU^s;+lpQ&eiA+nI1N-n`L@n1(rLpML^7bthnLNw3Zka53h2y70oF(rCzE8(Bkfgx0#LgtvJC;A#LslDWoa&>FPqPx*@&MR zAiTf~f~tnJD7(=e@W*pe_Gkg-JAoop0*c8rLm;u7P`X*HZpA$do}1~40?w^qZ@pJO z3yUfaqohd6s8G!+FlmU%QdZSs zq|7!jVS{wop~83+_}NccVqZ1NVj$vBwKR(cP+CN}vF6_=k5dPxOjBD|mF+yL1npM# zigSs9OxVI&>g|88Bb>VgL3{B~rt{O2tTJoG^3%*|JofpVR=xQSyGE!{&ktr%Ihw<^ zQw2(bAmUYYC#&h@J8hGJscPb|la8h89g=swz)9 z&mC7xmK2_*QcBxS43#7syob0YFbK3<8mTmCho$8lm%3c;-F6p(^d=YblB!=Dxea?G-a3uzw@S%}$Ae z_^=87fYP4v+RMMu#lr2u=J*qNkBg=JxLMk$k`k3ldEB!nq=!#nrcZc2$4su@#8z;w5gl>Ke9aKDt?l>AODeVYI^p<(Fc8B}n%qk+0f?f3e#omjB3Tcgjsh z_coa7OoKMuaR@`klGr}AxJCs8sIsatC=lo=^Yh~mN++CwYBBc0r<_)Icx;|6xMf0Z z1W(KUo&xSeBO@Ks%OmVdekEce3Oy>*!^n?}ZTE}?mxbx&*y{#DR#h4r?Jnn~p`Pu2 zghGu#CymSI=nJb>>(1PQ!NOsm8Lwr`2oZYsg$KCjZvd;{4(R~^TbwLk3V;m1_CNBo(x?7WMmAITwX90hZUwj{C>7SYux5|^UmtSAaZDOLV7x+NG`rvI^MLY^7Wa_ z`25VQcfMkM;TsQYkr(orUj)S^S`pLaQW(rH3`^NM!8uj$FcDr@VYu#QaK1&7wTP&n zjhLR`lZ+;OmuW|J*KA=nZAY$&H!VR91h@`;Z+C}!IT=ONy_t9@I~hs`=0p;Z%174g z6!aCQm)GUNOh2W0D*rqG|uwvp$0h+}j+iv%g8s7p< zRvGwg%J_C!yJ>xn=!m(O#*;X*9^MZTo3-Dd@?$KNNe|WAruqI#H5^~DVe$g!J4)>aC|D< za+ME~h;rqEyi}KBxRv7U3C<(SrDIFW7;JXucnLD0Wyir+U;kp{HbCCm6to5mILKDs z8K8l3$;>H7w#^MA)6P zwmZM`!;w!_z%-|@Ri6HlWZlsG)NIbgqH*iPSKk)UeW%5%jsm(AnH-rlR}t`u^3v{Kxn)CTu}HWqS7a-VK-ir>vIE(l*AD4trrD5 z;h&g-qoH@TGLw8_fZ;;m4;7ZpnAjww5-_%DZpZ8vwyG9*kZlCqFN|>Na-REBL!9^x zb7-~j*D_WoVa&UmMWe0{|25S-hu84lp=W#JeU6v1<{~rbPjJ=sFDYQA;|>Kt#t8u zs~?_i5#^$OORfWn;Q&q7vlVg*k|A8bX#|=8X}w&bqRstGTSZ7L$+3agik2gcJKAwv zNb+TLVEzL|vUW~iJ|d@Db7FhuE(x{Xl9kf%Z=`SOfTH)bF(1cjK zi*toC*7II=lbiq~j)L{8#_n!vjt#Zxzakj)kf%G#GvL`v)@z06{%n5f~l_R^#A!3eq!cT2V2O!5)URY7^+U&XI*UE zaQ2AP2hhF-tSsArXG9wtp>G8I1LaMMh2d=p`zD2QiW2jva?jR01sitrU32X``)SGbK5K5jw;?Lh*!GbchtMmCI$S6fB+b0zy)r*(;=EwFg=?8uAFIow ztDrZ(oOv$mK!0Hk1xmusMVT3LaRpa?r_9qmeUIFaU7C7CK2Fn3mtspwMD;Zah$rX- zr3KNsno%6cUU%Z67bUYg}QFC0@Pbz+ERc zhtK-Bhsr99^Kz8bDrKHw82O%-BIM3$K*z-@USa;~t!6wh?lkH_;0>Pd?r9DA6+KZt zH=@Adqp$IpySU@G>xsfUq0iZMc)JY-UhQ}$TIpxX_Zq*n(MZtp+aUOqA(?@WP}Z4;Oqb^9Nr5DxIv0r&KeqNF;3UoGPkjv@mj2iINFM!S zg{eeJd)_nSMJu1-bOQOu+MGGw7rI^s>E4h-H5V3gKuT&d|DiN$s)bxBuhbnY@$x1oHu7XCgq6)!h>nKz_YTiunMJ?O$^O|%}|IR@U6*#o5rw&fyONX z$Aa)ZuJQ(sd*Nf8<#GGNu=+UgcU)#G_}o8?tvzKYYl!b>$8N`ALM>aj@gd2%*?gj8 z&&_UNb6wg+t#ePDg7-Rn{u2-6g$u7i%<1rQwO$pWLPd`2w8XO7;~;c{`DUeim?`tk zvrS<;QNXl8om&;PCF(gU;n-4AF?0h^&IFFypf<poOKsq?#MDrb0sinwMVbW`{##hg@r}1}|ZbG~pJYziH;^KHfXwn1s zC(tg%ttmBj@2_$PGT)_CK{7+T42Hy^Xbn@tAEM7pJDWF3-ed4PZZbhi!K7SVDPi15 z4(x4=W>M$g$-s={Nyh_AugLqj@51LRFIQWdM6AJ{Zy_dd*iSDIKl@rDm%Lou}u)3Ny1%pa`USi60&hT&?}x9#ck4on*ZXT7-KYB zFr}`+sVLbS6{Pf>F4y`SgfkT`W8iSlrX#ZN>+RBO4%$8FTvm~MwuOa2V=e!%jWhqx d=^V@TjT{KjZ>jZqtBZpjI+}(WjcN|j{{x&J$ua-{ literal 9664 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 b{|{}U^kRn2wo}j7|0ATu<;8xA7zX}7|B6mN diff --git a/Frontend/public/manifest.json b/Frontend/public/manifest.json index 080d6c77a..fb7615ec2 100644 --- a/Frontend/public/manifest.json +++ b/Frontend/public/manifest.json @@ -1,6 +1,6 @@ { - "short_name": "React App", - "name": "Create React App Sample", + "short_name": "Bench:market", + "name": "Bench:market | SWE Finanzen", "icons": [ { "src": "favicon.ico", From 6598a2a71a81b7d7cebd498dbec2dccfd621f417 Mon Sep 17 00:00:00 2001 From: cedscho Date: Wed, 18 May 2022 21:34:07 +0200 Subject: [PATCH 04/10] design: made color scheme uniform and gave every asset a specific color --- Frontend/README.md | 2 +- Frontend/src/App.css | 10 ++++ Frontend/src/App.jsx | 3 +- .../src/components/common/AssetDetailItem.jsx | 10 ++-- Frontend/src/components/common/Benchi.jsx | 2 +- Frontend/src/components/common/Colors.jsx | 18 ++++++- .../src/components/common/DoughnutChart.jsx | 38 +++++++++++--- Frontend/src/components/common/Loading.jsx | 31 +++++++++++ .../components/common/SearchResultsTable.jsx | 12 +++-- .../src/components/common/StyledTextField.jsx | 27 ++++++++++ Frontend/src/components/common/index.jsx | 4 ++ .../screens/Activities/ActivitiesList.jsx | 4 +- .../screens/Activities/ActivitiesScreen.jsx | 52 ++++++++++++++++--- .../Activities/Modals/activityModals.jsx | 7 +-- .../screens/Analysis/AnalysisList.jsx | 24 +-------- .../screens/Analysis/AnalysisScreen.jsx | 19 ++++--- .../screens/AssetDetails/AssetCard.jsx | 28 +++++++++- .../screens/AssetDetails/AssetPerformance.jsx | 2 +- .../screens/Dashboard/AllocationGraph.jsx | 10 ++++ .../screens/Dashboard/PortfolioCharts.jsx | 15 +++--- .../Dashboard/PortfolioPerformance.jsx | 2 +- Frontend/src/components/screens/ErrorPage.jsx | 2 +- .../Settings/Modals/settingsModals.jsx | 7 +-- .../screens/Settings/SettingsScreen.jsx | 15 +++--- .../screens/WatchLists/AssetListItem.jsx | 2 - .../screens/WatchLists/Modals/assetModals.jsx | 11 ++-- .../WatchLists/Modals/watchlistModals.jsx | 15 +++--- .../screens/WatchLists/WatchLists.jsx | 44 +++++++--------- 28 files changed, 290 insertions(+), 126 deletions(-) create mode 100644 Frontend/src/components/common/Loading.jsx create mode 100644 Frontend/src/components/common/StyledTextField.jsx diff --git a/Frontend/README.md b/Frontend/README.md index d3b3ef606..f38f96b5c 100644 --- a/Frontend/README.md +++ b/Frontend/README.md @@ -10,7 +10,7 @@ To avoid incompatibility's issues it is recommended to [install](https://nodejs. - Node (version 16.14.2) - npm (version 8.5.0) -Once the installation is finished, for load the used dependencies it is required to run: +Once the installation is finished, for loading the used dependencies it is required to run: ####`npm install` ## Available Scripts diff --git a/Frontend/src/App.css b/Frontend/src/App.css index 31aceeeea..1eb69a871 100644 --- a/Frontend/src/App.css +++ b/Frontend/src/App.css @@ -1,5 +1,6 @@ .App { text-align: center; + color: #30302f } .App-logo { @@ -48,3 +49,12 @@ .hovered { color: green; } + +@keyframes spin { + from { + transform:rotate(0deg); + } + to { + transform:rotate(360deg); + } +} diff --git a/Frontend/src/App.jsx b/Frontend/src/App.jsx index 6383d0456..34da91365 100644 --- a/Frontend/src/App.jsx +++ b/Frontend/src/App.jsx @@ -3,6 +3,7 @@ import {CircularProgress} from '@mui/material'; import {BrowserRouter as Router} from 'react-router-dom'; import AppRoutes from './routes'; import './App.css'; +import { Loading } from './components/common'; /** * App root component with link navigations and routes @@ -17,7 +18,7 @@ const App = () => ( transform: 'translate(-50%, -50%)' }} > - + }> diff --git a/Frontend/src/components/common/AssetDetailItem.jsx b/Frontend/src/components/common/AssetDetailItem.jsx index 15388c3b6..88b0362f3 100644 --- a/Frontend/src/components/common/AssetDetailItem.jsx +++ b/Frontend/src/components/common/AssetDetailItem.jsx @@ -4,6 +4,8 @@ import {Avatar, Box, Container, ListItem, Typography} from '@mui/material'; import DropdownMenu from '../screens/WatchLists/DropdownMenu'; import PropTypes from 'prop-types'; +import Colors from './Colors'; + /** * Formats the date (day and month) * @param activityDate @@ -51,7 +53,7 @@ const AssetDetailItem = props => ( borderBottomLeftRadius: props.itemsArray && props.index === props.itemsArray.length - 1 && '0.5rem', borderBottomRightRadius: props.itemsArray && props.index === props.itemsArray.length - 1 && '0.5rem', backgroundColor: 'white', - borderLeftColor: props.activities ? props.colorsArray[4][props.row.type][1] : props.colorsArray[props.row.symbol.hashCode() % 4], + borderLeftColor: props.activities ? props.colorsArray[0][props.row.type][1] : Colors.COLORPALETTE[props.row.symbol.hashCode() % 10], boxShadow: props.index === 0 ? 'rgb(0 0 0 / 15%) 0px -6px 6px -6px' : props.itemsArray && props.index === props.itemsArray.length - 1 ? @@ -76,8 +78,8 @@ const AssetDetailItem = props => ( xs: 12 }} sx={{ - color: props.colorsArray[4][props.row.type][0], - backgroundColor: props.colorsArray[4][props.row.type][1], + color: props.colorsArray[0][props.row.type][0], + backgroundColor: props.colorsArray[0][props.row.type][1], }} > {`${props.row.type}`} @@ -101,7 +103,7 @@ const AssetDetailItem = props => ( alt={`${props.activities ? props.row.assetName : props.row.name}-logo`} //src={`${process.env.PUBLIC_URL}/assets/images/allianz-logo.jpeg`} //TODO: put icon if exists sx={{ - backgroundColor: props.activities ? props.colorsArray[props.row.asset.hashCode() % 4] : props.colorsArray[props.row.symbol.hashCode() % 4], + backgroundColor: props.activities ? Colors.COLORPALETTE[props.row.asset.hashCode() % 10] : Colors.COLORPALETTE[props.row.symbol.hashCode() % 10], width: { xs: '2.5rem', md: '2.8rem' diff --git a/Frontend/src/components/common/Benchi.jsx b/Frontend/src/components/common/Benchi.jsx index de65ab01f..4042d4487 100644 --- a/Frontend/src/components/common/Benchi.jsx +++ b/Frontend/src/components/common/Benchi.jsx @@ -15,7 +15,7 @@ import ActionProvider from '../../benchi-chatbot/ActionProvider.js'; import TextToSpeech from '../../benchi-chatbot/TextToSpeech.js'; /** - * Template to show modals throughout the app + * Renders the Benchi Icon and Chat * @param props * @returns {JSX.Element} * @constructor diff --git a/Frontend/src/components/common/Colors.jsx b/Frontend/src/components/common/Colors.jsx index ad382cb89..fa31fd502 100644 --- a/Frontend/src/components/common/Colors.jsx +++ b/Frontend/src/components/common/Colors.jsx @@ -1,11 +1,25 @@ const Colors = { BROWN: '#493f35', LIGHTBROWN: '#eacfb4', + TEXTBROWN: '#30302f', GREY: '#f3f4f6', + DARKGREY: '#bdbab7', GREEN: '#4eb96f', DARKGREEN: '#068930', - - + DARKORANGE: '#e47e25', + DARKERDARKORANGE: '#c96208', + COLORPALETTE: [ + '#e57e24ff', //cadmium-orange + '#eb8e1fff', //carrot-orange + '#f19b1fff', //orange-peel + '#b69994ff', //tuscany + '#3a97d2ff', //carolina-blue + '#3d9bcaff', //carolina-blue-2 + '#4eb96fff', //medium-sea-green + '#c1be49ff', // olive-green + '#efc317ff', //jonquil + '#ecb81aff', //orange-yellow + ] } export default Colors; \ No newline at end of file diff --git a/Frontend/src/components/common/DoughnutChart.jsx b/Frontend/src/components/common/DoughnutChart.jsx index 88df38c6d..20e3a1067 100644 --- a/Frontend/src/components/common/DoughnutChart.jsx +++ b/Frontend/src/components/common/DoughnutChart.jsx @@ -4,6 +4,24 @@ import {Chart as ChartJS, ArcElement, Tooltip, Legend} from 'chart.js'; import {Doughnut} from 'react-chartjs-2'; import {Typography, Grid, Paper} from '@mui/material'; +import Colors from './Colors'; + +/** + * Creates a hashCode from a String + * @param String + * @returns {interger} + */ + String.prototype.hashCode = function() { + let hash = 0, i, chr; + if (this.length === 0) return hash; + for (i = 0; i < this.length; i++) { + chr = this.charCodeAt(i); + hash = ((hash << 5) - hash) + chr; + hash |= 0; // Convert to 32bit integer + } + return hash; +}; + /** * Shows a Custom DoughnutChart * @param props @@ -29,16 +47,19 @@ const DoughnutChart = props => { setMiddleDisplayValue(defaultMiddleDisplayValue); } + const getColors = (symbols) => { + let colors = []; + symbols.forEach((symbol, index) => { + const symbolColor = Colors.COLORPALETTE[symbol ? symbol.hashCode() % 10 : index*8 % 10]; + colors.push(symbolColor); + }); + return colors; + } + const labels = props.labels; const valueData = props.data; - const colors = [ - 'rgba(59, 151, 210, 1)', - 'rgba(241, 155, 31, 1)', - 'rgba(229, 126, 37, 1)', - 'rgba(239, 195, 25, 1)', - 'rgba(78, 185, 111, 1)', - ] + const colors = getColors(props.symbols); const data = { labels: labels, @@ -133,7 +154,8 @@ DoughnutChart.propTypes = { defaultMiddleDisplayLabel: PropTypes.string, defaultMiddleDisplayValue: PropTypes.string, data: PropTypes.array, - labels: PropTypes.array + labels: PropTypes.array, + symbols: PropTypes.array }; export default DoughnutChart; diff --git a/Frontend/src/components/common/Loading.jsx b/Frontend/src/components/common/Loading.jsx new file mode 100644 index 000000000..f054091a7 --- /dev/null +++ b/Frontend/src/components/common/Loading.jsx @@ -0,0 +1,31 @@ +import React from 'react'; +import PropTypes from 'prop-types'; + +/** + * Spinning Benchmarket Logo for displaying while loading + * @returns {JSX.Element} + * @constructor + */ + const Loading = props => { + + return ( + + ); + } + + +Loading.propTypes = { + size: PropTypes.number +}; + +export default Loading; diff --git a/Frontend/src/components/common/SearchResultsTable.jsx b/Frontend/src/components/common/SearchResultsTable.jsx index 1829ac42e..3bf0988cc 100644 --- a/Frontend/src/components/common/SearchResultsTable.jsx +++ b/Frontend/src/components/common/SearchResultsTable.jsx @@ -6,6 +6,8 @@ import BookmarkBorderIcon from '@mui/icons-material/BookmarkBorder'; import AddIcon from '@mui/icons-material/Add'; import PropTypes from 'prop-types'; +import Colors from './Colors'; + /** * Component related to the list of search results * @param props @@ -13,7 +15,6 @@ import PropTypes from 'prop-types'; * @constructor */ const SearchResultsTable = props => { - const colorsArray = ['rgb(59 151 210)', 'rgb(78 185 111)', 'rgb(228 126 37)', 'rgb(239 195 21)']; /** * Checks whether asset is already in watchlist @@ -71,7 +72,7 @@ const SearchResultsTable = props => { { sx={{ color: 'white', width: '5rem', - borderColor: 'rgb(228 126 37)', - backgroundColor: 'rgb(228 126 37)', + borderColor: '#e47e25', + backgroundColor: '#e47e25', '&:hover': { - backgroundColor: 'rgb(228 126 37)', + borderColor: '#c96208', + backgroundColor: '#e47e25', } }} > diff --git a/Frontend/src/components/common/StyledTextField.jsx b/Frontend/src/components/common/StyledTextField.jsx new file mode 100644 index 000000000..f6d4bc284 --- /dev/null +++ b/Frontend/src/components/common/StyledTextField.jsx @@ -0,0 +1,27 @@ +import {TextField, styled} from '@mui/material'; + +const StyledTextField = styled(TextField)({ +//Label color when focused +'& label.Mui-focused': { + color: '#493f35', +}, +'& .MuiInput-underline:after': { + borderBottomColor: '#493f35', +}, +'& .MuiOutlinedInput-root': { + //Standard border color + '& fieldset': { + borderColor: '#c4b8ac', + }, + //Border color on hover + '&:hover fieldset': { + borderColor: '#493f35', + }, + //Border color when focused + '&.Mui-focused fieldset': { + borderColor: '#493f35', + }, +}, +}); + +export default StyledTextField; \ No newline at end of file diff --git a/Frontend/src/components/common/index.jsx b/Frontend/src/components/common/index.jsx index 6b34f1a65..fb5004cca 100644 --- a/Frontend/src/components/common/index.jsx +++ b/Frontend/src/components/common/index.jsx @@ -5,7 +5,9 @@ import AssetDetailItem from './AssetDetailItem'; import DoughnutChart from './DoughnutChart'; import Benchi from './Benchi'; import Footer from './Footer'; +import Loading from './Loading'; import Colors from './Colors'; +import StyledTextField from './StyledTextField'; export { SideNavLeft, @@ -15,5 +17,7 @@ export { DoughnutChart, Footer, Benchi, + Loading, + StyledTextField, Colors } \ No newline at end of file diff --git a/Frontend/src/components/screens/Activities/ActivitiesList.jsx b/Frontend/src/components/screens/Activities/ActivitiesList.jsx index 58bdcb271..5ec2127ac 100644 --- a/Frontend/src/components/screens/Activities/ActivitiesList.jsx +++ b/Frontend/src/components/screens/Activities/ActivitiesList.jsx @@ -17,7 +17,7 @@ import {AssetDetailItem} from '../../common'; */ const ActivitiesList = (props) => { const [, setListDropdownIndex] = useState(0); - const colorsArray = ['rgb(59 151 210)', 'rgb(78 185 111)', 'rgb(228 126 37)', 'rgb(239 195 21)',{ + const colorsArray = [{ 'buy': ['blue', 'rgb(59, 151, 210, .2)'], 'deposit': ['green', 'rgb(78, 185, 111, .2)'], 'sell': ['brown', 'rgb(228, 126, 37, .2)'], @@ -77,7 +77,7 @@ const ActivitiesList = (props) => { - {activitiesForEachYearArray[index].length} total ·  + {activitiesForEachYearArray[index].length} total ·  {activitiesForEachYearArray[index].filter(activity => activity.type === 'buy').length} buys ·  {activitiesForEachYearArray[index].filter(activity => activity.type === 'sell').length} sells ·  {activitiesForEachYearArray[index].filter(activity => activity.type === 'dividend').length} dividends ·  diff --git a/Frontend/src/components/screens/Activities/ActivitiesScreen.jsx b/Frontend/src/components/screens/Activities/ActivitiesScreen.jsx index ad290cd3a..576c619f2 100644 --- a/Frontend/src/components/screens/Activities/ActivitiesScreen.jsx +++ b/Frontend/src/components/screens/Activities/ActivitiesScreen.jsx @@ -156,13 +156,51 @@ const ActivitiesScreen = props => { Add Activity - + {props.portfolioData[props.activePortfolio]['activities'].length === 0 ? + + + Start off by adding an Activity + + + Activities are the base for all data in Bench:market! They track changes in your portfolio and allow us to create detailed Charts about your Portfolio. + + + As soon as you add an activity our algorithms will automatically calculated all important numbers related to your portfolio. If your need any help you can always ask our Chatbot Benchi! + + + + : + + } ); diff --git a/Frontend/src/components/screens/Activities/Modals/activityModals.jsx b/Frontend/src/components/screens/Activities/Modals/activityModals.jsx index 723a739de..509b6b356 100644 --- a/Frontend/src/components/screens/Activities/Modals/activityModals.jsx +++ b/Frontend/src/components/screens/Activities/Modals/activityModals.jsx @@ -19,10 +19,11 @@ export const renderRemoveActivityModal = (open, onClick, handleClose) => ( sx={{ color: 'white', width: '5rem', - borderColor: 'rgb(228 126 37)', - backgroundColor: 'rgb(228 126 37)', + borderColor: '#e47e25', + backgroundColor: '#e47e25', '&:hover': { - backgroundColor: 'rgb(228 126 37)', + borderColor: '#c96208', + backgroundColor: '#e47e25', } }} > diff --git a/Frontend/src/components/screens/Analysis/AnalysisList.jsx b/Frontend/src/components/screens/Analysis/AnalysisList.jsx index c9f2ea7d2..bc96b625d 100644 --- a/Frontend/src/components/screens/Analysis/AnalysisList.jsx +++ b/Frontend/src/components/screens/Analysis/AnalysisList.jsx @@ -4,29 +4,7 @@ import {List, MenuItem, styled, TextField} from '@mui/material'; import AnalysisDetailItem from './AnalysisDetailItem'; import PropTypes from 'prop-types'; -const StyledTextField = styled(TextField)({ - //Label color when focused - '& label.Mui-focused': { - color: '#493f35', - }, - '& .MuiInput-underline:after': { - borderBottomColor: '#493f35', - }, - '& .MuiOutlinedInput-root': { - //Standard border color - '& fieldset': { - borderColor: '#c4b8ac', - }, - //Border color on hover - '&:hover fieldset': { - borderColor: '#493f35', - }, - //Border color when focused - '&.Mui-focused fieldset': { - borderColor: '#493f35', - }, - }, -}); +import { StyledTextField } from '../../common'; /** * Component to render the selected portfolio allocation list diff --git a/Frontend/src/components/screens/Analysis/AnalysisScreen.jsx b/Frontend/src/components/screens/Analysis/AnalysisScreen.jsx index 2daaed8e1..bcf810e2a 100644 --- a/Frontend/src/components/screens/Analysis/AnalysisScreen.jsx +++ b/Frontend/src/components/screens/Analysis/AnalysisScreen.jsx @@ -52,7 +52,8 @@ const AnalysisScreen = props => { stockArray.push({ asset: element.name, - percentage: parseFloat(percentage.toFixed(2)) + percentage: parseFloat(percentage.toFixed(2)), + symbol: element.symbol }) }); @@ -116,8 +117,6 @@ const AnalysisScreen = props => { } }) - - if(stockValue){ percentage = stockValue / value * 100; @@ -145,7 +144,7 @@ const AnalysisScreen = props => { }) } - if(portfolioData.cashValue ){ + if(portfolioData.cashValue){ percentage = portfolioData.cashValue / value * 100; stockArray.push({ @@ -161,15 +160,18 @@ const AnalysisScreen = props => { const getDoughnutChartData = (splitArray) => { //Perpare data for the doughnut chart let labelArray = []; let dataArray = []; + let symbolsArray = []; splitArray.forEach(arrayElement => { labelArray.push(arrayElement.asset) dataArray.push(arrayElement.percentage) + symbolsArray.push(arrayElement.symbol) }); return { 'labels': labelArray, - 'data': dataArray + 'data': dataArray, + 'symbols': symbolsArray } } @@ -206,6 +208,7 @@ const AnalysisScreen = props => { analysis data={doughnutChartData['data']} labels={doughnutChartData['labels']} + symbols={doughnutChartData['symbols']} defaultMiddleDisplayLabel={analysisTypes[analysisType]} defaultMiddleDisplayValue={''} /> @@ -274,7 +277,7 @@ const AnalysisScreen = props => { xs: 18 }} > - Start off by adding a Activity + Start off by adding an Activity { xs: 16 }} > - With activities you can fill your portfolio with your diffrent types of assets. + With activities you can fill your portfolio with your different types of assets. { xs: 16 }} > - Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. + Come back after adding one and see how your Portfolio is allocated! diff --git a/Frontend/src/components/screens/AssetDetails/AssetCard.jsx b/Frontend/src/components/screens/AssetDetails/AssetCard.jsx index 76e27e677..b135e1c31 100644 --- a/Frontend/src/components/screens/AssetDetails/AssetCard.jsx +++ b/Frontend/src/components/screens/AssetDetails/AssetCard.jsx @@ -1,8 +1,9 @@ import React, {useEffect, useState} from 'react'; +import {useNavigate} from 'react-router-dom'; import AssetChart from './AssetChart'; import ChartButtons from './ChartButtons'; import Masterdata from './Masterdata'; -import {Container, Card, Box} from '@mui/material'; +import {Container, Card, Box, Button} from '@mui/material'; import PropTypes from 'prop-types'; import SwitchButtons from './SwitchButtons'; import AssetPerformance from './AssetPerformance'; @@ -49,13 +50,36 @@ const AssetCard = props => { } } + const navigate = useNavigate(); + const routeChange = path => { + navigate(path); + } + return ( - + + {renderContent()} diff --git a/Frontend/src/components/screens/AssetDetails/AssetPerformance.jsx b/Frontend/src/components/screens/AssetDetails/AssetPerformance.jsx index 3bcc44af8..e73981698 100644 --- a/Frontend/src/components/screens/AssetDetails/AssetPerformance.jsx +++ b/Frontend/src/components/screens/AssetDetails/AssetPerformance.jsx @@ -130,7 +130,7 @@ export const AssetPerformance = props => { { setRealised(!realised) - }}/>} label='Realised Performance'/> + }}/>} label='Include realised Gains'/> }/> diff --git a/Frontend/src/components/screens/Dashboard/AllocationGraph.jsx b/Frontend/src/components/screens/Dashboard/AllocationGraph.jsx index e0ecc3c6b..534b168c0 100644 --- a/Frontend/src/components/screens/Dashboard/AllocationGraph.jsx +++ b/Frontend/src/components/screens/Dashboard/AllocationGraph.jsx @@ -28,6 +28,15 @@ const AllocationGraph = props => { return labels; })(); + const symbols = (() => { + let symbols = []; + assets.forEach(element => { + let symbol = element['symbol']; + symbols.push(symbol); + }); + return symbols; + })(); + const valueData = (() => { let valueData = []; assets.forEach(element => { @@ -40,6 +49,7 @@ const AllocationGraph = props => { diff --git a/Frontend/src/components/screens/Dashboard/PortfolioCharts.jsx b/Frontend/src/components/screens/Dashboard/PortfolioCharts.jsx index 7f9382a9e..11debdcdb 100644 --- a/Frontend/src/components/screens/Dashboard/PortfolioCharts.jsx +++ b/Frontend/src/components/screens/Dashboard/PortfolioCharts.jsx @@ -1,18 +1,21 @@ import React from 'react'; -import {Container, Box} from '@mui/material'; +import {Grid, Box} from '@mui/material'; import PortfolioPerformance from './PortfolioPerformance'; import PortfolioValueChart from './PortfolioValuechart'; export const PortfolioCharts = props => { return ( - - + + - + - - + + ) } diff --git a/Frontend/src/components/screens/Dashboard/PortfolioPerformance.jsx b/Frontend/src/components/screens/Dashboard/PortfolioPerformance.jsx index 7983b2251..1c80ff1f6 100644 --- a/Frontend/src/components/screens/Dashboard/PortfolioPerformance.jsx +++ b/Frontend/src/components/screens/Dashboard/PortfolioPerformance.jsx @@ -134,7 +134,7 @@ export const PortfolioPerformance = props => { control={ { setRealised(!realised) }}/>} - label='Realised Performance' + label='Include realised Gains' /> }/> diff --git a/Frontend/src/components/screens/ErrorPage.jsx b/Frontend/src/components/screens/ErrorPage.jsx index ddce41aa7..1c51718db 100644 --- a/Frontend/src/components/screens/ErrorPage.jsx +++ b/Frontend/src/components/screens/ErrorPage.jsx @@ -1,5 +1,5 @@ import React from 'react'; -import {Typography, Container, List, ListItem} from '@mui/material'; +import {Typography, Container } from '@mui/material'; import {Link} from 'react-router-dom'; const ErrorPage = () => ( diff --git a/Frontend/src/components/screens/Settings/Modals/settingsModals.jsx b/Frontend/src/components/screens/Settings/Modals/settingsModals.jsx index 8349f6fca..7ad91d430 100644 --- a/Frontend/src/components/screens/Settings/Modals/settingsModals.jsx +++ b/Frontend/src/components/screens/Settings/Modals/settingsModals.jsx @@ -16,10 +16,11 @@ export const renderDeleteDataModal = (open, handleClose, onClick) => ( sx={{ color: 'white', width: '5rem', - borderColor: 'rgb(228 126 37)', - backgroundColor: 'rgb(228 126 37)', + borderColor: '#e47e25', + backgroundColor: '#e47e25', '&:hover': { - backgroundColor: 'rgb(228 126 37)', + borderColor: '#c96208', + backgroundColor: '#e47e25', } }} > diff --git a/Frontend/src/components/screens/Settings/SettingsScreen.jsx b/Frontend/src/components/screens/Settings/SettingsScreen.jsx index 203ecaf59..d4de636ad 100644 --- a/Frontend/src/components/screens/Settings/SettingsScreen.jsx +++ b/Frontend/src/components/screens/Settings/SettingsScreen.jsx @@ -4,7 +4,6 @@ import ScreensTemplate from '../../ScreensTemplate'; import {Container, Box, Button} from '@mui/material'; import {renderDeleteDataModal} from './Modals/settingsModals' import PropTypes from 'prop-types'; -import {margin} from '@mui/system'; import {Grid} from '@mui/material'; import Typography from '@mui/material/Typography'; import SettingsIcon from '@mui/icons-material/Settings'; @@ -41,7 +40,6 @@ const SettingsScreen = props => { { { xs: 12 }} sx={{ + color: 'white', '@media screen and (max-width: 768px)': { marginBottom: '40px' } @@ -188,7 +186,6 @@ const SettingsScreen = props => { { xs: 12 }} sx={{ + color: 'white', '@media screen and (max-width: 768px)': { marginBottom: '40px' } }} > - Delete your data to get an empty portfolio. Your watchlist will be reset as well. Be careful that we can't restore your data, so download it first if you still need it! + Delete your data to get an empty portfolio. Your watchlist will be reset as well. Be careful because we can't restore your data, so download it first if you still need it! { onClick={() => setDeleteDataModal(true)} sx={{ color: 'white', - borderColor: 'rgb(228 126 37)', - backgroundColor: 'rgb(228 126 37)', + borderColor: '#e47e25', + backgroundColor: '#e47e25', '&:hover': { - backgroundColor: 'rgb(228 126 37)', + borderColor: '#c96208', + backgroundColor: '#e47e25', }, margin: 'auto !important', display: 'block' diff --git a/Frontend/src/components/screens/WatchLists/AssetListItem.jsx b/Frontend/src/components/screens/WatchLists/AssetListItem.jsx index d782bbf68..24dbe1fb2 100644 --- a/Frontend/src/components/screens/WatchLists/AssetListItem.jsx +++ b/Frontend/src/components/screens/WatchLists/AssetListItem.jsx @@ -13,7 +13,6 @@ import {AssetDetailItem} from '../../common'; */ const AssetListItem = props => { const [, setListDropdownIndex] = useState(0); - const colorsArray = ['rgb(59 151 210)', 'rgb(78 185 111)', 'rgb(228 126 37)', 'rgb(239 195 21)']; return ( @@ -32,7 +31,6 @@ const AssetListItem = props => { key={`asset_${index}`} row={row} index={index} - colorsArray={colorsArray} itemsArray={props.assetsListArray[props.selectedListIndex]} listName={props.watchListsArray[index]} selectedListIndex={props.selectedListIndex} diff --git a/Frontend/src/components/screens/WatchLists/Modals/assetModals.jsx b/Frontend/src/components/screens/WatchLists/Modals/assetModals.jsx index e17dd092d..827e5f572 100644 --- a/Frontend/src/components/screens/WatchLists/Modals/assetModals.jsx +++ b/Frontend/src/components/screens/WatchLists/Modals/assetModals.jsx @@ -1,6 +1,6 @@ import React from 'react'; import {Button, TextField} from '@mui/material'; -import {CustomModal} from '../../../common'; +import {CustomModal, StyledTextField} from '../../../common'; export const renderRemoveAssetModal = (open, handleClose, onClick) => ( ( sx={{ color: 'white', width: '5rem', - borderColor: 'rgb(228 126 37)', - backgroundColor: 'rgb(228 126 37)', + borderColor: '#e47e25', + backgroundColor: '#e47e25', '&:hover': { - backgroundColor: 'rgb(228 126 37)', + borderColor: '#c96208', + backgroundColor: '#e47e25', } }} > @@ -37,7 +38,7 @@ export const renderAddAssetModal = (open, handleClose, errorModal, onChange, onC describedby='add_asset-modal-description' modalTitle='New asset' modalBody={() => ( - ( ( - ( - ( sx={{ color: 'white', width: '5rem', - borderColor: 'rgb(228 126 37)', - backgroundColor: 'rgb(228 126 37)', + borderColor: '#e47e25', + backgroundColor: '#e47e25', '&:hover': { - backgroundColor: 'rgb(228 126 37)', + borderColor: '#c96208', + backgroundColor: '#e47e25', } }} > diff --git a/Frontend/src/components/screens/WatchLists/WatchLists.jsx b/Frontend/src/components/screens/WatchLists/WatchLists.jsx index 1f5884351..c192b6b9f 100644 --- a/Frontend/src/components/screens/WatchLists/WatchLists.jsx +++ b/Frontend/src/components/screens/WatchLists/WatchLists.jsx @@ -25,29 +25,23 @@ import DropdownMenu from './DropdownMenu'; import CustomSelectField from './CustomSelectField'; import {renderAddWatchlistModal, renderEditListModal, renderRemoveListModal} from './Modals/watchlistModals'; -const StyledTextField = styled(TextField)({ - //Label color when focused - '& label.Mui-focused': { - color: '#493f35', - }, - '& .MuiInput-underline:after': { - borderBottomColor: '#493f35', - }, - '& .MuiOutlinedInput-root': { - //Standard border color - '& fieldset': { - borderColor: '#c4b8ac', - }, - //Border color on hover - '&:hover fieldset': { - borderColor: '#493f35', - }, - //Border color when focused - '&.Mui-focused fieldset': { - borderColor: '#493f35', - }, - }, -}); +import { StyledTextField, Colors } from '../../common'; + +/** + * Creates a hashCode from a String + * @param String + * @returns {interger} + */ + String.prototype.hashCode = function() { + let hash = 0, i, chr; + if (this.length === 0) return hash; + for (i = 0; i < this.length; i++) { + chr = this.charCodeAt(i); + hash = ((hash << 5) - hash) + chr; + hash |= 0; // Convert to 32bit integer + } + return hash; +}; /** * Show all the watchLists @@ -62,7 +56,7 @@ const WatchLists = props => { const [watchlist, setWatchlist] = useState(undefined); const [errorModal, setErrorModal] = useState(false); const [listDropdownIndex, setListDropdownIndex] = useState(0); - const avatarGroupColors = ['rgb(59 151 210)', 'rgb(78 185 111)', 'rgb(228 126 37)']; + const avatarGroupColors = Colors.COLORPALETTE; const handleWatchListItemClick = (event, index) => { props.setSelectedListIndex(index); @@ -298,7 +292,7 @@ const WatchLists = props => { '&.MuiAvatar-circular': { borderColor: props.selectedListIndex === index ? 'white' : 'black' }, - backgroundColor: avatarGroupColors[assetIndex], + backgroundColor: avatarGroupColors[asset.symbol.hashCode() % 10], width: { md: '1.2rem', xl: '1.5rem' From 6e8187858ad833af0b9e239171604aee9f07c3af Mon Sep 17 00:00:00 2001 From: cedscho Date: Wed, 18 May 2022 21:34:44 +0200 Subject: [PATCH 05/10] fix: assetType isnt selected from initialAssetObj in addActivityForm --- .../AddActivity/AddActivityForm.jsx | 29 ++----------------- .../AddActivity/SearchAssetsInput.jsx | 5 ++-- 2 files changed, 6 insertions(+), 28 deletions(-) diff --git a/Frontend/src/components/screens/Activities/AddActivity/AddActivityForm.jsx b/Frontend/src/components/screens/Activities/AddActivity/AddActivityForm.jsx index c75d310b7..8f4987a6f 100644 --- a/Frontend/src/components/screens/Activities/AddActivity/AddActivityForm.jsx +++ b/Frontend/src/components/screens/Activities/AddActivity/AddActivityForm.jsx @@ -1,6 +1,6 @@ import React, {useState, useEffect} from 'react'; import {useNavigate} from 'react-router-dom'; -import {Grid, Button, Box, TextField, MenuItem, styled, InputAdornment} from '@mui/material'; +import {Grid, Button, Box, TextField, MenuItem, InputAdornment} from '@mui/material'; import {LocalizationProvider} from '@mui/x-date-pickers/LocalizationProvider'; import {AdapterDateFns} from '@mui/x-date-pickers/AdapterDateFns'; import {DatePicker} from '@mui/x-date-pickers/DatePicker'; @@ -9,30 +9,7 @@ import ClearIcon from '@mui/icons-material/Clear'; import DragHandleIcon from '@mui/icons-material/DragHandle'; import PropTypes from 'prop-types'; import SearchAssetInput from './SearchAssetsInput'; - -const StyledTextField = styled(TextField)({ - //Label color when focused - '& label.Mui-focused': { - color: '#493f35', - }, - '& .MuiInput-underline:after': { - borderBottomColor: '#493f35', - }, - '& .MuiOutlinedInput-root': { - //Standard border color - '& fieldset': { - borderColor: '#c4b8ac', - }, - //Border color on hover - '&:hover fieldset': { - borderColor: '#493f35', - }, - //Border color when focused - '&.Mui-focused fieldset': { - borderColor: '#493f35', - }, - }, -}); +import { StyledTextField } from '../../../common'; /** * Form for adding an activity @@ -43,7 +20,7 @@ const StyledTextField = styled(TextField)({ const AddActivityForm = props => { const initialValues = { - assetType: 'share', + assetType: props.initialAssetObj ? (props.initialAssetObj.assetType === 'Crypto' ? 'crypto' : props.initialAssetObj.assetType === 'Cash' ? 'cash' : 'share') : 'share', asset: props.initialAssetObj, assetInput: '', typeShare: 'buy', diff --git a/Frontend/src/components/screens/Activities/AddActivity/SearchAssetsInput.jsx b/Frontend/src/components/screens/Activities/AddActivity/SearchAssetsInput.jsx index 9360ed40e..968d854a8 100644 --- a/Frontend/src/components/screens/Activities/AddActivity/SearchAssetsInput.jsx +++ b/Frontend/src/components/screens/Activities/AddActivity/SearchAssetsInput.jsx @@ -3,6 +3,7 @@ import {Box} from '@mui/material'; import Autocomplete from '@mui/material/Autocomplete'; import CircularProgress from '@mui/material/CircularProgress'; import PropTypes from 'prop-types'; +import { Loading } from '../../../common'; /** * Form for adding an activity @@ -56,7 +57,7 @@ const SearchAssetInput = props => { const [open, setOpen] = useState(false); const [options, setOptions] = useState([]); const [loading, setLoading] = useState(false); - const [cash, setCash] = useState(false); + const [cash, setCash] = useState(props.initialAssetObj ? (props.initialAssetObj.assetType === 'Cash' ? true : false) : false); const sharesInPortfolioOptions = getSharesInPortfolioOptions(); const cryptoInPortfolioOptions = getCryptoInPortfolioOptions(); @@ -258,7 +259,7 @@ const fetchCryptoOptions = async (query) => { autoComplete: 'new-password', // disable autocomplete and autofill endAdornment: ( - {loading ? : null} + {loading ? : null} {params.InputProps.endAdornment} ), From 86c1111adaf5d58e5fa3f76da375524f241dd8ce Mon Sep 17 00:00:00 2001 From: cedscho Date: Wed, 18 May 2022 21:35:02 +0200 Subject: [PATCH 06/10] feature: add a new Portfolio --- .../screens/Dashboard/DashboardScreen.jsx | 198 +++++++++++------- .../Dashboard/Modals/dashboardModals.jsx | 90 ++++++++ .../screens/Dashboard/PortfolioOverview.jsx | 3 +- 3 files changed, 214 insertions(+), 77 deletions(-) create mode 100644 Frontend/src/components/screens/Dashboard/Modals/dashboardModals.jsx diff --git a/Frontend/src/components/screens/Dashboard/DashboardScreen.jsx b/Frontend/src/components/screens/Dashboard/DashboardScreen.jsx index 56c584230..7bb4649ca 100644 --- a/Frontend/src/components/screens/Dashboard/DashboardScreen.jsx +++ b/Frontend/src/components/screens/Dashboard/DashboardScreen.jsx @@ -7,6 +7,7 @@ import AllocationGraph from './AllocationGraph'; import PortfolioOverview from './PortfolioOverview'; import PortfolioCharts from './PortfolioCharts'; import ChartButtons from '../AssetDetails/ChartButtons'; +import {RenderAddPortfolioModal} from './Modals/dashboardModals' /** * Component related to the dashboard screen @@ -15,8 +16,10 @@ import ChartButtons from '../AssetDetails/ChartButtons'; * @constructor */ const DashboardScreen = props => { - const [view, setView] = useState('month'); + const [view, setView] = useState('all'); + const [addPortfolioModal, setAddPortfolioModal] = useState(false); + //adds a dummyCash account to the data const dummyCash = () => { const cash = [{ firstActivity: '2900-01-01', @@ -46,6 +49,42 @@ const DashboardScreen = props => { return portfolioData; }); } + + //adds a new Portfolio to the data + const addPortfolio = (name) => { + props.setPortfolioData(prevData => { + const portfolioData = {...prevData, + [name]: { + 'name': name, + 'value': 0, + 'gains': 0, + 'realisedGains': 0, + 'totalGains': 0, + 'dividends': 0, + 'performanceWithRealisedGains': 0, + 'performanceWithoutRealisedGains': 0, + 'shares': [], + 'crypto': [], + 'cash': [], + 'activities': [], + 'activitiesLastId': -1, + 'dailyDataForValueDevelopment': {}, + 'dailyDataForPerformanceGraph': {}, + 'updated': '1970-01-01', + 'shareValue': 0, + 'cryptoValue': 0, + 'cashValue': 0 + } + }; + return portfolioData; + }); + props.setActivePortfolio(name); + } + + // Function to close the modals + const handleClose = () => { + setAddPortfolioModal(false); + } const navigate = useNavigate(); const routeChange = path => { @@ -56,7 +95,7 @@ const DashboardScreen = props => { { portfolioData={props.portfolioData} activePortfolio={props.activePortfolio} setActivePortfolio={props.setActivePortfolio} + setAddPortfolioModal={setAddPortfolioModal} /> @@ -79,81 +119,81 @@ const DashboardScreen = props => { {props.portfolioData[props.activePortfolio]['dailyDataForValueDevelopment'] && Object.keys(props.portfolioData[props.activePortfolio]['dailyDataForValueDevelopment']).length === 0 ? - - - - - - - - Start off by adding a Activity - - - Activities are the base for all data in Bench:market! They track changes in your portfolio and - - - As soon as you add an activity our algorithms will automatically calculated all important numbers related to your portfolio. If your need any help you can always ask our Chatbot Benchi! - - - - + marginTop: '30px' + }} + > + + + + + + Start off by adding an Activity + + + Activities are the base for all data in Bench:market! They track changes in your portfolio and allow us to create detailed Charts about your Portfolio. + + + As soon as you add an activity our algorithms will automatically calculated all important numbers related to your portfolio. If your need any help you can always ask our Chatbot Benchi! + + + : } @@ -192,6 +232,12 @@ const DashboardScreen = props => { messageType={props.messageType} setMessageType={props.setMessageType} /> + handleClose()} + onClick={(newPortfolioName) => addPortfolio(newPortfolioName)} + /> ); diff --git a/Frontend/src/components/screens/Dashboard/Modals/dashboardModals.jsx b/Frontend/src/components/screens/Dashboard/Modals/dashboardModals.jsx new file mode 100644 index 000000000..fb8e5b9f9 --- /dev/null +++ b/Frontend/src/components/screens/Dashboard/Modals/dashboardModals.jsx @@ -0,0 +1,90 @@ +import React, {useEffect, useState} from 'react'; +import {Button, FormControl, FormHelperText, InputLabel} from '@mui/material'; +import {CustomModal, StyledTextField} from '../../../common'; + +export const RenderAddPortfolioModal = ({ + open, + portfolioData, + handleClose, + onClick + }) => { + const [error, setError] = useState(false); + const [errorDescripton, setErrorDescripton] = useState(''); + const [newPortfolioName, setNewPortfolioName] = useState(''); + + useEffect(() => { + if (open) { + if (newPortfolioName === '') { + setError(true); + setErrorDescripton('Can not be empty'); + return; + } + const existingPortfolios = Object.keys(portfolioData); + for (let index = 0; index < existingPortfolios.length; index++) { + const element = existingPortfolios[index]; + if (element === newPortfolioName) { + setError(true); + setErrorDescripton('Name is already used'); + return; + } + } + setError(false); + } + }, [open, newPortfolioName]); + + return ( + { + handleClose(); + setError(false); + }} + labelledby='add_portfolio-modal-title' + describedby='add_portfolio-modal-description' + modalTitle='Add a new portfolio:' + modalBody={() => ( + + { + setNewPortfolioName(event.target.value); + }} + /> + {error && *{errorDescripton}} + + )} + modalButton={() => ( + + )} + /> + ); + } \ No newline at end of file diff --git a/Frontend/src/components/screens/Dashboard/PortfolioOverview.jsx b/Frontend/src/components/screens/Dashboard/PortfolioOverview.jsx index 1be6538ee..94781793a 100644 --- a/Frontend/src/components/screens/Dashboard/PortfolioOverview.jsx +++ b/Frontend/src/components/screens/Dashboard/PortfolioOverview.jsx @@ -61,7 +61,7 @@ const PortfolioOverview = props => { {}} + onClick={() => props.setAddPortfolioModal(true)} > @@ -96,6 +96,7 @@ PortfolioOverview.propTypes = { activePortfolio: PropTypes.any, setActivePortfolio: PropTypes.func, portfolioData: PropTypes.object, + setAddPortfolioModal: PropTypes.func }; export default PortfolioOverview; \ No newline at end of file From 9a66682d39c1dc33ba480a10b4c88fb5b867777d Mon Sep 17 00:00:00 2001 From: cedscho Date: Wed, 18 May 2022 21:48:34 +0200 Subject: [PATCH 07/10] try to fix: test fails --- Frontend/package-lock.json | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/Frontend/package-lock.json b/Frontend/package-lock.json index 00b2bff54..49952e39c 100644 --- a/Frontend/package-lock.json +++ b/Frontend/package-lock.json @@ -8539,19 +8539,6 @@ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -23563,12 +23550,6 @@ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "optional": true - }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", From 2b5a26596fc264822845b79786cdbb97a4f99e76 Mon Sep 17 00:00:00 2001 From: cedscho <93663333+cedscho@users.noreply.github.com> Date: Wed, 18 May 2022 22:15:44 +0200 Subject: [PATCH 08/10] fix: github didnt notice file rename --- .../Analysis/{AnalysisDetailitem.jsx => AnalysisDetailItem.jsx} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename Frontend/src/components/screens/Analysis/{AnalysisDetailitem.jsx => AnalysisDetailItem.jsx} (98%) diff --git a/Frontend/src/components/screens/Analysis/AnalysisDetailitem.jsx b/Frontend/src/components/screens/Analysis/AnalysisDetailItem.jsx similarity index 98% rename from Frontend/src/components/screens/Analysis/AnalysisDetailitem.jsx rename to Frontend/src/components/screens/Analysis/AnalysisDetailItem.jsx index 3a008c8a9..8752b5de7 100644 --- a/Frontend/src/components/screens/Analysis/AnalysisDetailitem.jsx +++ b/Frontend/src/components/screens/Analysis/AnalysisDetailItem.jsx @@ -68,4 +68,4 @@ AnalysisDetailItem.propTypes = { percentage: PropTypes.string, }; -export default AnalysisDetailItem; \ No newline at end of file +export default AnalysisDetailItem; From e0d707223d5de2663ad229a4eb208e572840bf20 Mon Sep 17 00:00:00 2001 From: cedscho Date: Thu, 19 May 2022 11:06:23 +0200 Subject: [PATCH 09/10] fix: test dont run through because AudioContext --- Frontend/package-lock.json | 32 ++++++---- Frontend/src/benchi-chatbot/config.js | 1 - .../Analysis/__test__/AnalysisScreen.test.jsx | 4 ++ .../__test__/AssetDetails.test.jsx | 4 ++ .../__test__/DashboardScreen.test.jsx | 10 +++- .../DashboardScreen.test.jsx.snap | 60 +++++++++++++++++-- .../Settings/__test__/SettingsScreen.test.jsx | 4 ++ .../__test__/WatchListsScreen.test.jsx | 4 ++ 8 files changed, 98 insertions(+), 21 deletions(-) diff --git a/Frontend/package-lock.json b/Frontend/package-lock.json index 49952e39c..b7e14b362 100644 --- a/Frontend/package-lock.json +++ b/Frontend/package-lock.json @@ -8539,6 +8539,19 @@ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -14460,14 +14473,6 @@ "url": "https://opencollective.com/webpack" } }, - "node_modules/react-chatbot-kit/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/react-chatbot-kit/node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -23550,6 +23555,12 @@ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "optional": true + }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -27704,11 +27715,6 @@ "ajv-keywords": "^3.5.2" } }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", diff --git a/Frontend/src/benchi-chatbot/config.js b/Frontend/src/benchi-chatbot/config.js index 63d3dd935..1dd6e70a3 100644 --- a/Frontend/src/benchi-chatbot/config.js +++ b/Frontend/src/benchi-chatbot/config.js @@ -12,7 +12,6 @@ const config = { state: { questionNr: 0, userPreferences: {experience: '', risk: '', active: false, effort: '', duration: ''}, - textToSpeech: new TextToSpeech() }, customComponents: { // Replaces the default header diff --git a/Frontend/src/components/screens/Analysis/__test__/AnalysisScreen.test.jsx b/Frontend/src/components/screens/Analysis/__test__/AnalysisScreen.test.jsx index 05d1c717f..f327c0361 100644 --- a/Frontend/src/components/screens/Analysis/__test__/AnalysisScreen.test.jsx +++ b/Frontend/src/components/screens/Analysis/__test__/AnalysisScreen.test.jsx @@ -8,6 +8,10 @@ import toJson from 'enzyme-to-json'; configure({adapter: new Adapter()}); +jest.mock('../../../../benchi-chatbot/TextToSpeech', () => ({ + ctx: {} +})); + it('AnalysisScreen renders without crashing', () => { const setSearchResult = jest.fn(); const setPortfolioData = jest.fn(); diff --git a/Frontend/src/components/screens/AssetDetails/__test__/AssetDetails.test.jsx b/Frontend/src/components/screens/AssetDetails/__test__/AssetDetails.test.jsx index b0ba5b117..ecedff770 100644 --- a/Frontend/src/components/screens/AssetDetails/__test__/AssetDetails.test.jsx +++ b/Frontend/src/components/screens/AssetDetails/__test__/AssetDetails.test.jsx @@ -6,6 +6,10 @@ import Adapter from '@wojtekmaj/enzyme-adapter-react-17'; Enzyme.configure({adapter: new Adapter()}) +jest.mock('../../../../benchi-chatbot/TextToSpeech', () => ({ + ctx: {} +})); + it('AssetDetailsScreen renders without crashing', () => { const portfolioData = { 'Portfolio': { diff --git a/Frontend/src/components/screens/Dashboard/__test__/DashboardScreen.test.jsx b/Frontend/src/components/screens/Dashboard/__test__/DashboardScreen.test.jsx index b1c93b92e..659e89488 100644 --- a/Frontend/src/components/screens/Dashboard/__test__/DashboardScreen.test.jsx +++ b/Frontend/src/components/screens/Dashboard/__test__/DashboardScreen.test.jsx @@ -3,9 +3,13 @@ import DashboardScreen from '../DashboardScreen'; import toJson from 'enzyme-to-json'; import Enzyme, {shallow} from 'enzyme'; import Adapter from '@wojtekmaj/enzyme-adapter-react-17'; +import {BrowserRouter} from 'react-router-dom'; Enzyme.configure({adapter: new Adapter()}) +jest.mock('../../../../benchi-chatbot/TextToSpeech', () => ({ + ctx: {} +})); it('DashboardScreen renders without crashing', () => { const portfolioData = { @@ -29,8 +33,9 @@ it('DashboardScreen renders without crashing', () => { const getAllAssets = jest.fn(); const setStatusMessage = jest.fn(); const setMessageType = jest.fn(); + const addPortfolio = jest.fn(); - const wrapper = shallow( + const wrapper = shallow( { setPortfolioData={setPortfolioData} setStatusMessage={setStatusMessage} setMessageType={setMessageType} - />); + /> + ); expect(toJson(wrapper)).toMatchSnapshot(); }) \ No newline at end of file diff --git a/Frontend/src/components/screens/Dashboard/__test__/__snapshots__/DashboardScreen.test.jsx.snap b/Frontend/src/components/screens/Dashboard/__test__/__snapshots__/DashboardScreen.test.jsx.snap index a5d5ceea9..6b5c5ec18 100644 --- a/Frontend/src/components/screens/Dashboard/__test__/__snapshots__/DashboardScreen.test.jsx.snap +++ b/Frontend/src/components/screens/Dashboard/__test__/__snapshots__/DashboardScreen.test.jsx.snap @@ -1,19 +1,69 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`DashboardScreen renders without crashing 1`] = ` - - + - + `; diff --git a/Frontend/src/components/screens/Settings/__test__/SettingsScreen.test.jsx b/Frontend/src/components/screens/Settings/__test__/SettingsScreen.test.jsx index 92964aa9a..e795f8376 100644 --- a/Frontend/src/components/screens/Settings/__test__/SettingsScreen.test.jsx +++ b/Frontend/src/components/screens/Settings/__test__/SettingsScreen.test.jsx @@ -7,6 +7,10 @@ import Adapter from '@wojtekmaj/enzyme-adapter-react-17'; Enzyme.configure({adapter: new Adapter()}) +jest.mock('../../../../benchi-chatbot/TextToSpeech', () => ({ + ctx: {} +})); + it('SettingsScreen renders without crashing', () => { const emptyPortfolioData = { 'Portfolio': { diff --git a/Frontend/src/components/screens/WatchLists/__test__/WatchListsScreen.test.jsx b/Frontend/src/components/screens/WatchLists/__test__/WatchListsScreen.test.jsx index 8df3abf48..002598ce1 100644 --- a/Frontend/src/components/screens/WatchLists/__test__/WatchListsScreen.test.jsx +++ b/Frontend/src/components/screens/WatchLists/__test__/WatchListsScreen.test.jsx @@ -25,6 +25,10 @@ jest.mock('react-router-dom', () => ({ useNavigate: () => mockedNavigator })); +jest.mock('../../../../benchi-chatbot/TextToSpeech', () => ({ + ctx: {} +})); + describe('Tests regarding WatchList screen', () => { const addToWatchList = jest.fn(); const setWatchListsArray = jest.fn(); From b425e808f4c7d0a82b272d8f42be8212ffaee8c5 Mon Sep 17 00:00:00 2001 From: cedscho Date: Thu, 19 May 2022 12:04:14 +0200 Subject: [PATCH 10/10] design: settings borders around buttons --- Frontend/src/components/screens/Settings/SettingsScreen.jsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Frontend/src/components/screens/Settings/SettingsScreen.jsx b/Frontend/src/components/screens/Settings/SettingsScreen.jsx index d4de636ad..0931dcb8d 100644 --- a/Frontend/src/components/screens/Settings/SettingsScreen.jsx +++ b/Frontend/src/components/screens/Settings/SettingsScreen.jsx @@ -40,6 +40,7 @@ const SettingsScreen = props => { { {