From adc8a572eaaa4fa9136b02560b0e41c771c3a6cc Mon Sep 17 00:00:00 2001 From: Jan Martiska Date: Wed, 8 Jan 2025 13:49:41 +0100 Subject: [PATCH] Blog post about MCP and Quarkus LangChain4j --- .../2025-01-08-quarkus-langchain4j-mcp.adoc | 208 ++++++++++++++++++ assets/images/posts/mcp/devui.png | Bin 0 -> 35203 bytes 2 files changed, 208 insertions(+) create mode 100644 _posts/2025-01-08-quarkus-langchain4j-mcp.adoc create mode 100644 assets/images/posts/mcp/devui.png diff --git a/_posts/2025-01-08-quarkus-langchain4j-mcp.adoc b/_posts/2025-01-08-quarkus-langchain4j-mcp.adoc new file mode 100644 index 00000000000..8e5d8e4a46a --- /dev/null +++ b/_posts/2025-01-08-quarkus-langchain4j-mcp.adoc @@ -0,0 +1,208 @@ +--- +layout: post +title: 'Using the Model Context Protocol with Quarkus+LangChain4j' +date: 2025-01-08 +tags: langchain4j llm ai +synopsis: 'Executing tools via the Model Context Protocol with Quarkus+LangChain4j' +author: jmartisk +--- +:imagesdir: /assets/images/posts/mcp + +We are thrilled to announce that starting with version 0.23.0, the Quarkus +LangChain4j project integrates calling tools using the +https://modelcontextprotocol.io[Model Context Protocol (MCP)]. + +== What is the Model Context Protocol? + +MCP is an open protocol that standardizes how applications provide context +to LLMs. An MCP server is an application that can provide tools, resources +(be it a set of static documents or dynamically accessed data, for example +from a database), or pre-defined prompts that your AI-infused application +can use when talking to LLMs. When you package such functionality into an +MCP server, it can be plugged into and used by any LLM client toolkit that +supports MCP, including Quarkus and LangChain4j. There is also already a +growing ecosystem of reusable MCP servers that you can use out of the box, +and Quarkus also offers the +https://github.com/quarkiverse/quarkus-mcp-server[quarkus-mcp-server extension] that allows you +to create MCP servers, but in this article, we will focus on the client +side. More on creating MCP servers side later. + +In version 0.23.x, +https://github.com/quarkiverse/quarkus-langchain4j[Quarkus LangChain4j] +implements the client side of the MCP protocol to allow tool execution. +Support for resources and prompts is planned for future releases. + +In this article, we will show you how to use Quarkus and LangChain4j to +easily create an application that connects to an MCP server providing +filesystem-related tools and exposes a chatbot that a user can use to +interact with the local filesystem, that means read and write files as +instructed by the user. + +There is no need to set up an MCP server separately, we will configure +Quarkus to run one as a subprocess. As you will see, setting up MCP with +Quarkus is extremely easy. + +NOTE: To download the final project, visit the +https://github.com/quarkiverse/quarkus-langchain4j/tree/0.23.0/samples/mcp-tools[ +quarkus-langchain4j samples]. That sample contains the final functionality +developed in this article, plus some stuff on top, like a JavaScript-based +UI. In this article, for simplicity, we will skip the creation of that UI, +and we will only use the Dev UI chat page that comes bundled in Quarkus out +of the box. + +== Prerequisites + +* Apache Maven 3.9+ +* The `npm` package manager installed on your machine + +== Creating a Filesystem assistant project + +We will assume that you are using OpenAI as the LLM provider. If you are +using a different provider, you will need to swap out the +`quarkus-langchain4j-openai` extension and use something else. + +Start by generating a Quarkus project. If you are using the Quarkus CLI, you can do it like this: + +[source, shell] +---- +quarkus create app org.acme:filesystem-assistant:1.0-SNAPSHOT \ + --extensions="langchain4j-openai,langchain4j-mcp,vertx-http" -S 3.17 +---- + +If you prefer to use the web-based project generator, go to +https://code.quarkus.io/[code.quarkus.io] and select the same extensions. + +Whenever you run the application, make sure the +`QUARKUS_LANGCHAIN4J_OPENAI_API_KEY` environment variable is set to your +OpenAI API key. + +=== Create the directory to be used by the agent + +Under the root directory of the Maven project, create a directory named `playground`. +This will be the only directory that the agent will be allowed to interact with. + +Inside that directory, create any files that you want for testing. For +example, create a file named `playground/hello.txt` with the following +contents: + +---- +Hello, world! +---- + +=== Create the AI service + +Next, we need to define an AI service that will define how the bot should +behave. The interface will look like this: + +[source, java] +---- +@RegisterAiService +@SessionScoped +public interface Bot { + + @SystemMessage(""" + You have tools to interact with the local filesystem and the users + will ask you to perform operations like reading and writing files. + + The only directory allowed to interact with is the 'playground' directory relative + to the current working directory. If a user specifies a relative path to a file and + it does not start with 'playground', prepend the 'playground' + directory to the path. + + If the user asks, tell them you have access to a tool server + via the Model Context Protocol (MCP) and that they can find more + information about it on https://modelcontextprotocol.io/. + """ + ) + String chat(@UserMessage String question); +} +---- + +Feel free to adjust the system message to your liking, but this one should +be suitable to get the application working as expected. + +=== Configure the MCP server and the connection to it + +We will use +https://www.npmjs.com/package/@modelcontextprotocol/server-filesystem[server-filesystem] +MCP server that comes as an NPM package, this is why you need to have `npm` +installed on your machine. It is assumed that you have the `npm` binary +available on your `PATH` (the `PATH` variable that the Quarkus process +sees). + +Starting the server and configuring the connection to it is extremely easy. +We will simply tell Quarkus to start up a `server-filesystem` MCP server as +a subprocess and then communicate with it over the `stdio` transport. All +you need to do is to add two lines into your `application.properties`: + +[source, properties] +---- +quarkus.langchain4j.mcp.filesystem.transport-type=stdio +quarkus.langchain4j.mcp.filesystem.command=npm,exec,@modelcontextprotocol/server-filesystem@0.6.2,playground +---- + +With this configuration, Quarkus will know that it should create a MCP +client that will be backed by a server that will be started by executing +`npm exec @modelcontextprotocol/server-filesystem@0.6.2 playground` as a +subprocess. The `playground` argument denotes the path to the directory that +the agent will be allowed to interact with. The `stdio` transport means that +the client will communicate with the server over standard input and output. + +When you configure one or more MCP connections this way, Quarkus also +automatically generates a `ToolProvider`. Any AI service that does not +explicitly specify a tool provider will be automatically wired up to this +generated one, so you don't need to do anything else to make the MCP +functionality available to the AI service. + +Optionally, if you want to see the actual traffic between the application +and the MCP server, add these three additional lines to your +`application.properties`: + +[source, properties] +---- +quarkus.langchain4j.mcp.filesystem.log-requests=true +quarkus.langchain4j.mcp.filesystem.log-responses=true +quarkus.log.category.\"dev.langchain4j\".level=DEBUG +---- + +And that's all! Now, let's test it. + +=== Try it out + +Since we didn't create any UI for our application that a user could use, +let's use the Dev UI that comes with Quarkus out of the box. With the +application running in development mode, access +http://localhost:8080/q/dev-ui in your browser and click the `Chat` link in +the `LangChain4j` card (either that, or go to +http://localhost:8080/q/dev-ui/io.quarkiverse.langchain4j.quarkus-langchain4j-core/chat +directly). + +Try a prompt to ask the agent to read a file that you created previously, such as: + +---- +Read the contents of the file hello.txt. +---- + +If all is set up correctly, the agent will respond with the contents of the +file, like in this screenshot: + +image::devui.png[Dev UI chat page after asking about a file,400,float="right",align="center"] + +The bot can also write files, so try a prompt such as: + +---- +Write a Python script that prints "Hello, world!" and save it as hello.py. +---- + +Then have a look into your `playground` directory, and you should see the new Python file there! + +=== Conclusion + +The Model Context Protocol allows you to easily integrate reusable sets of +tools and resources to AI-infused applications in a portable way. With the +Quarkus LangChain4j extension, you can instruct Quarkus to run a server +locally as a subprocess, and configuring application to use it is just a +matter of adding a few configuration properties. + +And that's not all. Stay tuned, because Quarkus also has an extension that +allows you to create MCP servers! More about that soon. \ No newline at end of file diff --git a/assets/images/posts/mcp/devui.png b/assets/images/posts/mcp/devui.png new file mode 100644 index 0000000000000000000000000000000000000000..cd2ed856734369dd6557f847dc693e678664a1e0 GIT binary patch literal 35203 zcmc$`by!w!_b>QZgmkw^cX#VUH%PaHba$iD4bm;$-Ho6i-5n31baylN_kHJgu9^A0 z=bCfopYhr#JheCXUiVt-6U$H~1xb|Ggs&kG2#U0n*aryY*){m8MtBY$c}Bt!0scX> zm(p^AKu~}F^Ytu&0hI^>c?*#id#~!AzQ63IJM=^fIlfw+)@!XZH^Y$;WtSnNvnb9p zp&}3u*^f_%kdnA$VMr58(ITU$!5m-l(s#K#yW80Cg2g5B8>G*kjgw}1!R}V}oZ1ha zjz+hH?Vbl2B0wOYSIHlD;lTN?o8OMTfPDV!{|*fTd5-#A2m(RiMK}i+vHE{~LIM4` z&;G?r8{^W9yT`t?-)r_my^7p~LTj`2NDzoG5>%ve``dZJ)Z#@mU8LG8XE+p5gjjKe zniA~D_eL%1--PPKZ#0vvd3NTA-0<$)F+&YRS~5F52Tj;-G+#j=_u1E^+bQzt$u8oG zxeP=lT1-NUKE55N_cD|#^5)mre1$Fp-8tUZ>e<-^AC$E&)~8zyd*R$=_Adg~dV@k0 z<4%H|`6*1c9@7v*5y(W_pIIdhYp5NLUwA%)tX}nP6{m%lBH_~JQSLM4tJk7K11kHM zS{XksiCJ>RDG@Y&X&y5!>Aq!CCIyxe)kCOO0 zKghAjbHP5l*dM_|x(vSBed%D2ZkE`3I0*TGOkwmScIF4&5qU<6(G>bJfHiE9jYmX7;i97Ig}VRlsBaF>^X_@zM!v1Fv$$7FI>hKtrlXgBgO5-BcTV zdpWcJfdQ;5+RtDLPr(5yjfvI|AsH9j8kH(6y(^p?Y>D6ER|^LF2SP%_ z^2|(}R95ZZfLPwP{0=+HlrA^Ha4%RBfM@xl-M?^@IllvK>6c1FC2`)qZbsZ->ZD75 zm;A?s$b*xgr!%DA; z{TFgpdMMSGrZ>H+A&_IY-TNtdQ7VQrf`qYYzO+q*kQlJcO7rW{$qgisdGqMw`xUmPULy(_9tT;2(K23|WIxVJ6f+B|Yr zn;=RvNFESD{kyGIzsJ;dpPaO51AN+XzoLOV<&9B&M|lK#;738}%bVtsEIkkupH2Bm zw?m;t6tn6d7_{d5QF@mCVtamI|Hkh;F7yl|M8x4eHdwb-XW=o~--wM4HdK{cW()_j zwCydr%Rg@Lkqt2&yEAOTIUxEOXy>UCm?Xag(V=$hmg4zRBAj-UC*9x*>&nj>-?{r% z>=tRb!n3>fmOWh%?@}**`6nALjNee)X4}?K8j|mx`Y?E`iN^+nc1p*KxCqa9EZlRm z2OJ3PwsJN(1&VlN8d)Bg9;_!Ev-VFdpcvpI!L~z4OIj*2OKhwY65@i<9gmaUHb3ZY zEg(a#v0Qdahy;nxPM}f|g>zBi?U|ohNCKY-qMV(x>aVpsQYA_=V3S@ZM^!)11@O{Q4PpY3X=*LsZFfV_^tFep(j=a6F+7rL=jP7pq5X?Z!%I82zLjP2b+V6T<#`(%I3@_2Py1r%!pLLh`*? zLJr)f@ypnvPVh-PNKKNrYSUauiIqGJ_HQ^XyLF%H^ZzEed!FuHx!TrVNX~h&=<4ZB z-Up$`b1uZNF*D*?73Ir<{1$*N9fIw!+Eg8QrZgDpg_`lRc6=w|`&bB>v2IX=L&{!f z!}p>*ExtFkNo~GKxNiu43Apr>elPmzwPyK%ak<&>X0P$kB4@ng$YrZ!^I)*0+zS+h zH|)Ki5@EYb_c`32EhfX8febwBibC?fHs*&h8F4UcuzsC|6^|bWsNWUCr0!p*R8+DB z-bTh(Au8<}#o0rll-z0l=q*p%^Vu6)cYx3$hn~8T~I~fkc!NK6e!})^lnQ7nO@5%_>{=0XD ziD`6Ik*VA1xVF+mb5e=%ACmg8f@hX++oY1+=gy-caGF`8JG_dyxx%F0vw-j<#r?s7 zepq#5pmj!RDueUZm#MmQB;{7ppW>yZ^uxzmy(SM{Zri3pdbLwmTBm7+{gqnQmjzY7 zsm|IxElaqFUPHQ$LeV-S^c?kciaVu}qW9SHAIW7a&J5cz;QTRge2S}@hL%iNq1)%b ztlnT9z?)xTkjIuW4Z-c2FE_=7pug5%Yc$iTvgRS6qYHIN+&mKTl|X3sj?>nW%n<5{ zgpv{M>_xm`t6SbRY3(0M-KD1^6CRn+)s|tWsf6@YIVEl2-ni5M9{fOS;zv4Kmfogl zP{Y3x=te61$z%)e+9Nzf>CfMm;j2tcEWfl)wc7dgL5IdI50CThinrACHRdZ3>l3H5 zb|Q5%lzdt#YL8AlwlKHTeH=uGYPt$kk|R{e>g@U`i_&c8)V%d0-Im%5XaH&SH7JDg z6erW65B$pz`ug#%p*OICaRPdo+TYCH?oxS^9(rxCoGI`Qx)DYng!CUC9Skln!P(@pnux{k@>xluRNZ#()JW0l3!7B&$j_1b;ZF+GQ?NcR#(>57Pd-d z=n!+)zMbuH758XPUAXNns5BGia5@zj$LG@`U{j8D&Xhq4m-Q=p>4Nh&b%Fn0_c^pE zySlic;$czXNohLlwIen=pFkzVPg74tHlMqswBDtC@=Fm%*s0?pPlaxy3tD~li6s9^ z$aTW?{VQFk827QbXI62yXby2$3AmOgro8ywV)=nVP5tHayQJqPpEut+JT|;HXoO*F z+$HQaPVOKF#I)8POcS|f2`U=a@=3FNuwHJPoZ$GBm;c*j?a%BH8*;0|mf^r6+Qo$` ze+Ju}{o6oBZ`NI8aN_aFB=GtU7Sbo{-vh&T=GKW^*gKBn1EL{MEuGst@u8Lw9}|>Gi8f zey|iov~R8w66L2^0t?o2Mp-FV+=oSF70POd)ee!J3Z23T+221QHAoVpB8JyBu!bY+ zh|Dj-7CvqIH*L2s&f2_Q#B;fwP@;I4pIm0vYo9N(m*>KXBMUmz4+jl)!vchKw4i`m zLs10If83yTG&=-cklIyO%zX8>+-ta35f>Miok*CMllObBk6p1Pe{P^=r}K|8l*P*k zrwdG6Om<@4Rrf#Yn4ux)ElJmMdh+wW>8~0K!#9WjX^S}<5w9(xyFTAs9y;xpOA_s( ztfKxJqGJ}BdJpOHD>%Dq0fqip^0O5U1oE!y{dahPci_Lgfk0jozx0Ga(CyK;pZ)*; z1Zb99JWCp?)zlSMDs2HOI?fs!Wk?-fV@+Y?PV3pUXGJCpKzJ!ejwwxgUNv93s}sme)N#{eQdoFcJ2Fjp zxVY-dyHR#=A(R9bbca1yX2v-zx(p1JV^d0c>wBNLy;-3}p%ROP4%df0lpx;iKf8{d zz9O_7XnU2(OXPGfC#NO;$?X;2(T?rmNJEA#0G9Wt*W8lPhMG1$#w7LC6v~<5!)sH@ zL{@u5Y~GH+e(Sc&Ft6*W#MRGuZY;z0Zke^btP~7*WY{fd?<}=%1B;f?)^n!S5=^fd zjcXnsHcxhB)j@!JHNtmFw>20~?jCrdZvDYIZ8QW+NxGr<-OPzstzMNdW4t+Oayz0# zdl$_ITDNDkFW+}!jC=uyfP|!2Rlh%}@*n{vPaAF~cJsA%*VtJfn351)m;@^Ui(51$;ad;l z)E7tia$ZHiX(R|pA<$|waOM+ZuL`lYYP=yoQ*2u^L{?`jb2ZHEpx5bg1xO}?fN2X zon1qeBJ$Va1S9&$u!T1Ozf*OijNAg$hpzhXV>2$y$z!+qe{6o7N;wTHp(bP!WS3FV zn|{|Qa;3J#Y;cv_PASm%xo6G9bW2TLt+bfdrJW7jC?uDi(}98lg-jotMonqNab{d2 z8^gpjjcqJ+IUDo+MOg|i<#Og@r`H37X=~|T3BiIleMg^BFBiD}Ydu+O$9FnmDZ zhR%!^r!lPs@Av6!n_umG^i{^Fi4V}+A_RoSXN@hzUiMbkwR;vuVh|zp0EiHGJjPsf z{`*Hg#PfR*lsgzUDg@$(qv`$<=Gaqe>ccA{~b(WJ&&(QSE!io8eJ&9ZAk{bG(YBYhfV@2A&=9fl71b z;B2@z2kH=CKfTn~co;WyeajiN z>bko7hW8ftNB2+U&UaSBCusL-gY5-v@~!BLP_ZW0GyRG1+0GpCgWU1$>^1l~lE?S# z2DcwH3|Q!)JNenvj6b);cRLFO-pMNKS1?f3HRwFMe)tE-gohnJeAf>V!^Fe68P~u- zC<@LIe4K4;H2wIwvMk~}x3K@ZmS&_kq9)DA{BV`s=h>B1XIlB948l=S(+WJyPPiJ2v%1$O#w`jJB|ex znaXPB@DU_EqYtOLPhD=L6DULbXGr1AOvup@{Lc5fs^?Tzcr5qF_RBLurW-V91RLyw zb}qKQ<5wBC9TNN*hC7@aQ#YmVK_M^tG74_i2fga&`g*AsPFHP$C`f`MGw^GSMSQ!2 zZF4l_mTUw?Ef>rHA$A)S1VED}Ns({mxyA z6TjwQ9tD;HOqRCjSq5t<480tlcoiz$@ANRsJ-!WRdg-1IRze1C837yH&y$=6-U57omsiIXh*5(DTsAm|ucmJ1JY;908nOl!7n1Bg94v3) zC(qw8qX>H(hV}euhSguDEiV{ZEiRY;v*Hfv!edi2j@{?ANgF3(iZGn_*%;*)co5;P zmLLhU_;`)8lV}OEdvl_SpD+T>foiRF{5}iN&#)r5CS6ZCr!NL88YDB$47Y}Q7P#jB z#la66zCb%a*VETfWMZUu$*R}1I-U#aEvPw_DgR*%I_qO-RJ!1iuoYX7AxMyLo2Wd8 zf+jVZI|em!ea*`)R|q|2nkGd5P1Im$$Y8Wpe(MstQB!#)KA*NgMJjtsDO8jkqB z+Et<;x}^wrHszINS6eJ6E>qYD;mc9mZO&NAdBz%9uj#7ksVJ!$eKdVqn@r-qZF0El z=wEq!B~F#X=b=8raYe!xXqa3-I5aqGyH?-!6jQ8VOIWR#QxHA{a<{ZGV>-}rhcqlBlJC{cCd1QN6 zEdslys);sGk(6IbHy*lkYN7eRfHZ%9WPKwneVM*aPDfTzmd88)tKxv&c>QR5@0`fY zf?15*;$mlK)5MGF5cMAnAT0*|1duaR6Jj=*EZ+Vlu^{`O)pAiuOJZAVUeNDGwLc-D zh^(&dvc79owDS4My5F5ZyH5XX-KBk zoDNVE9xMa=H{blscZHlB+oRd`tiAB(Pnd0PKzKC|NnbSE6wzBoM!_F5HHwNCM2Mjz zq%DU27Y6MQpV2+9$n;7ZCH%_u?N$oO0`xl+xCkb^cksh8dN`-m(4o|#aBJoAz7J6f zWvCahXJnHn0Fmlww70?@xD##6?I+_pS?JJRn>TQf2HWVn)l1`nx= zM03i;T+bm!-n(WB*P#II-#Jx+s%7q%6rm3JTn^RvmS8*mNm&&@{%Rztn%_W z`IWEWBybU8|DhrM`_;WSK!IxhcaRJ)#i;=?!0br9>K5$B8L7-V&x{encZS~=w80^AkdD%$(T9-nX` z6*Sat7bJx;d`T>H7S$Tz4BC;%#Ilu+37*=%8u4dja|{LX=;#Tl$$ZH9h50%xj7c)( z6!*8l$*<{!F%%-}CfmI?)Nwbb7kBS(TTBeIHSC0ux!Bzwgl*(ME7n5eJ!#j8y1TpG ztz-x3|CqFfhIk8^jPJmBD!&KzgVM05y?ASJ(W`>&e5a$6tkvv}$~HmziQlCAy86Qh zrf4|G{jaRJj~_6NUW%FLxjfc*vSG+*B%)#e8)OS()qk9CQ8w-Ajb!V|BF97o^nMn9 ze=LuPFw*D);xpml2O(Ry=dtFW*o;PJzMB$6oV#FdD2jMqp8m+)s>Q3w6zZ|*xSCR^ zBNf%GZ56Ilr+^lfv?Tuc2>Qm|g_bvAr{x#bWjUCnF%5eU!qt%_I--=^PnJ@Yn1Ce6 zq|x1XCu@80*>D&>kL!Ajj)9K;cfap-eC+-0!w?--e>e0lO3d%}8xxe5$?s^-p={m@s6zHKr1TqO(`vlj+R=_y_u%4_x*&zk+!8xYimNk z(e%vp)r4x6kk3RumKPvu4n=%tVmF_SiQl(Peom$puSm-)`i;i;jFujnxJOOb+o|On z5Yu7XNmp^nFl$#hNq|7+X0`~#5MhtZZd0dk`gwCL9) ze$VwzRwiU{(ADdHp9)G#QyJqW9h4jS2`u5b3LZYPgspFE;ZfKm-iD@i!v=O%(YCBJ zzrRFor_U2&){pN>zd!v=nC7Z?f6*i+M*Av|3M_;e`MAs1;U7gDpy8uI%R{J-hIH|2i-Nec<2xMfoo7-Nb_a7|D08?*>^hRSzyMQ!V_vsgVL26^kpq z`c6)Sq+UW~Tn8NC!%?BF85&9^WB#zS z7aRM98M-~UGbl%WW;hY90n21rL&b1wY?xbcb=zwmoE0)<=^tTQwdYNl_efBiwxpLq z$Yz+uYC7VC_`(UpJ_LzT%1DRw4}!nKUpGGH(ij?&Av!2~XwlIjvQ4k@Q22d_*g~z#0ccS~ne^mr zmTDZ&8ehV{4UkC1kCV!)R>-v2A!sXitRgtu)~YFAB<4=51+<57J7;gRXJkW`w!X59 zprcjo;$5AlvG}KphUH-YM3%R4{UE~*-na1tiUUSSXKw>Qq1(#|=hV%;&3g0gkN(XZ z%NS5!rve<@gs7Ud^_|uw;~XJq$gq)BNpUhVoAZ^nxA3NCxEc?U;Yvqc10Ff_MKMYw zXhL;(6)4b^%O0l-pVLIJ{G2xuA%N&|MM{iUrog*N)jjilojKe|lVL&Y%PB)J{l z8JN1RbX2)?wkSi6;g={eAwP|3CFd2x1qp{u*gH)&LD41PGx}X=iw*HUoAmQU?K)Bn z5eu8cZ1U)P?CBfrca3v(A>J|)In>~J4e9t&3@8Y6dsY{qi~Y})=Km-`Ke$rMy%t9Pw+J-OX*g}<&v=w?C(u!#|ErPqg+n!04U zaBJNovnK+@SK2GpysjzjN{?oaQ&z-z-+Di?^<)c`B4EaP$>U^KJ^-EkEuhwyAGIf! zX(BiuA`dGu8?Lt3Hn!YV&Ry;@q8Eluom@!;egAqwU0lk8Qct~)iZ>XC{p!$H$kvx1 z-89`JNCnuv&r*xys8_GT`;OkZ9qmfvecFF{0p1(fRri}Z=?Xo-nP1IgZ^PDQ zsfTs1xi7Hn2KEVTpCOsnb7M2{docGpCyxiIg})K;`z2rJoEmFzJiMz7q>su&9)p|= zjZbRwfbaxu`3G7)i& zD`MI(Gc6;yZJc(}F`dy{#EMr>B`F8VJWlLK-_)!`yWvsCpa>*_uGEJ!4^@#2)A3$Q zEmw1X!=?uvKrktKR3d8=ow9C{3qoC}+f19Ir-!~rsBc2;zXCe3TU@LJg3on)wWa9X zk7N0sNEFA@*9CWsNlAM%3+r7_$_Y?y0Zmukz)HkrL<`;i9qLr?a#5PZZ4eZ**ENEI zOpOF9m?TiyWMm`ZFQQ=jqoyOt^(L=RuRF%7;|d!u*w3y()Y?fXYoH`GlmqwopbL_A z$2%3h`jVE-_31QQ{czNSg`cg513==kW|Zt*Zs{})MeDeS1VVlB{ZiA&05tz-L)+p1 z`7=h$JH@wey_JOml+eU)x*)Isc*QqB$$Rk-TFdq%;DTYWWR{Y};YtjyKFF+!POsnSrwwxV#)2)$cjuFTh(WoU}d&ppMo{8CqYd)+|z!`A|itD$y%6@<@Sq+FO zqL~FKDWXi{gm1kJ3h2uc(A82S@i;$^6-sMvEEh(1*#x*5NQv40DBNZGd9*Avi}FD_ zI~5OoLC6z5xt7LQHUML~y%Efg2|VbF)T(xmLJ$4JIXwGo<@TgD3BXsxm)#4W&Lq=N z&XU{zT(s6*S?p{X+cN5G4=*BF&=nuSf9Y8RTD9i|hzx$qBmLbkvOXslA6yTjp$HlL zO)t=3LR_km$jfOmH17v7kAV*bmE-0*NJNYW9D_n`|=sHGK&wtV+T}n z1hVWI4VmJivdm8F_R1tl8KeEoax1hq0$z8I#sOoSBzJ%Rwg@#l0ILj#V-35ZS5#^m zKFe8Jd13Cu=6F4K&i$1xi4BkimpzUHc*aeBe=jXW?8g z4w}kH!#n*B>0hivcE2Qyd%lbw>I!-}&$j<81Z36r)H`z2;95`@KEJ9x<^>F6kfaBk zzr*H-bo5XYUVBJzPf9IsRdCMzgH<7O##~xvY&$n)TRqf0`1kxui&M{Zg`q!+fJ_)#MTU00yDh-#fCf2njt;$isQ0W~tns?&&3IFB zxs<Ct#dNzI+o4zk#7uBh zhByKu5+aERQLW=i+uf{!hbJ$5pv2n%1=1CZBAzao+h)1!)1Fi`&|h%89u7kv7QY?o zy)m|}vHweb9~IDeB$9G?7;r>V;h`S~*pQ|;+3Hy=&^PSoXPb(Qtglbwt{?(Nq^z<~ z!Scw8_F5G2H--=kfapGJ+J+7(&HWz(#&*JI1*sP{&Jt#DO=(8;njL5yYQhhCX!_y1 zd8A}QKpJ zAnM)Q^POUSCDraUTJnk0HKs}syaqLnqr}Tp%+!|bCSw)DR-iZ_yo3(*`(UmcnXqf= zsd*$6xi_ zLGS*JD=kH?psLEAD6nq(abpY46y|LZy3jbSWY-nVty3Jlp1Atyu~c*$8BREqbHN(_ zF&^mKm2_AbP;O(%H-f&Gp#1uyIG+@9SL#^`jmt{NOu+i$bf!SwrJmC!MBa}^*Z!B_ zPP7sRNEO8@lF}(rjHj`7`@g-1HdZI?|8NPGq7<3KMn75aTT}aE-jfMj@{F73kc%`7 zMEVco4=Ph%V>H%gOlOMH$P6<4`Xy#%x#xMMYL}=bswS?fNn80H!S3>(^YKMWBJf2u zF8Lgb>A%M~dah55N&|8m5cpe8;ov$so*|yAT2k=vk8LA^qQ90ldp@BmiSQQ(n}(W7 zl9+d7c*&sDP5cu|aF4Re;g`ZXfrKmrrE^eu8>(@5#9QrH0%BlGI~}tASXpiO7W^h{ z)3k?d9}8o3p47)v+rF;bvVT}NGSJXyWF?KVYxBK2`Q3j;mH!tZ8wj$4$^{u#AEtI> zRhEgfWk#= z5z?AHt9KWyz;|GPscUvsO?lV0h-dY*elgrbxc`l?$GBLoP88=&>@zq&OmGj3jB+#- z4*JlFaT#@Z2CV0r*i5fg#K;W~YHr#JU!F9(1fXB3-x+8xBQ5!umF_KToz}=FBr`<^msR2AL$n5vBC*q~EK>?E;dc|%2pdXp+G+ES)vQDg^Whn$l<>Jvp@ITD!-Q~m| zl=bWQ=REoKP;E+j@`+0i4M8PtZtfH6nQ0aAPCcW?(|R31^PE7+mkSG9YnN}5_uRj4 z2{lT;ef#=mZ#HT-bwQ2DwalRT*hzgP%w^G7LBerMls7#w$p*-?q3U+Srdv5Wx*ORP zq>j2PlQev%a$`OZ15L($zJ@3LFAM>88la~iwx-_bp<AJ62VewTDpJEowlr^ zha-}1R;`tL(AmL}!sz;5ITV(@vvgs-VJA{mPxvbM?77^#=R&bks}jL6^|AmIRufx% z^|MgZP|9Uj(F)h(D3eXrj@^yM8bBlEA$GgH&8wbAt_Wn?%kKTX{aL3Tx@^e4WC zETu*9vEL};`au+dD`J#P)r{g~Bd~1p*!rRXe+z^XLLv)w7~Cy}Xyp1+b81Mq*J^}{ zigHPDd1XcMugRIkhuh2E#uuWl1O(d=wVb3q#J+cjxq9$X<(i!E zWO)S>6u@sYs-mq=faT_O>C7W2BkXxQ;ar5#$oYy-3*$8v15c+S3rc_zuqrga5?5$2 z_N$A2?O3z4;*j4apK&Clre8q>r9GJJ+#87|wenqGN}!7)ZielmL*b({CRH`2Nxn~u z<^FFX#hv(z>J!jnKC zKG1lt#6igb$pJ{EiABMX0*+*=PdMNJ&|Bd0&2pR5({8@-btfC1uq13h+KU89K~WN9 zzsPco-~omb{Wi~5Zpw5}rIg|;i%LfN8BAF5bzDjQ*jKSUV&Spy)@}<3hXFVMIjE`1U891WAST+QtTSTujSy0MjhFb>*Es z4ISu?NQLiy-f1hMB_01RI@72yGx^)$elbJyHo4!ZRlv__=Z|@Y=D79=j5>7uC4D@15zog4WQ=A1VXt=)%fMV%w-QZXq3+c|8P(bzy$Hw_% z(4p|xo)=_QGnPIqgn-ildQcY9cXD#b0a|HJy5^**JO&+Sm;4$J7A8-n-dFUn&Wq2C zjQiGR`Pl^#Pk^1b;G6hkv_A`Dh>uUyP@BCxco;?v>#*m#^nBi_jq1zyj4#Ko7v^T# z?Vpzst6X}&6~#@|FlV+2*dzKm4QLm9<_g z*SgZrFUFK)6K{nwn0`D%$d0A%4UWzt+WX_dOP&{58v^~mIwY)JTU>MmiO_m6#Xt3-Ia+8X@v zFXT^Z`pVP$Zalz0@D8C|msDL(ue6|~j*1sj$!s*Z;G*M-R-aDG#AIP(*n2mb4QdMs z`HD?|(!?1yQm{o^3UCtvzW0y37Oz_iu&ZyF83DhB?f+&B0mzn!VS0Ka5WidMI-9D3=0o^#ia9ny3owm(BXH~@3HTYL-Dwl z7j=R{y6P2Zt)91Cpeli=dbENP5fTD^#}?Lf3ae04=W2c9u=7=GuVLRcbyF4>w}I4* z&5au7i(hRto(_CaL_p=V|9m;)GDvGuGy3iO#$6-I*rC(OT&9ntLg4y%I&?W8#YTeJySBYw>WC1PGvL~ieax&^MaW2GmH+p~rMx2Qd zUn14%P-q)yw-b*pFFj>1*tJU2hc)OB>0rK+m+n2Z0gyoZaf4<;m2;v#@57Baa zb^>79|6(!0tFCqc2eRr$jqpYIU#vtY?O5&HewLoN4T)N-ogxNC7Dn^|g*1Zn0^D=&D?`kT z5q#cv0_HbgXA;@|ajPck1$(y%qGs`GsHm6~iG1wqRl|Or^4}340DKrwg-LG`8^$9b zPEavO>MOWvY^VAwn`O0oQ!p~t*({&FzvV~B{+ja*gepy8TT)^ov9YlCP0svqVyqMJ zD$A;)+J)scUHdnguf)fY+*xpHdwiM(f>?A#R`w(TnZOlHPD%`cU>5}#5rsQ!VgDJp zBV@;IRS@%ed|4P3dKglK?Y|WT|C1|J`;x~Za!oukVxUUwRw~2c2 z2Q;G~+Y+PpEzM9^kH!L_*VcDUN+)^}uhI}d@%ALVp?ccCZ*<4`7638ip?z?+I<~yS zT3k{-k2gK6hv+9!YT;^U#){7&zOUaWx2(CaT^4Lyvjus+2nY3 zQK2<46DSQEpg+u+z%}i`{`)r|FaR0uQbR+nH+mfeloL|evFJWfkRc*=AhO$Z8*f%r zjMnXVN|k{xW1juPQhi=?h*(Zja&l{Jd7CZ|a?glfl+K@x;>f4Y897k1#Kqovb(cb8nA`|yTu>_eTrOSLF(&FS_&pAIx>JXClpKF!UIFX!yWK=^JDt2 zG2J-%g}k4t|HQk=%X6Xzt#RPHzd2kl!hRjtiVIwu5oW&`XaPOP-_xNrURRMxPepf< z+peN=!!P4MQLof;}S!O;>97Aav9oiwV8`aZ2T zHmb`z?9U(~3Ey9N2B3dAKH?5Ce7VxMD|bE}~3#1zTD=RC0Edb5P>Z>^(2}mk{(Y0k5KY%n7aL8zc=|WE5>n zGoe%|$_f;KVSw;N9rsIs36?O~T&{)!xwb*n{;r{+(%;YUM|g;dwx*sizv!(bSzPVe z>ti*}QY*{iDTxa|)MEi!&_w`B`TCjHLSY1{`L{4fc^f?~@%)@N;(vtp&|gN`=sHitP=x;fF<+BwW9U!}OwMk_J7K3asNBZKKLKv>vMeGC!2a_|#l4`U z#_6=4pQu2mw8bg^8RYTBS5`^I?3lp;25=F;E}b@cJ-3HgY>@@rW^zjhZC}an=Vtzc zkY)QsS|YCe{_*dgDr#_CW~|SpqabMYE6a9&Be}qvqioO8P+I%xk5N~290)R#wwP~PxA;TFDR`?U6s;ldVq7z#1 z|5*bS63}!O<$mxhIwC11B*XSuvjpxpg(NW9A^nnUESi&zI#$X!LlD@3fnmO_ zu=)1oOClZKtY&Pydb?5pc%kN?sQP$X0COv$jYxf4&h9_v)}6lF4p3I(-AE%O3_v zvHbt7*g`tU5G2o6c^tML;{Xo#bzy)&hJRo@zy|$Xq}C_@98J!`F(!Ysx?#`;j%vF9 zb5if$`pW;7wf0tI4zSR`-K1fIu%Yn<@cxT)yBk|_zBs@CuCg5s<@0vn-Njv(&;1*x z>om@T{Hu`Ke0-gfjG7qpui2YOw~fLuLBev8Zr`nrr-%KpF4EV}AN=w{C0gzO!ubs% z!~7U2$3!@3KWdH5fQohYIt<(NxVTTs#sf zDqZG5-Hf$w44fRvw7Pbvf8<&%>)+{Pzi37+8@v?D_p_|Dt+6?nY*JL{*LXRf{RM z+F{xTRlZ=RCa0$Um(GAPF^hqVOJ7=akG6pL$omz2n~!(|Xn~S*O?xQ|e88P`L5-v6 zmMq9ae>>3>sz2!8Kn~m_()Dgx#ve_OS~;)(G&7*aZIK78+lk=Yh$QGtfzh1SOHxsU zz#vlHS_iY$0(&PNG++k`R@A>|xy`8$PYS)r+eXqj83HW%3X;ZNbQMqIg=VLVB35M3 zKQl2Y_2IMscugDU3ubJ=$PbXX|K%Qg0rQdKVXYlyVf0PC_v}_B6;ctv+LI<~JTk87 z(9$Vss8}&S4>0w6X4U8ovkHg-D42|r9*Tj7g@c7f6)Oc?8vsc3@q1+ox_!E*v;*%g z^DE&=G1{yNVje{ksPQ{WEV`hv$4oYX!GOr0+`frQ6~XWKGVDST^uZ{6D~X| z!G;mH@99F!G4Nrnn0de`ftH=9z@d=wbgK}~YrkZXdgR~7(nL^VY5Cg(=+|V*7-2<4 z2$_*$l-=c}?*^+xV1SLGp0NcMEKWk7(d;%tEr5%8Ixowywl;vWa#%IL4_Zr8Kft&Qd+OA83K3?9wSEG>M3Nw4+6JG%&ZAzC8%UKb^KDrjZ|>F_uUO6;zGw3LXaUR zp&s!06+0#R_74?T6uX>hV^_HjUi~%3$8|V%zfCGT%38o~u=`$o0Dg1)pmzC(A{%Qk zv#ax8&Nyu=o9k~Wxt|2NJFDiiMk^nm>g5M=IOjzsc6V>xJ2eT+JyMJ#1w4&1gK&-RW{3w-at z`a#Ba&OsYTkUSq8MA~Iw^;ht0I!zV12dJpPlu1QR#ly)B#wd8Ydr3ye))!Yt{As{# za_5<|Ziw6~t0!BV3hD)&Cm5l4nkE~*q`Q*;YN$C8jtwpeEDNx6zToikcK3jZ1773$ z8ko%2SjI^WulOj^6ra@IeMjiVX#a0*T*<_#OaOYU6tVSpfw^}YGBV^h7XrY%KRcNL zC5z@JG8L4nTsFEppJL@E4nb$o(%I-&J0b&H7{8k@Ao z4fB$by9aQYFhkgG)8zS=x6ITfz$MSXlhvq+nPwvT7Sb$m>tG2CW* zQdYDvYX$&@W6?)|Mfm3;ENqf65CVYT9mpbHv;#;;hQ1BG~tYpBA2;uR9N&jdW*5Nh>?kbv?w=Hgp-Gj zn@CtwPW9*XctKfPO{j#`hRxW}-W4fmag&&nfxJ;d%d!PziG#c76gg9?$p5Dsv5Q3i z@a_5RZe+AbM- zEQ}le(6Y%+J20WO_zR5KtrLONK_`vqT`%}L@M}_*hLT(%hjY;UaYtT7W*9mq9$s8L zdLQWR*&Eq-4au@UA+;yL+X;A{u1l#H!xPEMUy$k)5Jv}9pCD?tb2a01mGrm$mluGG zf{tuOUV;#Im`xiEf6fgTmXun;-a!VNqiW$FeRQxOIJ(^= zv^0=h1(S^L;aZjuJumzu;QWZj%+I-3;D-O;VGl~lI^qQa7-Gt<1!hixWUXzrwM%to zt!ow<7P3FrRC4fU4Q^*ox80$#)0LDAvzX%M2TTa#XXk%IKfgOoVVW|)&k!Z@CDQh~3@}?j z7Pt7O$W+g&@P*B~(E9;HCt4H36*C+@!++#t zXIGcBNHnA&LyM}4u+gwc2#P8OH~79YGtwPA9k@5lz=8FSEfD=jF5O$%@LBx2IQMC| zsI>Uc9~?*0Ootg@RWo`79Z<$)Jj+Vw;@z9~b6jIp2 z&zvrhyPUpiM}gpU9`^c_#h}oUH~l%@~oY6+NVv>^rpPVAtT}R(tmmzgQRm?n4B|aVa%M{ zw;edE7;%-!92~C$-=|*V`@3 zPGkngksl2A$4(8pV7Z-CjLE(M3I$)#%&N7FzzT`u$f82{*$)8N01YI5uoyO)cQ>4( zuBpmDU>jC=>@|< zhOsU#sgrsb``@m< zbv&&URQZH!*z7J@fk7BRnuUeQHq$+C81!xULfv5RL1iBMmU!IlW%%%$Pa;gG=A3c; z_uo>mu>8#agpdKxo*uB|Q!_H2b6-q?;YL!RVuFzGim_)1$B+@iJ`ww|_(^0MsJPB> zqS`GFwPLF*=Z!Bt$uQ}RWLF;~MF(|x zx=W>{M7kve>F!dxhaMWFVd!r5&HL^z*7@GO)_3;V=d8ox4+UnPXP&yQ>sR-Afii+S z`V!|DC|Xl@@#Mhsd13wk4;v_H!1i|jOqUt}-&-3<5rAD4WY<_=rwkf7XwYMWHvXTU zPYSevhp!M}3JiU#%L{I&Hq4Cuv44`q9SO7#p&VWJLcmK&9wC>_s!8ukr@4tpN=o`2 zQA|T7K$rxrK}k0weH%m$bkyqRLNnMWTmYRP@a-4kPrA;>2%mm0IsLH986m*8eEWJ5 zB8MF&Yg$f_vbk(TW~7VQ2WB#0kUzA=h^8QC==5=4wvjmrv^HJCO2#jc_HG^sLKQ~@ z{$p+O*NZ-hqIs;(Uk|?q`ZN*Qq}t!W%NUsvN>li22Uzj==LhGfYsPFr#LwcR#r4hU zw{k8F)#)?i(bUk+zXqq{x!YQ_DeZsNrR^PR_xAa{t)%ULhczac)$u|#-zG-Kg`pwM zdyud*+zOBHy>J-WE|6mNj%U`S-zx-|A=0du^ZwZqXDH0oMyuHe`Zu*n_>KcOTkni- zUYZ3Z8GZ&yXn#8-ix8ROHQd{$;CYQpugL0)ZYMZI0-EkWn!iX~OILxmLR9 zyVO#USq=tP1{z5+^i!AXcZC4mA-LpcvWmpfcpo4p|KN~=$GBaXN@f|bD-cj{Q@4m~o$om|$`NA`)4BSWvX(*RDP&wvC{Uw&gV zZw?y&!*WSrq+Ens{mA1OzTjE|M$~*1wie8vCAn?9&FR_-Ihnad|Bm@}Y$t2cRx9f6 zF81P4hN%L*ytJ~<*@` zE`7&L8$D;~Fd#r@hA-~V_E<|oa{zexRB7`UCi+wQRNbdouViOFW9E~Im1lj~6)jKw zvKHGOsev||`QvfcW2y2V)YRCRn2*Gw7g9dOVt#KTR&$ER|H`y*b>nyW4Y?9J^tv}@ zetK}ojvVue+@3lvZ5Y~2o!PYhi%4jVt`r%DDph3TW^G2s{h}SO7r|It76uj0dBYWx z|4#}vh7>_%*=iU8Fk0S*9-K-P&UYJ?(^+p{HSp_8qF`*Sz$Z}ifeF*VvqeHao3)|H ziSfWn&6P+vq|*o;@##+0M%RS2$#ZEJJROBkb1OB#oxZerN#x@rqRbjMWW44hV7{KX z89`j!VeIqak>kFE9eA^oZ4>%zdB4Szdt_k!Y>iE)@>J7btXjIq2F6lfnr6up{{r6Y+8ZFA8pWdVX+dC)`4?es2xBmh!X*R1B{QAf& zX6|{&OXZ#%V$6TMH~(UG-Z#k`Z^2a^MnU4md+vUipCxXwSz?U(!M%&&v9?ucmSOnd3WK7c^-5BbYZb8%?>7i>R?c=Q9|HKZJjLE z)o~kqN7&qupY#c#zC1r_UoSLpt@#K{X7n44H4L2NV|*=s5*an{V6TgdOM5X7F%L~r z(my2k{uM0#*NtMk*11aAknUM6{94+m=JQ{Hz24ruqM{eA=Y?i+8@03Uta9!}%^j21K{4ILhf zPjwNOJM8^9RlNL9ghRx$>8z8hY5CyrpT#9z^J1wRrdX<#GK8~Tp(wn0Buw2N1f}yw z3EzG!-RY)qVF|z{2QTJ1PKfp6LXGdwrbrkVKBEH99@(_KxYuEyb|NoPXaS!OPJIyyH7ZR@NFZ>$ z8)YxD2Ve~hvH($KT|UZ}!-rZ})&rRtplWWiFjzv_%*I0k&(wk%l8Xztxf+{+D#UPn z?T-?MMsMbu4X7USS_!LVTVmm(ZXP?=QjF#@lArZSUE5nr@{JdWPYwS-2Cz!lbpHMs zB-yDSY@6uEo=V2uCJA`z#r)UZ?+_JHuiB<1tBF23!*3>5(g&+1u$SU&i#sZoGs!Tz z-1d#nZNhUg4{qR-)BEy1smN8?B%?N7B6Vm#C$g+eVPL`uF%z`C<5e>H_hF&(`sqA3 zF!}FrbD6Xg>MNv;wbPW^7`+@N>eYnOG5#j+Gl*LXhv{hW&fMv2lZk1L?Lfo~3W(0C z_cz&CZS?Y#f6G~*ic`H^!YXl28=WAqinTmo3ghAdAEu6w0acp*TQ}v1RhVc zWeWHlE$l+(-i?0u=RpEb)JdC}w8Og`YKM# z{eh(Q`Zz)Do_(KgJQsbU`Jeoitu@v|?R}Rlbvp$Bj*!t$r6AgdBEE91Dji|O2&LdO zd4IOFu|iD37{pJ^W-ny$u`YU0N!8YgE>9I4C8N`n{BdB$v`*rZ8LQQ-an<%Ul%)C- zCe@b;vrWn2mY5xPIKNvNRG|f0iL+Li?YzILdva<)fvujF+UEzIw$a{ZR*|8ZNhKRK z+m|;Tf+QMaQ+leibEfT)Ukj`PhIi_v+q3tK{A8gw@3jWY0(+fxT1eR$oCeqDXV2gM z6;NZKrO_^5FiviXh!6G8OF-o)wDn$QB~ST@KH`w;+Rq-oGikFRn_bV6hSfA z=yk~bdfJPo*BQcyy9a0U6>t)&*sqhR;9i>=+InrbXnDmkc4Dj6;NiF)j*R>gR;$6K z*gpQ-(Xc1NA^^>8!|lkI1nnD;C4%q1j&kYs*??5Rt5pvv(UWGiiJgSvj4bQk+hOLE zMGmc5&gWsBJoY<9x#i6jK}m6A1?r_^yp}TBCMETrrNuod~GF5HLARHn?cDGwU zGN++0uBD`{YkOs~c1|ql(2%uj9`Hs~T`Px`jm@qkKz=I&eU4b;I-TY4qB z9jhx6f2*Ry5EftEE%(CFJf|!~L$??&KKD7yZvJno3>G@}vW=LW-Um6ozkQvrb+x|<=@kgacA>iKn3leFZD_6Y^NDUg{d!6?&3%bTx=(($m85C-sGCS!R}GiP zBpOaBE*qoZfO zdEx5m0a?PV&?v%!^PA+nTd~t^AaW<8WZ~0y#Mmqy08~D&HGZuNFrv=p1&!1{EeP;4wcV^%Jeq(kvbYv6*?~OU6sI;_LPggl5_4_0(S6JuO^#RQ}d%rt3 z^_IVg95Z^R0JobIY0T9@WE_mlPCIe4kT!}u`Xji&rP{HKRxlD}CL?||GD;JgK9_#^ z66xk|#jmO+mQz{rM)Xl|gKn%hmbzf0{rD(_th37}$alpk{LyImli_>&Wc*(;Z|RsVexF4Y(tEf&*-QIe zGg6h>uOyqc34a;=jxqFV16hL;XI8;--+vYnW7G^oX_)14XJv=|z#qXWP2dOHV zL}p3iTb$IXSP?Pa$tLn7-$sRXDt-3{s96epIkoA_Ik8ij2$_STqOWg@0xrx ztlHl~z=PUC#QtI4Ym$H;v`n*p$WDQPJ#-f029(;z2AUXRg>XRg>lsybga zq$#e2LFb*4bjnQS*9^x9{qSTwPgdaS+|{83y;JS>4W5(ViCz0(#OaHWForb2b9qi2 z+PJ=ci6Utv5z{xuU&`Hzx=wmoM!)0j3z7vOh4sgZBU`H`MMcS5)){>mfn~40cqxxA zoXnaBoUG*hgVvn;RRzQ@ROwMsb~T?lm>9MuaQV9tnEy5~MW|@O+vU(McY1^J{eGhB2+x6O{rp8mYDs1JsUy<@B6BUVAF$=QAcpP!9PB!7d!Ir9W zp1Nh`XGVeoT)NmY>(wK#pzvEky>cFkxUrT^#gv@S=C8TkR5aq2(H&xll$!8mo_ny% z7Qp1-gUCaIkzTz@M`>!fiLxEZ+$a-_xWU$!Qwth2Q&&+nwxghoiA#>B;kH<6@7Qov z%hgExk~RAINk>3n%WHbLC3IC!y6}#Mo;I4`=+vhZ3hn0h`qM8FzT&$)Rz7C#l+YyE zBuN%cmbE7~A6j}p3cxp@RoQZWE*#PWg__hj`Rh@}^y1aN4hvyt9qkl|!lr!A2;p_L z(QEff68Rkmf3-vJ{&sUOMKlUE&wwI?;8$G5z^QpD<-zVHK zyl|;w$f92UzF5eK7eyqv=yq~a-81DUw_`ou*1|PCG!I>U9eLki!;lhDH`}&j5c{&Q zU1CWDQ7ka^&ueHs;f-||Tq*eaC6p{{W$3wHGrGG{!I;0lT#mV~g_j;=FN?jnOGs2q z48!<~wyO1Y*8z`rL0KJJ&;7TYj^ChvWLPQb)|jI z-91eEEv?b8SQ^?lXu{r$L0e^%j$J_KjR>)^YH{d=wmF!J%A~HO-3wm2XabBRn#4{KC}xLKO)X7YLK@%5n1xh+@S2xD zqc#bBlqE>kPuJ5AY&A}L>o{@Lef?6>k_tVmAYH5Iz{yruL?lM|1#b`#)B{7^lqO4n zg0Zrb?k&zvy`NB7RZhnrer>m1!G(t?4<%flfNMc@MOE3nvGV5eCc8qq(xNj|L_lc) zDcaD5=ZW&sZk19a*m>XyvVw27Lc|PT1`5Z=f8R8ThS*92^gt?GRyC>2VX)$Wq%{X8 z|1$91V@#xTkFf81`k0HwzU$4^0KkyyYvBO*#Kx*Ge?OHFX|1=ly{#^PoOrwVRKU|` z6%|h0hUJCVcnl0Kr~2Z^${H>93#Y%|042*|RECS&6K2qrdS0vs)|cxQI<~eqW|yX~ z`0Ctt*Z$*CPh&T_p^0y7$$0GJ3e`G2RMt~H-M~{;<$Bk0hf}W1i%S+we0>BtXZ^x& zUO5dk?W2hTKh13|KrGi~RXF|gl|}zMkZ1!cssSsvld+%lunk8_uaQHGC6_TiK;cBm z9EN`b$#%FKvHXjGoyBU)ve+R+j@)UvjX9@d}&B z%x%nEO<&C*W|sBLk_Xd?2BtF?d8SwIIKC00gf_K_^Eq zoQ3Rx8=5t4dj;pcjNz}ofbw1O#P^W#I%X-oV7Unx=QxbhX3@z6UgAIX%=}S8>Hb_r zmqGlM#m~RNa;XxCnz#gj{7r4e6wezwekF}vI^(#eg(+-N66gTN7jPKB+(5+V%CY5v zBq+Fu*qQkdEvVcDZ;G=NZ9rEBufX<`K;W7xsVq%A#($xNFSZC#UJX~`;YgDPIDW<9^Hjy{? zWeKhbxQV3V(g`b#Pub4u_IhdH3_V=Uw75I=> zz_)i*+{g);r=ctLKH^&&ok-zHX63mGHwcT3Q=jxMxwc((QN^>MwHqfk9N&CfGRGUjzlftz@Z=j+OJPBGMN?8)ukMn1Z(@mr~T^12uf;yhmCi z6z2B5aw`hfI}16%7@g`LS95C&G5V&i;k`Cf4CD&Gza6mRhzOKW;{RgqC}t(}D3k^n)&B_p*UvEoM|jgOy#8w9^b zr>g-EU*Yu-xg7{^K=|hx0U&E@QJngD>Ri+=uZ>RSPU(|w^I67s=%EE~x^+)x7klFf zS{8^J&ohQu97v)=v{>^z_npB*Al;AHrJ}M!oPvK&9a^r>-2Kt*Yu{7wWI=t)>vb~z z47jrE*DG;mw8;X@;MQxaSar7N5F4A+%v?`B7x!J-Ri*XQ6}nje6_F@~!7iot;j;p>7HsOay|E}C>`XF71(F zc|1)@g}QNZ6aLS?Iwe>X7J7I~1_zrZBfg@WC6^b!4j6ofw3B7G|6?;SU*X00wol(ep=}+3*UIp=_kTb^Bxu z%Ye&lFtp;MvqDE#f7N!sw$tZ-MMV?(!4G1um{K&Sc#ja@{@1e^RaAcHhj|!3JUJa#p2Q;v5CLyC?AusE(Y(KB3f#N!^8&A&-{V+ngAXTG^ z`@2(?DWD)?sj_2JUd?3!logC~jo2R7P!vYQOpvSKum~N{(p4t#B=@X7{^Cloc(#!2c9rq!KHq}29B#->&{s@+}_~i5rM9(5@kcFo7X{1@*NadPwrT$wgCB4Mb4+QQ9vNd8=3r;67e~g@RNRmF#M*m?ddz6@ z!hEM&9wWRs__mpnuVQngKdk;mxSichCbY?0>f^`vJ@-F~2A1w1=m!OR5-OpQ(; zz`(`u<=#;fGo5(fnMt6=Fp8@R`nq8JD z&?Ic3W&|t6m4%vZSw}%b#5lV;$#8>{%kdw;=drEXL*{kmHlOp5xAxWtl-f2CF zLJ$#_Gj;C+vINR>o3Oon;b%|S`Qfpgc+NcheA^3&mg2;MYvt260DDdeECeZJ_$kS5 zySyCzs%7@o?p-F9c^1I?K}N|YjJ#dU0o z{Lj(IjF(EB6~^TnHXO6AhgvZnLu+xWfItBKI4g>+ezP2ShI*l1GH8^ehgnt|#MMUm zIk8q(6qsf9=kmXhubBb1y@IUoEPE1?mL7#X*FI2-ftpt>M5-X^%B=EUV0pi4v^lFH zS?cF5ucv2ZyA*a<;EtkMF$NKrD)WPEBA z^^gc@0~Srrti1+$mss$aqo6(r?#~(pga9WV;j_$93r6X;z?E3`Z7JuavE$Jzbm9Ms zAWZGV0(D<89soip$P`VNH3Bm$ru1$w<6d5ZIf>EL71DC8W&Y^VS1_AQ3>~*;@7HLN zGsQp;4-Y|%!nAgZloYZ_<#Z-z)}6gB{X6auVbaEWMqu!Czh@2>A_;hrrqkFaDfB7p zy^3p4vXtlgivWeWcB;M=3Fv5|IAsjL8bD;b*IYYcaYOeb@L6a4d^dCBvc4-lAw(IH z2743O`4i+)A&d8y*~KWMq5+9BIwLI&0jrfs;|E~J;i}wI>M^k~Q=yGmciI+ql+toy zjq5ZsCdbtv9I~0mM0%DojYld<8dHY!OzbC6_ue2I@2QUaS#JJuHa&9Gm-qb-}ds2JUmxTH4GLoo_Vd@2y2pwg4HDE@k-i>?PAu}73X z)yI!*g89KT!I?}!rLC>5uc*qvK=T>R%Ek&}X$gemYb7gg?wtOI^8?e~gnp=`0Tj zg!>onxY;0Q5onJytl<`H4QX+bCNesn>%rKRtbE%Lz}45-SzB9r^N`e46yzpJogTiz z&3&(8+BO9#7SobCGPU9f>+I_rLa9fWB|!tH$6eDNa8N5<)E~C6Phv_P6MxZ7C zWM*I>hks}r1FhC^LK_fbH&pL772%UQbMKgeJ&hs<&NwtaiYv`+tDBn}(4Y(r^l^-i zIl5N3xGd)9niG2S(=M(0f{PO|Gr~Il0V1|-RB;>n0xDpb@Ac(nW9_c?oksNccxJKg zQTVsTp+W2LlPVp~ot}YZOV|QzHX9^(^mlxKwuK4_E%45JH5A`FI_dJMnts_`uD0@= zbU=*(qbisJ@T_Rna$B{TbZiZ(-FpnSKy5HFGqqdrFvv|VxYpVrTxglejRbLZfTEP4 zEVNUP(A`c>J*qiRd5*BD{ob5@lQl_mI-2?X-dTHk5#0|+Qh5AXVe%02~D+3~UvMl)pSP_Mja^ij4pz>+z|U=^yF@u5%R zyYI(to_qm~(778h$>{#J&64+s!NZ;w%W8GG{xBLgey<*OCp~4u5jJtU%OFWX79CPc zgM#pz7@RY3scyK;=5A`qO_uAFFJxyG@BnK1XNrWDcs$@{+Lo0-`2>YR*4WDwg%vP@ zrFwbf0p2%{hjfrp>b&QB%q&e+2f@=Byb=AEBv`U$!*Ey!YblG5!u!%3QO3~&nmh!%;h)D+L zDRl%ZFK$mwuCQ#Qm&Q`rrC5Vr4PcUhwgIGCmCRedW^Yj9(1n4_mAOWDofxgC$TD7C zp(C`*;63;qsGilbgn(LfTo)xp52YaUbF0NcIPeP!o-c1j%>azS1qDZJuhA~Q^U?6( z@e5bGg(_E%llcq4PooI~>Iz&3;L+5B63tEE?lM2w9A)f3uf}kBL1Wip{|vzPw1qPn z!W66G&Q@CM#Y?Qq%ULkHh3VD$eP0t2;>Fg*$nG;QS8KChHOp@@(&}+N*EbgcOSUg4 zrM0#0!LSp{Hv%1$5+v4 z7(uQ|8YGo^ACc{}IY@?nzV?98qKi}G^zYu0k_df3^zg7* zlIy^AGWK~wcnWYzbYXyrmgL`A4G~08l~Yk0@Cg#i zTmzLGty7s@MypfY(1b1VG_%EN0SyncW1Yy8^-W4H$>S$K-EDk`32+hsGz9nt^Q-OD z9jE^v5;Q~rqv*u*RLztCG=M<{If$l*G+?rxelmwu>SE?&PjBFfMLGl|abW zwx-@242-6$C?>bwWmWAmDo`C?O7;SHiQ5k!)WF6MU!|l_oY}aTu!8!qu@hXYx&ZzJ zP_`k1_j4YEHE{aV{gvc`#_S9Nsm zgaWD>I{2%8AC-&@#8j)}%SARGal1j{zrV$F=-r=4373e<*yr`U(lXf*q&johABXBz zQSwq{cxnF6qWb9a0e zIiE(8I~|r#_oF$$D?5n>1cK291dBQ_h0Pb>(~(Bcct{W9A@9vx_HRhiQv1n~6dmE#k6g?Bz3t*Q^ttCks$&)^pU3hURdW*(hEKAXnxo1m}pCBneq=Jo#G8g6r&!Zhl1eQLtHpIBf)o0-8S zq$5WFpr$5(mJEQtX`<=Os_(c@cT-Nz0n~(XdC9uqCnG1BlArq(O$mt3^NWGQn z;(1Dzb_*@tW>5Ze4X=t_?H_l>4vULRBXA^779vqmgBe^l|EephDbZ6A)o>jC4RAcN z0I*08H>}WR-seGA1IoWv;s6kzJfp^>>HRQgoe&@UjesTbni)`9+Pk&29L;!M_r1rM zfKoUi>l`2AW`!#^vhNnj0G-h&t6Bg!$ zZ2amLADW3z&0_};*;7OY?va|PWW@z3i8$(P|<`)WWRr&lKNkEz=0zddxnr2sPF|2tFq z|LzNP-g&+-uLT4XP+L3U$c?{m_7N<<#|P_B-iBYS2>a1^=|^L0$0W?1)PEDR6GuFZ zeirz=4;4R`ve<^6mNnN-Jt0Q_;;x;lI7!)Vu3@ENyxh(oEK2C7zDVUs+04!A?d3Zv z<|!gO+p0#ca>0ii2q6hWR#MSt8|n+opr4|GqlAS_Oe7or$oB1E`uz_Yc{8RA=m_;; z-6EWJ?HpnaU%i{)BKJo=@l+%yKFdG-@-N+CRHLe^wo|zar3wF)PrptCZ5OIf{ANnQ z@xBe=<>49WZ@)LpQ4Q&{!hiASg$-DjKM-^^uWvRf-}&!$!9@%aLB)062Ie?p%Gw)bP~! ziUrsODxde_`ueGNo1b2%^jb6$LtojTQ~F)7g#aVeL5cb! z_3NL+kM-CdC%|G3a#1mEv!68BQ2Nhj(?kD=BQoPfz1|!;EZ*6xFpRF1c&&cGTa}{x zfQ;O(+dd#V!$7qoFR#UnU*K881VzzK9Z@(v$x*GvHYwKtP;-*CfVQGu{Bfcnln-?B zD|t-|>|p7bgCFXlcTRi9qp=|ZP2tg>6fC7WHb4$8)Atjy>a2pUHqnem`+%&bf}=X? z=-TTN%ZIZgX5a>2-8v`Q9s6}RbM~ZC3xQTYwXZv9W#5PTfTew&Sfy-ye#3ygfuC%>!%&Wg{XcojqzbWbeJHYg-9x< z8Pe1h$90Ybto9pwbf={2^J|ds!y05xYyuDih`GqYk-bs!6mS+nkK1W_{P}m@kCw94 z2^2ZW%UO*rht`oTh)-|w}D`p$*$rj6PvMc%IBy1 z99#{*v(u@rGOb+G)T!lLoi^luss&26m}L;9Zu;2k0V^6H-2pSU?ei;RZtIf)5ben` zWkk{rXjkkR*}J2XRcg=!;53$f5LAeNs%3={9nzgc2hHv;VWgnB21C$``)Hz~a&4d= zvBsYj^gSzxQGN312|qDXLI(5wgrKyB%yY7Xvql;{G&Cb}0pIU8;g@`jhkNZ*{g)-S z{V1nwsJGSCQOOe`2_*|vwalHlB3to0sW*U{J++MSDDt~9+RPx(p_fIjdj;m0U$cib z@m=$}ytQt`jzkm!Va=|3dXSL54hQ7t+1g=m5TEW7?tLcx3py(hOgfVie^AoD@ESMz(aL*WG}1+~ytquJ@xIH}{a!`kY^d4EwqfTdA}bsA@xvuH*{$gYUf zME9EP9sN^S+AMQ&s^5Z$qyV}c@&LeudSRPn`kX`f=cRSe(*1-E3QUj72cz-mPoWO` zH7=e_XIPbDe70}^D)KO@TTQyuP^Hy{-?0&l(; zS?5jkC7U_n6!#7?wIKl!Y9em~wRIxiG(8GZgau~>plyNZub`&BKZp=0l%@oZfUUY( z=56lQEWLIkLu=Vn(($QrKCQt6kQG@I2D8GSHMX|QRm$6%t*WY$;VgR@)dCyAZ}yS% z+BrQuA(Lr(s za%nMZIgleJ93u6zWV%UPvt0%{MTBd= zp;utV%E*4soLp0|rIg0TnPnRr2g`b}9c5<*D!4|8#{TE#H+s#zKq0OH5XSzq$HV)c zahsA~vW)5Pmk%R3b=$s#m*0d@P|x5TwlutTJ^sBn_;N%Y#KJ6I_9JHgYxy3edVKz( z`$J|l)$5(`FhsEEMT*;7Aw&=2LwV=`(krgB_uCb1!=zz4oXlEUWrSyd62!TAP0{rf zH9r1`*H2SHh=lDo4(SQsUPIj0K4EdRC|TEnUk-=Iax($W5aBV810!{7S%>WehVI}N z5P#0q-=Vt2fQ59xDFFQ1VJ)LBDqnP58hmSwoSNj|$ndG~X5TcqUOE9+T=jp}_W`yU zO<0}W2=sy(ow{Qg>`uY8Olly)mtTq;GoxF#5#1dufq8Hcx@g7nQ>CM!R-FDu>!*+_*i_Uw7E+JYTdkdA7EYXB47bk&e0pFnc zug3D^u5=|#^x>q8116fvhj4D=NwM zhwSPG@lUq7p*}XUZN0*uZDd9avM8W+jl*R#09s6-v13gtB2aYGjpyk@j>o{jyl6L7 zwDd6DPC+heNs9|D`$qCvC=qn~#ev#X*0Bi$M(?EwN!eV-djK_7e_5Qc_VHh9+^)GQ zY8sL!2Oef_piX)S3{bJs>bl;U^FFU0di)p@jMIf_8^IEbyK=Cj@fh3F9lHZ$m{Z*w_{DOV9`shDW}F;1@mA+TX(myr>v<-S2j$nsT+ZgDq{Wu+hNR55!k5 zJw0r=%Dh;GEkeRiJYk(+qx^`7zwh;lk((^+Jkd6oTUyvE6C65%!p9a)ew^=GiurEB z{-`}d3Y5ww1;Q|?bjrL)HP+Q}yxZ9jHEAr&xNWP!-|1j#2RbZ3F0LPVFTOf6@DofY_ly zO_vSKmeVJJ!hhsQ|3ekl0dz?~71ky#MC4UboPI0uUhLh^=REjx1c4|rE+zq4HyGXZ z@S45p=2KKl$(IWpa9(S5MxAO0^R^fqFlr>>ZvV=c+xdWoaHYN&UPiDp7_!K_>jZI( zB1e8(k_$h~lE)uIBG!kmpgbnd$V^{9yyfN5|JJ!}B>FXC>S-HnDV1t>+aw~5X-d-6 z#_Ih7&c=$h&q-Ie1TG2V8Q&iMK8nRW(Sm2iuBX?VV6U)g8`lJW1r;S)3X*TL>+i!P zlqnkyu#gUFHA38X^;tz zNUs+?+UW`kwoWFmM~)m>Jf7)8-vE^4`o&YA`TR&49G~rKza8fEDeS%1e zm8aZ5)Vq9C(8NT>SXuy&E?RajKusBW_sZCRwBjp3ayOkleGMPbj1nE|+pRQf!?)-@ z`+)hMV6O(!MOn{uVKQ`Eh6wo=Pt}2hKsjH)_fb1$P=O5Y?1&aMCJR_7q_wO(KPiFT z@eSG!OsoV4M;>w0<*5jk6QiT&`-A(aa88NyK0vKKRuLL})-2jF>4Q$y8{4~V^^^cuhxiK8!H}nV78-8JnrGxydMx_(iTxuCNikB#xzwjk3 zKD9YZG^f#kpFe+{F;i>1`5nL%Kqo+Mya(XSQ{3CIspdV_b}VW+Ll0N z5#uo+vqBdpfYB@CXL8ND=I^CG1FmJ9+q2_ix2ezIRvgdEpJCGV1JoNhgshyC^4{?_ zR<)0>KhOjTkzDK@4=_=uL*BdXWmOmSt?&vqa!Kn(0CSjIVJDcN2`3Iu&nzr#Mp+z& zEA7e9zMadR%RR1{nBU#@c}vdEU{0m2ex3%f@jtNa$8vk!EOuRuQ6p|EAH5?jXd>&SP6#28NBtrDOp+Md2V8z19}`mytmHe=*)m_0h?vqFCA3Z2tj>&b`F% zAWzU6FR2pmKd{Lc(?b6XI{ANhQ2p-{*8ius01(4geDrMFZ4EuZf*4g!``x+p0P90c zuQ1|I(Tx_=Rvb`H-al6N2wXXgc3r*I-mrJLPJ7+Sz2({WO%9+ zprGloR?{reRMUtO9lf`2_837(@VDf{!5T*AL!Jloz~GVur^EOK3zGK0uF#soSp>s73i&gXmuV7!{GDT6#j(ms4j1I825Ay+2C9Dm{KU==(`L}UC~?Nc&OoOE zxKCqN+STc6w71qZ6;D{N^3D2jcv12KFn--(5a$H}MpY#>Y^ODEsN(C!m z_`kMe{%B+|AHjnXGzI5vOnsSqmKOz++i~dM4in@t~ z@SEu=RcK3QrsdAb^jy@}zS8NNzH04Ar;TueV$szN&e5@CE?=Ha$N z%!-Q)WN7O5ou>Kzz#|lDEwc`}F@E*N-w?@>tW6lMgFU*1T$Cz9hJI-nMT9U+$Ax!~ z_5TLa{hvrVj23Qqxn zHaqfQAN4k9_hrmR?!>Eg%>#^JR<6i2rg!$Ocj-H5mO!@$2^1Ci? zyWgT4W}<&RvfR>~>o?laEyuvfPZP*v#hu$Q)3m`p3y>j;UNWIa_~CYtA&ME)=i4*1 z)rL27JqEvH|%Q zAk_rHfjL0I_kZeQFJiTaA=H+Vq2DWzc03d%@ys{HT}It4Eql`;JV3T~6F%bBwlH&I zwsT7bRZf&q1A$7)yc+{W^1G8&l`Ns*q0-Qs;Wm>XiFpQUT4vT!F~oPxAGuwxjApMu z?mWA?Mc&hyFy#??wx-fto8eFJaY;OVI3b69r0+|jyxpX!GUMjzJ zHdUM0F1HMG-w%h*{`Fv{RaGTwH9k(3dvI=j@R>0I;u!{$@{jvJcM!0HCr|IrH@)^P9l<(S##fD4;E5^n{|s1l|9ApM zB_K5^x8$F)Im_@Pbky1!GO2i=p7z-zc7Z5+V$t>~!Y5z<7;O@YyqsI7t(ilA-ty4% z$0BWo1%h@O&6uPrYI^my`{<>+5WqTIHztAoLbdPkO5V)8*-3 cD7Nkqw!UU*9+#Q4fQ=(aiphzV2pfF)AO5K0JOBUy literal 0 HcmV?d00001