From 4c580e5d0376a90da9a749f76bbeab29417aec27 Mon Sep 17 00:00:00 2001 From: "Thierry T." <1940947+lepiaf@users.noreply.github.com> Date: Tue, 16 Jul 2024 19:40:18 +0200 Subject: [PATCH] Create Delta Lake with Apache Spark --- ...2025-03-05-delta-lake-avec-apache-spark.md | 204 ++++++++++++++++++ .../cover.jpg | Bin 0 -> 269550 bytes 2 files changed, 204 insertions(+) create mode 100644 _articles/fr/2025-03-05-delta-lake-avec-apache-spark.md create mode 100644 _assets/articles/2025-03-05-delta-lake-avec-apache-spark/cover.jpg diff --git a/_articles/fr/2025-03-05-delta-lake-avec-apache-spark.md b/_articles/fr/2025-03-05-delta-lake-avec-apache-spark.md new file mode 100644 index 000000000..c05785971 --- /dev/null +++ b/_articles/fr/2025-03-05-delta-lake-avec-apache-spark.md @@ -0,0 +1,204 @@ +--- +contentType: article +lang: fr +date: '2025-03-05' +slug: delta-lake-avec-apache-spark +title: Delta Lake avec Apache Spark +excerpt: >- + Il existe différent format de fichier pour stocker la donnée : parquet, avro, csv. Connaissez-vous le format Delta Lake ? Découvrons les fonctionnalités de ce format. +categories: + - architecture +authors: + - tthuon +keywords: +- apache spark +- data +- big data +- delta lake +cover: + alt: Delta Lake avec Apache Spark + path: /imgs/articles/2025-03-05-delta-lake-avec-apache-spark/cover.jpg +seo: + title: "Delta Lake avec Apache Spark" + description: "Delta Lake : Optimisez vos coûts de stockage tout en ayant le principe ACID des bases de données" +--- + +## Qu'est ce que le format de fichier Delta Lake ? + +Initié par les créateur du moteur [Apache Spark](/fr/demarrer-apache-spark/), et également de la solution SaaS [Databricks](https://www.databricks.com/fr), ce format est une surcouche au format [parquet](https://parquet.apache.org/). Il apporte le concept [ACID](https://fr.wikipedia.org/wiki/Propri%C3%A9t%C3%A9s_ACID) (Atomicité, Cohérence, Isolation et Durabilité) sur les fichiers parquet dans du stockage de type objet (tel que [Google Cloud Storage](https://cloud.google.com/storage/), [AWS S3](https://aws.amazon.com/fr/s3/)). Ansi, nous pouvons bénéficier d'un stockage à très bas coût et les bénéfices d'une table dans une base de données (en particulier la notion ACID). + +## Les bénéfices d'utiliser Delta Lake + +Comme vu précédemment, il y a la notion de transaction ACID, à cela s'ajoute les avantages suivants : +- capacité à ingérer des données par lot ou en flux continu +- contraindre la table à suivre un schéma +- navigation dans le temps avec des versions +- mise à jour en upsert et delete de la table + +Le format Delta Lake se veut être les fondations d'une architecture de type _[Lakehouse](https://www.databricks.com/fr/glossary/data-lakehouse)_. L'industrie de la data évolue vers cette architecture afin de réduire drastriquement les coûts, et cela permet également de réduire la barrière entre les différents utilisateurs. Avec l'avènement de l'intelligence artificielle, les équipes _Data Scientiest_ ont besoin d'accéder à de la données fraîche. + +## Installer et configuration Spark pour utiliser Delta Lake + +Reprenons le code de notre précédent article [Démarrer avec Apache Spark étape par étape](/fr/demarrer-apache-spark/). + +```python +from pyspark.sql import SparkSession +from pyspark.sql.functions import col +from pyspark.sql.types import IntegerType, DateType + +spark = SparkSession.builder.appName("Bike calculation").getOrCreate() + +source_file = "source/244400404_comptages-velo-nantes-metropole.csv" +df = spark.read.format("csv").option("delimiter", ";").option("header", True).load(source_file) + +df_clean = ( + df.select( + col("Numéro de boucle").alias("loop_number"), + col("Libellé").alias("label"), + col("Total").cast(IntegerType()).alias("total"), + col("Date formatée").cast(DateType()).alias("date"), + col("Vacances").alias("holiday_name"), + ) + .where(col("Probabilité de présence d'anomalies").isNull()) +) + +df_clean.write.format("parquet").partitionBy("date").save("datalake/count-bike-nantes.parquet") +``` + +Nous allons donner à la session Spark la configuration nécessaire. D'une part, nous allons lui donner les dépendances, et d'autre part la configuration. + +Télécharger les jars dans un dossier `jars/` +- [delta-spark 3.2.0](https://repo1.maven.org/maven2/io/delta/delta-spark_2.12/3.2.0/delta-spark_2.12-3.2.0.jar) +- [delta-storage 3.2.0](https://repo1.maven.org/maven2/io/delta/delta-storage/3.2.0/delta-storage-3.2.0.jar) + +Ajoutons les jars dans un premier temps. Soit Spark va les télécharger, soit nous les fournissons. Dans nos exemples, nous allons le lui fournir. + +```python +spark = ( + SparkSession + .builder + .appName("Bike calculation") + .config("spark.jars", "jars/delta-spark_2.12-3.2.0.jar,jars/delta-storage-3.2.0.jar") + .getOrCreate() +) +``` + +Ensuite, ajoutons la configuration pour pouvoir utiliser le format Delta Lake. + +```python +spark = ( + SparkSession + .builder + .appName("Bike calculation") + .config("spark.jars", "jars/delta-spark_2.12-3.2.0.jar,jars/delta-storage-3.2.0.jar") + .config("spark.sql.extensions", "io.delta.sql.DeltaSparkSessionExtension") + .config("spark.sql.catalog.spark_catalog", "org.apache.spark.sql.delta.catalog.DeltaCatalog") + .getOrCreate() +) +``` + +Votre session Spark est prêt pour utiliser le format Delta Lake. + +## Enregistrement de la table en delta + +Lors de l'écriture de la table dans le dossier `datalake/`, il faut changer le format de fichier pour __delta__. + +```python +df_clean.write.format("delta").partitionBy("date").save("datalake/count-bike-nantes.parquet") +``` + +Voilà, votre table est maintenant enregistré format delta. + +
Note
+Si vous relancez le script, vous allez avoir une erreur car le répertoir existe déjà. Soit vous supprimez le dossier, soit vous ajoutez l'option `mode("overwrite")` pour écraser la table existante. +Note
+Ajoutez cette dépendance dans votre fichier requirements.txt ou autre gestionnaire de paquet Python. +?HYAE7B#(jdiHs(7m<&a0d$ya>#u_etU2MNUR8!?bZWIVk z`XwAyIp3%xiHQX}5OIxc?`yfTRT`&i>GJM(zUES?TQ?3^mqbSdYt-M2WJqCy!p=pnLi1f?HpKo(leia!Ed6p08^8o4=>tpB* z=A&tprf+L$fwJq0du84HBvxDrKnzC~Mt`L1a0xn7appZiw?b*bWw6m`&DefKrq+>4 zwwV^)c8L4gvuNd1ZBWq?9Q~|uI_uIhskXOJkEHlS2A6v8O;VZe Mt5>dA$Hx88OGf0{}z6N4uLl$;cfRd=rSIR6?>8 qG=j&>A3=PBmo=r=Cj{Pw0>_^11wqoFkySGHbLRAPi5jg6w- zwR62#?eOakdh)Et&P;za>qS|Yt&MaBZH>CQ6Wy=pUC %~iL0+ZD=BLds(=j&7McqW d)TnJms8AMTB2$xM+g1e>7_|K36^WN=wsj<|^7mmfT!wSX+P~yIG z{j(iK+}GA;t-LC+#;9xSpV*|TwAF0~bvIIy&1MHtSK8vz`yo(XZb(0mm$|@pG70~v zPmZv3 Qr!S=2ue-Yo+;YR5hDYuf;muI{zY6p5m>RQH?q@=Gc)r~$4 z)uF_gm;1Y$hAb@XJna?8e9!gK Jk!0)la?Sv*hBQ}sd?i*YJ5vAEJ*Zf~hhat~ z!d;R2Sd^$y7yX@jcdkO;nf9yPlhkrcKY}9JU1Tl)qf@EzWKV&w%lDQO88`NK)tRJ1 zlhePr%2wl@M+b;*Yh`5*I-Ln^C!6%NeV0=1%_j8qPq!7$EKG~x xjSNY{W=RW6rzn@dLNmwn{Tm _3Me zDJBun%Y~6{bpbSQ^&q?Nr0=VhiLFDELt#~4gf*VAiB|(st9!AbkdBhA_$k%z)Tumb zihaUx-vLYY-qsH=LnuESX!j6v#TG<_DuJdIdq!0j0~I>+)Mg6{5KgN(Qu5u=L3EAd z5S|HPrb}GWA1ywWa5BGp$|)>#|MMj_!27YNdL8CVfa;e*y8*O<|E1uU`D_n|T$;T9 z^BsRZg$x4XI kZ*_(JN(L0lLv*@-`AnM&m;9x)YnYm{tGNtUCiZ+7-^K`Mi%8n%Z(pt zR#FH_#u#{-bMw4u9Zzx)h|hMjx1W5V7Zw-is7+prGG_Pqd`0-nbHKM}ULGO75nU0x zAzlS`VJ52sUPFl{?n-w4rca$AmV=7Ry8<3*__r@FYfMHhO%v-kGH k*a8{1>My)M=XO`u2Gye+<@YeYrE|q zqu&BVUXC*TcjYoeT>tqo;4KrQWg=m84)F04rxDY+Pu+faEIw;IQ&yT&42B?(s~{fV zcf3g&XFlz6Rb1+F)u7xXWlesy!ZYW~ks;yzR;)gDgwi0!k&0RCvkKws>zLk$O=oU! z-v**w&`>;~ZjF?K^F71(=YrCPzvh>{A5rG5wRcNt|Gh5C=Q-L1z7RUo#VX@AN|E$! zz7L(wcJr^W>gLI=Udxc{pS>KXN%4HV@(=K6iuud42T@h2-uIpZ*n3+M%cpFM!8^0F zrl-hJbhkRl!`^#QM!sy%>1(v@5_^gYS-fq}ot;&lo}{e>TJv;i9 i;HA(>-i8(On^j5< z^l*uxQGG7*@+QEDIX)^%G^z|xX7TaHBQ}w@udm$D@kk+d-K|~eAZ66`N9@pL_bBV1 z(!F;S%!}=6H;wme=!vL-d8#8%JB1;}B0am;GB=fq-ns45{4;R9rE!LK*fc+zhb4DV z2!+IYhU2zOPXlCWC-Q4oM!~qL
JDw0fKM9S8S@pYBSrac~dK z-(Q&SJ&T!&-nZJP-cw|LKiuhdF32;002yLY(g=71K`gu31f0-S^&P^N!a7WHBSSnd zMl3vfGey=AfTN2fPxDk$oVhyCW{y)Uo7tN +ZQ4xl=;lvI(O>ydvg#~P z4h**p)9`J+j buJ1?KEsxdqHt#aTisPqt0&Wf88)SBv3|sybgR~w8rJIqA $*_Ilsy+h|atF9 7&v;E$&CD*2&_j2= zzU(OmNW6Xh0l+1iF7k_kA-Ej%Qcw5$msF-`Mg_R)psn}8Yf-E6dUvU38mU^WBM?!Y zY1PnQ42AJVig6xBl&a%4rf8kKue%XEQx!q}Hq`Jb<*IsMbB^C1YD>VvHty-l`1pf0 z%o?HDYkA*arbzY%J}@TiKtF#{J!Ceb6O&S&MSgP_yfV`{89hj|+|q_I`X}07b#*&E z`rVSnuZm0N5;B`{wI!=?J{VVM$Vs+?_fs?XZSOB>eHIzCq3owonmk2l!lg{mC8MY+ zu5( )&H7h%^q$96x% z-QvC_;L}YfN+)E0uE__9lnzH!r0Mmw#x4_lGvb#coC{jFF-Yx=-9X)glfJE3Pj>G~ zrGS-FjZ^0Y^f|PZq$bocyvlYY?C`|u0EeH19=9-RB4zzmDrN=aPhG~V1x-6fKK&bh zXyR_66 z1mqK5ZKqnfmw%5xDy;kbA|o9S?;Ow(c_s&7m-yr @8Hqr8?MhQt{=QnnPmI2y=S8Q zcJOU%F2>V){ZgD>2h4KWe;pRq88<};Pl$F_kj@-FA(-(66=cJ&A;yM*`I*DPCOoZz z;G!Ya?vf2t>OHCZ0E>?R3B4O7hKx&f_C4W}ave5+bZft~HX2sZy?E->xC%{!*5@{^ z!EY0QMP)06) eholUb1B$_;fyg$gTMz zx^zWaAV$0>H<`hzX=(P0NSss;Iz8!dW;KWOSL{l)_i6yktMaSTNQLzbg9t!`k=Hn@ zo!5Pi-h9vYE8t!9{cDXAv?>AZ*t$J5hK8BWwlY8F>{bfg{0(ZvNt;>Aa5zg>sIbps z1)EMKyO)FflIz%p6`=>}2e96*?j7dTJCCKG0dzhAm`Z-W1Ds DkYPSn~FpN1!x+>wH;^ygdH%NfDp{&Wcd~_=zq-9m3M3+1GXx_$e~6y&bs~s zpE@gk!Z{i>^!>uKENSTR0W)nhBPxI)GC-iFLtSIvE2J#eDH1dDI{d#BUN+FYb$)^& zU^jg`)2^#|g87og& Xa6(3BKR&|DGbL8+uI57-RjDvd_gViHs(Pzd-1xf3 zF0SwXExVT{) -rGx)ZM(apLAyCx^?JNkSn7EVoawYhe1b-!J=qp2W^vE zHIUq>OZeH28 E fn2fm9;eKe?Z8V@-kX+&o{ipIY&7(e@#o`1?Q^x zjSu!*=f7VPF-rgZ*wB{o`p#}~N5aCUtnB=y+wgGJe}K}_moEOu%09>3ey5fUrUQP> z{+|njueY|BBGR_9mUo qGUm?V^ZYuE^`;bTD zE+b1_G}#g#9pBY{@&4}088DahXIEfTCAZp*izef=!BP4C8cG^%;8)reD@r}>3q;JL z)F3Mbe4Pykwujnnc0T(7aBaDUW5EQ|u&^v`)QAehf4>wFLg<#~a;0c0x4xc{-wnBX z($i)_Lp vBGga7-F1v1R`$sp1y)e2qFZb(!j``M-TC>I3q>@?4;D9s z>I(#~&lK{W!D)MLO^d-X>eoApoDcb@xAbfCP?i5fI$wrz*}BxbjE>R5R4-uG>npkQ zWS;ooFN>tV{6Xa@yF4h7cs(wIkkwvWj3_eh&eCOAXf3zwmK#I{H->gyiML-?bE!~b zFisfA@j#S=#ngK@;D-ejdTV0HpZ(SUfR&;(A7)n^NXJ`dR{sD =hQ~`vPo7} zT0IOojUT1em69r(`>IwW{J(opDfQhcM>DF@%AyrPon}w$iI|aae u$z8t!(K3p|G zb;lhNu(-dyq_lJF`ay>|EnUA6m&nVtzV}V>HBalq>nYkuvbEnRe#L8}UorD#Q_Ila z<}}FvkdfQddt|d0$759sPayeF&Yewp+=%h@P)DzyWrXInwU&*QEuOY}uH7z3!CKe> znc_9_=H}zi64_VYK4Q~(#3}!dOX@zSJacsda}@)A1`G~bhL4K<=wDgsOtvXFjBla5 zh}orjtrXok23NHzl#lO*9n@?SE3`O6N7YrKU1bDSpxN%hVlWkhrdPYHl6S(I>`yk| z$7X$_Vv~3N0gUQ*BhA}Z={{XP+iJGE4sN40^sbr~t)CS&e@$-cN=PFzJKuIuLo^HZ zt-(s7&D?5|UL=2{^vfg7C!>cmNVDFP;{{j`<_6~_M%>QTtxhvL5*QGLcMsQt?IZL=)o^SMx~kcgxb-{ zd=Diyk*^;a`@v&T=kk4K8`}@(nBs-5hzL)7VS9A`amf#%8-^?w+?@4u2q|f@KWNjk zbyWAX+vy!sSk6&czH&;&>CE7**&;#ReT^hEc W U7D-wk|y5Iv0Z+f~TZI9ZyN^}1M=I>kR-Dc Z_4X1Au8jNP?ODaq){+3_h0xLTN6f-9B~qtXpUQ z#5Ae+V~Zue|64G4wNqIMzpLF=xBN75Wf$4OnzDG-JWTT43DnrNULUEw3c;rD5~teX z8f!=hm3n+^>a6@MVJ!%$zSrKjl{<3Ol}rGQ)_bi_JcL6kmm-i`R`ZgRHngrM3&)jJ ze{b{l`z98Pr4=SVyYgG6yheHkBQZpg^eR;6Cqe^q|Gv={U!tAzv9SY~KDh6G;x;>y z>AB3T$B;J!%^i%SECEMV!&IHYvT}Rj%BI(Ove)($rW(%PHp7r>T#gZz#(`}Mw71Nk zssXwZBA>Wijfkp8W+6j+kxwZ5n?+*%moY(fI4`)gd!KF!&B#L?`XU3T4(28mAqxjW zJ6WpER=Qp-UVW>U##Uj$7iCnFo-kBT^?R^6;=(>$AZBxU$xfY41&-{eXrrac=&x>F z=W)sHOKmvq{I+&@h_r+SJ2SfkmkZ###LXzZcM{Aune=Yd16Y{MJrx3bG54tOO6>!f zY&C2$0i};brs-|1teq*#gi|9ub`g{5;2mW_vt8$WxS2i J-Fi;I! zn^Z%QDAXe-Z|U)~l<&-jLTx!9p0*k#BMuhzto!@w2a(#ik=OV{;%GGGl+}lxG6C~l zs41;|%rs&{|9aUn$zH?wtMM4~<%YEL*|w;l!vgT=Ar7v6Edw2Vy+dVITG@E34r5D3 zRxNL}db9)sMJwdj)K}Qb*QmdO1OCWUi#;e>?-?4 5SKE;~jg(`gZ6L5i8zXOj zGW%?5H4ynEwPWW^hvV%Up1}6}!wq5s?n(2V%Bu%TBN^0{%H6KIKeSUb1KK};2yPFS zlCjVpS@9d%6()VuuEF3FHNPP4 nukoR>!4t}B6Gz_%hWAav1E=@h z|6&xP(~L;Cre)&vHVwH?Vo4jBD+G=RT^6zvk+?E;mRIXyn4^0`(v2a*!#6vVL&=N~ zvhDAu;qZGSFL+ZM-y~Rc+&0~IStQ4I7Hm!H(pYuuQcWEh_qa#B%4JP}k_E?L2Mj`v z8?wUnhM}0qC0o*I%AkzenVH;FXOWCbVx!BODc?dzK{Gc$UM+0PU`*I%mD5)j#nthp zB&6qwmWppE&8_0L25NG9v|C}Psl!pLF)Ytvzj=0xW66wz)^3fY3p!0Pu3!emY!v}M z2Qr`0S#J+QtK45O?5z@_I?>E_0HOH!=xp7ImwHUc5TA})bl|&HvVZc!T6=B5n=&E& zrwT?#X7PXV6Rk2?FsyxLb7N@!afrBMkvQRq_-B@O*m@P>9gYqaN1}c3yJ1u_$C!=A z?d};j$hvHdebxoI`eNs}&7V_)az+ROsztcj5{i`mc7-RPZf{07*6qP$j dQUl(u;gI|vf%Xsm88<*yMwX9A8BEBoy+m#lWv&=>K1<&$3(c+{c^lw zptaIa$(B^TeE=f8z8_LvipRH});udBj6pTmJv}4TVM3`%!d8FL0ZSKN#~MPjPK} z&)3|q4%*~!;GMI)sdCit-Mz^fD)OHXzQSuXx~<)6G*&+;RLz4Ha_v+jA#bFdSBVTv zIQ$2wf?r%a^S~aS&dSDu^=OfDM}pw0AdKB8GS^8 wg{AsV;|BJZ00Y&h~(2eDCK=##q&5&tX(s{_;XM z#q1{OMH9_t#rxqr0?AsyP(L4K%#o6hmP{<^&zmmUjR%fhMG$nC6(%opb8d8hXSn#4 zP}F56QC${5w9$<+iO)Kho^vrvzkf~L3rb!G?eul~ ?l`mo9Vw0FDRyMtQI%5 yM2 K0ry0J!di@n=DLI9g?s4GfGK8wt(HQc?oMaRZo zYsz!zFCF<{1hBot{Fce`3fm(V_Mcw>^%BC;mvR%XT>KW|Q{bo~Q$vuplOu*HMHtIZ zzbWfmE1JQd3Kk|5LP7#JtFp&SmvM!IrN4_yXM3r*FUMWiP_HqfF=1dcE!6mU4J62y z4+eGewPNTSX}&*#f=4m;gxY^h!M-V+iBEb(fY(% + 5qW(h|L;ah)G9O>>={&`n#uwwsGl~ zE^wD3OgCum#8#D^+*UPiWozHvj)FjIRL#oKHI}rsH%IV?CaIqo5(hoq|5D}qHM=mx zFc=(D`E!N8O92YSU|Y3H4uGr|_RoMHgXf?~%d-M?{Q~$@URS*f0e;^x@>=LpM}p_N z={E(aZ;hSC0(~n|iPT?ezB)3c(VQGiYyEcM=7w^h6A+mbW|as1?ZnlGVkvC;lx9 zAp1&`D1(E2KK1d(bS4QMi}UUe2zle<@zVs=CDb_TbJ*#FK~4^aJ^WiYwtprkDa3qj zr4Q5*GO)NT;9TiNIqP}mm_Hc~tqu;oEl`Bp>#X&SjHn5(EPc7LL7=OAchpomc*WGv zJqB$a+SHalf`rH_zzFodZe(R4Bw)3JkG`S0p>gb=XCIT)wnS2vs&bIpcT`6}Cdj|` zHiliotdbMxx?Fa-wDAwGaioK9$Q_Jm{rq?QE;(a26b{>E6zFL@&J&Px_pYS8d<&Rr z3s-a+p_{D5rfFjb-;qWeVOd+h&m!$a;-$W%TRc^I3(%1& (HO#fl0%a}u_IRn2X_4mD3u^o8O@H3>s~2KfoLL8) zIy {dF+?cEmrx$jQds_z{$T5jo{kXf7&+dMo=LZ{g;jj7|*hm;Du- z!ZJJCbi%){x?8(x5(!B Cyq4>C_uP1;!7>JnL99eL9dE+EHDcQ9(IfMI zDG-wJ*H@MCiTd6xwbI#L#Ec7q8gys5= rabxWxj+88x zxJ+fYXDg$?%npnxgQ7w^zO9;BUTM04E-4=xduF8}K-X40hC>MCK>oZueM)!CI5wFB z!hHa=og$1oGRBaC*EUA0Xq!Zp)_@}@Br(MMplBxQ{^fHwL_LLsf2A|OeW|C%a7r@X zs9Q VHgpIk4gXm>&7TRG-l$1#J7oBC+9ODlIli)G19R9Aq^UC4% sQyWukCruDJiV;l;oCGvSrl{!mk7zZVY1y!;ppAA%xX5 z9cRfBG33L6 44C`ZhE+ww$d!yT?%dd|YY=j_56U% 1*y}Io@}5G) zfp$Y{onD{QG14_W_fpgja86|6amHolsN&~LsW{DSrzC>3eNg9Y8z`R3WA8Nyx=VUM zz#MqhVe~JS)^@7wrQA*BIhfUI1A#o9PPXtTUTclZ+bba_sB64VIPu9_JKAQ>5BA#R zkDxn8is5Mvt7|9%ipUpJ8+JH1S4b|ctPlNd-CG;v)&Ap4h$(h)YcvchhYnsV;8pI_ z_^Rk2Lr$^!kCg8_Vlu_DC22}|m+LQW#o?S7FkPT7fNfTy*T;u9C)3XaAI|SQKj(2S z2v@oO;Zqdn<)@s8{V<*b16O4y6JBodf>KBry0Z6d+u8tT*-M=X*U)?q&dVV57ZMjY zNCNs`@U28Jf^%M~?&s>FvpUjeYl?QH;;4B9R&K=}b|U)JMcUeqk-%>MlrJY} yVOgi!>zaue|*A7X_5G>WdyEm&@4>S^gG5g#)5s< z$5AP!j+@}+YbVWGPWD;i6(co+_2XRPetfYZc`-N!e)mI -Y#lpY}=;^~$BCGyx!g3`z z!_2wZzyMVYXQkSU)r4<}TPbKdT%7eGslTd{`#U75h#Ry-4vk_oAhWewb8{^LzaQ3i zI+j{HsV(<;l%DSb>)UHS1e}Rv4axjT~DCNL5?Oc$`L=9*guXg0WQg6?_;*Idi5H zn{OTaW9h`noLBghsK{7nQA66551%*z-tf-ki;*@X%iUj~vz~8>E1)jrqe=6jqmky7 zh{)fktciobS~E5_@iq%K(R=qWulw1OzZDR&2pJ noXt;LP zvX}ZHs6G>ohMZ}EE|4C|XK!RrFDlsW9 XsoPfeydR!= zJ^Y)ZzGM?GERvpPbQH1B_xclKy$;JqGNA%;@c77W>LlWNAemUia9T}-9bAAj;05Hn znbw?}1mrWeHQ{@MBY|^M(*bS!euu$JO1@Q2-&%g}xxc$AR=X*=1n=N$AJN;2@FBE! z5MWAcq+2VeJVBd o75N=GgCTazs)(}FQ3Zd zqkH|9$J9?{U$C&hU8UqvyMasIr@33f>pi~R%B49n)ZQ3pM?z~erA2E=j&R$jn7E_l zs0F|J{Xg(j-e^;Dh;r%u+cVeK|8{iPaXa0<`tUeyqVMHDfED^QG}IopNf|_!L64#2 z;>rs8anM<^iCJaH $e8E(3FCct@NJNUp8WZ^l`1CRuNk{5%zeabWmGZOG-1D<%M$Rbx?9*ZL1dIHEscH z*JP~h8N5jZTaBY4QNt*!P)ffN)N-ez)EQB}i2b6XjO8a*j8s+A%`6pH2R`Vvqj39Y zA$y&&c+54lptRF{1tKk0Fycv`WyLKTKdEIC6hQZFZ+-fQTeVif-`C0c-tywe8t!&l zcz+0{6Tcb}+(Zn *mlPcFO(zN1Df26=?#AWhT_L}%6WU9c4VeZTPkwp@!HsxhMQp@ zoX(!t4+@x4kO^4@q5@<+PoJP5|APoD40-=tb4ny@aop;R=F4iUThWU2Y@R}Xg`yvx zp0tS< lkqBD+#_Bm zCzoG+X3k)w(I(~(sjsB&zo_#f55t`e{)fJ&ROqYuzIUlO?=srd2W)LOw@wB>FV0lK zel+9ewNFw)KaJ6LYHRVx>V|Y>b` dN#?Q zy9Kb+_2p>~CwQ)b0jmmQsQEKWh_U1&O^4m%6Z_4_H>2uB<8^<%WBB&Yxu75k%V8F^ z5!J%XCh&XnPLaPCPY=x<`x8u`ILjF5t1A_pvZPfcn->NLzG|ZQYC5J29rGt-Rd<2A zec%yJ|3ehrsrkN48t8yG?BdO@9whsoRE~~}i_{ui4^LEdZ}g#M5*Afz<@_|zM`q{8 z)S!9cN}HMjSnkpkaip4(>po@u>-WcDS)$1y&3>aw>(`F^I+Ic~8^(vs( 9%7Pk|yK$>pb+rW8G4eddv zlF$msY7atC=Zb(w@jJZ+8MR4`!{ImRoJAs70V7?H6=v1x?*Adsp9U-pxwTfsFFu0L z8;@2HO~$5z`xc{P)VP*BXV%G?dB|--Y iMPBet;3 zFT1lMI_!-}9{KblaO?-~Xn+oY>A8flu>{jkou@XBqcSa0b-oBkHDaW!4I+xC#zn?# z&b$9sbOb^a_!Y1eRNEE}i!-p=!*mWN{|{30q%=#g(6&o?O{Q_Pl(=g_KZ_@#DAm0* z90P4I8osv}v=WE*qb@IK)&8)IUgD7)_L)oSgqpWnW|QW^Dl a@C-}vb9Kj_XcP-^w zD_?zOJgZd-)aV{it|4{RKF@ErGmcGZ%?9_rBSoyCZ;iJLIvp6c-Ptcm$d%sdTLm_Z z lRwwhmF=jt6c0o|l`Io}VSUOkQuAomW(x`?$&sR`5VFnS2e<^P za$=4igGk5p+)yM(m*X+B6q``OqZi8n1`0xWv3d8vzss$Zqxl{)rwB5BTz&Id;+r)A zPxVR}Cr@Qi^Yw^$W&UT7q(IL^i2dEGrzZQhI9}LRn5GJ8VQ~+*(VTQ_-y~qFcGzc6 z2wE=4!Ml8(!hM=T^bT^NWiviBp~G2|kp7Ds_%PT|HpT7%x~|fHU@l{LkgJt(yy->l zD8>VI?~cGDOO+Ld*9o6SekcmZCOWIowIz{WRD-YaG^2k2#$r8X2A!Ar-2a%E&oj0H zGWPE=mJyy~d;nZvW52<1@utunPT>b~&+qCy;u4Wpc=(E2R7~;BV Z&owp8W$GGqX0Z1B&4Cw1M}Iy6O&gQKK^zK@$T=iX>il;hou8;94a zMXD^2dC>E&k=xh)0bZvp7cMW*?Pgrv?DITH+}a;TZufH*9(&Gi9Q$@kLV9T6gpccH zXHS|=U-)zSSEKK0=52f=2lcMzG*|l8!MCfL#AG`owLU=Zhx@g6(OK!P&B $dGw|{4QSIJisifDs@XF1eU zh2Fndf0%-jcDHR+%-^$_P`I2g@1_3p W;w4`SZr5V zyFqa!-mb6iUQmdjH;+Gbc?#NKeW4(J=pzKx$_#b_cTu{M^Zm^yCwKbhl|j0FvNoTu zDgF(zb^b& tI xTXCO_ Irjh*lkA=10-JC~W zG7u(=d%N1iPjv?m?$uWh9zN`GSj-FP@gxw*7qVZ#s_}Y6n8ixxBT$z5QI?g#z?n3= z`s&G}vc>?Jm1E4QT>lySrG<1~
6maJ<_<&-a z_>b@N>JiWKXNEkgQ|`n<*C!1$mj~4R9-qBHkgHiN8nX_#=u) ;O+eX|gaSI-j|8sX6`(V3=r*}0G(PYE_vNyl9*3F*0Ej@z$k!$wLpsRwyd4bdJk zc8AZ0>&LBv+@F@@rcbwx8!4Er=AIhLl2*N0e@1FY-6#xL>ChN5{FuGiBQCXByKVuI z`0W2v*zGgDZC?A9!(%t=h`fj&n`AadCnUT&7G!nc9e4Ov^97H7E9Xjnvw6m6eG?ZS zA;0#zfLKchg8?V;*&aI_H-*i63jx+I36vXl*?oQpzdi^wC#;mnak7-dUK+d_7(*S{ zWu^^qpIt0@c#v_C$idg15g6&&VgLR l(Vn#O9=i$h&o6Rmv1QtPsLXojYg(1xMhe-b6W3vd3oB)@SI^^ zz-~FIUy`5iU3hC;7xO61cun=lW`Za4dRfwO4#52jVXCtpcyiJ3`H5%PaZp$_l391- zxG|}R5pv0V4 xU}9f?!SIJq>T02e;U $gFo_^B&}T_xgt_aMEHRqm1?qEc@N-&5nhocNFWG|PV9 zxQ(R92}=S8nI}K17L6a8(a4NzO!Be6#lKs~OX-X!c~!1XEB%z6e-Yq-6FcwpjCK#{ z`D mYdu>x369F zE8WRd__&snz(<@LWedBDmy6NW=V*-yP*fAHepRS9qT1y9u>k6-9$9==!k~I}1V?-o zVf554+hBh&uXi$M#+ZMJ(HS})D{hE&Z<(@`ttdK7+8<2S80;)e-F}Ftb3K=G<54<% z{WFvQ>6hoe+=b))V@LCvy9T0+zX6-}>(;M6op&AS8ww`dXg&Ii5&c(Fi#dwtMCE#{ zD~kobCT!u6l%&*|r*0!4h-CJRm+E{MNo%C9R`{q3$4zx=LtDY_1)b`wmJ+{+4TXWa zK#9SgUR7tVN?+e%KZ|I{qT;dEPYx6A`h#~yRfmtle5_2y*&i-dzpskgE} csMJ)kV;*@GQEv!*&1v}$aN{#juKpQKiKd(VTK-|k z$NA=d6pYgJ^y9tv6KxNypw@7=5>egk+oO~rQb_**uN*MWUsRb#*SWU!+ns|~X94d} z^ZP_$5BxOQK`%tUZXjtw`)>7>Xy$18ckrLD8)u))$viCyML&;$Qr^d MgY3;7Lenn4C$HGVSp$m~%vTMwqU@Co zz5DJxP}Fz0dLfo$u@4P0aLuUc8!%82e*#zaA9Dz4)c*&-9tJ!A)T(XVxw(D$x1x1} z!2Cv4#r=V?%= T<*z+$^%*C|VphT!Y%Z%4mAwSL~a~uXz1)2qeK;vwlsi;af)4YO$&!hf#8u zJ2lD4=cyh&EU zDNez^gUQRXonn_~%rlo;;^Nk$ Uve-X1&X6%L=eYAsr_%(} z6cmea+6!^K?!+#p-n4dOzjCq!y82G)@ J3GX+#si1usLR2 zK>}RjEuj<+j!{!o1l<}MvSHs7$qB0!6) i89iPc!!Z;i#7)Vty`G+!H)@ zrq~dfwQJ`mUeNLBbaMF2um9nks!rzFgzd=eGrn&@=675jjF&>2Q`v-_8nU|;PxVbu z9h(Uy)bP&FWZVJp)%Uje=e`H1(cE^3`-=nk5KSI`Lyd?Nd`A>zy6vHI^1`lL5o& zib3sW6n$VyVy5p-w3&DZtCjVM*4E$P`T4=+6^Py %28@RB&}#aupx?4%M0+41CzqJF+X|Uv a%^4nvC$)GAR&d1{0h??n6HfCH=uW z74*fmp)6odPZKHH%iZER1p-DR)#>E%p{L>3KX&A(opA?T{F6OGS?D;&_jo AF7Q_~p!Ry$%m!pw!&BS}S#-P|uV v+@Tf8d+KtF>e zv(wt_ 1uY=h?r^FIku^eYR$Z;_j%>xtaN3cgLfLJ6FTg$1J*AS_aYbbmQU5@@p3hm`$_hfhl>fH!*+^H S1f zyVw5#`0dapdy?jyd8HJ8tJ5?D>dDlFPH}C&X9dGvY+>N#TRchwzXn*?&i(Yk`#Vf3 zTX|pf<~6IVq|uS(YB!318!+XM7t>!ri 6*4H(lE78ry7K!dI&}s3sK>h+zryPi@^b9IU-*fA-OdSxETV*A zQfJV11 uk{TeS%6P7P)OuWD%Qiy3pB0XG>H V&+1rP=nw3E1^wDLjtU`uI5#m} zo*B)V{-Z4KPMudWuL9bn<9W#&=kt+P-#SXXvUW>TWqOMKgRi^m8(1Dagg&>+?Q6Hv z!8au6fsgrBHlJs=ykDs9HLe*;lVZ!gDv>yPgF|w4?Y>2mu`%pV7b}!YekHWxdA0AV zTSju6c>8eRr!?85-xc1zAJOyk$MfnSJ@QUM?q}6TtsLHFy}`mw;qbwL19_v!X{?BU zzc8sL7~VGgbxdB=RvMW$!2xPL-zhkw%O=9sH*qFRpnG?Hx%dSydac{pFC%qKGWwy? zUFK|I4Cj`-+vmPtWj U8I6lYii-47uWMu2&$NX~ zxq pj~W;-=*P&Us7EQed6}JrfVoSi>e?P5%7*t6e*u o*>D@}H{M&-C8hiob%O)4U_^~_-wguqjy`Qs*Qdi6>F z!I!2_2S&@PqC8fsudzu`QK|n~iitdZSg& TCZbRx#xP(> zzUZ{H%Pn!_NBbe-AKvxswNWTTzk12hT+tXFx+?phA>EWbUWZC(==?eYEk%y$%HF7u z{&4c1zg|#Kr@ubh_k~y{5Fg_joky`N50bw5GWtmGZJ#CJR=mDDzvTU%rSvO8zl?UQ z5y=rN_;1$042X(R_P757nLuX0b9zL8lMnXIS8SFx2<%1Q6)}CWaX$Y5Y(?MlaQ^_g z(b&I7euPc>L|$}RH4_TIF&F;;8M0!t(3#76T`y7_X^>(v2BNShdVkb|5f0|E5!fLj zDN3b&L=SxW4g1kW0?LPZ5hX=AIl8akPHR8^0HOW+f6CdsY$UsBq>RHjjo?J+FTRBv z9u0R}#kr=!*)wz=;!RtpMSo447wQHHixw7 i zboD3V^s4vbJN&w-5sT|`bgy0La>+2B=o0rdz1nU*jr+BmVH1UJnTn;65vFaq9mtut zw;bcsY*h6Dc(cqX%JM7v!xv(+K%27~sQzAE+$Mn}53?ed=Bm~2<*2`YziZb20Njr& zoE*3pYR98ji?mTta 0s| C+Y!>V 89w(K1}H2_ 29^1m76B9(a654;P7mNw1MoorESCZha0r{id2+w`NV@? zD#_)62DQ^KjU|yF$gm|2h+tGP7z9S*CfHdF4i?4E#>F(1pLJ15mR=>9>0xg+)$K)k zsNES@ NjtV~< zJ+TuNGvX2| fy*dMrX+N9G0;OA*%T61u&M jmYjZ^`7ewxs_6Q%fR82QFWMrC#(X zj@k9^?ah)TJat8C<#aOGo|dh(&@}~_CfPug9YbAxr{vMd(HhVb;Od4KOKSafs={q4 z)fXFb<%ad-??4CMAk*e?y8}Zzio1TB?SQ9a86y2#9AhMs)aZA+Al8Nmn)F<55=#Yz znD^ttj2!)YSzVU8zS7&HYos~eSqF^_i3uK fqx2N%pcjO?=C3LlLtYdAG zs)BqyImd)Y2}G=RJZ^^gl7wtXYUFz!9CHwj (Vo8%;C1o4Q!{T-%x)edT*V@&GIPF(n2m}V>_}uK%M$p ziQJ_X{{Rose}Sivk!=hmg)^5NEVeLaZ*cE#yC?@&tP^aqV#l=8-Nn40Paeh$%`&kJ zOPMZ SW^l>rehg*;D$w5OKRy SA=d)#r6s~PVZT=4z8&W3Xw!{sWWjIgxyo`OcoED;%EC!~AT=MX2 z+a`#S@}p2lsUeFJ+EFy}$5jisf0k+C22FjSe4wf83n8}^hm9s3B&%6>)DpDp&!Wbw z+(q~F!cFAX{L<-}-JL#v# Uf9k@Jzna{S+@_Y@Z>?sH#L Et4?;hGzOm*T*O53j>=&f 5#Z9_w zsg82H(;hqJ86vh5HrpJ%5f$zodj{!N-w6{5CfY`hqlKrTt d>wPFiMD@dr zvZO _P(@7#XYE%e}risIBBJy13i;-zv8ZC~iU>OoI ztRzrr)JG1EJa*f7gAyWH>It^kxW>4Pru1OMGwP9U`iZvAG + zk-triMmBYvTEU|d@) =+#uuzAkUqeC7CQf zn{;em?i3^f=J_6RqO0yCNW?nhWMVx!xJ_J8Dq{O%7mCJ_k;sn5Z0w4=D3j%%T+=pS z9Nf}6os&nd^c(3&img`mr{Taz DNKyW;5~s^ zdtIiRV{0<%NML;Rlr98f>mXJN!s1<{uyNi-L9AI#ua_FQf~}QoNb%ViN02zo^TxD4 zW(;{^6qzgw7y;VqNHndPs_bXuLPJc`)%OucsPz1?7wIpyG@TVU&$8lUaeWKX9n*io z&fm@=Z;I7SOlemT0xMquQwKIwBy7s*Sj{$*@@-7Y*J3KBA#tU~ky8>*G>vw4oT#|0 zZZ(U$B#;Xp)wn6m-VK{vn R=ZEg9c1N*J*{ZpZ=~tVvEJ1PK zXC<-X>1g8t D7BTV^j@AwBM>XmvRZB^6Tkq3S>gT>q;f8ts zhP7VmT`cPKb43x8CwbGFYP%j@7)gaQJfaP?@cZg3fYgpelFKG-z5x+%Pg0sDpOa|# zl)#L|*@%0`$Sm>2s(PNz>9B$t@k+K70L|1>>{1*=SrwWj#mI1D*9QnTn0GWMr!Uc5 z-`r&Asho3c`z~+Qdhhs2@O;KA6^@Sq XIjY+SVm={r;e{f1O%pgolby50$ks(}R$Y4| z`^=vavJ=X838u9=zcrVJNhb;?fS@@e5oJcO$u;GSpGLOZg pl^6T1uNffeYjpPH90=3Vo9smKJZA z^ bMmh=q0J!Lzz0C?KMOfnH4M2Md#fd9Z$3rw^og&9yxKODefkyK% zO*Hui$kClDTn!lK ln!@5#c}W zjVqH7`3ezd5-e-n9b+UIo*ygQCq>PO=EJgxv1N=)@fAjxfj&K~%8T<=w^3;d-CPYt zqb#)B@DfWI%J53U2}ZuUp($NM5s#HRW9%k=91ruLj(%A>Hrc-U9K6sH)Oa#-&NHrI zvrE`IT?IhvS#zx`=?ADU%cv)1WlWo5(NILwk?wBM$u4u{z2)M*NTyFVIQYLioV^;m zEOYnTyjy^(lPR&|3L6H+Baf?N!o$a#Ws~d@s=3xO9!V`@>~zcd*B(yttMqB6WN2ZC zAE727W(w0qxtLKrFZC`iZkWeoUFuZyFJ1G0!5$k)g&TzDgptV{WFvj|-x}p&w$!VQ zBs1s3Oy=#f;b2ET8iRZdmByb~o+9_gl=^E? ?7p3CxHF-%FS `366hk8HmRr~E+3;Jxb8vLpP!=ELl(S7i} mRHlM5Hw zeG87o#=98((XRBbU+2;G&GVn&UdENH8Dkg8q=x)XTy-6^ci_kZ;2`qPg^6+XZWFxx zvExe$N~|(;w6Z)$rGO-2!>^H$q+ZoBH;95Weha2`E?D?+VIL*HlK`1ne_>4O&le>R zD>a=Z!<+ KI7q@0P^^b`5yMm4ARB04Wm#&>yIdczVB9B2$vutP( z=vg-Ka58m?Yz#QXlaE;SsV2mdbAFLvo?5C^z-c5Jc`Nkui1E`$s$owi!Lu)6!O7P$ zXY|wd9}lqUWD`z{2D&h$)zrBNw$b5BY)RHx9x&pM*S5>(-z?~%+NF+;mlGU{*L|~o zj>mLr;x72ddKVYcn7F@wjd$P`c%;5YI|%T(mhRa_3RW7nKrk~48PT;&&}2PZ4EQfE zIj5; 6RXbES(V#H_SaXzKwn?08-$D_lDl$VIHJm5`G54u4y4#nXCkQZ~=SdpMYQ z#fV&})mD_5RpP*jm3HtgS>1YL;>MbmI#hERCr-|!b6plng5ujvrGBiew;j)hl-Bug z;bp~kNQ`J@&9FmKk}Q51eDtl0__*>P6s`F(vfeGjCTSL#vZ>|QzSif4Q|N0;jH%KU zx_EYX?P}RrxNJz}nys&E5_QJNs;apjA!R$u#I8fnlVa%ld04diVe$v(MFl5n7*O41 zcP`m|8gWT7qFJNYCpmXusO`xUDkRGc8qmOwiMOYJLgxKBbTaH9%@G$YDdJi-&qEwI zMm{+)aeeV|J+Nwv(XZRk{{UC<(HB3SU%x4u0h-X|UTf4+2n_g=7dtTxkAPvL4Dh}V zud$7h^^{2%TOphZ%xFjlCZm+C@{~3i{VO*d7e;>A8+jrdp;6d4Ft6*x?PC&78%0xI z4#&g$cvwa_FJT-v(fE;JTD2GPFGKo+#FLZgpj)y|i vlB-*Qy zPVl~t!6*1XIBNY3XF@t*GOigO;*;@!GvgKG9gARUskMZWWiIkHPMWQzN&18p!<}Mz zc 8HU5YL9 zwwc>Z YIVVlPfhvt7%ow{J)P0IXE` zQ#QrupT3_f%oEnaIBHohI(@Ka!R@##j4Tb12&@AN(ov21<)p%Nd-9NF4P(%nVpE3k zxK9yY2e(kT >NzlS9pqVvp~NHGhKvI` z%S%R^lQaVct5qVU)%P eP@}6f7CNZeQ?j|^jxQ)bTMa6168mQdgf2C!o z11zz18KNHBOhdY5gb5Y07Z*3%1W$eXC(E3=FTQ<~)%MT2V}Abtyq`axR1&TrQ#(z? z3Sx;<)G)RP5)e++s(uNRU}RlL)L8NdC8mNIS@5I6RGH+;8+TYTO?6paE`n?(eexBY zy7e`jdlnx^EP#sM*G?DW^!kCN(bC#A^Ds+atR_~aUb2B^)+ nPIbFncRtBBpYkd0zKZ#>>s{n>cJ$V_K+xQ#?lw^ixCOL~yp#bl{e)5&2T%01Sf zB~C6X;yY{+J=>pti2jaGZTf#bQFqU_e<}O39e`|^&y$E1#1d!QH|fbUeu~}kM~dFC zY#M+-NrjQM7DtvTNd1V8t{ONtc5yHoq9gIBIU+q63y~wpgf $;@2T z++k`t(w{b8 C!b71-9IVG7YFeA00uwXSp3QbmMtEJ+2F#0zueW_R11_w>K*zH(egbhxICdj;z& zPtA`hz{|>p!Rpsw%j}Nb6BiNNbb4pmdi}9gbMBx1llM~WS{zhyoQbw=mD+xNu0Zg* zak2-7m9cU?95|`)xXY3>y=1(T;jKAxM}@Hy4dHw8XNQ)t@?{k0YN@wC$Ru}sKvFRv zjE-%j$SWGwJg$yJaxy=cBz;FREmyHQF5 RJ!3rEYVv6MtSug5dD+>R>vEU=nck8M-rkx>BOwl*`nQ*IcT_qdL# zxp-W8C6edLU=~3hJZp_9B3B?*9Xp?luNwy _-m3SxcJn3qDKQl)(O%b61l|6 zO*F`;)}vA7_h>MZn9LU J+^9aWV< zPia|XztiM8R#%(Pr`^p*w@_81a;{{!r3o1PVHiwYcv|!=SPPHRut}fLvw*%+P}e*9 z!gOKUYDrdO{DADr7|Twit2CF9p{yxIF7^$65Tvp*Le#^=Ym>6{duwGh9(4q =5xXtsL;7GWR&HBF^@0({Fc?irI+WwpqxnP@5 zRK@6+j>bC?b9`J!dvf0uee-^s=Klb=(z j^Cq%imd57-g>tjn7t8ktBiL|^Oh$? z{n#R!>dLCL6%a7;2N-R=6qgO}RBJXqZRlLz*CHsTHCZkWMVu+E_sI}ge3Kh4G@ch` zE9yrfBv%?gL6yQ$TM@bDqRdBDyh|HZSl6p{6+NyyO?QSnyBbG-RXD>0nwgFqY0=#V z{&)} tx!;nO9_u~!k6^u-ll!HEQ)y-@-5C--0==wi zyhF*8x5GIXCI_43%4=8M%MPP_?IRHrn!>4ha4=9L)Agx2_O^>P@wVsYMO_M(pw?3y z^kPrc(BS2rw2Nob(YixeHpgwL!lik|q@#=8@uVlHy_{nXh$TzUgdd }C(fIM9>-z#_t zuO X+ZeyB8kWD*J0m94OHXC+W*Gj699^crNk>|2iL1W^l6~P>U zR$Hp42y!t4CcKd~w6-!m?MmT8U1p-wE=+kYDv~a)CRNXsBuM@9e6W!cByB~gMPM(= zaZU1vO2K4hVqz1HNVrTa^1aHct199wT(Gw^^#C6s@M{|x5x&nwdWd`tTiaOPStQuY zoy 6m*d4>sJ+RE>b>6Yu?*ICw7wkk=!yOVC6AW z%(IdrE+e-3J8hCj$-8v>VC6ZuDNHX*HaJ$P(Nn4}BH}J@(K>%0xFgyoXpJ_r izdJYZE+@K)1dNDSF~aAP+Cij*t)hr zvL);p*vB|{8GX#<#}RkxzN1D=?kMxii0DwfIE%7?ox$t+&o5z#(Nla@^iOO>#ORor zzwQ^?G~S+msFrgI6n4ILx0_d29- ?Cj z1ElKc_93*TKA)WuoEDI6bo`N|z&J~Vgc9MZoZMEcSEl%mR;w)KGd!h*qSt7Gy+v5- z84(~?X|P^fy5__AC48`pe67*;c4#jR8lkbTJyg%hy-5jUT$F{KWP2CEf#y^(hZ&9c z&9H6VN$-d}L{_s;kG`6b9O?My`8o|36 y){ymiakw}XSG04VYr>7*8)L)Z5lLa`!$d?O^ay^YsEye-J zvRlAfN;bi~2X=1-<)}YMI#L1#HPs=YIP2!7RS8k(= &5M)EXU$@ &Efsmoedd_L*8 z-?BG+R%aaJz9MY7x4%T{ofq5oFe~I)$*G_YlZ8`Q+E}&`iK*p^Xhz79$n0woxaV;~ z5lEv }Vovc#Rtz*V9^RwPi&OJEPajm>T+sb!pYun`XY#t& >KK)@q0*sYreD~OnV%bbvC|?I2#AisJB#BPUd#hI5GlKre^XAk^=(u8 z<0C^iQGTR~StAhAOGrt2HWgE-$K9K9zt}>sBuuZ@&WhO@^`yuylVXyl!-JQ)jq{yZ zC*Hsw-)xO{Ix8us+E08WdJiPrL5Gty?Qjxjh!c&Pb5+bWt5 cOS1?XK*FqEH=2O2!AN+`Recr{ zYp)~O7o(LLk29RJW=M;VR>+TG4b{{C02>q8YISVtDEAi6zLBPgiFv3OdqBboBRY_% zGKHd7jYo|C04iqgTmtOq$%^z5bkNnXEj{PVA0(LNJh=qo!Qajb&9Ij>bolm%exKW7 z`zDO3Nwe*4cFRiza{Ii3X9SM^_$7nOl|9yoEJ(N7&9%;%Z8E{#QB@sLE%M=XBc8-8 z*-g)hn*ktgEAv?%p^|E-Vpb`u0w(QMgZHdm>`=+cw2a{&wFLF+DB%@GD(0D~%Ge zW5~$jm2i@CRbM_kH2r!-Z0jD-6pHMsvL5eh>@?txeoU$?=cb#_>F1^;F`I&bsDfv0 zzeKIwvB|Tf51R%>j8Pe;Om;Qf`gh>EinU70n*_0m>5|@Yts$hH8Kv~wYx1h4%KLf4 z3mK>96-7r*9E~oHvnOjp#}x(qt2;WWUTQ0vj!m}7LTTes$n%w+Ai?d}el|Dy{QiID zfE=b>f9xtHj1q3#@=R6jHCK|4{OHrBjIs-dxvi|^n_VQ_2#>QIj6~<~6 z$+FRZu(@X;Dr}<{dG+t|v1})+v0A)FBpY%AxUG{rpp3^9_jmsQ4~m}MYqb2^Os??y zGcpx4D*P|DZ=3CkRL=6_jH{fVzkN|!Tv6wFS%~x^YnrbqV$4k2uGzLKblW)kQ|m>F z$1={{_A8;M%(<%67q7FIDpM)ofGSB9E3sbmYfCuxX4AAuPSCxw6OJ!L&9O6YsAg>8 z6S~Rc+ak+Ql^1l!`(s_nI=QIi33w39T{&=zzpF;nu<>HkEK*u(S@0VBI~O#w4 OKob9h!d*1yha{{Y6t{{V9T0QWgaMP%E*_k(9OERT`Dd>8tZ%-TNK zCj9;NM%SqRA{TL6FZcOu-VT52MUtO83cbBP?oq6fJ1$+{6`i(~>cEn{6jlh(lW%m$ z{{ZS8-Ld(F$2X;QRI5_b=!mfM;jz`tYgy7$Rq@cAlcJ|Z`B60;ax8nOa&en bbSV+6#w;jJkdbbd`k44S*`ekP(iT$$77d8`pscpNC$0xAe!TyPn z`{Q#Na|2Gye;-YJ6|U3_F6Pt&=K?{y&&~QKTt)6Wu4lw6V94`P3ioc3(~{J?`h=os zhcYXm%=}~|-eFs`oQh=uwF7pRl6G&I&iir8x`X{n!Ep)?-HEfY+n{Nz8!k1YKUw5l znfjrqCw?@*>~us!Y2zzpY7%zhs$!}M@k`v3_F>xY{{Y*hXq~Z7nucip&}$zsG}=eJ z*z6o&`L$xWiZ)2r6)^A`!_A`WFa=wzsfNevn%+sRYu5p)Yu|~et5r{XTG;NmkS4~t zbBG}aW=fDWu+-D)@{dzRyi3SlLf`i_wURBRKgj6TSy?*3+vkRryyR*b4x4W?Xiy_p zDpDsA3M6ElYdt{nBhg&7l(H;K%d-kTuo~oRaLUH7EK%={X4$ty#=TqglOzvi68A$V z nX&fh4_+m&Ds)i1P&h4S`VnOD91&rj2>MS02W$zSD>TEXPm#G3r4 zs%+JVWFnETL~0|5>zz;vY@J~u$k`r4;}$LSc?f!#lF+(cHx`_V)OMYQxNR`ar9~tX z^65ry>>RrndJdVVW2Wnvf2-?X*fpy6c_+R^d;0An%cq;-IrhppsY9lzYhI*}0d*a% z;F>7mjHFp}Ij0<{rde+Q+9t~fn2g;r1jtpOj?_eNRbno7z57^+n{D(R_G_?=?lL#F zS*FtL$Nj#FpR@4a (BJ8jA2S{#uQL}|!)as1a;u|%a2u^c zbt)D7;Y&$lr7Fa>)cweU6U90zA~y=2{{Y6nuR>J*GK1t1f81qrJCpSa{{VaFt#2t% z{{Yf=M}LeR#{U3kq|us+Qchvl_>4~6xe2(=Kh>6A*)9p+iWYM$_k7e*zFDM3VF;vf z*pA5u?>ivE^JSGeu52Y#D9*+P^H(X8(#b{>L2WKOtFQdYdRS8$b%*racC(73;sLRN zmJR0zPfqPivVc1{a-%*RkK0q}^GT(W==vTc$x1>oIb)dN=9`1@TiNaIAiztK#*8>% zzW)Gjc}i^CDr$V=hQwn>ioFKa-9KU6;6RZcoOUJCc%H}JD9-p&VoGe-rT+ju@Gbdp z J{$N3I712TWBXGww;wW!1NO#WOy!y>wa-& zOk!BlXepj|Nn(4X=e-tI@?w56soW~a-bBh~^0mEpDgAcJVQ(-gz< 2A(2q4CpXc&XL)CIN1kJ_@S(_S#_mRAtzvQD^~_lLv@Eoc2h zdT0GbCMSr*#(0X%XNXW28Lp~agVpr}z}{D%81|7qjI`o$7lJX|()pjFf7Op<-U*^5 z_v(xOV`l4NWGe9|*>GPg`XdvB0lGVSyW1`1d?!-sjpB}b+akOtYab4C1lc;CSk>B| zRzV`jTj=~_X@YXD@X}JoCVib_`a~==YxQ++!!Lgq72GM6J@S!w*;+rGzMOFr-jrC0 z?a?+_L6*YFif-cx^Ch4+bd*?TjbPHHDYuU#2u9n-{@+hO%tC_S)H_u3Y~9*o50*(L z>wyB3AM&DSHAc&pq*09o-=f7-%DVsvQQApZ+L=$w8XGc>Ee+gE@9`#B#6TZP$<0w4 z%+r3-o`zM?2>7~gs`AM85_s~;*xR|$85S{$r6-5YTD>T1F;K;`)&(PC$~3XWjIv1Z z#fOB}Pym)1zI4P@-F}YPGB_(2Ra(Qyo+8L@MAvn4GA!uxTj{bQ49oK*DH~uXlfr3=7SXB0%)Ya82*)=RjN?&4_k_$Qb{fyHT?A~H86)hia3^+4!z8d2K;GLYUv z*p2c`pbqj#KH|=i+C=t9P*m$B=saMQs!;ZpWQA9VXe9IkIb{@jHsF}u32y8Mhf`mX z{5gu;7Kf-7N1&~Xj7AANiJY3fHpwvqG*8nEZWB$EjH;lOQ($%@*&quRN9^>S%W7Y! zwE?c=`=$XCy<1+!E~b&qCqr}$vb$v*SrSVum>X6F 38!K$ouEn8^^ zE4)GpG938U1L+_PkjWw?Sv&1&aY+%8>I*w>e9|AIC(pIfoc{nX8nJxtqTd+qL!0uC z6RSwqJfACp9Zc=AR2b75-ppqAnz*i9*EOzK`f`7hl~*N_;7O_FHo8xkkEYAmv)1t3 zO3G>JX;P_zR8~ &m!EKEeBd@fo=K zop`>=pmHkX$ob>g5-h0_M=hqECK7_!Cd-f_wzl;3@AE^jhhRR`iE=#6cAt!`ueO@V z&Q3&iWq+E zKuLPEuR~c&I b@KoKSm T9NNqVds60wtE_;%+qha@|* zCTPFz41~(*8iu>!cOQy(`YHBuWm^8Cr_2b0q0&Ag#}Q;{?`xY6{grZakmT9j0Tazh zI}o9 YK`Urrlj{`O;uTpcNbKD>w663 zxoI=W$8)(aT8e|+NTkzn>9IYq(wZbGmF~0EqmGtEmuORmhD23T2{^R~=I5K?g1c}O z8qMrM>qf3fxdhe%=+G=-%kv`Xt%0(AJ-&=-MTkTM3ygeA3XDm8#3R47$j;{;JAPZQ zXjMM)Fk?abwpGuzZkhMQ8R~#3!>Q?GG^;uP}qRY$Jh=tP