GGally/0000755000176200001440000000000014563007414011435 5ustar liggesusersGGally/NAMESPACE0000644000176200001440000001112214562447013012653 0ustar liggesusers# Generated by roxygen2: do not edit by hand S3method("+",gg) S3method("[",ggmatrix) S3method("[",glyphplot) S3method("[<-",ggmatrix) S3method(as.character,ggmatrix_fn_with_params) S3method(as.character,ggmatrix_plot_obj) S3method(grid.draw,ggmatrix) S3method(print,ggmatrix) S3method(print,glyphplot) S3method(print,legend_guide_box) S3method(str,ggmatrix) export("%>%") export(StatCross) export(StatGGallyCount) export(StatProp) export(StatWeightedMean) export(add_ref_boxes) export(add_ref_lines) export(add_to_ggmatrix) export(brew_colors) export(broomify) export(eval_data_col) export(fn_switch) export(geom_stripped_cols) export(geom_stripped_rows) export(getPlot) export(ggally_autopoint) export(ggally_autopointDiag) export(ggally_barDiag) export(ggally_blank) export(ggally_blankDiag) export(ggally_box) export(ggally_box_no_facet) export(ggally_colbar) export(ggally_cor) export(ggally_cor_v1_5) export(ggally_count) export(ggally_countDiag) export(ggally_cross) export(ggally_crosstable) export(ggally_density) export(ggally_densityDiag) export(ggally_denstrip) export(ggally_diagAxis) export(ggally_dot) export(ggally_dot_and_box) export(ggally_dot_no_facet) export(ggally_facetbar) export(ggally_facetdensity) export(ggally_facetdensitystrip) export(ggally_facethist) export(ggally_na) export(ggally_naDiag) export(ggally_nostic_cooksd) export(ggally_nostic_hat) export(ggally_nostic_resid) export(ggally_nostic_se_fit) export(ggally_nostic_sigma) export(ggally_nostic_std_resid) export(ggally_points) export(ggally_ratio) export(ggally_rowbar) export(ggally_smooth) export(ggally_smooth_lm) export(ggally_smooth_loess) export(ggally_statistic) export(ggally_summarise_by) export(ggally_table) export(ggally_tableDiag) export(ggally_text) export(ggally_trends) export(ggbivariate) export(ggcoef) export(ggcoef_compare) export(ggcoef_model) export(ggcoef_multinom) export(ggcoef_plot) export(ggcorr) export(ggduo) export(ggfacet) export(gglegend) export(ggmatrix) export(ggmatrix_gtable) export(ggmatrix_location) export(ggmatrix_progress) export(ggnet) export(ggnet2) export(ggnetworkmap) export(ggnostic) export(ggpairs) export(ggparcoord) export(ggscatmat) export(ggsurv) export(ggtable) export(ggts) export(glyphplot) export(glyphs) export(grab_legend) export(is.glyphplot) export(is_character_column) export(is_horizontal) export(lowertriangle) export(mapping_color_to_fill) export(mapping_string) export(mapping_swap_x_y) export(max1) export(mean0) export(min0) export(model_beta_label) export(model_beta_variables) export(model_response_variables) export(print_if_interactive) export(putPlot) export(range01) export(remove_color_unless_equal) export(rescale01) export(rescale11) export(scatmat) export(signif_stars) export(stat_cross) export(stat_ggally_count) export(stat_prop) export(stat_weighted_mean) export(uppertriangle) export(v1_ggmatrix_theme) export(vig_ggally) export(weighted_mean_sd) export(weighted_median_iqr) export(wrap) export(wrap_fn_with_param_arg) export(wrap_fn_with_params) export(wrapp) import(RColorBrewer) import(ggplot2) import(utils) importFrom(dplyr,all_of) importFrom(dplyr,group_by) importFrom(dplyr,rename) importFrom(dplyr,summarise) importFrom(ggstats,StatCross) importFrom(ggstats,StatProp) importFrom(ggstats,StatWeightedMean) importFrom(ggstats,geom_stripped_cols) importFrom(ggstats,geom_stripped_rows) importFrom(ggstats,ggcoef_compare) importFrom(ggstats,ggcoef_model) importFrom(ggstats,ggcoef_multinom) importFrom(ggstats,ggcoef_plot) importFrom(ggstats,signif_stars) importFrom(ggstats,stat_cross) importFrom(ggstats,stat_prop) importFrom(ggstats,stat_weighted_mean) importFrom(grDevices,colorRampPalette) importFrom(grDevices,gray.colors) importFrom(grid,gpar) importFrom(grid,grid.draw) importFrom(grid,grid.layout) importFrom(grid,grid.newpage) importFrom(grid,grid.rect) importFrom(grid,grid.text) importFrom(grid,popViewport) importFrom(grid,pushViewport) importFrom(grid,seekViewport) importFrom(grid,upViewport) importFrom(grid,viewport) importFrom(gtable,gtable_filter) importFrom(lifecycle,deprecate_soft) importFrom(magrittr,"%>%") importFrom(plyr,ddply) importFrom(plyr,summarize) importFrom(rlang,"%||%") importFrom(stats,anova) importFrom(stats,complete.cases) importFrom(stats,cor) importFrom(stats,lm) importFrom(stats,mad) importFrom(stats,median) importFrom(stats,na.omit) importFrom(stats,pf) importFrom(stats,qnorm) importFrom(stats,quantile) importFrom(stats,sd) importFrom(stats,spline) importFrom(stats,symnum) importFrom(stats,terms) importFrom(stats,time) importFrom(tidyr,pivot_longer) importFrom(utils,capture.output) importFrom(utils,head) importFrom(utils,installed.packages) importFrom(utils,str) GGally/README.md0000644000176200001440000000326314321332407012713 0ustar liggesusers# [GGally](http://ggobi.github.io/ggally/): Extension to [ggplot2](https://ggplot2.tidyverse.org/) [![R build status](https://github.com/ggobi/ggally/workflows/R-CMD-check/badge.svg)](https://github.com/ggobi/ggally/actions) [![CRAN_Status_Badge](http://www.r-pkg.org/badges/version/GGally)](https://cran.r-project.org/package=GGally) [![](http://cranlogs.r-pkg.org/badges/GGally)](https://cran.r-project.org/package=GGally) [![DOI](https://zenodo.org/badge/22529/ggobi/ggally.svg)](https://zenodo.org/badge/latestdoi/22529/ggobi/ggally) [![RStudio community](https://img.shields.io/badge/community-GGally-blue?style=social&logo=rstudio&logoColor=75AADB)](https://community.rstudio.com/tags/c/general/17/ggally) [![R-CMD-check](https://github.com/ggobi/ggally/workflows/R-CMD-check/badge.svg)](https://github.com/ggobi/ggally/actions) [`ggplot2`](https://ggplot2.tidyverse.org/) is a plotting system for R based on the grammar of graphics. [`GGally`](https://ggobi.github.io/ggally/) extends ggplot2 by adding several functions to reduce the complexity of combining geoms with transformed data. Some of these functions include a pairwise plot matrix, a scatterplot plot matrix, a parallel coordinates plot, a survival plot, and several functions to plot networks. ## Installation To install this package from GitHub or [CRAN](https://cran.r-project.org/package=GGally), do the following from the R console: ```r # Github library(devtools) install_github("ggobi/ggally") ``` ```r # CRAN install.packages("GGally") ``` GGally/data/0000755000176200001440000000000014526730006012345 5ustar liggesusersGGally/data/happy.rda0000644000176200001440000042646013663637143014203 0ustar liggesusers7zXZi"6!Xh])TW"nRʟ[^ nt9 >O=QEĕ .jzrOR *F ogװh;RX vÉD6t[bIDRm( ŋ +H(Ĥhj>9" > l$@  'n:t(VPiBl'CrOY2ESP p9sn~%&Eh6&$%NM q"j|?-%(8&Ӳ;o~;g_Qφ_}B5/@DKnKsZMBWjO9N# }-r)S_z-;Y|"0˟~OJ`mH .V ̽[gUZ:PvwT.ZyO/Xdqo뻙#/KxAG{ T&.]+s{X ;jMSs#ΦLօ̉e; /o/ *>S Njejavg6k;Vl@t/dH d։3B"w1= ˵֬jsQ%L[3ʨqE$,B(\h0㵌N%Ia=mtUT>\<")QC^7حzɱ{ab1Nhutu[ ^E(f6亄 `Uf+a{V .&XYCgIkyT3Gݘ  $wy)w-kJIoDς]v{֭GYzpZ%2j1MdIX qet@%?1i?z Ԥ,NG ~rPs}pOEu蘨ZdSCyo%nKڰ|*ѨG1J4./zBkGFs~ h1Kf^cؑh~&'~/ā/+GimG)8UHM)k F/& 2tXoD"v|Ҋ$[Н>=w'<Hɍ$SN+a "pPkBZe28P_=C凒Hg}D{o2<P3)opuާ} 9 ;nPu:QnG"Z'JN?,(hPfʃna;"^aI xjrRr6iph>^ᡯ"fp*Kd'ܣɋVݍ-U#'6ĤVt.?`P:Fst`[? ϻ#ŷa .[ʀvq"SPE;^ѹPMĦ~4`'qD,HW(~!/[OBJQ=:Ue;>Ax'z&XRhkw6bL )1HabzHo.ORc^XZQrl !]T^'!ڌޢVFB5 `㘰e&_l%̪&r2y:4|I :wy&tytzijGn;+<3;Ե$DT(-|p=t?kt|I"h\Ih긖a}Z+SR6KRQ󷁭 QWz0d֐C@@Xu:.F q`p|SY]ba W!crI_A [r`*)VQD~)t1ь@m pNN)B^%lP5˓`D$Yx(1 6*/ZA_C9@"t2hkH0X"rx@"ރ>07m[ԩcw@oxjijuL;]azm#Q\ gzmy :^J3Wwx7xQ}[\k KS5b $HJ=3 r'$@@\e]p$9YN`iFv2Oܯ)>0r+&{;|+kXH#']?^*mJpe986FSG>{S6#E\#6 WG+^=w1r 6)Ի*N ߭`;0?1[BֈƂfJ#SMA9/Œ5=NJ qx>)o uj9\B6բ`|l}߬X6?J8Dag>:cb:%lye&SU zQt*VzfC}$WzèJ2u?)Uj| `S-.T،ܱ:gUH{, <%zpFMUs[\T$D-)f;z홼\^v>zLqnPO90 w׸K fX;PrnW^^=uϳ2Yn rMThA=S+YWK{RL` SZ?(4d:کk(GH1"iƐfo1xN&}hz|*۪ҏ%*-aW!%̪%X<-?{r=ҕn5 r>^ח Q󾻑3ZNFy$H>-;ױ.PKb&DCz}kFP5߀>C 3Si0UkSL,*Q5 rŊ(KAmb0`i>/<`/[׶Hoݒ,L2(+OH qbM=z+1wJXJ0B>B樣Np:~0X1ޙ'Œ/$ay]K]S=+"eͿȺ614Hi9.ԱO\*U[r,'dx7Vy- ~G(Ɣ`!'Ed"}#HCPʩq9&ir;=0 eG %}vRPsg*_ xZgGf#dw&vYZ'Sf_ȁ ~PCfUȜ_~ZX1la1srR}s4߾6h恎SLL,=E:? <%BJ׍ɑp(}iS:9*5P݉u6:J(z](.`@'Lz) $}jeU6AV6 [v9y- rMc>Ϗ}z)9!Ѩ蕔?mP:N|bf@Ӡ3zz9)TV*OfFJ/ asfH0XL2~xL~ .[.?+AJAAvV,u袻w1جlߓE]R7!ۑuc;ń\Ҳ:0Jux$Q#4'~Eح+%'T*;v}ɌҢZ31$W"։!P2vňр @%4XAͱZd.;" WbDGMNykD0F)mc\ǙmC49 q?* 9T޼ؑnL:*.0_)nz#Bt|l0Oy>?1Ǎ3,4lx%ڢ q< *OX4ܷ#v(b`SAۍnxX} WgR1ec+:p7>Ab?i<:OP:ƁDBTAX)B?߭Siz9o&[# =RQG}^˜YP7 ܝ#-SȦ{?%TIA+7,M%C ]SQ jBy+^LjV^:tO u 0r*Z0/AEB~LF.uiV9mqCUH-wcpjLYFp{P~ׯ ȁA^c< D`vr 5)uh)FuV6&-X'zV9m.)ɫaΑ[jB:M٠}Wh㽳uP(7/;5_̘m&6Ԩ1 O5hcK&kzW>n&ŰK s7H,%iZ+H(WH66)$~d09DJV?qVw`kB]Eõ {_ƺF2-un8"RtƣicRaMb(MfG'im[j 7 Á -HԖp88EOQ{O`HX]`ќkGR30Pw=\fa2P~ bmJ^.(owY}\S{Zß;޲b*]8B,&T}T!<򩆠[fB>'-'ƧSv"jjvShw|_+L#wPb6{mvʉA&ƞw ;#^stp_R\6 w=?|Y%LL_ysP/g6k$>ua<ھ#4iaN-[ʷhe-(-T_ Ț3뗁/ߜ 璖tyx|L77 ?`E1}d=JfJ3YU`E,?3\MR> t5ZƎ~~LbH-"鄷o84I;9X} ?|xI/$I]WKy+N-:Ty3+Dmy6 wVTlC 3cUr6tQ2pۉY]O˅/Qz[2QE6ӄͬwxCxx@Gx.W-S2&6^7 g(1I*D*SPKCPN_ho4LC?IJÍVKW=` >Nc _dj`z˳ODY (UEQuF||˱1 q-GI #1ATlO <4mx)}c^|wQ/^ys\bC0x[MiYVڰOLV n0͹ dܣG0cziү?9ɮ5&gf|0}q- T_TAHE7wFvՆBnGx35W w6LYѪGVVxKǴ\ϡū[},nJkZf `M,+|22κ6HH`]y%#5n 08dirh.ӛ ʚnMW ekbu5$낲.-d4Lyua&4Ot?&%w!;g:C/8 &Typ!0 `irD])6Uv&}NYKsWya[|"xq!2xZI?yJjc.L41N\ߔ‘?*,y M }:%c(}H!?fw!,[p=\"\Qp_.G]o4 J ?mBihQ^}mN_(ݍ1+))K)>|"i u3 і~klο:ڝ~yǺ]dL¥;W2&q[ԡ]E%t!Sçp,Mawag!n`e#B<|b5*!!t, \MفxSڅ ԙGj]E0PlCEG*en B1(G_ۛX"ٻ>#[\!5unbD? (-k O> )<\n<&? W&ĕoo A㦞>@W"'y(c2P%"TNy++ybwE &x' Lo*Bet7 ?& ynu ximIzrxb'|hU;R^*Io aYL>.;x ɷۿIlEP%Գ<9 X*;c0 DG=R&z9$D~^Ģ%eҡ@/CpTg[Yk$i1E{-]_.2-Y۪m匞R VrJ| S|ZKoԍZM zԨx1+a 6;gzC'+'jKp`qƨI+x%c!INk`Cm\fk{X,UN {SO\LVYe 6 ug^Gn@ `)g;ӇlI}FVQ7n!!;\ЏqutCQ3ЕT\Dx(>18lg3e.|[6K*:5ndtŻKeQ쥞$Z^*0M"u8?z|ŲOs oBWX SemPrh)vgҨwf™O4#5 ޗQQ29CS R-1E`yP."_)j~TdXfl1AZi7 czb빗fYdEh~<쒚e[dB52 ToxnG2kstmlU`~_pq&leL?Kʹ1ڱoF=kE_oVy 㟸vg ߎmunV)J@RϵdQ,$FxyNoް` ]3dqNf2,b/ ,5 p>rвƩOQ#OU[Fy3 ծ\E/iѴ~7ނ{{$x !b8DZЧzي8Y/1붯u Lm6uw#t$KBC1d~:>(Lvua{!sTEyNh=.$ D7Dcx qP?60>4@i&e9 ߱u{%YAvVZVDjSu |^sc,!8(G+:Vثװ77OR&:DjzOOkw3YbEL䵥 M#5+B.( wəH}WklRW9^)-Ua}X3j)0\?|dGrqjA^ڬzjn lD5lŔ1wgm6Q70_`4n|r90v D~><*" e&uen[DŽK+h*QDkOPzj'$oq );O04i2jG佒q9 ˈNb\Nգ^r暂v L:*sn =u7$@t&^\s?ܲQoDo&ow|>*ΥR~k @قJ  u>Ã%̉1p jeڠKfO>$jpӵ_qrY#P%M3vrT2LU~\_h πOY$pWI) wp#g%XZ "%e=&'UiɸqxPʤcZԛ)F!'mZm=8yNNH!Vd1gVwxﲒAڔ!Շ1O #&pjAR>[ yw%N`f tBt#I 7' (4 IkmH,n{4>IgbSm@:dϴ! ?~x+e#X vQG%tBP+b׫(Yo'/>ʍ5B\r1W{!3E~3cQ,COV\jd I]iuYCeʇ6k hQdi(Lކ[~, GLPM\yN׳YI(F|>~oV=[R;ѾT&'Lǹ#軆dvD`(Nh~5B/#;3͋1q*xQ70Mh4I. kYk#;ƹE5B7 bvnoX:4o?՝9g0`$ZRBcņi]C@R}|4;z"LVS4XìuNJDv*i;@_/3E]49_7SĐ9S˺ jc*a' j!qM݀/:!w4(]CpK3=~O=QM/s 'Cu!3LTx62c1R]0L f4FO.' ErHH݂ZNjWW>n* Su˸e~v$%N!hK%!p 9`oQm&K6_&1:Czb")f(TɩSQ eA\< ]?aw.Q\jm?R,*aӳl V7BP\n.)׬C'#Ų _0GKbFbesӤryD4kYjcLLdIgVm~wEDNSg}<5@{]Mea7qRxZㅯRR7>|ݿrҗh$srwDm')v- c75ذ#TԴva&?),8 _Ⱥ, dT'Q #zqa C H ~_摦J6D.}zl{U2>DziecҬߊVJGc,iƆ $d`7RtdE<ϗI-InF܅PU1TݐUE5lC9(U<#[pH$3 :vdv.k51χL$X &N>u 2==D1dz:v+V$Zm`l>[fcWrkv`C6-,;^t3*""/: 0΀ 7E 6|]P.vPWXOU,OkH/B5Nha\_O%USq_6tZ> 6BNwXK Uu9%HA;lz_"(0kີQz08_FkƉb{6xg5Zѧy&FwA2KV9JMFx??2J9n$LeIދ fzئ päxC]ƙUkttJ^as RQBR}.ukHB?2Ӊхt"k x"9-?]HW:&D=j0Z >NQDhS sFPl(p7Լ7&W\1'f^reZ6Giu R gg^ ,rJ^YH=q8Ug]M['&]QmI`PutaKy^rj7N+Zi*GVn\6J+̺& o0@(~E\iS "<*lվpl/$~ Rr(ɡB86t"Qnd?S?<0Ÿ43,6X.&mNj^m?{Sn9_C)s87%!DsuI\`r0$\M Itu`VPt?@+v?\e gLW() ȥ[ _)}o8ÂrxYAEW\6rUC,Y0I8iё@1A䂘!a!I}DkKiyi>Zsa & wң'[FHN 'G*UduXP$J"W ; ?7GТPr"=F$`&je_ISGrN:h=j]V6ihS+bW #D 5Zq܀Hqy*^f8%Id^,η>E=yJ3k+Lyl޷Dlڜo6#WL2w>SWaV I{%wJ{3,fzx"o/2m{G^u/0w 9fa:{ UoZgf(;_2? \ߗ+ ?;WUѪv1Z0ZcOg#(cd6 ֲ(!a0wF1lBqJRoS6 ƒs[ۭۙ들_r|ufxDf\AQ*8;jرz=:I;Zn2:fOnn@Mw*S2}[{R97-[ap7)S~}ْq΄oab(>yƖ:ͺ]r!-Kbqu_Vm{qOi\F8Ƥ$5F(X\*WX>H{EzDӏy;ܕ2hcVѩ L+w;h2 H@~qqA5#iI$/QC-LmK2;zN+jH,jNOTM5qE),+R r! el%؞] 0V-s3Of'"cjǝmEZH]8̡G$P pjT'l;нWlSp1 ̓FL !gpns_҂= |L9,5}V#O^9Qϱ*w)rRB3cKHj@\tu_=î3Z"ߖdAlJ+>49%R_7>.0I 6@>Z[j/bo. ǧw/Nm8 :&!~V3VM2 y`))hE,xCl鵜V ډp(wP|EUE6b76"ILz۞c߆=*D=M//k*C!"턘^ͿVE)I l=o$,uXY$A5W;dD fc0cN(U_jZ:{nN WzҌ amW^+ׁ;v=,[eSixtvkZp^ x rWNi+Օr5c7{uo7y#sZ'i~( ]nۈH{v$?! β/q c~f]2n>2Z Ru}0}G/q祂ma) 47j짐!xAﲃ ٷT]ŷ{iԔEqu&!lj@i=;YuHo|P`9xd8 "]/u>H&i ZkJ>s>U q 97Aڰj /5IyKH>G=hVyjjs{^nr݉dyND 1ULOjg <6pWT+@̅$zt >I]\Jz$(vJ<~  5JBU+81jyVs%mqk`5dF.HZ(Ӣhu/3Dѹ^5!x7͵` di`Gb73AҏjPnՕhiFb;SJ=>t(v^i&9.yЏV+Z{r0qW}*fS&iRxr( S<; 2+o%@cI,G`byOɓی:Vo)ju!X~Jl0rMБ`1߼Bjq2[5K6"ntw!>w w7dž==C^qݷZzևԨ 13Zm62:/uG{O\yDi&42zI%ǛI.1$RB@;w/){d,O$PkCvThHJ]&GVc;vS8G༼=|B$T۲?wL;ltضFTTz2_L_UtGU4lZ섧g9*ChdC?_~5 $4yQPupa[ae <|[NHa?~ΫM~cVKY'%!*ki<;8t_J_M??uKK& Sz݋v͎yDprĊp|$[yx.BNoe¥Ost.Np8O~c2v<J>W=t{QsZG=еd,J7 RʛvPAv44ĉ)gy*KTI>c[Y{Y"scvzf;$IK?6e 4Ņ#&_IX2VC KV~J, AQ[tʻm*UKu-CL5#a \ ]0q|&+0A@ LCzm>ԩ8{^h&{_va`4]VnR#8m1t;!XѷҀy>FbE.N0xHږ^;קޝn1}! i᷾ͷ$ZЃӆU;F0AYAMkORLQV=zĨӣSr&h"39JُrsT~ W1ܳ@! }'7\7@ Rks]6׈(nR)$Dԗp,x޳b?1XlЋ Rb1Q5Y,?m+%r(y9.ZmN,B/lj8wcH@(|>ݍ||+슄1ϯ͡m= EGW4)L yyXyAn)p4btee*ѓEuPϳ_lt229~,@?<YO'X<W\ⵆDܜ-_IAL>~?Ms k89%w{p3tE ^G+Уm6 fl5Ըnaf~r)uad߹L=)%jV6r+JO}0Z ٍyYM%}Fc;6! -ګ/'`jYQEbt|^o q(jAΚvJ 4}GLA+UaŠѵ ܳGS;e_6KotssCN1>up$@M@Tۚ]H@`=t.$#0 #,<rX9$ƌ}N-0ݺL/}iQ ȘbP&og0̜d$?W/E1IGcLm6^CO!^<9dOvw_#5E_Kڭ mV5Pv:UY<_,f(nƉ}>uӀ2mgp~plIQopJ)?>p1xjSX |+Dt\nLhCO )!WH//( ϟ G"I>Wq]}B(ͣcX.5'dNJ"G^YqD$ 'ſ֦I_14f5WPqltz6FR#]J=b2SM2]sR9+93W̔%jԠ՝({2uA3c҄A8 7{pO1*Y`}M8y|:9LT_<W/eX?{2X3GunJE89h[ƕ-|p`0xlU0_!AyL`f|r&ŏK<}AZW1Ԋs@":\{EʀN&vG3I^\l&阊yS1zq!?rl>W$rqIh:@[l 蝗y"%E&r<g9hs}'CԐ  vfXKOmmr^t+ jw͒^ێjA}17s,[ƓmwFMü+hFQey)]{vU8wnwhlW/aʹkA{E,@^gt[{B%œa2A)vŲtv$A# ] !"5q(A㭦O2'e-W_a(!wdzu<$AРsCtzEɯ.?љ~/!p7P@Nhr$M(@8U~YwV//VdۮKAn :fd`:)i~If؇JRYj~%3/)jca{5Q^Ȱ6/{~j^ Ci{NJ0B3';v縦oO Ӂ.돧L')C>悽&sgiK 緾%O="X DRqI{:_ =TVɺ::%G==^mKN8 cd~/?S5yNq Ĝ8d-?ϽCVd\"K/J^J$WMH$q?SCh gخ6'is^칉,a KlgńML2o䙫Rj,d<+tRax:kyCe*Jqy\P lx+JFY[ΐ8srZ~K#3N&qS=FUUZsRUx.3)G\fiZ\1#_g,A M4d#-.4<ë}p\JTմԧX}85[T W{:+F=ٛe c'WzyмUNמY;]c~[Bf,44]`99F[YqCeւ D'2nT䟻xk?(}) Ʋ( DwbQRfy!L8P8p k@'~1m6L `l a8%ҷe_n̗6qٔYezy5HwD;K~^*z $H춨UKXt{N=r?tH#xdEk+5#9HӱQѦrEYŧEƾYI|4+,`^CηG1񳗔SlŌ-6RW8) NcKHhjq:ya+z3LtBsR1RY'UZ_$8ans d٧^DkbH*Nx6(l} wȽlEsX)qr7'6a k_s%َ.q2Jۮʄ{FvxzU'kaKŻsV/ Z g`3%)%&HJE*.6AM֩V4#hm/9ww^diJڵٝT/CBb*[743i5xžci|4QzЛiߧ*ޓ̘~<3wr]C=u-^ϩ&, b{qQS޻C;LBe( vAg xTEW;1Q\?13N AǖpfSuθ;!"8Gdr& k \1?=ُ!vCl78u0U$9 9*))Gck4" hU`.1YdFWER5F5Dt<.fIsx"9tu 1w+:w}s+Q~$[k 3u0)F8}YY;=^-; BAQG8v''l2kt,Ssr\LM ;yHLY|CoUncr}ծ E`V/&=4IC,#o ykL+vU;[JGJW,FWŤettm 0N̛ oNG¸sM޹vrx/& j(XΖQ.m^,^`^+ |YH{f!Œ0 e#׃N=׃Lhfv%XYZH8;Mlur͚/!>pM",/cNS78OBeޢtS.ȍxKªB)(\^ :8gAK$e{mőd#F&f@ ʲ(Dac,)VeĶ߹1ߩ[ ~ jsJDКrqn}O\2NQ"wH 4[j/BYЈ7Dȷ 0&lmte4pKقnHyg*rbmW,@iCG;s`%kA+2Y G,&64p#0M^ u? ^GWCF)΁>$ 2=䠰r?\-^tnmab خ5% Eȵ`#^om31챻>u;]? -=caȖkbԶ?_CEF&IkUT٥ (sNH$5,I<w:1{DӉǕ73.Cht*/We%jk>?; >n.To5RR!혒ͩ>YX  mKqؐ,> ;J&Q2KۼT퍰UYdO'!ǼI8q)BP៱`ٸDO V)\4іՓNJ3ޝ wFf]r`wjz)pl3vm aYqnqfF:Kmh X2f:8(h_`i/RoYX8Dϊb"ѢQ6"Qi#d A.DFʬ[ϸ?ÔQ3 W?@!녜?hȒT|L--6wu9j9ɕ&ݒV?RX%f0u(D1$ps!P\k.tg`KJBGz+NZaprJ~N@0mgI.CY5NӐ\IʡEX=#6q=Ko2eד*˥ 袻?kOwJ##ge+6lw"ĺ!Rda>1uIMe'-s {-),x b .;f, ),[iG / &0`̥oVpcß:u#xL{@ 0XJ[dOOr7fXW2UHsY]BYzA5KA!Ǥm@+r=,7훥vN}"bKO(gDzjBhq מ&٫0ukt["V,f@Nhĺp6@ЃprS/%=?וO/ޕϞ7KyKm9=eRJC.D6W|q.(0,@,`Pe{mS$xz˒`.dGGK?e|x ] cNen!//J/.X+˄eUA'*m`1- "Y 6cDdOc2`7-9wTy,3bgnS{ 3I,+o{T6%ST/ї }?@@ޘuTs *Up)m= #?G'3ͲHN~\\dbڡij]w#'Vz̙qfKúJ(d˨޿ʼnkFiWwt =K57IGR^?X9҆t gD̆j-bd67itOےQc$W[ذ^6L\N0;[|+=×f.쯨b7\د<\=Ӈ.!~cJNn:c P1UeҐd}y$I20$}?c9;1YB!cwF.G--S&'Xk2鬥DgLӖaZ5o(:01?e#TH@ SZn$ =foVҖI5^.Pˆƣl)-9qFD8 p@ C\v \qd4/^׬ON  ˉmD.| fT s]>umFMjGUVO wO7[v(R/}*uIL*L冶B[@;s-LԮA_",#NJ]nP/0l=Y"@^mf<7L}~ۇT  *bej뎘vCSnE+luIڇXs=yOn!t- Y%H`3E9 4يph6OF1 ,@EMCݙ4MDTt;@xd9xg"@.&x= >a 7H U$*WCq4jyF5GQ+H/R^ʳ|۲D0̵c 8HDk!W^@4zB2JKn(PSV">UP?AAf]I7i"6z -?#?7e;?+ȳ_u8Q5?=2*ظs|[LF=癑-B0{oAԃXĉTr}UzV2XBL<(^A?8SGͽPz]9"r@wBwk` ,M)nm^c,"N_CɾAk-{SuxMОJg{l8I Ç#r dDx$Н"B4t6 &L7i@qu|RyՉ`IAC A"Fh4T/o\[0؜$V$MT (YOq0WЁA_:׺Yc<7SMgЩ/ت"[ɪ_ KN;=n^vnƧ葟'S-DB >{j?;.)J 'E;Օΐ[-'ޞm 0*|A)4B.^߶uܚqzr|F at{ /I:Nwj. j4m@t6}.X ie U-.(o>牏Όmy E&ڃ ig~=36Xr7@N%&8W<4#-|*qZËDz*pS_@ѱ6PYzQ?aMSҟp*O`P(7o vcMmAQ}% 6WXmYq} QBK6Gmb]WØ8"O٢GFvsPvǼA/@k'03e埖uޕO00[,ڗukh-!!m 5"_3XFzj@:\!`Ɵ+;Gұ?KBu( R5ZOl_D5JyBpc59oXOH2u s((U${ LrG,3Wq+T0\ߓ?n!Ե>vݬT *Y ,d?6+r1Ili{:-9@e6w7y"ttrק3}!nwA]jأ#"2) r^<t:`SD&L:n٬U[$8ĘezJ8J lVyBMy*I^E.T g:i6=Vy;+1}T,x < 8HU7I^;fQ9e<'7̕q+:*mk: [糧Eq V>,_%T.sz($3(y1f|8 I[`">BeV^x{j3,/bT~fHG@7L…$6_C1 r_M9m<;%ܪ~(OÝ1^1GzWȠ]7 !UwbSOZdаHԤF\'#x m^>6j"=Iԥ|@HKiq-2"CP-g֠N׀&5'f!J&] <дT^knΡ# -aa+_"$"6ޜQM8(B<қžĭ䄪ȾNcDּ^{WlB5kaGJI&UZ<0 "iw')` IBxt3#sjُY&f2"۫YL%HPrjyw⨍d?tЃۅM6q<-^E|X?Qݣm4"̣ ]fbQ5YXW(;M ?}Z8)`W(}$*۩j֤`D 90ƻQo|@j]͟G\%%˗D㴽u%F,w'Je 5dh;C% _'(S)'g5 Fl~NLeVI32ci@ŝo_P(h_j/ bܵ b>:SQTx/ס}5qTBHQgY/zzк6IS{mledJ;"" M&"C:T.UE#9N~%IiD`VU/iH_K'W‡/SzD\eMC Ȅ\ܞR$Jp bvQ0Yx$rQ.+6SByE~!7`)ĥE>"4n1gS~zre9 rm@o.㸸sJ% ER*R|K:A}jP|Q 4yvwq ƀٸqWYP9Z9>x #EL {fWGLQWqfʏ'g@v [98FU UYjYnXE\}Q6NQ0gDp4/mfPU(dJUf  ҝ3DKȬf7;<J?RYv,9( k ɩLBIKt60AIԑ{>+ᬣ= [p S 5(NBIzFW.=ټŤYmدX5Prӧ8RȔ&r-1m]&q"8>g{sdh :stᢝr(4vo"`ۯMOGX^ew.F{ c3t %fȮu-y5ӂ&lFeS!U2ѿ_x' ʹ.LZ dT5#d:ͻ7S9j 1%sW&Qa}OUQŽ煺X7 tc몝@fR4w3/sO VHݍF)}Li8 UgaoC[؞-[ ,H`UiBA52qF_/GpeN݁"cTtJpHZVu@YUaF(9k)|:N "'r]lGMwQmϒ*9>M" @ᗋݏsGdeS%IUi}Oc"Hx+ckxPue2HiRQTe/JX*AʡpЍ{tr5fiؓ|_wk_R?ro2kakm q<0/#EUF/['S9!X}*I2"+):bp$Zo.,Q ֪VlM9VAFnVP2f%V/U1e}66'ujX7 W}^fy'W7VUURt;љ* z$x2qbb?hplȻpUXIpM.0{+F@1bВ Z#ԓ:Ø?F`6\Ü%=H6[(Ɣt9b6Bl|iQ m Q8kkkL8A4 gpuAu$wmIe; 4,#6kgg{}%}GWgVv+ @ɦWya] {~b['N} $@JGVw"Y7p')Ey(PxVh#*siDT(c`O-7\6]Ir,g9~^q[CwDJ|'tVZ Ɋ hJus˩4c?"9 GϮ*ƫVi YZkޚvd`lʌR u+ѳ$0)ULT:u@Xz@LnI]hyxz)LԣP& d{zl"w{p@2k 'pSxWO A>+Y8Z3 -_ҰCJ|gd3lvSӎԱ@[|zO R.ð_qOoʻ0b:"AN6Wm:u@Ҡ7ufhWگݡ?>&u+_`[/+eݗ2ehdH/OZ%A-'SJ d7}C" :r%;O /$ŅF/ZJiE)X\EgU,&Io8쪧 vKI =)WSZcWU`0] SA5u,Ea^D]IWXIcy$6YfKj!¦jZa]2jɞ L9^Ir&|K['=dqkZH 6 eSyq_ƕonސ[Tm_9{}؇_M&k'Ү3*݁)ֵ% 5&Vw-6J1{{t 9E5\!&x}Wļ]. ^HPˊm'P| TSwqtUI5f+5 hhw5^/+؜'@"y@=SU}z߯U )5: 7ִ .^pj5CiTn(pMӮv5jD%-kbkd\R‹3i8Ac|MOrT|Y^u.fwC-X+* tEM$:&"Q&s8kwwRG{ >8h MW7X s~Tiŷrߨŏuċ?X (uM8ۣ8ioL6vCpu Iq{P`MFCX:T 5;pMr?ƭBnJ(y:(UJ_W@44 E[f<5","M? \v)X|d1ShS1;ݞ59i9EcQusM)VB7QRہ7௝yWR>q?B=Y % (d{vڔMGD J3Aw|{&ei}lQ~GN9`Žg#'S!y75GoBb2U<8w$:iI Cx΂K)?"n̤y!f0nJz:c.9PhkxO7;3Yy Y_!(zCc$iMx4kQa}к^ΪC6yE,%( WAK}Nbm/,Khl3u&@"7S=09ú/II _Cbņ@-PX9ͧG ν8 KF쟾rۯӥ6ޣMvHrvPצzXãvتl,9̟*^7JtTٚdP8B7Pf+ٜC\ Bg:J=Bδ ԃdPPGXMgQUj7&tN/YH[K=VnW4bLn~6#Ydl6HŜE2<%_DD3TD0\"gψr1yr:{v"W)UA~YϏ-7ϘV&j$?6H/Nۈ > a\8v1w?N3 r!1~8+ ^XlNbߺCMO“> vL"*:aŠMG~\]=U leItA92f{U @T?Bxl UI :*T ki%Y{ѴiQW{ D CUD\4;wXD{Ҍ3CrQHP"O,RoY['=· 6|xI0Kb ēUItϓk'”J 8:u8yͱD 86Oqx̲h@#?yC^d Z-J[fKKwF AY ]_뤞]=|,rZʶ+pIr[TIzx1!J2ݧn  ȋ >_μ%1#t:I/yPEbV-30pG0G>.3ϖua(6Pܥ8cD^;kɆ#KeZ=vӪf?liWQǧYn |Ih[>j*Jl!`8]>1G@ k*o/R F\z9j_dW1Ȕݨ;>@M 1:){RJPV7p.Wxo8v<:/n_F:cp%a]uM;ר7[X\qj(Uϸj Te"1:st-=@=0RP@ N.`Ҽa(Uk HwDA/h=P>eVU]=,MmXvw.AupHU8Mr5Vݲ 5`c:(U Ka3]R.H- :FUjy6q*4E쇪d%ϖx|OweMB,(I- 'uLLAPᤤߣf !HXgaއdyu }GRR\EV*? 漿r{}F?er%~,h7Ò.]=i0ƤI<ʼn[EYh!A%[a5/zhMF6.eg9\rV e" 478qQ9E>sA9 e4vB;Y/)``d%_}1>m \? [-8H?](>{Ie(rQMfn)R]b8pQɦ&ohF7;nrJX4"3ܩxUX}sl"\LC)6} 2TFHsl{]#rw%eupެ| 78ҡIcX A|]Z}ed "ۢ%'WṆH~t2 MH3s9Z, ? h>Y| I:8(i/{Sƿp ;hf/RZiTJ<ՉJw&sG1Jq@0_ha":pkd }˜&-LE o ,Zȭ7$(_ys`c\yd &TYl` 2=9rm]aOG vJ,,_ 8Ij&vU=51~`$\FQla3mq2D&Lg/[= 9Q$#h^[j*z|2##c[#Ro13YΨ"*R-XeAMY lGR g\ OG^T[J ۡ;v^qK=7iNgP\o $c.LFwu AGa-RzwA# t6r;Y#)h')5KA[K9b\")H)ϫ-SK $S=Ax6Ȝ0ES@2R)>}?9- (.g$VîA \3/G=,`;0[{v dTbzT?ZXz< e1XHe,0 VUoed:/QLu{[S批Q/|v݆E,=2㿡_qj *)-c#Af> `)CtnCW }".;5XcO8ڌ!%hI7h-T1 EEm)챙uGÚOK,wczfJL5'1?/yiV7)Mi;D{;&Pfj>M7JLVzoF#wJv6*?~R#o%/K|Rבٖaq{wcSZ!& ~(ed-dŜ[lU FP./g)^í+Sgsε.K>ŨMŇ} *qEXViB!2Rj.Pӫa:&=Q/O!2anhf8;zbǡ9YuG&փ鵀Oe{}&qX3 н#.P؍6ӉRz]S14PJV r@߼ h tߐY=||-.;hI-#xG";r!%mwl\dJ2[go\vP$i(!HUf=5{vG[tϙ^.@vXsYk$+\5QgA^Il@cwLLCBe噼/lhy΁)EeO -TW;M:  Dd _$[u@R^ㄔ;m!.R`fZW۶@#%h[I@|m"#h;e FwW:0E|El VT:c nǃ(hpZzko/:v ,Qc3˭L2ej~-}>:2;ZC14uDʨ.O0xTO6E:!YtME&Yk\7V%J%! (`dE>N؄ ^C/SJgZ\,m|p.PL z8yR NqݧX{B$F;!H<SLZX9;sJBBd4vgKz3p0!rZþ5 CS^zř?΃9ʋGzYp(O|fy| jQ|RU4{IuQo lCcg̃Zj2+륓S q^` v̒$" O}Zo#C%[%b#3v &8[䣡hsS Clug5ٱwi:չgn-VIS6 |XARrJqͶ?&r3.mwkUʋDz^/j)@-<BP[ ХN% 'u1~# j_cBi=x<TocAv7 Q; !RFN4)MW'cy*3aϩ1_>`s2 jFÞ<`1HsXl4Cta=U0![\fyz+^$[BE.XhfQ Tq6KX.Ru95T&u.5;&FdЯXl1b;ʌ " {fRLߡZBcnS8/ļpHKZH83YW~uЈ4REdܫYmW@M t|>zuKTqZu?CDcgWnTTة#ʛkpX HD8bgx&`x ;նDӑ [kl(+o2 .4Mt?iQ 3~2lÝ`3rt{#ڇjXZ9E ])}H&7[]B _+$\bߎyE3@9΁-"% "q'W#HwhuyLy!e'QW:"98kx)%DٰTCȺG\oG#)fX;,\  C:e~]HZ\/EP82ѷuɻyxh,W"uLx?x]"O!{YFkI¯:&?$AbGyÔ4.k=.?/*_?]GðX|CgJᄋTTajxbY|y|3!;+?XVHtddJa%.N%ުn+ UZ_81•}^|o,890FLW21y}wP\>Ub('*[OpmcKƞ]2RAayEbYp# H՘4⼀oOcXgOqy._Ż@>OjUc(h/2*M9;&,[Dy|4ۧ@zHFcX`t SJ1I<3 #J#Dwl#Bt$ʺPDc2>)^w95K0!- T"= 5[qhI\[zd#sZ$ꦎe/V>-Utuzvo[?cr_mh;YIj{;'W*~ir9S(@ҠnP_P3BUZ %+EMxqfR cU?/|V FS4d~n2*Qgj=\ E齵S!ꏻxh"s \1N|߯[Gi}6cm5b&)v2 L '&uECQb4ԤbCcsUud:4`:n232)(m Ǎl@sISt]y$d>60:pO% g\J5=-T$ 78i5 ;zqBK!m) vkj'tۑ6hEf‘nVr4<@}' KAfje6{{ӜEH;9c,>4jc39AŦ"ws+ip kDXީ%+`åj+:%׬m.&8R} ӓ%З׆_0se24 iɵlf<-)-@Fk(h&kml[zÄFHW A@~F2,45F_{#)}4^-a"h0έ[!s&%΁ob;. u`&S=Gc䧀0 XC2Z'/Q [aH$@G*$ǰV6Ęt `9'V5#<+MC P]"uPt^N8l\.ijq8x7HI㷋\wR/($kV&2j%I[Ծta6ht1!~u vx!_\t(:p(G3^u\sy=(f8>BRg`䩓ӑڦ\,``Ε @= wnQF)lk E~ pn'fNܰ '*^Å-TbȫjuDvH /TJ@Qc7k"U>3%8?nLWy*׮&i6~FӴ0ڣRP ˜҆VO5D0$h_ַ)_ kW[gV21_'u TY%ǠgdR $ F!=fYأɺKATkH{6طw1#p}T%4 p2'T&$DDKS2)cO\l*嬇$S-:e ^j?AD0zTɨbih͑i 4 vdSL,./scB?1 jRMaJU*nnWn.vi>v(eT8 ,g4YYܿhݠCoL.k@N1WA(oI!=|Ԉ`AU~b\bQB80 YhuH҂7WC205 g 9/Fdp֊Zۋa:ڦr,L'qJr|]u/ H/$bUc1Z飇<]I⫊1"03 f#ޡH(m wW-0$( &rnj6.bnEsE&^e8hFk5"@IFp0([H.`WDm` ƫ/O|c1\Yk !N2"T7^50fdP|Nh^tA5ȤQśak xJtW~9Z.idV* DJ=>wv+d \m}RhĂyl/PM܄N߽CJ*k_AbAOaA};3N(x]4pJx²N&ZwUFlbƱ"8KC r[{g2euEfGS.x 5k89Au)t0u0!׸ht3+[Ӳ0Apx-hsӄ"OrŽӣ4?h4)nrrlEl,T d$f^oOnpRzg\mMu-?TX)Hs2=;GvA/W۲-Ohpv,2ǩiiiTp'!2bL(Tc f ߛVbm7uAhZm0'6 3Wjk}ۨ I(~QP G6>-MY_<3uU~OCNδU.vesD$gZ3rBd4vR@E*ʠ+)ٕ\')wy ΐ\cf ˠ'zh`-lݍz{p`fUO$e0v($Xo8,p\?9%J]5ly{lx#zLDjX.[+yuv64V0&o9U-52`I H^rNTW$vj|)^ 5hϰ6tLj7ZZ^cCQ$XyoS!CӶQ"Am1FwBߧ髚>>cXI n_'6e JUtMĶC^Z;C a6ӄ)1# (1@#|?bJH[Qah7 `߶<$pSATt=t|!FI _phr 4]h|2Ha"EdC Vݽ*a5fjU5ɋi`E.yAhq YGCwubT*@O=X mGr6O2@әlrTDK@*+GhO_(z ӽ)1Ʒӫ^+*[1xy=̾"cԣ)P淬A)} 5Mh]V$`P>jl,mxevڹmݢY >O9ꚣpvF[o(ZHsxazsIz_^/ʱQc%@NN|hr s)<>#Trcm 8Za$ [>-}<<99@!gWha5]O@lꓵg׆c6~_Pj6NH./Xظ&z~d;?e=ae[PEJ5$OENWå鼃"*2,!Cc~lBft YQIn;Ƈeǹ7\Cop%<ʧvͬ0Imjٓd͟g G7?5 Vs};IQ&ѣH֑%PtL[|(I!KFsI +9(pja¡ogUDPLxJψOdD8mzjΜ ǗFU^vI'r}r{ H$d; ]AT IB|3Aa`Ikn'|nă3+Yưۨ8u3(}ߘTosƚ:b?ԹƸ(LL6i{x}d/u|LЫMQm D$mUN0%g蔿{9T>w)23Lٜ&azi:[2n6|nbr[|CXǿ>7׉oۋ(LW?r֡fv,F3Oh9ϵ.$OE"YNZ>q2JN^u2$lp*Jw),9#Qp< TL+M4!Ȍ] 3F.) s0ee[{'FĦAx.3\4aYOy2lVHE*򻓽Zhb2#8ohP0bO7 ^]^ȉC[ÉxWg!L^tvHυ z A.AF(jg~r!|O ${7$e}.C䏋}9j|2@5((Eo/i-]x:?)yȹ!"$,m#}LMc;JLwb*~H/@Xj|/+ EWF } Zܢၺ x"0%N]KS"uuV!%cxO7[0YdQ,Ξ5Q g[sqD(>;epdfh0C4W("r4"TnƸ5Lٸ&T堪u&]G\?7rH#(0-o LW>w&II)˸HbZeaWqD6jS*>,*PQ2C"q@.U%+NvK jՠ6Z=lk> ""{k/U4^5q,@}[3j;ar,Kh Q|iXQ|?Bnr>W[z|ɪϑne*a;vkj4_p %t75̐\]AZLKu{ŴX x/;qjʸSER=[Q\'3-[_FOoY_THcM`Yr$Ljˏ5ijᱵ4`8^,2ZLo`Ϊ'`O#Eux)ʟ` ګdgLɐ=]J}v+C:~df1]$gT_`+;w ,d] +c'蹯v jUm9H$FhݺwyQU2ke@BOx݇{~ }NxLiϨm_2#5͔::ڴ±+ˈz/(F.01,"dr= DQ2%ծ/aK9go04/ra?4ɩ fGip7M`=he3Bh@`7Fg8id Dh9M]{eWRahX(~/Bz\?^,'_A½̶D}>K\WPWO3phA Pg8PҦmzfRdlqb#;hQk䳞Rb5PDĀk_ū rPh`WQ熟gg"~0QtPFq. ˖SPe8q/ s!M8v Gf gHΔ9 ĻϮ2 e@hPP3M_e5D`!rA<=ߟzk2!-xG-ToL+!S6-}ld&k[LJ;dTؿ5m3}2(3xgv /3b*.60 &6$]@ +CV:` c#mS*>T+bA{1H0M5he z AfDvtuE=mCpkX|^gfKʳJ\e&A7߰K!o וwQIۢ1Y  *6e>Er֢@HȂz<0JЈ~:ORD}-&k \G֚dNRp͌MWNsR_E=-|BS7bz3/G8ÃA]̾ TIR64}塺-;5;Ά~h(=Ұ L*ym?AdeɈz($HHy:M^| 0gԻ$2׆xK'^-?W-Sm+=Y!wa^9s=|leڝ[u2R5Xg*sWj6AG*{X%HVv Ȯ"З?#Frq*s 1 ź4%*vhg?,vCB#ٔH6+W[?Vdg 1z壙MQTҞF8PMZ'?gYW0;w;{~Eo?lttF :+i[)8Рe5>:Q:T9/Xh=۟`~qhv?W }L B%_Cfn9OZ,< RDE3d[D}d>Q% ^"ഴB/+%9^Sb(a0 Uۉ⠏ouV #Ԕk8hlYB(l|3E/_}[ $ ,] Ӡԝ[v]94:pv\xL6r7N! \0mNQҌ` t[ή.Ag eE?ƽYt>E_(Ҙ'SBsCNܤUm[Ρ=bd*,qxNSxunŵwXsS%|FC`Y(zւ~6&fSz@Yg{i5zU_Ip?ބ3МF!:/#7 {=VI6$LCZ0 p1/.Kr8 o FqT_)3ysc=u;BIdT) nʒ{dOTW{\>:t12mЙ-8c Qls a1*1{P].]-αQ~uI r7˵FX \lx1RU ;*cwb+ vn=$!) Y^]0P(ӡ?{5 X}EZGh[j}v :6qKt47F~3/vy'gl%br &ԯυUnb"?tM; JA@tS9+6DzHqȒzȧU g8]sl#qwR|ύ'Lz% tڮC=4%#Bipo( YZ!҈Ӣ'.G(`n3]ʬ}Y32`3ʨܖC`@Ǯ6& /U]$.y/Ab!LNN11 _WWo?-ZPe|Q[BNZ?28F*^VBr5]9nF7:nlc $dNfQ[0]yD=y#gWYeCc:UGjܺt-˩3~æތ.?8ؾ@Eto z3' _񺏁<⮒jj.}+~e`!8E-0EIrTh;)D>')oʪoG+1A)H3jjju0 M斥 '*7\\'\IŖnqtU"m((dlR UKzAKY7u% hkW%RwuOh hir1 þYrBulڮ*_PioyBze@SrRwZ|4I+@!cҌJlֵ"* !Tr9z'Ek",߯饅/i`_2 kyb,IDMŕ]  "۴nond "|Ӧd#n_Y9kg$4|DHz~?0;q"܋ˍ4|w!Tm֪pQ^I-̐]7"JQJ&`-͕Dbόw?wL!x(jȌZi{Ycy"Ԍ`-/@[^#^a~tg!q<%mVBZ).uA^w~jD >@uʇrH6%:(AmO0=3;]_O5ˠpWઘ4K8{I%-W$}Xƹ߫8=3$ Hx`nMq x]|vk 0&bj, sq*<2C &<-3[(C؇KeMm퐌kK-3B$? (Ze?QD>^fjKA.1R[e _g.M%{~|iJR{04_̖{mCmpS)C%"Eqx;vU& "f190U{G &[Yojq;ͤd.+iP&],6cu +SU" ۶0-5V":*BŸZYيo ~Tm+I<\%M +22)c_5jv>ɽxϒ|%;QÍn]HIYY I[]-BKΰSq`Gk&B 9Y wU>"a+fA,.5XQq<#)a!@_fHlqQoqNw _jO Nh.rNU|*r2#[ 9GQpTK>u}i#5Ju@bٍI5 _ J* 4vt cs@tFƫ/)l@"f\!ht%VňGvL&(NzsCVDV1 ͋-vG-DŽ2hP!_Ony^uh`Gl"M:X<+. $:-dXjBG (Z%y}%s9OhY%*s0QNrXj`W0܋r4ssٱ!zləh1:LIzGC~FAawVN43Z۞BBj}&_&Aё~O :j@ .!50Zx Jx u VOމBe$5+G.ҦCȒh%pg5XyyT_x@ot r lI;eS܂"uGpU aٱ_`e7 HXG]w >/Nz7!HksIY x./10rp0;kb=BXq8M* b:[Je 䢏 l|pt'lg&oy"U\o#{3SXyv Oװ~rx]AԟfFC N%a&)Y&4A,SnJAM\ 1+W&1Zm3kH?iT;cat\N8p@?1B+2#FA64N6 A>~ ѹ|Q'3IO C _`rRft&x^^.W97Y2d^QNCѻ|q+%8@i_=ױg&Q)i_;gKp≮iDkjek*Xi^Ji}$ID4fH͖Qva .~r"ޘ#0fwC4S?79{G#Tc )y%c$[MTh=Dxέ8Ŝ}.63BһդVH:W0&h S{+bTL}iJIJf~݃ڠ4ZDГp^Ԩ03ܓSQ$ʕ}fOZzǽٯ_5}m:)X'`|Q(B'ϑ3Zͻ4_ޢněnufHQt0;Jj0ԛ (ErB>Fl^BQF' vm"Ψauf;%p퓬yՆCA hf=QjDS؉\zߴ' l{&mE3χ=xb#΋'5>%)' @d#PG?5p:c^v5LԂN?brϸCyWru/wqke%G5(wwN5C[sřBaaS - 9"BJ nlqS]`K w;)R]7l.nRhUCSLSId g=rz8{IdLjU7˳OV:.0Lˆ"rR 9Lk>݇$0Kf(]S'+6/g_1} lg6}V]ʧ 1Ym (aNcKd\BٝjgeK8@gJ} 3QOȖTPp$5k BXz1W6Jb@-8-|/KCu\kh~e!0k7_V(_vꎴeӶQ6t٭-F8DV4q #I,'%gOB :G|~6y:rFHjo~+G*M# fմf7NEf<-K9KyaDb} ,hCxvײlHX WqfS*{}dpxРN$gm%d~65B3cl';%34W^P=jRz$`K2K:ƛle/`2u_KxabD0K2s{-F5xO'9L0PMǥ5kMZ[Ⱦ{#y-쀮;"Iw7tV$䏳KUNF{2z̝i^wt6_su}O<8&E˓|?ڣ29֩w7U5V*1ӯ~.Ra2Bͼ{` ]YY{P}C2C)˼OKGS-{Bf^Lq58 P'.8F\tƠlOo&O28[fPn@BqM@X!Pl>Crmp嶫HM,;kk[ 4$ͼ) l%ao <#P=UO?)5©<~x0I sB݈7*U{N5)k]fK/5o>|D6m:q?%}fA-9}Tw`,llh\h'IpjD %FḫQ{xGquD3{6h]ooAlҏLW.? x\RuF6S`i/圕 Q)=Ј;[="d4c{鰎;Ns4ߚ:ŋ\)A<%rc5%ySKm"Y6B Zh&f~[.@P{w(3{>%˸b?2+K_ѯ)H#gKw~]VSLbۖ0DMx\kyoJlԑACOț'jg 07;f0}!4ƽ9ȸL³e-_ p{Ey<7(oZ}aDL{PC5uPp_0q+K50L sWw%Dtrʯ:i{s/"Ȳ,8[(QKaՃ5CpU،N3WbߛTKXHA@_40} 13'D*)|m|9Uf5ѸJOe^ z()r12Mo1gĻߨsu*pHfv94q}4uN6 fkŠϽi3oqK O&x=4"rp۾ы >Ի@&4%b:n58!Bκ·!HԊ. Y]ETıE 7GQ4Gt෹?9_UF&"z}gc~g)^?s|[sw}c LCp?r:tI$+/kEBj;A(8W+OH1 Sh dJϷnz7vlڊ bOn("4RF14i+ʂAMRA߅P孢Nܴ7lDiӾkHPo ܛ&8lv3&VC>N+x`jDL`,F B G-VmBx*(7`62m SGh`2^߲Z,SƋW'?A>0JRƣPF{<*Y.A\'f79U}[~_cR#.Y#iPNm甦D\厃l% tFq:]~tӆ%HP֧i:7ƛܞo7#{1Z23}_nM(Z“DkJp͘^= /_O1S8ꋎ\;6AUkw49i~]A+02Gd7Fd h&n8A(6ОӀ~Ik"}J4?tNBԩ$ 6՗mO}NjܚZE?v5&V/oXx[3Am\̨W{zF/Qe׳ Cg" Ug{Ś*%Xsed1#F0x/X_WGY_zu Ex{$lt摔XlyV*.bifG?KnSgKl M"QTB0<$G#NCjxuQIY ,wSDa`h%B=,NE@{ sU{s!Ef<~G^_o}A- w7 &\ tϨ&OwkvPj jha}~Bőn̠9ʴ_zܤ* nuh0&K$6Eqm!eXE9ܥw#s}W}qtקg³Es e|k&ϼD})"#h{˘w P:,6ec"~E` \=+F-:? .1&ϢRK3Vm2f_U 2:J[5vӾ|S<-3n71ʰ:Q<- ?"|~!&8nÅkŶEc)0j{UzŃjsѣH)dq#zn2,rj"?.,x#_S2/kƣ4gW4YӠxs8S޼1}G2IѹF]C{h7fp of+"^z,  kw9**vfȎ&BøèBGx+:P.GRvk mտUQi[fh"  ZPWF;rmj<ԺozHIa$yYlJQ*ڎ2ëŇE Xo$5NSirdEMBU> 7ujH<5OL:aGd.{t@ FVLGF , pe6/5usJN{kR@Z,ƨIK t'4- )jHyvx ] d ʰ|*Fw!tetYua A!l-w,<}:FƏxtf£WW_nZ/yZvvZ #O]峅tZ"3W˴xs+ Ȱ$(rx%l8@EkiK½FrVZgҤsf 1 -YNSK'"ltoėVdh*-k0 G/Op9`(|/%h(V8wC7=HܒXM9FOf X8ؚUy%"` rUIfMG04&揘YT_q/6g |3DQI8>)<҃6o%=b$2}u=p|5+3мQt>v ];„8/'V )g4'R!<+^Ufr1j  ]x_i@ 6x;PYT(O oePn}i:vZ;T۰)!_ wy/>x݇HT"c%WX]"78w/q٥s7ALp.JIVn$^>/.5ň"JuPhA`l_̑n`no;{s!c}b t 5inDWC:̥PO]*#_pß}Kҧ,2 [Q7?)h1Ŗ[DŽ׼pȀ/+.ǮB;EG5Duπ薘X j\Zyjq $K /MH.sQ~8FjWuW*Be<~X8 @hBia6"տ:а;/38)Rz +}2$@ )Q"t9yCk> _C4Y INO7̪GISTvm e cP~C3=tc]H8Ocǡ=`pSޮ;Kwv# br-t(D, E&E[e)&n%fLZĈ| 8/&Ag ~\x`e9S|WaxD|5N8r&CLa͛8ފ*L1Qب[@*Ey-p}|ybdJ@.$B;ZSCS^Ig:+гh) B{",y+ʨ/)na:Mճ8S^GƈK!v룍7Q\PA.do?i=/n5zS cy2Ny0HW~̶h%)0Wɨ-8Sm;[LOOJZѽqx^dpmTх܎\[| 9Ruyx{QX4g$N;=iVY[k%b xv?{ ,gF3S?.W%íG)f6+731m0E',rrD}nkMZuH?}dvĆ'gqi<+"[7ʹ5.ѰXu^瞋9x|qw`=\ כJ.eC !5 -sS/W6#!?nkbAE&9/go ]j /ش;U"p!CjQŚuiu7CDqPo".[6#b6lqm|k''f.3]g4?53՟(qMN*zX}2vnx_Xep.qwsN>VgdÕG51Qi=Jld;Dъd1Җ X 9Bǖ;Ѷ/wnىE¦̟n#=[9~eUN*ށfLZe8ޏ-(.q#Ώ쥳 -sqxl1*d>Qy0DP[K]oag!g%wޓ&7{(#S]qvypÅɦ$n181,ډE $ k_d^5pT\j'^"dTwwp_CL>m"kEwҒivdVv&Fֶwʍ{T1=NBfj( bJ5 n E_rCM5Ɨi]Qh UZLPU L*2_NCEHlPrȫrlcF<`+V~F =yy|=}E\g ҳgpd'зۡ,ZSn A+*V}"#Y)펱;S!$ҭYFf GZDPn~+i 螽-m?]m^3^c,JvcJ}c-ѧq~9 eEl SԨ6 I53C:$AhQlC .٣R@#ʃC ry戴4 #F fmw$Ii4xދ_hz]_t}{v>w&[lNʨ 3d~ϤX @gA,15s):-t`g.(cMgų@l rΆqBHY8Cv*josPI8 8Lٲ謱T7nUvՀh˅'Ӛ>ʮ6x #oEk=7fo>[:Z0sS +]^Gb:(m`n"  M*:a:nׯ nvQ$U}_?NLc޶Ok 4 ftqw7AI.>ڵkJxHIs6Q* -Xy4nK4ց৽4iTǒބ[iMU8jHa̔P8$9Lֻ`3}JF츯Nq/U3;5LKa+I뤙$J54AXaSt~M"N j&Һ];h,=qiCc^2Jc)d~b1(Zx:9;r!YAppI JU1(ӳۡKn)cEd ަyX路 m IS SԔg/D) ʄՇ=, B4P6hkuy9E U8*tipcbbNЦs}Z]0ɷcc6mr'߽o[AU$Od$1] 4ıU2hiS@.t1ͭqwȊƳMF!底jZj/Bu)"!;˃87oJ֗<*RSkD_0~@+.Ѝb ~Ʋ!"EZ@a~ ҟY,z"v +z:tk&/h\NQ80~B sC=cY= 0J|B ub QJ!NygK¦EKkL?|Jpu9<o֮/ƣ )PmPsC护 T>{R Or[''r#UGwk:0 LԲo7nRhƕDk_Kb/}3t9al  _x,5x\gB♯Iz`.Q}t,cՖ5rӸ/X(vAj Gn|ZJsh=6؊0/WpFփMv'4)bi˛Xd(bOȦ-a1kd? c|!@"<*'kmpks0Wn SUYz;j4{v1^lЖEl*OxɊ6se؟ĥ䏱P᠗1-7ћ6A RmG=7uDIͥ4kO3 AyhjjNlDԷ{H" g'Oτx ",D"[G%@Kt}n B6;:CtUIYF׾,\ UM ÝߠkO; ћ[?焮Oz{/?4?B1elFp^T(vPa3GWlCy1 =Oy"Kj62 v)3Em*|Ⲏ_hTE2cq;4<vZzd+`E=;9 }L!hx, g_/=rvnocInjMJfm@H$[;VҹFw?!|#΍{FrkS:xFM nJmvj @kz6LUY$_ƣi/ӹfi%G'd+XӬ"E5SmFSϷB\,IYΪ7wV.r!S]fEwׯ3YLaV/{}Tg}tw2E^M ̶֗ӁQ.7=Qh* iDm,QId)eƢR*a]?0h7M39ʡlm)Jm  :l D4P OHITd=!G9|b!xԏ3tL?lg]"S.ѭxuO6W:}(_IO?= &97]\`S|5h"NhX)HM$]ݿRy΅hz<꫶ڭ7yA 62Ke\W'\ +Ÿ?fgBu*}w{Ժ6-'PPؔ4;W *:W;'npm֦b:I"˿ 4yݣ=hాSpc*V!ARoQVsWAUB+s |2D3*0'emˏ weE~?Z2Y\&GR:\ mH!- ξ&6)>k=!mdֽ#9Gy5V:ہZ[&JG*_#zEss;׮]q;L%# :5&rp"֍g՛R.M=g}wŮXl--EOKN0j>A®24ssĉ\B)[[ ChRL4Fvn :]ԓdMY6"@Uu[䥦Btk&ٜguQ!94̨2R` /Tx1R*?L6+x4I,,R@k{ #%vqA ^PZ-3|x̜uC~2bTxgК3`nJ׃ԁ͈xL}gqIoGUPGpwvu^At(=Q׻O (G2=5;ǀr $v2Xx.hny4l,>cf^M#iR-C2 R ";5Q&'x)VK.0tvk:UT]ye5_)x3-Jokٽ#g>5"[SC7NZe \xpuu3sv#2xUv%#-̗lRu~ }:^qr6f$voАHA!e=K8'Àe!~dkKK+r0x&([wS_pثP %TL~L1tm豂Ix*i@,wƘ8Z.jk_{.k=y>"wKٶ=ᇸY'`^`~m^a1VhH< +֔QsD(/kCg1\.^;%$@U'*hF{kTD1?|i !gxfqq7ɎPZ{B#,VA+ Oifkv3TS+̠4̡(ϝws}6Os;zemJ.KueSej9eK$ ϗG{p}!ٓvED\ړo]Wӯs= ׏~+AhB8\7jx%SG w2~.n&| a´'烤!EC[öſkpx?hժeMzf#NM,6jqh/QK`o*<$5#`*3,W7rR.Փ,{k{o´xSo)"# &^Kbף)RWG95ҁT"’K8h6ltL`$y422BbnHF1{j|m2ɩr&n U?4A|ڦƍr-\*bVܠ7+ae14 *ԖeD7|5\z0=e b۾eK|W%xݍ)C݉m z'!$奾hߒllR{ڿUCL')`Wx0ѳqe\քs=`z/tO<]Uq'=q~mߨ# p.z; B @{BoBdWO~kE.! ȸ^椲fVmT:W3pe[xPݬނ|pE0yzڛW-qy;^5i3 ~ VR?^l.deixFHu^%dBWQjKsX!٬dZrbbZbP4 JC|•x( 4ꈘQ {SǪgϜ $|e"hEO.Xtb43ʏ|YΩ,enOD3BEkUU%' 'nmέG^Nֹpqr 0^0c.utUalФe8 $T.8t?Ye¿LpNygḜ SDU*Ĝz5_c'ٝF_h|B@<7ŐoՊeĹɹݜ0k.x)I_îE 񴛊H.Jw !N7[&հ[2OAO,HffA<,TQ8],xjVT=EO\"F>dgٮWUJuy5L^ |V'jf>”Lz6y._`$$W\0hOΘK/3S$38 "c|6,[5BqBWrE!eGC_~*m,ȞȁnxJ<,iY,>G4a &`Ԡ.A(YfTBN.Ͽ X] dM!< %&tC9lXx~(yध!ާx‚̥멮1 iSnK:28ޙ+9k4"C44)i@2p?vpKUL,Oc`4Ѧ#O:dY=R/YɀTK&ۏk>SơX9d&WIG4̋]&M_N^:B=s(;MnE00VRE [Ϻ_\")X5$Aaˣ_YwCB֒Q}g S!Oxzzk{0/!D5p/L"( a0o7PNk$;K9$YpɉL{hl5ɡz4j-7醘R=Fvb qoЮGݠ+DBB9~v|.O;\+[ M?SYxeIJ e|-A*wldI;D^]= 'H5]a1Ƞ52(:͕^|_j" )ڣRAJ7`KϠA13:5V[?/xLBw|[c/c͋wB̅/ ^c?bA3Y:oXTLX]surk_6 sȕ`g*'5@Pb?ҕ+Hpŝh5y 凤} jy]Fܽ ?(&` _qѷIfH-ݘwʽ}df Ĕ'6a ƈ~NI=yí@Q{ ?1Q+oN 3\ȂK % ? GqnC](%THB4;v3[)A-Whի7n%QԡgMFP5x;1㏰i6>y=ig_d .h4"N.X,u㥠EdKTE#0wOoWnˬ/`qpvd+\I'Dz$ e MЌv[.2i3cD5M~Tx6N"Ÿ;_ , , [5,;~9 Nۿ~yD8e:̌ wrրN0Ńi dz9~rTyaJuv yp5;~ {̈M$e}<- e׾Sاq'[ѨTϜ{ N9AFx'/q^dhD(vB^?OOÕ`M|_AX0gl IWHG:]WF@76N~ 6 7ovgALfmrDBⓛ f0b1WL574pI6JiiaQdn5B YlBmj|훗7+ś* מlhq2)F2`}+Zd!3+aSV¯h`VY*pJ D0w'&K+Wf {L=ix SgD|E"]bD*>$Y-",NhXF {9k:EyP>g%Ҩb?AKAڵXJ5 &X=śNT$20y z2àbBƽI3Ȝ'N@ g^w*!cȂbT'Iű3'C.L|{f y=j2db2";q%ѷJ^F(њI/wzf:mgL<} / 5` t]g(^1ߏU{)_Zr!~TODI9L"=>$I)wvu9rtw+dXZ<&t-w%GyWjZq[PtvӪoBsxeJɆޖ;8hs*s$HQMZW| }udE.h=60Ob5\UW)IJj墔Κ.C_@ae30b8ŽM 0Tivh/&+" ;踜qTy8ow-Mn ZUB<9(U3 N~*8bwDɲr'.ſXSRY rw!mBDK&l5Cp^HlN,ń.| ʷ'r HS㴈9 eKdRvuE|/a`]ݸ qHgzͥkLsͧ~Zh‡'\N|9UP d)O9$B"Z嬩ը%|Uytc4\kxvr)z'ᥘ-نŰSc7 sy~g .ݕ= ko#+zr,JAi:;Q? J@9j ̏\Y #^V@z O o ܦMÔʓ?H>bi9U7.6Vv8QbдyߴtY^mqY^lɇ!xv6\73-`L}泼șɛT}˩x'O)"{1 Y{4*ΐg̝rZl|P3T$|y\8 &T ͱXAR~րt ̹..l& ] *" U""Y*j_: 1mB7qX֦ ȱPO 5+ntrf+ f_X)S ݔ}o1mGWp_l _NӮZ]=[$0;ڤvƇ0x9st{|Tf Gh$Tm_+gdJܿPtoCRjTSacX;2MjabM _ e+CȂ>s9J6oz'Drט ę$$[eӤr?ajw>4 Rd/~\ IC[p ;Nh}pV@|Sݝ>Ү0E"sJ5|t#!W)к!4K<`~L,op~{=N}StD9&BI{`q`] P0+X-MQ_9GUi-0!>|Q >%rTu\JI!ŞHzPM "hoG'4O!:j.|4ԕ"no|t _q]}Hbqf}|^(h4ۊseGtq7* ̠D7 rxf竰 NS|?) q1I3PSQ=E1H)(%M7]Ɋ:}55/ |m,F$ec\5k^j4uV0 ˪-Q7>b\+vK9%g]OB3|gJ&ĵ6"^րe$h kS.+Kذ(ޯjNWc;xN'd_f5D5uwY5IMUtRO<~Fy 86ވد4&YCB@Xs;& m`fWQtXjry G %n/HZ̠TNgI3Gvr%.޴3Z)ڄHexT0]1DoCѕI92lX;r5~!d7L휥IOi?;ʴǑzpHwwQ]fǯuuO}^x ,v0eC9q&xJc`3LT 0LߵvhށyV"o;oc~ǠCkK[`__sǾl`mY `u e;ӄ49i~RF mE 48b$$U,⶚,alhhZc?>K>ݣe@Jb`_ff65۔uh[:QhhK}s P,; Iؓg- vgUG5A ˮ_'} WݵXN"z dH 19)'YC.j"W8Kc&nU"hz'ʠmϟrqTy+x (PY  Юx.ʹI N.jpD}y}FzWgMn@ BLHF{iPMCߓ/cgno^, x:0ʲm[ jDįahQ(y`UrfUԐ>Hs=P1}0-gh;^ }zS7b>Fٮ3SxƩ 0a?mRC/ᇱ'rlسNĬK?.q ,gkE<]bF|55f{N0jf Ή2s43~6F,ґ~TlyY/e0)Kp߄5Q ٌ$]-ƍXTS%9@fgS)~hV'*fU滦κ|^K;] U.}"Wa>HY xyRSDTz`G;c 2F/;06b) |e'中rCL7L6'<^@‹ A4J[mCZ^.ZdH[+G# q.Dq]eu] Lig%Woxu-\:^#g!JԒQ~ !?DG1(W?k 8c Q1v֞ / . "<7Gho'!ޠ}|YI"E`QW7aWo<^!r=Զ"$-wn*~:gɹj#O0ck U8ޖj>u%[+2wG>qUvlt4!ߝ*Hkem` D}ۢK\P "}=JLS9 IcED3C+h\`1cgʺQ"4𗟜NXZnknܽS0Նf5KblĪ$\ۚmL.?PQ5ߦkF:ge"=J"Yt^w *Υ @? S: nL袁p) ұ>%K9iòCǮR8fn>Bz_ ':>s~OB(FP-ʆ]3WZyZdiьv#]Y Vp33_#r {dsbӯ#[{Y 1vp6.+䫔F,e\^'k N/P@CR1u%q* dНnȖ4ckh>Gp/սs뭵^4^*& 2T7U24U hq%XÄ5Wؗ#2/]Wc~ׇ)̤Lk֨RKfJ/'mDxR0'эjou0XJwҭ=êJw$[v1YXڢ!)}dJ2Bx^^S25NEftgUZEIO̵zN8I BɎekeX $7)E⯖]rvp ˍ3?eʠغ䡯xQ*]xŻp4,"FN80&eA {,}TPUkk}e%`žSĨA6P>TRqO6<jQ9J}.\#ԳХhXرF0zP5ǿV?I5iGqq )RK7ڎ<JI ZK G:M\ HLuz U#&E@x0>t]t6Ųޝ{nz$)2RpL?'"OrZ|i!xFGk??k$; 颩lGĀ8rRQfE[1(Y'Guz;=k!?zt}BHM ^c$g |*"jD‹ך0`2!!-`>v9ɘ0M1Kʏ&? I3qkjK6^:%:0(C s~*|bƏH/zH= xəy#+N |:pa߇5ώO kk&plbu$ 6R Fe-McrVݡߝ NI"eC r+ 8[~>T<9hl'!8@@9,ڛh11l]R iëv54;NGwrE񍵗© y_n'C^(:xST% yQN:BڣZF;nps{u SRKLUVɓdF ޕͨY|={d&UbJuͿ_Wi" 7]>oIs\$CNu( XxVe>5usi!֠D_mg3 n+0hIC8i|hcʮya8ͨ\jk~.mh."ޛEQ0}rs/`ɦ^t$#&VQm}Ұ̵7;f|KQ[!貍pY-7:w)o#:!zX}Q(.*K"^zJJ3v~n#~oa+MΊyt`Xc_@e5KLcSʝ qG7i2M݃g94#?݋'pȪbq@詛Wͳ)y5\IO:X -%lE9ƂZH1N]Z0A Y*zL9BS#k2U)W|53?5ͶkAg9!]aRWفr2 b2~.7$u%UR0gC@ 3W@UwCED_] X<}H*:bQ/׬itA9g/ wb15Mcjg& '7Vi}5 *U[Hծ6yjWAh$\lI7hI8wj'D><nMEDkQڥE0Yx^lãEm*r4 XORljuI YD]~p☦v#S۲X=/ьG~A׋lÎ "'lAxp},הZM8W|A5I2f8OXmu3zƅbIƣ#Pk@N|׶A?drDv~>pخE)si:Vrj4mg;k3ɨ缰 e"5LmԜu4l.B)z qqyrق^E`ͯ"{#,@A|^z ;k{!Uvi6 gss247wOYsHYza8)!ڐE}=vT%!H̍.͌cb_ھўAϣ(W4y8?jU5rZ]tDz~9e/d{6oJB{͛*JZhAt{v6dv6"hF=TZp~(ZK] 8\&Cǧ}!=CǨ_W(6 k+>}H/͙QZD{|pOQx[t^.na{ g_ ҰrIT:nT0!xb? SV=pg4A )>M %i0=t|Se` ]-IY (TqўWş|y0",y#* niT1=X0yߛ7a]ARoB|q -++{ѽphWʔ823.`2ygrRʂ:K:\*I Aj8b~[c? -!Lb0VIH[0Xcv 3]Q]BL>:ў^} @}8/|wܜ"KqT}N3toQʬ<1*U3}Aĉ)hI&a0l߇5I¦Wu>;x!~y}ޑd"ݙ"JU):x)pf2G"|4C>!OhPP`Ty/ *zmd v {/'>SI$$].&"R]SN[9B#Vzг4 F*̝0+:qvI,6^dʱ wrd=bh{Ccu-G' 6vEüMoROr} U /*$ը3$)M1Of@-┾ŷ[J$)+ebA*&җbf#O;s` _0 7]^=qyl^"Vv6*_`A* .cb7mGȔ/T㬻5XS윍[_y$@{MȁPRįqPC;rtBxT%]x .-Gnkbwc V7!rGv|tHߛ$ظl_&)~]Sp܎ƒlCt؜R“S0Q|5M{ n`#с!BL|;!V4 y|PȜbW5ci h% vzV?$mjED6KX_g/LW hِ/_k߆/+{ v*Q}75AbDC9 MQ =#7r^^JvH3Xpcx*~%L ;rDZu hbUiGr΂̡7Q XLհJ3܄k?Ů~+#}'*I h^ eWnB~*BǝdH" A|LZ3YMs/qnNȰ3h#d#7[1y0QRO5u9.&~4#ןn4qJ ,sR䑝!4/ISfEȈr|-p B/Y} |)7;ybk;tvx(#iOo&-*uxwY)XFN՞vn,$NXH 0HtS<$]+TM>¡PD]yTÈ3ե"+?'o&MK}yNP(elr&n3*eU:uྉN{pP9UˆOk}%\L0^^A ǔzɏ%o{  &c6VZli&r1W" 7*==L0U hƭp`)ՀҚW,LRNgτĎ{M'\h>1vt(E=A+ѓ!w%RD fFC=hŔnink\bmDIJz;uC)~8Xqg,p IÂv6RjJThaˑ-xLϺL*9'™~0ԒX¿, rӃ B52{U5fA'rWL=f"d'tw76myhuHYeXAo݀-E b_]Ք;'KGǀ=jPy~L_o'E|s(=gە`!r4Ϻ>GX+TZj,h1sZ"[˨2ű#EāFxXJKyk{e,Ez+Jl$W꧝bCw{?,@໵):WELhCr pf<T[&tW˶K$D'gB -svyj>pb5}?!7΂LXA x 휹SXAݜ rp*8:J`-v6}uC$!z*HпXnHhiDD,h2ScNb. VHdD'Z~OIJ^"Yo}R* (i`gq^oT]mNo=u2+.`FC8xVF=J ?ޱƠ:Ӳ/wP}w/,$. b#≻ (u} vGqv-Pb.)}ϟX"O?q1?PMOTFvX(\36nS^3ub^liLJa'MM} ?{JqְA:f+,F4"r[qW߯aLȜ.] }m6,>s< 94eɟPRI!rKOy87;97cgHgq\z?avj2GzpZGxyxY=!fiQJ]4fgu(ͺ6 >]Sf^n:3ҨL_l^SU\'N,`34WPyDII9:9Rk=bsyLS=hy WC~ ؚYOxy:W.ѽS⿶: B4>R?/q%]>al?.`K%D'~#S#=ag''?Hn5i6Z4뷝MDVly!wTI}pS9.:Y~,7t{d56>Dw)쿑+@F2Ny{ 4F7 Aߌ)2VQ+XGWQbd0ZV$Y![A x7Y2QjHDؘzŗdѵ(SY:-7?#Swm m #Qng`AM bnXQkrei1 WKL|zUPuplaDKF$WG0@S@9|O )%( diʎ+u#-ϙ! v6"pa\Mr'IԖN݂ZX;`)WV2㲮7Ēe {ݘglv|rc{+g:S!?Y Ո]"dMZ e5ڵoMemsapłV2t%[>7\(W(Sj3~M,anAasfb"0ѥR:쒬 lBW,Uwf:s\G{D=C=WEfNd<$]Q 4͉):Tط gre^Qy44_} `]ժz9:C.jGUKBꊫ)* I j6\XZBߴtr-32]VYi7 9\ MdXkl¹< *}_b62Дdզk+Qt2|/Juڷj pMif`n}0,CWh Ge:jb;JS3c&+sIV@Tl4z2рFc5@//U%._c6I-T2S{j |Լ-N}57&[Kk3ڐj$!LH֍{ ֶE#ayXuOwm;쉌3^l"0^#?91t֛d~d-=@AP72 u"qKbO83 31aIB=cZ,፨1L :QLjZp+$0PsjHfWaA||`M1R%K(:3v8 f}q|Ҽ(Rҟ f+vk%} FT9lj #Kpf@:ڔ;|ɥ[ b'KąØ5Hcrp= |Üa F]׍!ρ1G3<`wdm]-ׁh v<,6T5zV9Tri%` uu 1ùl2&vL)" 까:y貆*P-6`Ƒ+_q`$?p=հz[F̣LLgtK4mh(F7Ql_>^؅J)R :Qi~܊ ~w<ƱdM<DwU?Q %` tRE|P4RMϪ&͡gC zt"Y$#D~4>F7+ʦX| H ] *' SͮEb }5>dr=Hd_׊ Z?ujgu.R.^7r6 _=-Uv v 4k{j'෪&ÆQ:_IK2vzZ'WoS*g5'M/# f<kO- A,nyRe&双aR+'b%HhJ M]F>OMgQ^sx C"t7FJTYؾ`GPCD<*-nkۢF}@r\9sc=!{l;̈́Z"r|Kj%rhvf== 4;#Ҧe͔SPFqFN[sS;(3t%tiOHVoZ.wsa8&,,0b`q1ir*fCqn (bwox-PH2+DCWg ;1y8hΉO/mM9RHQ7wǚhLQ@\o|T0T|t0WiN-K,;dc!F*ںCgc `RT  :2͡[z*zD֑ M$ *3N*kUg\ \6̍28^smt Сa;)&-9Pz; m>4ߌm'3C/Pycq}ݳD,+ys]B!OR$>fOli8`U!J7< ulqJG5䩋2+QW[ZFBkKKh˨vgM:Ea߹xmPJd pgk1Lu!bI_v?V6':v<|U@?KEϜe?D*NQ@HV+edR j%- oT5*I5#C$ExFhdESQp:܃shL*C({h@v>|5ckӬzf9\rFFNC-hwRweå<|8<Twr^l3a؝mBP+GJύkVTDEŎ9A+)Q,ޟL Ukg5vU8xVb4&𧺟 c\ _֜#'XsWT~=pK喻 HxgDMя >L'CI@57MK[D OKH<԰zÒ"O0[_ީ@RC#n4~ai"5-##3CL]u B1?A? u"`N'T$q$_>~$V)8x زҮ]Uh] 5l1=\6|4}47x?Cr5~%3 ٚY;΀DyўHyhܦyE<'(= )U@Ax*I:f7!îZ}}UB}H\ {BVŨ:7cܥ-kac0g ##C׺o+GHRd1U iJQ|guq?(YQ-"(d*tԋ&GS}\$z_7%׭i2.UHkJ7F30h:ң lV JzM͸~>>HYٔ/7ɜC8XFq\RHP-ײh |)ˢ8L%S =Aڀq>\$BFˡs;pxvE^SL|-?ޤ_]3\ig"S#U 눢1_E>!?\\Q0ĥZI KJ&dL. lPL;0Rg&2'b(yxS"EW%gִ =z`E*L 㾁;fY4v< %g8&HQGpf*LN,&͢\ szbl4-k1٥*6Y’1T ʔ/\AYSQ cRن5mh qA(ڎ<[]4J[ǘ`JY!%pDp+cυ}h&F8v{j`NRRemjO'ِL p!im ,yLL\q=*@ K'#$MșPF(tdZ2 Jt@ptl秄g5?x=HFKUVX?+\9hV'nzDL{₡jRG^n+.(ZҢ&N5Xx ĕɮi- *h @Mz}*0,*tu84kˁ`U0Lci$nsA%Q۪[yKd pFFp4#wM7_b=d اndGT {sp>7600M C#8ţw,0Iu3xOŖɐ@`_ pUIRm؟3ycR'0s +:S-q2=8P{Z+D>ҋ3~ze)rQĤ],։J_eh +OYqfF8J|󘪮⋄GXsMpOAuAOy@C M6ϗ@ܰ+_eبq.> w`O_pY/uFj {?ciҀCZT_kǂpۜ~?2sH" *؅C2v5ChfHt,CPb= ҢCuK6?}RTbNxJ>9D!1і`mGg6$; go;ua5c@j„YkIXم٢_&{XL< ,LKl/zM@ 9'|>=mL{ec$Əykd< P2â\8 VK: d&Z>;~jñ#v\Ct齏sQ[+ֵ? 2lrДШ3DFhctV`_X>z#w`筳c ͉=WH,5@W用!'ZwϞS'|G@s'?F1 e4̏$= ^5$/&7''u 4$]ab~Hȥ# iX> q%$2Jk4y>&! 9sOpGqPXL?Tlow|'[@܌L,2p>\23W@~ ׿i:uTw3MHY<>Pz)NPx?xMٍ^8U?Xy_7U+jDb|s'lC[ʂ?Os-6ĈeqlyM3VEKXD (ˋ$BUzplL+dN8<K;V:M&r1[o~ ` nI~%MKA*it|&ς^~^e6P"ފ1Nm@@F`MZ`)5g>l&dބ> Gc[ikHa.&]+L>;}y?p-y]\=aI_ qᡨ2f8OYr3@J .mtO蒊4'Ce@J!!ƁS5G@~s6#']ǁGucvB)e}l,uY+=cf1|0CZAw]f#TG/zRJ2 f"lh(UVar<b`9] o  cKHS2I4Bw\>ԅD͆ 埲w kBt!녈Ӄ(9k>oyU]rU6r U暉 rhu)H<W Np7z)M+(j /( 1eHL=_|XN\Go&F%VGcc! ߰&8A#{&9$NBw It;5hNh<LOf7%ݻړ<=l%\B0fLYI94EPǟ{h$~8%KZ^Ŗ/ً0\-Y0"h_AA\II3dS+f4;NozweFXܜ:xMMtՉeYG4壴ͣˉ7n#8GHZPa>wRqt*Ȯez4xFDj !ds7R; W_E!漉 s'$p&;~DU+!UiiVg *&+Nu1 K7xOMX+x>#RY!zѬ"99Poh5:*AW@e#nyU\}3f]$ip"M9C{T"捯g&/`Dd;|xt 8o' _1~OH/a{j;#0T16|K:IQh58/8**!/#gcS\ʬX9,8D{ #}j[ڛ@yI4Г5о!򣁗LS(RDWI2Ҁ/G!`xVUdIhtfib.2e1"XH~o1GZ<j{^r hfyGJ0¢1{]YVt0䅂Bd$A{M:F"6A)6ӿ:ъU/q)y9zS%w2{2'Mn<y+1&e|W"n3Qx)ɹslQh㯖ndڍޯ bD< UOr|uwM۳ cmN8r«ORlz@-6JN.zi?q{vYxW/&8]8lpP(M(N!2?vd=9ؕ3R%TkE%p5#bSim}t@Qri,U1{\:v׸s9Ex<+:ܠz gl,敓\xxq ԛg.H#u`j)./5văXVnuN>'+ nr/+}&7$ϧHr}!~$ 16ʸ^}-qx2&{%ʇh! OBv&CZS? /&ŶcdR&˙k]7PzwSKluĴܿy?RT}^maU]&W`x%Q [^@͓ġsQ?"mK@aAtb"[BU#ߏ!T7󾟆:]O R T 7LxBJ(g s-,O;pqVU@9E4sӦ/.34nw.%'v/0!:gWt? aW67.G s%L۠ 4  Eh}fŻ(V-HI u]6}r"nLK 9~zkp1_ڦ̑SGf3c8f anL[x+TDB ]-;pk:el*IU?@ܰ:(]lPbkmNv@SJtR,_Ql7 ^tyDg IMÉ])*үvbi84u߾3yu{g5} tF~Ta gjȳ3`bV|+ =OGigoV~֫e{Isa]ZH= g!8:f0wf챃0rXt,㤵['8j#m.mlSbT4RFlٝ KP Ɯ9.8 0ɴVSATiW=-p*Dyz“j,QJ6)^%ϋg8bN| ge WF=| m=;"Mo&Ir'kyK+IqjU7J%'䡳vu$gn4~>؁dBapvR҄?qR#@Wgp}1I(`Ja'xIFtc> &Rtqr ~gNǪ~ΛO+wD&c_L K2JpL >8+,) >Tۤ"ڰsB8al>g<@߉ㄈ2~2 EFQ+04NI] ݒ{W1ѡ g~Ŭmbv.C^|;(/k55V MQ=@AghK7.LJ|.V2N!S-s[i܅,d֣u Dj_8jFc=Ԑ7?&qgHf8ee\&8Y3 3[ 7s\@'XRc,e"b9sJl%ʠJЧgqE=¢_ >1*wW\M`'ތfI:f'6~: 1|?<4@yab@eICk:jaj}캝Y|rs1<4@[oK UYDgxZG27ectߟÉ8~!Dqc+:Fxw aAf|^V^"lGMՒm4PfՒ̉3WWfG„a;9EaǞqF$;"ӧfK>S 6~A| & ցT@Dg@+hJ(#>!:|~V]k[qNxK"LPL}54ZHR5Ȯov)>D;u:5>Ne sتJY Ds= WʚóoSG 0C Ms ] C>N$13waf-)-Q]"FvZ)hhzq/bHpQap}D@2~; &=},ǙɴjWsaJRA\X5}E2̇pę!ƑFnWL]Fk 8u;e?H%O> a$/_ C+6)MFYJX}`tXtptI2488=V́pR,wzJn#vCiZRDBYRWQ>VF#i;nC}Zɲ{pt+J=(ΣB+XHsЈ kW*sP{tS_qLJ%/)p|Yɶe9x&+`4OU5ھ]R}-q#95dGBذPVz!&sK%+Cdq穟b\՞p4_8{Y鯕pE{ 0f³ѷ2GG a:S5+YʂDq5:'ܰP6GYFJoH|mxtZ5pB8-??276a0 )|s^H@foq+'yuͨyBQZ-_uwڏ~hXvm|{}E9"UI,FQFr> Ж+.{6劥bTd%ޤėkU1alL wð MdKʍ98 z$|ƚ'5/D7&G18Jܒ,Ԛ gĭAΤ]|ӳSl+!r/ɷH;+ jkX<1Z3PMmNȜƙe/ جbI{p bTpwE4Ccډ/+l$ кHoyrO䊜vjBQIk3Mzj%Ay`K7!c"m7 CXq۴,;&ܓ).l7x h!qDIøtY!gթ$|_#N6Q5t_':VmVn,G`%ǩ19KMҀ}hIתּq *~*tÓ0HNƷoXu㚂.I6IH~>Eo@qY {PA%l"j{ͮrFˑ (8h :GɲU(>I*^db}]sgbTfIO' ص DU{{M Z6VhRI &ea~أY;:l)ÿxiq2YZ1yG3@2y+oP|U\M9$û!&h'#{wR36XB}zqchu$=Y )M9Z&\Bv'Lmdž ЇDNKv  B@Sܻ?M113%#c B*/6]㱭 _ _.(Ym.)jxL K#~d`}Ϻ+p_޳(hv,fu3 1%D@k!v}×dzˡ.U09g,Qhu@6~'t?J -+⋑~EVk DpI\T T+*B*^\DX5eua D+>t؊ߢsq|9kf@+ʨFѐȠDfjƣv>FjļmH47,*ʁx> =r!;퐼4jb9y,ύcSpZJbF /@g r ,B}?n[jKY{\$rJrޕ{yƔ1%}C ccS穈 )7Ca.?u31" a%%2Wq[nLd<ЕD|-GrJ`1?][rDƖ1eS-ie@.{doLB7$2z "M)`3sA0.#t0(⺩;FY.d.Jʬpt@r:Uw 뽄t^sqy烧qxCQJ}k J$3F.ލKw=%I-DOǒꊬ5 M p+wѲ~ χ2YĔ'#xLsV@PewVrCu4&?6 Q*k&Ԯ̟[KOI赽nn=oo p)ݒ-_ )2'8 D1)N@rW>s)죺#fa ?eXnmiskژK9Y2N-sQESP3}4ЕINkr[Ԇ㆗WB<7xiݠ4Yt}]Fq+\')E%0rگ{!fU, ]wz㽶-)[qʿ p/"kl;柽 a̙[) dgKEOj +=5oW#4[]'xT(ZjmsNuF;AzDw2(9qرj$VPۻy`Y^Vd|%bŴ.CRk{^De@ꅩAFBi@U=IEtG$[!҈xY'#:M gڃ߿ G"#%Xe VT=j T[A) X[59t b`)m &]0_w ́=,鍒җrM,Ds8_?pFqиD9aޞכ,fG.7ҙ?B':3??X='|(-t;:%Ft-3WAj8gpʮL(,;bw9X'"QBu8JV@ ?[ G^9{ -pmRSkA a4K [Ehm ]>CքzbF?X$v{,ͩo6sdRm x1@&FT䧏c,"m~ʽ(i gaw6\ #P1$OhG9+i4ܑu gc`M07RO izz= A8q)rE}qKFgoGۖh{.5p'M *!66~ pW@m'<&z"blێ?՝hu{L&@*d )܆+`Q]g:L {|3f8Yk&%x ԲvXhY8RWP:-!pVs>2w*w[f6tyEPWYP̙OR8۰0AzZ)Isj'Ce.ʼnZ = SCcC- 4vo^ 4YBDB^JjQKT ͛ޒ$֗3flN]TE-QӺ|?oyMsLs 6{h«*%99`-TXvGL$ԑ|K } u+Clr !b2J={v! xn|4A@ʭ@>sbt7>sC Yv"yb/J{ɋ.>8)o-Uj ֜,o3٭%oJgL`]Z釷{\@gw ;'U޷V{*ywv^g!{ .׌/Gi?%Rsل^o RP-HdB)&,y3 Wx] }5ʄ }>ί(T4k ( ^]R`mHv /QLo1,0)>޾*7vz9+@@YrjbjFLf5)tc!:Yc]kS~ 96NxJ=c#QcXzys ol_&H{"x]D Qa@va;.\O)N繁SOxEcCqřbrٌt89f-X ޒKԜAtkaE޷7=Xy4Wܿ!NJkŚ?nJ(F05;JZ"JṼ3)q!g=!|=~$kڛ-71ٷBwۆK#'2 h8 32\ qCl^@W4΋@ҙ~OWO5VUavYyo@_"(#yG-{V?<.C|Ulwg>Ͻ 9Ǹ{9I*Q{1Χ7I_:I*)@2 ¬2s+^W7!; {QARcЮT#8gޞ')0 vP!z\37u'ChxzL#_^ԍTHa O<1NPa$+B)izӮ~Kjanj51L<\zqHh}*R\wYWn@a^Τ jĺ$6Myv]q)dPB&Ym]K|T Cv-@7r.q.ԹR')CV3qfKQm'uϗͅn4ƛun*0CfxOZѳ|UԿmC:5%l ^Qg@ m#"+8 {?g6| :zhc`]8E1}D``+l8K~ݤ,H xR_*sV2ę5Z݉)C@V}OΏ_zõ@c${N7A ]c^j;l&'?܅^ JK<-4HFf!7sn 1%>ͤD+W̫;xl}|Iѫ]%{q+ JF""XIxmjбʂ*TO ^HL&[{QMQpu6pS~^onЭ!u ۣ}o]n '@nNuk&ynz|Z(4BiažV+CX S (A*^ R>1 "`yt^^)hD!<"G'V6ZsD>=3F B7^[>_ 2 d7O2 ޠIGa}K@! !g@TI?cQE*D:hNZ.8KgiD^2d<<}k"j76/RaA*<9&G gdV\Z(Mf 3X>sz"e͝tԃjX`?l&k*'O R:%ĩkd1m6Mj;x?auvᩱ|Ytx<Ē 4^ xٱeH]5-3Aw&,:fl{ˊAn,>^u-}ۑhZm pxTP\PH5*8 Yy =Uۯ/ퟧpdvy7H=@Ti_ 1ϯ/V2/M*9gNͺ6ʐ(d_s=yʧ~z3&3^ a-*"50Y}[ip|+9[yvS'Ô,0^`r\q'E SO^C:E&rSٴnL>7;g#|-78+1&$tc, ҊfNFXNGڂF9#W$I\.zܴ5+G:4yg yb=m'G* 4;eA[^>'OQ^c '~5P.6vTck3[Pk,* +] 5[XRˆ@;2ٍ#ql\=)Ѵz>W(d$rQ(@椹0\]&|iedfy3S]MEM@1=dٹa$?TU| = Fy;hh@|0NTVkY# VcndۤKR;E(99Z"4}-nWsdn{?|jvyp}w0Z8P6}K 㡕!y(}Y҇t ͸Ќ橖qA'ÃM$=Cƨ)q63_k) %O6j]~M1ygɚF/"z ktXhqBFv0!xӷ3Z_ВNhY[xz= e! e&wx_f C5md.։Iۅ#a mqK=D5D^Q)WGZgzV{ޅ_)UC C䨍UgĭMvr f#,rSq3Vnq(MԑN5~1fz4=mcw1*s~ZC#tGp~$⪷4DCGEeh-edNHCKHeyU"l-ӭUς? 7HM-+% Y ]H6t[i$GLCܱ2y 4#UQ]D8/>eKP)/1ٻBJ,YETTId쾫,rӛ&8.WxUk퉹[T_Ñ W}R"waG6HX4˭Xe}ŝ08bPm'( l.L.`^^woxerY@:6Vt qbGagdK2$XO1r I9SEo.sh_msG) l@ʗ 9,=7- M\t07D Ӟf~vA.Mƫ_"EdE&Ga!:ԣ,!y4$trx;H;KM Q NRr#9= FÛi읎{ ک5[x<Xc6;qZXtZ׭%G`Oܿ[/MMs[tAo5 c[Pd)*-5=}4Q]pCn/e6i!Z[5_qJcTQU hG%j>4ߋ>_:^Ø a1X'3 v>wU,yPΤP{1@J^sʿ+4SJõ M1`=lUHܳXҝ̅5, ѐ\&zъQjM<}䦑R̬Q-*KG.iBB^]s`r|xS^OBxcg"܍qi^2d^57(xv,"MAaS3z Tu7d*׋"[Aw&dČPdab4٭@jJG}J%G~W$ ᳂ vs`Ą3 $+M' Uw h`ffOXq[4;fڞdva  4:XWro=`ɞ9MJ iaҤ+ -ch:Oan"IJ3[>SaJr,zeIUeݛ &eu7tů>>MDihdžDSU,7~ ~;e׽mmuSO#`P-_ gİ͎x7fGYZ/nW?Gp{1;\9 qFmS|c+nxD[vjKQ:'U֑+:d49EXs͖ih2uRi*w{VU Io$pʰ{hUe|tn/R=$oڑ[:5j!o"\aNy9?:yC#X60NÄtHy!L@G1|D Z~qQf b(6VMr+ةjޞ]B%Ezͭz Ť8KP_.eOt9SaE"Y,zzdu@V"[rWXKĖ^9%+\{S9ŋtmK8*VD5g4׉{a6H*8vplb]LW6Q 88'rkּ.,[ 7#hL'Cgr'|PG)*ԆPO=Z|? \`}IYt7ϔj?pê6,y2l. qs^Mz@#آOMқYTQu:Wz_>dU9قD/QPB0As?dx%,"yhHP٨4mMSE6c_b Ñ*h k{9Z7rVVk9^w B8R|@Mv<Ba:s898f}4,p# r4ea9pWHggtv , YyVl:u3RmR86Y܈(jϠ>)EF.Mi?lxW _ -ǔ߯~ɳ|%`,N%ׄH-K'Fvdd ɔ3Yi?VL =^|ۨ䐮 H`gINj5E/~ 7v?mUk0)1JÀj\jwֱa#QPIsX& Tφăo  0U@(Io8_E\O7x%#Z_7zwhȟ@lYcYmkA gT%J"Ov.nJ.6*D墀|ul Zp$:O4 E&/@./WT-Q읫Kar UrʵlVJJgRIS9vWk0vbzR,;- ynݾBܖ2I=a51hR\nd2{hZ~lC;ԏ.K.dJG&_Ӥ+VPgmk.tlIEru͔LCpx.8tӐ%^oԓQ`3GX\a_ә~C]W״"Cw]Â00åfᶏ>X2aIRʜ@`JfI "ET=B)t!~@NPd2.BR$O<;3c3v+W>e@_G GsNvH;jN6~WNDR qy/v1R0؆)raLNcmS.uzSd$etE嵒s]7ɿtMe 2|nypCC R)ԱS[&s'b4د`^87|A`tvj|v_w5OU=v!3ô0torF&c2'P,¸ӪŎf`ElJjQHL f;U@5v6*=3 ;Z21K [(U`|B럓A >9ՠH;{KzxebI4sn{j;o`2~4 U'i ˓T][۶Y{oYD"fݖ`žwg5ŁW{^̰-QCfªCvR9w-lCA*Dyƍl6-0YΖs'pg K[~ʮbr $H{qGW]9^k mb,XXvKvwnxܘ:KO8\2H57M@'q7NAzrL@Xϕ^6M=9~=V- t|ҭ$Qzh03 O]Q~K3Yѧ˿jkW&=Ɛ/UxG, Uq3O֡2ʺ^6ɲ\>i!i=Pm`8b{1Y9M?>R3dW5kd\9|42PLl?uB/X5pC,LIҢS$ãUD*<DWq%DGi,7Ѝ!֭m~Ɣgb02x<@Y/˿ފ.Jd=.̲q9^vBbv;ĕ+/6" bٰ-J 8MVKJ &8ua0}ot*8jm Ȟ.=אfJ~/y~AOs\ϖ+ Oe(͚؊jd^糃a8k_!n&ȘMChu|T.g98DmtYh7z9q r,'^1x4ډ'3\llcf~B9V~|fBp'JUC,ù+2l= "4 \GHia8vi>t, [pi;$=T[崙Ѯdž̨NRd&jIw-ĦDVT.Ӭ=}|1_iCqWͲQ=CYr$n||N1s{^fG4WurР- aB`լ\H"@i+ pI!,^I{io)2FI^|Ԅ3bffزXVfv(Yuâ.OU Z5%+GϮ'&ObfhsG{I96<|`lGחy0Ԩ5`kzƟZqGE5uk 5$ZyS.#ӕ |CetW C UҢ/qΨ{HWɞpsXRn p/M0 {3k=S['&}e4b( s꣫ڿ^+Ν8/xr]EŊ>M8?팎~\Р8:pPF-V0Q-axX>cᖥ+RӆU:SJcF)-2M F*2`v ]Vhjdz95lbV?/Y?A( н x8d۩\Y #߁[sP~j{bԉi y 0$#4tX3T'uk<&1)\ФtXkke@MgoDD,HjDj2q]q<.:fHÜ۱ug X 0&Ůo ՒNrupR1wY0h?QOӞxz2Gi^f'[*GsDϦϵںg*sZTilܸX5&JwtZWnuQE(Z~q] .,j`;V_osMɍCTjϽ-c&y\vBy>%={}є ^EJv`)IukeZUй)xH1p1pJkRحuw*jEe|% Qfk.aOgPso)Ԯ5gEEX΀[vFFy~h9pXY>\:@\kMk=r{߻l5s/<&1d4y!1N Tml3/R,pV#1l X@Q:?}ͽ/,X8/}v\|35Z, f^ڨL7H}F{^9KՎ vMUR]Q,g.C0%X^~Fѷ azwBb'B?іݛzFYyGT}t"uS,C\D1GiEG\}WZhW&g:m+{Xנ+g`*fdFVtv$3?b <0Aτ] Dcg_ 6? Ew%1fG,$su>8%"d%m0b7BUU5T+7^K"4 VDSA.>6Oά"^Bʅ E _¹f13MN*}aG С<\וU6fHjJ q#Wd ;LfVwxSX8rO׆ ]I8O')8kQ^ Mc-d~jDCFkM(ٕN.O0OUG~Ѳݳύ PBgiZQ(n!RHkWeUȀZtL ((byȩ6ύAN諾"i_[ZӄX^靸!;HIdIt7lK1cyAg*W;"W87W !&_[l_AQۀ>Q3*AeL G /IۢCߘkQHieG +0C[#t)b_id=6Wr`ݝc3S,B.hʘNZc[+[{Aw'S#? HAUtXClJ<@惋zʪPxrWuq ;eLVqH&kgIp6ګg6 IU'h*"  \i}d^z;֞#4L`pU59wz|{fLeAul1^4#I< JK i룅ji7m?QL6-؅=Su0 ŀw +:D7%Ds778$蓌}""_qq(}w 18w6Sl S0^I.Iu`'A\4@澡6ϐс}U3gg=yT[U'5\!0Y^{3 ܎8 uRCX)d` +>:\tɘ% ~GlHC"=b ` 񞥫1U s@t+QƤH-z)i_Gƿ2O{amsK(ЌgS5\}uع2QA4)ޒWhP*=zI82a8'}:5,/"%7T4M $ m p;B%D\' @zP^SDY5СFz a٠veBdj$_ ؎s;Hn h_bB,1lb62LD}p4&7MElW$?&aZ* 26kI,:wL[8>7%Mnߥ:'Z5|(4N5ca 6aAt|v!D|wCbsS4Jr Skh@ baЪ `n3 4&BbZ׌ %Sdb8C7h[amҴ4F34fAӨ Is֭^y3O '{+c(viyFFb>q<jTkǩ:h۷ 3jRBRQ,`9k)8W΋l1:nd DVZ٠% )"1N1SP&f N?Nܤ8A|,I  ʥVtBgW#M3Hאkw!ʼZPH8hG]Ѣ1}eC>;器iz)ni~=44݃rm 8C=^!ӄdxNU!-S3. R1o-^t(j,ohԎ/_\C~AyO@ иtw'qwsՔ_`1Gd {iE`YeGu<;̱-~]}b%e1&i.Ql3ȔvL婶ie4~Q(6,'¾N SbN18(v9ǹWF 9lHsA-!^xk@k~N;!d MYY_Q%2H~6(Ų/!ԛg2/o9ml+nVM-lM('.7Pأ(IN&x$A6+f@ˆÔZzaAltЮ0N.tx0\[(#v&*G9fVV04JәFXCUuD+< 5A/R<1vsÅWDAj,oj'XZP#uC$JLpuZLj"'ٹ|A0̿2ۺ SC L7 RBVw=ۻU ] V*;}$J A8d H.jou'7%[D贞pr~!%_'6,^^y`-`,|Tna$j6ީ=MYam0GE|#ܻ ;szLc1@ I4M# ۢ!!Fk͑[Jmm M|y}Wö-DJ@ᮆXbd6Q>M%-43ṣY?_܍ zfC޵_U:8d{x Y7GmL\7+$NCZYA'mi|0s S_]DaBMډma4Cg<2W!5S  ʴscRD_+!Sw2@k6L/_@QD&MLM Xu GfAYFh#΢qPlp;ĘXgQ|G@/On\JOZH9_7WJܛS։9S4|pgj\YAq#ˏ! Ã*C"f\Q.=dQӨ}XXG[$a2yLQWQ;Ͻ&%jA}DsբuUt lOK&!M1>#(^j6cFun4x\c+֕a ;֐nx__YDQ ^-ot!8hK`IZpgDڌYX^=>x (_ ςـ?R#d%AmČdG/4fZQ|vB"nq y V̘ފ/WYy+Ws0H|{rb<#Sd-q[ee4l3\iip"PG`Z/J+L $#ݢN51+S5> CF yĮ-f%Ϝxf'k}\lCH)lҕ7%R{! nuIDthCH{B+euw!:<bɗ P)zS(Cz6~6D'2S:Nyv/ϗmY52b"2Z{Շ^Tdۨ溟|hؕR~Nj4W^uE<6%UnEg Ms\\Fz""`^sw⑬/dOBC4J8Vp"gft>4(|_w*Y8rfC4xA ݴg~}MMnr#e5ю>Qj;D v=ُK1I* H|ϱ# Vy?W9b*$"b1З6jKs{XR̍h"p\&R30~ng?OE))6):YMOp[qaYI$j‘V?c PZz%VA [l%򠎔E@YPGt͡A>O*l~<+P!9'p3G~$@]C3u{bV^BCAxVĜ[I2%چ\(J!m|W=$uJ֩.ynN|`j $%˳?K`[|7A]skN;D>5WI1Zr]NTE М!L,tme,MLu#6JlO%)b'j ` /P';n8sa Nʮ˷ģݓÜ>Ěq]Z25 iВk#_,uQ-ti-";>Q,[A+޼¸nbBLn}AC0T@B9O'@H.h96ưfhͯ }Y͊Α6ަ^~HEw!"S@qK%'#86M7.e=rno H{AXPpoxj\R;hPe^ٶGp-1<~^״ -}k5]5|ʄ]lkHTN)7)<8OvmKM=çX37AK m[p\1@+i/EWLcñҪ ‹% ͔kd^Q:8Ud%ĘŴFz}.F.*t:! Ig/ȫHx;6>\2hz]QƼsnPJ\vDDL?g@qN/czaUz75[9# TLd0 Ʒzua [W$+|5)紵qRӡfsC/sAB;lgz/TXq(\&&BkkLS)OIp\[;!Ns:M^X1]66G×Ui#yو_@Ax*0 'i6]. }1HF)Ai k.}=5#jF^iHZἄMLo@ A5N )u^T\ !Y"FGə]" \{"%>̺Ewt̖} go>f-MuY|]m*:pQ%&Fΰ'\(Xm8{jvˤU1і[bip ȵq+Ɔeičs|2 },,N0GzI66vuǗ|ܨ ClhB[M/۵%,~&!Z0>#r IVUHΞGo)EuFtmO,Har5x7/,f)_Pej|_^[W u4.zՁm,ÜFz~F)Gu.룖΃6;IL8Sv'qk/T j'-X˳]`r]}ޅiGi7 y^ b{_k\y*'tf2=NJbj[$pug_pl$^9Dr/0Ii۠:;/۹{̏K7'<^3",ˬ#mg`| }`N+V;.\Z|㲑NIK Zp=Fgx"zw%V̐(mdB=<*[֚ Xw{So`p/ G.'"3Lй8d/\.J WmIۡs"&NaǠ",M0W {Ŝw u8.^[ >T sJ+̡d뚋~$ل Ouw|Fj ۯ*+.D/!9{wc1>K Poq~&*`)'A z (CvB5 'A3IǺ. s}`_Go'!'fTBInþ&C ^`R'֠Y\w[Kq˚jܖyI[j#&,Ԛ !DFቺiZh'72Ҕ<#;tIʀ!q˘4pspA5qD=D qE?Ł͸*…F#"{GnM:iJ<)k[ IgmfpVR;Ϛ0/iå>0D~"= u cD'3u*Iia`?PWo WSHG#|]qɔkS[/ݠ,6鏆M,R6@Z+3\ĉZ yWLd@^\L'hr _u˽8at`5TylFms|dkP ZZ"$&uu&D^{;e),A",^!ۯ:[v|5d_g&=(Uj@KDzw^5ʘ &R.̚a]ثuWEMWXG"&"0`AQb+k~cKY.u0:.=T}|GJs~1s[\/Ք3 @L8`yY*1z$IDV9bW&勼)堏JFM ۂPCRst"`ecd}/4}RqWJ1I@v%ugMޝ'0P\m񂹙6Y<5&^9\JyY"%a!+\Opr"Ϊ]sazr&',8x i[Qv1u`= -(n@ՠ.升_#n '&•R@a#shB܌8V_8߇o8eY`9y8~R [Y.XQ5pTMe(y-_K%JFjöDQg֞l۲u)vCq{Mjqwۍ8/-py<ɐ'ͫ<*կV_L]lH74 ]MluֆK9KdkmmoS"ڱ݋6}QꁫIv[}E"}tWIBjm]^+[,}I/lNWglG_m}fZ[h̒K+y{WzMj"l E$9MY˥tUr\"]){Q]٭V.(_dEyϥmbp yW$~Wh6{nG~n}V"/Q-5/mrI )>C*-/mk=KuS$Tf-b6Ӣ66WnO?(cMz,*sH]TV:hۖǶw%[]"BG|mHҽ"y󯨽H]hKzo:٤*f.ف$dEllV^MvlEF44}NӱھH74*ok[Z}jlSNy4s[+Ey}-j:j7.ٻ^6m+NȥGniu.El6gcciS/6ehmMlֶ|mAjwvm/X{kQ;jً]juG{^%^6:`cEusi"PצltMkPt)fWi4QK<ظk}+/W; \6_іVl̶~bc><]UQI/mt9֟V?EmZEz"OQ<>mȦVg6u!i}jnkG[}.2ٴIeW/갈v?[njjEuىNke)[*?ΊtNS6һؖKy&E2M;K:iCGk:)͆t\+$m;ڇɧI6y]׶m"w6e[y[&1Q+(zj[GEugSFŎBdNκև MNlmN]H'$RۖH\mw诫.J]ٕ&KMMw/Ս2--kku+-_d!6rj陔޶n:-޶^\mWk2O'ـ.EvT6-mjmEuPD[_{.j;Hʩ٪}ꮤ'Ecζ|}ԿT'e,ѱկzlH|jhzS{ڝå-lA[6d]lfZ+gnIMڪZȪّ+Z9tC"]̵mduǢx.2%t "3;T-T&}SzW/M껨mloޚjOF+qm%XDV4MՐ? lmGп";e[/Evٟo辔FluۖަbuhKv\T]sz/ylmKK=<6٥&>K4S2Jn؝MѲ 5H&mLk2]T>i%VQYlF/\lmeIZkuUTEmVZ[JmSQ2i`.%DQ[锦gEi.JkSW^kYך.Jm٦nAֶn}G6:-+HN:î~B㥵M{ٴqnl۴VEelޤvѦ޶NB&Y՟Mld 4\F56Ӿ1^¶ewrK.aM<_-Mlܧ^U"ymuN Etzd_uS[6e)_yER;DQۦt5Y6d+}V'>m`#K]i.+w{N?uӷ 7~5oy~y3|xlA#Oy37Vk˵ZG1QP=w(hYP$ 3=zy߹:-/؉ޞe3=[#j8hoϼr)amE^\=ygklHlh$|U>vZ7^~.oY=[G"okE+TO^g浙\;޹mcMwc|#'m6gov1>bM_}qg۝a6Rf˞+y:ʗ!%ԿtE:7ع/6浩r1E6&لTgEmG#_qlsEjK#KLiaI ťRl#E1IEY^I>E/8+OFɏswZ,c^]!R;6E{Ӧb:+{Q]KsYlcE:7D{*'OWh񌤯E6R$,'<jsʋ_ڞQ9|+D+hDjٖ{| ,{/pMҩ"ayzyßՃTE$}.uWS n}ƗJiy_8'HG+S^\h;oZh~[̶,1l^MJ<`iS;<؃lO$Z;Heӻ?JR1L88O~FKzu\$Ms{h1狴;uS4xڒyx2h;LiT_r]>+o| y2K,yyuZ4ŔE${M^<$GCWUTwEYje5wIRKv+}|/佗gIFMsy~.vV^<'HWyEWwx,CQ?,RlsykRVz-;ZZI8Hj3۴R?s[،{i>GX>9?zEؔQ<]L6-UyͣEuw&1#k~wEe)z|6֔\|و6E]ƇJ^]6m7E}$ \T;++ȓf#.˟j:smr@Gjw)Kg[|R\Gl&o]Pҿ"YOسU/չ_x̟w7nE}fy~(WoE}[5//ΤK7{s? Fߦ/>˧;ϨU{Pl;Wr?.VNZyJWʛg;C!TfIVE^l>C-.C۹>g;X^96m<̋Kl#,V^[6/ҧ0^^nl+|gvQ=Z/o<]9fZ|E$)O%m+ٔ%~IZRvv(%EQ?\5*'Az{^FQ}(> + $)/o?OOFkɦ~[@ѸHGjKvˣ]fE$l~X-T'x_t.H6s)+-ooև}Ie*䷩Ow]>^ldڙw>Wwy>+n1a^Fˊ| Glc^{p[ڭ5Z;[~hFQ9$[Βɓ׏dR[-yHh\'Etm2vB<ˣAx9IżEҟT6cs,E ;P'nSR,mH<]+5OyX޻(ԏتTEs)IVT兮SjgZ?W4YE>iJP^hvW^EڷH:-sVxd94tξw>ۼ_&oOFG۫+˫< lȶ[u^Ciye۳=nKyNdGRHW~iyC?ɓAkemmEvvֻ&yDQ" cGhLy,*BI.7/NɓYNS^6^ΝqrAM f;MM4[/ҵ۝?s_Y't-֒.7E;"=l /o^Gv^]I82_<|d{Es;տ4z g[+H1 ׫vQI}_<6c2iV|Θ?Oϸ.۔Ӷ>a*I_MslQjc.$_) yi=?ˋwɖ[߼Z~.h6W6PV]f{sEms\n7Tm?G?G?GQ=g7aGgnᅢ}Z飒+R_{b&1`o,|o3t/!n<ϥZAr{fS,҃LÙ\ȷ{|!=obsVO/|]~e|8%/'ܼ|L3:(7y\awq~0&Ǒ~Ğ{.?ӟLO1ǑzB#3S!,[ 3#tRxutN8=^o]2p=B#3nOSrMX}wG\?e߁c sk:Sr9CfHP^y=p򿏴\?g!tHF{=K1=~.ϔh#3#vq4Gt- /y!AgەGrBܓ=sϩbE!3pzrc^!ד׿鷧{AM?usvsDnva^=J8<<9 W\FOgW7 exy?e%H#[ k|y>#۟I΁<g)d3b|1>OƟS{k{<=UyM/kzz~ya>I;13~ܮq%ؗۇg=o'nG-i·\^Ǔ=~Y~A?n rr0~R!ϙx/=3 5C ,ȳ`af^A=61 _gr9`>~r{'͗3qؼHX:>ρY?Y>i/cGA1?0w:^#Wu6g2><͈=EN1q<@=M3yS >G\nn/-u&?wȉwzoƟ8yďs3g:_^/g1ÒC=)R\ yq G8>r!~)ӛfw?92,|FC3>bG7sGg>O~W|99Mq68~y=ž32x|z:p8>%8_g.#`#Zq*_7xd9t]Cg&c\Fw3-|<ag=~FOfzɍ|| itGpI?q-chD/yx/C-0WS9렌Mځ^yx;"O[eLȾKZ =#>ΖA/rA#tR@)}z{8__gf0g\|3ڇKA9cG~1?}\RxmIGxSǿSÅxuחc~=;>3:|] -_:g+Jq Ƴh7w;}q.훑ڑW^=Z럥uViP?8Hi^cTqzno<<>^X~o_sxv8Ka^rݸyGZ{ xȞ%f{qoZoSu2͏糗!wI\xd Ɓ:Д y/W۴yDS/??t3qzFΑyw~ǛK?X:o~zw;3< 㒌V^~^Rq*orf~4O7sZ/q4.00/y9}קYzro~/?Űgd痥G=p~܎y=hp33s=Ӽ_CO8?>|gBrGi Υ<.p%Kb!F3? ?9H9.O2=yb!i)8tё)y=s}di)ob|}Hbߑ+)K$?=Hѕ_!\Szw>i?rs=}XF)=C~~tq01%`ry#X>.W[=[OǹS<bAwǻ|crfKg~z9R)vqk=}aGRWay#t4~eG$-yC>^x{ qy>QߵqK?0X: z||lߵ+HFK(cA!׃4/r !afŞ|icD߸3<д4xF~]?S;ځSnb|0ҿy[ sbWj~N/GTx y}zsE=hؾ_Dƅ4SN1O8tdzJ~Cק>OCҽRpIR<;Txe59k_q g% y8VFKvޞ_1H' h /ws3#+|/l1$WR?)&4_(Yyp>36x.62_#/Xz>ANΗ_Z<ܟ#^ֹ f߅~&Ls~O ׏8f~|j$/g^6㖃?άw5/8?vmd]s8{/m|~y糐7/7WUqqm8=n߬~A}O ,.b߹@`xύgc?N3>dT?=0f%9OiĸɯJq:?'ܞy<7s_N@>i]8_KamX-O`?q9=|i{b߹\B9Gk{#_8' .|ǻR?̟ݔC9i,Fͼy#Ybݖ]Kv>C.>eH#qTNk}g3v==O ڛif߹8- ui;;/A\vbߵOks&Kgn7?-?>Ɵs\qsHGnW/~}ױ1~샏y\bty<绘8Cz 7x{N1>Z_X\N1,š_=/3yھz\_y?̿sRIzٸu^I+FH0m0q%|>O=K?{f!=G!^8ֻ|_i{S{q>__yJx ;ܿw}#.a/|G=RN>/_/h<|؟I7f,_ɫC'czp87OH#|<-UgEz27y>?a&fZ dەпkj} sb |V.t|#?NO/%p~L?F4i| kWE.p/}>Xd!gA.Q}st<~b_rs[0Lx Sy?A&hS<үIøJ:?? |ş|,QR9G>1ߥqN\73@ 2>lH=q8lĎyޛ ߧY~<֧l|?I..T?Ji<] =w |{z%Fʧ[cq;O)_ zc|Ǹpladޏ~ea^oD/|>D:w>Mg%ŋiOvn'_3m,ҹv ϧ@˖H컴/E?rJM<sxg[R:=[x `RۗÈL.;a!_T~2-!GVg3>Ҽ{?ϋ;i_0<=i[gg9mx?C<WΣ-t<|67)fד7i&3?:KJ>`߈z*Ւ8#ܿy=s"t.d緡ftPw(~׃f~rIV?.?grd^cџ2xzswuCv +Gܞ|_Z;W裰O02~~<[]dzr~~sG}޼=k^Ӭ\=S,S?mqރ#N'~B[yY)FƉ/œwv#K1MO횏/61:ܮ!{+p$0ߪK{_al$9'02k y=_0~#bGi\zߋ~-AϠW4)~e#ݔ /;$Xfr|Dzaďrs#&}%|<2U,Ⱥ6 '{Qo~W#xFsq({nw&_f7cY>_7Y9x<=3,͋M ssnl~%[8^Z s}Ezx fry֌>_74肟tϛrHO|+y81η0ctNh=s=`78c@v?Fi aҾN/FD9&Yet7 r%=iO\oCH㧬{6  #7cArQ${[X>q{Fy$?#=MV>pz{G-7ip}9G~VƬrM')Nc<~dR|7b\x#^u4k#\,ߖǀLx?b܎w=IN/OqKx!܃' (e<@|#O&0*g47B{qҼ~xESxNp.WKq(m]Jҹi|93aAqZO\ٴoOK{/{ig)v8'=o~Gڅ>Wy='w1̃s|w}s\~N)WR<}YA?8>y>+nL^1Κft4$|^$;Ǎ|~fR;~&Ǒ,=x"񪴿{v9~";>=_qz¸!@OO֓S|5r{bW+cq?u SK!3giv Xzi^' aj}cj}ƍ<)}#ӌLGG).YH7m_? 'gΏۏ4KO3~$GO/ͳ,H&Y|V>yI=?(GhOlO;jދ# Kn&ف8N8Xy\[+j-|iy:~aؾx^,sd?Ϝ>קX|+Ğ{~ۑKgn׼?29[>2Ͱ4c3_O}]<>R>61ү>"q|>b~ b"Ά4_ա>&wV_#\Neۈ\let0} =¼xz<">o>7-FSbُ^~19oxz{WQ!rMr"9Ǽݐ)ΫLHqqn'3qu8{vq{~Gcrd7tNCc|Noq"oHq~7o$\Y>n,DžH\,T||IϦسob|9Gq ;=/ vH~<> o->y{4?z-_<4{gnL %O*Kduo?O'O#8%#oyz}>< \/2!ߏ,KOI0;o||X:6x~w{_g]|!MLN)nɁ<#"R80J|>.)~ޞ-$ma?N,_t;B:_iOYM^B>C/FVsٹ~RjW)=3ԳNO'^$Zۯi!π,o P5m=0?k";x>aOu@S+ }uO72OҮ-Yȼv#x~$Ŀ}Dy X~Ob/>]~nܧ),^<82./ד)ǵft 7ϷlbY9FR}k&[ _#UFR|<@8ӓqyBI ux.'ysg7#z2}TLN#9PCa,q>< חtN< mQy>GZ/sVk()C%׸wy뒧.lu+g{Sp,[u$Oluv/qߪǦWhM,9ʢzͿM;]|BJmIQv{7ݮbс^ky\5-٥F?{팃fguG]vc')[K k%Wo[eVM}˥wW5M"WSu]~,zݞcKo\1)tuoX'[ǡD.wQ6XX>Jb'u-= ƥ~lKqŖ雯Jä=0 T%:] nSMDz工_%_娚|ƽ\qh/_^ܡty~@UvU1VOJW>_>|rM\U7 بbNquR^/Rl{[zfUnybbٛmz)@PU#v;ՕĒ׎9]o _6 bPu9%u +ן],Ƶ>'r/ߨ0. ߥvܼua@UJ=}kĢщWcoEjn(l-_9'寊?5>r]wQ\Mb͏6Jr(w9's(KO͏>r%z,ƭ| hj%Ǹmjv/4p/Ϯ;h_z.[7&x'x{tM+_rVUXN,-$WUVVݾM'V=ͧ*yӻW hJ_6߲*O;_tڳm}`7Z8SWcѩZ^׾׍*WlĢW7-M/q;rkϾ³/W^|uirIծ|]ozJ_cSrp<>auS=H7J}&vnǥUё^J|lU?ʭcYrE7BNK)zS[|*WSUݦ`@8__9\Imhls([ʥC'հTM*d+ħz*[>nl\Uӕһڟ+ߺ5.iKao;-olM\v\޸)`RmkqÀ k3a K¯j9 s?trTotBsc@Y ޵0n9l唠zES_ǦֻD/6Q0\J9ڍ|ꧩV^t)n޼̸`@%ږOW]EUW,UY6ot}ʎο|CL ߺ-^nIβo~dcvM[7P5ߺt hZ;kvf[%+MΪSPg7^]lyKO}-F&x<0`\y1;ǿQCLzwƱxWs[~u1q0,? oZy|o[ZM)GYZqU V>QM՛?6J}֍9ۺU0n9Ety˖*%>UƀiϾrhz}ɡzДz ޕ1)CC*9nbub ۦ (CK7E {;}\M/[|'viM4 ~?@˒C?Q%V4ݫrr\o&4ŀ(K^tgW:VݮeJh*Pyw-aKPU0n9ϻzƕ~Y$|oz}7|#6iowƀ嘔ccb@rԍw ["w\'Sr4EIy06n0v>Ā49mjJז_{_z]tb^lleǡ|ʒ/+] .4=Zˢ?.ewM ׉eot){u˱Q1*>|t 򎋜&wkJy94~7:^1`R?~0ѳz1i9"oZ}qF)g98k6rKw5 h*qvl? [w.^UhPEκ1`\6FǀRe+o~VcW_w9nb@S-G,:Mŀq_w9J,ƀ]M߉\€Iaui,9ҳ|뒣iJ,oŀq;n0n:PĪ[|Ve?MvGojy4Ԟ'8.lulUm˯by}C_V;H7 `Z ꖧr͗CtBۏCKuﮎeuY|vUn\$6 B˥w^WbgSn m/$>Wŧi^--=I)UOUrvg>n9B-FoZSY|-ϸaUKr5UΦ+R nŀh:;?NbqgYUUt~OtJ5&NqsB)}Ki_?nOR:_zMŶKlW%Oj|{}5c1,]__6cFP9Co4 (+};֍ui/+l8_/\F,& B,y*I|Q䪺cщU/ZrUݾZPVuU0n9&xƀ娪\q{rIr%oYtǡr׭)rۯ]?um -GۦڦwӕmNp>Tt˒n7 Uڳzߵ\ L&}R@K7ѫz.Ole9aNiWk%ϸڑ&ݖ+kqÀX`KU\l+Ua,~ƥ]CPU}M?<+'-bӋeGZ:)_s(4Mk ^Uk^TͿb{*lz}rqK}ǒ;6|\OlFVf? \ZHb_l{]+򩻜c۵1[/m>_MPy/]O˖חkv|lj=+>P]4ծm\o吠q_U_MvS|b~vu mG R|*>uC\rPMiX9+vۧS>nRu,|%O1) vmJ)[>~rHrҋ]n[ݕ~,}ˡ)*}nioh8=M?utCoeOv\W{%,ɣwmGus*{ДrƖ+T*Ui}Il#oo1lUiJϦӋM_#o}jr/HrJ˖'VWl-W,y49ʲ/l:B ͿPM7ǦvMKG{?[NW㦧UTUphZמcA{wMK߮^ǖ+66neJ5};b[rUU+'˒W~|MX~ĶR:ޖ^ɸa볩Дv[Xʒ3V5CS/uߨzrJ|owecKוl4=rs]/\WzV?O4:u˱QZi|lJ^r嚾nվWbvzۿH!ѱ?MM`@V.eɣwcWY~i_Mi7NǕ>TP9O׷)9}WzKڦ|NW{n[N|u䭊-q[\uv zjJ9Cɩ}/}/[U۩F/{ոxlRz-bPSH|$UlEgW+_WǸ=[hu Op1TO'վ nreoU4$_ݗ/ltZ>)6Ʒi._Jzr1n9b?7!_U]/tc/K^`=[V Q._KS1ChϾck8^\Ģ[~4Opeb+w*/O|ĿPWض&w1i*T||BqhM)CU˧b~%_SL(qgbߗ^Ԟǥ|s}m -MXޖ^lgПSu=/[_r&|O]"]Te˳Ѱ[TeUGtR߶|֎=6EO^?P9|[__lMkG-_lzuc@r4UWt]c-,9|%ϮbOrJn<]]U|c\ɕ%|n*dMzZGM8Puc@r*0ifc@Sߗn;Pwm۷>׿>< Q?Ql [ ^JS<4 ca@rLO=nxOMׁ&77gD_c}uG=-׋J'x'n Nn,u1'x'xX隂M n ݍVO cWŀ`? [aS;=\Mgc`cr0n9&x=-OO+-Ǹ`@r4&k`@rlTyZ>O;Ż>7^i-o [`@rL9%[ osU|'xꖧlN0< [ k?  [I9&xWƀ N vu;z U0M)GUY<tBw0)t& &P -ŀĀPMÀ嘔owE w30Y[\SPwVg[1lLwr3rL҇ n-P5ߍZ=s1`\IC6bW,:MÀ]&zZ/-ǮlҍE/T>-/L$S<>7 ҭ-O'Tz, [ n)nxP'x^9W&?M׫*g;/lNp0nu1<PrUua+/oT [ / s;,*o&vl W<.P<< yn P\<6P:-׋) ޘI?7娺yR_q0n9&x'0.t}i<<~CDZGU%{-kX_uZUѓ隊9T^B[}FPgޗ~Sہ<+_+>TוNl4>p{E*]j9CʭK}shr(+mZKgN,, ZOZ٦˾\9[.-$~3nYIJrp[>b4G$po~4>eV^[>kBW%y49w_v}4>?UMY}jU϶]hϒ|l p勥'eozlˇHC?~+P[|泭kz}.]qCk }OJ[JW~ŲOO׎c񕰭ǒl>D7~W{-O^U$HϡwכFzK]rխRz^ĪOWz*[\󭏪ZP9x:|u}H]|sz#_Z._9HP.wT]UU^/oHJHz˵rhhtҗvҞ}_r'eP{׷=t5{J5}[nItZV=ʧq#嫵|Uc|֏|598Y_g/V;ֿ+P -h$b_MmW>o:g~,K/6ҳm~ICPɩk,= J,Bm$_(Xz!sri}ȕ^|l߈-$>V}h|cҗK*W(]n_RǟtlWm?H}-꿖zvGKJ/ (+}rۡnxrmFVneGOZmWΕ^KZ'oYʗCl bWy\Ŷ[9|eu,cul:e黭\w[%/ԋoP[?tcˡjՓG49$_eQ7eG,~l=-R:R>W|Um吠iJ.t}~j"k~[$}oT-/?ϖұM!^h˯,y˪|}p(8p}V?$4RzRK4ڍ-ߦ_:7EǽM)GqCSK|]il֏jl֓kvʖ~So;۲%#_9noW蹾=kKOm5lYvXZOtC7%:S[:b7W:C]6VrKtw[Z:[yC7pZ履\eUϾbۉ-P~~-l[N-]tcK\--4eZ,4/黯V9_:U3Ԟ5UV;hmi+.=7W~޴}H~KGgK7TeӉ^|a\Ue=|ۦ$'rz[]_ymY'-ǮZGJ Wc' WV{K\kr|˶pU>S(KBz>mWUoMv{6}YKPcIW6_~WMznk\~7%wP҅ک״wW}bԇ|{N.X.՟\wC5{\rߪ.FOn/||\ht]\[5yq8T_b+ێrիP{U#Œ۵\VN)v Gz?n5Vbϱl?$P^ie,\Ko+DG;oUzQX5:|Bg_>e;h'BpCYK_{~VBkw 궣6+} 'W[Ҟ]ˣ工־Ǫ?_UEOh{H|c+|e/<-|wnrpͷ}0XVnuU]~l~bՃ-]=ʥ}/[/|Mn=,.=kn[y*F?6C]\?n=UP~GKCHve+Og(_v T=?P֮tbr'A]]]e[ÿǶgrJ/Ʒ.VXzc+/ݕ]ϮҴv工cΖPVk?(+}rUΜo5Eo|B _k|cstM{mW-/n?;o+*M^MΪ[CWRvzUUn_$(K\ǦAkg)_JZ|v}ZbOo [qkZ;It]it|׍5*_S곝x߮UPOOp}vޕnxp;?orlt [qǀh*-Ǹa@rLxa@rLpPU'Wnx?ׅ'ln9%")L`@rm\M\һҳǡz:hO9~'xߺฝby^r ` BḝYmZ=ot [q`? t_Y|_5wU [ .ƀCjzQ1\}djQCZև}wm Ol𥳐;V<>P*ߤ>SW娫YJϡr4]?S{~OpX@r s0`"Ǯ%O 4a@rLpPn8?қz1n9&x}0>|S0[._wu97<11n9&)Bg= Onyq=`bbFW7lt{ht} 0~@+Ǯu˱b@r)?\vvƖ˕^Y0`R?<CY)_%UƷۃ/ O [Px:|]{_7~m1 V;h&x1uӟ .s[n9bvvvU1n96^/7?U_&x}0n9bv796 -Ǹbn'\ P<<11`\;-GS1 4-_~q;œ͡nj[| ]nS=v}Xt&x'8nxO'Z *Qj\踝Ie#`\iW+@rLĀ߫]ǿ]vÀq_7}W9"O/ny'-ǤnP\PB7ct [ sK?3 0ouB>Q}l++h~ ͕mjCA_ε\HzjΗN\}V|'|>4{WRzWXK_V? "ѓmBY|c-_[%)^w\Ӈӕ|%W\ z?[[d B6Ptw|$>RŊ4~3_(ۮ4;~_I!ߖk\+q+qFϕ-__?'4zϾ׮q׵bwlPMW:կjWBK3U<ela/HqUUqU~2vfO[bCY~7},g]59tW{}*/]?b[rپM?տB4#ŦlJ'}!TXa/WӅrIrv!ͯs/K_ZRl[?W;#[Bۂ꿭CK~V.gWk\꣯'vs'AoHX^Vybc~(Vi|Cgl}jrQB!v׮lyxVMB[,?Ċ'] ZgV}黦[bEhs|ܵ4+~BPIqFOzJ4>X9-To񪫿gC%_|EM.)?ڥ/zCr,/]尥ٱ/=IN?^ض7ߵvb/uXܕ^5zYÚ腂oWu#'sGW`Hm˥ޕfweC-+/}[:rAη-G]ӻڣj+^[t{iD' 4}3*Glھ^rp7)}hb_-o|aҳOG]7ܾğ>ʫC_[v=`ˇہ|t\lWzqD/X'6[Y4k]teqh?j[Zβվ}1^ӰKY z]ۿmm[o?|M}z-9mꧭmXv7}Un )f__J,msk / kz[_e_AG4pmX 8)~\~]jxP/]!taKGJ_A,?pm߲!wqo՟ԟw|cL@M,]J/q&FO/Ah.5{_;sc bͶb?W+N_ߒlJBKB[KW;ӠʖTߕm-/?Zf7nq+`]덷VR{oV>+]5N.;>m|BxMP~V>}h#!+Zd[O*icّǎ cw[;qwBWub OCY<ٲUW:'irW6KBO]qNU494ke_^BxMK+m/v5$SY[o]K/Wz}rXcף/-lw[ܗ,ǥto B{t<}hBGvnm˷x^C \m~_R:-_C|?pX@کroktP? R[bkgk߱[[=OHB\.MnFKt\!45_h WqU5|mc7tyBи5׎]#V$zv-tUՓw[MꇵP?+]}HӮ_K[ovf_#4pXt${>iS+N'=k%r֋Tp*g,Bzrm{k﹖Ӗ&DW+򹶫/hqV<_v#۵>P}'IC |Y~>?㛞YzoK\̖&,`%?[>RXB׎%Z|*Kt %~ҳ{t\3Wb=Wվy^q-_h+JZ5>}}hBh|&Gk֯ߔ޻ڛ/V!!mO7HrIJS_ w[~|]?);.Y|ߧ՚>JK߷I[ytrI!ʆ{_~o(~ggDzǕW?mMlK]+=Wteų_t_i/nC#4|U\5njˊbGR~)- 4^rM*^$Zi>q>Ev|'FזzW|Wl5*WYX*9-}[8UnOGtx|P?ŊbImC^>_Wvˡ)o?ǮW \? ͕-_=ۿM7}vM}6KCW |/N,RvQV??m_[w]7o!_?_IJ#W3Wt~bC؛oﹽ걯?+7_?W[/bգk$$?+Ϸ/=k]|k|\1VeK߷^_x~WZ=/K_Bd<BVYc euXڣ,lS=ԟKtb~Fbi~ї^,O\Ǧ/'lKrhW4z]Uw>C)4տX5N_K|8֋i^umoqWz'cmmOjl-Ċm] z`[߶QAU~;vIt%qr?VyߤzY5=|U]qBh } }w8͗,K |ٗk>"~ԸBk߮,=u[^ŶX/K{-MkIv_Cϟmݵs~Q$v4+ePTv?i>>/tmHOl4cl9lK]kP=v3︶]!>ik{ǒ5+-ke~HJNj r? eo|W?c_WtAg|kA8Un[]zqXq@-P;:?eOt'W}t[Gir[qZ]qjhPK-k|я--)-=1CY`ߋW{T-m~vAZ'7՟5H3Um2ĊbZCT^cwR۾<{׵)/JZѵzcىƒ7dg[\O(-}~*4XF,o^K+퇥||䗤~=T|5^ Տ/ԮxOAkƊKNe/߫N//)vtIO].Nzv~6_h?ڿoz_=]!߶\v C[ 7Uϡqw(Pzea͎T׶\TqZl?\+](/-}U tk 4z\|Ֆm{ ?}h\ne95%OYo>_};)/vV_?һ-]%;,+k^K_cXO|Plb^߲15X[eMYۿ*g>H\(_ O߸'6vanbO{IC2V|G\Ym4tTh?`ηlkH8=eŵeAhiK7Odkjbً&sp/ [zhnF57>t5>eo C_?${mzjOg|P⣽E,pmٶ}csJqteǁwW?!ֿK~PV{B,zg l˶i|w_ۯJgkZ~v 4pWTux8/T\Gqr]PV{ݶo4}-_mgU.C8Կ 5|t4z\w]F5-cׯHrCitR+o?+OӯX ]ˊ+]s[ؖe\X#v#/qb_,KGX b (6HmOo|\fh_|tq+_'~0_rG|Uϕ+=W.U?iƁ~M4ŵ|@h\3|_[?i cYGI\[\77_'cꭤF_*/eS49\W-wg=VXl4ϱWbŽ2hrڱX]UXFO~HE7~~/]ݟG~8?9v=ڿxUJKA/ԯHrjri4~!@l$4Yz/]׸@k]hwǡfϡm> ʊ7bGRHr[~P?/wviu\&[~_l>ͯWPcۯht膖[ۯh}g.=o+G%O7{_zz+WBfl{=rX}Ӈink~黯u-k=_K׵mW>]lttk~-_hz_hvj]]gޖD'Trqlmķt'CP}՟Kۿƪ_o,KϮ`Wʒ#b}Z|6v ַ\ri]Dzؘ/_𥳐~ڕmlcVeGr[_\UX@ǪOʯDzgWb)זn՘šlT-O]>tʶwINWRzDbۈ7_YEH_}pB=~B M/WNpv5|R~ 3ree'qWnzU/`i|yzZ>Ybl>u=-mJϮ}KOl2CO֣lǶz.NC![imҷ4(bӫ_I\۶7FZ|vSZ~Wt˶rt=X!TcKv[>qt|trڦzk78hU՗m5Petb/}m:L[>}Pp~IrnSU%I߹ _>ʣs!KӲI}z^]U<0oX![gpUN[bW\w_|ƒG[Ē뉯5_(?V5%+_I+__ycc嫿=Rvgk?~1{~e7^zU{oN[%<}KϤtR>_9lXlm[ګD?6X~j*_WzmP95ֿz}=Ww_4ls;pU덫g[M3|c7y:Y{Ͽ&OsO{lW>|eaI?KUrC&+Wzҏlk(rB-m:ggٕfWUhߵtU첮o1vMZP>vm eQEO-[֟Z~;r֯]+]P|MomIW\|$zZ/]qM_*mq>|cWb۹>vIr/ˡ,^KVOC锕/=HbSH~`k:_9R=ir/Nrs([n_ڂ݆FOǿTկp(l/5:ltH.sh]b9Oѯ>9ֻ*Wh}ƶr5U~WCU.rO[+Vn;eU_)3=W\xֿ&iz!K~$VP{y۞\ϖ>.˶9H!ԮJ/6߲sR>_y%>4u姥y}֏&+rkt|NJo^zP߉ePv9cӑqK?5;3wWy\;tbp]e)K6U+KrbOK\s fK'KǖOgK_z[_˞e;~Y^VPrIuwY!>v}%O] .[U=KmĶálҹ֓rŮSJ/ՃUP:C5n|=vimMWw;ڗq_7T/+M^'Nl_+UOl>\R쏃+|UktRitIJ/+}[j+W,}uMjk|֗F/v;NUS]|{v"z` :9o6Kr4(o(P:M+ m[ytmϖ~Utm 뚿,}(%9lMg+]{jߪ3Vj]__}qS{*K$z~'Vlp=me6Y߭|eb}}F;4.;]q@=5:||m:_.O=bٍځCTUuهDbw,Ρ(m9MDG'V-Kײ)/x:Yk˧*?R~~C Tte2}N6Ǣ~vWVb?5}Uu}W׺n4=qSWQM^]z脶+}I.陷+vr٦;ծ9Zz]{Km+mzkG骲{꛿WI\X _i–$.Uv{%+]UFC^u{Uo~kjvlKjniՇXzMZʶ{NGw-gh:M.{WZ7jzn+NcK*}MKnFCGӗo94~PÿKlH~.OH)*qig\>KXR4=eޗUX>-/=KGc7KnKnNG/|\ĮW*O_zl{OUv?IC}\W~'/]|tb׋-tO}oߛs{vW˖5CY\vkhw9߈U~_?5};.7ڮ(ѫKs,U^)#}SUCeK_>Q(RP?b[>ػ-]WRnPvyzuCGӁ^Vs(-Xrp:JJ'}#[9}&GY|қtmۉV޵zIϱ7NʖO߮^vIמ.UX|Nl;m/뵩۫^w _N_{v.+=>T-P!,}-!OV\uw -?kд难j-_[yx:c,Z/Rzrh\s^|=_~Um~ \]{kz!V}j~ėoUvmKוYl[߱/V8}]W\=ץ(AU~FgޗYY꟯\B+kk{P94]qʢ뛎]l*'oK'+P~_6]ߚR>.rv-[߫rǒ3\AlUU -O(HկHr~һ]UU7^ƀzm۾wڳkGUǕ~IJ䰕6-_|\VoFWJoK?/V{O;}ӕ]?ў[5R~\l+?/~}Kr֍mҹo٦ڵ/Oۻ'ɡ74??!ݹ~'[v%:Xj+gzJo{k/KҞbٳ&+?_8>u1@WSJ_V=p~UyS1T].^G/ `_uكR~}|jt}KlSIgc~bWlTĕNY_+<ʪXiX~n,͡l;ҠrǢJ'u#vKb*&lhb} ?)ibٯ/=|RHcm~.K?k}VNbEz7,K}UGKו@WZ>~!߹;+6߲۝C'8e?_>t%Ntˮݕ-vޏ7IX\Ė[[;6]v[u]髮;-͏ӕ=r9z'qAm?=mqP/U՛PM7}ёC?ʮ-=-[:}+-)՟ئS۾ҕB`vm>_uKUq(۟i~_eס|\!J.?Az/}n,ZR:^zOeMmKہ/_/4?"ӾltMqתڗמms{)\$wv lʗDzXRXb/[6=O'ߕ^]^Nqsegl>}֯neɧu_zn(v]Kmz [`Fsq|?nϗ+?Գ&lZMp>-G;/4eQݍVOuz4 hZ}V-a@SM v"D_[\Mv7n<^P"WpM_5v'ٚ7AJbhPm鸦-g]W٦k*wR_m .oyCVq7@SLwwЇVk{<\'lt{/h~>o qU-9Tg˿jw :(ߦ?nxƀڹle<9vo 7?[]ꖣlbӫ$<"ox{Zyut}ͯjyv [3`@r.O;}qb@SMp>Q1? [qŀ;nYr5 s[ -WYvNS4E񸗧n ["O +nl~vekNUب0վCq!H?eﮊ0n9&8ꖣl]׍M " [a>'I!uՊ[@SLp1-OW)TUoZ=5M .cR )n-GrjMnoLTvݔ]] cŀ1)rT-OU)n4E"a@ZG5?>W?ݖ|ϲqUnW>rꇫ>j߫jǪ,z|Bqͯ.ASJ`k-gUWwqj9zCP?+/nrI$OW=wu[RP9BCWmǶo-(g(?^KArĦkϕ>'S,]mƕǶz| \ҳo-n Uٲ͕Nhz \ߕ^,Œ*皾nmױhiV|bKi+/^(&Vimq?rza^+WʖGXv-i[f*,Tp;5|끃k{hCUUMl#􎿷{Yz`K/ S>HK~_wWƇ4r7~%pmWNUXXǴt%4|[mll_m> |/P{lrK~$jc멯軖6m{j8py8eg ?ˏh/|4$WS\۱l}mͲ0W_ȕ/rjkW]WS[b鋫},q?.XtR>v g ˎ4seKlZ}>6߲\G?#!bڎ=&_ơl9c-ksb+_޻B҉]eWzUP\LG[ڳM/a_t|eYΧiv嫥˿}!҇M_H`۞Uc_R>z*$O#ͯ.7OGP GסZ_We7gW:=# 巕#/᫇em~Ir&^v'S}W_u痠mZe jUFו+=W+]Y>%RGlwl%/vbU)FO*T?e%ɫGcK~O͕prktlk [>[P}+?)e#vy-oe/?Wylkw[5-F+[o/8W]I/cUw,K՞\Ɩ/^g赖҉m5Tb[$ZݘkؖGNvKi,eK,>hj~-FmCYvScK'X/Nۯ+1jZ:-k{kסS~B7}U*ߕ-UN+_[T]_jK߶WOc_]zhco?Y+_ҹ+[bXTUc[yx:|a7՞P~~[KүJ/}yz{,` MgWsXb r)Wj/]/+!?ʩF7V})o;Fv W!#=ʥGsO4y[vP[.Wz<\_lH!6W++P,'-]W{ Vrirjc=gW}оZ:[:ϵ|5})4{[y4=m/vyBs!cҳ+Z4^'8bٝߖ~/+G;}WxFzW1,I#K>_z ]7B˫AYrj_; \b bѪC8ڧjj?Ԏ5-,{ Õ+z,;tR~)D'h)AU~Է49%:~Soҳ>lirr~\?~tb񓰫?eW0ϡ7nUv.>e|ڳ=>QI6>0rgv=?*viroN^}&˗kդݻ/wͳKk;^,?I)%Knx˒}[yd_YJm^wdr/<8Yy'_5i+I?NzGҷ>I3Nd?{ƛN'cCμ`:ou/N7y!o͒չ>k!Y;o~$]-|a=&~wu/ۃEk]'H6G|G'sk?!wJ|-o~/?NΛ0~}2p{NA'ɶ3'SK>dS_[^,k;~awoz0YZڠiGOg~;ݳ̞{OKʽS2׿#tnk-dyJ[8!I[?|m2NzGsL_=G&]|[y>i6}t.sOI{P{p+MM?c~o&Y|{ӓoh 1I/8ƯXH:J_,}}7Lzzv;2s{19gp(iw~;%nޕ,]s7WS{c2{߾Z2uo,nz>y̕z澞t_uO7sſ{甤>z󛯛xtZ??n|w /ްrKzǞ0h7&_qp&xK}'_q7IzWϒ]}cß1Po%sNRnߥz~c~=w\'\*IJۿѧ<}tn|6Y\.,^^IF);M:'~]7g!Yz5vMޱo{twy/^2Y~d/gpջ햬=uO=sCCk~w7raܯmhWO9I~ ?e}Utg>Uj򈤻Kמ>|Ӂrs_8r|f!G7{A\ϑt~1lsˁ8|cy{M:AM4doe`';U yI/6t=-)&_!?1/{oygvS_m؞fO,8H?WK:_$C懟o<35Y^4`}`؞,CqS^/}^Z+¤;0d;8.|Szuud./"/NWNo:4ӓϞi'+ }w_zL_V:hSoTk,e~t0O~.+~sՓHﻟ;upGۧ>:YGn?x/l],~ݬ]WUwhdB+;%+o_Aqn'?Pߩd5R_Rwjg])ㆎ(YOd{&Y󇆔ttgIV~AC~}h*KX1Whߟ{%CKס{8fwK?_=.qw7ɏ-|7/9Y W1 #kry߫4y݅G.\)N3ڤ.%s?H2Oxnrg~,Oץ\=i=t{;w2}|T*(eǿs@rt?2/6t&K;߽Gw=qAwqГ K#;\~ l6fj(&ӷ#m%^ڭ冊2dq❕S27+p7t2S_dh&m/g& Ã~j%+Ow &+{!o󡤳 ",?P=v~xSr[eɃI_xujG=A $oQ6..l}.ppMKnA`xdۍ/AlEi|ǬKVxu8įd1'{@jKL?eٻZ.Ko!=at?a,Xz]#׹璿^ i7z?' zdɯ ۓf'K%sWw~wFAtys3~}>wb?h-Y=r.Nǁ3=iSv'~c?^o0.~ǽ?7}>l{?~{M:0JVh j#?xq$7m_Hǯ=J@NtHN /NQ? O{ñO_t 31~]=~,^J_ڒg w9o}[SµS,Kʧ,D{'iM|3S?;ݕs4.'_Ap*[^Ё?|dl{ˆ }}Ƞ??/l?wqڏKd4x|0_?iH7К?3⇥o ֣^k0>ɶse~u~gg6}f>,=v܋ڳ+c4pWŇ|>֗Jzs%[ yC(A^!9k>9C;3tlonf|m~jftSs۟qސ_yOyu~]O/װ`pd{:OW_:wp`?o}V֯6ӵ /Q?˿Vߥ ,ޘۆs [`◜ӿ%wNtCzo~LsO#޵)^9|8dWIz?hB?噩z0Hchn%dOqS`dqOnM[1p3YJ5I?IQe?lح+L^>'YG|AK6?u^I/vIqg ;df>F4.[x->}im{~'1pvߦE}aOTðl\}g0~$ɋÁAroǓ]Ha&<7\v9?Υaoi% Gĉ{&/t/xsҿ̳n#y ;tugu&i?vڙGܤ{Q_ϽO8νdž O~J{Nwbki<}o){q^3p'{ƁC>$f{:.L.`NtԿua$K_5-oi܀|՘^z'P]n5<ɽtm#/+xiQ4 hsd̃8}t>LZ/H_=|ڶT٫^9?n-o1ݙqAQd /Mqܽ(]IRJft@8{Dx;OD;F[:nF'd1Sv~PK?~c`Տ^QۥpOeqlvoNſv@<@=n vߤ;0Tr-_gCǷ?B۔gs>sk nB]f/Yi??so[|'3ϥyj[ ><_M'f<7in+ɯ G=s 'ړ5pМⰭz_t~QǕP?1-ax?Лi=^8tK7MBqfy {'yn0\xtpc3^դ rҶgo p>>=̣jh~{ddoɍ۩>0.|ҩf|Ob~zؙГwtg&6?{e_}uIk ߕe/?Ge~x,..Nf󬽅G'R=WIP<7d̃tΡq|w+ܾ䯰΀yOר鿒7}eNoJvaqO/=Iimuo78Y1<|75۽h>m(]<l>g7G~,c;]ެ7|EF5+v]\2t֟Qm̠a7%lx.{X9&dg0^BCzs7Ʃ|/N|k6fN(>}^#xEp2nF%GмңS7JJv4OZOVߺ^Mǃݷ{d67~P oͿv[{Sx~v:ߠN{C}[S?· >|Î+o{߶@~F4^0+7'Ϝ9+^Sp?_~00 ,jlbVץuBӺ܉Χsߒ<>,:Շþݒo –=-YYuc)~_r4c_:p<>-Gh<;.WdǽKSyct|?џb# ~iceT{Kg<3Χ,[g:'_P;d{?ob+tuC3Yװn˷ot=ҸM3oZ?ź{?t1//l~1aȵͼh\&E:3i}9 wǤ2fS>w,o[o㷠81]Z? 23q[]2<垖кaw_mPtiINkToZA\7h<񚗥ᰏ姐]ZXFT{cÅDs$o658qRSð󦏤paa}5xzK-^F,Y -䛿WB==?uoY Ѹ+,}me彩?_īxcmk1o6sEÀ1{۷\|c8ͧ_I~54ҙ㯟;03']]pZICndgg-~ >h?i{jodIL//kи7W"K&^.!fqoH0_7U'~j?Կ{JzO``8C1ZƯ-Ji9O@GL><}qZ>y4|x?"YH(u>ǩB}vB*WIߥ~h'ͼҥ8L<jlNg~@X/x:ww^H .#~mߣu#;vNK%3쳘Kcz<=xgnA:GP{#>E܊sg u3|%=7`2KfOݾ;x&{S\ӹS{ƾwUN@Yo_~w0~ٯgCt/8`бWO}sx-K?vn؁|$w/I_a]Φɏ990G`=[.omY1Xj^?z+?*m쳚@xoyx{Ϧ#h:&#ߥ*9X^/ d:'0ӻ-iǬֹٯzcWY:~x}$+;hsR?׸7ۮB\oxoyuvd_4X9A}tnJ01ӽ}=I9ƹz_ilŤ%xaNVGF03GSߓ.i?A Oh}kHӺr&.6qO/Si\춏Ka (Z'`?%tC4?t7tWx`ww| b~-i} s}wyV?>tBԿiܼDZץ/ /|0ad4/ >@So8scO</Hu._[~}.%oSqb3-^/̝Fcacŷ/~ixM{zwhE?̇aƓ+_}C>N?';lqm'=`` Eލ1 /aOIo_E 瑼_2¼$޺pO+ϧ}zyDz~sCbs:|,{R?zSyZkkOt:Qny5_|-ց.AvWg^&@^o`4>>{:ϥzeڬ[\>mx,aϤ{{R4s<4c}<b|m/NBq#U,7@q>,ߖ+wtY;~m1NǾNgibٴNuMŖ^LɞϠx]X1"?qts3sNČ߯sw|I7a_~`f<þC7p\}x uҿ ??;Gxs0c%;co}~l_u7O"6v?C|Q ^}3]i~&3󛘷DrmYdפWQ}Loq.Wk ^J;QO8߂yީoۭ/Gˌ_Zỹ,_:3wex^~yLyĿ8v^MNj|Mo8ww}mjhgK"~þӇ-Ǔo;-Ay:?nOlqYJQujGa|߹ 3t/O]}ژ^Jz}75=:(X\: ?y zKsa?ɯO^i91s_ +.doh%x/'%!̼fyo%˟v f9oi -Qf/ѿ?ɖ_17ѹʥ+|Q$?X>Νi>qIf]73D#~?ǸQ{oeW/5@f?F<1/z\#m7>֛;w(O~m:Q;fϴn֏֎8 q89^l/:"~xw.}װ2K;dF:|yC_~'m5i疣W-̾~Ez.q\_ݐb}w^Z$7a_N^i(zR:Bxi^irp+3[ys~|}lN OifF>MYΕNJ˱zW[̿}vG?MV6Y~9ke|΃n}hpi~jui5/#< G Gyí˴Kb-͹a^6SCO9d<7 &Xg4s{4?Y0}s?M~#i뱽?'sƯ@NW_`I~q.}wù|0>_>.]浻 nxj_r#9s"Qλ`O>Q!>Ÿ x<_uW$}7S]Ocʷޘ{^:,~|' 攋i4s8Ƿ%:;,(8a ]i^vO:xbZ϶|x,kZz;7~4?goCQyiZSdq_9 fHEER<هt5;e<33yx=֜~ȃt31|!ؿzU1˃iFg~s}8?<G<ѹ/鼿Y[:h0[K)r;"9^i\߾Ĺĥ}@)7sΦxWw8Q0DZO~CO\ݷ\+s.#\Oc?=*p`sAϡCǂW:5~@y#m f⭾B|GVOyܕO>Mk8}}RӹxJ[̸oy *< +0;7%:O=:}9?Ѿ|t_:U6yguvx[ m;\FyP|uO/3k)~$Zw6瑳}4l<vrIf>aLq-1a 犳s_ =?\~g_=~]O노Os2+n/ G$W6`!l{͋#N/^L%e 5y΃:u]ҳsIacvyܵ)]y'ӓ/đW{9꿰\C`H?ڬN`7X7=I?gh/{olѼwO֮FL}נyOw~Jv}^F_SH:]MgqEm2+'993)j6ҾyGXZ<'7{a l_uNsƯO_ݾ3u  %s> Ύfm2s>S<{ޏ旱v2;6ߘqkLL qo7C&}&nΏuB7݇8ry|oG-mcyV>pc汰/?#XO{//.]L'-Yw:>e\Y{iܻuMeOslfzm:/3txuo܏h;ǸO=O)cSg&Np*It~K_S8gsΣA4s9X/{5ӱ|s:גga2f+a}tᶘGdV>J&֞OY1u`%Ĺ6?y2ŁXc"浰 d4߱;;קi8o߿ߘs">dip94?Cv_7`OIȈ +I`9D|::_7GQĽX_=a+Ϣs_%}Ѿ{a 1u/Ks/.:+su XZ{y J﹁1c[m%s Cpf^s%q~tR48n4>ylcz[._s|k:;ҹo+lǩ޽z>7>z~ 7i QO']]|9d ~ޜ7Y>h] 30s;]-C+ou ~vù!ӯm{v\z\Hv{/V3񉙇þT9 {Ͼq i|S~3s?ڑ~WtwNYz|w?Zw8^Ϋh벘_:^1Ń_̓ɏnp_ބɑ4`/8s0O:W~v:Z!8?8!,Mp/ϝL랈>6͡{v {` ?qnsGT^#>oR,:An}g+}fj6iob!urtU`ݽй";K^v4.9=pbͳODSf"ѹ+#Y=8>$gO9~BJ{3Z[wͯug̼ןC:·OjߢjCG+-8]º<桺̾C?{F wO漁Y_&>X] Iϻ{>?)aL鴾r;oh杍>oG~o}8~֕i<?ko 6>f{3z'_ӬS;5w-Wpwuc>11?>{&}{G8 d] U~mfWHݻ<1]ZS?OG痳yH{ `zW9{y7+B6_;sovJ~}uC(asa^ <+u.a8ܝMvΜC}cn惴pAH a39fk}}7^'h )X>sm=T@@v {+1~:^1=oJ2{zٟukѼ҇sw=~Kg}tƜ+h]/w6',&;Ϲcψ}S`fwξ;!΁yгFs_5 yM|`Ƶ 4 u},g#{Pv"}ɉ{z/g8υy/g8ϰz{{_>rgݫsX_ufb{u2tnyBz dn}4.{7fGv="BgO6\ľ|b2wgϴyҸ4}gx Xg^bjXsnv:6fA} ϧeV3[CqGq܍.wx`:iG/f i7? p}H87a|ѿ/g|hn[~T_c #G:S݀իQ\0;W{mf p^ uq"yy 3N:ǎ+GWH~ ح]DzޣtWu鏿 Y#~}CaFt~oC| ѯ_ }Ƹq9ӱc_ȟB5Xǘ{=3ϧqW;'=\}=p&Ʈ7a?_ <.ց{鞃}-@m1̼Uǎ}12I~@xE}WRm],pڱgg3w,[{'?Ǽ<փ|?yyy[g86p'_l_b*tN}ִc̲{=ټi~)=/ute5[:ڭwUpX{-t}=6<s* uDw䇶_Cpڡnz6w`ƅrO@y5}{:iglI-/ӿA+'هzWq'!FxfsS'$s= gGٔYv/os{Z9` "si\Ǖ1P:4@|0߆qSw_}EC-Wi-h.OztܳiƁR?kw7ݏٻ'&}<8GuS0TC m3q?yh xg_mmB?s%pTw%\-]G=jOtε㾞W~g~C*/^.K0ϸ<[<[@A3}8r`k4or:W '= O<ywh_{̹hqV:ǘ q0);^EC?YYyy-sNi*o={$7 {m50WpK}2?uhft ~#wb%ozoENߕs'xG>Hi?3ݖbʿi|ԟJwZoiGw /ܐW8g̾:Yg[ttqmz_yy[<wgc~qN6N2۸w]t aw[`[o}/| ~ޏ(>[}1+y~X "@}~1o:t?}k^tN z?2fspqc{+ 0kh~OSpos>dfKtm4pnlW?\8ܣۧ 5qߊ ΀po܇XlSs]+gR@u=d(O~O8 08z ýȹkˁ8eb}$Hg뤙fpO~wqǒc3뭘Q} ;?u+a\^G};>t s98z'١ٯ|1`!q/i=Ip[b+>照[s=I4!nHqa;d'}śS<'RsG~t^J/#O73k^8`QwhAG-!.G}s>ɾ.7??؏7X;=x8?yh+]pNi;fH7F81X5ŝ؏c~͸~tɴ_F|}ߘ_A\+c_;G8{˓.{@?cBCgg( Ojz6kOGa}Na_-gƹ͕;#zKFf>Xp~ 7.Mqe{b;^+s6 l qU8߿ܸW{i]"Όs8<{cgLO{A`he˛۫ݘ~o~ ϥ{30nMk!st:bõ87Wy>))zwg=>Qsoc6/ÈO~C;Jpdb>Ѭo>ލ~~4/ySaos W2f>/O C܋qO{G?;Qy>=9ےSCKS{hͱ~d7 / a3}#{O;08秿}]mm;brnw?O݆GZy\Zcqsc> ^uB~hџG}km7g_Hp~!fEʜ=oOrk<4_ƍ&}a\>/2̽;=~f}g !1wAۚݵ|KDs?ٗ{:KqX]A0i{>޵iK̽l~myy!?,_]b7Ɠ736?~|pwS{>9٫S|{|9'a YGĺ?λ쯺<_cof^hi2~b_oI齐M43o{ͺ݅s7{q1ѿDdþaq=Lch~wGz=J 2ܛW.7Lq^Ls '';&ROl(7߁!u-/Y_fv9~xy^fڜa-ۿΫ3ů+?>C͉/O ;=BD]ZgC_Xsrf>sߏĺdw=f3ѝ9t4Mcq#~>/3st/L6_e[Fǂ?bP6m) DZs l^ aDJ?<.:/Lq3~}i'~{a0O50dv~wo;˸SfܫCkZzEO-~B;'}w'#{پso ~aہϲqK~zPc?S~+`}X+3X9nY|oF+R<:v3i}?PtFs_pc@2E7~ _>W:l֗{]%=&c=g~yjol'#nC (5B+[oI~}ݷݖ{90.o˜+]ߟ~{&͇_ʳޟvkk>97W;Kqнlh}~ ݥO#oZsӡߡ8:msN,~wo q~taЧ(EP،{\q?`M#<<1yc 2ssм`6`v ;~c]V:+4 ~$5z[Hp_O?}:-$p1m/N?p?6 ӝҥs>wp/9[*ދ?9Ƒ}t,ʁHw~"gcφaګϥz=1tN_}k?lZ׍sy6'kDgG1co.}S~us2d//C<0ny`g]R:ߙO,_qΆ󇈇>CC3Dӂ;!?E~m2[fփǝ}O3S4/I|aMm}>q}i_;֣ FgѾy~Kt?j᫏3O[@e8+pj\<'Sk|y=.Os1>vh_G$?s*HI>P}n[ƽد}qSߦO<b~{ð`&+Xo>c߉uf̛`k1ψ0C}W} 1#~dsdo4S~ٷemq?7wOkz>ppg8_y-Ǧz1K\a)`B8va܁qڣ} ?t#]ЃI5=ac?Gufz]:ܾ9/=%X/F8K8smNycW~+ #澑 鞞oS?{NtNg~s܇~g?;~akSڟ1yS-nY7s>E{==0 L0߈yly l2zߏ9<9_q?}~qgHNv9~ܗvvsNGeQw"f9xw{NYb?Nt'?^{=q>c b^S<=~pu~Ay-up9Ͻ⮥^+1/>tOh]p ;e֍e~t'h:/{LfH}`ܧ13N}h7B of\GqMd~v|~>WKg^A머ro:.q?gbC}o慱_؏ {|?nc\ž(9GH=a_ߐs.e~'WD+858gտaw'G?{99/>9>w7=i/O0qK>7 }dB:{yޢ]?+ݧwY1/={SsƜɜg̟zm!?N6sE>h{̽ط}i3popq_?Y3l=}s~jA0~ K~[Ӹ Hx2GޓօѢuǽǽ~O{^V.,SA~dIt_%'#h켝uLw}NycK4~:Beɉ N=)s/#Λǽ8ς}Q /u{kлX})K㡵w^'e0>X{߇"d'}]X30[NX}۾h^]h^ eJ8y+cqvi|^:s/^oi?߲~VDߓEy!'b?4i7Ѻrܟ34W}~8{ po~O'>`ge{f^ؽGnM9z9ľ;ib]m4K[Jb(}s%h܀>~~CȬ{1uUy `z)o^C%eL[a40Sܓq"3;i~{petp/n+c~ }Jo{@3?e1aKYv^K}7}Y|ko0K/_@ع͆pxcgh~6g'-?kG]+z}FXOXwN>c*q~NS|f*}?~S%KiGgDW ? '^|Lʅ?k~f<|Onp\}g('Ƚ9p;FHCk?*k#+Ol=3k#'>eQnΤ;= FrS#'9y\Pvٞ1NRƺT9YgNIyǰßwo}qn>\'zXqG9cK'@N8|~:ZEU)s'ߖ"W|=@<0ÄOyJ4˪ +{O}Jc.6w{'g}3KEsgrsz >s78w|i䡴GoEЅe~ ;z n|q{SA]M"yS|gwH sҡ/)|Ï 9gd/]}5|wBA4?_mfS+s{dwsB;_۹'[׺WoSPy{կ$k_܀E'uPTy@M;$?[}PQyYO ɤ/YꦛY@{p΂} A|i|fwt+I|&*>@dsIL6ē uNQ}Sg/*o&~p z`yJ:z&'YɃ=t>_ǗBАZ_Y9+,~%Ofނ/lm/ze辡 ]7dGCwj}h"*wlB?g^~;!|4xuz3C9@tް7 >s/ =Gܓ5ې'@?RutCN>b|C)ƕsx{X)Ob߰w_W>]-g> |!?'7xRpxAo%޳uo9˾S[YpwEѫ0ӟWIUm]{1XN e~?7iЫGoXN4~ \v+c'}@a͙){}#W>+sH >O/H) b8!/7{Y0:4>'w21xcG=2y3;%&zf;vy^az y~_z7KC8ߜ~-x%U/+sS5o4ݯP>p3xExb5)z|ϰgs~mϡvtɬKDМBY4Ԟr%Ű灯tQ1:ε4ֹEWsC=WѼ7֨欧ŸSA>^re g#~!:[_ '6:FPΑP}^ Fu+ŏ oz2΅v:ESI<\jN989VU&?W oK,>#{)MCvXKӣM>?9ߵSJN z*qij]szCyџl=_He9={\ 8sG_L۸w : 8ȇN^%z*(}h>؛C5O@2r)Y>5Cٳ?Z΅B3]%7,?>=peisα,pٯT]ѹQg)lyӓ+(׺~eȩo)Γ-N^/\1[;y$ryoc-zVsKQ|{}Ŕ/yUs/g(έH6:=ݏ^WzQǖ؏#X)yϑC*y r_)>,?Z~_83]!]zj{_<$']V@!9_cvp_!5S[\rSu¯ʹCP \yeoJ^S9%gw.sٕL=0Ws/N~ xttSY:[fCO>ttV{9<6%ۤSGFYZG57s=[hNΎ||ƿןM|DzO1DA#'|Oc\Wk%גּ#F?G眤EK꟧*{I~@xJ{}ku‡W+{˹G%gQ+ήQupd~Fu)T-eu ʹ柯_"+|"xIT;VyHD17֪ wf'ǫVSؿ?\@~PgXF ܮ =rYw>aq7BB|?![&??i{^GnW·N3^7lӭxPs9$ n̫yܨEtv柝DB?͒K//yޟ_>38|}FOC? ^WQXLu9qӫ=KWtqH{.\?sjTg)[r#UoM5ϴn> ^'|909_7s8+8e9p$Ehя$hލ?zN;RSm 䐐獏$|#/R%9SxO88u꧋GE8A39tOG5t.'s |O- #>긭t.'A׃09z̓"|c_c ^S+{TN a#G<$8Bҕ_,8Hs?Z䋑N=5RYi._zg3ԓW +3}.^ws# rvy$;H=r\ǿ*_,'WG'.Ѣ?X}OY6(u h,>ķ᭲,y;|K?0Sd'W |]Poy~F?[a3@zZ+\Hp詵\_۴_~zy5<3D ZqO>@|.VVOq듏 Vgoɷ~M*? _% >d7=cO.3kx|[s'eyE>Oнx&/(I'K+j*xw65krWV>A^ZuT[yt)6&\T$wz"/4CsּO%zOHK[9Asnr_S{M3tO }5{!例|cϻ{h_&;|1'|7:E Ɵs>1auI|ჶv{~-"yȕ|T{N|uדx/ٿ+G!G9yLV 碯~dEuɗW*/9ybnIgٶ[S _ Z~Exy;֗tWwNQ:HL.=#_|m$4}oڿn5yK|z= |::f|фOk5y|啛s>=G>C`qv|, /%x zm/b.%o({X)UD9=1[BUW[~0x+qɫ=ӹH'rЭG> ~_Ӻ=gKk.yP̚ҵeZwC{iooJTSV9kCDzwDz\io,/Rs< ;k`NA^8Ȣy:t5SFN3{=$/sxb/(S>/E~4si'=V6XL?g)`ݧϱy{D|7M/A׮9g%w N]з'G^}W9瓟/܈| _?"zcVXVxaw|p\*IG'c$J%<$|ygٜCha6y&ݳTQ'Lo< }t|?}{՜K<='G]ᗪh_' Rz~سȝ=.Ss(bp|]Zxz"S?I_?tQ?$-l.V+y sK Cy{VϕdB{=6"r>bgIߏ/ 09r|ifkt@Ѵv>?O|͘t'滞Vd^C?'Yy΍&׾ N-O>J/5Χʹ{rB)<878Ne=+9i'h LT,&Sh-$2pL<=PmCn28XZ3?Ocݳ/#%}7r~_7gz}.pO}S*>B#Ÿ9e&?yHzWHA.xMPkGr]H./~G{q}{>/&Qn9l9XȒP-|58LuK|O#<9b?<g],Yy׎yYYA!wdRDCO^5ø9! 1` sb{jOoѼC0○Jl>猯 29{9ז^PO;~\x^z j>GڃDN&LΕ/qry ᙂq^>!ߥ<r: &ܚ5WyK/|א焾kgW[H[;XQ|1wD62tJʨ{"ή\G$}\si- J&3=sW+|я>BpÑ'7M&Ϝ^ rk O?>XjQF'iڇ\ (xAYOG,;¿3|Aρ\~pK>C!pnZs3yãuԜE~wtEٷ#%S//9O%)%A{@~u G-@ B{.#?|{1:EzTK?^|%t:GK>4W{s7DOֹ &[_?(%?]%zZ|ǔSƜJ;g 7뉞5spE_'gg#׃=?A?{%jH2WGF{8[I=wu| }Ѣ>ǜ>9+m̤>_{,{|lɞ|ON42Xz;؏lP~OF_ɉF^G6伄o/WA|(|{Ƚ}7ރ_S^33\7#x{`MI\|yasڧ&ܤEs:'-;do8zu[WZ~_N7)U |w=HoV_Sg?vG}9~G|Pt_i]:b13?yM U/iΧSXO~ =u;Z?_Woa5d?ބu+sYJf|4O?^>_$P(ד.;~^z߻o}{;ɏVnǞ8Rz}pt[X{/J>~ۅd WO@/|D {uyh?f?s֍WF>z~xcrעO<w:'์c䞡DGM/MW L{ z.G:&fIK@=^mɹW V}vٽs|{aݷY,#M>sz j !a|+?(=u!_ygV,"'rw'C[yj_yIY7|AF7ksp-=C9 9T }$|~ s}ÂW ?_c=x_}]E/5K_e7,+ ̫%4o~4nNO53KRѫo^Zt?74.;¹7#^-=շDnM+:dH } Մ'g*os?מFO^8'[ ;?ý} Hg_w+ll[+?ѓpqw7;G%08_GŜ'޿pGzJ8^my۴l7E>{f{ oJO7YGsyfa3AD~ry*ퟵǓ[Ou z96oA 88<8pJ>EtG.}F]=qo]]S붞8]x29p_wt[芲 _rSşz٩c}/rhm y{2r~Bp΍+},@ H7Ott v1\d)7?8@A߂3~3x!벓>WsTn)-ރg¿ 7Ρףs/c֡j|%\D~,ǣH'!o ],sӅ/\]RmwΟʹ?-{Xc6^/-i}r߅WrNsrϕ#;#ۿ|K7LeG7zپl_%)zrׅ.]͗C/@9|r/7C_ ~_:+{jo<_!L>FCGEzݤ>M|TNu/y(З,܆ҟ o_wzx[6+6gsqލQ/;Wx }'s\|!b*-SD>cx4»%$=(jG頳=gδq4p{KG.:sj\/]efآf)EBWhVKBd?!:Kr"7<6lry=9zW`a?ެ\Sx+e^Ϝ?/+xHik8$?7d^b'\>}]=yӘ׺3_?}ȿBo1~>̓g$=ɒJYӅ/+OM6.IN`__6.<WڧCEq(adNG9ХA~s~>a¥1"|o<ϑ-IoP[ojϬ}"߉^616+~g~xo.2=M=܃i=MlF.{?tx[t魳9w/=|/߽t``4h/Hw'J/icل?;,9[L{Zz1N&&=t!{ei|^#' d[s8~X@of v@aN^_DW_޺ދŸyҿT$#^V_s&4wc!8r;8'$%a%.|q#/>t 'ScM|oГ[],dxsE^ 磣#I:8w8k3wޛäS#rѻn29 fKvyfCAKA:uk>S:iy_rO$idDS{;OsY3Bey8g.OY'n$$Ü3A>9jp7^=-; s*'CwLj4{dc͝Ylyp{i-e?|??|HFɻ^jN9{>{4ƼhyvtFܲSyN}Nxq;1O= xaL1tːs Ӝֽg)O}f_(:׽7ԏzq F9'^OnJy 3S>{_z=g{VlԟWjm s9Y:tg݃o+|'Ͻ2N źp<J\yNaOB9ͷom=Co}LYF~6Lxu됝{BCc5Os}EBK\9B{f/<}:YK<[w^=ޫ!o5(ߠkF+rˮ-)V sxr] Y'~bpl6pN+ѯB 1&? &~q|/.=t 0O G̢<|яe|3F>qx{">ީbooCy՜uEGo)BN^9EgK {' țWH*ߞW24lo[F>zkȯR~@ƍ\Bwqޯ}98Je;}}G/ o_/O 9y&2mq;C G迄`}Z1icgۗN˹߹[7\% [J-W4ӎ\_,y|U;Fs}tc7{dgjWF?7B S^(H3g7-sO5tnޔiy<4ǹפ{Ǖ˓Pya#7_)>=dAW)0cJX]|y< _E>u.ώB<&J9^)?uuv:,<7Odpz['*{pgv}74w;ҏN<_ܟ\GqӐe=F?M:T#Ow˟+ԇrj?8)z%_G3YV{SfQOw'^ҷoS _aK6Exm:?of=|o{\s|2pVq[GK7A :1}t#uͥW?+s~/ [/  '_Tq9v'?`/}2-N?>#!9`sW'(;W:NtW -kzOȣ 琞y빗}9#/=sߡs^ ycT55~3\W ̇t1)~#5K v~e?㟫x_:&^l5J7k/2z"+O?ץ/# }?OewH-y ڇ^F?|foua~X'/ +g(!3yDGN}ӝO%Mj珞=bqͥJÞϝfd'xV<+<ڇ>xJs((9 〇rҧT㦐_jOC93~&OA^sC,ys0ɥw@3|_w%'e^U>лDA?ҁa)Ї2CΗs1 65Gx̑=< X9zr`Iyop`}[__KB}mCK's$:g犇|Amb{iOy>^уi_?~=4YMCqVۿ= },*ű[CN켋=Ʒn?AE`SLGL׿oFRLWk/_~1KOӳƿ:#uVd}IG#Iٺ*yϝ4SOj.|yQ7ܴWyF?CYw~|r o =Drk'@Ls&3y}?8üNE+| Fetw}fXWzW^?;Ǒ}y?.*ٞ+k__@|<7~מO}cJGt? O)Nyޣks+w =MoEAxά#@t'gz/Ǥcn>3O7N~9G'9LziK}_ zSpAO%Od{=o91m3CpC|KiWd~I;A{oL>;zeyi|恘oGG\}Ps@e_pNg|@.0zG&'ǿ<8?9w?%籱W:*-= :;zQ??`?R6"ۨ]/znλE~0]>Sz!7^FW?!} #o_hrGл?jO?8<_A:lIK??"%_iuJ-Yg|r3~}-oʞnЛU /1[w4Xf&5Ht)GĜ7|m#M&_|et`䜆>پ`rwб$^) /B~wqN|ަ[2wksLuGͧo-":+# :r ~O9Qrϒ.8kpuf]Ӽ:|=ytg}rΩC=6>D<~2_!m78} :J^-t?#<ոc5o ?sNd|Kn ſ.δHx\r#80yO;KXpѫ_>'yAg๚sɦ>#:#:/=&%~8Gz8\c/{=}֑K3Bd.:oP{|B''J8B8z~{yO)nvG߁7 x]|ż몇z%};7H>@ymZ܃w/3t Q=+փ2]z|||q>}Isǽz#9ג2Wp/Oqp Ml#Gϗ0/GC~~Sl{r3{}g+ssD?&wLxN8@3MhX;ބgSUwы_UGmP{9඼ޘ_I:r㛿,pD}V~+FԾK-܍ɔƽspp|gҗI}uO_z'cGu}vWQFs]m[Fϐ7OY=.ri+3#ì<ƑtNq9WMC'Q~ zͳ|ω= zcK+߰_2 zz?𧤯jNwݽ^˦:t&}ұ5N"7i~xtם~ESzQ3/6ĽuŇ4Ԝ^OcEcp%z6n|WJ:r'/ "|t K/X7g|K҅}~ } '&'h y /|JxB(]>FJbuav~o4C }.vW/` ) ?-&S3oaAoV3u)_ =#|3U%!9OSaN!z?9~~ұگ9_ƹPK™9?_ =8yΧO7zmue= ͆ND/.k/b~b? wď垞d[}]{?{Yc;3?TҼs>P3[ ~{?:[SxQ W"|jl~}gyH|e'~#+p3nË7abӯ>JnI}gtn2_OQuI헵g9'~OkC4P*hDgƕ9~n}? ?C玎/#J$;xo# .eA 4=ۃU5nVtWBA9% r-6KGC^Jt ô?odNaa︘_E1b_鋨/_K5w_桁埏8;61C'=gת{=;x yc3TroLsW+?pCչ9w Guzق+/ .ao.ӣ}d]᪵[eS˲[ M\w6Bϗ^-(DãgJ5׋ >/YrKVugr94Gopg" 80e HK/?V%Ĺs ]U?(}papl4roΫAH/ :>\{I~G .0}͗Ck>}ik[ÿ||h:[K]:ztzbn92M<tNV$Y᛻KP0RF{كяћ'|HVws08UxZ3~#?cޅ7tO(|"gV{!1?;79ךcZ ?LS#9ȑr_/kgO69ַk,eOH{Np' |{07a眜srP%47Ч1uzhލ|[u/Nt|Oy6/7'zc9b+t^-v/Ę!g^{7:V(ϥyrK}C3i>anUƛJW1|޻lZ9wp=0~y /_y07SF9{u:55 ⿷Ϳާ^~N{8+m(g!ީY@w3>Gs5G̼9rn-{?dS^䛶; Gt%I2_b 騛_.~w@z:#)aLs`<OvuUgυM|Qz<O"?E.|) }$7Rz'ɇ'n=GnC@ok?AUYV%ʿ{#y_}fįHugŷν@ >SwſSNIhd} 5'E>F^까މQ'g?xpfy'xF|gZFi}nG͋S_yHDuAS=fv3@Mb9Wkz>o9~ p?"X_{D }Bs}{ yuҍvmxXm~xgFU yI!5ZJ{O^#cfd^E<"rs)%+U|ͥ_ݍ#Z7~"{G|=9uYJ~!(o\G/Du]_~ =${q_%?7 zQONre ]*榚#m7O&/޹>t+q9-u@{>?r{A_sa<+9tt`·J/<8&yo!ޛo4?8¾W fĢ>_/LY}jOG-KpAk7ģ֏WRxC~+WLJ8%d#+ >ǾozxI0鍞/FSSz|. [tv'ұG=_εD5_y9u4f:W[5?2V-o ᜎ^$Uu8~upu;{QJQ6߈GfA'9?8ޟ1 c=%?:ky9n\gH_s|tr!'U/ +.ן۽EﶵW Lue:$̋3#WlgPc{s7uSut7T\\y&ѳ/b==x_+^?\+tϟT.M"OŽhఁ.Vz"/$ge^P={Oeߕ,PtCUj'3ƾϤ9Hj_|}*k>ƒ۝i,<0K:ٟK ]эT7;z벳y(׺ǹ٤:/Q744_\>'91NO_6x&9g1tm"BܑnF's?ra4߫O.Ϗdm o O WtO-/ }Xyޥo6e?_OWN4=y;khNU 6Dٜ{4NQn N~ƿ\[9MRGN:<spg#]ɡoBxx>OO.p#qaQ6~nڭɁ#?&{G _̮}2-iO[ \%ԜH}s6 {io|W ܳ ECK:Ar| {s4?߾ss 2?ȗO@=ӈt 73~%ᴑD'rɝnc{1=^OZG)OC:^O)ADOB*O^7[ystvutO\俏/|&xamLz'3Eu igo^d`c[y׺L1؟MFqەD9c|9< z^'_^3H8iwVUc*Y$ps5+ 9q\9׶K->;z 9?KC>y݋3CN_)?G|9"rh? {o,)n n?j'G>:LW2h K='|jtz'DψϧڌzoKyzc''ЛgSk6^|9 !&lC5[a<߃y#~o6=ҟL.LI! d)J<W7Ƈ^9UzwūSF.}U[o:lfO [s/rt" V\C=Oyl?3{\AE#kN?a> N)l0%{ZO/1cW~ze-=| G\ _zpl;ck N]~yCl$})qz7˯^KNl#g{{yWD7N]z+~}n\:)o'rݿ6pVΡ?/;>(~=_sǔ~R"pfws}yjt^!eKecҕ_T ѣW'KV٥ϻW;Γ'˪3jtU9sWfņ_~: _y9ׂ7_ 5yaXGs5t)9qNϷ%ܒ5лZJw<ͫG |3V~NQh껊/Cķp:{摽px{?7E .=e>s&D6΅YSz5ޫ7ѥ΅lC? s[kޒK^ϏN7rQ;>{͍:GŜB-s"{0K䨱ĞD~|58Խ;x}18 qWx"yEK_-[TI-yd}D:<=-Q#}"{)}=!;+7]cu7f%{x}%4I78"4=3WM|)CS=?Dnyp|^K!Kf &^^8M냽?No [1yM[\_r<@?N}>+Lz(Si5ų_?}nd$ҁUq^*i&?2xHc|,0?EzG-"tJ{<|ӫON>Sz-q~ңG>?&p;kZ=Iٗ=YHG}wy~6W.'r7kS{H'oϾ{ԻS =1V.#omi\=gztTy7ʫҏ27Ug/<r5?Cķ:E=sISgO*εNv^qmK !:+'<6zS?bNzHW#;ei ?߷x sߤ Yu.DߑsЋes~IgWN S)I+]Ϸ/䣒O Nμ=9 7͚c;7}yֳC &G|#so斿>!z}?nWs'{WzO~=Ɏ~˴8Gs _ěoO{(Q#: ?r+iN,fzT{;+K>MǷH} ?ݤk'V}3rc}B̅W~JqsTZ)O6Cde&h>y Ŝ\\oj R.}Wk~2V78rx];!=U"T\ҕ׾_}C.~ssjȷt}6| 9ߡzrMO;KZk.K?jGGe#xY/ VSQ+zJz_Z^Tg dg]=gS^"[N#A/n2YS{%bOn9_"iUu]%\>Ά*oJ .=GೆOsŸo|\qrߒ]~%@?{ugI^}O>pЏc9 )(LgK(;Qz9͵ԣAWN^2z%BwI4̿'Ss6AOFW xnL[ŞK yLə_\zYv{\}{ GsC/ ^e;/}tͫJ'b-`On]p=)?y/] /0g0շ'EKrtנwOqqck(d mlyw~4eDP}Y48=f܋õ;'}5zod3\΋+)}C~_zZ9 '+bѳ绱yߋ(Vې_& ",tRsxNF.{K{H1W76XA ~JrUBcu ݯe*< ҸP3B~!W콑7AF{#o8=S+]ܮsGV[z7I o'ID iQR{hq_'ג|oxEA g'o}<=Yi%/Jj+})͛37Ny?JYgRybבc~$‡?3O{N[d!XQ_rYs^^!r4"SϜ{ywՓ؟XE~ocunVVSCEBM}Xyܿn][2uos7>X]zsdMLj~&?. w⟣_s< )4'3)O} zY4<w;O)\E{&/ZG ُ 9oid঵դ7̿ݻ;/>׸n ‹ˢWa/$װ9|{W$K׏/3K_=,ҋ3L?㡳vo9xose7Ko;|{otP[vnzqsn|ON9}{2?ҷWЏ:]9Kr^&qQ;+!XONWɽޮ9Nw3K(=3?7.q)/RW5xgwckYHMz.|~l7[7oh:]FΫZo ޖdp(lܗ;?@;s4x/#mwØw:^Ŝ,ٲG6#Ѕߧ?7=TzPzq]hrk&*lJn~?o.}3 .-KdtD{@Xc ό\_>Lp~~a4EOuCѫvi|\C'Gsո_Hi$z1rVW>>8u*+Bo۝DN(t 93E8H.;}/{F>?z_{oȞ.J}y}'˟Hb~'BO |%.+^/5ßA{Nڻ8酎<$j![I|)GsECG^Yr73?I7x}߳SPrkʱܑ+u7o/ޗe.{~9|)u%/InG^sN&xk9f4|6:w `{'5_wgM81㠗\a:~>r|S|yB=~6'γ}X'4g?i="{kpG?_wN~.k_>" EƑ7}m絨F-sW){is S\\]`_\,}tg}za}L=?YMzO _5*:ct U_C-zҚ_/z *yOCf^upt;Z ߧu^Ms5<g OoJ?7S)pIeľdrz9y[8ػwTKW9~{x~Or:++׈:GO)Ν?}ᓻ5huzi#ΊrozmYzKFNT9(%ӒF.|Gw?rU{O?%;syW810_Ïg{Gߏ>y_¾`y?^f٣n=jv#i_x_|ݪ \ܸWeo%Kwrr |&L4'wŖ~ԟw'_-T8{t̃)99ROνtEAOS({Mc}I9wx|忍Vt+7(un_RPe6?^]ßһ\sukq{_iFWE3=C^Cƭ7>k\ G>ω^޼~n|\q1ӫB6}9# zdF9K:W/ރ{$<묇/ٝx8?J8=?/51It7N48bv]U7c}'l;/}i)[8dIk7w_>zϤ\DN[S9EO\Ysz:rw#y |wWY_GKI?$xbTw^>Fptԓ>~.7-?־g{:on۵HNzd0(W9_&}?y/E,6{ ?O9#~{EY鲃7V)pnqB^,i;eNrMr>I~iM|Hxѿ>Ƚ {m7>dц\޷s?{x\?i\`EK^+_]\|%_\qf{]cS/\>'ȝ'pga~k9-Ko)\ l_}"Q%W=mdHNTO#sCx?pwrgz3 oIwyTByη~K=C׆t׵WB H6~tNwv^h͘-C[~FnZy0ri-,kiHJֳٺffGM9uG^2Jx*t17i\ܲ׌+S\dN%<%E~{n#GKӹ؞Tܿ%$GQY@i|oNEYFL'+_|V='y죰Ο4DoLϡw󴺂xE.}NU5ϸ飧'n# ,uO_"s9=&7ԟ^t99U|/yЇ9wGXs+^ni*nO\xr ύ>z.珯Who.>r*1y.NTx{zp1{ptP:N=K7j^ |: m=n#o~XOYME&􇅿`3Z/=} =}F0#g@ul{O"ރt-JFv(t5 Ck\[x,[5WYwkߋ|u^3zީ9rm/H8%:!9 bF_ٲҕx$>'.+'A_8~ ~|r(CF8`ui=ˎ=WGz7d# *:"𯹯uGc+=y0[r{<;)'b>jN^]dnl(~s6@/9)Kݳ=\SOwl٧GA;1^yҁ=n<hCENsȹMx3>GΥK4nD#}: J}M/W؛~fDsrO`O)?{@x/ 0zR~Dzȡ7;g5n0rdSݪ?&#~|7K]lnFkM?!|ޓޭk# [x?jt9xWW/V>vDI6Sl}7+>濤j}[T/9msh%>8< x^8S,Ig M~N—ȓ@@>{/sxGwz |MkNC=O3$L('x>xAK{/#1ssHTo)OQ:#ùnDG>/Лjq; -~3U#5n\*/{s1W[/jhPo1s9':~wZK9><{c/;sŇgmyXruйRH>9owh^^Qs#?[ړ:SӈzVM;DcF;?k _79Z7Xo~gBH +ٺ;פw]Rj #o{CͷmwV^<} g\*yӜ#tTtϢ_8 }rV6i?ГG\\0p87| |nǗ^9r[t[uߓ/%ㄜ/ŌǖuJ6NN<ܞx;T3GW.Ƚ~'Ga?ru;8U? Ld EJEv򚻬Do~htj ]Lwٜi]wo;fg/ΩV^SilطGM{zyTOsa\=ܧzq~K3s{9|~|O9gȧ9I}{x^[|Ԟ\y 䕣$*hO1^3A@;=Γ'w h'.i~{g g:sV&ǽ 5u.gFJnyN> '7c3l~)&=)Oo^?ys zLsEϯs0z38oݳ oSpmr%>W躪EKyQ"Ux5y)~<|t$Օ+:9D?z4³t9J{B{ K >(g AܘZ?G;վB/sw=ͫҧ {Od> dռ]OX1{V7u^"ݯKxүE~:W /$> 'U} =w9?|:sEFvy3z&U:'=?‡i?Be[O#~}Lr<?'Gs..+ŗۉou~>v;a咄yQM|1z<ۇ}]q+^̝%OR9ʎuy|} _L~y~Ћ_#=9E䬡#op:{.z{E#9ەr3ܼ)QzM%^?v[4/dDwGg^[{ߑ9{9}S{JY5Q_Pz3*˔rOP?SEb:&%rޙŗU2W}noSO虳3W\^k{4Z3/~Q\[n]hz?8_;/_0{XZC*1#G~ͥ{/Z'8"΃v6-1nux! "7:[\ڷh^~ISG[68sƝs]=Rn)?<ȁ#-'GޘlZ#USwZ\ܭޯ|٧32[1gLWM7oz۳W4@:,޺FԞF`!7EV<&@?.Nb}E-+sUE$~J~G*s :!򃆗>*K9y ,~wp՞^Q-x,{'}̝?'iOO|s|1 WBr#KrBpo; ĺ(t4ўS,? ٜoZ6Nl5y=FFy핔>sOE_~bztF'F'lrȡ3VۡNˡS?\:O|V*G!h[ RrqѼ[{@YڳGfNԞoMwxc^M=>"Kqosr(>GgQxae|4䷌Ω=|0|1%?s{k*X{i/[9?=K+rn-}j7KaBޑp1r"9ȗȡwœFN#3|*ly^^"y@yG D8(?&gAQ/ ߄oC!O<ѡoefO#F/RN%8\2 {d9%{:U5[-{M+o=~C2@;~W ~jq/0~[F]Q{hf7}bş'2y7]=уcMs֔/ʹ玫[7~MtXBNGKg5rtΕ Sn*os^jR<sERЧ36+{"9&[3#}:_>_s}fsA;ϩuB7A/Ԛ >q:xvɹ_9}-oJ%o}N&`IXx߸'Oy1^Ww~©~?g?|P"Yz]V.a: A^c^J{frDwQ0RY3ϒi=cy:\>œyG@>L&p|׌c91 sCd/w1UߑN(r|{PBVr/x5{=w轅ὫLchc?F >n(NcmSIt58g_IwxF~~bGIwF^"9cѻ]22y'o+? !\;_]f.\aCr}1Ǒ]M3&>=r4Hz̫҃ Gޔik(ڤ|?ɧrtMѳEΤv}[N8:`rًB`8s-|*#=-Vso&sr" -?e !+d翰wލ߻ХL} 9U[G>ATk7?|ѻp ρ4F/o~䰱һpƨmN/<~.&%+Ζt8gsH<8N ޗ"?uz>'#aomEsA,9ɝ.瘞p1oλA"7<|޿aF9~|2{UxG?̇Wxtx*zVṺOsDޢuNc>݌Wtc#;p/"Λymr>_\zG~ 6S.C0/þZnzͧ%kƇ?om(^\?]zIIscгvwռXYP:Ց nONY; WJ|~:wQ/9S.GCOE3 shrߒ=Gh!~9RGk#[F\YA̅䚠gE6t8dיſŹI;6vuu~,s敺c7ߋQ慨I9_QGw^9DƯ=p_G.>ySA.2Q1cu#ב!G~i+ς|SR8{c J?О[yBDOWyUs`O|;oٿ=Õ?$&=+:0[972?k@vsZ{X>י˫*gG?xl9Kqo[Ƞs/ O{j#O!/sy=9^ʽAW9p)ۇ7 ȑ GޜzM }0<>]]C=5p+sG.{{yo!__S! z୒GO-B2nEq[ LoQzȇ,|FE?go.yI# 7ziOEZ_^=gvU%onK5{G_+IN}t\.'O't#V/~9#T}B9"|kF{Jӊ=,F2V)͟gUOѹZmF~|*|!9U("ynK~Z]X|_ gGzCj[~/oo072W 3Oza88_+KbR}WN:yyIa}pUgFOEbs+(s $TγťxW'}(О~0^)fz7wΑ=)Ms5W﨟yt;7yO~{a'oީs7Kޛwƫ=Ukdu˝{'O;Lݜ_ίG/՗5åWcט__on|{\$rEswvgunm>AK,|#8 :x/pp#ćSY!;/ >|=sAFO-=]Bg%}rUEugπ9~:7zj߂^7 B"/|=OlNr22+j<7c^&= 9{?OG:ޏZ3JO?&=)? |$p$r5/U!zQz2'X>䷢ G%}ʟ(tlU&'=@19f_>&ӯ*}^x7WTBrCc%7%z{#xGhnl/߆8r1O+tJt+'%Y'w1ocopw W^SDum\냷f hoDs]}@9C=4xHWYzZ_EP>(lpGT}:{_~τ{ 2OSC"=< [V=7(xQCyޒ*s@ZGi/L]g^웈jXwP 9IyT~|t3ͷoZP󦷢?v)q'<нׅAC:Px~|rXWoׄO5bk]\IgWY{9 N/ gM79{>Ea.t3[kk%yl%|O߼,VÒͽǚC\U{2:]|09l/\nぞ y4ɝB99)vpq'޾ȭqyuͫ%| ?Ar DOuvϏ޸6۾}^uN0R_JSS*=֣ggM9P9W;9sI(ȋ2__πB?:Iqk(c':Zt|_ms=Aɾӏ=1rO·y^Ɵ{^2c>gz͍G>2g/ȿߵo\{؝]}"UyX__7ǝ}rx+HO_qx]Z}{W:+K;ym^y+.s}Wn;>a={PF瘨iȞPOq]ue= #=\rk?IPku8S\90__%J~_z6znڙrL:c<oL.s A!z0u<{es}b97=ݹ+-ۗ'T_)-sma݇wyT~IYTLJӾKC_ #U(=pIIzH>p~ 5rbnϒDzC7^ל_i#|EK~#ke5s8W^357~ x9ǡ"?]_GSq'7 z@=aoO{=sϜ~/)ߪ3kEt{{ d+\3WK=O%N}s_&ʧҸ8҇\g ^D槭SJ/Yrx#ܼUy?N|%8wRz  +W,G ^f/!̤츓'qyOiP\N7[S{,\O`}~~\Q aWo$J>Es;'iOziRotJ\,;җ'7yc'S!=wgDb?ߍ+sMF^9K5?<3E ~L~Mc'y{|G"zdE_>"y覜ED}S:_׾2zZ+!'r.K}c-'Eϲ?J~_t{?9'^"aGAsENӹ?ɭ[U{&!WK!p,t ëKɾ7cψ r㉾3'yo(~ .o% qEY Sż>kKO~ >"Bw\ /'K}:)ƛ[]mT>$y=\ǝ6V9s2]wf#.q'K_y; ?7Y k Bj[@;sW,>%>a]Jܒ~b?Y:eIη֏^?r+Ί%,,EoX GdC[_^@ o=C߮ݪ2"~,+~5Y񟥾|MtW{ <.- }m79171EEs%m vKϯTŸm@>KmsClzt̝kt]=8w^59)en$-*ܬƯ!6>IWw Է2?38}f܎rOgғASKaF{ʑe?OzIw⿂dk޹7|6Ҿwti䣠"= q̃A5=="=/MgWӜG~xvpyÚ wؘ'}z<&2ԳJ_#pBmASj%u :W%['/{{{nAWܥ*[&G_/a?(.*X:=rS^dr·=>F{o oNpS"߽*p33Gfg\/zF\b f .XG4N(qw1J{:pѝ#;ϜRyu ׃uCoGFhGF{13|.9'i*,|؟z=ٟ<= 3j 4w^<;qg܎{}o6_%wppFN4[ o  9(qƼ2-P<  }y <WX倐{M>ي[u_}+]q2g4tG&?S\UpNԞUz.Zۺ/:p 9s%__:o:@K|9+}ݺY$-SmN 9z*g|#q=A{Agj/>/~xԗ6Q9ҷw0RkoF?BzSIB< zפ:C2zso_ =x:ԾJV{3ޠ_-?t={ =a5VlPrS4ҸʹpャREck.Xt+݇FGmBIOR|X"YLGK_#˲sq1עa.w)?x}Soҳ. 'xEO~/K|xS5ݛ}=y8\_D`!ՇSOz?V^fkzﳿ|!WW%ľ9ZX YE7.󶿿2㤗vr~ΝlU66{lsrG W=K/@/ákj? :_(9܉c}AoR]su[lQrw3q.zT:ٻEW=z6ͫ7J]!tѫG;{J|~o/S}#<F炷WL(9ů/z{^_A}n./b 珽,(;RpΠÅ?ܫP_ggZWvGrq+IXFzD.9d~B)rg#!9+O9CgK}>CxsK~71ʳ"1S#ɯ"!GGݻCu]^}"94^=UMtF??/%?S\"yy]5 󍼇G7yo7W6dZ^tּ|VAE_\zr/ ȡuᣦG^G>O{ڏ\ %1z 4oxRM9W[g'` A}&Có GFd_LC3i_w8|B_^GsSf“?ńSe/$9ȃ1g,b7ˊ)rEt^%tDD%BDž=+ѻ>p5t}̿['g:wZOY/3wNc>\SA_|UL {|WCE.|zC`KC'^W{ncp>e6>ӉԻ̞>z>rrz*ίpX2x#kj!W!c_g RyO{1f~>糽bOQ^=dfvo,^{LљпH>sH#J| rlg{n䬡$Qx1gTy7j`BrսCpm;Oş4_N|kSψeNn)<|O)ټS[r"܇\ &?!~Q§h5[ނ<SS8vhd_fx@\O;X]zb5n$< = BGoxf!OL:Ϩ=Gx}z ^|E%,'zɗ }-b ܪy r(OЧΝ~tos#7aZ_ ~>j<_pyӣSL!>^zWB >z%+ZNǒRLbyÜ7?Via/H'g\xtR>O~,::7)Y~>Kt3_J>7پOxNk@?nQS KCEnږ~,Y6)}_WȊ:'j h!\%}P{y3w z"-OtrU^M5w0΋rهW4T /Aw{{ <3ճM'7>%ZY^sOQ\ r0.? t8 Wwo+oEJcۅ5&_sɣ͞Zܳ[>ϖ?)+>L!|UTԮpe ?zkjw׆ކ ydK|sng/owڛ'\dgNR7<{i|o0N R>Vgk$־t#(%x6ㆭӴOCk:u3Y=ޓѕᷯ^Mry{>|{KGm~" G{}z HboIO ͉6ӻD=M}UNgP} n:bSB<{gbJ6cJAnGwP Vg%U?W ל/q/^7ޛ{ov8C9w\^ >캦p5ύ':_3HV|3ުx0z&8wGVϛ=*rsFr{?%?٬!?9zѽQo=w >4[kz9K3 '=y<ݷ g_8t~<a5sc|~|7b ?_3iSqg~mJ^|$zӕcsuwK4n0|e>)5{ bYm*W40 4ru[}~\}*<B_m=ֻqr y?爽q(\;[U7:V )A=c^3ܓ[!V) @McK?|y:|z6ҕK]P|n,᳕Kf/#rk<_7sK+|sCHZgC7PCtؽ-t۫.ޜ|ĸW ||dz >]nZ8rӭ)]K7*;t!D?Ugy~ //|Q+^9(R}2E[==Z"<:׷璿p+y~aSks5srӧ6v"C7;^%gyJ͙GgF|<>* r9ɧAOE|݋o%<7?_q"ĽbEɟCnrTNj`]Dy 鄕]]Uɷ]0%w-k_Y0?Bn;W~ɍ-cNn.@l'ԋ* t*>_X~bzR?ut@,#^l-=MN[2'+gv֜§?޻;xG}lrNϷ{޵ DG9okq~:pt^ܞ}O~&zL~^d'MvWw.|]'~-2K6xz?Kߣ'%'~8N Fۧ8 vo8y;f?bO~;|+HCa o?oצ~ynA=1GnY{iҿA-8tS/ {AgF>#_&Zpæ9)|' u+/r'N^Mw'\ dO往{G";tM{=çM|ͭSWu4,.yk+4I?){}R{gS*_<1gЯy'hOP%>2Gܿc$xRzgkO.=ro:Շu/zϼ@p]w66kV< _/Y0ϓ瀏{Pܡ9Yy=3*_Ob1ݯ'g|n~=5սg|xi<Ŝ-'W>=~rOܯ~>aVkI'Fc'}.Srf/SX#[x3y_gtK(>*}#n\OxkB>jrWe >d+|+ao{ZP9~Yw_!"dȭNHA9/Uq䒢G*Zz]朡/_9C>bAyj^׿wK$5ܽz/[vأ"VsbXMs*8ЙwjCa?*Mg:ڢʷ$T{+zj{7qNw=O-H׽F߳|o>aoKǜ^E(vxO>|6:)D{үyn^Eu;ß'Z!ūۨz!IBwҘ~7wDΤȡ=#Boavkkg*8o|糧Zս3W' u7EG~z5k'"SEz`oNO<:~"J_fx6z/<οס|{O#'}@9^־'}ћnzѣjzby^pZ 0o@p{؃o'Ya]4N~ ]:#SG>|쳇^-@NO|B=zdy%gpn997K 'W]չgko\/^(;gSA'ar:OKy#~{>ʑ Ff>aӌ߼*= X3(}_gM%0@~&#7s`'?g׹R:,Y[*;&W{QBC_e~utfP&"礻YY/YZrڜQFG灾%VaNp?S]u5Ɠ}F[}&ρ\jxgxԷw^󬲓K4V/}/u{zK>!jS/&ǭ%/پCzџ=;GUT6dA))œ-MPV{/ z|zߏyr/e*{*w3q_W@Eu|t/J~?7sG*<=]-oB#0xTϟw σtJtezCr;C^rg5 ՝F0x}}vlG8ϼh[ ,cKjK9z-'Wy\)GiYF_NZG߳uPb`zr.O@"~)7>OIЛ_|=& 9S*&gy֞FDqΰKޛB{Wc^ϼ Vrtw^=^xi9DA }ctkgo(_9|K>5eNϤ^_I>?+8o  ?Hy|ʛeI_nyp1% ܀G',o4Fv η:\Ê_T=х©u>q/G%=:Lٛg1K3{:8-lm( ==cWY4ߓKָQTNB>lx|.gWZA~B`oRރ/$]/e{}c= U7K"9@?|o[ Ir:q:_o^pazUec}ySt=ȹJ>BSYwMm K}GyӷΕn9mb|\GEތq4<_;sl|6Pt9_25"W:FFuirs|?~G/|e"gH^\?瘐+n&NQgy_g9q u<7Ӌܭ[/,mhͲqǧs9{O[c^>+OH2d<%3KTzE:-{W|'@r48Rc }Ow.sը߯kͿY%cy8p07|[wɍb$￾𫙗82.|XQG(#-M;HG7 =7ЇC.czi;k׈ws.q?w-?ntQ/>UxqI4֯ߤg&F7Z׌'@r%LrF<|=q^#| rw|qÈz8?r5NT 7}g~vtg<\t{/;C]_Y{LexP9`O zdgk.G#%7sxWIopΉ{)Oz1 nz 9Εڈ1$j稟 K;9w ky~ ޡ(엝oqe1cuLj.7}X6 3ٗ"V2 |? }79GDBOEi#oG/P{U>pBǬ-ߟ<Ew_|uF cjp9s/i|~}p;>;dƟaeRNVz<4~ Ѓ㗈Ź85'ԗ3c>kzxZCiܯqW?k~u'6qwpJ7t|'W oHQ.:Bc|G7rޯ5O.Ћ:xI[2ss gso7}8|bǷ1s͍À |~>ё? }T0h|*3 οY hNBϘ~]+}>ɝKh}07gм?) /fs*:8R{[8_qVܪ A>kpzABE~ zBֽ:KZ r:y߲.+g7?*7FG[-_c~I+.j^>dx`>Q[oZ+ ay ߋ~uW\{?~Hd߉FKg)j '`GkzOs5<'oB] CPSG߈sGs:wϕewлX?[{sjrWD E^ZEonnn/%_qk73:XS96ޫʹ?Ῡ0=S<499Y?3DuS#e>O}be=//^ru~39پ5o?io}ퟫZ3A/ :Cqe=KTeikͭ>@Ag?y)=?_$8xWw{h>hΣ1W/{aC$z y̾}ч//~^ y8q{D;: 7?QKdAF>_6Fv&_2/~>k%]y0у;esLST>A6|諍\L{ߓk^ApFU(x\!Aϟ \Yl?>lzOYGi̥ΞS=έEO"'=%tr3ZQI/B/jhE 'Ïݙ["b`*|ł_ЯD%)%<ƸW0UonmS:zb-0CGI>b8?plF[7{]s;ɫw G_GIQ+{o'ΥߠOFf|,u\}Oe !~~K0^3ZQiFO*oispӧM~6z+oc? }_dXvu5= !˙[Z7_N!nKn(~^rK?)gJ9a#_n,f|Wv̳cG DIE~#<%av{fH{cz'j'(k =hozE՗[?뛷s%{T8KՂW(V?8=9SM3_K{<@C:I:Ko#Zp+:+w=# DK:sW8-8N нѼA>P< xbc!-7p?{#Љ[[OE4_C G?g!T^8]?7M/)|KzܼM~޽յ%r|oGMސk< t*ϱiK_hW'5AZ]]Lo}{pp}# _{盓:[}R燏 O? Qz7h<NQλȝ^}W^:d-|₏r2O"|kUoBy^ȍ|VLƃ+qg^G<WͼwԺ/p1:#' _ ~zIw}konQ,X<0q^+ry:D[_[ 4HZ3A#{+@E}?yO+2;_wxB6jЯ̼%y\_u^}}Ot|3]O+u#'&dww-?\.}kOWyO% r!O2Y%w?33+9 t,#]\ʝv]iL6/yR+;7r9/$_^m-.\] hmR?FiЫ[1[9s>NNr:=T4'ol2=? uVt?xeQ+Crނ[|oANV+$ߛ= 8'=+ê,<hS.:czk/9ew y>rQ^gW~;D_ gsɡ_i.=i1*H^%WŞ\ɹLx k [ne( 64wW\Seɉώ~&6>\FV^1>!SO<ν ;E>}14.=={Hfo#|$xzv뇋G8\k'OɡǗz#ܸCO\yVWcYg{Cg9|Oņヷ>_1pF,Gz<#/; B|J>OoywcZzN9-ѧ` oz7:\0r' ]zГfh>?s3:OG^׹@{Prr;'<'<=%49BoK)n Cm}tI}N#:GƿaiVֹsO?&gO's/t_h<{gǼĹYC< }4̕ï;A9x*#gּb=~Ƚg|0<} _wJ}t U)ݷ4QMx?~L|<=h΋$׃CrUV^',"}#ޟ<{ѭOsylf•gPs8ɏ__ڽѾc:xgjm|w;w)G7k t>ȽBןVsgկ#/QLHox) xHvɍn|ȃϫ9`okO̦<'ז{rqrZ#~b7&pWy,>_zvr=ɹnw>|Ӕx\ ݇{<0| 6Tx ~_Qsݛsش'S|@䃓~,=KCJvsӃ>/Y&s%)_4ɓ1NN'j[͝tyN+HʱOf>S>?z~8wgD/&r|j w߽蘙G*2ޕ̣,r7:/n/*/|5V揑__`( 3'{xB97yJٓҽ~}wGc5VR}|bΩʽfB2>4:n'HqȑHn:#7|9btHNP>3gw lzK_Dx4=p@tI  >~%r rg\ϼ޽tq OnM6<|iseLVPh^7齥sSa/F? Oo{|"zo{|(zÜG 9n[?ڲϣw~N=v:~ 7ߡHPȄYό[XyՆʾMh~Mc~|O9[=J~n rɳϦ5TO :|}?җgM5瀼rs몿uoL2t {ctϣ sz)G*{be } yȡBFom9OFs9C!^)|o膙/_ks<|Pcr痜zNb;r"'ύtSl&:y!XmgbgiW<'p1'wH~^qxxátkUvs_|CwzLN>P9IxR-pv y;4BoJ<9>믪hIW98OON*]*©x^7:g2wT\42O\86 ;/.]kmgOym^Cn j0nLl >?=z* G 2֓:ӣ/+z޼w\\` GCvs Jpl۶mTlIETضm۶mcO;:gAQ^^It+JWiNl6u;G2|6<=[^^M>BB!c7g>3Tm/8c}t䇓ڼB8urrл~HF>߳֕'K z:}ޠ(>|<$N腮 OBN' ~ozTbF8>_:*njSps 5]3[9m_^WGJSzώ<ܘce?^a eM'>GZYԣH+gVl{t| GooEO qE9n+\ܾxw|߃?*}yizݏ.ѯNd_ه@YKJO ]}n{EcϤ(F#S_ $~bde/;=MEe Лr&7k/s^1#/1|Ћ߹#1־sx }_ { {_ja sx]j޻Occa֣K^^S#b4F y q):G>̽o)7v4rwO z0+F/YO59PໜKēO_V͝х+oC#/v^}ģ ݆r:$XI=rC/{M7oIXz8Rrg!o >;;?1\}Iﺵ TV83+"zg ױ:Y~xgjӸ {y3qqN_Տ5Si$ށ|(}17½ɶ{,t fm̕ՊetG]?eQ٣Ͽ3>!)+_9Ö杭#G7\\&oje'C(1{] ңv_%ѱ_o2 nAGCou4&j,vsϵϺ86t 6~/~ʸ6{Epq*C{iL,|lO &J9qpc^#<(u,򵀷oG-YK>9|$HR^]?ݵ^@o<ד@j1:!4=`GW+ܑOu/2zvJm'}EM<|H^ft=7?BP9z bs.â+7]G']'χ6uZS>?sTsPڣ+vj;i|e@0/=B5s{{SgNT>6寈Vy\z ܳK`1 /y7{pv?>1Y!g>\MEӓĞB<=1rۏI=rZF9j뇬;acψ=/"O>@Ǩ6^ayw~ckY+YI^EΜYkCDuv{:yS7c8 ʗ^{9,!f9 ։k/?tmEmg}ĻbH{8s.0j&+GT6N-Y_>dxD _D~8O*{Vw^FGi:c4̳mNgo#p' />&] 7kI\F;/u/ | Oԟꍍ9>l~U{ =/6~^}=C^~$p e#LK)i|J.9xxooú7~/80 uork*Xx'ؼK7-#t{%f+=*W,Yߧ>cjND10./w1GɿW@''ay+.~optQ`#ﲎpb|]WI/'c Q{QQ{?[yy@ CB>(}UѺV>7[|O̽h?a?,ݪy'\9q͛ij]=[w {Awh\e ɿM/,媀{\8kDSKrΣ4?_nGetZ]gfҼ0=T}^?B788" wo)N7x|!!}*KJURQ?D~mO{T6衳ybeyӄWWn~YIF 21 ^\9C|>f <)|f:Gݝ~3$FO/uu+ho-(<<5| Cߕ-c}TS]tÜڛ~ge}ț.j{tO/x''܏|Hzٳ8t>BAO8VJA{|1W 6h=ĖZ=r-IHj">i/yٻ-?>}ykG{_r[mɕk I P~`s %oW _u|%W_eNcݼ::O!Usi2ދ{ݕ5|?{ fBv㵭1Go" 1=Sչy%ޢ~uYFاg<[h}tNwq~'_-M?=Q菱?$9$腺εuP;O,NQN'znJIo7/!=9Wi^j瓽>xWcdU~6khNol$ }*[ȉwJG39g7*6w58i]սP`_#')ɹ+Ks3W?WW:ɧ7pk[l/=4_b3>ѳ>}U*G|+9&{.ҕ 57?b]slߟ¹{<#Lmb0nz&^?pZ<9"w"!9ٸNg+\W>"|e昇ہs_de!:WSx>N!Es\Is+}|Jݸƥǘ-K/gOp򁯔.m=7.iH]9S*GpdR~ͷAmyEE)~8gIsW1y9b{Myt픿Y=Pխ/7/F1~HCs54k;(&Wy2E^_f 9]s2ésS#wDGZSd3oa^/&EM?;G9 ~HzR~m ?Bo,>QtK[pLI 9LC̿{p.$hk\kxɹy`5`϶Y?لo6fs\֟\S{Aw;q?X2+9[?4 =u!]ġO}m~ "׏|=_3>\/YyW<18fߺne1ϯߑ߲/w6ϑ~:1/;u>@?2OfKo za>y؛9?DTrb:{*^ؼ0y -hcsUQ9|^XE_<Ǎ{[iC$}}B %Hj}gE.KEgZ͹cǯ>opeFVٝQȖϤ9ފ<{>y_1/f9~Ӊ;6 .n{wpQg?K6Bs5_6/\Q'w{~!G}|LM3>5xu[rף7YS8 8285{}~>e0 }9;2>ا~+.|k WGϯwQ?znr}=ͥ+V3xYҨun+𾢥7aCO49c$%w_.w&z& ̕׀o2Wi`M}V[e^s?}9etuл0jᾊϋp\=M~Kiò4\ y{b.w> zbKQ8M"NMx~s9'ɠd?M+:M`cjhn(9xiirHej,_y:iOv/1z:C[K;j:~9iMA1tscsH8eçJ}cs"#d9&},gtϰR.^uny{eA њWw_cHIђ/R 6O]_=֏D]O@qlQYcy`ps]1F`9r[ 1Mv^t'8)ɚ:g~dB89ΓY\[kL&D0z#tZHŽIK潣Guz>HrW# )ݷ}|t1ng߬^?k o>'}-U˅seP7OIýD*Lذw9>='U ߕ}?ƹQZ齳 ނ._9'+.YK>c/è,-Lx<G͜O~Ff@o=A/r!Gi_}Oމ/Z|V=[y:3CsA#sTB:v 9ە|'S7Ccyt+sW{<{>LE|~qF䔦˫<7F!~% ^޿Gv0u J84߃DSzd+,7~1.rEQ(*~?)1dqcSķst$gƼ"oݮssr~%|Pҵ?}| rz -ۓX~>uƾBW<:8eg;>Q{E7:x2声7旾󤹳k'%MW^[ù]`[{> Θ<$?!s1&pt hǼ_j_ 2[ע:*ka˖ sns+17M}s/幌5G7>DM @'XB:?= =; 'opk=96K43鹄U*:qU@;S{ß;qGg^\s<\ i;2^Ls o:\-Ke E}VkE4,𛃯'ڻ^!W/BYr:鼩Mx:r{󹏪y>tv>8|wvo#>[-ry}.oJ{O#ޑ:~`O:9L)iӲqxp޺MgKLD_KO;YpFWbU嬑 ~F/}Q|Hxs]>;?rO<={}=_/#>m97; ~COZow=/n;X߻u7:/q߭Mcn3;aǠs{dN=y+EUPz+Cg+a{-_Dz_O8YBf{Wԃ\)x+J7E$<}䨖֒5[!2h 9-tF5C/q~ig=2~3딷~8r(g /]<>_[IoKTtQ_kjgϬk\{"E>~vަὩm"wz+ot ҡ/_nb[Ρkc[[˟ .jySj}vxiq[ 잆eͷLxpA ^_w@/&谛8w'>'N7t55MuȑCsgu.bvDo \0~<0|!=̢֗ ==ԿN~ca|ϑ>$֭WO^clyZI|:&\~p1euN HOOoTKއy)p^xspb|V^Pqcۿ'ץ57=  } 97s.Aw.}y+u#e@-#g5W^=tFseW(|]Wit^Gٹ9qA!_9.9͹oɯ,mt^yW)2h}cO\s1D|=5wK{Fy~S_FG$Ϙw~o. s*0*;:z_$#o _ƹl[ARs蟳ޝl}/Ã+o@ a4Uyu]ѻW}JM4~>rQИC{q9ycAY-I }폾jpOr,o?=M{vo w'K`~@_M"}EIYtDw23slϩګ:W#m`)#= :+z;c]5Tvʐ?4?_s~ xk;E&:|ϱɘ'6s'2}pxdr]x1I}#ZOw|KS ^&tO"?yO)Vüu+}_ޏ`1ǹQk}hͧ+cY?ޒhz jsC^zQz7h>y1sSm!~?|gUoT^k_wa<8s:zsWtQ^缵rD{1O \74-'W:͹1%optjDїTpqڮ XGBAwKf/Jqo#>_=k:bùU3q3 _tsw/N2o?KH N~ηdGplrt|s͡wlr-_@ʼ9S8 3Kg:c|ΏΡE=B:[ܧW:/^8E}=>sG弑gЗ/P{\OI!_݆pnQ܆™Y>$g> kn{Z 2W7u_wU'8`οj gI-莜ϹE} /ID%*X,?UG\\wSGg{OzVr?ev[{/r[ݛ󵻹us#g] ܃9La _>A|ٱ?yN1h5;A'9kތ z,r~sOy9ڻ9GK㹪s\n|PTDxrc[=ߔoH Yz'GgE^/)=Ju??t8[}S멿*:T'7|ݣW1_>|N*_ leЙ ϥ&"A.vl]'w֟#MAp>pcCnۑqNeqO}?d6.;'؋^uN&!~pzksoS෱{bSҋ3]y[SvOA yAWVNV>g6 |]6V^yE4~D{\w-@9@6z}kof-N> xB_?NTniȱ}ᒠwύlss?wC!<:Puȏf.o28~㌥}f|-詳Ukk^$0xEzh<~ޖg=J˒\JOsx!W>C 䓠!_~>tGn>И]s|CNr_̜>#}oJ?^Jv/y"k+p &ynqKC@?|7sQrc+EͷG2ƙOk.Kx@2mi|ۿݞXS6m7uu?MoRnZw}+=?\¹P̗bcז/ѹd'Ycۺ\0=;[okRt_컺~k};!yGh͓uӼn!ƹιO%.Y B߉Yy<ܓ (P5{3GJ2b79}_ޞJ~l?Uڗ'K."䛰ǡgʇI3}NB?WΗ;O.sK2tv~ϗ\Ƒ7Vos'+(t1:+iyr9/&y7?ǼW/o??='uɟuh7%;>gt=e( =:0O W=6!9D+辢̹ܧ/^y8A\t| <ՆY}pzFL+)܋A~8h{'|o;y;'T>G/>tm?\ړJK N>XeӰ ^쨛py ɓڿ@n\=v j*E:>O׏~wt!(KjܪtK{|ӓc!1=Ť'靃o}\q yݜ ;N.AIsn}:W}Y:YN,sAW#{e/;ihyTݥv_>%ůxZƎ#sFMC6 ڊ/'^ZA:qcL&myDJ%y33p5T"<}pmrJQI+:u+3F.y:s)Ϥqk<>:O{+J _C,zSwrJ*JW]Uzxۑl%x{{L.;:9|d+(%~n"鵷GQic?uBG>q/QO*x_wnKu\pe N&{BCNKrx7,g{yW|OZG{9">Qaϡo%N>;>1G+'0rϰ+Ɯ!ok7?tJrW?9SLYOqϒ5_KZa˟=0_6u}ໂGbꞨ>Pt;FfBIke߳=d,|rH왂 W99=1پA;NvΝuA!;V+ϴs(AkGΚ:}#_zmJY~:d\}&zҐIk UK !}1Y:zP:w Co En,=FّMG;/{03ab t7$3_ܯ~Ar!2{Ln^ʆÅǯ~' |-3>V 4voUQ;ύWsϋ\|'uW7V"y/`>{~.u~smȍI4f=9ӣsfN'SrpHpc Hyw=A>!~Dt1Oy9c-mO6a?},[e54__l>:t gz3rEؿi^ [؟^S.~|-O4)]Cґ lB5ʱs=qxC(wuCyN(lvo1?40_͇lC~\>ps#wr͟7wR"'%:F>>L)w^*tfߙ2~'b{KvV;Cg{WN1b^z|gϕ_tQ&yM_i!0]yosI?ކcuo}Rƥ]^瑞%DԼ2g|{S%~mr kK'2]J)Ega#'-2xN߷¹نWi8\sGv}]tﱾd>C}~_9= ^ ~tϵ/ZM |&{tӦ7*פwrCå/½<ܗ-zګw=̟МEa̯s'y^01_¹z%s_zN؃c~+ '%߷;R9 g}:C=CxB{O~wJosqkKƍkE,ދD3:/~> gGwM(<~"ƹBucK}.NbJ?cs?F5gOsgu^DEFuaGL. 8xO/ODF~Zy]Kvx yq|^}a.m+;8s=n|an$/\FxcNa6~Iy\ԞS 簯Y+\Y5_ 1`5B$ńK8񜗕//^S'rOf/Zy_^1QЃW*yW;Ig2ϵ 9+!8g ά>I1}{>82qOݤ<_n{1xJ|YYA_=zGs#@ zOZYyqoެ)T?#pИ#k,zސrlcOsZ>Y.<QUwچ_p/z4{;O~",R_i/O2:â+EL-x$!{$_\>qi\%zLIKG#|mzt\p{UyG=E}Ϋ\Ms\;D߰aDO$'B7G1.gl3C$J{zBGGy/CPk<6YL}E|t瑾296ZxC7r/d¯g~wރ7z##/;D>gPR3CގlJz"= K/߼Ssq2 uƞi'_47 >-/T;_轨^}4>7")^֞~VH|;5V?zt_3=99bAYn"^b:XQϿuQW_][x7x$xSk{ip;p'|Ew+ޡx{uF gGܑ¿'/.~}6s`pq5zOoW~)As~UstAՑ' <=|j w<3ty;sO?}; ]11=x7Gҙp?ߎ:kܻk?J{CTRz^ҍ#Ǘ>:ϟK}ϲͤgC׎_s]Qs& J:/ot9J0yO̷w(}j׍f(Ob޽!c$gcm6ֽ|H(i']%K;7|6Kث"Ĺk_c|YOcO[r˓[BjCT{ oб;7Gf}F3=ԭDa$>^\zPiINk.pbЩEny%ЫW>SHZG<ǗmdS|RLKҘz".m }{.Om[ʐK~g_-~x_$(ݼGp4Ii| ?msG=Osޡl}s`^:c<(O{Gr#ɓIƷpzMmA{W} {ɪKo}l?BT>Co) [+1E|64Wk;@䖏 y݅'g&AXISzؿ@N_9coƏZy;}?{ן^%Oj O!7k7vя8OVO_<猅+!$ie=_P>T"im{૘+Kh/_- ߵ=>Fd#x>+8Ugsܼ[~x#ڸ\C/__#;+{1U `o|CipG{}З{[>y4y)cI_:jU{G+$3A$ j)boEzw3/D/8d0^Ob7ȟJoOAceH<8[O]It97}@WMLg̻y1>-sgcbO~Ln@k\il/|lI}g S>'r%ZXSquii~η^֛=kd篭h}+,̃^?9{._Ч$ώ؏o5^T'l:ܼc䓋.i_g.,ύ$-y"Oۢ|v*T:eW~Ş`|>=#FOtmwF޷QKK|{=k}k(>%z攨<+(S9CANwU 'GVz͓@,~xrz^ȟw<Wj-^jI9yπ>c~sslx&g'd<Н"sテo V8Bo$3⽍sϖ syC=aAKqYOtkg *n8O9+8O1JA1o|YӾ朘[sy8Lb#ٱf4GO!/A{@t(~9M9Ĕ|y ?>ΰ󛞓rE>G ߎ>Y͟;/ ODoN}[d+'?3YΑl"*ב׼E9Cis~67ȩ!~Y!1OҟN.m58wM!>92yp0{C^S/.9|דR!'2dѓ}pYί<1|={|z$tL,F'6Cw]c蓸Яql,.(+8O9DZu/-Ykr곪_EI|A薺s(=S~:?Lf85/>aҸZ3n}rWb~()s"^9߄{};ǡ~Q0זހfʅ'~wZϩg \9Qz,jKy<'?u&oz8Gسki#>ǭ͖ST~Yy]1~bCt:ƹȗ>{>lt?u>G_˂'=؊ԗJNXyys}(9䷣EJ.3aӫuxT=Gbw[K:0Kߕ6QԺxɒ|m|1|8<vk.}&wPu>tNWCx%<59t:AϋkOĿvԧ8c4@Gx!!W&Lox` #y⹦p'g>@l{Kݗj#{!n_j?={<:9zDD;+֐Odtr.{ V}s|N ;\J䇡{?|3#%^||+#re fş1 gNjxt3IޏثzC@W+\4;j9wōS斯 ^?f{:y絢{f/W'\:wހ6K!',@4~|z3 ,^sO_:c59/?\z ȗC}{9NF NS {]CwoHwY7C=zdup{oǹ8iE[ކY}Ee[3 sO>{>gs\:/p5蟥o1Oq~\t̋g!| ~y/}窵}>W S@>|7?gٛyw1jOo#f_dsCώ\m>?Jw. }䗣G_u0? Ow`V9:߆9?~c Yc?{z۹Ϳb:T9T%! v+~|Xg> UλE?K Kr?^zmuouxC=!7vk?m|9cˎX_a ?z׉a|ti܏bs=r/[C?:zsܮ' {!r2|ŧN.V_σi} tS~8yˈ;/6ا!r?sϝsmγAt.W~?!_/[:SMJ+{g/;Ng*#mbo*<:O5&B䛡ǯFVzts1'97ϝ>Е_{/ߧg\Y&?vea=& SmݽXQ|Vt+c[rO|~΋zc}}:;Orw_>?Z>ZIYw#ϋQm;+>>2\Ss=3boY/Z^мe6ieO#7Ksp<|MxF!j87qU?XVy)[sOuW/9@~tx:(>ѷH7L.*6 zɚw}^orwd&O?Oӕw~_)zS03j q#-X>us{_˘*ْqub~.=&_>I7t?̕Ƒk.ߘ/<r"^ʹm_s9O`hV<"ϱ_y"CC^Psx&'@~t1ghea':V9vZG -fuLu5- jg9{jk"1ydG"_?/t'1W3&2Mŷҧ<>gZyH=?<{y6VJw~\C£5d7O?-r镠<>p@zuSC'WJANkʿȿ8">>/Ny#,~EWGq=z.aDn=8̹䮂g*?IC :p-OPϽ!ݰw.W:V|'Go |%ϋo?*A oayֻKY~TyIّr*O'{l-r_ed܏̜=*>^ !4:i_N!ѯ<װ~ZS}:\p֍N~.]".PohzK߉פiţFDU{3Oʯ <䞐my! =s p2t#Ã>=X:؇G,4s_DDg,||.;z*ᥥqu_7/ VB yQw{oE8$>\o؛cs[?׌{ȋJ/Fϙx?^C>+D;>]>Ş7x{z\g'UVV^FAȼ/ n[M[u.=%>'{紮?WrڃDnQ̹2wr?缧^ p9u>l̠+:&W?ܣ8{N_V=rхX+n޹rQ9{L,w]/*^X1g^ݘmވ{ y%̫ܳUCNv9/Ͻ9tN\p.1xwŞ^]Jq]ͱ屗s="Vo NWKg w_L2(>Nzɧ/:BO=OO b|k7fg-WsjCƑϰ}ج3(#< ~+ԷǾ  ^'Q3!0qc l9 {mQ㙇 _7<:r}/=Byw~ğK{}tB0o\w +v2St(䑑s%vx 9x/z su>i>/ܳd}:CӚ>)~~JK7{Lus`1x{?чhqB][Ͻ;B|>|WQ9ʞ.Dy_ռE~XАso1#A=CZwl?r2᫵MǼs{]~,Ͽ?D?8p|a::9c3r\{[i =p$1'>8B~^rM8O m~s_{ ֘A|&/{m~}S|{ЏYT|)8E>ʨSFw YjS:?Ip/u̗<]N nT1{t缙],nһ}罖9 \ -NW~m"o`9M}Gz͇kSyʹn8+^ۼ{ s%[?Xz~>ޠ=+=UyR|_U~WI{;[LsGC?g9AN yLKt_W^QayvQl2gB >tKv_m5ӛhFYJtk&oAiYtk>z\DGxyrJ}7˜V;@]Qr?$xѐ6ԯ>הNxGv~'[a)i78D9ܣ'c},mCEߚC fB^7=is>GuSFǁ)E>d1尥+(~# La"b7s>I xڽɁ'IO,}W_8rosN_>MT}zUS%ǂ>1;}Kϲr>W|`x| T8o}=|5rb^ПpӛVݿ-En}397[QCuM2OˣKI_gnf~m\9ǿܮDlp^š*Ϭs528o˗_t3C{nnh}>oX9lbtOuF=#xZ׏]8pm3W%o(^=1= ' %Kh?--{sgnp @kG̟?NOκGW=g|/l]ssq'$wS4:.(tѿ\YN@zN<}tɬ'5ΑŎ<koAx^[9d&ќcKӽm^oC|`XG͸%y{T:ȃG\Sxl8|{t?L?QvW}Y=}eOn+9Lyt\K/4}u\<|eC(]!@?JT^s/oߡJaړ遣ρ`AnK2PV~t}BI</G-OH9n골<rG98[A?dS10{Ԭ?8OO>5?@^U&z /~ ~?{GM샱N 9N.*='4mƎ! sjO!&:?ۺ$ػ{k'8GsdG~-g#??`wW%O>>nC[c7}e6_$6ydEMwC>Jj~{%m4szSF7sc=/P4|oܣ8Q9E9+[X6參t>T8N}\spF2F!aeL6=c4Kzg~ɍF^B7}Qo]qc5n\I9qKkɇmޏ> _L{[˻W9#]ԟ< <6Ii)ծ*cqΥbѽJx_qjDoߘ<veisR 3SC tͳ?K'>'gɅ_~޼9Ssqܳ|E Ðc@08vk;:ף=*99ioyG9|2\گ[2׃o7oRXd./ONWazk&Oofįxs~%[e3c?lҞ{{W'|xx؏F_\q='¿+UHuskn]W7ݬM6=ף+}|xb>}I/2S0Ǟܯtɱi䂱#\a~WA?@gcΔs}Yv~}^/x]Ӡͻp|IySɅ7t9+ͦi'_+gyrYG״Fɜnu~9"^ ݽ/zNf'"E{/ޗf ژK_ &ݞs%'(_9_ݢߗAs _4FE颲O7):tt' 4|; 7xa{ $`Q+g\Cx{=&g7{ {,PgT[ɹ<{(:{}ֱvnٙG8Q9E8uOç;yCB{ )й.}"{|3rPyycNu\K.EII:?zϦ)^|HNc3«Ld|fen{m;ZkWz ?7>ʝE{U9NS>j|SiC=&u_Hړz<r飠g{sϲ:_,[@W`_Cpޡ/j}phu?9Bo>fGIp0ѳ^?GE%vp܇p}>*G?t\C~=yŴoy%='SrpʄG?~ybOG3ߋ}*[+Ovu ?D_]>\ܲWiF_W]:B|\J+y@|Nl$)'[. F}>cޒ|シ<[o|8ihOg:ϰ׳ nh\4G}iBoZ[Rs)nz~Φ^)ߍq1?a[=a9<=?ߌ<}Ai{OC t"'䩦H/8{^??~܉9|:/Wn Fw}"a~ak^F@:s9sLWhE^R8"yl1v?'wGပ/ [~8ՄcEE?:Oz3sunټfF _|=0f[Jޓp;㠇9t&S+znޙ{\+xc~n{)9}?g|cݓ|zx ymb^u̧)KGqOP|* [1~jy!7~ηguZrO#^>S\<>Z+j)&.~]{Ew2}l?ƒU9عIxz#{E {q綳|7L <9*4psyR9[_VWnQk!z;CK,^Ks@^w ͱ~:jYxP=wwo:iWVr'=Êf{i2^O9|P3d~>6لYj=u|[ד+pxo+*\9} 2>e΅}X'L}o{1;&s5s:A:t[ јN}(1_x= /zD^個ml"?s,l1?źn1|.?'> \F(MݗA+=O[O(ODb[ N*䵤3}`ωs&17(_W_QT>|%(f?-wg=(V毯\kN;;1<\|gۇ_{6s 6n+**M*ɯt{`wW NBx8|Gwco֠+:'ΕN.i/||믚 u՛݃}5>y*?OIo#Ǐ_}?}䊀Oqkͷ}<tC{@^1z{[TYZxBB t7w{daߩ3SϤub~%}BA~UxWlIy//ދW}Ӌ?3>l%ZϗMCusd4΍ڪSy%/~1IC̽|)9/3) #{ɅrwVVA*< 3]Q)| DGOp{gm#^sX[e9o7QGks%)79o0OuD/O~a֝TvQt [\$}?+wN'O-/ӹT&a-(>A z+{97?ǛmxUE=ʼbs ??{a9#>9~'gNg@ys>ȉwW9j[_m)=;1zg/@ou1UO7'ǐPz҅47ѷ>-w㼈9z/V.fdAz*}j>T9;<q>]%=\}B-{ |Ϲr{8?OOKu ρG!瞽;f"g)cspX:$ #ܣ} {:z,rtro'o%F 8i䇌_:_痡ˍ ^Eѧ=}k =Hآ{Λ@בnз^o?OWb_ž%V ZvxWg_0Nv/ޓ\}.c՚C3+;Ow-ZtS<}EyszCN;G}?o2[{_J?e~~щDCTP-8+d%;1ޟ{ȿ!۪\ހd9]9vq,)(t3dOC .>=͢sHO=L=7=+^CW{ޘLwIs'GS6t3ɉ:'?}q/r¡3oֺ fw46 >~'}?@Zs_{U>=zØ?s)qe;1U<)|eÜһG{yrk=<?W"}Cçna٫xKhM'N1?&wL.. _sT5EG/x>OϡW\l٥V}15.#qN<}| k>I('slr ϫή7~ZrūD^}o .}"9{|݇<*ׯh%{;=/IDϑ#]ԋļH{ru@}ɟ'Ӏk=g'3_r>I53Fs Y .!(d wQ^s!˝`|=D>vW̧^*>nߣOy?[+;\=y̽GF}49qz}XiSz0Ε']Qrjy_kWuzQG+]\Q3 :0g_>:g/֣ܿ;\!~Z=@|:G=Aob[>.twN=7h&qy#z(&7O >6rx7oj1'>g'pcksIO:KtWԞ~zZgȧ~ܡk6tZcȷFM qtsG|9\EW* :_>QrJ#*5?S)}zfEKז^zֽ9\Qڃz7K\u/47DXE8Y' K9K5J+<1:2g%ŧ/~}ϑ<^y\7{'xh=|~ʡCk_G 931g#cb爽,EbnzeW]_%932%߫sYKkN=+%y%:{5|5ug'}l>{=G½dr>ƘKs)|sދ~h)>sop?gك$r- vu\nO`k/{*ʹEs]ȗz3EƼiD10: u Z ދ\lG=8@>Ti/.>㟻#>o!Kc~%+k]9Z3n1#6*^|xIts8Qtx7ȗ7#p?ɯ/lSRn Lip#/ݭ%Wʎ5D/\O\e~8Iqr! ."9h $W?ÿo ЁNwӻw\A9jsseoay+gB9CEm Zz@\9#Ls~ﻑ'9O{RwҢ`/xR>h3_CwEGOڐ'9H¯C>H&Q3<6W1ySG0_O{wJWQs,:|k;\s Z -3ѹO_\ݩ$'<\O7䤶A?_ܸdW=u|f`:r bsxVt{@ob{pzMd?jNz\>%۪q?O;m}wqᇈ$`K斡s 󡟬uK27hϣiwCR{Iae^wZHOܛ/rv;?gEs7noD/}/ǽ[kN2=܁/x*SKz'Z/K'C~ WB z\t?_E|2YL{fw&xlZɃd\lu^8+3ϽPymDx/ϹzrKS/;\[97{RyR7O|w?coyg.={sGފ^+?}TwrʹIim~sѽפX3p%/2}뎺>eLy~~Џ7bOj='C@mMu?s&ד' kzc. y"7@oB0-K[n )UJ dvz?(Wҍ _?Hx]&ruT} N?IGf{Ɖ=}Yo3h?};&+<HͭS.{AxM% WN%;Gt 䟤/~[|[O}=98L*_]sm9G/{ aS'\ss|C|HYR zbecDc~9t7,W }e@uvK/ש-sA:**w {|?^s|::ᐧTAP0cW9 l?xma׽AD2]a>i-$'?ǟN>UL'+tOvC=@{_n*8_ >=O?%g|\IxzF#wWVN,yW;a|$LJ4o^#*iЗٝNAÃӧ Ou*n7|Ğ3݋c%w&1szt|_1BOO#&bBu:۽ާbГϣT}w]Fy=i%,;G@܏1s:/G\]Q"tZ1lͷЏoD[vi/1=)|1[gXF86~rr3 'K ٻ_O1Nۚ,/!C=09;ëgk>GE}M]澢=pz(݋m=Gy_}锚;3ǓZzs+ϝs"C^r/1lMRQ^1|R[xDםQ:;to?<3kp>վn y54o>~+ W*=>9WQ7~IÄߍy!,-/]cuoZ18W=&ύC@niMV`@?1pp𬪹(4Ew? =| }yQ8MbWwQ&/^dgyJ2Ű)߄xLsy ,y͋[t]7nA3|4>9EmQGﴵ7gQ{L>0|v{cT3a^{7 {G >g Wľ?|X[{E'Ӑ<']嗸y=31(5r[ ʡ#?]@ % _ј 5g=ļ<=]jYݻ/=zbOC}w|鱦GysAbD|X֖ON4BZ @'X˸Y/$joh~s\0|D2{4yAYZCi|%+' F-5o쳱C|҅2旑;9u{5ot>s PzO)~arS%] {IrukBs!#*Q}3/w.O~=8j$8ϑ|KN߈o7ȯDW-̓CxqpOz!y(7 _o|5 ϻ7z;KKO|[|~ _{>\|^j7x; jDK~<6p!魝?An |{"_ (s ?'|J&ɩdn?Qok]hGbs,9Mb.s#_]'9YD/8 RzOQ"_Lr[ws;kM#O>iS%=#{#WV=g]N|ϙsܛ?պՍ8%|oNJCsF>Buu'_y&wvW-=5U= EȭO'Y~+?6ҹZ]sq>̜[{^z`/pi;+Eti]ձe3Oos#[kL_ jmCx!~ym#ߟ\Ytӂ9շGw(&P]_d׃{>7m.y;>n]=b73d8Mbsm :wOI8[O߽t#'5E~:Gyz~K~#3o9} No=S?ؾHz4wK_ |m옧 R='o2{++_2\߸=9cbIDK~4ػ9sL{~ѸE{[{:Wxr_|;Bw^r.pts/y%'-yϫ/|;Cg\=k~{OG'+\lK@/ _9ˀ\l>@:ZK>O;Yl=:tDȳl(7HU.Fzٷj-To:>9<9« 3X[3^Ƀ":G}]y]쑥ǥ!8J}N GeyWdEtf3X?>3ss>s4﫰oGb?D9|sWjR_+ʯ]^>_1w?R/U} 72?۟uUO$z#nнL49}=@'J^wN\gz/߉8o8E__sn|DžsKk2Ϋss"'=bW#׋+#iO&{{sBf'7{GOOe]Q5߶envˊS8c.ӧ+?/W|tgG?׻Yt]D]}ɰ;X> EWA.:5#|C/.?ppX1oQ~-A;EDݫ~ \9M{*eh-Ճa9C_01+G.+_#j?X{2{ׅwEx$+71?sTk 鋨zU3r=8c/9ۢYS—ֹLO [sB.:z2# 7y|+[9_켄/ |9u5. `i 5Fuťז\O'R,\wtgMb{*Zν?HO9|99&:|Zu$ âB4_ˠ`b?9 ˎonXUoqtQ|?覚Y/h@GXe{ Kc?y37g+}uy> #2빯{tܿt\f^%|wk=)n 5"w/ KA5Sйc䇡@.ܡX^B{_}@ҝoR;NKo_Ϻr,kz7z2&׍|¼{q|]rR_k@P>F+7zn?^/[M93o]''[?H>}R y.}5OܵOl-?K#97빯yt7W89aὈ>8丐F`}urkgos+}bq1۩=+aSe=^ =L #" &87;Wc?zSG ̯9"Y_K뻯DO-V1{uG $zރdҕ7~ԞTLk>0zMJ:oϺI x O>ʸIEKצ˦? KΖ<71weЋ>9}x/x>ѱ4oԽ# +Z`71G2Ο|_p+`bO'=Cj}'ymؿC@ 9@LS^弨犼TjW1'J^[gG&>?su)H"9Uw~g׮gqZri?/ >o foQ?ُ~Xѭ֧]>u֝ςm= |{s3m񵁷g=m^VmC\#{G_V|NC|twMwЧAXz:c_KvtQLb3gu>C'+֦sZL@}eYœܗ}5?p3zK#/^p󿧻kAϙ<4j zj^#[gι1x7*<45g<:+n%셜ڧ%Ov K<#uKGD^12z$Ȟۑ_-r孋{E/JymǢך&{W> wub/CsxjE'Eѽd'/>pl/#ߍ<83WױڹQ凗. ~U=##W7_0xg)?Suk _Z@s6ENOq%Z\KÅWC68B8~{r[=5 -s8:ھ3 YS=c|m=q~ޘII91WT9g ~ȯDޣs||)I]A'礠{]~N|.#cdVѾOG%~QM$Q7Ͻ,|5yȱ_yXQ]ti~ܓ|6:G7u̻Pzwy)||Oz)Q_EBW^1m ʡ,'[7|3͉t_c~ 8~=|Sco x)~bڭB}~|~rt;^-ωޭt2 <|w=@ 4yu6 zpz) w*эI7s~򸳓펔 }~9a'G5\=[mpNwٸ8'>|󷹥\xO!I??L-ӕƎKۋ/G>Jkuߏᾯ"O.}ID~'JKu?ŸӋ-:<肋ES@= 9iEڨ&W\|MO I\;thW=L^J7۲]z7\/;Yy9y/\oyБgߪ_/zψz[A7#u>U]Ǟ&3G9E9˓ N9JvvYtzK\r}1-n~~lxHkr-ϦdK o,]ckoqx]4w-szLGD.8'ѧzv$ׇ\ACj/'G/x:twrz֯!Sk~cs8'?$R|u>+OO~6rSE?D :|x[Y>U2Ý;9_P6n昫PN>[pd ™97ܮg ^9}7L2?9/8?/+?7yS]֣v Hg1ݺywƿB^389Eg\&{RӞyn{y'ӓqLs?|]Iq >=9i*H.e yDDr|Їq?p8ZdL&-q-ɇxdGBO+CuråӴÓ2V.~ DGVCGy.ɡ$G1ۀ')ߐ9*QH6Ϥ»7_i<<}]I:?}_ӌ :}9W9' XkGn%~y{w1\: z6sΟ81:3gz#/pq'~,U~^ErGqOۘx'SH#qx|N51U_MD/ۚПq1{W%(zOLN3jO φ^:BǺĞ'+!/&AɗF{3pKL9QFa g|?~E\ѻZ|*L LJ>R=ye?ssW'x|t&77Zikj{KGݟ~]z>=| 4"|q`INK?y|^178h>ܽyK?*_{ޘ7uw>wO}ioe o {Gx"<:Q:Z Hޝy\.<XΏ9}<>W!$<>J}'A}}s#}z蘳CN _|QS_ȉ3.PBy'ɃDW~H C t?k3|U?)WyB'0w3伍G>_VohNG|%9cUjqw/Z.> FsXv͏ yw|45^r ć?rpy:럻@qt%&}Cl2E%e%w_-=yOJϝV?7>6N{O\)5Yzì=?HE{E_&JxP5qůty|O|U9t?Ӽz6vNO5k{=9\{zߖzo8Old{%̽kח "K4{3@yH%Ms_{\Vc]Wϕ,:*̗Nн#57ݯԼRM yfHWq{*RDt.SHOy]H\̵p ?ϟƝ\9~{l~na+?ܛƁ#^uZUYԗ?0x+_B]yЧqHEcoO%;:Q٤ ZqrS򩋊}4sϪoMS Z_VrmUZkԸ9kG|=L5tL85Wt֘Fz~UK<{ Z6s67]S`ݏ5ޥ8hfh,Fwj=׋'z5WrΏs ɺsGhn=?AS.{l~w1ڃUsuX*O:g֞ν ;H]@xퟵ2tܿqK'GՙIj:#!5Xz8 pz43&'Kߛ\H8ϊ{w1[?~HG4?z_jU<lArxu>_s1tH3 7 &W_~Oϓޒs{*7񍞏چg{I/~t\=LM䘳˭C]]|" :g ڍ·n zl"|%GwyE|Y!-=9hHOz\lr:M.=>se[6֜ž޴DG ޠ~<.R@ɄnR>ITkޞIo}nw] \*s;NC] :0F$_ˮ%_ȺK+|mZ[]֞}ddϦpWg~z:9gl~'|vfCzdckknݦnss5w:̵w[rVk?{%WxUF^[/*= - SڷsNsҸ_SA.k*7~~0ON!>yчKVySgwk*ֻy9΍WHltqx;/ks ֟\Bx8sMZ5O4vw~kud_98;dpwTeu}m/8ܦ7.^ο9dja}ݮ ޟ.={i9R>Ӵep~~vӞ/io3c4$o)9Y[:O½Y_'Jͬ]m@/v!^Օu> O:G3{[' ׏ρ_@9g wg>k!XZ9fJN0toqpmFnx7Å3$%v۾T߳{W+NdwV\YSEO\{ {{,7@ نs;o9Ux1n_ |9BVʳ<[b?!Wuttog5]_:yŇuV?̓i]lf98;s1Oa~Ȏ24ZzoaH6\y{(޾~]'[wBy?ɶ=[MsN]'^ڗ+}%_*'8e`s6'Ә>EyΕ̈́f[S#>=]^[V8Rw~(hh`h|'==$x|e7x^f|/E|G CCNLr[SGG|_pƳI:)xT:NӾ߷5j{>|p|(򕥋wWan.{KNc͔3\P?NCg^i|5;-ndKWGHM{="ݛ7y sHUGxϡhN* s[C>yi_(}%{jIӳ W5_)4曻gÃ%_oN{ʹܧ=?=X|Pܧn5|=ݣאw xitU[Gi!=?[|l>m|f+.sd: ]&|lc6>#8n{ZO#TrNt|ҸX:?JSEx |Q>^ӟޛL*0CiCFI0WUownƕ3=r9*kA ;J^EE2sܛ,P2x(g;7R "ʑOt' wUI>A}^{pZfp>4W{t_$s+ϡpIY8!8my܊rؚ[J4j5&}&G;5qVc[G|xg)hO_96?7K7D^'[e|^d++K t 't$ ;gu?645Jtp֯)^Ehc5r*tn>\y_%+IvS/*gkcrݢzn(vҞ9]K_ s_dgn]#<̇oE<):Xzp_ l'/Y=e{0E|w?yP}7u?u&W=iMP>yuCu4vυlқ(;0>w johUk&K?Y-t`+I/szx]t2N*;̽g*%}K=}\yryщF*%P)zQ k.?-׾v?:[ﻯƼA{Һ7+g,*uΌkk/>/>!s9i,{)Qs&|Kg-Yd(g6/s?MR1`g]讻5GS˧>{иymtn";tp?hOK?:K1~{5;h{wŬc_ԗXr:Z&z`gl5_6SArAmz}r acE1姵9Ժ&p%ޖ90V Y:T{ұKF?[ϯ;L~C]rtkٔ=esC[qyy5IUL'\}D>w:9kצ4Ÿ8FtS ,x󼃓l֟&n狹 dΨ\h=;_[vɭ\ܹ_'v_K^^M$W{?XCquo8[[}V֖<[V9[q8G"3{gEgonN">uD-Hkkb?ݓ}WmryO/CMֿWKGu\:zOH[\Gok*7 \}OH~^\sro[_{=WPV=uSJo z{'s7UT9])bhԮv.YfOOgo /(ry.|Askv,\}kbˏϮ1> ͹\uHgqoew)?$~?}= xf>K~ϭ?7d̜|J~^#ηz~џnܯ< fzljmy&6g|/ɝ[n$sa:3IO~\A~#_=ZIix5'wtiϪVSyR~8Y.-(w;cWH/n hsƅG=*4.HTš˻G _=mW46u?yw-| [tns.^_9Pҙ/qo죁.q^ %)hn>T:qEtnw$ ҍIOT=׍޿/tϑ## ڞy߯:go<}67tSʁL?T#yF}yY)'xJ>z/G2|SJ/w}Wam(},{C8hn,^(YV}ϫg +|m76V̟tlt\wF"AzÕغI{Nk1ǼJ_ׁe_sN޴ެ)!4V>} 9Ew2FtNQhz褻ُ~s-j; =} kqG{m/ ^ _hV 7K迂7=~W=G=oo+\#d7i.A/8=8g۠CW Y8Zrio/^ZKg={ߏ]n$i|~<ڧ-lk1?6PkyBsy5;NxjiY<r/+q}}x}pEtammM ~yأ;:y3GQڹ99ko4M93n_%]_=Gn3?|3tx|Gh"loP}=^.(w{g ̞мlZ t(FR?ig[Ux}t׶3>BHPOb*c_8ļ)G~̏ym&nq_W>N, ur-E'90A')-NtG?6fU/=~il[pV)8f&e-^V6ܙ7+(y>:y櫚#1W`Z?$]Eoߡ{m%\'ΫRe͟e6j~~WE9wZ{Xm_ Atl;{|\s!+΋{:={zGJv|Js=SAѮKW}e$k~eJR=vń9\~s6 -ky%Mۜ~K@[3l-wdrCbE'Vϔtqdw=[y_ ׶>xeG7̹^}{-t%ţ5W**}zr%DtꥊV+o螮l>OjxFoWҦʷiO½6qF_"z?ҷfX6^wq#aھ?nG{>>*Qi^ꞤMmQZ<<~n=>{< yԫܧ|v8ҽL5rθ}ཱུ#+f?~1{g:΢b;G X>^zt xg4ϯ2}@EeuCNR߈z\kX/Tkt?a~)N*⛫\#=+]Gy2y:Cn1փ }.I(Wvy\>֚}[~^>uv=zͳ.s>[<{{/5^㼥h'4&^ĺwuґdbܧ粣~#yWeG(ǰ7K|#;-x^s&pƍG={#γ+GCYkN3W.hDʣIƕ~@g[y@U.^|ֳ~o2ݵ?I7הo=7t'\Gvpkf4ކK8kΪ^\'Ӿh̩e^4G8:e񥿇ξ/r ط'xM}C${O{Iw[>+|6d Zo^T{}S"G.K/$Ϡ15ʖʿml]יƒ;iN-ls?@1 >._E_+ߚ7t.9\/Y~ K5raL,/YX} Q?M|~?Y|9W߼qGxw>R~?ISؗb~wF;[~s<.4W8)ōֳ㷂|.Kn6{Wa~N9*;{:=}˸1;9.,>{BEz dr7Jw2k8rWO |9lU:Wѩm̦s2xAxds^]W @9sjL-(-|BwB-µ󙔟O.u.C7.qw}si7/<{Jrˋi@~iM?sy0e O'4QZ?'=_? N=ؓ'_6לH~}iEWp>!|䳶7ۙMڡyF{ZIS+g~7 |Q!H#'W+չHg/^B"oP8 ~ĥ7sﭗ+cu8o%s%Oo"Zsu={۲|}!O~h:7k՟s~n%$:`?'s`u 2ށ:7>ސ;gAZ_̤|+bEjq$;G9?a^ ;ErKx΋MC?c0L1y+w?rt~y~d빟]>֭w'WTkڏt.):z sżL& L-*yIAqmOKovjgq{XG⧞ {2yG'u\G=ΏN\1w >8ÄgHt&W=H8^Ov1uo{?<68cw+%#{P6SG|Ot}o:w`WJvվW|e~9kho+ ~rȫk?=[5D~zix[1yx_mA{=C;/HWsw^TViu:g9xp}gS%#RFyt5LRg=ިթto/@!M}k䙒[/uH/~>r|Gk~s%|~8W׫1t ~~0} |7= rx ]+fzt6O֗>y2[KVRi,/}S+'w/R>|䷣h|0jO5eڏo,1kͻx^R|Iz ~9xkr7p1zgo~H|/[Uug>z gI?uUcvr >Nzϩ]9b/3o>^s}O1ίQǭ5_]Z+}0Ӌ0^??tߵ)tか3LV{\k{#=G7S=}k٭-[\#7<'eاk ǻ8L8s9+DtS8핥os/|[zceOMYƐ ~~>bJ?f-{^ou̓YwN_qȌн=O%N< ;Wm碠W\$3z' Oz14Gkޠ{YosE?Y}'='Z9qkKŋo||WqNw~1[D.ɝ z\#O $zV|߳"z{LE4s_ǾD Wόc;hq%G^|ZkY鞨yCiY{+>R}C);?3R}oA+K%XxM~(t/"߳z;|$ndI(˞xjwl[kYN}l<9ʔN >q |3k$LL%E$zmt υ\bYK|v|Bb7H>25>0'ȟ}a{qk O$Nj <zzp#/z"{zx< 3'RJk)%5ש(_=r,`V7ٺU' Nҁf}c1=6C.S{'sˏXرw^,<7}:k'jk[.;kma?øG~]Ð/>ɼr7e^\'6rr/FNȰ|o@?$yB\rpڮkoE8?:rF^Q8mCWOt#ZS~ArѽW^=CūϡtF~4^V9PY~Db`>z?ֹ n?3<[E\NS' p_t^+u3wǁҫZ'=y^O~yl!yr*t->r*<ɦNOx^+ ^6ys2eqM-1O}y5|R+I4|FuN:|k16ٸ]á7s.~\egCLcG+6P-c>wMT<1ޢ\}H:A}m e7ېH'[>{GI@|>_3pvλl;Yc4O:@Os~J"Z_{S.y*lЇ'C+7g|I'zJkǵݷ8q^ܬ>t_S_y/+w-Yv:*|Yo|!"} |o/dy=g?' k'OX~#/`UOk}e'C/arL}'_y/4/k?|vAݲ r6MdȷWh=83휢{;i/o}#]@S:tcpGP^)sMys1~e}MQQ$}>>wz]|:8%ybʟGM ??C U<{ :Qr(ыkOGBtpOO./&;Gi.3~) \boG͵_DO^d!ߣCх[Z=D+r>[$G9zt΁3㣇ol>+Ac%}J\Ҙ/QL)}g\6W9uk_Mr=v>9ݽ I6.@w*xͨ>t#H5w;}?\ҧo/[:bf52#u>?ypjt23;կ^.cp>厓H9"үK9:׌9kT踽k! >Ӗz #p9 }ũe`xG$o ,ޜ,%xlnқEuc{У;OœNx|zެwc'Ut $qgFyA9G7n;R"ú]ڗ12j#/sL/c[ȗ,c?}SCe0s9O2:tm9;-x3_6ԞGN I}e_#?>e]l™ws/u<,)> =(3es?3o\ ra!Njt{%_L$.䨶L)?oKKH]Ȝ]_ݽR}1F;( ܞ<]r'kβ91o5z'\ֹ~_jW"_zkfJYS;{4KC!yTzNN8G~t23Yty/s/f+]ɺ|3儁n5JP-  z3@g{YFn~z^}K/a oSǽȟCJ{A7aj[Ŝ_< }vfT>8~|JJY_2~t+Ci.YSV_}V*r#Od1i+}}~ْ΀s?9X|PzX3O?1<ԟqkٯW?ͽk>9 ܭߐ~>) ƅ ~* 9w.a~[z/~[ud ozgȕH{~(ͫÓU#]sW\{]KO#Zj|;Ios_N [h/YNޫħɕ%W{l F9ܓ/`nA^=}sӉ+uo+ L>PH+M-)țEH x{]9V;묜e0pK,_Gud=[=%˧R=4½_#ź@z w}qI/AYkq%)6]L<}{ĿK,Tycl#P. s 'G+^zGy}oD_?tFß9AXȅaJoƐpIpZt&ݟ_|ұ˜ΣO%?~/尻g}}nmqчASkR+?"rFӪ"Y|/"g7 >?},=sOݫ̯:+7ޯS+6^,ʻ}+|W_&, }Lp~U_aIW>gXKgcwIcgO[{x{_ďDQ}eBݗDߕGș@8Z훕Gw |kxGvs\z +N ~ȩLzypzWKWVO8tܒؓwk}'8st\0O N/("Yra}8;]{6s'zx҇sJ@*_Ի]y4-\^]z1s[=";x"Iq '*[yYH:ɷ ܗ2 o?r>ސMI)I3OgU znG=s9->pbe=I]f\{F5(GZ_|R19w3RыX 2SC3fen' gpމX_A%~O~xwf(#Fw߉~^>}#+bce_Zky(eN~mٷS'rԋd҅_24]Jx Kվ#}:OK>J7:N;/Bz|߽ms~:K>5~=K:~FLJί2ϑiOn!\`Q͟+"gxgϐKC={\w彛z8*7j/ 1r.1yk-|븒ZF>Op,p[GU;h.Ϡ/Н)ZYM=]s4PWJ\ ޗ7| ޢ"CEp.Ur479z`4f1s֟ҟϹS/m+7d{N$}ݹ<ܥ{9|)܅|r 9"/۟-ueA=lm|I+?Sq?͎y \Wͪy]T[-=V~J˗~x/fP~Dqx @ ֖n NaSG|L=5oG}zARyO$w<_e͞W>c>1{:_=Ƀ4/,$=U:zMԾ^,|\W`hNo7=r箋s4rtC[ _J24Fr*3{Q&/<x|i-s8u{T_X_~_߯qo"|8Fܙ_;@=Ϡ>!eEȗOt7%r7>0lGY+/~#]?<%r/(~DӏN _q}1ȿDN1#g+[~|:GVw^G!}!kۿF~b>-^z~iuO.dU}nC97 okpx &~Щ-׆?D'螮d(veN z5oNyI7;_vz~*soi1ΨlQ*J>X<ј7W72&}g^}g9JoF=9X}^''bvWi x~|ywc&?x66c^".\x]YA^zQȼQ{~@c#pp5gѣF~3k. Cg2e/=ɟOι:_9=7*3:$9P;)s{@Ky[9#y ~ Qyh }i7'ʞ.ptc#!8uzrp{Kk=. g.֛4__ݼunJ_7:-p0n58g#?6n75@ټ=N7zǗgޅ_GJn#O"pZz_uB_ ivFʆז8z2͵=R|A4h{[9 wp䬹gq^G7tC-XO='#>M=X~t՟4?t^^>yYGE\ +9̹;!7Y{~ /S̤sH{σsxxzlˇoq NxY|Ag\́??2O~-9Ž9o?Κ?j =âzrVQ m{7YX1s;ɋ'?F_һCs`G)2^  6%KN=z@xbKDs /2zo{^:fw8Us3?{.fC cgo&x٬#uĕP(~nW/>zoU9} .E9_Wb|} w_8gx#z|#'s9 >5rM$8d1mzX7fzџޣzߑUN^;yͿ8z|~_s`b箑I>iXwO=5NodB [/Ks*1{JI䍘o`(!oANg_*NX{'17Xz/nΧ G< |!9OƋKZ U>zF Ύ~xW{ ׀4%sS8go`'K9|KA޶:ȷ)vNy!>?17EG OY<X/>RNT9AylBGM|/΂'Ejr?ֽ-<ܳ.[Syw>wOGN :3}9/$W ]4PW{KB*葛]g=sgO>]?3}J>~g|^/~^ӜCq6 |+:ε>? s_~#XZI->7=OXe(?ތ%xdf>_ rȇ |g6=.Pd%vW>~s ʽPC`_ ]NBGћ߼/zC fj=ۄCDy 5OW{]|O':y1qΫD^s]_ǗAg^"5yR/ClkNE_S o#zх{O{Js+cJ{!e|A }t>M{Gl!(7/J,x+ſ0c]&s|t+:K/''eA\E S 5퇏y\0&ܣS¶: 3ɂ'\N1ψ3D{J;L1~xho)<=<)=s (|sSK=W+ަW<߄pώl)]̄<ΐ.؏6TSHU?ß۾[{yŋT7zĖ ۲בZc| <|rl)<Ѻ]zQn'xjIn^|B7LtwE^'}y/?_|Ϗ.|߯7K^}G53#gͺй2{q|> 9χVQyTg^ۼ(:Ǖ _4.r+礏{LaQ@8wv.DJDr#}Cn5xkq^Jwq>b@yvidfA0aqO>Ii'̇5O=k̪}lg~?y'ѥp^,{ 9g>lr9;`y ?&٥!7,Y /~~U $_ +lYJdp{B9 CCJ|Nn,!ϕ_UGZ}[N6{]i-~|9vapZt/RГMVt_#GyHq[kv~<W'>F{N_D A)}+ɏ#u6A}]Xq?%sypoSo V׾ Zewl3pc{:{k.hE[7nD9K-̹+aɅ? ~ֿ=Cv/3ߛKrxz + xa7g>r/}{ȹAC($%}. ϱ}4 _{5kv#g짼ŚY>*zԳ^\)G>J'o{awז}}}UNeiN=,q_==:y3גVc{U%}ԝrЋ&ʟׄKyy}ROx|~t*b~I.|U@Ջ XTnNO1sxcsObp CG0CCI[< }E+<Ϟ^_679%,$cZ#ި)o&OqϭH^q|95.wo{i(]4wǖ:OQ@wA<óGy7<4.#c\U,&>`@K+v1!ynm ܡӹzWUď\g D>GO1!^oGg{+q֞:g9ȑH6[H֠{^"=y,RJ3֖oXB8V87^Xdε_4OC>?6:/(G*di?o3 :/u}w{`e@o-u1߁F~~ ѩ7S#қeSHg>Lzo}ckHy;t|臫/H79RFF|lQ9ԞI::h>& ~[f.uFޮ}1Qx'ir򧄓#OQR'.1o;G=͏; ~>|`tM+WQ{mf87/;xO5Oy%N>q_*dDΥxB|bqlIʭܤs`)f\.>ԋc vV>A ֠%%]w^J*g<B>r?1,q?^X}G~)k5o^]G?Sz|)讃τ{s[7qπD>+iq ‹ԯV :"X߇}W.^N ~~X<~t֯XEC[z){2O-]dkk?KzHr|͡C_Xq)HoMGύUk@_yUO1R#>>-ȫC'0/1cO4'rN,sWdUw]uqhp'~8r tR2d3+w Mɼo ~ޮg.:"FşsFY:? |#9Ҽ81(zCr?( ]=OMx'%<>?t=~w?:؊o54ް^sB:緵{]UNenDF*5C~rȍoJstN_TJ\/@} >Wѥc1]sx0yR[鼨mwO4r+η~HgyA*|)I{ݻf] x,P8|h) ieeOžjc/M[O^?Lf%7鍫/>]7{"z͵yC>z|G*J?!F ?辧:t>zI{ʩ|?~6?"~ murW͏ob'=<'JB?8R{T^)!}IrУ}o9|c⼕%{n~oxǫ?6?_sݛ`~rz GŸpv?# qQ֯;?/$ g/|n^ )CZo}@,~E>sE賬} .k\{174p>~{fbͿ_BN oPN?tNjK6^G|c>O;q.!byros=i'8TpcJVwl K}k{|i2IN_|$[j$N]"/6ݫ+*G =foύBŗN[WAd|'/%R[4 -'0/o3duXV^r4WuO|7~ w$P+Oaїiu|ons/ 5#ϖ?}{?psbﰏ;oA>sr>ڣ n^@7a5TG:C`eπO$y71GX7^/s ?]ykm--~⡹&.[.Mt֌?C?(%HiJ{>}&= <5G?KwB8&[𹜷qҭ6MTw]V=t6?}2zD _P#8~ơ;"T}'Z:UH'o>vzJ% <6n^2:ng0gHDžDwG;}Vq?{O˝fzO +s'MAtOoGt&w&p/{e}}}765k'Gj~UG:8yi:}_fNܽ6=Z1*yX{qOKk윩s=&";tnyQf]ġ+N1}D59:(.^ʡGsٗ0apu|y5wq {4=/A O̼>rȧ!=rUӾcK'{y,wN=>1l ?v9GJG^~c+G_9AWpqp|NQ߂/&>ߍ ?)v}~Ǭ\jzoм5Gx=-kS?DoԿ\䃏._g~!9Jsk? \=N VyiEȿZ{`N5mCy.sB$ \rSgmơ-gWʟL VeS&>_[sH_1⹰VS s5Ep?i/+ߩsv=GvLR?gۇ,|UTݦ\yDbXo܌b?  ]SKہck+r/DMCw!c#_ \%NvOzr]7?\INf\~8QieGџsr&(v^yJ?ȥOE>`hn=hpz{t/s xd3>oLmw۝IGA>"}u~Ч>^wAS|Rۊ3tP;]|{FVkťO ).^ 8FֹAO:prGVuGq76_==&g=%Yzĕ'/~4z/'tVs.qKrS"cӸ};#<Wz8ߋwIOn,w#CG9>=>9`oi<^r.iWezK_d0/'/{B5w.^};V[$|jQ꿤3υ~jrUChOUt>ug??9.oy'5:{tctxu儏{vϙd~L)SWψ%pk_odpi^f+=FQ~|oJ<_`6m*~%7ҙC>s$ϊ?{w܍˒Sso{c6~lxǷ\UIO8e#>gFz.oyc?^k6 >}c3WzQzon28ߣW:' :Brc{Xedh?%o$_7hݫƼX7tVۇ ?{ޏ ?1XBdr^O>p{\\!_q J>6Ogw|%^0z'gLawM[EN=:o9U'sN_ӿN{Ҙd[a.N?_ӸZx9xK%o܃=UяC?c+ã\,_ `cCW<Źy7ǿG~ }X-Jܧ_xz' 'g2F~tj";9)~s !J|膊k4'tn#[Enu?=k9跳:/W>S>k]sMr; =`kuu<:7zwx<x M)>H<]'򞥳ȿBZ䅢^"s97Qs8="uwъ-}Ufaaܨ.g转 ^Q]dϷP9&oZq |~㫠-4z*&>Ωjnfo:X>y@sUC#W19ne7o|r9f~mKS?}e}V'Jy_:Af_: .??(=;Zj6]A9 6RWOHw8AB݉:Kʇ0|k$G|!r?L'igCzk鄓-+k]cee2> +n^z=sC{7}Oo}<9^87{zW.BF|{)&KO>FFCDk&o3*BK3WoM/jM2@ PG8c|Oʖu>=mL1Gg=O(>xܒkMes\ЯD44C91CFyOȷw}\|o7 _yaQ,^{z5Wir5ɡ\x<8TMͥ3G^OtY> S?C#g꾇9ѸRxpW:=v$#0\P8 *:7zG\!g& FgIpPc<ޒ9{ww|c`?B@W'}aB{Ue$e~_mg%kRs=)?PK顓˗9sBLU_^\Wm>>aG^ z;7ޟ~OSY,\Oˠg\\'Wަԓ4܃y|Dݓݛs3tǴ eq\PC9&W}fuI''΃ήOك)SYH:[trћJۺOǓ@NrmogﰯK_c?l+i_C8pM%_>y[I"Y&/r-'y<mQ7W^u7z__1||kpGG_SBFo2YSzΙuJ^yȗW//}m5qn΃³fjO!=vUσ|jxI9ΧJsT>XCvwg79rpON^ɹ_}E%K}exKɒņJW|"?og.v+[G}O02$S/=cl>+p͵[S}s'GO/7)* ބS}#ފ._|tKk7)xO1>or؋%u>id])|pɾzۗ)ǂgtG~H}9vȗ\{5 e/zT˄+n9:gR@T!%Wq|:# Vsndt? ];O%],,o~py0/|k9Ɨb_yo_9J]p/t:^^}}eGD9F 9R ;}2.k]ӥxs'&r}F|VwǼ-{:ۊ!~nG.3}ij=ΒUΧ_s~DW}~ge`wD9-3J{ӑJy=eru_WYh~t[ Sx}{k*gvK'sGƾ#> }$:E,x[tDŽMg_{1~;SzCZzi[O/y,pft^۹E٧^_Sd Ϫ|p'xz]d@rȣh= p&ϵvйǹD">}Y!?!<5s+>CW㿗\t}(}`[Gi>%.? ųN>0sqqU缱tݑK{\_~=yl+8 }q=9TJ7}ӋrӉ\4Ř ^`_@9w_%s}.']O9֭ jÓ_N41OXQ{b#ԗ.ސ쉟ʟXU̯`05'Lf$ktk>_k\tѿ~0j~c0&y䣱_F_uߕ?ɟT}ꯦ\֟牿,y^zhCV>W=чÞ-R?(3aNGKM3v^qu# e"R] ;ѣ z+W>C޺|t6}5О~p@B\XAy(_ۧb/1cGOş˧SNDc{wst:+ =Ok*/O=_e/y{7_ rlLNQ哐 %t<ɼ|*:bz^wG!{UxG5Co19y Vm ʗCwL+?t_/o󝬡\P{_Gr> G|0P̍EEc䪻7;tvaSMEs'w7VQ>u7S*K]|IA C":y~)W>_DGGA'/G1sot/w"IsϠ8JEӧsU䂴n gOytD)<8$c[_:|S[:'G^#w |7Ì0%pt?kkH_ԥ^"N{+OTU7n?>f| ϋo3{@s ?}J=Wu Oczdo Z_F5)?߻T*ttN9:_ހ}4Sf9i ;sweg[ˇi_Tfy0r|Q_sgnݤWy#!6Q !ϝ*K]P9ukk.>| 9Rޏbڧ;֧5 .c=nlyp|XA-}"d酆]~)i.<ff 'SK(}Z9ΖޛxIrd p/_mon_@z ֭޹dW(?9BW[W{?U0ѷ2s_}ss_ranjBݛ0*9`#$뽪9Lt?zƈ~_p:j_džy};Y^,J(:{bڥKp>h߆I@z4y| #z]r_-~a|IFX:D2zX$7ɯ^9Op?WFK;o͇^x<|G>ʷ] l?E/z=ꇅ}_̥g|qiC~\:gt^BNKg[d-]C[9g|j׭p&s'$W\IWU@W'AeW;_:OsrM V9G8}|XCO N<'˫XE k\^~oocјt=y75&g1}蟡9,]Qp_}E2џ5 ]҇uY{Nxrˬ=ȱK."t޻ ͦ,VGUpbSbG9=1ՄE%'oK񇞇=o=؛?q/>wr5r}Ga>…34d ݯ33g"3${.|W딼= 8\9Ǒ<|^0y0gRS_ㄓFNM?1wnQgIcΡn_{{k+'G<>sͻFd7zmeg_wUws'9שd9wCmsVg1:W/AW3akrp۞$]]SW02`d')Oc H_ԯD 9[{=7}!|yvt\B/]gKͽɍd&ҹ__P{oK}1sE1}?՟bo&CA'o1=Q7򋓝=?dinHn3|7J 9TtS.^ʩ=Royw_ 7AMr?+o^9?Q ;Ar_9ِ*[>=-[Ya^m{fZ'sEݘCx2o/&/_ib Ї^G9[ig4EQ[z"RHpJ<;=yͤo)V8r5&,7<d Kg/rЍ7^N:J|W[d?z3gSZ:i ^Nvs̹Ԙ5y+,K_L: .J׹>_=[BsIt~>vέv_<|GϷsWWCLwy?/3\➾:7~1G*}?k-[wK&rρtuvѩ^R+ p9)7?IyהcfB@x}| }}#}^ponn܆<{D ?,-Bг_a)䝐cL brh+ͶEWS@gCڹ?=F>&4\kgtN߇}fz_g! rJ{Ϯ!es{ ȋpV?/_9Cs~<$WΪs/ =5ӻyڞÚCOXs*,^S͡!_3͛/_#&9/}( yN"O-Nx>y 1G3;ç~݅8:}89knX."՛lZ[o9sx_zs)x<='׋&ܲ$pnͯGKk~S<' ƣ-9jBC·f(LυN~Ϳoˎ"dz~BGl?CS0|o/𹫖:_9\8{OO-/osA=9cCXᛏnܮ= |2{mMN5N\l)"~dͳO 2N^Ob5?7YMt=y/aGl9"}6ycaKw<^gq]?oڧp>G]Wyg{IS}5sanܨ=kc\#^?26@d}†Ϥ4@'>/BxYxyrط'̨s{N&#f8/-V9o> Klxka\=٦K'~2r;^HKzSgϧ\+=#V~^_s9>wzy>9g?] 9'͋^>g/VBjP_UɺI&}A;qKa%?>)2_D )]rr>1׃k_N~ryVnpޟuDs黂GW~_427Q1vU?s/S}2$֞~8[%15^~}G룇 Y :G3|C$JqO\+ufy/ߑ[7~y=b_jk855jz[Nyxw_ ~J?bY[y!-;s>}  >wVLj_|&RFwq挑W¯_{Wяor#UO~N=/ɩ$y^s kO_|LQ{^n Qe+<}l78 >9uig70 9c+H5|s׻]9>9_&zW{f:/'5r~QoI?p:x&s{3E.CeJ&pZ; _Bcqn.dZu۟*=f64kwƹ:֡ҷ5y'0h>jqq/P1ZSȂER=Е Kޫr{Μㆿ#|?_h?>|~GgԸQ̣#ߖ#yqpsOUi.9kgA^;ԛF^req~݊|ǵ?fρ=Tc=r53{k} Ǿ79C:'O}|>|co}7$G=w EiO-rJyށ<%trǨ>A=[}FGH5:}$Q/K[~E7,~eIx_b<8~M"!xW2˩;~~9| W ߕu"'[̟>R,?<9?T`g[ye3(;J f<'{{t٧O׹lAņAN9:K~L^t$ԼE/='WAp}}ˋﮞ<G.] tWߏgQ^%GUn(o"}NxPrp 6ѫKu/}=kٽ8ϕ@']ԓ]}OBh]@׮_ W3nz`Z<~qsf/HWD/gMɻ')~tι5~sL} e!e1n=}͗Fub^]⇢ݹٵߑJg;jϢ9*uD k(9|]rn9{Vs|?̟o8NF~r m, '~n/_s3}|$_LCߤݕǜ>lϳxMCO8~ C/foG֒RI_qpnz_GΗWkmbƆ~AY9_8g ?uze@8`7BCt [)VY̋k)z>~N?pi{5GD8~7TǛ(0;O9ͱ?LuQd^P^^|҉(/)|;{;W{&}' L΍>>@H@q#ﯦxkr\GǔA\ɝIU~?|諚0ݗd8-y9yEX&K.+̧ޭȷ۹ON%:MZsyD:|_ɔ+[GѡSB?GvBzGi ϣoqٙ?c .D&?gq\5yk{wt/kD_}鯴Ws])itCJ7[Vz [O<%wܠK;6J~!q[X?ݭ){7/r.#kmC0~)ޝ{ 96-;ȱI?U |ovǜg>zh_G9om.^r|sDGKNq h}o.gZ?~Ov`t-9/ϫy^jdON_gg yEN rEoIx{:ʽ(W.0B8NAiCOqix<|j/N??лYcy_9RG8?]EqȌy};L0ƭ9u~KW/ [9{J'7{ghLJLNK˽bQTxdO!*RmQ[\X|Er;;o\S|/a4{>o+?:;{X_;𻜧ꋗ;e#"wfoRxN[ sy+ /`䞢/7rkGoL~uD]})r':]w?}(Z'|`Yt7voWH=>ixhrwIM?Gcו9A,-ߪ?;x <<{e72?}fÍī0ϣ鬚gmdz{1kQKi}_&jIֵ94%{ty{^|"M zuZyx+>LjrO|Jϭs'VNE.zu RQ. :΋xNF1x䍃w_ Gi~%}̛.Nac>'!é> g%~jOl~)|7Ż3GoC&{f7 -G8y W^wgE y՝})IsQi"It{:Zp3hjo|?z?FނG֜'S˟{W Q9CrG?C^f[H޼ėkZ_I7d|Ktzτk@ωmh>k}<-<ڐ缾NGɼ>=p$Iw"1FiN~UWg_ /ҍp7y hoϭ7[\C/4j GBr(=ZK߉~!wK9J4'-f*[?*56-s Bd)~_o»ƾCBwN=ٕ>/9~+مg2?Fw(z9x_ϵ Vu 7<$eY>=$8QpSr:P8|js6{ɺ镯~?}X}qͽOY$3ỉ1^؇ЕoX\Pw~ϟ^(/wpac}=q6.Dap tϻsMiv_Bi6?KO5Ϻ"7Q>zmҧ~;(]93%~C{tIK~ϵX۸QI5?{&t@LSIptUS ߎy>P;9(KGMN0NGd @G=k'WXcܧ}>U}ۈa}nc鷗>=<nș & F8W=2ee-ucK =cȪI7 %W?9䧇=t|ŦqNw.ly7gj__O$I=Z%35RFDZuB:|<;m;o+§|BsyqT|x]b7腻k=ޗ/lkrCF D< zғO<9kW{eFs% JL*7L^"b9箘M?wkWδGT%\z͸i5߇nX_gKr`rr. }wr4!$?}5Ѵ)psD[;P`a?{p%#}c$W\򆪋 k._O{7=8gx/xCoF99<ɲgxomK|Us\ |ɕ|3t8OO')r9o@G'fcܦ{Tr ߯,O<?'ȃ\] 7x=I1N53啢 KItֱOR~.yQ,nŹY ;S\{sɓ }q9[ŽwB]g<)6b~I)#tr^8ypd[y@zs7 ސ~ȉ\sxTmy+cc@w}UzjrȑFqxrrS546m<1-%G;ZXs_efw//.bzt;Z7uά9i*sU\_+w)% ^Csuqtue+4!4| Ɲ'ӽDJטjk;׹ete'{=MǯxYݛJsk'5z)y~<]N}䝓k}[PS|:w9Pd‡L.%~\[Xrɽ8tG7y7pηڿCpsٿ;{+wypr&d[蕘K^ɣ,n,=Oh/Ǥ}7;?q~LA?˿ӾREq#Z+2*:m;ӷD_aWv>v^׷~xAD >npKzmx?&;t8~u7beѻWܠ^08Ss]yd]$ywHh$:|5,cS9O<\b'>WBZ/e勵q֡eo"'ۜF:[r:@#?⃍xc#,QN|kɿ/<9sĩ?S|fȃ<".m5ulM~g "_OzT-]zosQ]`1JO۾UWi=;%oo>:zbݟt+Ctْ|^վN~9ug{_Bg㟻Y',gKjbcV?\=krޏ_Z>Ip멍J_6[_2CrVNpyS=Bdĭijvbto}j-\pzA=ӎl`kʏIHr-(a{ޒbFW)ki<|Ta[=;_ݞNJk^+W}uCwQO=*19 NJ8OjC<(}p{E.R~+1~; OY7䬹=Qg^/ dgrzn9E?e B|jZO;Zq7)=ttBJs}_fg~__,{:zo#2g-h< \=ߗ?'SCzm[oc&G\A:iG|=[k)|lf8УKHHgC˄[Ϋ^T* op?97>y&{ }E=@o?,ͦ9ݞSkfNh\#:].z'ɭ5w="=#a5_RVx=R%KnuwY#Ӈ\P>g_ ==+{ ?ƒЧ>鼯ʛȹoŤH6~yW>]as>syKw9}X#ϼ'o3KNǖws <~ͼi_/$>־;8kEOƹU}M>q䬧rNF*9Y{O{^~Ʃt_N{K]~ 񪗊EQ;~srmew>kϐ4G|}ʓGJoF}GW'QsI:z/<`o{Ĺwg& s+򾓟w] 5go } IǾMrpc\OsN;'F^]K i?k>V~_EmNO%:|VpIx{5? 7?%:k ׍_cyNOQ̥υ~|eu Зm{fuߕ}} uƏs;뜣;?6^R89gDOx J ׭8Ko.^># 3s.|m{ObW%akҝugs>r*5Ƀ¡+O:?/h9oILǹZ|8zTrMCʿG#wxbLQ{ +J }s}ͮg#wG<}IƺW[ n9efb?J^ܟ#9{/t"\<7fЫ>MZfsDMCe=#su,_Xut_ V;(|y+<_=rzc%grDO)=M`Z_Gzѳů_, z;臷O A;7+un4Wޗ|?O6>~?VEZSSzO:kg)VR~#}[k->?اMoi^y(ս5W3"Wst{^[/u[?Ʌ}l;|Z͜ޢ #yns<zt~Cx]"G$<xHr~t;=!< r+9:3t b?ҫVR7ӧ@UӖO<34tyɺ{|ȝS6s[ՅcK8Ig~[E)r@>Tz{~%GAGH >7Y{$g, =oBrC*~{z=f[,Pٵ#S󽏎# K5lqQo@o7~kKh|Zg,X?p0=&z!h?-1|-ok*^~]ԓ/7'Ή}'2ʋ#=d;O#}4.#/Kb:N{'# p}êҥ<$w>Q+}c~p#p oiTr}cN%\|t>>FtҖϰs N/~+w{Fovr/VVaKaSҏ]\c7FJ:KlecG-@z~?\|u_1#(p}ty `xw>|pv95nRCtJ};sK}z0岷C m>wB4y/9e偣7ħL,!K{,ncM݊[O/@c{N~A%1.x) k ߳Suew:g[RrY_-Gr"w<͵Y?OߜZ}YG_W^GK޿+gByC}Sr5Z}$"Ftq _B-E9-׋3JoXRGΣ_UksGdKWdfrNs|R[g,tOj;Zk?;?tt޳ π>Z[z9(f?\l"}g5݌3+x|b_/OzA+WS\>`{_\A -[$>rYO?3"/0`2utؚO9aO^XD 's<̙س+w𜃧öo~J:cy%tٞ˗zSz+@Z6rɓ9tU×\:$$^R \ʷE]~nz<'K~G~鵗?Ϯx$N\{k9=13'~0?{j/-/oğ_~E471oғ^G4ϫDJЏ]:E9E ?ܡy/eןVc5;oZ={AŇ/sYue7[6 ;{~gm0KnA訜KMP̵Oټt?D#ޫ|=A7bzsmClflEiP~̝3R~Jt18B9+ҽ\G궞CUyk~9Z? I{̡=1 ˡ_7�W?IK{Nό_W:usM>ե~[)@q#tΕy}|Gm*u1{Og4߃ Co 7CiSe.~~vp{H<1>Ci0'c3'Na~9:3k/?rVN|k}%/;?O}Qya)Y3+.9boz"yd|a$g)?HXW.q>1Յj?)NYW{M6tE䯶_s?qh_^qQJ#0ϵ}"tڟY>K~3zA~/=<ztt ᄃ9 Ecc'NuFۢ^xmzBo\۽-CqNs\WO6_Y23{=Tzjcxzʙar%vD.?Vgt??K}t9},W~EH.OVr'GyFG=;kgԹ8/y&9/DXP‘ׯtu^GV}0i\hLw\=1.C/F}ɑQxb==_:9!F{IONvzY en9 \^vz:G}KZMw=~,e#7{eK|GoϏ]-y1וWnaDwfͳKߟ;{wʼ=yȜ۟RAWsߐo pK+Ʒ_-Қп1/ Gost僟әWov_S>ɥҍAO[|+y_G/׿["y+A =>=+/1?[v-=}-E6"Y@~%0fxbO?$~ pTO>^r/}O:7|h8ҿ9eV۩=CpCtΓJ\{pI[e=GByɥK"g kJ~?MV"_>}r4=K{4DNC J1=L%}Ū:gʗl8޾7;Cq|F$">DG靉o;O=C藴:rܷ5v/;[ }|LM{\uQh =v8 y-MVOlg1GܣDWY^%|bއb$G=ty7J9y䂓M{ZKJ?9K s'~֢#o _O)ޭʅ߁^#=:r#5 }Ñ>߼yd]=i1 _Id=ƺ5|஭u eϫ/H}|So|RZBuNjyI AAs ]}*ro_\ Z!?e <][ co5''(~=x}r5G{uG4jr|~k_9DyJy,&jV0T8}g!{KK/9[1~\/(>|[|%ƹ%֡\o^$9%2O@0~$=!e~'t99sF{%}\g*~xOȯGgoa>xt՞lS *[ioh'|L|1%>LxtXC4r~xJsn1W˳0w֏NRG᳣[+\F_g|uZI]7xv+W([fd1EKxI:<&􆭃s} ;rݍ#F{g uOÏ?0FwLO̸<|r / MнK}kw{/Se-Ul~>r/",۾෥ x,??4lt9=%9@N?={y??>T!Ic*/i7g3/&w')O7 x2'Tg螝QtrHoה'}8_|~47k]%̽MHy8+7^4qɻo'{w=kH]\&oesaڿ:ݓCsSj!HڣJZ:7 =^~-z9G_6M3o=|tpU>kʿA?iXfwW>_gDωTS%'|oF|z5ݯi}sq&(]=P/@O>yn $_/ћ\C_X|% JUs2`xzcjɗ6PoIXYg9J _ߣ+z=.wcSe[Xmƃgt.=OioE!mnW?y|}/Sre':3|O泘w^X2FNN6fސݭses[B7}lUEqg~8aX?q_>![xsl/V1|~fj!|I -ޖ_ Jz;o|ȏ\>,_cIszM7;t>9?&{r/gt1?|(LXρ>L#g>%? k^F޾N>wF8ib/{X6y>Ʉ~}?C7i**tӝSX'6{s2 Z_>,Q~(s+Mcs9.)7ON/y }7If+æd}sfKg0y@8v1xjKgޫ*ΓWaC-/܁"rzKcC/}8<^]xfI?|B^3l_w)'oρ@߇=@9is5q$_^'wOsttWsύzg ?Ym8G q9׳w"W¾yAЇ6v |]5{4W=J>S?9*ry6ڸ$'?_;1"7{ҧP=>G!s;,szKu$d^fn#׊jp|g7gr ?k_ym}KJO1sK}7|{ _߼L/5I-3oo@sEu.F8$7! utv~^߲_\r/*{YɽGGT"]}8{Ph~Wc^'ǥ<}|:)=}ov@A\#A.6$\osW̷|G͇P|: /ْM}=ʏQ߳۸UsݳKl}|)t6$}v􏑧|hKhQ3~>c-JeirV/v\ZGs9U]7窇}1 E߁NJ%N~>ᇜ_ċDo/=GOypw:jޓ~5GoAW>En:/}*z}V1>pl:w:XUzFA'&zLpZ|3ܳ䙎l,|mtwۓQrRǟK&M>+u_ :=#s['Ŝ9OMi_!lj>\rۀ[q[}>R\'_jޚp~ x[>/MȆnoh=.k79 #Oo|;w5>|LR~K^>3 _W5{w p,"׃53ݧͧEB<>JG _Y?9z&<\'{__]˽۝Ysu*S MąK?B^ g+h:z87{ koRj3C,^^_iH7|K[Mp3L/Sc2|<TxRtf_\eή\[9hQ%3lyO;]8Xwsd+INQѾ3s͗:YK_n}g/_n-(>a~S2gs{Yy riݰ7Tד]5$qj3xϵxOw~yp!CO~vtKC=1y|/\9gZ<=ΑY+K$+x=n\.X:4p!zٻjOossH]0y2p_m&9^c7_\%@}L :N.?)Boa*7;! K yGɻ> itO?r=%潫/yt Ob$\1zkǙ58zyD+^l|=_+g|1K;5Wor 3K;]`{ޙ-t =s#<{=Y>}?a:AT^uʾm}OJ_7_NnWV]M},Ay1< xc =T?y>po9=l%~y~__WlBNS:NCϝ|th {d诜{@yퟟRs?"'|]>Ź߯lsHLq9|qK$'%|>d7"Lr׾p?W7|O?h9 S|PշT\5G9}J4sFVtcW4/W^}.b󎍣y{&;F=sҒ?A7?HM> m\3$g7NxY>@O~g քIGzn{y`ń{:4{\{Y{,襶?|{?}J@R@MN$c2|s7CN)=5T]}bןOkO‡JgԹ_8qgv)b;su`^jazxڕ18zOG#]s^J9?y=Ta O|b^57t%ܫ쟑{t?:'xBU֟._:wү9l]bu5+r_'yr)9ny>ʚƓK _~q?t]Pf7HE$>3Lj*x=X& koI1k=:la=.2zCk=5:2ǹy^0i^`>>C}q2`rK[h5j#w$6ѥykȕg~| \q;GKO^~,/FD~GKl>Wr"O>=| j>%s_s{J譽gT X}Q:rYCl?n+o|'/e'=)Ξ<7sB݇Չ%?J/S,lϣڼ%ګ+[{O6޹o\탯ޅȋ 8}{.6z!VFzaxt3G>1mMΛ\ SusqnqzR!_1ҳs@ʼ+>yzyEgD_@9oЭo#?81FT=v%þO'@ofDv|2oo=zC7r 'w\7?|qOsŸ99-տsvi!1m: 8Y4Ϡo䩙u tt!ɎI.>y^}U"G{;P}Gf>3remMi?/yemr0wY~w{ڟJA^}2m[\Oy٣o5/z/%k9qrK4u:|nt΋S =Gikߣyrcɽ%Ϸrv+1 ջ;\%bX^|.}'͗;p՜k586{)uK'&u^?kj?oس7Z\}\t{b>.aU ̉䐴~y#Wx_ӟ?hRGAO6=]xj|jѯ^]rΕ\=Lrr`<׭5{@2ߥm&/9t|7ē$'R1ӽ~\@7:·[9}d^7gRO9;oy <=Ůړ9{S! }rm'뒍_չOg }_/YLsYo̳K\7Sڂ= {lt1m Ut2n)EAML~^t=Z(н_B;yiwӾPH@g.v.me91iʕ q^{u/P~]#\`55nI=oWSS[ λ=-u"%]S:y{_/3rk"Gcxde%_zr@ zebzۯO"YB(gkGǔ|-x:I/9C/8a/巠*fiYj_l~p ;H>yqu.72 ??|1vp9GuKΉ?69WO~=Isbzoter<|٧蓤=Yv\/Qs ;O\?{rx/ <f߽ ~^W+rOquN9+r{\E8kLty\+{A%E+^#^Ÿ5,=xGȽs>|r~V#~e<bĽƝ <>-Ly>*R\w}w2WS}GZ}^o`rЍˠg;G,pҥ>#ֹU*—ҟZmOS~4&v=X+]!G|O{#=sӇnB;DH)Α[t%>YO93˷2><1\Ĺ46]#]P^yK`ǂw/j-}~"'{Kḯ;.4rHSEO2!]÷y}Cz:8Lo?AMg =ڍ)8O|E\Hy}r𾭞{Iܧ#3!هYL{2/x[{7=,?[s}Wn\v)0;s&{9O!Y#LxYx~W-Q$\ܐKn-}!ѩ4(|أ8/tгM}l)J\/~JWX{{g*>M| ё0qOC>,]\_I`"}ukQ8h.Sxb3cIOMӽ? z.fqN wO? 7 ;otC9*2WLƍ~n_37WuG~z-Kr?Y/Le|"9sr^s1@}?6Oqrljknzd.|>҃оs?$MqBf_s+zʏ֥9#[BO7ȭ-+4rCtp_%,;x&߬Wsc{@@wOf<8S{~!zݤ*n\ޟK=Dz6 Go@ЩWޡ&9Ese97zӜ_7rt/t{D.x» ܘ=6x=|~Bj<3pb,ݤ5|-|E|aX{|m+Ǒم %}܏뻟~DQ|[~qz꫗hnk#E'^~~-$\}9 G>4?N-Gy0t=sH־L?7:t*|IrV?0_>4P87O~ιҳ״tō%ܞyrOp.s?~%Ϩ{^Idj gX ҏB^øk<C/94M4γu/W7l쥹 <> i_Ym{G?9T0{A|os'yMG5D󏊫GQoο?@ F;y-'[.|@+\p~7-^[=Q=8r^*nO #uo+&? vߓ}.\~ʚFo7}Rп>.{C9y-!G5Tax-p^KOvomO?ztzᛛF^P/nkj7ɟ..ϥK^C4GUf{Q=HhħC:H|S+өNN|,<9uSW~l9~gz`_QFߔO{:}itsNDZgEOSj/ǂ:B㒿CN:57pN6z=ğv ]U |;y6՞ -+3K=D<^ɘ>,\=U2ϥt(t.7Ni?Fy(!&u:#/C'Ay%.>׽_k}7ܒRgo[OrRm4gvx1^ Pyӫ½D>n~㫿G#_^I7'I\*> O<$K䀡csߐsFGurN:C7φ9\*!=kk)1/' &=ٚsP:8Q5i`}z;}B}n+{M۳\?=ɷ^m7Sʹ8޺&Hw}8ܜ5,z3j  eϹ9^ ?W_p^' ? 峧_G Ҹ]"D^t{&t Oim/|/zGFoşN-?TΏ6/^_K>swS8|qq^ CgI.;il$3{^ σ~ޔ\itQUқTY]:%rzs:N;j|>wHÅ/zomr#ͪܳ؇}ogy~Vڇf| keH`rN&~ܵdk/|ƣ# Y~Kk1+딮#;|x{G9;쭩^z1~oϰqWԽ;:O+9@s>8>U>_Zk/'|Z' 6pNO<9\jJ{s6\ܹbE2.+8\8.|#GyD_{g"7#7yd{mqvSN8Ru)}oxjCڧ; w_L6|>凐kutw B%)3FK}0«W|^m< #U[̠+e 8}Ni׺c0tYvo3 ދ;ߒs|#\_a4UwG<;hl-|q94w ={8/{@q/1wYA=xި39 9&_pȕWkN0|ݡ}[#=YS{EMFg漵3YwM|y?,Xgg|P\'zRΫ5*Η>rpW5 nH6^]_|#7W@Nprz%'Ky>~]3w$7{L1/ޔrtQq(|pz7ג/CqkMouynsWKXW(^?5k6Uo r\YύKֹsOw9ù \vx˸%sp.ZS𣾧5`~{CϚ'@/O-sBXgU$t4D/˺o_yTpܭe?]. >|AgOoО_[YY}<{O)~s\ zE`cT_1pD.uܷ34{k_o_iOts/co'\ -Cg7VEzv:OG+s.>1#Ϳ.yi eϔ{(=JY'O:;rͶ>Grv ~u>{zkKP9SzV"OvO9"gWD觳 }v] =YT*{8%(_XW.\6}zrN<+C-=AKz<½t{J޿W|{s<ӟQ/}]ۛNϖ @>4e'Y4υ^9tvӞ1zunΛotk=#+-~ MVvt5srbOY zjQKUdz?]>=YxzIcC!zQ*'|s3HWl+csE y^yp߳б%pZ}ǜɣ46u_ Oݢע [麒E{V ?WGzX8WyOΖ{Ͻ1Ò9^!s_O^y8r;EޞsѽT_> O{;C=?|n<'#vtߗO?J^>4_PWa˘;ZWe{,>G籿T{KCU[\|H_In8F6?? <<`Gkө,oE~Kmr^>}xRZ.]L{G+fi.)}¥K'9\3]@8BƓۓs|h;>s(t< fN"Ѕ_u@W<'uSCYWʎO;oF?Q|SS\6pZ 9uΓaB~> #7Qy`-FvUW`Zg-msɯN=4=K{QgкI<'>E>#: {0f=%t>*~V|/=ᯢ:_5cw3[SWy[v>v9?V} J'>}̥bG N5tޯ֋1S#[ ϓ(!rnO~^P{E|T\]RZ=sbb{\x"w: D:YM)rom; QtGR\ϓ~Uq[G>זr_ݯїv|O ~}9l*6վr!Gųh^N:|N,[g  g=O#=S 7K3܀.,{K~[|6(Urx_G#8/~r:o'픋 nAևOxP5:|{K\o8k=?ƍ'f鿠w9"Y_,sxǵ#|4}3JK)977kO^C99rWؚ~ OFvҾFa>jsH=W/krֹ_#4_gqߑ7@0z1_IC:+Do9^Vݖ.6ޔ܊uғ5Zx䗑Rp~} #ޚFIao^O=8)|(C }/hnW^mޝQzxL]M !9*3}_KW^nmsΙS*")f' K=ND>M4o"B8ZENesx>| E"%===G*(Nyg3E/yC_E2@~>МC\ s~XȽ>%ZN{ޟh\"MG+O$C+S~u^z [XH[ hN Z&͋܂a^a/D?C\)/^.K ?%rnOwPzo !e f:غhn%yeSߝuYg }ڧɆJ7 = {HBwRZI?ZqE> {:p"})4ׂo!䪸/+&'Pz{kf߯4󡏁!8go/>>'!W{$:TΓ>solf48e焮ȃBS}U:5qOE9搿Jvϭ9=wߤ:0O}/nj.|اxywCEw I}E>!7y} GQ!53(ye֗tN}SW~tݯc>ߠs| < _Bq_z#gS~xMޝLn)8Oq_0o>#h"[Z|qW>W4\.YY;zspj.} 9 ~7o,.z^/EREsc*to6ZGEMvx=O&6Jdc{Ua=?b_yD䤣"w#z󣂯#?Lã47l~y^nr`B`28|+1[:b<6E0y7rς33EZ4u-s+r8G7?&>ykBg({M~=W !z+ZκwSş9AEߝ%},ez04_^'O~o,#4OU4'j9}kL?Ǣ]5>ɜIo}=|ps<yȦI?:rWN׷'OUg*J*x*UуFljMr5tZ[[f]<|U];yP{:hATnyl.7Bs!'%䁾\O(,Jso՞^4phVH>gu#$[ZZt|!oX/Yu~Xo{mo:T#ҕw}Aa/_=rmM|٢_əPZFS<=ߴ jo{gNx\q]q+?Ƿ'y^o׸xQ?-9?tu+{LC>pv1}zz>[~zs-(C^}>=zH=T'1,|Ir>S'Wsors>\V()j}}˯Ꙥ ޿[q;/dCǷ*yPzB{t!w:ަlIyd%|5o]ύAzyr{xW%?;Y‡xw~0xm<_g^Y$3mO1`| yg/'ߌmpK#4/T<%< t(< ~\Kz5#Zh~Aus7𞄎5ɉ8|aOz}ɿͼ͞(*=Tax7YLЛstKqEx}emGIot /|_:TrD;Cl}>F{s賣 .[3+^sm}.u2߆<^Jz,_)mRqop?LSYѹ?ԞQ{zN*e'X}ϧų8 >~@orrDŽ<HԷ6Er>0O59Q{E6ˣs3y/tl}1/uKOXXxPex+pM*tzUζȾzׇ)s%G"[ WOczeD{o6yo>ͽ+[aQ]<4\*~:zK,|}+Ҩ-?>' ~B6z-z^Ğd?dwQZ՘>ZG{1=KNc~{0x{=.܀y 49"v`.32G+ςp S|irWA\%s=,9}n<;XOh94!'>+CpXr8пUs@_1r]iݥWrC/{9Yw_ OKNW*;r[>sɛl|`tP8orQ9W#$_t=c ~7:7.΋s jkL2bЛ0WG{󓛛wçJ5>%ﭫ+/랑مKO'yu~h=c92+`>zXU9#Rs~J&_FsW9t3Q9MUS㎶">v_3/Zx|?ʥ%Fu!Yr5y)?#Q7hn :\-^h`?g#?s(Ia׽^ĥ#_[0_/jczK9Ol=tnNE/moo.q[Oמ1riIsa/d$\CzH s]U: KrNBޑ֕s 8[i|stأkb[W=sHǻa <]K{s ~>əuYS$4 {4_Z8){$|~ŸuoZU&bgc=*l}S |Z!VGxuɹw6} 7tsF#_sz;_>O4~sY_D=yk^4Cw|*2Nsc+OH/?EA.~^EHun'}=TT {[\7+O-t1OөC!ɓ +J'^<~Isifv91RY.޿lKBϼ{O𩅾$έyă2Ǣ.#tT~sQsssS:/j?>Sz[ukk/1rwJ~~8]M{[L_S-3¯½ori-=':k x0?+ \y7x t=Mi6 ^ @rL7MҞ \O P8okDg(.5l\l{ս&]# |2=Wt#m7 s!'xew?'u{D=3#~ar~ |C.<;P2xxۣ)ʫB?> ݩGtt1,>m\::ۅ4>Ys ykB;9I!`1ɛB֐<-4|Z 䃠BW$_K^=OgH,kc[x;/zC9W89z\y ~l|27b> EY<}aߦGx6:_+sC2Vc`ފ|?z7F $]=`hn\|9s=>_g%BMp&z1҇M+_a1n//A}f)n=Q{-t#T9I_!z$k'ȟQҾ'琠KWVf^7U }E}C_E? % =/ ~NOI7}V.~ʸ:-r3ku^|4Vz|ǍT}ma9DsL[\ͤ<֏AN|O`>rANw.CtG@ZՊpcYʞ}D4r 7ý`|x!GYσuRϛVOuPsWb}t{G } yμ] 8{bR=Ag4^G$?Gȳ;msWgv:gKxt ygsr]C(~ י+۱?+w޻wVָ}|Zz}{ ;hoy|zHɅ`?~s>Yd ~" Зd&xrD*Ǖ<|kkWb?M(|[p`,=wU;O>{o-\+;#_1+C_R=&==֣K9 &<"r^"_/?o7K@ 9S׽J>zp=џ bߌz^X>?+&ɓGߕ>?s+Boui͟ŧK>r r98 IQ{ =[ǜ/d,9ȏ!,M0p ЧT}%wxc8N>Z¹Ue y[0K?n)^y +<m5I6R=S#6'o!~ +"qhn;DteJD0M2{-HR ,ŃGfX{_h_f /jx9K)oO zt<'`<Í{k]$a6Qz_?u3)hnC>OWκAr2Y>OW^^V?\+AW^wJZ?G)8 jFZG 3 W܀ut7foG0~1!Hg~+{KT9ErNf^gQ4ܩ֔/?L~_jܜ/`Njz|tcHז y*K{n:7Ӊ_'RC߼{\s[_rC‚O~iM' <7R{o8K'ͺ[ʝqA/ 9W{&629?>3KDDұO3m]/;~7HzO΃n(pK<<8;Ek/9;)^9}ٻϚuC.wEYu1ӫxJGGa~%zy ׇo=?:V_swZSڗ}q{o{_QV|\k}(3B/I5s;xr4_,X-\*t#ho)]9t_~WI.Z|S[6W1zؐ'~w{۫cE >nr*OJ*F 3G2x8fB#|F枾%<<+Wâ+wߒEMUTK=]}He)'_oolOϪoBVd_u3Wv:HP?!.߮\t0mgLo~4~>GʫJ3mO#uZ)Q  ^ Y{|=<\N9M^L;l}r;?"w|JS{*Xql*=S?$cn(E~d =ПO^RK7;vMT[$'>Ec:|NKGWK&O5#>*K2λ.|0k-yd{'Ar[p-睡Dw=܅Y_{ݓc}1Sn񝵏3tDk!Y | /YG{ ?~ў]Ct? X?O eg M4p;v}c{\(|}C_+G9&t;{QѓXZ#ЇoCq_ 5@F;|T%}scja%Ms1O~R|CP_;'=n|,bQߢ='K]PA0N=#e//x}/o) ~tOZY[- ;I:܃:X 5|>37&OGGk\3Z+>c,#\qu J~+|0ė)W2_bO% 5#81d -ӷ1B,~pr^Oq4? 5='ZkϢ9˽l$荅U__(l#v8E!7}9\T%c(xu$o&9:o %_r{ѵn?9ΏZEOj#ms<6nnoNIT7s\쫇 Ppnk3螲ySOyl=88'̞ER -Ln]u}| QtߧԿ}{>^e|06`qc#qUz+ΓΝw{)~Aww-nD+W?^tͯy;ZAyGs$}{ d!ǎFnLck+9Ozt+`a)N0~5|zM-+KHWy&puT;`ph6| =;BG}䞓!|.iԾX>={%%a-! }g/錑|y/CO=\5Ȼln~{FE^9 >B^<{ͥ'}sCcfUn8O^)DUoY6mmgfA>xk͢y&7ݨo]gWxC{ya0K]zt7#YX܁>Kh?]NlUqwV^:^_E.ecS…Z/)xa]H U{C|BVuiOltj r{?U _pt1yΝ*='6nnf[Cg>$}[_9X=i >^U  h!?\ ёV?p~;}ց;4~::gw:5O_裞^~͸kc*n&=7y!uo@ ~tOùּRse>\pL&9!GRi%9PɡzHINwE 98*ݨ=Muo$?5\ yyaJ.[i38}!p'z:#禄^? ',;Uy5fgŹ>|7s_|,̥|4C3/̖PNzt?ʺ4?ﱂ@uF詢[.3zk$=FKb./+<:H8?.xp =d߈|7jrgB]W"^>YᏺgHy}%HjAIs@\G:"ɦz_;F,\xt߼OEwߒŽ B:y,͐3nΓƅij= ֟α4ߎN[{x>N.!Ah8{%^ }Rhitworn{˯c|_{9۟1LO ސ90g#=Hg ~M88 rmE?(2R8)>~J)oΣ2G<{|J߁7:ACὫ=z)]kdO8̵*x r)b³s_Jan}o|z?ay@U}G2Gt~٠'/~'yH䗅z=#;s0Iy#,~/흌X- 9|j[>EM>WlSxMM\rj]A÷9-WF'bniz{~_%\=>jk r]ss9/s{UDNe m>!.RBO{ ~P>k>+|4V^W"R{m~{\tL)^:cҞ^]W~drw-P~>B7r+ᾨ\-%c,t2ɵ|KXZx,sm*z[pンCwO{52rҷ-ͯ==RQ_7=WzӾ܋+=7? .='=gK'sma=OܒKBޜRzrg95s++G3齥^u{wN}R &]ۀogw+~roT{ý? >nXM%= {㓃g;mg:ϱمQeAN?;$Yߢ3߈;+vm0n}-,O53_^~WHJ6T {gL~ s's@45K%->4xack{OYy{J_ pg]X97>휒K[_Г32O4RAiy<"4xt=VQ7B}AW!yVVտO>z跉Zv-6.0ߵ;4ԜB=vɝ,)<1J߄ː^/[Bgs{݋:|!wtrU;B?ܓzJ#ux>_ =TopԱ:_%Wgs9}/;ݡ=!,jzOGK_<3wO8aqooB/I]z>w!w3Vcd*އyo2g᧩mM~г~xX 耪 :s9Z=t[C>OGTOio= ׁ_Nox]S?po7n\S:?Ы2wN+=/0Id\ݏ o:`2} ޗqpa E_I^2< e9UwM+*?uZGoWztBƿG}}e3n)zQ5x _}tMփ&zt!o-o|#sCvK|z0woɼވ!ZW2sҋ^~F_N:]uVzzcK 'CZGx@9sk/oSU~s-図wjΗNwk],̝ánL?t,NJ| rkؗ_5gfKOs}Klȯ}\TryV o{]'RzBz򓝇r|ǀYNI{JZDzvr9=xOF%gcε>rȅFFgjrDUX=ڛ™XaKhYR%)sJ+Z#yZπO =zwt.#E=j/7#@f:ri|!71{HvÄ4WL7'!oVz%v\|䝒#M;-Q]ឹ8ɉϿy?'O2@MUɁ?[_ߑZ\9ewg5PD3M7d\bW#TО4ƺ絯>;wrhgϘg|qt7mS }r% !w ?.:䁠!g& KI2z6΋_?}_ y .>/=gPthM;WA9Suy43(RcЏ,}1Yy|_=pj+x)x{?}I=!ԗsq{Lo~߼PXS'3{ ^<_kLWOD=PN_d T5eݕķ}:{]sq圫}<>7ppptS=Dx+|>nWɟCJE?/O(yܢz"⑯~rG}!V9#NͣgC-K\~zIl"ܲ +o9s܁\`H'Yζ0n(>G{L2\-/\ʜ ( yj3F z}c3'6K#-+rWц3'x5 b ==u HxE8[҇_[ooX+/@~\l={t~K ?@>"GWd:~OsҺBI=st[9/Z˩z~$i$_;>OHjCjGZ|r_f3E4^~Jny{_Rzm>r:G%](~r+).cfD.w.z}U^kW}}uWf3|x(tX~}@/I]J m ܘz-MPx*Cзórϑi6U>Lz9Ԝ) n/侀EH.}&xl1zC˜Ii$6 _s=K'o ^vl>ḟx/'+e<潨l&|'w-W|^y.Q.]g]ι{k'K񴼟? 9sskfB=3B<̟S}(sN{hO~ֹ/$]|B<ց'Bݨ#???ǎwȋ_ۡG9I-:Se}7eb 7 }|yo{9|܁Sh\@DĹs0w#uP[[:sX0.}Y|ݙ~wVEscx/;ԵSn$zzc!_g,p9j^FoiS3~DC'Pqt{gGuFgJo*T߷5-<|kgwHm=oі |9t6Tl>ipS<=~0!xtoyys~Y%烧uoOn)$>5zkHo{n~gmҖxe~JpEOK>.~$P{[~vtVs჏^ѹ.@#7OC *Ei;/Fuu{/3notK 'f|eK_ސϺБ/).6нyg֯FONsas }sX}G鱲; Kk^wtP[wa-yzE8xO%zyi%O\ :l9Q7C~[E[?7[B}Uy+~7Ru zr/>.#ڛ L%}r琂=`8`rTx }&r}yo'\@t5E=)Fܻ 1 z9z=oKonzޕmt/{㲔լ(b0N$:'S<] o{&;~%cOx/нc 6܋;XYc+gtd73o`E2=ΙN# IuQG\#뽛Z;.g|eL/5dž^] ӴoT|;6sCI  /C .7>eߎVG.>h{_s !t=,!/ q5/,e:a{LxZ_-(;B?|#`'tG>NBoswD<~ѥcVPY0wļ%>guۆ_n_hCV3oTDc'O_Ҿh!:_Ԇ?W!y㽌q.ܗs0@^NkܼGПI:9e=yxm 90'@|l gt?.]Ą@G&B{4}>.5O6 1nlߊskw1Om0HzGZP~wr>wOj]Bȡ9ӹk ,=PŃw{tՙo;Z`Yk\;ѱ3Gog^+w/9]5]tAr>~$Bcv[ٲ]쭉+;wKs$LIz"C_]{oz?d kg~:[ψ{5NPMy9gGhz_ʛv9Ke|L-:x;]ɹk '| ܳԸLgv!1yMEX?c?E_=Z៯Rٛ*Xa= =9+ћ~9=\T#}j)CE`4oW&_#_D 䕰/$cU-A|y;&qu3oҵE+:sX砗=}9'IG?E)[O y^wv>~a}+ N^8u_GKͼ .MVk_Hx~!ץ|a J.u~ӧVU`е9_jּza;W:m_Vɟf܉yGk>r_gj6:z 1nzѧ~n!=o_)朠r/-6skJ)ۆ>)G[\俣s!=}&+؃q{A ~iu1?3&뜩=su==_\6m0"7Χå}G HG>Otp t9zPi};911%}u\|{V[/X/}s.:"R_e%:gդG\L\#?b~ 1zh/=77q?qU76<||c/Bn.OE3{t_yU }G~-1אs6Z:] 3^|p/9: +G= vo~*<[7o y? |?7|?|/ko|}]tqGKh}>w>'0M.)}XKV^%+}kU_S}SsY3KλΛs؇#]1cˀWM9{vС~X-;YQut/s~) .+gtrm\O>6Ι|Y-;c`RKz>pH<7O_垫=/s#ο3OW=I#jGܪ\q](=+O5םLp>Cԣ\!\uss_m&=w}hGԾEi.:CÛ凾YB|ߒF:J934;'MFOi=y4KKL^9=77dO{TYwx|^̡E8,ڏm/!zBunJ䤄\諥A˹XjNI6~/=ߥ".yZ{4=U1?*"z+_КZoo<-+sL=GpH'k>9H? r/F$9;4]?^9qss>~4~.bo>C27ѷI;S}u/k&4E7?ϧuz 9r/?6 \g$<D~ ^UPGh!>1_-oygz+z_1z^*E?xyWPB.W)1W3aYcSfC?ug\ ݞAx/:XC/9WL砛5^?V>~~d=6zWaO>WOuϝ:4>Ӛ51{>ە{  {2H.49.3'^>leK/<|Gqn>;d NZXH}<5x-!@t!~UE-$8J8'ywϾ7E |_%9 {8G}#?T̻E }!96o'}f [~6(ugiN˧tMOwּ {vGؼ8 >JھΎoc![ؓNJǨl|2|ɝ?̝k^'n+ƓM+?Z-r7:KJN5n#\_4_zqG*7^fr3Yszs֑? yǃo9:bYQ*x?篰w%t9=ǒb={o6dzj*{cs Osr+ &/ ]Q ~5_qNL[->_w\\[VO߅{PO1Cゎ6sͧb2ց/๤.=>5AkhrσHBKk e=rFͩ^~?~~@`e5}*7r;2Vo9`LV9ߪUkI$ Ϥ%֙NC|?)679$^=MƇ+;9&Ȁ7.-(=k5c~Y|[_˷zoW.C<'h~ǏDzmtя .W}?'D\ҒO+Yd^IޱNV³r.ׇ/6_9[ݿ7O?#'=V{|ŞI:/ya^[39irNeu}þ?_xtYssM?K/[I/tK:Jsc&<#"\·F~>%]C6??ނGx~зŧyYb5 \nv?I,GO~y4&o?+:țqF{j7Wi{Tuwr:8f>ƴ| eO_h)Cמtue=)%Ul: =hm% 4}•2SsowZ̉Q}O_} 92YI;=IYҥ~>tTw|o G/9:Or[Z0~z'kx[Ws1 cϮ=ݥ Ź?W{#~.{Q伄x)[4Xp0oՇ=_!| O.f}!A\/[OJgg7i}ktÕ-ϑlfR_=,y-AK>{+'ʽo'^yQVxhN?҅ ~@"M'uqs%NQn~x0u5׏!y2 \|>:H=@8K~Zy C^I9<|H9 4{'}ǵro 7([#$;^??*It=ǿ{^qzw>ڙSxN9xwII.StG̩K:]'91wB_c<r@a>{WܮC[GL79X:_\Oxu9gj>ϳ'^ϯoJ_VizrQs%>y}R>H3I¯)*οtdUn𣤳RT g-|347>|LӗN OQ'τ#뛭ojzE<m/z@ͥW =~:z-ɣF32I }K/R9' A~Wq~az <#]rVBnJʍBZ;RI[Sg qOg̼tSٷ}Qt>JOq|cYMt~3Do/stM/s>Hzzj^aK:y'kO%ߛ|TrSŷs>?gz{)9?*xoN#  DTs%:/8'ӡTzѾWt/Y\kQ}K]v"ݟ= \zt#KH6{3.|*Oν =IzSo*y?mѝ ߹ 0|XSK.snճƽ~OqVA >-}*)Mo,#=;W Fz|L!q͔;ܟ$}WeGzƆ뷣겚S;}NuN <^iDS2.s9Q>{AyOAG gbF_䬢v\d{+,{"}֙f_Zjo~R[-J}zwHz!"tأ^Izx psy1E})s[#'xnȏӹM)>F uݏ>x2_pC:㙕>U;a|Uv-)YQkf{jޣ@|4Ljx -] og^IO˓_L{b@_ ޜGyU!ٽ!ɹ=n!ǜLҎrW Yn+{D6y8r=O`b||ZKO2zo/|'<8 ܴIǼ|W h%Noq0E 9{~I>|ǧwՋ\*gv?fC.B'Dtb<:}&Q97[8T>C7ş @l*:y9ퟨy'է.]Y+Y7r]J}A+H$$=GB sâ*]MMs*KߍOsڷ%;izN\!rz`F_9z>;UG~zLWNr rNO';'I SrUe]k>~ x./0^=䷰N՞~v_K| NM:; K9ɋxCsgz4ϐn`?g&)~Os-A?dzA=j&G$X_Drx44SO.ڔW(!ƙyϬokн76+zk.!pvsuޕ pUYx x2B~lOV7~zÜ>Am?"Cٺڣ8lnKC^/0#::r/B_uq@^]~]{/&/*<>gGqq˕o?t+|G@ {G0yvT.ry+U=S}Y0Okn__zlxv\7{&U+䅢:|+bDW|et]8%~s9w5ѫJn ^ 0=?$goyrKO;A_/W}>̵Ow#Z§fl~=t|s G+>o.}Pa…s & eJAy (g?>̋OOB?\N8^9 gKyG=G:J{hi˹ε \`^D砻?0Y>78O{I~@3Gྈn/n̬.:}nbO^mr}7"F:r!W<9^-^B8a}~!~=/}^xT|>Ӿ.|-u:W&H:AGx "?xU2oy 2|UXSm yOt];'&QOUu<4䫔W>}8)N`S׃@?HN'<-|3>krg_;鏙s灋dz#==ws $чosR藱^lUxyT:_os9Gt<ߙhsFBO `-w>Rxe1?ѯ {nu|7g ߐzСw>@ 0VSE+>WsIG̼}> +G'^Z;cn?e|@=A7 n}o.;Q<1CI8||-Nv0zˤsϔ ! x>߄^|"^Ezz-7 49oيw:wp&^pdG(|i3_BNj|`^羁S.B ?2|vBnsg\{#ގsO/ؓ۬=!JͿk嚹%yYOZH_ӳa^:{W}+lj7+|̍9'ۧpf7 5:_!JnU.>la,}7Q~i߀l_\KâɓM~)szRC5tSIp&wO :P9yF>e{_{Lm'_hߊ3{(RU7"aZ{'NPa%~-*z>gsrBϐ_5)x<+xgz;&NM_O-(*;&7sOP>4}Vyœ׷_2׋;*E':G7ӹOиY-rW^?O>YPHs5UhA/H/*{m;skG gbOVuq\!)!vȭweͽE_s?~shMԚ?  9x~aOyΜ/nk-5t?bՒ^+& QiBCNNG9yQAR9Ó͇=c_p>0Kso\FlNq?{co\ tOdߝR _g3)?jdҕ{Ni˒Kt')$$ْa'6s=OJ=zoڃЁ֧V.؛_-~kބNK'G%yOߩJjj=JrFk{zxW^s9~ o8X=1n{#ߧ}͡n'48qxZ9[z2[ڋqfpdߊ=~c|`?rJj+'2Ƚ {~ SrLӞR9a1gkOLVO t.9e7k> EGɟ\f\m Sυs7"\ mq[I>7|iKO|M?𩞓Wݸi?*5r˧y$sAf4haa.=`b.&AMzA'W ={7tS?98cKMw >{^|63g[JRQ36zŝ #V~9c|0W#gi?}*[}⾧Ǡ~ržy7=?SG=26!sO9yb?qHKFsht /+:ػ?X.#|Ccu.q]v=E&w)t!ڋəGR/߆__*}n]KNpI'<._96x$d>}~& wz߽'g;?iYq$R g~7ӿ!~,G>͜h)zTh >-zZzV8Ns[U_*{9MNC }'5.\¥m '!oaٯ .6F{+`.O4\r)ԟNh oԞn{UOt|{ =ED~h'ճj}*;<,sk|S/?=ՑSڣ s.|K8 3';b^מ4/i׉=^ ޒk^ <qE0s-szV{ ~1ޗ/!,?SjС~AI*?Og@I>N}.6D~Srb]-B~?y04*X@yqT|/r'PyKVB.?/'><>M8Agc9g֒@|u*t= / N1]&l#CPGi^C{s%%š_ }J׶1~~6J}o~^S@xNz4љtRA 7?ֽ߾Z{hrFz׋glWT ; S)DžRtw }y%zO Uɕ6yc\-5غзܼ9ăOÿwZ9]з&?(~ \|*x {A画Cw/T}{ϭV[_߿q־^Iɥ&*n/ܳY5E'8ob c{O) DL%4OܹFk^>5Z~\נSe}^QN|t`'Oj>,>xH}ncOкK4yeo]<1+9Wyp20`rQOsL93X9sׇ 9d%g8nޅ|eN߾?; Ƈ9yE:Kt"^/復{iEN-z/pCDMwN7 TJ"y{c k 7sx/9_Ek)9=W<1=i.S|ptNuw~ 9,;\Bl}{\rk`&o]+ztbwzO]W: r3zUX~&z &bo GI?S:a~>! +Jo p9/+uq_&xzz% zki,/y c=|҂ˇ!~Eg+htS+:e=䂐[CFr…GŸ\џW'{,ek'D 9 O:ӹK,tW๭Wo<r8٣,jNvSU~|ɟڛOqED'lɳ/OWepio8}Gs֎v]qE;$3{l;"<|۾%>'_9E?#<y䩥?m_kny[ -i4}_ܠsq:˷K`|۽_!w|Utn1s܂ɧDG٘^tGS'~tIC| {蜧^=?ܫĸڎs^rNnټsz|&ݤE+Xߝ,D~s/=F.]|Knޛ皧k[#e<{ns +{{Y8,#kk:x SG:>qi1[{ϲ^>u_gPDs3Sͺ /K9Ջ֘B5iطoC_d_ESsmM9$.^<ۚK7YF&{[xQ{y>d7n풧{We/}3꼪zoÒ>zעq‡ ?VOeIʀ[?{n6Ǿ NNY[ O'\ `9>'Λ><(7aL z[eK{^i<z.ٽ?Dzs}kr"ʻ~8ań'p&4n{TK|w|yu&'NN--z%qS>~LyW$'VK8{PB𵃇E{k.@c܄p9L2O-/@'xvqЭֆ+%yHssH8zOX_\L~%|ֿt [g&\gU՟wqed<_9\)vN+-^aBG{^>\8絒ows;ot K]hܤb\p"1>|^$i N[7(ڇGx tz{[8?½i~ x㿜oD~gr S|'tsߕW:^;>}4/V`g klNJ;r /j>?>z?lOsvZaO1oA^|ůV=}VƉ[8,0zzt2gOԹ~֥3\נ}7WUܯᅜ_l,(?arhѽǢPhI|ي DݧÄ[U6RN|e:M|e/n ܋.yA8L^ϖ #{zv#$Ӫww r>x+fshϽ?Vputyj/mnld_b{߻xwZJ_9f=+Z$_y짭z'DŽ{Χź?+}YEc1zjd+/x_H:Er c鉩o\TS?VG߸3=g\sj7I3FOW:f5V~$>$)ד^iz҇ϐ.%]Gv9yTKNSGw_s&pe_W|9JFy)Wj܃+=@ %3'FݢtcӝyރlS=))z猾Wt>ie#ϥ_=Fukt2 v7u15>o1Q:Kr*+o$hHy ّK<8Xv#Bmѽ|+#yH2{$~tcʥK;H9)87r_GsS}.^+J㼃| ':1/򼆏^t! &r)=·Bـ+_T+85ޔܥ_:o: l>rӸ  5я.9tFlP~?GLN9 sAm鵙œ|ezCW)}SϺs߈w]$s#:Zd7ҧ./gs3/By&g oi7f/'_>zCrn* }@w>\H#>$p!z1W?q3+俔{9ǽn?&z͍\oVM_cԼz^k^jB G aEķp*g-=P|Jݎ'ܣozGj߸>пf~?|uλ[{?+zAlBo4~XOz\dzۋoW `Zo$'|1|~Erwˈ9^ 2UzA5ռ>V.+enͬ)<ү# 3B/HUtB.9S;rܪCkj@PD~&&zN,r%j+| zaƷ#ed 2ttiB7eE[ע土dewoũdK^sm俭b݈sȇ?{ϸ=DkntȽ,6ɯJqapH^{x9~,?;@z#zoWhoB?n  0ূм/~ У<%5?G4=c}H+amYu~=Ѓ@>|j \+ȝ8"7 37b OWIK&|9]xygY|ѻrHVد'==]Wc 4}JgU޻7WZn컁er{YqrCn?a\ ?oz 趆JL>yyk웺@x ZSphUIo0rs'|/G~fsɵ }sF?ezl?s+.;Ҟ}_': ɚʫ|KWM}j:E xsAy7Fk]ɫ$9zP*4~O HO`:Z|XErkGogPGt <^15wkj+uhzЧvڥʍonyt7w:\.4-88Zc7=})IM0>-=s~4=a9BF='!6֟G4y&=Zʹrۦ8]oC:9N$7G_h \笃$sG{>:{6ఞ+~ |_y~#p$-ޘO.uaeǿ~@xuK{lRnVTǹ!9C½[J^W6|dыnA?g{~߳K+ "\7H^X7'UD󟽏g<Q.1.w9K\Y3~;E= /5yGy6l㊼dC_uj0uTKKnWn< sXөW/o'qԼG3 zzy#|  OPMҏC‡J7x^]o~6>Fz֥{r[n 3>,M?7 {4w@Qا>owi+{=94Fw;=\m9w+t2Q?GyMV׽x!puS_߆OoLo`3>wٟFXO"g>%:/>ToJm=?N =|?7zӎmO GoN"FBkWg+><г`e9#58#zz_AdP F\y1A4 R\h{^Gy0ݝ^*rj& ..<= / >?ys SUien~Obo"TokCsBnh_mk%;z\x1tU6=ZC<NIƋM[%kRoOܿt_yT :C_atLJb]&9̿+_uuIod{yƫu_[\>@u3<Nd;HLyky_c}kkУVsyy-a8W< 9xw>z_mdRCG$K]?<ok9)kj?EE[I ƯB^^ЕM6.ܮA3 2:9=GG|uHi,}>*{s?<-|4s0=Nބ|#썣ydG5_VQʨWcm*z'Wn)|3q} ~!sxu>cA/|[иbmg{ƒCzݠ}3>9pXc&=nѷңLF+5~7uG~x>9_@)t;BTOљg<Օ|ߥ-9]{;lzxZKxc3'*ܟ8jW7묥|O¾7[[oWضȋ.!Y{)YUx{%] 1C|4|IXׇqz+k)^r<UQ|537@9JP>vgyߐ_G@Zmsȕڿȷȿt%ka)#}Xst{e4.9kz?%g\AyeoZ,|8鋼ʙ u?>ȫg|Uo]ckt;ԳO%}At3gPhG^ڕ7Jw3r9J~n!WC^| S{Fk̠cToD[ ~ɟH>)CIgK~M1ӦƾG;Q-#zCxg7b)ӹ{Y~J 'wxi鞒''_jBo} wE[߿~tp WO_|/lM~u^p4i {dN=_q[>9![!z'L  9 '\DF?L{ (;@a܅|gɯ}DZt ߐ>W}+A'/x^K9Zycs~eW8sɶsٝr:~O0w\_޷`]y=X?=>,sς 'p~+t 0?rv\|5:L^Ypg=;鹎7\!'1CM~A{3VsM_y^}};u'w *'1I_K/ 9έ#|/ȹ/au_Y$OH?3{1~D&b G=z~_.]f6d pҙ=г |~#>Gg1i 2n=E7~QݹJ{..ps[!]yX#Z4Jk;oG>}} Ƒ>Xo ?J)žVrMwS9=psʽ$pБx|pz8CoPOr]-z:}~pvN\QAOOS8 *sn5?yeٻ!ȧK~/#9u|҇tν/~b9R~k#?{ZSs!:=7.t+܂Z{#EIz?AV|?y?ynWs~֐6322ǐXAqtoW?3470_Sf34$|^bgoPgʗS.=KK+G~,լ/$Bv?|urݻ˒e_?z|sޒN3M%s541rB_Q+tʍ] Hͨ<7GA7-mf3}9ɭ4{7WRpE7ֲ;9*9\eߌ|uU37? n_f>9ܟAy>yQh{G~W܋ owy!ny_fgo3 ao稹dxpp_fNowupy$IUn&V')tӓN'/FاeCKƟ / -x|^|uכCOcKv_dJ_U5W<&Y:s',;ֹ>7]BoOOY! {܅/:px}V+ ]W8,#Og|Vxh{ßH:[E:lA{,EhNh_5iM  .iCgNsg%/Ee Q>惺c#Ko|;yqsAoMOL~sߜ/,@v$e(X~r@muM~Os\MyUJYWYwrk =: sT/=*7p¾=qMcg>y:\yl~/}o9TyCz[)C=LL4V7z4uI7׼rF_$WOгd{wZ;{0{yה=x>Ar8W O,\'^%CW/c>k79[jo]{3FzTtQC<P/ G*=zx tbEw O߮}qpxړċ>ϑ5卮Pn,3[R cSuk:w?߃^ oh;㢿?{`Q9Vwu x?% 5 := C.g tOi|yC_skM|#x~L{/NrsKsNVJ˓^^~?T˧ } ɉMynBs 5~Cs?vMz3~trKo˥k|^U[s/Wy/j=żݗ Js:߂Ӿr?=o'N\Uḽh_?}Ӡ/!w?fjG=8Do9I{L~~mُX[jK ƫV"k s82/N&~Rz1е37tsM<F>&t )>1x)2pCC0~6i(1eܼ=:K ѫܓ +gN߼З]σ&tmٽ½Нӫ7?NWv7p;vLH ϊ΅ފxӊ?cI5o+?RGOg>w]=L`x`> }5?ĻsVV,=ae+ _vc{oW@o>d!S #ӛ*18ʗ_ vѝDN6u |~S?Վ~n6{Ct'|Kz~JrڍoJ.'|L3QC!mVc#csINP0|m2/=~( r\dG뼢,ѫ_x1W'>?<13U%UvO=)?"Oo#Y?Usc4sW.痥 E~/x,'pz]|ŏ9''^>+z/\-|?r}@7\r%ڋo'G!"oD{vv4.?G=b_C @`4o =9%O-ݤ Qн§R [/:iu[,`ߘ{HB?I.ϫsZO[X=A@B,>8ӏǓ.<ҫqTk|Z !b}!!OshoYF['H󴗀wg*=x ҡ锍ͼyNp'xϺ7l[4Cgy}sUջyz|\PF#_p1i/lܤ<) Z@MdGاo\p!x%W7=D~(t!Cz~~E7";{}kE.X 7ޕ7G(|4<1SbKޚSsx^~;kd5{5gA|>uT՜I |nqo9g}mf'YKԼONM$g:f@hw>9ȿOy#GOT-Oȃ#ԾerHߞ.)be1+L?YV<$ONYb$/)es7wǿ,\g/#*!#ﴞ^D~Z}?ks/"/ vsWl͢ /+|&.Kt~73xp# 3>߇\xQ𷑗.~w5`~^YUkѧW~SC;subfBN{Cpχ^Og /ߘʕ#׆ jyuwJCEh%Oo(r^TƵiWH޾ln^Ϣ)3F:ڳwvB|}_j 9懃|GW" 79gִ۹As=~(N[S{ 8*s"J=-N4O~pOwytz.omslH/aMgޑOw9*w!G3|y?|Ab>x4{lr…S͇GÒ'x-"!BoM#5yMٻ#ҏ{yN̿!ʽQ)C8nuzoZ;^/˔<4s}9E?+f~osуR.'4½ECnsY[-'朂vaTNd蛣x }0c?ti/17,i0GsNm-xY/, ]3<.;>-CѹYTsP}ƯӑϜ}<k\ه1ʵ%|{нW.ќ-b>U?9Wi%^"|SQB>qcsG?s—kL Gy\o Zu^ɑ!#\қSM-}Ɣ%l_y|:mK.duɦpׯp.fuu.1}f!W}Ou$w!}*$3b8_kOќZ%9!ߐޣGS^Lk 7aڟCq\:_&߫^j&s@yߘC;In8]9ȷ'ѺD|T{ߍ9fc@. ;&sTov1e/>')]WB5ZEUl? 2:{Mx }6<}%M>}t~5.QzY }'#3 Vy<;~]:PzW% _xW55/W|48%8o~r>N6?w##żP?K_`s6 c"dy:a~# QzzWKp0_ ||D 7ͽ zCJWAtOghh{qZsϧ >^2͕=,$BMo6­ D K(;|%9oPj>C>Gn9z' 1`|'f`#ZJ+>|d(o5m2?Sxp_sQ4?:I{\t\z _an}CF.wu' 뇗ިW7奜?y/swu-Wf -9O}A\A)WPtƒӷs3o5jY xAטeqw}OC`¼FywkC5vTue sV65qoɝW|phݵ}-%s%: g>!\xaBZ]_ #=A~͋]q>&,l?yC,5{}z[Wk[?Q: !=U #_WUxE͚y7,?*uw]\aWsE-F =un&K+_<^1?5w$x <=ftyKf/ޣWxC&x=yg WBW\3׌O9ACy'^]PV09SBx(Eg^iq+NɸWN裰'\O}y?:Η=C~#iO??FQ@39Gs:'%%t'm8a4rϤߙI+}9뷅r KS:SZe !W~"xA_|LNބ wT ~]%0Hr} hm _zztrv|-\.a͖ʣйGΧ!uqL˥6>RxF>Qgߊ5LK9魳e_#w \; {[#ӃCMn< :SCwPG;iO祵pnrFKnvm%Q AoMNRgg6IjyF(#:PA+48(=:{p5tH5=~K>k|?5DŽ"ZDJ@7_1wÆ<%&.-T f_)/'Exsk>M?>X>5G /κwfC7>\R+Ggsz/^!F/j)\S.4;JW~AW.+8MOd;B>sEqgV?xהS9 N2rI&(_0Gh|~'E?Uzt('":B| _v2Λ9Nzru }_~&{xpIȱF=u7x8>^\:>ޏm"zqzo {ҕ7V l+_}?$(ZChpB]~N:_7#%9}<}/On {#]D鞕|N\c?"Vosgt 7|9e>Sa4}=t |+Kz|AJ^9{vʠϹ*><Ҟ]ş O<ˁDghp53y4:rwяLn=zikͻ7CmR?uu;\؏'6_"e|sW{ ECz.ʗ.{q{W%_<{Bw=]D_ أ݇|ҽIM|n.(|q+ȟuـWX!(t{=BGg{Y3!)x^؏ǒ(Ayetx|,Tz.p$W{VWy$q{s}nUVJ1O.y_U*8yog,B|EOҞNy|@ϗ9j@o|Zد|?7=ݍ z~.r  |l2<[D>=(腂.z!Kt߲e݇1s\Qs [?ini'hpwɒY5u6Sf_޳ģ$W*y~?uϠg'<+D7Me=3.Ëܡ6./{v*z_Ѕש{qMy)huQCr[/g;sg~Ot+Qe*3?Y=|L|޼;?|./gNI2xdA';Qheog&eVka}~ɳbf>'ZOU;NOÌ?' _Ttt/ E) !ҧЧs|_"/~|9@H9r踂}agq?=BO U0/7YxF8}0=o5ͷ_?vxs9C<,_u plrzgU448l+'߇{9vjg '999WAGC l"s|u͂WEj>NiR:WйGGoMwȥ9tr~;_?\ߋ>s5\e?'ܷq[+N)=^h<>Z{~:^SK;^|7|i{'g`_ N~!n=|@F25} y#6G >j_<s Gr{79^&[uV퓕;Is!K zx3r>Cs5FoHּY+]E9zCʹG78gu4W[ўI{h:::S d竒>̃[wʥ^M[ʉ#: mhMŝ 9|y"OctY9CgnJw(OMCwŸJ<<2t+ )>t/.#> A^$|FSU<WT2}{9Gm=^ {:c)A(WX~S!trSuќ90B|vTJ%>U~jrl;~';KO*ڇz+~AU[Nl VWn$wtlфo\狏I}=K~_ #[0OjYĺRS1 +apT>\퐟^/з7}!=56mpOA?#3!w_''IoP^y&>ys3&N!9Tܳձ]~ÊW!O{׎~^g{~ok{xo"5x?βՑt'B_n*W)7{ PM%/wO}@C+W(pz?_Eߗ.~9R9Ρ{d Hԯ~\1A ishooޗǔ;ϻ'4x_!7m_47/TUƛ򛰯jOǶy|tḄVI}Saze~>GWLK~휕ЙŹًW2= O\2 r:+]UjwN zIoߦC__sD~GAgkuyG#={c>it<#z;W例w'ɕD4+yv{6I8dʇEei͏좐ğnbco.5_y?(*Kެ1Z=3/\pWzGJOHexF[D{T𥍏w?kjM_ս3Cjw~S'/~FE7۾D< z`s{_ ς[O۶"b^$?=k1>){~tO(=aur[ESi#1z뇩sYxE#&zt[+pY6Ϗڿy^+}P}*̢*2#' W9Uy;{ ެ>ʽ8 :b0^m<3#t>S}2~U!=a&>zyڽ=ԏ{y3ľ ~9t$|~3o_V[tos;tH;^?g]={ɗSθ B_C|ަ^6N'{fIB39GfS<'8gЋ<7 {.}QW=ėh/D7K_(7旮_#_Sk~ݓ1~~0wYPt'^!.=UydSkn9 pOhi//[ӷt/-{xnKk4ocH.Gn4мYG \sN^+~Wo|{ z ]ɹ^fc3?ʏ:go1^!{F z󄟢KEWb+8?(.I.#{ɏJ=>@C{ pn!9[F~k%\'7.~O|~7 rsyM=kv_8cZ | ^4x~W+(ok]i~?R>r=2f>q&ǖ8x/گ Y;A~RĽ7p9|G =Wz ɭj΢y>?p|&eMtFe?aNv.L4:MG V%>c;n ' =W9~ߐdjk\JGNҞ~Dxv}t`1W% =˥>K>)؟ܒ/Mu⩧>๙y N&\|ѩ0_DKަDt'_>Lzzp/=7 }COQ{/펔_!W|m6򡀷{͞rpt }{LWC} G=U&;jw fX F^9}p{C=z ÚWLtQ{ ,r >YyMso;Muk_} [S9נ*s՚ ׄytq*B5ޏBދҟ-=~DI_x?1&_u3uQַg:dztu9>R_论L<^-᭘/O>P{i;.|=,[E6| oѽD9^lW#q~N>T~zrȇ6_;x  9:h||7N.[|g_5Vr0%nmydxmm,w +mUNTc~Np1O\wtnֹW }tpN>ce>brO~?ro &ۇm|%僣a9=笵uN}ٸU;'z/o yd]:7н#Gaϝ^i?!_)\M?9 5+_/DI]cF= c'yz8D@^^&1O;s 6|~i7Β8ѿĽ.)YM8GS6o~z{jCH^FoU{^鷢 4po8x-6pE/_.|DݫBN93B7kv/q%7n3:ϹS/4/*7tIgfo3ߓ΍_% xq_B DWWlX>U9%sJ}&?'#g4haÓuۧg 's?w>ѧX2JQs_2Wl|tKᣊJ6~pʃG{ŸLWyf&?I}6\}zOt/Nҹ|)XgK[<}*YY8Juww`y.Sq_O=_(|*Uge'[ o}sh5Mߩ9xqz믊7-O\Zp|-/qE''ZÚÓ3~!Rݩߍgtzr4NFsV_|^:G;Z=wg]щڂw$?cu3tOr1֞>c?3nh]|F#-y#\]9^93GK)^<>^}^=hmA_^z|Z/0O<ӸZxisoZ.]ܻNG4ǟܑ35-{jy7Y}uZ4hG?u*^56OйQZB{[QڻH0p hoJs׏kٜ:I[t%䳭$){]=/i~n!Tk:~'s.]%O;__^~΂t,G7-=@>֔g]Hu+{5trNUyज़7m.\[nULxmXcu $E{HѾuw^碣W,7kxck j=ħv>-[{hzyNʷ:'zݻ奌|EB}m!_Tg2b#gF7(; ɊεVYvƚiBu% \(‘[{=>rB3au8a^VQo969Ή;WU^VRTK w]ezjzw<>ڽ-tW.=3[\}cI~O9wt!¹Knl/jUVX~&9_zڝ˺ӭ_趢 fN'[쵂c.`Ion~(?tp=xnh4S0$M^4\uk} KOQ_3~6=3Lo՜vֱz&v~j=gGK*]Os.Oǟok1ѼӤ Zrܾud.)HtZ{=ϫv}ھH7Ғ qh.>Vs}yNni .^s^kNy~ι8gP~FIRPW9 QeW#5U[m^qC_4'Ծ?7ccO|Pk]3-^x)cokSo)r>ڿutftAxǸf~7Gi*o2_k9fm?- a:/abeͽ?xѺ^|n{Xfc ~ u~ͫﻼw4}3$6Dlwey*}>)txV=;*ǧ\SJ̑s=[f$`wяS|ou/vOkyfl}=+A$~o㽐l(l}JOI>7|5)O~3!+oZO9*5>o5t(g|rB:ZǴo~j­=0X/Zۊ^n|%=\ryE>5w˲Ojf;R\y=wGޜsᾼͳWSgo勶+SWr}>ٗJkknW-jOsI7E23/?5&U!v2O^ZEz7@|¥>W\߿>ަ 4{;Oy.4[E9t\%R%|~79\޺=Mܸp˅'7\x_;nԘ=vP^ ggJ?K깩¹Xr2_ˌkb{A}Pz|=<>Unlip_;g4o{ca6ss*Z-o~ZQxGdE9#_hwާGrN.ܳdqwS[Z}~'o;MS:vsܻwΔ#[x۵ s<4_k,ܨsM#̟}/GU>y 2o7oJ99Es{ ܛi>t~'^1H9'_s›]xYqtýu֏(XM>ػѸΞ87G>޿zG~V?NvPN.U"G-!q1\j}_Ç(rَWQ=|GGj/,;W۸{[֓sc=b7Ž~8r7  ?Ygʼn9_;Frg/^8Ek":˟*c"k|{UN{V^b8˳ys.A姊7f<`1T˿=ݸOxHw.qXQ uv OLmlٜνʷ\oz)cxsϟEMyYԷP;sK{x΂G1ukc#|ŧ|_ԓRM#<+so/\-SŚC5g?!N{wij)ve=^t՟i`y"|ܒ{޹P^|>R"Tu-ɥ-R<Ɩ9/SjyQgLpH?^g?mC_)ω{~ю|5'w|Л~tBΗ-'Nyj&Z>G;Wp _ \u4FGx3`^MO+Ǧgӱ227Q\+皝, \&0z~:m?qq=[[tܦSw`1Xo34־1_s6 ?>ip_Ͼ\"΍ʵs%ۚ_[\<&KǹeW;A7N8^YfgjvQ_7{31{`=-ox]tÄ luz<5]ANb; wh$*z/{<|I6:|?gϮz^Ĺ6twsҝzm-:{'N_{)y!^/N9;Vm]+|xk>|箷DK <8>o'_Ɵ̛0Oe^=5WtNsrO 0\t!ovU>\s)=&&Uq3LiGk/V~΋+-Żt쾽=>hš+j$g94.cW[`1R),׆sR/,Y0}Oyha)N:v}QYL{zPٟ&I?goߦy5g|'S.;|Ndn_O9D>:iy${V:'ғgk.J}~~17y+y4!*/'o?yr6p9!I%9yB/l?nh^TN,+|g>_,FjÕORT?zz|/{ҹC8`+_k>?F _2mr"'9rhFMGIR_ȯsm~/3n=]dCӔy)🍼!:Wy~$C^Se5^y`8vuYuEi)[7(g%9%VU;1/FgRP6+ '^gnC}ԜT&z3 DbïNS/7}k7֖h"Ffx9ҽ+K_,AYO kg 9P"~|Ɩz>cpzNxZ{oZ8siG?X:ݟu\[unPE폥%?K~Gy|49•ԧĽ~#s~IGNy k;DGZC9dMkGHy 엜ͩ,mvy7w}>OB3oQ4ʽ ~y/;OE=Urcegh^<3m)Qycg רltsT4CSdbuo!{7 #zk";>%*sx&=8_e#U (_sC)cc>Us룏ޖ!W{0{nwʵ ߁y |=ݽ؇i~bc'{ =e 9yq x{ȋ'}.x(PY̤/=} Xr,L@)w7 ][8:'|3J07Wg,t|{KǗn4|9s@5S{34R>\BCrFN|^໭$w=Ics(o[RpnWtYW^97+6Gy|k3'Ϙg]_1q"9CV^Ϳ_MW|-C. )L |.̧S[vcLÛ&܈}'"IC?oCN<sci S5|ɗ-Nռ8:zr#oY:%HI:E[\P繜Sz&y~x8GoO[s~νx3g0r؏]Nx0-~ƹItrñ/}[脍\)bז|E敿[8ٯu/߯_.vAį$>CΉsʜߡwx|)܃xéװwhcY5fjJTfl)WӾ;:|ݗNiv%_{Կz nsUi?>'8Eܫw I|K{߃uz*yCsOξ߯r~|t ~Ggr?MQ\nYs>>`ߗ#'4y{ ;92 m_= ȭιwuuOj*cq7M;%?[(W㏽Qx]:˘dxBswf:w)85<|?p! ޑHɥgχ%\p4OzWӝtA ͝}z#w_o޵с^ݚDzO W#g'rv-?Hs L_Ϣa} '}{?eqkt+{y/W£U搎\,ABsrNNWNT;˓y%>MėER|&MS͓\=ɺK霑 {7ȻüAZx/ctUUx^@.(){QW|a˯#`_o\DnTGæP^WMiC[͏S\wqiOd%yEvN.=./UƷ&|ws*o©su+;Kw7x+}Gr sdO=D{teЕ$イzGލo_4>$bTsG\g߭93Ar;iyit̽ .KN<~̌00Ol'}:w\~ؘԾӟzBs(Ћ.9U%rBlܱrtv T{RF#93ש_0<3D̡_=~p-wx~tUŪiO%ן7|#׸ui9/|C_N.搃Og'od iꯧx3ο+se)~򯅿ԹS|?众n1.J)ࡋ4~Ҹ[oߢ?#<~yK[ /?=.sšD}[PQ~9zm?Q1:^ >)pƭ {xi'aNB)yѿs# |YCGЗk ~}-~7cq9q_ctNOMWG*7O{#=9~Dt[wi{=ᄝ*ԿSji ~b)[|..AЁ0׎;znj.kexY^QNm~oEu*8}OD^9t}$7z#-c煾O}#ϗ~PDCOi&9SuG~pkZxpyGϖq y })K ?-WԾ -H'J/!ow~I/UG?;87<< yh{ׄ^IӃ_t_yYsuJybN/f} 7-'əo^g,oN)Zw\S(vH'|3=0N`Cw 7>\bod8~2:?goO>qtE|:ГWowY_}m6 J|Y Ty{ N~E_bs=]`ݫO\E|ޝyk?ecOhG{ ~}y\{o(.sw T#j_޸?'`_޹L=D5{@^r:`,o'~Nl7G> s;~⽩iOŽ4~{s |ۺwge̢\өVM\"X [sx?e4~GS.n *xKq0*v_Z|R;Lo J+9_jN9'.q"\l}y-TU,=8IT7>O?/ug7v޽{4:yN9զ>'+\er&CÿTgü~bhtи/;;ϥ4Kփ?d_+:zr?I\@~?rZoh>+|g|;q99 \?|ɏ<`-gK|4nMVqb.\_{/wN2p W=׹>'"zy3+hn! Ce[mhzγǶ+}tTFme:Z0xFZу{/|sy2W_3;+ }~ɼ$}nN[z{[k] aSzV\?ҳ O>oU>AgZo#  O\P8 >'WCdk|䖱כG(D9:_B$ <ϔT rEW3ߗ'n:0椃^Ey;-Qz*?^4;FOM5{9uk4NO$zT&5CX g/9T^^Gҿ4r97cUppqP<՛/9[?qߐ0>W;>'yOY8!_Eϒ%Kg*r;"M׹B^9g^s&pcOߋ|KGA_q)<~>5v/|6"sl4O_]~X?S=>_σOpWyO4o0;ލ_+$xk _# <7֏IͧK~sk/ -}2;EN߇|?y'wޯ_)^n`/?ǘ&@3F]=Ly~tۥ|UzGX7FO{d3]&t~r.#&4"]932{I1U1^ ^O={m=+t/x_*C~7չU{ϵlIw Oyr񁂃5r_A_=ș Up>xr-ʟi?7;~$ykDy 1o _D$@[r:ߑt2]okc u̹y'7<_D|ռzs7sRw;=x{ӯ`%|=iBf%_Vyݿ=xoFz.W}+=?7IʣFO\Pb|%Cya$=!>s4 +<O쯎Ɇ~F3ʿo[CkJO{^~{ȱsrmxQ6آiu><A,4m% #z5%3i \~=9ГJ=`"gyRDy?+5xd9M|g3y8ay +3=5硯w%yyQ?kOk|WF.y'(\2V+=ÿbm\K^$rh˼C^+mx.g·0O\8:ڳۙW{=o$B/Yc=1t[D*< oUgFHnW/[߃敔kR{Wx缾9{O\/ɋ{t-$K˽9|#~wsȳ/#[Ͻ1^8rO ?qC~_}uYxޣ=(w6>>Rcc!׾XF,OxnO /e>xD~"_ N1a狙we(=]|ܠq WO6i?_S} C}8#RWxIp?=W};˭rR=eU~=7#߼qN\IG'[D_^>Uyݜkhϑ9 G|qj,y˹9 x!D==RA /]\/Hj\侕PE*Nޝ<\=ss-<߁>&x+b#+z}?}!zAq_}I}&o^8μ_Go>)|=qv^)̽طirޓV\.'Q^>q79g|<_ExrseOAU,Ns{#A!{"4]chk\ʾdݼ'C w)υ~rVm<  ]ٿwl( D:+~}y𼶖:iA:xu~M_GUEsPoUs;~j1zG }=\}tȡ$iwo'1/> b}w휺OįREs9xlsX]#(tp1_ɟ>w+k5W*99ӫ/_I1uO9?= 99 t|#f?Ϧ4x99n0g7?o 吢#{TZQyn81_g X[y䈑\{};g"hvv;U\Zt78x(z{ۯN\}&9πۺfzFNcOpO^4f=Ur8|s:ʻw ֶz>ޟ'=ns١%ps.*i?1[|Ʌ:ޯl t{&O7bZ=o߇O?ͺ |ھds <&yuhfVâ^^9},M^QǷ.i(6OK= o=\wxm|µg @_\OtҋW9S*^|s8О¾>pqF\kKt߃ϡ9ۏԄ׿I>Iʀ}x!zW_F{E3z&Sf[/r/]ݔ?lG;w=29qGc.$">oГ4f3jz{} _߫Ɵ<,>xצ\{|>*3hN~KygG48cF&=}Dʹ^ϔs,I>Nb0!z[z'?tx]VΜߟk!= ?ԟrԯNp^-+9ҕo>JI)FN·F&Zﭤ Nƥ͓99 ͹~Bb~'vcIT攞\hk;8%8q N?<=Y_]F3'n4^ק6|~f#zoM8(4KKs_糊{ mu词WGAWK?zc徢[K9~]b|975sWnlj0r;WWSzf?"W~Z{693\'yrϽ=O'F^9e`oתs̭K7N z3Os OE^ %mnD+;dD^U;kN%pVws_ou9[OsIwO] <=@dX=}rY /?!<%?2o1/s"ROy9\<} aēSN?Tx3>QU־}tӘGBwb?gu*b8gǟ9;G/k=Aq96~9s3Sw{yx~wg"::r4$y|t5񋜲_P~KKO/~;$}Lv=n^8k"'9{a{ӝ47tC*p xޠ#w ]s~&KӁ?> O|S܃t^e*W=xo3xד_s?9N?@jZ~`` CIDž.ܞs>^z!񉠟gs1}nܺG̛%>| tѕ\qpr߄SE]7P߳\FN{r-sE7 1EyX'ec_'yoy rt~3CxhOЕҳD/k'_ +s,8םϝúz:9Om+"߆;7'ăsNOl2g3䝣g_?O}w6V>WWm#ǓRCC11_O72vpsAz1iܩ||M_F6B-6a׃`v8HO_cyskܫxX|gџi~r799hrorOwH=P}^}Ņ|qЉN*{ͽ?eǍ;8Zo`?^w{y~qc {< Szث8qN3RO.׾i}Ĺrųwޔ?\+i{!${=& e~O|u;>=kh.= \LM2/P6̓Ӥ/ Osf_Wrڊåsf^%I樾Q73cNq.\w~R|37sސI_~Yren$-rO)ݥZ0+˟;͏)*ΧE~.tO*\br<#AeՔÉhC7?~M.:ayjs++oC$xn mܒV]Zzygvdspߢd<_zͷF<ᆿ ?9q5yWP ?xk?͡=rf=koxxCGAf~ݒ} ^7zǽƷ@k͠k9G蹾y|?CS>pst!ܓѻl=`w}o?9 ٯ/ùcN?oue/g8<ɯȾV_Aڌ_0W|o} !h Gm_%cاZ/)O'y;>HfK<3>apx|K聓Ds{+_<1pxkEUW $׷ʝ>4_97_H77b^97{W9Oк?n;f?}S}p8wɏ{Ȟ}_t9#fko ?~|ᴮ +9WESYE=Q4& 9HN{?Zýs&OۄydKG |:SjIx3.|;W~*^In_t"N>¼yS/{^:5Ƨsf`+y/=<~/ =s' ~ }h]*oinP y ji侼76IzazЃ}>$|_|wWy{DRMt+S ^y૝勢oR2".H k|Y>CVO_>r!\D㆓qcZoMt-KsKVTx?"g}tޜ;9̫{|CsR=+s;}=|31_+iw碷MDA~}pD}o#V-W}=9󗬷;]:ssGWG(|rkBe]::Cxr]fmtC0339 z|1]2SѭVS?Qo+/=rL#9{CZEytO#ݮ9cj{IoS^+S')6v޽7to2!=:Z>o}:v?̝eN%m;>G!Lmvc)g?b)κo發lgg%+I}oε 'E;8|<嗔y7'7 1{O#:<r+uXLzrӘsv>Y_ |zk?{E_?8?+]z~pÇ=߸< ~vztS r/z}oΐ,r o)0 Ꞣy)>G_lY҇/:;љg?<>Y>@z7 Gx^ɱVJ~r %~{AQs- B(< Б?Cm0~g3rtO??pr-ŻDOOwC"1._f [ԺI ]ȗ½jg]Cs^Kϛzҽn1C_!xZVӂNXN?_*;9)4i9riuͳzxgt)tuW}*XF:|xv#Z"=={-u_Lo=ܮy}6AWrȏ,N"^| =s,1`5l+pGr3F |33N=B֑iͼu]FWy+{QWCj޲׮iUwoǞ5z1xDGħA.1GI y7 ߎy9_ I?xCe&UpgWޙt./Ok{By`rOB[6pir#"7ܗJ0aG3ϣ7x|S.W@newݍ?8|Kd(pIWItGz=B/0:Бeujѯ>w?ampީ}wxϑqQ۸FhsU˒kOХGڻ vP >)~p~xG|3IvZ!ϝs v5qIgBi#G޽S^O"81ٿJ{M'OO>lߤIɯDx﹙rEao-$`Sƀc;|o?|i—3:i Fң\|8Hm o[ߎ>n`zOotkM21xj]f>_91WV^W$kέ0scxikrn`?H-rcNIN''{} B6AmwI/1?Ao|>Gb^eXWM.nxȼD >soy9kޫAtߺWo$GĖ^'>C|΄4/9-+RKL>跳N>8[,_"ryn_\%O }|9o)ϦwthhkOt^Nby=dR_49ˁ86z]_]gk\"[2>C/zSy}7ƿ~HnW~*7s_܏{dҟu~s;uA}:_OBO3PW.:pX+W{N>S*r3ǀ*fro ώ+0_cϺӢODݺO|m==p1|@D]%pyAm@>A5]3x87DBzC;k?ŗMJd?k$j^:C:}9#VK']Ϙ{ȣߢp ?U[DP>S{OΟ6s ; W<7ɅoKsp/s"zStE_xOx`XJ.42 />0wG?7F;r|A9/5fp}Nyoz|'>T9zڭo7߫U'So?9C1JpZR9Jsֿb>;|zv3c?A|F6䢑P9XaH%i>^zc\s>&';wo'=Jws _ 89񞙿+ru[O?'~xеZDO^:77}{po+ 00?^_9ҷF۬~+9 ;;}0FJqm!?PkSΫ+^q~_rÿypsr:x^@'Um|spEG^=g z k: ?y\K A5_Ԧe6ȏ;ԣ1h8̿R=⻣= W{ ]шOcSnzt,l||.s#۰^AGB{,y7\|ɿt{˽?/Kob*x)ď'73^R9"םOKGsy; Jo*3^9{x·@|'[3h%߀ЛGS택HgB"{=UCO\&tq~/X''6Fu(Es1wCUZgdyq9|ȧ|k㣍^"?xN|̕וCBC&WpoauŭYGz*gI pzi.)ozj?лDu$cj|($V;.[9]@WkZoWL~Tu)ß1mtZ{EO05:C[gxʃs7:I_8RgLUem͢~ҚC"φ_/ ySRϪG9/F80t& WdNS9)/+\+Gr+[k'}f6\zʷbhExOn{IgNOMOo4oU$/$Bx>=t\ Όr8g^D!اC/쾓g|/ލ, )rE'2R5B>dk&<6Q*yT ?79'ć0WFqmpx!wpnyo,tVC~s=Oޖ~~?Foo$5\ zz'9_7<ٳ7GK88x 97ﬥs>t4T>~7[!ߩrtq6 ✭7؟M){ŇyқJXt\֜\,/NGs5 {/qӒǽֽ}.KsMG^'?xW ;wyk3xeϾrC>8D|w7kC~~ѹS{Asis{@$xZAS_~V(9s񽯨!_@>M/5W}u9g}Bv?խg #ZD_|zCsQuć&9X/4;ҷCyO 7 >y_9~bEշGΜ+wBÇe}0cn\ѽ3 ߆sVny0gGj.7E)&Kt'yU5s ޤc@zxN+;:&87 ~^[1W/܊EIz0rr%o oĺ|*ܟi82{lV8?l eNg|Oj$߬:kw'˼p˓ %o)nJ{ YwֹF6Ӕ ܅rkxZrE"]mճ==?u2O1уU*K{3>9[RZs 9΍ X'w5w KuA!4m+'t<7]L>et/~CP%Ax b.)6GH y}_t[D.:Moo&>8G;y)}EߛgOg|KN>Fv(09pDŇB~C%uojzWSsoiF+dN})BJ 厕3 ڕc^ppjq%+D=S3e9i{a wr74̯)3gbxA\e2/%?\8,ysԃxե׿DН{ _^n RgJ=xA oycjM._yʚ[e?4z}"o  ut쏜wAg|7|# g^b4쏃'}x]ЅC_ѾXmi|eBiH$<6'g{ ݭ^;/>&7 <}]uxsz(xGj9pE{8H K^n.^K9o($>_gXt~ΑA}g8 >oxqߙo DGZ`~oՓ]`|I?^[PAٺcpRo?xt. }_K9`~+yu*Y'N|zK~: .Py G*|HMa١Z]|KAi.!3mϓ/rgңZ\{ewe叚N}Wsy bm { 7/R/W<Cy7$}`ϾL>nV0>ߤӄk:Q>+zO3 "{'KpߜN ѣ%r8|{I_ H?r8D|z`Xr/?^9:[%>G9ڣTW<]u6=G#hn+??Ugq7{ΜE/ȿKO:z韛_?[!;X}CۿOh z;l:'slq @䉌>XRrt._\7bmKcY~髅?"}F:"~Z.3Oz(؋7ۺ)ux7'z|z;{>LYr_=K籓tE#z1+ށWCW#c>ˏ-n9>6r/O-NsSC77ߧC̑4W>>J?wK#_B<8Iz1#?<_ss7& '=S/y/{{up0p"EcŃ:zໝ?܈7}/VJ?=Σ@w @_ ݓOL9~9QUA-Ht;oϧjU0󼳄͔R?fuk?DGy!=Xym<9!ǂzg1sCGG{jM"='K^Y+='kB.$=ɡu. Ş'1K!{s%?2[ſ9S-"}}pƞIG}4 mI'4u_rE}y 7s|[] ANELcRT.튧S>81-i|dÓv}vcZW58E y`+=!k//U @~u>Q>ItЅ#2wmJ=+G< 㗡4~}rr9{Vg3?_Gi^>/|Mxp|4S||SwCG^=J瘋+8"81 |/ȹ$7֚3O- ߀?eoYW;p,8lcg:=ߵSE}X)8G>ڕ | }ы=B8Q/~lx//F׳[NP85?)y{g{F^ zۢG@ή=*ǡ=jʧ^*yA>ke/Bo\qtQSz]e}^74yfD |ѷҝz/M|ʹ<}3p䈢+v/ Ilo>W|tۏK^D[y}]cN9=Wڷ^FgNt%Y_8tC7/> $ y.*DIgW|/;>sґoGo3Hщx =]m8q,GqNsw_{>'x)qΡwa>e@_6?h˱4[k3h8&\5r 272^m[_8K}%BN=>8Yߍ}5?\D~]z5~fKs }uU}j\? _G!ھUݛt75seC9?s?k.bu}r_s{.aֽg|}os%_~~tOt8'("ȕ×x{{dyOǟ=t3Lz~i;cqn6OܮKȭ=$pasOUxZ:O9WGߟ,GoU_x7O}Ao}x_ЧSķHCmaH{?(yyo:LbtzwWoLb <8G>ϟ{GJ_2yGy/o9GǛp'x O?.җQ(]}Nc7ep/'StlH#7lzqaޯߣ6F|D@hRۼG3(_z'KKǽyP_ex~xlpYܹ_p_{:iz/*IDGxʍy$K Wyf;|*f&F~-U;mC +{¾1<լWﺈ~wut "gK3}= |(xogfb@?0p#o|i}Σ{bP=>\ҡǯn;j}<w%golݣ|޺'>ft սO+ͶS;ǹgW!?'\w|+7#|Է .ku=67#WePȩWAUų=sHP]h t7Ro/ yio"ެ/ 5~Ba>ݵZί @ OboFnHkT?.?Gǔ|fn(C_(g}dwRn ?sRf"eQ:tXG6ڃz{~3OW;rπR+=s\q8zcz{ӹ Oj~'rH _"y˹>f Hgm\e|sWσ799/ȎRn 8dia)~mH'{"'o]>~5os}?G ?'I0yKsZ 窭f17}1}܏gt^Kp}59g }/R~}#ú'{6t~wy9ϯ} _c5g*i_{D4<3,72^s(:YBO%nD~o9׃{uپoxyߣof7ou>Q/(;)rg)w|G.) M˖xM*`srCb4؝IM砫3O: inw*^{zN{Zy~HU{:>4a7(^J}u>T/ p:~Eϡ yA| }#Fn8;|w{'=_ݶx y~$rϘ Yiu7gW [uǞaAqzуܥupb>?=å×N9|hyJ3ߔ6eߗ~%'|k+ H~=qr>0x x5#xֶsOI$K?CzCrXܛ=Vʵ%ו4zjuʵ 0&'KLJ }=~guW^]&,er;t>8l!ɽEŧ󋟞ghMs'<9dZEKL5/,cwHzbRE\'^kw7~B>&Um(vl._Xv߭VL8<:_L98xscҞɡ(O\U<*|俖 ^~os9 ߆થDžg߲k_OSρK~5Kq@G9 ;.3HdRSE;ZK/+7-UYLjr_9zWy ~CIC|~^9̽Gڳ~sTqC~/g;NqoR tȕNr謫^xRsZKY{#Y')^dpj5WV7ߘpk"g7O8Az]t$̗#ʺr[*K(:mo=挡9vsL8qGﮯ !Z=5yCon _'' ZK^ޯ Ge'}dgFW˘i\cJe\#T^L{sw'i~N3=9_E ?bzZ'%gHrdnVx|tp7ʻ\1{Ќ J_)<9AY8y;9ש982v_u;k{F=#Â_їν=B~ y9K􇡛$9,уr z+/ȽFg^ï4ff#w]a)pf9^W~y?rwn*'B[G~&Ǿ7AguG}^{~C\i1_>GO0ts?lzwF ؛ÿ^ŋ?Fw!(حHg}]:el~3Y~s=ape|cw6aϫ?bI'U"S0CI_ᖽII>?x g)?vC8g]sFҼ/ZZK1!od MùE}/Jß? IY"߃3/;ORsx֑v%y[K;l#k]^"zvOV?$*2#q]=< ]q0dPqׄUC0qwp6rq/^vS$|33/^}k{ B_^iG5nGr;۸[1V|սKc?o"׋ڮz/{?=JA@ \wyeҿpN]`.,~ޘ~'/K~sfmw!'y\#gހ9?^G~ty}&>`7^3/\3}\[K/<ҁ7rx{N G'>G#,(i%!zN=smcU?t!V\1et x9W٧',]?^./ ;1~'\|&t & {loˎsI?oo"+Kk+ .{&}WH|4:irɏCYl"}I~L}?(G~soi~ϣy_j]Y^+?SD7%Vs?1:vM11~ׁ?l#ah sc&}/?<< j=u@zi_j?p)Okt*gWnh >bxprO/{ɡG/o){wg/[Cs&_=XKM\oU9n% q"c~L/ [&ܔ PϹGzqT4CGO ] :)b^~|:ƒp_/=zI}4?59P% ?uOO0"=j=o}/|gv)pa| pϨz(t#" TxdVKxc>x%k;.'=7:=%|ĕS 8~ =t 􀀳u~~4ΥEG_9]6fu)yy[xͬ Rʳ>ӕu>PyCY4J!Xg{\vN<'3-C=&{@:75F{u̗9N:&٦W;Vy|I罢wy~.29 kMEoCo9r|~^B9p7rUO_u*(A||q_V2~`~<Ģ1'{YCs]֬ b'\X?oOJs@gPfk兆?3G ^Ϟ;jτ#\@/s;4߻?.i̍WZiG/=r'Fy0ϱOżZ П\{:Q/sr4{ _ry9>?5jp~u߲%L=oOw/yGyu:>Q94o}\ĵU7RLb8Nއ3K33n:za{7/RP]E GOr~{Ε5? W `r7?5zvٟC"t=/N1HbIm/z (>\r+ȯCF>}4&o"~ ܁א @N{\")\nʸ5^5ԛsV)+?eGᔕ4OC. ?IN YHU1/4}Z +fVJ!vy.cѹ ]:QxsHI~9W9]{^~-煣;"l/^D C/P?8%tR^ubMXޠD_MGu%dt7}:y|o/xۏ9F?ۘÍcʦWzlA#y6ݯXtUn%8~2eͯ<;y^ss^3,Axڑe]bD7tFG&8%}~\:Hε*Ϥ|"t+u_g'^|86Ӝ@͌Y=7?6rr?zO}EA҃1M[`WnyEV.a a:qrztpry+L\幪uzCwXJ<@z~mܥy ;':{/~ =ZgNϷDUƿ~oS>rб綞sަstutЙ1ݸ>9<(17GA@w ^V֖|zwN}Y>Fyھ?sl<+  ,ߋ-VNt{'HF5~;MߘyѝϽX[O{>Y}u=#Ƀ'{lÛOA>/ʓYaywe=׽#ᅬy|p?x,=%97܁{3|erX/wR齁՛^zk cG嗔}<[F9>ͣ3g||P'ЙBY^y\pȽ /y{z0vw0[&HI>BpZ/\,6ҡ.K&͝B$3}T<1:17wظ_/y i>L|| J t/7J/z/xVƊ]\ΓOatjs/>s.p5yϿ?w/c޻ba6x hNf]Ŏ<ד9u_8zƬۋ= =7kNz#r/+_{p| WDy?dwrz'OVCL1z6W>7#%x%pݏ Oo:x{59q3DOu=V[{1 ~sB=s?Lz__9> m/A+SL)9ƇΥsxh1~hyϩ}|{c|bIow[VAϵ0ܹdƃ-h=7͏J.{WiN^tLݥo]簵c!7rJܔKt՝uT+2?J.CWR[F{=ݽ>K|Pr3#_6wվ?;>p/8__2yË\_8xho͇;\!Rc9 } T|tԝ7fH։xߌytɔ~']Tok"_p<4I>C'y{4rໂ'^7}E7WU?rEW&}yi]3?Gd"[y=,wB9; ܰ) G8=h~GOOΨӟ)ᔣ<>PY9MyЧ7eo龥}/|wto_W]WOkߠ'"W5xyisyh+syy2]to/?!H:ˢG4t qdəqENuj >^gr5Q >Dsq1/sNqqYt6atg2GciԃxH8 zL;5_z9LJ{ki?`o\1Ɠ}}Ρ޽ ߟ󶳼v=u787%瓓VzXDsOH/^w?1$rGbs{zONt)]Z$};ʹ-\Ρ=}Z?O<0GgKk#yM.| >y^WyI9w/C7'Cop?7x&:H_k^9vz=G\yϜǛѯ~ EpoxB;A-t-c^Xtҹ77!{|Χ9pd>4]>P78Tf|O#rSxp'D{beR 0gr-5?4ϜDz#zE͋bļsA !_Y{+b ++*_XP @ߍE~r>"|xO>[tNA-/䠠9&{iN<\ХMߡ̡=1KͽӝY71&;f ?2`n^zO"o'w[-2޽w[cʿԓIro}|jڿ[sF'<Nce$_{| ޑo&~ KZՋ{}tezCA^Bt/"ڼy N.{xwk(ޙ|b佄98}Aƣi={xT{f8 6hݞ{_>6WQFڟH=iS9nNrLA䍓yg/yQL|GCFqjasaϗng{>.z۪'i.A 8+|eH>ά9$zQO3&oo~- ~TSGn5:=_6s_k9O?,B{ Ϊ:z'1gw\[XxLcW_\U>xdr/wu\}|\$?>MmQww;(Ǎ|_O7hyM:ɯ})X_r*o'tz xN^u7o>qr[ݛ=;;9M- &ߞ6xG7 =/##ӌE:n7N8c}O7}{ji0[@!8 7 0=䎲!/ >_d_ߤ߳{~]S{$C7$ѫ@ OW0OV?|y_O毌w> ~8]҇{|97l̯==9DΆ}ŁyyxtΝf` }Oݨh>&_r]hwy;R օ猴"E{xyygבzzmwWB=a{W_|z؟<73~)NOǜ模3{~N/)DphgyEaQΣx/"_~zQ—E:P ;ݲ;E}gG\r_gNUn Wk, D.<17_B.w_",}'|ƻ؏BJu ok<,xCy% < !y_dYG;wZ'L%=,\̅̽7C=CFٺ<|pxz? GCyCnG8RϚ><;U'<.}((?}oS.5דgϙt#?k7~l6rpTZ_: tAsy̍+Ox^{FOOt݋oK?G?ԧ߁^L" kmy Qn={"OL <=z&oyq|U49񏡃v>ã %>( 6fr>Vhm37>v4[1޿{Hߔzg3R<:#Fos{$gں ӑBx5Ŭl{ih|Nzn*CKR"1zvK-g~DύUߘ# OOfpTx{k(X\1玾mT駣7 ;ϱ6Z76n H>z v+']yMGϥ?Kgwrݳ琇cL9~I/9I'Wsg=S}_{igs# &7~6f+;p,pʝʥ@Ŀ,HΛlsQq (=CDy|WYaՎK?gx#O7''A}־s,v~{j_ץ{O󐿧F=ϑeI;?X~w+#Xw&5:sL:>]x#x"ߑSovyǧBׂ.0 ro7BO/@>ke٤{`e߲҃?N|W~7s7y&䎑 ^Sw4/q~xMD{JK}7~>;*11ENi#,; XI=gO&{>>*/#'Icqҹ^oud}t<RIٙw !ȗ }VGn{6xy/e7DDŽHN>KyGN~st>dOH'=9a=ƿ168nt_:'\{{?|N|4tW~ī2wozOa]FF{nB;{Dr?֏U]K.bTwRɵe nꚇo&rC|ζ0~~V?z/z!e)?<9gra;Dǽ/-gwx,6S`(ظnyn$@zcϲ(OtT֟5}:I4zߙ1_6pKߥ'+_PnoƧ~Q;zxZG"bՒg {CW;^tAۇ-ڿ'Mg.#__#5HU:W'{*@&=|m|Y k!}<**?Kg+o{uda]۸]^V*~߇~loMt9JI0tzM8ט#u9W=ˑg^WpC>7rG /Eo >9Oh_s ݗ*|U5s&Eυ|Hhs;9-rߒ{0zRi~l5O=gL}ϱ0AΏY7}uɱYKu[)gCd)'rvK.m߷SgA +W5?s{$yߤ ÷^A|(6 _|aoBMnq|[sQȋһ[ٽ[u|g_9U}gu9ǃ7}<,HL,<O 2pߠ(HG=9}ն#7(:9N8Ҙ:ɋjՕ߉~|?.xMw$_}{-Lkω\ʧ}"ָ>đ|!qOsT Zi/=R"N$=SH7^=N=qCgdCc5sy8ӫ_ :oY9áOܜު|CO9SgJo_=<<kK\| t|Eo _9>?f~?c6Άvt#rP3V]9uaަo޵Kwḿa-ݡ=G/o;[H?٤D~[K*2zI}B2\.o~{Ee_{&z&n~ ]Ny&9SW4z٘# \s_F.yg^:R37=~esu3軍7?%_y#Iy5/b<+|_zOcBoy~/x yDzLU0{B/=S\II/ޛVthstE|g&я|$h>Sׁrh'sg[M5IB)z/[wOiOΫCx5zy>xnا+Ճ_4+j0w(}̮=*I7y>觥_ >tUks{TݷWْw<&4g΍ D<ܫsΫY^47ș >eWd? f~}d9IS񿅾ؾWKȳcܹu[@N7>™k)<;>zx{)߭ n~2M_w^USo`7j g5UÃ3s~.psHy_u/g:lYٷGדs+%_.+OseO_^ <¸LXD *h{tߗ?.[Ky#_rSo&Z_q=zN|H>\ڸu*\?QxG{)~]f>(}m ЛE繿3Xz/|Nmpp#p8|+Ļ0'F.9+Kzu޽W}j{lp8)E!Υw:_K+>j>s-=\utqj+i4[{='YL|L{~FszCVNOt?7~lhn/g^*ߤagQN漨\NrTx/RJ"'|kCK{o-PN9|u]/;rܣB{Tcuv&+GcA=tAT߱;(=\ ?s=xO|/G_<[}u;aE?;I޴w|W诙7qwZ7cOq,M^Ni{lV¹ǵK xs:ӟȥ~Wo#YᏲ4}s!ǐ'p1 -'rV}V6oGg>?<_sx>pȥ"gEkڏyY|em-/?{dvr1^UNs}mty}u45CO J~5zN9zioƯsgϋeϱtxZ.Q zJK-sEo9ыK/ xm0./4?hˤm.oݙ4}|dc*&BM^ȲWBWOi遱m6[umqK]윗Gߨ4tGݕt;/+GzgAbc}?2|ί ?#ZNԾF{:Ez5w-|:4c=\XGnIrgJC WΨ)>7&fsHO9 Oy5غ~|Ont;zK6䌅.}#|=|YXҥ>!sk|~7tqIgv|0gsVIHqhcޱ;y?h}*yyC0ܟ {9K/&(m&,7趚ֹ+ky9@Q /Þ|?mZvcG.9QRzJkK~o*<3?/6N@=Ezi`.~`'뼏ypq'Ol)?|[zЏ/9q^7+=Ur[Our6=U-ٻf$/=CsAkjh:tyd ?{w_|~z~ћj.7^ERtO"xwsKu~FO]ßex;Ad#~;w/zG==Ə<גU^_5΀5M;m=aޔDžo/>^>6;=]4ӫ_U||Bzcs^;G{'S"|hqybehWrCsXYSQy܁3>>'PM9gO~CAz=v4b]zo?c_BS7}Ό}ܦ=X:mcg@<ϹEU~@pK'='}"95뜋d~ĝ/Mw+1d3hދ~Js9,s2ʮ~uO:Tcl}jc0w-_A+x'|>|kfG~e>!78@[s&/+tSkjBcG9:Yh|+xs샱4D)~=be #m={.|t̫gկ3a>מ1<8?^{ gFxmUwO I| AG5nŞY"}^{zoנS̑S:]|Nx`8Ë~ļtÏПW["g]Cnг'<)'J'xރ~-_YrpgmƛWO~ZbyLsguDy`t+qnY_{:;pdސt&J~!>tʇD߇ކIG.zat~9?.ssD|PMN3c6ߋAjg7>@p?+_}<9w P*p xI#-pb"_ٸWoҜO>l7F~ 95܇yls?w7z C쟵xy:{ BoPyA{@qwV}4W/Ş|MK3T*e9w%}>Z9O'/,h݊sx;aG{Ō-`Nt߫su摞|99:EOR8&rX}2/B|>uq|wcʏީ}qTt%G}k},T`Z_wyޮyޱzA=+⯠Kp{__9o{vaG{W>گسzM{hپZ렻{k.l\oUi4֖OaGz[_.9|<:8{ϥdžMᛵg :6{ FI⽉ƒkCCVy<|oK~K$s(K cp߃3m|}O/N- Y$8Eϐr+c~zCio~нvM|g~]|t"זќ΁=t~Vtoi403 ?yoD8@A}G!G>p#nɻS_^6v: |fO)i<1oͭ;}gȽ߇?+pE"{ 2=%3y.4Z~? <6O~t1[鬵d_o?-&9<G)7 ZzpeA"_z%/~`8o}Ew2?5~!衳˷ZG> {=6 A}Ծ1Z)W1+P?=_ʯ~ʹΓ{P|dI3'_i'uW~󆹩V}3Z]9͖{F9ϋR>g?._"jWg/{Nt>eSrr!m8v!Zl=}ygh~ GqcЫA ೺=ȦB=,/<$ﴤ(WIyv҅z_oS@xNz魏,W&6vvWN=ksȜ@/7mG\(_֑xo?+N5c3ϡ3GSp>bY݇wGқw'?iϽS7|zO_-ߤ=6ϡ}/>okk^w=(Uy}o~>7g?b> }\{i9 诂DgN!Tht)C(dk^:W(<6xz#{yos;ʍ$!|&_ +9QLifi s,Ac# DDw)(oYѡ/wכ(-}ܗ#+ǵ=Wޢz.@g|=4k۱;—C^<|O^=#SK~ }__I[[߅&߄ >筿ǏF}2c#?auFQY/ĺСz)[z*.\>afecӴG~/s<_v^ ~RI^ㅃw^]C9棺wO+P<3ʧb*\}\lS̗xIzÏ\^R{񣢗'ސjɡ_fl9kf_lޡPr&ei9 NPWn+<3tK_pN/$#|߇ýV{7~NUy|[j=|'ρ'u?st>߬xwtznFwNV ?~{CobsD%O1ZA5u}LJR~ CV[)0odl>7a\qgnt.INQ}' g~Sr{{_ ?ʼnCkO/Q1Ӽ[Oȃ_}7 ud'J.Fo~FH9S2ō\0ysc>ɧqޤ3eʃ!ǝ~Srk,]G˾ ]uf寑s@#=XC㰏=kz; V;wtw[ងot;#ࣜ<ݯ7$웈|L#˿~ҧ |;\~pL}5gOQ+p?7LV9 ȉm&YvG~?(Y: ZgU1~ҚGM7O>p3*[k~}x>7zϐБ݋ί o? );P7fw|y1o2F~-n9xIxxUx%ʻvryQ/=ߊߎxpzgC\xrz)#/-tt7.:fM+S'"_X@Dى+':>Ѓb+>ږCgio?ca~j. =^|*33_X_Pf䯠d~fNz$3i}zٲW2Gbμw& ~ 2g].jgzf1nx6ֻDO?q+u4|Ws.6>L6*)Ώ0իģ.͸: 5VC[7|XO*zfz8ȅ7yfis~p3Es{G/q෷DΙ B=?W9! g?㛀w>N:? %?b}.-ꮮ"{\NǾF#7>ᜇ>0=9&wsGM3 ٿd{=!2$|Jo\:ڍH=.g\ytQ;}c΄C^@h<{gӾ6S ?s"W}Z9Zrl<89BNh|쁎MQivptY{ݣÛ >bNç.C.[k#_[;#(?T|9zi^Ё<8RJ}fN}wAs:z_)L͋eKk_FskiBHytNbARNnP<蠘_d>>|>7x7GGZ隆؇s{k|& |њ+UkC9ལ`2|/'_KEW^Hky7P}Rw>+}$LX=¼M=?y. yt/ }ޫ/=5}ux-qC[oClpܻN4ԞGo:ܬ]r  й \8@s~ߡӷȣtp Kj窢{'}z96M|D! g(OȯuG}6Iy"m7~;hJ*|_x?cO t@/v{!YUbt_'^\zE_ry)2o^Cy%oЯ>GW1/P=Z}KџT<{8s Gs"y8wV^vSgN-~&|Ou]-ʦ^x4|$6ўCuu>W>j+OCt}Ӎ]CC\N՝9^?n+ܻ=CӾG^'+}sw֞GPl=kp^g#O *=tqw6WDkK[q@tPWAͅcүqe{ǽ\7zߚt$I+?ϣmK "öL/ >lA{캔}Brmܲ}xr0ycꁏ\M Fz臊'\8F@^,,%. zO[g]s(C3?_ |")o_>QObOyzG~'o'w?7z83~=s8/Ћp"?8[BΓCWϊ~΁#V̽+?ZM>zS7=G~o:t(*z^MhFN/sCnWoVW"W|;=Q#&>o.$S;"=ӷ-6Nz)E?V'59=_  9sC*\xݿ$+]䛢zm7>ʝ;+{s,/\!}#_<p^vwu"$'{$.z'&̬coϢmQ}pcW9wާ7oMI>>'n;w~uyǜNϸ?? tw>T x QŻG]ZK'^ssApb=%m'43~z>I=391 _r>q/{B_Nod>SO=s+O>|yUa^ʟGc_dkUzY']=^6N{~݇=~WB=J>Ur=ŝ╝TxWS7/'5]<>:O$wRn=o:YW|+Gr9:{? 83s^A_\]-!|d#Ogy$GNt?m- ܐrmI^lsǸ} oW)Z''xg`Oao5ECSkBAFsA!t?~xjZ|XeLy=?^Bޜ~nG\up ⾄s|顗!MOy%!nas|r৬/!=Do1o1=Zwk'buĜ}\KkR8r 7ͮs|xM|9ht4o]dgWp?/< zϦ^cWz쑇9%{úE>4oO^I"-ȟR>8kzp>ω(Zt#À}cN`er`~^ɹ9;wеXQ>Tg$^ٰ~]X!9-t_Zq+t'oBbw4^υ0mNM*8V_B-oyFϥy⅚K#w8zGK qx^o}Fw]rY_S%9\6Yͯ獼X~ w堋O ZPz0vSwW#?dk|>䷀x+VI=O\My~/[ukKos9$tKkEoϚ{Zy? p-n>miO'_Zy~7c콖~Bx-j̩E g 3ᬓ읽m^5⫤?4re=g K >|x'wgןG>4Gy/2Z|H!GkCzw:GpǍ߄=T}c߱ߛ \lyᩡI9[N| w>za#/KzSp 2/΁EJǜL9G^aХ)?>ro6~1v֟]j+ g1G0/zʃo]I_F*}}9c^aapfcc/='?/^r*'9{tChCw?^Fyg>aś^>ʦ=)=\ k$9؇ ~ ?<(0?[ 7=.x(Dїj~y~@SEnQ=Dž^ո/ed)K<%$N~FsP%6L]}Gr/gď{Nn$S_6 k)p۔/<8@A@^!t 7M{X' PPQqW;_?yk?ٽ?g3xЏz@nW?:u_c&?Y}`Hc~7#^Ϊ;e2I&@/+(}ľAr[c C1KXQz6?_*](ٗA2ϲ=I[G c:k -RzkG [Ϋ<|lC9\:I GɊ!F9@3UN%OtVySǀGQ!ye:y's񽯡[?'g=&z,l||3 =EΦ?}V} A (}h0XxD;A<cFoeeK{ӻN6ۙBx@ep]S= a|IQ7C:o  97|{G5m'8VTNI:fK&o~ ^W<& x*zUsp/Z8I+}ڗ;7u~6xtʻ'%k xOxW$}!:)S SK#=oCj<{?Rm*Ogi&G{wͅ9zҟG. 45s R$ՕL~=r!,"TQ:_ 6~?ڹγ _ ?9=<'^CtS<"7ĸDiggmih_x(!;t>Un.C4{9e|-l,xht?낾zU姢'?ο{$on ͿPQz q =؟Kߺwd 'ٿy^:`[C/]=8 sʸ+S}z?g{vPO{*C;;_-wpΝ}˵o>%#se}E-?KVy\ keh1ڇ: EwFMy}Q{.G}׃_<0OoçlǦ>iټ)X}Q;g$G_Z5-<:cVG[z6rjI.MgU2=S)LzM+뺗NgGI3"W5|&W~)|^r'Q3(ĵwW#pvszk\zI9̒y}ca{F> #_ }ngZ3: |3z{?$p-ܲ;_M=+܇}z!O1'<^>ǃ=>,B[c5霭+3?k|WQ3#7&+l&'GK/٭6΂ß;y4s>3D'꿇9q*t"}kk{WB9+<{?)ur )ut?ے?^.}+bG/4zWC%=k*/]yoWȒ(z<~{w}[n1?BwtˑَL}'9/5EU6_|y'p to?oQ!+?2^٫%3Ϫu{EǁW#|f!I4Gq_1y/ U3>Ƚ{fo,ywN5}>ESz^+_~f ${z sʏ~>pro'yţk]<^+|=Z!0X{U0c'_iz"g c[d}$:_D@ti8-]𰜗%;.1;ͷt\EZ4 }A~s6 [缡%ؿ؃;=#>${:s:F>y{jg[Ib. r{n\dx 5g$(ʼF;eD~siF>9+z\TOBAwvnG>|Dy#97(l4׮2S)W u!3es {Kk^\gEd)_}RyK1xfs\r~ 3Dϥ|>I_KO9k)O:w8Kno#)S⹉~l~Gз1y<#0=n9t1 ߽;*km_ CG ׄc'~7oů_s'&.Byc^_UWt ':S|x{n2xɏ(-}^8o M<8Mt2yB||oO%~"_^v/{S{4?SfǹT_{uoهr_~N|˾Z^^h y_( =s&"fc3"O>5h?YW8KT O{>s{|t4zKߓszV;a{^rm({ -9=z1(o)x s:}p: '?'>r1Sǩבs8RK+S!*SQOs~y8C3vwTK )_Ty foh c#:稷ta/xo$6zWo;XsK`ފ^ji@ڸQG ЯRlʏo}5xO1Gѻf(7.ռE(^p~=S]}:y3~|lb~\@>=:g+_ĹCƩc!oDܪTxtoKo͐cL}'Oe}- g4DΕ\7*NJr,] ʩkJ_ ]$|4>Jhe=#fis_tҽ:p.G֖ϑ{:sVk<ǒ  @^彑78S:AsG9%IkUsk!:hhH{}{[\ҏzrу?D}9ݻ+|)gOaCoH?Bx18;r7/|IYvz^ ~͔ =OO1_'E7/|۬ 7 @L5"Ŀ/=O~\G:l|OÑO3^ݜ=܇IЧϓs/}rO?GpO{ \y?e'Cz= ͚oB80b|T с rM?sUx 1Ds/&W_ $!th,ad頻K?}>\j\÷ 1lUo k1/N!wNSO<[S[|#%Y:›uӋ \ۡ+z_HyrѺ-42G(Eϙ&ø:>v_&;z{-򷢧$qugPzm׈:irƩp:>)X'O4pW\g7>8xO<yO&GqΩ)󐹜U JΙEyxi ^*!=Z쉜w1ρK3DOss \A|( 'hmqqOJۜo=`mc#ڸ:ȍ \ϸ0yvC =K}8OvrsB`6ROöYI:} 8vNr˦\΀|;lHOMs!Cܗ͋7|Oy|d99z^6qܚW:诘7zʏiqIwnE/{.9r?xFMq= WG_st`_y搷ϧVIs\jqɕ$Q3q?ϳn詒nV=ToeC*#oЏ.~y}Y!ҙV9|acӛUK#0k9絔t ?|+}LNn&LO$w_}usۿ^ٿZ _ O!~AnY?g̻{c=4< +Nz*g+ox5 ?_>|; 9O3myѷ:a{22g+@ {NWśK=arg ݹൟҟ۟bwBK>跶bI>aQcCu΀~`(%V~~g<:wTwz]UU3+iѿ0l*v"~ |e}avvoZ2cŹy A>wt 9fyٞFnս S|+_5oP7:«o?<6xg9jF9+g&]#onߙ|+sg~8#9֡z蛺h?Wsk={" ^|G|zok Wwv/ɯ/']u =γ ގzUtܓgyGNhdwSqgyO^=\6Q˟G~cQBq}lv)R>L<d+:jtY0co|:򹝻x/ϗz_u bb&ς"I?ss_"+nܐ| ɯ/ߢ }'7dyY^}98TMP~PNn@sK-W$:?_DχXڧݘz` B/M}@CGO@/_~t<(o}gse58m{㷔 k y%u~\<9Hҝr4~?prǞJQ\7~яDoswi$vis^Nzh?.er^:foq|l8Wбs~84c]/pӜ_.6s>(357o:›ϒl}d< ['?=/}WxW2nYtëP~ ҞAѼ WѾrͯ&1YNuq[p:9C׵r]_p5^ N0{MևXuŭzVz7?tWCI_'dU yszn/y2}U{|q9|^iqoM\;>Auoz_A~0:u'C,|Vt]7q_ (,&FҫGg|)+?/&].+sO,#ǒszxї|z̑5}yNo|壳SO=u O8QsuGh#fxarm *(r=?EK}9_E)S o]=4V$Q\no8"O9`t[ׇ /S]~N*h{;3sICS|,}#S[^<;fwndW7V5t..z 1>ϰϑ7pVhwpUkf-|I9n&]x)A'*l||Ğ˾)T 5' t: 3z ;~῏(8[1BT~tzw0Zb_NjUzѝ}g|јsMEGNq)z<ȋ+crՏ7TT¹6xsq|x=FoI9|<ȏ+m!$OMJ PUtS|aeԹj\IvƉIwLzB;@|^%E/9RbI\u.Knͯ/_KKyd/e";zڍVK{w_-/^gë1;މ^x˶?waF@?,yN.Uq[;0?=m俴N )/~q3}|䁣kOy|?.̼ '?2zO_9oOg#c9nh^WZXZ]x?fn=Og;ǾWCEҩGߒZ#Ϙ+/SћZxkuaػߜm+>xr*w9~*>ƃ!غt÷ f̯k} N}` ޼L!_b=u8/xwsT2|:y3suxA7n{;엑{ ])sC&]?:3|W"YD]OCOӣ_-Oϥ9e/O׾R;9h{ai,M"j|68蕚 ÷o&|DGN z懞_K-*5AEYqo~RTΛSs,86G}t9HI~vnlWq+ЃqJf,0Бydݫ'l'⼬+\'٤ψNzϻ79.yW9-u^q]!'1W:trj|>c~Yɍ#yw}~|d~GO|Z|r5&n7ƗO<#\D|^9gOly^G,+x@1'_߆S^ys/Nyo/ȷfG!O=tuN SL [j[+ _T:I|_8/+\F}y}C7l#/c(z{q=3o[I*;w@0q)Oɱ"o$:U~Vr39טsbOAW]V+pQ6>"a0v.G䰛"\g3sOGa2͍k-)O(ofS.9<7ENs읦y {x>Q^): S+*حUgF|k }_|OCGrqb>,4{$?|3<|s}yOyC*pt٘sW)N)j_kO.4g_\N?ov^tvq #^}qd?~Sy|hO2z Iyw c8)ͧ܅)]sn||ܷvo|Vk럙p.Yڵ[?]s q?^<@@!{(H~ MzOυϤwt݆zW%AoW?HoEk'LxnYynGFrI/y|1]KQCWkhjr܉zr?oާ]޵1#Oj] d9+n?_ bo$w~җD~/(wO.%G:?nN?([zy|w7kO|l){y?bS͙VnM|a'ǑZݽqyx6Y+⋯^<ǜw~{^\Wx'Hx G'8a99kGyL_y<יcz:7zWSފ1+g?|~VIs8qvEnY:Bq?ټk?B/G@\f wOs<%H/)/si97؇wjss6<)$ϡտؗj_m_[̡$=~?Oνr£B1xijfK^<ʛ9+䁵ޛW3?8mtBZ7КiD{}ぼOg^$(y#VOgG&Z^nO#z4ɇm|/ea*ݮ})_F(">/yx:~8J܌m8U‰8'۽mԋz]8o*&:d|7RkvSi_eW n[zCCJOշP_kBn| >gx ֩>>wK+9"7%0}B鵍o7osnLSgtûKo{3sSCK} q9*ɩgh 7[>-Ga7"Ϛ&2p _ލystZ#K? T9B~Sa$.xo_y5CA#y[^U[K .^q/xxvo3Gpi#-|_<9_ ?|: M Opߤptx_ ߗG뾴 ^}{/=[͝t"K㶐NRvv8t{>߳goK0gCO4{nu ɯJTg~/rGs~jQ9_ Mrq9Fyzh@{XA#w/"Ix9[З3ƾcs1ygkE[yI7!ÄR1O_9z1 #[ O,\OtwzQG=Oy}sГWdߊ0H̽ O{=Qd_G7Y+7_Oހ#pyi|OOG~>E'2$9 K]1_W~.siGpC)}k/~#C@:|Eyj,k ssqz8O߸quݪ\|0:ϽlF`VS>>ݘ3Kю $zj=o룻di'ƽ̽LLky <937uϢ<%Gerw9_=e928rSFq'9gA  oy9}/O yKKV#}A{GA]Dӊo|>p |ܷƐ ߏ9|$z:+ rN'?JNw|؇4Oթ 'b/FG ~y^\h=#>¥%<K|e7ҳ"B' m~_~n8ͫf^  2O<'"7 ?kVޝM9cY߰kc~f{9V/݀;A I'\r#l;aVQ\Ÿinx}3D)W9:rGȭ=H׭{1w718 Cg#|=X_98[opH' 3caȇ%̸K 9tN9Eu)K^ihSNҸWN\|{ ?1%78Fu~(ѯ1ށlyK~~}M&f~<[?L5|V{ʱgFs C9񽡷KolcܼG W[aw'EGcEb?AKwSYX>Oƭ;xrg3kJጕghдO?AlLC / j^t69=$o}c>Wes_uYGS7<|ه3T?m{79y@V|\<(rފW(]$}c隢>Pry._KP` YkEzo|$zy{k?/vא Ϟ2 S\d© OAo^[]R}rO_;"2G\}/}ّcF'R>g>{  %y<-FzO>sk<%#}{Vn[Q>C;xٞe]"19%/yBCϗ:W{yM/d|{.rȓN}y>7L9~VOi\gw7jQ8\G_sI?0y|պ\ Ia~tI\:'8!0;[ه a^'.z4/)tC'FO~3 o#} |MwdģΓO]hweҽ~Μ_gw9ؼ :fI0p(xc:jϙWk| Ow.0quOi';tw=~pAz+?ze ^Ys*5Xghy7у78g^\~AG٧,o*zg4~8%zI迪ϙн}vfc޼21|sPU=Gs:%ϑAy1u_Dt4>t>SwE:k=lLo<~fxN=яM?ppF /#lػa+בfcѿL::Ao! 4y"/w}~^};H3ߡ&|:Sƥ_+pv9љ_<}g׮,؄x;Wt;X}"~~9gtFy׼xy^>c^qZ<'s~2WCyoy^'O}tw_"ڼ|_-$ sYٖf=A:sj9W{[ӾByt<;}O~{VeËW^?>kC7߳|V^S~sTj}? |rnjٯB?#(bD/"R= p.eMxPyO|KULϐOퟻ2ޣ{Op)r¼ZcEBb0?y|;OPowcYrA <?'\Por=;߀>{r$˫(>s]\D2='/ѧO s-셝G}F'otƋ=}ۍ܁9 ?j=`] ) W#u,=>};G \,r?)_t/NF/~NperɿaS :z;whgہxEMN@g}G&>~p G ?هxV9ܗĵ+wk1o uѓC7x>Lպٻ9,68/-toJA[2xu_.~x3G> y%w5?>< }# sإy$?כi@ĝRifs\[(Ǚ[twS/ s@o C=WHy: ѣ⿏`PگO>F>u,.^<[ozޞhnw_4ͳw~8;z=7W } Yԧ׽Sz*A@W:_JU* 8J3s'|?=yGq3s9$=cr#zXt Xؚz'44CLys{zF'k[_hSS9">c|@=GO|=݋?tvk)W 38|Ok999Gj=s~} q$AW)| ' ~0NIk}\_Gf ZYo {Py1W䥑+W:SVc {>|\yYK~,n x_kppV/I+53灎=.=0gzG/?#3,:sʇy#NJ?Vcu#G~nΡ>nA΄OE |u}3/{< {<+YYY;ͬ_%7wQ{9@Uw7W]77J1ylW{Jx=Oc o߲51WVPyc~ΐ=9Hg[GOQo=/u_}7I=np<%?$ 'tqߩs>E}>8:找_ɏ唣֞J}:{ my=O͗b\"u(+wwv?sm<鵨̰`׫Ljgz! ZG0?M`{:/c =5c{/š)!%Z ~XzxiNz ϳt/&uȣg"g>R@E7[j4Gfko.\hU|N䂢hvyx/9y)ɯ>ߟnާ?< s=[ތ'W^G>P=kxE.|$|3_i] -9<:^ڇMJZ5Eʩ"}`ʛ7P}پrN aw1cw]'ᇑ?^9mCj+rZBu/ʃl~9/]yѫ_ϫ 䁣pί[9W934nyr'Zys8g>_wIm<[r/~io觵/ofi@o@y9sik{}?~TwrSZ"7Gmk8}N¡:h>׉ ң?`$s!/;>ԞXێ"\x:O/g~&щGYM8mkߦΤJ~d彼WZ|#}J9y3`?)"] +)r8$ c*(k1VgD@þJ~><ȥ.鼒|oy'} ܗe+N3&8yUWaZ$ws.נ'C?y.Qu^Ak=Ga9Əy_x~ǿ.}{)7sy>Kч1x|B>]Insvc%Awo|5s:S>tr9O s@|FoK''ϖQᔔ[oGLG1c\`-BsrJW:xT~q»C/[/؞W}]+Db= ~ÜWRSu+ٗ7D%O(}7𢇾~}m_;[Ƶ9{+ǚ\+uOfQ_"*Ρց{cjOqgC÷{4sFL}_At"?HDR6Ss;zrl]|ݺsw`^[=΁}B(cBl4!@ǹXz+ŗgwZ?;D'LN!(+ a&Mу?~*t_L!}~/Po &`BI&zCpl_%leJ9>^"(~"wyJS_;#gRn'1gT8T,%m12ǥ4wU6pc^[x)5zLgɍ g>w gj>f6o@O >oG4>H:**?~zt/ `C_[Z>|cE/'c5WRXA}mÏ?YtGB/\=VM%T[r˗ ˟Vp$R>U{o?_׼s~:r<\;K~9K <6yY?t#}?=!njNΗvzwtj6g5f7f<|< ?y Y'Wpvmm7:CETwML\|r=:iY%r5 Oxj8u=)ϻO$t8/ ] ]5m x=dp^=} [[¼[O5|7zk>#cf#Ky[Kw˾J_# WSHO:ti7Ͼ>>EڗO?XOb~:p l_X.k=AMuL^)wS}GwIg+.짹| Q?xS7J Lݬ]Ty^aۦ%z'>*g߇tїc0?@\6y}I>hAṠ皏<:q8 z>lr\#w<.}I'oӹ~мs~ᒣa%ȇFI^sc>%'ɛ@zs̷U{o"w?m{/6is|vY~@|ψ\UԻ ˜cWwrzl~С{[Ͽz^ć7^So]uwJ7Ӏg|/ K\!ٖS^rz7 M珰O!{/z\#rO@;Ir70NFw}WuES>wYP5i'>vr=_iA֜6_ <*NuΓϞ}|)L[{/x_lEϺqȉi]zN#ۺ F>u}nj_IN}. CzwuoWғf=D:OzJgWX>_[sUsO̅<1ujz]b.l\-{yqhb _g 9⵳IUb~V>y;wī'W?69.)<;pxOD5fDvmP8b>Et:;t-\6Y>G^Jh7v^s(p:9=n<7A$نW=7\\Bs4ۍn4<ߢTKu{zsRxq{E>"8<6ok.~xW>={>-zqWO?yw^<~|EsÐs=5 O,(]>sbqY/sOH/Gֺ7b9 ˈ'AWDO-ڕ5'||'PO)zvJvI1q󝯷Wφ}.9|E9ɺ{^?Ϳ_ZM: dž|^Y||rre|V龋;c>R?98ŷXX9'L/_1¯>V%_sp|VQ~W$__v:V~—g+JC8|Qw;.-8z%k֯gu4sOEys199eg7 cL=%M-Rҙq^qGaO bE)CsecVc!fuաk}G˹Od Ϙob~Lq BW6mp.|]V_B|(GO_\163gdz%;yAO9xo_W~k?y#:g/ _Yu{Άb f^򭢧b~/ފl=t|~G/l/k/iE'9N.|tqO|zY=U> }IsFqk+L| ?9?+;叀bg0<+HܢK| N4|~;tj(%raHŎ^47= Gr;7 ~\;X/u{-—gͺ?Oމ,Eo+[7w{'ӟ~x!|"3Cݮpip^ ?W^N={Rw <{Go>ڣF.vީwrDnOWО|}fnt[ѭ2Ԏ~GП9 ^?F4pw!/5[P>ѿ>K~ޮGںW4ΐO>{\8;}ܟg]Up:7|ݡv>dA$ו<;|4; B?žMo2=LErAoAD9ꕚCJRu~WG%G~ߟƔA~U8S" @liZ]s/8@օVGo%}8x6 K}7ȗv~WmWr#';QUG C^~!ѯ [*?r}{ {@N><yh5'=4rY៌4ѓ^x|Yiy3yL 91suKyrh{~5|~qxp$ݭ8lrQ1],[GվVERՂo鸯{|?XknO8ή{z;"}r=&ս_suxj56n_ȼ-9N̙BMc5G=% ~%L>;|ACh;Op{K53po"n_m‹W2<ޛ|cwG'F}@NQy@KO.XG ??\s=&:.U]Q:||'"_$\yÚwq <-{%~ƙf߽' Wsb/?g}ç{ăf d^z4u{*~I7n ޚvw-#)#:Ͻy>rc.|o{- |z)qo+BO\=>|E,<*ĿO<)n1|<sYLzSWma ߇}@'$rRzɏ'Үjw ̿jcޱ9y;x?5䦡덼S;|(+P8z-L} k/%t;~=|"׾YJ ~E;f[M^Quo{:|q̷7|VmNM{ 1P+硼?O{%@ʏxչ{i_>/v|[9{#xA("Os23yM֘[}5㼏;~zjso>V+SI kg{n9m{kxѷї<ԝVy$D{nAr T,zo#Wd; ޛvx$tXn gCBs.u˸Gg.'ȡޟN|ON>yVS˿.5 s+o YQ9^dm܇K?}_eS ?2M>W硾wwܢŁ}7Vo(*Մ{r֮TP򨊏 7oB9ӧXC>7|C'O<\m@L1w·UswܾWbdhԅtӇ-le~ p~Q—#?~ٵzK1r8|kD9~5>;ޛSy5|x kI]F/"2xȧq.x/N体GDx㶲^`᷅EutŞx܁3W?m" 5N"?wFkfsv'S)xS>Oz·{ ;!W?2 ~tGg=YB8K$PKz"EG]r׼{Dzs.~=s#9a/V~? ߩ_ӄ'FKBه.M#/m_\zS1/Bϋ.SW:OW{h^{ȗ G!9phvU"|{u3L|=Z\CWpzwG"}osom?saok?^0Oޕ} <|ysۓ=f徘 ]i'9_| قϱsT]r~# /[}o,BzՉr kolg%|=|uQq\I lܻpέ;~>3|s_}meBgIP}&gxAysrΏs{_glgNk|i: D@o=yN=2};7ʟ~i.>#+%1򇝧yA"x}uz/-d%})L?ШAgwg-+{&o2y\ 6s~= z1>s}EЩõoo܉_:f7Gԝ짘Os^o|t>Лs5|1.'ꋄ_;[H䶒?Ὓߛ~~\2ae_E[Q =+F?* s?.ij~\|c(~ zS6Uy×d7\1{O^Ç ^TycR%0KRŵ}ogc"^rYF <6x_WQL딯 |QK:7q{,,·ϣ|xIky/˄>nx~FN?D'Ml1\Z/c%O޾ttwy3u^? uL>^~f*7grNBiߔxΛ3ғ6@k=[G]}a!N9/K(CWzwDWn^q~ |헔K^<s.98C6 ̿ /Gq9tե53ǴN}l ==dz# ]QtQgk=Bx/O;~.5s|>WOKc}Abʗx2?^ՙAI}~tG!"yC#W&2҃PH|rg3oys'3f9zDЁE[\{D{L>g (ln^e5GGA~}cེ/ɹ.<\9ryO<ky(|Q_GI>W#7p4Bƙ)W9jOoO&*tH? ~{COb]4~sMQf]q ߯?Htj;ϐUj;{?y\7\45Es/{$V^Xg|Vi:4ѽ \]G>[=p|o"st\<ق 6YżЭ19_ sf{sܽ=1З.!;sN ^_5<9?;$?sA&%??x~-kDqF|V4_ykh΂Wa.Ds @.)=8GgSy 9ȹ>Ζz,jsVr6ּX9!7uI#0{VyM9=mt3sϗ=cůF-93_YY[R^7{02qPʣl4t4:^Z;h#JK'9\coV9|l!~}״o{>I5}Oїp^EuQ4gT97' fϟ1/szEvaђξ߼_ t~/tV7EMm;5N*= zs>՜O>`[\ywd7||8^ =*JoJWY6a9o7$,j'Y.I_O֜o\˼-М;ߜ|`95}<&tO|K-[|Ȁ^4 ~IKu/{[#[2M_L~c)^cj˹¸= 1'Sb|Y{+zeNw_N">l{2 8}i1;ud7Wb~7WT)Q?Gc~y||KA?}or1 =OKНe%> 5Ra,zwBx7t|v~z 7o%]+E{>{5nz5yƝh}SG/7ɼGՋ?_miѹ ?<]S6j$/N%?k|g{k72ܝsLMm<\%zфh̘7K^=lJRM d~D>EUDUT՟Cwڃ/W[˾^?I3pW=I^-~ U'-<\sHrIW]"~'}+s$zq$ YQ=49O7r&}cŷ1eptt/*/]Fvrgk÷>/wڲ'/ëI]d}6{K׸s^mG;zo-^+|>.+d+?:܋kܭumޓrᴝSP̯~g pgf\%=M[ Ƿn<>jut>A~EϚ[nи?z ?%|W 7~@x㽝?R;Rs $sۤw)Op%7ݮ[r}'|?0r|7Ͻ}9|12}. 6.mzOgb889~}Qȣ^9tM;~~Fs;Cړ_(s䝓KO9t/W7ppS3gS㜫|)#3HNXjr7j |u>;} K9H @ ? w>9|VrG禥nZ?ZL,;Ҿ}1O: x^{=s`?=A+PR?xfY)?x} npxWn1> 0?? =KҍC{6=zݛ6 ß:ݘ,3(Wg3*><p™1ٯSGzjwh"=9 TGug|{B[` `}tYF>|2M''}1LјKu>A9ь|j̣x4|֙kt$|_"|5=Md-2q-ޛ⛢9ȈY\<-:tKAG 8GGWdޯp[3#LsZHΪc%Comoe[UmJToz4_׺DZ.˜JxSv RuV6;KrWqޒ]O?E^ֳ>8y19]ۙCɥm4Vܓ!2r%yNg䡷_LQX@*d9x`Mםԯ~/+tq|!xM{zz_σO(D|){o\pD qUfF{O轮(o9nc> _;KlWY6ԟ1sD>JH'|VrV־=793y6LNz)}#G ?[zGȷy~7Cm|uhݳik=ᣄ6\R>Ngs^\Ye=ť n $727R?G2\irrsttZ3<=з'_4{o]M'  υׄyb<EEth\Oܜ)7rt:?/>%!/ow,]6u>wɅ$s`w'7D.M>I_B_aOϦ} y'9գC'9ZP̻~Q{DFk1^S}<_6O i/F#\˧96CC>nm'[x?&}#ȯ\ǹS>g,{s;GD؛#1_7<&H7PI+)zsEtcdVr_C~^O.@Se _raӯJ#>灏>CwSDr^_}ynjǝ##> %p#q^{#{=Ʒunʩ܍ZG}hP"9r5V^Oe!<4g+fu8bQ ApAQ;6~T$z N]=V;}GefoJ Y˛KRk\V͜Y~E"GdY~Qp «GW&rGXBO;yPx:gFJ-ެ5bkڇǥs0|/s—=iKBw 'xNbNleFCW#5Y{?Yll>4W4v nmt`]5;q۝^T\}to]C|ӭ _}\`NCV?a?*z_[-9%pwϝo"+|"} >72~jy߮sClE“HZo3~|VكKߏʮݼz}Oהސσ=!l>vogE^U'Гg;|9ЧSejhv'f`Nmb$_9q{_)$~~x\rCϖ{w LJ@+WAMnpmxY(xҡegGPS> ɩ?ްJ/9 =uqK3~ttoo+z ~^<ú.G" _oH{zз9-|kŹ/Ź`9?V^ǡt^Խ}ў=X{ϣagOzo!z6/ kn._w|;%$/^ƽ9}P?MI'S^gMxlSվovQXr'~ ^QC+ szE.7O>'&],/!= ᯡWަY# .F/fUw|>SvDzǧN{C࿿fO`^;5=Qxz~Zͪ/π>d%)q g&%ɓv"|Tjm?2o?ܫFGL&Q;Gӂw^xW}coby^Ԟ̹#_`}R?7̟u Ň˹\<3yB~L/?-/m"f~ٳ^CZ=hu\'SG?3tȭϹzudMBG:e+Oo!Tn B O"oc}K,%̥snu7(6n<=>OS*GF_O||\}Xf?COyx0f7IKd!Goy9cGo.z:ONgGsvW87r^摚xN{b=TvF'O2$zc?fsBOɿG?],n_'>{C^ONqioh\=s $lxЧ~2zgQ3{LoS?B+-#MʲKt k^K#{/O:e {Gv>=zւ5s>6aG ڹFfɣ_󽵮rq0:9=C^XLy?yYEs|Uoo=\/z㩟|n!|D7ϟ{>J.U>ֹm']?z^O:q1܃|.Ћ` {#:*?H r;s^3睅_,V1g{DM$~=VR/Bǁ ܏codnF.S^E_v{r 7±gGOHzO3.8:23Zg19k⧉|Rb^<1Oa0w!Jo@|sWkmͬ/6|.Leҩ 4'Pu_~q΍+7Fz}`a>wcH?o>17&W >ḷYG-KxckZmw[ys޶_y繣g(A3&х/->9b>|Μu2O) @gZwsK)jvۛG}K"wpj|G^c^Vk*f+}V}xsأ0o3뷭+G93ca~e_?;uKGlsr'*9)}7Iágtxw< O\Чx٫> {Ycܫ MK=o^Q9"wֽͽʯaUm:*0 ܜ*GUCh aݝ:^*|#z8Ks\0]wsᖅ}҇~`EWWd|ydJOh3;I9*p׋zґڟ;e?geoBOlط(%tNDjt.=I~/(?m4W2_G :zW {_I<}s޲.>v&h\9 Ë|Z8ʻ~ϭů73C..Dmӭtg2pڑ <^uWyƳ?g)/>~IF?LֳCWW=yG;k8?<1u? /=| Fu=~{{ WćLOTgV늞b%`- 1x1?G7#y؏:9/E?UC|Kp|s2X!W%NO o=z 5t%ǔ{1 _Z]:\1829rx1KN{dxXw6Qۅ9^*ƞ'i_zC5Zj/ޠCuP8^Cg;=ƹBy[31Ŝ9'Χ]s| ' |Mw/l[;Ѕ.NFi/-b=gE[_ྫpoE~sJ>swrOe|?z_AQR@/loz#s߃ 9)LxBsL<0bEf7D.sѿVN^I򵙏"ozރE{XݷK:rwaߨ,UH`K*L*:壂"7(:w$7?HݕK=zG>_ܫiwqr63"%r9ݣ>ѸSFN|ot.D)Q'X?g|0s۵1ǣG ނ޼Ö}%`CuQt>wyGw%}"<syjn̕y/׼}ЛEeC)=ļ>NS s"zz"w!`πWc@NBj ȏ{E{ }e8t;'>^q|:17^BtO{d~it:f^=i4nB}}ygDnQ[ƞxָu$6}|6c4v{ ݨ՝+=[+ν > gOR{{?_(|lLNs__z'kr~ Cmr';+L/~CpMMF|zrHV.+"'=ϑdB&ѹC~ 9 k ay}КT9.N}.6A:_cӋ9zXN /Xz$roxOKzL|tǼo^rq񽡋o8Qa}w+T?ҽ_hץϷ>*t>7}Ӟx 8#/<9:PpOEry;># r(')#0Ǣ6W8Wu)##/Ӎ_Z|>:҃G90~mF1f%{[3ϻuG跓'\ekgA+炎e܁ꡌgKHRoQȍ.Ωύa>olH?s4{gߊ߄?#}.IOI^r?aCwEY =q3m%%| ?t{%:I򿲥#W'wz}GϜ=5yҳG߅N*z\OQO!}t^+ ]J 7yJz7+ѫ/_3:6$Grj7W7t}z/sT){>-kK\8mv!rK 3ψ{'JT ȳ魥>>^3N<Ʀ3~O\si_s =E!o>7z\ڧ&zqOzϡ? 3z=E/Cc꿶m[GRIE>&O컙W }Q+,,>s:JӞLH1NR.Dx'zoȣV^K xL|8pEʿ/M^ Vޛ֋ʩI}o^YZJ+|r)+xW}[ܖL 0EKga~ ܧTbd@ap7=C8_됫Ay_ c"'zMɋF̩'݋cl!ma?⼃3޽RK7GG {+ACWw~?\=zyes|d}EZשZs{7R;_orp!9g%/;}sNBc'=O~#t/7 FO@[ r꽆_Oݫn:V|υ'rq:F}|;˟R*/sO_+<."g}k|~|ܡrpSU?8<%.OʾG8@W>WbUhyH@ڿ}_,p1nqF DLwϣ|.ߐ?)⿉߉O3pY)N7z)̛}&rozEzqѷܡS_ܧ[VUNA,&}^9H5<_-IǺ}S)_U"7wt.4küغQyHKe7_n3|sŏ=փǞ/7_4@}])yݧ|$C$>zGv߿@z9yW*IϼI[c?i*?܎z%|[Hs6x@m=՚铍XYvȯǷWdOZK^˸ro ̣իp$~9T)&ɑ(sy*BP:CpKD7#׹Z]/ +sHgjS(EFO^"]}ϐϏip(-/_@37_oYg~:Wx޳Ժ;ŗB=Vsi>=[{OcE }1C|(rd]*ǜb2>)g1>wIZUSX>ދlF:O~ {j!Cx{oTqrEN姅O?usAb+r U1|>э+so# s O9%͍H']\O\E~#t_l|n '?zKC\\9÷>矣 Ok(skz_~y|2пk*8xaưH8ygZɁy.m?3~pq^Lh]SΉ~\^?o^5wyH>{~~`Ozsxɓ *5=*O*;W~9[˼o4s[GI?V=|:&k^17rb21b1Md{C@^oQi>dI9ߖ}Sˏw#Wȗ`Υ,;t~?zȟ%71Y.zsHC>f_WREZ鯈 ȁ+po2Wҗ~e<>ԛGI%<|p\nqd in$9_[^IudR^| >ٕѿJ:Cg|y>Q9$90޸Nxceߣ_}௜{ :_F $to7:uЗ3?/WE4=7}zfzG Bs"gurU[-|;CO9'r=_3ʑ>jӟލ^#3f/:3.pUQ5VNs/Z_潃C;xmO:أ̛WBT~3vKi97 tD7眹=fHg]}vtovR:8rRɁ&\}LZRq>F7l}{s7rV)эuS.-/OlxW%rKuD//:Nr.0;wܳ3TCy~w Yo}rJkƪ_s<7dT8&tMx`;k}_ ߈]g!<|$|)c.g`~~>v`ۼh##:0zb'7wz8E:Hx‰Ko)&9'oΕΖ vpNsuS_>X\"oyM/8~*@Ă;gF.{FU@쟜̇ xdgGto}prlH5r*9x޸ܸ; /\^sDyL'D?yK>Nr<)Dŭ^:z/"'GǦA{=ޔޑq_)Y1pC ퟤ< 7Iѿ^tŇ؜[wh㾼'Sg߃%o_~/ܞO4J)߾->.w߫z:J>|g?s_9 Eπ߱ȝ1o-'1:aFKB~{xwm/Re9K.v5}t~cSO8o ~Wr0K͘%JQokY.i߫b:J+&Wds17sM) .UoD3{$=8/K"zw+Ç8.x}7̾_=ƞ;p06fSHQ}॑~u!Ҵ'<\^}==scauߊMɏ _)?98y%Q/߁~Os:8ߵ~{=RNGyj<]&9/,@//{vc.R8>ry3Ǔ3~W{Q/.3zᣲ1eFWPgEԾyB̠|0|2a#wRW"=o~c z/N?s5ЯUro77wT:=> ~CO~!7[A9wd%$}(-ܽ?&Zϑ{ssi8:{oN9z/wFisΛ;r|G!g+ϣp'x\r E.=#:eS-*9=6wު81zȧg9ߘy s3=u}}=7u?-ޏLz“jG ZGϹρ!Aف_AGKcӓ_eq!'8ơ{Eȕ'MxvVV^K{I{g;_>s : Kdڇ;7$'pكy0_ޯk9n|G;W׾EtEgtܯCH YzU:_QV~SQk3yӣC7 qVwT5VrI+''UK:wlyIg1:ā{9߮qgľ)>#Spx76|_կ~O޺yg?&_-DwQ-<ޙ/oelB(o}+Ǖ3n ]=0i.Oc= ywDl˂'N.,f7Լ~~uou[[9A'.=|Qlj3X>Գ/ݹN:o ^=z?_e/ (.z0tN /;7VrOCɏ\odVֵ_2 K! .sqptZ+'E~?=}r}vtwȺ;:ǓK$bv8?‘_{LpZt3#'ǁg-tח_>z3kGtо]8?sZ*[ <縿6D{;>|5_p9+e32'mIݻ?;z졜}tE ֝/|)]o~p?py>>tN\s`Lr`mNR' ϫ5&Q=,Vyw䒰qU ݅W'3,@1|9?eEN|Yg/%tKmx#z|=9<>X_M( |̳oNO>xYr''YWtT6EoM# 6FvG񽅏{J͝Khy"W n⻹G[zx6HYdg:ƽ5}#\Q9kcSZW.ѕ6 Ό*F rv>JgC<^c5g'$dw)gsw么^5YN/6zh+S9ї7OS7i{SE?~>?^R};fo)"~W~|9{YG|~ߨ =/|+w tͽ}埠߇ E]:_gS叻w>ȑEmËu{&+9WKwokx:kd,me kOp"πȓ#|g"QdKKo^Y[??w+G {i<tJx8xa|P]գNY\H[X>? ټOs??wt6. ׭)LW?9opQ1V# GC^^ymϕԏq=ޮ i%o ~甼5܋/OI}ΛI vLYV?ŸbsV]#=9y)cȅsm>q1_s~+޳̣_z]S}, /G?Mz7>9+ꞥ~Hz4r^# CX95#=#oΥ?!Κ3 uٟ=/]s*~̝T> 7Gu_su1S<72k G<,f>w)w=|>rwepss? 4O_ackޏ~7O+7l4o^ "7aDyܡ>;GWrMB?o|;FoiBsw{S>>e*rNcN(ܡ\k?_çx~~rr}n{+6g\z%]bt)%L~/Vc( }?{zSӿN.k?/S!|}Zpur[y>~oF;>ft9EN,z6їV,6>=?3rӬcOF]t0[Nnpt2bljG /8Ǚof3l뿥{  3/B2SwG _xf7tŝ{<s>mB{ݖ؏D#9sAk<\66z536#{(`BrtN>N?|~Z#'x-dr/Ɂ9f pfߥ8ƅρǂ "§?|qo'Neַ=dzO]OZvoV+( ܹ3a0G_rYW^w?oYEOzg|y̶aO9Q[_ _cw?>Wp4Lws?D =[/ռ>o 8E_q~zGcxs\$Cܟj]G}\#)|EߚAc5 -iݹ{| O??r@;F>+¯dxȇ$hvIK+וּu9x'wbdE<' 1uw CK7y7=C7'OoʹN|VzGU?=+ɷ~~?| p5җ~%SSpl= Ə2}דA*E~>t pF?.\^,_?9DsI7^1"ǣwMuO_PP{o }*ׅT= 4_xx|Ri:tw1'E4kx@~µGQs>+o$/G g7cI 綾\bE_EzSk̷ \zqN!>q_{1~;t_;HsD==:Ǧ?>M#2o37'׽E7 dO-ٻ +II+}&O{d *87b^|>w/CBV.O8Szo+r =:EWk/} { rN+y8'§Du=ț/<2s߯{s9}"z@yoP-ŏo<8tёww󘿾M>?:O=bgC7?ԿHns"Ǽ}p pO8̧q{~eBg<i<폝դw/=NCgjp4u=ѿ~@:' K'TfeG6o/^:z9g㟷/QO?7wszJsgFPwy!}??ܠO_>QtQ |9kOnƺ Љ.mϼT?^d›wݸl9u_7I-!}QqA֧%^v9eyZە8$1s#,:ˤ?+;98y}z{׹/*rע~X-.p 7}UOzyŕ4F/G{ʫHoS9_Cxx^|F?軣笨}x1*FT>S}EWK̯?.`܆/xcە/GDo~cK9gV\J%=/{.I'ONNmoO:>zxiGkМĹ[R ta`Υ$9ӣ|gg:IoGLwAw' "U g_Kmd?sr@{У\DK٦3g$a3ɥ"W|˨O_Ѓ|ij~=0g5z޸_%wF/G#opt++gtOї >{ {Sq_w3/BH>}}qgw7GBh6vm_P4O{>]]{o~#"< 7Vڳ:k0y]|͝7F?ϗ?P_G&3yd '9;rF9BCutBB> :J:dr;Cn[4Yл7~W2~̓%ÄjK1?4ӹ1crp_Ov_Y^ =Gz8ow{a=g~uϹ1FڽS|_upȁgNFZĺ\>*e.EN<$+;ѧ霉?[Fj+ׇ|Z~t#P#_ߧoD7s{XL< L|!B=>s.IxIy3kFxL"o^~_|𘭫?s~! gסk7a[Oc 8]ƭӃ^=˞?O5^N^sN|4x~/Gy qvÏ,>CO.<`xߏEx|:2g9dC3^\LigaHz9Q/l~=)??p' vF+#wS^ӽDNy'޷bٷ./^E~,[9w߄gK9N%}p[!w}^䧑Ko,sVV_Bӻo%5y7V^]W~}+ϡy*?IGy Gy97:L>|ŐV7NG\iTc;usIz휥V엒^6u \~U1(^ܣY|w pm%-==跑^U`{֢_^YlV}#wov}O{/gM<[ { <$;ۣ}$N%G}Unnhn/rGGwmn;[G/t3n:ݎ|`"7wRtemظnqݮCW{ݮfݿ -vCЭ|G˗[w~ ލhy%~-܆ .w7O޷D}GzzR[>`|Z>b/DӶg+Cmz'+8[^m䃎Ymḇ[Y}yX+gF+RwS18|mpƖ1z>~,ڭy2/rS_Ҥ뷴nm^k^=kY&D՛oioND@NyJ"Cn煖4TmmWv8/*Wkޜӎxhw]KyiS>T=ێny| OoI\l <&9smiP?v24xY "uk[~V⮯ҔC[y޿l6 mo=xB t#nG!@h-N \f/NyPwE[+/{-oiiU?t|ֶ=I#W mK?6-u's-ή}}/R_2v>q{mhnɧ:C_m\OZGϷuGoQ~h>}mDu@ܯ"zm2K?LC3^IKďE+q%P7ܫ/3AE{V=EkO~rMMԗ>q^.{O~5I_^z\yę6yJbOt&_!oiۏ8=ۼRw$ٰYi-:HWBէTwLV| TG|遷7s?wŸ×u ~tw/jkSˁ/jCkvb-{iT~srnJ=pf4^8aniO+Mw>3q!#3dآSgr-k.ny^St m3n/rٯ|KJ!^9?fڶwf|箉4rq] >ݶ@n7xDNc:ulێ jwZyRwI}["|}ZN';tw郟nmfsVP98sJ[^{+jh?W}FQ9g¾'QxHZGi*C< ^V%۸m x 9q9tfQ+]M <^o˄'#nɉ[=u9o|UOi3ɘoXc34#擐3oڃ^Oq[D ѯ;ok29,mЊvNOi \g<&|+"]n1ζ.q!m]`B-;q]zX=+ҟ}};t-_у,0wKm8~KUjs-sMm@wpw[]As[Kͼ+>Ҷn%|D?=;M8:rW' :eVD.mgC>RQwB~-_zeOϕL޻;'.|Cq;@ƧfFjvWgNت{ [ϼ#Έbڵ-}O8z|GݶϺ<su9p4xp vm3xR/69t;/I>4O>P=E͋끪r_;2z(sQhn&xSSOm_>j|| 1>4r'~sN3[1*;O\@iVeumWW:ip[֔+^`6znr ߿5?/J_z=sK[ILKzd"|Ş]$.m_aQ&y){2k:=)hj̛kM{|~3: =>tʅ0#~fvX̣Szڹ=Crˑߴ3?W'ζ鈟8 z9(6=<G|u^{R+W<4Ye#+󘠗yR/m}_2%B]Ѯno-أ+Cw=̍$Wak1_|<*U>of[z֏蝑јwxmcTOPsrCWD^W>z+]A]3E1ʳOV'^!@CܞgtE}N:ՓoT<ր{xmNO DE|rԧ¯9ҪO'#n&?%b94yQN\ 7+k)Ɵb}m3уV}m[? <3^ii/.vhց^31=~Cz7?@C[in ,:=`.4q]]Femؤk/Q@⎪5v#GZ~m_u~:D^7zwS?hoaKzhD|4hW'n0}2~"x|hQY|@pM=:? _ivˬ Z**jyd#ؗZxawNs<=;*ܕS|g7t.yȕ}_/cmۺ=m^?폞W~yjJ;>f}-ͱM"q-僺~\u/jGtk Hv}4낄Vmy?]yQc|vzHY^ޑ|PуoĿT `ɡ#]omS=A+"W=/0$.Ÿ ̶ջY^w1/q6/pԖ}2/@>ض |Gדg "~m^ '^x 5e|±P|'[ɼݐsB~/*4J8Rw?#vJy_B+ KbE=hgEW]?Q< '8'D!P"/f},Uhc PIG\/5KaBWsZBO"??ҢzyBGb}Ͼc9nۗ#On)E@.CFg?#yS ~盹ĪZ7꿂:[ F*`A_vI-q7| j=Ly9Ry>3Q>89| 3(# /bʡD4-E>%:/(ϸx O[-CyACQ3_q'="㑒7z|ӹǶĸ\g;u E<ItN:Kla>ŧ%*z6]r=)./B 7mӸ҇n| ::wd\-I%g>]O˹T3>ࣷ+owڝ=i0?00߃Wk}߯Co–jːrp4k:]ua'oQ8Zұ @K?C~J~#…v zLO?#7ٶ-`Wc ruǜG$<؎+"VZ8ˈ {q]bcտr*zX#m+m,Mrчڶuw_bgz-;~[GujbMhOzﮫCf AAzJuzCq=mWa_N0~GhYd5hWr^%+-vn _ms$wWB>9#߆憾/q_6=>8dX3 .l{7qjhWqЬϩc}?/? #q/9p^;w-`3iQw<|%OM<^ÔOg|/f\7vޮ@iy ȿp'EV(r=qs#}SpZ `}Q/KZ|SnGcү)Mo>}I˿s?éZIki"|/oyu:=xhBr䬓f}6ѯNDOG>c}iek qOx~Ѯ_~ooH}\GkOi WZ:(YE/6UyOC(_ _dXOr@{P>R(hyp[Kp{ؽ^d_ "&s7CʱBY\qaP:zK1=GioTޛwAW7V mнy@,+G9|;m۳v1?C?? <ﮈL<椕?U+-]2.RK;xM[zO{Fo5':Y>yЪ>d_f\4rsg䕂xrhsW!o}?oou ^wMoj/ʱKTz59G~;IB~Z[rv^|{herQ\m)~!G| w>:c\̛$/d/yabU< N+mJ7k:tUpۦ!Y(%I})k9ġn37(ߋsXOzk'Y57'ڔVWd?yӮz z*g]{y@@g8yq'وM@or"vz)CG\ffnu7/GyǼq1.u@~< ;9yЬ#|_)꺌W+c= ymwxwm}vF? =7û~V><c߰\W%|} W:zM0"Ǯ*'d (zFץ:ǿ|/;[ saF{8ϖsC.NЌWLy7_O׻&bE䔃?;ٕşWcVO^᳞+uMn9?kvj [چ(ryn0:ŔS^΋|wO9 Gyzr;\ggztw9Mq>;?sg"?gwf~t}B~J+s؇u7z7T>zyK#:ӣ>g=8UO vP:ļ~b1|:A?᳿| |Q^<@Fz)9OZiWS->\ 6\pyaȾ3G'͹Ms^iYO<޹(N/#MK|(ߒ.=udI#\Cb]R?cGN9hWL,| cZxK8t|LTOxV{z  x}I>-s1I{ʹno߬9yB'g]W%!G5૞5*yG%UϕS>b֟LV+s߾\z/u}tCOcW~,4~w%WW%=u# |r_= {}Sx|#o~~Ows%q׻D>Z|g_(|_<߀U?%{}z;n3=h<à)G;E|s1/s`F>߄vz>ym' qhEqVRzWd=Hk>Zٯ Z{RoP.4;=%tKK|tbO"D;M.|pXrQUs#L!3Jp[ cGor3m;mw_ׅ9qQE+\GO^\@\HAA~W)r<?ss zY/x{;90cg F}huwyνM!v סۓ pns Fy&~>߹򛓿CzrIC>}{x"\m(/~SzKW=tx44g_Qⱹ/'i.~P)~rΡs!|*EARnsz϶n:i|8g╱ϳCʕFq5P/vzmz#D|>h) )A䲈KwtoӪ?~| 6)?ˉ^7ןLs=r%9(xzkМ߼gw^F9ͼ7wz9Y;?ɨM}ZxLɃR"t?vļ!>Jȇ"z[벡sMSo>ʼ\ghukmҗQ'rh|.q{Asˡ<ʝy.^;69Ƀf%vkʝ>rOvHr䔇9ց8Xt)/yFۇHg O8l;h|]wsUO>C|ñX|7ն1Rbw /ѹ"uKT~Mq("_c< Z WhţdǗ=-"ZHZɕ8ceV~eׇ&nտ|ɠS?OP rG;}}'0c_0EhrgJ)6WߑSd:;5$7ǩ ={1ğ6*w齇c(r7+r<~s nByX7gAl ; NCN"G^*r-yyNК;E8K>+H3%? =䪯ߖȵڃg}Jq7+3A+" ')Nio.ʡw*=?N:3ɷGF_3?!w5~fby_y`KK~_M+>S>8/4GЃ>鉵slG竉b>PߎK̻p5xph8<{̽F"zmgvkaǯE>.tO.,o~}cgލc yz;zZ^C^, OLmy>Q~935.;"bq=轓+^9>yB?)|8?uXW|vE{B*N? ȉNܾg&S8ɍ'63\G`B^s?64H|쟓Gy̗f|}kW=w^lS=tR/1#>4H=}z\}-\so3B;Td<Ǯ`Wϟ}O6~owa!p8Du_w;[s[\i̶֩ϖDc?O ڋI-O进U~Vf&@'FH>@ݯ1CsODnu;U|vI}1ʁӭzMެGsS.9ƍL6Wo3U';ZNB˰ %$v!OT9U!>qgFU?:~%*QDZV#n^pk~Z;d=9 eH/1\Ut]9..x=?u".}/gRhڱ :D}ya_e)Ͼ^DXk)_w}jdיvݺpc3H9hn@'wk1N@}Km3r;;7TCq~(yI/E9^g!#WT}oinQhהc=_S?l懺G |缴[sOuL<}6aIoufȡϏ}|XyGWry|S*m2uӱNdyN'˘/=\s#ё7@&jO?pI@ \޾6qZ;ĺhSΕ^ V{gGbm-u944EN Qoy m[X~Nie>k3+Z>YJ'rT"N8V.ܿMܭc'O~ľyC/\o;~To(z\W_J+(^ ?˓i?'9)ɫ`Z_*W$\ 29>q_Ф9|C_ɏ@ 7q 4z_W?5qm2jO9+Oo3>N"חAuއb8v!xu;/=>yNE%u|[*d7Ofs޸7-!"~ Ξ݉#]9ֿÇsGέ11vmʳٕO}wYz8_-ox@ȗ';? d{_dbg|CWn%D'uE$~ |}…X?\wzK&+rr_wm7ux1Z__ޓ"sP>4rhC~q .)O:[C^v؛CK\}d' |E[z wzh>K{|@yuy;Wؗk:C+wDF}u|z۳/9Ǹ4r ⑘ߩ@[sszȕVOs*;9Oy[6\p R\?уz/7cѿ;ms9~$uB H>y4B3NOyK_m͝wE@#9?`Wħm^|ݝD\$>IvNyIδe:?Dy!Ҿ6=n&A|-؋Wx>l}ِ_gȡg nS<-9tg{/2_$u]=\zq4zwH'XorF@H|Xt0zy@RN}Q8`vRu?g8ŭ{넜sIscݓ_ܝUa&+9d^}T^#ިbO۪?Ǻs#"WZ(_'ԫu珅< d}wF>F(̏}PG~>|ֱW=T>%-q~"_NOΣ׾}#Wڲg$3\A;B/g[#ϻ$4x}jٍ>;pˣVD!ao5.m-Op4uz6|X7;ۦ#~&C>)n_8G_r?EC: =FMD_fOX?Wd ]s<$S}IrC2٦^+IocL%&@O6XD_QO;~~zaȷ mu`w_PZ>z;/y7GQ7s4$ֱCzUK&auG9Zd]<OȇEξ,?fjj;O։~81 |B{mޏ^WX skWUu)Z##\0#z~j{uBWǽ_ W=wOs~ZfqL MgsK[5?Li{}ǂN{~@CkV}իUޟG_z~>׎vs`OFWz={tz~qBnT>Ñ*5Ԯ=AUUU~VJ꙾?77p3t];ޛַp㌳s|UT;McA+uGz_P}7N~Ak\4%k?jwKtv9UfhAO8J+{VUv~'w_u:}9Tف#;^E7 cW˽g>]rp流UqCupQ|(t3ȍU?럇Ӯ}ܵjܯS;˵Wg ծ\y$굾Gr=A7?[WO۩WkCUvH5VH\{?8oלz7]eq\~wj4c~wqG\ew]i+?AXP7oǍ}οtjv~oUC =6HA ߵʿO*ϵO}Yu>~wg۠sSV~seiW==Vq^ΞqC=g'8=g:NwdJSz?/NK53u\}Ư Ϫq5ΪZ_F;wG]~W\^U|5^nt->}g_\\,u@:.W`h9>486U6znqzc/E덶{W* ߭?k56辫#Aڏ;]j}pq*Jk815{븨ϡx*~Rxg'W^**6.Ԏ jrvXzڏOz_ z澋\r{q~>F[gK5n~5+;Wڡkz{NGtiׯy.gv0]<{ڏ:{*NWu8a,wr?U+{ZUy}ocѫ-7VNeWz?]A}k4};U[{R^R7s;ڍscA?UNC1Qy.숡z|7hّwtC׍;:;}Rq\\c#xPU;c;{s7Xε~[UMw~]]Q#5~}=2|gVhgB)gqҍ{Wq͍sEwtg]CY\3qw.9]<ʍ}PkU;lڵסAw}ߪ'W{M5>xHh/TWUk,]|Q^sv))~.^q݇4USj'~P /-}'Ѝξ_h=p7q]_NsoPQ:{cҍc+zb*ྻ?8}귾NqKއWZGRŁ?0ϧ{qX"wpK'W\<Խױ89wU~}<|=z_4}P팱8AeoV?885UணUOkgǹp&8Pٵ#KV=.mtvPǽ_W_\\@[͢?~:<#$8A}^7/X[.]}Mur~?]S:=z0z},~VqO]?]mjW=k'U<տ=Tk$^{,Z\?㾯sL^c>_uՎwrGgWNzsƆvэoΎ/jv\ȝZ\Sg{~ΏK99wj7j{r=]&rnzc zu\why z꙾qЮjh~~>pqBkzn$_wνg׎=-]W_U|8?ɵ7ᾏ\\KޗT)n\M^?<-zUxYst;BہWSF*>+K{9L\k N=n6{M"wqʏvg>>q_*pō'&Ϫׯs\mz..ןUӝ}ZCyTvCyv{e/V~\}o}R.s\q8*~?Eύ.r~zp{n}OΞqH[k諽6'\^F_^ܸ1X]WƂn~'U|\z]Vzo(#hn拇?W?yίnw=zn}?VvvڏUq}.;.xd5SŕP١l7 ?\;WzBwvT_ܸ}}z~o$_m]\ontGX<|鰪ߊU۪<xO8;=c=7]ٓ=,7nW ]<ڍAgs*ǽ_ lwd`,beg)Vq CP:Wo\7ڟj9h7]3nwq3}>gVq*_ V~`UU~2g~OBGv{Fod=Uŵ/?zou㸋 W{珻ϥ~ܗCjQ_{}\?Wk~\zOCۧϮ>Gr?Uٍ?= +SgWDHe^ߍc)S;.Yq./W cAXʹs~\;wqtvwvhgR]U̵gϵ+g"UKeWrgqk34^ƕ꾜32~뗪vc5%zG*j'_:{jgڟ<Wq^*~PU\B_.Eko]WP_ÍS0Ծpq*NQō7VtYMcόw?Msoyv[OzcoD^(M3pN=qNnz㖷-9{z[n=SEmy<#iןSNϋmDŽo;팠7O9Ը۷v9Mgvݲ{ߩozoSRgy7gO~KO#;O#;O?yRw$|G)w$zG'=.uGw$rGI_ɗ椗Bp-[u77-)gן~6}-t9GGally/data/nasa.rda0000644000176200001440000111576413663637143014007 0ustar liggesusers m]߅v̌fhwszzzf{z35/ '"0 DAIIYdPPH@!$D ( (r % FI{^߮u{=Ҫ}^^{g׳=}׿n_k~~_o՝?~ow_ޮ oY oY,,,,| !!!!!!!- 1!!!!!!!- )!!!!!!!- ^BBBBBBB[~(!!!!!!!- ?IHHHHHHHxoNHHHHHHHxEBBBBBBB[~KBBBBBBB[>ߚ%$$$$$$$eOHHHHHHHx&$$$$$$$e/HHHHHHHHx‡޲޲𑄄,޲c oY ޲ oY޲p𖅏&$$$$$$$ec oYxBBBBBBB[>O&$$$$$$$eS oY,|:!!!!!!!- ?$$$$$$$$e޲ل,tBBBBBBB[~&!!!!!!!- ?𖅫,|.!!!!!!!- oY|BBBBBBB[/&$$$$$$$eK oYrBBBBBBB[𖅯&$$$$$$$ek oY,|=!!!!!!!- ?ߞo$$$$$$$$eag oYx oYfBBBBBBB[~!!!!!!!!- o%$$$$$$$e oYW_8'?=qO~BOID]NH;JY̐!'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'ğO?'S拟]c?ל-^}O*__?77O?鿾-[>_{sw~૷?{?_?lS?3- >g_w/S;׾G_9[߂?o˿GD9 'y?'D9O<~4t?oo~|{77}s߼W /?7T:Vn+gOw`0 `0 ! `0 `0?o`0 `0 dgw `0 `0|> `0 `0w`0 `0 o0'`0 `0 \`0 `0 O`0 `0 o0~`0 `0 `_`0 `0 M0 `0 ` ?`0 `0 o0]f `0 `0|v`0 `0 7g `0 `0|7`0 `0 7j `0 `0|O݇`0 `0 O`0 `0 \>`0 `0 o0~g`0 `0 7n`0 `0 o0z `0 `0|?`0 `0 o0_`0 `0 `oS`0 `0 7O`0 `0 o0OC0 `0 ` `0 `0 `>`0 `0 x`0 `0 o.˿n`0 `0 o0~_`0 `0 ``0 `0 o0. `0 `0_`0 `0 7 `0 `0|o=`0 `0 7& `0 `0?w`0 `0 o0S! `0 `0`0 `0 o0_~z `0 `0|?8`0 `0 \ƿr `0 `0|/7`0 `0 7?`0 `0 ``0 `0 o0> `0 `0_`0 `0 wC0 `0 ` c`0 `0 w `0 `0|n`0 `0 o0. `0 `0}0 `0 ` ? `0 `0 _ `0 `0 C0 `0 ` /o`0 `0 o0~`0 `0 o0& `0 `0v`0 `0 7! `0 `0`0 `0 `> `0 `0?`0 `0 7r `0 `0|O~c `0 `0|`0 `0 o/`0 `0 o,v?kv?_7şs%+?GHu7s?7Ïv=wwV|y-=~+u9_kh6 a,_; Wa ]$=ϝ篮.)/o_-[7x2/}:/,/_/x+~wKܼG sŏ_{^"i[Տz^·!{K}C ~繀ԫw罺o[Bg PH8 /ns\Qߘ ?ZÒ'ϋ(?}J'^j_*tG8#?/t +S_>,BrV<KugSoNz[▝>xGiTv}7#W\x?(g_[xhWėzzWh\gŗ7 7K?HT&{|BV;|ƻ;n?t>/Z!ѵپ*%v}#STW._X^7;w뽃= = ƺ)?~G1H>ٞ'?l)|HtY^~Wc|. w>GNEĻӾXW?V)[ODž~]siҍu?zno~E^9%+]Py'OGu\|W# m?Bg?qW&]q܈WOyx{϶w}O8b[K_~/WUѯJWk] ݧS_4>粲mX?R.w6qEtD=dǎ:pzn{k}sRqGދ}^Ԩ-q[ny|,tca/P?i7'5m}ZY*+=mo+KkɰhMuP}> xb]N>yz8J_e=i]g]xw:\?NsSG}?ySHyW}&ў/_ g&;:!YQjBr'~!uy/u=Y!qYo25Mh&=묓\RZt@nW}?N'8}Xǧ^]Kyu^Z9| t7g'7_߱#wqzYwڳDo+?Bgϣ^H?mno`{zQVm_S=~V|m;]@h=D [ov6Ӷ 7u =<|9 qy{/U|ѯ)H?zi|:/={fY{DH'|tyu 3?3m[!::SH{sI.t~w~4>}|Jי [=wW?M~/te5V,,|Xq}?oujB\@Ƿ_hxv~ϭYwsFW\>og+6w 6ǬsŸ*,O~{sn_L>W];GE|yw^._<7sIoiN]O%?< z޴Nu zкox}5OtDd]zM}&;,g`;{~>h2`g֑*zȖC:Osvv~X5?K׬}OqcWP<6w+ԾˍouW$x+N|?iK/}WmNLvøʱ'y ρJG?=!׭L[^ǷpZuO>oZIί~Nt|C"ͺyum/h;4'gYhe W%baYW:^yvDGu:Dϫ/*ݤ9 ͒u~|+>z|Dx^8ٟ!ksyM؝ ES [ݒ/CG{c/O"~/9w3YyNyRtA؟tz~>պ׫_<"Z lS^k:Y/Ozڧsn8~+p~twkX1CY?Y7ѠGwy#O ,aԛMzΤn.S~~Su5߼)^pM_5=NTyW{<ֿ/sR{\!j~NnS6KJks[3bO/[Ne[+]/`yީm?unrlq5 9yu74+ϝbyt2;ָ8Jw:an/5~9mta\;vg=~L=. X~(R슯8<Oz~B\uޕnGq]v}qrExx^O|g k.P){>O_ ujji^u3:} yWC]hK5?soZ\&%O<60w~'{zֽvR^znG/|x6>ո,C<*C~=c~>^zQu[kkWk^/Vq*sa^[Oܷ=[6%|6x/d?p/ cM:cW{~l_aпDQyyׅx Im{+[|BI'u~_WǠLyu0gڿU}7o%}W䷿ۀ.}I<)nO:إs'>//Ǐ<4sUyGrkYG?rGxV2:>H ϱÈ y{B~ݕ~(>”@Sgi]|)?{I g%^&H~uE`]r_xX_5RH#<igAzQ!Wx^Bnuut||)ֿbӼ1?$ / pxxus>-7:\{v~]J=tuAt߉D})_wⱽM hp|m}t=U^z~1=/yRh? ^^8rz~4IKֳ(t}~?m\oLCX'q=!>ar@>]o<?o6xm{ӺX~ Nj=M鱿_=/ݣPGjm;.'%4wx'~!~Cy-<:=wG"/ v4V}r)~q]͏,3z@E{M{@[Cnu.'Ҿ*,Q<`7y^7HO3_M uo=zWO/lNq~m]nOl;U?'.={PKk`ܯrbu!iO)ֳ̻ -Լ~z۪}=/v<>3su{}Sy~Bݏ:)ߴ]ڟyܡ1.S=~y;~.o.}>.Gn(fyi]uy<8}۱Oay|X|63aImoڮs y-^佥=`+C5/OaoB8Kswe䏿 _8n? P=Mwƛkߺ /s>n]{;=#2y}Tב-ӵ'Q.uf%\Z{t =O>4Ow'qJw1OxYn|K7g5QפSgyXau׏y'}~σ=~|Aq94ui3/ ?~׋~?/^phZOc_nOyGG;nt;Y"a?׳=#Ei|=T8vQtg/"k'o3n=Vv.)/^wkSN=~-nv _S7_aE3*#2̓^m+quX7,89ǥgf{~5ImOz;XWN3> v2KJ1tic+?0jڦq:xڭ?~о~L u~vce/y\H~blW:2>uW^v5c??m7N~׺ju}7ګqV!;ۺ=+:T|a?{\ci<|* ?J?+;Fr?ax}vQR엀ρeӝ'ux/g>jq=x_rWn~jFv#]>¯?+w}qp/n_9>-J!2%ɏG~p=tYʹSK.~y_?'cOGal?B.wI^u'_ˋw"x>ut9x8))7Əro3|fNI[+>&=ㆾK?GG +ϻ%C[Gxtgq}๵mz9Wϖ*#7+X'pݤKNJT?h~uqۅ|5㺽\ocVۭ=γk;>[./8h?aϋWv)ú>F-}^XB[3z|Q-?ֿ[Ƴ'UԾϯ:}܏4G+;-*cr~zq0m/_k?o?eGu>vy^ߞOT_YgjO{] JdޫkwOoO|1ϬOz=ۇ~~_?~_/,L;>;c?P?8#]4SIyzgrCO.=p9"^ݙSt>H>Þp>]Ws~;(u{}ڿ*ɩ[R)_^lN١_J$'a!ۥzZOzAtL<{\d_loo_wWNJ[ժ`{^oe{o2?p{7W~frCw}GŸ5t:=O{x}f1+?e[Oz;_v[o/Vn[|Wv:Im]H7Y8_kxB'xy^?|;BtLg _1? ,cD/>8G|<ۅSCP}WYJ?,G~ákzN5^ϓBVu7yp;<;W浕/b? G=By?{<zbk W(q~xſT_6o4oNurGryi1o#o+ο[[ Og*G\q/['p:ui}k}gsynr z}gM/|WQoZw5w_d+xw3t?ѭoy^~wxiwfcζn wnnr8~q!?kQ^~|Ķj眿gރ{|B8+~(m,/Nz։}oy~q={ohG>M}v_ OuD? Jϝ Z?ZWۯb~j0z/ Yxp3co?__u}OuGwa~#Ia~/ _qOG"uzݳ I/kyu·B Ny< y|~X[ߧ?|U|v+u'~ayxa/_5N>G{=@Dy/;ϓ`)~e]Ď\s2QYգoz\eO{ۃM9_\<χ{ZN ~~_]?}1=qHy{=gMQݙtj?~? xz:(X? Mc 0_=[cǷ:;%ѫ|{觴@1tl?4W^9u3|m~(򺗝6xٳmvXUuOJ{v~ҷmSxr8mN>z~K⤿]'Ğ _tرwUM~9=Oɟ^&Ǟ,ܹyv%ĎAO zo#ltx_fyn]w}t=~VwK͐o߼ ~e% ^xw;,/t63סP('v;-Ƿn-X=O?(w]vr~Ͽ8 0~:4keQߵ3nW?]PNc+#^܇rL{v!%,m?OQ_LR_C}Oʫq)>,y)]*SAgCRo\xxPW3u>#/g~ԓ9]۟zDz_eOcU?(<<i멉=r[i^z=xo_)~}z݄/-ӾpuN|ֵ_{ֹ~xij^.^[[{ i`]dwx4ZC~QH{NX0_|9;oB5ɿq{@W=@A<7| 3-EʣIaɻKG1a\_Ǐ.,Ď_祑O߮Wzayߞ~:S{ywuڿxh]\] :XOR0=S xo=*o_<a[I9}ydTj~{ڧJ9+Q}=>^h}Cm9Wo;?F@ʉךxoKy?sYuz]%o-{v z?:[ay!gnK\s?ghﮄ]E~;Tǽn [Oڧs}yi_ȯet/hߺKVe){/ۮֻxڿ,p=ODp_[!x;y>~%x'|yZ?,BxN@7tY?Y%<]fVɅy%SߧBGyH:6!ߡy8]OLjcw]Hn=vҩu_zdOu ϻir]vK=;_nNc vAq:(_cVҕ__uۃb#ޛ>{5_}}X[x\ަ^8=y͓o~ =2>Vu?o,ƿ߯m_wkk1}xǎ~w'bV ;"+:09s}h[_nk ~u>OBw;~?{F=7k=]~%<Ͼ3/B{f y>,œr{|ߕN{iwu1*^_"qI/qz_9x<|lڧjΏi($<3/0D~^*O#J|z$gm瓿ۻv .z,s:dOq5Lyz~̅oC~ 9I并[?+?r_r]ԯNsOߕ yuIAu ~oδo%xNSE\ha&i^7n<d?:_~L~NӺxUY?:HnL7iq{|fBJg}x??xH_ߓ+MWg"潦!{B$_o~ ]7 ^,>Qn1^yؿ^*G $?X_JTh? t:[o?=~!㝮{z:{]wWXSo?ݞOۏ{8]olK]B}O!9Nqv>'#N../Nk5-q' _1;($Nr?6nWC}oM.l?$_/U<13)ݺ}-=VجI׳{&̫{̓3ŏ6CyyYpC=:)YW 7{W֭_׋7¿6 ~k|Y@+Oewi>մ>7?na?ϦF~8?IsƎ>p]y:gga߯(AoL'~{Wx~_0>Dm[zݺ޾(y<œ~#?+]/[N;^2~@W<7]nh?pF|)_])u=?j|8~_%zayKz#s?nׁ~ɿqtP7Mv\[~ϻ)/i?qWُC[g=~lw iimRn=_4i%(gO}#ر5Nׁ|o*p>Oz㖗wQ8G:{] ҥS:>o3=S;1?pxu4`ǿ:;u뭯X/e W,yb|zF_R^\oo߫rso\u\>Ov78 _;tH[v׳$sz&N*lHoXޫǽ~. Xҽ^u\yo N^:`Go7p]e 9~u{4XwKni*SH;K~ִKَ = yni7?m']q9qy|I#_~BMHf/u'X3z5{ylˎX)xDz|}I!K7vS~'m;ڿTz^J(SHZz^Qh|<?7/Dn)_v]&= :S?> Ns}Um2~@~r}AxIG^O|i=e@9w{O׾pWxNu~'_A/m/Ѷ7ڵ1kx׾'cc+;d}8metl ogn?: Ϳv[ W[u:N=zi=_vɺ~p>^_S[J}NՐNگN7\G9y׻7jIR]ZܽQ/ո?|inؗˎG8tlRm_}ls'|Mvoxҝ.ОQOnM|lx<= oǭ}Ͽ,q-uA'}E}y}@O,.ֵ|ۭ<Gއu}gf;L߽[_n;~lyu|Ǜ2=[\ѣk~o6үr:ڿ;Kow\ߺ[v~:w'hg/s?#q{~Z8,ϳ4ú^<ǃ4)=THûy]؟|}UhU]'4.5Of:W_OWxރ~7(t;ino|ʑח1ʥS?i^iH7Ò'yn_s9u֩̓>zZga\wS[7-~MOwPF?VN~eA /Du^Ljm._9{=n~[۪~ӏ=2%>6G8EᇴDlcgV(ɅP_Gn[tcO=Blw+~}W*g:<&~ws!t/3w>=ƝhNì;] Ys5^溫Bm?|mہhOqi^}gZ_h?J!宿&\+DZgur>,tf>:oUwt_A'vq^>  {]6PIqv6ZS~uqs@xsy.߼Y(mկr.3GO)O~a~;ᅐ*~>Br9WOu7u`zԾYG?yn*sc@[Di~ {"kO~Nm&?)]ߕ}7{7e7[u㺧n :ك4XۨOnX_|tA f; ۗ+*ozh}rSqon?Ou)]mķ{Nu9~ݡ4?e\^ϰyQ2[ߏ>J:m9ZfGxN%|Eǭ ߫õ3i}^3~o<8ta;H|<珒:ǬZ:,E_8u.s[u^G@>ѿ"wW< /8~{@u<^Dž<tP=_=?`)^/|rx_7nWHh)W׹b_,}yvj,^:ݮ~bC^Kqp/8;>w^?J@+}簼/5~w7UD=M=KzNQq*>ʓaV?畵к(=l꟰꼗-7\ / yhx=cϫx[z&v {=~4<_zry_{<?~֟Boa<rX^:{UDZW~(ty:OsX"<+a'uOqx1/ {__w:p/;<cb'ma1վǛykm=q5/~N;:i>Eu+݃ZM.Ru;}+!Y|]=uv9 m/\(}=x^<ua~{BOuUS/yaNz=+xRoo}ٺO{9W/{d.Yayz紞.e^o)t]M8S?fv wxmG }ָu:E{y{Zurf{묹'ۨ>L<ߔ!V.܋/DV#_{~Kz~wcez<રBtJ .Ki谼g7ׁ=zf=?u_W@: =BW BʙȬEyn5x)Wo7Zo? χt [㹴O:w:NqO^._vwj_+B4>O\\wi;o' >@֟{*v_ Vq]Zy.:H܏[ϋ?|goB'~(\vu]xv#]~.𴟋uϭLv1͛WwQzѼ ={wKכnX^9]?=sۉ'h0+~~i]xޤA=wwzG޺k_D*_޸ߝ.|;Ŵ U)'mwmr1wJG7ΛEFtnnGu+cx`ao}wg*?Syg]'T:yQ(>0}/)3jz]/_./(/eHl=v!W;σ,^$W[-y`\N}V?qe2x~G=A}e%^w:Za3yAE~A/χ->~g`owo[{u}XoUڇ? _wyuM~ei?<_Y|O7Iy><SK_5=xG!O[PhV^vw'XQQN:C; BMv`7ax%}r"iBc=ϝ;;GvaB+3/xڿW\HÎu?Hv=mz^#<(g?~{ޟ[l+Ճys?x<=Ӷތ^υ?(~6w]H[Wem/ ߃=cœ^A<حq]Kuuƺ{_m<wL9ϺEk/ :3akɺuis`~ɿ.:^tڟꟃkD}.ߞ97[t=r|H{F}nؙK=߯k9gxGp+޷xQH0}t;/>{RH㯪cuyDWowۥzN}>jwfq\wn_*SÿЎ{=ϗ< |~Y'>vtg_x~'~O7{<㥶?i<^Z@w#Nes? ǹn8~oZ/PzHǐ+{R˶z\uBuhxݿ~!wK\ՇImq[n'~0?.S:.PE:wUܱܹ=_nz8Nus8]R.m{ڴ>/z=w?fLEKL㗄Gğ~0jm]G<<߿95 _¸ pͫ^[]tRWaׄ?gp:n+=vxw:nx/s(wztXge³0^d]L7{<[CwvA]D~<2] ~?S^uׅW-Dh}?~'{]{>M]<u\.%_"(D!_x?Qq]Sk<u+z qtcG:>naCd=?>8ϧTߓ}^aÇu]G}B۾{\~fS8lw|I> &{݀?8%WȦ2VSm:Q8m/?k|[_n+wrr{Ǯ#hsa+Np#W<^uֵ1_qTb!n4mg39[*Sf oNRHukX^xm;~Je4ᵱNu4ҫt|YO" qϫt9au=uBD_ xQhe5~7 om{E~Z}#O~þu@/x];]o1go:Fq?D(+o?ؾc|.?{{?zZ8`=}jo/S:=~6sDx=̮Wkz~vs|+Z_?XBt _"_^?\L{ቮk%oϭuok`~%z`;]ӵ[gaO3U:~AۙڧDg9n'n_ؼ}UKN{zx'#vuN׾u(~ujwKߴ;B?uk ?t~c;jt8&t̤]w)=ڠzp\r7NOwAX'_\)W83]{gvo»+^~w?xܤ XGn!^3H<ٗ~˴O.>Ͽ"޲fگuʗ ?WYC?_oDyOOߟr;o=vijx0+[~Xc>_ze^l]DSmkf_1]W?GnzV׋9W<}mcѮW.-eXOW]O싻w=b?,{ɮ/vϙ]ԋ=__H?6:jk:~Tǻ_xl/ysxG[~P=y*~>OT'/ݒo+wύMЁF/ϳ|NrL_گ }>OU_"ϵ݋|;٭;: P'!~/?uy~~.峎<{^<߾CǃIu^^x) vb'7t;Uമi]2O]tmcmH:˖0_z5OBny^g?*?D8[3?;(ov_o 7u+݈rYŗKN~o"JX>K?_ _S_{~2W7S_؞w?ē_ }_lc[z9,d"a7O:KKu\%\ɖˮz߯p?micu|<_QzKmw%<a1m>x\^.y+x5eg8i^^e|{0xUxb[/_=>qȭO=.z`uvΊCk.t',^ogs놮w9=ob ]m.tkl=_BCfttz}ݒ宿U[s߮{^k.Y*폥RΦ^/<𴎇EzoJ:Su(ߟ<_[x)'=siո;]qnE:j˵IW!:Z i+}Jx#|*}mG =v { 'sy)?,Co9}V{~lk{8=yzv܏?)1-:on?:?ۺ]ܠ{;\~45Ǵ^ǴNAоT=>po}9o8lc}h=Z'aeOoHa_,o_G~'UvϗxyޕeϻO/hpg:gttxu󼌇{tH gҙ} yW]ۦ3 8/c{] Un_T۫7mmS({ݶwݶ-c{~W{•N'.臅NX;؋i<ZN*ĿHÿ?uy<S<޵5Cu{|.ďGwC!N ?ռBϡS^'wn׵OӴ_TT!zw{=jXy}MSWSz'|uD7>n?F,l/z[|w,ܛOOC;]AʅuZW.@^W<+#<}Hy= ?{g1/ʅ Mqu,-񴾵}/=bk~TN(smۺYntFغ4~o+?]o0Vگ^cKܼ\sW%\oOe{>g?[ '|iOiGL9#?Om?/ƔwˏG>Ds<:anGW|P]^=/jbϞ[:n}֭;x>arC ^*^ >3{eN[v=IX/v?bվ=ʏ8pXywkO}{~z{z[Õĭoگq|gҋwzs׷_g{B?|RP7XW|_=o}˿qLm7{X8V(yOd;u]_h]־E?2ΟN&M Y.<Ϳ߽=:kԯm;uϿ$S~~ua/թJ]y\=.Qq^;׫=y_mvE{?0<6о`G7kۦNgů.\#j~V:!vAWoykBߣwuDBu_k{NWݶ滮IAYͯ:,?N]K `W?+l|K8q O>g_8}!?:c:.ŷק&^o</[;zE;E'VرO`t >,oů!?y*s_vDO/ ωPOW\p /n,xKKݿtvL;<''%ڟlzӅ}y^?>vݫ+]g?+=qVtuigz^W~^W:>cxyhm'B)gwfb=wy|J73u?̛Xq?)yE N^G?G4mӟd .7oXv:E[mʏ-_kfu;ee!cӎF=n]^(׌=bG=߱ok|,l/:~X{;{oC8#W|w4nϰ)/GgiDKm]~h_W?6rlDLQ?}^8,^=S|W.u?a^Z2/=הwx{}oڿ.|_wF'v;TnJA:~mzV릅}C/O'Ek@z ɟ>,«Wx=%x_^=O=]hݛ)^3?oYuu߮H =O?V?k}}|w{^ƅxugϟqP|'Q.X8~2ẋOs޴0P>O|US~s:]Gz~.]]|6Zwk]iִ.+|+DZ9'ڶ{yoZ绸]uuo|;_]5S<{J,ty#Wϫn:j}|5zx{[ݯ^^q:yw_׸Sm+<s -}үFgsz}B>^rqB?*Gݿ}ʹ;=ۦO›ױϾ6֛W_PQ^/-?uݟ|wt?ǩd^|A;}q/s}X8|moK@>q_1{y;i?}seI޿(C<υgçu> ,^g{J:l|&})?Ǻ»}'~`>Sqn#=o9 ɏp3:>7ׯ3rSy|덜Opހ<ތRtM姰Z?$]nGut==nҹCpQ~u=?~ulh~-zQ>z_o0Nnyϫq!v8+{==.zdا?MmmO>I_|:s_m_\QRnפ~WnWZ,l}Ox7߿hon+#;qwo3wG :oXx<U 7xu,l}@ۏvEzN! 'Nz IAl{[7d^^7YC<^?VHh_q዇ym+0·taV|;~Z_񸝸,syDt?3_xYgߙ=i-?se}Rh}7 *dF_?d/Ocm{į \wk>+=m~*w<j5|6F{A(x+=_[\JW懮{>:=W%xߕ^_5mtLS {~M&(7W%t.ߕ{<Ⱦu9Ou_=u:.a.{k;{ ~ǿ`l;]?0R_bz}b#J/ 7_M p%{Jq]t17?wUOc%apt)?Ǘt~[jS;}ޅtML:~'[xP|Oz]~{g A:&?#xw(WA_j]~"uԯ$mnXgrn6kS{kyܥp>һ><\7XZ/}D{9u~\^uNv:3A[۪߀^qԁҁW `_gK[}ap})gczě{,B_n{XǼWezط4WwXh}MNǏeuVu787/Sa= xݒwquS.s_ $WgBK1wl iWxNW:%aɗYbTp;l <~o^'{t꤇vS;,xח8c=o?黦sR_ ?}~x^ב|][}mw/[՗>ʗ_|tiKcJО[C<q9CE?zˤx]c\h,?v8Π.~~n*S>» O18MO-??xNij''n]%>]oy|:y?}?Xg"OMi]'χ~XOQ}xzyʴwo9δ.MzGuN0# bXO])=Z' ?U]oƭzz3gCxqqiC;J|tnuwOEء[qvc7'=W_:j>g!:P9^[JKGyN~yח&㥼wyK'fO9pF>kWŐӛ.ڶ棬us>gzm5z©=4~MXc^/:_c=U{[ߣyׯ;R^gu_ǟߕϣyW~W·Z7r e6Rju϶P/tsoc9G7 M~^m}'f;;+I4zB9Xu9wK^+uă*>>Îz?/x_纛ed-Zm=jǑAʥs=?Wx(_-&ϳ Y/zx䧿b{h%Lܯ8. yz<'<߉|9^g{N7WA>LR#} p^fύ}寎׸uGPQQ/f֡^WV<ğs~;yzU(ws`kK޷I﮿ O۟rF=f)ց'Ӈu˗uzɗ}8ϋpeu㾤RHqWs|N:? =v~ktq~ǩ~ /(㇟l+non8d};]mzuw+4⩶я(Wkw'y#^W~ח[CϾ" ޠh쿀~lqwA~~YZm'"*@s+ް=I9Ǿh?BxN__D;zyu?^?xwG֍?@. Ïy߭߫}|똤׋/2={e?kߙt79߾_<|]\z3kL 9n<=pr:b罼>,ю]z| }SO~﵏I9ig4Mӏ*DW?ϝ!_hǸ/He<iw=W>w} _y{~J}^)??^>.sںmGOzWO?ߺr!}hr_oޥ~9x < iB_ϪlD;~)}ܟK!=&WK9P)SdiEJ~_1>}'[=vݚb%eǷ,[>s X{]N㙔st zasFgh]R|j_7o)/yp;ꏞ}:>vڟ_8=^4c5G]y8pS~gtvd_~@u<~[Ww)d_^r{.>,K~o=rZ/31¿|X"3m]<4ߛ2+N9~(^OM<~|#|Tnx>[yl_a)η?C|Bmu9U~o[_zn~=~o삭Z=3 <_=ҹ^7Ͽߒ3m~Cfs&^=>zla/u`K\OzcӏîM:vKzm_@yjo\||m㞅_{OmzދyOӴgs{s;ʙ^V(.1guP>H9~?zu<MGy{ߟ ^m/߽rݿ!Oqڷ}C}fćo?'^w%_OtsݱdiW`~,+ϻ_=~})_;OuY~\.G:;ُot8]w{8([!ݤ:w4}ϝrC/Ϟ~D?,h$_7}WǟGʴm޾׹yW'$AKHWs;}m/;{ݿ(clHbax< l-:oZOQx/[/q+V-RH Q#_wuu3{꾴oiP_wv9BGn~g_(PS/%=ߴn~L<$^q1(o{;^ i}J郧%YS~# o^:Z<}N~Wr{QHr)csxz yޞ'4M*~牸t{.9Ӽit>b]W8ps~O'ܿۿ Kxݺ~C>,k_/~}4I gt:]4^?{w~ϗY鱔w?OuUyYwG뺬3 ~a,:OEI#4v=T=!m׭cϧ>0#mLϻ5jr>M惌X+oG'$?^+žyXޗ|p`b ~5n?(?Zt|hin@p:Y?r<3ܟ=xm.*ׅ9\[:ēoXlp|xzV/ iz\f7y$Qy1~ul?y.m:l/nU}K?^->oFϺ1>ʞqxrty~ J&i&P$lcuB/sd떷K\ ݏ˝Οy(+}^^Ⱥ3 z)@{G޻Nτk?o_~{~\텇wկWXƯ. i/?ۿ߻%/r?}o_Oڼqtnҋ;;_T=CzVovz yly~wG;n>:꾏7>cMzlzim}pw~M>ܟAwK\/~~mwTl7/M8##qҙ7e' yZϙ3^h mL:K>L-{]dZ{]a.󼮕8ϱ};=,7yjc׏:|)?Fl+[=/j?>ԟ=w9zRc߳)uҙloܾ;kE /C o._MaB( 2|Y<'[uyn!M_~<u7d${^7>{IG~V__W&,w}ҡ.tma`'u<,q-{=wmx#ϻp(t0mxèNc5N?pIwIǾ(wqB]voi/g?zn۟^?w4{ZG獽p} =DG(HmOwo=b:[M~;c[a||6wcGjyKS)ޣ/ܟ~7pZIʫ?Wu#oznmXh?ڷC=^uϋzvёt}p>rvW4SoxOw8х8,tf; =σbx/m݉i||%Ǯ0py<{4d ^퀏}ܟrP^㱓>d޷r>l_N:~M{ߗݭ~8ܣIuhlX|O}ze:Lr ovf>GZC:/u>/8^z|oVLx~^E9#[+y:N9$kr[ƃN޺q_f?~??ta嵿Thݒ);|P'k~&߮. yt9eVz0Od{݃oi?yC~ Vn7Ni]iLo7i[։'vB ~Y:xY8ӓS?jwZRqt=+7cn<7gҷ/ďzvH/ĕe<%]l7VvC=>@}[nhTC~m^ndohSm%ןowl'X€k>tO?u\߻bw8q+:~Om+۞(4hIS'hk=~sx?z{{xgl? tt)Wċ.u/ٷ>OuX"U}[Wx+#DE߲~G B Eu)#pN5dü G~z9vߙ?߆8IH}E{n=,COz?_o?Vx^YomSZ.u t7Uip}Oz hJ$>GՏpAylkG==6y>FK\}Z.ٟ|q}sXZc=ޫBɧ>߇NB|;z;~ngjg)Md]eu~^eZoz3 X=밼/I|zgʏiٮo{֯n}ZW⾵o?5!?HEn,j|m?A/#}_^m7j{^T/߹s"}'Ӽ}z(7Ws U!vzbZw~ĞqYh?H$]<'XQig.Qq_>Nǹ~F:4nk;^Y ~4ȸ>,c'6a>Iw<ˁy~ӿgi\O:a{O~.z>u%~~o)WֿQOPmdĶuz=. 6/ƹlO~q=}I߅StD#|m\rpUqYڋ%U{6O{w+KlImϽ-7^y}ڋa򟎯6A=~߇P=K)]^ĮW"==aɻ 7ی{z7̗z>B ua<Ò~2woQ3rD#qsW9߈.*aU^CyU)>:<.惡p_]غ|~_OqnzQ^N'Q.}y^7n.?V_Bt+/??,"}KsXK H= ϔ[GcVh=~^WȺI{ny_9ζt;|]s1 }s>_|U?oy?|}7n`χ5LO?b3)܇|#]ZP{/a*q(~k{x[sb?)sAu#,q?gpCxB?$~Cľ{@a=|hn<oז8~_^ZSRH/ _BoXFKrhoy/^76'|G_;.;mcyyV|G`~5>۸3w~z~7쟳E!!SYDg\}5ݽ?ퟞV<^Ǔj=׵YH~Wig_ݒ諭(,l˫}ן\7hK: SvK^^5w5[pyr<~/ Wg}pW GoAuCrw{t묇Yߵ^w][?\>u"yko=~<[z0ZֵߖzFb?:n0c=t}yߊ?N?;k3z?w?;Gm{GHzzTOzERx{l{Nl_u,A}yqݿOͥ?@χuօw1^4vZrF;J߭RNWao&n3H{S|hw'=˵n|~Z3~ovA߭./ GK%~)d~:ϸN|U2_ C: ;}+`_`onHb{88,{T\X~볊JN/wAq~2oQKm?gskߺ2o yk(x'?ec_xGދo}Osl]{V=~=^KǃA_σt{߹r{Yo\Áo./kzzR?sۍ?O^:u??Wyl?d{>9O]Rw_+r~8ˏ9/]>wL1'BۃtX{]_ݯ:yyt;tiUGy} G=O:=.n?)=p^9_p8[װu!ϓE|Q?3+lQy %n?w{!owq;!K~X"<0yS5:|{.od7z(u]a/կ_'侔[.WDuK}r R/@!:o?T#oK%WqU}s&m/,2=`?:!2z:wrwa{~U=2=٭cWا_QVlt~ywyKlݏwN;J=v^'yVQOt~~3/cE/;׵ygx~|a=~=?l<rYYB|&?/3|vy-↑K~>ez}㾵MO/ gx[w^x^VjxO<2{|c'N /_ǎn<8?o_Qy=K}Dz_\iߙ c{I븿CڏƼV^NyGu(Ƕ\-?~_sݕқt/+ v?z[`N~N'Ov0Ly\7 _퓿K΀KڷNIzNay('P<}qLuOogϿ^ׁ~|u_s+:~UH~ۯ \r=E8%}MlV[ϓR>:}78ݯt|~~TzV/L^w:뎵ݣtQ/ڧƾ-jD'u:/:In8W :O}{3F,qҡ@c_y5sذz᪞xwIj=Bsfh]<_pz%^q8xg=^Zy.[wS뿹_7 r ?V[ <'=׭}ە(>=r4zV\>=?`_ dzt?sֻ/vB-)[*,B}BhBIIN&=" (([IGϑy Umѭ ?/>}Xk{Kqmտ4]y.}i۱JIOMq>9wU}bW$zWgXOo"Y羯 iHRf~>Wpt4o۞?Nu8?=oW:]<|oOy,I=qwI׫r"YױS&)},ٷDxȞH>_`YÔ3>n=>O~o}ȼ?{^T3ixp=e^%Y7'<`ޟ̃61ǟY xN<|9%g/oR]W<%Mp/hG$h'<1Ư }L9qy=wNa$:8q]o)+]9ࡏZo.K|78"3~|1_wϸWg|ucwahp7gxOG?zNq n~f?'O=y+mϖi{1485i|&^yWsoXy>/pLcG `^.iɮ%?%}?c)<1!+Opz8~1$6Oybū/~s$x뾭刺{/odh;mg0"Nq<}2ni\q^C3/ߠ?lw/V= Ҹ[S}pZ7{z`{<+G$= ߪ"u<fjGZo팟yyp7yxo.N\dIZӲ]l ;Ǫoy_ҵ"EƻDz}Pwץ>敹?ӌo;.;{zI8|nKEL񌬇>x:z䃓HIW={2^O߳d=,&Ʊk}ȇ^}H9pzB}y:/4.qmKE~r>[ƹ붖71'3~lO4?^=Y>m|=v+8M .JOd8d[`0O>'w?]vYcJ{p]r|y{{X۱uعYL|3&zO-WA+)/vs#{^xO~~wd1g|:xEQyƽXW:P1^Wws9c }J}.cq i7\~o<||٤WW}ܒ_'|uq>upsHz>#̿2ߙW{|NC#/{"9bݠ|ZHN<+I;_%}ngu\7ճ|&ґœ%8ɞGøzomTHzDE;q5FH /^L%`vDwxco(c}|ԋ|/lc/O9ϙ>3ߩ78(x(kM̻0ĸ ڟw㿌{R۱c))뾖XNگ x8|x}[[xIo7\H9%I_#mt_ DHczBDcQ/%mޅL[݉f2m<k<oYgX3?i}5Ǫk[7Lx{G:v:vߕ|_s~'I^Hi_8.n8y砷5O?~wym0O&y'iՇ*{dݷS\vOdrҒ')?ƍOro3~͋*N}<ߛ4o<>OyLʃ߹$}Wfq_pJ{X}}URS.p>yA/㉊{HYܮƑўT[/9ij 2ݩx r?kMyu廴[z{9*ًGa>;% Ox[d7z1>ПU"oo'/_o=fjcw\1^aqgG?ǯa|OiCROeNq|9ydޔ?Xb\74.L?)S.|~ڃuܸq aݱ]C{2n|ǚ}'M;N)|]?5m܈{#T 2?<k}{k9/ؾ(}ScMH<ܟ5/Ư:J/h={)>ǭmpO s m7/bǭy@S"-i BuǷ)V]>uZ;eI{_K?qߧu:ϽM<)%8K۽>''OagqOOWz Qos.xAScO*̫]Ӥ/)/i$Ыa78<ybc=_>W<}qʷdqNxӿGO&xfy>>`uxG0GI׫}}>K?:{|9c]zm;!ɸ0Y[7o1C|=KBoﻶG{ny ';ƱR1>{,>x7;5I=2˟RO?3^oү~KҌ$M)seqKuqmo`S54qTswhOڛ׸J}'C4m{˒).?0 |C7^8_w3"3. ^/=uw?/IHIӿ;5~ucw%!UoY9KƯ|纶˃It=7kS xHbsN|H;%L؝VizWiŁURq6.$9vD#*O2| u~܎?)'}Uϡwԓvnq0I<"?'N+>o7~e`xJUz0G.zy<}Kf;gOqO}"cX "kd=e\aB/ǺݍzF0Ṙ{f;1m/ax^a683q4<EJzG[dqHw4RqI[Qt\ks|WyWhРsG~dK|$9qȯI2_wIst|Ii$ӞyOEzy4k>cE2^C?$V=?T(x]d_*_#qU}UORwgH?%{/ẊAƼ_ iD A:YaW:ϻ>GƻQ+X?E2.o{G鎟H?tNE'+ >jc|)%M'wHa?g<02_ww ](i$wݯ6~ß0f[|Uzo!}PƟk?E5_ڸz7Ӽ/y7k޴Wq{6}n8diޡg(|S{6\׏WRe q9̏1NF?Q?#?aQ[Gy4՛qϸAG~?tܫ-s<4zx~ys[{oFo>tܠŽ&mƥwܞ|>'h6#37yxtK%Uo0;m=;{}M7}畎E3:_N.>*x9x>ruN8嘧Z} iҜ՟=riI|\DKd a =Kwy~8/82];=ћ7* 7F:.I}G)#eWMzv }Dy߃~yh/'~Ϻ?/4_uu ']Yv,y6s(vb.w9㿊D}sH3Ɓ|/Uw};}?mG{~Jގ[2sOH߸{?Oi_}R?|ks/TO~gq0Ҵ#~w;ԗzl^ό0Nxu|$Hy?8 k=ءc~8=+菞gyg&+D~'笎otB犤]â^;|8&qxOׯ׮Fm{R)..}i_{H|s /S ?a<.rcAo@9MH=t>9v=>^{Uo# A_|Pcٗǀysy2A$З\#XHGڎy#;!vq*In&I?A'}4o>%M?ԯx} V<2wx@ѐ6cS0VXӖO0O7.~y#O8d\PN댯ǪwzHE}L9!ZFU]7ߍ; ݮio߳ާ8H#W9ԓd]7Kl7U_7~ü5o ="sgkd^m}xOY"czcOOi |O 7s[yf6GG-޺ִ"A}ykloy0)EnG*=Yr:?ѯvʣ?=GƩ~ﳶv6ϾMIYu.}G ;cQlgxs$7m_>ƃ֫}XOmn%X-?%3qb/CYW;ƭN=k~3zR-fޣ Ulk};rOMk^ 1R;D%̋x4_ȼs{Y&O1s§c型P۝}AdӸjytnϡwwJOq? 7JOv["iK:)+zo}Ͽ=?zaOq}]_'aU'y8)ǁߙoḨ _f<8>ϻ!'=g><}f^5v2c|cNq%۸Heڗqs٤ .8<]c۱Jvχ7S.|xߣ~~Ho{v'xOTqnyyss)軖Ņ"k.'>Ag|_]\^Wx'^6xyE%?R9ێk5?8uܭ[ȧcs2㨶oWKc)XG =7~d_:s5nm}~*N@|l{&+}q];ۇ1󪻟~}3NX˕qL;@wKkK>43|k;W[=iڑ_~s|I6x'޴3qS4Ol>*yyJ︄;#9{}Ѽ%`_w H/d9΄uq;'OX|8|x#M;]#"~w<}[寕{_0:¸5NσҶw]so>~-S;p[)S:؉|5yyIS}=ۋdG?p,鬛5~3]/?o~bUXeHۍ_1g<㐬=׭+^~p~u:ϱR~wEO+}wۚTqZm}v~6<^_Nv|66̓j\Aʙd~_-A1X' W0_IqC?]#低 U/EJdy2oΘ߀x޿Qx;5`;D^o^LJ3Nx8}IW!X;{&_U?n{3Y7iƟ9cxz ӒO;RO{g7?pH3mLy7ty]qRU{}S|;?ǣB/%+)k%qz}>*oяk%Ne}{{QÔ+Γ|Kbgۏ4C1oCoHX%841YhG>aq-'XގkD{ pM_o}īz;F/ md]"}ߒפ|vzwzSuԎH90?zL?2|j{NJ4N#y3ߖD_4^BzN<+bP0^7}{<><_:\}8u|n`ޡ^vЮ03딖,|ǝ>k$wKyy~H~ I{^6'iԛc.]/>Y?}w_Ǎ%ڝ=OXWM:^T/ڽM'q{3?Ӄ)üLoxǪi'Uo洃\X%k?3"̓bvוȎUR匛O$F2zձ_w["{<.㮬]G{[qzg>?qI/?b;&8_r|-?$19qE ON}OrE|v>>WGR鳵,Ϙt>5]RC;oxr wDܧ} dߌ!_b-T>}cx;HƟ,9ޟs}釉E뎫1_rcļDn0^/ҋq<_V?zoh?l{d?#Y{!|7|Lg=~ʺ`{HkۏI~'C_y߬S}c1noǚo =}H#qN?v gq_A;^2c{8zv~+Izk~;c';9k:c|z#U7=k\8eO'ǣ>'9MK3Y_xKNKi=ɿ'GG9qDڵ=|WY<+`_k;q^=ڎۻ;ϋ4} {$ o=ۃ_О>s֗|y?B㟨߶JgBJ~(I/O~<<^ޏ}w8mJ[H.+cݶyf}4\g<1^w}"'<˶h5J9)sO_}}gT9[1iAO8BmE- _%G27A=wm摖4|w7_y5i>9KseK:yg=q<-ׯaƵ5Z$ۍgM>b?uBO>Ooؙ'N$f5\UžzxX.{lR/!w,~qq@no^8M>oc}?oyf>Zs'+'<*Ni>y+uŹ"O!pzbn;<~O/l[y)>'b`j[M8߫杘emxLƹ}{ËW`9±J_)zSdd|ޏ~}kߎ5]dV}J%hGSO~q/ipko/J~'yU}V")WXI}@oJ7XcbҍIne{9tI>x-|Iyo>0.ăCҟ=R|?|I{>evW }q~t\>;vø3;Oo<<3ʼ¯*>G-3W:W|謁S\\Qk;tϓ6Ns(%zk=&~(/x m}?uqƯiW7}|Q~%v~$N-=OSyN|qxG,Ogg> 9)w>w>ZiFYvD:~qi)}wŗ$ȸ[|+6qD}v>?xKGW >߿[y2oYp~??K^]hOst$~by1y~:vrϥv?>}յ#w˟/Oz[O:)o}O~>o)0N)iZIHH։8G2bCG_;ѯ *o)[G:øP^7)wY7i\o_'z3=?F-y=2h8ߞQ.y{=3ϛy>u?Ol~[q9㒌;.vϥt}Xhoډv0nyOs8қYnϳ'+븥Sy{]?e=ƛ-#IOGc ?zc*SF|<;Pfެk7<3Ǜe61cJƹ$~)rc^wZg"Y/,kv|nwׇM<JO?ݸAO[ŅoZMCu8\0;Uo:U5z[q/6OzL_W4_lO$m~p?_$Kl9K,oXzHZ=x"xSY'_lێ齅*7Layg+&ߴ˰K^#o\(ztR<ǯz_.zO+;sspyѫ'?_.}ыyip=-?YxomEzD9駤Oq@d<&3Y{ސr:+qhܼ,+'߮'u?=rbq;?8ufW;ڷ2!;cίo?=D5{|Nh;>wf/dCo}.=&;~o6+i;~53ߣ!@~gy.%i/}:q۱'sԞ;}/_{[x?@曙W7e`s5q9׎o3q~V}6.ySo`:| ~/ ,^'zy'C>P@x-|q2fO Bk=u*h'sڕu}4OGO9wǏ|ڣϱJ;yD量~i'&9=ۄ;x&?d,Iߌ>i?;Nj)iq$o?Dڳro^/5w9(*vi"c}n?wO>5ADo"{~sK0*=,z_ζ];_oD֎N)i4*?+i7d]g^xq'z<;58zھko_UyS|_%x N=#7koxڟ~v76ŋ^!~~aJ㬒cA??;}<\\Ers\6)ƃ|/*P^pos58ϝ?ONf>>v{zNL~׸mգ8$}~7?؞|=U{U{c~_x[,/]z4*b_R|{[eyBgwsyEߝƱHSf2'#(8ͣy|Y5&i/ɼg^>֫w_0%=}ko>3{tvqg~d{=n|Vn@2nЫ>ũ>$;ƃqK$pm$/?r_an#5.(ć~2JU2>qZyugPړz`GA?U΁~[}uʿ{iOi' {7)tuқ4w7Zw_0o^Drެy{$q$/={_5z-0t/w"ٸ¤$ICWazwoa{{D-E;~|~qgԞ{9c3NrQu\Y/;ʿ?zscߟ3pHw|ؑɺ͸jR<"zOi/z5qkO Mw;VY~Pʳ'|~^+?,ָ͸A<}-m8 Ljƭ:#OW9%SJ_烼}p璦}̋-6ߦvz}#U}{3J쇜c A9љ?0%OQ`BR}#H}z>~_cz3z@އ_4NG{,Orgz;>C)޴???Xƃ 4v:;iWizyqmM畞x][v~WUW<yF/c.>5I.=>w =mzzRR/%s6bEӖn_]W^ES|#=O{ϤGV<}Mh׿{ߊgmk9^?޴?y/4i| }U>EG1ab<\"?'TQ}-g^ ho/$v俣p2uܥ/uXc{m=]sjw Wx/AO'HÔ6Q=ywoϫ\_>Jr`~jD?7dqH;Ayg{T)o*85ag]u2/|H=oZO?} a\s_"i]-x\ڌ&i i~x/>U^N6x-iKa<~|dyqX,zB}޴auzSƇ:XNuXW?dG4G>g='G} <=:9kKICU>_Q9)EzoQҴqSgn1oj:a?wK0nzu<ŃI_G7<ǤOCYMO >2lޱJ_=R%kOƳk;^vuDO~/y·;>tܖqrG]|/akJU)>^.|&v$>Y:Gm]U:M|υyرصiפﭷǷqiw>~'s~:q7<w>ױh84/vfac/͟q<yÎ=\_ ӿ ^2 Wo{@i&IO~6(5Y:|Sc;t-ozmx]'3Foxm| _s=FƷ;t\qPϟU߼Wz|;6_;~Uwc[?{}y?Q)'0<~k8e~8w@ \3z ϓigVz|}僣hK?kG K;=>}OI%3hm>GRLW_}nP_1n8'=?z=ag=w383$I>Ƶ&m?^oߟ>m#^??q77;D]'|_y'[ˌ|E{'zQXOҷ8Veƻ}ށdr{Criq|/ O=^?>H{y */L& G|T#>}Ji Ǭ_ߞ}0*?'錫¸y\Ǖx}[K9Yxt3~ &ީ=Ƴ.Oz3[m;{3DsϯCg۟g}BI&%)oKtKnkx/vģ1_aԣ=U~(v|ǾdO|&g|B;Υy'M~G1N{}`\=+3e=#Ja3]h/3^E=/?ďP=˲j.>ɺGG_}8NCr֗ۏ244vXc-sa8wߐ}h?r{w/$:z_?,ç3I#\#}o؟~g{~oyS/ y8nI~ձo/x1;_cƣ|~M9Nu}Kd<!ζw1Ǹ)^x]:rN|+5̫EO *o)N}JGcNG>>Cϧ{W"stw^G2&|GA-&ݸ{})L(8%|Fg8gGeS?'u[slǗ>qc w=ry޸_?7]Wyyy(zpI;~{9V?<7o(o)帷SY?=Wqsߟ՛zENK$~wF]y=˫%}V}|]gi:5nx\̇$za^*rN~sc}94Ey&]ʶJ{wS6B4,'*G>]:d}'SoO~U 4YEz{nAA_KGo7Wy%8 =VG(}Wܸ#iEɷm?^gx?>Ot>i ķ^0>7ݛ|0/q/>/(_>ƱY(w2M5WNmSz/0Hin~ƫQ|)ۮwszHp9~#z99u8w}/S|IyyT{[!|㽋ʧw8{{8_ƛ=xȉ|N~g N;R߄:L<WJOapO~;yg\qawG2|m*{?\ǃMt߼_si߸Pqc-o*H xD>k[XKY!y&a;q+/܄N;[ h/]X| w<qjޚxwO=Ϳ8p[AG*1*oY'86<>㸼}Gwy\ާ>Gy8fYi*~L']|"l8WIO*m||$xSqPO8s'[\X%]Kz؏s|5+&I{`/s^O<z3|>q:^,?oy~*׊$^ ׼,#幯/yϒi(QOWUzv-^ri%\}8"y^ }=ˑ_o#Uo$`/X^;' i?{d?s?$ nc{a7."vTvF Gy_%\q_2?̼t.W{,|W=}q}]U/ۇ'Gw9w~~>^%*<7R.q`ޕH>2sCyeއ7Ʃ\=>OLq.wKڸq g܆r%}9>vۯ'-?a}=_c|?|wOǘKe\X& ziw֣p{w|ρuz0|k>UƗ{zi/בH{2?v W^cMKxh}{Wǩؿcbٟ<z{9"HWqKǪiexi|<%ߡOg'xt=~/~'~M/x}w;[|7>_mk=ڿ | |~*w˻)]K}/Y_+Ϻj>󍣈<9ſ-߁O򾔋|}nxd]dq}ԧ}տe=!o)qg~N;N!y3~ xHHߒ1K}=<7^|ii߿I'@?P~qYKd|}}&}S?t-?0%>g$~:W۝t~^zൌSYoy*g_C2H>A(>ŭurK'M$/-Si_s]G#m^KHF_{Ozr_!-}OC^"YO>ϽJNӽDH;nmJx:wڅ?V~{lw/[9ͼ7(L;yc~yơ&^2XtKIJ8f|5vy8n8ËH;S1Cc^S53wIw>WlK.y˫W;g3)]/Q?iS_c5vE>}r&q8.wY(/l<"O~~vynP~b$>_Y"y̏Uv?{UӼdڔc:$k ϩcIw/r[)(\< e|a|4~B>m8}~ ߧsöKWގ*.ɪˡWekgƇNy]I/޶˳ȶʵ]׾~"?Lm1 J{n|{ܾ{9qmk9J?KƓk7ޏ~IN=1^ԛq{==O'Byw{ cO>sDw_6 r 5x5i3J{>2GCH{1_i~O~bW?so^:Uwཎw7\U3/{loCf.}mz_q7~Og⏙G=c^_~`(DZS/O9ˉo;?3_ޮwһ0V9ݻd|zMto{<~ONdYZt?ZDFֱ>g񯒌' {E>uq |{||&m(mӯïHz>vZO{ѷe{Ρ4}i wyϭq7ط};K|dt=9>Hǁ|.gz^>{z__1>o+='\/R97^3}~2کNa\O;7g+eqHh˶;~>u}oԃu{"O"Ui<}dN8_ǃ}4 "ߨī1?rؑw_%v]8?Gh}yyWXsU.koG>G`*Gؽy{OsXʻIfҏگj: /lS9x涭~I%ٶ9Q+=}\u;]]U/$ձ>'o/>ΥX7sZǿt罴[㎤gl<}/CH1y8JsypQz'ƿO>L}RpQ>8%>s:wf=G;<&'~E?z9y<|ϸ w{;3#[os_8 t{=9O!qZ7; |߼*s٤)u8,ǽPzz!~)n?~Gg>gysw@ntT/zZk"}^c}D̗(.tz_N|=_d{7y.̓oI|Gz;}_헴rE/x>*!Ͻy!ƭ@;\oZҌ!Ѓ}HMzz>Sx/GޓO?1., }||j_U{{uɾxK98󉇥W!ivƎbmx;'u|o?8b=281m,zE$s#Y3zZ?"{{Q$ CoUX<3i@p6~)_mk~4su/ z<ŁWϢR]yx|IOo/S$ ^M=_Q='L>Ez0ݾHM~HH㳝Z.J>( y̼3*ȇ Bf?7_z> ZOo{P%x㶼}}Ny}cS|5{>y4WI~Ǘ<[7/B"};^˒`s[#UZƻ'=E瑌·qbx~o;{7"}jqGod8E`}Cy]lsi1n\;Wz%}9~c^"D/E ƹ"+^}]?.7ŋp|c9zb敀/ѮϠڿ+L|MuJ=}NqVi^)z7-D1>{^+G8~&}͗AJO3OƇsz_yw6Nm=G*.{$4uQ$Ϋw)8Czl]$ qk^CпhwQ/oO?ϋߋCo/S xߵ>Z?⾊wI1^'0x_r=_nI/`ډoļ]{ɱ~;H_([|ND¾f4~3n-u>ִ#0k4nh;z^"gh;ycC uӸPc&O{ϫ"2?&i}UPiiϟ>Ivu2Hԃy}4ϱJ㞝OyOg88EzgytՑ[b_~E?|Óz'D=Iدgu[^GdzgxyyQ}H"r-؏ƍgq`HcQKdsO!˛'H3ݒ6?hv] ގIz1^QdJ9m'&K>%S?Ƒq}$MqHocW߃q)xŻMoLLy2ԓ"98щgq-W5#^y~̗a2n狧!"zWqyqtMLyx?i}xo1/F2'~4|sdYv;H'n^~xkIr\ؑꓴy>{Oz܀?y>ߎG1.TAdC&}& C9sYAۓֱ49_jFZ<I.i~)ms"oV=#G$`~C}_A?p+=SwTA5^`\`0_Ð=+?-2O;ߓ߸;|w<6#-墳'iЋy=9;G{#7mZqF޴דߚr{ҽ/q_(8qq6nyI{e>uP;/qƼ+Rz׃J#{#E_>ow'qIck:|U߅z`7=22_U-̷+8ⱖJ_<|tǙ0'Z?UHƇn<.AOy:G<*il_>s0n,vs@/c'P~Ҭc/a)c?+uz2Oy>\-ٓ2;۱ԟz M;O$:+9xUԋu0.GyDž>w|u_M][< }"`ݾߥ}cWs[#OҞG'ֻ~և=Wsd`h[Xӓ\NiSoz}&}͇4.dqarSHI͜?F~Wy2}z~ii\~qr:IzOv1o|۪[c|3k.㮗mw<#ƅzJ' i?)l]1qN;'羏$q!Ǿ~~dwWy'VYN~Mtωo9~"'nN;޼s X%NcOS޿(.O/a|/EEAYϑ;ߤiׯw?*/6i#zSG}4>{>[ex/H;UU}}Ik?|HωG:Wya%?\S_1Y]ovI;ˠ~Ds!R3sm_1~߷y>awK ?$<$zGSǪ_}Uc}??omx(Q?6ߛD_]`ZE$/S=_ri%uvJOC]'q^qﴟơi_tn>ޓf}q{Yg{>e^ໍ'zQk~ͫ,/ii(ߏ[< }tzڟs\i-y~=_;yi f2;/*ڣeur}S){0O?oq ;4#{INx}!ho|:ۿTO)?XR?vCN8>e|yuI :92HeqyGogUggߙWYwQ~xӉwxo^̃dvE#I{]5 R>cn\/EN|_:ޔ=76na>|G3om\v^/~_\+xĉqzga^qs *g~yp=VOqI3{9z8419?Q>z8^k==u;5my}Կz<'}rZwߵ},.}_ =ޚO5 oq=- 79lowU&;xy|ƃ̣O=|a|il$nyUNq+,r*8pGw۸^:kuּy96(Oe ܏ߡ7JʽK>897(hI!ڮU7ɇOkk<Ws?7i  nD{_3w?zǢWIc>[8>,2;ŏnE&]>VKYy`VƗK/?Ҹwl#}kGEzc=+8;<ϝa_9>q>>(1DDsn 8cƑ>|㚮(sWVHA{HOƯy5=?)n13яyE/ڌܒ6&igfxf^K;_#*i}gt{z^̣`~gn\8jyViqh8/$8bn뿣_)nx_=ERDy{ӯ+N9ۉw||'W?4~8~8zzf>8yN~'?K@ۢ7 ;v3RxD 2ʣR>'1߲ͣx"WSK>8H$7c&vcKwGoPkM9ڟz!['?/'AG[|qx=L)^>vIW2N&=:W>q]o~6|'ϑ'~mxjvO)[mwos|[Ҷ{}}d{ͼ08OFiHC7{njzzLq#gEٯ׸IcM'sQ9vuyty^gרr0~wsd|3~/~gԯo9);zﴯX,d|z}{|_G&Ty^>ƇݮW=ߚw\[?ů#}y5[_+ھ}f\q\HFO~nGN@!97JGz_0nwz4yOK?|;$}zn^ۻ|Cr[s\3oJ?z2O{}~k޻e0>EbG.4?yW'*8=^Սۡ)oq{kO +<&MpwCo~w|yƟ?Ƈ}OU=w=[~/F?[߹mz(zݏU_/uHK㐒f_|7~g~^EҮ-%|i>ێ2ߙi1$ѻߢ77_z#]o;2^7f~cS]ڥH~K<#yN:<)AzȎ/?4oq_G2~Knǚ..>ԛ^#~bd׺z{dm%.8u7F[CFo/O}#dNiޝQI?'o6D?2^Ei$ƿ8"N&ʷNfw|$8۪i',v%C$x=x1zЎӹz3m'i~3ȯ iO)_-8˙o`\"i+zE5^iڗvg:2o%󸼩)}D;ڕqd dN1<ä%הg^~ϑCP˞nbqP]$xHړ I{ƞao>o6N;0N$TyU\#}v<4_|ț>'ˍ;^7&]G._Eoc[o~=x}o: =^|=O~WizҮ^Fybo`dcZi?Ɓ,ƥk3m׸ F}̇x=K/{4N#im\__ wcsTiqFgy=sܒsWkybiG=w\&iD/!]'budU?Y%~__V;kgw#@[[_T>gܤ8;ű$ϩ\IGGd2&?ywm3.&qg>?7\'%Xs#3r|w}Oc9(e;2N|gm''aKge"Do}q>=*o\;H8'1OҌCo8qΟ̛@?com.gMv]!n>%}i}da=6?|Aodmcע>#c\( K3rY_$?O߬;?~W7iqK::S"v7^˼<-=A)1zG"'5xκh?vu{]2NWe_d]Jߞ&]>Pؗy 2nq`8wp8<;q9'#|g&f>7(#)ΐgIr;VWHt_ӱJ~ygdxVI'zr,/sY?R>AӺ8B),o뾾{U g~ǸK650i>nIW>ĸa<4![Ƴ[۪Wq}WC3{W>ybN1gD!zx6˺ɇٸt ZO5s'_K2nZ D/(zz9̫[݄o>S*g}܁z=iwG4_Ը!GHg=b{^#=9oz^JxSm.Iǎmq8Svny A]Iێ{sJ9Vۯ$>YC'>y~'i6H)NqmEӺ}4 {t@7ߙD{_#!.IO8жCUtϾͼS~t_ʄp*=NMuҸC";痿s$|} }'Ai'&dx+r~gi[q|=쫾_7σ)'/1l>om0ڼK$m 1~^ ?J7={s煍?xIrYaӏ|ӹ\dM~/i<{:~=Na,L{}-7iq- D=?'^ ⾦}iGV)<;cXCCUץ~m|zt>L(b4{y߸> ӼJx}P?{θ8q559rڕ)gǼx/J؟5 %Z/Cng"їx;.Bctz$x$x/ϙ_㎵ӹy[_P]?{zR>Lş.ʡ[$o8zqU)g|qSۥџv/6 i?Xdޛ3k<ռ>ʷ_jzO=]UWI}|?sۅ|u?%q`=Y=U"G*Fou3n}8|B{_zO,8b=D2?];~e> g5_h^owӋK;yxǪw׍}cӘ͹^H ^zB:Ҽ2'.^ [}OG}:V}{_~~&\-8z~S9݇#oez~r=\Ϗ[ }/}ڏzۛxLz>%}jW{8[uGo|]8?(9>8楣#zMx;ҵ6>gqnyi8)g~,z8>y>AK=JۤNwϖOTqD3pS}keM>e|=ӿo4}_+{~>0> xGGG6uo7>~qwv*2:?U96羭mǪ5|Qyݱůﯕoq~q{}wZ|>9lqiݼwCKg}I9+?V=mo,9we%L|q0=+{HD9?!ЮmrP2cZo44n5]$~Vy`ȼz縯Ǥi?";p{E_z;|j?E_@?}"_ޟέl0lW=}r!'kX7@ho uUx_Q|*iϒ|\4uc1<'by n=kK~zE?g: i^y3_p+A:^,i*ƭrZ񶤽o^}N}3a5^/r赯><~r Eymym?G/~yoWOIEx3s[㰝ڋƇ|gPθ׏ܼ]퉗I4c\0o;+αݞ;,|zIݤ52Oss|S=>OsCq蝴 ׸HcaFO?b]`ݎU_Ϝp|}%K:a;u8qtyA3yd'^~o,mv<ӮǕq6q}'t;YK#t$;\|]Ei:i^ W:HͼuԓyuğI>)'=&m;_0~h|{}ӽ{(wVY~CoL9=9{5^}7~#i~LqI9鿺|K;P^ ]Tޏy7iڿ _x|v'ϫx{g?Ǫ'܇}#^ru<W} y䇔caaA_3a{fI%öʏ?sp8%l|)YޟClRθ;鏤x6&E}x:wuXԓww/?{}GwJӱ>=wܝqCƛ<=I1K~Gaa}7i'O}Tzޓw_^1 /xt'5M89~|A8BڟBm'z ?v3x4~5MA{e$~붾~igxw3GqS,=咦2/'yi+G_laG>F0νې>_vqc+m[ff|yj>ݮ?W(;d1Φ{wuN8 ߍܷUy=51vd$|~d}?O6}H猃RE~O:K>Ey׻oAǪNXNo,NzFϼ9߼۱JaGu?>?OI^U񧖶>R># ?4|9 U%GDboy8a~㋚'HƵϩm2>ѳz'8% v{3mwQ;x?HpEnzϭ71??t㧬g>?U߿O=q'5{v鏼>{_e!2/iWq"'G)"z<%]SW9=Y_:^>Hp<z?ֿ\dqIWcپGTHyOƱ; HIx27*W%iph5]w5|Joм=㝶Y{~x༤35{GXƯ2niS>=:b\v ٯ>y£X3~Sm{ݒv{6z_O:vn4>`i7#4i1W+Q/sݩܴ>gW9N<^l$Doۅ8OQ>ƫzx\X/ޮlIG}ץԊ;cci\׾G`c=%A;e;Hpu{aoI`4@;89~m;o$Tcͧ_*''CZO/1NP=\zWx"!_O$m<zG y^I?|w>Oyy&^)3/}G?%?Y;נqۏ_%]^^ҍz};>_y߀t>kB+>º?-SהO9H3^i/&ɹ|p펿COՋ{Wf?c:N`[-$I"RFyc~o.hLJuNJw=q->{0,YW"{ϞT~}.\Q)^I)r= џnyEz__9;~}tW|Yo7oKqRѻ!>:b{炎7=I~Kd**'v,8?K^8_b^#io[edиҤYwߏBk8=f=qCP_;l Iq$±I}<-ⴿج?~_6:Ց)8*V}ýnI?YoٸHXG5yƕ6Ǜ9dE8b73B? l?7gć̏u;"i]HZXq.4?EW}zޑ=*_9k$s}7<ر˞4)ļ~r8H CWz(!sxC3/*S4/xϿo ~۟wU軭xm0 tܑ}/qpKz(W/?=/=G:_$)zd{ԣu޳'xe_GoXN+P}')oL>>i<ƫEy^UEccߧcx ^_+o}o*྾`x}?ByuyE61ύ3o}noy3/R>G?)Uy[I } z<ҿ<|{zOy׿Oy!k3N'NyJmg||>ǚ_ތW=g\<:/N>۪ s+~F71?~C ng~^>z=%e;~K|}8a';4%N~pKy-OPkvmp^n_ǹ{[߇}T|HG+]?k}=w;ٿ-Ά^ws7$e\9vyiS>ͱ~$s<zcg|?=h=7d^Iiл~j$ =L<Ѯc绌kyV;󰼅{Ntmaq_k>6<#mj_oj^'!/&q'3c| I״ۣ"U>o't|{ēcIySo|^]$8~0֓q8e37_y5F6 `o*^ʺzN;/G'=E<959Tc>w~?%wA7?k}zIP3d=}>q^QZO^G3կN9'o}l'#ɼr*vcoCHp1%%=GLzG&t}}Y/>?pk$%ź|%y[%z${7:c]?~?X~"y{W|<_#{_>SJ{kguI>_\ץjIE*u[%MGo[=z=s{+|\;WHb"{nO; ߒ(߷=vtv~qA?C{._~v7~s7}GσUM}"'WI}{G$U?kпGaaMECšK-W|8Y 9ۼϮ'g\_V9w0_NSȉi\sdy?w4V\)NEH;|wF~"4xQ 0/K-A5[.|5.semoq)#'txm-s~/=a0.|M_3o}r']j==Пq*|ยsH/9˧J>uؼ~_;_ɷ3|4/)]s\/657xz>״3wvK~GAo>ho3=D2>~^!s܄Ҏ9>۞_*IPy_1qbոޓU>/ҼC$*˻}V9\yG>;>_>QnzoEo8ډyX?=4_L}G2 ۋ79S|Ӷ}GSƁ=_i+=sq!4D* zDbO?H=iu?)~98k;ѧ8Cҵ%'hc<˼{ty)W z_D}H΃ͧ1q >~7xꏿ47!͟j'ϑr߄|Qį?w:r:}mЯ'n/)zN3>ϕ}%=qƹLJq-?7tj_윞kQ>ͺɺB=.ƍq(/9qWܬtG)I_<`My}~]K<@:ƿWt:sߣu<H}=7Nx }3>eaz:UgbWWpS92 =|qUʛ¸1~b>㤺w /ǧ}9ǣ'+Ii'>?u9yףz"%#_#i#}iH^Ͻo+#ﶧW'կqyy[)XG~qR)iaF𢡊~GXx=-.wv58zxN ܕ~z'r>o2}ybo>@pf_Y+ͅ?I/ځY>q_ey;ƍZOd9&wUƵeeCY9v:z]؇=iƯ-;##Rc^OP9f\HY;g/+xÄ3^0۷{y8X>8K|~[<ӼVZ<Ɓ&]9wkhjgyW=}/Cr##iw}>Icx\=уqM_xkB;t|$rƙxa+GJH(4>{/kƕ9E;lH桹W=c}n\ ?i$͸ō9wuFy/?ww$Ec>*5 }}ߙY_#}̋9~<߷UI{3nNlOx^{C)wd$ٷ˛)gOqqէxCq'ˢ$~=<ǥy;x75^%w_{N#{wOy+8b\ïg8cK=T=#/κNc1>׭ޤ}e)v~YG'm|̸MSގ>EُD:.t}>I=ן^ /8?;Ɓ.zNZ{F_kd?wke/g/푏CeC?!xσoCsfQ>ʛIyޟ/,rߎw+:nCSry ]/]'A9O8~Ƹ{/ }^)P?oɷ?1f%{~4^kϻFb՞Lt^ǽۡ~mhUg=B?4c>x3>l 9VNG-/f[kwI%9ތ4z:gx#81z_Ӡ?G ?3"~}DӺ!p=z.KkҌ#S|d{vPkxξO5nB\%/%M.X6Rñy̧*x*ONҼx78Py7.*YgX%'z1\7ەwׄ}<~;opz;մO.΀,}N~.I~~G?;va0=#FOo*KS-i Wi>==ύS>v0ue.xD.d|qXozw.1pOS鶻yKCWs}h!?4_/(2c||:E#$^igݸEO|՞츏>Dz]n->Ez,2i9 d?32>="9)'|ƸAIIk~G{#4_i_"UӞ7cM18&};V;Pig/kͼ ǩ'42Kzsz~@OfG:ִ|};>'g|o7o|XOƱ(䳮~zp_%:/劣̏7˾\dL=Ϣ_YPǝq\^19=u݄\5걭xNP|羖kcg%ÉSq$ÉGTO;COa.EyGWM$8y` }9Hs=<0d|gr2_)|3߿D:W|ƾD>wG?GD}߽~ {m=7L}^b(Ky$Ovg~޾;w\5oGO3s{Sʁv{}ӏkz=3D99 S;yK9Wq^oo{&;vq8Ʒ7'8ք.>9{ɺbքS/q'g:x)xBo({l_1n^-}l$u}<.Ci#<wwzo1?[X5|<}}エc~;ݷ{q[~f'7Oj_'3d5}O'|H)_"gvU.W|7I֝zxؙ߼7̸kyC}THϧy y0n|d{xSs;ǗyϦܶJgp#Lviߎt>8Sx~ BץHp'ǟ!zы;gl۾3ԸNgIʷ'wKXox>匏bAMًr;_}vCUvtz$M5'q߿E1mg=m?{1*.֋eKsrG4 Y~_[-ﳟk}'IYzޝ8~MoC'Hmp潙f/OoO3OOoTqi\ IG[^/RO~.7q?PF߃c~GG4ޑKQ5KNq!D{qxڛvF?|M| 'XhgCle3_#{.ẓ2~mωc~>Fҿ艽e{߬_|.巵V~@i^>/1>a|x_-]KJ2}cG9yC0?%/׸#qq08/>ViGӑ}Okͧ>oi=T/OƯFOw9+!kJqO$ɿHo~~a/^P?QmG1~CTϢg!s^#zw%/#?}<'RR'7o|>g#?7|W'kx?z)anW)|Ce<>=ǼoG·oH"gXI$:sZowu̟Au1q߲tҎ/̿|@?n潎A]ƭOTͿ4nky"}ltk9Vy:mϭwO秌4~qKAw7_z;N|Qu8O> 1NnyZ? *=.wk|}N4>cKc?LM%W9$J<ɼB8\;o"P>i? qI_uuZS۟~1: Ӽ~z5ibZ9ω#=gu(?jO|_eȞ< }^qo#ևz*_˓~,_9;u87x-no5n+~p_DGL};;(b7{~4OOM=|I~ʿw擘oܸ5ȶo@_IgO\~S?pZ).xY}o͌I%_Nas›w瓤JG޴ ;v7]L1Ow]{ʳ/|Kdo>K?iO{̇xgG_άSy;UOxv%Er~6/v Nxq|>gU_SG3qp{[uz^)GHǩ7>KqVIy󈬏m+W?ȯIO5YO_WG2ռ5.s76O<Hݏi\M|\~;ٌX3uI$󢌯6g[ǹ{aTO<7߄WN8]"=;??HyПs@w^}S-_&v0uix]'4^{>kI+IA?g[K?k'i_uv}~;i2)3wOJP?e3ʟ96߄4|\uI%.zsXe$ܴˣoGg7lF/ztlH(>`>~FoH3{ SO$NxiG@o}O|(~O9yw|m=7Ϡq/9Oʃ\qT*dP4g\su ;. >Rz5a4kw2HƯw'"4NX3.x sO/@w'H})}}?_8~фoeLwAlwwOw|nzWyPzzIq튾c|1?>ᅟxx5Ҍ+aKKSѳz_}?ih}^eޒ?FFk-?ŭ>/?1H:tכu;^_wǏg\k_o_P||_}/g[obo4QAd>(g.bbDyx7Sϑ!i֡i~ii|LJM#_?=~hk$OMǧՎJggFKy}kÿ8w(i|!voyTsQ[q9H뽍S>4^h f 3_8a~FMxv\z~;V+WKƼ =n屩\<|85O|{_Ov~y>]n?Gڕ~rϙ=^Z7b<8^c}F:Azݥ#0븗*d* 7I5<8oLHH=~{b|<3WT @Sị8Ծ,ƅ=M{ޓy~?:칔/wi?4/v4xL9qi8 ϧwwe?3It?9i3bH}KqbۑyQ)8y zٟ Yo=uDOOPO4;">"w+o'Ƴ5$i%-~lۨG'%͸af0qP/v]xd]sc]`w0z3U qR˻_2lށe8)yL~qO}ףԣ3)O?zG>>ǚ.W;f>ž7Cz?z{7sB ~!o2F?wSpۣ7}A ~HGX}'*w|q s?~U?xG=&øYMq%syN}0Yг~ykˣqG9SiKgB,.ߩw)k2[ʱ`o*7Hs3ŕ"oc|]/OD=,^O}Dzwy-'E§/W~vzyE_Jٯ7O9v?KbM>D/o|$'M{q_$; G'cʃS+|Gơ|_]>ҷ&}g_ߙ<MM۝k1_|G!>7/ӧZXwA_$xC}Ky7~}yyo]_yRuFﱴƭ=Prũqg]gfW|Oַ^ZI74}޺x2y#7Kk<~>=őuwU')NU(M9vﶦx:n=x\P`ܣu?b;q\&<I_$ dyH-͞[`\^x4q=H~a~EI\pQ)?@g^=׺]??HmI=qwd^|b/J{KϿos9q>Q>޿Iz]hSzy_+.o[}IUV0g~K$vGHWgvٶg{{m F/m?=DK9}w|>h;soٓ~z{տtH9?Ak$vTc}n<6;[;slgn8{]y>Ow6Ճzz='OaүU.鮓yz9ƹ;}~rHIxS~.m'ϭFXNqYK7*H纭}~r*g~0DZLv`To>iq'>Wyl=%q\~H.zDmz7Nv,<~}i*4k甾E=i猻m[%auq MY_8|!Ms=wly|s9gڞ8gi\ O}<?}t|Z/"=ɟpb>4m0N~%]zI_UW9ϱg|9YW}n)X|{=4z_|Cn#i77㸕0їvƍm[%ۼb?/쑾|<9qnSJ3=7SlwOt>}|x/f{Մ6/sڅv31YW}j}jHq}q|4{]˿kNno.ƅw]V_gy}C>_~·;<#.z[x{Ҟv;e>?9m<*}~&II>ƵGM}g9^w>=vڷ6-<d0ÍEz;exJyL|Ozz7|z\mKi#_o5/m?a^\;5=I::o#;x^0oGa8G>>]#9^)oMx[s2̻ioN<siW 05or?3[R/6nqµUG1ԄgZ/yʼ+?۪7v?73F< \p: z?<6]^Mq?۷N۞u؟X=/tqD?8~l:4?xb|۱uyx c'^}gv7m^A}~L;NdD?x]:{n^9M?y6HYy F=7} HE>U%vΥC+NzNǕjg?_|y%ҼҷB~`jC>A;xc~ye>>DZd9]^D_'yHo;yܟӼt=\?GyLMqQ/ro5?χ<+|9؞`ߜi\v>C]$m^xw*ә "ߊ~͇D-|dNOz{|Nh>,ya}IN~gi?hjKJ2O3'IIo˿w.;3N^__rސ#wܢϱz=޷A{俬Oa>έoKS9r]Hy~6/!rG}qǎ󩞖ivKov5~}ON{zJ7볭Pa2.*OJos=N\N^>d=9_$OBwqo;~m,e+/Ki}}:GO}^_{E?dw~S={ShwƋk>=?P)x^Ǒm>v׼$to37|//p2["p$ꇾQ~ jĶJ}81ߛ7;i#U?ER?K+J{0|oq#K7.w i~DDƹy~q#E﬇}w{x]ȩ]<=.ƫ>'O3]ga}-d_pO<$4^CyOcEuF;z%ͼWnn?;Ņ\ɼp<-z@=7w1OT!;$>x»Omog7>a~6^:z2|p] l[Gֿi?ՠgL8%'WƵ9^՛L.d|gqOi~L9?"Q迯OvXy4RZ}g3u|PA}q̸q|)p[uVQ3/~4ѸH#e]c\};y?s~>|)N3j|/c½~}_:zNvg,7~$<;cO:>e?O!۾y߱1ycƇowؙ⌦o`|OHDxڦzgvQyl?9\o&ؿNZ3_8ǿ]]ǽ!}??Hs)u/zz }ބ&8TqZm=IHKXe}v|>4<~6^jIsƭlj9ENDg]Ϸb7IA/F}z2eyl/yߢmZk3ĥǰo؟x ?4sڟcUD^#;>K/'I9+Dd!'/N7^dގWvwl}8P ~7ԫx˱DI;|zU綶]~G9̟:*sXqq'w}[wyt;!}k^N +*oEf\_vU?%^WQv;E=֟z??+O\%;}ƛۇhWk#MqV|j?CO<.@,7j~q.9j^xoͼ%WK?dߗ&^'6|׸{$!Eq1㋤U+zҮޗm7cߤoQu~}'?-<7>q vIc/c'w$z[?DNaS#/Ly5O$ƁH>?(c#/o7.]>HƷq9ՎS4oG\(Oq_w}> G88TS>6o =i紷_4q߬Oi|uvW~eީq|۳vD?pMև9ϱr|q֓S5ȸq0Q^6.} >4v}ۮmRٿfp{NVޮ6km?޿7aREo]v'Y_Ҏ?W*z0X~|OKߘw]?Sg_|U.k.iSz%_Ѯ֟9xC>e=0IG7?V99ex/ɎmluÒz>zm~58y[{k8Ŧ6S{Lx2~|cAuv`E>vxCȑW3'Nn?yrOo]>u6nG5zsH+Ho|c?ԗyV<&R9 ͧ6NB;I1-|`K`=.iMпyoqHe}Nb;Bț-o]%G#yy=x>ϙOBU[ppԫq_yNyk8 ۏ]Q?8[[s Ю;Cٸc?ތ?=#|!|K#;|c}yv=V}mzL8PˠD/NH&@&;"^O~5~}׼?|6ʸ:rW~aS\7{?}ۛ(_Xv?{[ޙ-=qmkx1ʰg2oe;w3j3e^6|µɟt?㞎xq,9.9L~ӹu {).N-K?k{㙇1wIϑXϩc{>z=IH'wcrLuٝ6EQ:EREQ"-eYVeYng^Zn~`c0<p>A~|Q0BB!b"Vfg[Ċ#V[qwp<';vO+~yuMGJ^Tq=m?h)~hR|̥}{}^N6(Zwj 6]d7e1G3칮s{o+>:{c?o1 fJy;|ngs'ol9ۯ[z>7_~}AuYהY͠_ _?=z)_ۃTסloOS8ݞrm]wTpTY8/tP8H 9˓8gzd'sۧoe{={uoŷ_X j^g>q^PU}AF=Ky)Ol|+약 ;X?~Ǒz;qkx]q_O#S8w|=xʋA:cKd{:_q{TqZ}}+_t*ϸg㰿Ex'.=/m$hy?!wK;osq-?䯌~ j? \k'WwA'+yA_zܩ!}1@(ݭ1)x]Mws1_m_FUu\SO|>#BeLyDZ^Y3~_><5{CzB +ΝaOGq'*.x!vqA|v)q=pO؏Wzp0xV8L'ǹq\w9oG?yn7ZO0v\iรn_9~=Oma;fjl>g~65w<^˸bEέ:A'=~z}SGd=uCT8_LIj=?Vq>j*~q뜛U8Z}*Ϩ\bu۹Qw.>t 1tG,/EU͗{>9`­Y] yw|3Ӡ؇?`=a1mDי/ɳ''Ewqr uםqQM_0(8vθr߱zۿżMmPj=yq._0(ߗ߯z<.(J_!7A]4xv@qH_'A|}gq ]R~㌗noeˡKyvܛc_h#/qjk<z8]/ҦƟop^EwDžW=9u?Z]vob|G?|b3jq*Pu Ǚ{VTzqw+m9+~F>rĤv׉:Ww~D/.!#o;/h7 _|I2|*|w /_o?&!+q{>ֹ>~~w~W1O:WY_w#ƫ}~F{;UA:p Ν G^/[l_c|ۘoo8qx:cy'''z렻Q K7*{;㮃2dkaFl}q/To{qkn.1~PS!oa^_X½m9f Wzd;N)^=Ul/}?]~iEz\~[m.yom <_8[#uix;_Vg|/c]oI λHhGCWĕDɳگW{O me}5A^WINw?!|O u}Kq%Az,wӋ_ɑK+K?F_Mx?  a0?/D r 7x _ex;eMpmP=~}^§~ۚZm jn2^|n?lc96]Ў'~/rlφ#b;Lyyml]xymw\??s5og]_?7ynx[^=lGR.YWPب\k{Fza;Ϸ=m只߻ͿI3S/L[>U~5ۭ?om[=<* [π:/r8 ޷}{x^ÿAgyWkmf-\Ey[sPZA{o_TqgVUq^xǕvljnbv}_Q~ qeW 8EvjŽEW#i}[Q~9n*/U@^WQK0ǑUNycJ?_[>+|Q_~8ڃ3Q7;z}ym=OkA.up?l:7^`#O)ә~׆v¯U;AǁV~pJy%/)npCMV;v+$(7^C. _YB+;Gփ0l9>c?(|U~&o=*k9G_ů]Ǚоkk Z-ic3=?gYwqe;wݯPƝi?/m; y9+<|8Πί~K/GY}gw; ̓)ꚂxyR_:w[Q{Y-~^S/wf9nvn[wFqr>ؾ`⸎ރOQs/]o :a]d1~h/osg#~^tϸԇ|Tt[gygyq$?b#͏}wiWgb;}^=6lڈZn<ޏ#a.µӎ#j >09ݞ{\?oC_eވzc1oot? k[;jŹtܯ?Wq}Qvz3/k׉[ZU*; >sbec<0޽/qe=p83Y??gmsoY?֏Lqy*|vB &;\1y0)wL+.dn%fW\ j{LJƶqjFW\U^Qeks^c=Cγ;08.C{TR_=rP>83ߌ7~?xP G+hwqjG~ruM{FP۽';H ~.-g5ο{؋zɿ?q݊}9>,//!_ |Ϯߘo|]J;f=OTssuMخ5@\x?!Goh=0m`<9sz~vAuWCMv7]qz^vƃƅcVPK`x~kq}*njwỺvxvy][=#.<xlϰ}wz?x?q|1:>Kc)޳Wj3Oω1Owmo>Po;Nq_~leWUi_gy<չl {B;Ty^6qd/oUޫOl`;;NuI^Ou/ÊX>Bm'b5e]>f=vR]8_r??{;Ṡ| f1ţlܩ]hAG|:v 584- G4[y'U8i\OG>ho4ߎ'?qaVwnʮR=N,hj|*\=y>v8ۻxMCTuyOKೲ> ^Ǒ]c} z_2 3 WWqs82؎l9ַ?ziGώv0Έž:mqb(/88g<8Rm? m|θm5a=4lpޞI 9.q^[ܞSPIn;/j|k ݞH1]\sw |F/|w?^p%|N0(z04=;jG{89ʞVX?MnU?ss7xXsh8)?j;v㰮D9Uܠw/ x|ǓTJݮGa `;y}+A"Ewhr?xI@|^x;g~oxJO<2헩TruS9}/Rj7o/j{Τ_c\x,mzyϸ /ͷΩosS$vῊCq]{8}oGYWl>^oG?zg]O[wZrw{>|lGPqr񡞣x)a|~S;rG.:y3k5i?QeO1^h#a~'hwю>c;Q}c.~>,9N~N= ;uZ1*;uO#/-:ʿ~Jz_/㡏tvO|nDj}ú _|i{,W;/ǝ;v9vtσJV]XOɡ_uw\uu6>!;N)rR^Vd?;zρy 7?,߿5N^'nCNy೴_?E<ɳ5Ԡqo4Bi|sħuӸ*:^vƍ5'!|/c;TlN8ۮ?v8;/ڎ>O??W=.FG|^8kGy(:gQ۫`X|~HoU~Uv@olwRU^ۮڷ :]qTz@/,Gunv3;&8EstuUz}D=Mnݶ3>8w| :붛Vv9ƕ㑹m>Umi~bRU~W\x_8Rm^7A߹~)/~>:I=g;쥥^>Rě7bD|F>/W]śDg7~yauu/Dk 3}?U]l߶b~~=1νI_CߥoOGǺ<z^ϯ^dGa|1α?o;{&/4m2ϭ[sA/G~Bq^}ٛ>|z᷊cۈڿ ecs<"^ٮGyWW~ G3ݍxs&GUy@^o9謹3tRQ'Kqj^:LUc=v5gRţ8ٮfd j?I__eB}i|uzq^b=t|T߱>8`q6SXmPE;o}=8Qh~ߕ_[ſW/>iܶ uW#TBUvs(|罯MgOQvVqA;=orew=n'?)v{:ߏ ۳{Y mݿ^]S&8B!>P3ӿ7/^E7oW񜿓IZ/8: J>z/7(㣻~xz'يz}qH;i=Q]׾^\vR[O_[/n.w=?e:̸{c_uS;.M0=n,q'w+ )]ޏ[sx 8*=7PrxkqwuROS*q[d؟R˃ӶjƗoƽl<u:rv/W{~Ǭ8߿}lݷLvQ7#d2 |}{\Gz<8==9';[Mq߇lu@iPyTs@]jQTz`埧c$gm^xK|2u^59q )g}ܪ^Qg;~sVZ'm/ל`9Vc&P!7*{f%RX׭w~})>4;޵뷭xOkx}8qBqN;~'MDbd_{u'Y>y>xD+{33pkdzi_r+{+}?=bM軞g3ŧ|*n.Bvۣyy/4+NxD1n??ǫWlT㎬zt"jg{:pߴ*|*dzX׍OBXO:Py&2_CV~N{hA~1@y[]~c\V< nRk7?x}ەZ?=_]ȱ_z>'Dm2quߧ핝~pgd~Gc!/OjsN;u^ǥ 8?+lվKyp֣l߶v.˟j!ǙxSrpOh%. >e-}ySqhC{{@oBOy>[npv ۏs̃sg߼V#|㓐S/%>ˍ)qB?yAE5?xQ؞#{iKs=pv.w)M+{y}~K#/`>3~ǑG;Wrȡs5]y2~1_W3vAO#^:Dq12/yi1 Z?8?EiSCo\m9 ?eĹKzi1^ﯩ]^ka >|2>4Nx3-c7eTya?(8oS}UOunRXGlw3‡_zzV_9[?u;sqWEmaq(zP/k3g#^|>q8R%zqlwoDӂ~σh/ jO~e݁^߽y=>w[mݕ~:uo ~=~qfg'p9qA3GnD+}w>ү= '_T;_E"ю\˲~CC [ȫpjGq_rbҷ_ON#U;_*˗*ΛsKXgj߽cb\! Au=}P*|zvu{(쇟\׫qo4~[zBi#|{ݨufrvm^=ܷfe#a|GV ==>1󋜗o;*+ozUvy]G3|7ۥu2.P~lWs']GUHOq͎p}_?u+si<A?^cn MrmAǘoˍb|n<_U~#zT+A'MqIyejyP݇+A~jWUVNS}s+u{W/ǩ9yw޿ڷ}S#jqTq|߸xؔ})8#5ў9. j}Cqq_My|nQliܰ~j8S;ʸ\_]V~s쇱?q)nUFԸn^K~7ڧy:Ws^޹e|cߥ{|lPO̧A0C"zU=@CWg-O99 nwh#=Z Tq>O̿{[os-1.?"~qUN8rc{XqO۩n߁{7.rzPg?{ o]g[A+{*=}vX^Uq8?x=7y/z}q;- 3=*h[r;:xFY.o>G/9?Wqq} j<|=7ǹR9=9hCR^W&|Fx 0Ny\?is/ٟ8]h8^X38:Opk^S_~OuwL?PKyϟ|--/+z ~^Nʭ1Ռ \8_㱝jʫcuv%/?̸xq->wn{=]y^8~Eq/vY/|VCW~}#iW_Z{PEԾ^ƹ/}qH7J{E|9nM]v6AӶ9߁#8~+Wu}xGj^ÿc+O}qcGR!v*}۠=&(zܬ9~?]/!|qz`U8-_Ob=v3Nz~~9WlwNg ö~W8x>}}}?s뵌WSO_שvj-SG/` +3ۛl/=~fi;$|;j78Nv+sIv9}#^}]^Xo*i/;nzB/[7'Ly$mg{KTc_[?f}mr\}iUv]w]M9+|w{MyM5qtW6gKT)L q 8.O*xse|hg}=<X':vm?x+yާ|?g=5_x#hU>wM߯g^ރ(\x]J{Wk~ʧ'xyxGb?+/i&{$}~DDž\Ǽ/bwaouzkoԬ_G~Dz5ßhegpNK?{[q6;١Ge{z~r}~R{Yw>)O|Wg?ǁV?cp<1x-IN\s]pگ#?|a|-~vӎ=w1z,ϭw:;x>> ~]?_rh$hm?ץxwd~+q&q\D6>< |t|E/l|mE=WxNJoq!e=^Eon3}⼲UAAm7/V^Yzcq/\gC.2|çR iw7lڌO# j;]׋G7^oKdr-o^m}Sqs]o66g|؎^~z1(OӎӨ‌w۠U~e/rVSaݷb@qn{ו) Ν_^]S sDSzpuǝu39>wԸx!{{9|wg>W~3_8qu{\Ὴ[T{|3ߌ[i_ *WÝ8#!8~dzO=پx.=lc\x aͯܜ6m~voE=v8޳AǑו?~2Qy;hTWyYO>z_l$ ͧm?w\:n׺< Y>V=ӾQZqXP8z:olw<-CDn[wp^"dH9Ю>CG|moq;R/k;T%׽@5znM{.v)G%৲wsN+/z ix+@1k;wPVet\"olgT~(n=վ ܯ3]]󣌣ǡվo0ř}vxpqaq>!o~^{|V~QU+vC?q0.w)X9q? ^xo|w<ޗy_̯b~|ruMO_O㽟xsQn'*ޫEϣs?m˱vicNxo#^Xgϫ5-)va;_`'~Vv&_Ǒo〪x;YO_{gю۠=^ῊG|p!qn{ǁj|)soTzO[:gC9?zΓvV|?u98Hm7sQ?oA'O)SǛjٟj#tٞYl7Otv i;u$Tٍ+; ׫}l_qy]e'sg;KKx#ǷX~mDmgo u^.8\W_oECg| R Pq\N}PaNX #1W;(~0%vu1λs}ݏ]5{=&(ɸUd_}m,@9ƑH7KAoCٿI;ҿSd˧vn=jI25y4Ko}bx omyR򓗿waPǝVkX[zSݮc?s#zIWq~)U|TP+Xot5cH ;nv?{ո4bz;zoUOVTkjN+_8>L?p<.ٙl|~vT?+9^zU~۷*8)㌞_sʽ$O{֋q>VetgK?sgg}c6R8_ Oዠ}W;x]=8R<x}>ֹ} ~̞O|79=q<yb:|wj^)^ߑ;OHW?xVfD_a=]=~*{y9A-_lzq킎gq`ՏA~"=>z~AmuuxduNzWWq[lO188y3?wj\'<58{r^Re?ޙGJ=&\nU!wZ~|ODmu~xկY:n8/ yk3.lJ{q'Qn8s{>nu6>{>L;Zxj}E|rׅW(8>*6~3v|;!/x~+2W:wBt6hd;W?ܩߏc;ij_zx*'(Z{V);^QZ\xWqN 绠KqWq^ Gx|; 糠YPw_2Ny9w<=ׇq[,{:yF#8?|\_i/sn.dG.Rݷ}K?~o JV0tȼ48 zcCg[QUe*vdU<ǻ_8>N_|wОCE{5UOUP:~v)g:~;Ǖ?gz({ Z'Uzy_Eϥ~L,'*+6a]>}a;V~> %ǻ>rq3[jY~1~} ;jijuϱ—C)̳/fc;v2sgkz}x* Oϣ~^a Gt0>Ϲq\_k}z? !o{\GPZ.)ya%Q_'39=,wyOydn|g]\8爧6ϼ󠓿>:.*d8/I<#?o*O:y4^;N1E;G!lOƿ@{}En9yoEŹ>g?>z;]+bs7A-<=DMЯ Jgq^"oihqﻸy1Ҳʿ0~^T6v6ݷyFs=~W-e6|lV㩨̯nǑr<ӍytwVU^KW>wd<8/۟*?%&>\*{Y9^Un6w8=^vʞq86蟕=u}FZiqlo߷/ێm;eg 5Ψ쐶u?al/ |6R3oWm7YqOew=8vfŗMZP:f?*׭Uć텶&ow>]]S*y۳+~Sz[G_8kς՜pj|Nо~:ߠ\c9{~q8`ar=^Kt*vY/lEKX{cj; 7AmW[/]|k[ݔsܘB+gj1 Hvlym?㍪v/wl1w^ٮx!8 ~ߠmظn]h$C^կ9^`rygc;Q= `P.h86>[mϫw'zGu E쇱ߥzrgLcb|Z^sq;-]w|ۻ^s*aynvxj.wA+HgҾ~uG8؞nsރ3oI> *=,W&ķ0o~r8%yhUwnFG}N>^]Ўú=xgYz>oς/o㬏SVojW#ģuﷂ(\\s;a*z9>A*婞~: }%_[=_S;NdzJ=HY'x3.*<@lscWtcl=ʱIAmϥ=/Ɲqdza~_[Q< ]j&==ͷe?|z=9zpվ"j_*DC\GQAS@uy/}yעTv.{:vPx_nG;ԸO'W>XNg\8Nc[z~8b܁?~y5w:8뵕=Yo<ʾqøq|K/dǕq Yhw{[ƷO[<ߙ~Cnr㪊8nV]9.yn?2GSޔyq{v|<6RvqlǔF>mZP8XuK*+=RL{O\8I[z:+D{\^=|qq.88Ҏ=qW:7qpǕGyzz^m~5/XZ񶦎:>;/>O,m?޳5>݉8XmPVq87j:?7ۭ$emjDŽ&Jy_cjw3OytUߣDZ~}NjY1;5WR;g{MyU<)'1_Mqd>˟Vm[=_+(DF| Zɻ|?*?uqYW} ^qx}\S6? YZ/Xv%K,wjB*Ύq j<GתJCo3~6>~Izw>-,*b4][/~wh8o Z?>v*ޘa~)6(Zo:q>x=Øz1njAGg{0*~sʟWśWگܶ>5ŽsʻJnԠ)NY9(.KW#^U>|Hym,N/3_㼊zį~J==. .g?+TnoCOhO;-*>Mqj\5E;S8p^PY_w(9Z{TqWٞ 4}Wu-g}j:ZxpDǓ?e:~@A'|jLϻcsQ`=V:^G5MƟ18UJl~W|&ǯ.jǫq~mǩI Woe}qE*OSx9_ۛvr?;.[Us\/|J?}~XtzL}i8Rsl*ƛoSrqxAzއ]ghe#_^]i4;Ĺ _8 '%hmK`GbqWά~'G~>Smv Q;C=x*<@^b;qyU3Mq*uw0*To^v@;ި۷#.|;W3]A+=~nOw[YϫKq߹\1謁J=z|rA49HlMwTIxdO;|JЮ*.>yU;o~o2,xٿqփ<0?o(Vvn :]"q'kt^_Ƌ]+/TuT{XnTGS/ E^ۮq>ŏ~ʞb}FYJ}8Rŝ8_zZ7}ڸ_Wvv;/XO|7ߌ7򼮸΍Mg?MrCkzU}v}PrO ;Tz~?{?x8*~Rũya< O<9f;NE8/#pY?^(ޮ=ZEc[YN8ρ^yW/|Dx67<6ᮍ|{yP17zMA[qe#/#?S]ƿ7hgnq^GH/Sl?|nՏ^>Hv}*(CqJվv2zg~~x|N!W.x:nq"P~IA;`nyWq6^hkjwSlOpD;yEO|}^8n{܊_x&*+TU˞-Ǹ1| <+;Uy^v{8u\񒾸}Ua8GB׫Ѽ{s*uO%Z8s]CO] A;k8Ox ĝu۠8qaxK>md;~3Kw:nǮ?9|3h㋜1UDZby59^ɉ?*NysctN9otq.5eZ`QW 񜌳gv5{q_ }^`ױpcmz}5^xTܦhe߅ j/vƵDžS~5h"NesAgė1tw|'n[(r|j1w)Ϻixxkz~=~wMG7=_9wܝl?;qcnb\8^-owm=s1~y}jO?uDžֻs;99;/Qߡ?<rr<⏱u>8v*QUXC|Wٟ^JqYo˥xuMYlG8oymXgOR\g).s|S5?8&X۹ڎlvPsOjsƃ!QVqB燱Oh(gp{qquO2ާq|K+x8|hVֿn8}kƅ?sϩzey 'lR~M'V^?hW>EQ#jTvVg>8CUauT'c{|T}mqAnG%O?Sŕy*XTyY}7״C|ۿ~=Z.|^C㼯޽)8ig/>!xy"|:&(-w<;}/j{Ta\wןGy( m{#P{tn܉ZQbN_kZP]o<>] jYc9NqkNy۝lݲ: Kո|xZU/O: cǑ^MP%gǍQAv^n?vߛ8qqNc>Rǿ\j<]>}<e0O_ag!5Gf;q|X>iTvh7.(r;#\P 9㸤zwsճ?;{qf['cyl7ğDy8v]/W/t?!d<#w'޷u.ۿdGAlߏ>x _K;{B|#)x8CN+_|Any_=_]Sk=^!A޶^\?%Nfs>-oxCnŇ?m#{_Šx=QNqQA{ ~t%Bދoj}]?qNmسk7 &m*> ]?޿-^WY}q⒪ \.k~q|$8x?*ơEtrOd}|9ov?w+wr,he<|_:~?J=} [mq&?b=rviWeamr~ ڟ~>7_eJ{kyF2΍w&ρ#h볟_OGx8i#~NwGcAdo2m'&} xKqp=~P :;8_^7f/̇2.HipK5a7y`q# |:nWSrDDSJeK?S&oy1Cv(gEVz02mx_P^~%Ze0_7"g*~绞]28 ۹hGsm[?k߶q{?ip܆l|ŹNlW7q̂kېo}.ΫsgyP+ 6qn{%DخA?c;T~{뜛OuqP]+3Ӹp RN}PcC'Az}+/ss|F;%aUm(iw3a[=P/͍+}ھwv8r7(_R֛_M4?}o;yŶkx^Ϧrǩ?.9j킼x7̧wun ~/cb;~/ߌ .k=JwxM?w}걟ڗu>z`.Iu@Ǎ8vks??:?>l(Թ^*{|Oz?%}}V\7:ru6(8g{qOבznQh3nxs+Uş>}|gƧ탌5ٯAuvǑr9$Nq]/۠_VꎋXr5&\+{@o8ϫ}zscGg~>;}0Y8[rV3qn?=hفDuvm<O9>>ye'SKC^V>z|y\g}vk'*~b{/׷AG߅Sw؟O6snúl΃q|`;b?_v)yh_¯z^~9>xylEoLmL/l/OWwx.w7|G]q/!?=n_Y߱8jr'x>ۧr-7ÎR=86u^Nq*(?P~LOxD^զ8H;j# W9y75}8/WהpN|l\Ky]_:Slʭ?=Cۮ8GZ~G>%#Gmw\bz=G{<]P/)1O.F}ơP[/quOUS|}z?4Wn8wWuz5|b~y]}{Mu;8u!!׭_rָ=\:hǎwpe-ƇЮҏ]^MPWz?E!=߉y;kr-ga#.%J90_.GGq]~1麽'޳\GQs~GYe\9EzfqAiߝ󩼎۟maz g2]?i=w[?`;di]*?Mu\s΃2~mn{Ok?F_C><s=>AO kۛ*|7:?붇Wߙ?.U.Sq'N;rWzO8.~wЯ?}s+DZ3MPGkOS'x>{~\ׂ=EtqlWsUyaS //>CʓE~n;f? jO_:};_VI+qAe_wo8*cî;I5'kQnGq;ǭG~-(3Mq\w ;''j^6:<5Ovt~k~纝'΍[쿳]ȿdp>!v*LJv;z|̎twsw,O8Su+vxU~]ZEg],mw3N~]*>d} >l>3'8i{ܕ\4^U ؏q06n`?p*+7k{󸚮;^*vU'l1HWgo>s=;?W~%s^|WۛිϞU;\D[Qm#hOPm;)8j_* y=^A9o=N5 ,WzOl-)J]=lN+΅&ނ:n#+QAr08^jߩP] j[sE{'㉿KzE}rw<wGl2^yη-}1v*k{"wq88Oj t9_2.=#΃v?ϊ_Xq\7`gؿ+trE#7'{N}M8?])1->yWuVYPg6wƫ+[Nw9vOvLuys4.U}b'|Uv-˹*nWrQߎ)8ҽ޷ߦxqƞ}yJo۫?d?~aǑOY7×㷼P}7w_ߪ}lr~ ~lW}zOead0OT:mDZu%;<^'zqc;Z[*#:nx/8~j7Ѡo>Z}rsS=\P)݊c#uGJyS[^s~iGjBqQe{U]ϲ  :no> JҳCvux:Ey5ЮxL9yy*n ߿ ?⹾ˋnG;Ǒ:dese|žARVqU~=0L&nz:=WהG/ X/H{7qoAqΟWX3c㽞z^7_ĸow1^AU.㯫x:_߶>Mum=9ԞUmǡ>xwK8C:zL>$αymV;%z\q|Ox/'W#~MT=o~nuys1.qsw}T^ٮhm*9Tozνyw?r|Dž} ~WkǑ*}Ν8s[xg< ;a;?U\åٞ|" Gܪ<=z?ֿ;Ϋݪya}}z?)\@=ۗzm3ߕ=ʷrc7[Q#5vU"SY/D?\zWtlx]u?Wv8{x >OÿcCGևY'ҹ7x4a\9vƷ󽜿ZWi u<o8/;?rǭ^=؞޾=ny 7??vAwyGh# ur98\?N\/ǵY}~95[{sqmA=nd{ t<=^~mu.#֏u^׮兊ƗNtڧ\GxN''u;q^ճv~#:ο'5֧Wxcq|ZWS*όqbBPNտrǫўȟ\?:ŁzE+9mFӎuK:X>@E\]xr|.#^ׇ~vc9n'-_?{WO~ׯF~ j =goSmx'fFgW#{_:WǺ4ay]=t}=(K<3~ze}).Di'|oIݫy_U2p?۟oОve.[ J{OOqWO a=<|n<k?^j8x~uM븃W_ 3>wi).lyR]>Ⱥi/h\I+zUnJO`ʿ켑*vn'i#?ٿSi=ޟ6>qgTe2e9PuU\=waqS~K+;neK?~:_Ez]z-S_ a}dߜyؿkC\^i{H[OqǑw긿?zPA<بzϳu ?wz_y_G+=g?XoY7/:|J7鿿}xb>7\][?-_E(̓KXDnі:N*yA]hۥ+{qW5vl\Xs2sD#pkat<X/߫Q_vnoЮǸww89lǮo0C>:SsگJ;_9}ԏA[?w^?w|w^XqUb-oxg6:I:|}rzA8}O贏PP3W MmzF{8~GK\5n>W Qo|y$\A;+o qnA_l_\Oό )U'ȣ& ΡU>zwv&wW,?U6/X_X|Q>s]qd{BなjyО Ʒ qώ#]z%ώ}_Vߖn/rz1m{`USz ǭoun"Saw˕j1;۞5`z5xtڮCmߨ\}xn^o3?s5b$z}Pc[?.ΝBW'&8&A;C6;>COyw=vz[[qW<[.0> zqs{N̗Oߠ]ρn_P#\]S=/D݈V׭Gq :IwNϓslů`_wE'^r=΢;fqaqf;_կ8›8wCBݍY6A'HE!:x~̟qgljz'z)=?rxZ A'ٞH[ϵȸwl>}a׎no>H¿/z/i`qn}z)|o?_lcזK#z[N`emO?lwZuWD+Ώ߃hmWQ|yxu=8ҍ~ߴ[ߵOc{W23᫲_Yoʾz<˅#{qG={`8U=zW;b]{rq㛐G:qx~|K>sw]k~|Ź`<1~⽋}]֗]P vws[MoKӸCGLP;ZycEï;]Aςjϴ~Sq~%u?u)(6@3}xx̞ypd}ۙ#jxƓϦ_5uZ 'MoToܩuU;&\xljl"/zz1d[v~o788j{=]<=wtS\[Q{nz+v9> wي/:NTъ]mP5morrrqBKm7ϖ7V%Ɠㅼ/[َѶtwgyntg'):~>/V8Rxwxj;jrOE\+?vDP#jl;\審-Y?w-q.݌:yxCu9K^gxb۾A]9zw=:qX#/J?wP Ǒ{j}x !齠Ɓ;~7yw_ޟ>O|#=?+~xu_=d: K? ɼ7*wvCq9r3_TǃT~ʊە~xD~R!{ާôsrzq~qs*V?ߌ*l~cܿ+{)Swa=vO.q[Q'yZ\z>[al߰]v/M/Ps=_Yw6<Ǖqd߫7lVv!U{x((y/=g ю?K"ķ6>Rۣ͏㜬/W5t܃_x?t?r?w6/Q[7v}xv.;My:h_%vMy[켛ʟ27\=;/w~sC瑟soi7bn}rz8߃vY'skqv\q˧6~SCyG>Ou:c{u~IO۰>R5G~C>G#??_Goi}߳ y8w[x%vQ39~*l4;*}-j<}mvG=Oouߗql{e<ڏR_(TEqMyeυ2o,=m_2ul_}xy5_wA年Kr{j eD9.٧'|p˓qW8Rޖ\U~.}i reA/r^=ʶ/d{ מpuMy8|}p=*t_鸰gߧq^߫us?sW[Uk<1륶e7AN\9|/z㯪\|·9gN?uC 3z5tjyqUn쟻7:IixߊD߇Ƕ_:`e{cU# 8n?c;o%/XNkoW@xs]}jg?/sW;zU?C6:΃9ڇ|qg'Otۯn6+`\cGq^D{-7Vq˶>soW mot'?yc9g6|ٟzḃro}Y/sc^u|r(*~loENoe;mWmqln?3~6c"xr~Ĺ>vFWѴSqg.qxo#/muvЯ=ls Kg=7dx\s=y#Z|46yj;]~rK3lg_vHێr|j˷[VyC9S_?UYyaƏ_UO3Ǜ{wU!i.>Q[M'~ Ex4nu_MjTqGrɮN/FvcWﶋ>]urCȧ.衉VqP3Ì{{yG/_)鄣cAm߹_/mչ 猫O /M].o勵+>_aݲƖ|8'':xn#<*^#{r'2^=~*;~3XɅo|"g+;(is<~;wuǑgEu>ze^Wb;5ø^_ [9㮍}hW}Kzxv5- yR-~[C.[aX9OvH5c>xZю듾8bTv Юw|+}zq_ڹ*Zg(~]?9cD@.Qn=lE1q'Υה?6(ryEoA'}OnƉn7 ~a}hG߈}_Wq=_I||;v-)Nqm;8|`;ʳ]>\^#Ĺ筟ݶ?9ܾygz_EYOloU9 lǗ^ւۏ<5uqA?;'/gXPx/jǏ0';&zdF}'ϴ˸ A'Q-h7Z_\{;*gNjNڷU,xosO]W+>gb!7+rOxWS?ͼv<^_*%q·#voܵ uSU[v8ǃoěik"O?Ņz3nx-S6~8ѸcՋ]8g=:NuQ{\g?v/,X?z﷑QE玏}3~N}|;S_O_Y#gǽ80zcW~l;P~Ǒ=<@}!+5Xo|>Nn rnEmr l'~?ۡ/%TzJor*8K1s^y]rH;lu}':_<_g*;姿}< |o <,ʇb^\9;7n>(qWǏyYo6UvIgSQ m/}Is<μveg8uދ퍶7D/kZ.;9.mu\7x?nW󝞳=xۥ ŠЎd^OU# _;ǭy=1NR7.kP{xy !~9_o~5L<87e˺/7{Pw8Ҏ|kZI_?|;Nu?/yҿ}686}Z. P{m>v8~Ʊ1>⼏;Q; _ujZ۵j;)1~ldUqBSocyh0Oc;k%w_Wyuw _U[*z>WԳ <:~JNoy s|KqFUZ>3uvYmOr/}}z_n :᪠O;z|oMr*ҟCXз>O鯂~qϯr)muތz w >q8UcOU?e;>=8'^WA_w<)돶cau~=xݓo >';@*ΰ͋/Lml$Wq&?}Olw|}Liq<둾ߥ8"Xw~LJ?W 㑩)΢=#0?lv<\{6RCⷈ{W#S~7^t'm*,:l\I[gqX7VEqmlrjlTQDZS\ C|U~[YgvPg+UDe_s|ۑ~mmo`^[g8.mocky^ng9- mov. j~}#|2N:qxʎC=`p]s)E.2zÇhu\JyqbK'a=yQnV۾kyf;])Z.W\~\zL7Ovx۟8~%p弯sM&q,Ӷ8/u}˥k)g^9a+kcws˱x4-lugvvBvƁ=/8X:ow||~v5_4QCx.o=因Ƶ g8mw9rq#y_k,(1}ήvU8p~RНsq{q]3ζz.@@y_~ޯ8XOr׹mP5ůYF{zutǵƇ7ƹױU+z|~wǑ?EqjeC{#Z΋QG¯;j|oʷ=f?(bN1ތ~zݮzsO޸*vM+.#ߎpДgASIU ǕB'긞H+80Ǒ߂v_o/ WюJ?NqĢַOE;Cy"qN9ߞ_F;i?ZHV:^KGh?xvu=[eJNey]0+3^G9' eF'O^SkoZ*8IhO'η&\W.?2eh_Eu-w&}\v>s]z*uwoVWL/UB^ݞ˱ d{ǽmtNq-7ѻQ^>Nѣ8;IwxяGMތI\{{\8]vGzNV:'=̛Q6N~D+xtokAk<ך !\n%O/{G!;ˆ7OJgr_Y1ǿk3ߖ_ {M(W+Uymaq/˼f%o+L⹼^TcL]܇u|+a #6hVu7} T ۴ʬp9} 7l#2#g9,{U ~Vc8cnڰ+,d1 :Ԁunxi3k/~0΃NYM8vmN4'm9'6Q$pYq.vE>8?x;9XIϿ}?͏Ǘq<8D2ifly,W.{yN +YRɗa1÷:ghG&ľQ[Tf.7Ε٠i}vm65ɠЧ/l)풷5~<-[jǭU+;{*6雾j;δk9~*\:CnǹSgcqd9h{ O宾R6[fYQnyJNxAwy.z\{u#vq]j78)Fw̏q.'ESA}']Ey~<:j]έ{Yo3Y鈫rVu.c`]j+Vw\gYNeUU\+*7sx7W3+N eFզmi3|^s*i oVzr?`$0ͶNnH'aǀ1 |]7whyɞs=k6rnlH{MNǧA95k]*{.>>:]DV3>^kƐw2r]~e[ֹJf#S]ej]BOkJ\A[WkGaO^SߴY_*wqx}쬭cQjc8N}QWaN,mMϰ_-ҥke6[m\olk uzcZ2>ϵ,#޼ޯb \ WlKs1S.QY{merOeF[ ?t*Ͷ՜xĽ5y~y(i;vy8N88N8A>h7d6><)S=8x6킟]*(q2M|}vr˔<U2AAF֝K gy}\8or]+}wrWGS+\QxKߣMtxtd]oC2ulu['=W-C _Tn!0j(sr{gx*q^gqodpiܴ9tY& q;|ʣlMYwzO6S|~1-HlxFlr;wOӵ.M4cmqqX}P~6Yr;y}F$5ᠼl39vySSg2~9GqNϽnen|fypmޞS-WX<ϩ)y+U3IO9](ˡ,Ʉ7,uö(Neg~>WX`U._Gw[L ΪJq7ڢ|ץKG5=VVt֕^չ͗[s+*^j{m-lxVk(QyU9n.\u-{8ܾ{ypڝ6L=V+w_msz֘$a΍ooU㡺z3<|YwuG?sEW1㽇m.ouk `'mg+Lk`貟r=U{Sj}{?b{rp^u f6gUϓw>lc3<;w۸Te5󽕬 4u:nZnڨpe|n{՚ۿco_ZVjݦu2FYXσEz]wuZg_TpvWzfU|xT^KWY7+,pWc1Թoz[/waLzk3.˻*wWx}ܗnK+׌w{_GU=a>w!UYz_=a߫ږyzT1ju seve1r2f62Y\ >Htզzfc%Vrc;m=*Zr^o#~.{[)ns鰿$(x,߼eUskj]SwU>>/„.pۺsXu{ 6nkok|Ku|t 幯(/&pYjd-76=Zu{mi`0̻9A[綮=yFY1Y0'&z'R]+q<\<ƈ7{m,gȝ|(:_C\wm{ͳoS\9;C2toԞ^L}JYߩe~}_\{of~_Zg~״v/]=?qYSkma9܊K9<2ƲXV[>˪Inڈ 2X gd M kZ>,@Y;yM~k4e(=]߶؟M<?]GYtfcmsϮq/GlDy]χ8n7p4 m=ϋuo<1ߌoi.&oS?yH׉u|UK]GCC׳źUiL3y}ZZVظeއEVy&M*eXaܧ+L]Q{>沿i> vx\75+;_mbls<sŽy\p'B<˷|XzYxX+,u, P6mc5 m3} V>Q0vcdܑ 1:`T89m>kn^>i79﷛=N|nrlg1݀owkx ?,gK+,dteNk*{a;ck\m3+;Jw}_ v˲ObZ%>^iծV=VY2s\<֡W8}~Vk[ymLx|o*-{}? o鶙 ⌝b}!UK= 󹒵|itG7Wڔךs۲?&ine;lx簷wȼ=Hed{5NϜp£tG:pm7ZۈMlc 5&N(6~͞\p/B6mg9~ 9Eyi2Hb>1gOu.qeCpJw";'/K x-p'~ucw5ZuZCn5Qcj=_16Ya G:I.ߪ?ߩ k,m+xo;+=ܰh)Zw>`cݵQ3gcffClB9½CS Ovw]xl=m89ڹ~7ay֢U՚7km"ڿߩlױXUUw2.1>Vm?*LrQ֫bܞN2f2f[:wa5^ (t5/B6+,Jɘ20ae dXً;*cӑm"ۈ687F0Hd,cd<ٶO=m6SԝyON`pˮ`m%"EC#N{foCǗfO8aߥ?q$m#ޏN݉C:(~e÷=+\^R[k#V4~4.p7~vE9Z_ +W2tu&@+8[Ցyǘ]϶'7_xx|%cW|r}ͼZgfmvj=[aѼf6RJ/dp)ϬeZſ,\o 룏\^7*a.>}㶿kCu^run^Ke:2/3_m*:ԕ zQ>_ǁ2owrﵺ_}Y!rޔr-x9W&d{|%W8fV*_[r]y]gy5!:9.[ِX\ΞN#fvAyy}KdFzmm]lٶm=m#n3% a~6er{xL|K^m^Dy xlӹߺǪ,0duj[^-C^rp,9;e%ZZ~>yZ᳼Flc8j[oڼƫ*d^i#/ۜSy^33獥V#>+V)scU?Mo֯:&9S1?z/ "3gYa-?\[kz^; l5Nc5xٴ?\X7ڸgi3xxtlMIq 6氝fhx'67·=nm̯=A.nd0[˭ԼdGg=|4^Yu;/oy׆-'֜^4߶Yޞ%^_szz1P6}ukJǮ֚lciW/jDߴz X#_ųOr/Dz 9l} l=Yd\r #mn%s KUszLuqq?Ȧ%:çu~()DOkxoJ&5~>c8 G#g>o7{*MN[mq>$?h78Qm^ ڷw۸W6?mk;ͩtBfG:ԃr‘6\ /k|2;Vg5ا㟯o>:|X-c %;[ lYW _: }jk@^[r[TYj XZ#*\kE=ӽ\n5_1o=uzU~r[O>:^WVe0 x \gY[ʗJ,Ocʴe1x Ηu|ő1pה[m6l?sX$TvPminlAC㰜;y{.yV~]<7ȕqe}XK}bQ~^m,~Xef:jY봟r9m^*=k8_|uoJ|2_)3?B>UU?|_\޷*:r+WDy= >\rW_=`+pk}0۬onЦ)\[0͓6>ls}?X6y3Pǣ629[Fݴٶ9p XI|E]nQȃ.,2?,[kdUW^gWyUJ'[zU;SʕnozVkfUm y>ZUTx5껱ɧZ71mX_(ITu(H+M|yZk^OezM}fsNq{qjk>3nk<汎>hstVnzs}O[c˹F{ v;a.c'9.7vfڍ6x;oqm O۵6a 6?jt]tĩyݯ/ڍToov8!o~Rޗl7/RO ?\y?˜m^3^͹bQv{߇maF^3snU,}{?Wc_{\Wrw0y~q|0q.3\JI-1qX')1Nr:nqA%3o':9c 8x\a: ;+lz}/{'m#d r沈yrOG+Lm͘}6"XoۈYNe˻k#ZRh7iwM, v9}cuv9ɘC8+_/ڍwqpmRH5zk7sy~t[<߲Hr+ҞqlmS[Qڲm?߈с5ߞ)kf\z&`ZJV=+`3X>(2x Wud52^:Tmn7:۽6Iudv_^y:Ѭʷn}]kDƭֻ;#uʊ̧w9Xl 66M6f^z:n|j.^xkA3~x8ЛTW./vmV-x*1(q֢\|:M}d{n7vx̘.7-ZnX&Up dYxӳ1j]v~ wڼJ:3}iV8$}kP%ϻۋެͺf^՚Z+^ﷵgXr. Qy:Lj|\xXμf=q+(1ųM\Sy<ym+`;?VYԽRy \C=GtT68`Q9yƃ+qr{V}xtkƕOhyCuqzLmSYn>xu;1[a6p֛OƜo#i+i(;cیr=|ޱ\kG֓Yy6L(lX^WA.#0Lwc^nu|:^kj,R^+zos~:?uE-F\W߈gNu)U'j̽3/%WGFM]z< 7>p/.oz|]):Z⥒yCI ~xGѓ \ϽD_ֹ[*6yoE2y59,`;^pȩΌ8=Ns:"6Hژ&{+q&:6 8 l=8>f/S͞_gJ:7V V9]qu|(s|^VzpgmkuQW8j=ɘ ߵzMe_QAV`ۼgZM1I#j0+QZG۪+ǥs9>VXܲ+E=+\gZ7{~>2v۴q͘+X 󸍱u7gZqeqmIzn|6ڜr;N[ 'nQyO༇&> <_Ao9a6s8v'z_`qh7{%6|*_͞)_v~io羄Ǎc|V;,7aTeD.VX>2rV][beNZ^g}e޷m^?VNH y5E%=p)N[ZYo9d^oqƸMoy>s9Oavo9toꘙ7}ӛm=56{s:n/t O? `9a+8(6{qw* iH>xȼek7p(_s:NX6m?|}:0͉ wƷʶ>rNNnڈh7QS%wt{18Gc]J'A/_l~2ek-pٔ㖞 e,sX:lϫ5`O/3\)ek 9Ǘ9.~ܢV:3z(Rٹs_!<<|d:/P:VǶ>}G<2x]zY! 7mvylO)k081O>X{)X=yƘS=krj 忝ʢSYp^_o:^o}i{q\c˕\2U~9q갾{֫Wgʼ}wYa]ec=. 갽cUH3vզrN۲*LvX޴^ϋ{x#c|-˰\1rDfZ_rڼg Xa#2ju~t?mXnvcx'TꝷR~mh{~u<=Sl{cU΢]xُ[sۘw-#˸TfN])]c"0S.3j.Vȿm16˃G^ϽGy>\X'c ܃3W\Ä2m8] mch ʑaSWeӣuʢs^׍?usU/c^^w CWoT๶(4:ns/W=S;elfYe]Myo $cA!G\>ϭڙ},mAGFOy}f, Ʃ^sV=XIGGmĹy-kolc&-?5;cmr*\1hR+\ʦLxfLoܝcϓVCΔ;|>=7'c^5ϑ.Wdep1UVXɼVe\*;zr\7 01׾U_[W-Z^7rZ]Ͻu+Ppms+lgVI[@`}kQZaX˕z?fWss} nq+لlX̘8[m=--xifvroia-eyXG/ʭ.k&2w^/mec/A^x6cʌ+DoΓ͌cVx&>c 7Co>p-u~z9&ad<6rPj-szUwUfUwZ[7Wxcux\ɕ҃+`e޿[^owfD9~XZaJ0xc-_37x91j #+˫<VeUur=I$Zkݧ& ynO< :gtU{s~Ʀn2 ;sUR+UV9+_k\cYK@:rXKxk K!׿i76.Dz(پ?SMTy Q˶UcT.!~\;C~F ݢoeicS>\z>_Xq/wmU[Ӫ6]l.n#+Ly4dA&Z:s1: l3q(3cMX~6M+ec::'oQ6 kǣ6b-Vlڈvm>gd,\H{sum# GS\B'sv5Ga%WuD='Vd^ 28?9ǖߧúnm-aTy߶ ruVzJZ۸&պಒk KUe}B5\8{g^{^|rW:ᘒx>/ީ[:+ƛ)ܣR_ތ穘t3G+M#nob&H1Pm{~Ӳu,T?kKO Nc|*Vd9~[qs|P||[k|T5q۴>~O6C}y?>1Uu:6]ٕ0Ƒ|ԍ&' cֿ n}~|u,fY^ǻ{Wv\O}Ldu|[nbh7n8+frSBl0߰me.,n7yWTLR5_u/'v؆&[5-6Svk|/oKS>/;禸8b#j?sA)1wyHq\2E )oqZ>5~zZ(-9Լ  l}a8~~m[ cO׍mM׭zggͣ8cXmkO,P08q;NUG?kp7+c|:ExjO쒞{ײ1Mo#<ޭ@X7-9|[~S c߯n7?S}@~/xq|յwoL[} ?حCcjMtu}mM!Wm߯ ݴMesF2Z7N$QnnO:NuRRckOO|}%zd}զn;?+aܭ$N(S[Φ<+O1~NL,uX 5.ϵ91d>ej4afy8N!hyp3{8?8wn'>]&A1}n\[RDUq> @\ y=ҭ5>ݭ|Ok?M4Սkz_tc>>D7cꛄOvqS^u9b [x*:㏻G=۝~ϻXo>׭~Xeޝ^ƿ>=δ&M擱ۍW >fggopNm^mgbs5zjY.?lrj=:1Yc']^]7&b YsLk㜒MbC2ET,Z_ϧAtgm!r1S>nV'w>؍Fm;}|[}7hz[' 9b?V1gʵTGܓ^jϊ88s;[?lMh`c?NS{!Ɔy'\5ڮM٫Ws͕lĺm[mVºm;W~MǛ-h?O3y9X~QZUqq/D{J9TlW,ڭ7~_5 \iׁ }NS&pYs ACϊ{j:~xPv9b?ΓL/u5=Nu.xߍcKݴ`7?u0k_J>ҭ+=mwߡgj>٭gwmVݪ47꣏'es"\9!n叻UBn?_T2cy15H\f\V1&뚡4w:kʦޅU?bbNxʮ[Y}OtGOG׿G:<żHצtzy>^t wǸGq}~˩ pyxaԱ$ޮkǡ!4GkS [<~pB,nxObw]出9:yHmxÇyzh6:? T n巺o逾ZYC/uS'Vun{xw#1rPx>ٍwջ;[8Ox8q[ݪi*z[:#~w*u >nt5Z꣞S1ډ ;23ޚZ_ބb:.Ns3^1}=3<~L)ހ^59uX/;~LL4MZԺ~j.A{tz~J/ NviNZ{M<&C/ݚkV9U:jX?xGCxC9}[<{5y(cSsA&p:fއ&P#p)xe9_}ǧޚn%$bmcyp^㤏:. ̵;k{<)pV,TӁ=yxS&9ç1N=M޳~YLqJ3\)9ckc?C=?K̃?4N IFSʺ}j,9X֧:ƲOMҝ:w<Oy6%;k$;Ѳt-)]㚚9P$:R,g7[Eۦ<܍4ॎrTS9+szqqؔxXnǻuӍNqD?uJQ)v>*Oֹ:s|[:g@ q0أ8} ͣZo.Mmʔ](mUSh{֤ǔ u/<$sjk{l؜eSܐkuMҝZfu%;3Uﯮu-ܮqXgs=zeMY*):ح|c yGxe _:n=s8 =S>jkԶ~k_W_ᵋ=5Y%bqV,P_סϤak>ؾ/͵YԔuLt~׾s*oWljser㰝cX~Siێ[}1{u=3smxO>ޫv o׭ꔌ#7-)o1{\|vh.Y|8N#W5W[sg¶wMsu,W|b;*S뽴ߨmas|[jS9>*,9>R<@5V1n::+R.r}YÚ?דsVya*Nhomgj}/VmçYuPwn6kX_/khm :e_mwMNͱ~i*v3캱\_/Lv-&ޝ}WcRDM,=xKֳޝrp6/SMŚSz_Oy*Vf6X/Ŏz϶}Sqȃ]Ώ Z r)lAϳo}81Iq%?RC*gS>ڍ#z?>ҍ6b):u\i_V9~}='^S=$1sSwl~ٍ_4EI{va~): PۭVM}/M{MD/~W)~UQg~!wߏJkJ&kL:ryQnLb9:V.z[˙cw;T!gپu:GK?Rtӱ״}OtwnW(V~շ>]֝ˇq@ R/qOVh75Nbxjtw[owwv:"~,_,9Ce{VZO]G+{2~aNud3Ym Oq~1Q$)c53S~kb ǚ}7_xm)o%?3h1B@jn)_@<(Psò)LF_MSH |e~ĺbpMgb>rSTlc*v?uS-1-M,}ݺ}N|־7;>.k|ux 7|Lw.|I}x]̽_&摪m\s7\)\zォXg8}Ц%}Ϻ8-t˧w>ݭx)twV9~tkvhdTlB՝kb=>f0d.O;.z0(F!Vkwux2Su▪XW>Ug/vstwu޳i~X~,:c˩Xhʇڷ{~Oَd88+xA1Xmu% &'i!>ЭuCgRu/pH7>ԥ8x1~:]ݶ>>T|Tv|#^}~znp<ޭ_un\^ab?qԧ'p=խ7{[6gy涏vZǃԺ*GO5{f>~ݭ$yL7|3qȄ_'Ԍ~M{3ѓr u1nsI:~1q\/ԴN,S5nω,wVAW}sUG{5ǼT''c ϩ\ɽ:kg 9bԱO bN'ω c<ح<)>c+ؤ~}8Nc>x\1P.>>!p\ETR38ֿd7}i>ZpqK1 F3|[}?VEADTOۍ OwJ?r|Ov2pձPn;VQ9_v1g㏻շ?x!RLU/ͩs=ϭ|dS}NYت͎c_>3L:vEOoM~ѝg\%unƾ8CޚQ2[Դ'^R?XΎ~)Zhgxl*tlXEz~)X]9ƨᔝu5?D(:yoyo7L?3}@+ܫc=xA:yq:{Z=n OwzǺoW}ǻ/Gq'TnL>x`حu~}c~6ޟwqY[?,bTm;[VXӈې9AȳBu\Sn=6}[_h7}[e/@{Z{w5OX7ncG|>ñNLᏸ/uy>8+@e? Sk8j?]R[1ZNPG97P7 + ~u&#ڐ!\XYFX7_05qߍqlbgz,Ϳz{Syi=L6>SԽ)[[Sv^cnN<t1Ç>|ީ~X]b8MMܣ>ZR||T棎kKG'u2xu,nr5Ow:t<:Sx2y{Ss^?xN;s6)ٜzo/N.SqЃz V0kxOgΊ.G)Ʃc{W~v\xp);6iwb `O/npzJjsST=>zpe3zfj>ֱ-ﳎ$I㫩5kV3u}k = $?{}”M?A?VL3qqnἸ=MT0k8K.g%}Vp5u:W؃32 ᘊEh˺ⶤ?5pAϙGW5Z:opfx`uno[Vȣ15ǧdSŞ? \diާ|FC]Ss=aߔߴzpgc*fど8> {Nu.h`[O1;^07p=hJh=Z x>=0>ͩz=حL_94S|[m{ S>ܧb6=,r_7 |'8i&nUs[@VSn\#^puQ nvݪx: yjguͿ_ts tYO^pwvM5_ܨ ]nC']8K*]n5lְy= ^o깩.S뒩OuQSklmcrǯ1+s8zww{*֪bT}_roLSA*]lJg7tzvSkW5 }Fe+ugӪ|yʆ!|YJ#; _Սߝ1s-oyXn:1B=oUߪױ/ ߚ n}?o~M4N]?}ˀon?'c_kSM2w\X녯MŔSpY8om.NY㚌8r*+x7DM/ljmM/|PZx^K[G[?Rh`ۧ>ҭԱCz9>{tu}N^W8ŸJ&u񾉱Dž>bZYg/txnS&~qݜ+Jb{w7㓩xk__rD3z1D 뾂M?_d8w}r ~>Y) 5޵cdYweʿ:rV|UǤɟ[VSc uc!Ԋ'H17_m7>GNT|qf>a.t{T6!{^b$Mۋ| Jm[mc?%>gߍ}:~>ҭ}[{O#cNs5uw~: ~׏v:taV@H7zg?t-W¿{w;rpKIx)u'O\^R>|~vO>9_@7qS;w1DίUczmd _?Nun;+|-׷[~t{Ks;x~s!\ i_uqm3؁f}qp9O}T/,4om9z|k:[;NjnǷN- ܛyP?)2;x:zn1;_hR>ޭCqܭ%t﫧1a/c|Ϻ"ILzXt[+ޖ2NǓ;cnvXy/7z;^ېov+ܶv˘o;OeԱD\l"k _N7ys|~{?H9zمq]y~_E_:/G/kK/ˇKV9MhO7szn?vrO{1#>ZT; il8̗~:΋\߂VJSֱؒnmџ>6N%Kn&msS%dzu@_I|_ ;{/fұIz7pu|aA9^dOu1ʒ|#*Y*'%}LeVp㏺Uӯؖ%Ywم9Mɶo}# ϝq4_]nпoҭּ=^ح6=]t+M$Rqʖw#Smp,V{)^m)n߯%w㰄{~8 c?N%ֻyOSj~$)^T5b>Xjrd}EKsO݉`tn7|%݊{Vk%wtŸtȼθaQt^FخMqx.H;mo*L0Zu|k2v?zn7Z wxn.bvSs99_4a_-u㔹seNǍsK9Qv>_`.ߓx_~ح:T}LK7<~w u㧵E>ޭK7u'׶v9p=,걮k9;ny)߲ʖϷWb7Nk_oW>פ1oU_ZO]sT)/kj^9:}x>^|[&?i|2^-y?*TmkݩYu ym } 7NX}mnb]en}m[>6ǽ^U׌,ލyy.Sjow=*wJhaܼBF(V,9GF!yYuQ9zX}Ny:u+2k!mStOV=ҭ6JUҏ*\?,f׹'U XMs]+r^!mPoCvy7]'Fǐ>yt?/wg?/Nbۖx~NunŅγwT <}~-sP6vNW6G=SM؏^~>[Lwצ5=>^otn?W{|f}_Ge;QyQ>_ދQ~X$ʩ\:~dU÷ lԾ|c_?{mGo wMlQS4B.ƚo^[[75@ʠco5n!⟥^,%iV…oj7oL5kW5g`[x]?_䰋۬kݺBmGoa^\x`Oж{T-R:΃o,Cms 9vlg.>~.}w Ĕ?Ouˮ}꺸>R8<[nQW|Z9q/t~jok8Aw!?u?f_~~>[?Ot޶?.S]%l_b*WRMn:7*Ƶ sy], o{w:gf|4w]~qmp_u7.O6y_mS=GݬωzgzjA>Gɓ/wNGЕMI32\Tф^Swcn/ڿz[8Ƕ:~[T}Rt2ut>7x7WL _VuQnR*Y.ﯕow: [:ok]>tJϋmqvyo^lPˀf%a/Yݧc N5KJhuOoC~sݲ?p.uϒQaVKgqOu_]y79n_ֿ{|T?STw/0< pڧ_~Z{֧m3ݲyXFMK樧b}u[PkPI6s=}x:'6vN=3痌ߛ]B'z<}NS^Ag>X/8Vn9ZKg|W?p*Sۀw֯)yxߗTi|r/Fn 9W%G|Mn}w5ijZ3:zEϽ_K}>:!%~}/|12.K|nU݂{ں:]?%:7K]e \mzG<]ԟ~O>ru6?-s~19ϗzd~a/~?6LuwߍgK煪ohٶRv==Tmu3ϔߨnׯwm6m?Qyb|S6n~jc˦_V[GǺe\N< _"3u,!gd;'2&㴺w]%zمpꚕ>|:_Ěg)Oݴ]??wrSeFLo%.Y>_[ɍq#wo}0@G?.yen9257}[TooXlthݲMǶֻx)߆VV؟!K?œn~|x1ձx|9ȼǻ-%lF>٭^F;u[bꠏЭPʶ|ߜgYl %.|[8o~S?_lu}óbm?vWӾ̒Nؑqn6'{QWʛuG- ~cw׶2uyImsnt:_nsp9<gom߿k6yɦUcn]ֿ k*Eglac"73w꣎^*?RdMտ*n}mIt6YG>ȼ׹\fn[t[?SytE?}:@w]`Ժvݹ%F_?rZb5#z_x?K?ݵta}4gձ?%X}ld zoX:~ӈ="f?F3{-54}؏zm1Rޏiښ~RWۦ~JPj_Dn=nK2]g۹r{STcnU;S~%un;K8sK׺f"~'?__K=ZӼ\\VuMuP?KCO|%Qy[&Q߽ӭb+jེU _\Ϳziug0c _#mn^2}[oSgɇ"xߪXfv>/6O. }_}|>Ɠ;;7y׺:z=n~:?SEӶ;*_,xܫ~'NY{q ߻g @/H?㫿p^^u~K fl+>=[2qRKpޭj˗%_j-яMuc7z[6AƏVǒ?uxR%uJ_/QckFny1bO~cTzt:?gȽFr]*hxk5;=KӿT+H% %w^p?Ww pF>K~ClT]y]amu հ߮Gx?Vos|mqֵKJwU|,?ߙ~doۯ{Sک/|[z.Oö<\VﮝUs|!տnOvum1nYZ~K՘-aTjݶz~[K|Lz7u]?:ԏ'3?|yna׼@?w=%hݸmCS4-O.UABdi y|7i\چ*yw.XG{Tu.hotg۶mM?|r:[YjѯT&'ɺ3cZ3E?9Z.Х%Y)K?㵄=]MxwzOu9%uzܻs/տ!-~;s|v\Jf)م~MEK}|z~&z}^WOt[6]!–rގ|OU_ov5y_5K|fΦ疰8罭nsK~z_ImYx<S4'X/~C}) ߭'Kkmnq/rԿ_j&6=^_M>Li|R]Y܋^G?.n]Zߛmb>qVw:_?WЙ59SLjKw^|7DB5UKut7=ǻ}>Z/%_!Nc6ꟙKOwzϓB_?֯?)yԭŒMm;~omsLO?;+Mj_6kEg͓m]n|pؑ[~'bݲmxG۴c b:mxw]/$~?|!l}oz%ϖe.4wQ}@귽†}{wj %nٵJ^m;k ++خm\J^m'ٺ|޿u:>mo[R}cP/y 6k*E?wtYwDS˷~}ۘY?ܯcG\voo8ؤxgp U^.})'sK׺oCv~[ـ䮨kו~ą[Q~~yq2n9GfVvq|~k l{_TV{;Ξ ~U絑ȥ׺Mچnovy[֖Xb?zw г?_K_>Yjy~,>]տ].7C2|7s1ۓxm{ϼcԒun^n.#?K~XQsKE.?1i7q[׃n#υ166lu]Z':Sשl|q6ἎvmN "%~=V]Nً3لJYV~xFgRr!Dg)|?܍?i&3퉾wy.nw>Z%b{_JgmW˞XA'wyo>MNjt{v̥zkzG.?KryK|_[o=kw Z73 O|Ouf)Z<ڭgʏM}ץ߿&5ǵJf~y]].MiY@~ | W־ZTM?pOu_Kz;[Ϋ_Y/},m|:÷,jD~ ZKQyEos,Uؽ%mտn [sK^o߶Wg7ne9zkM0jwOSMڦRvkjO(yӭCxR?\{gWCq]sO<ж1~ye%u>UsoPSK_pSm6lݬ`j=*Zo-e]Ӓ~v|[v}R'WA  ?.R/hl?|[]qڤ{}QZ7uϻz|_wO]n}]׿D"}mN^\"H[ڀ2wı>|Y"ۭ[s^1㰄!]wX粧=^8eN~z>o"O"Yʿ?Ry`^R(§*_7N?wu_\Z_[RdP|޻ku__)uQ}m;yw[M/lﻮ/¿յ}lG fsmS߅=kۼU~,9y?d'_ֽmݼ]7?x'O_Z/ߏ΂ه!ӏ__|lԿEm׋zs ~/XA3R8MOn7%[}[}ޣub.vg`1ׁKα]'Ou]c+uq_GI鯷e/O]D'C{-:'ŞR_Ϸ'n]?xi_w1NI%V%Ѝཱུ%o3_VKuϓC8}R~n-Ybx2^sd~Y"~k^Ѷk]REG~oZu9u΃@NT/׷+\﷔]^v1:^+R%^o->_f?zɺݭ~b}sƵ~uw#ޭ޳/Tͺ]=ۭjo/86nX{g=c/>:m|(9umok?UO ].y86񝊷mڷQ炖_]{=?] 7Oq.'t[Rx_Vu얫ci~+oC|K'~[7qCXkw5QTYۭͶ:b}z-=g\Z6KM`Z69goyCB?o1O}σ?Fw%t#Ӧto76z}BtZ&uN`^.Kw%G-n=Ϲz=:ߩpgˣ.uݲ߻/{_ ?On60?=~6[݈vFP?{/f[m=C=`ns~-kB-R?5Mj7sq?KQWnޅr(Ͷ oWݍ|\Vn^^w},_sJSG#l6NjE-6?h7-8Zor^wZNv"tͶ64Im;fmTR1G5Z_ޭ+ԲY˖j,C"-\A@ttuTs}ꯑ3MEOR.y,kng =}SGz |ou>v=]K.]ԶֆbVvrur)ټ1%AotoZOiK{ޫdkV=.qZ2dCCq[&5<ٝ]_m[}2CK^udstsfRA%~^&uZ/8/]WyV~ދv16ݭuuTKفz_` `t'޷b.~43V׮eI/wrӭޥO!zJq>Ӎ:![`g? =?_%S| {_lmэ:s?K?u6qԱ.iCU1뺶_%j=df;g/KкtB.R>~MKO=~a)yWz$~j%Z2n?sǣݪ-c_ޡ|?%EFZum<϶O/e*9-&]}%׀I>(׸p~\KӐXO똧m2=7ow³9!s{F.ޡZJDY']?/A?߀7oRyG:gvڇ:R?̉j$iydbL8_*P%}k?D}|؜工vUh:>}D2O-~ߍ=zb of D3X2ӏQ\%=>XybmC_?Y߮6~lNw/Ln}mM;)9my~C5E۾5^>vxc?6<&o2U%k[w76}~M븤Mi/kxp>ݺ,'ݛλttX_men7Ϸz>~s F>۾:v~6ʨεV][jQj;xh1qo̡5y^zU̗j |?|s}Zwc3xoK {[}'?\sY:?8^z-ئ!vzr[x7봶͜)}m:m]~ua_cw_%ާߥ'D^p-\KkzWu~q uWO zm 9N3usspw3z?;T0n?p.aKz?5.bm?s^6~tw`:L}zLKG=-k%6Q ߥq]%ӨGY:q}Gr!?ZHX2 /~-C@61ϼӛlyxq_OkC??dIS65CO#?|}ōS@߲пp9v_b,u={K ;KKY@3iw ǵ@ڽG\]=Azmg&NdK05x|8bIY7Dw_~~?/}r޽~d-Y#Fm5럿ۭ|yqO~пZ?v{R|7\ԹͶPSOO]5Mkjv゚zDƋA[Ndڏ3h~wzr|~gZOY">+;Vk:䴮ug]geuRCg[=Xg/W]KQ/mW )yl#]ԫǻ]ίݩ]xmc 閫?gMגvS<8/UKD[|"^k\ʱZ'{-~W}of1}[>ڶ|*I7K?p|[/W]WC?w1'Y?otK&Rn=CޗkKҹJ_v_ϼ?~msԹbK|Oݬs pϋwY:3.Y?[ЋVg~Z%}[6Yot{ĵ7r؃jn񚾡UpY}%nuI :9,G XFMY Iwoy]zUʍ"g{^ڽ/Źt^O]fmtZߩX"Ԋ:6%}q:~%~]??KXSOm%ۭ~k[zK?7Xt/q]{ 6iϜe.XTMcD|^؇h`[;UGDMת-}\&wHߚ\"OU欟6]gMSot+yzuRTg)?~n5-%_\LOk%h~k)sFnC/t5!K?ol)]w롗KȯW}R瘶:o'Z߷ҾsNy]f^?qY_ۀ9}Bҿ^n AG,U{_? %럡MW]\yt}[/f<!!Su عy|/Ͽ]jv^^fvzwK??o[]p9֩\m}H'_" sW,#;^ǶuIK5}K>`tWZTS_׺,u*wX.&O~pg.]wi@ T8HKuk!ڧ-;z->:^Y~2F>v^Ҽϕ]8hQ ֵ??K7]]zoeunߔ}=cD,lyĩ2Yz?Kka?d.n hn?=VAfkX>z7X~RxT?m1\/ tƼ^xU{n;#_j{w?zw[{768dLNnVjQMc'C=F>ReǿQŏaRi?(_?,%wU[k%ﺤ<^̶65 +ܵ=8/~??Χh8/:nű?}7,5ocKy Wqqu6t&\΃ޣ[jO'K?OĹ?C_Vhq16^ ?~տ~_=kٿ5%%Cת?둖?/ۋ/D:GuR.ocsL\7Ǯ/#su|O}/:ޗ}^;o4Ob>}[J'_/myG}8 tcW[ο3Ͼc)Y ^2\?P?Կd /m?V䰗 q{n- [%KZU~⳶j-ӳ7ϒ5/W/])ֵrM7~]:u=G"~UGr5ww}`ygck5큮QcmGȡ,Y6n=!%'!W}T{f:߱Kߗ^?߽=z?<?ߗsk}o=?w=um 1%e:X?_)a/1 [&\΋w?mc: :p[QsbMkzGM71>K?]%7Xk?#k⟳~w*_?>ޭEnoG`ֶt)x?,]]#fSת:ODMml؜6xⓥb)r~T6}[CoTpVn~ljx w\[n%]>Y5=.&ױ^|Mح1zøRo^yo =ڭi~; ޺ݧc+E_xxy+>?]}.?Zs*#EHρ tuN7(@cS:{W$@|}#qu o9p}^*}PƍW$ ya:yqz^.?VD2?%H0?wCL|1nDGFWE|p=ɿŇnoDoi^z[[lS9_'Ͻ*%:m8=JLn͂^r ?+7zn }lj~U|2L~*[o~Opgku7jޫ7 'M|xCt)sַϗŷ矡qAgjye{kI JOsw | $>S?GjBi} ,9]I:G7{냯_Y|\O/!|wg<7 q=x+Bܹos={7`i7ZOql)7Gju?|=$pItџn9O0L ?xS2L{yI0^п6<=v 9 8w7^yz S|8l[FoCS>||L[OǹֱC oTr?3A/M?S%vu{GCz;n-zr;s;OhfyJty#o'tޢr%O 79sb?'0iog ۺmnzsShhؔdR2<Wv?^'}:'96n.u nI넹x~f\n7DWq}kx.<(xi^IׁI{ 2W ~&_8syaZ._5sN][9^ǂh=q8qO㐧Iy+_9)Ǟ/x#=:$.T E?xZ'O}q_˕멎VZҼ8i)31Г%}Q<ߡ5{ &iv]MG%cU7;'$t}}˥0[wuܖM$WǩM7' '=X AxqZ_V,E^wuEA<,iPT;=Nno ,'|FX{\/tT X3ՠ맂|+7NWB/_~rOy4>s!|K|a>pP< 6< o'љ>Ny%W.-:[2ǫ>uE5ץo%]4Z~vIwtY/3ۮr_⧬OIg.I ~ZWp'bi?4a^nj{ב ]<1B~o@u) ܡ}73֟Bhtx>흧)~/tr<Ct)g .?9W`+87?[@Y0<9זm<\փdO<.II'%{a[Պ6@uΒ<qO<^?gS}tuQxxq ~Б`߹?Oj R1=3|_0;1] aw+x: |zR@,/`Cg9'9Z?u1OJT0|p=xpѪ1ˢ|3t%~]v.<::i6']5]گ1λ1#=_ܐu0'}J1x%ּ.ˢ;?|4Ogx/Fa8+_|8??\OJ ]ڗ.|⒔<|Ju0*r>9|O7zΛݙyMǑߖnunSY<\.zגlC~ z=ul%G;_~MWZW%}x;n%/m O0L $@|A7zGk}}WC~R09oK}]Ϸ)`.?ϯIOә@4'GZy=>uuKtYmi?ona;‡^m%>h %&ayZFN/|<屓޴cx*r~gqi}+:!oU⮡~׆>wzߊo9v}H}:Ӿ@ ØD-go؟BF~-(>8zv~?^'$~S=ׁ/͈. ޷O3ȁ<^>c6;,ϥۢ93_iݕIuir.-щo0-oKy8Go['-8S~;qY=J(/ ŞI)ߖKdiې!c;X{!b7#~̧5 .> C~BNN\+y;gK~@緰+ܷ}72}Aۥ]yx0rTPq3覽g)Cs|B(_R.}|lt~:%GtzPCQZO8 w-u< ߐoȇߪ OW7Η'iOin{lZv:.?7_!9C{g1ݶ~ַˢyA>wΣpy 둮ot\=z7_i:Si{ϥ|)+19%=_Ys)W^Nyֺ q׍@0s#m W 8CD_k@ͭ<\72:.q%zI܂5MO\)r#تJy= ;qoK@ҟ)~=[_̇M:pޭ5.7_IG>v\|q伐a/7D|X_rg?|]t{pљ;^:t73GA7q= 7R{y>~3ԯ9{߉®CŹNi/g7F7D0㺔P37}N$/7}Bם~ӝ ybO5#q?rxﴟc~?hߊ[}m#?idX)Ϝ/K1o}INvX~^iп/~wu~Fz8/]o[`:PI;b?p'7$O|\߰}jǡ5Χ0M[-iF1m[? پܧqH3ivc\_8q8ax8@[>D3kiY\g+yq=]蓯_:^w 9ZN_,7@؏,0o:oOS}Mw3FC>Зy./'s躖j}i\zosrヤ뒓7>^;_+_f%N˒ hͷT/<|ohԸ':SF#gZvi %]k${y {&~N~qn^=Hiz-[Zx!OUHLyWW/?}e_lM_GmSz|w,h >A] t8 lw:=wIyὡ3t>?O7K{^wz@q'.HNCm؛zyo%Iu5ӺΡ{}9r=[T:۾iٻ$o  _xH'n}<,p߇~俿.c_v[ $1hoB?g+5 #:iR/{RZtC9~3gOg8W "<=Oz}q5؟\ "{g?Qi^9(8 O?&< "~2~0kɿE|h>%|_ )y,s'얳zov>Л+Htqu-ה<=n;/m=M0WZdy)Gp>Ir)s]~&gx{?/+#7J{1>mZ8/abyru|y|@7~-x<qRDפTs~߭u{)}In ;7AAwAW3q>X<k⭧~~Yz~[_.1'`wQt\΁/i; nã+BG2nO%ݩ" Ǎi= ?_kqy@|/q:W'_軬?cƣ7LzטѢ;ѿ)}sڧto\81aNqxo@W`W4)ц0u;oN][>&тs3)3CΓr|k;#z~uN(?ۦAҺ _,םqii]:ƗIN'y9|SxJo/ӗvU 0w+߷>n`x@`{s!%`9g^^i3_@Z/wK<,aɏ9qJqS Zߝp=O $n7勾,S%y>N%HzRu(<+I:n@p9eH>s/xxHdO1NQ@?[9H<ϡ {ukbR8遡~r n?7p4ˢh~<ػOAI>']xI4UZt;5W?s r ;t7A3џ`˯ۿ@O.KI_UsCczSg>bZ3?U!v)UKoHr>[_=ssM,rN{jidIoZߛ^*,o C<~ /GN/aNww4e'LrmT r"w1<1?-|"ӪkhNB?|G0ΖW+>"E1^N(_;?:ZC'Z &:^8;HyQ^~$S!Vp䯊p@_d/I`x/ZON{x(dghׯyYۊ[Luv|%xE׳>>V\;:$ !<> >ᣵr?|P(Hp~lӹGi^^-Ϝ_3k{t޵W[늴;=tN0q8^ZM{8rM'zM[n*3;%ߤ-8ߣ/8G>K͝-'@?(YD17Gơe|oMXLMsGץe?lR^%di⢔KoٽW+|VS-93@o籘̯jƇϱ8(ׁx>z~+Dt:8N<}я|o0 >xLpYS0 z+#?-;/zW!3[ ,:R΁Ļ/;ʯA }GX'軨q>lry<7lCO|5Hp]3 9p'`'9BY\l}n|q?ɟ_z)Gy ùu "c =~ןs)/yp^yyW|_ Dw׽~ov!7ޞܲim<[vq/߲[yV$Һ:У˒Oz,s9?vy\~'<Do<ʉΗ=N߉ps/}7'mq~[+uq+ %FS\<7jg=N4t.O.y'Uq*zH'L7|,'yR|ܿq8[xXrJ}ȝ}\{]}g ?=ގަxu~{:oE;yEr8i|/s>]w&寜 ~w_3nϦ(C =O>z\\/~??v0!ݗGWEUwg_|XNֺ7C-1:9ODk_dhCϠڏ7ky|C/`y 풼Ӽh@t"w(<ʛ@[v ={۳|nK/Rk;>eϏ+7?:i7t!}Ixf9O)z2~[ ?n[ߛ'ѳgtno}w>hzĉI~p7D{ ͯթ~%n 9<^&ckx%~O'ZH퓝I ~WHۛOutiZqyLvr[Ϙbn}{iUMw)nO+ӷ./~'=k܊SKqЈnuy~?)דzrx ^]_ 9-̧7lǀ?7M#:^?Tg>h21^ t8+4zs>ѿ{+u$~@tX7ϕqhNv)ه4[8ժ'a<\oýnJ9ihϸҏ[)cSK?KKAvGj8wԏ>Á7u6{#`O0K~.8{ -|CϥyЏ"n-øZ-;?Σҫ4?̿>i_g ,3iyn{qNa{U?y_ t=/_>%K/Jo}8>9:i=Aڹ'ۥ}Oz o꾡#qtK{`OпKK7 ; ,T:_h:Gey@)vmOyI^)^ןH@{(|1a+ןI_>@wb[!:, u('h݆ow4)e yN|6M yiA)kC5OX?=6Ioyx,GL|Ng/oqm;>FA/)R";>ܐlol7_#^-3^|!TwEgs܈׽qXs;1ȟt@g0?/SȻ(}ʴIyTd;Z>я׫\ o1mjH[) =[z?p>r3_~ysnI:xܬ֫oHItx9OY_w.ۥ@Ɖ|UߪKy^AҾB_2N^W^xR𤸛Bkߟ:\9o֫%~_CYi=a: ]ǔHߜWaz^yo#}5/ OƑ)e}uw~O=otӏ3&{$eݛz0a)oȩ1c gWCnOσ4^ab] S|w >%1VgqMF\4Ϡޗ8.GW?=LD{K-CkZ_,/E =~Z{y#hoC;<7~^OwNu_mN.c7IS͇!c9 'rn˔G ;W^Wy7^g5#}@_A_k!}@ߞS4_7_IyKE.{r?-Pyfg'כ~5;</)~T/ت{7~M BV#};xCZ|'M)c9@tBb.wׯvtY-=^zA{=|,g}m;r$|֗{vGkOGO;C轸cvw1i[y ?w'v;׹_ t{x=_!푳YMGnIZ|Loc<[)? 0~St&Mבw$z^]KI߭71=-7i9|} Ο=Wsr?\`G=OuqU牾II?u>w_# G,/Ys77;tSHL0{^)xPq 7{^>Bm-{s7LwZWR'nǁ4JuG{Ov(ɋ+#WCWy}|tzL|:q$=:>8'XDgJt:zO| xsOQFoKm7C?/(|>Z> C{rGZ}:6/qt-XzZy֧, eOk xfo| ˺h>ϾykɻEoc^zh[Pu=85_ćOK>d}?QāW]6,̃oJj8:~Fv>@9۝V>MWu~,yX.i%KIyily8O4Doʟ}/DGί rh\{ӛ?mL|y>Y_|Jo~Zc~ͷ#sqk˭o0Lj]}dW7q{yJO%#~##K_~/^8Q|/8^. )߂/ Q}Kނǫ93^?Z?~ Lqb(?S?X>$nγscm<\7 ;~2 ߳}C|D:d'έ3wLwn;rY]?EOI=ӹ~$7-L}~ ϵ@oIdkފYNKɾq'9; 齶džGzijXxq?Kui}Simq57 ։D!yoV%ɉw(9ҹ;.Ja{' |Ȧ0F'?Ag-/;NQ:)N$ί'=>{wlyϕw,vS}hbגo4^;u|} yw.-azs{)>ږ>Gvx\SѧAG^2]~#I~ z~$>R}"]qt9tng>n{sCsn)v|XSon~>ǾK Lׁ{A?tqz ttt4\G@;1N)Ӫq$%EoS>n/r,yI3OZ/z<'~hc|q? V}[3+ Dž$m';03ڷ/)^~P~Q?+wZ; |a_:_ݜf)# :~~$>UqLu,|ׁ/wD{4@ >v*/?-BOق7"Q4ƞ8i1OP߶W]HĦH;;?w$G1mҲi'_я!?|0>i7Sur.XY_ou ]Ou&nyHr<~+Z0k}wSh]rvzCxܛ?(?U;}MsZ_+']'s]Ȼ{ƍ'1;G{<|}Nx@_+ofc|z;.J0>]I풼Locӊg?x%N5ݗKdo_@nr+_˹'GC~<(It:=w#C{Hӎs)|PkyrO~9^&G{E/Tׄ<%^^)2Ϻn;wry.6`oy\'@~NI@lLk}A_7公EOc1ٱi<Ӽ}w gaon2_DNm_O ݯJH⍥gcWז;w!tY?,ߴh}v< x8_y~$2sȴސzX_W?^z!W+p$Ki?@ C7:=A){Чr}r9|Bb^$:7K{COC Iy4?@z==.gxxqp7=~ Z[DOr~E2m_+9˟Λ?_wtZGnַ[OZOyT?l\}HzߊK7n9ڿIl7SY tiO(?#k@ǕrnH8zJ/_<>Cz_uH7<:z\<_]Z:޴\:&yWZE>%:wͭol六ΓC?ָa'uK'_*g;}ۖ|(V4|ٮahu[r6?ǡ|&OYNI~krӼ?L8E+jwHt:>Ir2]sEϗV 9B~Ώ[_ Cܓ OSCI;ե/qāױ_͇SE xֿTkqqT2ͽv#f=p_t~%ϗָ@CzҟHy2Ο#t>7߲xS^.΃$[y%VJ0񂾋%q5~$y3'amR=V멮}Nj)~v~vcvO u<˗E׾Ck[>uLCYwuxgWlxKC>0]3Ύ[]t[ge;f}}F ǤW-ki})tSXZy*m}j}qHxP蒞1nq?}$/5,3Bюy]M`o@7=KyUڍya?go Ys-;2kҸ^Ŗvv).7~M+Orp?VX;H+WGpi:sϏ'>RZCeG'b'GV$9N(/|;ϖP [WxQ ?=dm?E)Iyyio&2Nί%߳?t~EʗءrI&~\iq]:ty<ʣxs3iпo~{ۧtt[Hy{$޵ z5 nioޖ^q}\ϻ4dćb>%˹Wvָ8χD幔?8g=^_/j<OeOJ/<9uACw^0w>&Z1.:mW[S=IүTo7|W-S>|>͟= K7GzT>%+_AoZ/s%՟3?%>j`>{q~LU/tXrC:Ue$/`x:w5э>C~ro՛7izg$#=^%}xu=apV~'C#[?b݉y`:|'3X?ojR:/K#~yЭ<[+۵dZ#OÑ+ rw?A=uG!.qvh{;_O}u;@uq|z%_Ͻy~QDlG<_뭡clM_o_h]}rDo8*.hӁO[xRLLw1@3i9+ҟV~<@e=ZǾ|ү{G81ʯͼeU02FuK^z|nބ ͧmόgBg[1g̿>Z9W۩z}b%:}:¿3߰ z Mz9^bnx.Mw{ &?f;qNMur/D;ρZ߾nyy8@5o\GW<rizsWtAڽZ+5?MAAE^srG}9UnZq}Hs iǸ$̄ _0SF}^ѿ N7??՟8o c+ZsMapyHvjҾo{0Z@q /ౠw'#?pnTG`|=>cУo\yH_ !s7_.m+~Maڟ7@i>:>=. o΃7I@]|qC^.۪kIy۟dϼN|&a>nuWkHrw7y?'u-Zt<1"O4R'$/r/u~'88s{nKnOA8ϵ1ϥ"ߟ >{ܐ7xyA˹Y d x$!||8ɉDߦy+t>W _Oo2>?wt;mͳV1/o9bO[ -;g:tG,;3Je9ӑ7LqR'xZwgʛ>Fل>zG8ܭ?s$I |G!sC:~.]s믬.y\N_ICl''Ivw]6c]t>UgA34Fug'vvy픟2Χcɕۓ߁ni_.^y8 8=rݩu1|P!<qx9$zo͏넑7$a_*tR y9fz4o 6._([4 Gc d/op"Du^oIyg{,t~7x>/˭yk=E) oaul@~$oINX}~Umm1.w9Hu^ޖ~DwHvjQ̵?I@w}?{~nAOH%?D?'x~]'WZy"5 aD_ʧ]xY,Wڻ;ND_i7.cV~v?=cm_i?/=4>G@3#ݿ.sgq|?~$D7CבO9iř/?췁)u{vc,TG5t{Rs XtC}}^A^9/pDPә|u\,yNqH|Y<Ώx@?zlzr?MS缵6?3s(o }^&[gAx?Di9sc?PW+ }_'V|Wy_ZD|Ly.,S—W|^NW9^"y'Ins,uS>5{ӝ0YQ5n'I.g8?q4^j]JyM#.R|`Z$i=|O!M>]=ҿG&ّٞ 6A30Rr=]I?ГE^"[^~>\g,zEѓ{o9z]2w }wx-wsyɎX/X>֯4}R?!>KѲ{K'/Kx]Ǘ#Gz|#[zٔw2r}ȓ\dr'a~Asny?.'o+|-wLz}v7:y!Fw,ә(79Oqr|=r8nkW->| g몹y~ܞCPzM+8IXS㖃zz覞gyD㚞R}Lw _3Nަ|וὨwkS/Vj.lMMч{o k}ozlZe't= |uq+_C}wَzGuyb[yu P2>ϐn{~x\t!Sk.u9y=[ŸYCH_yoɓv|ֿ.yK3o^ Y~r]֛~~yX__#?<бW tA/p0=V~tX UvH@aGC]?ܐ Τ){ugOR*qAWuQ+KϝѺ*8w>:R]uio>~r[w19[|nuA\zS~mBX7ɿ5.v(=n)e~8Ot{ޚ8:ϻn7Ekߚ-;űs~ >LYG^Wu\+qO#7/>ܞi?Ɲ~/哝\#?oB^__sSZ>I#fmуk.o4^ $:}?cP6^aZV>;֣7Y^yx~lY/wOkg#~>ZxO^֭; _}g?]pK7@o>wkqa'zy47l๤sN)+_=IRݛ1^Bzs]z{ܠ3d>Ҹ._ֹ>)Ks5Bm]M= ԟ}y)v댾3Ư7]-H{rw '{]סCr`3z>ŒHtZ/[o_u ׵h|Fy+Q[8F:_Lu:/%Γq~ y=9y8}>.wqƋysQixx~F_:xvzTd>?:q{Z9<9Ks sCQW9dZy}/+Y]`~r1_ %})R\dh,z\C)s'm8'@R!~x@37DGZ{땐^/.1>^_'=|NӛX;h<;vqw~hGҞ=!_u{B;)Qi}wy= 7׸X:[ׁ'U9m: ?uK+K!^'qHy3!j==o><~Ey,]ad;ʣH=Ҟl'Sh+ H{ˁ腮dL֯DӒ3s]zkq܀-zSY_Mv[IO9C/=r^uqRiLO_mrV^4O|88ۉy4|N&?b/KT7ۓh|V7?tyݞF^4M)o[y dҋ$<ntjoӺ}G=?=_OU/ =N\? [\׼Ky4O[}K+Nz]^8\F| 4_ :x*nܓ=.i1*\ѯw^-Nt~l8k*.~Bߟy_* uoʣ9Ôb|y׀{-=7eG \oV?m}=>ЍǡE?8i)=ǹzˎ{K͏^E.C>B^ }~{+R~%S#cums-~,֧Dkǖ>kR\e~ΛvOz)Б(ZSyC=tcGIOOK>^h=^ZOZ?y]W/<WO_GF9O7Lyߖ'yz֭||iA'剸o9ٞz??W^z'HϜb/kܠX<-TaO@/uTw/sj?= \_,?է^SI B֩ |;o77cT<2ʇ~W |;=WA?ӸmϗɟOyG1< +~Z+z=[?*v!2Gj{GvqjwnOÞ >a;*7?Iu@ 9ץW@K~-$+饽N+j77.4o|]յW?W Z//4|x47-r|Nֳ]MM׷|Ə{>lJyjgzG 䟓z%hAO@nu5[y{,|kO~|'q}z]x9љvzCwMbʹog}|]z|5r0no?׌H|8qs#RNύp'KyMm:?cra\/;iz'?c=JY4nxv=n5[y>G?[/l[<-y]q_@[Oy{prq@_5.ˁoE+~Ppo ffB/GW_*|HYoZ`N٦oq ]/tNGyEA/0/(p7]X|V3@} Ei[i2ʟN o5ߠVZu/|o^_)70ГEq3]/l M!/6M~YYNƟ!wW,fڏx^8hՊ;[<32Nwϟ$os?~}D8A/lӟuZ$ZvP }I:yn>DgDϵ{nݪ?q;o^,<ahʗJGn$gLZJvS>ǎGk}Ok_ߓm׿'9IIOl7$_O|כϖ>ѹ@UH>D,ۇ׸y?C^H:Tx"|䯎ca?0x[О?s'Ge\=#s~z^eeև)7-z/Lv԰e~vvSj ֓̓2Һ3_lZGrUE0/>oO禼?9݉Zt/܊l7 '~ i/Q|?-]Zg_ x?'YMMW9q鷼mo-o3'>6Ӻ~% 7VH;r|=\ \ݩq?=gܺ7Aڵ0%M_ˮ_58Oɯqާ|PN|$.Ȥs Ӻ?= v|7uM~/)ζ1tyB5tb?h' O }}ptsi_OxWS}q=Qxߙ׹So|a"S ?9i?qZy)=zO H;L'|$R|t$=m}r-x#v7Շ$=Zy/ t@Iʗ? ^-6+ڿ8NK%K!\0:1Wk?q"xmTfdioc[n%WSi1q",??}h?eݟIUѿ!槥οN()o'[nʗJZAڿ/?ԸB/<|v0zuC"'K;Cq)Fߐ2xC ?Η8o =nI?~ys->[s(y!I<j?W֓t_yEr[zbh=K5I+/'g|ݦתBޗ5~ƛoW$xɾ{~:mk9~@XxA{ ]s+ {Cnz9cW#ԟ9uߣ&הzaO)޵^Z?<{=PϐCM?loh-$~7*LI+yD^^?ڷl~ơ(t9;ʷj:|:_ͺ.x|$?Љ~<G+^ %8wmZڮ?-y[OK27Lo^ܚo'oϥ')Y)K?nε?2[AҸ'yTKᡝrga~ySW<ۧןT?$>}/g >gN|V\ÑO }/q<W z\=ަr~W ,7M/0|{iN<ۥuLh=C#Պ'y*cz7>OܘuOsQ)/@t6m|%G/7':]J7{{w_8CП#͹ćVWݷ;y)lC+qyHCo tẊ˗z׉Awo/y>oZϐTy}gDg]yp?گُ#dvƟl LZo8x>$? K3iOEC?KK_̗h%OV'ǹc=?w7>O8L3e%w_uA_]g7Sy {"z~ ~t׏ U/E~'0+W:y~=zLrn'l}3]#ϛO_}/u^Oz>EPtߒ~XPOpn~OL',z:yhg= -DlՐr~=4 z\'#>O0_!OYnGj_N0xaO1~U/3@ g}txP[/}oW ؗ#q/0}L}=!.uxuz+ʻQ/}!8z=`+q>]];bKiǸOomAƃࣿޤ}D+3"_XM?0_E\_9<חsۛt'yx<>L%}Izq8йHn'3z=.s}@}~|:OCr5n^Bw[myσ/Յ@!Ot:&_:}p~rHap@uL/p~%ϙOzlO@'n4.f^a/%>>"ɣݦ.c9@qHuSt u2<7O+ߖDgi6]EFn;O1 Hsyx:_O@O 0I|;*G 偠O'恰)nتzf4WM`ˎ>v^?'=NM_k M!4IW4Zup:|$;x,/- y=o>y>$>lw͏u-⮔JcAS=)nvs_|S~)>w<?ߴO:3;yLu>̼ÞX3=^ t{]qH 93oyc9oM˱@7DY,tЋC=M_H*|]o=p!LX2|tܑ<-DtTOCO?աX^K&i~gTyj9_ssJѭ+?<=w4G7?7[uFh=uocuqC䎞KusV{~CW{cgIqy ׎/)p% y)뵴NrߔϛMf\[u3s}O۟VݞLJ0~'}I׉/9yھ^n@7 gjH5\d2O˺s؞Sx]z.i{ ׯK߁7J7v;w ~xAO;s#\Oƛ ^wA|c{c=z.]rHۍdE=}w# >sJxO7Tg:L Ƈq#=2>W)[19ɟύ=?̯ySq_~k;9|? ng~?м548|).Kt\*9'^}yKn.3LiZ&@K.JrE7OGuSև[N{(uyZ/_־Xߎ? |]Ek|_ps7}4o<G'2'74ů-n}2}II-y`ƘVv|XƟ@ӗ[oɛi/㺧k׭_I|nZy#\;xHqSicƁFz^'0wAP)Jy3iO)u"|CEOhs}ۃ~כ@k;~ޔ}"ћG 5#yq ?γޛޞ)oӝ7 s?E}% EySk.i^}t~Rn:?7W-q;lG{缰e?=N^G=VYojڧ~:b@K4έuy3.N;~:;-~+Г{>}O$9^*tICʝrvq}{YpC:{>tm/r݌N@ۇ$uSE: dH{Ki(<R ?Ee-t~N>Rr@2~;~v6:^/~zoo+⌴JyU?7p(Kbn~7?a޿P3xxxhx"q )U]8^b쉞4OLt'=K^pOϭ/ Zni>뾟Cdx7_Qz`KiQ}n<0tܯ{In>OTrR`g@BߣOx]Z_Ρ<D|8Φi/sӉAn)?:6^׵8'rkQ5yv[OSފFΩG`k^q'T9kCqi+c9qw G\O뤼ピwItZ%INszk+͙u&Q^>ԝ |h|7ߣNr Cnu:_< 0^{ z?䙠ة_*_(\䳾(X.^*|HB<['S/ e;=nuё?eL:c?@oz?wkh;0g{>_k(1nD{k:/қJ;xmZo| )OÏORA^Q=.^u@?K zn], {[>1>I}G%;e}<?3'1]I~R=P/η~za =nǾޒ1t̕ߦJӝ?{/׭/IOX˭Ҏ-=MrKD'$j~x|U+5?$?'븦iz0 Sx\>pB}ߧtRÔou8J^g$OI?q>/$~[A_xHo#SW\G[wG+lѝ/[ 'f=oŵ)G,WәAnos=A >ڎX֗d7EZAy`:'?#~₴D;Sέ/dZ8ȼfx~8[$~tmo w~yK9?%-_5^;5H <Ϟ' Q?c@~ߏKkyU`oIu]#9a}W||Ç=띿Jvz>;轨T?k1]i_rљ]Hs5>9}JϙnskMBD{vݽG稿_vpt8{j1yY͖KX#Sc}׵z9[q.'}q;~ˣjx!%7N*1 ?oZ9+!ݴ}r!?ہ#z;W_U\q9A9ނU9~W/](k_g/Al'..yc͇t^vI|ˣc>ڗ$?W㤞^g8NoN}+ԓv]^Ϫuqog{޾/߹Bԁx։zӃ]Ճ[?_DO7;QNn{ v:o;/~nX?+~3دHiͶ=r؞G|}}QK\U/~|{6/`v=vQ?>i7ߊx?5IotwRdyد컿d6#_l=WvsZݟj~\dezփz|>\g:ƶ;3v  t波\Uv<'z^ߕ_(:nh?9'g~yzMRdk'}zu^v奞 롊 ;ڍ߅8ѵ!EdSnmީ_4{__O8mx[ƭz|%bq\<='9įmklŝx0N'W]{r?;r?j5O-⡡OԮں=_%8qפzsqvwvi?/햞l/ ^XN?WiHK5w*Prym9_*Oe~T!XCnu!/a8# ϸ#;vM1vKw=mu>$Vߣ~~c7nǦWNW')]/_]Ἀ~vQs,;'}%OGۮ\~31}\p\B=ާ}q[qݿFydy[׿|OG;7>[=]<;`=8=O\߸rw'ƋI\wq;֋'>GruLPhP^}ߵ~śO׾ov^3_<C~^٭zyپ#zw8hkᗗŔ_Osu'E㮝BKjs|DyGUGqT?zOǺwrpֿlgvͻ9q0?tY7}z y-Sպ~v!Hm_zsg=*8q`҃,5lg9t:u1ǵٸ[OΟ]ygQ~.ή*F{gPwDGs::?V98*);8vEwC%g?/6,W5q;;w)ڷ.J}Sgѱag{:u.vq+~N}f;uEKetv=?V)n_߸p{?+r+|*nTqE;/@}IrX<Ώٟ~ַw\\Og<iE?'ޅԇ)͍Z/iW{NP*}H5o]y7t;;Ї]N7O/*MU5qz ӿ_nxqE3ǭYOaweQ>~sUsnr7΍}Uj6%`[rk'ՋϠO+]gv:wE{D]8|㬋3('7>7K~;;Ng',zc<\dz\8rzx^T4>և>|է}wQ҇2ǻ4K./ŝt]pxCg܅gý_Ǭy{δs8{Ne'E`\FOlo.d}Xx *g*/ssTvߨ?g?58vs+qWU+"󶧰Y8>;® vT37!lV~y_E׾p/tvzӦ^.qmʻƱu+и{ZP~]~Sω͎C} 9\W78A=%!Y*1ݲ(qe3+/!p?B M:8Ajg]O?ny+_ 퐎{pg}<ߡ< yx}xԝ,۽SSQ;[q;Aܐ񇯷uv*NW>iNS(?p4rJY/|>{A3~bwv%{Qgot]vs!:v ~ {ߐV:?Yَw,a7׃TygWA8Uݵ'W_KꡲǬkY~C ??G}KWwWa]_vVw> uQ]}WY.^?G\ߣn|=|(w,W}/w֭C: c<]d[ם})vqc9u?˩K=rN\ఽG4<6wzqP{ѨG/^|׳q]q ߂1W3rQyhOTprϻ86E v?t\sa\\Mfonjo\8Me}?:~:ƍHg\p^.{0Y6W'[q ԏUy.ם'M/Oqv_c_Wnͻa;xtq)?#s,V8lωUšt]~9K]bþQ."Q繟ːvi?i~is o|t_:_ \;e;y{\z2^-_q{U?5[wW0a7WL@Зa*8=(jiw=|Zgsy!'_WXW>W>_\n׭<..RGu/qX1uv<;+'ys8?r]s5wW:?wqk/Gs>Ww*^cNd۴Sb<~]}5tuvi|:VqoփXSN8+~ܴߨλIq^Tk{:~rln|dJiݪq59grsXqqu`kܸ0*O? p9r;7T~VwaGm. =O͸s~a?!vAU!ߕ-rڇ>~a5Ct~+=9П9t}T+B<#M}n]0>QY.7_:wgsx3yEө:_|f~r~e[y+gUO.7pWsjO X#?XP*>D]ɮv~µCO]݊No>xqC:\g,lh:|pqw{/dwivIoB:C{_{;s|Gw?ry?zr*]w}W 7]>qgί>}ԓqu黗.WD /pg'.z <u^};C2^YƟQ.)8na=~q c?qr~*NcS]O{Wqwվ0ro/_>3պƩO:ڭrTn?x{f/u߻yOX'guO]~~_~_4=oNc%tzQ]_grS:od{hҝr>]m?l}}G}voáv{ھ/_=:giA{^>{~+NE6wC>W՛Q}< ]OG?]Py)׸?H?CyҎE{:Grq!կx눟Uks~z}= s~vzg:r џxsUvخƍ>!/ҬݲCW}Zw:H}ԕv﫳[̖W煴Nw{WՋknֵZjQ{ʬU=Pn/za_ƃGhvu4cܰf3mCNkaFfvL?~on\g)lxIa{Tp?;׼٧v}eʧ{=b/=_dy4w~!;|;@;z*ngcGБ/S2?kqL_yrVٸύ?N7>_{k3uW?y0k:f{9lRwߵ׌p]k~kj_~3צT}3;w~sN71PEx5/>8?wUn>nhڭ뜟]=*7ב?yTXf7x?fW{.WhWϠtiy`>(W;_7~QQv=4}W?V}\n_ !ith:ߝ'?!ރǰ]ثvL:븵}U\h~X:/װ߫~ K?ЭʿnO?Ώdu/u?h']?_?xoUGTQvr=vy+2n/0,'?nS/D[n] k]py=uO?V=_kq ~W Ue/oWh”ǕKd:nG.E3:f{vؾ0?7.t`~ 'x'{YOu/:V?en?n'r~D?읥?U^sYԝ֕]~?~w\yW|QἊ/=k UH7t]ҍE7}Eg\n?#]ߑn|5~G*qwܔۭ+zu:㠕Xq?>$uu~cS_=>g5{yU{H׏9^`ggy+8UV~xHZ[8V~۾\(;ι .~@=\AH/~x깾.>o]4r!}Q߅4\_p_tFmWoynN.nr R=3x]8/~ ymNQ;qV/t sA e9ɻ=.C}WB:~A{~g(uaݻQ~qQ=c鿻|Zg}SsOߕ?|_hU.jռǾGrr:izۯw~<eArspW?*9?We9ϨEcu[~z[ 3Wsj=ޖyVCBǺcg}|\;}λx3O8K\O\̱GuW/p {9|Xoy.NOxGv?d=~B?psl񴝗uwv:;?a?dq;8t1T$@w`,߇(׬=?t[nH=1sS*Ip?)sqck__v5ϱ/w;66?1cM?&u] O:ˮ_=E_wv6}7ۤxqv^qO}>=տvyOVI?"(嘍 ^OSM_1Ǒ_%g/YWw_S},쾟x#sKrW=b/7U>5%W~ E*tz]ޟc?n=<[?Nw}o]WqVs`t==jtw~qzt.~=wd|F9yG~}X: QyPq ?o\9:}5|SlܤGnn?Wys嚍sv.}ua{λx9NH9^wo?r^ڗС/9pnU'gy]<^_btl9\{-θ/[ M79ﺰG.Vcn8\zkⳲϹuۇK*{f֣ޯn?+_ٽWtv|mA+;,g^cN7>/ٞfU}x_p}*y;TV@N p qک{Y/..˸-[W^wʌ/k߁ ];|lv}3Jm6^ͳQ6U<ۻO3.8|8Ug.u(׽zsD3fx=]79?#:'~߻8O5qx{1n#S,ב!|Qq_FE+s~k{{nQ7Mc_.>lu>az9[}v{A7~tt_]G<&UlƼ6+;OkbVnͣf+,|ψU{^gu zxӁ5{/`/$e׭'I}5 ?'f|_!:c;ϳJwc#}wh6|/]wcBu?z9e_8OQ}0cD;i?{^lP{?;?b~@:i{EӋw+~ ו=i/J?ik_N=.?vq*޻MGw٫y8Yrx6yy#ٷ ]{tL~l>w𝳦ܼ߭OuIO+{5=s3.sj?1`&`g @G<n};q俛ɸ/=_]}2>m1Oվ]yyǪ?+`y/bPŅyow9Nr~n}WqgXo;ӭT5ŧ]?s~no>wry;.41wrS y8s&qa܍]*4l/7Г׎w|by{y_\yn^:u벊/Mwo;v϶7<㼝yAOntg^G+y{rd0nwGW8y]2n->^gh7uu:~Kخy5<> u֞:Tf=nw7GاN׹oKSW Xo{ǐէ g{Ky Vy\^Tu;_gǙ \Ө?ivQqC׏<ԑ?q^G:]}YVv}w;~W=..OKwlo.9w *~Kd#Y?=\hl',_5e}=U<*^g봿Ub\IW<˕~N*^BҞַ~v8}gtq,W,].NEsf}^{./ ^@gQ87g;ήvy3?qqB}U|D=h \w̵KUf.=_OOuqNgiitdCg*#޿ړUjh N^U8'8]uٯ^@gGf9c\[F0ʡ1)nWt[?.++v[]=b;ցnjG_\.>Ccinvl|My?k`o_sS8ra^;?uC^r>X.m]sߺ~<7q=>q_c(͕Q/OrݭwRW;7bփzR߭'E:;\\fWWgϊDZݭO uWprݠ.ӝN~e{E2Q[۱r?}7(ӗ>U<9^6B}+~\\/=n_As#r~U\E>fzK;hlUi/Oj")k3aXi|SJqq UO /*'ۍt'̖dyq^񓯛݊c{[yΚgb9X>TvF7/zqqW?,'{zUq+]yXWܸ#nwq`yPo~\|7lʟtVy^t?پi׊NGX9#Ks}K*uAuq.ʩ>3}.ux2:r>~j..Tq׍vS-_59%Tqn}ٮvUln_{i}؎#3 fNnz%Ykfv?\e'4}N_~]޲ߝOY"}O?_W^u!=EѸtwn_Ut?yM`y!%zgxOo2~%G溋C;_U9?T8D'뮟Ǡz`}ϟGm!f?c`yX/<<Uwٮ]g?~֋O~˿]9I_=ަ~ʍ,5sWqõs|t~S2q=r /v~"t_}&I.~(;Y:c֗k;yo.dh|S9ԏ^a>2].tjo.Nu }Ers8Q=;&tq y="@r;$&e9'[|v+u U|R{OG{hOnYGq@8 ꯯P>ѹߵAGzݿWh'O{/y\=/m3nqJ'nt,]si}<'^N{Q;V?$D5ͳx/r=9?U\>E]{ήWٸα9dk+~5 /9ֻsO-y_!V<}[k?R'.>}ٿy8~/=urOG?yɭgz5^ͧi/d_>},s<9sScW齺92O?b|\9z/j:yS̳3.Q.}]>Dyx^3p8Ywg$$zᲰ:@}8vu{l=W;]~8;n}ѭKG(zk|Ǎwq:}z]17Ty%w_8Cʡ|/q.-u.=Z;\97=hӧ:u]M;y{v62w81vGOʮs}Gگ_+(߿ٮWywW*_v~~^Op&U9X3ګz_8Q/I__5E7/ayhߕG>Y伈Y79X"ٶzMu8'׍#gFwևy+/q^׹oEM??<|ܼWNe ucֱun<,Ojjבv_{oc]CVKQ..T98\)IwP|OvSճqnYů}';9㆜ήjEwu~gcnNYN?ˇ>;w?Ng3C_x}6*_屯ے\qcWdU)=Ǽm=Wv fd^ǁJ}BSP*:,Y}^lw=n~vT#\Wfq{ul?%}fi+Kpިw`73]o݇qr~rqNG}Wy]q{oyucߡi7}&_cG'a}ủ8GG/W0nE1?;!Ew^wo:} ˯E)EF^gv_yzstd*Տ}:a7/pf٥{wGL7:lT@ .E;i]Hdfixqc~H`?_hdy#s_|{Ա|~٣xOwqK^[y;^"?m,*w(7s< U'WlSV ~ 8k(ݙ'^>y~6/.?=j t^|b{K>"ϲU9[y{JBe|T>k{w켿>uZUֿgcQ[wWn@oZj2[+fŮc^tWoc*~cWx#~ӷqk8yݞg|rsu{CCe?5#<.rFpOjCk~wPtǡn < r\|+'C;e[o4Y_Žshsߗ$&Ax1J*Nc97>+GUD;;iQ?:nwW'~fxSr™MՏϺU3E\|M:gXktqͯ`'yierd9'[_la5S/{|Z*KWI|.ee{Q{c{r+;\v>oٟy).xۮ},GtQ9n5+_C)jwPndE~Jyi|r{'N|qSN?߮]<3đtKr6.2VۗlG͎g?*/\<:}bU.WNqwv*q'W깻w`7j83_v#s]uߕ^Wu>k\wSIF9 8+ϳqzuNr6.9;ނa?pUuֳvpI3\VE͸..̿R~W~ǭgy}M'Q;[ /֛kתEӑ羥xؾ;d羽oGϳ_lYpXW]<,'jܧ+;;No~~ D7/fEy+gTB?p[/P58#|F}gE{d"igvCu)D?ͺ[}VcMnv}^/Z_?% daUM{y^cƩYG%)';]`e3CIcq2i,fN^X/ϫ;;9p|8UUnwgc?&{ٯrVwat7ơV,c;ݼUUVvzN~SgM\g?C}./8ܭc7Cj=g|ڭN~=V|ݸ_]ݾwOΞ*N֣=W]<ʱ_o`.N;~+_6{hyWl箾I箻s]y\[ 5κԬ:V\KzƵsqSiԃWi?װ oyٻ︰~i_?~@?nf?Ƌm?תF`;w[7.uepn_yM'RW./\%+j~(^4~u?'=8[ < j7'r֏{Dm~Tۓm]gQL>fi7g~w;8iޯO.{5/A?G=r?fɲ+:zy=>~v;}]9n!ՋGuƷGv6j^rOn府ujTWO@Uq%7q@Z=cI;O]~Ojgwl'KSW*xnOnvc_~*<\rv/AOCUPUJ`9]OU=*!{8W^1SǩWny*ʩrV8OÝ>o˵_uqTG+Gֿڽ{د:A?;GW |aKS~XUA;uNLZ^ztvo+}$|/۩vtdzHWoVqiyA9`κyH\Q>,ӝ}KyοΎmװ"ga{-I+΋ԎU{~pR S3}{_o/q1W\~;'[0>5nz=']Qu=w@.QrV}WC:Bx뽽}[Y23uѶ_ <.SQXvK<熺sjf%pe;4aiλxB_,w?\w2isj?*#DÍ{nX\+4xz gwg}?Cy?u{G|7|ԃtUPPOeýߵ'_Acs]ϳ¼b:ZWCcz{n=d'MW^쮳ԗxux3+ݵ?Qz_#1.\ﯘtu;_O_^z-{v]݈to?ܶk'i݅w؎nj{n\'_Gn^E;7j'NK_Vy>o]Wy#]ud}O>>=}k>.or<(!d|_wl<u~%f&/S'9꣚2/W,?71y#ۡؔw1P]3s^쾙QN6O} 1qZױ3u8ry+rxg8eKSN9|U~ V< ^>~=qj~iq؍Uգ+E}ꩊ['^TvVv>ک9lh_;]=NGa\\/e%]| e? ,w?U~A*R;{e(?_s|;V3=U_7rnq$]]c_|:yҭxLt]?\ n^wxQ.i9h<6Go7@!g੹Ջ+CHWݱާ(8l\N_ݪg\iҗHwK;W^\XNwzm]<Oyx+{^YDz?[E]R|U|Q!T.:_~ʻ[]ww3`P}ns,k~վw3|_vH߃v^|n-7=zviHt׹ߢZ/QcT>})W{VoO_!֯qɽW{zQ|D\ya0T}5rE,N-ոcߣn OW命};5u*2k{Vn<ܗ+?1^*Սy1C]y9q̪ HfU;/zm=ZWo2Σr vh}|Sq++}42~5~"uf)3^k+8qϸqq|'vyՋva9h7:S.9*>/p'Gna!]Nnn^}z^^}v;tfgGs?~ܹ)QXN>K71Z_a;/74U=p?ʡR9]|wagc4i}:y<gWp;qk.]yUG8c>_]`9ňZ72C;][}tFb/qW*/)^Uv|t&گvY#U{m?\">ͿV㥛/Udw:s^|3E8n|sxΑ^=7ޅݼ>kgSů؟?.zs^+ݏL}`98k'"yv8i+:gu.z?/NAŁ:ׇ\7N7_pG7t tu$yV}<>{ԏvվ `}g<[nw7J;HG<}׿xA[qݧy㩱OOp,W8wto׭i׹G>>i׾8+ƏwT/vǯ}W8lvp=.M9=+(RA9/8 .|Unl:]z?}k<`c}s\ݼhv>V̼٥y=;#{n>X٫y"^/xz9&n=.+7KI7wAkvTWoyrQe;!.ުDO}YPcOvG*{Hnl/c{w&Wݷ3y?KЕqDowcQǾ츄n]+?=xwzGW\?w8n%us5yGFRgG؟qi:{OڱK~Y=٥y9t^tc}gXTwEgM;>.^#Ό";]_}OٿѬNU};ܿd9y?u::~U\sXitU?';UsU㈻R_p5ۍ8]oǜWeGH]`[NvWI?{q+ϬqܭcR}>>uESPR} ʍ~Kg^.Q?6kn>~nש|^޿?~RGݍ.дowoU.Ǹ 1_"OX?+rlvZI?H_|9hv8#7{_ ]Uk*#OȐ~d7BXWN;U?^rƧ{fr㍋9Id/z>ۺ򸸔_UKPX<7Fg3SUq1?m{o!XcG#]Ǘi^7q;?qƎNcg~ᄋ6vxP/!#_gף<'w_y;{9WAz۟Uϸc;wvItck/.Tiٯ+v o_eazG׭L}]=d? wZ:4vrtwWw o;apy1׵G;uZ4Uo~^_?m1"~aM}0nR_yŷK~z)Uw,<oƜ<_6yo9P޿ˬWk_'xT.g]?~wu*nN_}c|Gw_wss*^E}p;ܸE:{<]y嘶'~7Dnѕ۽_}w櫪E{nޏٶXw&ܿ#Sq;^Vѕo߸u8Վy>י𼾣vq]Gc]TOVyٍ}@wfyR~+]?rqb`m~d{]*ysӞGg~ ?ecz\e\yЕ]O|ޝqT}T9ntήGMnr*;=='5ྯ}Y#tcXo^Վ__vs c?ļr:&{=j;w];Lb'zwW6ﱿqpv|W˼1wtu{'o~ڡrjW&+æ{_׹U^CWXQ?odocuk]pfs:x~_EnN|~.g(|{ϛ?b=Uto.wWrT-_=T/cQG\9X/;3G'q|qOՏ]7?nezKgՎc5.ey;ogK5PWI/vgӫ'߸ͻܼ{̳~_++Ϋ]w>٧v>ϟVjَǸ}G: ͝3k߾vyL>N}Cȼuup[_޻o~~R;>?nu;Gx:߯y_K997#ݸe}w8r"_ͷ8OEKn=uy{^uv}N'9.΋Nph֧'۸ҏq}//{;N˹߻uAߙY?\:N>Kݯحϝ,u}'0h<+\??{GOd?7XWU8#;zގ qԕzAW /"+>[^G,]Jg΋4zοDyd똬[p_svzs_9\<+\V9{<*;ƽ^n<uXz=軌S;e7EgשNGO穗_Y{pWxyOUoԃv}ݺ_]j.^~Oǜ1Zt~Zh]tѾu}'ay_ ur߄8ÍNa?uƿS\y :|tq]< wP>)V7ҝ'G =.T>+Qyx`?iiXlhСǃT."~tW/ۉ}UTn`At~SyoڸOy+rr~ov4qi};nn`yy|>{k7ﺩW8v*oj*?o>sA7:=g8w.r^ʻ9ew?Է+rr2?̧yݺO:8Ir13kuO^g;}]so*$sS]gqlj=z۱iʥ!kP?yU;T>xcqvsRPzYTGP4>h|?\U#hn7xW}x?6wk ?}'O]n^0;Op'}kw9-7Q7_qkxg|G<Ọ0NH2MW,ea'g{6Mf:~cgڵ'aZ,/g6 {~cGgx~<˵g`*3˾OПXN׿nӍ|9^T}7o7~r6.>:P3Uqs^fԩ.nqcy֡wzGұC_rD9ΎsCs^ܯXW_٥;IG߃_pr=z?:F~ F}Ga<]E"ukvuys&{_l׫{n'>}H?h5}ʡ8fHc}폚- ~8ѬnֳڟW5oݯcqVoJ(l#\_SŬ#//gʳUzxox(inm ~ؿxl~g[U~)Twd[z^y쟨~%.VKwg?Q_qUq&WU?@ip}nk/.Y_W9*~|Y_߿qooߣN~5QX k6>SSh.8!EݼVnjk:?n>%{^w=Gg'B_UIrv=]4xQǴopO{t59ݶ;jOxv[9vK!ݮ8?}o}ߕtW?~ Շx;8+ l2GԱt:!;wsG9qrjny U?7v99γߗVt/\pthC]VCy 򁴏NFSW Qkۺz1;杯qP}<ݯr\e9ՏhQ{伷l{|%>ߩƛf>,=GX_j/q] Qk\^׍,i;fs:_:yCtazA]Gg/*Nr ;taKoxw*^<~0zݗxwI}cn{8u[n#/Gnu/u~}C{tDarUvW?~?'.zlcӷ}~vUݕ*o{8G ۉ:{㼘}]nuD7Ըzh69uN=w6?;jil9\|w=H=W+Nv0wopq*#2_M~r;iUiw9jx}X̃v]$;YxS]v|Uw4A㦟({>wtqy<*'?w;~zUx]Zi8_fUŭ{U=^~ۯ=Nkg=#;nNލ3rT}qe-!ϟ|qVvc|8a7gyȸ S4<4N0?By`5Nv}P_~վ/(ꩊ;1u h>8cKU?nc8+A~}Gץl3|wry_Om?V#X~[xy*vG{Omvվ;՟cX~ y ڟtW{׼yzT~tt~\7qμugwwwO25PO>/}y]ji{]ZC?U9H^g-fցwn&E?t~>Gy#۾8ĎߪݺԔ7rlW}_DGf9~}OkG;Sƃ`o_`޺%Ǚi?S٭~Ad@j[ogߩs^R?JGKθIG}'^/\;w:^]%증-}91Kyz1NλQ:{5{WφqY;֓K2tcS9T!qCQƫU5WS; gκ*{\Mǜ?˯|׫[x.{ra<ߵWwv:Xp<7~*wA{}Votj_ W^e?כSgIϹDS\9s]}cq8^>MSX?xeSN; ~8_Ϛ>ϱ*4{uh ZcO}~r߫~u^;4rvXqL'җE?[YGwi~Wu/U;~cv|^>õkSƛ}?:~rMum?qqN~ެg7vqu8]Tֱ\s}c#Vg?v8a5qZ~t₴ͻHݯu{\vvN7}j V{/9>T~ ?G7[7=]8/͇s6v~wLIj~X]=p {~OAspޕbUA:x\ʍߥ<￟~-{CCriӵWS}(N5?u羿"/Yw՟c&~ў|w=u~g/~?YRݼGqU{xiwSNGLwWY8oBoWgTt.ݽ;F﮻7]$r̶*NB{y׭=_lKw;<*^`9SثnOt\}G? xהW߯nwqҨqGjwc<4PΪ_tz>7nҏx5Ο{furcy}|lzp_~w߸Ӹv|ިF>h%N7Gq G{q,}t%<~\Wq+,ƣtQ!wp|.BH?]2byHp}%Wnh}޸nd\ǸOrĉy-u?|Oq'OgXN{wp\sޫu߽n<=?7>@CS߱~O{LsykN4A[T7/?uُ?0//5_*_]Z7Se/՜K7λ8߬WI u /$PN5. ul7}_r2ogr著1+;4ζ׭_v=l簿ݷ\9Xn3Ot~2~g6~Ul:__HSf㈴S{]'9U?杴Ϲ8øjռua|۷tzrb>psŤ[_;;zr'Sw:te}}=#u'j~3N{94d߈Aӛ߻Ӟz:9_|?8=P\Z~ ܷg /~5Ͼ`zG]72|q+7θO8J9jRp}u~cr<}~"G{_S\VzR3|GUvH(Ἃ=,ܻ> Y>g]纏e?$opl3(Q]17SKf֏gIOoP1kwU|8.^>~]fv׬;=]o/?q+پx#w}vrݺywݷo|UՍϊU\73fdy |x4E$LtgO~5/i^ܯ$:?ekt/y:s3'eGu\߹;yQ~]Z\>:w{*ߝ&z?ݾ|+w~Ǧ8;KVoz//:l},?ڕk7Y+qu{N=II]g}YOkw]|?rHoe~gϾy{}Λuӝ=Yg\ ;w}I;g܏ o79u7% ډSPGUei/WelϬ]<.^~{_v~_WnouѮ=1vz6Kg'o7Wq<_w]&癜Oow8ُ[K?w/NWWvUzõη^༛^ ҭ >Vy[ r}}y+GՏCd^Z.{O#.ᬽ+Dl<'v*'k9v,O{~'藴k~5XfAWH_9Ϙnb?Vbo܍eϾ]~Y7o[ qǎwcg%7_\_Skڇxmқ]W ]Ǡݮ{*XT!7>:&kcحUe|}?wTB]9޹pY?=xU]Wkw?'xˬ_xN\`yg0Una;+܍O{(7V/c#fώ;"'n~ivOdWB;ϰSRO>tn=9;w`sfz_|U܄@:=yz?h]6}lOWv#e/kۗK+Qv9qvVAOUy/ ?_Zsrsqe\|MȼgRձ'uM9>;UܸO{>΋G:l1y['M+Ɓ;=+i/޿:zg+7{62[n7.>ׯIWWqNwKgv걢ݭO|ѿ]w?,n]}-}v;NceWuS7cjvb'_[}7]m=Wm=*A]v7yMz8g6>7G~sze^\B+RoPOvQ_vJo!5t׵^պ/x$]QMbzTq;[U|w:~༕KpgyhY?Ӎ'zpgx^wI#߯WqGO0:t8*}q}o߸N~*{];{+]nڥcG77O":ivcy+^5{.q~qy,~01Uete91T>+"۷ s ;= e:EY?*Mzc~jߜc?WqK_ w]=Ӿpٯ׍;՟WWj{6~qzrT~gv?s˵Οr h g\?38 ~R]v|UdgSwag21=Yo߉7B]Ǖ;sQG>Gg/˯]n~&|Ɵ+=;uΝq\~E\|Kz^vr/zqT=~Qjc<׻?8w{2o:mߕx~t/~*%\ 6城byux3nە~rc7tTǬ߳ߧ}Un]}?f;mgJ'W=+^N|+¾rv8n_U眝F+Տ MM}~g}}~_\"yq~־/'[yc=T7^\q }f7ag|oZ/$~_vb|v'Ji?w?O(??G~t)z侔F)8M^=./lWC9wyūN7w/ϣH?^emVōi?ߑ֏<<4rֹ{5wE{{EY;_kϵ{o+lk'^]v8u=Vһ> 7miUn_*uy}C/џp?*qwZhF6xۗ\c9lUŭu`.t_߉~΄Ύ;yw<.>O;d'ͯS;ݴVEx-eާוh!ߧ~9d9]?r>~\>ry/B==I>Cۉ8KsލǰSԺ^.YSyv7|c'jWGwgءV.Ņl}򡜽͓0&]PQEK;v~q}WawmFΫw׬רm>o~Wԯ37kpuv٭ym9?=}g':<o!hHq~']=n^W}+v=c7n=.?o<.~ 97!i}u֮nƓ~O;W : aC9]yY.7fB_W+/.8G(q#חn1۾?=+|avw('{SOW!u])߁)~о|?h~寇^^}{YjYX/6y|χ|Ǜ| ߫῏?h] ] ] ] ] E}66666666YV,A je5ȲdY YV,A je5ȲdYmd9rh#F,GY6md9d9d9d9d9d9d9d9d9d9d9d9d9d9d9d9r#,7r#,7r A,Yd?r A,YdFYldyFYldy ˃A,Y <dy0` ˃A,Y <dy0`#Í,7˒|\%.Kq .Wq+.Wq]F[J>nI>..Wq]F[J>HqmdI>n#KqYȒ|F6$%,%7ʕ|ܒ| WqKq r%'K>n+%\I\u\%wq,uY$eI>˒|\%.Kq]㒏J>nI>n+%A㒏ȕ|\+kr%$7ȕ|\+%㒏dI>˒|\%.Kq],uYAq]\ur%'K>n+%A\I6r%'K>n+%,uYȒ|F6$%,mdI>^?|\;H>˕|ܒ| WqKqur%$7ʕ|ܒ|F\I\u[K>.A,uY$eI>˒|\%%\%7ʕ|ܒ| WqM\u\%7ʕ|ܒ| WqM㒏K>.,uY$eI>˒|\%~|\+%\%7ʕ|ܒ| WqM$Wq\%7ʕ|ܒ|\q],mdI>n#KqYȒ|F6$wO>$J>nI>n+%\u[J>nI>n#WqM$Wq]\-%| Kq],uY$eI>˒|ܒ|\q\I㒏J>nI>n+&Wq]\I㒏J>nI>n+&Wq%|\q],uY$eI>˒|\?H>˕|ܒ|\q\I㒏J>nI>n+&Wq+\I㒏J>nI>..Kq]6$%,mdI>n#KqY'r%$7ȕ|ܒ|\q]\-Ǎr%$+&Wq+.Wq]㒏K>n%.Kq],uY$eI>nI>.A$WqǍr%$7ȕ|\+.Wq]$WqǍr%$7ȕ|\+㒏K>..Kq],uY$eI>$J>nI>.A$WqǍr%$7ȕ|\+8ɕ|F$WqǍr%$|\%.KqYȒ|F6$%,瓏ku[J>nI>..Wq]F[ȕ|\+8ɕ|\+.WqKq%7Ȓ|\%.Kq],uY$$| Wq+F[J>ɕ|\+.Wq+F[J>ɕ|\q%|\%.Kq],uY$r%$| Wq+F[J>ɕ|J>n#Wq+F[K>˒|\%,mdI>n#KqYȒ|Fǵ\- r%$|\+.WqKq\-mJ>ɕ|J>˕|\+%㒏dI>˒|\%.Kq],uY[K>n+8ɕ|\q\- r%J>˕|\+8ɕ|\q\- r%J>.㒏K>˒|\%.Kq],uYu[K>n+8ɕ|\q\- r%J>Nr%+8ɕ|\q\-%eI>˒|F6$%,mdI>n#KqAq][K>˕|\+%Q6r%J>Nr%J>˕|ܒ|\q $eI>˒|\%.Kq],-%7ȕ|J>.Qkr%J>˕|J>.Qkr%|\q%eI>˒|\%.Kq],\-%7ȕ|J>.Qkr%'ȕ|J>.Q㒏$eI>n#KqYȒ|F6$%{|q .WqKq\-%J>˕|ܒ|(WqKqkr%'r%J>nI>.Y$eI>˒|\%.Kq]㒏J>Nr%|(WqKq\5r%J>Nr%|(WqKq\5K>.㒏$eI>˒|\%.Kq]Aq]㒏J>Nr%|(WqKq\5\mJ>Nr%|(WqKquY$%,mdI>n#KqYȒ|ܽ~>v|\+%A㒏r%J>nI>n+%\5\ur%$|\q,uY$eI>˒|\%.KqKq r%'K>n+%A\ur%'K>n+%A\%|\quY$eI>˒|\%.Kq .WqKq r%'K>n+%A\I6r%'K>n+%,uYȒ|F6$%,mdI>^?|\;H>˕|ܒ| WqKqur%$7ʕ|ܒ|F\I\u[K>.A,uY$eI>˒|\%%\%7ʕ|ܒ| WqM\u\%7ʕ|ܒ| WqM㒏K>.,uY$eI>˒|\%~|\+%\%7ʕ|ܒ| WqM$Wq\%7ʕ|ܒ|\q],mdI>n#KqYȒ|F6$wO>$J>nI>n+%\u[J>nI>n#WqM$Wq]\-%| Kq],uY$eI>˒|ܒ|\q\I㒏J>nI>n+&Wq]\I㒏J>nI>n+&Wq%|\q],uY$eI>˒|\?H>˕|ܒ|\q\I㒏J>nI>n+&Wq+\I㒏J>nI>..Kq]6$%,mdI>n#KqY'r%$7ȕ|ܒ|\q]\-Ǎr%$+&Wq+.Wq]㒏K>n%.Kq],uY$eI>nI>.A$WqǍr%$7ȕ|\+.Wq]$WqǍr%$7ȕ|\+㒏K>..Kq],uY$eI>$J>nI>.A$WqǍr%$7ȕ|\+8ɕ|F$WqǍr%$|\%.KqYȒ|F6$%,瓏ku[J>nI>..Wq]F[ȕ|\+8ɕ|\+.WqKq%7Ȓ|\%.Kq],uY$$| Wq+F[J>ɕ|\+.Wq+F[J>ɕ|\q%|\%.Kq],uY$r%$| Wq+F[J>ɕ|J>n#Wq+F[K>˒|\%,mdI>n#KqYȒ|Fǵ\- r%$|\+.WqKq\-mJ>ɕ|J>˕|\+%㒏dI>˒|\%.Kq],uY[K>n+8ɕ|\q\- r%J>˕|\+8ɕ|\q\- r%J>.㒏K>˒|\%.Kq],uYu[K>n+8ɕ|\q\- r%J>Nr%+8ɕ|\q\-%eI>˒|F6$%,mdI>n#KqAq][K>˕|\+%Q6r%J>Nr%J>˕|ܒ|\q $eI>˒|\%.Kq],-%7ȕ|J>.Qkr%J>˕|J>.Qkr%|\q%eI>˒|\%.Kq],\-%7ȕ|J>.Qkr%'ȕ|J>.Q㒏$eI>n#KqYȒ|F6$%{|q .WqKq\-%J>˕|ܒ|(WqKqkr%'r%J>nI>.Y$eI>˒|\%.Kq]㒏J>Nr%|(WqKq\5r%J>Nr%|(WqKq\5K>.㒏$eI>˒|\%.Kq]Aq]㒏J>Nr%|(WqKq\5\mJ>Nr%|(WqKquY$%,mdI>n#KqYȒ|ܽ~>v|\+%A㒏r%J>nI>n+%\5\ur%$|\q,uY$eI>˒|\%.KqKq r%'K>n+%A\ur%'K>n+%A\%|\quY$eI>˒|\%.Kq .WqKq r%'K>n+%A\I6r%'K>n+%,uYȒ|F6$%,mdI>^?|\;H>˕|ܒ| WqKqur%$7ʕ|ܒ|F\I\u[K>.A,uY$eI>˒|\%%\%7ʕ|ܒ| WqM\u\%7ʕ|ܒ| WqM㒏K>.,uY$eI>˒|\%~|\+%\%7ʕ|ܒ| WqM$Wq\%7ʕ|ܒ|\q],mdI>n#KqYȒ|F6$wO>$J>nI>n+%\u[J>nI>n#WqM$Wq]\-%| Kq],uY$eI>˒|ܒ|\q\I㒏J>nI>n+&Wq]\I㒏J>nI>n+&Wq%|\q],uY$eI>˒|\?H>˕|ܒ|\q\I㒏J>nI>n+&Wq+\I㒏J>nI>..Kq]6$%,mdI>n#KqY'r%$7ȕ|ܒ|\q]\-Ǎr%$+&Wq+.Wq]㒏K>n%.Kq],uY$eI>nI>.A$WqǍr%$7ȕ|\+.Wq]$WqǍr%$7ȕ|\+㒏K>..Kq],uY$eI>$J>nI>.A$WqǍr%$7ȕ|\+8ɕ|F$WqǍr%$|\%.KqYȒ|F6$%,瓏ku[J>nI>..Wq]F[ȕ|\+8ɕ|\+.WqKq%7Ȓ|\%.Kq],uY$$| Wq+F[J>ɕ|\+.Wq+F[J>ɕ|\q%|\%.Kq],uY$r%$| Wq+F[J>ɕ|J>n#Wq+F[K>˒|\%,mdI>n#KqYȒ|Fǵ\- r%$|\+.WqKq\-mJ>ɕ|J>˕|\+%㒏dI>˒|\%.Kq],uY[K>n+8ɕ|\q\- r%J>˕|\+8ɕ|\q\- r%J>.㒏K>˒|\%.Kq],uYu[K>n+8ɕ|\q\- r%J>Nr%+8ɕ|\q\-%eI>˒|F6$%,mdI>n#KqAq][K>˕|\+%Q6r%J>Nr%J>˕|ܒ|\q $eI>˒|\%.Kq],-%7ȕ|J>.Qkr%J>˕|J>.Qkr%|\q%eI>˒|\%.Kq],\-%7ȕ|J>.Qkr%'ȕ|J>.Q㒏$eI>n#KqYȒ|F6$%{|q .WqKq\-%J>˕|ܒ|(WqKqkr%'r%J>nqe%////aaaa݋0 0 0 0 6aaaajKaaaax?aaaam, 0 0 0 0.0 0 0 0 QaaaaxaaaamKaaaax< 0 0 0 0_aaaaaaaamO0 0 0 0 " 0 0 0 0Qaaaaxyaaaam70 0 0 0 ٷ0 0 0 0 0 0 0 0 V0 0 0 0 o3ÿ0 0 0 0 o3< 0 0 0 0_aaaam: 0 0 0 0aaaaf0 0 0 0 6aaaaaaaafo/0 0 0 0 ݇aaaamaaaam0 0 0 0 0 0 0 0 [aaaa?0 0 0 0 V* 0 0 0 0? 0 0 0 0 o5? 0 0 0 0 o3Kaaaaxaaaa0 0 0 0 o30 0 0 0 V& 0 0 0 0?qaaaax0 0 0 0 Aaaaax_aaaa^aaaaxaaaaaaaaj?0 0 0 0 OaaaaYaaaax0 0 0 0 VaaaaoaaaaQaaaaxyu' 0 0 0 0( 0 0 0 0aaaaj~aaaaj" 0 0 0 0iaaaax 0 0 0 0 o3? 0 0 0 0 o5 0 0 0 0 o3? 0 0 0 0 o5Iaaaax0 0 0 0 o5aaaa-/eAaaaax;% 0 0 0 0|3 0 0 0 0vaaaaxy7 0 0 0 00 0 0 0 V 0 0 0 00 0 0 0 V0 0 0 0 [ 0 0 0 0 o5aaaajnaaaaxaaaaf~o 0 0 0 0 o5 0 0 0 0 o5aaaaj 0 0 0 0 o53 0 0 0 0<0 0 0 0 o5+ 0 0 0 00 0 0 0 Vw0 0 0 0 [aaaaaaaaf_aaaa[0 0 0 0 [70 0 0 0 [oaaaaw0 0 0 0 [ 0 0 0 0 o50 0 0 0 [ 0 0 0 0 o5; 0 0 0 00 0 0 0 V;aaaaaaaaaaaam0 0 0 0 V0 0 0 0 Vaaaa0 0 0 0 V70 0 0 0 [̓0 0 0 0 V0 0 0 0 [0 0 0 0 o5' 0 0 0 0Naaaaxaaaamuaaaax% 0 0 0 0|3 0 0 0 0vaaaaxy7 0 0 0 00 0 0 0 V 0 0 0 00 0 0 0 V0 0 0 0 [ 0 0 0 0 o5aaaajnaaaaxaaaaf~o 0 0 0 0 o5 0 0 0 0 o5aaaaj 0 0 0 0 o53 0 0 0 0<0 0 0 0 o5+ 0 0 0 00 0 0 0 Vw0 0 0 0 [aaaaaaaafZZW0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa- 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0sYW~ɿO>|i'˳?|{oCo?97I;sO:?'|oE?g_[go_/W%o^s/ſT [,{G~y[͏KLGGally/data/pigs.rda0000644000176200001440000000243113663637143014010 0ustar liggesusersBZh91AY&SYtdwj4#L  Rh M#hɣIyLd4i& C#A=@Ph=@C5  4  @4 a@4$ASODzh4zl2zh1@z P6 di <iC/37;?CGKOSW[_cgkosw{ǥH zIY(Y=, ;DͦaO.or7g.aϟ V7='~Y_ս!ȺG;PJJ~ BZ|`ɲ#o4d} }fH,| ,lxH a(q/ f?R rmW{RCw\ =").tPE$6a:,Y $m=eSQ, >oK:R]vٜίcCo:+.6t$\W4&dHg-41%jt8Xң~"/Q ޠe2g$G M0 .%$Qa)?kjac5 @+RyV(asO :Ay@PdLqUKa'A+i)#Ka2~Am\sJ3Njvsj[9EyRx 9;ZLQ3RX ,L&ڈa6n۩79{HK!^Y͂$zhY\!O)+xv;] -5I]Ә/HUPS/yJz t|K!S&1n9,b3̎ *TG>D8xo?]BB? lGGally/data/flea.rda0000644000176200001440000000150513663637143013756 0ustar liggesusersŖMOSQ- |% cK "q,P r-Pr|* ~EK,Z&qctn;=2ZygΜ{o{zޠ1g55[O5ēc;:FT֤;&Z6:+ҩX"rM ^.qLBe-wboػc<K< <O*JM+6ȃp̂90f ]ͱ7X_j?gVx׾X[T%}]d_(m,{]Ipxcenq5?G}NkV/yC9Ig\Y=I3cA=SXvv(h0m*9m$±{T|'mVU;U0YYCC`kTo ^vD-S~S>+,-Q[43#7s#gR=pį 27M}5"Z`|9' }.=(#mK1y@:Ѽ2`A3!fۃj5E~ Np G>'8q '8 8Q bNpHNphNpxNp\ /q˜ ;'85ถS8q'8rc:'8nG '8fpc'8J91e rNpMX EX %X e.Np9Q '88rNpG5'8j8Q '8p# Np4r8Np͜X y_ ! |Np pNp9aG'8 9191c918q5'8 iก9q#'8J813919Q X epr JNpx8G'8VrNp4sc!AM̿,$ e~~i Kp9Va$+&۠=e-d\UMcsHh*p@͙k)hp4yVQ`\V!1ٚd9Ҕd$}=Nk ULۢYM e~**8s`g g,4_("ٓ-(PI0(`*nрJJ!,?+_Eoؒ3"9ǻ]@K@?w@Nwc? <s|Y[yRRڑТ"'PbQO>i3lHX/y|I# ۦ΂٥!X35QPb#Ty@xc~ |ЛyjT;{ȯa9 (HIȒ}%%JA$Z_x9𶮢u: 73V➆(E!- ]$:x{}%Bo7KoPuRPRH+Tx8,+Kխ&4 Z9 a!85WJ|Y j!P)8mP{- &J>q}p{F"yHCPVDmՂԚPe^[Mms GD7x'ZeI ! DMJ8w-żS`" $ ÕX1݃叜 Br P gHaEnQKxvM t(| óH^jJ'! 6rK@(!8eY-gE6K-#(J{C{_M`vZ.0aw" Prq( aFh"6Н❅a*k +AC#I{SG;v`gˢtmWN +8;(X=@PZFC侱gӈ MJl'"nH@G)X**MbJ P  c"q}q_#ԯ5y˵sw4t; 6/\xr9CF?EXfZ?yF ARs(^x]IHܢ< dH5j|eDY^;"wS䜕V MxV}T.#V7m;H5FrXPu $0SDVMqtN$:iTKv6[.d~=DAHAjE%-="*/|gfމ<>3ܠɉbJ竏G?|_xGw[A_]9  5GF_݃{n2a7*ā "3G;rEQdArnxNBBLm )<ڒ=+ $ !2 % u^D>zvHե@u@2Sf97FDuhTUd{jÉ;.80lXUgZ"uCW?<8o f"͸.ijcGQPl& -9,?W?>{q)BHٱw@NB$1 ͵z]#_'4ȎyF OqZb[mkcFZ1L:9) g]?D9ӇSP4ߥҹl͸ peEs(Y|}_&b0p)Z-P('بϡTiR/fueޙkT!(4F˴bqqѬ7_j 6so ,IdHM )x#N}:1#/` R5H&^D#Hv? ,o=U[s!z%V73x'9*}PUlN<~"7"NomWJHhܻjRKTw{ۊy'\%hPΉ~& E[?᣺ѷLNfPϽUAc: _9AQKxH?֩ 7.Ly{*}A#΅LA2guLCrt%>=xtO` O|kDgBM΅G$ʫMh^:g~33PP̌V)FdD{rUar#;,xA$)0:cW@ÎҪM Cb:}rL~9xG|?ݯ.c+21J@{@\ά!jXIPRͦ/:];VAò[P.Q|@ ^15}.j790㭧w ahurji˯,ʦ[5qw-(^H(P('PBzy**(g-'IyB_/v A5Z#)FVH J+DV5{&<F1w?hu@zso.դp{C{ gw .`-sHpqL_hW:|WQ18HJp.[0ډ(%sltS[ ^IX2dl$c s*X*,B-^boj$w}R%X?yE+?|&(dAur f뷨\w˯yLkwPpD2He Q(_Ccgֵ,uDo:wrH!Ak ڰod QOɂDWfY;^+r %r188#vuz `h筛j6 ф2pvϐ-a;r"ٹ֑NEc O(9DpfxgP;vj4K1@jBH(RKRKvмYg=H;$vI /YKS =@#IG n=zv]&B^k7O9Hx,p i:NZ+K*b%lRd}t(5eB)-(g (tcIsի٤`Wu+`6Q;yg\ fcv/PB2ރw% %5k&howL{$N{F+n7OsvL&̫:^51P:O=2+aOSwa%~ڽj[sB04zLƧOlRQLGPT{Ev_d?'p2X>jOړsd2>]| %uT{=9;\d7QT~zbj'JRmj/pTW;%sPm'vQm7)UQmF)/^~mE_G?a}#b1c28/rBZTSv+ss{k]koV޼+t+y/ϥc_y}Swe=_h%-L+eǹE\זMOg.`-p_MS˵S>È3yƈ5Tq~(q;sA~=p+lW8`}f?ca̗Kl{YA Giik:7?x9[3lokOם>CWv~` 3x uyc/n}ޟ&y<ž=vaN $\'Cw|A^帏B&_chWsb_=< a_?}5x;Os\DC>8#8Ãw1;Α[kO|O#ϱ؅]Aa[A8C;>:T+3S߹q9^SA}שd eĽ']grn~qKn.Y8;gUԃ^Ĺ w Gv~r؃,q">ĥON`O?OP‘u;3Ů}&7QWu~Ս{vv#.E֡5rΓۍcrMĻvx77ޔrЋ~~2u~H1ޏn_6oF>Uًv qv>u uzLVqN>S vnd(mϑyӱC4}*~/,~-u*-y=coֿ1y^Y8[Ռ~ȷwش4eYk7׊ĨUΛ堝lM+?NFvͬZfk^X;3{:?Qk :WeY^[Y\ng|*VѬiU5e{qunfǨ}v=սfn\F(|b<(VPk'RzTƵclǾUMdލw#wuAvҜth.\^ڒlowõNowus|jsznaav //ЎHD$f!V mtջ>͞~)e1s3Ilݤ?Mf,_:ʮlpY>7Ү nq]^k&;?M7ٻUmg_ g,,T?y)]v._\|Jd+V.sW{t/-~yl=&t\xH'N$Sў=Ҟ=O{ڋ R)A e2H R)U W2\ep*U O2_gDx:0<Qj>"rTJwJ,M R{.6a"M̸NstI:a--IbC)!!;-L'yLPr s+VsۦR6 6iDl"=[ gc#E*>hwȄ [NKytf!C34XrUZVCNLwmG ) ^A(eg4 ZN啱qRZ]duFjNa*7Ԋ]kN-UJZ#S6Dt Q`lv߅8rqᡥ>I]7F,cj{0WH`'K-i Euy 9_~f3%,[=qt΂|7DT6]G:F\Z1&E#=|'5uN)YJ/vSge0%,lmK+wŲXjQ虆]9)KΑX׬M]lix[6,_H^[SibZ 5wKaR5R.ikSlk2K ,'8SvݷG9"_Y>ӫ.lɘD 5uwu]A5H)ķWro1iuv/[QX/T6B*/X!^$C[K.[b,E승3])C%ۨa.Mj7JfR]qI9pnDHxauػFpBzp猖TYkPZwmz*^5r*ۚiYɭcAhO2خ|WCxl#6)S " AmcˢzYE]ik*#v&NWm,* m'&!b#1q,ԤOdug8I!ZnJgٞ3kh)'&3ܦ]6%%v0HVܼ:Y-AC -wl˛ڷ^yA|MHmD^e[kE*&AyHI-0bZBK<=aŝ#<C,iz. +SʍuÛyM4Q"dZ0 \SLɚ((UڶI-b{;0LPq )Lj[[[vmd[;:ư:Mea63˞$6H/dغўyyNL䴫aGlY3[ILcY]*ZȫQdvl[V۱8HaJ=PJ++QNrm^^5HE2 %qKl 8f=5 PuCl'%F  Hg= J[zj' v4'*MU ѥI~1:\]=bܢ  ( Z:MYUe(/ŷSҚ0fZE;w .a& -5Fԃ 0(HhM܂1 0X2wb>B4$<#)}n_t|txg@:&C r jP9m4S19ꀖ(Pq!.~kLy5ۼ^FЏ04,j454LCDMWvXE\` *"h.|ZW%ZGVdC&dG%Ez1(^['4\.ؿ%G9y]S]6t֢jqz2-Dav7ݐ|C !< [x3hPP5)AAL*B J2dL16l DE30لI 3 dh(!!3) e00 R: upՓ'Q.urhoNJ]jG;/r؎Wfy ǖ-Sێdw95yP{Ny)L&lGtg[h_r6AI[FVѱc!&ت -PmlkERV4emG^*HȠw'x]:JjL03f% v^%9:6͔~!MW ܤXe),\EvE)t+ݝ03ACuژ!3D 7}1lL ilDZ$`2 G^ދ&9U1 DPν0xMBL?.YKJhZihUn+BB$ }aKbP0ie4ĜtAVo>|x>Wɩ>UamIwqEp·K&YU*KO)l|%fīwkEV +Ga5>j=#^6N~rgQml&qMnPE_ceѾ2kT5UTL.ndb)ic~;(и"'y DHM<q=&zqיNqJF/i1aDduF ncwl^+$z=G#xu9b\j+BWh*ʲ[]tso/|j\U[W>ƞަ)^wQvx^ˊB0RYyn]BrLtXcN[jAUmLpKW{.P_Av_dS /uV!!*8[ ¤2ЂTq ܺ䔂OHĊ"#"D"(ԚADlEV*%6 Ed(QDj"0A`mS#FKfXy[jոCJK1((,M79\q@jѫ/m"QLZe!&PmW .]ky#mzr-i4")f 0XFs^E6 N_Taڅ]|kIvJV92 \VU b[De+Ƃ,F gצn  {$6P30b,hzmF  8IʇjKh0q `kh#ZIƫYVh،HE OmքϽwaykp<",T E I0`05U r@x!<3l; ȀF1u{w$S P)GGally/data/baseball.rda0000644000176200001440000104362014526730006014610 0ustar liggesusers7zXZi"6!X])TW"nRʟXVHqjnj-&b%i*\CKA*֚:(T( W%p8wep`KBC&5SçBIkn>NQ<(%8 >3Z_Z'5so@F~]]sNL凖8һS ia WaXj(趏gv J%[\- R`/4 ԣ;#0O-Kn$e/N{QE!/IKm!}}9P_<.J$IVx, ҏ`Y"{ucf^qHa, /5!Ԇ ;#X[x9QzcK@E7z$mǮqk0YDoWR^o^ gGg/#jkwЭna}BDw;$>ە߷"on)1혳ԽI5)$q_ +W$ԱƦ*NviԼ Cm׏ࣂCGm^FsCƩ~,iPEiZrg6EEs~)M-E->?'yD3,v;+B oW}q^=?HBF$ Bo>c ty֢ߎk޾][r?*:Zs˖$FeQ(? ؼO 'NLaQ!4sd1/G&*g( | @oGRiPjO[[0fR~p*ZOxY9fXqz!ī-󬱞[> V+mꥱ6 ~)z4vgtkq,1+ʄCRqQj1[0<J6R6ˡZ1aBn1Q}^@k)wWʫT]B0ߥi[: <իЩЃW5_RU6_c%׏mvӁ/mxd+AcEu۽fywb` J"-HTT,:^>nԗmEu34gl'mP·\T.;0|K4t‚E?Q8/'-].y|+3liXP, Ti/8?< [ja o[W KasesrٕUky^_|WQ㼅ӊ>Y$At݉i4$8^K 57u47vuRH?AXІt=v V=@KDЉ<|l@qRKy?S  Jhd4[2u=ZFF:뱾zoxXpN[t? tw`xJ`Y! ͽȺ[|x:9 ЯX|>n{_o} ~>j#6tR;[-,E}&`hlRxͲLJ+w{+MdᘥIpylA;7> Y\EWq /`<섨.voLcqAU>-g 3PŒc^qr?œ}C10vӸ=uRUMؗ0xR˞(SP17JA 7# |%DJĨnV;8B(7ڬy4-hnL%}ՋcI>𐤟rܶj]e736H`k!2oXhtǼ/_!q%G/s!:SCܿkM`8`{!n(i^`(+x\a⠪t%5u?ٔh.M˱ ja%h=-[Fj 5[(iQW[D2,pkvBz 2M6KWMm&io쎜*}%VԣsB)T#VBo  7d%ϽRn ~Ϊz&jx^=Cn1{;j pzF(v,DM#}0F} 4skMd~ OoZ7 : yPb,k@0~Q܎ŗ f+.+) t=c`)P.]Y.sTl# Ű!QJ0=H cOg#Y3k ·ބ-d^w|1ZX.6T3E&>qK,Vv9F޶:XͰO }i+d7Aܞ- D|g3?JZZhqlan>?UªuhV-Mz* 0(W*7 W2ws!>ܛک@R?犎o{vv.S%18Snk,bKYr\OQF ;A2\ձZil,¤j̕p.Lnn2[c+`^pN2*&`PGf]zC~x_LFյ3\W|ɃFd g^"Hn.Mc׎O"MޡNFnsqu"Ȃwo# _֬:; UT+IRMNihrx P92S.5r(>Օ$1 Z&,fQ^O"r|u?m^c;=]5Z.c%,b!,83t#+6Klm呔K`܅ s5`0=X8^ îGpXxBHh8 nIxo̻zEfA V,zO =*P3V63, cu;5>T<Ų`gwZ`$Frأm$;FvxB#bR@IW/"FnuYa[N KT'פa^o\ [8\aiAOIIi2=Tʺײ>7jҾ\&f)@u+i?Jl(5ˎ~x@@'›Z..I=s1 tOCrG1IfzJJ1lSZBG,<2:ᷮ؂>"js%K"&\>:S 7Q i [*!|yKp'_YWXTF@C2(e`=q٦$кeUhBaDȂRW| YPab{CFXv_v/^̿|,1Rfx;暡 _-jy&q}Jaz.oi~$y[4_#OpM~*A\Q!vrH|$jYOgެ"jj$#7mSzlM*ǿ'愍M:wAfkmҚcWErS9.}t&BzXK\w(_ =iro M_̧=BjlVjI!6t|ݷ;u Lb]cT*ǽ{4&43Aj6a=`ywB8^QxKM U,v+_fw$ҍR_J7 TF|d*+&Ak4فT`ĭTR69dGT3vދuW_]T쇁ԍ eAS D йV0]#[ DC6FjvVSԡaGzPO/K4T_ Ғ.DB0+d(t.?~c% hu*hvǩgGf6k'I3Fϋ7 7 eudY A1<8 qէ`o^k끴7s[QhZLw PÝے&DP*|N.W0X2l`j[9V7CEUr-6e|\e=$X[K%4w?栊~}o9lo#ނyO@3pvgVʬ#_RAb@W;MKַmIu|RYw 7z56{_bM `n|1ն0K}X˚^OKv^+X-.[p %i1 bp8+-&j-QX^MFF3o͗)"nVǾ^ՙgC2R"SGdD]ꒊr~+p3Dot( ^"}c嗢l!_,2)HI\" n,}fcC39W&y˜|SƿL2r 9po.~Dy)H!w[u1!If9[#MR V;-d_eP &dBOirI swlaD1[dT9գ>bݿ±o6;L?MuUCѸxI2OKQh@) 5l# !y%$O+>NeSM@NϦ9ot"პ$Y$zFQ6- OsO8r_RE60qrpR ?Evws g/ ED>2Ts4rX \]!BKg){uQ!t#)K)X XdQ!a)z%6[rD 7R> !#}0G:] = `H`hJuju :*ks/~ɺަW|nQ ~tB s7yp}$Ty&hCbU]E5MvU[S04o< g^BG ʥ8䅊l,WMʶ }hۑqCrId%H~4 c&ZŊo0i!w3h1G|n#_c=!=^cIFq!*()9@Y}m%<`kHְ[n2خʋj|AytV ?3r":VM_J0hA{g1g#,^̀'>28n:=Qw:QVyk]zk~ۊAs{?1{˶IMPCo ۧHL^o[p6/9NLoZ]̬n$0 &V"iwqu Z 3D8whf;3"o 7qdYĜ\v3Gw"?w/@_cۊS#=/63iuTަʆY]:@ a$5$y].&w$(2KFtV FCӦzM734qPW q_ BY7b/88Kh4`${8.r`nT]l`8Q Yul$goKnWm:ůI@q:d #׿ѷaOftrDP ߴrHE R+}/gչ)LCG ZÄhGx{OppTYЧhсS'"}[c/R캮 \ :C7]c~ܑza:7`Sl͞)Rz1<):p?K| )18px g ٝ?fД[I1GoZq2 "4#D49,ƙA9{B/k$ƸBC#xnۙlEgE외#s]cPYwx-2D /+yZyBX~lE8Q$af3=5E.g`n}jx/)~?os.˲l6 ;-PdնӧPb?Bl<]6_>e] $ 'نJcDZ©@m={4'υ|6Ez0ˉኽ?ڊ _W=ӃOMO{ $- ?dpr5Y4Q,TNkJbt]C0܂6' S19'@¥rdQA,D{ 6񙍷q}H7W mSEϛ8Q(N1$+@!7aMI14_G(-&%+>%rˑ4 ٽޛHEj>Bd8-x$'*gaq;/<p*J\ tRQ<*w}(*0Ēf;yH}SVCLs22: UM1`&%sс=Mk^'yzntY& gҬo;qըi`ԙ;-M4+61~f'SQu9."wB^v󿴫HdѠbaY~gD)BR ySPɣsz%@У2,M#[m7Ɇ^vJqՐ^-Q,ci¢?yB(9g;IN$̞9#z}Cbbܑ͡E~Q'<,ϓe{ٚ`"_nP#|&Bfx7lH|}meAB!L"BW)l 1Q*&` v@;j3޷|dyhl\;o]ҭ&CGWՓdK3Hęֻdg_#]Lݐ  :XIo>k{&1|LD$9.PjU1Ulx|$DH}U@ +;8 @CF6",/vKܽPȳO14!S@l !t@V~rȷofIl_FF&!R.,tIp-$S5U1%fw0}DYH'Ib (㨞' `la dvā/& A 1^FcD-,#l(oA ܄^K>EpQ7[)QF8!V('n;淳=pi~onuA 1peA!?Žk7#\|&7+ZiUp s7iЃ 7I;OHb~4F^pj0&,%e{URqGvg/D5K1C'.e)pNȓ4;za(ݡR!?-""Z0ں4OX~9ՓkDžZ>li9 ءݛi}8$nh’|r'yo)T9$;fOF?>XG9tG3: C^I6_(Rur0r]qyh_}DNS E32t(i2dMDsPx9-X׈ TɧsjH2`<0͓t{Qh2<2oA:UVg8kB~31V'6bw^Vc F8eUj)@*vOib8L$jz/w W딙|Oɾ"m_.H!f*.fs<9tؗsnٮ[}h Έ',akn\(T?UAR`kc;ZgZ<Fs#ߵX-DojOv.^cftlc+vIiF1vl"S\]Ujuق;# Qj/uzr|-j, /vMgׅVPZ1saB\5Œ:l6홾FveWY̋txh7o"ެ f,hӬGr"#1H &>gD%@Hxe!N#!R{yE0 @o vt*\W^[p4kc(M0M}svݯ)Mʥg]-$s,dV"t++=qdr05)%hC̛aV@VS03 1Kv~-#+'+Il1/8hou+9$O<d }1Э*N8"!sGe*,}gJǯi aی I6*wlGgڸ'+oBOחOI_6y0A*kؙ!wzAmCq[=g!Rb"fJy/"ʮ{9m_t,; )C[6?E6ǗN 6h4$piM& $ekC-Ϲ]2f.e&ɀ|;Œݞ1.! GZ03 ʒ%L#Oh8˛OCR@92*f]ȗ4T-oWr2F?Tz3)W%ZR"*<}κ-TP7aYO?$'{QwGJ')BqW^ Vx>CU9[ EKbvsr[::` \-nlfD2&|ܡ.@Bԕ7$,)vmݘrb1˳[tM4]縕5oAZِa҈vrŊC&A@=VGMt遲 #0hJ@Zh\M;QA umnPFaſ0zIKj.8ZL>-Yj!@ o*L$+~rB ;L'{gIc!vz ? vYңuۋmվٵ<ƏjPy@c5ٱk,4/Mo9+b!grh>"Vv9W4EݜN_Q'ԭd曍٦/&w< 5ނZH]+XZ2Ut7oh+>zjW.> 4R0.[a^9 ܍yԌSl>#&P%_vƧEŪ%ߏC>@ܨhfqٖx@LJADyٓ}.^P h=HOY`j#)G/ #j~lFIN)D 1B nx;r?Onjͅ"܉z}b)b"yG.iA2f3<f=Ad~ײ.3?PqGHnMT=ܜjW$8'e*qG"Qf(ߪ89"3> ֽIZs_-٘m7ǂ3zEa5 \G9j#dqLWNP $Xb'Sh!('!IgWcgvrkgC_?IWIԟM$Eh*3a??5BTΚmTtZ܌X\>ؔ+n@ipZ ϩra; \oN&%'kؖmпXX 3;݁r('LS$w܅D 9t c4a[N"x:"U-'Mre4Ix\'<ќBZ0¸\rnkStx>cu#{E̗Й@U{ŃEĪ۫!DVe7+63a @|C^^^:ȶ+By; K`UVeHpCiT2N Vs)`MpuZs*d_I!8 %U5yPE"> O]7W\IxW@}e 6M] 5F縃T:C࿉ ^dw[xwW6x/u*E{QQk湴˰"p .-ݖwjEgZKD$Feyf׭+M#}wЂ4|5W4+αZQ7y:!@:-ȂTga:NŜ!"5jt3:]3s}q2\YfZxUNDEhXQ? 6M2gu^+>m}>c\URrp3@6;6] UEZ6D6ry<+[a3"Ҏ ?H62 EnM9!%/@fq,7"S3?^ߘg6@$̺ ȯKB-Zj3Mu*q\kBؚ-&Dq}` M XKn%_d$P3R0=2K G¡3Hefb3^Gջdʑl)-LȈQ؎$͠lGcτ)>zCPN<x Ψ(ʚښ0KN59R[CW4_rkQdAu`@sܥ 2-voINxZt[߰H.38U_ln1g9t@Q(!+V l[9m |w=^Bzox*\|uiqrevuV?Jg+)逐5ˇ%u eSLy U@(<@:R'V`pc\}n#£8AΣޛ1 #@"?iv ޫ!92!Te9JBa\L:-%,KN1z|g*q[ĢVv驷?{x/Rxɍ 'PUP^jd<1LfeN|uj)Ȝ)r0nm|mIB耖Y^%VCN+C*j;7/t=Fl+-ܵPG8Hr)04EcgmHX؆1+U܅Kc.aP{Ϋo_ 5:fKBgdķ40˘<{l%bS}䣽Xπ?IFp3kP4T-xB_Տ<׿ݞVۨNW_ZbRz*7VxٗD^\D-'ܯ ;Aj~Vcx)uHG=Njp$Bvt{1ԖWa-=)-SRTǣԉN}m!]/*9ir!kʨz^m.Y'cwtOǜFb匟_||&$=mI"BmB'! Ͼe*&.Kq!D:N֎ӬuB}Yh|YgwX 7A u8oz荂!jDibfeD~P5!HYƒ62xKfTE[(S3>4S'*qá0n_xKs?5;W~_ԕ& hsGzmRcl+nQOft'_LYҜ,Q eZ plz>yzK%XmGEcFMi[ hME#-|8rC-&7E_F-7Hxp|ػivW֭]GѼ'q* 3آOk̼>d5꼽9}t,b++M^#Ze3 Oѧ0J>rPRc'2} F24F4p`KCَ\T<@6DT3GӠbŐjZvTx>:25Y&pkKJ5X?>]_ɽTdkUaWhӒdb@C;#~ZqvHSƝVEj#^  >ӕdueHgrG)B ;lYMf C!> Q`hyZ:\8:K]94p2lfh M g;x y<}P{z؃U%tFhYۘO@h5obX0p {9s L<ϡ'6ѭ%0ɸ/ywݥviҼ ы<;{6W( (qe}RpϺ/@e 4URcP :8q7Zx1ƫqRK"N#9 րvO8U3➗bSBxDm5!!f'OJ ZƟ Eڤ1 ŲuHA@E "74EeZsT* =:[>o<56&Зzehb@^0hވIźW٥]fBSA_[ 絜+MSGzK̫~tqdK N"n>H) JW=yuEMEY:OCb_FkKYpI\pl7i[5bb38)̺JY@Ҷ@)`.<)BD됑/Zs /Q)D]B4w_3X_Ao'…~u ezZn-|T{F齜ՆDٽ. ,d%&zccL2'P.IuGqcW'z{ޓfW'Yr5ozQ1 (Uud (gL>R5=]W|F\rEW6UK…<ιӬhIRW9?n%CEKdq) Ư1(C8U{+/?xy9K i)&hOtMrlx:>}%K%N>A[*UNvЬ%ļGGc>}K+ Ef2tD 4vx_Fֺ3a4(JU]pVPyqڶ"Y@qL;C`D(+`c [̄%#8%2?&_W$.ϲ5bʾ8ZgaSefSaO Y!a?T건AusQI+ۄ, H}$bsM=v#/avGo},¨'S kb.l.%R< |AV0P9 fxe+5b~pu.6)uGG@1wߦCIU(9% clR?],YCk}fQ9:9IQFi*[rG=I!_+2'܏]~"R#0?;O.QH3J28?D}.).QꍹQIp~;)L)hG0{M dZMG^YqP7Y T9!vB`%6wőnO'en3Sm5y`)u>Ϟ\!=*nXWv!2\NDϞ" e-Vbj,G@x|eė7p.k:*(#t;*IT) 5es z:.')\O7Y&+4$pyH84/;QUe'Y4N0-NK(tRV(50?Ycf.O"1UG^U P)S6[`S;(}1]1v}AU^f<+×`ǝLL ܸHG/ %Z'1ds}A-ީf q<$|Uu[BFZ^r*aՁ8H dVȝLMퟅ|fj!9XqyyDTr%ٻeStRbD웰Ȟ|ݥܱQ2' ,3XPzN̮sAfk6n)$`6Ҟ4sU.V^mzu#shEz -U.K{E2'3":˄6AV~ >{3.vdB3Rpg(HPH{&"o(bݧb,Sr;6z4RϪJ#Y+OaZŷpeACؾ9(OST/7U<tt), !?huHo:$mRPrrg)0/ާ OAƉa&zNH,^yqU>^on1Lp@|CZgE`$t;"Q!߸qP 87~ECs~@}o]g4ddYEb(b j9(c[&E%QegIѓUcµ12~C:K00ŤngdJQA}LIUb:=@a/`d`sӜJ7sj 3ò(C8b<(idˤl1삐k=;)3B QZ%=K h9yVskmwvM=̥1l/K< <#F_b|"5`e.3]l`XnO;(TjO‹6+di[݌l4,nzerxtWuRuQ%guPwkն@5Ѕy[|wO$Mp3z4VE0.~#5ݼPx ;w] k ɊYq&ʁ ӒU۸խ9ᯂuUEَC[4F'^Ftn=Iu.WtuA@\:D6?uS2Tl(pZq, mlއ{k%;?2GRn:pM,z* $^´n[laWl &b4g*4xT@)¬:TH *bliib^qڄ7)8&3&^.K#LY8tBUt]JotPZ2*Dya4I(,kۃzF4yU^" w|6=/֓9&@TRX4{4.uY%f!ıg6?P<|@P^)h~gLjȿE6/>z]] `$kMExyMJ [Iǝ`}4Z35j )*g!RwSC# =̍.GG2|iX0_^Ǣ2w=k8hb3Β#s <:eq: fhTslco=K0Tl |OzcǪϹYw`7UPrR~[- 9'Zn]aӶp`RY0:D {.'H7tOi Wig.IOhsSϛ;eX$+iή~%WVxM}Dl~oGdo;tԾ ;iNqh;H"t_T%+L^n &j=z!}jw$׬Q5&-ISrWm{ǡuJ^\"Wؾ"DeܺW U՟wL^ϭI{O"-D/|0;y7&mR]Rg[mC8dnKl">vj3ybf/eB;*i"XYk7w0zꁙcr7.MA&-Q; ʁBj,t'ޟru;@A>A&T۲!5u'dAH;kG[0 ߚ J0Fr g}TiXE5S-tX[Ľ-Pc%G57tZa 'AqRj(Y 6LpL-| 1=!(F >֏hAԋ=Ȝ 6mo>H6Gnmj`d 7{`QL"'I!>"1$.\nPeND:&yUKQbf]OԒl%6AFxt!EɍZKx͕IĆ: I$t7g0js_t %7a@OtUs-C\sź\&-C09U T&uS̱} ̑U2>٨T {q)B|[}~WZ.6S?@ZW֘QTRXQx{CLqAwĤ3&-M~b霼 ֑-'e>Lty`x.a=hclXȼ&SX9L2U0s6߽5*W-?(+II#Bj7Nf髩i xB2!9dA?Qs(1o.ؔ%J,2*Bz uTJxphWIPs1\o!S^{ȶ6c1=W8Wi YY{\9?g7hG,v93vfk~\z(WA8AܞEw ABvjHSƒw|$[sc Klg#!GUWhבb$܏ Of2ÇHxő,v_\S^7R*-Vxqk6y\ $Ϣ=$4)%2Sȭpaiq=UDQS,e!*b7:L/jUקҦm%݆qjNV6 >C`] .]?r: ȣK _]bn6Fġ-(΄rJW1{YpEO` ՠSz>8y`3e{x c =M2jYGAFx(6 ?`tj`FH KY_[: uf3PJ‹r=ZܠR:q;^okX`꟠t6B?!rcNt& +Eoƽfl| %$V!bܞ^zqD{LcS e[D%$?gS.> R.oG`^Rߐ|K^w'ZGW N(Ѫu܃YN**Cf;|y?|PWa%M,/[ u(߳Ev|U 1'udm i, "g!Ȇ%bj =/!< 7C[ophn2pʳJ8ޜpuRً llaUM(ނ>?%hYw PwΏ.%u*{9cv;r .Sݵ F Q?20?'$H=Hv(qN roS fi[,ÌvFjq﫶6o@MRmq1+/'3d]U`Dv{~_GU`'?ޜ3H.r:4i!#pE)Y2Zmj D/|P hsy,?Rfh\w}hR?ɻwu4E>)hEXתfS"rU6\xX,n\5p1pIr]=3%Lߓjٛm"_1:esh?д #Sc>.L/jO(h9 %D @t%`x| ¿uQ5'햨7Iۖ\F?fr??vW+hdfՏ<& [>eZo@Mpn]=_|wfE`A%$WS+X7gPYSkF,~j(80{} DX/j_NL?o:0 h**GiUpLД SҔrXmK_W>F@>TQ!5j oOb"oN>?#DcSwy;9 Ę YR" keA@Ίpf'֨x9?t씢͡_z /n1}g]q aDzjLOڗ^j-#^$%j}z,4tRUQY0`*k[MbG!%+e:T7Ǥ6fF&iݙ}3W^m@tQ* 9W?%k5;% [d+1|R_e ӞÎi%H sE#Gy7H) uv~MaC'A!_ ĔN|DТ Y*#_1n:7 6D:`s׉ox0H}=2j K뮅Y~Z%gl?nZ1xMVF5}: foi8.X>[aX䦽.LyuSnpLE 9XKXՈ5êF}a?Bd 3}zN*qU!>dR/}g]]$6 mr_& 젴 %tYI8Aw(Hpcޛ@e=?az§wSm3S,7(˔7cq7K n~AܓI,brrFHBU;\v0u",N.j4 6{Ld# J .{byón>*8րu F_\&] Wp:KIiʒͣ4"P= ~a$ϵ3wx) qmDb"^KA;Rq= RaM[[OY1| %}& 9b*L-,2wt$l-GCE4G';A2͑+02GFFj/Krji[f|x"]ЭӐK["ojNO3 uFKL}v8\:Q6I gǤvWt#w]φ`FxޥʪuySi=ʅ}-vju@^3 ~N2N2E?`nmkTttqM_Ӽ{u'\1 f>I!pFqt i#_/ӫTAd:%I’hst\w(GvBW]bO N#xB , 3`&~ӏ CcU׬cy! N*ed={RVzm ŒPAؕle:yEf^1xWaBy4!bf]͏g*q ۷olj1~+.''_IhmʫE Ad密=tO8Bٓ'׺ob> `>6pEO-6ͨjcvc9^_Dt`Yڊ42<ه7XX>1B'$I%avk2H)@N d s GaEqHؿ)E_)Xllh(o|s&kL]|hGpȻB٦,sC&R/GJĻ;&Cuz^D?:Bέ筷x 8f#]xoƔ63J~G˦QDQX֍ 1 9;2s4]z:GP9,Vh;tD*,jA4z{NF< ((lK9=Iw۠kS3ɣM-~Fr~9ռYb B3  Y{Y`'`Փl[<5-n'~YuN#Qґx"Piwĵ۴D)\{1~!WB* I":^n1>U=2, kQǧ#otq 79=k1n΂X>Uཌ^6U/vROj,"jvn~VdrMNjVh鷶'*Gh)wBGXSh],5+3Nq'j-@$Ρ8B{dGyʓe%Wa-c'GJŀ#`J1<ćRC9Gv %sA5U+C}I 4J8L F IP֠-I z!UCCNmi_Jzvnt;╚ȧZQJyo?_֓j\Qyf;>#H~FXP@.{9~XDO NaM\|] JpxXWb(Ǹ4~r/,{v"0hBI4C\T*NxbW a*,zTWF4͸PvkVrD XBMb_AP7g |JM N9N^^B1pi_<ׇdl|UpƐ)wA.QMn\FDRcX6ˤvWV Eei ).rM6cyΪmv5 T3;JyoHϊvn;nvq]T\`{{MXTde>غ6v]\M 1r& N!$[5žѨ`%ISw{&߳ =Moe5 {'2[HO05`y]sxLuT^[7`yp@<j)LC_S.@Om*v]g7e {M6㐒7]jX<̇Oq:k=~D +-$LBBk)Qo/vО'#VNiScnu`7Y|ڶ/Bԣ"9Y*N4T>Q!-<PgxFq= U A(wŽ֧> Ed8>! p ZF Z+e k,# 塰W`K`g`śnXjD2,s#~ ^[$2t"&Od؈`ԁD}rkv>3l23sHgzL 5E c˻9dEXK9GJ}ҏQZ`!`.CA48 ?&SZwc71#LgTY K UqIXW0݃L31=1۳KN1y_S1{):B 9pץs~A1nLhk*} z(|)Eby'tP[VˬFwHKU6h*nŲ>4|1 L 0Pg.h Ph-G8L3Nr7?m\{Pؽt{xyyԧr2ˮ = -P#rmNzsVGbWs:zzeK !|U!DT #O*( "~i1@֘|Q5(b$ҏ (4N32Fi%J`i+\ey$3vbeB aųt"g嗩\ uǽfacqo? OKRH8SͭP$-f8Ek]o/e/0S bXӒ@F).QlI'W{o>PI` QL[v4<ίL1w;4Ӥ{DO̞E4{ 0à(="> Lr*{Ϊږs G;:-ܯ7Ķ9=P'r4(_Z3-m9L^-^LSuK(HV ! 7“BB%1/GXQO< ]}ZXOv J J]/Ji;~?-BIvؘ{HRmNCEX:P~6zD2[ Zϐ^Qg"]{b쾢B,c,R!òJ*HXNVji–D#g>8cf<0dYbk}u9Gpe1;;"i2nbJvmR&{@NJzh>S?fR, YHF4Iy"!q(mv^35M5pZSt3Nc%Nb,MY@%d|> ',3K F4tr 29/7\LP Z ?/8k]-xߡkT 3詈dndXHhGgnVlq頏*]yȒ~WzX˱eW%ńiA&0P_]?v`Y#1=2Ȧ0CY q0Ny+PAfK!9nDf>6bކkpQ8c6@BEݽoL:Oz#IB\¹l{wLN/wQ]v]i>X{(XEU]I:UǓ*saM gliJٴ)` ~@0\CYq~t&Yْ*잊(&g4,GtptFa޸M^'ɱH?ft|O^ΧUl>ՎE eK>V3xФ5: z3?mnEGgEKg͞QbXbVVdQ ?X U*S5aj `k[aΗDNbEO="qEBd0wzDaxBx @xaS7t{~R}εϣU5Mq9&(RCH8+c FvGE`Lr5H5bQMx,#ˎ G9>V7ҷG+Ro$J4­~kܶva5a}1 ޭT /r ʣ[[fCR]δ`̚)Pʚ?qʣ#$dZvfn4h.-%:Fϱ;hmw k JZ[ u J4,Y$xwh24RA6I܍D:hxlsy\[ctVex}-{cU2u i'#ҏ"grmpP,ࢮ&SuFlIA-è 7] Kٳ5 s_Yҹ|ܳ <$xakB]8{ִ}βpZx?}0X\V)ճ䧖#pSPIW'{`O21wI)gu2j9Nϧ'^oJ۷ҾhNk >LQitU2M#R`^mʐ&l±'Eop=nNJ+vxmAc7T[C ?U G'qn2[p:Vʨy!>ۂU8jSܣVq)u'X@( "##ґm=%` Ifc@5||η["'?~jT±YwWXmÆ[Wb4 wubҖ[@rbk8:.brXg}l1(d9 ,()t6}'n"Mϗٙa2"$%328{C>=)6{"9.Ie}' 93uF@{`la4JN: C8 c.Lb1uw>'#dFUSI&y*OG*qq5l< >& 0Գ_E8G]; 1??!#!2GCľlėkY\kgjmj]3gB8VC*(o'8gY\v{)k$>R·>]!Y5Xo4?nE+͒VKû0NT3tDL*;Ft`Dl$"Q M"nv( Euc{k.!]-#^y@>ct#ѴG׸{?k~F v7H˘ "i[xR<ğɉ ~P+|.w&('[f9|` А|@[l:= XI"+_<-r|$jHK"-_ufPM:59nÉU>fB{N&)whLO%p >d'\>0BX+u#d]1[f)e܎}`jxA֯bh?X f>W0-@- eIwjqE4iq/w(IJeAZ]Lu@CKjv[E9zSET+$%EWj]RoFvY-eZe]%ӈdӈوU7|4/q pxƋlŝVkyK9˥w&䇦k[KM)Ю[)|Ӓ . x,k0l5'cH\ti'/.mFu ɄQW<|&'ߠFT4Ez%YGʨb[$mSKkoYL/IXf IEߌaXH^JwYWg^q 4 c!>5)b`PeGB{ZjfG5Qf\LD2q2El|4zs!enm ;;'92p_)K/e5 Hj@&d0C<h=vLdwj6=NVɎ; .r<Չ6Kf.Дn_p'656n*C22))GWQT^Eڷqif13ίVX oy)KsQ&ahvBSjFDљH8əlOCaтHXhB.rD[9M[- AnW lKyq`G6BS`nrMt qR522~ب+۫ 3Uq95+ȼ}Kx# {6޸wX]ڹ2@.Tb X p,i^u{ъY.[{h_d(lb̏iY#ka̻*ke+.O f,- {+ۄ&$܋]uVkRˆAC0Mq.Hubtl(wL ; }٬(L 2QfNVd"yjz ib~Kc[ZRhRue"Bв֪\oQKCPBW$ ^<#DV&fpk.iWD A _beKRV"T\0^}Q\vn qO !2rݢ@vXNyj[CN *H_CD'Is9SԹZ*uFIqThn 4\ NAyo:l=|E8E-߼g/:.7{\I6 \ƍغo@q 1D"KO}*[pnQaR\X~DuA UѴV <զCWrŔ+WtFy5ARJW7h=<:!n̹W71ǼL$pw=һ@g*Źs" oB8hR:~= y35N)۲^a܀^UJ@\JFajܞybs/a>O+6nBs:,} iۇ8/.OT+$fgP%%BkV{[$ov:)=]aF?"-2y''NyμKpMYrZ #MڑAoۮM@M`@ˡiEAO0>';Z2+o%h2j+Vs MڂO/OtlA`vr΅SI5xP<,](Cr9gb.}e91^ƖD h0BA{~Xln^B1V?k7V$%_Pks0؞*ԝ-[:"y3!)!ݥGF0nn*1?C]#3xyzQd[8龔ZcVӖ qHbV>3+ `4q*ozuf;g<USq}%8-[}~ϜE!] J7 pRp<|}A_:JD/rF8#ߓK˻+%zjLTlWv)k77raZFq : c%U0h6MG5"s2=~h/ wD)8rU^nO-py2BNQXmDqh(F U, c;8ѩT< 1FQ'EqX}REWb4kJuT7?NK=u7 UQCZPxpNm&5}옒H1a=7Jm>YI!lu铀JDhKA^uJ*9K *3#<12t Ga0gV&y\Gfgz60 } ^wb屜d-fSW(ӓy$wl6u\x2;ZplXGO`*~uz<ʖB% +gkcR_8+ﰎͭ 0ÑfluHi^s3ɹGV,5>g Cmes -Rhz_7=#2sN 37C=qQ5 J/RX&ϹLo R26l{6$ܪ(LA/B{ƕj=|PivGGsK疹"m+xC(b +W/eld~zlX2+UlӢt=ޓL8/s(!w@pM`:loS/zyڳoQج<(ЋdNG4:;QV.wCL#X 4*k,v߬Q?@ai@yN"OhWTt{Ɓ7hP܂?G^WFvզ$zޖvzq55\b i-9K7~@6p))*/Yo(!K##əo+pVZt#`70RL{5ख7sv, *,i7x_UyvC;lzSR&.Xf@BPӅ) 4ț:RUuA;.mτOJs2'-ߓaN+|B%T;=()1y(F> q|)՘K2Jd,3!]`KͶW )c7 /hwv݆J`WzX;'P"]檂3R+#m*@4^՚ ϧa/ >D 4N.5eIKm;W7m&V Lk+V*>j ̑P$ar*?P/J~2_,Wl#g<{{pL^9@JS*DWe9OXᮒIv62FH)B-4:(DjhPssA ʿoMNXZFfuT`$jqf li!6V@#g$Umd=죡LS:itבpT>Ki0lhUm_MI 5l\L5ڏF\{x N6{QX.xOw*%wnj N[/uӠoq2F§3ql}$ u.ah a.$,VcIV}6KnK|^{b#ŕ#<(7.[ GB V.ե,H8 ud<DyMSKПT+ңR+d-5Qe$"9fB́EsIi3OMԈ&7nAi~]ZǂUxؾ.:ȵ@u@x^)?XH/f_ {Vr3i0Hlqqپ&2FJO?(U5ϣ:'h7 m!&b/;,Hgh;Mn71N߷dHS4gWC[>OwۆE81eO ͙.ݭOZZ{py{6GxaɸrHo%ouE->q-uGrl!3ad(a#Gy|@vQ;ѻ\`5 ;J!teY\BĒ"xqyPj_50kms >lz@5۔'lq#Cb)k 7wGց~}agfc |'#ae1 V|v |\*W^۸Rd1cʙj]#MN(27 {{{7Sv>8P#g1Iq0 s0)&iVnj_zUJV:;K-څ9˩G,~bf!yTH}9~ykzyʌDbXYCy`{`L@Vq1sα5iBWRH G|d4cLB Ms kkR&ܟzk'Ug>DyZ5D_V5^ rxkfn4H(G6'@eu9KS4VĞ\ p u!Oݾ\0O}П&*뿀I[;0'Oo,L9E4d@ x{%t37^-t^ {-a ~:!QoB0eVJCsBS"&$taDI)޽$5֫n0oZw4. ܷ'[bclS ]%wk֥޳.$bݴ3K̦0}Sr{L4 752Xy)+{>V-+u_G 'Ă\B2ʢ 6/⋪ha7 # n T4ԯc'~y8"jZYxW_ *28Fg/!OCwt}-ߨ5Q3 *+[f4-{w_k7T e6<5),, nvM61Ix+|-]]+{[XaS`W31oJ9'>. 5jW~]^jSp~IXg]YzM: {{nV=]޺kpb\X1ߓf98FJːksn {Nx~+f)8퍒6{>Te @,admDl&kcwD>ɄsBw| LRG0d֫'JtNQ?3|8 \I[q"`}%OЫICWF]\1._!3o_ p6/9"S*DXXV'M26Pqx&Gg+pri az`B2{|Mſ΍ hDvDoM6cL/H( Sr8߇[-PMa%O z+ Heb[_ށB6xhTLV䢀c߫ըsrNս;tkX#✃av*"Pb8,3e9Br;ܦ,[&v=Ae*Ɨ36/4?K]пFka4uڥιt-&UkRqDkϋ,>e+et;1#hv&c ֊6Ο0/ 0$]鵰VR"H9EEӢĽؾkql :ӷDg{_$!o'bnȏ"QS__?4mp6= "&xU-tUUQJ*!pDUi:*chmkK;;.;̓qk8 /#lHjWa%(Ȇ2).>0tl TdRp8|[>>KݍRdI(8V=,t>rs*K#||2~Z)b9Ё/]tv!"*NxEc 4xs~TCngq_i0iHv&"Q Vx(}Vx{NcӤPuԓt!@A[ELNToP֯L.8yqxeF.׼y n-˄ swSjevW>b )VHᆘ6~Jԉ%աx6\eXK'\f#낻\48 u{aN7qf"%jC9Sa+dur h+雝"샖;D3Dm&R >A׽* a,(כ FMQ/ JI^Kc$L ͣ*=*2Fru+%J)ΰo,+Q##EObgc.Rvي'u$zk{2(u]H ~YҬQR@ϬRgMۉQ I3!=l5#6#/^f%><.R*je7ю);,TXXBk s'trAVwJɌ)i닢q5h&Ct FkRXY8)@"28TpX'G4{'abf ̰e?2bZ:ʚ5uia B lNJ4Q`˦JX&/ `#` `\M~;q 7&C_|0^>]dw6ZV҄H}tᖶwpQ%xF0vfJ_ ~=pԅ }{gߕp["U<4| I ktL~ ȞV<MiQYyXV !к6l Ԣ/O&WS0B!†L4]- ]`y"/tk-V:ڱ굻T0oxƞdԚq~f7i!#GKEz~lɈ֦ ~e:O N6wH&HuQ Ƚ&UTeB+8nsz MFYȄ{ҕ勬~U r.\6ePCH`< f&ȫ;ncehCJ dL#AB Ië%UsuR,"鸚cMNT?4XHIdq/KMcz5'uڒQ]R̲+F5 Y=kR<pjϧށTLRH4<ݓ?H׿:Dmd5l)ߒu$m4u.NQG@^u2X|˕ܷ|X]4?R1աC?/{(0%֍R 5mN%}RRKLڻ11}+r8̽W:SNBt(+jz[ -pCف&oonntꟂ^uWjRV\P 9si(Vr8M r_肷 r( &9+ե(yW@BE.~d)s F9 K*}SqqI{Iy"s"}>,ϤM{AQW2VX8g?8%qQ|N0L|, -cV :),n78rӦ;9:Aé|M=Goȸxf&XuҌOK,Uvi^KO(S)ʐӇSkt( PIA2^D)Tgc^HTl iYdkάaF#I$"Vb3aB$WEQ TMi= 37.KSWܞl&.ALrBI%X׈ceU>4Nt%]3NXʶ^LJÊkCQ$2M< H ]0Q18Sar- .[W̨3I2OIAS@pfDtº4>wT5ɡO8:Jb~K\ ˴bcI5!A@nc)YP*qS4-k"c7hWC#dHmVdJEMM;o]tj}X4qhY:MWHzt?9=+)7]"4}4/uR?YVŇ_8QS3-ar/$ᶀ_ {]K2Ik)j( NjV _]V_hi~/InSEI*˪.!(~ ]ە7d2̟<.&{16l!DZii*%qz/֍7a] JNuB DZǏvhg+][7c]G292棍 \z;MR lt$h󋥰Q(1fm]U,RXɢ=걂zF\5624¸=]k[Y{xmY >ny2Ƙ^A4̾ؑU`T4~,Mw6Z1&OKn\%d(*\F'2xtsD!b6}J$8,'&ӰU-wNx 3:C"KV ͊3O4=FAܯқ*nSuJw!ԟn̢li\~K s fYC,+{QlSMW+XT6~ mɀOKvm+*|g}Mdg7?} 8jt@ԚZO]RAMizOmީ8c۩;F)""◵fvb NF / rXyCt]C^]'&pYvm8JJ޵T(p-|:`SyJ5ayzH|^6}/8e+V@H| Y$Q>Ѹ°$>CR)DS_^F-9uN2aUburp7%IP-KSWu' 4nJsC̦)8yn:TY1|9 Bn.p)`زʨq!EН_#obg/81+QK>(D1R~` M台 Dk5`S#N^ؒ̚ܕ[gMfF\cmʳc>9@Z#ƍq e3t osWWP]ײbU9y+ wp_qE^bܜV9rg=X%#t$5@&{K@wjm0eÍ`ab1nϻEG[Uvq:.6oβ"kPb7L,ѡtoC:H>ůQL~JKvJwf*1<}W8^!d?g~qLathQ %a,HL0=\cS ׂfKm'Fk;7m)opb Zƙn^ʴDC-XPV nRrܮii6뭰fn^+e wU q tPm>z3vz6}t!14ڳP<>AQD΍!+}33 hWT:vDžgi9'˫ E/X_{˖ øַE˻S3΀ीz@gU+BcAX|0+qﮉSjtݸ85N/WK%e_!.e G1fDap(C!NFm\Ǹ39P=eO* jut(uSWxMzhϾ*ہsī%IZ U@6 )mƺ쭅c{i^#]˫mӥ*x:H4l[/M&A?1Ss(:rh{^hɃW(S{zZ<Xu*\V^/TPgU}8JSNlo\s{ڡ[v55_;uȫY͍.a5{zsTZT@eTϙ+yl_|òF>aPĜ p\y(YY{uXH"NWT7Հ8*!->f$Y#1e#Ծ. p @_2f &u+(3BCs@'o5Q͇`{sHEFx}Iamؾ֔RvnﮨU{ۨKcI}{~dNt{zm,q`:nfJs8=kY<U򔮴ܒrJ rD#Fxt"AÒ'Te'$J&Jq|5k>b8'RHM?1 5GF18x*$|_(\I֮@n3L;~SEXVcʚjOhOtAȓE-lj,İ?DWP^lͷzwvkb2%O$w#-%Z.XhB D67 x?J?3& `ƚ#?An[s澔 8. }}M/E'#A=$a6T}|k\!Y_bevρ˄B p훆$>ݫ2}84@aֈҬ]Ah BK+ !؜#s{$tU [ Id͵>gĩ.^#wֱ i,`_9䟲XG˓DR@^ː4VEI{ ?ū5/6ۙR ;9*M[v$З(5[=Myc[ٴ=]&A p7[Z܏W](i# eh*B7Yj1kcN kN;"ؾ ,=@/ӄ̳r ^ d|{FF`EӕC*C<]ӯbCP^opv?7d)}Czˣ,hH>c%poFBG63:8Y0\$0yGd*@"m//90qJKYdv2m[hf(c/Ʋ𬞡_ܳIpo('S%~Ԟhy/E)[@(ަ?\yc׶F2LAuݿ# F.lrsT.Y}9 hxk=Mݺ]L,lWqbGw ~E]q}J(9j˱; k{!br>Xu:c@Կ*:jp0ޏb 0i ꐮ!A -6 'z ]vMӶ}6y9Ӭ=0&R^G~dl&AVȜhFPcz?o!}ZsǠ}l˼1-u]E8Z&OK QCr-;KC;hS'v(`Pݔ_9'K,Ɖ i `?}ޔ%7]M,Y' #O?Ym:ݲDiҸbV,lCBS:<qgw) *Ŝ:o,Z݀33fVA@dV~caL|IoP9#_{]EZ.fj&_5%9- nŊWW Er@9;5*a.7vjKC:.1Օ`zM*K2k"+Z*h>wN-W7<$gĞoicv7%|ß6%R],!N 5Hٖ܋8+'jr!H%dI| 5pxi1+rthpD[ypP- y* x4lP0f2!Z,| 4p5ɹ.Ib?RT3:~}@eKL k?h_YgPls&^Oꔢ8:~'#3؍YhB@!FV&2&n8dv΢~PXs C;?Gv uH›^kO,Ͱ.AY]!fdغE>v1 \8{gMy*~}$fWr4 dB"F xΦ<[Ro==|"IB 7_:0*V\hpP,.+:nǞ,%e֗Z^;Q9 t%`RC X#9p1/lCy aRkdXӁ7Ad?|_ʖ˦ڙ̻U:ZU^]ĒQd&LB5B~]V'K.ZwV[om "kཱིOS7H3ӱwe-9ɧP G^"7lYLLL";?\kN\)lM-=։Y7o+5҄]Si#TU,1@qMr~Q̈Pn4/rW"hjųrEXȒnz FiQh`0WbyQiPr<\lDj=em09 ea6c}:o5̾Ō^#zxٮySur6~ k Eo8L+?_f^L(e]y. >גb9C1GڮEx靷xLeawhc߮~c%@ pVhutRUɗ=0dcvʴFZ3 ;/&;skq4#m{Ã%F%T}{ؖN *J/5(K+!K30NϟPc\9Y?Hq)D}T댪Ym\|ء^-4{j܃갋0w\ h՜YIjd , 3kr8^{5*qqv,?w˭HѿX[ȡ54VW0iN}Lslhh3ĜX~.6hpQI(|xU[2FinSN-yth40]@]ٰr5p)brU0BdrzclC3:jy3,~*іY-b϶p0) ` &cJLppdRm'*UUƐ]w.d+&Ml_K0\? cJ\.QH'+7/>P`ʭ;'fLq^Y3j_gƿHHW_܎>0ذzS맖dya n5PyR7,;`Bbٻx 2a,7gSgrŶS?=V]u(_ϕ/w1pN/PFFĠ +$(|\+`mmXK{).C5Zɼ șĖBD]x˃ѿL$\XKd5dEou7Q/ "L6\Aj$yzA}l{\jnAP qCUv{"hS;6G5= aiYJ=F4ϜxnUiy?"CsfyɈtF~uU*Nj-DՁ2}=R k2XN[}Oai@Ѯ'{C=o=O BV׮)|+eBn#6D\AtAmU݇؞Vfh@c{I C8WiH$iW8;hT SkwBUi }8>gX 07+01?Jc[O'mF{"n||r,݆N_vOF% v!5%-<ؚ3,;{KoyL㣰.:;Q>CCё;X!L tOr~6(J!wSIg֡="-1H~fԯԞ*J(ͧX˥;ϙ cˏ$o5l4 m9YYB8b x|'I]*C)txLL*g_g(I+Oen]kSԉF隩 dhЉlzRvhK*բHV$HwVtmH{(ƈ;GpJVQB<`C[8Fn r(]!/N³X:d'18ܑ_` @>ԅ~;3<"!( =) _`6ۿl0)CjE3rtm4- uu)hBvgzJ$< i\rȚ5)锹<.z*vtG7%9s͖bLGw!kniȃX! 5d^]kRrA{D|..u7nh^\wet' B¢X<CÂ*[C>PLԇÜ*+!L9ghjEdB/L]ZRm +Jsj&UTčn#iMP̮zn-6}ٱ 7`Zk2Af -'0@ˆ?[vHht#IMEWoxmv#V])W3OSӚ_&64#i|USZP2U֮wpq{.ބIN-e,">`B[ptК铲iu &&W 5BB0'MF:(vYuKH*'FZ[݈B_cݟ"̵%cnYkM#u.ZvG&Up<ֿNXFh]=c]1 ,Cj_s4'9u5^(\HJ.,ad3!œ̏(:P(5!gkv CH}o9!.1]JъttTe"5Z򆞗]|0 ˩Qf}d+T'[mv'UfDb}J^w{}ra~VDȆ:|ҬW}H"f8YXe:G7L5ýڸ "2Hၺ4b+*V|9Ey 4_mc^#R0ƻ⣘. [PWzYKڠ[䙶b[d7jԪc5u| @0JGa-gΓWFO+aӄ+g&0"!)#ל_qi+.fIT Y\B.Rv(%= )}*I7aXipjދ 4 KsoQ0z¶[t rD _P\A,cWD̙O!paw;cy K+nS4钲v0[+QVqan{?33<;bb.Ɣ"LAg۲!v^ fЎ%;BjbZnf_'&uJi#\:G9J Jw m?-y@d]#PTclW ~|9ٔ} sZ4/*_2G]tr0i]@a-caYuuQore2Y {PJ),j 27Ք2>yXirf kFێ  nZ\܂7r)b0[4 ]l9\{wĄRq l9EX-Ȃzx+ӕ 0g j m #*:N16g)%Oq$aY 3flԩ7Rb`a40IWZ$g*&ɿدqM@"]?A;뀸id!|{RTy§$9U*<0UʺfsȶiwWuzHknQAv;_IsKsI@}.4|]; OnI&'$4 bD CJ&3lG6C;>qu~O ! _irX` CUѭ_ k3Wr4~S<qq_ q_YAUx8pNH?l(b&<=T=Rw@VS F mś㴕?HB !m% w଒et)gQ%z;5˳HJbob鱤;J H _ˆt Z:+>5܏0-+v?fr)H#!-3O"9\W%RlE [ldVɨH޺gk^$pK\7e?ӼXȤ`ృ3xvW3Mq&uFWuo'@[-`;*1ʜQwnpfd3Utpf|L/-ݨQxªc;kbD!9x^Vj!X x -qǝ`zl߫eDPgxdtoGWQ#)r? MܳgTn'n܆9nI֓t]%dnS;yWp3>"UlIBBzL}IFdr0$Pn|?\ܦw8HL_#>dcE.Uj!|µ`FtKֱJ/~UzlDpE*|ኸh`F0IFInwryP? n2qYbѩT9 I66D˧+cv mQP;?"#2iT*hJf) ^J00J=t<}&VE6͚/~WCUryY1`##p!E-5(FGm!U -`Ծ/h( smBt^BP E]K8/bQ̀؆⣯ d Hnb]x W҇m`;sJB-(j~T慄5Щ악!$JTڄ3o:~"(ÞלrX>O^.}J˯3dqQ3 K7\}{ҿҊzX9A:/6[=]qDqr`尚&: *Fd~E5?pGX{~YP5& "J;{^ܑ Q ?*eD%xB@B d6Ѝ:d% w$߹F?Pݓ M;ʧsc/h/x E^: ̭aIk8 ]\K ކ xXtNL=A(*;M܅cl~ G ow d=ת,xf\3*}^cԗ֭>!\0P!E`3&x'"3Λ03 OMrxzdWֳK*0qg;vUF-/\D8Y \PYC -K}E#2^gOdtsLs긃Su7F f|G<X猥WrQ{w{ fҙRXŸK:/pk]5-{ckJR QΟd]vgk]x$Z ({dǴ: $hY1O* nՕ5I31A+`˨S3^C=ql#%Ře}LfoMCrc`V*{qMGBġ~1JK5D66/hO3]Nq|Z. WB#N 1IýFה[SVg(V-C}qP[1haAmb|*ƚeYyѥɟO7 ${>qPpȟ1yiGiժVF箤֑|8VraAX+7KNq6{oez]mci2; cɍL-R0?z7/btt >0`Q8PĠ' j]a͍=wZ5o {+ ;1|o `I@C>;l?۪"$89G3/gl2fӕ{KRJfE*d/5-B68}j_o[F$ PM#zD F=fQ {lp0V Oy@jC۶rO_RMv`)Y1^"ҷP Fw痮U+ʔg&uي 1?Nd4(+gKڼcqTU(wɾ{RAQD VʐO)[Ej,#e>44~|D⽈8 aFxhR h9$.rx~.%,z\ iDXCiKhduu 8Η}%j?Wi65/wKrar"{R` ṼNNbÜʂ ]h-Rgysb^s?fm5Eh%ךݰ)r^oIwҖۮvؚr _>3o%`ZX aGɶϬ1 3Ȥ=¿*9Gȭz' cb{p]`IwѠj\jɲ*K@) nz4 v0ЖU(>.f(b.PS{U&Z5sb ึk+ɛ1\aCj08–G\ͮPef ϴ|65OSwNh_Oȏp`xe@~9iqգ4MHLߤK%k< P9J Q~^U{umkV Ja mR*v ' FxmElTӋNI?gR"`'n#{2@H=I;3<R DHY-cgN2*KNiƒUl):P@Pk 1}?1ZѪdvW*}L7B\Jd(0:&/Z'K{QrkeɪPԩ{kwm=Ge+C?:IS[mL7Oa򅏜GƆ&^@xQdqʦ՜beW9 ?޾Q?1_FKz^8NL4L؞{㳪+u=jY3G0͙ïVT,SVr"KFSYyCQɉ+_y`NS~w{h}[s_S(Z0e"b DH^MR#?)@TylJ6J/leX,G_k@ludQ\4w,!B$]ʣ3З<5r[ɍJ-"jA΀zT=NZq_a`wV62ء`qàzҡBosu݈kuC3kf+%}'N@1(gnQ5cz]ߤ Jug/y6dX>zͫDDp s_pEYm7p 4ƴBVK|XW'aAaz0 CnX| 'D0q phL58hqR {H8fOоfی! )!ߪiCn~^sP`!ℋU_y~c·T`"/%Xhq'벉9#L<>f4ɩ^:Z92%+KߦP]+_!GL[=^Pym:@^Wj{ ^q=ۆΚ,buD; '}16 W9>6A+f_nA /\#rN W.& ?PьO\dԻG~67 f*#DzX^Y'x ިKvbXI"n34fLH|N㰓*=_5f?6&;J8figs5 JF翰 E~)ZR2BT`̷@[ȓ. 2ŒK?'~"vDz@aׯv˰jr^+@ɼ/( x[wh_3#u-muD}ۚ6OO:)~P6*/mr>B3p 76e 'cCeFe_/FƉx qTNqlPC5~ip޼Xs"} ܵlVr "pŋwws{,Q+˵&EF3F$sƋv|/ϕsLJn !RtfDI5Oq\,~eN"B|h-} wfbgFaZɸf4kߥfH ."洂ݤ>sgnZ2' &ě}7ƁhcG (/nRO h$sE])M'7!3Q'l1 .-Vj ZW_u\͗+-=,eߌxƌ^wI #c0Ժg!VDкi]|9rP} 4r"z@ ՞f]Ks5SHƳ__AҢZ'k dE' ږ;zDq`Kv0 KBLFgcFd^]+U٠ WIQnwgM5_ NJ t05ѵ1J`M,@`D0^cG|L>C<ȡ\v)M&6ԁw뀟5[/1^>+&k6#6qeztSU,l2X!yȅϼ+3RHٴA3_ oZ*IX}xk*q*-1Ht\x^QxE@+C ssOk3MX%; ԥ(]\JYl/l2NMؾBuArFc>Tb h0ȩGh|H)- I[--AIf/v,*u.qb7U+]`CɁu6'\6 ipdhbf@ft]Y5kȚj_W'y#Dc] 1m0WF'3Sۇ 38a<kuSyӰcF?N|7*-M> R&w6}i$] l;26x^]Zڳ3ps=Fr}M8;~o1l:J$`BjsJ7wx_W̆?X/LvҪ~$ R6Dmw%Uj [oj.ᩘvLShp*9&&_!T>cBazj*H; ڦV.ڻxUyf/w՚P26F]G89'YcYCMR8j:@pwq,pY)S |DW}u>Uحa&}:cTI )¼qJKn$'GP.꬚4h&)fCEt\QA#LMA$rTILN0p3S uKrȘ(5kHwJisę97L~&ÙkO m, wCѳ%Tڳ62ПHZʈЋg|V5UBChwu[1di?S #ޠVGU? -[6졬[W4B/+q&Û&/AcT&e.tpqU5'LOYE`3-1T(I^x@,zdo"!20?&qVp$BgL+3-=%Zd%ՙX]IET-k6Tw˃rz>7T)'nPdnc_^os.Ga ̔Sep<  8{Y,(T CMC#-ʙآumPO%q6}7f=>K滿+>q&P'Ko9uߘ_ [K \!`RS90e 2e6Y@mXL`(G5V'paCxǞ]=,xuSe&&E^wWu޿۟~[ieEZY_a [gîMY SA 'fYp#ꍂr?PGwCh hm3_HP2iRn}u(ή#@mKښ9?^K,Mʓrb±o 4S:|EzcDvdy NkZ8^shݒ9V KLt&43Mk t(!iزۘt%SX ck0IޕYxI^DmO䴖(" \L7MrF8?%xNކ #GXn~rRL0D`P;{k[x;h?D m%8 d@ /N)4 ]׬;vdp3M/RL|&c5GUKT$K%I&&EG-F5"Su?bf~1x?ma,N뼝n>usP)$8P IfPkv]NAi,9q|^ʜL/llEOf:ORfʝkPA7zj&'?HMV]?5ZO7 ) 4WǶ;Wb0z A\B\Ne~:)ӏgTʙ"/ckکiY5C9m{ީS %Q8ƉgH$1j}PFگ")#t  =Iπ1?ʳ'ʪ|T1he$yY0܌蠈\"+i(FI0R%st'd>ސ:mB&uz21:Ov-4*xc܌Ea~:R&$Fl˿T{ f}^i<*p]>`++~t.Eg7:/@3PDtu9zSyu,G~o=hDOB2£5"&8BĻ1&C}3- % ǃLٰi1;؆辆85a!Hx'-HZ&j f΅{!? G/'WpCJ,n@L/HSA-8SnX 9Fzh4twsLAɇ3O8*@|_82\BWw$sS-;Ar͝rŰ WIo{k+gjFg/",̘>VIs45ؤĞ笊fPYDV=pR>Up\9Wfu<}/)=];wWݔtPlV,hqp7ҸCS:;(*JgMG{b >mXWa<\lQ7|wM@qESr^5H\zz$71$G ґ}v[,]M{\@Y/{dF"Q88# 5 5uhK3 O~jmmIRQ~Z$6׍D? }td*T bdx mvlrɄĔ*;J4wӝ=gn껭Wȗ< ^=ufu:Oi(iOu?#1KI 6y/kke7c8va 7:s F%{ٶ/sKwpwSr%Q,Q4-d;p5lGt-#dUҚJlU BX7xnǺ#t[E黏3:nj5U ~2dž>L[$@m!VlUdbI(*2@~~+T=MKq!4vs LT&& <"{a΍y kBAzw`[X?7xĿ"kqD0 >s;"-e[z?gb0`8/}0VdE9wha`O6Ӫ#[tzh" Ȭ ~-\5bf?wgc󏋨=lFMoŎ 3~4.d ƍA.lϠdbi9 ;:9C>NJ9#B_OUOA 7Jc* [_[03uHU u2kJ+=SúgEzkU;&31jziC:,BAy~zy Y||ƀO+z9o:JhO"!7^"5<`CF MgSc`e7ɪ߲9#GG?>ΰqz>sih_I[8񲱻AwV~YiZ40TQ@%A"RE/:u\̲D~;#LT3Γo Ȟ "m^! lKp0aW3ԯ }\!n4du+E)/D[tVaS&$C=7'+.>|,\c 1<~LqjdU0C162mO= iwAMab8dx4~tm`ki-mךKERuOLLlwkpYEO>RVgS놵 4,P,t7$xҰ=4K΂Wo ΅EQR ABUOف]MMgpl$!m21*酦uIdUTW8hBQ~ Y:-RI|0K3/B֔qOeKBT .xn:pшg*Td' bv\{aΊO#A*sᵲ|X̑G~gxAe:#\`Q.w}9:޸v@ ~rja$`}GɄ7mȓi'ƚd%'ӆ=tc2 V/8Bkþ!Z*svǎj&?yYE7?V$[Oe; %iDMvG-3UU. B }B8uBi<(mgXvPZ, _RȂvOr/6ד }aLi )p LF5 K뵤8mv˨/L-+iN/#ϟMg殷hwD+U!4&5: ;dD ^X9_ )z+@Ax.fGq&|īԞXOչm)P2 Ԡ+&o1!*yF_pvҺ t'sŤ,MSH(SFj˔܅5tg|2.UA\ֆfdKN2Br2m7O aZcљdoflNz/& !yPƅq쌟 qK.6R{-vB%p[,KPe-bh8Ce[UHF1R/3 ՜o'gW>-0 o8@eAb׾НwJ>ƴ7Ul7u&k6';[MpRqx+xm/dE9|iPۏ??UbIw``;IrRGOS'c^"2)ƍ}<i(!xR(1[ה|SUuz?!/ pCDm3(\D4~'ˡoCuyL15rvc-%x n4exqvTj[r63 v 7:ױuu&icwN%=vMFz3R>Y1 >1p Ư|W--\I=vL1ߦyDq K?{d,P K^mןvsUܣ qEH _]Q0En 2y[*s[ oxIjg_muXvs6# jhVlfM!.LT\zG|v {I}7Da뜒u.j^PkBkFZ18T#k97+U*[ u(SscAڥ$ʬJϛMv!n.fk"}sLVXϟh3DG%F.'v8JmOk9I V#kU{d'/DN,p; ^u"jV mi#nL'ISxrRU*([ rh#7d т"M#/cĹWxX'Ǐŝ^˞$uCeڼi{Af \7>Ռ̠~'´2Y7t荖!O;Rg榡xR!ܜ|sqs b0hbfr+N֌$A8Mh]'ŽJU/{bP 5fasS.Ui%4j]6[^N0}}&O^u6:?8;yxɒ +H6qܜ棞G I_alx*":7i͔.<tm\fÃONU2$e9 ] ->XJx+>i.8O3uʽ[`^LהupSa@sZW_|Fk!Q Qg>9y˵E]߆h'1lnDLֲ (~urv9i%F@ )ߤg2v2.DZuNT,4;9@ _oAcAl]HRΉ[|;Ir |kuJ)Bۍ͚9lq,]9sG0_X万 )Uo忖kwqF @s2v;gkK_ ^s%>kJwi ]VH.aHfr,ԅ9ǎ]D6o&?cxVf)|TNt _~5x ѺG Oi!\.SOXp'2!Wd|2ޯ9X: _# [\}x8c߄1A*E}XËa^.׍MWW*/A'DUtPQׇYmg+`đ8T}gt/릩y &Hu>3d͞;^HE!/&u7c u MUpi 1C%-R'GPZA"P*?wV|DJC h}b<4fV6y`0^Y\?[g-cJFP׉uixeu>T/!iQ1of%H=EJhYˇq)c !qDhP5g|22KnC5s %HDPw '?#k u,PoCd`'lő)vK8=@۷Bnw4{,A;٬yY5 , ,"U+؆ٛ ',0i{(Wc3_#<@Ɋߚűz,Xs:X6y:842)5,&ڮoRõx-kق*NS61kLDX4ziͳKs#H5Sp|^U1#j2bf@KHh`)Qmfm$lq?*XIO 8ɀk)JvDWJY=,{Νi`{5}Ի Lqbޝ 43{΁ XoIl]U+jVndG@UĆK܇eoЉBuVc̭fli+.OeF]v ٯKdeՁWKm)0Y!IC~#u5ʋ`#G aS:e"ڨ\i*${J!6j֛g%hJry|a{n[OM$8k"$nS_SWhԗ U4ZIAD\+Vp #1[)j7+Er=v^#j]g1j9T51S4K:"(6}btDb8jp_Bw3aZOQُ!k9N"f2q7h/E;K0g-Xa7B775{}R~$[X }Fus߰+ٻIJM'iL{'>H r+ re9џ34%UFX|6LT?W/i*EaxRUL  bl47\'D6_MNǪS]ܼk!f^ z8tعu`ip8K8yM@\~3/pUKeY0fW|U_ܘmO 0%8b=׬ɡ|5jV7cNL]^Tɕh_1: !}#mi PӄxuhW6KET[ٔ}nGWJ`EKxg뼪PE /$G9Np)MOpt-*Kkdݺ6[R{6CLlPo\J-.۵#-Q jfa7A 3B1UE+>'1UKAOJ~Gu]q^Ս]fWtxu>N?Aj$]mD>;xBZ1SYmF.. "ۇ19D5L/(bŭo 7m,`_Ot-]~݃M~Md mLs"-gIu#NhsU==v&|?wq [; )lJw.Fnqf)Nc;hIJ >?kP[zȟ&W.HrX>=6]N|T!j᠉'];DpKP꼱u!7v>\mH$<5*{8<ä]"rZHYɂS:x/Dw)&CXk@NqRC F!JxMRLN%K/"YE9D5OZjB%sؘe[ID;-5%U.*+2v9ĺ9x.vB3Uc C\e^ C6y 0u2uYL$k}ܲeҞIJykQ{O7pN3J{WP(le5&7" ?.8skI >v{߸/s:E.E]mbkxͯ0s?<^P{1||vQ3y\^U\s| sC F0ޗNo% r"7"%m?X4aDjWH;j[{`abGLc GW dYIvk&ۨX4j /GqI-a%fU,{- &+'7뺉K=q ǵ"GZH;U>oftK&aI@nAD A )2ES|@b9-*ޫb\/ 1$gP9.}쯎s:V. b ~J&J\c +9 4Qk"|Mv%X]yf2x QQ+` {? -Ĝq0`a{ӫ$kC4:B,YEDaE6@?惽7A˰7/E@0"#XG\ijٷ{ÏP , 9">#a32y^K zK HO.Sp}[kwໜ!|IVz؃sX0J$:ck'p[3?TުG> noe$ZXo u5w_(bAa@/3':`of ; }֧XF>(>hXS#ߨFvB/;(X:Nq;i=,]T@n5tw}E+%4B2DSjB132+E O,}v6}Ǔ3P/Z階kkY&iZ([8"sv"3fkyXAΰۧ6h< K(JkUlqs$> sʡEwo5dc7GM!mmzeo!ަ ]¾ۃ박_P@٧+rq:b>3yX*4fXZo~\v 0YȈ+S=> 4>7KIDD$  yzq'w^K:cti].MQ.5˕?0"p=5Ck*;Ak/xaS!A#HqS.b@'{&U=xYmDҐ!gRڋF//gq =7i^!?f9<4<>.TW5M.@+7ĠlբW/\[seGMawC{vc}}Bt2C,y' q7{x 4K@8W EbDt,KEWbo˜0N1sGTm^ļwE亭Bjno+KnB,=䦽kP-x ̨gnqn\Wwv']y콦NH˾X<$lM_ݽըƒMޥq{~(ͧC0M4vQw G~MD=esڊ$uN!0fA-)w+gR6&ޢo=>%"Aeb2L 5)9PtD q=S0Т J .!/Ѳ6x2)mxWBay؛lN-[vӔ/3J-(BWuTeem TOߠ>Vwujd[ԦFlNz7!X,?W7ʾT2` ٦Č9PŹgWwX~qZwQbWRaDcS~)lё3U%Jf+]RW T U NKs?le.t쇪՘Y]ۏI竅M~})<1AWHEZ||hau90i& 5S Z['lv͘qkey \vvRzmm1@}އ<;4/3?8_w'H,b9]hHtL,4 jrQ\ k銙&3| W;Vr5têtín_3ZC`@נ$(q"1u,z`CZ$&RæSq >x~Z #1"7h*A;{x yTHyzlQ7C'rʛo v!.jT+Zb*zTGo\ϭ # |8 !+1,6'Q:1#IAV(ٙ5(Ina}+Z\:a ^zuEg10:jYFs#nymD ,hdJ?}-?˰I0Wо򱡑EwVӬ\)?1~6Ouyml+~AAOR0% ߎP׫BqB\w@ Z]_$ò$r* ZJ=y'IasY AXy(E=vgsݭaڨo ͻ <&BmX>ZN˛>7\kMCf*C]lzմڄCPWiV"\Q0³: p'=p%\ z̛U1k4=]Kor7Dʩ,{DLG0"1X?'~=$+7!T'n9q|_>C \}_f7qͽ!5AB$X{dƓ?sLH*M)VsѴCxwewo'Pg; A̮7~U':,.}j)t*`D˜ΟKS1:QxBCFk5q:扫J!wdBkCiC v;qbQՖW4W&vE_Sc25H`lP'Zn3.N FTCQcq<->帘Z 2վLh(5@WoF-9|g!Hb%əᵬl"@ȫ2|, XL$7 (lUj#kq@wOZ.>T| >"M$dS/ {-8j{L1xqOz.URX8$aoP>(QSq'qSǚ  T 0mꏩ7PvYn#)9jM__MmL^u :S|:H6 v&d$π*T! N scXu! '`uytɼrXz> pqo1K5j}{抐G@VԴunϸ]W]?74ahM]<{k.di~=^C@7ԅj?XaTU8YAKq1utEٷoc7BN:F)쇉W/uu>lR h !iGnϹxZs SS^"c"(x͎i᢬vo3ㆧi2 UEJ8K?0jʚ5;mhJ-K|V$RL%%o]۔v,,;&I\Q]cLJ|5T~xౙ->eJ\Vd_hu<6E0"'zovIM>r06k%?F (-Kai(AIȦuZd}u=ok0D+F>B,lsMY`)a+1Rx|!뮵oUW3T4* y8u8Kvz:3dF@ lhmލMb4qf93`==|=wXI֘`N@AgMu^ָv\n]"I$j4\d鉧o/-J~?wC()h^[eNZO-$IA/Bv 7BIG?FD: [7K-O|C2,1'!ITʠyV3\ܦk;OkZNFmަ8f *Z>pS2p4]TIQ◳d+poKyx D9Xɿ<`\;.j`D_*5EZ˻I4REs8i$p'[۠E$`>ݐ8:~T}}b܀, G%sI7C^ f܍?kix8FHIWf ִ mhE#0"vw>%FA:쩣w#+s|ȨI9rF؟`U}ivfJ/b'ڔgXeK J vx}n!m2Ѓ{G*Mb@)h}\ '.O_i-c/62 A_VbFwt >W+Tׁ!]ʊ&/6` F{lnş~N=+Dᢆ'ȼH]"WF zQ,'i/ƌL껫 RU2[b%K:xTx;{9eovQ::?IfQhb|{{Rz׽.I1,6&މ2[O@ͳ\HekK9r(.C37SY?Z"BX5H3Wv@bSD _; 5+rgs~lJp8[WLn D*5]d+̉4D)f 7iC/<%I C}OmiDTЏ!K7$~SFDHD<٩QN)ll.{b"*VWgCLze],x\9o0Jc:)bLPgNѡԅPtdǼZM"0vvbzY+,\$w;Π!#``:RA5h!7]`]#ݒ7t}<5:ĎC$%slgU5̥YG7"lJ;>s348CW'' Dpg_ށz$ʐ|}X`ekV{iϺ'pYMșu*5k5dhIcN"a^ p\ kФ@5jipT2d>2}38je׽r4 j.ӠG*eګ:{ȶr9ǜ -a5Qa>JE9-B n4ldx<=U06.'aKbaeTfM |Y`X@]ӻ^l'-Vkjǚ *2禢՘=ꅕ;g rVۼ_* pEwv>ԡR1=$&޿gTg O[iylbh! 35S!"T:mt* \1s9ڥ56W~gVB 2J7] pE@Oδɕj XoMEΨ!nɪ)Mb]jb?ǒ|wB&ȋ ?ˑM5p!O :QKTuGLO?s`{tu+8JAJZBizf°/Fq[CoC W܋.fR+l8N{_%HO4\zlA#4/ӱ>I@=K_)lpc1q]FTH80nZlth!?Pn3*'|w~pad%ONRJOM-;Z8-:˛5v,K({FEt4XV}IkUYştyCj΂2"e2۾hQ!hfF\|".#JVw'G cUdV&#yqv>kYIԇLv#Zu{k%'8%ɒ/`m7׭c4>,"3@ cmu>J;(ǾT:F& ^\Cb*[S{Ai驜MBLAsLWA<^TU  t꿆gje:','˅2o|zdoJ;a?5VVBNzNV}Aw劜9q:S טZWh i'tBeLȬ{.hF`79 `x̠}3h'l{OӬVNDm oy-p[LN*.4d"FLBe?A3׺LQU fd\Ch& ;EG{_Ƃ\smܶ3i[fՃ:n>=1O%K-" NIئʥtv'4 IӦVGT؉M9x|A,ҋⱧZoE)(O:⍁5B%sl0g]}ӧDTmp8B*|V6al"!D4-6TC$FiҰZ/^a_yC+#XŒϩ-5Rt+Cb6׀7XsIŋ)+ qhʷ¿ބf6f W1ql'95+ 8`5>c3}2D2L+S a@﹛P8LPahQ"}n S<9qtud0RF)ZM![$J+K"@CjԲ&%) ͡-Z%3/~&21u0bP~ WQJ<;8l!]⪳[H5#ZɌsi914f"qqs],\maKo07!5Ps2Gy['nt~j0W JkN0&9F8\0FRxkb Ww]V=a}5x5Z]YtLf\^'}]atqe7'Sz rzQ`grTmBT|ܝk}[mO_ +zg<,&+!ԌYDb wHЕޘ_88U7.9cr߉2D\__0?v9 2*cӎ9а0-q!ِoU٠}p_)/S ^?498fҁsh ǃtWa?_oM g7;|2BXY{@K~ * |܇1*a_*3DJm3ƮaqCirESεg2o1螱;i!Uf+lWג,OYHeOg]yX{v\ϟPb}JPv3G +vG=CNls ?xA¼kUH~P| ""٢נ{zlM7@%luԿ̽& l`՜|R=8&>tMj]0k`` 3Dznc*ԟg zC[;@y^oOTf,lc}h~j4'KBkjB;p?]wʰ6_ Pd]ڼ5Y{_1Θ1K.CW^ďdǘ dXnm2Loyj=pXR /O=4MOQ~ѽ>J !{=(yy+Cj*ཏܬ^3cizOi1 1Q)NݕX\N Cc!>+FRYyx}{q<걤\hV[i2g٦nF@dR~O{{.83NCx07,bÕS Pl{#Z,=WOɠ' xX"{8=Cy SDzV> ~"M^jMt-'_ml_]3#turO6&vĶݒvZEy`R]'h1u4n?2!KHo`1l`NYbCq hDzYdj_9_#4XCO#u5mYB6 9QҫtA5zkdIJJϢ9{S Z? (zL̥CȎ\ HvıБٟ4k"YWVbIP.j^gb~J1Iڸ|UʀRե'?$%)놼DƑlwU aM:ƾyPMQ>* QFBzRݝS'^ܾp/eB3- LTv!W3?}SHb^%Zʛû^}~fg%)y3􇕞' Dꈟ[Э mgvbq1 Fi0},t=Lhr Y0izFa8T6 ܔW[$ɶ9n΄,qt| Gt?)SUР8<h:9$FKo ApRњAP .fQ8Ms"oe zw[5دB9B8;aFDzgz-D{ &򬋴C0?#r<$f{T` װ! iPP7"zQfo6j CR?UV\%h&4y4󇆓*v\mN$> {aJpˣUCD.bh:=\?oJ)HJNK." \-1B !2rӍM*늩qxc:]9~cԩZFWcVFxPIZ:~؃۶UΊf?ywL`n Q-Cs pFl]잝b7/Έ XRfChAY(%t]{rHrGQA=Ō }/V1BxdӏT[RTˡ8d";nziV۸8rp5QyN(?|b>a +7|5"'tz1٭DET}F+T=3Jtٷ$GXn!_2Qn:-U\j5;50،>LYxl:W.X(O?yfpQ)Fp9 h4y/; r$c837Fia:suaaB=o]s_:UIi^teEVZ&WPxzmg3ىC(Y5?@ {X4)l fq5ORLwj= o%na.~fjJuG*&*R5QɄ1VX @ZmRgOeDcK!B'Iq%zx(b wst#) 8,KSLvIRp&j@) S,o{uMwʼrn9Y?%Y+&6ikSOHvnӵA7<{q1Cm2qdR~8:ͅ"!? L0Hrt3,/%o>}wT%pb6XRHݛV#֑Kn>jLsJ-9_Uan {GWZ.G}v-"Deהf]r{Z S#?P"1ǿ~gqO1s+M3s?;Yq]0s;pLb-Z~aqjcTUf*XާTiM̖5|ow-6YJ ? +kT\e-%dY'.1_}獽=0 rX+*;`+zv]zap RG+, t1=:!mEJ` o4h.DDKEukOEڪw8_%oKӔpYOS?BTb Rgwg{9O6z8tv| 9G5ـbi&%:(._BU_(;LΗ/+2:ӒСX϶CzYF5{.Y$ \ɤP$Q#7fJSHԵ}" Ƃ=$G96&L"/4Y ^8,uVCkiPzȧ\V5^ uRdd`5< ŘMუQM5E~is*?Kl~&aXxU8n#qBOPѾ5wӽԊ0];xO7`˲хvR?ʹKhCeYLوbrq~xes=m;EHs:eƚ]Ep^hi?z  *1[+H?FkD&g-(D! ~$97 BBFwhWjQDr;2Scex"-Bx=@5k#h%`!Hto\-z&ȭ~CȅonkSljЕɴ0HV$xE_d_]dU[*beHͥڲjz ^G^]&țNx6eVx`SFG _`iN鱥%9yTNtNH^"˗\~`ɂ폺qtQo# /jnNrN!lO0dl]< 4heX,qAW{}zk[K8]fhD=HRd2ظ5ț4_o|uL0R%>15&06p5 E51G9S*e!~=sׄ{wx[-p涞-Qo@izmu܍f=#<8af!+di挐ߎZWnW J!Ko @G2):wLrR|liǻ1KMDE`g2>wGid}B )Ĵd,=KJХ6R-X#u]}܃/( }εj(~ x}J4z_ySabJp~Dewih Vcoj&h6|83EjG\»]#&l;IFFLOPQ jKw $o)鄘/CΟBD7ڒgȭ3_h3ZtiTAhk9WȻ?Wo"Hs Be j`@|e+Y1[|khsh!zy BEq)d!LVr(Ȟ `j*fn([#aBv,E4E.pCئ{$ZKUyܰ5t@v_#m##i*X![9 zCzلUcT~u`6&bTלCnoO^W!B͵;+/}^~ O_Mv0ׂ)Z#$B}RH!^/7X^\*h1P#H&flW_MjՐ e?et*^0;8BH:EL2j-$A.ߤav bڟ\d(>du,Ya첚q'aKr[Yh,?l ĘDbK0?c};,_yڊ(,aGRֳ>ˤ7+WOrM~[$5%Qw{ ) džŚ_]Q;Κm6EubI,b0y˪o*󛨉t Cdc,QDrns#[Og$):FEҨmj=4͵@j2XcgY4|}0|~*ڵ1Y.~"HZUlt[(T 2~ӽ16T8s xb-hrۃJ8=D)Wݪ'٪[C]y.E/6pCo -пDt*šYm]K3 Wp E Ԃ5I3-IcE@6B-&QQr ߨE:\IC9^fr5/hA=J|Э-~6j,Ga4Cx,3 kQ9zvP$x8y؊6N `M=',e^_% ^hWgLLFS[X\d7t*n8_z9B`Mm2xJwq;bܘqc_m'5eJ>@Qx<224Zcsx 9kԛ%Օ5F_m k}._VS_ /}vF8{|^u0֌ KaF1zW GI`wP?Ѵh n:=6tqOz8BÉnqw*޴l0ܦx-XD]Ӧ׃*LJQ"axh 1vMf 2%vĶ=- Y@kl!bQ2p 甑W2Mm2c.gzJ0ģ(GiD]C /8GV[` >aԋZ/,8 6 +|k–{n/ \(KthtCާ<͜$AY:\;iBzK:9wF=2M oor-A3ϦdƌFc8k>0[<ϳ}=زaU}v,:ݜ6` 9gfV9ĵR"VVFooZSnlV++鮴Ga&کAF#_;Q\Z?n$A]4<<gAG **J"vPc <0ɖT!0p8l_}W 8|j1L-#^u6Xd9h^l4v`-c+>qФK<1 PvƫhO\LOCHРej;tN+.W#&SmPJ0oSp'V{XwP^fn e t'E44b3|sAnCCVL6bnJ(fk "TH2H,b>w~[>O/#BV $NwV 2Wrv?) ةW3|gz N*|W-rUj3|'z1o$@~Uq[k rqYj?ϤdO+ Y/C,S J[8-:'4SY5zdz+o5HCu#=2ƕQ4 0I.A V*c|"Wva~݅.!wEQ6Xc@J@pLB4m؞/ʤ{ e&96> JIuz6FZE3]zpI\Y ~ԣIG} t T,4 r()Xm[x) xz$J? ,>Cz31`vtk%qtѴ}lq lB(USL ۥk"єc=dv6!k' |Վ/ihocVH['N}sufH$@Y>%lg7l ϶.h{~;+# 6oI,w v"XeÍAe?a'z=\]:G,q/8"^ KV =M91ݔ}Z{22ŃJ?H!PcXR>NGzz] `=ki94=/.O]#ĿsΦt `/5PJ+64?~k]/*|beN“o`=s.GжC,g l Z^{IC땙 8 &ίefU[+-o3sp1!|ervQ2|s+>\\~5v*8~63o/琕wE{Fp$S WMslI[U(\܂ެbShl]Y3eGBPSM.|`5g- ~ȔeEgʻ-z|0I.d%|f#.DQⓖ%:ܰ,PUdǥ ?B荞빰i U uӗ ^+eu![d%?>6m_@H8om1ajIW&녰QH(u/'@jjǿȔY_& #>2]y<.2ۖ~)ŬK]}A} s e)v7}dž3ANt {>ë2-ˌoX0m \390ڱhZBBGQED+qyK]kVskzz/93-?<%P|)wDWȸKJ!q)Q j͚9F|m~Wg1;-.F}4KpCahvpitIEM@C??0: @||׮eHS/7Tʋ<);Wa ÉG=`5i xf"^CwtmpW<{=>Wɰf)h60)vi yVR{ P .ҹ>)IVhyǤpnM:5XJgXǩ.lI}fdq14z!Rħ,̫'Q^ޮn&T`iv~_"/bX7 IFX;ڵgqZ!`qZ:N1K'!|DSn@A+kS61bΟ 6;kdzh[\,S*/ exxs5B$4Y )H+ѳȆAs[؄Yh2~XSiB/w_3W9}}O\I|o[GoD?K8"40-yQYSD-E3^?)f=߼%^?0?# 9씽 $|3dG{cx*~>ie=a5ݞ[zFP|HxxoUm<}Tw* ;?:@dC90 yj.PiY~42F ʈP=N]f/ӝjT%_D{}c DMWFuV_TMOj_gK<-*2epӽ9rQ PW)ǥrAI2H))B$>`(QbP=Kk=fx^NㅋBȷ}~eǚg8G+Os.%c3qå!y <O n4ys[G68DX1- *hJ!0ח@:̥9ydY)*n̽Oi[3eBy5?mcFV&bop'T ϖ=3?ba6T̲nKͅFb<` j,M{K-f9yJh@Ѿ|P gY !waŖywg}4oPKr9B`+n~Z!> ^>IB"[d)╅G! _wF||b+BbL[G:5iT4piûZtw`}f;g Mq[ ;x9ϰPL>-S΃d=܄KK *] PW=C/CxfRŭF?> >6@T~.eL w/Orh~O9x=ݔ|&KB<$ T/{r8Bti7H%h9 QP 4E1p]qiwszD _qS&  u,7g>X6w\tNklKܲJw\o F qa[?{Cnks!nCIsV*a%ۇ}jcnl=h[!y ʔ\bkZ۩VRx#y!$yTMipW;B M JZգ}~'*;%X%IQ1ꎔV徕/,XI'咬6-{aH'LN ;u~Ln uoEH8Q1hؕ/l8[u<ڗ@C(] DSy1R+C>P\2󠫢)GӴU; %~ܱ=tT%a7=U$JIB\0 "q"! uڦ#u8;7\,'AxO{NW ~!HEwN.gi1r&0]P f=D/<[' F57W^~Y:Jzyg}}d*pº. 67@h*B}sIl>tD3"/M3Y!zF 47G dFL̆5hCܹC{uu)<<R4cRJ^1/{ۓR:MUa?`GШ.ZDg#/`'WΒk,*H8zp<!"k0S;u&V,M%l|\)?[j{fy_\A%dL`?-j~D7Ws ɗq$NW}x}^HlHA}( N!EJU2K 5ԍGGMB*]wT+ YL?3(96Ciozhɬ$ptA sw '+D}Lt@wkxkU8)ONƗ%莟-}8O)fݏeoi:Hdf`P!]fog5X@= tdtWrH$zG@Y;GD.:gzm Wau`dcA#eZp͓ʷ0T* }+c9HLhkB~ŸC6}&v<'aCq1&0V%Zjh9%aߓ|s\bC+ q&-Ajq}R@\ [G! #;pJLCiU6E7g k F;?i.i88Q6B!ƛ3qK|-u]Fw?$48NB͛<"|*S Q7N2$*$3[NRhP8SzP!3.ps-wdr܃'ImWtI>dJp;W wj>gX,inQbAnHÝT du7TkcYe3~7L뼶{ÑaC*\tp7x[$,n||+n`> -wM^uB{x[hT]$彖>w)#t4MK6] <0 ;Lp's [s}7!wi顑ًA;sV*yjthgp#v`?SGPa)rvo҂H{yUEd/M~o0 ,obg; `T~|[%(yUO[2LfQ II4C %~h5bd܇dآvQŜvja8> EDeB]U,de o[S <{6{g/1ԸDJM{7a[5WTq ]m`/ttqUyV*XIu.Q|Z}`PzLPd%=S9q$@W\^ڱ[3&% kߴMsD jY;>34i'~zsdP\R-~Ų3`~28AgIA3R_-;y`ާ F=:zF[/ُibMD_HaCC?e =44_9eZl$Ά6nfԼ/귈`)ʎX2`cUL|={gnly1 ؝BG{zD+% zi\~酠?c8ݜPh5fr64!ORcA *NE?De>ypХ),D{T٩Ytop Du% ېʹ9 sx%ͣbh8s=eg gq,6%:4hYvhv?|݈5(RU] y" ޥ$n3/Y~Xk֙NːN\D:0a/vR<}p^zަoBqo= \IU7RdzRT%n(!/n?$5IHn?:;#u!#J>Nں (clw@̺b-(Z:'2R= ⚝t~\TQ|HDYHv(#$qjwceCup 9*( {T k[Zd.SCs~v.ߠ<oHRmOn1ޏH~*$IX* 8 :ƳY\[d9! ?ZlNK_XF.ktSVp$|,eC>pq+w4_S3MY'p~W{ڕ~o ʠLzcuw<,,qK ȑB8jQڈ0.'_%%7\ۛ[-nUk_dj/hX1u ;_psšlJu*΃E:UuLh.4-^~j''6h*t5pN+w1ۜF*GJ4a kD:"a,<(Lc[ {jFj[鍚CeKf "jXRvԗDH | @*vL bD?jTTMZl|GH>%~F:ȧRۆV'v-G2Mi043c<+bDq.u?d E ~"Żӭ +5[_ eY=q֙8O|5p=c 簶PeDE Xbc5!]$r+?{]as[ho2n0ҪU@hDZGa'?IZx:CيK#JS5d Ywp2MP1<7}RLF6cΜ&vZ8ǃ==QGuw7뉤¾Š^0F*0FkR@ˠWEkU8# E_# O a.mx'  t*1B6,)I.)T`7O9g& xL138 R;!%[5¤ʎiKnF~~o lY2 A<!5x Qvz:O5}LduO# u/Ѻu"~R:AfVgsFKAz~u_k5tPU|} 5BB!z{Ђ3iqg{)%Tu]v:g?UxZ,'|E-GggtݟhTb `]'jI H_qE%VW`yfSgu^( jH&w+Uf^+@ Z^G',J*HgAVٰU{P1(GkZ0!@}+bVdĕH;݋No=7@uvkE'>[E=}瀛 2(ީF!!k*^sc3o~{+QߊdDZ3Wv LH@驘PIm R`F|/nJ{R-H ] PKT{I`r@8hu_^ pq*H@IvbhEV񂹟Q,և7 ^e7&pE֛ &`JP:u#w&N&4zF}t{jh)k, #@7{RV bVUZHd= 5Į1NFČ Pc$!7jW*@ oDB 3l)ĩ+(XA[ߟWq m1C~uF)Ft?zY9?|kzz젥v:JU۷7`Wu,@ȗ\JQZYk<ݐaK:|6ڈ~^xdgdB=?6D]c7/Πq[/@3~$ZuS9)!NL~f}'_)z}A@q5~rA{.%VqDIFrClF+fdx)`ߕK?Zc2eӿ+tFA?2d&99*%']=G>鶚.?\:r+8Hmޖs%3?-W?tQv;X:Θa`Bcdջ& .ѣ(mg`EY{; Y@<>^>zx슮MCD _]U}/xq"@I;dZJ'RZ_F- 6z8fLbF7m혅};%Yb[]1o_>h)aoIv4=)[ 7=,>=ϸRǶs9PO^n]r-X[@6?OѸ_עyE(&tTj XRfpݮaZ9 fE ql~MD?x!H&CJ |,Ux2_ol iSDhlj/%B2B〻ΖQm 63eDG:^|78HnlJSTiѕp'ʜ1ع&8UqՓ +8² m;,kM4M@ N˽\j7WDT?.aDוv~5p|P07nzċ&5~Sa"5 S蝤/)5[DIY)5"եֆ=o%t5Xϙ `ŞZ t503΁LCsK(T|'%ϯE6Pe%5a-9gR5*.uAIے!s! PneSSC"U~e>{w5{qkßfvW¶wX&N"/AzJ{ h_0]E%̤Jì$+ui 9kxrZ#X*j''YQ^ ,|+ЊJI٘4N:&?WnPK+أU5j+gEEȅUZ)N4Io3Oih?ٗU@/ϊi2 E{Aku]VrH?r/ҭDvZJµgLxM4^ 6%I F+rȰ2ibZ>L[ @ẃ7j>%(FzMwm'P@Q2(ָ7{Ktb1tUrb,$Ks0큽(]ne4(¶!H$MCksi5(ټ%aI,!b^#*fQVRAȎߣ7á:^8ױftYLڇI#?8 Y*zԧ E` n!i74h٦[!cutLN:ɺ$ۙ+_f`[Bs JWj{ Er (kU`,b_(oen0ۨH gg_ S=lV)>C<'EWT#(T"7=2t@:O eEee">,Z&NJWu& C3sz3<bob+>rHWkVH>8ϊ7)Ih_R9[?: &f.][c{ i#J#UEX󅀺jd%[C2A˦ ' =t> 3s DZ;&a1C®civtwVFP8Mt;>ct}Pw:ߙ< <@PHs7(᭟ꈃF6*DMG& k- _f{UC!XY9g)B}*,{C} s]qngj#e/F7|?f!Aع[ 1' xE/ܩۮ!9vԘOЦ3.ޡ4E[ 7\bBnEL2KS_`^`һ'uWK]3viWkJqaN |ޕCЉwBBufAbg{n+jd,[iH,ފ(H)\qV͆z;%efwʡE] KQu>Zk>(|%9|ݙ1Ò!@MkZ# hڦpĈ"U ؆ ]өO)Do%*D9.es}a1+QsZl Q[fh#@3bBA9PTxY-`iXYr<[oɢUy@ ԕs#ҌwIIRХj[ɄѤI-,a/=83LKr0BτOԪ?N'5 G5K{vhWWY>JZkeB[46UZNPxHVo%( /;8.4 xr>wc H I{+ɮc1M&U}:UOKebq%>Vӥ8I8if?]rUjZUj<8/CCȎj(#]-su8/ m\5I4uvCp|G-Te#ʾ?mD*}NT4ĂLWSqS Br qb+4]ܓ?rY^Bzj [l$!4AjB.q5m{ΦC S~Cf hm6x'T'XtbB1J@Xe?1 =Ic/i-n;i̭I[:vrBdwPË.LG?-wH(-V܌NaO}akHb~9MYpD/QH O9Ӛ4VozZ:?s2nS(buB"Y 1x6%<Qi;Sm0d5wا LO/\0_䝲(M{5) J\=Oas#N`Pvs:0#>p-*9(ui9|g= maP2Ջ-FXa[ ,x׬6D|ʆ=s-ldj DS"#$Ցq(bZ* 1r&Y-/ݙh#ۊo8vo5L鑦8҈% q\ [h1(OƏ#21@8[[F^c=h-ݫX0';{< 8e{a;2KQEL[ާDJP$A'Qhanpsb'#s_7YCn-SO's *zQnsܺɲ'5~L% .J7%9{IE=ZȥW#e`:./ 텑MS_VuXئ(]=d[ˍ89HH٢G͟‹L^.ۀ-}?:f/39n:({dl? AS'W:H/ Gak? g8䜶`.=rh݁P.D,PWppW i "+$:sd.=RYͨ؄ u]pz7<HUmzg?fd MB܌Fo ~7:K`' REݸO7;Ub N:$#A홡st"Q>{ nP; 3Ƭ\H!uߓXtiEp,+*w43PJ_!Als~h]n{/5?g˫ǫpGHcl >(!S:n|ޟ֍ ƙb)*,lOjc1 K-84@k1h 2%rmO hq?foB'*;峜g{%'XhntH-\{YV'#Hf?"@qcy,63SFȫUGn{CEwBN'l d"BKbd+2Yy`C} et_Jşݣ}OV(maϑw)!$q’a@ɘ[Q6YtӳgDj`[{-b cJ!I IQXr0Y6KQ+ ' / v\*J |Xc(kO,,V0=<Ɇ PqM|H~%F~Kk9v(o{ z+9@꽫 ;ۇ8NvlA`2.;ϱxֱCݿNBr Ԑє٨rOuR&ɐ%m ġ8PVsNMSr*5x1M#mzfǕ2VmScϤܟaH$#hX%r_ܢ_&zs7y%u!VNLQ7s FCOvN!9 Q "3m;֕("9@eoaպ,\ `Pf7J`JiXul[L%YtNө)@du1[r_aHwAA+Je9w]w^JYYamr'TLphLm'U bήGnL01X%v}Ã~0G(Wȼ+D M70 c<6!_'k[h|Fk0v r:JBl_fK,pTˇO. NTpɍָIBHJw.?\5jEgpJR$B K#3,T~ |G} C̯\\n2'{ ji|lIP :tP.,S(5UJ@@&>)^ dq{` ES:;עUqR#&%'W1=@$z*/ᡗ+{EcEKnԼB'XYtKTO8_ߖ"LF ХQqR,v Ğ1X_Q :2;+VlB+s{uD䝾[M6=Ji`cg;R`'12 '&*p}5u⢴Ԓ_̷),2*Yóa877ΟC J@s<TGHrLrr}*-*|@2ځ>o.{#ZJ6?fNi/p;~\,AsFz>'iȻ[^Uы׶<+); >s&gW,\5LK>[}}i3*~)?i ؎AgRR@TYyVr8A;-T&ׅd̻I Q|Xa cOOs4ɑM*Dr`Xf4ZЄM͖p1A(&߬PM4KM@4@^z]'~MrlFq;$4l3R.~JL_X+)VshFM9 ALܕ\F h_6H1֒ZMCvEC6;ݸ/s+_O~A1{5Y.t>x,aYS{7weڊN$o\ z49-FZo`zp#$Qfpg0k3Wi>y^ p,f',e>VZ$/0 6/]N>^`3H[OMl_'ﹲE4 V87Ok\{-W *JS{\"84!}Kfz _o{e:?e_xYfrvkޢ(£?&A@K>r PtopvU@FQ^?= }#1GDA{1kz܉$u}wƯ `ޠ/ Lȅ %̼|\m\[ήmΓ+, H~)Dzyؑ"7S^~H3-򪧨]U ?h죲Y ,D^:AJ˺;`UYƚ036p tFrt 2>.]8#?/ek76c{'RP,ƍgWJ^$uE5FdP~sv)3qt`5JȻiP+EX֩9=ܮTH1s /YB.Vф<C*#$dSPSpԆuUAI  h,8h/l[qM} :(,7؇Ef נx?IxR-f|Hw3;i}#JJ5JYEoLwbsFS'_usN煞'*@yv|DTRބ*8`b&:DɎ5զդu4̶,Nqbn+LEPEd1#rZgx"a/"X| h{t.?kwGg$HٺTSNܱG$Z;P=߽ڰK]X:2[ Nw+DnNp)gt2/vqXBDIYFIfzf9/Y+J&}l_5u&LkbuwL- OCZ\fwhg?$HXѱ<4 eҗ^ڟa[R)ry04\i1>8J#NZ/tFpɁV)\]K12>@!{׳Ux+Hγ*|ha,b+ f`briҏ:n d09MśM^jׂ:ZH HVQ#ҕ(؜ `+i. :qq{'O?k]Bads)98Zg;.vFe 4~PGnaE3|k)&3d߽c=hZ" +û^kgRǾHKJ5z٥F|8h3dM>hw] 47uPGFGbLeXЩo&zWl0~m0n⩰+Xb4byy}n}fKJ]1MH$mbђ Nɣމ[{r9 90{"x-MR,L\@~ux٩E#.8ivRpu;zs{/4U*ш"d=ФSA>: ,U,`fj?QTS'
  • mI}1op`s>DsUg{:g< WvU>Wcilم<tW <>DlV(nϤu-9)>Pv84E(xҞѐ7fg ‘c OCs\n`DUb: R"?D?אN!\d6c[n$G)\DU=G4Zֱ`C;xqoڅَIMM-eBJs[Ɲ"^qAgđibAbA:?pKF<̀/3|jK}2-{] T1^261‚˷ЎDZZ˸nRs*|q;T2wxCįm̠ ԱGIeDit||ɩ{{&WcWG1_iVXÖZ\^wJBLFm_l9Ky|*2ͻsV#u%|B>fPP$~MwwFN#OȾP&Y"?\n`pU>Yʬ/sUTica$>,}6W_U.k93-Oo}m:gYFF~ʶ! ˾-QD 83\s'񮞙vXhZ:"EYRC1xA:wIF­ZLWWCv2}3-P@m2II=~67>&i_MrWz0A HuU33Ϊ3&AZ4f6#YNk/}[^c'B ;誂eAۧ unni65zS 9Ʉ$?sN[@᜶5o Q/EZV}Dp5k=rfYppb0X5\Fen&Fڜ3vח;XˍBdIٲrǥPw6-3א q{A 5 gݵxTD7I0=g;:dRXØn0T ŧAdE-i|$5jt?En<ZR C9ɌޯMׯ–o<\>͓9 Ȑ5Uj(08Z LZzr1I:9r 5F3^i,KfZ.ãS~>>B.æQ~3X"hEJ6&O]qP@[dΑYkʟہ&05J=?/?e/ߡEu8> 5%59y*C ]ؠ丢K9}6ux8y2aYSM0nGr0ad[&oJYxEUj̀ >sW3Am{6[ !^F?A#vbC½; FWo5sP($;`nkB; o?Qn'Tj1{\XZ6/;H@`Cc_ E@sF|Ȗa6i]JKұL &@W& J la51zV7{ܺbHT:'!{- t EVʝ7c?)yܶsdAU$@G-NQ =G ++N.j/x`݅]g;?tFcaO3cfK2WrJc fWYܬ|0eޙTr#:4w2scN0CE6WNbd߾JYΟGzC4ws12$wu.u7IxkĸI=ջvl45*g5\l/]w 'c2D)Gu}-T6 }@'7R[nKj AB^?Gt/d'g)- 71cXOE+ZS|x$]S(W:iکj+_ۓC{ǎ}0@YݎOߒz04sQ% FqnNH"UؼĦ۶ۿn}@_fPG/ 35@"(C%"VD?tҁN0KnXW.ini $H^aO@ : ?wZ (YsUm^=/b 8ޤo kA QC,iIM$M5 TҢ~L86W_^^f%a,vC'ߵB>!^ۇL^W)3WEj$ڣG`zĿ:23oNWk_n69*Nf'* (*B4^q50dcgZ ƹhX{| Jv@GP;򳟆f((^y0YM!24gپ*yhzR@G[=?ɈOo;e%_Gj68++ث&WOۉ X3ޗOOS^5N$x#ʲYzݙFǺݡ!ٕn)oQO`cyDk\p. g#O]}w۩A=iQE_aPBI@Pee}m~]f~R:bMZR?TYj')Sj/h(藥xx"* |UY5C!7z/XF7cCFPIc HQ`^!i2,`yT Ð8QBX"d>L t\ $>l3-jAUYQRTi/Ud7j&Ow9btbB^IȒySzJ҆" /ι.Sp:iZƈtʿJo|kJruu wǨrb۰Ƙ||;?N`d*3>Aҧ?bhmss 1Èy Yg ln-][c|W.GQ+~R0ؤX] hH{0Ï [ah-=$F0neIzҫWJ9qaNyX Λ^@gc-@dkk6?i4mfwƛ |r ?Ҁ-B=ܼO>‰dޒiA/FT.3 <42 C{]GrW 96&{Nۏ@!*wpzrggٛDAL\%>eҝ՗*1/< "OX2O*28AQ~HBj'x(> c CZ0 >zo|)>mrޱ/ʙOy {Mv~xRSӮ k"MDty̟Q磳Y_ńI}zC\&f'>ۊ4-DPSI%R/J{>jno#N$`3Uk@,_\̭kpZT8{vz9ÌWFDUP%5#Y8vGD3Dж> C>B Or'gFˎ O]$c~Yg+C > *ﹳyO8f7‚tSGMDFHA7hWw$e]~xXʞX3YQngfq*s3;Y`ě2=gtl8mjj,deXXpE,ɨQY|د:kNX3+\M@՟.&:JyR$j r($<"xLFp$.c&w@⫰t?ƹ^KoúJKq֐3x>IWt{.8ɹ xĵvḡ*.p&CsOwC$fN:]l[ۇ;n|gEg@ P]KRx8$*ybݢ,sےSI^|WT+eZ&.^nQ gYD|DL.,8z[Oly 1,bkq4σ;cҸl]]( cDfc/v*1Xzo(l'K 'z$,/2!I?SR-͇4r]P[P P8B!jо_c Rl*ro™H'(] |ދsRPٴf}3 .+>+C6pn! GSa(gZ0pfta/=(;/N{se~2zl+ Et8jHc_L}K~}KɈKj4E Gp'f?U_*.97[|{/Diۊ* {K4yъ2'6"si6fݫ:!tf} &_=>Uz7OگrbrGw2[,Wrܜ1@X;AojaRYD12Ñ1&Da/:8&q㝁R ,qM-yˍ0 oq qT#QL8p$0MԔ%rNL}$2.bФ?i@EC<{[4Sby0;Y~E#/~{%cpM8\$<';*fXJa=<sYilO#V CtXߓٹǀKu$-= ? xRDʊvR>H?iUjG h+C ^Zza?b`&AdFȝ/u+6uX} ;$a F[ρDEI>1L[պ. fMVLD^FO~c!L(A:(9 (Nuy (LM%; #[ lՎddalB8ҭ f~n1lQpȩ7j7NOh<. Dk=9T+.口0]۞zVS`m^bU#AWI!Jid U­;*p<n,''E(0M0?> x ㎆yyi1F#]cVwc->vI^<Ԇڋ:1$5C_E0MߊMm% :BMl;0RԓXʾ9],"|2\pElQ́u5zAy%m|*׭7FJ}K1֞@U zmŋ;k s@ mC8i!&Nc',l} S{A04\4"%BR),0f xͨ$,E;lnp1il*Z7ew sN┱ &iNПlww FdP]3nRpfhVFzv)?6^0p h*)Ŝjt3悁üqwS Y&y߿>n`//:90$5ftn"x Z"9Ka52ѧ5\ʌK$*|&>8O9lqx].,< jLsȎhۊCN팱#0ߦe(ؚ5;|szd.ߚjycVYY+H)c/rZEM>lUX@E9hm df\|ρ̷q*BwQJD GYXƛ u}Ҩlmh?I{fr+'L9\MnbA`t,Kcp/6`3 HS@~sy6&YY@.p0LEeS>c;XxLXo~Q婇$B@2 ‡GtY:tu**R`9 ) X dC⡝VZ< "pI`Dz^oo(~p 4@:Kw%TK D=WAtE.`>-9֨V3WWM;iA_{ecs B,8ble4#9pR(RwXh!5-=rNT㹺HA+tG"A T`|t%0f;x{L&Pe%0NRң֚ >FpCy5\L?V(Ti~Ab)eXhZ!W҃XcCiҭ_'8l^SCl}A9vӽAOЍPwMipХz|#XqvGyI"5 OtCCbVHݔ(_9*,|XO)>^13t@%!R4$|%2o=\R؄3ߏB{ͭ;<2kz5Mq@y?/ ^E9f(W)I{R,(,M'|I`Y5p= -=L!6ydm-jp$272pW&-[K}R}zg%!w_hbqM1k04 RVZzuEC)xIaJM ׆\MN |>ES4焇 ༳9w7C!dA?t?hV.[˧A\~ٮX@lg3\ˬ7HFN'wͭ|գH`>F ꀱ4.a4Az-Nkވ|#P/>iC7m"NF) & ubvp DW&.e^/X$"-*XK{_8۱g[\_դT,hieܻ*9 =hSn˕4<`L~›brr,sIz{\mB4YX̔NIlT1+K_1qۖl)EOA3 h/]f.w3Y1{j`yԲ.5jRמ!6~V;2TңLbiWxr PuU N&ucnl7/Z1ABHj£ʿa[l5ϵnFѕ@?_ ko 29F."֮l=&MbVo'2%WVW ZZ2GP$<'z McUgJcăeV B"3m(~ o /M?0&} 3eNhrWMW42vM +&!uN|%_xeJ%2nQYL)y k rU@uOA%dOS]8g.L)Uѿ5;n.f R5|p[CEݥA JWػG٦ 9f;3IZvvinkG< hZl-{iڪ ,ǘ(3b(in*Jc\h2*)aɹWm43؍zO(uTHxg_.=( 5쌓?8ӶXy(դ]M](4CrlSo1q:7'v ~y[F%^$?to(uwŷːIJv ryĒ(2#tQSNnB1fғ{)4?B&o^]2mGs[IpOc0y%^<-[^R>6=Oў8E{_aN93!S3`=ϵ͞Ņ.B:M3uBC[OHpwGF0Q}9k@w!D~L3tRXiJ ]"L.#0Ԙ:95ﷅ7qÆ5|[hl+N_i{0v^#Q!TGOd&iOEkպ41G DYiʅ'U$!h-- h?qS4ngO?A7\_Jp!ƍM!j:~vòB$hk$]zK&ՃǮ 7:O 3bEV MDIe yTk@p>PA[zYGu^qZ&6j@}8ZriHeSDmfZQTҢ=<(6r%`û/爀#&,JԂz)sWdmwp@C0&LL0|nb xX~ҙ)4&_j QBӇҨ|Xɲޞ+:^L׉6jR! 蛶RUn9#P|ş>G#( ाhGA `N3TJ!z~L9)sZ*GN ۖ pvyЌ0;b̋ln@ut1v A)VFa`e4%:(ɬk5: [Z.@eDHuѾWح OV8a+ &k8g AhO`N bH=vOyPztWe}LY܅$Ǔ)b/ejڸTm#_5$`'X7z4%jIptlB#:1h\iǶ%8qS/e.^v٣l^β ,Ʃ?V5nw oj%NFE蚐JW|sb+Q1`8{u ހc?L? 57sB{ҶzUmS侓9]P{ZNhZIdsWf~)I$O z5i1 y*)SZ՜!Sg ׃y[w['?հhgx8k1Ӧ@H vId4="m.P&setx3앻E٨=8+2[딁LW95ݙ9nT,? f֨FDsxc5} Y6^ l@oMv*6{"UЯVzWZ3"|*B/r$]d,5#եR&8a:1 1ۡ)DXE}x;)D誄̊#'l*S֍UGp&&eh?~Mtؐ9lu IN9yvbV4QXQ-!~5G꜔`@ 0b;HΤ64UmHL\z_:)Տ>ؔVe'ԐudR ߺzo gi o;[ zgX":I;貗Q(oX4Ɋ;f!,KM#8+w̺^3w؄}tP;I<1Qz-˭nkO͎xLBKի,#t,3IW uZIw'",`;O[:V2`$D. wQ]/i10k8D5r+1Zd;0Yݼbg3^ٗޞJeYeMOQY0gB9 kų%~Dӏih*R}y}+%|g𖽚JLy 3\+aV^/˕/G'\k(R(#$S%r5Z1  }?[P<_!Mt1WWs#ޖ6| ]z?ܷoY:ȊK7G jIq_@ %;1L0\h'~q# WyG3<͚5\e1ֽbl'SB?wj O cgM[,yDʑ+qt>.Ѝ S!P71oRu˙-Fޠ֊/QMh\MaAM=]+oCuy;eV]{XLF')[iW] ;~$'mĢS*R9剦, ?V}Nszd; ݡF^ t Z$*cԚݩeW7뫇l+*x,&Xu#ZL4_c9@zW/Xisc3i$D9rS۸顁:PS6=H[fzsu]N,i(X[ ˍQw@39v~D^3cqm_XFl"}7佐k3LL }smRY&4oQU J}mv:7`^`ݔ2-m+)Ǘ|m|"BU92I'g:?H=`N/~.@f>i9iHvȨnڱ~es,jj:^ڔq (`=&S*. @V e V#mI14G2]&@[zPvu)P?3SX>` D^%#` b_Jq6xf_nz`d5lW7\=/g``o,+p^f7dIQ?/L_ks"_iaԙG1?lM3c1|9)JV< |/ѫumD1ij-4PV.BXj ܀VpW؉up "1ɻ\ܭB 㥧 ^M2@D1 bu__h0.菔1A&Fruу9!+rBʵ W NN3@r ZXcxM%5L͊&q4iX\ub?-56N]ࢰ~땱+f0*W7vۭrZo>ĵ{Q]b܃t$9c)v.[]hEО]bAr ɯݎ3h&N=(J LY*;'v$ 9=t=xM1_үrbOnVjOFVy:oL%&U=8#(?ȫ4 ɔK$!6@D3ux?:/v5P*ܞMvoY۬~嶒KAs'h(i7!9zĠ$ URN\+ .1^"&8OuהHJEXfcFR1cm fl,"-^:RDgڴ֜㏰V93-khae;q~˕~u$Xm[c`^`)QȰ:އQsXoC\w¨8%\YyXQtE cGLw 4B_D{EGr6! K{,f3:&ҚBѵum`hlJJǶk\=!m6:~S:F]UvMlk5UV~C SHMxl w&gIjɠ]xcRW aHi|2سLx9lq/4f OcPNp=ɴF,-NS p&u%F&$GegIT;/{sѵbv*^oP*Q^=OޏL/{cp^%a(.ܱoW, #zHt0J%Ys w^x/C5W[cݣl>k:. A /m`.=DFv 2ttКJAAi_Jn_|lZ U0mli;[L[}bR sߺ'oF:pɆF^:DV@f_%{s@tXe_Eert0|g/RO%P^։0(d?g,Ẓc ZHf S0CG <<`|?"`TT= ^ "J) ~:Z*hu edPD݆>"#*nJАxrҺ6z#E !6ki=Y~X%w-_1m@C3H$?08W}~; as5kb]=5찏Hl[x*!6r}-֨q+\Kb[Bcqiić;zE sc);6a-I.h4p;ATPYW^;_%𐆎W-Em Vw^f 6NJ\z^n:. Ed ~!сWcZ=$x$/xGg&:=Gl rQUfa[71CY`!`ٴ,{G*Kp5SpvhJK7 00*vӟS5Y7_@él+ˈ㷚KuB'%^x9+tJm>MXngQz0`}r'^r-v=w`H|9?RHx6.q*ė^L䉨7 t J?UBtKXܟwi B  1]eC:,gۋ ̪#KI+$r$Lݨ6j e1wHsNITpj,K `dÑgAfH֨P:G;h)P Ox;T|bdg SRq iWT݀w,i/~}K>RX÷,PMJ6;+Ԭ"jϷmT[gB360ĭ<<>/ ]gd1Ym)>{O.T:@7̈ض8!DEBO]}?x|{|W9 ߧe{7Lci1Q=翵Wfײ/6bJd󝋹w% `؋@T MEhmS@PoB_w[xX(c@u"8_[0C9 ;K;J^.S|OOgryt eLgg^|&!.;yp$_rXG݃XDƦ Aԛ :TUB/|0cxӽ# yDszt& f1/ٸ::U_r>؂~ɮ y\ ؇Dk,)^:.-6Ӛc\iTo7UM.¤뺎RCX+SLZ߰x.h/%sMiڱUqAzW2a ի`q0+) .rXπ M MIIgep?h# j.؟:sH@jv=Sg '}G铃vF+4i>zzGV b$+_fAMHFA] gulZ턱ڏ1&%Mi̤@[V.LЌ浂ڞabpS~A6jCNSQ~;RGZe32k {%THTo pcdb1XJ"8ާ3i(^><9ބh+,~< 2OιlASNioGğztc922{i€20}6s,FlYNӧd2lHgUq*a-"dF_*KUİK x8R(]ʝσhtL%G03C!TÃi`p|HmP.<2 sJL'llmlSc V׋W% &5uM,3\v_ј6%`\(Y쥺<ۣHĔ/V$=?S/ WZܴg'ŠbŧQ̈.è͋PAdsKA  Hpۧ7gV#Z@m1NYuK6Uj=l\5%Ci]1/vm 9V`$>r*$JtϹLvﴢg[~5>^gGB֥eD]оchq}&y :7 w&TL8ic,Wmb*ZQǶ[G0n~ph h]p|,GGJLp4?6vh6}X«Kz2u$l>qOeλnc6Z^)"_0|^''4"=6-MyJ1 D֮Ih \kqBL Wzqf4n< UbI}ZzN9geXo1֚>(Gk\Rqօc[q#mh&:֑`iǦK5S+Q`JU8FV?sbk\1?36oFAFA6Y~kvI~ wuo/UKnm[(PWm}?-??k7tfަv5 Ո3_~9M?gD-mf1ɤe|[4c$Y}<[w9w=dڗ)}[0ok_ೈsGLQ7$CCVb 9@m2F 00C]g_0+hMH&ݚ5uyB U6:\풐c 'BVE E[:7 񜎣PpEش쥯ɺ(ሕcsp;X._l !&(G Nw$=z.ud"my& Ll@!<[:c !aPk-7F 2 QcGmc=uJY䟫1=HqiQD1?c8AocQ_?ĸTz'bؒGO `voxq͢րS]/L]da~˳ZJ9%Q٥q`l{/аF<K4oWhMZ[ Mb;0yۮ(,cWZ}VRJM =LI |+-%'?< uffB$\iuY;\%DVz)DコzS*|nl{ƴ}W.hA4*ucAvi0}Z +aHN <V2&Ƅob Gses_+kaf}6Z<ǁL xY?TQ֪>ʼnsFE9XMV.<:D84:GמEWLaT2xGDCX."l5gp3Béq3gh!ػMAOc$,gwh__D/|uwZUF帾/E=quLSUJ! eX1\stn_}{BHLLgZ0UGrCUvQR@4n^zcZO}msduuneSM.)|'Yt-imbdh3R0 3?,׶8EMD5Gv6Ons Fk 5Lx4E .VaY)/E,@q{'ʗ 3t/> \wH1G 0/ k^*BW5 k^pɨų;/&p(*A+2 nHE'홟]6)#5(|%ixWօ>p@Y27ӽ]cS 41b93Ѐ~pn<uNyY$F!ES+_zb޻?$Xb2N=آޥ7K@q)8~z5(78-r$SX|%|N/ХD?WWꝭS !/sY[θ6kIʫiԑ0ĉhRW9r]|=xe ҩUƯ99LaFrw,5ZfGj `]I1rES1>G6]o`UQ h_{=0?|,y&.x3Hdu<2j8Pz ()xy0\; ^ACܖӢU6غ4fx6'Ɇ /kW5 cmm2AUW "vRh%wYFwU5ݰ] GXBxToi#F:{ޗ@CG QF2YO\ c%qpUuKϚxEĬ^8ld1rDN{&G5M=O-̜wu57d/%gdIhImZݗG s|0:3#9ED2j3+d+3ŕ@=^KYA ӲtI,[*:e/1\/-?H2,77ϧ.LCM1l>s D#9p< x7w1L6w 'y CpL(2غzٞGh!63ۿ[ØךCiGC<#whX=3v::('aDQ7x>Z<խy^,,+QWf{(al9B)5ͳ¡:AxLHH7b@B@Թ̣Qץv#rq`tUOڪW)B wBRo+:Q3ź)K5SΆGi2*ٯQbf+D+bUJ/&Fh;.ZӛOfjMőϘIE>.2leRɂ\pKVݹ?K9 Ӟz'U•X6H6њ,xLcz,|֡f(v"o)B1.#rs5)Iw;zPHeIz3j7!Ż(JH@IF;%<'/s>ب 28mz,6j~jU*ͳj` iJb{{)>)[[{ Un擣d+0xCL\i!17? |?QB;w$_*)ǩX2~ (B鎂a!lZDN`"L-cIRbj:E\<`PG~5):<2!70p^Jg"]D>pq3rzzԮF㔅 ;;#ʓ 8צZj-Ց S8Ly#4/kt o 1$7FPQ/wfP;:d˃.Rl*B>`xMϪ&BZYAW7 Ccݓd.3x UIafCUѳMNQMuWWFQ3g2](=ziHӳ(rBbdtqqDNF ^'QC #\ZMPXǏll3ݕogUgsSӛYz9Hѯ 8שiڬ6Xo@`ӐCj0fFKL)2p .>nF~:/KRbZq׼秤9!]vttɠ,҉*0X{74m^!HdPpl>x7w:eFn@/Qq DcGm/AD9`\PM'dz[)Ъ ٿTe労bOn܋Nr>8bLOm2Ү$1{V$3*Ine*kJ>z\'L e=^!}ܣzD!']\2c;{UǑ`xaAnӉ ¾h-V Z (6;d3+ve^#`x:[gEΚzCJ3-]Y[ɳ :Ϗ82'ah#  #Ʌs)4iLGf'T{^+*f>q- tp/!܆ąfzL@ I|,nX1YǷߧэѣ2KcI;b5q}vKtlJFOpf=RE{K"qbK8~#+Y]ïlu!j_Q!ê̐q,F 75c/.-#OYeD}SPg҆fғ ׫0l cNLѓlSQ G;_Ix?O~Ô,7HSnu125խk\C@ċD\Gmcjw#"w.l$qJסK q0%2T-CBNV5J g ܧ" #KIdn ʙN!V< 1lBY_Ҙ%tkl|$J'(¬1),Lv`k\ G)bnO܁!o13&u)jlpd®^R?K%.g\}xꬾꠙiA @quybu>*@m!\ ~uL4޼΋:1DRmiڍ`W@;v&6K$"yN#CmL^d)=o>AmӬr͚z*RTRӘMlCczwss)^skP)|D7" aّ"Y7+=&U."PҦ^~ %o8&F!+W\K8͍S7xYʲ2ޒa2k5?,Ppkш`1+.\}kٖ.H׽_|帒 @YgSIܺڎ \;H!Y.3wV%t;DOZفglgyIMH;u ?vR O]#h$eRTY9 OWF%ѝf5qUQФBQuUl /=Hi`*`ŧ :-",V\{QΐM*-&#xv<J6<5-׈ZE%EC;Y8pr;>€$$EMXG<'aʼn"߲P%նx\bsP ,Z:llƴ^ek6t#hZ*lڏ&Ó\[,('#6:l5- , {AY7^>ZaԠ^iC~Ϲ ?@cnLG"Q=i.g [ݴo*XLaN!#kU,V㾯O+,+:RyXWwCOEiBf{[ 11!V>`2Aol(FSжF^K[Q0;{o/HˣRT D|.sn7Vhx2s4gM7Xeڎ!ι ❨Rߜ<ؔ*EQ;mp8'Ew稀 kX"\U}K`Ulhr!|)y5L&J: ~6JIX:v[:uWFw6hn]aԭ61P #6m0\k!Qm};Ur$C$azdHDE\#X—MeÝ8y aUhe?)%QnYg%5/Wi|]Qq}>KPh7@ZQH[\lf &7yS4D$?cv6 Q E6<>q[ICd:EJ=h!ad I d$yꖘg&0M}8MO7e3.~_v%9$9tr=iPUsqn/ 4y=SwaƸT>J\%Xfsk;jcxSc~XX?zBfX[k۔dWEv 5o+tZt(gv&Mwj.lt =cfZ؆Zl`Lt|JT YJ qӨi3Ws܁[]Bx4f4S"r#`~L(ImY pU )U}X,OG0JI?+S! !ߍ@^Zĸ g2W yӛ[o|;M"삵ATrjc !W2ȬBz"y_:ĖtJ YQ;Irp%_X}(@X17Wej/D@j6UTu_@HʗwvSta̢bhwHu\wticv@ǜ-Pث2Da0@@s/g7T.ֱXVM @҅XU^!v)PpzɆlٵ[09umyT[Bt uiNxcvdTAa2 gPs3F[VI#)orp,L$1prWX#y*-8͕RD;k.Gom5_t~C~=w ^2cw<7@jU"'a_5 +ly D!AW*٥î̞;xk2OM&zW?A9o/+%c-H+n*&UݒfY;lb9z*< `s# ęEƼ!.((PEi;%`Qw:x{7NXH/\-@>~8^7$=i_,x>/?Ќ3ra]E{Til=ط~pD cEYL ɰ\r).U~{SA2+2z]5$LaѢ%9 P a9~v5#A/ -[)(T.ELfK!a=ĕx*0F/bKapQ邦oﵴ,&>SD2,.5l?">Ob<|ȑt 1* Œ>q, M#_P2qKo}C'Ia: ' -q}h-0Z:A4P@XI.Xϡ[[ʻPUgZh xvaH?>qO)zFV(q([ edoM)D0YWL"<}^p>ezrP*\j ܴ}2x?Jg ܨow[e%Zq4ILXb^ xU)j<0 Sbz=hIKSfL4Kɧw԰q"ȼD_5j `^b/``/b6Hy !jhs@QnSu8C*p 'AWǚNݞJw?4JkS(fX+vjlN ~׈CsaB'C[+o 9,ԁCqe.S#WKpԅCêڀE#_b4s o')\-|kԭN=' e|T~VɍsFm)8+%>W =' q7wE0tKT s`RцBrvJ>)3i +rh K>$Dz2]p!`<]Fwh JYQa,+X5^! 9T%{Tvw2c <@*yKo#}r.@י.l^rm$1\45vpB|BUʡ݄p䵟l'"BM-<+RjA[d5 ɓ0:g{g*sh؁J^ό~?Vxo uP CR8t $;^L*ש'N$wY#U)&бP\F ث$>/qN]i%, RB&)\ g5-݂;k'[Ж44. oe4kX' 3IyƏoBiIs.5\F-\Sy]`2mkԕi@YN]auq }5)H%x kwᐗk/URrҔruP,_hJԫO"G߂/ Cv(9|^yC" 64%Y:iCE.i@?dQ = 05"%G' FӸƕԾWQ%<$2^v+ޝ7l{s_-?<|d(^1γa?iƍ;", ،äTy0b6"5={xp:u0'kPc3,aaVj94-1l4"p*wgs}h:*eƀr*\cgu>UgaDȸ1Hzŭ]唞o )G1N6D3Z}e7sf^ͱ}gT)cd⬡yBS:3E‰r[_ݍ2~ +Ǿ) 4Yg, (IO=ױEx({_74Lq:G}97a?F'lL > W1_ND#! "BwLFq.?S3QC3flHz`mVJB)J`Cǜ4̓~ukG=@d6:A m,ۚ YZJzxC6|k=Q>{庍JWCpx΅IW]<[hoLq|ۡZQXѵa5?ɹ;Okkkt?ԦQC$`14~ y'PB`/CN{_z'dKy:Pnڠ?\lے P9`] 5ev "Cy ᩚr~шRu>+X\RUD ]s|"]j{YUn;9_΀R@M,qguH+f`,M8.++ZVֈ$O - ><8o7w V>!i 5PCیllmmɹ\*)ޥ۱>S}!"9c=1+ħ^wPkdHlU!%cy(O.m -\_Ͳ cWpb^":|wҕ%qV#?p`S%S;t3w WaNx5zPor$4-XP@a6@ȟuExXl~XlN}<zHl}Aq.{LJfPU|Z Ccb{dR R<216$:l WĊ˙aW},2V& :5oi?2u&zL M#jyG|@P:x{$T ' (Z7hODG%j]LMx4<8f I \֚rv;H~!/5MWɦ=V& z5LHY \N>6w+se01H6ت>bLMroJ(77K2n 2Q2 R̂(u!"x{їhPK,QIT+ e8LV3 z#uP |nJgonZ INnHudM-=3KSUK@ D>8_U)`1_!EybF]CEi73@N9& `g1sOY`$+(Mo[;(3<^(EBwL(; a.ZEnYw6:.ͼ _0!~-&N= ;&J6G|fP k8U@pc{TOU)85T|8w6dS^ۄɄYp6mzzw[蹶.\+$dA`ue Q\!I]8췁tڸF xw"UKz <4Ÿ6䕬f)W{W>‰*j9oրՙr"ա@u_ڵ{baWdb)aߑt]k8ѱaDx8|jobŭxTj>MUϋw̥f蟃No?Rt#)?q(8u^W GΎoB9;ԃ?pĹ;/*;8*PY]FPT0<v ry×^ 741O(en#m/bW[yb`;$KP+pX0f?о@ :n gp~DּV׭F{WՊ/w๰:.L n%u6z'ɻJg:ˀ?lOT Vbb:"aUT"&b~11tT?OK?euHwA7?ˉ}.՜qwR~Rkl{mA)51j$_LQ0<ꋥroAlWD+c%Val診?hyLf?4S\DUE@R1{?/FmK2#%ٗLX1A蘧R@Vn@`j O\X0'g&Rbz7o8{M(=tu%^rl,nYΙo+od Pc,*kۥT*~|20kVa-e# Hۛ ӋzrbF x p D'ʹi!;ч')8F8a [Nm[;vb\+ d ?l~m(4Ć/mmR0*6ϫꙀzuL3dy;XLrL'/7Sg0ѫk#fk2Q;v\WW#< URs?B0ؙX%KKL ƾ%Bd1Srgp q\)BЫv[:D;ƺI9~j[;ђds!! HX&`5b{4>٠xs/y+ uE`z|'PO>FW^=Nd;)>Vtt ؀ᛸ_%[uQWD06Xe'#/[zMg9I6K6fs͕*{ںJƊF(|I7QC Ay%{߾ =9Y *Fy93mXdr9yj5d+ g,Y6K,ԋڤQԖ`SumI }t-m;-gd^= kIjJt|].'vʹFqfL %p˟83X``ݗΤS..)jh#9ˡe"t 2-"k#tǎ2J+Iךm)ܓY#`gזw0Gv > [@6Cw$Ŧ4s'e=O{ ]rwG>v2804!LŹ]手IhZE:0_`)^9yW@(s6"ڦhbE({3bZV c?6 hI';vhi!-H{>l/B|&7PBLm,hfh{-5v)xs@s38u[+뿐̆{ٰtgi֒s3(+1鰞ů F,k6o؞|+[^]u#{&sj' C¶xW^x]VKWV\lz\I``Zd'q0y1Z:\t6nbY HlHƨTՎ Ͻ6xYx7{~T曛/і>o%4oRn-N "C'&L&9ײbmU攔kti-{L$4NL'[aA 4tV34% 0wqy2jυ /[4/P"P~7vkshKj])TBlSSdӾNEk86fK;Z]7Ȼ ͮёA*65Jگ :%֓{х 䍱Qic}3lQa'l0Tg\nɉk |>9|$ʿ.Y2V) ^{9B7_ӸlCΉMnv}w+֘KY5YqLnO0uL2eF$Sly!!0aQC3e`ԙX\XaOHeCX0ZSc`EtZ~s ? B&!CIx.$U7 rfFC*Wt0˻Xo'aDb*Q]͵MO \ ^FJU,i9jwPM$K61-~[էnB%Ejq 0]c,Ui(Ki\ϧ6T2t a7h }t@vy?p*JEPWӽkXF=9_ŘB>'(R2sQoȆMj+ >A,ADZdvWqL3ϟVќZ1~)ݲ:%`t6 M?(rݝbTje˶d)m|w %:;qۆ YՀrn־ dCuj?C+X?pjv?VD.6WګBA`QYjitbR,X$>8M0V`)wj,^2vtH.H8Rkk㧙g /.3D2i b"Wu5{'ƈ&c!lS7a&;v5m4'gdn\UU"Di,J>'ߖBSW5Ik&yjNuےY!BB)?RC1qHRZN#zmMgXޡJb dc`rWEmMmGV 歂V}}ˊXkMդ*7 bmN12"ߑC L6mh`,LȊ>I)-P&y ;ݚmGLka5xy7wE?tÓg9\M^u; ~\/2xyKSq4)T|)<@Q̠Ť t^-%D :#i|tEE#Y$=5}3JFF'gawo:ܪd6t9#n// g@>Ϟ3th EM{.tZ;Vb# xP40ۈԁ4>|FL5ۓRs|ɗ8J¹|[ˢVՠLW .MgU޴G@gUm\fL솃yNZ9lfhϻ!*2KBU%b:A?P\Гtan٠ N{3`p~6l8>1G?"YJlKŻojrEfLo`V..^z]U9 L9CG׶f[2 E\ dzK^ !]`~.gi_ _;̺e]>8x(_Yww9KJԈnDk/ǡnכ')RdHB,twgp [)Id&6kg˧=3FH8f kR e9*K_Pѕi6#Q`jdpn=u=3 #nM%d|:D5+Ax:~cD2WH"!@E9 (o||(3P襣╌dr,vi/)eK(4!>9ZlrL$-("-A/^l~JQ$21)mmzq`DĽEŎ$&ԝ(_>}j|$ uHtrs`s>Ms7Z +zngi`E齹rœk>މ MГ Q"ZXzD'cF@j(٫!$iv5+ Ad=#sxer-J_/۰OحղphEbEe/ w&C(,.VD~.c+<积c u/qd$gPLj۬az*l@鳠PWu/Dq֌|qheJ>I,1gSD?nV# ߼F^Ό$xBRaCB82\ߌ_ ]PizR蓯>Ǎpu$nTZmKPv'{pV!>%Z8+~B2iIuV_LB|OS.1dA'Dp|ȁ8W2) q@M’/ĹK )N s^t\R˙f/L(?Qj2%s7k eC,'5pj0gL#a9j"%W+݂yx< ? 8x(}lᵦMmPbiHЊ1V9yy,jǪ +i|h䡶uiHԠ9T^6[+ YB_Bܝ,0jͷ Oï *ӽ'ةs%f^1#""gG:CxP (vbU܎QTTm ^Nt>)xh̟{Şea΢[˛zbi)NObƌ﫝_l}Mhm! ТiJ-򐯗k YsV]ؒ.F=MMbZJ1@sYp=T C=$,'\!۝HvkL|+f0^oNCNJ@5/UgY-,XEL=B}Qfķ@ m+f[F()iC/>&=@>u ܰOÇۇ%kxnrWAi_|w[ IMgn骕>Cj!*Eoq2w0pY__2}|ϊO^%LkM7eJBc{zvKLtХhܓz t_!@e oFGb;L6_PʃYLA4̓XƵխeb `X) ѱCbPѭuoOss@WgSxޞցjt`Yr/ \!3ί8LslnGZ<&ZawMtLQq _(A!nyxZ7Q8D# Ɛ"gbJCx}rk5(((* ȄEtlZ0\]у|n*I9nG),Ij![(voiy2J:$W O#bX,t!' zRpIYT|u(a<)W~ϯ(H0;t Rh }hG=ar|c1< _3%C[q:^Q֜A@6j D˕U:4 fԧ! ~(C@04c'À {[Qh}d6LzV/@3}j.E7O*mKǮd!4 f]s,\ߜxPLpgy"]9G~c?B7a%uO C}*_B5ڊԩ%C7ҸƝW~  PUb9/A)n;ZbʗM$xѴMJ: ʥKS3~y !$z) ;ZBA6IK9iYJ=V_M'^j9zoǼu¿&P&(0On慗Jl{d 谒&,HTbHkpC,OEkwBӺ0$ȡRDxkN~+W`|+IT3\s_'Rvhί(Z\Qd d2h4>ZuiӸe`#uݔ'j}+.mv" {-)ZNՎT9 Wԍ=e?/牆?hoke_Ƹh{)/nx%OX>\LT ߣ]`uA4'$rj~+9 ^g六g4''KY I#=:C Km_t(361Vq,ӭ1|dc&GE2c]ǖQ E4:YΣgAx } 6W*G8y0 ".{o,Ds_).)SMb(+NOXf+qՇ "+m V=m`"A#l)S.yQ.1~(; go~%ôe 5 `e%m7 ɪiN@e(ivEӵޝpz੓hCL SnԼYMH k+`NV 41lZ=r6Nj%6 q`sM]y+t;N)~v#'v3XppDҞ .CeLo,oږyB{"qǥF,YG;ixf-9=Hhp6G #FZ-56)GOxbz厇d[7'qa.`]`?E;&/JEW{X,Ũ^?_xǻ`W*F7:Ky/LfvSRo7[vbp42tI|Ky_ҥ3+7j~|RH)G V-P/σ8UGd:& 2 5^[%zdhZ7^ 7#P UB`j8[3X̥i0VS[#2P UQP 1Unz%5`ީ3 }KK׳8iq7~e X& b+Dp[ gt]ꩉ-?e~3`]c,lhA 5D§;X;Wu~皔KeG)6ރ:`ͦT僅TG̤:G2;d)rjǤ)hJ׫74!R]# 3,S (n>D4;NB^@QJ.z^ׯ7?O{GK[ˤ)o|IN`k%v=)3KBb ]gTո*qMRm|{J' R [xsY승4N?}U>6ޤ xܝ\IiS݈}je)ވ< rtuD@9htst/p8B4 (oX}7^YAQQJ Pg+0jDVPezrKn*S,M`|b[*}|, قϳLq =6Ȗp&6s3gZ˙+|,j#HEm K H!d&zGPH(G'@.ԏ]8aFVa`/Zks^tޕS{>*e'"мAyHb8]Ikyuz_E}}j JY,d>NI_*a?^hVєy,=lHwlبkcKE$-m߸m 2HKt r=pa0bE@Pxϲ)#.\-1{d8kK #rĺ,yB5jIɷhVKr:rrX4i9|Gʰ.(A{ߏyUQ^Z#S-3FR+n۪zF43kjq` ]b-X2yx3̗Ir 6)k\Kkl!G6#G5nظTF4I.Jn}5F?3t\lu|k`|TJ848rz w4Śh732;P"hjg$o7'08L$y=/Uc0X2Nmѱ~<S[G1[ ť7(d.@e1o G~.n>̚SdgڔeožJjiv-7ȚhoQGkmQkL3O! Sv0!%y 4olUsDEU11:PS雳/)-D2]lZ mH{;ǧ*F^d Krud 1?.X9hU={Xtʼܼ-Qp6\1G#?3DM$Ox.S/N(TdS/֝5B TKb_1@B[&ZziC}jF\8t)fR +ޛ [(lAZ^_zX?#8ɖ0u$R<ۇ$yNO?vn-M5:C7O`&uPbcv[k>͗7;-Y3n]^V_Aژ?tDѶ1\K9 2Ieޘ.{I+j*9cOgd.VQqr}j (q p@p!wLv)]вZzO@2o^ONCMm->`o{H![2N]n h 55`Rܦm3[4C@.tW㸄(Y՝02xDP4-*^1-KbW:ۘ Ĵ`tāF6nPʇ,18,"}F;\.v=3^tmX%Pj_9ͬ`&\6{`Xzld>by[mP䗭ڡ1q(u+wÀGٔr=G6cVҳ6B;+U+ZOʺ+?l]}3S< ѓn_k[YޱZv׾C1lL^]#ѶҎs! oQ(kI/BRH8Rh*' ]񂣠 g猂Jylp6k H f5T7D{ړ/96A0r=|XL.1̨r钃>\q:|S[i_o1o Oe[(h<`8%JW)HVyL#HguH뢻2XV-W 7+?wAz^~5od~0t5M^jKCR+ HҒ*_PCa#ċ3ȍ֭PR !(mdWF w`|HbyŭW%,|^g_^$˗ Կu{y+,V{1hc< pO7x[[;%]㢬Ô\uV @Vm .  ;C#w.zYH,"}Ob:kRbk2v,rg^íQNWFV&35B9N`9_[ӓ%~3ͅ$,sdTqb.D7°JɆJI+;h`Lx b /i$۹ ҧ7n܊ 4 ˃MA-A0+tEkǺ땠v粱.4d-c;RV|j(k t^Z)b>3<౮QY_h~ZNi4W']YoA@+eT= iQvVv+b>`N槛g*DEiu"{_*hKJ6Zi04|,i*YS 7x2coHB9;֚Rx6VNriDÌ:GW,8^:[9{{OSϓI$Qij|QN[K# N ^Oj:i;hnfzSW,n!KL@#l9 hQ7_$傥ảL?ZepEF+oP>yc삷U틌ok wb }F.ezF[ yĥQgG-lj1ҒAzO6. ` L\#A{]"y΁0\ΦiJ'/`iRQ0޲ibUvt1+Ӱ|jV h:|%{Wƒܙ^Ɗ` Z,bXyLΊA-ڥڋ]]b؂.{!͌/i g3U+$WE)D =16 W7=3ek[X'*G+ crZjtY,̫Xf^6139JD'E i]2KlXԮ:B9w%7rgGa.#r_ "^[5pP.OT#o^o8/dϚֱwݨD___D," іQ5AܥKc? )kZ: Nqډ~YÇ2]TQ~*~:nRDr+ (JT &6Q  Z"xMj%h!`uvlgSWGb >G.&q =4gaȟLڽT @3 ]@t |#n+2 $1#6f\9aV2!7Q# 6&jlM^/EK^HJ'9m8ojMc` v!O*eܙgPeIzWKБXk- #ٕS~Wg,vSN77D5VwO̾w G74q%h?># "7XlC[w,~˖E~Fj'LHCk#pR^{abI # 8K]aN;q#h2ΰ܋A޺08_l8{&'zh"QtF6>)s|E)FלtZ~/sPPw~⊼j2UP>k&5\^#NLjnSʔJkd %)V!XyIo[ H;m$ucOen0mqJO\93 |BBkvC8fȚ"NG~'lOߐ@o^nz Qvnt d,g:R-`mJ?L}^ y:RkY/u/#[JO.rCqd+fMB^6NMbp!lJ0ϔA6½Ǜ#eZq|!c6icx9 MHՆ_֬uoŒ鈊 f9 ޱ`dikdcHK|@6vQyTm w%E#d2W "蛬6@Қ\]F>%Lѧ>e30[Az㗓uÐq{o9Er;ҙOi>^n䁮?F``_ 9٨M7ӻ2.nܦV"-uF fRյLpSa0}Tu(X :ܤO 6L`.UGTrXOC .RɊY| XO $&`~w cmZ:{[zUMჿdb?7xI-<'A/hkO)7:-hkP$[@^a캢WΞ/Y@RgC=^K6}~M1>!|^tgmP@TJsD՜8!s׎cD[9HB6(x\ An1ע,.pi;U.Z7i&U(^(y#"l8;.")q#'糷!Q ٯTgmw=A-jŐ*/QXY^`D izxPvO;\&WàM4ݞd]غG߱1E(#,f+Mȇ`<+sVc(lE@C>LȆs2MO׶K] rFOy1Q;Y$x2|[*6R~0gY4dmJemLK!™;\reIC%OmT>JspWK}dw{g0KGW-aIPV/sQ Ofo~in!ЧN45nﺫ[nrڀչ=I,rNԯ 'q|P{h~@xq?N_k1x^~e VJY2hhs@_QPWidX ^^5ph|n+\VfI>vxZh$ՇжN f |Jy_0(;b0=$;~\W(ڞM[j h?PwGѻk3e|7&D"*4]4p21PelzMfhnq1`5~Naf 7?堅Y~!1UdFm1I*r3<-x4^X1Ʌk77D5f_ YHSLVΕh9'c6$ xfTt炠h*kMeIs:0D!1;F3-sgV\≞B̊\J#Ƹ/ج(C!hyP$O+NT^:'QY $+S?,R~`>c"?3n.[P*MʣRMﲒ@cx'ceky -phBp(7?$pY*m\"wƵ7z)rUf FT58^h+m< / 3_aamy }ʢ6dZGkG4vtߧq qzp Ӹ7ZA Tou{/z)ݘ͵EXNckFwק- /.[l2hj P>GA>;"Zؐa2`;1\1dzv"\D" ؜g,}g;WHjG/R&0p k8Owd!7U/ Hʉ15N$tM.ޚolft-7U0sx[)|#A7ASέ&cϗz6ґSJ`JdoE7:N7#hOfi0,[bMf%EHlp,tn*?@^8pQaq[!Chh7*kBT5aeE8 пG4uNs2w1[`;K8Ցjmd<:Pt cEy60ĞNAR M$e`VԈi,G3!y[$BS]@#Ŭ)9L jieY5_.&mȖr9Ξ[Aea0feFqbbe9v%Y hY 'RGRaQD6E,; vCitDP$xr E 8,,dR$oQB~<#XrmۄfuD*@HYC Jp\F,pFY.kUe5ewIF:g "7.Sl%7B=5v#!M}'<=3P3i{>md lw W2*Xy$`c#lHl3Vӿp@{(uq'?_FXlio DW6r" d[$0K/a]g=9[  DXuPlƄ9?vWB<&BX ijȹ)$7QQw1841tu=Ie=, ฀ 2:G#ܳt|q }Xr(/@X٩jFwX>-?#BPE[14zu*m/D*{K僆 >q$ԗhG(Q_CD#C;ʰ!*&A@5Rޠ_*¢:i[h?[():^n3mF6UVAb:#R2/f&l&s8pIQG6Y%Kښ :ʺň1{NiܯT m ebxR;ZBθPaD(U| @0`!vPں.r?Ox@h4p|lB-^ ]D>"`_*?ױԧgC{F4-S(KggL_|9ӽ jE N3(L Ơ‹*0}aO]4Mp`n }H8ThC&?1Fs= ?WM7 kAk+j]|i+3k/ʤ)|#E .61dWd 3Z +U zX&#TZm1ғ ()6y ?vɇ k6]Ҟc#@lfwqY${'١Vl𷕑Ez,~ًiC?wV8h1ZY…ɛp%F[ƕX[89nwJ?ٳ`3l>hچ^G/T +A Mb3s6q6g̀P\dN+CU ТERRڐ!l5pxVx`a摻B"}hm Irj] =4M `o!CMŸMc ?) k7Ǭ Y6Jou2A`!йwzlPIYKU3Tx⣨Ɠbi[]הm~bwl#١ld `odi$:\|4G@^V{a5]ԪൾrrYU)he.ͪ_3`O|Kȁ,_c1Yf@I0"BOl$O!'ZkN>)CB鈱(E.Z'`B]C1 Dn-KˈHgq6 $dVJE Nc/喇wKUuկֵUQ,OZ\N0sV$1= /O5SzpJ7јޒ7;gqA?"Y#QYDx-Z.i[4u`ZeYyo\=" Pl`ob(\^ZX[/O+WQ Pz&h6\YllH"{[>xBaU7ˠ듀-'Abc<0ww$|ꅛlv<}uٜCe~<o u d͍Uߥ΂E  ?0~m[Bmh+ /OFJqg\FV}j.B+ٞaN;K@+06$YXV+-i\:?p7Otri*#n@X?s|oA [ G]9\?idVT;A:\hZ^M0;2 ؏؊/~ͻ+k ,P,> ȻsXOFz\8kFpG-%h!?XrB'R;}U~Jj 3[Lv3} FwawF:yw|T)Ø?Ց`VEUef9;2iHvkl3W乸 J;:*!ˌol~Ǜjg lMJ!sQˑ~L~xK7}Xѓkn2^ :@38bzitvmA_,Da_C+ ՅFscdyKwt͎6.1QL@{\T)ZlR?Kد._;xrƄ vvW.'"ꖭE'-wtҌKMo1-&~19O\gmp+e%^Zu_]Mf*TN{>6F(Cdҏ!BrFW9w;{ CKp3&5&pmɄ_kd4[1cH: j%w.է0ӽ@/Ԁ"}N)c+c~(TUE# .Z)1 ل~ [w+ j,tX|3*4+ya]3n[r:6%q &ch!E;aKUvJL$۹s.Tuy ["w=i:֐Hɱ8)LcȬ&5ڨ+G($ܣ'-4yx4u-:NEw]L%D"tv={JI\RvQrv)C6`xŠޯbYRrɭHHƋ RAtSȶ>x o'>v;ŸzG[',$J=n;=QAl 'cpO{(jbunwۼ.nh(/4o$p g,i(T{4{&Y4lToB'Pbt&2h'_UD\r&u|%8hz=`7թf[LHWهa oG:PQ"7l}3MAy=08kwvdl_*Tr>7 v]rj mXDb9%kp7-3g(u㽶^ Et/wKa0Sg{ShtfSr B3RGFv9Fܛ .ŋ-&U$&Pr ezr8rG52у:rf/ @丆x~R囨lC!Z110VD n ;E~x,P.sFATb'(2hdΨ&MY%+jg6:bGq72B Hye"Mrҗ7=)huj p O Yan<~;lB(>0miT7ԽSb$fJar=;Ftay"{MsKeN3ܘ{Y6LDje1Fg@RhgW[WsUAr'vk:hjgX;ͬEx&4nxw&"]O=0xEQoaNOWe<$9/gW: V>r!;ܪ:Mq{m\]JHUjIM&^E+L?t +G_Z.i%ᦇڂn;+i6УG^{H{¾R]bcSHhcq*FBkW# ?Db.x |`'+2uo9%4qL_dm;ޏF8KYՆ$8ēR˔k)HZУK H<(&!@V% djlcRr>(ݤ;$r$[SB] zPsc2lbAdf_z8UBUS2vc i~梽dnDOA8Z#m6$#6`MZ6&UyQSU։eTa N`2{MYWגgo̎Q rŀNՎ&\)d ;qR_G9z3E.Rl6ʉ` ,~X|+RdTcyT-HXa>bCO?i8#0x3`/CTs |1C U\;e;֘k:/d6ho,ɠҹ?d02W OSRPgb-(]iQ*Y6؎ݫ$D.B6[ h? ,$G¬tJ3)UaB [%IQ-a0grWC+@//!FuOқ0u!tIE P#YcZ $0EN^l./cF`CU<> ہHFXfR6jwءTc8Nwtox%5X#J[-t/WD 7E"aKJZhIH__'ʡr]B Wv1#w1X?=jIuAp `0ެ͌Xku/ٻv “;m,#aP:m>Wb g~6[؋N"& Ow$T]dH-yx*O0ޒ2Yuȳ쐀b;2wZ_oZfҸi:/W&`υM$(Xmo{.2LȋW*]z\hm-f_ 0{#z*SG"8lۥ6Cy (I쭕o.Uo낭A&mT1V9Ją04e2 veL5'2[<} ҔSI<#ǯ8DžSi+cQ$=ɏM!wUOL~bf1̤{9ݖP-:+# 'o|۵Vl'A"qN;xL(ë!|U>H&"l׻WXN< $Z擮;WNmN󸆿Ho1X:>!H,d-QTm?NNlaƢ-BK?F~-^CY%&бE_XQQY'T8')wA[gJ48q#}N_ƅ /f?B X5y.Dk7p{2r*w/FL&^)/ @v(N$ d]N0Lo,)_a4t8f oH13,eö#"js_)Q=+zGZLoEzs>=k[,DN=켰_o+zw tD@47}ptKXO_@ʂ(+aQA7IyR\m!¡L4NbeY*ӕj${g |"BCTޭM^7Prx/SB0 /vY=qZ܍ yH-Uu-5٨ ]!{x?QGs@'bJNLDړďw"% iX_9020 _)nث|)x(a~)P8l5,=|:ݻB^숐%Hۆ?@~6aϙ#ue8MCVw%Te W~殤SavzIO6E6馏d? c|AJљr?C|<ǿӷ׊8,ži)QЖB\s lBcIr$MU71u3tFF96)w]^u+ ,_MW%ZKJz?{+YlW9 X՟9^lzx #b/cF0%!Z=dDekW3VNzq~àdFJfy'Xٕ(~FsQ8XJFQR{D5{_/J/6^g&)fhTΨW Tfb#C,:9m yrF/XWSF_֊Rb.UmѷDP\fI)7b -~QauP#끰X_af`Kw\v)zR.D"em"46ԈHozXBMg'x5f,h$곾|آXVezȓ!gFD(@=?9Rx=*, yn!r;*s6nU*!c:`4-0c h&uHtX q Qܘh?8'[TT8@8M0,1 £jx"L|}s[0ϰr5BnnJ+kb*ivehZڝJ^i,bғwe_j̜b^jԨ?Q9{T@HZXݦxaVzs+u\]!&wQ SPg\T` MA9`%óy^AXjM6/  :(1EVea A;]-.JP6{QEL r1( уg$=wjө/l=U cdX?Ykk8F";Gs|;s$ǃsV0;=S⻏'xC3OcQ_:WCU(3y$([┕n$zRg'yfwOF"dtɗ?Ј޺7VWo_Ix#m/XVg͏AX=-vª֙jy#-:U`H>igE02p.}g w;KטNZ6yPZs<6ߤn|$/:h h_lvCOFӥO=]ՍF`Y_I'aM8n~vqeI%?B!z@b7dFiܒڎ'aШ\tzY;YtP=nFūɂ`ݯTS._堀.`+HrC \5[A yQ,= 6dY ^uY`Iv|rY򪮎K[G+s24^sE`4j2gqύbHsqB"` _ S՟  7m>T=QQn\*Y|} ZSLnc|2\.`09We[aٔ#ԞwBۍ2ssx98v.emT^E&C S}%ɖ_-rZ7)3j-d*ՌxY6/ K)dfv%Ox]sA6 kHLI(L}0",~O bEDvyO^Ң팻jEO;Zr}ca ŲBx mal- ''f3ɹ`V[C{wM!"+ jǫז@uSՍP{:k26(>=L HC_'HhB_Ll34z~aFTg)OС~Td9_׏$ Pc*~mIďn+̂eR+8wfz2Uΐ1qLt֊:0`H]ES) 0}"|)%)Ujbc(a=~xa"3dĻn}JV$mt< pk:>)яtl''Z;yތv𰉅?fGLծRn T cF ^ceH1CArqrzzlnNӹΐ[@/~)5U\' 50OT?BQ)B Pk%{U6YК0D=1awVdN0VMwM%?Cc6T{8+o >LfQG}`ZtI(g3ut2Cqdj!_-cW4`&P ͻ%̀ظZ=޾ۋd AG9@ ه!\ؒ'8s}Nf=ٜgrWpfe9EpcLVmE]@:QA}´W1ۍ>r.y;g z]'J!K [;p4d;eY{xӌZM(v: 0=|-Z#)V@O>" <&* NNt`[Y&$8fbZQͧ`3փPGZ/Rm@%A i|3eq7reyCsA ..5bo|dn〕I8C:غQ+G=y v ǟ2i8%[~W ŁMp`UF[-a%1( ]\ sOir^k.[\a"c-"ykƂ;"_CIhŸY!1 x{q;|*BvBYާ.b8 2LJ\D܍Ij[Y#SLtwޥ賶WpBǎD{KBJ'v2\6vGXqDLϾ=14ϱu0+B%{"%tv" =t0U8YZ^o#/aR}Q~۟t_Z ;kTKfռ09gclOX x,4 }C4,.ݽܘ\#/srTr$ [L |mNJKdivAC6L瓳Cg:B5oQNNQygq(Tw12Aނێ_OJBHRP胀^̑)$Jaxb{N>8W'P`OjT~s+AvFJ0y:(WӀo]Cq~;+a?[Hn-$K=`i)K(:Wz=ͻpJ-_ ,ѷTKt^oʩ6d=n(·lzё]n/ tp$aeF̹6,.eeuIѠ` wSMmM-;7hP.ve{I[J|N?wGLzjWhP0 I">WEgzQ%-Ԙ].D޹ h?Z)(wVe QԈe|?M̩WH)! W}3$M%E"MW`,E>:oR`M% 9ض|SmhF3=T;_b!]o3ɑ %3FƖhwXV߯MY Ա#,,l8Ca$ Zgm&\}" y|W %$a ]Ld<=,ϖI %>, ?ފ,̽%|PZ4C[, P GK,ױs9i6H. 9b!ܼ&N~|4 E5>|xwXKʣN8%_xЊAha-9n<͋TG?^: xw,SR%"鳷q2DqҚltE 9Q?iQ24|5 dhx;L!L-{UqH.Z]''oqV]X>sSQ$vsل3V~ޜ ^@]Y7=}e Zk1Sa!|.}hEz%GSyIt1ݠJ{Y0 N5Z}Z g_QBK'4M@ !Uu`<{(}6%Y{q@سa8>RA (,.z 0(A7iu5du[c9yv`)LPs/0Gj V+'3QbŘpHV ShD"'|Glr=b="]7רہQ~T}'*~=(Hb!LJNJƣQR9}*\frлGcD8+8wAAE#RCf1rvWܷY"Bm1L9G[} v㮁e<_.;n3%sS.!j^P# /9%a"5cQ\oN+($zk:uVQ^_Rؿe3YM8,@ݛPչQl=SBA|nQedt;LZ6cIVkzS Fխ)63#ehnU֖6 +N]oRS lh5=s/?_X}ĤxӘVl-<ʶ zpx8ݍrG`XžcU9r^ ^qDb^wrң Eͥ`ȫ,EUgw$$%Vy\#gbvIjׁ@S %8Ŝ[i@HN{d`"?Xfٷ2/']'OdPwPA0~:|v;S_s ܉ `3-22Ah/uƏ0fU(_F8(Dl.0T3!sѬ*:04" UQʛ 487X&k`ӈ`շ&imWcV Wien67Fmz~!/VI˟FIQ 狰EZUkz:1t&)jЖl>Ks`)u~]kK`Ѱ)!.9%;xAk'mgAkkniZ5vWR!A CXyZם1?G$PGE]E]ٴe00Uf!"TtW}ץvaf22} uC5@w !x$I_d`lh]~wpk&1;Re5xO7W;vAЬ"x9j}zlsO%(}6 -8=@Ѐ BiAS.1UqҾ$JZ^0VM5O:!)5jr+Ѣݤ;G!t% ՋvWot:V͍FkGx@egKn5QA=BsLlM31tHT&\Fեm: v `I*=nn]OA5UڔbmVڽAx d-x%[ rAcZt;ѕǡV..)\׬IT*BWW#ohXKI6ا apMģc24rf{5N,˼Iс9-D")ɖ(:hk~dpo$"&.1J,øB9ԗh^m`ߐ;Q7#<pFW\f8s7fxf dD"<Gi&m* J1[ȊmZVnH$F%`=@VÈI{wbIn "mtNkӟ5WLzX< j`"o%5J4 a)Oh`g鲸l`н؀p3ڣ u%;hlvS|FlǗQ Sfw .>MT{֫WUW[|i>* s** t"UWon69lgE+F;@K$W.62/DDDPZ/ˌ*\fL3V_wrZ&Ȫ

    Tm߉Οȥ@ʝ7VS/*hű4ֲэIWq:ĬRuw`QF4N걢q6YIaGQSG:vbGmy"ѓvPCUkTT?Viሉur+3ӥ- K>3%cZI~ =GYAͻ;[ Cu+/3[b~=hԷqiiI)6 :5!Ĥh<萟>OgdTF?ѫipNz+QfES828\!QÞ$L8 ܸ( = {AS$ DAE|0Lj5V}!W閞*Vf9<)r<#M=sP(Tr)q\ɲx.vpH?mQtP+{-5~iU'|4(]{+ˬ\Fؘ]ItʔAQm{No§,J5-߀?"I888eюǻș s~FO0憹>㢙z3 '1KzVZT|t}|I/H$B#(Q@;idP~X}bצ۹L6֤K›IE̼9԰ǜ_u b,4azTu#zs3&t/'jL Y@~9R3.NzUEhJX=bRa16H $3e)֞~g8!M/$֪|3O5\<r#]gCM27$G <.%bۡ+.,maxXilrmoi8K%ojr"iFX,tcRSRds0fKa_tjH GRb  n]$xbRx,;;Ər⤋EGR=B PëV8B+*~- Dt`΀UEm6&ګ.径0(5pk@+^K&aE '*'aR~@B VtdjU5<C}&d}]t5.)Qn\`4'/;?  rR;0]}*$;I}+U9bĤ1+GHv̊!KW:J9 U;+!%"ՃV!{;2 uiiĐ8ǫU` |LaU1FQ [–o[qWo)B%%!dzI2[#/k Qq܃#D`Վej-M,Qu@y|sRc٫T{^|ʸjzRmTkcq]qn1^$?@i"2o/WZw# KK.lϐʼnΚdEpˆF38OZRt{EI3ѵ؆I}S%|h$Xa=l2'o?ͯ|sp9mܕK͍Fź.륮ͥIecLzq&@Vxe%`% N⹅̄f Jt*xlO &`g$ zg IxqKk:r[mfps+mv39E&Q[ǖMT)zyP#"B9);dd䛩AK,}~rN{Py<;a8 w2*mrG œtp@p_yŠ1ZC;p o%LXy@| J^++g0@Zk193P C=%M|ҞhfBI&p1"N9y# ؞8ryRio{!BoYК̞z Zhcq՛|7x^1Qժ2I{LmyT0~֡P%aX$=$_Tjy,qn +ax8Abm{c.6Γ.  լ DϡLQ"yMd31f+"G  |CI:Tu8BC{ G,Z& Ʉ/^v.U!dyI ?~$8J!'pHrg3&K}=TH)V|{ n46ZN]"Y7A3sK-їO U*O9#f*VM@vsmʌ5܊! _iN Xn:137Im# .Zc0VuSe+V%T@y=CkƥU,9nWbΛ)W!=k F~S3(;ZMKAip6M"di.Xl;|KTfÔT74tm[d /E*;iAn7BM>KPQ v_d=b>]>ڷ_D _J^ύ>%<gZNUGnU5`X\GV3 Ɇq1/͌ҤԸ%i- \b9k*i-9߸YRz٪pxg>O"CϿ쇍q&5m4uP=o5@Vvhe "CRBCDx> =a.\K4i|=1NM<3FG:Gԙ8 853ZHQO_*f:@ 0!Kbf FQO^F`bZQYfK|ݺcK%Icv-.m#[JMY7u!)۩ ʺ;fz&yƆ-B/ ' apm*{%(B?,aTk Y&zCK\撂%~mBȇUzS̿ѹMmY%|p,^}tReu?dt] m {g $so9~ְД-)L=Z\.x*`.7(. >fr('x6 1%Hgr}HZP%=Dk%+7ej3"7 ^!@sTU_cM5|H8sD RO/w>a`͖:ݘ@s׮K|@X<"5'7rҵQNRަ4g|P0UUM( _Xou,(v1^DŬoVg{:-Yz b"BU1x=W.*3 ›rh.;?T1zơz`sIMo)d?p0"L/S ߠ!B.N" L隊ʜAvNRρw`ʊ\8jS4~ _|ۦ1 ֳtS[؊KvNLf Rߡe握X7\Fŏ! '"`YtҩD-.$YZ%VSꩱF_Oil, q_S'W7&B)SW|+9SUJ?JI`(|(q>[XgUEA*cJ\w4$ ! Fx coi]XMČB$mu UJ"9jnMGb_iq;~Mi1JA6d7 Q#Z iVc'sAƐ+Bf˱θo^7LL@vw'A¸cj_]n2d&$i`Hvx?wFReo!M~g3+󁡯}TYk#}m#ߎPJ ;3;*NDD9{p{$j@L?q$U{{v0egh QSz­ۢ11jeV{[oo"_iN/OulI࿠t>y꿷Jݓrg0x7s_Ξ>T{VlkC~>34Չ&gކ:[(Nvw!۽LVwKI[jvӌ >,4TWXt獍Lu(ݩ*dM b VOY[PdhFz6rV;ŀm)Y?wHp_(bm@Ve~7sцt:nBavӷ:CD2 DiJ:$me(Yܺ;tͽ;,6PZM²aqvF; \E1~x;9d+*f/` X WgH'qNȟх5 H `3(x.Y I-9A Sq|mFX2} ~2S?a`HBJ7Dr.D]@)啍L޵Zl ɲBܻCcđW}vBа%_Iט@j$._9DFcTW,ӲqwJ^oJ\KMZI(_ @ JkNڛwXbVj[ۀ=THU9f6K0 $ l"GFWpl}8B3݋pQ&ۗ#bcUcȟ(7U^LF YBb,IK}UpMdHBeAMrNYOraZ{*zI:ZAЎG^yp}%u:kBH(c\L<;Bٺae 6\u0z\ܸX! rZ'q1ҋ1v}E@rro K,Ot=^ۓ p I'fXQF 2wƶK#]JlVV`PKTpSݢ[P#fYP{N3u]bp&4̕TVx;@j&k L4xWmʱu{ Dʔ"9Dqc(OeP.CIZflZ+3ͼe nlepp'BOE!O6ǾDD7ORlR]7K):Ģ?tT?7鉳MH`[F m.I'5%Ȟ27 AsQі{/R=vh 6.)3oV}Q Hq Ez-y6orP}R)Ӯ£#'ZwJ% {5 6e0CNl-;ٲ)J'hv6QJ'Se'RG >U~wC8oV+WT:A )=x|^]M:+sS)5O!3%]asM{Njl IJWnvZ@͕oY$RkejygpH]r:jq7 (|C&9䱦ZĝK|"W>ytReDZգmWܕofjFCM:=SXUM@Ȟ:91 [ؾ 4.m|~/*/f~8Ie)}gP.î4d@~fw/)Y5_yi_*才c  U9ggWAݪ+OҮ}"6˦2)CR29Oa8F@H g)Xeһ9wA>ڸn.9 ;Z'?KbNHYkPҹl:ʶzہ`u4Ae*=VoAaɦZ;5:t 쿸amJ"UbK=KvܴHn6 S~a WA'q pDuS!Pje2,YN &Ay$ru? 81mBԔ)_ðo=,T5JtNݔ.Iz8a$Cm {+%%0v[i) rh7T52P!ծY3u7SUY2e|!' ]4mIc'guqX/w{Kb : ,⒗;JiMO9gyPAs/3;b${a̤AA H_ &hH“SJ槫k(s/CeBm|9e /iWJԸ!tHWe'<7e-cbYΔ}14oֵei7^:gx$WC/yP|>ŝ optI锴 ߳ST\5)B-!D}z :}B'Ɖ|ȣ.B.T?^W?hzZ8mcWujjQMQ܋]4(11݂eHnG}YW?3mf"nK38 q`P 5<%ϵL6 }WJiQS]J's%#R6y?j8/p c$ah ̮B(@Ⱦہ|#ze..ْۗwbEjnkՖ /·c,}QYnL$LoE|WIܰO%x_609b+ZJC{ T?,읰e{-XpEmԅ!T˂Bو2ʳp#7 :%!$lOęOSG!m~z:7%H5qڨ{k!)]GxQ*N@۟, 濞A^_VP1?:m3+bKꝬR׌x6c?_T?Nu"SFL@k0@皹sFuۮSbA@q6|P l9Α ^6'm\k$]^o_$*uŔTI5X*! L݇!ihD'] 4 kM<۬)w8Z1khLLe 3Օ1Ř~**a !rKD43x}2QN]=a^/hny@@7Qa0uh$ _U( *~ | rOg@f UslFg<00ACp3( D\j%pz M/*;GP Ed)nZ%̀a6J3/~uu"ᦐ>"i@ǜ:xupYo>ĭ7/4:p,ew[bt9/ry}ν"д9283HqЕM9cHoA]m;JmPS|W2s,iefthUUM3O+ @{#z~t2r)D7[) icT CAʹ^ }r"!on d?KMqfT>+x$w Y:Q`sտK|]V;Q. ?vp8S5#N>7"fVƩ &!y jdLM{²}wNX+e/7Gr[FhZ^Xe} /٥8,٠/D_8EGow7qH2zH/#( hmZFRvC[-DȪިm(\O+o؍ zeli>ag9M!rROAĪ:Պ'̸S%D[0/2/C%|kasGyX PXDJGk1S_J,A8 ~%(Bx[bс=xEvF2U-{t6cc#*̥QPF{ع `4~wC '_l/UXlYdڪ9I8ppy3H-wв &~+kٟ+E^xK^Ƚ=ϘWpAH(dH><:~>ŠߍųU~)=jf=Q.R0tY2]p9kgl n'=^lp_6-@5Kt!>MvŮBAț N˒1 'r!e''Y;jqеCc_gE=+ P%˿lX+nnϝo]A5Au 6,Ng7t%]\| ccC_i; 9]OV8EV~kt5.i. ur\)|NB0aiP铯FN==MO{/uh4:rB؄MyF̕Ây^n!|52{v6`W@t)Jl+&bm4 +xxaAx&i/ٲ<,RJSavV뽀X'dOe2XIdJ(}:eрU:)Ļ\tzɊ [OhUW2m%%:̫ U%vWe+0KYc)jatet @ />Ċ#P/P,管f?,Id+3GV[JUgCH|LkaUAc dEx/%_VG_٫xU|l'SiƐN/n WaXe+1$YDlf<>c{Cߞ{L+i/ ^D AOY}fJUo?A&Yt[[>@eĬӑyC~^f|%ժHnPG\BCZ$`8E6ߔa,ɉIJ]ŘUD.l<Շ |f 2N+q䯜/jC/k(5CD#HwP REG~qwf ;w+lkZLH0.#vK}1?cҝZ_1l83 ݨa*02&I]$<cGbFT7 &m%vԟu4,o9/͔%WzԊPesH1]USμyavl{CJӆNmReo„By3?M?j~ϰҒ6v;26|.ĉmS]\ޢ gziac HaDƎ X( D=rw&O{p<f,bfG6gxiYv!ywښѓ]T%mį.}SD}օķAQnP=n_'^=B<#j#὏ɒ!@8L{"31>.Oa{ '`~ù`R 2'pFA%tzwɳ"co}cp9ʾ'G,zXh?HN&Ap,"g!Qm]|?vQ2F %ST|Y1憃GҪt>+rYE&?&;([jZ)* ~C&&B/è)O\nǛIJ*d~*ӁdVG*CX[To:XFKSMr5zPikm'֨UUG[-q4?oj:P2#?kKi4-- (I$TֻP~@,,Pf j˃7zcp'xngM Wwf"u(#NB^#%iDEN ϲQ;Y$dHj-ׂWG7Ή_1 WaA97e;X2܏Rʀf5ɹj--͑fHf}4o|=- wVCRΖ8b^f711`HgkU[1%I%bEht<#/C&{Gџ8 }MJGc WTmA8nB۶"x,7܊NaHh CfL?u^/g>+";h",ʹ"+\e7Ϩ%ԛxos*ɎMNzQ U-r Y]F&i g.<ܬޮ㬏'c.61}6'`tӯ/vE1U6c[7$Ћ 28{ *F Y`c4؜W[\\iuNkx׭|ey< =62 o]~xf?|#$@\!BYLu`Ł[4zwo YwC L4z n:vkqſLV,xptAAI#6h/MJo5X_fX-ӱe~[{',OVѬ',Zޙ^x+ D:QSxTp-i_}ҭ?}8IO[d`U ;Tdu l}VC 2!DhfSL~k4)P0]!uЍ.@BAyʴ$y$xfe.IGB Nj}wPuf&Joۡxal&$fB> t2MM]L";Jx!ﶡx)c38uN1&m7=/myhS<W0N ̈Ċ7izv*_Zzm"cKT/` &~OnD'+78zFQ̩tj[8+CZ$D?;!vEebXݩ=y=[!פE%.^U588BTEZV'@Rb*V(M맻(aul&[G4kNBsu !M:ϱ ]u Ǝ.XCSsȀFAI|W&hVz\ƿNo`9S^j:go3 w9#(>SM2A|`%/耻y=jʇifI6gk]ўO 3w9Yԓ8,,ͅU)qfp8+ĹC]SU]|)e|ib[ g:tU6v}W&޼W WLZ{N[z!+،tbfyꀕ w҅+es5vNzh~$, %P\Fo*OaA$Yד5vym i C[cLŒM$4 qlcge cd=s] 4zخYDg9F ́0$CuN33{t.đ1%Uגʹ)Bfbz3=OSjddMNhB4?3n%O#= -Dt-֤@T_ws>?NYz_?X_ q!h9^z½W!O{2-QdQ>3fn X.6BDH8ٔ2(ɜyAE# 8> f ڜӎboژ4GƐD~D#r.PRo7XhnxsȎeo{7RʙA/*E5+LDebHĖO'1}jT ޑ}5aΓќMh`߻\`E*=j"gGT*Y9shF#[ -=Fjίr=d{rXղ/e:U邦8(fR,x='G~ܒUbQԎbw?!ʖ6Xa|Iʕ|$gc޺nw>iH Pܭyp8BzoRqu%(!8i Ds IEYi ^XJfc棓V?ּrsB*c%Peg'߯TAcK#=6N#"QFSaBX@{Dklsr0@/_@:0$Y CXK]&'!^md9~%N9GtSuW540nd& UJb()bR{NV"}"avAԉ6oCMa(;'O8ly]?gq9 RiXMMwD2Z` Nh.X[iFf* };5/|]@ZTnvb*Mw-o21#V 6wp[H!ʏhf !!/릁r+ ޵W: ciI7=~un+#mi/lݻ"dbx.uoxw:Կc% ܑlјt/1$f 8TP5/+a&]|I4=ҧa9%KYZ˸A3#|>Y 5E0vW Fm"7hDA ^?ƚqaX?.9#fM~ЍECh.HuaJˉ5fo*'H/,kVJ4|@m"]i`rKhy\*I/v<{Q]-P<.*^gw'wiR^[ϱC?[\ᭊ\g%m*c ȪYqT)gc%A"з@m-D \ G:$)a~p#HKBqF~ؑ #,z͉]׵rSs2f9zf Vyl{LN1亇 δI׷hZiSWEpJ! aQ(Ѱfa_ЛPDz.-J.@ofAw7&=W`b#MNH*?] x2 Z;EG+ JIML8rŊCdszJ:)sx̳UڛWtmJfWmx~|TN漮6bHP*dhR; Td+Q=jz 'TK֪gjPNΡcW֢- @ Cjo։ky<¦wq'i]H1cF>tgwH ]x~kY^}OyjOiwowqÉ aP^^ 9 0e&%Ă'-:4Q \榸mD_g~{tD=±a*߫z8=cjrB*m&BЏؚJQ' 8+藫IϥBnbj0E G,}}rS|X^0+nq|OL2>S=]٬ղ{7[ ]E =AT#YKmj$DEBSҔ.~}EX|(&lW)_B)aO RtZ2[Bll x&E~C0iޤ1Cc e^ȱi/2 ,EXR2[= dO|'ܶQ;N;T2ߗ=q[4|G+WQ 6 Ca1aYZF%xJH= ۛ x,#|+]#(֓yE$Z%hXE~T[d[p_~5@;Zuo:HM 2A C3r0{2:85g,EXN?4m`O,-?ڨvus,ەaRòg8",%$qbHeMzl b/w*HCE L[Px+lBsJŵe6Zb=;z"R70jfNm)w: )O4!Zw{WБxVD֣X!U9TeKެfbX*^h qƽi'ސke@NE8" *v`AqJQ\?hXd+"e>un8 Rօb_? 0Uw`End!ٰG&?ΥO +j 2KfK['G`v(U ƕaL0t=ג⬹\crC rBƢvrix śHVy0:J CV'ۍG\!X9o+eCˤzK;WGNNĮP]* X)[ʂ=^?@f֑7~ 5>Tߕ,B{`I|yY&Шm:&Nqųu{Qgp, c pW2Z?gppա\:n{@No&MEtIiՙ ]O[^]TkQaT?+/(&?,_'I][|検gnÅ]=U5zDVJ,GmX$ t8h>ԯZl+nY:pJo9(9ْFegujh`")X{{Թ~('糆UGCqv#^s 9nرHTQYܡQol70ko}8-K.2g\Π( I?sn>]Cy*$dW%6 Whk쉊]Jd/2񎖃5Z:ɂHKsE0;fXWǶ8.]v͈nֹmLaձH_$D)7XXކwu0X"uIS@<#r,Ï&fkzH48VN<<|iMt,zn ]Da gM ʄ֙oT?i)v #!̌G=id6EEUg/^Uh#cۮ\ F'"jngGU[;RbIajnbRcۏV/j00B:W=6-#J/bO9ZU1c1ͬƄM41&BՂ}tワs d͝/t{MV5  MMFiAwP] &B:Qvo@driUpXmb_,q6 q*dJNCPtέ^c`[p}W*&hѡ xÂ.;,Q&_) NQL*5\@i2BvZIR1 e4(uxG-j%ɉ1+t3ƇQвIt^_'T׎_MSLQa0HY[W E!1(!z) B<HnN߶옰ΎY9!ushI?Ʃ!4?wEgt)jԻSplI ǧmʐ4UM}&_}%|B]l$MTz yn]~6_)ڝ6/7uwiyv{-+g =1lkX {#|eHڛ\Nb4YEj˕( u,W.8&"=2l/;epŜ#uDE$?G-> DTH1z].;G8%' yzjQ;Tˉm]lR%~#Q8n>l(My맭$u`U򅽡7s=w!N9AM42|D>?.@%L0~'EBƜFB Yְ_{'#IV} 3s){ q(;k @ڏ]WP}wĬ 6 {;Y6U)`%Hb:möS^C&vzJ;P1C8Tm$Ox>!3u9>FW>oi:]g. J= qp9 j< @YO5&&'cʨ\d`;PxPinxuh|l} ~ٲjI SߒS>7p$pąeNX>^jcxqg ;L$kXs45#M +5ldĴfs҄3z@ 2k5+ad Yd̂)J!??)5CrIFߧb[Fks{C:Mc$M|']7V$yі5#_b܃.ڒ']s E$S;s*HۤJ'P>u/tΏ:]?)W`頎NeRŰZjmvⰯJeԹgKWqz%*9''(NӲR#)O@YGN-WvčZ\d: 91PVg%MA6J.~ Y.J[@ IPL;'\mTA~ (bPg51]ݐq'x$dz4ټ#5n&{ 'Im(:u HW}>v)KMYӇ4H<"[r(88K, 8w`ϤtlrזCI%v/GY5=4 "PQ *,XDAdsrlQJ~f7_<yo3?y$vCËvt1۔I I d\Wtp Z,pѳcPS^bMtŌ10N]Z/Ǧ̏ŭ'#?'L (3TLl.\>Gރ/CJ"MfٛiO-G y0]AGF5y>S'9Ǐu ?Nau\l>HUUN w %*vZ)Ld_ 7TZdsDf~@n" AcSɹT{TÚ]@ZMr N/Z{PE̙t_H.ZXsz$m^xi.<1Ü )owZ buVW7xQI`UljA%m]vMVD5T]'1H"иWN6[d&<&-4ԯ#+ew&oALQ;)β20'o@|7 ]N.]gќ<1deXǗH dJRM8FuF̲0u(4AA(pirb(+ΠXJ?:>ܮP' 4GAغ͇#@QVJTqfg^>ߑw_{:A*$%NYI͆EhY49L] Īsf|dDTxb * V0 (,usC 0h}I9sV}fJ5eWz􍊶6>zz6؜ Vvu;1 ?K`yX67DkS1RNj5~<&~nuwPP@_{3:-wSvW$^1$S7.hr%S&-cɶq h@G B w{ƼHmH $m,5OC 4Ô^U<6X+eb{ ,$jh̲k#_$h̒ aWZ< vMeκ#92i_QƱsV^Y/Kx'?9p.X`]~ʋwTæS,>ZT 8=ӯ(;%{x~ݦG]gY,ܲDpdeުxGg+/؄xGc $t.9W"ػx"7mYHN{B1IyNi,[HI mJeC P ti$2x쪛{6Q󗨗8؜o1ZY3K=uSu&vP@PHFfHGZ(=>~`W˜ζAf{@6ƧNL| )Reb^Vyetڶ/ܒ2kUJfW3ŁVE$l2lS  fur"~*2д[ nܙnVpR^)"ffik]U)9U^[0٥xLH/|?=˓;#| >ȳN&@`}Lۯ>Y)F.B:, x*FSSDKWً>vְ9Z<;]q/>`>vRE؄֮~ShOF-? ԒxQ.Cwב([fl [_B98j.\Q,03VP# F >ND%L7u%_<TKf)5M  xLpߪ25hɹ{<|).`d݈&>O$,J;x] @Ӌ~ 9MxăiTD]84y$DR}[_,#0b7E~d㚼YPWiS u?kTyŰ4CMgSgm^ʷw]P3jLQy1o?͔نo̩&{兾3>fnxsNۑ)T|]XmN{8n5%Itp<ezz)uW,Et-dTCE0gm8{)R2%kh)Ld[& ^nʳyUr_qʄV<1U1ra2TV1XqG{TkN .4[:Jdt/yh,}LBV]m cp8, V^J=\JCٺ[MofM_d}uU7sx^ /FHT], B?E;S׈+K5]_@z%z`BK]PT_ZΒKZ$r}y@w&t3n ĎݨG!uDza2WNܢ٨Hdf8#YԠ>.8H,+4UŘ܌SfoPg_BĐ,)|-Oh1HN5T7莬wuMlN}nnE%⥮>ALheBс^ǃF1#`= l l&ϟ.>%r_=(4DCj-3ԝnfAUBcFqt ;j1p~X=kϯ!h5v^ XD˛|ޗզ1Pޯ,ۀ?crdI'|uрh,,kc: pv1]}@O18Uel6[ OX5Vͺ*1:$XatHٷ1Б)˷oj [ jcJ1gh>.^wgzcT5.;.ϖ bdM/{Z[.By[ 4 [k Pg)#c eԍAORN0H%v3tUoOTic1H0;؂de!HUn2Np c^*q9EjoX3>^o6%g0nfCbM{_=M1.5\q+bem,x(sٗj.$WzqŹݒšeѐ"ZT8(ڣ80RpOE!0˭ v]WJ ~ 8N`9 e鞺 y,W5)2kF)i ̎eRh9mbƕ=k3bAJ5舂Ho1*li?䐨x?uAtBTvN|!3zÁǠ3# C`ZoxG"KLzFPQ /+@+6Z@IosQ^ח,/c!- ҃g_b7!KeIzP?ġW+BY~A?q)G€c)a nq`GS/;kIkƂ+Ǐ2EW:c <0t`#s P\*1^݇w<fdCĭH&fks| 5z"5Co&1B'PoI]{Qd7xtc#&qIԎ6DuE~*F ξ`턷[3*_^n1Zv!_SqCˉҚlQ`&0-E.RIuK'2(^ԺHe2(o85So橄)}ꦌEjaK:l^tQ}a}5jJLnsu(; R c1fs_Їʲ5|8}*ߪH2W7 yw. \&"qAm]d]ZXh"kyj^& LAP2jɛsm̎\޸/_.Ntwd6"VK&LXҖb #⑺7PG2*܃Xo`wt  }7GIjY,qU=10qmnVZI32CU/%=c#/w h:dU ?NҏbY'pG^HYgthgvM_-~jz #^xMhyf^*df>-KmtJ6 4=S ELuW/wg>)Bs|P1ju|2H(Cw]'І9USYL@ )2X*), xO<Dž Yuq<֙TtM`2 aEÌ0aL =Taʶ%9fj,P$AZ4{L .*JLFggLX?)AݳuXt ?>\wIlf`"dꅊDy)<'yI~on6.cwLd֑[t7WHlqk;$Y?`9v67~bUe≠UTPm疗uf7b4la ;x<^>o/Yh 0oi*c\^9[p[GFP3ie\q̤}XT/#)ʽ |D u0^>-[*r/{e8WϹ,} ݄YI=F]"MwP4a޻:,/O >s7ipz_F 7IuoemؿR$an)3>e?%û ʎ8MAWnbgqY.# f<pf2xqde7-U=Ē FV_UARDUx^ 1ՓOE3X)V3%nM0(\&,ՈǦ,DĎuik"q\Ng;%7- 3PZ^X0g!Ւ+TfRlhs.<ۈ'2`_]y_C}L^^jdӯMrPfcw?)(PdQ}OZD_mH#; 5 6N.EU0"R|_4zE2 uB"_ژGG&:Wo$39 CCvDUC-?]Ug| Rڎ y\5MU-~G]v* *dc|9vdZj edj Yiŀh=N-B=mMc0ӡ{QX~P+uAd*-X.o2Dګ ʠ9,z,U^zP}DM[Ar :w('2;"Uqi8eD F R`Pȋ{54̥SXsYyFu}L \전A1Z 1ijr^*adѿLsE1vt JBwV`&cF 'J o69#е ɖy=r5xd<_A#<0^T"ג $稈ylLmwy@'t:a8BBݓ"FgjOP[ 4>5>c6^-э6;jI1o|t㺸t] $إyrڤG$'}Jn*s.0pqSuh o9s /z/j@Q/;H \Ȏ; J3C+3wWT8%Q&S(Ri&z/n^un!U?X6:Fd,HNY@c i{^>BɂYؕ_jQM0!U͡tZSt@wei1ɒN+_?Nى ="+Dr> ok<&E*e+^eE Ӗv;l/ᡇ*]yR8KoȽۃ#nqWd~,5vEhюQX*6'ڪ鴻neekӉP)d<7*.oyLj"v#iy:g{1ޗ ]s t0 l9ADbB8~/P$Ϡ&L)0V/b(<-7pGMmvYL!]FNŞ`ӷ$hQ=;k򾾱RRt-^C`x[uА *M.G=F{WDt? U_G"Ei ļ"RKشhSkds%o@OY5ɫ}&Nm;mQ%H]MeηUܑyB=*{6h)J.'LJy\SK}O_a{uYhKc:20SF|;S[LMʐ,a e5WF:L@d9:c%pB/~BgSNDc)4fLƊ79妦j!Ad\XH,am<|))Q10f!i(f=rV&j+$]ۜrJ(_F0SY1mV $kscos,lc Qkg:}G,.`~hYmVlvV E.3Q^]}\9P%][EQ8jf?"g"+tDž4i3}8\~Y^wRJt):! {Y=߀$% PNY<fhlZ&b%ĉbXUjl.f)!%ro|Ò2s YQB 3vqq)IٞR5#yNJ,ˌxK'j_ڻ0L TIz<ݙ-{^K]J UW;E;Q'kpOv2 Qɂ]_HW]ea${^7똉~_avr@"κKvr~~z{sж[m&Gc ntCyby) TSli1_!}nVn+@۱* wkGj}" 'Mxc[i }HW^ jY5wlno, MX3pwדUMcv^zMƇc0U -I0持[f ;JX.`cK{R..$Yh l@׶P=$ C\&^M նr!~Xyll)tq4I=6,6]O|+Ή kL}:6x6sF F%9՞U#P"n(sp{](!VkU!l:_VTQ^tBit/ ~WNhtB/*9˘S,q㜉P.MдIDMolIo&iљ DTY9]A$"L咀W|SbI"lR$}2{gvܖX*Cp9\ :z}aPQ.[{]+`Wc,NmIejdrJ!4DC>p.q[i)G}N<2<9Ls ;e=ǸzˆP"Z8A,b,;fHUtOHKAcY9VzM8rs.A:fg~r-S6HPA{i]Wv7r"UC07쏢,愶ucY!NU@ڇ;i1 p$_={tGc/Ȋ0yn8=) ]aT,%%68VYCBI8k$Q Q.¢ՅmG!M|t;o h(wh-+o ])$5\p-hs/@ǫbY^0K?`uOMl *N:sA?Y4u]#bȴ줖gH+$ l.73ZuG~<'>Qyr󎲖&أ#`A֭.ݟQ ҈-FŮ]ڽ]t^ᖃ9͌$$aXV;|&cD,,aU0Y$t8`8Ӹ|2A8% YAsGrRKFXy9:9A壡dkhzfE4CEr R,,XZI[4ހ56t:q:Vx+)K Y)u6qXN60 X34|c*U'=̺ o-zE,@l\c-J\zwE]KM6>Fa} :}Ǒѽ IYsb !-@'g῕ Xa *s#"V-ArɔsAo l5('KlugA&"ޢ8f+8M0Z]K\R0nq :z$ .0)-\=%}^3Տì"~q)W # yp dѼd0_ԃ WO48EYJ4@#H*ptd6˳ X (Qg;^cw@E1 ɋTɜ}"ԒIj|#Gqfx? 얈Pͯ<$Ю~1yZxǿэ(' }p*V~_ a w"%:!\QT;sTd`B@KҒG]S&,A\ u:Qag{}@_|V0P0@5ZMըo7?]ObSx*=IE]\i8 ~$Q̃)g%A %v@u fo.JwC-'Mjp.)N;0ֵGfND͢wP=`Nw7O','?+fu%mM{-9=lMOek 5!d|F@a Y**l6YwFe 7M  [Uv%{‡[_ȑgZ7]fk֘ p9pmbf$v!N结tqCX(H G|;cSGR^~G\H5;DW_\i\#nVw8kUh` 3=$44D㸙.aO\gs>fhA3~V!qޜ&߻24$nzh Cg=S2:uPk?g\S#l?njSoC2W0lbbٛftX(}WU#} gw%!'YԤ_x*wdY:y%=Ɲơ]K!ݺϭoȇG똖RN_aGK  #Y@y|(֏r5)j^6$$.#<>c}BR" *k{7I8* |r_#0ZIS'RF9t3[Ml_$|h F$K N A%cgY+[uѷyJu`V0kbRP C@ 7d8 5[X+{^{# /ȱcaq7k̍aWC;4@ ]iWGL0t>49Vr4`C|v=,T`E N-jPVps,[J>uTN{5Gj4n]}FNjuLM1y,d` IIbGDH;ѡlR19 { >LKR]`S|1[Af[bslKJvHJԾ5punۯE;H$1U5~m"<D/ 'AxVRor p>I{k| TZkZ5 -2P?L rdŇtQ QPUrx9hCW t!T[я@HacgeZ2t=ӆV6+h.y%i(gᩰ'T\vծnǺsQ'JYNn X/g.<*) a9@:UOљ740㍟\UI[irTZ){Щ3Лb:MUϾl '9#ڱ7'!d"tNoJcۜpOZ>#/1e%hůxsɠ5v0#^j*lRD\6b! : u`tn~xMP1hRosXjaBD[Hj-K]Tss]Iޕ6Hr#n; h5Mhe ~}hg6/9xjTq/nd'O+j7{Z-@#!> 0Ҁ9 3}*EeN0Ziʊ\Ib`'~uu(Ο_iޱ7 BWǡ\VGz3-eCHIx4^l)CRG+ɷŧea*MՇɡc}'ceQ,fAb;R,+؎M$Yz>_F^OHOiKʏwNNIwlf ©-`'Gw/oZ`Iff)'6,}x : ;&^4 b&_UP키ph}.fPKRK(/.Uw#Ԟ+^4ĺ-I $l7ׅqsl֋,%L&h"8wPTv(<'w_g] 1tsIXcr K_J;{mA9Zo{vd1's,@߀ɳ6&h[ƭkp"Yb"f fsZp=G+ϸ4J@9G4%+(F P@'BC[JD4bךdbuXZ qiK02/4Xh3pJS<{nD}XȺww@ cFV$'\H&쏨]~8[kqM@NW ^Ôdm'38t۟s&l O_nb<ry[I(68]=18 \ i76fx:6BūxwCjVa:9fjطҐ+ͦ:k/2gBD\ JfzԫUw( \/#‹ ]@o_js7eWa!f]4EY0j@~xpHDU!sXW~Y̞'Lw{SCO0+?ST\ҙ7iۦb|+Љ,BTKUZ]YnvnԷ59V {H|qnB])Vy4FO'o"mzc,9iLXmw *Ӓ崞P_n*,hJ d`'$-%{xd~M+rxn)vC:%*x[JǤBA`nD3Mj: 笺UsA7qqf'wI8(27nVR4r,BrÈ?o`Li,kTŹ SHX,`,PaIt/Or2{y;wU,Լe+4:l;,~­ã 6n4 "*8Vc2e]|קTvS~5϶w.H x@DZ ل;̟ZxvQZUN!TC+Y0""΅h}2 U⑸ll,UlMQ-6k _ Ǻ,Pb'.VR;x0(W/c`sތpHKP沓̦E% Q̈́Tzkl| _}&~{IvHuQŲU Дjm98$(%2f*NJ٘hWWRt]]`xE&7eV))H뼨+G8gՄղQ+Fk fZ ^#23TdcwY vK9[3j%@%4C{Y/ҕh)ÊPҎstR!Kxpقo~dE r}O)VWU*b[ueQjwzxBհQrJDҰt'Cut^nM_P .Zg_/'bg] +P,sX[$ت9u37)$;*3q)D֭4|[gOx0d~*ouK 3,ƹ{wB4˜+H g&EB_ b_t T^ O5#o@TKuޜ:XLhrML f ff1qGgo'+@~MU-;bkMkSQV:n1\5ľޙŘ*5SJae噂LC6|X7dP( *r ټFtQvɣ';P 5`#/ .op1:g%{c"&c ŧbw,i",FMN;/س4P&jJ:.j-uU@cpC%%;N1;_t+0z5hAK>WVmS&q}XjOfCpߡgX/) V]VW V|$Ώ&d%,.ᐑPU-sNSZ,?@4 PNB$w-cty4 ӧc z|)4[sRfιѱ!ymuԢ[[Ek!ڏ_XpCN : }.,ƀٯaJ?Ƚ>Vek!MTh #ۤa6Ll:ι'M9Jȗ~y΢oēJxcHA\5Md,#%#1%~_2M`IW  jO@(6~| |tL% N} ʦ ـ%>:EbLLY{jc)<f8ۀo_a3CNFKઋm5FC b"p FBuXu%ľUH_OЂh;zBu2JqZ$ Zg]r8J*Xz7Ω*(μzPi&>KG&ɒ@ތBS ˺*=Xq 2b68dRKޯ.$` 1٘}g67t@Gy*) VC0eO&q,/ .mzΆ*rƽ=vq\V .Zaɕ 0SE*y\ \M>n54(C0;E_Ob~8YWL+t*y`w(8:yyB*}h_ِfK;dU~+=İ*0;ׅᡀ՞5aIxS;h"z^Ԟ&tL.B|uPdu7t"*]هW0/Hǣ>kgH4et%Xm:@iugM1Q=N"plY[MoݩU^"iiX6WV?a;j%( a =C4QR{YZbj7ɓ[Kʻ~-WA)q9G*);ˣL1Le SfMuGM;" \?ehsuSd5^PҶCpxdW$Mn)_R1=sX:+D֐ˆ""u 4P}5@W#^UDv;2sҢԭaIA>>,pSP`: jrAͽ2}>l9dnP\X`֟c.b=d׫7*XlF_q@ݪ6zd r5E0WOj6+ZG9(֫)+&Hx<>3As.?1㺐m q:֋u*|NAK.X) (Co$`pnG ??r}LIjrw[k VscEQS֚b)\J:Yv3BS5䈓_\s?&::ϣ9z֚X*|rm/:E6W~GуIK*+X475'O%Q~ds{҅>PÈnX9u+k/N3Td0sV.vۍjSB,ޞnjJe{'ti \Yٜ]@ =98 D@4N_v'-yn8#B%÷ת Ax6^L#@HG'Iͫ_yBV3:%5 @ bԩDV٨,QlT%dΣ{I:fn4{vUdQ9< OclMahz[w`f$Ul0ca6u!emt$v`skdrk.Pd㮳ͥ>P{fVԅ10uC2A Яpn6+g= {V)jaο[6S˦@ mpx{},5f@}%+oWimQRV$GQy)d wIoR&Ḱ.%ό)8z m44k䀻5Cyq_}^eW~<5ʡ ,;o^ۖ5%pڕx5T̾ܜI/%4DF#tv Ϸ$}oe I4B.~Ώ~/{-Yp{\O]zq2+RYR^f<" tyб!|=:;خ7 A1M7 x_OdVڍƚPJ^mv=TMuإ‚nӀ{&?J1WV?]|('fni%aw-8>>Zd]*a$.HooI1#PӶh G9Xws@䀸+|dž?{YhGsV~p>W52Qh2N/b3ngSMykNԇhQ&ʧy욇}McѮLb-49 ޣɚ ݬj`>˵3:Ρ=4NUr6I{<`,*fIN& 3PiǑz>+rc{215L1geQ-nk} sA^bX}I1%aN j2(O8.ϑ85TfiLDw˥bh{TĮdk?0Dʓ{Xpr3ͱ)>b7>t I,+f|m EiffʕQ8y! !kT 83kȥRI f/ԃ.@ʽ *~8L39e7#T`93+gEaD.RJFEm2iގ8XւAnv\W* k?ƺh#{pRՕ?]v,WI9D8%%\˽*J93~GH{f@1mJ{nb-nafło39XQBm4[I9i=&kGkj[)1d){⼜LpC~ ,Dxae%/#ܡk">P(ESaL} pȚ(Y RmŬnԿhIJ6(g=>$$BQԖ >T\*WS!e-5ā-"qvL1m6ѕ(/Co/OTLd^ 6EbfYftM [K)Nzι ak=k ;' +0zP%f,[gT2]̹*Q[VG%q{m@28Ծ`BJ4eeMwcҲ CKy.s҅vC ezYm$HKC8Ř{59~b`\x[ }˩ $B՘yk'rq :]Cȍ_uiV}장ˎmhfy~\ n8\g{WJqF25Dsm2\Vxq?IGY ,_ L߈QU8}z;C?9Ǹ=?D(0TҸMp+Tl!cV`17,K;1 [߲0z&ʷOnU^PC0Ut 8Y\4L4v"|Na`N(=zGe` &ǟtÔsc̷lkhjڲ%)WX,ч;{ ]W5Ze*1UXHBl66mXd~76Gz6Z5=4R'4ۣZ߯Ue{^_}8>Y?ϒK]N)$` sV,x?Z\Ü_X.Y=S`jJ%]R֖<»GY,n`SA1Nl& 0jfQ5sbc0/qCQN)ПXp/9]c0s 3/H⌷rYXݿ>EV-^Nn0-`"zTGt:MW ZxV0wi 28NAz0޵pDZ~hݔ(%ʯ;x㰷j/.PF(w.Gg?E ~6{;UI~QڥV#dluC \rHVa_ruh,]Jߴ]r(j/a ]oΆCo|V3-{iȮz:ν!w1z `ixo\+c#h翚Dh=qm:5I8}ETu\6 b=z1cH׮e4P]GHb3a>zJB NfKIC?U ͋ 0LsաpB$;Oz\R?82"k"0j Xq;޸Qr9Wl(\TnfLWA!. .B4s&^6mu:=h&6T*\rndH3M^8.ph,~shPorVu\#; p[DٷN}E$l2uGnNM3U[|G7S}k<52;iy1} ]Ud%8-,(84a =!co csԋ~G0 gf/CQռާbMLu16PG/ADJ^&qGUXeX>fQa!=Mz݁L14mDj"ڛr7ܧr[k%2DZ9_y&Ŕ?o-hq-k`$ dNB/-THr'(eml"€u`)cSpkTuz]{ym?r5,dp $X!ϒ]).FvNE샤Y;y`՝hXŵ U D)+2~RBnm/-𠻖\;r!#'u)bjӪJ)5&g&AݣSԽYIo n Q"K!U+}QtA$j|>O$|LT\aRzſzVX3L}EmkBO68%AJ+_P䁍d"g x ]FzM P ZUZeꦗ_x1D?zr6*{|ii}j::3 N<ܷlʦZq#1E֧$ߥUSg{W9tv_h8!Ki [J\]i}W_!}s6`ŀ]cYɵQiGl쨼ur.C?Sʧ9U3YʢWfN`7[UW6Urb1(exv;30~I %ԗƘ_jw2MQyqoFfgV`0?@Ϲ˸t{?!6n@#.d 2?Y`Ň]]NjPn-D8#SW W/ \a\{ T>b3V!}SJΡgaJ.ORM85L 4bN`ȗ⏞\Qft"2Bpl9V+z+}UOݭ`%pn*W7%W3' IҤ*=;tvJ#r81f63E.9MDґS}_T%G^V?>4ىXeжSiZ]OH̀ŀNMK _};f -KnRP@x7[h5凃), م|K.k kdw'ȕj3 4w`zB6p G+wO {Y} >7\)>i7PN왨K2M -m]#>LHm|X_;r߇΅}zl¹SD(ړ{RvEpԷ'ZX832Y`29=t (Z7:0m.fVaRIK;)uzॎ`"-9,% Qjaai G7 HH:E_eK&mbB̉:u`߁1i;fxֿ)9V)Yހ^a0p_; hGJq(;(R⌆Haء(1٠3|vώxQY^P]J¿a! ⑬ןH2Х 4FQ5T6v'*aۆeEC (ƷcG"Җ^vRQek/̰~6?7nOdUyteqՑNpgl49Y:YzPVC5S}DkJn'ETZi)F_ ezg#= ⷕ@|9 jh <N~4"Œs>L Td4opaMj+Հ݋]}5Ncgt~_g`٭7^Luʠnyi~EpċH5;k,ss#Ƶd7,oCU>vo MďG><+!*.iͤdp߷# 6+v7؜RYԽ6 ,Jg+,=XE眰 tyeUX)ZZ,o^/Hw2)r, CY@dls;aC}6D^ub*/Ij7ը[v!bDIo$DDj`o j)_os\<4OT1WcMy3 ];}klU)77G}D:8]k櫆Xvk6I? ]Hc(5 n2}׵0j)BY%N3&3{Ci,R?VҔQm3Х!YP;Y =A:K@׻ nBILߵ,w;ҿsq[Ewf7jM~QDS2n\8yY*$֕PJ*z27J.ę{^?:D93$"'E)TαBт?A(Kn v61Ǻt&OKC5%+.3r4▵M4(׾)9鸱fc \07>:Qtchj.pV  u{IJv>H2OLi 8,%)s/Wѱ'1 $v $oBɰMDXN2)"#bx C~ӤVwL%ͳlu%Z4)2buP~Zz^%">ِ!Uи; Kki4F-,0Ⱥlʽ&9c)#|ʦq#+;z#e+x_ l{i64myJ 4Rүi31ljLjQm嵬6!^*S{Ԫ"G%`CH^c‚`~XZ ޜ4 1ᨓFlz.u K(0Ƭr.x%NYZ<")βBK;.thsµ\RӃ)? !yN[4$a.WV3IkG=y"vWwH[E\8ba nӣO+TLf-`Lh۫^tx%0UJphJS.PP[9S2w}P}jGg[]4.Bz;7ZWDoճjb1XWc7#6wײ8r|=8@/҅l.ݴ(@!|C8Q N[VK,#&}+\3*Zf:?x(Xh۟Km>I?S&l¹S%)+1v v=^5 @=j\4u0! \ ՞ JTl$r@.tf](%D͊C2nd9?hi_:(VqmScA+𝳺#UJ#yܬaH?uu42=RxcÐ5T wٓZN̤z$>#6xyLIaʹ*ޖ㮶L{7^1 8D%w<@q&_TY;9gYCpq4#m7һ;].|q.cS>>•^i;뛉Pg-3UtE0nu-/<|U y'5@^2#b, x KH;D_#W$áR#;m7čl4Jt|M$q@~.QLvE* ǎh+݈INr܌vH=~U"HO7J}jO VQ:!`{z}]RDGaJ 3ktH`i+~zY%#{f4EmZVK8et%Iy>pC&y:(a2O߀al/|"f}F:ZPW5c.-}SN(Bb /CJ7c}bB/sNL3鵝_%e:p l!F{>GK6l`\jKRF9@L^SThgDBG7 "RoCV=")?`SCk5CxBJ Ɠ?-2rOdu{ob%=b< zc? D͔d&T3`oG%8f>fbP颡mǢu/@x)F+úUN6Gja9M`,gcWs))XU9e1x rOP!8Pwў%FcMCvs Wpbh]CiKEĄ#hI႘F>@>6393e*҂xԠաRYa4`M<6 ]C+(ђ:WHJdɴ&gys#&a}'WaNB?B%aZ?RFk&7<il @Eni NOhbqOe &@GS]N=;-*f5e &Ř"F$\wݜ:yhZ-"I—Dj*hmI289BM^8joj֤ 8f2@JT`qg# J#LZ5 =J,[0lOP1-D|`|Oa9UPP5hu5 m|ĶaM]l0mq HcdEO#|GԊIӄ.CVu'(wj4K$} rr됻uR6W'xBqft-HsEWf]:终v~Tv+cE4Lqj'n)Zc(oY`l QRPgEt z +Ux]GiA絤POtdrD. Z-'JW [m{ӡ5Wt#''.SK^P)v7D{Wš]}1sΘtotݚ. D]ieDR:hA1٬k7M{6K^Kܡ)B>UK͡XVI͂;C9MF`gqi;Wۉ]!,Xy[dI O()jG5Jjׯ,,yqyNUy"]<"@9Ē*@p8nPCd XƧ/GmWK)Kǁf?H9=m2U#[ӻuYiR'5qtݛk8,aZN@֘2LęA^ySФ7\p6ӔQ C|хasaC"q?[0F2  @j'3 4!ΫL8@TV%|29_1tL/. ;=] cO}1¤DW@EH͆-/RYClUrkot0:6F6}r P߄߯ڝqAdWG`LbF3.7J 6 nf+!5\Ȃc3*?F奂x5aIGruCC˥+a^0R?deKg.CBxx/gʫ㡼pƽUiLǟs~V.~|p` s;0iY9VIQNsԹq1nGMɣF ᰀÌ) M{sywKHi>K?ᆶC} *8Dl[Χ*f |?齸}5iBs}XШQaM10Ǩo&Fցc(3ZȂa}x$@ZACR<@ʁ;J^2ø~QF,/HEAe#I3%e>Zc]+M6H PV,`zc,k` KzFnJMeo2ӛjEa7"MNϲg^ءZN<4ɜB+ DS6xl܆t)).YbGQ'7ssLY[4 !AVc co#YS06 mxQ{ռiEX6Yo'U60SD5AttwdKk|TC-cQHd )V)Z߬Aa(ȄLO`*͌((%P폽=ß"$۸ޯ1y++^ɌR% 5'dT\FNt"tΟZϧa'iAޥ֠=)P5 G;Z2Kc\~ڟb\1+pGp;Zt|/ں \#cujҪڋ7bOߌ(!.cX\˳2R`a T`È5sRO1.Tm#=? à55 ue[m[~͹1hT]g WZzT$8ȇl*aŔTg~V,j\Xt$J1(UQqB*yهΫL,ytްNFlDܮ}zF#{F⛡b%1D9DŽ1iny1W)AӞ{s%.T@Ol J Eq1gZu㋉Jo%]No{e3j/&T'ӰM$[7GQ5ȂE4vĘAc΄joF =^ $0Fσpv 'L'1IWA@8dyW/6zI: "uA bJ^)ę/`w3,YE@$>znkgn4Kj,%i,)45WږS^$T`ާcsLhOpHgDY_Ҥlq?C5n_)=R}MagqrqVwZu,6yWFcOm.$srX- c霢[jRv#.& /n&2cƘU_( Hb`H׋ܪf1dYQ̰t9gv^7)_{3Iid{TX֚SC'QEQߪ Sc߈h]a<|L+Ba^Ԯ<NnvqWU`%yvo[+{\1얾rn+jP*v"n3,'>;\w{MԚD 2ӾΎxIiCņKCB`}I0`X69O9Q:n8chG]vZfaD6nF!Z o,R4NQOv%]YϚ-Dixyۙw M`BOk"/fP튶 z3ZDؖ yA)!>_03XRuODPCb2]/ i¤dԹϻ Ɯ[;uտ6!B ϙSs͍U,bٱѫv'!Xw"3}4,%%{eq^;fd(:Ί2ȻSh`ГS&9X6߮1' i(_!s$|)C#Ϛ>.w:;Gu[}&I7젉}]M6(k2S5xUִ/fUr]G AP,;eY|2[9&Ղ>]_Žc#"451Ozz;yn$%ҫ'( $'MN>jV8p^m}1 2+IגkTJt t2Kׄ$Mg*=r&RBa[ D9OCJrmkQ"ݵ'6[( ȐiWxGT= &$G9[a> 8mSKp?i7 hףn-<+Okaݴb pӄNȢtxYVyrޯSJ5J剉3BQ6/ՙ;;qB4,>S>D]m b9o9_̰6s,%`oFh] f`Ux<|Nӫ @V=f@ ]g˼ &_o%ҶA^<slVtmo|nGñ~BLmcն{灜׉'7;e$p\ivgO,-3ÿSjn%Qнx%pF{^ƺmvOL- C>y0E3K 7?ng[vX2> zyzqpF,8K ]L]$rʪe0+ Bfě2w&o`_A)01\+/ϋR*mk}wc$DՒ+?9ǙA='4EV2Jy=>o`zI6 wQв̡8H0Y:>qx70g?>itK^@fϝDQ`[q`WoDm*.6!5NGt:Ő]\(AJ#o?1 X徒C]K%sv*}| +HByVL/NPTözs-13Lyn56%ot/{c.;2ًg#*p Sڟ/_4Lt\+[Qꯔz!ʒ !_P[*WyZ hV ]=SߴY8~kp_a6djl96l}-܆\ILd߶;4S@Dc/q[V#'`3=rG)+=8?s[uNd\V%FD1T}݋n߆boA>C5C +HMaNBE|%D Z#܏mc6pG;;2eGrZٔ\ _һH/Ěs!wEi >YUA0 )͠`B֏ʗUL׬M+M"]p?j ^'|5雃 NM&:ؗ3G g>-OXϻ:N ns<;:] ޮʆU%&5E"_x[ͦҀ64cr Ch4 rh##l6|26a c{ hye2Yќ\ N(཭X-} Î?yY8TwNK;eGZcJqU_p ڴ8"g}K7s FkfY䲳zZ % Zx׳éQBg)tڸ!gQqYaZ8Bf ]aO.I; ݯ(~PxOMs&{lMպ| C ;GqG[.h/AK[_ TA!q," ~rI_>KZ$&4dɕ_=gRKâ FFPTk4 Yƕ7_96)K3'n (c6/_x9GkɁqӶW_XiWW$2o Ct/?j_bC*30햾K3Á4zIti$TuTAG@v8ICDb mx gX%]k5P47 <~ީD'چԚ\)K7H_huU/j 1_+)PG|9Xb/ +-Վ WhťiJCV~˃n"*A&D;b.[T\\a"2ҿ`^ȏib ,)4u lZf!i%e%_R Y >t䩋*J-f_![ rfy\.Z=)jUGa=C>H-5d#?2Hm6YV-s=v38C&:w]r>O0$u97A^I7' ޳\eUim' pd$*!Ėٲ1IH5T; El};YiaKH4s~bC%`[Y!W:mw~/L>%q9̦j_whpS&5 o3=(GuRn"9_MvaG]q<ٍܿwJ?aRӁ<րbp B"ÛwkF F?1rhmQ韶F#2Qb8}k:$ƫK`Zz4A)JUt/;"JjQ1Lq͛8SUB: ,y}>W͊нm.^}icԣ_A}&%B"?h .=r')qHc>g;l@61-*`}G6Kx q WGF8Jdϐ{8K{hStר&Kn_ 6aqet.V_h0o@nODJtnR4_p]86b5~vDX,&G؄ٓ-K7,&$Ru$ihtVDhaApisO/ k}Li8 V\s@FU8:]sxk601$;{U?~96A0HJ6cK0Ԯ*"3W FĂK=g$L{urS䭣wea t&) "ZkqP&2VdX¥8o- L_TwsG TauZ j_)lq\>/(;]ò\7946?< ~o_"k'- z! H.cE|)9wPk񕓱c9 ?¹]m{(<{rJk75-.GN&QIixfRBWy~&s^mR/@\k0Z"cJͪWw ͺ!|1IIۯ=oHu1f9?{hdڛ+[9d-R{MkJ-xJ.&+*Scn?7qVXsK)\uܣ4D8_Y&Rɂ'ƨYʌm+o푏G69E{M݌y8ٝYzu(dx1  hUS!ލ 1l=|JPر <[g^]=H:6;]G؀,(;@~<\!JFza4P &'_n3mYW8.q|v |ӯc7 ?x%``",YsuV3HU6Z˸]P4fїln8?0CqCUކ';{l絬6-`lxTлLrT )c }Ұm3fFmN灆"r~ 6AB@eӋo4H37;%9ZY7P{UvJYɻO\Sq>SIw2 vDwQ@pTDP#ځ%}.iPNRȍVr7=J,7`z^a6'1[iZ޹[u[$cOc԰>+KB"fүnJ %r-ތmav'.٦2ȚCtf},R ~tfL;q i:giUa5]>pԩٙ<+uul_LuBV b5J0Kdtpڽo,;pG,uA[x\菌%X(+? >Ğ7]X=5^{',n B@HmYE;xWw5C|H\kۢn)'.1U a&b3kQd Ju#H]!Zo[G2[a& D PiV8a|Gdځ/?J  2E@i:%m,0QJI26x8b| ԳY >XSXOSevUQʨНM?DG.5Jߝ~%'$(.ҺHcvX'"ySaOJbG@>}c_3$pĤ$c^z[tTLHcl );m)x4J1@7gwT_R lg\Wuׂ22\MeBbb{]/"€8uvq?$'r ҁZm*䪭$!k9PCBƘ=H&I3PEK7VXڌRU\2RC1N5EZ3Q*+Ct,}Bu՗.Vrew2 <]bTZ''o~IWJCuv[ Y*xJ}֫~Lhøj10? \E `z.mep `*@>6([YmsD7x0YZђ>ЩmsHywiMKd,pyZ#w&+B|#_߸NLQlbbyh8K~c>w1+i QmTAY5=y:e$]܍~7pDubpilJ1Uw )~mߑZCdh)ѥS5ǘв喕mΪpl=Wk<=v@!i7Vd>f0 )/ۨy8x -)sZy æxXlowm$w.0ӽ,l{E0vPvZmٕ@68 u7O,ߙ[f.#݉< `Q{nᆞ>_5!R|,/CiukPc(% Ʉ5SXƳ9\7( R4_B,]NK@ڦXz/fj.l #Ŏ5CMY'4ٰZSW(N/꧈H ,Oa ; /L A%^1Ƒ= b0ts_+@H8Qо,U c-Y]0c-@7m±DCv7:RxU8xJ5]Sc2 A.2oO=):N_zWyq&j (^K ``Pe(h~y\`K|k?1ey ~u>66SF0  %q'ܪ\,+ڹρـ2,ibNC0 b$NK=8Hi׺޺[oUF)4Vy;_DO j(ftER"Oaؚc&(_ 5R߰"眃YC;ΎWس 0Gr0 `_CIEݤD6[C= T$X[EيߌݻѺ'vNiӆBNyu|+$I",* HG- =A8ixɝoC1v"IÄL'`˥+uJa`vk{~9ڽب)obȢk`cB-KI(X|RvLWpO'z)9I՗uʶXC# )^#\^Rk:}]TqqcN.J4gxp,%y&7w2$.ЃX%>f Ar$o.>R.V~nX>S}ʖbǦrSQ, aVYˁy٦0-vzk^}6;n.`:6ouN уCOt 4*чF^Ostk ~h瑬`=WLfp4ڕp{(J<q?ڊ q>|yo9v1:X/ׯi6Q4DzFtTF7&aI ?StfM)ct>Цdjd/lP4:W1!|e|uY-!F&,T-s<4=|WjC #Y8]vcoCd4 5howgWN 7LvFd K!BMիphtyDsF#ҚH˯.M-!4O2YY*=%rHJ* , Q4ؾ݈I$D4x8fB;{(ɋ7*u;Y5I[x:.吰k,6w$/<04 gwJ =Kr|4:W>v Yt6Bszb[:Iw׵F/$2Z3Dғt%ck1ƥNBԴctO jy~e`{@Yvb^Ux /(by6xs,[ u1@V2u _UW-?،ƅ 2@@YE+ݒt7/#b ߺ ؾb }VCSApM(cO,{Ukn^E1)Bhl(e]: n28\\p[Q9we˹ 6#Ij+>^ά؀AE ǝA4R D-*&V-SH{VVyWHM'w-ʅim63ŤRH C4'/՘!TZWDfce^oS+yR{yL!f(J|jM&h*KaZp٦χq]ƋJUݑkz5}qL#gԌLRP&7 潁^3I' Y2VQg [wLT40qȂd_7< $4[QԜ4hQn;DnkI>Dlh*m}r\,: ďtp𹅔] πwbfм#Y^QTcCXz{%vZ>mXHA'EU=&⒇ܩ saA^/] c~kt1Fj"HG1/}(FTQwn ~q&\ w@5F(QuyxsY ҴYEd.!=)}~x7AztWz[6:H5H )i:W7tŖ‘1ŝJ"gH*_8E<&> Ŧ)?ݷ!j}R(h GMZ#e3O3nW%znjlׅ.񫲂)Mܽ7D508ԋqgVԄ{B,?Sػ`E{4a^Te^x06PaũO}k`#} )B2ahĬ* A"1&Sε6RgȈ}MS?m*w0v'*u.ÅE PPn1o⹾pO3/kSy!B/!(T0T79W+-z^U @h1+!U\: ;ݬ1e1vj*| g   8=p݋j17FE* W7߫\Vӭę[VT\<闚 ЯwTYjd:dLBsBա땪[DнCTRp6Fp.k@ɔdOlms%H^lkݘ2X=Qt GUiB7B^*a؇!Ibem7Wi}z]ZkZ>qkY5Z\\܌y>5Kd# )]dݤKfgWrSNb&0(`Fg-n@i.旃cZٵz |"#<+2ӅC=C.+v%os[aMNi.,U2ov) Dz(p}!Y]Ȋ1gaQ>Hs|^Dzr)CWMkSԀF+A(4nIC 3IUƖO9Mݳ} Xr>I[|adQ {sO?a9 sX@݁a%oV& Sy1}D˚ʜA`Rm?nŊ8hlNA<)wqH`l2L0q}&ejX\lX)T_SoNZSe[C\79"w`dKϷZ0cgh(HgZn =ae)Nܘ1|Î:0Ae\h43MD.1>d\opZe =(^Ar6ˇ/F~$@|*g)&enLG&Yg:.'(aYuC'kDPozUwY@PwwIlV*H( R(W0l#<G7`ꀳL%[i- bq0fP%7i4IfVx__/KQbv59cTt3Q!B`'oRI0w'+jYǐ} Xn %xз==dyX{ed쫟OO{]!y$ #h d N4mP f:~d(Q? &7ɖz/r5!L|nR 0Un"<K8x&Ze7)r' u&՛!w-qڼ~(uۻk!H?~U߉눎VzVM7xoO;JZЗGl{7fq}C /hh%E ps<#8sr0ii&BϠaGq5_o^J,,ϥ>>`6&.aDkI -(!%V&ôr>E確$u}j0es mcVkL=DJ*R! +׉Sy` v,$7MUe_Ob940-3܋US Jb69yCja?h?v'q[,׾"XTCO4aڗl_s>E8~OrL=5 ,~4(A%֩[1׺A92,DWm׳ %#Q*F6|u{ *RG|# l^Y Z "]Ӆݕ}PJh@uF?+z(B+l2 b:Ovh;Gи|Q~.^([qwzԛI9[$TqPBNy'@. =+`o-\{=+20l,I_SRAzgO7HhZ,zRW U Eۅ'iY3oNkd2O=~9~0dX z< CMqx :8N0yv(e8U\72 mv% \J ̒Qtl~Qn.Bl Y([U^xn3~0N"% H$ ^h jep(wu/Come]Yp88ܮnX<"9C. k͇@|(N#~Rg`{deYzjj8V!ރg+# BfmSICڣIˍ}]9LELLZ`p؞BÓŽY'YHR:;|4 acWz%TaU\E mH+d8 ^&%07#'ɉUm%3ꄱyTƜF}*lJx&LEKLYrj_`~l_p!Xġ[ i,yu|7le3pOxlBC'`rw@)VX*:d `N*\Mr+0ljU"RG%i᝹4W4ohR RRŭ/5)WźU5AQPU/ҟ%`U2gO ڏX#@2x< F$AYte%x6٥ƕs\!G՘aqnUXbmLۏ0zSD'IH=UͶ~E=b}෣y8=@ƹyTLu6K$e˅2E|e]=fkFm5r˦el{b]6牻)8fGľiPsV avi3۽QQML|$UT 4d$H% 9e*s.T@<ټ%fc5"!~dĞV f8IG2ř|Goɰӎyo:#*Z)^ѱQ4,*!Nh-<F,!>\Y4;ؿa$޴mU["@JpiƳڜAH/얆.c&(;0C`Ӯ#nkHآ p &'z&G STO֊险+̬/LMXrp)󢎚] CgMOR01~7j +e~Yy1:d[Xc.t}VeCOҿ62zq.H'|T Dg>+醚 ju g\翟`Yd3ͅ+WHҎHuafjCk2K ,em}_a=Bw[>J>3l\I=^zLwRҺA3klW ̸-.U>5+\?A٦n]ؑQ1?Q"Ga> 12 Zc"@)͉'N.KcN_R>I=5р a-n"a3(֊8.Jty qJºZX gC= as.POSIXct("1998-01-01") & nasa$lat >= 20 & nasa$lat <= 40 & nasa$long >= -80 & nasa$long <= -60, ] temp.gly <- glyphs(nasaLate, "long", "day", "lat", "surftemp", height = 2.5) p_(ggplot2::ggplot(temp.gly, ggplot2::aes(gx, gy, group = gid)) + add_ref_lines(temp.gly, color = "grey90") + add_ref_boxes(temp.gly, color = "grey90") + ggplot2::geom_path() + ggplot2::theme_bw() + ggplot2::labs(x = "", y = "")) } \author{ Di Cook, Heike Hofmann, Hadley Wickham } GGally/man/ggally_autopoint.Rd0000644000176200001440000000263414526730006016064 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/gg-plots.R \name{ggally_autopoint} \alias{ggally_autopoint} \alias{ggally_autopointDiag} \title{Scatterplot for continuous and categorical variables} \usage{ ggally_autopoint(data, mapping, ...) ggally_autopointDiag(data, mapping, ...) } \arguments{ \item{data}{data set using} \item{mapping}{aesthetics being used} \item{...}{other arguments passed to \code{\link[ggforce]{geom_autopoint}(...)}} } \description{ Make scatterplots compatible with both continuous and categorical variables using \code{\link[ggforce]{geom_autopoint}} from package \pkg{ggforce}. } \examples{ # Small function to display plots only if it's interactive p_ <- GGally::print_if_interactive data(tips) p_(ggally_autopoint(tips, mapping = aes(x = tip, y = total_bill))) p_(ggally_autopoint(tips, mapping = aes(x = tip, y = sex))) p_(ggally_autopoint(tips, mapping = aes(x = smoker, y = sex))) p_(ggally_autopoint(tips, mapping = aes(x = smoker, y = sex, color = day))) p_(ggally_autopoint(tips, mapping = aes(x = smoker, y = sex), size = 8)) p_(ggally_autopoint(tips, mapping = aes(x = smoker, y = sex), alpha = .9)) p_(ggpairs( tips, mapping = aes(colour = sex), upper = list(discrete = "autopoint", combo = "autopoint", continuous = "autopoint"), diag = list(discrete = "autopointDiag", continuous = "autopointDiag") )) } \author{ Joseph Larmarange } \keyword{hplot} GGally/man/ggally_na.Rd0000644000176200001440000000116713665760216014451 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/gg-plots.R \name{ggally_na} \alias{ggally_na} \alias{ggally_naDiag} \title{NA plot} \usage{ ggally_na(data = NULL, mapping = NULL, size = 10, color = "grey20", ...) ggally_naDiag(...) } \arguments{ \item{data}{ignored} \item{mapping}{ignored} \item{size}{size of the geom_text 'NA'} \item{color}{color of the geom_text 'NA'} \item{...}{other arguments sent to geom_text} } \description{ Draws a large \code{NA} in the middle of the plotting area. This plot is useful when all X or Y data is \code{NA} } \author{ Barret Schloerke } \keyword{hplot} GGally/man/ggally_points.Rd0000644000176200001440000000145614527265752015373 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/gg-plots.R \name{ggally_points} \alias{ggally_points} \title{Scatter plot} \usage{ ggally_points(data, mapping, ...) } \arguments{ \item{data}{data set using} \item{mapping}{aesthetics being used} \item{...}{other arguments are sent to geom_point} } \description{ Make a scatter plot with a given data set. } \examples{ # Small function to display plots only if it's interactive p_ <- GGally::print_if_interactive data(mtcars) p_(ggally_points(mtcars, mapping = ggplot2::aes(disp, hp))) p_(ggally_points(mtcars, mapping = ggplot2::aes(disp, hp))) p_(ggally_points( mtcars, mapping = ggplot2::aes( x = disp, y = hp, color = as.factor(cyl), size = gear ) )) } \author{ Barret Schloerke } \keyword{hplot} GGally/man/ggally_crosstable.Rd0000644000176200001440000000372014526730006016200 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/ggally_cross.R \name{ggally_crosstable} \alias{ggally_crosstable} \title{Display a cross-tabulated table} \usage{ ggally_crosstable( data, mapping, cells = c("observed", "prop", "row.prop", "col.prop", "expected", "resid", "std.resid"), fill = c("none", "std.resid", "resid"), ..., geom_tile_args = list(colour = "grey50") ) } \arguments{ \item{data}{data set using} \item{mapping}{aesthetics being used} \item{cells}{Which statistic should be displayed in table cells?} \item{fill}{Which statistic should be used for filling table cells?} \item{...}{other arguments passed to \code{\link[ggplot2]{geom_text}(...)}} \item{geom_tile_args}{other arguments passed to \code{\link[ggplot2]{geom_tile}(...)}} } \description{ \code{ggally_crosstable} is a variation of \code{\link{ggally_table}} with few modifications: (i) table cells are drawn; (ii) x and y axis are not expanded (and therefore are not aligned with other \code{ggally_*} plots); (iii) content and fill of cells can be easily controlled with dedicated arguments. } \examples{ # Small function to display plots only if it's interactive p_ <- GGally::print_if_interactive data(tips) # differences with ggally_table() p_(ggally_table(tips, mapping = aes(x = day, y = time))) p_(ggally_crosstable(tips, mapping = aes(x = day, y = time))) # display column proportions p_(ggally_crosstable(tips, mapping = aes(x = day, y = sex), cells = "col.prop")) # display row proportions p_(ggally_crosstable(tips, mapping = aes(x = day, y = sex), cells = "row.prop")) # change size of text p_(ggally_crosstable(tips, mapping = aes(x = day, y = sex), size = 8)) # fill cells with standardized residuals p_(ggally_crosstable(tips, mapping = aes(x = day, y = sex), fill = "std.resid")) # change scale for fill p_(ggally_crosstable(tips, mapping = aes(x = day, y = sex), fill = "std.resid") + scale_fill_steps2(breaks = c(-2, 0, 2), show.limits = TRUE)) } GGally/man/ggally_statistic.Rd0000644000176200001440000000413713665760216016062 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/gg-plots.R \name{ggally_statistic} \alias{ggally_statistic} \title{Generalized text display} \usage{ ggally_statistic( data, mapping, text_fn, title, na.rm = NA, display_grid = FALSE, justify_labels = "right", justify_text = "left", sep = ": ", family = "mono", title_args = list(), group_args = list(), align_percent = 0.5, title_hjust = 0.5, group_hjust = 0.5 ) } \arguments{ \item{data}{data set using} \item{mapping}{aesthetics being used} \item{text_fn}{function that takes in \code{x} and \code{y} and returns a text string} \item{title}{title text to be displayed} \item{na.rm}{logical value which determines if \code{NA} values are removed. If \code{TRUE}, no warning message will be displayed.} \item{display_grid}{if \code{TRUE}, display aligned panel grid lines. If \code{FALSE} (default), display a thin panel border.} \item{justify_labels}{\code{justify} argument supplied when \code{\link[base]{format}}ting the labels} \item{justify_text}{\code{justify} argument supplied when \code{\link[base]{format}}ting the returned \code{text_fn(x, y)} values} \item{sep}{separation value to be placed between the labels and text} \item{family}{font family used when displaying all text. This value will be set in \code{title_args} or \code{group_args} if no \code{family} value exists. By using \code{"mono"}, groups will align with each other.} \item{title_args}{arguments being supplied to the title's \code{\link[ggplot2]{geom_text}()}} \item{group_args}{arguments being supplied to the split-by-color group's \code{\link[ggplot2]{geom_text}()}} \item{align_percent}{relative align position of the text. When \code{title_hjust = 0.5} and \code{group_hjust = 0.5}, this should not be needed to be set.} \item{title_hjust, group_hjust}{\code{hjust} sent to \code{\link[ggplot2]{geom_text}()} for the title and group values respectively. Any \code{hjust} value supplied in \code{title_args} or \code{group_args} will take precedence.} } \description{ Generalized text display } \seealso{ \code{\link{ggally_cor}} } GGally/man/ggcoef.Rd0000644000176200001440000000524614527407231013741 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/ggcoef.R \name{ggcoef} \alias{ggcoef} \title{Model coefficients with \pkg{broom} and \pkg{ggplot2}} \usage{ ggcoef( x, mapping = aes(!!as.name("estimate"), !!as.name("term")), conf.int = TRUE, conf.level = 0.95, exponentiate = FALSE, exclude_intercept = FALSE, vline = TRUE, vline_intercept = "auto", vline_color = "gray50", vline_linetype = "dotted", vline_size = 1, errorbar_color = "gray25", errorbar_height = 0, errorbar_linetype = "solid", errorbar_size = 0.5, sort = c("none", "ascending", "descending"), ... ) } \arguments{ \item{x}{a model object to be tidied with \code{\link[broom:reexports]{broom::tidy()}} or a data frame (see Details)} \item{mapping}{default aesthetic mapping} \item{conf.int}{display confidence intervals as error bars?} \item{conf.level}{level of confidence intervals (passed to \code{\link[broom:reexports]{broom::tidy()}} if \code{x} is not a data frame)} \item{exponentiate}{if \code{TRUE}, x-axis will be logarithmic (also passed to \code{\link[broom:reexports]{broom::tidy()}} if \code{x} is not a data frame)} \item{exclude_intercept}{should the intercept be excluded from the plot?} \item{vline}{print a vertical line?} \item{vline_intercept}{\code{xintercept} for the vertical line. \code{"auto"} for \code{x = 0} (or \code{x = 1} if \code{exponentiate} is \code{TRUE})} \item{vline_color}{color of the vertical line} \item{vline_linetype}{line type of the vertical line} \item{vline_size}{size of the vertical line} \item{errorbar_color}{color of the error bars} \item{errorbar_height}{height of the error bars} \item{errorbar_linetype}{line type of the error bars} \item{errorbar_size}{size of the error bars} \item{sort}{\code{"none"} (default) do not sort, \code{"ascending"} sort by increasing coefficient value, or \code{"descending"} sort by decreasing coefficient value} \item{...}{additional arguments sent to \code{\link[ggplot2:geom_point]{ggplot2::geom_point()}}} } \description{ Plot the coefficients of a model with \pkg{broom} and \pkg{ggplot2}. For an updated and improved version, see \code{\link[=ggcoef_model]{ggcoef_model()}}. } \examples{ # Small function to display plots only if it's interactive p_ <- GGally::print_if_interactive library(broom) reg <- lm(Sepal.Length ~ Sepal.Width + Petal.Length + Petal.Width, data = iris) p_(ggcoef(reg)) \donttest{ d <- as.data.frame(Titanic) reg2 <- glm(Survived ~ Sex + Age + Class, family = binomial, data = d, weights = d$Freq) ggcoef(reg2, exponentiate = TRUE) ggcoef( reg2, exponentiate = TRUE, exclude_intercept = TRUE, errorbar_height = .2, color = "blue", sort = "ascending" ) } } GGally/man/mapping_swap_x_y.Rd0000644000176200001440000000073213663637143016055 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/gg-plots.R \name{mapping_swap_x_y} \alias{mapping_swap_x_y} \title{Swap x and y mapping} \usage{ mapping_swap_x_y(mapping) } \arguments{ \item{mapping}{output of \code{ggplot2::\link[ggplot2]{aes}(...)}} } \value{ Aes mapping with the x and y values switched } \description{ Swap x and y mapping } \examples{ mapping <- ggplot2::aes(Petal.Length, Sepal.Width) mapping mapping_swap_x_y(mapping) } GGally/man/mapping_string.Rd0000644000176200001440000000062313663637143015531 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/gg-plots.R \name{mapping_string} \alias{mapping_string} \title{Aes name} \usage{ mapping_string(aes_col) } \arguments{ \item{aes_col}{Single value from \code{ggplot2::\link[ggplot2]{aes}(...)}} } \value{ character string } \description{ Aes name } \examples{ mapping <- ggplot2::aes(Petal.Length) mapping_string(mapping$x) } GGally/man/plotting_data_type.Rd0000644000176200001440000000045013663637143016400 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/find-combo.R \name{plotting_data_type} \alias{plotting_data_type} \title{Get plotting data type} \usage{ plotting_data_type(x) } \arguments{ \item{x}{vector} } \description{ Get plotting data type } \keyword{internal} GGally/man/baseball.Rd0000644000176200001440000000254314527265752014263 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/data-baseball.R \docType{data} \name{baseball} \alias{baseball} \title{Yearly batting records for all major league baseball players} \format{ A 21699 x 22 data frame } \usage{ baseball } \description{ This data frame contains batting statistics for a subset of players collected from \url{http://www.baseball-databank.org/}. There are a total of 21,699 records, covering 1,228 players from 1871 to 2007. Only players with more 15 seasons of play are included. } \section{Variables}{ Variables: \itemize{ \item id, unique player id \item year, year of data \item stint \item team, team played for \item lg, league \item g, number of games \item ab, number of times at bat \item r, number of runs \item h, hits, times reached base because of a batted, fair ball without error by the defense \item X2b, hits on which the batter reached second base safely \item X3b, hits on which the batter reached third base safely \item hr, number of home runs \item rbi, runs batted in \item sb, stolen bases \item cs, caught stealing \item bb, base on balls (walk) \item so, strike outs \item ibb, intentional base on balls \item hbp, hits by pitch \item sh, sacrifice hits \item sf, sacrifice flies \item gidp, ground into double play } } \references{ \url{http://www.baseball-databank.org/} } \keyword{datasets} GGally/man/ggnostic.Rd0000644000176200001440000001307314321332407014313 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/ggnostic.R \name{ggnostic} \alias{ggnostic} \title{Plot matrix of statistical model diagnostics} \usage{ ggnostic( model, ..., columnsX = attr(data, "var_x"), columnsY = c(".resid", ".sigma", ".hat", ".cooksd"), columnLabelsX = attr(data, "var_x_label"), columnLabelsY = gsub("\\\\.", " ", gsub("^\\\\.", "", columnsY)), xlab = "explanatory variables", ylab = "diagnostics", title = paste(deparse(model$call, width.cutoff = 500L), collapse = "\\n"), continuous = list(default = ggally_points, .fitted = ggally_points, .se.fit = ggally_nostic_se_fit, .resid = ggally_nostic_resid, .hat = ggally_nostic_hat, .sigma = ggally_nostic_sigma, .cooksd = ggally_nostic_cooksd, .std.resid = ggally_nostic_std_resid), combo = list(default = ggally_box_no_facet, .fitted = ggally_box_no_facet, .se.fit = ggally_nostic_se_fit, .resid = ggally_nostic_resid, .hat = ggally_nostic_hat, .sigma = ggally_nostic_sigma, .cooksd = ggally_nostic_cooksd, .std.resid = ggally_nostic_std_resid), discrete = list(default = ggally_ratio, .fitted = ggally_ratio, .se.fit = ggally_ratio, .resid = ggally_ratio, .hat = ggally_ratio, .sigma = ggally_ratio, .cooksd = ggally_ratio, .std.resid = ggally_ratio), progress = NULL, data = broomify(model) ) } \arguments{ \item{model}{statistical model object such as output from \code{stats::\link[stats]{lm}} or \code{stats::\link[stats]{glm}}} \item{...}{arguments passed directly to \code{\link{ggduo}}} \item{columnsX}{columns to be displayed in the plot matrix. Defaults to the predictor columns of the \code{model}} \item{columnsY}{rows to be displayed in the plot matrix. Defaults to residuals, leave one out sigma value, diagonal of the hat matrix, and Cook's Distance. The possible values are the response variables in the model and the added columns provided by \code{\link[broom:reexports]{broom::augment()}}. See details for more information.} \item{columnLabelsX, columnLabelsY}{column and row labels to display in the plot matrix} \item{xlab, ylab, title}{plot matrix labels passed directly to \code{\link{ggmatrix}}} \item{continuous, combo, discrete}{list of functions for each y variable. See details for more information.} \item{progress}{\code{NULL} (default) for a progress bar in interactive sessions with more than 15 plots, \code{TRUE} for a progress bar, \code{FALSE} for no progress bar, or a function that accepts at least a plot matrix and returns a new \code{progress::\link[progress]{progress_bar}}. See \code{\link{ggmatrix_progress}}.} \item{data}{data defaults to a 'broomify'ed model object. This object will contain information about the X variables, Y variables, and multiple broom outputs. See \code{\link{broomify}(model)} for more information} } \description{ Plot matrix of statistical model diagnostics } \section{\code{columnsY}}{ \code{\link[broom:reexports]{broom::augment()}} collects data from the supplied model and returns a data.frame with the following columns (taken directly from broom documentation). These columns are the only allowed values in the \code{columnsY} parameter to \code{\link{ggnostic}}. \describe{ \item{.resid}{Residuals} \item{.hat}{Diagonal of the hat matrix} \item{.sigma}{Estimate of residual standard deviation when corresponding observation is dropped from model} \item{.cooksd}{Cooks distance, \code{\link[stats:influence.measures]{stats::cooks.distance()}}} \item{.fitted}{Fitted values of model} \item{.se.fit}{Standard errors of fitted values} \item{.std.resid}{Standardized residuals} \item{response variable name}{The response variable in the model may be added. Such as \code{"mpg"} in the model \code{lm(mpg ~ ., data = mtcars)}} } } \section{\code{continuous}, \code{combo}, \code{discrete} types}{ Similar to \code{\link{ggduo}} and \code{\link{ggpairs}}, functions may be supplied to display the different column types. However, since the Y rows are fixed, each row has it's own corresponding function in each of the plot types: continuous, combo, and discrete. Each plot type list can have keys that correspond to the \code{\link[broom:reexports]{broom::augment()}} output: \code{".fitted"}, \code{".resid"}, \code{".std.resid"}, \code{".sigma"}, \code{".se.fit"}, \code{".hat"}, \code{".cooksd"}. An extra key, \code{"default"}, is used to plot the response variables of the model if they are included. Having a function for each diagnostic allows for very fine control over the diagnostics plot matrix. The functions for each type list are wrapped into a switch function that calls the function corresponding to the y variable being plotted. These switch functions are then passed directly to the \code{types} parameter in \code{\link{ggduo}}. } \examples{ # small function to display plots only if it's interactive p_ <- GGally::print_if_interactive data(mtcars) # use mtcars dataset and alter the 'am' column to display actual name values mtc <- mtcars mtc$am <- c("0" = "automatic", "1" = "manual")[as.character(mtc$am)] # step the complete model down to a smaller model mod <- stats::step(stats::lm(mpg ~ ., data = mtc), trace = FALSE) # display using defaults pm <- ggnostic(mod) p_(pm) # color by am value pm <- ggnostic(mod, mapping = ggplot2::aes(color = am)) p_(pm) # turn resid smooth error ribbon off pm <- ggnostic(mod, continuous = list(.resid = wrap("nostic_resid", se = FALSE))) p_(pm) ## plot residuals vs fitted in a ggpairs plot matrix dt <- broomify(mod) pm <- ggpairs( dt, c(".fitted", ".resid"), columnLabels = c("fitted", "residuals"), lower = list(continuous = ggally_nostic_resid) ) p_(pm) } GGally/man/ggally_nostic_sigma.Rd0000644000176200001440000000261013764714663016531 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/ggnostic.R \name{ggally_nostic_sigma} \alias{ggally_nostic_sigma} \title{\code{\link{ggnostic}} leave one out model sigma} \usage{ ggally_nostic_sigma( data, mapping, ..., lineColor = brew_colors("grey"), linePosition = attr(data, "broom_glance")$sigma ) } \arguments{ \item{data, mapping, ..., lineColor}{parameters supplied to \code{\link{ggally_nostic_line}}} \item{linePosition}{line that is drawn in the background of the plot. Defaults to the overall model's sigma value.} } \value{ \pkg{ggplot2} plot object } \description{ A function to display \code{\link[stats:lm.influence]{stats::influence()}}'s sigma value. } \details{ As stated in \code{\link[stats:lm.influence]{stats::influence()}} documentation: sigma: a vector whose i-th element contains the estimate of the residual standard deviation obtained when the i-th case is dropped from the regression. (The approximations needed for GLMs can result in this being 'NaN'.) A line is added to display the overall model's sigma value. This gives a baseline for comparison } \examples{ # Small function to display plots only if it's interactive p_ <- GGally::print_if_interactive dt <- broomify(stats::lm(mpg ~ wt + qsec + am, data = mtcars)) p_(ggally_nostic_sigma(dt, ggplot2::aes(wt, .sigma))) } \seealso{ \code{\link[stats:lm.influence]{stats::influence()}} } GGally/man/nasa.Rd0000644000176200001440000000164513761572054013435 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/data-nasa.R \docType{data} \name{nasa} \alias{nasa} \title{Data from the Data Expo JSM 2006.} \format{ A data frame with 41472 rows and 17 variables } \usage{ data(nasa) } \description{ This data was provided by NASA for the competition. } \details{ The data shows 6 years of monthly measurements of a 24x24 spatial grid from Central America: \itemize{ \item time integer specifying temporal order of measurements \item x, y, lat, long spatial location of measurements. \item cloudhigh, cloudlow, cloudmid, ozone, pressure, surftemp, temperature are the various satellite measurements. \item date, day, month, year specifying the time of measurements. \item id unique ide for each spatial position. } } \references{ Murrell, P. (2010) The 2006 Data Expo of the American Statistical Association. Computational Statistics, 25:551-554. } \keyword{datasets} GGally/man/model_terms.Rd0000644000176200001440000000154713663637143015030 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/ggnostic.R \name{model_response_variables} \alias{model_response_variables} \alias{model_beta_variables} \alias{model_beta_label} \title{Model term names} \usage{ model_response_variables(model, data = broom::augment(model)) model_beta_variables(model, data = broom::augment(model)) model_beta_label(model, data = broom::augment(model), lmStars = TRUE) } \arguments{ \item{model}{model in question} \item{data}{equivalent to \code{broom::augment(model)}} \item{lmStars}{boolean that determines if stars are added to labels} } \value{ character vector of names } \description{ Retrieve either the response variable names, the beta variable names, or beta variable names. If the model is an object of class 'lm', by default, the beta variable names will include anova significance stars. } GGally/man/singleClassOrder.Rd0000644000176200001440000000165513761572054015757 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/ggparcoord.R \name{singleClassOrder} \alias{singleClassOrder} \title{Order axis variables} \usage{ singleClassOrder(classVar, axisVars, specClass = NULL) } \arguments{ \item{classVar}{class variable (vector from original dataset)} \item{axisVars}{variables to be plotted as axes (data frame)} \item{specClass}{character string matching to level of \code{classVar}; instead of looking for separation between any class and the rest, will only look for separation between this class and the rest} } \value{ character vector of names of axisVars ordered such that the first variable has the most separation between one of the classes and the rest, and the last variable has the least (as measured by F-statistics from an ANOVA) } \description{ Order axis variables by separation between one class and the rest (most separation to least). } \author{ Jason Crowley } GGally/man/ggally_cor.Rd0000644000176200001440000000555514527265752014646 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/gg-plots.R \name{ggally_cor} \alias{ggally_cor} \title{Correlation value plot} \usage{ ggally_cor( data, mapping, ..., stars = TRUE, method = "pearson", use = "complete.obs", display_grid = FALSE, digits = 3, title_args = list(...), group_args = list(...), justify_labels = "right", align_percent = 0.5, title = "Corr", alignPercent = warning("deprecated. Use `align_percent`"), displayGrid = warning("deprecated. Use `display_grid`") ) } \arguments{ \item{data}{data set using} \item{mapping}{aesthetics being used} \item{...}{other arguments being supplied to \code{\link[ggplot2]{geom_text}()} for the title and groups} \item{stars}{logical value which determines if the significance stars should be displayed. Given the \code{\link[stats]{cor.test}} p-values, display \describe{ \item{\code{"***"}}{if the p-value is \verb{< 0.001}} \item{\code{"**"}}{if the p-value is \verb{< 0.01}} \item{\code{"*"}}{if the p-value is \verb{< 0.05}} \item{\code{"."}}{if the p-value is \verb{< 0.10}} \item{\code{""}}{otherwise} }} \item{method}{\code{method} supplied to cor function} \item{use}{\code{use} supplied to \code{\link[stats]{cor}} function} \item{display_grid}{if \code{TRUE}, display aligned panel grid lines. If \code{FALSE} (default), display a thin panel border.} \item{digits}{number of digits to be displayed after the decimal point. See \code{\link[base]{formatC}} for how numbers are calculated.} \item{title_args}{arguments being supplied to the title's \code{\link[ggplot2]{geom_text}()}} \item{group_args}{arguments being supplied to the split-by-color group's \code{\link[ggplot2]{geom_text}()}} \item{justify_labels}{\code{justify} argument supplied when \code{\link[base]{format}}ting the labels} \item{align_percent}{relative align position of the text. When \code{justify_labels = 0.5}, this should not be needed to be set.} \item{title}{title text to be displayed} \item{alignPercent, displayGrid}{deprecated. Please use their snake-case counterparts.} } \description{ Estimate correlation from the given data. If a color variable is supplied, the correlation will also be calculated per group. } \examples{ # Small function to display plots only if it's interactive p_ <- GGally::print_if_interactive data(tips) p_(ggally_cor(tips, mapping = ggplot2::aes(total_bill, tip))) # display with grid p_(ggally_cor( tips, mapping = ggplot2::aes(total_bill, tip), display_grid = TRUE )) # change text attributes p_(ggally_cor( tips, mapping = ggplot2::aes(x = total_bill, y = tip), size = 15, colour = I("red"), title = "Correlation" )) # split by a variable p_(ggally_cor( tips, mapping = ggplot2::aes(total_bill, tip, color = sex), size = 5 )) } \seealso{ \code{\link{ggally_statistic}}, \code{\link{ggally_cor_v1_5}} } \author{ Barret Schloerke } \keyword{hplot} GGally/man/ggmatrix.Rd0000644000176200001440000001121513761572054014327 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/ggmatrix.R \name{ggmatrix} \alias{ggmatrix} \title{\pkg{ggplot2} plot matrix} \usage{ ggmatrix( plots, nrow, ncol, xAxisLabels = NULL, yAxisLabels = NULL, title = NULL, xlab = NULL, ylab = NULL, byrow = TRUE, showStrips = NULL, showAxisPlotLabels = TRUE, showXAxisPlotLabels = TRUE, showYAxisPlotLabels = TRUE, labeller = NULL, switch = NULL, xProportions = NULL, yProportions = NULL, progress = NULL, data = NULL, gg = NULL, legend = NULL ) } \arguments{ \item{plots}{list of plots to be put into matrix} \item{nrow, ncol}{number of rows and columns} \item{xAxisLabels, yAxisLabels}{strip titles for the x and y axis respectively. Set to \code{NULL} to not be displayed} \item{title, xlab, ylab}{title, x label, and y label for the graph. Set to \code{NULL} to not be displayed} \item{byrow}{boolean that determines whether the plots should be ordered by row or by column} \item{showStrips}{boolean to determine if each plot's strips should be displayed. \code{NULL} will default to the top and right side plots only. \code{TRUE} or \code{FALSE} will turn all strips on or off respectively.} \item{showAxisPlotLabels, showXAxisPlotLabels, showYAxisPlotLabels}{booleans that determine if the plots axis labels are printed on the X (bottom) or Y (left) part of the plot matrix. If \code{showAxisPlotLabels} is set, both \code{showXAxisPlotLabels} and \code{showYAxisPlotLabels} will be set to the given value.} \item{labeller}{labeller for facets. See \code{\link[ggplot2]{labellers}}. Common values are \code{"label_value"} (default) and \code{"label_parsed"}.} \item{switch}{switch parameter for facet_grid. See \code{ggplot2::\link[ggplot2]{facet_grid}}. By default, the labels are displayed on the top and right of the plot. If \code{"x"}, the top labels will be displayed to the bottom. If \code{"y"}, the right-hand side labels will be displayed to the left. Can also be set to \code{"both"}} \item{xProportions, yProportions}{Value to change how much area is given for each plot. Either \code{NULL} (default), numeric value matching respective length, or \code{grid::\link[grid]{unit}} object with matching respective length} \item{progress}{\code{NULL} (default) for a progress bar in interactive sessions with more than 15 plots, \code{TRUE} for a progress bar, \code{FALSE} for no progress bar, or a function that accepts at least a plot matrix and returns a new \code{progress::\link[progress]{progress_bar}}. See \code{\link{ggmatrix_progress}}.} \item{data}{data set using. This is the data to be used in place of 'ggally_data' if the plot is a string to be evaluated at print time} \item{gg}{\pkg{ggplot2} theme objects to be applied to every plot} \item{legend}{May be the two objects described below or the default \code{NULL} value. The legend position can be moved by using ggplot2's theme element \code{pm + theme(legend.position = "bottom")} \describe{\item{a numeric vector of length 2}{provides the location of the plot to use the legend for the plot matrix's legend. Such as \code{legend = c(3,5)} which will use the legend from the plot in the third row and fifth column}\item{a single numeric value}{provides the location of a plot according to the display order. Such as \code{legend = 3} in a plot matrix with 2 rows and 5 columns displayed by column will return the plot in position \code{c(1,2)}}\item{a object from \code{\link{grab_legend}()}}{a predetermined plot legend that will be displayed directly}}} } \description{ Make a generic matrix of \pkg{ggplot2} plots. } \section{Memory usage}{ Now that the \code{\link{print.ggmatrix}} method uses a large \pkg{gtable} object, rather than print each plot independently, memory usage may be of concern. From small tests, memory usage flutters around \code{object.size(data) * 0.3 * length(plots)}. So, for a 80Mb random noise dataset with 100 plots, about 2.4 Gb of memory needed to print. For the 3.46 Mb diamonds dataset with 100 plots, about 100 Mb of memory was needed to print. The benefits of using the \pkg{ggplot2} format greatly outweigh the price of about 20\% increase in memory usage from the prior ad-hoc print method. } \examples{ # Small function to display plots only if it's interactive p_ <- GGally::print_if_interactive plotList <- list() for (i in 1:6) { plotList[[i]] <- ggally_text(paste("Plot #", i, sep = "")) } pm <- ggmatrix( plotList, 2, 3, c("A", "B", "C"), c("D", "E"), byrow = TRUE ) p_(pm) pm <- ggmatrix( plotList, 2, 3, xAxisLabels = c("A", "B", "C"), yAxisLabels = NULL, byrow = FALSE, showXAxisPlotLabels = FALSE ) p_(pm) } \author{ Barret Schloerke } \keyword{hplot} GGally/man/reexports.Rd0000644000176200001440000000232014330752755014536 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/reexports.R \docType{import} \name{reexports} \alias{reexports} \alias{ggcoef_model} \alias{ggcoef_compare} \alias{ggcoef_multinom} \alias{ggcoef_plot} \alias{signif_stars} \alias{geom_stripped_cols} \alias{geom_stripped_rows} \alias{stat_cross} \alias{StatCross} \alias{stat_prop} \alias{StatProp} \alias{stat_weighted_mean} \alias{StatWeightedMean} \title{Objects exported from other packages} \keyword{internal} \description{ These objects are imported from other packages. Follow the links below to see their documentation. \describe{ \item{ggstats}{\code{\link[ggstats:geom_stripped_rows]{geom_stripped_cols}}, \code{\link[ggstats]{geom_stripped_rows}}, \code{\link[ggstats:ggcoef_model]{ggcoef_compare}}, \code{\link[ggstats]{ggcoef_model}}, \code{\link[ggstats:ggcoef_model]{ggcoef_multinom}}, \code{\link[ggstats:ggcoef_model]{ggcoef_plot}}, \code{\link[ggstats]{signif_stars}}, \code{\link[ggstats]{stat_cross}}, \code{\link[ggstats]{stat_prop}}, \code{\link[ggstats]{stat_weighted_mean}}, \code{\link[ggstats:stat_cross]{StatCross}}, \code{\link[ggstats:stat_prop]{StatProp}}, \code{\link[ggstats:stat_weighted_mean]{StatWeightedMean}}} }} GGally/man/pigs.Rd0000644000176200001440000000222713761572054013452 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/data-pigs.R \docType{data} \name{pigs} \alias{pigs} \title{United Kingdom Pig Production} \format{ A data frame with 48 rows and 8 variables } \usage{ data(pigs) } \description{ This data contains about the United Kingdom Pig Production from the book 'Data' by Andrews and Herzberg. The original data can be on Statlib: http://lib.stat.cmu.edu/datasets/Andrews/T62.1 } \details{ The time variable has been added from a combination of year and quarter \itemize{ \item time year + (quarter - 1) / 4 \item year year of production \item quarter quarter of the year of production \item gilts number of sows giving birth for the first time \item profit ratio of price to an index of feed price \item s_per_herdsz ratio of the number of breeding pigs slaughtered to the total breeding herd size \item production number of pigs slaughtered that were reared for meat \item herdsz breeding herd size } } \references{ Andrews, David F., and Agnes M. Herzberg. Data: a collection of problems from many fields for the student and research worker. Springer Science & Business Media, 2012. } \keyword{datasets} GGally/man/ggnet2.Rd0000644000176200001440000003267414526734600013704 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/ggnet2.R \name{ggnet2} \alias{ggnet2} \title{Network plot} \usage{ ggnet2( net, mode = "fruchtermanreingold", layout.par = NULL, layout.exp = 0, alpha = 1, color = "grey75", shape = 19, size = 9, max_size = 9, na.rm = NA, palette = NULL, alpha.palette = NULL, alpha.legend = NA, color.palette = palette, color.legend = NA, shape.palette = NULL, shape.legend = NA, size.palette = NULL, size.legend = NA, size.zero = FALSE, size.cut = FALSE, size.min = NA, size.max = NA, label = FALSE, label.alpha = 1, label.color = "black", label.size = max_size/2, label.trim = FALSE, node.alpha = alpha, node.color = color, node.label = label, node.shape = shape, node.size = size, edge.alpha = 1, edge.color = "grey50", edge.lty = "solid", edge.size = 0.25, edge.label = NULL, edge.label.alpha = 1, edge.label.color = label.color, edge.label.fill = "white", edge.label.size = max_size/2, arrow.size = 0, arrow.gap = 0, arrow.type = "closed", legend.size = 9, legend.position = "right", ... ) } \arguments{ \item{net}{an object of class \code{\link[network]{network}}, or any object that can be coerced to this class, such as an adjacency or incidence matrix, or an edge list: see \link[network]{edgeset.constructors} and \link[network]{network} for details. If the object is of class \link[igraph:aaa-igraph-package]{igraph} and the \link[intergraph:intergraph-package]{intergraph} package is installed, it will be used to convert the object: see \code{\link[intergraph]{asNetwork}} for details.} \item{mode}{a placement method from those provided in the \code{\link[sna]{sna}} package: see \link[sna:gplot.layout]{gplot.layout} for details. Also accepts the names of two numeric vertex attributes of \code{net}, or a matrix of numeric coordinates, in which case the first two columns of the matrix are used. Defaults to the Fruchterman-Reingold force-directed algorithm.} \item{layout.par}{options to be passed to the placement method, as listed in \link[sna]{gplot.layout}. Defaults to \code{NULL}.} \item{layout.exp}{a multiplier to expand the horizontal axis if node labels get clipped: see \link[scales]{expand_range} for details. Defaults to \code{0} (no expansion).} \item{alpha}{the level of transparency of the edges and nodes, which might be a single value, a vertex attribute, or a vector of values. Also accepts \code{"mode"} on bipartite networks (see 'Details'). Defaults to \code{1} (no transparency).} \item{color}{the color of the nodes, which might be a single value, a vertex attribute, or a vector of values. Also accepts \code{"mode"} on bipartite networks (see 'Details'). Defaults to \code{grey75}.} \item{shape}{the shape of the nodes, which might be a single value, a vertex attribute, or a vector of values. Also accepts \code{"mode"} on bipartite networks (see 'Details'). Defaults to \code{19} (solid circle).} \item{size}{the size of the nodes, in points, which might be a single value, a vertex attribute, or a vector of values. Also accepts \code{"indegree"}, \code{"outdegree"}, \code{"degree"} or \code{"freeman"} to size the nodes by their unweighted degree centrality (\code{"degree"} and \code{"freeman"} are equivalent): see \code{\link[sna]{degree}} for details. All node sizes must be strictly positive. Also accepts \code{"mode"} on bipartite networks (see 'Details'). Defaults to \code{9}.} \item{max_size}{the \emph{maximum} size of the node when \code{size} produces nodes of different sizes, in points. Defaults to \code{9}.} \item{na.rm}{whether to subset the network to nodes that are \emph{not} missing a given vertex attribute. If set to any vertex attribute of \code{net}, the nodes for which this attribute is \code{NA} will be removed. Defaults to \code{NA} (does nothing).} \item{palette}{the palette to color the nodes, when \code{color} is not a color value or a vector of color values. Accepts named vectors of color values, or if \link[RColorBrewer:ColorBrewer]{RColorBrewer} is installed, any ColorBrewer palette name: see \code{\link[RColorBrewer:ColorBrewer]{RColorBrewer::brewer.pal()}} and \url{https://colorbrewer2.org/} for details. Defaults to \code{NULL}, which will create an array of grayscale color values if \code{color} is not a color value or a vector of color values.} \item{alpha.palette}{the palette to control the transparency levels of the nodes set by \code{alpha} when the levels are not numeric values. Defaults to \code{NULL}, which will create an array of alpha transparency values if \code{alpha} is not a numeric value or a vector of numeric values.} \item{alpha.legend}{the name to assign to the legend created by \code{alpha} when its levels are not numeric values. Defaults to \code{NA} (no name).} \item{color.palette}{see \code{palette}} \item{color.legend}{the name to assign to the legend created by \code{palette}. Defaults to \code{NA} (no name).} \item{shape.palette}{the palette to control the shapes of the nodes set by \code{shape} when the shapes are not numeric values. Defaults to \code{NULL}, which will create an array of shape values if \code{shape} is not a numeric value or a vector of numeric values.} \item{shape.legend}{the name to assign to the legend created by \code{shape} when its levels are not numeric values. Defaults to \code{NA} (no name).} \item{size.palette}{the palette to control the sizes of the nodes set by \code{size} when the sizes are not numeric values.} \item{size.legend}{the name to assign to the legend created by \code{size}. Defaults to \code{NA} (no name).} \item{size.zero}{whether to accept zero-sized nodes based on the value(s) of \code{size}. Defaults to \code{FALSE}, which ensures that zero-sized nodes are still shown in the plot and its size legend.} \item{size.cut}{whether to cut the size of the nodes into a certain number of quantiles. Accepts \code{TRUE}, which tries to cut the sizes into quartiles, or any positive numeric value, which tries to cut the sizes into that many quantiles. If the size of the nodes do not contain the specified number of distinct quantiles, the largest possible number is used. See \code{\link[stats]{quantile}} and \code{\link[base]{cut}} for details. Defaults to \code{FALSE} (does nothing).} \item{size.min}{whether to subset the network to nodes with a minimum size, based on the values of \code{size}. Defaults to \code{NA} (preserves all nodes).} \item{size.max}{whether to subset the network to nodes with a maximum size, based on the values of \code{size}. Defaults to \code{NA} (preserves all nodes).} \item{label}{whether to label the nodes. If set to \code{TRUE}, nodes are labeled with their vertex names. If set to a vector that contains as many elements as there are nodes in \code{net}, nodes are labeled with these. If set to any other vector of values, the nodes are labeled only when their vertex name matches one of these values. Defaults to \code{FALSE} (no labels).} \item{label.alpha}{the level of transparency of the node labels, as a numeric value, a vector of numeric values, or as a vertex attribute containing numeric values. Defaults to \code{1} (no transparency).} \item{label.color}{the color of the node labels, as a color value, a vector of color values, or as a vertex attribute containing color values. Defaults to \code{"black"}.} \item{label.size}{the size of the node labels, in points, as a numeric value, a vector of numeric values, or as a vertex attribute containing numeric values. Defaults to \code{max_size / 2} (half the maximum node size), which defaults to \code{4.5}.} \item{label.trim}{whether to apply some trimming to the node labels. Accepts any function that can process a character vector, or a strictly positive numeric value, in which case the labels are trimmed to a fixed-length substring of that length: see \code{\link[base]{substr}} for details. Defaults to \code{FALSE} (does nothing).} \item{node.alpha}{see \code{alpha}} \item{node.color}{see \code{color}} \item{node.label}{see \code{label}} \item{node.shape}{see \code{shape}} \item{node.size}{see \code{size}} \item{edge.alpha}{the level of transparency of the edges. Defaults to the value of \code{alpha}, which defaults to \code{1}.} \item{edge.color}{the color of the edges, as a color value, a vector of color values, or as an edge attribute containing color values. Defaults to \code{"grey50"}.} \item{edge.lty}{the linetype of the edges, as a linetype value, a vector of linetype values, or as an edge attribute containing linetype values. Defaults to \code{"solid"}.} \item{edge.size}{the size of the edges, in points, as a numeric value, a vector of numeric values, or as an edge attribute containing numeric values. All edge sizes must be strictly positive. Defaults to \code{0.25}.} \item{edge.label}{the labels to plot at the middle of the edges, as a single value, a vector of values, or as an edge attribute. Defaults to \code{NULL} (no edge labels).} \item{edge.label.alpha}{the level of transparency of the edge labels, as a numeric value, a vector of numeric values, or as an edge attribute containing numeric values. Defaults to \code{1} (no transparency).} \item{edge.label.color}{the color of the edge labels, as a color value, a vector of color values, or as an edge attribute containing color values. Defaults to \code{label.color}, which defaults to \code{"black"}.} \item{edge.label.fill}{the background color of the edge labels. Defaults to \code{"white"}.} \item{edge.label.size}{the size of the edge labels, in points, as a numeric value, a vector of numeric values, or as an edge attribute containing numeric values. All edge label sizes must be strictly positive. Defaults to \code{max_size / 2} (half the maximum node size), which defaults to \code{4.5}.} \item{arrow.size}{the size of the arrows for directed network edges, in points. See \code{\link[grid]{arrow}} for details. Defaults to \code{0} (no arrows).} \item{arrow.gap}{a setting aimed at improving the display of edge arrows by plotting slightly shorter edges. Accepts any value between \code{0} and \code{1}, where a value of \code{0.05} will generally achieve good results when the size of the nodes is reasonably small. Defaults to \code{0} (no shortening).} \item{arrow.type}{the type of the arrows for directed network edges. See \code{\link[grid]{arrow}} for details. Defaults to \code{"closed"}.} \item{legend.size}{the size of the legend symbols and text, in points. Defaults to \code{9}.} \item{legend.position}{the location of the plot legend(s). Accepts all \code{legend.position} values supported by \code{\link[ggplot2]{theme}}. Defaults to \code{"right"}.} \item{...}{other arguments passed to the \code{geom_text} object that sets the node labels: see \code{\link[ggplot2]{geom_text}} for details.} } \description{ Function for plotting network objects using \pkg{ggplot2}, with additional control over graphical parameters that are not supported by the \code{\link{ggnet}} function. Please visit \url{https://github.com/briatte/ggnet} for the latest version of ggnet2, and \url{https://briatte.github.io/ggnet/} for a vignette that contains many examples and explanations. } \details{ The degree centrality measures that can be produced through the \code{size} argument will take the directedness of the network into account, but will be unweighted. To compute weighted network measures, see the \code{tnet} package by Tore Opsahl (\code{help("tnet", package = "tnet")}). The nodes of bipartite networks can be mapped to their mode by passing the \code{"mode"} argument to any of \code{alpha}, \code{color}, \code{shape} and \code{size}, in which case the nodes of the primary mode will be mapped as \code{"actor"}, and the nodes of the secondary mode will be mapped as \code{"event"}. } \examples{ # Small function to display plots only if it's interactive p_ <- GGally::print_if_interactive library(network) # random adjacency matrix x <- 10 ndyads <- x * (x - 1) density <- x / ndyads m <- matrix(0, nrow = x, ncol = x) dimnames(m) <- list(letters[1:x], letters[1:x]) m[row(m) != col(m)] <- runif(ndyads) < density m # random undirected network n <- network::network(m, directed = FALSE) n p_(ggnet2(n, label = TRUE)) p_(ggnet2(n, label = TRUE, shape = 15)) p_(ggnet2(n, label = TRUE, shape = 15, color = "black", label.color = "white")) # add vertex attribute x = network.vertex.names(n) x = ifelse(x \%in\% c("a", "e", "i"), "vowel", "consonant") n \%v\% "phono" = x p_(ggnet2(n, color = "phono")) p_(ggnet2(n, color = "phono", palette = c("vowel" = "gold", "consonant" = "grey"))) p_(ggnet2(n, shape = "phono", color = "phono")) if (require(RColorBrewer)) { # random groups n \%v\% "group" <- sample(LETTERS[1:3], 10, replace = TRUE) p_(ggnet2(n, color = "group", palette = "Set2")) } # random weights n \%e\% "weight" <- sample(1:3, network.edgecount(n), replace = TRUE) p_(ggnet2(n, edge.size = "weight", edge.label = "weight")) # edge arrows on a directed network p_(ggnet2(network(m, directed = TRUE), arrow.gap = 0.05, arrow.size = 10)) # Padgett's Florentine wedding data data(flo, package = "network") flo p_(ggnet2(flo, label = TRUE)) p_(ggnet2(flo, label = TRUE, label.trim = 4, vjust = -1, size = 3, color = 1)) p_(ggnet2(flo, label = TRUE, size = 12, color = "white")) } \seealso{ \code{\link{ggnet}} in this package, \code{\link[sna]{gplot}} in the \code{\link[sna]{sna}} package, and \code{\link[network]{plot.network}} in the \code{\link[network]{network}} package } \author{ Moritz Marbach and Francois Briatte, with help from Heike Hofmann, Pedro Jordano and Ming-Yu Liu } GGally/man/ggally_nostic_line.Rd0000644000176200001440000000263113764714663016363 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/ggnostic.R \name{ggally_nostic_line} \alias{ggally_nostic_line} \title{\code{\link{ggnostic}} background line with geom} \usage{ ggally_nostic_line( data, mapping, ..., linePosition = NULL, lineColor = "red", lineSize = 0.5, lineAlpha = 1, lineType = 1, continuous_geom = ggplot2::geom_point, combo_geom = ggplot2::geom_boxplot, mapColorToFill = TRUE ) } \arguments{ \item{data, mapping}{supplied directly to \code{\link[ggplot2:ggplot]{ggplot2::ggplot()}}} \item{...}{parameters supplied to \code{continuous_geom} or \code{combo_geom}} \item{linePosition, lineColor, lineSize, lineAlpha, lineType}{parameters supplied to \code{\link[ggplot2:geom_path]{ggplot2::geom_line()}}} \item{continuous_geom}{\pkg{ggplot2} geom that is executed after the line is (possibly) added and if the x data is continuous} \item{combo_geom}{\pkg{ggplot2} geom that is executed after the line is (possibly) added and if the x data is discrete} \item{mapColorToFill}{boolean to determine if combo plots should cut the color mapping to the fill mapping} } \value{ \pkg{ggplot2} plot object } \description{ If a non-null \code{linePosition} value is given, a line will be drawn before the given \code{continuous_geom} or \code{combo_geom} is added to the plot. } \details{ Functions with a color in their name have different default color behavior. } GGally/man/add_and_overwrite_aes.Rd0000644000176200001440000000132314527265752017021 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/ggpairs.R \name{add_and_overwrite_aes} \alias{add_and_overwrite_aes} \title{Add new aes} \usage{ add_and_overwrite_aes(current, new) } \value{ aes_ output } \description{ Add new aesthetics to a previous aes. } \examples{ data(diamonds, package = "ggplot2") diamonds.samp <- diamonds[sample(1:dim(diamonds)[1], 1000), ] pm <- ggpairs(diamonds.samp, columns = 5:7, mapping = ggplot2::aes(color = color), upper = list(continuous = "cor", mapping = ggplot2::aes(color = clarity)), lower = list(continuous = "cor", mapping = ggplot2::aes(color = cut)), title = "Diamonds Sample" ) str(pm) } \author{ Barret Schloerke } \keyword{internal} GGally/man/gg-add.Rd0000644000176200001440000000622414526730006013625 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/ggpairs_add.R \name{+.gg} \alias{+.gg} \alias{add_to_ggmatrix} \title{Modify a \code{\link{ggmatrix}} object by adding an \pkg{ggplot2} object to all plots} \usage{ \method{+}{gg}(e1, e2) add_to_ggmatrix(e1, e2, location = NULL, rows = NULL, cols = NULL) } \arguments{ \item{e1}{An object of class \code{\link{ggnostic}} or \code{ggplot}} \item{e2}{A component to add to \code{e1}} \item{location}{\describe{ \item{\code{"all"}, \code{TRUE}}{All row and col combinations} \item{\code{"none"}}{No row and column combinations} \item{\code{"upper"}}{Locations where the column value is higher than the row value} \item{\code{"lower"}}{Locations where the row value is higher than the column value} \item{\code{"diag"}}{Locations where the column value is equal to the row value} \item{\code{matrix} or \code{data.frame}}{ \code{matrix} values will be converted into \code{data.frame}s. \itemize{ \item A \code{data.frame} with the exact column names \code{c("row", "col")} \item A \code{data.frame} with the number of rows and columns matching the plot matrix object provided. Each cell will be tested for a "truthy" value to determine if the location should be kept. } } }} \item{rows}{numeric vector of the rows to be used. Will be used with \code{cols} if \code{location} is \code{NULL}} \item{cols}{numeric vector of the cols to be used. Will be used with \code{rows} if \code{location} is \code{NULL}} } \description{ This operator allows you to add \pkg{ggplot2} objects to a \code{\link{ggmatrix}} object. } \details{ If the first object is an object of class \code{\link{ggmatrix}}, you can add the following types of objects, and it will return a modified \pkg{ggplot2} object. \itemize{ \item \code{theme}: update plot theme \item \code{scale}: replace current scale \item \code{coord}: override current coordinate system } The \code{+} operator completely replaces elements with elements from e2. \code{add_to_ggmatrix} gives you more control to modify only some subplots. This function may be replaced and/or removed in the future. \Sexpr[results=rd, stage=render]{lifecycle::badge("experimental")} } \examples{ # small function to display plots only if it's interactive p_ <- GGally::print_if_interactive data(tips) pm <- ggpairs(tips[, 2:4], ggplot2::aes(color = sex)) ## change to black and white theme pm + ggplot2::theme_bw() ## change to linedraw theme p_(pm + ggplot2::theme_linedraw()) ## change to custom theme p_(pm + ggplot2::theme(panel.background = ggplot2::element_rect(fill = "lightblue"))) ## add a list of information extra <- list(ggplot2::theme_bw(), ggplot2::labs(caption = "My caption!")) p_(pm + extra) ## modify scale p_(pm + scale_fill_brewer(type = "qual")) ## only first row p_(add_to_ggmatrix(pm, scale_fill_brewer(type = "qual"), rows = 1:2)) ## only second col p_(add_to_ggmatrix(pm, scale_fill_brewer(type = "qual"), cols = 2:3)) ## only to upper triangle of plot matrix p_(add_to_ggmatrix( pm, scale_fill_brewer(type = "qual"), location = "upper" )) } \seealso{ \link[ggplot2:gg-add]{ggplot2::+.gg} and \code{\link[ggplot2:theme]{ggplot2::theme()}} \code{\link{ggmatrix_location}} } GGally/man/ggally_nostic_std_resid.Rd0000644000176200001440000000174613764714663017422 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/ggnostic.R \name{ggally_nostic_std_resid} \alias{ggally_nostic_std_resid} \title{\code{\link{ggnostic}} standardized residuals} \usage{ ggally_nostic_std_resid(data, mapping, ..., sigma = 1) } \arguments{ \item{data, mapping, ...}{parameters supplied to \code{\link{ggally_nostic_resid}}} \item{sigma}{sigma value for the \code{pVal} percentiles. Set to 1 for standardized residuals} } \value{ \pkg{ggplot2} plot object } \description{ If non-null \code{pVal} and \code{sigma} values are given, confidence interval lines will be added to the plot at the specified \code{pVal} locations of a N(0, 1) distribution. } \examples{ # Small function to display plots only if it's interactive p_ <- GGally::print_if_interactive dt <- broomify(stats::lm(mpg ~ wt + qsec + am, data = mtcars)) p_(ggally_nostic_std_resid(dt, ggplot2::aes(wt, .std.resid))) } \seealso{ \code{\link[stats:influence.measures]{stats::rstandard()}} } GGally/man/mapping_color_to_fill.Rd0000644000176200001440000000053313665760216017051 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/ggpairs.R \name{mapping_color_to_fill} \alias{mapping_color_to_fill} \title{Aesthetic mapping color fill} \usage{ mapping_color_to_fill(current) } \arguments{ \item{current}{the current aesthetics} } \description{ Replace the fill with the color and make color NULL. } GGally/man/ggally_count.Rd0000644000176200001440000000270714526730006015173 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/gg-plots.R \docType{data} \name{ggally_count} \alias{ggally_count} \alias{stat_ggally_count} \alias{StatGGallyCount} \alias{ggally_countDiag} \title{Display counts of observations} \usage{ ggally_count(data, mapping, ...) ggally_countDiag(data, mapping, ...) } \arguments{ \item{data}{data set using} \item{mapping}{aesthetics being used} \item{...}{other arguments passed to \code{\link[ggplot2]{geom_tile}(...)}} } \description{ Plot the number of observations by using rectangles with proportional areas. } \details{ You can adjust the size of rectangles with the \code{x.width} argument. } \examples{ # Small function to display plots only if it's interactive p_ <- GGally::print_if_interactive data(tips) p_(ggally_count(tips, mapping = ggplot2::aes(x = smoker, y = sex))) p_(ggally_count(tips, mapping = ggplot2::aes(x = smoker, y = sex, fill = day))) p_(ggally_count( as.data.frame(Titanic), mapping = ggplot2::aes(x = Class, y = Survived, weight = Freq) )) p_(ggally_count( as.data.frame(Titanic), mapping = ggplot2::aes(x = Class, y = Survived, weight = Freq), x.width = 0.5 )) # Small function to display plots only if it's interactive p_ <- GGally::print_if_interactive p_(ggally_countDiag(tips, mapping = ggplot2::aes(x = smoker))) p_(ggally_countDiag(tips, mapping = ggplot2::aes(x = smoker, fill = sex))) } \author{ Joseph Larmarange } \keyword{datasets} \keyword{hplot} GGally/man/ggally_facethist.Rd0000644000176200001440000000133214527265752016022 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/gg-plots.R \name{ggally_facethist} \alias{ggally_facethist} \title{Faceted histogram} \usage{ ggally_facethist(data, mapping, ...) } \arguments{ \item{data}{data set using} \item{mapping}{aesthetics being used} \item{...}{parameters sent to stat_bin()} } \description{ Display subsetted histograms of the data in different panels. } \examples{ # Small function to display plots only if it's interactive p_ <- GGally::print_if_interactive data(tips) p_(ggally_facethist(tips, mapping = ggplot2::aes(x = tip, y = sex))) p_(ggally_facethist(tips, mapping = ggplot2::aes(x = tip, y = sex), binwidth = 0.1)) } \author{ Barret Schloerke } \keyword{hplot} GGally/man/pipe.Rd0000644000176200001440000000066014527407231013437 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils-pipe.R \name{\%>\%} \alias{\%>\%} \title{Pipe operator} \usage{ lhs \%>\% rhs } \arguments{ \item{lhs}{A value or the magrittr placeholder.} \item{rhs}{A function call using the magrittr semantics.} } \value{ The result of calling \code{rhs(lhs)}. } \description{ See \code{magrittr::\link[magrittr:pipe]{\%>\%}} for details. } \keyword{internal} GGally/man/glyphplot.Rd0000644000176200001440000000211314330752755014525 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/gglyph.R \name{glyphplot} \alias{glyphplot} \alias{is.glyphplot} \alias{[.glyphplot} \alias{print.glyphplot} \title{Glyph plot class} \usage{ glyphplot(data, width, height, polar, x_major, y_major) is.glyphplot(x) \method{[}{glyphplot}(x, ...) \method{print}{glyphplot}(x, ...) } \arguments{ \item{data}{A data frame containing variables named in \code{x_major}, \code{x_minor}, \code{y_major} and \code{y_minor}.} \item{height, width}{The height and width of each glyph. Defaults to 95\% of the \code{\link[ggplot2]{resolution}} of the data. Specify the width absolutely by supplying a numeric vector of length 1, or relative to the} \item{polar}{A logical of length 1, specifying whether the glyphs should be drawn in polar coordinates. Defaults to \code{FALSE}.} \item{x_major, y_major}{The name of the variable (as a string) for the major x and y axes. Together, the} \item{x}{glyphplot to be printed} \item{...}{ignored} } \description{ Glyph plot class } \author{ Di Cook, Heike Hofmann, Hadley Wickham } GGally/man/str.ggmatrix.Rd0000644000176200001440000000116413665760216015142 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/ggpairs_internal_plots.R \name{str.ggmatrix} \alias{str.ggmatrix} \title{\code{\link{ggmatrix}} structure} \usage{ \method{str}{ggmatrix}(object, ..., raw = FALSE) } \arguments{ \item{object}{\code{\link{ggmatrix}} object to be viewed} \item{...}{passed on to the default \code{str} method} \item{raw}{boolean to determine if the plots should be converted to text or kept as original objects} } \description{ View the condensed version of the \code{\link{ggmatrix}} object. The attribute "class" is ALWAYS altered to "_class" to avoid recursion. } GGally/man/ggduo.Rd0000644000176200001440000002503414527265752013623 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/ggpairs.R \name{ggduo} \alias{ggduo} \title{\pkg{ggplot2} generalized pairs plot for two columns sets of data} \usage{ ggduo( data, mapping = NULL, columnsX = 1:ncol(data), columnsY = 1:ncol(data), title = NULL, types = list(continuous = "smooth_loess", comboVertical = "box_no_facet", comboHorizontal = "facethist", discrete = "count"), axisLabels = c("show", "none"), columnLabelsX = colnames(data[columnsX]), columnLabelsY = colnames(data[columnsY]), labeller = "label_value", switch = NULL, xlab = NULL, ylab = NULL, showStrips = NULL, legend = NULL, cardinality_threshold = 15, progress = NULL, xProportions = NULL, yProportions = NULL, legends = stop("deprecated") ) } \arguments{ \item{data}{data set using. Can have both numerical and categorical data.} \item{mapping}{aesthetic mapping (besides \code{x} and \code{y}). See \code{\link[ggplot2]{aes}()}. If \code{mapping} is numeric, \code{columns} will be set to the \code{mapping} value and \code{mapping} will be set to \code{NULL}.} \item{columnsX, columnsY}{which columns are used to make plots. Defaults to all columns.} \item{title, xlab, ylab}{title, x label, and y label for the graph} \item{types}{see Details} \item{axisLabels}{either "show" to display axisLabels or "none" for no axis labels} \item{columnLabelsX, columnLabelsY}{label names to be displayed. Defaults to names of columns being used.} \item{labeller}{labeller for facets. See \code{\link[ggplot2]{labellers}}. Common values are \code{"label_value"} (default) and \code{"label_parsed"}.} \item{switch}{switch parameter for facet_grid. See \code{ggplot2::\link[ggplot2]{facet_grid}}. By default, the labels are displayed on the top and right of the plot. If \code{"x"}, the top labels will be displayed to the bottom. If \code{"y"}, the right-hand side labels will be displayed to the left. Can also be set to \code{"both"}} \item{showStrips}{boolean to determine if each plot's strips should be displayed. \code{NULL} will default to the top and right side plots only. \code{TRUE} or \code{FALSE} will turn all strips on or off respectively.} \item{legend}{May be the two objects described below or the default \code{NULL} value. The legend position can be moved by using ggplot2's theme element \code{pm + theme(legend.position = "bottom")} \describe{\item{a numeric vector of length 2}{provides the location of the plot to use the legend for the plot matrix's legend. Such as \code{legend = c(3,5)} which will use the legend from the plot in the third row and fifth column}\item{a single numeric value}{provides the location of a plot according to the display order. Such as \code{legend = 3} in a plot matrix with 2 rows and 5 columns displayed by column will return the plot in position \code{c(1,2)}}\item{a object from \code{\link{grab_legend}()}}{a predetermined plot legend that will be displayed directly}}} \item{cardinality_threshold}{maximum number of levels allowed in a character / factor column. Set this value to NULL to not check factor columns. Defaults to 15} \item{progress}{\code{NULL} (default) for a progress bar in interactive sessions with more than 15 plots, \code{TRUE} for a progress bar, \code{FALSE} for no progress bar, or a function that accepts at least a plot matrix and returns a new \code{progress::\link[progress]{progress_bar}}. See \code{\link{ggmatrix_progress}}.} \item{xProportions, yProportions}{Value to change how much area is given for each plot. Either \code{NULL} (default), numeric value matching respective length, \code{grid::\link[grid]{unit}} object with matching respective length or \code{"auto"} for automatic relative proportions based on the number of levels for categorical variables.} \item{legends}{deprecated} } \description{ Make a matrix of plots with a given data set with two different column sets } \details{ \code{types} is a list that may contain the variables 'continuous', 'combo', 'discrete', and 'na'. Each element of the list may be a function or a string. If a string is supplied, If a string is supplied, it must be a character string representing the tail end of a \code{ggally_NAME} function. The list of current valid \code{ggally_NAME} functions is visible in a dedicated vignette. \describe{ \item{continuous}{This option is used for continuous X and Y data.} \item{comboHorizontal}{This option is used for either continuous X and categorical Y data or categorical X and continuous Y data.} \item{comboVertical}{This option is used for either continuous X and categorical Y data or categorical X and continuous Y data.} \item{discrete}{This option is used for categorical X and Y data.} \item{na}{This option is used when all X data is \code{NA}, all Y data is \code{NA}, or either all X or Y data is \code{NA}.} } If 'blank' is ever chosen as an option, then ggduo will produce an empty plot. If a function is supplied as an option, it should implement the function api of \code{function(data, mapping, ...){#make ggplot2 plot}}. If a specific function needs its parameters set, \code{\link{wrap}(fn, param1 = val1, param2 = val2)} the function with its parameters. } \examples{ # small function to display plots only if it's interactive p_ <- GGally::print_if_interactive data(baseball) # Keep players from 1990-1995 with at least one at bat # Add how many singles a player hit # (must do in two steps as X1b is used in calculations) dt <- transform( subset(baseball, year >= 1990 & year <= 1995 & ab > 0), X1b = h - X2b - X3b - hr ) # Add # the player's batting average, # the player's slugging percentage, # and the player's on base percentage # Make factor a year, as each season is discrete dt <- transform( dt, batting_avg = h / ab, slug = (X1b + 2 * X2b + 3 * X3b + 4 * hr) / ab, on_base = (h + bb + hbp) / (ab + bb + hbp), year = as.factor(year) ) pm <- ggduo( dt, c("year", "g", "ab", "lg"), c("batting_avg", "slug", "on_base"), mapping = ggplot2::aes(color = lg) ) # Prints, but # there is severe over plotting in the continuous plots # the labels could be better # want to add more hitting information p_(pm) # address overplotting issues and add a title pm <- ggduo( dt, c("year", "g", "ab", "lg"), c("batting_avg", "slug", "on_base"), columnLabelsX = c("year", "player game count", "player at bat count", "league"), columnLabelsY = c("batting avg", "slug \%", "on base \%"), title = "Baseball Hitting Stats from 1990-1995", mapping = ggplot2::aes(color = lg), types = list( # change the shape and add some transparency to the points continuous = wrap("smooth_loess", alpha = 0.50, shape = "+") ), showStrips = FALSE ) p_(pm) # Use "auto" to adapt width of the sub-plots pm <- ggduo( dt, c("year", "g", "ab", "lg"), c("batting_avg", "slug", "on_base"), mapping = ggplot2::aes(color = lg), xProportions = "auto" ) p_(pm) # Custom widths & heights of the sub-plots pm <- ggduo( dt, c("year", "g", "ab", "lg"), c("batting_avg", "slug", "on_base"), mapping = ggplot2::aes(color = lg), xProportions = c(6, 4, 3, 2), yProportions = c(1, 2, 1) ) p_(pm) # Example derived from: ## R Data Analysis Examples | Canonical Correlation Analysis. UCLA: Institute for Digital ## Research and Education. ## from http://www.stats.idre.ucla.edu/r/dae/canonical-correlation-analysis ## (accessed May 22, 2017). # "Example 1. A researcher has collected data on three psychological variables, four # academic variables (standardized test scores) and gender for 600 college freshman. # She is interested in how the set of psychological variables relates to the academic # variables and gender. In particular, the researcher is interested in how many # dimensions (canonical variables) are necessary to understand the association between # the two sets of variables." data(psychademic) summary(psychademic) (psych_variables <- attr(psychademic, "psychology")) (academic_variables <- attr(psychademic, "academic")) ## Within correlation p_(ggpairs(psychademic, columns = psych_variables)) p_(ggpairs(psychademic, columns = academic_variables)) ## Between correlation loess_with_cor <- function(data, mapping, ..., method = "pearson") { x <- eval_data_col(data, mapping$x) y <- eval_data_col(data, mapping$y) cor <- cor(x, y, method = method) ggally_smooth_loess(data, mapping, ...) + ggplot2::geom_label( data = data.frame( x = min(x, na.rm = TRUE), y = max(y, na.rm = TRUE), lab = round(cor, digits = 3) ), mapping = ggplot2::aes(x = x, y = y, label = lab), hjust = 0, vjust = 1, size = 5, fontface = "bold", inherit.aes = FALSE # do not inherit anything from the ... ) } pm <- ggduo( psychademic, rev(psych_variables), academic_variables, types = list(continuous = loess_with_cor), showStrips = FALSE ) suppressWarnings(p_(pm)) # ignore warnings from loess # add color according to sex pm <- ggduo( psychademic, mapping = ggplot2::aes(color = sex), rev(psych_variables), academic_variables, types = list(continuous = loess_with_cor), showStrips = FALSE, legend = c(5, 2) ) suppressWarnings(p_(pm)) # add color according to sex pm <- ggduo( psychademic, mapping = ggplot2::aes(color = motivation), rev(psych_variables), academic_variables, types = list(continuous = loess_with_cor), showStrips = FALSE, legend = c(5, 2) ) + ggplot2::theme(legend.position = "bottom") suppressWarnings(p_(pm)) # dt, # c("year", "g", "ab", "lg", "lg"), # c("batting_avg", "slug", "on_base", "hit_type"), # columnLabelsX = c("year", "player game count", "player at bat count", "league", ""), # columnLabelsY = c("batting avg", "slug \%", "on base \%", "hit type"), # title = "Baseball Hitting Stats from 1990-1995 (player strike in 1994)", # mapping = aes(color = year), # types = list( # continuous = wrap("smooth_loess", alpha = 0.50, shape = "+"), # comboHorizontal = wrap(display_hit_type_combo, binwidth = 15), # discrete = wrap(display_hit_type_discrete, color = "black", size = 0.15) # ), # showStrips = FALSE ## make the 5th column blank, except for the legend # australia_PISA2012, # c("gender", "age", "homework", "possessions"), # c("PV1MATH", "PV2MATH", "PV3MATH", "PV4MATH", "PV5MATH"), # types = list( # continuous = "points", # combo = "box", # discrete = "ratio" # ) # australia_PISA2012, # c("gender", "age", "homework", "possessions"), # c("PV1MATH", "PV2MATH", "PV3MATH", "PV4MATH", "PV5MATH"), # mapping = ggplot2::aes(color = gender), # types = list( # continuous = wrap("smooth", alpha = 0.25, method = "loess"), # combo = "box", # discrete = "ratio" # ) } GGally/man/ggally_ratio.Rd0000644000176200001440000000233714527265752015174 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/gg-plots.R \name{ggally_ratio} \alias{ggally_ratio} \title{Mosaic plot} \usage{ ggally_ratio( data, mapping = ggplot2::aes(!!!stats::setNames(lapply(colnames(data)[1:2], as.name), c("x", "y"))), ..., floor = 0, ceiling = NULL ) } \arguments{ \item{data}{data set using} \item{mapping}{aesthetics being used. Only x and y will used and both are required} \item{...}{passed to \code{\link[ggplot2]{geom_tile}(...)}} \item{floor}{don't display cells smaller than this value} \item{ceiling}{max value to scale frequencies. If any frequency is larger than the ceiling, the fill color is displayed darker than other rectangles} } \description{ Plots the mosaic plot by using fluctuation. } \examples{ # Small function to display plots only if it's interactive p_ <- GGally::print_if_interactive data(tips) p_(ggally_ratio(tips, ggplot2::aes(sex, day))) p_(ggally_ratio(tips, ggplot2::aes(sex, day)) + ggplot2::coord_equal()) # only plot tiles greater or equal to 20 and scale to a max of 50 p_(ggally_ratio( tips, ggplot2::aes(sex, day), floor = 20, ceiling = 50 ) + ggplot2::theme(aspect.ratio = 4 / 2)) } \author{ Barret Schloerke } \keyword{hplot} GGally/man/ggsurv.Rd0000644000176200001440000000731714527265752014037 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/ggsurv.R \name{ggsurv} \alias{ggsurv} \title{Survival curves} \usage{ ggsurv( s, CI = "def", plot.cens = TRUE, surv.col = "gg.def", cens.col = "gg.def", lty.est = 1, lty.ci = 2, size.est = 0.5, size.ci = size.est, cens.size = 2, cens.shape = 3, back.white = FALSE, xlab = "Time", ylab = "Survival", main = "", order.legend = TRUE ) } \arguments{ \item{s}{an object of class \code{survfit}} \item{CI}{should a confidence interval be plotted? Defaults to \code{TRUE} for single stratum objects and \code{FALSE} for multiple strata objects.} \item{plot.cens}{mark the censored observations?} \item{surv.col}{colour of the survival estimate. Defaults to black for one stratum, and to the default \pkg{ggplot2} colours for multiple strata. Length of vector with colour names should be either 1 or equal to the number of strata.} \item{cens.col}{colour of the points that mark censored observations.} \item{lty.est}{linetype of the survival curve(s). Vector length should be either 1 or equal to the number of strata.} \item{lty.ci}{linetype of the bounds that mark the 95\% CI.} \item{size.est}{line width of the survival curve} \item{size.ci}{line width of the 95\% CI} \item{cens.size}{point size of the censoring points} \item{cens.shape}{shape of the points that mark censored observations.} \item{back.white}{if TRUE the background will not be the default grey of \code{ggplot2} but will be white with borders around the plot.} \item{xlab}{the label of the x-axis.} \item{ylab}{the label of the y-axis.} \item{main}{the plot label.} \item{order.legend}{boolean to determine if the legend display should be ordered by final survival time} } \value{ An object of class \code{ggplot} } \description{ This function produces Kaplan-Meier plots using \pkg{ggplot2}. As a first argument it needs a \code{survfit} object, created by the \code{survival} package. Default settings differ for single stratum and multiple strata objects. } \examples{ # Small function to display plots only if it's interactive p_ <- GGally::print_if_interactive if (require(survival) && require(scales)) { lung <- survival::lung sf.lung <- survival::survfit(Surv(time, status) ~ 1, data = lung) p_(ggsurv(sf.lung)) # Multiple strata examples sf.sex <- survival::survfit(Surv(time, status) ~ sex, data = lung) pl.sex <- ggsurv(sf.sex) p_(pl.sex) # Adjusting the legend of the ggsurv fit p_(pl.sex + ggplot2::guides(linetype = "none") + ggplot2::scale_colour_discrete( name = "Sex", breaks = c(1, 2), labels = c("Male", "Female") )) # Multiple factors lung2 <- dplyr::mutate(lung, older = as.factor(age > 60)) sf.sex2 <- survival::survfit(Surv(time, status) ~ sex + older, data = lung2) pl.sex2 <- ggsurv(sf.sex2) p_(pl.sex2) # Change legend title p_(pl.sex2 + labs(color = "New Title", linetype = "New Title")) # We can still adjust the plot after fitting kidney <- survival::kidney sf.kid <- survival::survfit(Surv(time, status) ~ disease, data = kidney) pl.kid <- ggsurv(sf.kid, plot.cens = FALSE) p_(pl.kid) # Zoom in to first 80 days p_(pl.kid + ggplot2::coord_cartesian(xlim = c(0, 80), ylim = c(0.45, 1))) # Add the diseases names to the plot and remove legend p_(pl.kid + ggplot2::annotate( "text", label = c("PKD", "Other", "GN", "AN"), x = c(90, 125, 5, 60), y = c(0.8, 0.65, 0.55, 0.30), size = 5, colour = scales::hue_pal( h = c(0, 360) + 15, c = 100, l = 65, h.start = 0, direction = 1 )(4) ) + ggplot2::guides(color = "none", linetype = "none")) } } \author{ Edwin Thoen } GGally/man/grab_legend.Rd0000644000176200001440000000211514527265752014742 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/ggmatrix_legend.R \name{grab_legend} \alias{grab_legend} \alias{print.legend_guide_box} \title{Grab the legend and print it as a plot} \usage{ grab_legend(p) \method{print}{legend_guide_box}(x, ..., plotNew = FALSE) } \arguments{ \item{p}{ggplot2 plot object} \item{x}{legend object that has been grabbed from a ggplot2 object} \item{...}{ignored} \item{plotNew}{boolean to determine if the \code{grid.newpage()} command and a new blank rectangle should be printed} } \description{ Grab the legend and print it as a plot } \examples{ # Small function to display plots only if it's interactive p_ <- GGally::print_if_interactive library(ggplot2) histPlot <- ggplot(iris, aes(Sepal.Length, fill = Species)) + geom_histogram(binwidth = 1 / 4) (right <- histPlot) (bottom <- histPlot + theme(legend.position = "bottom")) (top <- histPlot + theme(legend.position = "top")) (left <- histPlot + theme(legend.position = "left")) p_(grab_legend(right)) p_(grab_legend(bottom)) p_(grab_legend(top)) p_(grab_legend(left)) } GGally/man/remove_color_unless_equal.Rd0000644000176200001440000000131213664365623017761 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/gg-plots.R \name{remove_color_unless_equal} \alias{remove_color_unless_equal} \title{Remove colour mapping unless found in select mapping keys} \usage{ remove_color_unless_equal(mapping, to = c("x", "y")) } \arguments{ \item{mapping}{output of \code{ggplot2::\link[ggplot2]{aes}(...)}} \item{to}{set of mapping keys to check} } \value{ Aes mapping with colour mapping kept only if found in selected mapping keys. } \description{ Remove colour mapping unless found in select mapping keys } \examples{ mapping <- aes(x = sex, y = age, colour = sex) mapping <- aes(x = sex, y = age, colour = region) remove_color_unless_equal(mapping) } GGally/man/ggally_dot_and_box.Rd0000644000176200001440000000163514526730006016322 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/gg-plots.R \name{ggally_dot_and_box} \alias{ggally_dot_and_box} \title{Box and dot plot} \usage{ ggally_dot_and_box(data, mapping, ..., boxPlot = TRUE) } \arguments{ \item{data}{data set using} \item{mapping}{aesthetics being used} \item{...}{parameters passed to either geom_jitter or geom_boxplot} \item{boxPlot}{boolean to decide to plot either box plots (TRUE) or dot plots (FALSE)} } \description{ Place box plots or dot plots on the graph } \examples{ # Small function to display plots only if it's interactive p_ <- GGally::print_if_interactive data(tips) p_(ggally_dot_and_box( tips, mapping = ggplot2::aes(x = total_bill, y = sex, color = sex), boxPlot = TRUE )) p_(ggally_dot_and_box( tips, mapping = ggplot2::aes(x = total_bill, y = sex, color = sex), boxPlot = FALSE )) } \author{ Barret Schloerke } \keyword{internal} GGally/man/ggally_nostic_hat.Rd0000644000176200001440000000365013764714663016212 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/ggnostic.R \name{ggally_nostic_hat} \alias{ggally_nostic_hat} \title{\code{\link{ggnostic}} leverage points} \usage{ ggally_nostic_hat( data, mapping, ..., linePosition = 2 * sum(eval_data_col(data, mapping$y))/nrow(data), lineColor = brew_colors("grey"), lineSize = 0.5, lineAlpha = 1, lineType = 2, avgLinePosition = sum(eval_data_col(data, mapping$y))/nrow(data), avgLineColor = brew_colors("grey"), avgLineSize = lineSize, avgLineAlpha = lineAlpha, avgLineType = 1 ) } \arguments{ \item{data, mapping, ...}{supplied directly to \code{\link{ggally_nostic_line}}} \item{linePosition, lineColor, lineSize, lineAlpha, lineType}{parameters supplied to \code{\link[ggplot2:geom_path]{ggplot2::geom_line()}} for the cutoff line} \item{avgLinePosition, avgLineColor, avgLineSize, avgLineAlpha, avgLineType}{parameters supplied to \code{\link[ggplot2:geom_path]{ggplot2::geom_line()}} for the average line} } \value{ \pkg{ggplot2} plot object } \description{ A function to display stats::influence's hat information against a given explanatory variable. } \details{ As stated in \code{\link[stats:lm.influence]{stats::influence()}} documentation: hat: a vector containing the diagonal of the 'hat' matrix. The diagonal elements of the 'hat' matrix describe the influence each response value has on the fitted value for that same observation. A suggested "cutoff" line is added to the plot at a height of 2 * p / n and an expected line at a height of p / n. If either \code{linePosition} or \code{avgLinePosition} is \code{NULL}, the respective line will not be drawn. } \examples{ # Small function to display plots only if it's interactive p_ <- GGally::print_if_interactive dt <- broomify(stats::lm(mpg ~ wt + qsec + am, data = mtcars)) p_(ggally_nostic_hat(dt, ggplot2::aes(wt, .hat))) } \seealso{ \code{\link[stats:lm.influence]{stats::influence()}} } GGally/man/get_x_axis_labels.Rd0000644000176200001440000000055513663637143016170 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/gg-plots.R \name{get_x_axis_labels} \alias{get_x_axis_labels} \title{Get x axis labels} \usage{ get_x_axis_labels(p, xRange) } \arguments{ \item{p}{plot object} \item{xRange}{range of x values} } \description{ Retrieves x axis labels from the plot object directly. } \keyword{internal} GGally/man/ggally_box.Rd0000644000176200001440000000166014527265752014644 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/gg-plots.R \name{ggally_box} \alias{ggally_box} \alias{ggally_box_no_facet} \title{Box plot} \usage{ ggally_box(data, mapping, ...) ggally_box_no_facet(data, mapping, ...) } \arguments{ \item{data}{data set using} \item{mapping}{aesthetics being used} \item{...}{other arguments being supplied to geom_boxplot} } \description{ Make a box plot with a given data set. \code{ggally_box_no_facet} will be a single panel plot, while \code{ggally_box} will be a faceted plot } \examples{ # Small function to display plots only if it's interactive p_ <- GGally::print_if_interactive data(tips) p_(ggally_box(tips, mapping = ggplot2::aes(x = total_bill, y = sex))) p_(ggally_box( tips, mapping = ggplot2::aes(sex, total_bill, color = sex), outlier.colour = "red", outlier.shape = 13, outlier.size = 8 )) } \author{ Barret Schloerke } \keyword{hplot} GGally/man/brew_colors.Rd0000644000176200001440000000046413663637143015033 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/ggnostic.R \name{brew_colors} \alias{brew_colors} \title{RColorBrewer Set1 colors} \usage{ brew_colors(col) } \arguments{ \item{col}{standard color name used to retrieve hex color value} } \description{ RColorBrewer Set1 colors } GGally/man/wrap.Rd0000644000176200001440000000661514527265752013473 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/ggpairs_internal_plots.R \name{wrap_fn_with_param_arg} \alias{wrap_fn_with_param_arg} \alias{wrapp} \alias{wrap} \alias{wrap_fn_with_params} \title{Wrap a function with different parameter values} \usage{ wrap_fn_with_param_arg( funcVal, params = NULL, funcArgName = deparse(substitute(funcVal)) ) wrapp(funcVal, params = NULL, funcArgName = deparse(substitute(funcVal))) wrap(funcVal, ..., funcArgName = deparse(substitute(funcVal))) wrap_fn_with_params(funcVal, ..., funcArgName = deparse(substitute(funcVal))) } \arguments{ \item{funcVal}{function that the \code{params} will be applied to. The function should follow the api of \code{function(data, mapping, ...)\{\}}. \code{funcVal} is allowed to be a string of one of the \code{ggally_NAME} functions, such as \code{"points"} for \code{ggally_points} or \code{"facetdensity"} for \code{ggally_facetdensity}.} \item{params}{named vector or list of parameters to be applied to the \code{funcVal}} \item{funcArgName}{name of function to be displayed} \item{...}{named parameters to be supplied to \code{wrap_fn_with_param_arg}} } \value{ a \code{function(data, mapping, ...)\{\}} that will wrap the original function with the parameters applied as arguments } \description{ Wraps a function with the supplied parameters to force different default behavior. This is useful for functions that are supplied to ggpairs. It allows you to change the behavior of one function, rather than creating multiple functions with different parameter settings. } \details{ \code{wrap} is identical to \code{wrap_fn_with_params}. These function take the new parameters as arguments. \code{wrapp} is identical to \code{wrap_fn_with_param_arg}. These functions take the new parameters as a single list. The \code{params} and \code{fn} attributes are there for debugging purposes. If either attribute is altered, the function must be re-wrapped to have the changes take effect. } \examples{ # small function to display plots only if it's interactive p_ <- GGally::print_if_interactive # example function that prints 'val' fn <- function(data, mapping, val = 2) { print(val) } fn(data = NULL, mapping = NULL) # 2 # wrap function to change default value 'val' to 5 instead of 2 wrapped_fn1 <- wrap(fn, val = 5) wrapped_fn1(data = NULL, mapping = NULL) # 5 # you may still supply regular values wrapped_fn1(data = NULL, mapping = NULL, val = 3) # 3 # wrap function to change 'val' to 5 using the arg list wrapped_fn2 <- wrap_fn_with_param_arg(fn, params = list(val = 5)) wrapped_fn2(data = NULL, mapping = NULL) # 5 # change parameter settings in ggpairs for a particular function ## Goal output: regularPlot <- ggally_points( iris, ggplot2::aes(Sepal.Length, Sepal.Width), size = 5, color = "red" ) p_(regularPlot) # Wrap ggally_points to have parameter values size = 5 and color = 'red' w_ggally_points <- wrap(ggally_points, size = 5, color = "red") wrappedPlot <- w_ggally_points( iris, ggplot2::aes(Sepal.Length, Sepal.Width) ) p_(wrappedPlot) # Double check the aes parameters are the same for the geom_point layer identical(regularPlot$layers[[1]]$aes_params, wrappedPlot$layers[[1]]$aes_params) # Use a wrapped function in ggpairs pm <- ggpairs(iris, 1:3, lower = list(continuous = wrap(ggally_points, size = 5, color = "red"))) p_(pm) pm <- ggpairs(iris, 1:3, lower = list(continuous = w_ggally_points)) p_(pm) } GGally/man/v1_ggmatrix_theme.Rd0000644000176200001440000000115213666472400016114 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/deprecated.R \name{v1_ggmatrix_theme} \alias{v1_ggmatrix_theme} \title{Modify a \code{\link{ggmatrix}} object by adding an \pkg{ggplot2} object to all} \usage{ v1_ggmatrix_theme() } \description{ Modify a \code{\link{ggmatrix}} object by adding an \pkg{ggplot2} object to all } \examples{ # Small function to display plots only if it's interactive p_ <- GGally::print_if_interactive p_(ggpairs(iris, 1:2) + v1_ggmatrix_theme()) # move the column names to the left and bottom p_(ggpairs(iris, 1:2, switch = "both") + v1_ggmatrix_theme()) } GGally/man/ggally_facetdensity.Rd0000644000176200001440000000141614527265752016535 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/gg-plots.R \name{ggally_facetdensity} \alias{ggally_facetdensity} \title{Faceted density plot} \usage{ ggally_facetdensity(data, mapping, ...) } \arguments{ \item{data}{data set using} \item{mapping}{aesthetics being used} \item{...}{other arguments being sent to stat_density} } \description{ Make density plots by displaying subsets of the data in different panels. } \examples{ # Small function to display plots only if it's interactive p_ <- GGally::print_if_interactive data(tips) p_(ggally_facetdensity(tips, mapping = ggplot2::aes(x = total_bill, y = sex))) p_(ggally_facetdensity( tips, mapping = ggplot2::aes(sex, total_bill, color = sex) )) } \author{ Barret Schloerke } \keyword{hplot} GGally/man/ggally_density.Rd0000644000176200001440000000203314527265752015526 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/gg-plots.R \name{ggally_density} \alias{ggally_density} \title{Bivariate density plot} \usage{ ggally_density(data, mapping, ...) } \arguments{ \item{data}{data set using} \item{mapping}{aesthetics being used} \item{...}{parameters sent to either stat_density2d or geom_density2d} } \description{ Make a 2D density plot from a given data. } \details{ The aesthetic "fill" determines whether or not \code{stat_density2d} (filled) or \code{geom_density2d} (lines) is used. } \examples{ # Small function to display plots only if it's interactive p_ <- GGally::print_if_interactive data(tips) p_(ggally_density(tips, mapping = ggplot2::aes(x = total_bill, y = tip))) p_(ggally_density( tips, mapping = ggplot2::aes(total_bill, tip, fill = after_stat(level)) )) p_(ggally_density( tips, mapping = ggplot2::aes(total_bill, tip, fill = after_stat(level)) ) + ggplot2::scale_fill_gradient(breaks = c(0.05, 0.1, 0.15, 0.2))) } \author{ Barret Schloerke } \keyword{hplot} GGally/man/ggnet.Rd0000644000176200001440000002205114526734600013606 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/ggnet.R \name{ggnet} \alias{ggnet} \title{Network plot} \usage{ ggnet( net, mode = "fruchtermanreingold", layout.par = NULL, layout.exp = 0, size = 9, alpha = 1, weight = "none", weight.legend = NA, weight.method = weight, weight.min = NA, weight.max = NA, weight.cut = FALSE, group = NULL, group.legend = NA, node.group = group, node.color = NULL, node.alpha = alpha, segment.alpha = alpha, segment.color = "grey50", segment.label = NULL, segment.size = 0.25, arrow.size = 0, arrow.gap = 0, arrow.type = "closed", label = FALSE, label.nodes = label, label.size = size/2, label.trim = FALSE, legend.size = 9, legend.position = "right", names = c("", ""), quantize.weights = FALSE, subset.threshold = 0, top8.nodes = FALSE, trim.labels = FALSE, ... ) } \arguments{ \item{net}{an object of class \code{\link[network]{network}}, or any object that can be coerced to this class, such as an adjacency or incidence matrix, or an edge list: see \link[network]{edgeset.constructors} and \link[network]{network} for details. If the object is of class \link[igraph:aaa-igraph-package]{igraph} and the \link[intergraph:intergraph-package]{intergraph} package is installed, it will be used to convert the object: see \code{\link[intergraph]{asNetwork}} for details.} \item{mode}{a placement method from those provided in the \code{\link[sna]{sna}} package: see \link[sna:gplot.layout]{gplot.layout} for details. Also accepts the names of two numeric vertex attributes of \code{net}, or a matrix of numeric coordinates, in which case the first two columns of the matrix are used. Defaults to the Fruchterman-Reingold force-directed algorithm.} \item{layout.par}{options to be passed to the placement method, as listed in \link[sna]{gplot.layout}. Defaults to \code{NULL}.} \item{layout.exp}{a multiplier to expand the horizontal axis if node labels get clipped: see \link[scales]{expand_range} for details. Defaults to \code{0} (no expansion).} \item{size}{size of the network nodes. If the nodes are weighted, their area is proportionally scaled up to the size set by \code{size}. Defaults to \code{9}.} \item{alpha}{a level of transparency for nodes, vertices and arrows. Defaults to \code{1}.} \item{weight}{the weighting method for the nodes, which might be a vertex attribute or a vector of size values. Also accepts \code{"indegree"}, \code{"outdegree"}, \code{"degree"} or \code{"freeman"} to size the nodes by their unweighted degree centrality (\code{"degree"} and \code{"freeman"} are equivalent): see \code{\link[sna]{degree}} for details. All node weights must be positive. Defaults to \code{"none"} (no weighting).} \item{weight.legend}{the name to assign to the legend created by \code{weight}. Defaults to \code{NA} (no name).} \item{weight.method}{see \code{weight}} \item{weight.min}{whether to subset the network to nodes with a minimum size, based on the values of \code{weight}. Defaults to \code{NA} (preserves all nodes).} \item{weight.max}{whether to subset the network to nodes with a maximum size, based on the values of \code{weight}. Defaults to \code{NA} (preserves all nodes).} \item{weight.cut}{whether to cut the size of the nodes into a certain number of quantiles. Accepts \code{TRUE}, which tries to cut the sizes into quartiles, or any positive numeric value, which tries to cut the sizes into that many quantiles. If the size of the nodes do not contain the specified number of distinct quantiles, the largest possible number is used. See \code{\link[stats]{quantile}} and \code{\link[base]{cut}} for details. Defaults to \code{FALSE} (does nothing).} \item{group}{the groups of the nodes, either as a vector of values or as a vertex attribute. If set to \code{mode} on a bipartite network, the nodes will be grouped as \code{"actor"} if they belong to the primary mode and \code{"event"} if they belong to the secondary mode.} \item{group.legend}{the name to assign to the legend created by \code{group}.} \item{node.group}{see \code{group}} \item{node.color}{a vector of character strings to color the nodes with, holding as many colors as there are levels in \code{node.group}. Defaults to \code{NULL}, which will assign grayscale colors to each group.} \item{node.alpha}{transparency of the nodes. Inherits from \code{alpha}.} \item{segment.alpha}{the level of transparency of the edges. Defaults to \code{alpha}, which defaults to \code{1}.} \item{segment.color}{the color of the edges, as a color value, a vector of color values, or as an edge attribute containing color values. Defaults to \code{"grey50"}.} \item{segment.label}{the labels to plot at the middle of the edges, as a single value, a vector of values, or as an edge attribute. Defaults to \code{NULL} (no edge labels).} \item{segment.size}{the size of the edges, in points, as a single numeric value, a vector of values, or as an edge attribute. Defaults to \code{0.25}.} \item{arrow.size}{the size of the arrows for directed network edges, in points. See \code{\link[grid]{arrow}} for details. Defaults to \code{0} (no arrows).} \item{arrow.gap}{a setting aimed at improving the display of edge arrows by plotting slightly shorter edges. Accepts any value between \code{0} and \code{1}, where a value of \code{0.05} will generally achieve good results when the size of the nodes is reasonably small. Defaults to \code{0} (no shortening).} \item{arrow.type}{the type of the arrows for directed network edges. See \code{\link[grid]{arrow}} for details. Defaults to \code{"closed"}.} \item{label}{whether to label the nodes. If set to \code{TRUE}, nodes are labeled with their vertex names. If set to a vector that contains as many elements as there are nodes in \code{net}, nodes are labeled with these. If set to any other vector of values, the nodes are labeled only when their vertex name matches one of these values. Defaults to \code{FALSE} (no labels).} \item{label.nodes}{see \code{label}} \item{label.size}{the size of the node labels, in points, as a numeric value, a vector of numeric values, or as a vertex attribute containing numeric values. Defaults to \code{size / 2} (half the maximum node size), which defaults to \code{6}.} \item{label.trim}{whether to apply some trimming to the node labels. Accepts any function that can process a character vector, or a strictly positive numeric value, in which case the labels are trimmed to a fixed-length substring of that length: see \code{\link[base]{substr}} for details. Defaults to \code{FALSE} (does nothing).} \item{legend.size}{the size of the legend symbols and text, in points. Defaults to \code{9}.} \item{legend.position}{the location of the plot legend(s). Accepts all \code{legend.position} values supported by \code{\link[ggplot2]{theme}}. Defaults to \code{"right"}.} \item{names}{deprecated: see \code{group.legend} and \code{size.legend}} \item{quantize.weights}{deprecated: see \code{weight.cut}} \item{subset.threshold}{deprecated: see \code{weight.min}} \item{top8.nodes}{deprecated: this functionality was experimental and has been removed entirely from \code{ggnet}} \item{trim.labels}{deprecated: see \code{label.trim}} \item{...}{other arguments passed to the \code{geom_text} object that sets the node labels: see \code{\link[ggplot2]{geom_text}} for details.} } \description{ Function for plotting network objects using \pkg{ggplot2}, now replaced by the \code{\link{ggnet2}} function, which provides additional control over plotting parameters. Please visit \url{https://github.com/briatte/ggnet} for the latest version of ggnet2, and \url{https://briatte.github.io/ggnet/} for a vignette that contains many examples and explanations. } \details{ The degree centrality measures that can be produced through the \code{weight} argument will take the directedness of the network into account, but will be unweighted. To compute weighted network measures, see the \code{tnet} package by Tore Opsahl (\code{help("tnet", package = "tnet")}). } \examples{ # Small function to display plots only if it's interactive p_ <- GGally::print_if_interactive library(network) # random adjacency matrix x <- 10 ndyads <- x * (x - 1) density <- x / ndyads m <- matrix(0, nrow = x, ncol = x) dimnames(m) <- list(letters[1:x], letters[1:x]) m[row(m) != col(m)] <- runif(ndyads) < density m # random undirected network n <- network::network(m, directed = FALSE) n ggnet(n, label = TRUE, alpha = 1, color = "white", segment.color = "black") # random groups g <- sample(letters[1:3], 10, replace = TRUE) g # color palette p <- c("a" = "steelblue", "b" = "forestgreen", "c" = "tomato") p_(ggnet(n, node.group = g, node.color = p, label = TRUE, color = "white")) # edge arrows on a directed network p_(ggnet(network(m, directed = TRUE), arrow.gap = 0.05, arrow.size = 10)) } \seealso{ \code{\link{ggnet2}} in this package, \code{\link[sna]{gplot}} in the \code{\link[sna]{sna}} package, and \code{\link[network]{plot.network}} in the \code{\link[network]{network}} package } \author{ Moritz Marbach and Francois Briatte, with help from Heike Hofmann, Pedro Jordano and Ming-Yu Liu } GGally/man/ggally_blank.Rd0000644000176200001440000000075413764714663015150 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/gg-plots.R \name{ggally_blank} \alias{ggally_blank} \alias{ggally_blankDiag} \title{Blank plot} \usage{ ggally_blank(...) ggally_blankDiag(...) } \arguments{ \item{...}{other arguments ignored} } \description{ Draws nothing. } \details{ Makes a "blank" ggplot object that will only draw white space } \seealso{ \code{\link[ggplot2:element]{ggplot2::element_blank()}} } \author{ Barret Schloerke } \keyword{hplot} GGally/man/add_ref_boxes.Rd0000644000176200001440000000135114321334313015254 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/gglyph.R \name{add_ref_boxes} \alias{add_ref_boxes} \title{Add reference boxes around each cell of the glyphmap.} \usage{ add_ref_boxes( data, var_fill = NULL, color = "white", size = 0.5, fill = NA, ... ) } \arguments{ \item{data}{A glyphmap structure.} \item{var_fill}{Variable name to use to set the fill color} \item{color}{Set the color to draw in, default is "white"} \item{size}{Set the line size, default is 0.5} \item{fill}{fill value used if \code{var_fill} is \code{NULL}} \item{...}{other arguments passed onto \code{\link[ggplot2:geom_tile]{ggplot2::geom_rect()}}} } \description{ Add reference boxes around each cell of the glyphmap. } GGally/man/scag_order.Rd0000644000176200001440000000117413761572054014620 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/ggparcoord.R \name{scag_order} \alias{scag_order} \title{Find order of variables} \usage{ scag_order(scag, vars, measure) } \arguments{ \item{scag}{\code{scagnostics} object} \item{vars}{character vector of the variables to be ordered} \item{measure}{scagnostics measure to order according to} } \value{ character vector of variable ordered according to the given scagnostic measure } \description{ Find order of variables based on a specified scagnostic measure by maximizing the index values of that measure along the path. } \author{ Barret Schloerke } GGally/man/ggally_table.Rd0000644000176200001440000000437414527265752015150 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/ggally_cross.R \name{ggally_table} \alias{ggally_table} \alias{ggally_tableDiag} \title{Display a table of the number of observations} \usage{ ggally_table( data, mapping, keep.zero.cells = FALSE, ..., geom_tile_args = NULL ) ggally_tableDiag( data, mapping, keep.zero.cells = FALSE, ..., geom_tile_args = NULL ) } \arguments{ \item{data}{data set using} \item{mapping}{aesthetics being used} \item{keep.zero.cells}{If \code{TRUE}, display cells with no observation.} \item{...}{other arguments passed to \code{\link[ggplot2]{geom_text}(...)}} \item{geom_tile_args}{other arguments passed to \code{\link[ggplot2]{geom_tile}(...)}} } \description{ Plot the number of observations as a table. Other statistics computed by \code{\link{stat_cross}} could be used (see examples). } \note{ The \strong{colour} aesthetic is taken into account only if equal to \strong{x} or \strong{y}. } \examples{ # Small function to display plots only if it's interactive p_ <- GGally::print_if_interactive data(tips) p_(ggally_table(tips, mapping = aes(x = smoker, y = sex))) p_(ggally_table(tips, mapping = aes(x = day, y = time))) p_(ggally_table(tips, mapping = aes(x = smoker, y = sex, colour = smoker))) # colour is kept only if equal to x or y p_(ggally_table(tips, mapping = aes(x = smoker, y = sex, colour = day))) # diagonal version p_(ggally_tableDiag(tips, mapping = aes(x = smoker))) # custom label size and color p_(ggally_table(tips, mapping = aes(x = smoker, y = sex), size = 16, color = "red")) # display column proportions p_(ggally_table( tips, mapping = aes(x = day, y = sex, label = scales::percent(after_stat(col.prop))) )) # draw table cells p_(ggally_table( tips, mapping = aes(x = smoker, y = sex), geom_tile_args = list(colour = "black", fill = "white") )) # Use standardized residuals to fill table cells p_(ggally_table( as.data.frame(Titanic), mapping = aes( x = Class, y = Survived, weight = Freq, fill = after_stat(std.resid), label = scales::percent(after_stat(col.prop), accuracy = .1) ), geom_tile_args = list(colour = "black") ) + scale_fill_steps2(breaks = c(-3, -2, 2, 3), show.limits = TRUE)) } \author{ Joseph Larmarange } \keyword{hplot} GGally/man/ggally_diagAxis.Rd0000644000176200001440000000234014526730006015565 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/gg-plots.R \name{ggally_diagAxis} \alias{ggally_diagAxis} \title{Internal axis labels for ggpairs} \usage{ ggally_diagAxis( data, mapping, label = mapping$x, labelSize = 5, labelXPercent = 0.5, labelYPercent = 0.55, labelHJust = 0.5, labelVJust = 0.5, gridLabelSize = 4, ... ) } \arguments{ \item{data}{dataset being plotted} \item{mapping}{aesthetics being used (x is the variable the plot will be made for)} \item{label}{title to be displayed in the middle. Defaults to \code{mapping$x}} \item{labelSize}{size of variable label} \item{labelXPercent}{percent of horizontal range} \item{labelYPercent}{percent of vertical range} \item{labelHJust}{hjust supplied to label} \item{labelVJust}{vjust supplied to label} \item{gridLabelSize}{size of grid labels} \item{...}{other arguments for geom_text} } \description{ This function is used when \code{axisLabels == "internal"}. } \examples{ # Small function to display plots only if it's interactive p_ <- GGally::print_if_interactive data(tips) p_(ggally_diagAxis(tips, ggplot2::aes(x = tip))) p_(ggally_diagAxis(tips, ggplot2::aes(x = sex))) } \author{ Jason Crowley and Barret Schloerke } GGally/man/ggally_summarise_by.Rd0000644000176200001440000000473414526730006016544 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/gg-plots.R \name{ggally_summarise_by} \alias{ggally_summarise_by} \alias{weighted_median_iqr} \alias{weighted_mean_sd} \title{Summarize a continuous variable by each value of a discrete variable} \usage{ ggally_summarise_by( data, mapping, text_fn = weighted_median_iqr, text_fn_vertical = NULL, ... ) weighted_median_iqr(x, weights = NULL) weighted_mean_sd(x, weights = NULL) } \arguments{ \item{data}{data set using} \item{mapping}{aesthetics being used} \item{text_fn}{function that takes an x and weights and returns a text string} \item{text_fn_vertical}{function that takes an x and weights and returns a text string, used when \code{x} is discrete and \code{y} is continuous. If not provided, will use \code{text_fn}, replacing spaces by carriage returns.} \item{...}{other arguments passed to \code{\link[ggplot2]{geom_text}(...)}} \item{x}{a numeric vector} \item{weights}{an optional numeric vectors of weights. If \code{NULL}, equal weights of 1 will be taken into account.} } \description{ Display summary statistics of a continuous variable for each value of a discrete variable. } \details{ \code{weighted_median_iqr} computes weighted median and interquartile range. \code{weighted_mean_sd} computes weighted mean and standard deviation. } \examples{ # Small function to display plots only if it's interactive p_ <- GGally::print_if_interactive if (require(Hmisc)) { data(tips) p_(ggally_summarise_by(tips, mapping = aes(x = total_bill, y = day))) p_(ggally_summarise_by(tips, mapping = aes(x = day, y = total_bill))) # colour is kept only if equal to the discrete variable p_(ggally_summarise_by(tips, mapping = aes(x = total_bill, y = day, color = day))) p_(ggally_summarise_by(tips, mapping = aes(x = total_bill, y = day, color = sex))) p_(ggally_summarise_by(tips, mapping = aes(x = day, y = total_bill, color = day))) # custom text size p_(ggally_summarise_by(tips, mapping = aes(x = total_bill, y = day), size = 6)) # change statistic to display p_(ggally_summarise_by(tips, mapping = aes(x = total_bill, y = day), text_fn = weighted_mean_sd)) # custom stat function weighted_sum <- function(x, weights = NULL) { if (is.null(weights)) weights <- 1 paste0("Total : ", round(sum(x * weights, na.rm = TRUE), digits = 1)) } p_(ggally_summarise_by(tips, mapping = aes(x = total_bill, y = day), text_fn = weighted_sum)) } } \author{ Joseph Larmarange } \keyword{hplot} GGally/man/ggscatmat.Rd0000644000176200001440000000240213666472400014453 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/ggscatmat.R \name{ggscatmat} \alias{ggscatmat} \title{Traditional scatterplot matrix for purely quantitative variables} \usage{ ggscatmat( data, columns = 1:ncol(data), color = NULL, alpha = 1, corMethod = "pearson" ) } \arguments{ \item{data}{a data matrix. Should contain numerical (continuous) data.} \item{columns}{an option to choose the column to be used in the raw dataset. Defaults to \code{1:ncol(data)}.} \item{color}{an option to group the dataset by the factor variable and color them by different colors. Defaults to \code{NULL}, i.e. no coloring. If supplied, it will be converted to a factor.} \item{alpha}{an option to set the transparency in scatterplots for large data. Defaults to \code{1}.} \item{corMethod}{method argument supplied to \code{\link[stats]{cor}}} } \description{ This function makes a scatterplot matrix for quantitative variables with density plots on the diagonal and correlation printed in the upper triangle. } \examples{ # small function to display plots only if it's interactive p_ <- GGally::print_if_interactive data(flea) p_(ggscatmat(flea, columns = 2:4)) p_(ggscatmat(flea, columns = 2:4, color = "species")) } \author{ Mengjia Ni, Di Cook } GGally/man/print.ggmatrix.Rd0000644000176200001440000000135514527265752015473 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/ggmatrix_print.R \name{print.ggmatrix} \alias{print.ggmatrix} \title{Print \code{\link{ggmatrix}} object} \usage{ \method{print}{ggmatrix}(x, newpage = is.null(vp), vp = NULL, ...) } \arguments{ \item{x}{plot to display} \item{newpage}{draw new (empty) page first?} \item{vp}{viewport to draw plot in} \item{...}{arguments passed onto \code{\link{ggmatrix_gtable}}} } \description{ Print method taken from \code{ggplot2:::print.ggplot} and altered for a \code{\link{ggmatrix}} object } \examples{ data(tips) pMat <- ggpairs(tips, c(1, 3, 2), mapping = ggplot2::aes(color = sex)) pMat # calls print(pMat), which calls print.ggmatrix(pMat) } \author{ Barret Schloerke } GGally/man/plot_types.Rd0000644000176200001440000000060613665760216014713 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/find-combo.R \name{plot_types} \alias{plot_types} \title{Plot Types} \usage{ plot_types(data, columnsX, columnsY, allowDiag = TRUE) } \arguments{ \item{data}{data set to be used} } \description{ Retrieves the type of plot that should be used for all combinations } \author{ Barret Schloerke } \keyword{internal} GGally/man/ggmatrix_location.Rd0000644000176200001440000000461314526730006016214 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/ggpairs_add.R \name{ggmatrix_location} \alias{ggmatrix_location} \title{\code{\link{ggmatrix}} plot locations} \usage{ ggmatrix_location(pm, location = NULL, rows = NULL, cols = NULL) } \arguments{ \item{pm}{\code{\link{ggmatrix}} plot object} \item{location}{\describe{ \item{\code{"all"}, \code{TRUE}}{All row and col combinations} \item{\code{"none"}}{No row and column combinations} \item{\code{"upper"}}{Locations where the column value is higher than the row value} \item{\code{"lower"}}{Locations where the row value is higher than the column value} \item{\code{"diag"}}{Locations where the column value is equal to the row value} \item{\code{matrix} or \code{data.frame}}{ \code{matrix} values will be converted into \code{data.frame}s. \itemize{ \item A \code{data.frame} with the exact column names \code{c("row", "col")} \item A \code{data.frame} with the number of rows and columns matching the plot matrix object provided. Each cell will be tested for a "truthy" value to determine if the location should be kept. } } }} \item{rows}{numeric vector of the rows to be used. Will be used with \code{cols} if \code{location} is \code{NULL}} \item{cols}{numeric vector of the cols to be used. Will be used with \code{rows} if \code{location} is \code{NULL}} } \value{ Data frame with columns \code{c("row", "col")} containing locations for the plot matrix } \description{ \lifecycle{experimental} } \details{ Convert many types of location values to a consistent \code{data.frame} of \code{row} and \code{col} values. } \examples{ pm <- ggpairs(tips, 1:3) # All locations ggmatrix_location(pm, location = "all") ggmatrix_location(pm, location = TRUE) # No locations ggmatrix_location(pm, location = "none") # "upper" triangle locations ggmatrix_location(pm, location = "upper") # "lower" triangle locations ggmatrix_location(pm, location = "lower") # "diag" locations ggmatrix_location(pm, location = "diag") # specific rows ggmatrix_location(pm, rows = 2) # specific columns ggmatrix_location(pm, cols = 2) # row and column combinations ggmatrix_location(pm, rows = c(1, 2), cols = c(1, 3)) # matrix locations mat <- matrix(TRUE, ncol = 3, nrow = 3) mat[1, 1] <- FALSE locs <- ggmatrix_location(pm, location = mat) ## does not contain the 1, 1 cell locs # Use the output of a prior ggmatrix_location ggmatrix_location(pm, location = locs) } GGally/man/ggcorr.Rd0000644000176200001440000001362314527265752014002 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/ggcorr.R \name{ggcorr} \alias{ggcorr} \title{Correlation matrix} \usage{ ggcorr( data, method = c("pairwise", "pearson"), cor_matrix = NULL, nbreaks = NULL, digits = 2, name = "", low = "#3B9AB2", mid = "#EEEEEE", high = "#F21A00", midpoint = 0, palette = NULL, geom = "tile", min_size = 2, max_size = 6, label = FALSE, label_alpha = FALSE, label_color = "black", label_round = 1, label_size = 4, limits = c(-1, 1), drop = is.null(limits) || identical(limits, FALSE), layout.exp = 0, legend.position = "right", legend.size = 9, ... ) } \arguments{ \item{data}{a data frame or matrix containing numeric (continuous) data. If any of the columns contain non-numeric data, they will be dropped with a warning.} \item{method}{a vector of two character strings. The first value gives the method for computing covariances in the presence of missing values, and must be (an abbreviation of) one of \code{"everything"}, \code{"all.obs"}, \code{"complete.obs"}, \code{"na.or.complete"} or \code{"pairwise.complete.obs"}. The second value gives the type of correlation coefficient to compute, and must be one of \code{"pearson"}, \code{"kendall"} or \code{"spearman"}. See \code{\link[stats]{cor}} for details. Defaults to \code{c("pairwise", "pearson")}.} \item{cor_matrix}{the named correlation matrix to use for calculations. Defaults to the correlation matrix of \code{data} when \code{data} is supplied.} \item{nbreaks}{the number of breaks to apply to the correlation coefficients, which results in a categorical color scale. See 'Note'. Defaults to \code{NULL} (no breaks, continuous scaling).} \item{digits}{the number of digits to show in the breaks of the correlation coefficients: see \code{\link[base]{cut}} for details. Defaults to \code{2}.} \item{name}{a character string for the legend that shows the colors of the correlation coefficients. Defaults to \code{""} (no legend name).} \item{low}{the lower color of the gradient for continuous scaling of the correlation coefficients. Defaults to \code{"#3B9AB2"} (blue).} \item{mid}{the midpoint color of the gradient for continuous scaling of the correlation coefficients. Defaults to \code{"#EEEEEE"} (very light grey).} \item{high}{the upper color of the gradient for continuous scaling of the correlation coefficients. Defaults to \code{"#F21A00"} (red).} \item{midpoint}{the midpoint value for continuous scaling of the correlation coefficients. Defaults to \code{0}.} \item{palette}{if \code{nbreaks} is used, a ColorBrewer palette to use instead of the colors specified by \code{low}, \code{mid} and \code{high}. Defaults to \code{NULL}.} \item{geom}{the geom object to use. Accepts either \code{"tile"}, \code{"circle"}, \code{"text"} or \code{"blank"}.} \item{min_size}{when \code{geom} has been set to \code{"circle"}, the minimum size of the circles. Defaults to \code{2}.} \item{max_size}{when \code{geom} has been set to \code{"circle"}, the maximum size of the circles. Defaults to \code{6}.} \item{label}{whether to add correlation coefficients to the plot. Defaults to \code{FALSE}.} \item{label_alpha}{whether to make the correlation coefficients increasingly transparent as they come close to 0. Also accepts any numeric value between \code{0} and \code{1}, in which case the level of transparency is set to that fixed value. Defaults to \code{FALSE} (no transparency).} \item{label_color}{the color of the correlation coefficients. Defaults to \code{"grey75"}.} \item{label_round}{the decimal rounding of the correlation coefficients. Defaults to \code{1}.} \item{label_size}{the size of the correlation coefficients. Defaults to \code{4}.} \item{limits}{bounding of color scaling for correlations, set \code{limits = NULL} or \code{FALSE} to remove} \item{drop}{if using \code{nbreaks}, whether to drop unused breaks from the color scale. Defaults to \code{FALSE} (recommended).} \item{layout.exp}{a multiplier to expand the horizontal axis to the left if variable names get clipped. Defaults to \code{0} (no expansion).} \item{legend.position}{where to put the legend of the correlation coefficients: see \code{\link[ggplot2]{theme}} for details. Defaults to \code{"bottom"}.} \item{legend.size}{the size of the legend title and labels, in points: see \code{\link[ggplot2]{theme}} for details. Defaults to \code{9}.} \item{...}{other arguments supplied to \code{\link[ggplot2]{geom_text}} for the diagonal labels.} } \description{ Function for making a correlation matrix plot, using \pkg{ggplot2}. The function is directly inspired by Tian Zheng and Yu-Sung Su's \code{corrplot} function in the 'arm' package. Please visit \url{https://github.com/briatte/ggcorr} for the latest version of \code{ggcorr}, and see the vignette at \url{https://briatte.github.io/ggcorr/} for many examples of how to use it. } \note{ Recommended values for the \code{nbreaks} argument are \code{3} to \code{11}, as values above 11 are visually difficult to separate and are not supported by diverging ColorBrewer palettes. } \examples{ # Small function to display plots only if it's interactive p_ <- GGally::print_if_interactive # Basketball statistics provided by Nathan Yau at Flowing Data. dt <- read.csv("http://datasets.flowingdata.com/ppg2008.csv") # Default output. p_(ggcorr(dt[, -1])) # Labeled output, with coefficient transparency. p_(ggcorr(dt[, -1], label = TRUE, label_alpha = TRUE )) # Custom options. p_(ggcorr( dt[, -1], name = expression(rho), geom = "circle", max_size = 10, min_size = 2, size = 3, hjust = 0.75, nbreaks = 6, angle = -45, palette = "PuOr" # colorblind safe, photocopy-able )) # Supply your own correlation matrix p_(ggcorr( data = NULL, cor_matrix = cor(dt[, -1], use = "pairwise") )) } \seealso{ \code{\link[stats]{cor}} and \code{corrplot} in the \code{arm} package. } \author{ Francois Briatte, with contributions from Amos B. Elberg and Barret Schloerke } GGally/man/ggally_nostic_cooksd.Rd0000644000176200001440000000254614527407231016707 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/ggnostic.R \name{ggally_nostic_cooksd} \alias{ggally_nostic_cooksd} \title{\code{\link{ggnostic}} Cook's distance} \usage{ ggally_nostic_cooksd( data, mapping, ..., linePosition = pf(0.5, length(attr(data, "var_x")), nrow(data) - length(attr(data, "var_x"))), lineColor = brew_colors("grey"), lineType = 2 ) } \arguments{ \item{data, mapping, ..., lineColor, lineType}{parameters supplied to \code{\link{ggally_nostic_line}}} \item{linePosition}{4 / n is the general cutoff point for Cook's Distance} } \value{ \pkg{ggplot2} plot object } \description{ A function to display \code{\link[stats:influence.measures]{stats::cooks.distance()}}. } \details{ A line is added at \eqn{F_{p,n-p}(0.5)}{F[p,n-p](0.5)} to display the general cutoff point for Cook's Distance. Reference: Michael H. Kutner, Christopher J. Nachtsheim, John Neter, and William Li. Applied linear statistical models. The McGraw-Hill / Irwin series operations and decision sciences. McGraw-Hill Irwin, 2005, p. 403 } \examples{ # Small function to display plots only if it's interactive p_ <- GGally::print_if_interactive dt <- broomify(stats::lm(mpg ~ wt + qsec + am, data = mtcars)) p_(ggally_nostic_cooksd(dt, ggplot2::aes(wt, .cooksd))) } \seealso{ \code{\link[stats:influence.measures]{stats::cooks.distance()}} } GGally/DESCRIPTION0000644000176200001440000000527314563007414013152 0ustar liggesusersPackage: GGally Version: 2.2.1 License: GPL (>= 2.0) Title: Extension to 'ggplot2' Type: Package LazyLoad: yes LazyData: true URL: https://ggobi.github.io/ggally/, https://github.com/ggobi/ggally BugReports: https://github.com/ggobi/ggally/issues Authors@R: c( person("Barret", "Schloerke", role = c("aut", "cre"), email = "schloerke@gmail.com"), person("Di", "Cook", role = c("aut", "ths"), email = "dicook@monash.edu"), person("Joseph", "Larmarange", role = "aut", email = "joseph@larmarange.net"), person("Francois", "Briatte", role = "aut", email = "f.briatte@gmail.com"), person("Moritz", "Marbach", role = "aut", email = "mmarbach@mail.uni-mannheim.de"), person("Edwin", "Thoen", role = "aut", email = "edwinthoen@gmail.com"), person("Amos", "Elberg", role = "aut", email = "amos.elberg@gmail.com"), person("Ott", "Toomet", role = "ctb", email = "otoomet@gmail.com"), person("Jason", "Crowley", role = "aut", email = "crowley.jason.s@gmail.com"), person("Heike", "Hofmann", role = "ths", email = "hofmann@iastate.edu"), person("Hadley", "Wickham", role = "ths", email = "h.wickham@gmail.com") ) Description: The R package 'ggplot2' is a plotting system based on the grammar of graphics. 'GGally' extends 'ggplot2' by adding several functions to reduce the complexity of combining geometric objects with transformed data. Some of these functions include a pairwise plot matrix, a two group pairwise plot matrix, a parallel coordinates plot, a survival plot, and several functions to plot networks. Depends: R (>= 3.1), ggplot2 (>= 3.4.4) Imports: dplyr (>= 1.0.0), tidyr (>= 1.3.0), grDevices, grid, ggstats, gtable (>= 0.2.0), lifecycle, plyr (>= 1.8.3), progress, RColorBrewer, rlang, scales (>= 1.1.0), utils, magrittr Suggests: broom (>= 0.7.0), broom.helpers (>= 1.3.0), chemometrics, geosphere (>= 1.5-1), ggforce, Hmisc, igraph (>= 1.0.1), intergraph (>= 2.0-2), labelled, maps (>= 3.1.0), mapproj, nnet, network (>= 1.17.1), scagnostics, sna (>= 2.3-2), survival, rmarkdown, roxygen2, testthat, crosstalk, knitr, spelling, emmeans, vdiffr RoxygenNote: 7.3.1 SystemRequirements: openssl Encoding: UTF-8 Language: en-US RdMacros: lifecycle Config/testthat/edition: 3 NeedsCompilation: no Packaged: 2024-02-13 19:02:36 UTC; barret Author: Barret Schloerke [aut, cre], Di Cook [aut, ths], Joseph Larmarange [aut], Francois Briatte [aut], Moritz Marbach [aut], Edwin Thoen [aut], Amos Elberg [aut], Ott Toomet [ctb], Jason Crowley [aut], Heike Hofmann [ths], Hadley Wickham [ths] Maintainer: Barret Schloerke Repository: CRAN Date/Publication: 2024-02-14 00:53:32 UTC GGally/build/0000755000176200001440000000000014562736311012540 5ustar liggesusersGGally/build/GGally.pdf0000644000176200001440000135744314562736311014433 0ustar liggesusers%PDF-1.5 % 2 0 obj << /Type /ObjStm /N 100 /First 823 /Length 1353 /Filter /FlateDecode >> stream xڽXMo:Wآ@JR@EoEHl @,Rv*[HVD,iʂqY"aF2DŽd"aRTDeLLYͤ`Zk#pF+tr% KabiO9X29S9g ٹrLiӄ)Ȣ5 #L+cڂࠧa A0gble E>KLrp)NʄNg)jdxTʔ0XRbC SdH- 3I%.8R:KC"ÁHF$0NDYymL ZN'l5!i$.%US%4\J:7Z)pU)>)^,SQR _ّqE9(Aa(\zH 3B4%`1p91E+2iM46nYR8mSRshZdNʁwڑ0p!pG }>kkbsjׯ5O(,C8tVW?U[.1on(]FѱPRX^)44uy 5fmVWY5)lC* >g.SEᚂ)qXueJMݴ佰̣u7M9|SGxOq2yTr* x?ls7BwDȗy _j7= "^~K+R)g=c2ۦ& zw{5|ch(tOMүϧh#bߖU \i@맪Hc9{7[hD'~.y'-ċ8`ΒhLL5&v/o@~UuH>6,6G6M+&"6WQCs2DW9~>_[vջܿ3,e6Vns7:'lp}$|ڠ_uGxם|=mfj.Gn(hn үO; /duVWy"meC5mz&9]'?η&; ̫XeÀ}TtޔgÙL~YrXL1 endstream endobj 393 0 obj << /Length 1023 /Filter /FlateDecode >> stream xڕWn6+ 84I 43i /@i $5ח)Ųi%Xx=>ICto<vwaaa4"prŧ% }!].}z"eyawe ibm|OɁ Nt;OF+ȧ'4‘6u"8V E*lTlrR;=cRvz- 0@`V^ca}&#ӧoŸ~^_Ef :2vK,,gqbIEXGGƏ-r5x$vH E3Z ~4$C D,fVa<If1"$#ݼ+V^uQc@S=^r-y$O4F(e+~\3P0y5]z cq[(j+;k*CR:x5P8CWlip)0 EٛT#g|eܨPc,юʭyL' jW0o$$zOrlपc{dJ@ |}3;2t5 3_Qzbu/lZrRt 40S]F/RlKÆ7g\ЦJUqX˜jcpM+A/=2 4g6(ЙUEo|l3ڛ6L][_rUUTAt+3S?CM)ї Ժ̿ڜ;RO#mҜ(Zr{}0yeCYz3]jzOy[u=.)xmy ^1I_ܭ꟫^d&# rj!$½'ɾd 3dJv.SVҕ.&iMp{) sίjʼnR mN{Mk endstream endobj 203 0 obj << /Type /ObjStm /N 100 /First 876 /Length 1759 /Filter /FlateDecode >> stream xڭXs6~BˁDǓĝi''i1ǘϗbq؀l?˷vPg2!Qif>\指!j1Ԇ1a4 IfA " d@.,4xOLs3-#Ԓi 3!# e)$!f4FQG $d b J,@KI#@C + @V5!cXCj]] ndAGdhz+O iE"E֒; Z2-R 8(̄of0e\AnQhp8\f`-A>3+c4Wj&5zp xzX xx@ hTO@y4"p<(tDQiC0O0H+-VrBeQ(3r@ĚЈBHRrjp4`lJe94XRLjȆ$քiiE^O |4.lC1;9a^~-+{sv]:^$휿e|opPk*b*T$ToG$MiUPq5:F]9-5wOyƗy\T|㢓oeh"nx "Vign8RUi4kP\ެ]4T< `* MY߬([]MtըiJgӋ1*'Z9n#݌Ջ]l}_BsZA3{9o^;cHC6|[-սuYV? (1u|ӻG7[/,)Yv+Yc /:Qme.l.n~t$5s\qynQLB$*+REm|psf}v@޷н@G\>a} ˘6I@`uT6}޾;ë*-lUY4ƈ-fÕ|_׃wfoA6'RG7XUz:B8j Nl_vvi&ge׻h:^mr{/dtI?.gۉQ52JV'h뀻<Mn?lt۹-mou*oo]tf}=>3Qo?8"KN~jGӤ:>|Ȼ_R)xKd{G.Fuk2EOi>MRφ6K*N]7I6OV~Mf[ sRU,QMpm7Y&xuYh$nܦR>uj^W kߟ_uw2Y ?v8WuyTc̲'8ϷtGuǩ$ydS<MBbxe[q=x~w9y>GWqn/ * ~IGt3rr2ny4yHa"$9Β\׋_U(ع9]&_عW$t/f=&V~}ު/?): "h9^l9Z\kD}Y_̊ɉ_#=om[5x^> stream xKo6:Zh!QH-b8 -ZQ-D'Pƻ=˶f83 9#'I켻izqyc'Fq@gtƈqFi|PoAx ȨL-rӊD"1 "j-*ףOخeeQ;'x |,7 }} |A5kz!(kK+a\eˤsT/dzٔ{E!u ]'\uO®H UiAU!.({mŐ;ʵ(W2Ezڥ73EJ|թ*2]v;dfEySRݐli"Ye{XQh+wj0x/yViC~MVLo\OL~zimaGs)a.T+r}#ffW}Vc0~6nqUP d9GڋA~Ei/C?D?[wwo?NWXT/9\*\Ov\lbY1~^$әa>ȧC=7⛶Bkk{!1cr@QP- z P(Aiz &8ŏ_f+FSۛw0'ls==LEJՓQ e4 xQ!-@}[R䙘G pa?v&JEI2[ghPKYOU g ;]=u-> p1m}`hsws ]̸h" {lGֳmoNr7|,য়_y.mǔ7VYT޹#vySwO׫ſq endstream endobj 504 0 obj << /Length 1012 /Filter /FlateDecode >> stream xϏ8Wp X1?Vc[B0*`d'۩MKHf>}?xG~{f^izG/"$Ie) }߽ E -GQM~3e7n/4Zd!'R? hI )EmSY7$/[?Hx#IQO2_/]X;&^aĒ n)oʜ~gMdy\jH!Ÿ wԚG?";^5M"/}9BDcմJC?LR)9 e(G=pP4BګQwI8p՜qq)l7QgܝQx'[5B-#=5BbPz$e224jqПuU=,l^;drl̪oʪ GP\ y߱^J}& qA~ǩM*Db3==W R,F?CLZC$W~ S7~vP2_C]![{3x >vw@3d%lJ6p әLa[^UR)BG[OPfy;KvM;כö ѝ%0["VJbVX bkhZޢ9M܀w2]cXX )G%[LP w\Bus'GJ3{KĦFSle6S|6T{>ĭeH^v ȅ:?3"lǖ4rUIjۋXMf8VLI ہI}Dh[ 6m/> stream xZK6WpEIP@ -INsi8$٦@g}/c'Nc} +/&'OsiH$A0Fv 3j6?_>}L2d9F Be^(w !źm _r~_[5a+j39M FyئmM>< FaOeAP_{L"f+<#{ߊιbQ<8Pw%t+esNHw|qB=ml%LȤ0vU׍a\sd}$;޿k#&M3")+$A/k9SS@@)9=Ѳ=֍,\f  I[d+Q?D¯[n^gIw$:~ː>CWF-vqЈ" Z_ŵ텒d(ڈ=I^38X+ۙ vUYA6cg@Pkl$쏣Jñxnx |+[KB %ݴ/a͊O>croBof&yd:6+h Zn¸"?U1<=%bV|F&>SzXWi$VX׵[LLYch[jr:\U֌::?LqRJHZ͸i.';G~tX-d՚8U&CpMW#dԁ_h X]! T~}܄fV 7-li<>+Ta8 DDIiBV7y9:LeA5C)}^?D>nToR>b2B P/ʲd U7IMq0?` endstream endobj 401 0 obj << /Type /ObjStm /N 100 /First 916 /Length 2370 /Filter /FlateDecode >> stream xڽ[Kϯ1pXŪ" l J$aDAcp}U35?VꭃSI–:%)j&ŵIVfbal \DdG= D%J aD!L5Qg$ZqKwaK-q9Hld.@ܛt (TWSe_AT+ Q,%qYIS(\;>vr 0O7|RMpOJͅGZO*UqV lPmI&+fɘ]A=  V5Փ`;4[ȗ$5.  7pO Ԇ@J KԫkX'h[qaMU wn.ܰ5 4H\h+:<( ecIà-5eH8[*Kݪq`0h6+I[߼6G_ 6$(L~@apRű Կ6 .N.K̗o_}F#6&剛oc eP-Бo X*RٳY: ([w6܌_߼ycz<ί~ޜWN~uvtͧ>\壿]}ۯn~J >С>= p˭7@|}q"Nɝ(1jcx #xxxxxxxxxxx|.8_~__4Qޜ|tqݽҵX&PƹROľe:M:?OG7Z Zr8#[9jϽ -S`]vj@SxC?CQn]0Vr#wzmwϡܛ<-k3{Mh='ϼ`5#yZR3{ntA9#p*eOs9HEC]ρF\LCiq As@P$SOˡ\`9 YC/ȺڄC_ق 8^'ɳMZ6QwQlsHE'ֻ(y%Q'dT =m;5pɨ&?[+?Qᜣm5{x<&2"ƒC]}/qwRi+~c̾XZwKŌFQh)EEѣQh=EFcggggggggg^ x-Zk^x=z^x#F7o;H[K+/!pM2M<ͩ44p@ʁ97H9 MRPn9(8l>Zvi Tfef58U2IUvs2Iu}ab>$آ9Ϲq@T<-fsPQ+8Pϭl>|΍C L8/ʹyAr>H/f Ϫ>bw]/Z;Y2ʂEb}΍3-d}@p%'XU# 99 E51wHu6S a4 ݲM97>fXP+BwQRϹqmenYweIwBsn,tgD݅nˢYg(hUxb ]ozO?u6 ݶ~?GY[z?Y}]_i9֔ pX+ʉ} ,}ul7e%آЍ8xxz[pl:HfНsȫn6sו5M8` ;[t{D(*ubq@w `w,v:ålA cf 9+k;[f8++Y',qDW3|+K3[zd캲#,v~HWv|eMzcҖڲ}Wra#x_7fmXg,R/nIukkQQKGOF(1jcjtV5:UΪFgUYjtV5:UΪFgUfխH*~ {3^dp CH?Y$A?r6!$:s~$t_AG*HoۢG@FnH[B1=+j;?5 xמ8SX4cwFi2v@J7U~jOw89{HL9:D3Xc endstream endobj 608 0 obj << /Length 1676 /Filter /FlateDecode >> stream xڽXo6_sИoc}谬a˰0hk@de›,ޗmH|r\T sB8ߋ`d>5f82M_P2K5cPtϵYmky/_y`Z@G H1)uT|d,BNJbB;H仝zBu(q`Hai Wppa(P0!%uT3n;Q? ɥM`d</Q0ġυ%! _o`Q?xR*;QD&xR&gF^<^Ӆ֒h&(HԿ'hꮴ_c:-HlvEP 3Z;TUnFF/VveNLI@ Mq|&U.V>e9 e׹ 1Q]Iɹ`x'(FV/jE2 TyXA[5]4PE7uEgg㒢xb%0:5'_-)K9p]N>QKγw1Aͷ{1}½/<b*,Ck|h̛.=27L<W~ǧ)jUQG:RO-8Jʢe/M=,.ͦ]+Nתӄ!x95l"ˍVÍ`g@PQXOK(abtڶPSw7TgL ]-$ߟ¨~d8Uj$z-߿ cި2.|>g}J+ f)~[eg<SYmw8͖ާN)Å+;8]'ϱR< ªPNM;- 5{':HܴڵMm>,5|^ZL_!:Y݊u\+:*Xxh$VPNF~ތ:Vko&wO5o 9Gn^RW*Bꄅ[Ў[]rM|4T CwݝW$%;OG[!ԥ=~Z$}zmU SQTL ? 4vja՞q roL(9tߣ8G?sW endstream endobj 620 0 obj << /Length 813 /Filter /FlateDecode >> stream xV]o0}ϯ6PiNI[ӽUE$H2 _?$&4MN)6ps}L' @N8$#ˁdI ܹϸaH$R$wYJ9d}vO(|p}@,?)cc:.sgre寻61Po3 w16Gֿ̣ |vΈ04, E"GBmX:.Cp"ezW$zg4lpWB\r92]i[ "ˏE@N:q"G\ v4T:X*A )=a7!,T立^Ȋ2=z8굮_29jrm ! `i`y]˹j<Ž<.Җ~rR#4RvmovgFy87꼨DQ BMM r &θ U>4?6E;\fGj`썦_]5ìJ0#> stream xXKo6W{BR"%"M Hw{. Ƣm"K8 fo83by_G?OFפ"DYHD)P4O@|| ug e_&FШ >Pn|TѴ}Qm?Gf*F9igFo[{O#D HI)A!"[+E60Ҫ=8 \&ǴmY20gBZ?uɎj@s 6~˭^լ~pSݎ ,"#q؜+Ei`M4*=a_&Ėd9N{#N,,ޗ")+/5 $ , 25N_ދllBv:y#*:g{]=w=Lڄ׆yj8uLZȖs{fڬJ^z[+?] yݮR})௘Qg ,l򗕩 1ׂQ |"0A"03\yIВ1ܾZ W5f)o״c&z>͊jWY:/~6Jv!zkoQ4aopݞ=[mX=KhlǢPUi2QOdLrF. R2eiW1\dSщpxA-n7R)_w7ƒ K xv$ZƆ`/w0ءkַ׬ r3Z,MBplAP  s{X#f5Iz3W>!L6yB3UWX׵~j/CcS0-aѯᦻ1+ĺO0~6/ n =Ìa>~p"~'ki8LvSXX6?=<8ctY_FE^y'w^d}Bf?w|r endstream endobj 644 0 obj << /Length 1089 /Filter /FlateDecode >> stream xڥV]s8}flYHuIgӑAq"y+D upjX!_{tt00x7i5[Ppf!@ aPU܇iy~y҃$rftKBɵ(v ~ qdvf1;_PЇ7o0Cڀ %.н0X 8e  S7z(ɥ+S)=qB3bR__B@FT3ux%~'$ z I: 8W. @Qc||%N頿r||x)^՗ @ c4KȮVJ*Uԕ2H:@\{CTF#.!@'Oqmo"j -Z;\D0[-G^;P;7N03ȶ0$i-1B v$ f1`Mx&!?bSP|Z>4IBݘ+;`ݨ o?WJlҧs])e.PQlD61 *k6~X404luaFl ҢܒAi ̽!]_+m\?R|ߵv{ ISι Cj߯YۋPݓU´ aN6PtEiörLiќqnV|7Y!Ɖ4.Ik;xVW7UVخ[AJ>In‘3%+b.__TYe~;l~ؼd; 60 f+]#CnY=]'n+ݵMJ4XRsw"Pjh}ti,򹅾ǹfO7?wMb@Hid6mg}h)OԚ3s yoQç0'k9jKX'2Mk,vV;:t4 endstream endobj 658 0 obj << /Length 786 /Filter /FlateDecode >> stream xڭVMo0 W"߻Zu0-Qlrɶ:Na|$I!*A`!!B-S,3Q Y;U(QHBҪ,bOzQ=LKj|OHpeq$'W߱%Y6GJkf$~mRS[\_eK ѨI)ƳPet'"(82 |uD5DunY<,|{'et|4تfZȅ/Y>d/F&Fe^2[۔JzI<P4%YS Rzi {C5壖\!?֬FճRR\T<,ư3aϕnYC2}ˤ=>t9s)j%8MZG>%1-#'[=E%WІFD@O#^EB "nju8`˂8)߷wCB"wl KbpTwFX|??^Ǡ1lNjv&1K{R:^; emJrxu8H]\#ı~j}۟e~ ؿDb]kiL54N بRlԒAܕ!ovz^gdE|E$F*6n :vu꧓.u=?өKO"-jg endstream endobj 667 0 obj << /Length 1116 /Filter /FlateDecode >> stream xڽW[o6~[$bHBZ,з5+b JtP4QFIJrF<_-2l3ʮ/3W걃1oU>}^{)ϼbƈ#W׽w&cg%i|:voۀQ3N(!82>`rƞKeϮ ~d^gD\ ]虠 yѼ/7+IB#g!9%QyLjN/"N(K )aNi*%7,V(ں 5TٳXu RU| rYSգ)C"`[w}|(}tܩ \@ḱ;et$#=߭UqaY<|A}thUU+]_UOA\DP/}\# )0M"%  zGAظC\l6>1 y>.8!^=z[ hpa9 [C1`kBӹ u{ھ~ǃҩ k ţp1*n'Lz6^K۷&M~CS__Z O/iW ]9!Ԃ,i> stream xڽWr6}Wp2} g"]!v:My3\hy+wAD[qX9Xrbr1SgFf;(%A;ILI"wJޗůhRFCni w?:ODϙ-7jKًy8)n>UR&&TV+oQ85vjF xI>ARSF 9W6kJItB5!?l͓ɿ1vqLϜ\Nx fлVNȐ0q5(aqȜ8L&ei.h$8YʆEHt"7#jfѲ +ϸMmfk"I!GOUeL4@fhQ2#al [BgM|[x_Iuʺ \0CB&`X_kP?Pe'SRf, 6u)2JsϏܦz .;^Y*( }؃׶c"Rq.+|<*FG!^xӀœoGVE:8lr>Y|{zx>:Q p ׽w:x,r7 zj,[a{{)B|ӖwjG菏hjЍU JVkŽΊvPs1P39o,VOXBԅ:;fO;!3G Gְ8tmPA4U,48,l'W|]g.OaC,4uSmwIT, hku&ɉ6vl6sYJf7m96v] \, l:K) iO,Zm.>OԞX0rx]3n`Ab]*=1g5ڮ.RF=n6wƼپy$OŚɕp% endstream endobj 595 0 obj << /Type /ObjStm /N 100 /First 879 /Length 1853 /Filter /FlateDecode >> stream xYmo9_Ꮰ^̌BE!IpA?iT* &ťtR[{gy/K2ΰd#a,&`r7c05Nd0)Ćb0!"9;2{LDWn&LX3&E`ճ 08ap0&+`1&ab 1L&`M@^WʠuLR&I# D "B0;IĄt0)&*Xx;Bzi$^'(vtE' 5͓F닣tah-o^-)lW_Sg+٨yn<l/鲯X?ǧ'ӛ#fWH@nr͵tRrZ3f@-H(l*'LUdP-Ta姒na|vaoL8PW|a' ZW-;݃wPP 5Y(!Q|_UbfgdܝoVA vZdU)-qe;8E |_XpĂ<>k==ޯbv4zxDn{^&D=|2mzYް7.YC g;6;_s65(_zPѣXFLC>hq 0S# E+i5)޹?bK7O '͟/;_5Ǐm;vqҜ.E{|1G#8 i Fgu"i{cw&w<x6{bw?͏rӢwá: t*BKTQ%.*(!hׁԁ④GC _o7Yb8 RȣSe! I3wCۺ ԁxKAvƘBuDu`k"=IԂTW-X(E .J4 zaR: lQ{"X|wh۳B]S̚'hǸJNfd "8k؋jYN?,#ԷRF" JyFM_^n!oK[UR"R2Ձ);URo{QLsn[*j*?km\ՙfwM[@ QmXfT2Pl4Q endstream endobj 703 0 obj << /Length 1070 /Filter /FlateDecode >> stream xWn6+dRԳh-Mnޤ40hrH*yw\KA@I7pq쇛;17pn2QJ8a@]&un]tyD{<ħ1d6RR(mgԚ^e#*~,ot;PW<5r,&.ehHֲ- H}Eҍ\ef*ѹZ| d(~DNc㗷aBa+Ӧ_$z>(jQI8|zSB BB]c$}-E]|tN%'QfS 2F3RHl8db6[\0j>y{Ek+$p|>R-[]nK-uP )pٳ\'V jZxQ4(I*'.Qlmzڡepzoź[elY5fڂ4oanD(0/ ym`7ΨT qUڪm>of kbPm"5kwn)|wl6(^WC-ZZPҲYrʍln?T#uPv=t,Z?(ق f]=qz2 Eo`TzxWHt]կS`ifnjuӜ]QIuR؄`#-FN[8׳_ށ%}#S!p~\o׭;pġ9r½[c*rhr#}muGϘ J3 h,"yKu 4z79bbn.0'9ܓsvR{eL!)Db*;Gp 2sW#S<vҒ1舲.Eo;iO5s B7<3]>j!%[֨(Y![]~:Gmv?zzoCkUN'ؖA:r0L endstream endobj 715 0 obj << /Length 1021 /Filter /FlateDecode >> stream xVMo8W%`{H6@{Ji$"&w(Rʩbkfg<;(qRF^,AF9ˍs5E8Eq{%j+^.L{&(NokC|}dm$8î5cr|vC, ||pCGk4L-\]fBfAY֋P1cy^H1/F!iH^}*z4!$y{G˺`@E!| }뷅bF 54)a7\7K3Ua[^?l#/"~7G$~wz6۶D͍ ;`BLWЄ<;_ GoVf3mƀ+w0Xה7,g޵5f\*mr-;/6~=HWv9:#-ɡwC?A$]]cgi|kN@tu% r$ZR0FqBH祝@|=rˌ*(鼭h ^쥙jc7b",҆u0y)S^? N!0A9ۆz`uH@$siVA5U.g߸ڙZt~MVE‡dۅ%]K^QU1g׏>3獦^/Ycuu޲V 8ѵ.\ElًOLT;xfUeʹE6zzphWfՍo/5v^lY 8C{qfE ꝹڔUΦCcLôPw0}n6~.-Vk^[#a͓$ϏŮg×j9{/Qڇ_l endstream endobj 732 0 obj << /Length 971 /Filter /FlateDecode >> stream xڽVMo6W!`M6i0hVʢ*QM;#:NЁ8>߼!A5"feN T" S!Je)Iu-i:gQ\*YylYUZ/Yu֦^D5~Ժ6uD?vaVe(* $'D['0n|c fIOcqߺҎ*1=Wܛ|F%;)ZSVMD;qxE|o퍱`'nBONRS߾T$GEŔ,ߠo[KSN҉0!.r:1 ^>P%8J[d,?fb8ՉN z 1c\ ]{fw(IKqd-kH&|8G}7"KfZ`R(( NOL["4HF#?Vz;iL1\8Uq#p_3/WSFA:C_Q=o)^Bn^c}-Y <hk큻Vg=\Ij{ 9%J-7bm*\֎4?SLZ%m[sx3gCJp֮(,x)*n=s =muWxMrc 娺Qa`l-mG|88wyBzQ:p;yX̩wdsk8s%.9Ht?qk$9ȶ>/O'{P ݍmiیd;**41=sGEP[Y< wܼgn wHt=m77Z//ons솘Sҷ/S?or}}Qҽي=Nώ/,13ڊ^T3!8L'1E/T endstream endobj 743 0 obj << /Length 797 /Filter /FlateDecode >> stream xڵUKO@WzJfهwmsQ*!В(BK8.Nهm<73%ϣ\F(Ʊd%@P,8C'DU=f*\.Ec|Z}*ʈ(f_# "Atq15A xSB9C͂YPe@QH$)m覰?:yǘ8m2VYXd`A{2P8/™UZ6iwo4FhJcLЛWjBvYEL6FSbk1t;ð[D1> stream xU[o0~ϯFZ=\*x`&{Sn͉n;Nۘ%SAB6q}ss@N9A | Ğ Kp3qv> stream xXIo6W61.-0`ӌ:@K,DURr>-ʎ noF}uusDŁV1r`3[e?y,k—>=螇mF`k1@;aib 垺 _xw[aܞwn8X1HKǚ:=x!h&(|hi '4 햶E*5׵4{%Y20^z-}Krmg-XWLoghJ+( g PŽ-j֪)SRs sយSvU~"Ǚi"vt"~Q.h)2)aQ^|.R6o;e;IOxA%#+Ph;W~\s,o_6@ iohKٟ-@D FOg&hUFqRvd'US/o 5]뇥cZ rzlr%;uSd;rRov֏2!tbyv$}4w蜔Pgz20$IO?}9zpd8'ۢ98o† IqRt[%uhuK)*HlѽT`}Uco#'Q'8E/gP(D }k4> u\$[YM֬wM [Jq_L8mҹfau!\:WQ 5J0]ZP#~(F$3F_Z6nGaf@KDKZɲg LhYhݾZu5mg萙re9te!zGq_Y&()׌cRJ9q_)>茦<<]}ke?-H $Іʛ%uhoM8RZn;xrd۳/7? endstream endobj 785 0 obj << /Length 1402 /Filter /FlateDecode >> stream xX[6~_扉>nԪm2yhˀ岛=`%UEcwn9kek߼c'?ZuG}+].}xcyJi$5oC\?Oq+9GRqϵ`?Ql%͇O&\(٢J ѡ_E$>'t3 <(AQ.z6q!̵bqDٮ }:%Å`̏bW Ԛ/ViB|B N6m~[eܫ}>YړvvټJ6F;þQX\AF4]U7n@\^hJ:1E1d(IGyzeW!]ĆoCD}g|ѣ6SdJY,]xd9B6͂߿}kzޞJe]53Hs%CPyhT"~ܼ/n9i(q-xȤQ xڟ^.{٩]vD,򬸇\Lx NuI r}SSىT%-,p|]vu(FmkУc+gtHs%Јŋ۵I0nΏ @/f΀i4RwCCs]l&! 7|5#(V2~5ѡ &[Ժj ykh4nf Y%B'!"6% z_UP}AFˌ ccZȏ-#UCR>ة ^ȗB6FpŲ FO+('eB hS^L!aP0x(l87?ON endstream endobj 800 0 obj << /Length 1163 /Filter /FlateDecode >> stream xڽV[o6~ϯ@هe`$jVVƭ1ɤ66&$"M|w wnϾl.oֱdf@AvpM 4/78)>Q,v0"gя7A48JQYd3Q?qAUT<#1mt{2{[j9kjNind'v}/B3v +%XywĎgCapsW__;Xu+VUU3bL}XyXQƝjq23\WhoYԼoV%lgGi6D{>$48Zg=|;Pw<* ˺ujx{񽺪O.=5w7 V?'k-Y=l-HzZ)sqy u=#z EqBWW6x% Os? L!K4Tb{4k"[|ڤw&d{RnFlJS&j!:N>qC<+[VL$ց hݾ#0IU'=]Sk[{\b{"r}wl>Rnqy"Ԟ_ endstream endobj 697 0 obj << /Type /ObjStm /N 100 /First 875 /Length 1691 /Filter /FlateDecode >> stream xڽY[oS9~ϯ#8x.6BH\Jv 4ߜhӴuSc|囱-Q`=H(-] DVC,#"KMm5l~-Ԣ}3ӥ\4!TS|h!Z')>0`2W,A!7J9Jj- AÇT|>hT@L>R0@}ZJ#+H'F2i%aX2:z# %14G*GR(ybL"tƘ*V|0h;, 14׉44&&PY= rƅ*B `!  2+Q0Lɪ4Ů*SLl'&! xI@aB=+28P+AnlD\yC`"kAqs'*Ҁm5[*]ܞ6n"N}!td,(&HeϿaQ 'GGo'] fK"F(&ꜙ8Gpf<~\Ça\8.v10ئq#l:`:g:X_x14Lbb} )dr~c =69E_h Q ~1p ߖ"~e^~E*BP`i/RIrXYZLSp| I[lZ% דmmp_PdPĮ~uwiXEQ\ FpjL%zZ#l"[yv?i 3@ e7,8#pEg19#gITa‘D$ r=^ uETk"a֘\(N˯ň2 AMc\j"w&+IdI&;1ZRj,NxueP{>0RՐ,T5j.`}%O)t6"݂hz̹bB]4nT?b'![N}`XbMLyHk'3?B>[z8;ΥqR&p j:83=x0?C6zw4[|~s]k%Ƒs|,Ί8h' c߽`o N%gXSfV }9w '&!VSُ ɮ=tH ڽ07*r`:s\['yȑ.|H-Sn$1/# 'W>WPg5>I؛bl-i앱,HIp+EޝyM} +Ӈ 9H>, ٯa*a`/AUTI⻘9^{}K:)5D.3\2Avc^㦣|n%ZXFNݧ]{jn5/Tڵ d7Pvn5keSO3p[&a ?.W_f߽"3f endstream endobj 814 0 obj << /Length 950 /Filter /FlateDecode >> stream xڽV]o0}ϯ <[?i6}%Al} Kin|kRbv~ 1(XF",a!5zRؤYzL||ƏA3C %xwG1HWz[q~mDsp7M&$g>!`0 =Gx[!C9Yq͟YEmMfJcS2m&J1%W*.F1$(lݿ]J| `402͸! va;A`t]L"|]/Db)Lu?!FT k<60,kf&n2cyLxY;nuѴXL*ΤЁŇ։('u6yr%LU9u#aդvdQ4Ѕt4M+^_(%T+幱6Zx.6JgapkC ;dUu'޸[|y,:A1,]۬MBe;9[n'.Kjmr4(Ad6)5IoQ,?-nC/m QMn2MU.sIF"b)=#{44(QAOو.! ȴn3dld<fjs٦6lJ] ldBT)]@NqjcnYS 2ߋ[д›m8lY2'YlGq Lc?Y4{,I7{ W }]t%E14s` ֪Li^8ܕkIm0 ]`h"W>:t:B endstream endobj 824 0 obj << /Length 955 /Filter /FlateDecode >> stream xڵWIo6W3@͐)=ӁA[BTJ>!&J`|M&D,~Z/ί 8O(AiBph]OgeXU=nvMW8E4=@ ˂8+;6r̫ 5ϬՑڊ+O:LQI hCJUL\侫wZ4ƞPm,ԕ{(t1l CYϳGY808\2p E93ʞ77VF7OPDqX/-Z'xz`pˬM<}oXۊQqճ7U*'?<}geTK0a3ݧ:b%'(f[0^Kʹzވ\RM1_~[+"ς{>q6} ŕS NI4.L'(8-vC)S uzLˡ4;n )mi?!Yy"HIz%o-*pt$ԅ#q%LTe%ós.N=|;}r;kvl=#~H<58C5'1W,[ endstream endobj 841 0 obj << /Length 1151 /Filter /FlateDecode >> stream xX[o6~@R= PŶOia- ,E{~i-Iv$stlef?-g/؊QZn,cz.u;'dee$AH`%e NJsqa1iWmCVgcCH8l'BQ)5*&6%m.c B~O˺`|)7"PxE1ߔtͫVjMs^>Erv>7zm!"G{%b ֞ZPs/N =8`spR?j7c59(vtRR6X ӆ26UkђuԇՒeS2~c~0~&E?Ja Xh2MCK&yKwy"2\?ۂr>Ik!MRٶ5$.v7'??jI({ָ}E^IMeλfS͟m6se /gw3!l9 -H& Rx Gփ-ADDDnf}[)">ziϱ<0N?AB׸LP JIoLmv]fW9kHp~EE[ QApcl#I,p>,Ȭc>qڧi*^fџBzZUI+ΌBXUZoWɸ!u|,P֕LctM; "eUU9âUNhtxeP*5%ztM򨆙Fdl3C҇ΟK<ٯ".Tkz( 7[;$|츷:1r0rwu]/a?! 8+D˜`OԷU\5] u2F8 ] endstream endobj 856 0 obj << /Length 1107 /Filter /FlateDecode >> stream xW[o6~҇XPw)6 PָOma0,Ec~9Nw+ y.߹{K{Ӌ$r'A+Q Fqx|\NcRo9亦ӯq>⍰ + $lTXςTi-ir"L HY~ "}-tc||nXW`JV%]MKWvUMVUh`6OQ?i Y,t'^9 E`F9xUw ML2gg] V-`|K"c:?:$rށD+mHױRBM{K{`ѭ?]%yp.c5o\͠׈<7~VPd6^.$驊?6,13FŠg'zZ9=t1Hc$n !7-Eۗ;C* |VI]n(D8MU=Qń uU\'.;mM8wjC,ᆲ印(.zz\^ 'N.J\,1Ujp e{-x< kheQA5kE?~:?+MkrM݉q`d\]7 NVb~w90)mb&^tNoMRԷv}16{w $^hp"@IOV X 5>h~цH=ɔ{2šGO> &(髫V Nz/=p/s0#lX^gA|?z5;r"ZҶYpY=f\ R)lˎۺ(؝\n"wCeW4_W!Bč"mȗ|9 gG5A2D, QGXFQZgA0K4A M|ym}؏_c2v ~S(/z֩5{J΁J' YA΅/"i/TV[$C/> stream xWo6_!ds֘O Hsчu0Ѣ ҍݿ~m)W.^I-Rub8 $" o/ߤH2 ib2M2BWE#A0uY[9, cfN|'s7dvV%G}Q f jœ5[[ְ>|Su\oV`1,$Ea0 ;ZHl'< "I@H𬐕f0&B-N I+ *.F - ~۠M69_!8Ay4tNэOL!QlcPDYǬ޶Ѻ"(f?R؃bGV^nd4yB 5+Ha_J83ޭc]JV̚35<!S8悭hQޱ+mO6a}m]ov4>ڢ|~''_L.>E_LY9e+&bIĹ313 /.?2ej^UwWxq6_|-/7oLKʽ( RrU zjwP~Z$|nAl)SDž]yO-崸wXKg/-9[%F'w1c4i!8@u@w`ƕiܕp;*4|='h' e%ݪ!]d 2(ΣNYfhq#jmĀMv7_@9zU7F׫J{мV}cdrf: 7|2O GLo[/Zmgʜ.65RՊX?FR̉;mk;}wwcOo{> stream xVKo8WhŐG6H0V6~Y^`|ph DjS,f1Z%Q`2eQR&u F$T{qc )AttA3Lywr`+KOkZh¼Dw{huɡJpQ(s{$g8K J=N -Wd9E[6B)f"~*)q1ko;j%I~h0!>+J^p@;uM5/ԊӊQq!0ӈ;_zQȓ̏LS;S27‰npBh[U~1}"ȡՙu" !3+Ib* fm {؃c!PQ: /|BAj{i{25[щJjګ׍vBfB6މLg#{k*rE@LoIYqWZn,0c:QA'N0Lp071} <;<ȗFpL] epim7j&c3Ԫ}nL[|pCQXKaKFrsC> stream xVMo6W6P3$EaX6vaEU7Pd&i0DJ{of!h_Ln8YkD A$&8 Zų/W1? sfESQe.Ԫk&t=0$6aNE|BP?"rؚnQH)N;}L %8) peQ%6WI0ppiGSZ #gs&UMki8_ņ&Lh@}Mba|9~jBGB|X;Z CKQ^w^a ܝ)1!*$&A>ضR <6g4`$?5b#G;pDD$F4G"*Un cG5NM~qwz:|L]=dmeig@}NrQYykjH/';ν9qH sB6yFe>[W.d_q/@y+(F7F.-^Kѭ.(rܗ#( 'yw;3Ό'p-All̃mQ4]fz/˵в澼LnĶ*dsysp=)aj ׻2kvfeܝnb uYj^˄o&3 qȃ{W8_[a@b8F^jݝ=/zyꆀ#SoiT G]7<G \jOFQ,W(kLLr?76m0 (ήg1Ά̃D&M4ʖq#} qQvMb+C$eF /9ޢA}yߩ`l/|XԇJ|q endstream endobj 897 0 obj << /Length 1107 /Filter /FlateDecode >> stream xڵVm6ίEl|Lk3L3iX5vlqweIC!i?IFjYNlu4uD~V(#'\ߙ·Qp4OɞX=8{5N:x f?"W;ٮM<cwn =wD5d #R~#Ӻ1 v`, [1жO 68]m`ED֔%'O䅨նȹ*T uȏ<,D!:yhi7Hp#\Ε*)+ПЌ CJd/עbQIݐdy>nՒe2Y ҶNE!/ēu\ӝcƶcHO-XR]KAфHx^N+H\p4nj6<5:^K!Ǟ >|t!5(Hc#qBOM~?j OAMwbBA 4߳/mpF 3*WxxwxVmoaozBznMf ?_:7ڎ#hUߔ͛dAQ tm;і&FɄ'#Te}azvyabd BsW놤ΣP8PD gqlXrƓ*%]B![.\ N1 pmo @Q%Q$bu^eŀJ&]L~g_\aZ<_a1^ hwÇi-KL {wPҐ~s´ o=Zl ډމ/ BV endstream endobj 807 0 obj << /Type /ObjStm /N 100 /First 881 /Length 1693 /Filter /FlateDecode >> stream xYn[7+l63a`n dBq@"\$])cںN  /u8{Wjv2FrI#;J8.i<ɕ1fQ0S1dtB4BE1h$GIpT,5(V[(W a%aw=EͶ3k.0%.%c11&T0m`iI]"X49%Fl6_ .ޮ_&?gŻ4+秱 _W IHUo7Ε}X>;:rWn _^GbWϫGɓgbx7K|9 g|7r~8ꑍDZ$k̽g⛅a4~IJ\VjrS)$*_s@sn+vo28v<[-ȶx%nT U kxgK^.kYO-z"zD.BmwQUGZtv`7VZJ[`VEMmCmXGrmMι[v=Ιv3V#TOVCB)YH-d:  3l(Qy\s6J&0ZO2ZoU|xao+mۿonw--:X1knX%fhMC.ዙ|՛3xD/=VW1AWB}_(E?Mup4Vo~xG"DK- &/Iogny>uXeZ(pF(;Кy3c7}`y_Fe]1ڃC8"7.RtZEBHt`$gKq;%"؉ؕV~FowKvoJJd+cb41Y׶j5.1UKh(w`b p0+~{m+kM&4)遝Y&%Xow^]7n_R6:hafh#bI}`BpMsAJˑ}=iݧM1pYBBbqW#wu4Y,HzGu~ji'yf9kо绽 6> stream xVM6W*@eJ@JdfrIslQZ[J0ߧ'\r%Dkt?c ,0A5(NP̢-Vr$D`Fsy(UqF^0\ som7H tdlr z-e[~/OheiTgMQOYG02k uڳ$>Nplu}-n׻riy*t[>Eյv[;kvև4):$[+2AS808Eά]M :;UC@ł+INކl<e>?vsF"k|VNn?g&#H)Zng>G}/E156))엋֓R9b8c@ *Xc7~̼jW+Gsߘ(<cWg{?Ӌ/O]6 0_TwAI2{m(R8|#9{Cxr'xwڐJpG,U0$BEqHүQD11dB eb1 L}ӴGP C.mei[Y01$]%獉N۪{s4vCv{>1ۙ9018e*r~_o0vKk@7^&ĝ~ uz5RfK-Iz CdahX3^ANhNK5z9t*k)ݟX]9ܦ HG]zV$R*5B&??NSjø7|{ endstream endobj 919 0 obj << /Length 859 /Filter /FlateDecode >> stream xV[k0~ϯa1̪Ph] J"rȒIKZcAttAd(ġgyh!Jm]Mp,MȠdּ^ʸ^\ݰw!nYml19Iٱ\Lꚠ ^ 8 ͐CAcw.'_:}!c}2`ϡ'AQLz,:'sܷpЖ݆<咩|iQ7rB P`<\>qN|cg ЪJP[;b;䱊M1/#aN囑.:oZh6I}S_Wb~Q2:nB?K6f %dGc81Cx+I?x^'a> Ob YmQh ^AS0@ռ̸Zg݊ds7^M?߇)`O`Qz": SM6Y\o҂W2[1uRѩ2pQި̠gtn&eʶl#B}y7H[}!9koqح֞5on z 7RI7z~.y6++LX EW`2uRv2CR@tock6JGjZr~VJEI}Z'+ac>(lG{Wm:7<IAׁ ˼,( ^ush]]w+'ZFS|7sɑk%y*1 5fsýe^KF.%ib endstream endobj 933 0 obj << /Length 901 /Filter /FlateDecode >> stream xڭVMo8WCmbH}+Z4qNm`0-LUb6ɿC؃AJ<<{4A%"ziXGp1%a(Ѧ@ߖYmXhe@cLp̚\EKVU݊%˹*Sh4ma1Cy~_Z'V7&ƋuTIXy!˛!WB쓒v,DT>4TC^$f cS.d08sx ЩS!(Yl?=;^_k//b=!DqF_0ž(t0~t,9ΰ|oYӈCi>ء,5a%!4DyvGP!md)z4KkR*tzRFw#]C.qHQ&8[b9&YJ8#j>G ֎Jhۙٵ C` tX;Kg,Lβ϶ˡJ#9s9)IS_<.g9VrY7Fv815JJwvNu6 dk;g,ǿo&|A_)E{|ی3ނjC|I> stream xV[o6~Z@͐H"M0:tش,LI"t˃A$sAja>9i `h̃chWil*a ʥ7yׇ.ycdw+}O~<*Br;Vp)#wjEp3y64eC01 ,R٥18L' B"%0aZ~_kdmH4傣0@bù@DPBu6o<.<4qgk `tN>eg]'_UJrKgD-/AOIIW̰.1lB1޷u/|wa ahepl;'S8s"f!)`9k_SWH<ȵ9ge+\(b ø97@[9dYnZPD{Y6xđM Aom4|isu5hBlpB$U+W~!{wONums&kC<[L5P "FqS&9ќYh-֫S(Su{(oCʠRBlW= w4Հ*p.|_Ac? endstream endobj 963 0 obj << /Length 1364 /Filter /FlateDecode >> stream xڵWKs6WpCi j{p^NӦj{p3(6|]Iv`o+duO׋'/IH"p[QJ@8$8ϗ֯Hh,[,˪9ǶÐzv-|g]/>d€Q5f3tKۼdJ =õB^[s8(@`@ 0J !#oI` jɜ)9KH "|{;Yn2֔sBQ>8#IhI|7tMW!Ĭ{>P+ny~}if^*w&^qFo|jAPGBzCGOx¦0f8[=]zp~޷j 2V*zFQI+>P?1uN[,mUBs1tg:zta4W'%"AHyqi#[Y^ uWMSjsHm‰H;4?z7 ;!"BCP76u(w 2UVf^vCwkMW"p` uPS" H`(̋?V2rB${?5'P\^Z \l F|WYp$y 2YeJmcȟ:#c8jZh$S(3_?qV%@L`܇w5ڪV };(+b?-Y]5c] fZ#J"]T^jIبw|lyQ4 ?- C*͛M[zDՏrqި]~ܵVߤgKW`,bv jSm:3faQiޙNwih.#[sڇpiöhrJC;lPT),mU8)P  ?UϹr}bιl>-%^^|eS}U ʰZ"p71y)18i> stream xWmo6_!b5MR![עE0l/i0-s%Mz~$%Y 0ߎ=O|88cz.u֩s7ϲ?gy~/Jو~˚{?0Aa&"3lU9#rB=DIvI'G-ődDwG~~ƭq 8!ueCSgN̹[l$ އn_#Җ/?n؂h /E# $EAXY ԩ0qԢjDYHh.%P@QSB YٰF^]  \\ª>Ŧw̵ L,SɭaXG-jru퓲aG%$ oZK͹KX=&(-)k[ ;VU&B(/@{h(4o6?^O\O-Fj|jЀhe^5:Zj懋S/>Pu^m@

    zY1|7Gڍ l^\>d5|q*/zurgз8g_(L!a 1dڷ67F #Q:5= ~zCl8*|ؾڵ~g'04 o?Ui  bU {o]=M5z21i;W)GPA"j%]&MKoR*Q6;,+ è܌/eZ|C]r-k-z~99$e3Zas ө7HW gj.v9E9,ny: 8@)tt1eTAeI{ `7Te\7_3nzB KSj֭9X–lk̙UЬ`-Ejm8*#P*'5ϨT Ӓ]BUC*'OTߖҋRN=4Y"]r1Ba?!zV- I+{_,0o&I%ΜC3eO͎9܆u.3% 8([u7uR endstream endobj 1000 0 obj << /Length 1370 /Filter /FlateDecode >> stream xWKs6WpCi =mi'ic'DbK Iq](\4X~ؗ:ع}8 ;.' 0q։s7ŧoyr#PXtA,7hlɳK6P_|i$gZ˻/r ϭoЉ@8A 򵮯K[ir,wm&Jk^r7U.Fa7kaIl"5f>#2YuJvQF1v.! 6wvWA^9p|Wb.&wnf4&4u/x6M"NK~9wKbS-;ʛ[ypڲ݂i\d$ϕuE=dASs.g0# 0%$(!4p{ț]U*{\d2GZ'@B9K)eyv.Q_EY#+AĖ~Ad ;rm$kf~9/! {I "#϶F<y(^S{'!]؉ʣ86<ȡATˉzB7p4[qN)%þeU@0$&d%U]d4 j~"C#6 o y}p$eFȺNL'!&a/ܾ?N?^ɫn:Yyuf,ï/keS Kgttv^|+$p< l_7Jn^:޶W#RM h|[" ^Ϗ!G/ &P?QWӛcUͮ$5gB%iB+B&G@Ǿ+4@> ~{QS0^i?F brձ%PGLD§ITU2+{[wʭlUr9rEa \S\&܌?圹kzpw}FVX){`c~Qmswl02+5a:tOV\ɶr]˚n&r)^Θ 'F hAK3q: . v5ƋA5V3h^IGB %Ӥ#) y"hMne I(:Ə}h̸žFB8jGey+`6/n&Q EMS0=gQxke+fǼ}}ˍ N(KZ~='&Djs/%@T0l endstream endobj 904 0 obj << /Type /ObjStm /N 100 /First 877 /Length 1622 /Filter /FlateDecode >> stream xY[oT7~_Gxz<!$.JUm! HwQ!8.=f!KD bA>֐BI-İR(,ºR4g9V*XB->.%khq|% 6&"XN2Lg\ZA 3Ne,P!>E;cSM>`,5*>#R JNθSĥC|J"\q5BqEJ :396-$Š\!+'*mP/Tk.Q M}`ף N8JF &Adh C^+Xp `nb]0-בPu[ 9物$?ag=4EʼnP\  ;, 3E*5VUg@G%Dhj a狗azy} 0LC|yh12̎'G! S=[|.cs[w-BO~ pg04Q+qUWj"V?Q+|-f44Bq0ݣY;FKܽFdkDzO"S'Es[k詼 S/N)VܙKζ pJԢ`S ;g_wu)k.tOB]R c`T+QHF]QuAmFUm,sSf2~ .'brqr Fzr^0+CW;b籲a n =kN0qgqЩ:<9u;y|kEmvu+ &W'.ѻprz;u. uă7j–ڑ\s.=*LY^ya8^?tmF4 8@%Jr[?zX|<0xʹdxRdX[a3v.IhluÈtFDL Y(~Df`p .`NNx%1059Q'd X~ҵ$:IV׷q5:j;uVb _DZ>FqI;N͆{[j1w uSuv ?3 endstream endobj 1016 0 obj << /Length 1179 /Filter /FlateDecode >> stream xڵWK6WFԃb64M\6h YR%9^H2wכ&Ё"5|f@xu I ;A#Spey(7evm֯/"6" i"UmADrg+9$`_\B _%NA0xk73;C ( ŴwH|` o_- '!2ll(!=POuE9шY hh# vuWE0ff;EU*Ea~vC w_#@ {!^EBǽLg{De R}" Zc'oyr峏#Or1o["(V*/;Xf^]^ōi*RUvT̖8"Ȣl#䵵""0㠆xV]^h Ό o> {BW.`3MkOwPiZ1Y€QC߷<: e͑^LaLy/Gd?xln:՝YN ^ߪj&Flr _f8.x+^E}'鿒]kďr#|QzN|pשc;q8uŶ: "k:ѩs x5J A4U .ELsZN^})mNdUKjbj _Ű#48^Nv+񱬄w%;83䫞  X2$EGy%T5M˙iUgVJ~tJH*Kcbc %gSJ 16ꇹs?U癐SIЇ#$;8g!4(fkQ+F ᴒ?bO(SW7֯E+$gbyT9lfSŧ Lr K$jNm|mlDImu(]m]HϻQ֙Rr1+I$=W'J,?$GَZ5_ߝQPtزy{-MCP@-hTŐdZg tvס|]1ZCrDߒ(>-SOb2 endstream endobj 1030 0 obj << /Length 1382 /Filter /FlateDecode >> stream xڭWKo6j,#RE{Hhm% ĕYIǗ9aq0Hf8XXWo؊I-8+ ڧ 6zD#Nץ͓ey~(ɡ:%r̅pXǶWe"+!6[;뼭&7Y[0O˷HF Ifϧ+/\V-Z;[nǾ* j=ʤU5m{qJ#A'R/8iq3Fz!p$M! JeEGR* )W Ⱦ!tP.NMEH&B0B8& hd2PN$4c> stream xڥWYo6~5:!n,E۸}I- []+楿3$%Kɢ}dl+lvzvuDVL rlx~`MZԺgقY?mJ"HlqmvHi(2a ;ɉvޭgfXrF\JhYI1h[)|GA`@u7l)@ah߱;$Quhj2~;NCԋ3ϴ |Box4sݮrΠ.ž&VO*幞ݙ)l)oLQ+MaHˮ XZZ{08vv{R( Q8.2k}O/!M" VDžP'hHדM4!ƥZ8VτcڰClAe?YST]gmBKﰲlƺ⒡t=_H ':Lр+=0YWxQ~ oŇ:-U0ð+ CwHEKAVp1qkR>ct `Q> stream xVˎ6+tQ 9$h EvlHBHL~{/EJ#rftS |yx_eu("b:%AxDp3tHѻ{?]]Gҧ@Noe^ExNɱU]N eǸh!˦Pl(QW.$d{[ovz:Wʮtm4B>ESԺӺ*Fm'Lښ< pC+Z +øN1 Lo;;ܘDM 鸄!D\S=uߓtZn/J(Ze;|T2 W.{RK;Nd&5yP,L|N2S Kel͛Ɣ :6sD̘rA) `_7-Q@MMy tbNAEE0t`T06Cכ 1,b ɂ1dZpGuRz>Sގdۯ'gYtrt$JI"%O1a?.irGnAmUW h6IC)мhI0AVat4Ӵ<=fT )[e'YnhU0b{BXY:_+-*9)eU6nfd6-0O#xz\J[=; I瓛fn./ix FTЕݹi|:d /hOυiюM$pgB|AgBqx$]EQ=qY7M9<_xz(=f˶l'SJ?.f.iqfqZ]@IU߻Um0;f*EW_̒3KO%]KK_{]δ/L~\v <MY endstream endobj 1076 0 obj << /Length 834 /Filter /FlateDecode >> stream xV[k0~ϯa1̪P(l${jK1m6;؉R3`Ar|.#"n&uǁQB( ]-V~?ey[UVv?PFT:0j15%38GI1$h/o#,M Q깰|mwJnxHx4YQ/Cpvpў> stream xڵWmo8 _vjU߃n-v6}@8,ky)RE!E")zNprzr~NHD8g~9qY :wn^u~%~(X`)Y8Z?-L4jL=Tu]WĸHYڡ7}NKxg=heW6yK 4 I.<7]"Vr*b?XT-Nvf>7,+Zՠp5V4o.nȞ4 qٮd(zxJ~y>7cK4 9ǰp{2U>}t@tp2l}<>-+Uw~1(ۄr4>{iW| wE{-t Yxc`}2S]:JC>iuNYkK8ZjMZlA8fMX=cӢ:M9Ok+jEW'Lqg /b"wC>Mv%S4+-m30Sy'aVZ@WȎv3ᧇM&T0Dv /D\m)ƅ[Zc;6/=Ts18g>(?:YZ}twM2;:-y/vN7:{ }xʺ|\KXl!FBlty_gPjq jдgҎcӘDF,HAZ/Ny @{z|pZX.XU r6+/~t̮\ P.F=ڝ\>m:- xRKnپS4aqP"rdlz2WXRٔ4tԛ Qi%GX5;wn#UXO=sҬXl@ù`&'?'^_u-ɪ-wr؄И&ί^r6\M$7OVeGD!?jv?kd TLXe݅  W/D@$kϗd#K*3<!XVjU;(JXf1idT;9CiVxޡϏJA GTW_m ] endstream endobj 1008 0 obj << /Type /ObjStm /N 100 /First 967 /Length 1717 /Filter /FlateDecode >> stream xYMo7W^(rHA&-P$9uspm%5J$rqVb7C*C 2kh)䔨8H o4Po,pR_Z0&bSkgN58oR 'f7+b.ᝐ+>U',\3+=fRV'0 ,+T>ᕵ!=vU&H`T ŭ16w,!XԬ+ ,ӄ5-,]s ĹKXk` w q$ *<.A4A2N#k*~*C"+`ݔ}T]]­XomA,|McâX|qxUq UOZBvS%n"S Co&jWPA*]"=*މɓpZf~_&~{'ؔcA92{XU(0[GFJ#NXk؃b< 1a,0r=O]-_60L L_m/{;Ç7|-6k;sl<[2;9=z|1c#WɱWh#atw6Cgp3u_]w2}qצ?|g2}\V}jcLaSDaI@Ɍz_˗ˀz"yX7xǓZ NpѰ:|%OyǼQT?2_0] t+V(ZY Y +}rB9j>=9;q]tK (((hNVZ%5'oWHw7L>jyX&O- : o˅(8$/L)|כlq<jj;p5аh2Ĭ4E<46_GIvƢ#Wbi ] N͊#tQMd[qd[qd[q[X=2@%lQ`w?GɄqODX^2¥cH1qyxWg!h/hŚA>D#z660cɢ~CfV2x7λ qqnv>X[kvb??ĥ~%h;ͳ"y8b~zw6"!\)ldw`Ђǃ :7:,H oF ]e,WE>rUo([@՘Sk[ m`-BhOИ M:k{埜صNj]fkQe.~EGUO`;˛VewB1s[!DF{"~PHDJA fi?h?Ƣs˷{?V̱ endstream endobj 1101 0 obj << /Length 1056 /Filter /FlateDecode >> stream xڵVn6+tQ=))h4 EN-j. [fJ盇\Me9vwЈ,C d8Qfef9Y8Yi,˳]ymPCTvrGɚ//d;QߐǸiD1**AI4Y[Ԛ-k* !iL?怋 {'WaN5m9bNce3!3qFEN( %~(f(8?LQ9ůPSgw\w hy=g(׽2i$pJGDږ3`!=ia9[QQ8'Y<6K)DKT{)S=*kDqKЫ)4I,kPv}$ME sHZt@N8VBN@4J 3JN4s \$&c+ՄXe dY,\H@i@n *n>i' a*acgdŔJ[YG(u/Rsl UV&!)jwDʾ=PU gR]~GّN.<2mO5t y85{ _ƍf-j9q- w&U[ E"|)9[%y 8t* VI I@\rZ|>>w{B-;l0Ub|Y{0_w PUT-4#~j Dְ?V/x}ԣeESVE52EE\xzspQ\Nx8{O__ n`^0L&g8I x G@G ,l`0tIg c8;ҹ)91Jj/Ye(5r@mHE:SʄaYy0(vLӳ39=i([ 7A endstream endobj 1118 0 obj << /Length 1563 /Filter /FlateDecode >> stream xڽXM60z ~S*-=BkӶZY2$9e#Pμyo(-w"^(T.V1.Jb$]6/˿W{`$@lvK$Yv~N:]9wYz`r(CY Av?'0=?eɳ*oe?Ӥ?֯?)gGO:9zO8y1=NL?%B drޮ,N['Y˟\{Ygw-i!0aB츇rIp;ʃ:Y°IdSDqD[7C*0@7*wWIXۅx9DW^CMU6ӝz3gߠiϷ=:-rk'nuɄvn͞@$e]׳귚o&!EJcsi<*u}*sK^Dn U]~+$aS#hOد68 *=ʊ]NeȰ.6?eO{fk]ؼJSa EK0 Ɲ^t+k&)R ?Aː+2e5(l>q*}X^m&e tU\z^,{#a2nv&!!x #KFyl_tXMr4%$}7Lb]mbèyN *%:Ytf? VW zk hn KkaRF69\TEq`P!diΞRgĦlldH:í E:>u%=֒8š"| rv##8)ن/«F8ASS@W֛1w@;65JhkzS Huu{BlDȸ<Pކ6D4蠜_͍=2gwߥz=44ʘyv@@x"}:dR.9dRFUId}9-)ęR> stream xڕWIo6Wh1CZ=L1M (N4DBmɑI LP}.NQ8QB0 cG,@,UM:yx{e!8IA2udA C' 8 R߾T=,E? ) AWa %8)JHi80^$ۻd8K\OAD|U7}g/p?!P+-w̾LZQuybRHq&O1NCε,.ˎh$~VFZ>ƥV_jfB(3؉D 9S= <@A;Pu&!0Ôt1IƁyKah#4 &t`lԍ4c(^B7j 0W<(y\I,@ ( y.,9A3r\ː T)fދ?65_x Ľ-^:d=tv9 ?Dne$1&h.S)&214m@:rBz*S`@/˦VU-dHNa`DyE3p!P7RAAx9t9[H&H`Ijfchg\(Ɵkp<վ{|zZ ;.p쥫,N1gҖץk'NduyhlY|du&^=v] ZޗJoyf^ا*r欻+ 78>*/E endstream endobj 1138 0 obj << /Length 1078 /Filter /FlateDecode >> stream xWY6~҇ŚKҢyhGP,zdOi 6%+"Y-2b E ofH;ع_4"gq\DNaX;A0{:J~DvL))m&ȲRa2PsޫνXjWOl -S; (GB EIm}7OJZ VWKԺ]3d?\w0lcZ]{eyۻ{-b! P*A[p EqRn2-\77һM df0rQ P=?q[c-7%+%RslCXA` Wfszޕ%ir+EJ4k*'kPԂْZkAJ$Xsa0LBZ&>F:)t }Bt~u^ \Ns_ζzw,;.O&9L_&?NGcr ?4|>kkY-r`kMY+aJ,O*k-}qp%|ж^K3܊ѯcWLd/4GURl,Lg|O.(^-ϵn^mU҃82k1#[ԖAY<`o5 cbDVGqwe(gUN޽&!|O-ADCj*'@UB5^DF(I_,KcR@$j 1hЃrI[{^r>_i T.х{2RaP##e]2:2Zk1Cҏ$aP"9D(Z sR G;.L.5PⴹwKb]l֜DCW6|;XT~<샃| CNjpj1rw >^",sӯ0%*ZJ %Ldt LhQاOwWӺ+hFn]>\r/ɟ>هߖQ^h2 endstream endobj 1147 0 obj << /Length 1115 /Filter /FlateDecode >> stream xWKo6W63=l$Eîm2aYԒtbPlQV\i %f2Z R_tx[6[>"ׇKeNwi内g7 p endstream endobj 1155 0 obj << /Length 1022 /Filter /FlateDecode >> stream xWKs6WpCi$fj{KZ9% LAɂT,wDPCjw-} {k{w]y +`B{IQ|}xe]$8AeY4eB-hoۛKA9J)FRe#VO01Ϋ-_0nf~WiA畨vQJYF}uZ?j韵&gpbѴnuݣE~֜n54}(E뚘Vu'?#Gn(CQɧ/[o`(RYKn=JJh{=L:0\5@L<ċi0 :n-g&,=F|S> ?U[AR~M/oE(eQEU:O~9BL[;p m}ZUl=d2+\؈ذ5Y|:tb"82b=rqJ/[VEvpV777]f^}e=bqb{Jx6.״w"L]|ЭydI t Fkavwvfpl45gz<Z@4Wm7C˪|3#% |q@US|'e7kPnl*Y|ʖKj.s}/Ǭ bKxFdh(6ԭժc~XJ&]4B(YT SiV"NM޲VW;}_9MZ7 ڟT75ɭ7eF ]0S[0gk7:{qs#;&%5!߈'U}gZf|>MH @??.nm]T'EZES v0Ű+"j׫}$_%(# a'`e%8_iuVSuzazFZX-f,I+.˕}eۅ?>61sMS|sGFM=/00 @HL endstream endobj 1165 0 obj << /Length 1156 /Filter /FlateDecode >> stream xWmo6_!d&5CK]`A1a i$j#yl:vXNy4vr;ף74N e;a0v(8rIQl歠ղݜOl{(IQA(6nfFm=!YO7RANIa ¹?5 ٥a%@c`|>Rg3G+A'~݂U6veE(oaD1e5K,[+˖ /u&^b;z'k!VlEEAIbw:" XeUǻ>ؗ"+hJe$p6fREY}m%%z;VQ%݉aEmyOǮ^-xͅR@wS4Qcdž`b&.];QV#$-l"ݒԵLyCU[*8뷷W҈w ba7JZͳLguUI,Mk7Ԥ Ҷ`9/B) md[0-~G4f2;ҵgD=G RGN/~x # ,U9\u*Ue1@XN/U]']0p`xfo6Ț_lBحk.( oho( ꑔ8~*" Bm)gZRoi%klEkyUE28$,A~> stream xWYo8~k1#ꤊ݇=EPS0Vʒ*9wx8ٗE"g3ANU8 J"/rV[.ȉ#R< WQQ(, /T03sIW~`ɼDr/X 2?nf󧵨Y6rAQ.J@_EwUŋl ]w(Siiy_{Ƴ;1w)G8 OjNjMOͥbXNX*ɟj}A(`|lv/_]'M8 q 0Fqn*&^L.Q(Ic롄`&) B^lF' [`(Vˁz*+lGYPQF6g."`+L$Kbű15W1L 5dү cEm Ȝ!rz ;tG(9ݗ#Xz@oɷ2U^ }R߾~N઄ܬVK=Sń|y$ J` >K  Ь7 $tocRAb!7LM~ǛI,x yN"E ׍UupK5CA+®НoPyA`4Gz!yXԮ6$uÄ*Q-[_ֵ;*gC]PWDBErV|c-R=) jQF%Q<,*Umgzuk\p&(aE~Y<]S^aW?^e,hi:ȠCDԒ4ouaKLkyI\9}OϠkQhbl"tw$PbbBԹg-5 ZS26޽j_z,.yܻ@I$Z0O^܅%y@5{Zn. cG{ՙ}OkhPՍL.u@͢I2fzo9bdd _/_ endstream endobj 1189 0 obj << /Length 1109 /Filter /FlateDecode >> stream xڵVYo6~к/+EEE i0hJBQN_![e'mao83rrW(R;Zm-ql?8rUn}ZEFꗛ0ǵ c+lҏ;q}k%I^_-CYۊ\f:3saI/-~l4s@B?^Z/J\ ccSZJDVغ%ei깓聾.ϵS7Q}:6xlFK W6kaKQl18)˯DZ7 ?b&xnFС-%Zu\f1AlXޗe)7ힰ„ 5 &a[Z-Fe>}yBܐWܾ} f?(:سp4d2pCcGi];hͲ)zZXu54+RR3ϟ$,=jRI5;>=ZwKD#-C{E8IE潣wۓ={W SjL4vn~x V j (mGTAC9={=\Xk'Y5ٱrl?MG ~.V;~ʾw(p-? (}}дc4q14#/$2ߪ0+?gÄ(HC/G"y]`6f%dCET3n3FNhmxӘ J.ԸT.煪l^[ԣ73Ak Y@/Pr0z}oq{ ʴzv s&F|/mZc X3|ȇR_K&EE)pzt픣eKp>D[T8 3e`FG:-|" ZW9na;ѳYud2ZomR{ytE5㧆֐ïw#Q/]`QV/I_煄Q0G bbMyC@!w:Ns_;%D"TZ endstream endobj 1201 0 obj << /Length 1582 /Filter /FlateDecode >> stream xڵXK60j#kD= (z(=$łh Yr%y!Ç,{<ij8qf8z'o.~Y\X8Qm5{U;eQ !A]]S^@`DlBBx'']l'lQ\.SDغ ~bDH^SY>}9cp 8G)Uz]]zh\]}>>Ka FGwO Ss6WDml0a};lV4=lLO\PZ6ݾo5Ny?g!  W8F~Q\Tԛ |Su5{}1t=P Pr{eER ^6I7 *@LL;[ ;z8`FXX{`Lg b4.a70OӬʢ[{UPKuv셏/KrkQnn%5Jh:%񝧏{3^?0<lnec!]HUC]{,ȳzZYCT -6=J:7{$u᮪?p)1A0xml[M\oaU{nl00'QTOZ*ʒS+(!us?giL64XopYmo%)gWS0FRj%^d m܏ ǵǮMzމ> stream xZKo7W\(r3$ #@p[ 'NFeo h e%;Hr{fCΛCpPN(:x9b;hDr)d#%aWBuV5;I 5@dmuZC1߈jNFNj\Q7 mJOV"5*(${G(bф&mjNSIlfUPIw@U␲`gyQbT;RLv!iWTA Kxl,RUlQ 8Q[TAe[gRl_KvB$l"AAAlTK?H6@Up:"D[BT n 1 R6Qm I II sI%+75)ȖW@; odmZ`fmZA=`ÒN\)~Rk@J6 Rk m6Q`#ԡ36uf$֙ID;VzU!Xج@k9^a.yB ĸA͙1CƃY[j?y䆿tt92ppt]ONFW3l~꾸#Rd.)R? k&C ӣY+a 08m?_5&I[#|8i(dꎨd$''8e3`/uwq?]Qw>wF7(΂ۡ'g Gyy=xVN`W:x>{h*aAzX>y6`7|cWDQ٩$f͙yf%̇N#X<́}7%eE,l"Ln<'ҜmsUc0 b 5S78.Ѧr$˕<*S|B9f-sE #;LaG'E.T_ q2>'g+xb J`H_O-򦷒*S+*(GLx<9&K 5R"6": ?;N |(}wp#Ynki)m5^ج:[<>}ls-f ^i7hEmwV !NO+ Uh!pڰTX(@:`؁x ?l]##pJ<@W,fN%u&[my1-hV_4,ehk.rS^6$qW)"!< AQ@VI'U=9+εsB+)«DKAJ_4w\?r6yYQ> *u7h,}%v~CzI*}hTC rvIWn^IN*iAJB˂Nn8 UgݔncrKqKױ]Y((Yyߴ9Zu SђQ3YWYݎp޼KXP ɕm7+]ʼ$s"ω~geboѾ{y8麋Œ O endstream endobj 1211 0 obj << /Length 1491 /Filter /FlateDecode >> stream xڕWK6Cd I]M A$X2-EE~|y%[l|13 gF+<콹xusS/CYLcfQ^cԻzȥR7oWQ6B$Q N*Hq QJoE-JIa(*!rYI5Zl/v+9.Z#oH(şSſ49'Jͷlewg{/$`{/<}o8&FqH8(#1#`r )UÃ넬+a:%+"G2Gs1Sv|\ƨ26јIܑ$JέA;n x.2i:l1fTq>icv=d`(:AQDZ7%w }խP<;u JlQY 3fD`Src4 Y_]ubE~kuFXFAyM6s(< .3FSvذ +'g}lĔpÿޜ<xi8 ʮkڟ-cA0^+ ~Qu_>i 560q"]2Sk!9Kc ɑ2Iz`3 s+Hn9(`]f?@e!3L:cTHGi&cHCɄIzjMۃq=g])4줓ѣC3ovE\1$'r>4LcnH>wPKimY^M*wh zCݕv܂SPtQ5rsEb)ԤqztMe]KXqi5u"۬X1Ur3^B蹽K]UOw*5}ShYhh܈_iZ+(rط>X݋|*AY h:5Appxcjl  nx~JZ7xi:Z0rY\=t={(C 4l VUHn9Q!|{~ɋA }! uNb(9h(lOI;6 endstream endobj 1224 0 obj << /Length 2621 /Filter /FlateDecode >> stream xڽZKo802Q/{Ht/ha'{Y4d-K$OSER(:9Y_)ڮ>޽9W1WVZQ ۬wYE" 9mZV{G=,1%v5uW$ڐrR+֘$nGo\pڤe aGhakvC[gna=Ho~IniN)O3S47,fAS/DƼ:T n6nbY71a*nO~u0IU$g!G`#$gI)E,Qiqcd~c1P -C{1^D e5L"V-մX~4=L! 6IFyb47{`>?y 㤿Ӑv|-plV5xNaȫP'M=:V$:pXP${qNAA|EOAc;¬4ӣSE)\厴m;jKBv^;&i.sN$DagJ\'Q<31Lȑ(֕IB'DTfKxbv 4=s[V a;2dcԼAL.P4 2?X(4جaЀHxײ1?ѱ YM.;\~ϗ/LP]u|ã2,8(7XֳbZ}uM͚1̹\D\/+̎L/&-?Ȅ8ZJO$$=6gʹ|C3s~ &&r4A9x.A8[+ g%;=26ƯPדVj1he!DE bHqtb#kS(9Q|5|Qki~J6.}- {1&qC0I|o?`M5 c.'6C pա_e̓LA vBNC %zZ DӓQ@D}d}' TO^Sqme$4 5t)sH@G?О} Lkwj;6݂.݂l\* v4Ϗ\S Hy0@[8Ff6}}&5jZ+y&q/P䏋D=)V4̥aA*Yoc jB7iM9{cEbpҬJ)Anl9<6t8:>WQ_[Im%[hZg^`KNrްKf39ck4{.嗒7 PT93y|#<8'%)T'XyOkm#{<=5 -T?u)UcTDD@7RNdm(NLj8ƴgSC^6 v>͉ꅖK嚖-&aM {XI%7<;1 1 'fE S q'V&-*)CR&uO3ٰܷqj^־iK`K}`z~$iwTY:9M`^0X[#"yt&{Xԕ`w,ʔP11=4r_n8C!m?5MvZْLh)n@DD:#2R8^pSzZuITMh!O}bo76Z VYw VIgĹ'{:Tؼ)Qx/Ke?Ia84k?MaԶllq/-.ÑFD*gpD3(갫z$g' 2|Br>Ok[ܽlg( ?9c Z}ŞX<3{M$}Y-6vr2>j_np endstream endobj 1231 0 obj << /Length 1258 /Filter /FlateDecode >> stream xڥW[o6~҇@̐6 P֤C[D\$Q#8ٯߡH9"wnx.^arvv;;S/CY# $( |>˲퇓($M=* dn+^:O3+r-4 " G2$rQ׬)XX8?,hN)Ok! a GhYIFDAp! ,k)QBZﵘА!** IE?f\1\}:{ 2UG 6:`]}rA0OAPE;~犵TR6[HR3X={A뢥7}NTB"l[Z1BY3PHtz#a݅M.INcr\4Z7&h|-EmWT {?V.Ψwo*9oRb2^ WRO]~4,倅r G%( ve"ȿ e[ =Ua|Fd3~索7v=-2cFiVLBaR;SS{UoG!r59/vg ڊ>ٍaI٥h*Ro5Ke3$Da$N;o4y`.M!3ߝEKSA޾m%ݡ v1gT34\i;gZ)x_n¾zCY.Jla6辶hz?tۓ JG}Nڶ1N h((u؟rY0B>BK+bmu2\oaAv&q{ sTe|)=V톾oB$ɈwҦl})_ i"M (J6F'EK6Dr.MkxccOcyOB_Io`v(q>8>JFڔ2Z?]N: 7.!]3ڍ"Ӓ*cg~43'Iwڶ>lS (OWW<;go4W:`\nb[> stream xڕXI6ϯ0| !KӢH&E4m EA3v}IFd|Gy̛|RF8og fq!}> o>DE$J(.?2Iv ٦_ +EMSԢ`l qKf+?A`=w{ \a-28d)Nm.{~W,1Y|_dA+glr*lQdJ-mhe(7<ع~y& y?G?uxēY>J ұ[j\[|%juRTO/W%f8ה;e԰a(#;s~`LJF9 ;_&+]5;=Tam>o%֡ŻZuy@|ÎAYNִtH|[UtlhIN(ok^8j-$a_=kY)ŔqcVgG8f?-gN meJOЏj>MrIw'aE8?}CAWdn'ta5kdqn\ZoNn2AsAB};cMrUCb0YG(Mp;GFʑCEUgKiW֬<VL5q 6aǬ] sYW~?rd2ŞB\#OoMyS3pz H :U`N;"%B8N[6Wuh;rᇒY#կ 8v"{V^5ݎ9eRZg1D(: mvDpH m;ێ^'na=I508r`Dm ĨG%</T 5WLӽTqA9!D#?]4ukG/8/6{G_CvCs|Vٴt+wc'kChLl1qW9qͫWnl-kշ&el͒S=YQ۳&+ps]ey=SY &%eVqLVi OZ959k 8N*:[S5J~vw8Hԋ rҥ0PdbE'c\E]KIOmCOǰAҐXsJcP}wu窦ђC3ꬁC#EqL~#En1WM\i/,HKR/m > stream xڵiܶtEQ~pIE)b4B̨14}ǓCzA>o*eiDW+LULv{OoߞտnLGC8*)q3ߜmoD<ڳM Fm-^Uq$W=A"?Ê^k6VyVuy[l,U 6젭I٩ AYK޽[O8 {.+O֡ztUԯ,3ax^9gtE_4jS3A`[5x= zSW{Dz땔^G 2g2 +@\ޟGKDKDt_hMM6ZnOj(-$9 p]GcK-@o`lD`}@t! !ȩS5ss_2)v42Rw4oV87އS~[)NcOF:9TH+I,JI> .pCӆ4=↾x6S-ʡWԳPfcL=vVΐd4O%dh3YYwUݡ)/I=<L!UN褸R_+ǰ:K&4pL8AM~,Q/46nՖz44C3ҟrPNXH Tjg1-`!CgqyV*S nk+𧐩Y]D%mZׁHL@aMX E A=`fy)WM] 8!h͂sgS4R9QɁfDN$59-]K޼zaI>nټMT&EtVH)7ͨ!^1dmR^rdK('XȀ€H&3u?P)b}Xu*#[4IȢ`bg 2q<6ǦE v7d׏#qXq/Bӫv*JF*gM QZYRkV.kD_+u ϳS`jʳn0e| d@ #2( I0F0$G vy@T`U眛sbNBbjW= $ :E R)/q_fx9bKNϴ'GZdx)k>YŒӞL;ud.)bq- 2BlEᠬG+8ҮW뀅cWKÒYq3EHF૷-V(Nk.C&0s(' K{^oʬt=(ouh:'ΪX7ԀKI)WTuUrм42Թ6{1K 43"N1М--,K`'eœ[dxٷ[u5š]5=Uv+a Wq0u{Si_ 9-UL%T2}9CZk2f J(R{@> stream xW[6~_aMח-d dS ;-mYd[cږW$呛i }(}Is>˧c*-pnwusVꤑY幮l#+\' |kWX>>EL2H"' "fg)b@\ʕoJ|v%܈POb1 8žžGyi'CM+1T DNQM2\'e(ĤB1iAw3Rwe%0G(U꿲`Hu'Fz :B^&&@kvgQȣ_td#x|b] Kd 4͵>B 1v)$j"@\~$.g:U?ڴ \,̻8+X?0qWjal@ )I)6'؃ ؑQ($ e9aGW -<:_G\Qw(M! j^2uˢ&y)jWPc1xO(nTmy,5-`*bnVۭ.S g*zVe>WZF'ֺUwDrp|w/I;Iq|"As0627744mYMZ<9 Ⱥ`<­n_Dn)/vb 1^\ORN%i=C>&+Qv48Nwl24 3FJ]:IT6@u(-Ra=g0Ə<*K47SzHQ 2Lb OZȅZ`y>1ZPλS 5{W(kwBl- bl{p&7d)?So: #VkB쌌̔W+:H0\TnvQ/Sۄ8ëӓ}KZh V*'{}ZEF'蜴}ulwo?߿ s*wZ ~VE%}Lwc>~!i>-_S_wW endstream endobj 1271 0 obj << /Length 1227 /Filter /FlateDecode >> stream xڵWmo6_!`,Y4M0.a Z%)Tl忏Iٔ%7 Osǻ癩|zZ%Ic !c ?Z,OuWڌwj ?:ŕa̍kQ(j̒q&P|)E`+ݑ(pC XsZJ&84A8d\4msOScOLL pȲ`MEZ39[&'#nޅȗH3b~8]зEGGs DЛnzg}Ickr1)Xj0ڦ5ҥ1#`=a'';ŵAɻӤ_q<|XUž OvmqߢxmMk[8|FJz|wvz1!16_M )z B#Z.nFSHM0r4{; hH9v"|- /WuX^k3%"}ԡD6u5 .8:{/y D1c[g452k糕~&kۼm0߁^mIzq@ǻOԧNMzpS䛣eNNW70Wjx7?{VL endstream endobj 1275 0 obj << /Length 913 /Filter /FlateDecode >> stream xWYo0~ϯ@TR5K ,TC*5MTU2V Fd^J}Y{f9<& }77c7fmySטƗC/xm:H,Kk"lm|:3 ;F0Gɑ@sıj{T@@!rM<>BGR8U F )*jR 4Z"R)#v,Y>ԟ amX]wT*2*#o.0'?Q RA_jn*wi:m4U`R5I1ܚQ+cKDk܍?ح9(icĄ/^Y~eLr0`AmԸk3R;[)' H(|]ڴ̡0\Z%Hی c$7ǽk Wه);t,7 L3kw n8nזo67 MqHŀV^ nu^\bqE<@as낍ָU1Y"#duAi'g 9 g<zD|ŭc%^kأ C{<%ʾdy]jFncSm01ڍeJY;YM.ο4m}H$H!<&B9GG-$HQD)[)k17T<6Gva6;IQTǭ:=M6^0uu*1(nu>t7M-\?8_^0WQo LP%nWsP[=tױ}y6hM\}pt dOFHQ {s`V֧KxѪɾj{og_3 endstream endobj 1286 0 obj << /Length 1285 /Filter /FlateDecode >> stream xXn6}W I6 Am@l-Z[%CEYEfș3g. b [g?g^`(gwَgFMud=/x$x\,_ֿ޻aOȺa}[z]ف-WԗJb"I~(rb7yok{fbD]1b_DyZNFF!2"x_ԉz[qMG41l.KPPk͞_G a`6ޱaZ/ghD/`˳m t^}У( H$SY'V,˴Tm`B7~M^P`U.<q;U^N `ݱ rPS$%!78luCE?A +(]GjyP(ך|sL ܕI9)hÑ"ǤèHY^aH!f9}'ЊceU@セlӁ9x:r-ei'KD|he)7|WqjKm>xݖ*:C!Liɉ꧸A]R\J]QXl/Ğ .˒VCjC %ʔy+'>ђU5Q[2 ỢlxyrYf .Jo :ˑk+Gf )2<AOɶ-j^'! ξ#?Gcx(zYRf9^ک|9mlѥ!T(wLl_,Qώ-K9kmgh/W) =ުXRwT.1!W+Pᰴh2!moS^7EeWR`1I瘼>]"tG^Tp YHv8QMTy Fy[,)vh~ .Y߂YFmnN5Y+Kjrm.GllV ]%! OӕvxZhAڥǮɔ)hD>,Ӥe('j7 ]Ȧi'TrHElI⯤Mdl@E빧lJ [ endstream endobj 1295 0 obj << /Length 1104 /Filter /FlateDecode >> stream xڽko6 }dJ,LTߝH)ke Mx;ޝ,.ίHM F)l\J4qtv0-!l:49˔1"/TkM6=)ˇs.&s@ڝ¾fq<ڡt\mdV$+ƙu^IUk`U*AHle_(f6}GܳR&u8R(#m )jlE.Kvl蔾Іm .0; .,g_*d@㲷kl__ï䡑TfyZ3i)0J؞xDf@b>?lRBC3n$h.(haUu1&=:,MFK*p2 ފL6MvHGԱ JF> 0>C$y&$rRfe[볺UQKC@R˓ 0e⧩ƱިEU%ԇzYI/!Іxl*nb@bۍp|/C" >kNFAδjIը .Mu\X`g[O?;}ׅ/ lo`P`y02bqsK.A߸P fϰƫů]<]&Pµa9&18V)N /m -I5NtWυT2T ˻,ü`a]: 6uE-Z2|o4o?u7a&d,d򂇂+ÔH  G`x]=DEψs?2rANA`woT/z2 џڇR\Ћɽڅ}4nxϓ+C e7X3)ں3B Fy endstream endobj 1304 0 obj << /Length 1024 /Filter /FlateDecode >> stream xWKo6WaVHel}l,ҢE FzUÇѦ4͐̓#rnf?/gQny8!"'\;y^eۋ08ea!Ss {XS"l C; G,±Xb"t~WPM_e+ոf)ȫuմ 6zͱ7=6]/ƒĸY?vVu%pA6 7V%Y)ǹonŢiA~6]5a7.&4 Ҿ;A!sqܪ.XJ2υX*hC Vy!j/WWЌI x177U3bu3 Ns$mj5i2 ^i~xQ(=9e^Z2 #Z,}-H:PV `=]3;sִXF u!Dh>ToݲUXw[vvŖ_ _j$0C:zեr~jv9OG!9W̪&Vʚr74%XML 6%i1tԪ5% ; riw5b$3i8ꜰx2 !;>?Cξh{DOy`{bLhe'6JL4Fvi9g&1ృ(=<"g y hģS8w?Mgf&};>ߊ̴M>ci24(:ٴͽPxl/w- m_庾SWʳ5C[s@6牛$ZbË j8Ȩir^odžy-_Fq>yܵ0t/,9r!,>`nosSWAX%?m%O0 V t+imA=! endstream endobj 1205 0 obj << /Type /ObjStm /N 100 /First 978 /Length 2104 /Filter /FlateDecode >> stream xZo7/\rf0 |WkUZC^P^7%[iΒÙ7\{_ql92"Il6jSLȂ;ޙX>&K»>C~  < -\EXMIJ0!NGקb3$3!o($홂ZQee=#FŰwC0%3Z ,I@@ˤ-FOTGKH_'G1 `"pZŸ} o"xʩV? ƺ:ɤk<0)@&xycp,M}\e]ka'YLjx "3V,əX]sf0KR Dl'8-0tW[Ġ@" a t ,3"#FmW7mbЈM/$7IԷj]) Z_8=o`ʩu7[ep#qƩFccLfW,h ,ke5U-#2gЊL39c]w-^ß׭i]м=f?EgsG_/79x5&bQ'[0PHц"{cL4>tyk^>g:aLg3{]5g٤f:=i(VqzQB. ޻: 6lX闁XB ~5dg׋X3V `;Z5"<7 /0 IAgMR$I oo%7]u tku bpVƪ"&/ 'm?ႈ/R|VRߌ^#pl8ضN$\V011<UL2nPf3H)@oGa;*g0ΠI^tE{sS!MFM-_ lʓӫI}^ܡSy `$#Tvlvfw;)z!yQ!?#\? ;Η5;#ȈžϮbz*1fbe d d d dOgCcĦ0A胁#?V6= D0~48wd~)sbu `XȪG"FeP/QAx+< }eFY7rD?D=}m7"!%Iυ^aPu%[ll8J A=SaC^:mh(Ϲ|ogeM+o@e'G=A5cUjH{*Ԕ3*e ]d:kNM2I94  Ta> stream xڽ]6=ؗ(Q !-himZA IήpHYe6D|,yͻ",x4{|cAd1fmy1R@ &Nʞg1- Lyb'RxgOx} ASU>PC5"zW>}zsVͧd{:Ư?1G\W/54<^j(ӫw2t={444&\\%Zj?/OdkK_KZ<=u=~>1oP2bnK.y/`MIߕKGni ~Hҵ8=P|:qBR\ .OՃ8/iL5c*(K @cf--y@f˥zd/:?-"1geY7Ҍ$!,;!:9 !9 eӷMV77%c"E VFV|1O,9>&ݏѬ]}Z%49*y^ Ry,d(MUY:)Nmt}VNL*i ! Wv6xuI_\`D]F(H;meAlK_`ahv!ļVf=.#*zَH8,[1o(p3.pU8 UƢ9},\qP0uXo c!%3?jc>$@ݱ*āZ,,'o0Vl^Tv=NN mp):+êZ7:ˮ8!XU;RA`n K'ì #. w@ʦ)"܊־y?nqxQbaY/AѺH~imτn IԓAnʈs/G3Sg*{} 8N' ՝7H(!I~Է8笶^Jm6ֺAcP15lqA\1+nYBhZhHQ+*VwnDotakMis@-!M @1RK8$|֛Q:b37$hj!'kݵA1${ \4%3Ǵ6! }FP?;O7,~8dYGh i YF ,JF'wB;Sj?/bA+{[1gO8="7b&T2ʫJV<:vӪ0̓t`?oV endstream endobj 1325 0 obj << /Length 1807 /Filter /FlateDecode >> stream xXYoF~ϯZkimHcE$<Ѣ3;K)'m sof͌_~,f1̮39s`]f&WM?_̏{=.X3s1p nٷ37,E qH3j@>,d+R=2rٶN ttuRKj)r.}玖e5bkYCR0>>\\LGJz^{ũl|ع&Q i=<&xžOԻN, s'Qv1/-C :-64lvYoԴ疇`ZL 1qk.}|Oa:UKK Q-˦)# Ɂ]VD]s] -n1ZmHXk3]l-sy45-4xde(m=t*ig_ѝq B6ā%;ְE9Y"ع'[:RDL/ ;t4~I0Fgqw۔]e$ th`7uUhb-YZmZYªKiX'@Rfxl C1pGfRs91w`0&=y v $e2mK߱Y.Ji & BPJ7: `1qpfW80v= dEδ{6V IjmiQ(6 h!3Ub fn!;*~K2ٽ&ıRY,v:GXs-+cѬB4}cتf⹅#TtJ~4nNJt<-Ǟxl=!>bZq'UZOa @ c%yYk}[&ZB3 hX:rl*[Lѐ)qcnܱ4j%f5B1pS)|)J262ef6a,F wh= j+ۈilSqEj3y+^itϳ7֪*+8Q-5.buiVQ& ྣzCƻc hsUjZt]|4 v*IeLvg lM]1(!ƛJ+'otC(iް{|렩 8!L@Bbl誴mj-nhZ^XdlqH9ʃ&SVUүmVwY^Lד'?#섽NKatʅH%Ƕ3 vEf7ӵg](b2`mW@3u!BRm Âs0kt}3fy _1¾es͐K;Fd3JzLx/4d\ipcPf&4Suc/+/P;zG74Nń PˀdCit'OMztZsh xˇ8Ӄ.yd&y܀(_vrjz`ۿfcWtn-~E !?I;~7N>0, endstream endobj 1339 0 obj << /Length 945 /Filter /FlateDecode >> stream xڵVKo8WP61|YZlR(m㞲AȌ]R)Iw$RZSV؞ 8ewPHa%0BqD 7zHIr.q$%eLZ?~+4ij]Ygb0%g1L(Ei!h)z80/o:C(QHQLBL8m=;Kd24L_ː,U@w G 9c#*˘1XuN^,RX#N@ʆV΄6)Mj `{CL~U4Oެ&Ȳ}memρ= !!?4æ2x"a~sHd6Iga8t$"tjC4uyc;kSeF7*,ç?jU<.[E6;&}tj;yd}Pߚٕz6ςuy\F1JJԽ.m!}m.1P' qu=Em+w#Q> ,t"0궟:1 Լ6voڙ =fz;йR?]9'v۴c4 J@:q=ƺ{ƧI)TW'wz.cRօn[oXfȺƮ򢰳2tk՛YSt_γ+6 4CAKѮnvp?u%(9bkI6Ig;fYݴ[SndN7/ηG Xy^_Z]$xʷ_.Ǩ6,T@bbI1}ޓ^hhDul6 U2$dǵJq}Xkw_R؏tZ#>._` TSgLJgO_l endstream endobj 1350 0 obj << /Length 1363 /Filter /FlateDecode >> stream xڽXKo6WbWn@amEزVTI^'C)9PgP/{?t"wfKQJ\;OrgpWMT_Y1'~EA Bn$ZvL5 VFǫ&ɛںܻAWe`Bf(>wHTrS?AkY_ۮeE1̊f2'wRmjNGB5x`hJFq4ζ k$ >;fj,C۪b½7qżbʊ( A$~02ʋ<S$#ԧNM~ZZֶ,^ =փvcwJp٬CݾKlJu^8X6YM)i76.msMecH6^K: \6ԫ.'@`P#6qeol%xraA[ZC p)-lDH7N&А> AZMjb]kso!]B<~*O!ݥͺDϛXʁe=EH.A"p.@W w|?pE2@&1zlYTx~T[0?[ wuRq4IIsSEi'6[!' N<q#@I KtxQsyH\ʕ/R\읪 >_B^b, i0E+DA]pO"s 7ZcS,Vt([.O_zeIj~ƀK}" H;8EwpGFǣOҰ׮Xu h+\)WW?:"'"H!i4~n3Wan`ƁNtb9jFmu (o8i+@QǷ\Ae`M=;z24W5d$z;O"~8T‹haqӎrAv^5ߣC:1;N;_/΄SߍxSf״KB`Z?MZqZ&-k Guӥlrg:eխd~N=L.GMC-hmf^ 캣Kj[8nvV endstream endobj 1364 0 obj << /Length 1062 /Filter /FlateDecode >> stream xڵVKs6ϯvs`Yīæbew{uMbX;>-$3B积[կ  m' 0:ۃs`}&F3 2)dod}m GW7,t" |1MJkcj;z]Yu5XK(yR?{cͯެԫ_Y?N@\p#FO}|NE٬Ti3Mu(\ 꽁P 㧪 Y]uia,uDn30B,/m)A1&s׊ݺxsME-/$?HvTvU3yN=vp#q=9>!(K㙶P/Q@O)rw-(E<:vv<#џPƎ9GR[~} @}s^0',tUɷT#@-4N #Sٿ6Ec}%HPG@HhH(P3B0c&c%x= f|ߵQ\He}cg(t Z83V]D S4{{I'%vI":S6yJʉcaDۇq杘Eaа퍳 }(b ^Uct7 Cf0Q_"]8 ɘ'Iez`p훦,A )GuN{-BKeK$1,V~ģ%)/똺i/>LȞU8eJL4]k~GV<0VWWlBd`vq\<(2zǔżzi5SV-$K.3" o@sLLʟG. Sֲx٢xt**aR/MZ7yhvٌu_vB]jK~JOM)ڷw9p(bO'[dQAKB7}%4դzj!@ f=T-YȥI1e|09- jmu1*ڇ:.:R|G2q0g W # endstream endobj 1378 0 obj << /Length 1003 /Filter /FlateDecode >> stream xڝVێ6}W~")V)A8OihJ"uH539gf(!P>.~-m0B0D  v9E a'ғFE,nc1Țŷr[iNڀ N7gOtu;F0`n"6q`&x]II%JHBDĎFIjB Y_u +8k,cc=6]{ޛ"P3IMN+^';Ia`$'rh;(%Q1SYe Ta|CʙiN Xެ\f jft`fdaP:['b({߄7R$zAMAW4IA6OoGbpZq_##(aBRjAjcDITifV?S't5--U$k֪,S`~(D6=N!{uy,1+eK=|iU3? (rÃϞ: iǕ:aJjwbUQ h[5+%N)F% νS{>m_>8 yy7m,,..V46eѳsM2tyt&@.{~r ƊswuGd5X|ͯ:.B{|rBU3LeÙ7ЈPKzՅnZ`hcSTǑBFM3y eφR3/x8JfSs- xi)/G?z endstream endobj 1394 0 obj << /Length 3041 /Filter /FlateDecode >> stream x˒_j@n7iJA$FM2Iݍ@B^SF6p7}zc*V,VOϫ( Y³U,MSdÿcV B,lZ5"؛ sG1q}0voqc -VQ$ga"1Ҡ[-9XBNJU y#x_.QpVd.xis ,JSƭ4VfS}*Yzl3- 3Vij+"!4wt[,KՖ$taP?DA[*ɱ>!1j*`PW_Aa8V$&TcQ'>&t*5ʺc?it*8qhvFfzv< ؾXRŷ/rc(5i-FjlUSHK4:a =pЂx|EeQYHq / ̅`iEY;c'iNRo$N>`L\]W; ˾AF;5n "xؠ |!UU4R~YN29<A ȉuE6Y#_G B<3Ux%̀@ڏS˃V# 92a3KJfЎ18äÚǿXe3N@>8ϝ83'bc,OO^t,V5 ˶M@u?0S0)kO d?uF7षv}^kɗ걪{{f]6Jc_&M'c{n~;͊DʄK=kMKͩhf8NT谉+.[Η@[E{AF@G!H>ӒC7N-eGa"^._}sH8!`wd{8r'#u-&0LLmZ5r3Q# M߫ ZF75Gבݨ8Kj~nΛ΂xB] ܱ0 [ch9LD)KãH7Կ44(sLZc1bi?""o)qw x23mu@$jbѺ!yfR:e΃=eR뢉,l2튍ݣ <# H:Y*/i.Eb&P&1?*Mbit]*vC[i8qMCntcmKx89F y;˴Z(P.Z4bAk(-8"]HI '<FE&A9j ,{J6#_Q.9h3"n6IےC 3tmVj+vI@Q2eU2m.5{ <\#@V’ԑ 0]g<;u>FHSWّI=`q8Ρ+n+xZ ;eSf)Ƌ% Hh>= "w8/3#iE_5xpjXE}U$IDHxIܯ)0ohr(ܵ+r#[Iﻡɩ Ilm. b)g /ݐ/$K>5j ̭QG` ixi[hQB&PC=_83|}13K@xʗ$| HQoYRKē*-ĺգ*xJfZƑ{>uҥǶ:^PYiRR;@o%`-u]kٍض/ Wb%sjP=y];Ͷ1 +? D2ONzLG9xF(\. '% -$h0Ƌ+#hDAۍ'v˞J!^{Ot a3㶡E 4@[+3UBWBn-iAn+Evk" ۱nal>zOV.ZZ>'tXdN$4FBdlwtW Nyߙj$=@zݨi~\fQpWZ /X3fuǻ@  sʀo`>?~ÒA#/UQPvH~ c{S:<.nwjƴNtDJӤ-۱R |(x <7fy/j} 2>R4{-~FTq²>XRPL$N`f]ѿ ԼLW~56: xLD.>9[E(XYVM5Σ> }+ޙBR<*aJ38}ZDJ ^Gؕ<itΖ311 wNOqKmur]]1$h˭Rm>dFHCZHб ]і=:#A|>-lӛt&4 endstream endobj 1420 0 obj << /Length 2501 /Filter /FlateDecode >> stream xڽˎ>_aIzQ 0l'Y"ndh[=IޞޯO͙vw%XwqnۇwSYtp0dQn4dI$6q?'bsrIdv9nyZnpe3HFxh'2Aݎl~+$Wf)˥p'݉4 134Nty{AUH@4PՖ. t_u+@m*p]1vi#6;Y$CG qVelx^0K=scGZ1 in HXt-J;vl&+ Sѫ=#QrjV>X)4 ~;85DX!CZҚX[a7cgL NWY+~:uJ,#Q<,ŬZ8#W3TWz``(r5j,N!l-PJh81xڙ{HH?|oI}י9& >yg6\0>ޒʋ)&!O${sĒsN%P٣/\,/ׁ6ߝ~2 d"̨sO˒YbM2QM8u[ ,hsA> xûAmL endstream endobj 1431 0 obj << /Length 1405 /Filter /FlateDecode >> stream xڭWn6}WC¦I[4YX,M) DխKËVPhr89g"/Jz(ou7qG 4Eݝ,xIt #aԪ_5𑟼80Xo]ggAZ ='.(3DIbyD˦`+ i Ccr /VƋnnUҿZ36}?$nUa:|;H䎗M" M,dw7(:&(yP }}ֿ{0 ~9tA p|#xl4ɔaK*RiJ %*fQlYXfGOHw5;ݳR'fulry4sE[@ZyYђm,xɡu|7k^^?HqWo9#X4^'I;O7*ゥ c/Ƒ&lpE\tzCq|zT=t ҢQk,kawcs3޲dU&6܊7\fRǹ_nO[T^/*K[0RvkJOP蔇ƆJs:ii;ƊM(o,`m ƪ&=j81QʵDPCf[>> * ;"`Yn 8dƉvgrf #X-VgWfD%dȀ= c'ARyTL״pnf4NWrU7!Hp"g4 drTȆi'[.鮪6=ijeE+?L{-7PHy#NYr΁r6 rҴo (ey$VFA;e;7UBVIx^R%#cv MdZb}r)P9z!8?|XNQ endstream endobj 1319 0 obj << /Type /ObjStm /N 100 /First 981 /Length 2374 /Filter /FlateDecode >> stream xZn#}W/U} k/61v\\RTMI+Q#%z3u9U=[VFYoa`FX eUtE&WIea@*p:,RË R)&d_p ex/ o3b sy2"( "e,˒Q.aYge^l l9 XJX? r V9~0 r T 3'G;Hg|USKT棤|."'dC N0a)` Q\e9b,bT40G*M&Ep6Y8+vȂ"be>B$8y 9'2BǀQ?l=Eٲ>,ÀZRq$6EVZ TI,, lƽd bfJ&,V%[\ydT0!LB.D$% '$Eo\b%{^eDCTfFlsM0$A{'?[<'͏E.i@4gj.&v˽W˯( kN 0PEȿ],|aց_N2Ia}ї4?,+8̧oO͏\^l4<`O"-j2$M{NOUA5]~\췅O.Vo`׌ r1똅4Ic H{6l{}i7aL D.,ȼ"b/\ˤf_ 6wnj˯A- FZO{1EtJGPAD> 9{,B&[^~h wU}php뀺!X<50+s߬䢘tNňgٽ@ma2GP<wv`wXgda(pw's=q}OxO ww|P(Ysqn5B$IC RI~{g9"Z,Aj  RBVWEz V.\GHRK5CDP~V (Nz nEcq^Ma)Tx[YpKD Fi栉ah4 äAZ҄0vC6[Go_DڂsA :J9W>!!|\bs?Q::0fR Q:E2(L><.)wk!AiJ;Jٮ+w+q* D DsY:X~:JE gaYo\`kAU ,/< \Sgu}? n tYߋH{ҔhSZDLvΆ+R8=zL dPwBmSmq¨];YcyyZsK֧w{#eބ^DEG:[>zΙAs4oOO~\4$}_f:?/Ks&}6g#ܲfv$BMuСZ0vaJχťPg 7v[CZJ3h%J~hVLb%XKb/u$reݠV(V()mywWkqwf] R0?U"ÏXvكlr 'ZݠJjڮDX_yR;aj@iLڨ8|nR=c6&ןG4*;0oF b72ʈG92_+:2Yst`Qy3hJr~{1Ov bW<bz=_z>stRJ%lklۢI,O-_'ҖtŴVc9Jq:fyhG 3G%A"iUmD.D-eW8YOl>F$jz]-R>~ѐ^mr͍# )2ۺT߶m߶O-ڜ79Qn&.MI-E=9@bkou|`l!"B9Gqr3E K@5b{BМN9{(a %;˙fYvpsP䍌,pGxc*~Eȏwrl& KWݰ BZn]6S ^N N7$op m[(* endstream endobj 1450 0 obj << /Length 889 /Filter /FlateDecode >> stream xڝVˎ0 IpJCj4Ue^ #)ɒ^P%ŝ&5܊@*PJ1n4N^?~fCHc^6W븇Ӥ/Z &AY8{~%\&s$ $=f3ddpvEp|(sFB+\ԣы~O*v5{kN־E:RNn08Y^f9M?Ki^jウޝ-Oë"<^O 8N[iT NkKj |ՄE|Bbnk} 'OV!5뷖:tNxěЏN;i4eK1Ƕw|->9"F"&'<-+3>9!jt`8Q$KRmA'4-bߤaUMrђ%!=i̒p1Yɋ}&àGYs_2ɾkJ(s瞽VaKB8CZK˹@-et)xrBFt6wE0q"F)/ۉ=NZT3FYF$yP;TTωs_7pH~~duEgJY/|sΣ t\>]y<<캚‰s5rm` endstream endobj 1461 0 obj << /Length 2925 /Filter /FlateDecode >> stream xZK=ˇHJ{la9فt VKIOkԯ5r94g'?|ͻ:{Xfy 8g*1p|}ye>f4aFj*yox=hZWNZnzF5,Ke<-\+eqWuypݾb;[=7zua~S? غ-MtcCDPLDHL[()c-߹DU.mw,뎕K}&b i-˴#q-tu]^-+~W5Uٸc$ }s(*Nm5ӣS7Cg? fLM-aY9߆< Iۛ@rL:tnU4Jxbr vev1plt@̧_ۢ`3J/ ?4;s!]QrK# [om:rW7E?HJk- GcǼ]3cWԞJ*Y=9>mtL)32{ Æe`>Hʫ2|AH@k d"?.!~-Ixe|uDzp ~ m'}=6#q` KHLZh?VO ;Q,GæĬqNYs D0dc|At%g/\*(aϿPXLs5k^"Y*ݣԅ;`U z `o6v@zC."@>}Gͧ:,Nߑ"X\#_+w]b}1e.v{' W߶u`BJ# W@J{{VѾO+:G4)ŸɦF*x|])3]96Vd ƨ'W7wV%"M1cO$bviAv { 5z5e*u՛L(d등Žb*ɦA!f&be͸! a^̐)ϐϐEϐwo29i!>m=6upBKGb0d| 0rY5)r଒|ŭA"8L]vpp `BU{zj}bz:7fA1O`m|26fX4Pލ,DE#O$['x5L*CؑWr" 30k+f{&a߈fhRǠx?T=KVd:=u2Kj@ |๴3CBm¦=`xYG1ͳTگK1Wv83{C,@|1oсt\iBs0dk:,7OpLqb<7i^ŁJ| n}㫀]3/}KEvyY:+-UWBK{3e2EF4_B:z2\ iuw^6Ddu{w!cCc:33g*z'oiX&&20fn|Ӹ o/y~&&eH/&/Xlba\g`:Vh+t.m&G MY*WyC ͱB_} {uV Z ` []G?uE߿ZIR{*<4 \b 2. !VF?rHf6tNݠOD3.F/;-=9%K9{**w&7Qk7"^kp/33yKLZ}`P(ŽQ2[:oŧ:I~oW"dgt;-j%;(jNoK8zK^VL{u< KEOTSK]hyif<24xW$ Vo/G[k K>3 zHWA,^b1?b>x9c,\l^I ̆,2P =cZi~i~a?7_<=9zC5zm3h+SFԄbCGړU3Mj.hixD0E:%N WC yoHB)qSʃ!K L11Yr~)Ϋl8(gyO7L>qy+>7 J?r߿~z3 endstream endobj 1471 0 obj << /Length 2518 /Filter /FlateDecode >> stream x]}EO0Je}ۢEwӧ^Q8gbcss(L(y0%Q$/>}M*gy*Jp$]e)g*sSr? v42hY(%d&1n hk_ZSQPΈ,f)˵t CĜGn -}wm3tmm'*r lkMwk}9}s ytH3)Y.P6Rt^Izd jW!XiDzvTN}#8Zߢf>r-Tdx+E   |Zç8C@!%*v(?qśv;p!/R ܉RnRGn(P7|:N ׹h@6q£yۗn@_`rՈ S>$FHD絈H;}5T]P|x=?X| 9,f)+M%]&QfdyT)QSܚ!szFʙ^Xdof2^8?'Υ 4ķn0qˢ},!/.^'#BCWۺ 7Q 9 ~,]}L: >r^{+蒘(z/1bJp 7֞w_%uva=vs̈́jbv%\E8T[w?<5#r筩zP~CτEةp~-4T(䩻^qWC1˳/YM?V-;sxty⺑E&Z8`{*\P̹39$+bA YʉVFLSDYFS|>QO1ĒVVsn]l=l&cKaΈjQ2 +N(hm/o.-3"MU hOcM":F{m)q&ȘTqE'|:$߂>Dt7̏Tdޢ0uy,az/lvQR)I2QT>4$OdgQk(JdK ݘqgAk]2KOD~ e*V`#- ڦ~!Z}" ?0sX Q;k$%2}ȌM&k>pфcڥ8B 9-ԗ.^VԧCqSV7Bє4tEӟ89;UGKENa)`͗87)W" U"MA-|E㔰e-kɣ3u!v(h<]%^A :G,z"2;?x_HkkPҝ"ED h|@q@L^qAagwbߐ\ߌkr|aۋ3&}|,P| [UPe\sqk]"qVOlhzS $P@VRMxGnU!}mk^^_^?eެzcZ8Mڮ$bx{pB ƔJxw[0 .X7\g)0dyOA#wj#D nu!:J9`שkweGXV Fy ƂJvK tH0!уPqE@r@CuȻN-/j>THeLgbKGU1d)6% =q6z*qz˝b٤茹b"Qg:tG2gUy |㫏UJͣ ЪcRxKM.QLYnw6̷$P,Ko b{.זėm ֦0m_MG ޴i|m?EYғ `/ SZ6}PͶtiL07$a"%>$ 2Sf{O`~2&f b~Z犋m*1aB=1q Y3 *+;ܼ+_v96KBø`=mG^Nfdo򱱓Z9ͦ-R6Y$`qfFlȾcJ`†ȝqfacm I5/9}63Wag[tex@yL~ؗA endstream endobj 1485 0 obj << /Length 2508 /Filter /FlateDecode >> stream xڭYKϯhI(1@H&b6 C bȒ!S"jv7AG_}E'7O~}snT$7w7,ITț\&q_Q.6gYF%`;phqܻĭ?l6;i)&ԋ5V2V{G4켞COvSUkw viG_5?ۆC}1~(aYdC-p>8Xe =Q3 ]$ &lSD0wxK=ypxkY\P-`w%M XvdE1pQ_a-#6vZL3 f4tϺ3??DN6\XcQdjO}s{۱{7΁WB,\:22;̍O]6,UNI]OΒkg!AgIAnuC'/hntG޲okPѵؠdDmʦoN Mr2tG+̽ݳm7͚8 |,>0:eri~B8ee3jh?B:lS{E}<iB( r~qqӡ3swN^Ũ;2I0[4)J|dIy,rB_&&L+NC>vf>:yat RQbrןk0OC{:!n08A|JUi7gkZu^hLBrn>oB!VDvm=ޱ>8~Q1Y,Vӥzص (銨]ۼg"۽ 7Y6}3;p!Ư˙[ ޘp&{TNf2P>7eڤWM9[3b3IbXg |2kTuk9ԃ܅SEׇR G8LaEtj1~>&dpPN"DŽx0|B ꗶIdLmbbPW`8}>9:Η#se ؝̧X; eibB3h/ၾ _:OVع@;ޔ^tpEd6#:P)MnLE5/젿b)+EaZ$0ōmIϗ:ACyK-߷>Fv䤒Eti )n7PqߞT\7ݙ1u(u9/ߟLX D\_Ͻ>Fh^MM}ƑQNN T+$.-jKΜRŦ^Ug pg*wۑn>mP" :b@k"7ݘs q C01eD8yH !d.e* +\B4ju%TH}a]AdJO|2d}Udh7O7e_. Ǫ_d1 h!F:%^X> stream xڽWMo6WhU,vʖ-hMaXa40VHJ_[/)RhQE{"-y38I\_\-/.3Yop p,cc/i '# \`} BM0ST]b:a<P?c_q?mTMqLũc\)<yJy#^둫A4§N^0V͎ G pHZA rTZBWH0LدzuLMP٧Avزebȉ$ FDZ rm3ʽ4 EECЀdKEՌ#R`.Btj-Q*7-;5USW MͅqF` I c/S\p".g{=Q!{+.> ZWh ͆ĘX+*Zfp9+z1mrD}w)Dlu$` ?I/0GƢ?_ʠXrR=M^ς=bP-zq$|=l8j/{ܫOiI45J h$1ys_]XzĪ_[CiQRP wL9j?nH u&qN-ZWR:znc RJ4ilСxk{8M\:b词%rz$bhXm^.YyO&nV(#2_.7##%Bz[Ab۷Hω#/^;JLa;J̶EtCx3;H{t:J;7fmlW5xVx  "en{b?B:"T]cl!?6MJm)E =*v^ !oq׼3ӦJ*;.AwckYZ!ˋ` endstream endobj 1503 0 obj << /Length 1596 /Filter /FlateDecode >> stream xڭXKs6Wprgl$;C:;dqNiIL(R!(E$-˙^ X{],~_EiSo1b!bQhp>-c~O,14m)˪bWo [^ ,Oq7\IpҤ $!}|X 1¡3{LQg;Fxy(e]uZFDs5IfyKz&CWgTo$!  j!,@SLx$!'r tC,D8cފU! MUwNHsX:ŦamLDz 1sT}@%Pl8P|lV|?;G1&?8Z"g@GP ycέ_fFq4Kzv+Q%uV*I>}8T)e^qdm-^>O:+d={ë&ˆ·AuuL!V@ʟ*d^Lث[:!dd&i!Lݨ"de@g{ThVՓ4wbSaƬY!hɋ b}w001=4EIq!q&㾬izC~cΐj4%A 6`ߠYd: |SZ MA8(0ծ ˜+i*Ygrm*G7{LQ ^4dYԑSykR*`:Ʊk}+Xq{H*eǬj?-(M@ױGhlZ"/tuƜ;i6]tp},S9dEZvsJ(:qOe+"گ̡R>E!צ3Eav+;m٦f>4?+[+Ѽ{BaiWE0ʠ8,/hD-2R:n:tı0&ΥK)"?ӥV66;av?ա` Y`G&Ǽ Xֆ~0 fi# e 0e[FlFlm-Лul͸3J>5('p< xY5P7ܚ`irsUVƖ $ cïR K%/ÜV꼜I w E+.H@xOycٻJPki?BF8$?@>Aؘz4Q?N8;/s@. Ul&$@pk  Bsg+{gq]QUvJ0\@*}^ X9ROz8%"ҧ"3[(l'jkUTvYy~%($dy@ͅAxmj? =Nq>痢xH_D4}ah Qj χ h2Vz1Ti`TV'aIɸJD]piVNR]!C4U!?]WZ^sU׉U˯$BQ?$N5/?{ endstream endobj 1510 0 obj << /Length 2666 /Filter /FlateDecode >> stream xڝn6}".6un.z:S[DȒ!I~ύ(;I_Lꐇ< WÛoެUe6WR^WI(WwկiE~ڛG/Tp(!$ ny7g"t0Fvo˛i'\ܘ^jw#o_h,O>/haaUY*ԆY뇱>^ψBg^ۼ HDZ(ۼEpY`ɢh r}b-x] w#}Y qdݾMwq$^ 9Z~dLd{Y1ҼFCߝMuJO@O-+/.^' . ad_70X3y:>RG Slwt@T͂Œdr&X"[ SδmsKbqnx▰W Olȩa([-< G|~ ܂ln,ʚWrPum#S ^!!<ʫ5~KHh)1iz*@`e'D|X{2X/rܜ'i?r˻7aM7rgvZ2+ӑh*h`U'r7yn.qg|gZv! N,rInJKn1צ&?0xz= 8{a f={9Í&L.t=bdPH){P ")΂۔j9׍fPG_S3>eoP9 7J"e$PJrV37X"=`K-@I/ڊK؟ࣆ?:G_yɾY2 L`8{]0xMRƗzwᏂ^^9̲b:)̕NTLд(D{52Ĥ0%j615xc+^x2 #KߕzɽrsQe3rSITBmw-o;u`[DC\MQ0k a6qes˜)!=j.DFP{ u;8"|A% ﰭ* ̢M HmlV4/\`6b(~F6r- jbg5ޡ=?ܫ"L|gl5Y8Ajv sgk׻aY;r* v9m|-` nuGHEǍ5@eP|`! }ܕJ>wO^p y~FqŋfA4*`=y Aa1"_w S=wy (<_T8ѣ@ rNrFJM]t `fj䂋AN&{hDcL |ƵRcl2~R 7~W5ÁozW=X<]~xiLq5mK(KXy<7R ?P6LA˲'= BXݡ2JxԕˍRU'z|mǃc([B/LϏYrr>[}h1+LlwkVQrsy ؠtnY.;2*s8T8Z5|kOCjừ5Z|?VCkG a/ls3]D]s");p:%g|h\'||;xHڎ]nME7^נ!5eY ̪[a"JWBz[SAhwI7Bލλ?7mޭyl;9Dx;NϭQ@Y^Ah)AՏ:xbw„@ϦNRy@WnZP;,zbGn'g99FwwoA endstream endobj 1517 0 obj << /Length 935 /Filter /FlateDecode >> stream xW]o0}WD&MSiO+}2 ֜8Rg642q!>>s޷֗Yz:{`u#oB^?7Kj>~=FޠPT1i# %e3X-`ιHnjkauCΡ4 /fA@ p0#j2I3#'ҔZ2'43p9˶Ֆ{ ?o;p54K%f.@}QVЕ mJM%M B)4.u8j=9]bŇJI%۔散s;MBE.TL eRo7F_㛔'bDW[#oP%CK5j=/Ca W;VjQnhv L.I9b1E?aM/n[&L R,,OS>9> stream xVm6_ҞnRR:o95r!:&؆'d[my38R؛Q8i({pS%f?Ϣ#?4MZd7gK@6hQZx4j}Rݎ"߿zd-\}#7T)"›%WB-oH0hPh(BAb2jeN A/\vkR ̨=ou('#TJ%mXJQHS! wfץ/L$f/̕UγWlK k0IHGiM*>UK(@S#6lS \t g>2+>{aj6|/M4FtM&!ìp6 ē )|48FiCόCF#fQ욯[*Y#,so֥|" JK`F}8wDfVҡ|g9GAwi@i?ex=dp{F%C[!Ay/PzSߝBзvcb>bؙxu+ҋ >~:~d?wY>´I~!a1'ADsvHHoXݖDv%V\[ caf**^i 9fiRKv׎ZV|rygT>um3wԤŵ5s/âlEiyJu9Ih+W4# endstream endobj 1538 0 obj << /Length 2022 /Filter /FlateDecode >> stream xXK6-6`3(@i P,zH6@XЖl%C)KZ-S)r877L_^d$z= DǤ'w4f&;"XCٔn^yuv,1dG86x:_|BLYjoqO]ʎ;R 4?>slƄk%B2h@h}Uj;Mub9dՌOS`>1.<7||A,mZ6X/qKǬ0ed [w&Lz^̒E<bc7ⓦFU<'a~3 M4~hTNi-5izfvjj?SJRg5EN[fug{6< >G_HL>3Hh޴AG-7H% 1xm3"0m| n 7K [7cp./00\F&b'uUDi > stream xZ[o~ׯc 50 -'AqlZ!9PbW%kryHgu+AYf!PPΒQy׎&IIR)bT4Qɣ%7$T#yI" ҩ4Ug X$@ NP8lLO""SDV'E^w.A* B) R"E*xVle @L pe^G[ZmERΔ2L)Y9Ve/jjDMe5ҥ,0Y-eóJ6ʗBIFYeЁYzNVK2sTTV#)o#/%HYzIY/[CJ6,,1}H\ $`\]E륿T,HsTl-f2.&QQOPT2B*JVFev5jTEdde=$2@"+e )"nx(h [ P",zTAPf+ U6KgD*9W&*a[rreEcЕ1ctItRA`&''7j^0i>,φou_'o>7n~i|aҜ#}Z6&,{NNTA5>vy^{O'y<椣E=o]xhypl6hmۇft 䳶bװb˴)0hkẁd' RnĠ=mF) HG м:.y/0,^6rGSaM^LsFi6bX8C\k as [, @̉fYɟ/> tXm}` 6cORvkۘP;u󡜨w ^]x 8t'[={+qtΛ}w^w~绺~:k'`hBES4j-vb9uM%'*9tMVx »Uy$gb48 Bp:Aϲ:4pZJzbI;v/χ_hv8JtZY& |ا,˱,r97_8B8@uߋg g2άTn.=.|]Eaڭݺel6U>?TjZBj¦WViL+)& o"4>eƼ5Yހ$mYW߻0A݁ H5vр{`fipA1n }t>k76 ! YXpgu,\GMϟ@jvV5 fa)oɧ,,eA㳰vN"'Ij5>6X_ -ُ➼5?I> 9blk#X[8^"gVX議IL&LĒ'5M:&NyPHOSDs:6*i覂qxݢfAWBbR*5[ϻ| \WQo EaD+1I;~J.~6bY\` -;PfN>^|O h6Xvc@_%BĠ$;!vw˗:yþ+ pGOF;H7p\Oۘw+tv%-˕ݴf}Xٴ7^>{Յ)*꿥)Q endstream endobj 1551 0 obj << /Length 1851 /Filter /FlateDecode >> stream xڝXY6~ϯ05+Q%-ȁO;I%+Tl;ázS,ݜ6_^Ně%q.Bo'tU~z& X3M{H5,eC{e]vN\ E~e6+ɳݞ"A9Ke%̏F|.'^_vȶҬԲ_sGbTEZo|y +E H~`d}ڑhc&C۪9mWpGThcA¸\KBATȈ䠲.%И^ Uʶ#I A2Uu_ԃgA F7+, UA@FWɊ.m>_SCFMSwd鑽& `h/-x^>MlhrH&TNlP/E1w2zI^DϒYK|HHs/ aTuB74MY`$.x)ԣL#1o󺧽TCU:hP(Cӏ9z:y \8]QoR&dkv?.dG.u GAEz "i+U-UO4BgΚqhk۔ AsۇAH99(o\',$wja3YYtf- ;io,9.JUr8U8XƲt)cB1žfoWJϙ;[v,>r{/!You1NB-LX4[p Tɋz}ẈD8p"~ V/EPm.eBTۺG/_V"w"\+ Т mP^ w$ n`% MjDչs.(Sc8 xb*/:J $N58a9(`;9\<&Tpr[\YN:bQsm4ת>JkIb~~X_0he'FdT5aTM"籕MCW2' 3AtEBUxlP-O٭)* v+k'G>Ii/с3d6VFvȊ6OtS[{Slie?jB#[xȸjB+Տ>sZ_eՔ:(haNh.NWA|t Bxq0@w4Uui';Dz=j&&mb,;4q=Q{0i}q?g33ť.݋, gA8tyOsғRqNP~5*Za%z6?I[ 4b="ˁycC@vgn,Sn [9 kno̊wFQݢ>ɎƝ ۑ#RFazͮRgEosUf[noQT|.H/ f5 0m4p?}6V zzU76g.Pʫl)NV$hoĩ2xȬ?42UpN)qxBQ8*F0CkGc(?>rM5 V ?J1l6zeX@r&r|&fYƗX̃xE"!/m3nr1oWBNx/a1okYJ endstream endobj 1560 0 obj << /Length 1338 /Filter /FlateDecode >> stream xڽWKo6W>@(Cl.beZ&*(N}"%@A8of8ɵ ˵~G9Ybcyal%Do-,ϋϷq: R 2EQ!Rs!8qO?4&OϮleuhEwVyN ե8;}uг7u8}h|'KsgEUƟ~zE3TZnbpcgA.32)d(aפj\=˩e{)A|PS\ Bz V/܏f/"@WkԨMYB[ǎL}FoyF  9YIM;TUs;rُǷprMka[؀g<ڐ؁W)WFmݳ=׶97r݊+v\Rܠ7ؚ@^"}E%;\rm;^nA.b+TZy:T1Ua3؞1ysP g\qcVJu$:V}E̦|)$ ( X:jVRü|O~>_.QU:xv=ȡqaHV|| L#el5[~ԋ5SGtYf.V_9jM m~45~j'paN S#N3%hc3$IЧ[s}W FfźIT*Z!#l+ :gixlE2}ƅ0o!24ďO`]nS£JTI[-ZȈy5( *#Ԫ [&X>hIh-BR;(۟Uۘ v\i b=&eUyE;V ޓ uTEg50bY A8A E3=U0,R8aD2X`Gw wB 1$Wgmj5KN-1WoڗWΠ.XfF*A-[N1Z[|eEA|crSoU۫;dԣıvDJ~=It@X-&> endstream endobj 1572 0 obj << /Length 2961 /Filter /FlateDecode >> stream xڵZ_۸ϧX%^4fDR$E\.{b!Z[=Y2$9 iI:W jH3FW۫o/~yM2Yend ۫Fhuub=e]o>lB쫚uN@;(DĈ@c&(~`0) 9=&^7톪4at)kȴ ze#FO Z0Au0zj/xT۟$Cx&*̆oTлZɐ KR96ai1ƌYPLÈL7k _^L1W396ArC[p$7Cƙ~ ]:0hj;P;&VbNX!9M^m$fTIfϿ#z)\ KV;kwiQG4ȻN` zwP{zpKMz ] SB.2Iu\2ywSޒ4-w]tL.u+p?[&ӶN9jrU)e Gy--x5zpW, nQ\zI,d&=KKXā@HQ8ZtrA`L谺9{Vbzazwuqp.$x?m41ȻӜV\M֜F%s "^_wҟ(LtJ%d^ };k,k$yd/y-$w92m4|}/o'Cv`#H\M.,*ge~49O^sF"&ښv%j3u3Rer%^ٖ@zڰKzjk6"'yN@p?y?g#;f^cq4b)M r 7ZE\2u8( Ϭmaj ZWzBژ9=B罰uM&"ž?ffI76R+qcI\U8 \c/c8ճ)^)s51ٽHrN~,ҏt6e/~@:M%ޛorntJ'D@?N}_0¼v?s1¿6,#,NtDd sspf-w=9j\O ,ށFa*p{Nryǎ:A8WPO˶GS7/ ν endstream endobj 1579 0 obj << /Length 1663 /Filter /FlateDecode >> stream xڥWmo6_ab*QoK E[0H$ް;(K%x<>lO&~<8`d8m^0 ]6Y'_7<c4݈YsuUQ&f3;n੭ PXuR͜h*1r {+f?If SYlp ؾ}rɫw):keƋk%eǚ-\;.iM{&5k=JOިd&k`ވ9osiCle,i^f"-ATцp0 |_[e 㾛,\'2sĐeZ\їeY~k8tg ;[쩾=GszK3ް- !ֵMm ܻ!>עSM*L6zsYތ/ dƼ!up3W8F0"#5n㠟gԽcԍ-2;Ha9 @[u3jhO p" &UȜ7UzXFT.?EҘdiR~RJ5\3m}K/gϛ0j~ *A]$LzeDs6y[ILȷVYOI]JR^HYQ߿<&|r?FvHD>[|yn'L@0U<\?aUQV_kݳJu6\'py6T]`WZ:n^. <=nOHABWB6=x~}B'UԞsVF}y6߬YR풲 ew/pSݤIM$1(-$MI0^FlYr^Ʌ jTQYRLXAScD@IPbmjpϞ/3Xj=EFBLCjdX8XЕU/@Եd2 ܹTl =` b*`+Bggp|t:4,r 譧BC<_L҈dDf@뎠=װ7P/$Cj&ڼJ{H1xyS.FV_YujyГ- 쏲R:TjZ!y+=#')ֲ U&Zsn)TKFp:Snt݉sV( 9ѐ2MZm`rNoLDO ?a@%f@/e)>o RǴxBf=^c?9fV9=[J-Phf>oM*gScN [PqÄk{ jNEl?^NqGR /V\mx"W眬#e3> stream xXK4ϯ02[;w`vb u)u,K$z 5K׭~%Wzt-4z‹0HSo6 I{[ߗe٬~||,,q9%rj̛sXy"GL+ߌ&axk4蠾;US#5L[hGarXTjQѯT$PqD( 7#E.p\V5t3EXX\yiSU es\CCL+v0zKضdb Bi4ahH'9a`4΋/ (MmQNFuPP7HBQYo ε=9`RRíml@JX@A%FG p1f e^BZw^R ۿu ޚxEKjCQBn:{vRxKzGs=;A84ڎ7>RE:kgNA]^]O¡scOdK/wҒÞ$fT]Z!G8Z^Hf5CN-TzM  s endstream endobj 1593 0 obj << /Length 994 /Filter /FlateDecode >> stream xVo6_A/ `3/C6Ŋ`) Zm"Լ/)R0뼢xOe+JQ$17/v2F8I Nv 90p~Si$2JKW0  Sc΍2lKRpT+nMՃ$4%W[bԮ=qzvNX.s0X'SD\iD:>16zJūmoyA5);>͝Sm}W$`T>hs#o)77\*IF?tSDG)ޮgϐ  BQ jvsBojK2pD+!p\~O'ay 7iUzB,8CaDA3XEZO1 ajONC ,=YP oteU+ؙnIuoI;lv8 Sf*V#jO-$,L2"4=k:r'{ޥ(tZc8PM ԪZ܋S 5𱰆gb-n[32]WtQecΨkQ 6;/ 2'%6$T6^UETc67xr`Hqg^=={~YӗrM_K{ endstream endobj 1600 0 obj << /Length 1874 /Filter /FlateDecode >> stream xڭr6$X>Iw495=",H .˔,e<>Z,~l3sf]xsD["ϸ0 fa0d|r]e77ws8 # QQ.s7.egK"T,Ս\EX3ͻۯ [rVOGd[8U !r@qϊDV&}8@$Ni9 NL P//5U;>7h#^"%w;MSy] ?x•!Z70tU$-H"|GTM?ꂾZ[9p&.fW ܟ+][Le x7-{:͓t*LX>*n>x,Z2\!ND6VpT-T2䎈 xz2T-Ӭar>_NOː\Cĩ@ 9Q:t=SV9@hz{Ȟ?a)"9>}8WV1b^Ľ0'k KWSM. 4aWTN/K+٭kKgyu J~%0䆙m[1ToyęppXоE. ?ogϸFiDIg iҍvNYZ,EXEod#.VhU:9dqVIyފE;S *F 7fw جCH_Q'xm4 TɊXf/k%4G}TqB-Ii``X²Ko&l' M)[shD`#r]qGPf*K!]ˎHף5 ŏy:#~Du<1W9, ډicO XDZ!dͶFrt;ؾcZ:P`Z0>n{Nlg9 {zjd6~{`"hU8:w22GB}#sC#"`hDFֈ&#kcr`yR% bi 8ziƶߏw8 endstream endobj 1607 0 obj << /Length 2093 /Filter /FlateDecode >> stream xYKoW 62h[Y9X 냅k-aD'|Țjɡ'j\4jJWb7ot:iE+*&_}^'odҏ"Ǐ}Ckɴnr\F oxi z1UѶE}oǎ#vB'FfjLAn';U;wzoFRU;e٫l}W?ByM8N }fۦS' ]ҜרJo?,K6l-oE;y[7tގ9uIE\m~dehilT)PhP}8ZaVu &oҵ2iFcfFvfm.y%Z;9Lj{Q oLk CGCBfGsWf%tB) ˬ/A<: dи޶];MD!3dUE#B*d l$V'6%˸12ܓɆWEAa؄v(`{HWYjC}uk tgFM!T͉CheC`Cq| Ʀ8 w|_7ߙ1*TOxCot"R\Ȕ[?pkf&Np $!v 8 רE3 x%Bcrx/ c'kyR0хc sM-]D=\pT7QF+1Jyit7<a"ȬbUA}tԕV]N[WApiԷZ0\fpz-oX#}؀ENԓ5,^Zԧ6`,t;)#=[ٳ6tȶo GrCx=1 2{Ke6YR~(Ÿe䏦!_5rYO(J>?N|.ChGO?, Pgp "(H2^/Kr: E`a᜜勺zCQׇ?@.J~S)cCC5ߩL OO׿ b} /}L\6 +) 8hxн 7ě_v ǯO Ì jM@r[AmuzY? .=i_q_ ߤ mUMZ*KwhOxy,[1RG wy/~JSxok6asUԕ|bd2/O7o9+ endstream endobj 1614 0 obj << /Length 1121 /Filter /FlateDecode >> stream xX]o8}ϯ@R k5/MjWmO*r+ d0Lddセ\{\+\e[D~dmo-u u:m7U2;a'U.3( _rJs\wK9tW.&: -&e\3PP5 [ˮar2Xm<לஹ9B)аU<ĭaGE ,a)_/x|;·r֬XIlr`|shyAgs/_I]Jb@rM @$D53K5`cy1vR#?챿-+ZB@(/?!?7 b&NNEN$'mkAs+ǾYW=s1B=jCU ^h%z6;@"SJoWTOhNٲ*K@bTSP-4'8gԫ'D|@$e?2 w^=; "D٘*@Mا-~ Y0DUs7Z4JYJA:t5 y/o4l[?^ q#\> stream xWKs6WpC !@O{h8N&)dP$CRv Av +<{sxqS/%i"o 8 ɽ_}:J&'Ir2EGu{ D!h5Qa򰯺՚|KWԇ5E wM}³5wE#ڬJ*H'fKM2~ה"9x7}˛ۓ'wzp؎^ i{/a{t'#iB?ܬ8_+ʗ"W+Q֌* mSֽ!V4-"Юx){qUzѫ[i(U[)Gb!L$&g"0jCV57sJ0c>Tf~ P|_QMa.btl[D^[$hi;f.NWػ`wA<ڊR[rcn[Y ڱUU/D#&ࠑR?8D!j׽g=NkgW\N´M* l.k4Β‡w"f';xM^:w^4R]]]hl?ZtⰗU=CG8g 8<†<"{hI u{U/ʆ}UC5ŒJ9AfM#ȵӕW.k1͘꺓VovaI]ψVoKk:lasLB|sN }3BIt"uh@d?+C}+z?Yeٽ[&巛u), 9&:1k?/KC£+vU4>vhm)$/ӷq~ǮB.kddw1 | endstream endobj 1628 0 obj << /Length 1329 /Filter /FlateDecode >> stream xڭXK6W @% CiHuzIr%ZV#Kΐ,$>Ï3 zD xYspUq,F華֊r__ B{>TeX!3Ylf[gEj> ܣ83pްdrCnE3NU7fZN۽,BMc;].SH+H <0#oUnqŽ+52ͣ6;9smloU̙Pt( ]2jGm]]˦$.ޢp-K3nizV!W1_F 5q ^0S=5ᩎԧ % N!T;tXRgy틱 7rXH~Ƿz |=MD<`g%l$':!ϚD Ov ?%.@ewa, o .k·?ͻ<ڌ ȑ']ng>ʊ޲JdErJ t(.f'#;UO(! ȗ%f3ޚ Gu=cdJUP{1zW9f3`'. ,bL~·P!IbF_}H寖+a~Sw#nu5~3a4.p#)`WcCP{yGP<LKtck0;#R/礀i~Ąsؔm> stream xڭVn6}W.CQWmH>4n- ڢlmhɕF~{ɢ#; /m.3gƒ.~]\MBfy~8B fф|uI/QHdV.6֛֋:J! |@OL0(D4>t 췱G5,<만s-ˆV'a#ZsEW%hTGº<F![^2 #?ŘQ--Tdpr=.rHAClQ ++rn%':X k_;NE Sc]V7ePLP64߀D&#R8[1H/3B d9KUDxm6"rj^/uQss0 k6gINт֐I0zؕ 6Eafmƙ:,pi?fjv--G1CPb-M%US⑏{%\Y\} )3g}N7N7;rVm1 7c'xtSiZK^Izɱ\8UzZlJƩф0"] m2">㶋YiE/'nZ;Gwwpt-Ac3QuÃ#d"KOLTrZ%BK "y|eCm|L)NsjrfBBe]9AE]'TP=^Sc ۹45>aLeus`M7ϑXqQ)t|+5V[Aσ.եw4EOtDsxR~ˬh "gC|?m/ ^ɲJ>#h8n= /,JF* Rn8N$^Mfh?ܡQ޲\szZ5X)td# lN75P[Oں6/%xA!>.Z;ykr|Z$狑 ]5W=%(2ًƭT-4=LmX_tG K7ɚwvsN:NE)HjK=w~ȒOqŜ7w8|WAcabX"=dUpzyZ׿߼H;rGfv?r endstream endobj 1645 0 obj << /Length 1280 /Filter /FlateDecode >> stream xڵW[o6~J50dR+[]"`,Z&"KH2`}": y\?+=콚}w1;9O2/Gy& 0F$J4(&wQxe)UŖ/^q9Q6OIeM"I, Jҏ1^4[=e5 뱠BF9j/?F~lF$ ~Wqs7zX))~aU`P(ʃ0 3.q`BjS<3Z-67sJ#`}\/Z׍8usԑba?rnB6 <ի\~Bݡܦ,m:CE&!S>xS5L𿙣2uPhf.[Z9KfG,:7TH^p欂J-ӻm-pҧܭ&?DlpVUYBڭ}5Wu7P̢ka5yݵ@^VBHK̛nͫxLy#UVx/[ڶ.o߽y3 F؍3{2κeݖR> stream xZo7~_̐C2 +pN.̓loTdd4vrVZ Gp8/) (8lDt\Ef#Kپi{ɩJ]&cN`ObrUiBֲ&&j&(ih+(cN TN&~X&e#r\LcaZT]TADPjb3RMSvcヤRNf'iG"NR5stMJXK{Tj|bH=Jp,&0bŲ(lS4M <R2(5m ٴ*#sJ g.5 q5s,ot TĤUfxm 8-5OkPI)67_bGH³"m-RpHOmrILAxM 1lR`mVQRѶl[ i6*D≭G-GrṭpfP@; ֙!Pb`4Ym+sl`lڊ*glC@^i4r1*p^B8liQ(U8?/;7}\6雫MU>cw>L'ƽ= dQO<)^zrӗKگVFP߆gT>X[Wٳcݯߏk2lC:z8Qr_%i9<n&l~l}<4K?_##r^fPg9 x~Zn1^-{?@HR!b_`.7}򕛾>mx=wO pY[)0K׫[okR{|1q5 gzF)pB1￞~ܻ6Z6^HqX]FϯV#Q?+Q|AE1`_$R Hjh VR8rH(k,b4pPJ(|wcwb{y/d!m}Q!a7dS9:dM&3@<&1GC'\ݳn=& 3Y/Ȟ1>g#~vO.ؐbv]\tc܊3j @٫ʇYi4#FzBƨxxwD~DzN6ݼ[ `lS|4jjwut֏fV#n |qZ *0 Գ>ђ ܸ?C_-{sm<ޞ@G|򨵞rvT(^D5 h}PГېX[ "K|N8hd̆:;9hZleEˆ9^͟-e7$u[ 80 |1Ǭ|2F9=㹹NnSY-主)Z2tY(b:H_I/ֿwd=dީM1!U@ns}u֐w\mGƨBl{̷Q N+PWT ]A$Ua3Μ4viL#bjoX' ްV=[_&{6<0N ӡ]> wt&v!j/qG h(7DetngAD77˴1{{<諕rۥlǖ[']7K<͒p]["Djvr iLM[[>G &Wvϑ_Sc o-?B| > stream xڽVmo6_!xf1KK!ۚE:芀h%$"%_ &)=;.gg.Ay> /M [ާE-?߾Hdc)K) ZJX|˯T4Η1\r0B2eU 엫@iBB%6]d?7j(>E^%р"S(*p!*Dz+ J23D4=ECr\7e5Ύؐk;g# @Nj9Rpn;(7@Ql W턛#ʌʘׯߐc5P)A|$ҡe;" P ba>˭ޞ0BweNTI]5gw65(Ɣj%&OgG(#roy(Q] ^qamƂ-?PԵStX#.Sb?-%[Z"Nv8B}K \[BNCmQI$[ׁ4s8L"zQqxsͩ ޒ;Lʽ$Bf$~`Qՙ&Xd{tnJs6u|~[\47&w~H #:spf:OAgGU=zϦ+0xEެg_g:Ctd IBo[>}^6 3y^]n]3Ȩ*,I{a(J4t φ⬩lfsbaQ=n&fB0 ?rtu{z 1ѽCktΌR]rhG0V'Nhͤ,i{Q+ŭp~h[#B*)LtZsӤЧ`*>:Օh>. 9_pQ:wp/Wc bt0SmPkqA8ʎq=d/~i?ϚS6(q"Ibv|2zF=>JÜncG3{bE6t zꏀ8,nj'$wak:f> stream xWKoF WYx2=ME/m\DȒ*ɉ__Cȉ[P$GrE>!#Nc1,~fr]fE3{X|uE=`MKF`kdVxN3*_w|Sf(z^ݰ Aw`Dcla<,3jǍ,rsj Ld]f|o*ڐEY\٧9F>iވ ^\#ߛ}@ρ-E!7L jJ@{#FRL9]<[r-IZjF4nD޼PA&7ZCgs\U7Blye.ԼzQo+ӬC|$O$0Jۆ RG)a l;Dϓ10,(ؿ!HtT## (]ݤQP+XCYߎ+Efc,V^APfX_)mnJNLT}74Ь (ti^L]rljyEQN|߅&UPW`ozWXDY4ѦSy~-lCм yF5Y;BSc>UIM X4Ԏm 2HsƖζ{Ǐ->z7}l62͊T> stream xڝWmo6_!t&5CQ6ktEdEXU\In;%K~IHÇw',\~.IYșsGpsU4$d^ȷez#n> ZЦ_]mrj(d"iתUz8szHęx S4!w혳^T2;]RPEV F]čOpo$ h?kPG><Đ%!>A!GkF af'V߲:5scnuj< 9w7GuJ/@y@terW5 PΨ :s@,-}%Q8b*b\=CHlO;0/d159/nihIAC5`x0 !!{X*$1}4YӬ$QT@}#/C3!$3>٣5Nm ]Ucqi:N߅=q]37QOޡ4 ~L'yn^.4 BX`BD/"^o陁aI'0 /"e3+eDh ĝ`ʲtyUv!Hnr@mF<$}dMt?Bu(RI4eq2ĜrA g_ax`DPhvVp2$i}<@T -_U7 C/oL,r(н!*(N xrs%yYs&%I HSy.sreunye1a= O˽EJJFCQ \\M`)f83V\TI/!X V?f6EsvH9f1lji/nN@ pPww&[ChZU8QO,uy,+L;u[^]`ͼhYVrEN /L0zq)WTwojU_ \_DPyyN%q6:[`]\S,r+s6tX@TS Xtֺ.zw>w&۔zG?Ll//P64wz~oX.E Y˖%;Jo:#KݒY'[˚/d=? ulFn> stream xڭWn6}W٢Cꮠ-EEPH ʢeJrm}yEE&3FXnp9%~G*/L8'8k?M̋~X@:hh0 ΦZ|~N_O M+'@IK~ПUoّ*3Dr8-U00jط|=&hm+dg+ S6\]^c+O>fӴՖwz-H9e  _s 6-mzj3L\(1\`Tk9튠^d?;\d&oE!7cM|"eც{_w,WMN{V NXYR鬋=͉P81|Ei P|PK_vnQ #eo>_Jp#ZQž"u߽x3Hl҇Vg3B4cd?z8. A68>uDXv3BjmYeu<ן5kI X^(c$X{˞-sғWnLM#ȿ[.WT{9M;mXU)9Io.GVkWV b(u;/ss##\"wHG\5%^nTRMc٪pYj) kJ|:+A6¦1=: H|c+-G`:ڳ-?JFH7%Yh|nѮ]hxHiK;z' .~l!_}C6T/MZbi1.h}y5ĥ1ϝI^qܰj726{Xs~,)<ԧ 43󠂳t*cּ[H5otʒlw (DWc!~^sKf7ɛ}ıi~K|d endstream endobj 1701 0 obj << /Length 1601 /Filter /FlateDecode >> stream xڝMw6_lԷS.׏vH{%"%˿@PyO7@=潹yq6)"(0+3Dqe) (w݋4?,Xn'z,2e,`EWU@|Ƚem #ko~Aӯ5 N ,Hce %rc^fT9y-z1aI&T:]IqLI7f_ԄR&',I) EB{ցi^ ?HD:3\vQ^v䮣ْ{1b,+ @7K/0adK+c oEUSDs3_(a/![]ok;)r0}`Xn+RAҵڨjm@j*$Ek= a<U!Q6J]; =A܁fgC}hy 0[ go-M#KR|ꖄhOܑ!U%^^,Q8S[߮uMN4ZZ7V̡֢#U:`j1os /u֮(|`"͊G)LHpit:Yb㭈܊ghjQh14ͮ%ߠҒΡ]f n n=sƊ0Arng֟d]*SZN cB1% \4 5DJ1"D%uꐯu&;]OJCf(a=qYt_B~0("n!*׺Ꚉ<8D2PuRf8i#)%Uu5:ͮdK.դNыکdP9“d7C@ޫ~tr+ vϟW#9ߐ|^}0u7KU!eD,#^)|nPt+amKy:0o`_fǖI3R )TDŽV 2[֝ʍ5]csSoR a]y2Fr F4<.,<ati}E$:0􀙑!8AanGU+؟E([AK2zC0=tK`JCFFgv!Xiv,Y\B;(bA!h?|!V,Y> ״|Ls Š rC7Ќh9a%?kM7 55 £Noـs7ZJ;ݲV%!A=bvݶ8sV7.v@4 K)KWmM,:yVJ.~8ʊZpM~{ؚk S endstream endobj 1711 0 obj << /Length 1088 /Filter /FlateDecode >> stream xVKo6WE*6)iłiY$'ERl%:"9ofvR;?.g7apC:˵C0F((`Yn|TugU"Z @E1hNs̰z9cF`WO AGR>~ 69c;Z8>>y,f m >q""/+H"k͏)v ͫ֬4z<>iv}DfwS! Cb5̟dٶͪrdQHx#gZxS*i*I,3؂~n25/p( pיlD-V֟*? 7`7lWlގB@[ji۝kıcAjG0<#Lxt8a# CW#{vxo4,+j̓1OŔAU.Y׋c.n4ru0=s݄6#imxT* =mZ{nk)k7> stream xڽV]O0}ϯZi5큍ie/iF>$ $]Js}cBDЩa쟸>/D`.$$.gh2EWL>H՚ʅh5)ыEECSwH 5#U6pg5qI,g#=1@;QdۏYvgt Q˅xE9~"6F넸IHBbMu+EFč(>(Y͙=ٽ!: cA$-{۰QAs,+&L׆v' G{I"0Q> ꆠ))WS$(ŞЏх7+,RULu}[f(°hcCSsSFuR gTTkBXQ  E6+LѢt97XƊ5}TΟnIݐoS|+iW&ynҲqK|JPL 'BYWU󣱽+ϱsO#m'6b[_\ Sw²R~ET8\0,Nk_6㕱_5z}}UCtgyXa%M|.d !j秎CU0ƽ Kpt'M߆> wpG0׹JSO*WqJ1*-_Lc> stream xY]O\7}_kχǖP|R+EIڢjľ'ϩӏz\m\ 3=#Y񦂘@J%(>QUdq<|t|RpзMХdTDkF8Yt*C&O14QxG)7Sȿ =$u)kpafuo%毜G+\omn> stream xڽˎ6-2z+h 4hviI`-k%y!-pt yhfI #gk?$|' QI396Y&Ut>9Dz\=Ϳ-?]^{4"8hƌne7FxD) Ƀ&-9 \Mv .' cqy8#~F!@ "Ol-~R oWޱCжe7YeU9h(U<$ R?=ĞĢg{c}nE*ܮqvMy1}\Kw,Ig2)QPuU4u !nOu^u۷F|4$MJz Ȅ;W*(84|?m|'Xރ Ї"m:۞mĴoer2zE An@c01f@8DNem/VpWt>n=&M內S%}wO;#Jdjd[We+WzZBAߔ S)+EaDuW ~LtNYVy#&ܳt =1x#ppgx8S"Nl!KA L.2]Ejy'豲;^*4}"aaLJ,-*| QV*ȊmWXQN4ל^/?Wo$BCa*R5r;ЈRQ}-5XkVaXV%fĵ|]WӽطDxYS(]) R;2뵎ٚ.(m:kud`;az"ؘ{33uʥ(@C@V?ۘ=@ Y!DdOC]x҈\_x+wיqW5R7dS0\ endstream endobj 1759 0 obj << /Length 1079 /Filter /FlateDecode >> stream xڽVKs6WjƂ77I'VNN IB_H"vrǷ:e1_ ShĄ4ɟ;}`|O0Jb8A8ϭ] Ȯu~(ψw |: vP7{[ew-A1<=v$Pm J-[-U3ru8Y0#9_r޶jJXE=F,r!SQ Uo2d14ffLևIi{SjO>bM$yzJ!mD8. Ro,8{.Ƽq%=|Y9˪{G8یK(x8jeZ5zS9<Ԃw}+j#14v/lu+K6_sAKjʂ_ Hba]>RBw3gC6Zts&(1.ӄbT5~tژicJF7,ʦٵ,kӶ1]\!E5#Վ}vwq-6'YO*ſz??>#{qK0)/?_?{.Q؜VuoDl4 NP4^o[QU(%͔"ih2 y frZXCk(Lsj/Aco<40*T!u|`ABVx eKȌa(L ֆٳg>4P*@^K\osʾ'])&?f}Q(OK:Z_( ʖRڒR}`bcv?,R l_9='h.mխMȪkjޏ&ฒKgr>4!#*e"?Z6 򦖾hS˞\Ӳ3[7@1U endstream endobj 1775 0 obj << /Length 1306 /Filter /FlateDecode >> stream xڵWn7}W,Ј!wEa#7qS^[ȕe;\]Yexpއ(RF4.=1ȋ#BzuHQ(KJq;vǛa:X|vh6`=c4֓f[2Qv$$E$i(mfF)- ;btWDzg{-NfY QVָ6gZVv5-#Q}D༢4}x{\;4>}c`E hrx۞;i#lS`nvsQ6պ\njk =UnDveӢ;P0R|{ p<Ⱥ:v/.knUg$ގW\sfKhS.z*1gXl Hw[[DñNv(CXWFjH^<\ _BN@M%3dʫ%V$gs e3 *4$%x7)W\/  pղX V-.@ |Z^ W;%'( Cs>Txh "~3#BSB˝ O9[+$\:PצO1 ƻɏ #$zr2@~xδ8P/K0QRJ{ q_zJ<{ } Ջ 90Rg11|JM"W̓w[yЮj'$V5==q)ꖞbL 'nY(ZX(F1 (< %VìT~Q,{I1o;Rլ ߴ.;˂)etDf¸?{ oƸHC&AOs(Xp:ZMF(TB467/>/99:]u P̖8"KQ nŘ@c::L?.[+gp[i Š4x_nr-z6e#bma9QIM]E&Av/OI$ K8_5c|wʦx)KY@̄IM v\:7-LHc'm@:J4]:ЏbuSPk4:KV~[[F u>x.4/ endstream endobj 1787 0 obj << /Length 989 /Filter /FlateDecode >> stream xڵVMo8W(kԷzsdbw H_Jl8p/$3o5@d~e Y`U $1QU#q#mrX0:fɎSy-/s!?64bWE$ e,1-t E1|!ybVgy#qB.vaBιjJ,$>_'' %9%NTH9 daRI ̉&g0c$I0!F%t5#A1إWρ`|qk$'%SP󥲪Ϣ}_O7BVD1$ˍ-כ#۪AC}IobUTFȅo(+mս(;IHa uG(źOnd#>XCS7B+14A,0tiքȵY>vh]#1J6sk)FHH>2`[5Ʉx/`ZqJBXHQ wPԕ )eu*q΂E5y ns%e[էKÒp Sc]%+WҰ8huػAO~ڟÎi>M<{o̧Zi[+_l2MMw#n:w(aEE4w?Eh|Ϸ4<4 \2Ғ@s9 =[}5B ^zvD֞?ɓ ^N^OFU;C endstream endobj 1801 0 obj << /Length 1226 /Filter /FlateDecode >> stream xڕWYS8~ϯpMj}P;P3EM.SJ |_?-1(JCee\>ݍήȈ8pniؖe^`ec=IRL゙]qfǠL-_Y近 S˰7A&G{xͯlőVGsóm3\3vOo8*no[fF(h+zv=9nj#qKQS.3Ƿ&DԠfY!fK?32xj4 џ9<{;sQLNV82=WЁ_NxV,zp7{)aG̎|-}*%kI+g'bn}B F@F]3i 5IN^f˷t:-kJ؊<N9ZDߺzT1B腜Qϗ%דnN\A&5~Gzn6wmʍ?hرiی}8yg:]mMҕ>_D)S/1SSB{K7q*ٞ*ZeXD?Ge`̎Gu%jsK^ea27l{36y<,-J 0ucO6)ZAr|Q~"S mJ_dYc-Er.Y]#.77W7^k>vMl9)6_2PCQep1[(1]psSw+@ W">X)cI~SM Ȗyq@1ɪeH *=rnA2.Sȥq^c\E;MX=. 唈Hqc˛Gg ct/Xpb 'M,ГjCN+j3Zk}ﺟ endstream endobj 1812 0 obj << /Length 735 /Filter /FlateDecode >> stream xڽUn0+dbHQĠ=h  4uzICiEHVb}G m3.) 49捆ti|'@ ns4#JfG'e6НI ON.e<SGQ)0H$Aɠ%n sx2L{fpyJ5MC)}7^[F@ Eᘻ*40OrZg|Dc# "Yݞ4|cvٸnEgQyͺmuk%.{l1#jd;B]ZsX"3 I^|G`m~\yg B+\Vaڤn hޢӵO>c%\[bh=&թ^﫣XU z[5u^//A>r"0D((*|a}TFHmo. 0 ~0Ɗ͕E=fQ{4JnR{Ҕ #ֽVcaAR?i3Y d/4P|eɪTcty "39Gfn4XjTeF+z?W|)mA6M\ޥa@ ѯuS  w̱1cIXhY+m^ga3aL8 g +zFsO  *T5Y+U/ #"eJQ$N5 O _ endstream endobj 1739 0 obj << /Type /ObjStm /N 100 /First 963 /Length 1467 /Filter /FlateDecode >> stream xXn\7 Whnt%RHhɢLp@=Ը8sʏ FWsDR|SrJo}5 J&BZ |QXE vriI5+9hsBcjWUGHfN;{bȖ[Œ|_)N_xN\ O?jdm n] ڥ]̊[rںJ.#Jζ@\:) TZ]@bY45g iWTG*0FSp0sWgDcW=%9 䰏9Ki+{ ; gCvT```P[?`4J򗴑^C9NC!D I)-5,\8]pR]u]:6V \+(wAa4b3p}!w<ݝP2ȝCv`%)CnAWUHv?ҥ8Vn?]~؃.mfxkYP`1XA$_~]▢ٛœ'}:_0[;ggb|0Lm>X67X{\0|qOp_.r1=hquynf'V±"&N.@{1==?_&gX_plu~yy7?\w NE!ؠKؤqDi0}z 7GǓo]5WBt mcM›cH_Z %1A5N-fpfѓ^1!su8D(3-f+eIީDl7HW*րv99 z}+$RG$Q4fQ4wXD MiA7w8i''My䶍˽ZУ"ѻR!bETEt?N>mWIw_hz[UAECcQjADs"H*I<<듷g˝&x_g1>zAx2..l6iKCHdhbф|juT' ݽ$uw{mu`m n{VOM SEcm^h/h̻1,latA*Q4v8kʻAb&_j2u(4 `%shYс}bsCJB ̨b1]jeWr=v 4F|6FcquYt/hFGi'ϕxB9*)~BCIOQ ޞu|taGQdrKE:QpB>6.R1fhKe?h˜])0*6@ endstream endobj 1829 0 obj << /Length 1164 /Filter /FlateDecode >> stream xڵWKo6Q*D=Рu (ZxӋ\VR#[=bC}ػ{_3 ;_V֫(qRF4r;`0r#Pgu>şu斥 Po:Kp,N/Oc~\ʘrh(Pя=JK#!4ğ{|{R fX~|'z͆ުIc,qg1aOSFI ҋUHo_^w<L.ʡsx {B}7l 0zjHvK8ij̚e0fSHCe u^JU*\W3a)*)jɮx Dy5BI+..+kwd~Ȃ0A!NFfhpEC~-n൅7}n}5<2,|YҔ&ŏHhM;)A$ߤm6Nn mvyJA+`p9r ΔX׭(شWesPa 诟?}қޗj{&Js)d1Rb&ځWDIW(FUfVcq`UH+T6LcY7+sVꁺ>{/GU{ qYD q'Z&{p;2Ifx^2:#ǪCQĸK*KMu4uFjҞ<⍭p[h;Xheyh|X 2+$,jl> stream xڥVKs6WpCə =NLjON.ISĖłȉ^`,v[{;~5{6"ZxW+3,LȻZz|ջWoh!8(t٬+uVI/ƌywe($ Aٴg2 >Q2R6r?T<uK.i ;6;}iv+R pPXCG N0^+]tfs*@u̠ J(+yQ$壕+s[IuZ%MmvJ!_TJY=]ժ1.=,c*d `wԳ{q x´.]ػr]6V/W-=>S`}:#Tyscw0ʱP}Ly3V`G6]pYq)sRVZ؈ xbGLtt(nz~ @]y=+MIVd9@|V `?> stream xڽVM6WC-S=llE.6(m$#~(^- ΛyH6$E%hFETB -st?o(se6Ȏ+D͈r׌” y0 ZfW:Eb%8KW@(H f0^*>2dX4 YdD1d=4D3,~ 4 AN" 'Tx~2)F(>Յ(fK:+W2T]{6N6Jn,ЭݚbE'Bif"nx8`M)fJPdmEiCQ^]B'^7׻CQp(Lt lvY)j6(L~;Ct>evYRbnUo"LFL㔥&RPG(9'M՚_R!Mod* S=-4o3Q E)b|b:ժ-ցy)1% 4+@zJ0#MP-zYͅ-r1D]WX2_p7 t~ ' KQK ,p$7!B>.+,g=Tj,Z)W]c?kg7 7ocwEDT1,{gƓoY I~ǘ*P;Chb<`Mn}^}MT"QG9q6س4$.#d=7.FPץzH;H0T`WT-˺kݴ2ws[HDә|콳s+{iֆŦ wc4.(+ endstream endobj 1872 0 obj << /Length 1103 /Filter /FlateDecode >> stream xڽWKs6 WԑfbD=r4>)ӡ%:fWIy]):$AB{zv]޲P[<1 KbXHEmQ!궲MZ66'f]b̈b",jv {l`+Km/Zy!(BKQw$L!%QS.opr,]Zme)~;ޟ?OE(h, 8r#tdɦwc bIҐ?2s 0ٵy QUzը|l:K -1ZJ (?,,]J6VꯄQ>Q|C 3B uyg߸)Kwboe~6<$_B_ğ@471ϯ?| 4I C+wkL:'^$sO\זQhⵋ]r"Z/ ֍,:r $(bS>R&*9e'5Ds/&bDp,o 2O+.Z5۵jTlGJWͣ))ԽјnL {˭O茾퐤Rs&jxyw9 mh}  0Mnhj}lE ŠͮڲhY I:Imvs ݦ邆nˀbe->B_vRw2w 3|vA;Pd)^R siZ֘ ރvݷLt?Yqg0;}#8;eCs(7+^ռi /> stream xWKo6|dzmEZv}"Ca(뛙o)_ZS'j` $F~gU8w۱o+˚yWP~er1H[sKs}IyޱVug YO%yC$ArQ0[}Ya^T^ Bd@v}[ƸG.94{ )m[1jtE K}pJgr}Rg̬=ܡgݵ?h0z Kw!9+֡c/^z6ohx X=X ZmOY<mӶ״3ƌSnv<7Zxxu-d Cj^dI =uW).HƓC"V \p_i%}1(X/70 <*$ƽ,|[!:϶z,XK%=pTJj91VEu\<h_Ⱥ=V0Yf # <K?׆$Z?vo`^ouؐhcHH(~H0d#Z#|ˋitQ=:逑jƟ*hL~%|f'Yt@#DW:*RB_BI7OլSPC 8YIFTc7 \[F yh$H7pO=W}ޟ rXή檏+ب endstream endobj 1900 0 obj << /Length 1175 /Filter /FlateDecode >> stream xڽWKs6WpCi NbO2C54"$C!)Aiǃ% o+lL~^L. $`(d"F<" M ח"m D$ At7fƧI=쭼\L>L8 G!BH' $`#EȂ7_;}"Q#A/OJ/kIKlN9&86A+vsG#VIk1:=QV3{ۚOS]l\~^bBΎFwY L qSMgu4B2@GxnB0Ą U*ktY :B6lIb~^$2|"W6WrQ$hlgD>\FB{N>+?0O\1^O];2:G"pf6O+2>̚z%];,2R}2BTt)mxp]v]4J;:Ma0#}-n1jW^/O`^$ ޠJtUQW"WԦ>|疏&M1wЃ`ߡªHrUQej8))R'ܖMSc枈KA7t^|z}QHW'RֿIϮoM>=dPY6'4@L HVhj<u#;Y!Hy]|npOWuR43,}Qv~tFEoq7tiؔvUitS$Gt־UH8 :NxB0$DLaA5wr 3E$USs/>WE mn?LXZ}+VĎ$;aK͖-P< 0r$‡[u1`31 |Dg/\U-S#rF3orB}fɼ6nu[t*F >4Bt2y\TD7,0:S.Ymlڛlż- oXu̘߬s(\o:81,?iЫ1Ml4/EyqxktP> stream xڽXK6W9I=HR$HuC,jmU.E{gHz<8Dr8Q~xRfQNrdE4IOedBgz}k]E{tnuY_~\~R# HhOA_jb"{-NGh[\غϕvBL 3Lc %UF2+𲸈Q˔,ΡEe129lE+b(U>pi7G`Gڃq0[ᥴ'ܝ߀020:aWn'sK@z)DL+x}(}?W^.w(֍tm`.@Jpq3 =Nx7}ܛ^L\ N;7s:%7Ѹְ9sSǽ{48nB<>nLRsG[apJX5 EeMov}Kk" ng^7!]$I{}͵yV [R&4ݧ-ڮo^1 )U$(dV#A7NUZya`˥)^Ê)YTn4Fhf؜ * )vDB O |HHeEYtlJ}R %y<үݝz whB bz!.}8!nuo4%8cCsB ޯäU2$č?N v{4mm81BRPMg`۔𑧂(J{k{_,I9dnsptУapn~TUxPrFg+h'2 @7<[nͱ)ڇ gcy թ5U>E("!fWh u&fӞ|enkq~ŀ-UX[i`4B'4pyzO,UN}sOES|y$A|)|QyfCIyg/ I:MaM9$H{o] N(4d[`b$]| RI:ɣ!0IvI7-%y֣GmpYc~.|Å߫}blHu}Cu芭B]7R6>nCt;ㄳ6B&W1_~ ƭ]nǦScOův)lDոOEC(Zew$7egij9'ryl1Pk m3p.q~Q~?t i/ ||u'}I U>͡cB--ă]?=^>&A0 /֋`6 endstream endobj 1841 0 obj << /Type /ObjStm /N 100 /First 962 /Length 1468 /Filter /FlateDecode >> stream xXMo7 W])Q@P6`mAY:{p\{('8E~DRB (P@S MNM+!K ,/89,NHֱ D J%h-u,!5T&S,h:VKEIq8;2uŠ u:U⮛r SWKW(i,΀\W-N3n xī .. \\B²%) *X"]*-ͷS!]n\~R פέ* ze*~tAh]|*՝^lm.tI0/hwL/MGw)C 8 s9 +BbL[JwssYorthmġ>Z0`Ѥ} fp5DeƩC `F(i 8(X0΋9! :Ɓ ʨ"\Sl2JiBr2=ݛF)oLJx.Vk@` F endstream endobj 1925 0 obj << /Length 1009 /Filter /FlateDecode >> stream xWo6~_'50?WHUT=C!w1,* 6ɥUMl0k3|3zNxُ(s27ٕy.c'=7+s/w?_]ǩ #{kz11W'dF6&H3<zu 'ep u6~i(l}w<aӈm9{ZwE;5 |?pQ"]ú+h$lAjDlMyW@ /b\=70m_la&3y*VD҃N tkS v35Ugi;>8bkkri3bVƽEmEiq.聃k5C?fyy5 %)yӣr2IC f+{+Z2ib#|٥ɤ%eAUn |P\tB_%ugG}=2wZ/n]}hǼ+ZM#M*aYd9m㮥n)߃zo;-sJ4v}-`HA\V[JUxo5#d}'O4w vb*D%hʑJ$S%qQ*?{> stream x[Ko8WŮU")KѢ{X҅Aی"Զ n,ۢCӤD%]`#f>{(Ȃ(x}v{N$M@p{( cD Epz~o?@А!ߊ B>5$D 6,`8<`0 &ٶ%[l?a`KvKiHH|`KWiPְ_| &Go#)(&-FDDg-1 S<52SSx/9+ta sKOae̻خa @x`N[.\xS[z 5H>΢Yj-*.ENY{ oDVB#A88:2DaN6B\Goi50%8fjb ۊbSx.1c94 |)N]@do>*qx@2 >,.tzQ'.Y{zz !PN) ]R9hI, ‚\|ƅąԧ..DƇ][*mrM7ٜ }r ˦Ilٰ? -kH.E.i-K=Z( YSRU>hLђ@0jUPW vbe^̋ 6[r AB>zHD[^<%=Lbd|47r N\= N/u6[fse>FypzO05‘}MSZ%-? hh`)$=tF&V0PSs'P(^'b ٞ׉ID!>TX`ikl"p/ֲ?I`_('I8h:jvdt )J(gCRr,0ųlTe؆`BfЈET?-q=1*CY$Ȯ7<}i봎x,o:e& Btc59{MԂůO5+c}Ph~ڵ]Ezm_:_CWΔi暓J.[g;mueR+ξ|,$<85p2)]K.X祑T7:*\q@?=D/=QF8;/K,\ b;ȵkA~< ?! ^WWycc$j7 [nz9qZV-UamE{Ju7@9$$!H(,Y]fq#p6l endstream endobj 1922 0 obj << /Type /ObjStm /N 100 /First 1013 /Length 2640 /Filter /FlateDecode >> stream xڽZˮ߯2pz~@I0l-Z(E`5)NW_Iz3 t갊:jO%QG74ホAv_$dz% '閨HO:Tݹ9&DND4s"!HuxK_ 4t` ߑ潠<X%6G7$qﳟ&)4Y'x01@"0Z0sƇ4VԳz?^-w>Yo<;1=^ @ 6 }dn1~Y3\P3GvFv9\[_E2;@8ekP48 EE#9%%%%%%%%%%5555555555----------[ @nr -[ @r={ @y#G @<y"s95 DCah5k @\r 5))))))))))9999999999%%%%Dhܝ~|w?雇7?ݿS^xu^TQYՒ'o8wcz*g _~r j@{6 [͞[VnBXWj2޹,{eòy.$% )1SBE$h% B=YEIHQ&ϓטdDl nyVBZߊ2U J)X#,r[T!doGQqPYF"lXsC˨7bQeBekS+r#Ŭ,H)`JCzlG -1@y(RH(U)<} UՕ! Ҳb<2q dJO dOgHl!@HV."<u@FlHR3^  NɘZ`hj}$GjI^"XlY ##R\F!":*5Vr$dWJ,ȍHÓk{[x2udG5|4t-J wGgU%C+I\IB86uX7?Jm~PSx_J2]yw{#\a[? .Ӿ|r%>J6 et+!8HX1-\!@K~4CHi.ዘv4e zy~@Ĭu\7@E5|@ DUDxv`>pP[d?~?Hq;]㷰H&jYYpR:G{|ˏ)z 6pD !DO*0 ݦ6H3nIgMƈ~`+I e@*1wqn> stream x\KFqVTQ6J&J a`Χ7ࢨ͡O 7 çTn$,`ǧ `6A@qyo~3G/C]??}Ƽ ^kC6/Kzx? 6E}~y1F yQ~Jǝ ZC #>sOW>]@!> 3 D!hfyJ/lZz]wf?ŀ =75HU$%8-Ņ$ @ y5RL.#jW.7O]&7.ɋ șjx0r)ҜS.1D*ˡԅ1GYsLJp racy:YQߜ$`D̰Ζqq T#$GzuJv*ɿ{e8 lN"B9F$N"iŋⷩpi&I=`:Ix0{pK>`s8GX¹IiL>=|WNܢ7ʑI8|J*/bNspGRGwΓ*0Nґ}tJrCW (A Ov'H"d^Qj~̼2Le'"br`ˍML*$z ˗+8OqV]߰1N팕Pҙu uwջxvD`Qb⠉>ouvN1F?e8&/;1Eiqqd*Z(kS%dD~VG KP7n*6V' 2ފb !8⫏駴~j76yWOT#]m }RgL-ͿEU$Qv֣ZTd")Ie=,f- H`tG!h[t_W/#%9E/H)rً"4 z~=Qur%Jm)jl`DO_SK64Po6&O+G+& /4ֽG8WzďH0 d2I endstream endobj 2052 0 obj << /Type /ObjStm /N 100 /First 1022 /Length 2817 /Filter /FlateDecode >> stream xڽ[]%}_EWURI&I}p!^sJ~p߁6tN}uPO%qV Z:8i%Ԛ@ QϹ%*m%0pi&%2Luy @cyXx?sXD*VQNs3ع?ptmM^+ ~xʪtE ^ #뾾(`NGZ|֤|b(m>JF͟xy#5h%5mg s>G)VƜɘ}]ifd>#hXF2S + a悇>jbIBRo5KӜS24JgKL>C|iHzMx _ PQ:tBn^Bւ .叇 "(! w( C`C9wȟ C6!VϹ2BԊ/ 0XԮ͇oză˛/^׏|L~k7xXǟPm#/d?=vϞ~I:4v`7|SQ?ayqu5AĀb1-[ @nr={ @r#G @<yțm@1H 4-@@@@@@@@@@@@@@@@@@@@@\r 5k @\YYYYY9D&@@@@@@ RhB )4HA RhB )4HA RhB )4HA RhB )4HA RhB )4HA RhB )4ȡA rhC 94ȡA rhCM^A``a^lUmlGa%y@GL~ Ng~9$ rJGig@@m]B3to}IvZG>o!-S#hN1Fzd~;-gCBq'n $x 1:{Иx8)/>?tAO-KwcM$wn[l9ψXР)u&չCb7y%rt-` uh+=[ @ҨgW4\Wj5\O+aVZ֣Xɺ^|*CdɓF "'Б[$`s^\*Ɗُ̥S/#j~`+#dCb ;}3jEq&z%_/ D1T9|! :Z-~u AQHȰUWf ^2Z\,V.WT.v}Im v[ll:i%? q)2/u]ӧH*Gs0,Pz.->1oE wAb I,|MpLi_@bi\![$Cdāb#d ,>uHEwU)s*VU?jڶodRDIY>*q%ǡD5MY뻿h{jYD"YB Ş-:Jq,`xr8Ƣ@LESO:* CP-wCpz݂h9jW}N'o`Yfr덏¹8Dܯ᯲鬳k .oXyQq',_to$hsEbEطPޕw; $V& ,[CVq [~iҗ vM}>g,Qۂa zR"bxo7eلqP3zcx`%g3tex~jP~)m tG%:nк^;MI/C-? qDsv[xĨ{{&2{ؿVïHܥ~ E̚wCy;[~q3,FYe簝&˝V^|5< endstream endobj 2299 0 obj << /Length 1448 /Filter /FlateDecode >> stream xZ[oF~ϯVj&}&DC[ҶBc3!h1xl}\*3xp-n/]\0@2w y]OvuCX2vAȋ. GO_Dg: tm$2Z:sPJў3]>?CoIs cuQe!1T^KzئKd{Zѣv .g"_*sѱU C`w;XA=T# N+Ibrl7wHl׃mUGvEb~[>P{Q1`Jnbއ&}k6BӇ4N{hvl~+ب0sAd'FHf&A^_2$. ;,+t~uFDGT6 os !@jd,B< ׳Q61xiͣ4qIU0RY{ܒl~jgü1A΁~O/( c!VY3Fj8H=Æ1^VHK@xkYXY==ULꌛi*_j ^g0Tql6q-Rvh'X'BcO1VBgD:KtN0`:>^ tFoSpkvQroun^@P_$gG&*g 7^;0B2 {UGZmV w;W 1~/x'k׊g=:?y Gg1?Eymz$CB!8I߱leR0C\ {c>B_s:a"|d:d#!>(|u௵Ju' YW 5ۮDU# q(kC (0 U S6nq_=xmMU 8"@0Q(R ʼoF֢cQ~Q5}Q#kA'=!>m}7ʨL@Fiu_4y&pj|^\S83,}2|ǻɡ endstream endobj 2220 0 obj << /Type /ObjStm /N 100 /First 1014 /Length 2500 /Filter /FlateDecode >> stream x[M1pHV%@tH"ȋkVճ>{`Ȝ]5K )\rD(T-$ʶABC?BNzȹ)a[*!@YXqȭ [y?OqnQE cN.f| #3!0(bq bXI(-fۍ{&{H2AulI \vS݄Kݰ%W@n{(-H҃dm۳ٮ%]W)&cKtwPs2T *U=4A}dᶪi }(MP>TP.J5 k Zĵmjo9 !6o7 fCǦbAQBOCبCأHvzձېZлMvs*i,zirB9-*'1;/ ԤS,85Kp6 tǵ-- jƵ h'얓͸v4`l>yxzlf/e8٨ WRw^ݝp뿞wO??}Ȑ>|y|;p9|xa=.ȢU8 ?= |}oI@f>ryhr()WIхIl$ZHZlH+ IQ 3!U/v\a}&ڢv$VBBz+HFjlXDң + 1r >+g)ZE.Xp*P QJ0$V*x V#wT AQ3 ! aYr) 8KY!5*\ rXPT$,h%QgCVj}3!_IT.Tm$&&rjԕDvIL4&ۨ9L$% %^C=L#6'[Љ$FFXI XkKB'jedDG@OgC5/eZ: EQ:H n973ILJHH@ _h dDs4)@aWQ">frh0Kthb"1IfV_8,%. kRT풘"q mWF|1Kt?E6H[إp#Q r!vA 9]hv$.wI `a q (9%q$DrLŨL"!yGmZRꆃޠ푎PEb *oY_80afǁfv⨳^8̶i>@% eذF9TF17 B6#D1+ec%!S0 w AQ !hrk iyB$HE"s\ڹE*RGHg $[~Jʠvߠs Kޥ珰 ^Q9F0J*>Ǥm FUW9]b-3gdHRgUx&d 1uCfR@#չ8jb ̗ѐU7o DΕ$ |7s0aγ[I:[. u4#[S+evOo`I$|1l?nm~v;wIh?ŦNQl"Lm(D`֕S?$>WKMa+^ܮ$vDa45LP˨jariG|"ܙ2e0Sh- ~)k%hƸ)渣0DE#i 91͖CAW:D-9 -m%Q+%<쒨78$%1\rCuT9rDOіŬRRC,ڂtnTRh[_Os/-5o禲=NCۀn( ²bjюx"Dnv#U;2Jn?-!n Ea$΂@U *O(vl"AڪZۜe+aNg3XT_4__y>^`wRA@>=~~wpzs[ɻz1aJ;khr9OOi55^8/JE/.拾,`Ց#WG\:ruՑ###########7Gn9rs͑#7Gn;rwݑ#3ǹy\s^}FR~{5p^{LSLoe !^@˨CEKܮiQ>wK endstream endobj 2301 0 obj << /Type /ObjStm /N 100 /First 1014 /Length 1995 /Filter /FlateDecode >> stream xZM1pXV'9Ig1W^_ܭwNv~$^"K+ 1eAJ7ɂ+ʳ(v2²%p[%*DA(utuFK!N %+(ZtJ=p^j"*c!kk(Z/,(V[A9"®94D\H$;EI RCD^dx#1VZ ﰎ9N%0l7HŨ%bshx\q>1 -]k |p³(C-y+$k1xY۴Li[yZ&%XPkX`(E+zT4<:.%dZIH V¦Bó6{,A\SH$]H1(PYD$X 1(ζwUȻiĭS6lIfͻͲ86iϻٖl\QL .eQtSM i(zsliO$ǖ"X._py?>fh/4/.>~\>`.*\ƣadVajG˛7\S-z|@ Cp @B.C>! A׀ @tj5 l!.5פ5:~Q.[)Wf3bv'0L]14 A&Q9JPQ WĀk C?KBD\x{b)@7=s@f @a *!ĕi`  c!J UpܪGb"-*AS#vIdX lM vA=68 @ 3XUf\ *0K5^ 56thRqՖ;ΆD[`iB:4f i(Ap2MkiI{tG!/[Cߌ~ D? 'dU_d. Rĵx!"|$$2~l@ٝ0]"1$rqj~Ƣ]'BeIAlx #i )>Yb*wb I/TAuaatW^0SS 9z4ͻ3.+M0?^ҵO 9d^_9wU̝7Q9@   ڙȏuMq !ar/ >R# w**6Q.}[.J@#?ӧ;p>0;z1^7w?r< endstream endobj 2321 0 obj << /Length1 3091 /Length2 22394 /Length3 0 /Length 23922 /Filter /FlateDecode >> stream xڜT]% ]݂;B ݃ w,]nr__?z0Y\P3Ỳ G7&6fV~9dofcɤr7uظ4l" l4ui6N?;7?? ~)nmD9yXY~КӁY5S'kZKW7GS _V6 :-!_ 7=_A.V_LBC: _@ w:)ؘ]wG @]N` /; ty~MLkVV? ˯8_K̮̎@7:R +"+ `qDdJ̑ ` +xYYY~~2Kar.?t //+3ͿIsC?j<:?S)hẀh9WmgZ_kw1?翻Wx[/EqN"no.s/Mlp{j"?%RQL6ٸJx-Tḽ욿coTzQG4m/-`b fv../ r "n./_"X$~#^o`X#6o`8,r'o"(F`.o7sQ\T#0E7s\4#0E7s\tF|`.z8o3upLEo;;l-9݀.6vSF`3Ss;W$[X3Ss=3׿MY2ʘA$,bc[ {?9o%b'M;HgσڲaiG_ ?Xn+ 8hd tlb`a~DV\\o[;;; 48'(66A~/p2u:l` ^pƜ`a8࿐;_/̿ss2Gfԃ |i~!zf&_X~_,n.?,'p_W9OUUcI] t? swpIC-m4G\ q[+Fɴ;x/KqᱚЎr@vƮ/ݨ|1]ۀhu1 s$[F1I"$ 'ۄ#Il8V9w@0:/x8tUG+ݒ,i璤ش%4kܑvLe#d0"Qdtv$Y)]X~EA6H}BeV$|9e0ے.l0m]*@$6>H?J]sKLYSBQN ֤~p9UDw5V an/2h~M#C_<\98d\Bҧ3&oҬBJp$*;Fjj] Vuj6 $*"_|UPí'yx."^X"y~L碹Bz2)Y)tD](41z'%fvlFпc̈́JpTb*QJW!B=O*ma!`;u:  4!xȦw~N'}ENĶ (R0~H3RV_- +E]N n: Q5VsSx F~c\k_!_ƒc < :?Aߙ+Ъlc{Wf:~ 8=Tj .Z\$q]ޭh(ϻǨ*Am82 ^ŴñNSj)BVU$rh/9%Dj)+h~Cp*D@ooy`$> FKOe֜ NdbU vLmyh-P "j%|(?^)Z)LPB$ Ņ9 .BzyyI8"b#(~1#٘2&5ꚧgPtbHw*=e#\$ыǻp8)ի3PQ,Mw#,.1o lWm!꺦Ӓ^M?\zp{eb ebgVRap bFXW@kȏw{>'1IUI&5ɸ )g$b)W/[q?;G!zƲmmQ/߀?jՈ.u~88n9MF+j#'OS&R?2 :`ۙ\5rEMܿ%4*xf)?Eắ 7]#֓FN\\6ȇlWAHxђZD,}B06oz]d PXixm7W![㱵Udf+غo@^!,^]U&A2k.xZi4x^f޾`oa}jQ"{IyMC}od+(:E;1+#"v[zIdz s6b:a']ovf2~%;ooxf ]7{u`x':&[OM|{P#p?1~FԘp,bpy2v,t1֋b`9R6Rp녤wqx3y;Av=7Dx)T4ɇQSw2E>1Ҿ/ ys !fr^1C}qw:׾҉-V= w jO?澳*mL;M7Brb9<]30`i7g;/BDzdiͺd.(w}$}(bLNSˠώ*C$ k/_en[vIc:_Y"xRǑ}Q}@xPv C"9~j?Fp DDhPWhb!=f]Zuj;n3-%=Yy6z==AQ^q}-hZ{q!k}?n3%x^(mӚ}४3BT!mB11E\3:q-:YH9ĂkF}"[p@QqZ 8eV/+ZL4椊ϩk:#Be9We i鋒aqi8g/ "U9\Ic"@sS [U;8Ŷzkhh߯oq2; @y[\pnh|B5nk4]*fu,<Ͱ[LQ2!afR̜&d98] 2^DǬ6AJhSV4 mX r֒DAID\P 6wn|''Q CA{jOIWtT'ٴI~5Y>ifyd]P^v2>;7)o?A'w3yzJ``#{{.l -1FCNo2nqY።ܒ˷G Ǎ&fa5]lA1mm{`޶ U"Z,v4 )dt%螝 f(~p.Mb,urHt?Aqskͦ& >awQnSLB墠AʰiFGmŻ**w(Sة8*U}g~U=섯f|wI[ԑ<){ro>Y{RmHNMA !+(FY{cqALHa4"7/yb\d`ahYQ\!Gfla mZQӖ,&Oo:0* 1QQ2wp 5,\$X i$%i <B1a+hvo62uiYZ'J R?#'^u yVwGf>},fgY%Sbz ēDҝݠ8QRBy" _tGR1NhcTT͉|:BeM(,ꅌB4K7lF6,mC3O mlyU|oU.Kύ)Ňg܇i$>cCj((`bU]= 撛yP *-,vU;facbMOxA ?W8%U=ؾz_7lR\^P(q&Ɨ|'@>ˣ7O3v%tR-2۔ʻ$qnWÐ0x7,=q.ZD"28E0w2agS 9Aer[,> Q2 #(etⱞ;=-4;eT쌱'g~~tu2"saXi26ĺVVqF{ڌ@lby ՊI&>\0r?`*Oi5#`ZwIuR6@|##%8o@{eﶇ. m>_ jU. 3"?2W|0DI5ڼpg#^.msvB`Y@⊷n-*H~ E3j-~r;Þ;@q299*O|!~)I1^8;fOaf 5i[:*D~76F]wܒGBa IeB1僱Ao32F2 wa&Ub$?y }/D3 Պc8zqgDN['j^E2! ,'5<֞R'W'1kQH.,ZqYyqE&(P og3ᅐeŸ،|H}'?"=M7D- M @j:$D'28˪;WVۼob/>k*X٨nJ‡'s.p̯˄d#MdE8䤼ߜt?&Uhxk!{|>R;ƎeXɿz JޝBΈ}_CsIooy&ЪjH`,<{+la0dn.@&}ftJy 4ZrȨpid"oٍ Uk#w#sw7щa'9T]kfqs;}.zOmm4(9=@5[Ӈum[V:炷"' ̯Vo'8Fq+i5ޝwVIcx]}P9ᡏ7}4+Η(48)f×͸>Z\^ \=pYauݷ;N̝ElC&2JqD G>? #%H:(DmTOZzy" yh8xמ3.R04bjx00屮Rɨ>G<矆1i[( nU8)eN Lo[KlnvCݮdh6qAm/FX:]5aAkRLmo`'NUs#{ѝM5Cp6&Yp­:wk)-3FQh5,/*}Y23d0bʪÊ1X'ˈ:ߵ]Ϸ/r vR 4b 1M G"4i$E˃ò/U۲ ['ߙcd%=fAn}x>. ݜʬ$&f'EHH o.4֧^wrH/Mo^z \] y#y h? *|F%ޱ~?S0m,oDdT1s{|? %5DzfwaznO¨byJQZ- ĹB "oJw9`CzD&9CKڬOY߾%2ϨΪB7<_j:lDC' dG%O668TM.uMkz[hѹ#4,1k%Rlݢh-VU@5@ھЂ! z}̑rNzTN̞ L XJÕ!d,4=W8ӳ=&Zx9ŵw/S"d?GH]Er䐿l͐AB&q{5_(>6y2fn;ޯ*[v\vV((s`OP]Ȅ0߄A ]8|WFY{ 3q:AkBy0ؼ .S|_Zva1/wchsc: g 0<&A'NL0;9+&0j)k6h=BGg^mh^XD%c`L#!s ΊPAǔe!&  !J$s}(BTRlPy ԛM#Q7&RI0@Ӥ%`V ALqXrmA dkpv0/JEgoxjOU4)ۆWDZ'"y=bVUp0ՌK3q2'.q;GY'Nv8JV3OO oݨ`k;` c]4E'>+.w{;C񓱮*˟.t'Sݵ扩Y;nkqMT NU3#u㺶ll shFnc B( 1`~&۳AѬ AAlիnN$fdi l5Ñ^+*j9~Bmu6>AYH񵙴*bR+d>`a U#+INpgaVPN)dISMBzi^~ 3hD9VMFg98r%fg::>RA 7A{$߂06sQ`2ƒaEPXKJ~jÌ` kXNJu@JRV;݉^a&}8pk>`F[dR&x#4֙5XxK*ԀgG͸yOꭆI?@ђR1C ۻ5yGhRT0럩06:Qr}=$Ch8 ,{cN71#&ʤ R!y^GiE-%%" Rf37~\ sg5yYrPL?8ArU“7ٕff#!:PȈmby眞^hS?=C%[!(" ȑXq^=US+?z1XD>ux$EGv[%]IӭZ *oSaQ$_%[P=ُpEkjL1vOۊBRӆSR5G g(`̱DQzyB؋:ޕWug&f"O`<e\w#j˽.%}4!Uv6,H,Xۜ|%Fď~\=V݋]g.|o_A&.]BEpY)b-@|&e\) 'tGN:CfX;v%V]N8ߓAlWZYdJZۅkV&Yp9Κ6/jH:~<gtC_>u2N W|qW~߱=̜( !1FS `[X>e+:4g5%5&;rf %yr:gyW{ 9QZ.+mّYiU9{4OwΙD (uȵ`iʜTu9 a° EQcatq]|:[ѷoJ7 j~( >iJ}0{V^#D \$j`>1NNe!vUD" "a|^&{&qy,' tѹf.#^N>={[p/B>,ؓ 6YVNPo3TϮ헤C듗" f\(OChSp: 2 :M9X1ٗ+mtՅd]R`!m>F?,u~<4il|S>,1l|<1@E\řB'~"ꢔ BlZ1(?[/^%\1s7UabJ UaFNIP_ti[$S;ȶA4)N~ /vBFb̍*+22ztTVy^Q*־jÍLItd˝7@>YOd}b|[Pn$z߁D;|T`N?3)*-se@E|Hbd/xPrIM笃&1{ZX%@;U!WpT{l;ݘ,?EiK^Eє]' ݗ*!&wP|D/ZB:#Q5X^%[4s\Jdnv ®? c@ SFPկ:ÛgŌ"BǾ0wl]vtfEmO2O>:Dd ŀ}b{B͆KQtwq2j:""ڋ^3ImF;[,LnYk+#c[OBy[1̺'׊J+G1ӐJ&:oV$~Si\CAId{^"lBhؙ$ ^Tqn?-|G)tKkj9eo!N4^#cciN5Ai2J9'}Ͼ2x}hFFrfA%gWhOuȳ6SԶ|Y!mvstսIbY;]ƌ)# uz;©d߰8!ٓ:U -RJc˜7h]OZ3R]&S%W WP=R6 \%OzT%"o@?J#22=HakB;;&RVMi$#^x_)}Lx<&;Ak9E\갇y(ӓXUKri /v*F Rb}*:ڶ`j|Ie 1հM֗wN3]>z u,,E[}EK/lc\KPP]+՝GYCTL#_ȵcL{+) Q.ji-&d,i&UŜ;c+}KDP;8ZTع@m~r6)RkY)!_[觤rE<ذy]ԝ*%o'.|m ƺ9s@1 KSKgZlj Wa0$p""ۋtg t ZfDJ;Kn;%HS&Tw|ݶ"\(t ^g]u;A,s-|Iê=ޫS "Y_Iל÷#7kR,(}FO1$9akhp_V"oTUIO^ajd:Y$ ZWuxEc?+v|bD;e,HDVqWBiꇁсj7T V@]m7_Ԟ^:jc0pf`'g^& ]UWih#W0hL›Y|yϰJ7P{,tElkL feDO%R97]8W{!~H`9M#yxݻ2*7g"[=Q8*OCSW}x|ь$ԩL+FR &հ>/gSOk R/:u.]kbo#s_i`TKϦM'd#@sί.| f7EQl0H"3|kFTϼ3aBEC||kX:x1^Wfno1LBuGD+!'{B/UMY'pnPJ>y"䧣1ؓIWWIa$(Oα7RQM.r;|V&kU+Oznܶٻݼ d}w1= ?,d%Uߌv$X^"P~lep@DiW/3 |&z{,~ iwhU cъ;NԱ%+Zf<#W MƣK{ +lʯf=,jmYTs+ ,dy›^a6]Zs찙1 YY+hW8CÄj~|&7)_y۠vݺFB$gC{5ܦIJ?, ~Ԣsyzxf].?_QY9)!יD}mݮ*n>r_ySL`*OaDono"Oß n_V @A"$7;0@iy%,p#Io;=(?y+d16ArDik"$XVcP3T|/ EkpgZæFVz=gQEƷƄ;v5>./I×GAkRhV hfo`oWB-?Jhs~Zrztp}j>ɒ 71BVȋkhE,W96=V1ExnGઢd)vKQ*@# XjUH@=J*Bm?cBEz1G~gHXfeWwa ^,KϊO8kΕ2GțirT$"d'AX>)VoBP,I McpBk S R"׈j0KĦqi߻RZR*ϯu.X*QJ3cZBwDz]nR|%x>B.",ؚO?{kR;M5K:m d;Leи8ٗ?N|"5 &g3 /Ay[eR~Wx[h!&VoMnNR礣< ZgFsrA/ylK#my%;qWAM9PDQKY$2A4xȧ3 4~%ㇻ6KX{"~^<-#d 1r0(1gyFmeՔd}m+Uvv{ Q/1;hJ5"#?6'"3=NZ;Af7E2+34lըaAVoC\W# fh>k5BT0H[nYQ\c23E[HdqSdmkp:FȴnxKWBeבjY^r1-s7sfϝp6 xVB/DB$Z<$kTrkLu7Xуd,2Ei_tSYFqECY^h]tfdMC1i@7Ѹ.Z|(hۚDTQ |el={!KRډYģtmƎvkQcFO7wMܡ5KC°CR/בyABݲ1##|,dmy6l38=1{YL,*@qP`.gsG/\3[\pi $h.b];0eT?}Yub}FOGC1\y@.K㔓-H$A0<`Rpm-\esFr?2.Oӥ/qZAwӝDnEZХ+԰K=ʴ;nתNUѓ<"˴Zjd=Y ^SUHhWZx HUkIʐr8b JQaf͙@~$#-3ts5Lj0;PiF#rG+"^\[LSf񼲟ApbE-[  e‡kLFLUE ifa nHƺ ߣZOgtVxiM:mVI, ]zF:_$u A)Է=s[#عFo*CݻiH!{uF*/q݌k5ji<渘mq t4ֿS*='td2cq$Op$Gn7{$&2WW9%xՄvQp&|Vh0HF%0&1=J:iAz_;A׹]PX2D'UcbcI t>F#jkHcjruwzA%6SSpa.EhXvr*w:H*?F1%4=~l_zO %8\>LXE'_?$׈r.Gj$ (HuspD+&'T,L,g,WJ_nd +y;U0+pqucUhUsm#ppc3J(7X ?7ZUV2U\C u}LL6ψjc`eJU$/ ;::G1};N`cܻ(]7-3Yւ0d%+e6gt mu}[6a@ӟfcw83lcܷ: Oʓ:qv|*S4oU?bA&UؒjM|$R 3[6H/pFOsl} 8"݊$~>"4[gk<lj d][:LjR4vSd\呿y9L23HTŹs)/{SG lZyi5 ]U{| q)$B*D= gySv+:M 賹^ XbpNŚ\TuStt߿%7+}%CD#a C{Ŏ MvjNeה38CKE:-*){~y{p̃]l=[zAL}©ʹ(ߒ(08Nx/Ȗj" "<^9ґH::H\ң j6̵_lwm_w{w-vhEo_$t)T"s2 lC) Դd|>aDMŠ<[PMW EC>rL D%AQ,\鏳HZ`"cypoŔgӂjWv|#"EO雩uj(f*sJI [6>TrYΣ)eO]fQ2e~ ^$/7n=iɫ[I@&;ҿ8- {~ʈbV+=|I}n5.a?c m^tQE[1 h H wb(YԯuՈW/K (…vl&pP"P1hG%_кzv>d랤(& *qVzëjWˏv/55G pL"¼|(14)P?K)cWj/o1cp'Vmj Mz<0۠cG9~AA|.rJ!ܕ- JMYxKA׎QM$k]J1f*Ih-X\V偙p@H 빚i6G3\h tןLs#_HkG"=:95!:յL xf7/YTEG~ 0[5m߮,sNR$DR1hqqF3![\7/ l&OzU צ$_)nFh cd -DZl`!6A7_HdWemKRuorb{p~ -^1s;R= bd/GS&ahJŐEJ$ S=6l1ȂL6j7iF lU.=FGԴ: XO>J1j:i϶v*_6Hί1 k'O-UQ(zjG:+lhEb|'i̵Yˁ9;@_2jKJIdj+=yܞj8QV>x:<v@wYIFaO@39?I[l/~WF8 ,q!" & "/oZ0[Zy0rEܗlb4PϠD@Y*sDֿ&KO[+mi8"n1dհ[ 'W6]2#a ~<p}@x L}z $Љa9#Zz{k! @& j-S60;wiV1pv¢@5Od  M?єB{s~P>5%&a#iE.UdܔxQl˞ ={B7cnDC l\U4;Ld̎R(8%U| Dݰa߅!X+kelWW׀^ jM [vR¤gxVl:\HIm#G-M+(>;KXǺt" 1 f.Uį)EW1LlTD=^F)>s:\acqqB.@8Xʺ*25n ܥ7tQ,ʲD͑ ɦ_ZQx:t c6*G^/c)e0Rw/D)yF Z!E,1^| 7-l1=MRct 83 Bۃ -fE_/'I'[|jH?@hU=CWrѱtӞqrNoJx%-^Y&;WdezGLO\&sprunOvN\q4#LDKPUἂ iGe`46|nMK͔!VUD(&T/cA rSSbĮ7^SbuKf:%<(Vw}8̾Ue[PuHZhn`-TAܰ,[YDaaXP[?akRW(AYk yuJPVÁ+(13zOefF,УyAbwÖv j ^ca~\\R8]у| ȧq;0|n.jɣP1鄛{Yay8-yb4l"3%"sU˂滿] qiڲKMϙE1"75RKLu=8 㑥~'"Z_2N|r$ބ8_rfi$@DZ4coyt0B ۷JU,B>ut&:ELII"ݳ9UeDV&l%5y+C"MQ?Nܗ-~hDTl`jT~|ҿ9@Ic@̿@Ltyjt0KFr:?!V35,曢jNtV`lv=Zٵ P\VtVOcj8^rizүjPY;-Y\yۚX;K0xa:|VD|Q˜: >sYv;]붇N͏~aݶ9yHI[.[ոrR.Zr0*-/-1x,XFe(޷WŲ6We-qHKpf&au&n'ZSyڳH 1Rv"U۳`T1,P}Wm/3OqKb[Ǡ /81j)?|)&50[qky&py>zKD'N5ߋ+{̦Q>TqdVHj< ǹ=+Mx,%`CmL[B6>'yf2i\,TECPX)<'L%z, Z+郑+P y W^\lX#^F-yLvؒe3nmVl `1ˍW( OyYLW, ڋ_"e-rb&@JT nűvVtײqǼVW-w%K˔%ɯ͓7=x? Q]](#vn-!غ(T0oEGCG[ ]|"KaqMYzwv5͑H'ލL(( ̠:;mӵ^zȏqZZFL G`y™tKjH[Nqps0#koBKjp-~@UɠIwWxﵠ߳ð2LZa0mB-{+<c0s"U֦&AQ ibh Ar|!yhy8!y͟Ԥc,ȫNWm*ZNRay/[g]A Ɠ3G{ RrX~T{24߈veKQ;:,*BDBdvK D e#7REm ZكQ3\ [%?٩z@Pe\MI~+RoM+cpQnI-~F/ YI%q~bwwim[;LP=`AEzr|@B`CxH#u0LJ!*T!p:֓d!.wcw³dLq Seð;P\oS蓯r7hg.@qѻx(z Ė(/ Li#ŖQkrk{pzوLM&1(oxP endstream endobj 2323 0 obj << /Length1 1412 /Length2 6181 /Length3 0 /Length 7146 /Filter /FlateDecode >> stream xڍwTm?R")+ݍIJ,t)%t() HJ#!t(|k<>\3>r14Pr@CpH( P@ (Li øA֓pCQh.T,Ph{@"4HBR(i* h#P4 鋂99cpCx )) _%w( z`3#0A@`P?Bp:c0Hi!!oooA;Zrx0c(:~ C&H 0uLo0 *`(u;@Q-] 9Hp9!; 07(@]W?`74Xu%#[ A an?k{jp;AOB+p7owpY'R j`U$9A11@~n`ꋄ2~5#H# h }^P O?%`P'ѱjo`|2w7W,u-/2/ " @@QIv8`؟ 2a. auJLc{wJl0j+&y:O?m\=N56 o:'\_N?afhyl|[ՏcKCoIWCo. u N\]:f)1Cb|tw?:C?MG$ٻrypxhEl*5!fUE7{dSk(8W.6;XNpKu};cB*g 7b#YZSNY0͗Y\#u|g{'{dhYq%]V}l|W]:՚].vch[1wds|ټTXG]*r/Xf OK-D/f=jcq~ˍ%@B Yq*~+>+ֺjNw/'1als}QGpp* +C^ :qDH*Bw~fIM~O oʘOv;&ߑa-a,2K;WDױF-E\K]3PpN Hk4(Si gi Yg\ԓO;"NLr7XlY7*3,<޲ow%/2x qOmZ¹ zJSH5+\^Reڍ/M {5N7A]Ov]x^x[A._H:d:3q<F^ Ln;3$Ln~[pnxbm#/_@zRLUj'a0+G9$a -2k!M}rWv"0H26 9hobjga$"W"2G~f l㡘 ! ҵ5m@v&傛ddaAN;-2EŦĤWϽh!:xgdo^WKG Ub4/_kPr+@߼=Ivlo=aõxНÚ2KjU/p+XwY!M #-0:mNGˆ_ u'wzzHI-6/+̮5B{gOHD΁Gwl0v#001{(M"xxC1S!ob7.:` Z`kYЯJcLxkRl•к=Ql^H흣r! /Iw`CMMF^94ה7-.5> &36o)to>na}F: /u̬xŻ` GM'2I eӚn1%aF'6?0 sL"g]dp)A'=I:-BR-} 㷰i7OֿsaSݖ܌؟ ϿӪ4<vɸ5"c(][#r==&I}r %zx[ o鳝'& G D3JKnWuc%R~$atW䥻H4JSk-0pMyGQܠ$Ft߯KJɩaj.yhi}I1_ ɃՌ-%.[r5~Df{Lg:7/ߊ*DQfdzOs?X `62~K +ʼn$5ǀgothM:R0A>VYQ}U}ݭG~c"n\ aU†ٙ9|'qhQDuxԬUh|tc3"y#T $GSR]\OmtGw\Lc Oq5.$0- #N`{r*g鮥+tn׸.(.ږ(^T5?1}Z :'4k4)J~>;t˰eN$Wt!:3n1hNSPз й+N٣t2=hg"-D{ ^K2NsqZ7VRfd 8x.=[޽p>X"Dt~isMˎ<"/1*ng  à}dYxUkπEfefncpF .hP{ótkD dqr%,vLYk/U/G4l*oÈ%N6N}4"(v N"ԮӚw!2՝SKw|"G7_mGxrEKU30z~WW/;-\Ƿ*c7 ̴[##\ Bdž Y)?X1 =O xkV0WOL-."p$W\r4yKQ 5iMb&UE;)` kc g ڿy_DM0 \[m\8K򳎏Ho+[L9KuV⛀ wQQ $ڎT=aeTct7|tsptqZa[ߚVvh?zm)N!܌U0 dn5oKdrp/٘zd7MU^yuǶ\R+dϏ(Ln Vd4kŸ7(u75@h.q KO@0BBIi)?\/&R9c4a^~.ऊFuh&=vb$vir~0-b5U)vI,6urN*_B6w]NDaiF al|#ܿA{0UNgJAlC)' uC] R g磥*Pf^\Bɉiu`?"&c>#W+=vs-W'󓣅}#j>~^4Rq%.? &=?A&M):ڊ.*.bV"^؄s;Q&v.9E;v)jD^H>BӥUAKT4Be{J}۝MknUn~lpS 5oɓ4WdEmRCL^f <#{%9?JvӞ}MfE Nk)Ǧo,N$K@]k7{8.AfLu6hP,-j}m9|$)%LPHhף׊De`ਗhهogat#%'QS]y<ެSa p|J; bgߗn]P˨4ZP |t׆_6EG=K "]gW%>|CeLQ yH6!%E __>N="$ IG?L0Ji۞҃\ߊe8Ek&ԇ:Z %=|'eo zE ldM֎ p,qWfZ8>vYyTn̥_lRJlVG}S9:)XM|)K(zy7lhmWW-˅/r/H3 aMT~ACTTWLӥ|zF bڈxFCL%*%D&gN.tdYE!sK:/\&25F˚wxT &SO>Rgk~NcgS|OOU]Q)\1}YIU%ͺqё:s/D5ї|\LV"ڴ=,"58sS>F|o0' ]oBl#+YP!E. ҶۃG/zGvgg5BnRޱsɊCbQΝ{Zb/ Of}{ad4زh}ZMybCZZD kcu ˷N %\8%N¡=N.oqrO G_ Q[w,vIn h_hrM3 k߸28[ӻq-=V]nIiP>CtGU' ':-~5G' nƹKjsQ$id'/ K>z^(Z({ڢ%_"Jv4Kb-/>ݖ%]n0T]x֨[ QX: ) R0VHF[ޔޡVk%k:/W o\or̗{8=*;9/avԪ{;80m"A|> stream xڍvT6 "!%Cw ҝ0 0 1t#H4HHHI "!"7{{k}ߚf}u=kuVe8 (hjxq G_0. G+@b 2N;8PD'@8@h0.jk@GsB @8!Op0G 6I;YӓwfxBv=b 50@ 3.3ׇ W|l ߟn="_`Zo?#gN1Wݐo7o9A @&)CVb uwo*Ifn  X@`?#сA[Y||C |!yrC {lRNC [0 Ei |HZC~3#)+5 xu#@$ xaax87_]~ Ɲ%BBk=$1M q}J_s˔zZ.篖fN|ϸ锿Y%LߝN%a&lFyc*HصE6{2ֶ}̄~u=ɞ,$%"jamZkJ5hČvW-VBNϿq3Cո#-D‹,{&/{lL^F<5&i砈vT2,40 ᎐Ԝm-Ų%ikxd_}j,^raMyK$#,[dd&^U*mj W~x.K㥍]^ޛ!V=2v$=hP!٫c "zTb4ܯ{^8^]R$Ne#8YZW(`оSZW^h]Q4y㲯b5? wMVqH5oIXn7=hίy-|hJ4E aL?{.ya_"UM'ӂKN{k+'8YܖFo߇ 'mԫ;JoOٚhOPQlgΣ.}?kz sZj-S]%H>r]pt\ǛA#!$EfG{h{a{Y)yf$2(D~N˚Ӷ|]6nH"]E!}Iݶ)7hzYea:MXOLt=Ь]n7EJ_?cȳJFeTox_,\IԷd mk6MB(>Go0|OIAbj|0(m+,|t*ψ*ۜݳqO'^o??%eΈX"XЗ~G]4G5)o/`zc_Fj@zt~̽ }_bw)jbc5xYp/`,9?/ xh#<١RmV)qnҟoI$S_:G:šgEW Kmu?n54 aa*P7Ҏ,s5EaS~/bB /#Fg3^:,wr/E44$GoiI[3o {BU@˦p$1 &vYQ`MC75qkm!MR{NtZsƘ=SQ$ hԴf+(vaĻ7џ,W8dђV Qub{HhoB R+^|r4 *Fxz61Iչ؈^'.IfZ|Z6kHHIJFU[Bܜ R4}Y!aX`ؙP^ۖcxbx#?[!AVǸio4.BGQ#Rm4PjtɜYD\t7׍F@.6A7~6se8/ <OO0rtzws^N(Êm3KXW~~zz(EreFӫ01SzrU QFP˛ K)I?jm&VvF7^&)`m10~*Da^!''"y=&C^wv} WDڪRf=IΚդYV"CQ3gN)  );)Mm5>0s:!v0oW_ ,/բ:w-&Ҿ Thu,|ix5p1Yz*!Y~Qg›@%rTpPą~k,Kn7o [O'Y?n ӯ*7|Ȱo ],fcG`Ѝ]asL2iNW뿂#  ?Ro~"A0&gWsYNN|Hozi:b72!lm'졗V="\Q&`Nt t9_&O4nԋ{R!kƐJ5m2e3g7(uEaO+/[׺=(7?:݀.!^/^g  F7 *wW0L Rvu3iNq옫DEچ06ٱnKRU=&xϒ4zvL žejK8gm6)qd&ZR3q=EͥrtZ`$Ͼ5mEN(#4[7vv WQʥ7m|)g4;[ ޛʼnvDekDVrBQ^D(fpraw?.p!"4ty?؄#dcyڍ>Iq煰][Љ[w^a`iEZ_<=7'b|LY*_@^\C}CjDټyP+Bgp,b|gP}`hkEڰ|hPtXla٣ |{ѝ%JrIXL"K;*p5$HTk쐢r"J]®:$T:׉MLPХ)#u> Ĺy䖽1 ϳQ VlZqwF,3TB$\<뛁%FIp00DA4 jg@ǒw 8(4G.ӹ֮#I umNPtkl4Oǣum'g: Lj`QBm~'Og]%eL \qr ]JbWOٴecC bJ~[\}ga$\A6f<=s\iŭlu„MIlGi.sBl}.k7މu1qd9poU8QgdS rĕmcCxr1`>2غ/[2|E<ص3#~cmr[~z-A&"[6Td&K<(ý>m{giQGKh JF:y}\ 'A~tG6y>rnh'TT=Հ'/vzC-LSdi(Wn s,\|g܄Qm%]~dSu}A E Q7R+iOTUOpe߶TDq+n~I?^ұKL *]K/S޲Nm7v#l*8x9vN= C[b!RrQ(b=pƔc"A(WPB;JV_&N4?1;G@f9aܜb>_-tBrE*@ŒmeY |Y0J7 gw}YҔ'X'^b0PA?,=s X8$7XTY4/8T{9+Pa[,[p7KhM CXj endstream endobj 2327 0 obj << /Length1 1428 /Length2 7069 /Length3 0 /Length 8042 /Filter /FlateDecode >> stream xڍtT6% Cw )  30 !"]*C R"] Rb{oZ9gﳟ}ؘv`U8 (Bxll$c3#< p"(! - Bt0'$⒂!AAI2 ha`<6%/䌼=_K=(!! F@A0 v=!`?BpJ;#n W~8I A: ``.2~<63nwDz`-؃a00p{8HC!k! w޿A`ApW7s8B`6? ~AP? n 3T a!== _% s{*0%+2v_?} {n!0_E8x ` 忔[? `{g_}_mnp7m@# @m8@;0RV{@߿WnA}C_mM?ۦD_"]3>7s$d{{M8tᷪ8#r+AQA[]o %NH mm? W/VЁߎ쿩f?CvxU P!H{?j2(և{@~=+v>mN?T~@|n|og[~y-/Gꨨ0@r[7p';"o@'▍ۤ>`{QTKyxG:o>!7\|/w_q!^u5O/pO2^o}UdPwpippo|?oKS=}>cՀ+Ӑǘѿje{> !;nUԆ]1X-¿D}7 y?̖m>B͌&!>:"a|/p^وLG# +Cjz#ҞAvdM1>3 x_O B ca-e^= Wpv夲jrEiM,L1~QqشIn[5M3]|'kO˵wr8[LOIҿBb45ȉy'^=W<. >|pѬgŕ{ $cPoGa7ab7v__8 ئErf4=͞}a UC S+2j'.whtXI0-6K5`Zގ] T h8vX_<.,T؀{G+v=[0~`街di׎eXыɵ9RoKo^2GNֆtTģqOʿrK#yƖ:btV4oe{ӷ%Vh{h\ &;R9θkǘYoe,E_eyi<7I.~kdJ4M$ _;A %teqkdT}.0VPuɛYUs}hրқtZk|A'U @ ݊.٬`ʏShlœ(mzXj8|/-?AMH| Dhy7/ޚ(݁PGR3^?g`s ]bL9Ѩ}>Vp@GL'B繗Q"ӽ-0 tZZԛ]\MTjZhj_}8 c8"[L_i賲B/6΋j-]84Z=cBlN/JN4{hRx=OtZf=SŸq#hk&(aN5W%==Ld1\ҳ֟0l-/IYVJ5y}zǣfB>ܙ,,M:e~0 &6YdXwN:ZvQx/.=Z%6Wr߈<׳]bSIV qƓp :}NB'g©aF|[CK3N?HlRtr$.s\k\:W/1G\)@*5w2loWDSN۱ N}nvnkv\QK: P$4(J)C!w$*UvL;' Zqx"IS1粍uV\߆lt_|uoĂ ʬ8zlt4}ƗU¾ ,)KD::cjmf,1]njTqIBfM0ָs3k\ XFSݐ5_T;0Q_׿hc b37&8iUJ`suMt C9'$yR'@iqN' 6Tb´s A?^  ܨx:<vnR3ܐbauSS!B=~yo a-N2V2̪Zvo^4G$̏XP~uDN"x?BQ)+BX xފD9ȳ|x6X7j8V#z֐Tnp4Dg<^ZַxŕZsS{֏SfaO(wlKsLL?_Fz-jM׮$a "C*xE~x{8ɝR'SpqO%;äOeoj{aU ?oƁo긴o8][+i ^'Zx:|?x1.ؔ+tGeFHY˒Ijm5!٣]}K 41^].fb[  AЯ[>l,%Euޗbͭ"ߍK.ÅK^|D6S[f;QˣYޯ 5q:G',ˏ( 6?a!8 zKH;|rwlf)m"+dP?e8AK1jvO Z4XO:ۋHœ!ȪxF4?I.#4\7} ?p uKRLc<+xؘ^Tt;l|3 V&D{i_㹿ku";T2ily0.L֙dawj]cZgA1?xƛ~mk]k0-&0ΰʇL-u|ҚmTʼnGtFP-3aA3ʂo%$ ѷP+b`26B^48qfn4,~zKXuKT"g:oYvr`4Ih{r)ۏ.eUTj% {4y#ud;?^0d!骡LPmb&_%! {\;ɡv:ףOSXbV+H&)^p;hnfrxy\Y]cZo<<ް~*Vj= ŢfW6ayȣi<։()%gp#+o哊q߂*Sc"7p3 ΃,Sc0 )[(}m-4*hi2hH{eJ]>7к5~ȸcLKnxN"g_y9ڻ6>ay4~NwڸMh[ހZHd5ENq؀B6UM)e<[$[2"RZ=7oDc [kXS%,C]b5/WJxJ7$~BYSNqz\cȿztOkԬ\3dO̹gq4uҺTSF-iR nz>gqo^ims,ͳrpf?ІH~Wvg5c)B<:e aG9 gQpr zc w 1gI H{[|^rZ*y_r V"M8IVȜu۩+J/r'ν#,K3ޅXT=JѾ20"IswE<ϗ}kymiР p#]<mV6#tzvI1lw1}1ĶzT2rileBAT.׺/rcVۂ|VwͪMYEy<{#&',=,;}M+[`эO{3sWV`[69.\׷vk˧܉W t#xf3̸Mp6zA<+TS[}gjPEN7"rBD>I;xk4 19|r$?1q@\v=0EQXAy_9PZ@yc]c 󟉎i7WZf,x~TYs$um9Q{%DL'UqB:#ƛėRwb굎X^gU[^X'abK6lZC =n ڮpwId4DؑL 5_ֻF0 iy3v,nfS`h(r-{@UW ƪLנI@}c.՚ ]#2":yQ/"UO263ŏ~[B1?үyxO^8rbA9T0LXʎp5y"Qb1 |+ƔcK.S .ّwCV8&~]˪i=yGsT^䧝{s9|pwpa\:M|׽??NY>O SMsq@*|# "40U{ˆ,&_25ZYAxP ͋QOIiVӟ(PoOR_`C6S1%%4=^ͼZLg\WXNJ4K 9f/ѭV4< k`nmMnQ?lmW`ֆ=Y .:]碈KZ&eBXKGS!^K)8h( DAzbҴDh{ChfVc{KPjaT 7Q2X,u~?!Gߜ*~7 Fq3mmma}2}b` KeQOwǹfQwBON2xRƹ9'7*bxe_Fw:F)+qu?qBt` ƢS)ڍn.wrض|W+dieԋr9Ø0;Q Z t/\&\G eGdԍyB CROPvh&xSR1['h;"Q؄VU5Mҏ EVeuM,To`VϝѧhWb5Ɗ%U/m>>_Fcp N!>CB04@?@D"mƲS#nn]sDۤDHiw&6CqHMwc/_vD]ɹ Ydq# K>#4wa^d9%%uQ@%w><@orO] ѵ)eݝ߼4*oAjܝci+ %H91fkR6UǵWMd=+z.{Bgb1tЈ BY*T_7OaF$(蟥;Ŭj#Vl]YY8D F6|?R_N\yu*2:Rt=Nt%Zıţn : ڃO:UPZJy v"? P& pP6sR۶s"!)=fbg_tLD?=>(@!'^A '8\CG]d+CcNQæd~c E-HG~PA.|Fxb^sMcO=?IƳρ7R Fa endstream endobj 2329 0 obj << /Length1 1386 /Length2 6039 /Length3 0 /Length 6990 /Filter /FlateDecode >> stream xڍxTSۺ5Ҥ#H7 & wAjHB$t^7J](]zQA^x}kk͹d30T`($F$[ PT!4c$f04 T,PD@4HBRQU C!ahN% III(<0 8ܰ!`0H#K {{{ B('y^7 0a^0(=hB$g8/1 C!H(0Ðul$W?ѿ#p #H/ Fa^`8n PW2 cBh8׌¿`Y UA4ɯT0v}+{GBt6Ex´T`&ۜ`PJ\\ =| ¿ ~;31`pG 0@tsEps#Ik9ƞ`0( 7 iݷ43(@PJ@ 1@?X-# W}e?#^?s顰̅xMtk;_YWwGo?_v#| `UjPs_ՅAn€jPB:a-+Vp /e77 3@0( |XA\w4]0YW AAMDL`|~ ,Da!쌁GɯؙhW98rLV{[0 B2?Ȅ8UbP欁gՈ" zX]tQeg: MqDmLПg'Dl* XG.d44Zxzl.˞#wN+-n"7Z^w D8N$Ytfom%7k2SiCu&'NwiW`O4(4zgGl)ð {x1)QMmX㸅ȣc7RՙݵwۍF=UsRպ\RfAd'dPYcBA{hۊQK,Uw ^4mu gxš? D?|p{jn+Aݥң"ę7Ej:"v"7[Q$[>S 7;<Qdnef&NJ[DVҡ5r=gUw8(BJ3{9Πsuwo!!|_mTEQkWM%i݈{1:O;̴LVAOE;747LE?!һ$}MaR4͕zWd'~ 3C?~ՖSv[&-Nn䃼@jie5{左[F׽Ts UIȧFr):]JZY4%P!M?WșhϏ$ءaSzGQ4cQ˚]WV?X[t8 4"Se =y<#0lZp\7.E{:pU"U^hzzIǶHaITX>oxYPb'yq)F~Oi7&lT?ˮge(l~90qV9]\|>\*Zdxv]W}[?+gM)e Pjo}q}G.Aj`{ƴ5=G3WC*IDzZ3+W- u˳m7fHqw0LgJ+hR7RI[<]6C3WILggdgltyͱJR%5j0[0r'm>8i(s>{meǏlp|in|;ԙvgn]I0S? !0j)n-R}E:/!#G㨛U9:o۴?5f>b?^\sNMܥb=!ڌ8wnc\6΂'2,Uϼr`}Ʀk^%]q[9NJ [x;N&"- 5z.6B<{5B޾K~'\}BЄeG4lz}]g$-!JXo*T2.?`gl`)V !d~oѣnW?wݑH ]@ O7}oz]y)1X R|[727r4UE]zaEi-U'U7yYhc-b0kx'8tx.Dѳkx%{@! f njuɁby蕋Iv|Ho J8 3$%ͽl˾&wIbpa[rfR cG(]S6!bs~P^Ξ}<ѐ&A$㰓[v²s&>'+Su oR!Oωm") gK[A!ţըC~moC| [P輱:Rǯ.n"cd67wK6Ù_'Sp|,F|a.2))9 \++ĺ| ,"bBnUhME3ƢQ/~;XT悔 MqwQ,;[П!%7QM9J0XHtvdK.8JpS\dYiہQļ J)N|[!=͚QbY%F~=Q?cґF՛^gl᦭*Ҫd_-Ei;·'Mc]L]ecgz z 6R kSHXܕj^TQ J̐e4>c V/cbje`rbqؙaΌ O`kn_EkV2BDKW i7Y͎rK%ȑ/ɷkhԵW{|Czn,)v_-vwı{ e yѼ5OR d;, ]kA\8]vn>&אY8Ca"r7q֚啢s;<5 Ll@.Or%Ռǣ==+䂓6sS/n2~ }URڈV0fo0pj22fm˨@.g^pdt,Pb쎆DY0g+*mռ?sngS~)nFXN`fLe鳨N}t2m `^uyu'cS]0 `%O)Ĕ J(RK0)a䫌  "MO-5Y@+횃-aF $O8fh1*N>niȩ.38Ep:Z=g\P_kn+:Xh߄oqʑxXv:#-"]SY 4{r#}1E(BuY0ՊcyOB4/rky8H»rCo 27n'EPf^X|;8Ԃ&Q`YKFY4@F3nfyXܤE)b /c=u1r5|!*x]m:1LJukgsC:!a\ ݅xVfO^z3z:G/NT+t kNQg7ʯ62OWNm7w|PlU((?=$F_d2R^_EU\UE"||wp_*IA؅ӊ)AĨq\ݱD?jTI?"+!r S ;/B،1ПKfv#{POlduk"'r OP5KֺAyY9XbiD*NQz)hrM3Sv{COEW=U#sSc/$.gK!Aj Cb%\cV 1B&m.T 2@"fUR_B>kqQy'E w؋,%t=/齗AA]ޣߑRFɓfab<Șp[Ci$q6qnyQ 7(%CYFXfr9bR3ȓPW@яPHVrJU͋7p,lk_*Oh}'yIk|N-LKR}şua sjR8Ė8w_noUmNf S`{*js,W|ƩI)i"flvX=5S]j}1w,oPN5b* ]*"KzKM%)։u.MCI.LDb#P3pAk˪kSE]u.z_|>M`qX>u"9=zڳaz s}%p^5`,hoN~Jxd~;B jwgTFCVclSd,iRоTsIXa-s*:EG-t>ğJX"[ss=d_SK hǧ'y~{j2K` ÍexlTI&yʞZԁ~᪸ nUmV}BWQ9MD`Ͼqn /ο`i$TעKr3ݬk-=mxA] Hb`#b\ ^y)Dgw06|bNmP`f&2E%{ E{S0d3)Fy!Pש݆mO/O&h@*-.>͍$lmKPYg5PCk-Ǧ *\Z&_&FLX?o-X=8~8 .+"=`Yδߜ7W@Ce+37q㼮Tw;?Fz0| /|;ܘ:o) Ds =K-a鴨\gWE > stream xڍtT.(0HHw#C0t7R%R  !Hw7 8޵]7gw}EKG a U@Q< ^>1OMrH.H((4O:@HD_DR vYy*8ԅM䉄آ=y; E `8@:w G q[I tww;"60-@EAh&%b\k;  wAg­Hzs@ CVCx{6/f*NC G'0XM5^! E; `70l& P9\x]`F*>ey, GOB sp;5) UKACDl(#aaAQt~ |NkP_5GvPHWsE`j:ZY/  -/+? 2QTR3c227HH"\e5OcWn@U pG|B|-)77;;0Ͽh]Qh#67ǴP+GQ`6h1y0J /9P- ׷_1 ZCP}<3~!a{/$ id@S}$ѯkapW_(?*C\H~ ֿ z@!Dӓʐ ,X@A/bLu}&,e2 ʭB,UZZ3Kk?`p i~51Wѓ;3 q34;=uq qԱ.Oɘ<|&gl:+LX:[l"xGTB0&% d_gp.d%ݘD*Rj5Ft>$kyy1Dprd}r14+AJ|`݇@+2_`?IH~JrRлUZyqGл9P]D^b^j`7% ƻ|r: (eJ;PC ),?J!~73-gU`绘G8&WD<"2~=*AӠD}pt2ܭG oގm J: Л,qydpfJ_M]'bA[s1M_ M[WL顫~R8`Őw1xe=o 2C]̌קf"gt{,@gGf 8JOCHHC#L;[$ igneT+e'Ȕ_vVvONِAI7uҿ+4&[a1[xDW.g~54!A+/c]|x"Zugyco r >^j{Qv%ga?ݢحy&p5x[8u#vlTP`Q \:[';~u20#+K}=Ϸ;4’5~]P&ƛlRƀ5'_^K AR)3 50ȸåv}fc՘).;EEGgyVPJ޸^suvq8҄IW 4=<8JR>3dF u  .,Rcz*&#fH,0sNhmwtjd'R.vOȦ30Vll0.i i^W5f0p'vJ<^ZmҶ{5* ~HKphK3W/lc+>-2xҰ6q6mQț!H]=1h'(EY~'t[w >|P?[\/Y@8|!Zk7}PBL>SOK_XUIS׶}952#a4{^5S}gWWdʣNB7a2l_gc̲@e1U69Nyj #'.o8[ V$;-_2*<S9,u._8zD/;aߌ+2Ҽ3maW(?ORyfO^[cHgM'PhF iMkɭ=aK {;wG)BC][Dz=vsj~'P,WX[/Oa1k"C#JReGGKI-k}َI73hbއ+V-q ~ 3ëĿSȓvIn(/5'Uܖ۝5Ӳ~Rd?zmUY}5s.1oጁ(JXlP+nvs^سi/BR;@|8 }2VT&;#SdkiOZxz rq7p óFܽ_V7Gsh.bJmedfT6*;sBr(bWQN=HnSGpSSm[2!&f(5T FR 1^2svC8j%KzXSxsy yNu2`cPJ |Mvfig&ik'kQ6E6EpU(B i /;U8Rm+4T`a?bǀt7׬qNޔmğ=ȡYMGyG ৣNpF5}N$XvK @~Txr6 <0Ӱ%Dz^͟?NvǨP:&oer#M@qR#?_˸R;7.p~Y栖bz$J}$^:PE~L2]ZYd~oaG9fcUe98 hߞXTyJn[$I{|r~.E]Rvw>]!d}S!2>ta$K$8-,Kmsf҉9窏}-lKt*V~T<?z/!)9>>h֐}0e_=xji6j?fQ"v`>GO<0lNZh.4(u->;9Y&i{OHO8;E;-s3-J6[mދG?ԛIs]OFP<|wٲܟ&^a:h.260<`}c**m\IWrH߫ËiJ&TGB'2m mL}ʭ<_%zT,fJ{tHVg &P.~bjVSRuQR$μp53e&|*]ȪPm(^RTIYӱ 2]Q'BfKg;/'6y^`E)~՗?a3W~E>L:lߟpYpm{'*@]'Х'L÷[z2n hvZM2mjkFf̶GKv 4.`"oE22kIƳ II׶CՓM߀UUZvk胉[dO-(miONP%r>NQuOͰ#q 4I'qSJ<Ri"Zprt.XPii+hg| zy|kخ S̥ZbP/ap k5)5U ng,&BWX(y)je*=R/_Ոeڦ|%* 9{wF޺P6byy7KJh)${g`x̡D4F0Z|XkGhAq@љyd%Dn|R]]=n۲N/[qQgh7f1G~핳5 VQzKD0fQM^<̘x)=}ל +>z"rVkx b,c X83% pϳHҚ7,NJh1ǻvo }QsiVM|7{U<`#HeqW88*4%hδnpwZI9e[?NAQK9k]q!ƕ8N*ۂ|=V*b&:?3[37 qikh0Jb:'u@^DxcrbX+6Q'F'A7‡$ݪ)Gڶg$E_n L:oC|y]0-Of*JHW\  BOGpNvc^oZi+7^ zξGiNn< ĚssVXjY*{ۉ]z&m:[d9;9ER$諩^HL@Wop; |!+xR6na7j(nT)(MygxE&]N9>e}[uEpn2JNQw亪J%%BM43k!%_{ ~!kF=jYW=u^M0@240d߼W3_\ f\34ik?2I endstream endobj 2333 0 obj << /Length1 725 /Length2 14862 /Length3 0 /Length 15411 /Filter /FlateDecode >> stream xmspe-mc6;ضmtl[ӱm[;~{[ﭯ?SO1֪z(H$A.j@Ff^333 B hbe7v4fUOwttP;а56rhڻYZ܄ݜ]\9 \,s+[ @LQI[FA @-Nƶ%W[+S) ;lLAfVo 7?̝j" j 1&511 'q3?@SMGp,'`fe0ZXś Srif@]mmj1{;W@ {w'"-5-?2.!>%'ﴒ_,U.NV]fI_-[%*j ``qq}\SW'' ߤ3 ¯.ٛXUITBL-|[EmifxpH4h"s-sBjD<!_.!|U.xi03Uq\[ R`=u,@b1*BJXISg|"jPg,C LwWw) - +u .tf9kFڊ]KZsL8^iqw}Hϐ J9%)w4Z^2UnJ;C"P5"ҦާRtqM+;tVb,ke^)lFI Z,!&rgGa|n$뷦_7O\4x{ػDi_(,beQ Kc iUa7׻y3mI0k (_9 3Uh@S;Ců⓻O0d6*D|ĐȰA.Y2Y 'sK>Nnt$ [_fhIsze69`&wzt|7 bӼ"ƕȮE媙f iӯ?= ∜`nCh1y>w,v%nVɺI/g>ą ;4--C1ޡebDuyUWLO4QʩJеjt_d/LH 3ڥ$!NLrhB67g׏ ֿZj^f25B0F~߶5 ه$?x{4LeG0G^vPهH=X{j2ޙW֭ :d9Wh% v)qm w:?;7ҼK &WNras;y DFbqyɐv&?EVpK@z43ǧګHcb_%76~ohͥzz'=6>%X8 duN,&S*F`+~ ?$m89弸'g{Y0-B(N$!ʰuu+q[C=Я ta/)S^r=0[#*ge`&,}4m<÷c,e.Э% q>Gj ΁tj:Z M8mQUKn@F^;L)'$s[l_wEA6DF!X*m~J5&gn悩SMhXa<^<è@b_!vO+ZKCGz9=b3R4S:ޮ@ 0DÂyCkuzbn) T9v|" Dqѕzy@GrD<1uJ$V`y^({?nΓ²]P8:`Ț3>* :+sg t-FOw+{?5kKCI3.w#D`I raN ɗ>В) 8\{e}rϤo +$C\Ål q4&5Brc['zɞJHx]ZlU#V9=!&.RJTфioSg5{v3Ls<8/+>uFyɾ3KL_煷 ܗ$\P4=^%d86B#\ztt g\Qqi!+y[᪮W"I4MNy9 "߲"g 8p[\e}b ڠL6HV R_lo$vbhh[Wy˜w^]&C<\}ER'Vv8U75E(`V,Q_bk0Ƚ*ٌĄWջYF.q4y& -qc`k=~Xi!VC }xMwWf|,^LV9@#JR1}2$w:~MQrOyn ZF#ydo`j6n>jMEL.%riaȸNZu 5{2d)f}#s$T`s"{.}b1Ϗ,c,:!DYqד~D;Ni.o1 XXi$R h[J-amٚs!KЇ'\ЪwcRf̘Iwz:L˒N&ѠAQxIζJޔ¬tL^A\/7%t8}FJp9FMh, 5gn7ЁSBdc;lrzNj:hƈ7CEwhgfzAB_ c.smo@S֊hڮ؀60ϳ{:;ӌ'XKt^˅.`chtڋ^#1ZNQ`|! ϐd5N5;S]Y[De\I 7 ҜۤAE&FqQV+֋jWަZvzoX\1/a\:6CKNu'ycܑ9͈r<*qܦr)L#B"!JZCʼns2ŁFE)MkR[FITߑo&)8o#TDEpl?E, VbW^\mYg$&+c) ?ذF!7^aUSzrUfKJLMf$FiZqQoxkiUV+L\ER]J҇%"aW_|}i7Lb8{Kd8):|#X'wwVCKW.R*n E'E \| ɀ  |2R0ΒyZ72=1L¼z\u` `Yk{{TdBߪTՏZ>$6c?gεřSWN+{0A6±2yax)Q,=A>d  Io%5Ħϵe[vx]Sc}tEL9Ca['t3)!n.h@v%^|uqiC/t!Q`/i\_Àp1uI~H؃ ;9{Ѥ8s*M}}r{vêel?g&_>h܃[$\~QPzl8-a6R^aqmM!woo>8uu܎E tBkƴk\,YlP&POx<.#O+;LԆ)Zx1lqxTǿ\V,OXQLA/ӚIp%S[WM7+YcC/(AB.%)2׬,'G7`i \(>h+Ry5cʌu=mfYnʡe cLG{˟(375 HITʡEL:lf,,+A{*a &e(6OuWjӌf0gA;]KشAC)v ^Wt\Wq[c^Lf~[d펶7#Bpd&&͔6V-7HG#K8aPNleoH_1G5,BG?5-Z-78 .C>V-;^nZj? cGjp&(49'^7\mS37Մ4votB5W.@ qunL4kVG PH' kPwiWRcX7@ӎM˧"WUA,<:/p]"k|ѵnB0&R}H7#ja|BTmPs?sY(S@8]!53W]V[(j,?C);OGWMgz0QF ABuʘ)ל'Tޱ=y{JpʖK5D&Y^IkLg2O$q59F8FJ 9+=OCWm2pveǐ{6r~JSi|؈MNJfs7 6T.z= cͭ (l\L(gr ϒr;]?a7dfFOj:ש} dwP;uBJ9z8OQ{jCNL#nV\,y I'O6SKT}gUUfv޾*#JRfA7` 2U i;낒jAG*Ϥ:U(b)|ݫ88ʰ5u^{vx_IC4Se,.A2̃Hšt Vy)9k= G"K/μb>*E u9kO#41`9X*Jw?/g?$sR X뒉_aH|* -T ~u{0F܊% "FW |cY/U_6Q1P٦eʃw[*M"<ßR@F6DF1/k0IJ"󫈏 Fg7,NTl. 1vǰ[xp16<="&p7z. qҹ aҀ>#@[ I ̒W9M?He;¬wyC= %Shm#?"ײ{Q[5EiUپoUwǬ%O\Q*-l% i> ˸@ ׏0#F|{Vy1S3LO *QкjLVU)g5ZcaQ9EjL])q ;an4`{dWؾPRKHXe*wmћF% n%ӫ'W1a20V]6F6SWr;=5RcjWtY5\P5Q\r:˹)mۯOj IHYR4]2:3a]hƶfc\lչ!K:N5v'1PnWσ4Us>ffv`c<Ǯ?3H>N2p1Eܵd}!Ln$2^`Tdh=BWss-04KELbn~ӽI^ r@*dO~,拵w 5cAi?Ⱥș{^:Hkw+`L8kS?Ea?1mcʸ-T0v(Ov2P/<1ֲrV'$T %EF4g(sS@A^<|b0(7@ĿKB+k(|a8}}N7Q 3b˝O%뾵-1YA“=@mUAŕB9Z#VM;%]`ҘJQk[ZpYBW=dEF.y-)lۭio#-3am2jzX@1 Qjj.oaԃtJjfI^-U+%9@I=PՄ\tIt3C ;vbXQ&9p}_qe]{rY|A Cx)B '9,+L qA\}Z^^f~ra8ͱ{i3\2ET@ bA{=MOUSC+-zXd ŅR_3t p_[HǎPxaRkmQoj*EB?MB<#"+;BÿIIK_jWL󩈥[B"|>Lw#ʹ߆N?xwv6 {83{&n)+MJCswr(!sG>X?+%j}cw ь:. 81M,K}YMf_9%Ԏ44Ad{s;nvXd+!<,h[솰~ WwڬdԶĞ_|֢ {_T-qSeX""jJ6OJD;Bx  s:`+<-L'[#K`S#cќBAGT"S+wǦT 5ɝT3yʕBy]*RA;ɌM׌@ѹ cЖD(Oq۰fj2@#~^HAn0 9ӫq9si=[Op&ʁ~J 9,fO+y ۖrkI?G`X5B \[UOBhhZy3)weK"`."6[a=`H8'1 m<߼έUIJheowZ}=.})z{ ZB*ĎJ:ȵYߖn)NTq;\W -Xwd1]S$9%܏jLֺ$qrj-M;*k*ȹH9]w YoG *߉ީ Ln;kP@7@lCg E,@]&#Y}.DuS?𖌦OisXSQ]rE?Þ.ȸrH?ww2QŊTaďP}DfE`qJK:c.̐Zs@T}Uë9o~\m|g g=H%0$rTIj꤈/3=gϊn_xO.ỽjL4mFyAGB7uIѩj ҿ=9`;6c\L5{u_SwSL=U|xnPTzy ASxJ-1;3ddikއ@Vi/ot[\Wg lUŦ}kRj!V}s%x@GC!=l4Ԭq@54(H%wrLwf0*>\0Ca$+= $zY=ˤ8[O0`{ ӵ;NI^x9E\N/gjN!EL(*6Z*z /L7%Up3^Q+cdaVL);gpy3)r %1ܣtb`:j:kuuVbGbAur,az+v>Oo5gæeP.&ڪ1Ze.-' 7 gBZ-v׮Q~xoݲ-TQ(V]XYUo-Ya6N_GD5nl.n>L:P^ڝ_ݷ @\2MK.>$#.dz}Nyиa)Q9m’8S[8;TL_戮'+_J2,ƌEC;ӷbmuɑ6G{l+"DR4.~LT:({uxNНdYKKᾒ"L`F?Vӿ?n!Z V\H5Ȋ츬 ԫfF'oǦ\tX7 )ZU[#7`*B3["zu#]?{Gѩ̆NP7h_z1a-œU{q~l+I.Ҵ4cgq W`THo̢2Q4'nc't9m1o kϻϤVVWmR3j&5fۯbcw;T鳜\чT{+ڎ)U5ܻ~:#f&6qdjr-[FԑFn37u1ܒ#pANoF{Iz-{L0;Y7YK7J|A\+Bo,wKa IҮsdu0YT K#zh3@U' 5F 40rM16?Xz@ zNH9\ėG=2"dPv p{iîT4U{L"*g&׵6{Qj#aDʋ 5hDrIǃn_s7ތ:4" [:+9נbwn4r{ݖ_>S/I nbĪSpa:[(Op\k5UB"oAԔv#}ˠu>~Ƃ8aYbzl9u[ef@3C(uߺ(匿βx[⯋:>hڻ)ֱl3[n H+i)_jeU6a.K( ]rTfXLg"&tK_pU~>u'p\h:.m&%ۼG fuv@PLeۮ'~БLj,s€Ip8A=;8\g<rJ++]kG>sk/B[dl,s'J!o֗{',EPuٙ!᪦i?ڴ^0xL2eiOwPG?[ҬD@= S@mR0sGE\bgV#kv1s!8Z?E!n;IBŷ/[>m+BtIm =5㘸r8ͱ'> stream xmR}TLyQ{?lhjԘhj0[s3stT,-EZۗ|4VێJ"16% mB[vo=g}=>qb %Djʢ39`bd2ζrt㰔@0OJ !Vpc2YVq$JAyJ)bJL|u-.M+a D"JCa (K@)9B0A$p !4! RX$_[,|((lXNhFh Gt+ @28 A!zD Ґ@p$*R h|L0(>GHd*U!%dR Eb$AMZx#!DnIO_0Tq"<@*A Q9!hXI~Jqh* h( āp&}Do$|b-Z%1W_+8CCqA&}Br&zKmU. o_3 e (].'ڡfǁEaʪ% vGm:oy׽sg=;4愷M+m˥=h6skɵmy/e>Z|HPlQ="&c]Y25;*Qf~`WYSeܡX^C79;R(&nHSfC+#wJ荷$qGۓMbZDyYVI~Wp.G}*<Ŷs =MSfYK3OCV>v\8wy䙣F({ :ߑli(.^׺7g!*is[gR mMYRz)Gؙ캙wߣ(#+ѵfIWDvuOЃcsNyE3^eo[_S|EQ3NN {k.pX^YOMg^?#=>(7u7EaS{CP>77౲WR'_vIͧIjkr(xIR5vk&)hٶ1bWw6y*dS۔uu߭)2R]IɈo.?ħz]PƆH kWVCweB`ʎi.0 v )ŻV)Uܸ=j6|CΏ endstream endobj 2337 0 obj << /Length1 1144 /Length2 1528 /Length3 0 /Length 2250 /Filter /FlateDecode >> stream xuSyQa"AXHx\dDg"B+1+|&WY#]AĆ#t rt&TA>Z4s:¢gBvP#X4L,SB ]3i̜!>@͝[q?,fδ6Ptw'alPXp+c62@gH4Lx`Ѹp;џb B;E`B !@5|SGa5 V ku^(o>H0fn_T06x)"o1WB;Blľ  îWALd3Ep?5wO-47˝dq\xӽsiiWsYw! 10uL 2)5,fμ87 `px.1"`P @7C0sN0aB0 Q̯4xf.=eςAp+P/AIg'ϐc0nYXm,Zn+t^fD6r)m`9o9L{c" j湥i0=gCT~Ф5EkcϝWFWO;T&#񺓛Qz|%1͏(u#%[҅S.x^Ѡ[ꨂJvU}E*&6޼d(۴dzt̬]ӣ뫻5S^ّX}Dkm60dx0t~zli^Kɚv󶞆{k'֩#%ILf=?x$6wjVurhu(237k<]iu4Mтָ'" ^&?S^PZo#fn=q-ޞ'IS 6Ɖg'v5+:+E-%F#/7삯O$1w_H\W8PAݓҨ@BT9>2hZJ?U7[qf*L&\꺪#oXl-Aih\Fѹw)}ʭDءx5{b 2+: M%w:~uxe[ؤ=j*/ާ z:V]q[e"Y)sa@&YDtd[~Lwp[:eMY1uX|ƹڪ~9qluL,a$+o[{$mr>[4|x~p7>Qi\XZT< 0\8e@<2}llDUޭ\Q=D-)p#1ve9k|U\3)J)}AؾގWuЉ<گ4kli3[}!FW7=81&A[%E R9etI犓%?Hd)g֍{}:drވ>~s@ҞhReQ? {#nq69WxKKԇn7r겜p=*VmI.xu$ #c|?M>ՙe:Y`{Yt2C eͺiۍ{6i8U捞5 K֭^]%+ ڍ#VE\~E"Pk~%lLs+ęyoj UVHF`iͶ8QO 6kKZ$M sSC] ąhv~B1Ja:`:>LcKRa-4&w([nR(UK}5*a㧬'R4>o R:`4V̷(2語rnxjo \s͓T҅ اPPhy`#qRãvEjA fR[SiNuC%eNy՝թsG9޷h{cdE>!Gm,)hi|-M7Q21dՈDZêhEm 쩒\h endstream endobj 2339 0 obj << /Length1 1626 /Length2 13870 /Length3 0 /Length 14709 /Filter /FlateDecode >> stream xڭweT\.4niwn݃ ].w̙u?sGҧ꩷vo*2U &1 G3#Pq0ssUwtPvSdRZ\HTT.@S#H -@s;; bce j100K 럚wOW+hC5@$TTe2Z bjPu31(ژA@: #\cLN@sw79/# ` qX=;l@nx[: ]LjbgUN)ܮ6j廥_%{ڀ\`'\f@{`N.6psY #hebatu}Nooǿ hoɌ׬ȁ,l[9StA ;S GhĢ~O G+Gs_.}nʦx_2 (Z4n߭u@+ho:9{K@Vﴰ2Ch*m P[,M\ dty&6ViZۘہ"* S7x}%1 -Mfm>`M/wlQ #. ab0qp߽w@|ܬ~Mʿd vwH- )}S/{<=@'iu\ 6#;\74!i=T֨Y\XWe\4k7Q3T o@ @l{'TxN&4CWrLSR^&.毰y FݜW%-۳,kYjtjoR cK%8ô ,C4&dUJ ݿGab種o:`")WLbJ.jϥ,lu{/wr4fV[)pE+Ա?I˯ϷM{1b6 'z+D7WeƏ7RrO^T;sf腄7e{kUʹ&DB<qdVUMXl|$%D\鈢4Ng `l 7܋׿ mC]4qD܋#@~RTYL?&qP%LT<3Ѥ@}o)  JuTmНyQwvJ 7AtN]F h=!~mP֫u>D v^BP J[ӜVܟސ̼/@« ç{WfߜMK*A죫aƯ#,NcYwjWLک8k|CL=W[WCP@ 1((þ$XŹ2cH/Dׄ8kssOT|U?Tx#Rqr}4Kg1Pȳv>vrpa^FI}̼KZF~-‰5iƎ[^p 7𚮁H|Ƥg3Dװ jp%49=++_G9,1ٵ-iNkzg_%Xh=qs~ ,XVp)}Symixd^@R J'?E 18n}-"46OPn/=u*(ԯEUnA2Ps`JEr#6.X;ڭbȐ+fhra )p2 axVvnR\$J,f`Ά.ExWOpVs؇Hxg('I*}fG*V>̶緾Mzq;\ -}Pq5V5,md/x[ ^m9ܒ G0 |v.۷>3w1α['a"@4<&R_X=b!w"eC.էq]5;*D/d$`  UZ0nQTpF#h_4m]kUVq3݌kh`:4 w'nBS :+w¥f`(T>}fqg jp$~"H&H U4ŷk\¦pʢaF* auhMEMav;W0#Q+|^4pp@k's!eHG`68fq՟K$rِ͙lyiW:S[`# >EL⛂Omig6wp2% v#;F)RZxd4-%ƥwxx6 c&טGu0,#cّV? odڿʢLֆ(7"ϋM&7O=?&b~*AhxҗWX+u?HV2%?)`*(9VR&0rDn iC&ot+XO{ќ2jp S[''UN"@qه2vZsYB|DW%At c+tzʦf"S鯙ʼng.㠮B^ *?/&sGkjEN"I$Cm/bG[XwqV(ҎMy{ 45…XʘFKE[E_ )D̕dkx\ب(R7EM<#K·Gc>q,E3Łn,8؀?7^$ىLjS 1',J?ICMg`YjL>ζYKU $2dR)aĈ%-jBo9Wg]@ջ}Q:ެs`DSW=ho +w*!vKlue{ίiV?v`i屆&fxLR+3Q_EU䰾ҳD Z<0]z/#ݫtFpn|Hv$3O\{=S׼|tl~HLŌB;>km @ekY~q@8V~PH#AɄbTݛ.1Olw8clPL.kbZVvUOk >#ՕcHiu7m[}E; tS4SV~Nضw^.@P`!.MxɓHGvykeQ3@̱M3K| ^nqlnٛ+m!t{bDhcT>S+TQL [1*jiu.P'*(bDLż jx,~pkh@] Zj|u+[bSRƩKt]T9gTa^ڛM,[tߌL+b̫#DTpV`հB3i0VVb>n uJ+ThmJ eFp}Mn)Tu2L{}!tRLGo[; wK( a΀auqfa^|̍$c0V6ߙPem\o63鉚PH8xZ_V!IrI0HF_|R9}q%dvf;ƚG3 $z1ʹ\m½>犒8e.ͫ'#5>sݡOr( %F,Y'\-Kž[Sߺ(Eℓ^!]_0ӈ^fO,tyrCjP5xd$eR%+쀮~o㑊?P>~ nhY[B;{14i+{!y^=~=Csq{Hmz MgB 4h\^U8:cA<[?)O0rIi T=Ƿy&>4 uK *S)բaڷ9ש&|BD3Dv؁UJD-;=ZpԪn {qbgտm{ժ 11KfI6d :CAM5O0h(@s#6߰f7,7"ʠuHeTlJ-uQM-zJ_`;Ek=~/$z@{7vras͜qw%O 8gX{#i'D- X6E;ڎQd<Y[smc݃WtnWLz4Këp*B`~M{Rkbx>.+k+sL{G!𶥇xPj%u[}; &64F!,r}ZFQ2u-sr$0{ hLD|_6_w^(خ“6 3ĩUV4Ư>~3 :n[]齷h iPۓ"C+xjQ-~HBlVƜ@}Ӆx1B%<3Q4{vA *KVQF.-݆${oOI`Ib-֌8ϳ^?q䏫V:ͰVŁL<]MmWpgLoHɍ"Cc5wWެs*}{E,7(]`1G+ChrD=3:/RgL1Mg6PWZY!~|KP 4I5]d} kXtE!?}aJfvGYAQ whk8[{ρ_q`}[`w9ӕΆLW؉I663!P>A7%ݥ)`T$R p"IRTy̜+)~HCgJBcrVZH\D25^[fH**M.;"V h5-}EI0H۬؟f:.5 uː,P 7bțuTխ\0E@;YS*-oHbEq:&RϷB9yw(N؜9!:صSNK9PhΉ-ZJ,N:`į ;sK~ә3_6>"Ab*@&rv{ʑŦ̺~x|{hÐZj/FyL.Gt2ރH5.Q"]L8Ua85 ? c][Wmw;w.Oz~ԗԽ%uJ?Wi4Rk(nA(-`GzwP!?s7~!rq-jMk(!RmnX:0 XD׀m#Z*N;rq1^8q&|>z6l0gF+# sOE9L甐]2ٱ3m7vCt-gfF(܅3n[+cx{mA3/xo5MV!=T b0̆o n\֨ڣ9ԇKj n7P0Z[x}vW*V0tm|jrLxWSW GBJ2${$[ ڍ~R]-ǐ43́Lt DѰ-|''wEx#ݤlgjMp [[JwKӍFjr:ՙ̺] ?ќ(A! M&넽~D@xWdJй QZrE-*>waS& V]'CGECEtt`#_ '0,nJTesw8TW)$}\)J,"+ө&#i9*7^=b"ץk%i@iIR7'e);.~sAv+k gK fx"DLC)2Y]l#tɃìd{ǞN8mzZZ DjP{>0,&O7h(QPq-WZJ{ƻV֙bS̲'@'+R*z?1FJ,3>FݜB I#@fCY ֈUڽ_/HQD1U1 v"#L>ߞu'&||CWk?2l/>T&74v,Gee[wCyLG?Tl\)tG/`*dEg^t~r'+4+" /:C ߭PưVy;VH~-mqw+- 5+X.'rY+%vv3X9JvfR4QUPs5%VGVO6uLt"9Ʉqϵb I[#/*~v>y&41Wr?avye(,u`9.#j|!2Mꫀǣ.+I5)R 8"N]"c秢]%ex:PzZVgŒSa5qUESоp*LRZtS⦹^5_Ew=R7m~ "$uq{D^(Mٟfr1Z-rnlRzl^H|cE[2U?7lX9=|qal\nsnșJ$s]1_bs ɶ5@v^g:B<(p6>i :qcY2R=4ң RZbI(BgQn{MW4s"Yen]7͐JUγ)'@&aY{C_k)B3WGdQ _d\`V#@=-a& ʣ~YEi-sȶFSjn;KS//@*ja$V )QehXv~vOZc=7,7*uړ-to;R-J,ݫ|*m:wBGZ;yR;>.wPx.fz# #<> vGb%zE6ir@;^1+VUϢiv/ Q}WiAFE\ x5N>$4pFgsi0JF@A#~W W3Eژꪶي!d`ůUFgӔ!U&Ē0jtnAyɈUO~{U J1@ɞUDߗ|nn/#jx1"11&lI%Vk (E ^xINߵ̕vLTr7~}\?MiȑZ=Qq-v{ƉHЬiuoߤCV"<8Tb{ cMV_8N Z\W-Q5d8'OZ2; |Ye9kP\Ʉ)IYW4C~чs ¸5:!;(ZKU;؋x(Y#gfoυ"y0O XDBgW˺QƾI~x w~5h9YNvSSv2 –1lD/z+y3B&Tx6Ly+Fٶq\%=I[4tN^|u~UU7j#J\Bgp=? h*M6TRu ~ׇu떴dGiz|tYEMDis}6m5٭V;RR訛s{p1r]mp;Yz}y"v=?CþDLgqyEއk& dpFkyJ;DbSh+QPXє}d[ٮ3) Ӛ#iLK/߫GiOBRo]((Ԓz ˜ Iark4hMF l7Wy7:5tilPH.W+6gŝ8gs,}Pzu@<&2ktH3Mέ+2.y_4rylo`K r$-fv"԰PU֞f,b֨+/B/+IM,?Gn>9᪉7^4|{#0 $i/VyStdȳʚ"밃;Ү#. D`T+j<15lWl[;~~noC^*>ȳ0̦/N3T OI$ݶOwSSMN;3WF)i=|eV*dcmbL.fWCSVxDyOCav)Cӕu&TZYxWg"_b^wط"}ܖcc^k1髺)303$~$*QF<^dta{"WToSW}x7hƨ=B:qRRHmǔdU˿(Ns鬪CVfbtڗ!>li(CCu3fşGQɄ ZF=1] Qس:Ǽ^ԙƩ)`TV =[?7xǮн3)DgG$R%wtkXQni/Q6.C}gA"uFbO+DuzrWӬ@Q+P^BQ1zV!"/K2ݪ[eYSH!ͰQӭHBS7޴r@vkדOƗZ1)\J$pcu98՘#x Qr#,Z4M4.vtO/k/)JNX}jqR |HS\-k>g *\'I7懩28ڎPMsuTHfy@iyg)q\D|0v*Ơ _w-Y$x[wCsuVIf.,cQ'Qb=JkiB "n OOBgԴ 6ߢ΁EGm\x߬zj1-2`gZݔc0a\E"I3bQC#dD ?~̍,L}GQwۺ~+Jm)5B>T-<}"/TZ戽¥l ( ]j]PFL+bU0>JE3Gqf.-,TEH `Οhׁ8{\?~)Z ԪpRgːoeq}Ω+kƝA?E+|<[%A+LKWC `1<[!1%jtzO(sܞQ| 6ZPm+TDԊ냀 {V(3D(A..{*Ak7{&.E`WWWGbr-l6b5s{dluG TCm콛b@%vOw6<'1,d<5b3~jVu#0ۺ;|@uH͇ʵݐՅړC8sGA AjzLW]_`=ZaÉ=i0v(TrNv. v,OR" 2+"Reٙa~'9t^ B:oL ^)s5~FCV{&TA4L z[E\/ zHpdg9jz ]F0{V}U_fȦ>ղJfՁQ"(}di[Rld "gDc~53lj.4'|hX@TʣjOj5;@]t[ 4t4[ꩊ!؟ƛÊA+vbm#M^U/MXd+E#8]$͉iwm^x8Ǜ ޾#YzxpyNk)gO^ћȶl@z!^sD$2rUދ;+I:AG >}nRXOenZ]yCB5m 'd>hv^esظ=|SWJ aeo׃wxiM =362J僅> ]KȠ)iqZo8}HߥGѿE!) Y>iKr"2u>߭GV %^ѕ_فAB/"Ә{3XkOC;~5OvXvG^Γ b$ 7b3BҸ\`SS$?j * oub=lW:BV endstream endobj 2341 0 obj << /Length1 1630 /Length2 19563 /Length3 0 /Length 20414 /Filter /FlateDecode >> stream xڬctf]&;[wl۶m*6+m۶TUQqz޷O}~1&؛XI^(aoBP5quVU疣WZE.Vvb.@& 4NV.*uMjZZc0_Og+ ;7-/*p̭lQE%miI:@ht2(XLv@j?93vV݀@Ttw3o\Vv6f$WnnZSwvq6urp$&<],]lW 7kifoOIu1s=\eY9;{_i:[Ygt' /_ul]*<g24G6}([]GeKr;:LG{*P?X`P=9|5MkFnA/:;H:D9<16:w 9pGKkrFid \ݦYJDƜqJh% z$b'~ R(@G4):&cн"}Q':k; wsԊd:i1'RNhrF,'[ (z=.0 5jC 9JV1̿#ҜG?AT Ⴅn5cT|^]LoAs: g} Cڲm&≖#O1hMgD\4=l-݃lՖ)UeK9dR7Lu[)ɱKxfܧpT/HD ;R*3hhds*S҉5o|.3Y{ل}Krp w8qsZϫ =!\voNҞ/shp؜uH,67%LESQnsP~VʑkFHViI5հ"x48k ?y93?* (ZŐ/5kH #Y@T s~B]>%*׼^ٱ:yXaE {mX |P.6Ff[(P= ѻk?v_A-m1?@FnԌlSovqz[z0hK샵^l2xOj5{l@o8q8fOcX2_G.ZLђ2oH^Nj 4^?ggJaQg-z{uӲ_-S^hJz:|1kp3M4)RH\JkF$Zak yٻdO*8=kfH/2`R=(t;l5괾ȕڠpgRаDfGmlڙ13Ex[JęK 8ǯ ,G [PBe[=hn"ԡXO\ppBw# Pə1 =zѸpB5v|-#wM4ā-z:4H!ZldS(Phjt7 *nzKeXe.dcaȣ͎%nY Kq4=WʘQq)3w*?y@U( i^|>`7c^|ܿz@'mQ'CK5o8=]G4T:#˓ߛecÙ8#=bP"eԯ/J1gC1,2FHbYS^LuYW.2DʝbSz?_cݒe-bͨ&5 rӷƧD\[M<}3ͤq,PteCi_e}]iۢ:o4+`CE5rmݜ$?t8h*b{.+% .w>c:&VU^=ea\nI Vtק6sUDכBym"?e/{o.2V-K';sqfU :ky62CO%D?lB̕N:q)ZխE4*Z|굚5' b\+τ- Ezpakڣ&̓eY\fZ"* 0d3`9*'9gec6H+0v9O-qP0?e!ˎ#6&f VK䃥ua"^34p4*qP+# rV ;kI^J81-O78 J0,(u&mxH[?Co0=c~0 PթWlMKOg]L԰Aنω 6C)+#Ѻat>qqql&raE5\̫9"c\Piā\ta w1%׳mطD0PW{if?+qš.QeR5="|K/<\A)nĖ`h P ;1A0Chg+\v@k$ θCAف2D/YYKwX?vF/ y9Cm|Y$Y ~6copˊf4ͣ5t.%ڇ~d'5Y^(cxޱxRE\0t"Nt16u$J)I4cО#y9_nG]O/ FBG9@o^*ΒKGhcy<-Ʈ~ԻܰHBsd}K"젇Ue-Q~l8rX:Tv:v\K;InGR4-l@D<\\t&vsN&ݫlVep|*Y>ƨ?QM)vr6"] /8 gmu`nUui]:d@Pу/oqJs '&VAH sE,ά^]PpTA(_gFx_LoM'A33p S6b1GKdhgR +s(5NgrJlVkiњRr_0%V$4]axO?Zg_KV-u=}BpQ0xTXFU^;*elk= uv49 s%OB3敏e5 co E̋C) }$lv?,6vөIF::a1e؞Q: qz 23qU ˂ !0:tI_l޽Y+'ZC[ud2Ϻȧ7lm&g =`^|syrԢ&d1$Ea(svK ?Uo^>ZLbG1'N!?)dSVѠ=52<# lZTw櫮|Niwe߆XGyfP5ryQVz@Q+r36#'#Z|'#ݼ!)C4HAD& f.&e'% ,dWı_V'n#zjڮ )*䅋Ϩ`g_I!jzw1psa{$=XWPNCuQgNU^\1O:r4J&$ گNuZ(^tR ln5K2v_1*")>8P߬Ewb>![ZX6t3E3*BOx0 fmg5q=f蕡{(U _NbUEi N+yL/"gٍL Q4w-NC\^3{?-cXҊ~ D* 3N]ӿCxHr|kAHATLCTfW$Y\EҼ{}I&hH3$>0ot"1vӖ5$P*zXV-c"gkcJ-ڐebﶫE>(ku`ͣ̉nQ5f[iP{J c@Ya^mNޔ9.Ͱ:̷Ыx;-0e۴!tώ_`U|%51V nS!2;q]iA5:#c}ƠcQo'N* .کa0-4q쾇mVlS cp tCy`׭;1䒲afG쎮qP…Fՙ[//ԽO-BTpKQ6dga̬Hˍ=R$#Q+ٯ'a/!0t`j& 6h /(b"\PzW`YƂB8RG5Jbcg9U[1[an5Fw8ΐvYc&R'rFZA5mhUhv5{%+F\a` v2=>;*1n9gBy>uī=}vWðpX=atY];{|m5 ~n;#,/?,g(u.. Rv>Ŕ! s ѷ<*[(X i1k%Z5 O0 "A4W^6 k`P.=-iսڇN [xlP0W>$Lel(t1+ Kun>u-^Uq5x"f2.]ޠ.G_hn_ΤMx¯;2 :C~a(oKWma8nT|#2U=\L] t:z1.i<(|:_Т͚ jamW ֿtL+zJƼx;^yrj=(}GTT"S`_ᡛR C>rckH̱kr !CIpv,}ꦒa\=JwHϩr:سIZ94&ͥGHf0z*}xxIּ[86 n]/LUL!c9{cɾ] -MJ YaHQPq},lr e{|@deG~@ꝈdPIJʤR2&1?焥FFޥ]pdM% 8V):M!6 S7_ae1(l W1W.0Hʼn;xjSUNy\}AviaF#,[v3JjJt.pZsU+sQUDmeB{2MTQ {L9ե =э=QNj40*)41K@\[Ym!̰nE2N%fLG຤G|;.!.\BĨ_O6f+_09戼ܶZePLr#H1z9ccX{P-}z] 0[iZRJxԬij XcN > WX>b( q!4?r brFLM2sȜȆQO=V`BMj?J(hpƘuDT4(M=:TC`~pİh xմg*)OdKН?WI30 Q _ABZNn]'V=nl5| "rڨH*uC а!KJi#ﴊh|b7+}JV4bɎ-H:d\o%^`5/(I:硭2{XdtHxhOea'M)ʓ^Cbkb_PY#ȋTFR ՟|I"LMV=[93|M$Z!|@[BΌlN8h MKaHe}E[k~IA/YP.)GWrd!I9#<+1i}7Ѭ0C y8!2yM#N]ixS,||93laH)hQ͆Uܬ/b==yݤsdP5T"ʺLlTx1P MG K*T8_oegZ v)Dzq pDځX=JQ`U}龷M7BjDa'jgp2=gOH^.s/IPd׍_E(d3 4yrnVU!^_D2w쏨 DBh1}v\7Z7H8~ł<+AӠ\t{a5A0_,7Z5w(p͛o9ւsPvHbh8u1Ė'*8D$o1mߌ8oQ!E- FZ6"dNJ* ䷋ANp4ɫ># Y㖍Ƭ\RJ0DfcCg.t@CбQʁ5bkl*y . {wf38mO֣PS1tl 2JlEq2Xnz:66dS EYS}vʒrՈ'[nX^˔]Agn^\ Wߤؕ,L?VPQI"i> &*7 (et꘬./VXUJZ9meLiA@9uHy"dQDxF,MA͖үkT~!٥29g EZ'K=i9R~tUϹ v`]LJӞ&['ZuI#{X aBsw :~}ҔY{/eE0\}e]ϗ3tV;](Ï" ]$?ibg)j% y~`_9΂DO\ATZ _x%LCc@N&gxg3$4DP叹Ќ}(Wb?[B͘?%Lΰ6N?UuVlɚz8E (nXz>DZve(֩/5=PI*" [ZP€e::{c0ܖhBW}`4~uȯ%jz&"﶑YG\a]pt}WqJX[H4^Ԋ8[Y6FKI:QFV p:E]S&}{ )D] i;Uv@IDVݏ6~SThM_0p4`x*'|>7mXhv3ys`eF)&0L{SN2LٰkVǵLd5 rnjAr-`d7`{ׁU~;4 J57(PI[##懲f;@D_ﳑ F%y̩ʲ ^˄@SТӄÃBMTBvF*+jV;" -1#awntv5*0fhX8Ш!.XU:KDrAivqOG.d;K}LR$ %(,g޴<,jl֌@H }N&ɯWfٮթP9$dl}SM"yߐ< FY Ϣà+蟰VA:Gk~*$\3uq":3Fdvvnо?4.jL֏}ځ6guj! РW9NC:mPtr-ꅣJYK1K ?n]ow.(dNA,PVQpI_3JE59sWeNAui&]dvʢSY.{ЬaSr#/ѡ-ˮ S;]̑w#s.EhS/"z?z5`CVI 8n~ke1gs-`&f\ObgVK{wa܌/=xA|1韆 *[̄V\$qVStՎJ&zr( ~q̛<p@Ρv43i\ ekAgB/e7(6n`00%)ߋ_^9b;Ug3 LG 8ʁ3 n~ 8#fĨl BNY>=V?*-<j7+anHt¶A|8Wbzhjq? ~ & ۊQǽW\Z9KRHw- if)z=B],{4bu un=zuQ!E/mP XޤLHO4ʽ2cyp:4i_fi!gx I[AP s2*Ftqa\]^$׭ܱy'(XUGF*fï~9~[ y*dL'ʄ % syO:I "N d"7޾ߘ5wq^;U:}$;Q ]RS|=gn=#f,avޅ.TPJ֫jgSBSKwѷ98E8|Ibqb+xbOD^'y76eQ>:Q;c@ b @A`*yHIP{'ӓLdG, Gj(FYop;fhbi>`joKȪDV"u+Q38DҭXm5-kq)&ρ1hŝZHUk8GώܬC3yރ a %@ru(v@~u*i{S+ ޚ+ _[&_wCζi8ө;A ^'/%R<R X9Z f`6r@  MKxGod@b8"z:q:/(7&%\h䗃( `Bm9 _x+AP+g*Jv`QYa)PTTMEأqMDySڊmTw&ruU&W푱;o(փ1śdg'O `-/HrzL_ݦ u4?B},LUIDBԠ\h_WZu1yQ5ʏϕm8:~2FT|~ -H&fx8f߉'C_xN<`ܐ_"O5 1ǵNG95_ưEwvgF3ELt#N(CET.tOl@upeMUݍ9՟yXD@S;H*>xK e^#3юV`)r1/T[f[$f.)pOz*cS~HӋ5ګnPcHcN)a4v+j'xCr+ևݸtsg' _&%/47,M[̷6` eѮvɩ/1T.xVk}{T6˒ ʉN+'bݖ!ħX!vk s8icgs=Ϥ P i];VWZ`rxLNhK4-,ԘsP&Rf S-s6@H#"k=~ƙ]iI8- KQI"/_ZYxgQ"emyŅMF ,hm.o2 |tjXG( +=wJIp͎#UnL~_Z e~KIxc#^xiD)%^bK[tu37j}|HQx+XeIRW0 J9\ !HZ ¹/*BEۻldAJ =*Z7|\lV% [:X@1 SJjwLB AT1s5p|.D]u A(2U"{k`Es mrVK~ߩs ;CɠhsݕQHB69*zncR:Z2r!q`R]_DHW*>/E@i4Q=: gHZZ`2K?0Q۔}iT橜YGM-ْn!A< Z/t{!;_Zi9%= t B {|`Ȼ'Olax{Epygjn4V( ؟g~:y A9&;UzB!QkO8(¦H%sǜ,I\4ˢ k-VB>9k4lâ d3>#FWuh-~jL[1V.X(}nTBa#l]zO9/| AfswyZ"XnӲmoȍqQux i!;+ ڡqlHͫ:2+Y[>A|FZ=^LN*5zn%#euo@sԦAGD%UK8[nKtGY°mA VK% >N$Z 9(0,%.te;ng/Z%rGSn99ݬ?z& JWq*?&K2 +\P\ GH^H+%{baa9$Mۡ;*՜.dܐYl??=YB 8цlIk!zOjoC~'Җof[k[8-ܮJFYMr j(TfOD ]5mjHp; .Hϥن)Y&h: Xq1oAjjMBq>%[Hvj|Lĵ`e/P; VKPg-VMYEDT%D,&uSWF("N'rX~q<(HI}v4lL՜W5,L1LEq!Csn= u=L$3.Y_IM< 7 cȆ| J쐕C9381y=iV\a6[u,vѓ5nr8mrYAZP Zˉs&kA[u '#"ՖwM!ًa?7njoJ{R[{>y4]h [`Z9 +60BID8 9ԗ(Eڵ;yF;a6 \9!!~/T^Q[,61, x r/%Wr%̔,ul<'8ܓ} Xsn~lga#EVK)Hg;BV@P(*8Zɞ)ax|LS1M'89C=/FO^aC0-S}ofIb_KIW9*o%H 41;,f 7'b)c.γ"+r%; ]ve*T`HU l4cD&8v:(|jG]#I : ([R5. ;o>6%F.Tb 7?*'4"E"`zRN- lɃ2edCp'ـJLbг6YcZ<~r?CzFiwGPvRYFHl{&~S:zɉEi{|Hf2ꪯ $z[c+҉52FNj~@e?BQ3cpϖNgIG9G+HkfB?Bse@>.ӲZz-J`eHk*ofdvf!WB1Wc Jg a8\]>/3VHF@I$((1跁)6#u8^s;r[}b2Pjq`3RN qٞ*E&V$=%ǻa&<{96*^n;KC5 4$v8eE@6JLĿMYSRJl K;?¶r2 JW9)2 AZ|9z&,T!ίMGYm;,V(лYqSwIT4#0T(BhΪstq[zD SdTG⧱d.gS=8j{#Y1 H(5>!l&-/G +|cS(yOIʁq f1" "ji#T$q2\(I𞝾AbS. .I2#n=)9@'L]yD%^pX02XX=6} e=%ҴNNDw^qګ$30má9 8:FZOMQn+/ lV w.gveB/&-kBK :VMhu"2*n/|&x  NOoi,B[{"6Xd":kֵeW'hKnU˄fw'Q3ū rQK\AqdI+!=N.1eT"#ivCKוOS؈f"Hnjn<->mρ,uZDGie cxyآadqoOD?eQAУV sl،=6J6}>=d{v&Bݧa,aD4Sxk3Kk ZAޭ rb5aC,0Ε32iALҳ.8)K!F9Q\QfO;ЇZ7gJ}%0汦>NהrXْVN`n/I]PlӼBmBN%)&^ZJ\.מa%s`Ƿ'?;ƶQ /sCbڌk}?ezb3-xd!u@ܟosGBq:4~isRphucɮAew*Pdp)P'ђawKlBk$Օ қ;u\櫃jdX,&ʲ zSDU\4F?m/IK`yzG=[h!9 (O\215($mko{O>">`R&=۹iRٜX]3j' E4$'!x.8?0ԧ:^WY9իKiS :`y,Ѿ'՜D+X+ey،z+*MwxEKXB9 i , 99nl@ix/YA40GC.|iQnf~l-&LpT IHg%ۉEӣZq9[p:'rK9+mDTbzmgC.7/;YG,t^Ҿj͑_C:Տ}+93c 'XHpq05CҌ䍨&oŽSCJWٗ_ ڇ$EYk3踭y!4K'灚a, ?H69d$WcNBg5BCLCyQ' R%Y6Sr{mQssWm7nn0s∆!S@l\;}~%p0248vHF~61Z{b@dWd@ ק.T3isF_C5Fۗ~oc~aDք0 7;tzæ\Qu I~oUx 5upeݷ%c845'ZSF̔VšpCw.ƌ鎿@wN,ڑ,82${Cթ QL7F fsbv7[ޢtu1iOfu51;gExmSܧMz=.E}ǧOWkb*㔭R['R{i4]pR,?JLsԳujgLFɜ37-B'`b~;e_g-)n~KdSƘ/7Np4nt<׼.p( %F^%#1w(ʽ T61(ajf302Tg% _2XҾ? ˤM~`!3WSjo8|RPoWTAhY "k R+hdG%"˼̠;Tfbr;׶k/D>5MջUl2=E'O*H)7wfL5uz֘9v5!l&,vbtI[lo) 龐FC3xHf~qD >zQ:Rhw^ tq!.kN aؘzr1L-*:7R wMD]"%wW#K!p]2WlhdW "|G2fMe3֗r_-2E#z>((`bVY+B̲|[YJÎm>5 I0J@mu A5)z G0ZfxbEMjt 8s30C b>2+Ҷ ,$kD3K;(0Tk>:"n< <6 !FMuQ8JqNѬ NepGL'޲i[|Z9*Ok -O,lIn%5 ̳@ 8tEpZK4R/?AH{V&=G0o@SL ((Y[ v׻3 endstream endobj 2343 0 obj << /Length1 1644 /Length2 12639 /Length3 0 /Length 13494 /Filter /FlateDecode >> stream xڭwUX\ݶ%I;w)*-Np@&{o_kʘ2UDIAlXy 6FN*`0 .@:ZA↎@^& 4Xxxx(b`[7{ 3sG& IC`aP86@;*p4L-1E%mi):@ Z-r@` X0L,%08-݀@ۿ*z-`079 [;M]n '![{ͻL `loax$.< vxW&`c%{y:Z@Wǿ [kC``2 @3C{k;;WzC[[kXg@kSF$Ǝ,@HLgEd 0Knd:g? ;34IAn)=$e>(o!?rtV0y1 @wXo>6n7+ {[D@f00s3Ka i 4Qp46Z:homOk ,S30%_* ߫xd%%ˠj>l_Y8>jn@)6_@QQ+~Sae?]fFffwпO濱S7 1 :Lg?N?t#-/,Rp2u{Xm kr|+>I![<ߞ+&x_m_dh>YSu&ϳ?{t`Sr1$hFx\mp2ko)<N#\<9bۢz'D}lC=>;|"#ˈB3yLəˡl>Q#Nŝς1]Kٛ.Qypr$k^ =ؤAuۂi oUO$E| /˺M1ot&ōON$ ?Yo=un_: d#ꜼUm&vq/?P: g'YFWa C}e2c>B2Z{__겖lNIa:Ylh%'$tmmڤ3\jByՐqf $ڸ`r Akƽ\((G'IY.eBV&_.]{P@j {gW[l%6%@ϭ8ڍYrR,06 Hܯ;pP&Y +0Mg Y{ 6 WO"nQfݖtyos rXa#@}_;řKA:s 4b)]I2z܌J@|<#5- % u*ټ]:&eϑ;BHq4S&^ "=I *>Ao<JEoQ۫UOДYny9KYY8r.Z^\NR !i>{ȥ@C Z~_ g㰎K^6LV r"~LީLWv9RP,cBQxx i ȼ! _ [Pz ]# Υ/XJ55,A 2ch Wecre1ؕLJ D%9m4y4ݱEs^rTnz*QrfN0DfK̦j+Wz}7vT-ٱMhS?*U(Cg4SM)@l-%N4+J)=9,E*,82AKZS }Yƾ0ѽ>oݵ+M՛*lY4hSe!WX'D3CNC .CXΪM%ɋs0ʭKWRJnF'6xJP-="~YQht]e$ҙc=< -XkԢw,n('=HiPq>/9{Hn13ӵ~RSl~9=Cu#^Bc؝*5T]S|R| dCQh Gv WCO;mȕQM5jE^«_i v#,OBR[tA0~42Ƨ2t͜m?ƦCQQUp{ 4eZ/xK3R~P ']iu>I* |]Dv2л'oV "x׿>ָ]^C#Uj->v(t+5EhO$E_(g 1U"ڑfSqZn^~ְh_EcCAw轆,k|2V;`ߓJy5E 6r3oL,.'{}N(gЯxi ko W~m?UCTvݗ1 qńc@Feפ+V}'jO I^k۩$Ι` õX rg&͵ů?jS}0v"!!-ZT-<XI7}I-/ˆ-MI?Kq3E0h,9i\y( DbQֿQKxS\Y$y6A5Jx\#6o,8Ͼ~L`h4+}L?xio+$#Xs@;&N"TL>6DCh+tjeq$q+VE3t,GHQPF%$ժIlϞ$1֒x\ t m]5Qe7<+)ߪ([6/!9J2q˖[1! 72BJ @}e.fhEEݲ0/^rR9{/u{Gg`\NR-g|bӊﮥ U# 5vd}=j-ѯ5WߟZ^M07G/7k;ݡib+,SHV5(7sڽEN(aq~4p敄C?@ꕴcٝ\V1^iJ CP+8 UƐE=X;v &O5&`7gݧ,I4KZVYl$G$ܩ0ctd4QL>$S=n[8/N?e@>L &TИ`vt2TKUPY^~tF.lZesgeL:K->`sQ,CͻgU."\zKba~ jS"n>rO fhp KHXE۠GD9Yʮmksٞ r=.=L7ɣݪZ%ɝ"GX cd#ugEF?jV?*Vᶶn% 'FοQ7u2}M ?ufRF/(pCCdV[- 4pٍ!K<a~a'\P!4W^"#{-F8H YPUgڰ]jj?I;IiRA-Dw<`\{82+gfJJ #JkD6C`҈ M;f*mon!-+ Vy~J9@on&Rz϶e5:0Z>P-3);a:: \{mKY`Hk-6u%>)8<$^BKc[*`Chw7?u ʇ m3k )F"-%twQTZ5Ze^gZ:&&:5ndc;wٍ/ZOho\Ufh37GiJqUmoA?tgf9rJtDdΊ6>QF&U#x{`:i0lFSb.g41;qScZg5uG #ml8WaPNByDD@ -yuC4\F[,L>0rSs8UU[u+6-<0oT"TRgQˍqxkGՉzs^g0%MCGv&,cQ":ʪU"IR%DG>I0u'NCTvR,PK?{ȗzAM. ;g-aٍ񥵔jWb\&kU"o-$͞r2^aȀit+US7+L\HudRj~)2p&h? 0fJ[9>u>n8M܋66n-Y2jXfwD^:]Kם{~Jwe3#\Å=1*U%, gWUBZ)<ޚ0.(q1VM~vۯ#r\M`,Un`P|NQJhi`jsտR &iU((fd'\< Gw @eHM_(:md-emG.}2ʢF?}.`~&W?5`vXΤ/,68t!!f\pG`u *Q5)St|T!V*MD`+߯N5"ci+kJaMtǔȊ~X"#ޖFF=>qhdk rbH}jߣ0Hh?e!Uѷ_P~kh4(ڞPƮI+LjL?=b@@hT8 -r Q!`N5zd@ .TmvO׶#x`:[QTK$tHM@BW@"/yȌY:Kx[bIwIv&qO%E܍/`!G31NݷF7 H(nK&Zbiþ{-mi+X2=S~faY} :X"Ҩ]fh4J>'E[*{Ȁ>z %*xgj!0o %@yjhcw+߭ysH=au=INZ{yѫ.jU !FAhB*f꟫fspKUS.jˋνP*%1(Ԯ;k`igaHKJץhj-SZ~ٜpzKGKG c1l9B:˪$!5'*\ $B(Z{F ^H6 8W%_(&괣KvsVpllIqSC7Ppgvqv 醞Za7ZyFvDh[|b(0 d~mne]^%vV!JKtOFBf>@/D׹ac6Y`D!b-D?~rQVGMsQϯl6؁deNrivgi$WXƦTAFM?Т%ŹqrgO9`mqɟHhq vHm, -ZvIV AQl,v(pjaY|H~gl%XPX$% ^3hr֓Jf 03t{7,I2l>9>U4]ijyJE^I:"%6.2JE T9"WlQ!U}&įo#no<ˮ3jsl d= aѐVg<8V"me&yxƙ΅?zG*Nenqb7"%su>hg|Q%>TF1ѐscRHX'Ip?G0.~0Hfx TIr3]u܈*4GKDPU$Ana8yBwA@^aNoA;^gc zD-,5c}rbf^}w KdU%+N(gfJ!uef&j~J"R5tV# ݪwt QQn5w-g'|zUS ?ou 4>p.n6_VD1*UZ`nWV%:{Qp鬉ZԎ+JODH:eAdax" 5A^.ku|UQh!\w bx(ҽ>^A;GS~.f{Z>:]Kt)"UQyLu ܓ_748.XtN)Wa3luo!Ib';m^wݣ tIV_=5"u9#YM`"<* R(pUJI4?N WT%Ar'1::|:WݣzSQ0a۱S$5fNiC8 CB)߼ !`͊ 0/ִ]Vlܕ$gb\׾z7CC% Q\tQ&.cP3 jD]*$-oVNwlTHZQoM݃ʂV/(}(ze]+tԳSM-_oBV DX7Բ5NOZߠgAhk4?kGKUIrj ©or~Ƥgga-8 ҏ_>ǎ|9G~cWhQ!^fK unNtb'tqeGS"+9i*'oL5}ڽ+,c/>U'0Hb4+hczWX4w^o..5g*^oiEso  _)e< Ҡ>GN=|h@vdC8ϧshM 1j줟 h]䍥ۆ->2m+_ cj5Ԏ:ZBPnG2g'g"r͊Q\?xkZ3G8W'> @0"iTnɻDN),Yc">f[_^6zB!/*Nx[^~mY!of;ԞЪȻ}JL1 DQ1Q !rՀ8MX_o "`䮋&;޶\'䛨9}k4PYYÑ$!s._=:U$.юz7ܙ6^8(^-ԐwH7Iy'Ŷ\$8h*=Uۧ^5_}>L$P7Xv,9T1҃vy?^ɴh&D^֏ nbP]6bNX3gN6H/0+-řiiBhј~ׯJyxwPG#j&օuaPѪr7w'$~- . .ېy19S8dHjcNkwsa=Obt Ei[$ eU] K~55Y'nSf`1lQb>N 3pGyDaC Ԩ,=oZ)~X X"s$cS*vX ɕcl*Pdj.i*tA4l_DŽ{F3\H*/ j[!RzNO;BbLI>$ K[ԃl2,FP$27vsEVK#rF9w$+SΎ71PE2c:Ϲ eAgI"x5 >W'5ݜKf5TDKh;p/ukyhĘ"7u;[UP}bvNwZP\QJ!pM>Ƌ7",E RP*󈚳/ AYޯv[uvBψ‘F<4ogW\{ί:dNŗBSqmR,5ZS! @j1'P4&4<袌@יI6!px;;YG@(B2uS#9u6u`!7G7"z0 yS&e簷(Qn٦t!Q/ٚ1+R6IXW.j_yB3[8qbelgNViW-~-Y."_݇28jVU"RoCC}&_y(Hu8j%? )9nx`o҃2}&#%.(dmwt.vCU<@efUzQtʶ|JyТ^0JUOG¢:t: uA *dLr=HX}>AǫO?G«*C_RSl<=1BPש/e1*} +0u3mD371;-8|y_b7,bp;Blbu=R% P&q]iNYmt#6GM~Bl}h'Vb*v^г8BoVi jzwz?;5lq_nM]hB6i(HTܮL(jdFkH\ũF7^30l.aP-muF /yE&LW)DP/#0q~ vL#H\`>-oר.L(N#٩a7|ӑMS8}BYoDyBd6|i0|Rb0IV*B޹?ل3EɠZ#E왠^<5[?d?y;VR[='q*ǐba#O1$1T aZVOeVa^=fJ*ټӞ64c$ʍwi׺sLuDZ=`gx5dm`ɴp[]hy#dΞh"LU+l&uIW? ^y-𶤑/{>!1\Ɣ 0|>>;ԭM P-. zws@Mî{0-nh>ņ]VDfZxH*HP#'_$!č[I?ah :-R\ll]GE6V:ta`"#[eYp_3:Y3u-/k=Lx¨}kM _?qGWi8UU$ፑ2 '|Zx=PXAohJ~h2:; 5֗BHdDg| f4 \m~Aŧbf `!cÑ]f1W`>"e;@^\Ŋhs@RQ8aUAɝ(: u(3TJM r_1i/l2&eqP%54G,h5Zpk9e2R!͓Z&f@Uƿ˻/].n;4${l"%?lg}>]uUb Ӌ|Eq=y/@gT# o8ʏ_3~j -7K_sN8G/}4zI|MI/.CLAOb';B%&Uٙ6=kY)<R&T7Յ5i{JGT-<ՃgIBN],EJS[9m jˑYJtW;F}=W{ж'%(n:JmOUL\}HS䛐ZLW:v9H!yh6VS“K4Kz3ܮO:Mk=dHȵ1̐vf2BlS5)"ɩG?rH&WȖWY^p f (XFduOhuY04%`YFp;b[ЈjbXse)}=ݹ ^ݙ.(Sǰ*CwIWf#_3/1thʜzJWgs;?07 Vw]wg\Sl_9R7&!x#e迿&NSNP% "MZ^[h $9 t=Կ*8 ~7;KWGȪ )A. DPqa;)AeAt `pU9O!Փ0D'1/]~r Jcj. …ʈ;x2.D"8I[JW)pKHr|Y"%~N٭8LRֽLPrzGcp4J( |zo\D_,{ pSF6nH.ڞރ~0_5ok$?Pm@ZQl P@rXm.z&'Hho3@Z.SowҢ ĔtK#kԫ Ovjg aNأOTЫ${wOfIR0Z3s$L1dfq Vl8%< Lcm 簦z~L]/ {ԡE0ly3r=ꊻBg~T%i^JN7yU`k|2&ϳ 9MG  GI78)kQ>$L~|L$9{"4 ]>> 9٩"DsZ? ZFX 'fGT;zF"PN~˽.v)m#nHaR b5HD(}9P\BBڵ+ SKru_h;w2#5D;1a/5ۍ;.6YSْB'WƗHFhVX &]t"m(ӜiKeD;Vᡃ/X!ڲ2Fk?Ħd+ c uQ;Pk3ͤ>%YVITb`=>> stream xڬcx%\&vvlv:c;۶:ѱ;m;uL?;g\WUwUV$J "f&@I{WFf^< M〣sZ9؋y@38 `ၣ98z9[YXU4i ?.Vʿ?܁v@{׿ׁ@ 0eR )=oJn&Vy+S ` ``ofOk.D\G0)trq`p6w{+{S[7 k7wWA=bɔ\\]L]*KNWKcrX=Li__ O. odV*?+8-l..irs;'__5XmXX4uy7w0n;_D- `4cRpp@2 "UJ-fk`lwg=Y6΀'_5rW)D-*o'L`nleW7:Z_05K+S77=_0}?l9+ W5/G f`P:xX8y \_D,yfl efdff ?sjlow; 4[[v0 tcu,kR+. uψ2z ellZ:w8=òM^nQvr1!f^hx,@p2kM*CNw9<`qD3MoBiA/:L>}C5862<{ O#/$՝ =Í,О4A kug}hKӚe3K12@8A{Od=YioGdfm:YnwǦ4DI&jK;|Mc-vV>uj lx?n-xI+urM%ToIPc;Xҥ>FԦ`PmC(о'潞tUU5gk0(S 3rR[(nr{"ݍScs6:?[f\=X%^D|e`;#XIU6vJZ|%tHeD?xE0kPQ,VL8m)—eA^Bz^S?$~MM'P\Dp_L* 2TiD8X" g: tK?O%@ʢFk`|W% nOKмy -RW*N ̠T]}֊NV{5NOP|[n+Eʧ=/ ;i$Ӳƅ}XLh;`Dn 6OJ㦪Pp^FNw˥ T+ %ՆЕ)ȎwuI#X6 T5vxK0qRm ΰ_F#:5kH oiy5ɹ*C]yzr6/aCx1LxQG@]q7%gDʼnO5з b6ee 1U4+4XMkS Aх.jQD=uy5Ki>aI05kj U5u)<(?n ;S5-|[J<5m4AOV$7գgt$yw7-i8A&\3hvlC?70$9Һ)=V8̀U77E體a~PM4(U~,- _OM|C`o(ePEfל@@8[A玻gH8~ <*e\SwAtiD"V͏ \^8h\yAh? 2J=0 PM˄0Ʈyv hA3e{,S9nπduDc{9BivdL}&Z]\:bIL:uѧY8g5M0+O7} &(yρߓ]`2`iZ#17Vf%lb.P)bcZ3rܒy5 'ɗ,KSf/ Y\'~IHeˢtDi,wQ`:O3.FQ"L2<æ ؓgMGX$c<^^a}5 7| *R0S@`/{~(qfs#1ѡm֝ՆWДALBz"!M|z;Q?`޾1^{ /:{ltZo*rA>bt<,o{u53NcQIhe^jۯ8u];4|kQ-xVx{`prOvSs\WL<"0"GnB33 :r =}X1. 3OD PvPj^\ .kYxܷar X#p0VʱQ>+dP)O3L]63 |D D/FX׳{ؠ%,k8fRsΝNDAK^Va,'MH1v~ ҂KZ=cK\'Ji)V~gN=]xe! YuK՝^OK+|#jhY'ixeoG?li+^K}g]r|IuLXaq X6;aW{IBasyZ7U })dӭ  lSJT3lj_ça` :VHO]v]w dmM\0#GXrq*TC_.)ZhH=b pql7>ZrHVߍ1رz~Cخѻ^2'+\ #bcN魤~_ƚ7spg==4 E2jyey+T7rzW &,ZFD"dZ @^̮[av'5gJΤhԔNɯaTG7wEt_ .Vr B.5G%ƓT#nQ2O987raS#{Zo?ԮCP\ UA ? s^ANK?zנ_RvE"2x& }Uhw#m[xmCۍiAEo QnrǹEN}nbl1}A~vjs]$r3;٫YぜB wkB@UiŀLm: 2ժ}ŅXW'cg ޵*u"!8Z§3{9kd {kA E9W[6\ >n[~H`RW`F--!dxĵ:w43lie]+[-<*8k~ ].~7}+S_*T X 1L `l#Av}zHX_G)+!?׌JpåZY=-/z 3W]ٖ&FX{vUWq J)N V&kFX 8R(Y*\ HW=5 A\.0U1XEouHDGd-2 $[-]Ig.]AN^NYx3!oV4 9h=5pD}^c)i7.Yp;"5{; qUOF#˼@p@`])% heVmcޑ2/a5|3rg$?ania~K2<}F,J917yii16%yIJ;l'xqHCfR_ ![웄wqu.IϬp֏36ڮ-cGd;͌HoWfoz~b++k=\0MXv-HO9YuOʓ~cmU6 Lku,d9\t$@5x9L>9ݭ#_Yr¾T~'iwX/Ufu DMvwKˣuC-/&=%̗lɂ R+2cٕ L CHCiF)H?X+,.cx6E;z 'r#\uy{/ ,Ҕ$FALg 'P'I^8+! 1*-aԺ[J[T޷r2KieMZT8. N(ϑ,EmYA, WlvI% ᘀP&l0#e6gmE1SvkHD_M|\"iBFӌvh|~{CPHq о66ƥ!fzU]8$nW*R#6a;|75hG*Eda 0)k p%rօ\N YH9v䒀krlU֋?B$Y‚ninᇈ Ӧ\"ŕC|I~ ZԐB:* g5X:lJ#1K]q.?T EP_iMFAhc@.^_'ިZk0ɫٴ\ײY%GxP{`K#/W}5յrFv0h|6,K}7ЗSn5]Ru7$ j-tj·U$E& BJ75V})ߐh]q\fΰ ;V%D @Y#;9猽A4LT{> z k6$a5M5]noIh[{Ӏ=87X@>qN5䩺XD-BG8DjYZc7K#|?tS Ls+xZestç2@Yp]j߉b,J䌚L*ML-3}3NKoN zا] B0.,V(fFTb4V ~[vY8cFEzG:D`[W^)N ?"Om!t܅k] =)lv5%$A3$>E$f跣`;OD9XJҼ_H)7!\g(bJaǹ4R2pWwEg/U[V/h2#7ҍk|1MHoA\w2 xd'n7_MT[ZTj9hԨY!ʹ%ӰlQL=8MP]eiS:_$[Ͱ33iv< -)EۉkY3׶dTj[%m]E,HYCRA<҆in$VwcSn9AVdp ?Km393HT?wR܋CQ!epl[/u1+ҞVN)܃Mz\aGgS󀭎H[aS  v~-@;}X7DZoeNx&bF{25&uztqEnU-9(,~$̙!J;P)﹘Ȋk!ouObD\*>/eK} 6j*EkPu)܌O- W3^sЂ⹳0vdK_ui8n+@}&?+u=AowoL/Zw1ݺǖ=0=%W{RSER鱀/[H^}>s*̯?NQG%zQV7I셓:ٙ&9 e&G7 RG? n{Y7h07rw 5q>CqHKCDv9աRe^6PEj&b !m>._uv\7#n.}Ν5Gm`)`G{`hl7!h#sYz{-mŐtAv>Jb!sCSyJCB.2f=z*pнUɼ#88jz /z\!C`VX>"c2+I9jx>F, e F?;HlWAb5[<+LAvU`i'>}z"-yA-Xk6&/uO0h_f%}`(#8n\EE0P)oexrD̞e@(S!۽Lxýeզ]TO\SN5y5GsnfL2ԢjafV L52=4n_}9uL\{'Ȱ3:%ʸw#z']JG>u:s+UCb!2ՎG}ɵuz23>Fk+sqv)n6ڤcn9g)I1^Ⱥnjf1 7kវm Jo4'ou20DgU,#,Mﱞ$({J/89 Ma"w44|eQ7 Fkr#;CxTۏܜ df()vCaa,GӇyQ5tM j~At?.% /Yz|t\[TW41 d=FF>ېRgT]We%FKM w 6_SZ Kd^A}:|5{MQ ܼ8YJf/$z^28<)Q Q c0{K]'=EL|{_9ƈ4VUPLW{+|E@pB1H,j38ӱUm AB>!vݘD`xIazJŚ(9#0kH!;JJT ;?xSr:92L]6XH=ި/[C{7rY|j6`eh%׷GOfJ3fM&oB 햝1ΦJ{?Q,+ 1kNKVad 2 qh?oX3"95~ATnf LL%eO 4*ٗ57کsy$ GOCHU#W)>tPh*5G6SVD׆ |S@,-dϡuN~-Z*b5*:So~i#Z$0& X: ]9r#k5'xBMKٍCA1~O!uW>x@@b]Ð7r$6Ll4v)rv;\7 ߤ¦ M:Ƅb_ #ü4x<,VHR:jkf:pN&]yW%DmCz9!Ø<;)Kj 7IqH|}Qcs 8 x_ Q &yL@TRn%y+&TNB fcuҢpBDDicO[7>H h]:DFnd khn¿,،_f;/Uf$P9Vz"乏í]L>zYю ~yT|Q*0q`ᅫDeֿomSq %|>S󴩕H%[kJ:CĻ j 44}2u4l=X <8] -IXM>U%f85(RԳēά.w~² ZTL^?$|Tnh~P-d>DVQ8F4sM4 h#9o `6E*/՘VgXxi 1g!*x Xs"Z rL8 Ta; uRo3؆fh\ݵԯEFWn\t_Vd{۠`4ȣp`u#_5Z.}Y 3߃!qEz2LLn1j.V_X~C_8(p3U<-Y]VyHIH/Xc{A-{( ?>Ɩ_b!78 *߈1nۏ [=ߦ Q/ҵx̦gêL`;A"++:OڧuJN 0RR<\?'&kUӅ; wQd&a$TߓZܲ>UJpY16m(JsET%ˈ;h#i9t~xizP9$t.7s,9gc[BˉXmT#`C}{&ЍItq[k_#RF: >S1lnۃIw7^+mݚ:S-9ך\ƢJS *e6[* jYy9+8p϶4[0V۹Ww O$ǥ!R tF` |+")3"7E%lH'nhj?ߚ9aF<2<C$O%Mlp$ظ+7:oV'ޓ0SHqB(TYlW9I^Z(_t\H[?G\Y6HxP0ڬeL$+Kas"#D%}\^Doຳ]9JW\J=t\jIu J٩W%cJ qtw*_wƌ|w譢I✯)U&m]<Ɲ@1 BF$ItN!>MP,0-Q$U9M/ZW(YgID< %x'a̛ɛV4G3&Pf$Y?s8Jf $˪Ӥ_ .ڶb aj"@{?e}Ee [⿕)YD F+k:xO[8UF_X_M'ړ4r=y[#_՟ \3틫ltHwz4.Idsn9O $ Ą.NsXZ;fyDuֵe|`]LJ fD96\t0x> #{Y]^(JUK9_-\n!41 qp A[Ľ8Y,u+qCΠ'3JXZKaO;i.B}c3׏}K7jP?nA& *;]3v#wۅpFH8$gѮP}O0\x*~sM[CȻyg/gb*'Rf$t C$I+t_w},#GZiXzZ,a2/I4Kp0 u{ cpFS9@3I* Ay"&\ՏQ ˦@ ªSt2.7wh1 SDpp$T/q=,b~ٓ }弡BaN^0:XmܷӦ jZsoh*}4al@|sRDc<{ b9D!5WY$)/LɼPj)2,\RiS\%WUvTnxa3C.d:^rg2,j.TlI59= {PH*7Kjuk- `CtzW$jN1$H ᴄz q%=\Y8]Rs dP$Í#.c^x6YWktU WKEktz$71ּY*A3CEV){C~$&t/[Up`'1ڐe.Xl1"QCo^190iʙT9;ڰxa/3 61⨘;vywR(照]vY$7U?өafANs=Z< ^37!R?yd&-d0?CNAr%Ǖ8\ŋxXTx|oOR lo Y,.+.W2QLADX`!cNIzN_$ט ͢s=RZ5~ڳ(0G\xOhaj5F{/,V RES#J8UiǮr@%Mu"sC8ÚBOLv .n7Hl(|ZF|RѵD.nBfNY9 Z##d?Ј'k׽^g4iպJUXkcJɋ]\W Sq^&QR/(Fi'5tR7n-<~R/ĔK=4a$ Ĩt(.CLrJe]`A9LPhl,v_ D//ӟrhC?FxEMbMv"?~zkeAZr9)F$ %ˬMNb-O_IR{1J%bom+FMdy7 ۚ˨h&"@lp~eoHLp~!]|沦BQ8_RXY7 z٠YpA_UU _8wW5{"`5M@ɿxjg?}LT QpGnczk?C9O8E mI7շ2b![on 4^ -gkV2#ڴtVmZ5Ov{"D:ӊ#,wCqʼniX&NWL(3EqU^!]k=lٳLgavGdl5M0@E۞-SUm^eg Ĥt4yc<{&@Me"/ОamrCwp?`1(yk1bR {SgTO.dc(u5F_ס/ XTYuU3D~9d*O۔[ԟ9ʙ 熇n> stream xmTMo0Wx$ ! 8l[jWHL7IPV=M̼ su;Uٛ=w]yil;<[[j<=?׾+v`&ߴț<^*;~&Q>MS >_P{=s@dkx;`VY`s4JaQܡn.Uu9\Y6><ٴ.Z.4>Dӗ}~r:-d0VWk,8yLһʮӮђ[*mLr?q 5F8@=@)& 8Rx uD\j2HV0CzL] bctI g$`htы0\F0s jd< I6zg W qȐ+#k .bsrbmXK7ǵH7Gnb>&jؐu1VljOu$՟qWS/%1{\xB!K(hHTЖ枃Jρϯv=k2UKς_:~$/ ~E+7ˢ/ l(/} -+ZXukoԝE?ZKq endstream endobj 2348 0 obj << /Length 695 /Filter /FlateDecode >> stream xmTMo0Wx$ ! 8l[jWHL7IPV=M̼ su;Uٛ=w]yil;<[[j<=?׾+v`&ߴț<^*;~&Q>MS>u;q~:fc_0F)lGιmu f8Gӫ6b"!YUe.`M{My?IC4}+̝l/Bj*{pϻƲO('$ *{>J-9_eQ"V$)MP:^9 ^` br @ {@(\,RH&ti m+3ԅ ,;F$БzFFieD(0A1a8yΠFpnù[w6p@ )9r9b_ia|F-(:(nQHY^`nA|n(戥K}s\}sԑoA&vqc⠦ YK^ʛ!_my_)=^ ^{TGRw1RDž'xJzImi9j'pͽܳ/-_Z,N_: ~iyY2q,nЪ5QN Y58.] endstream endobj 2349 0 obj << /Length 739 /Filter /FlateDecode >> stream xmUMo0WxvHUdCmU^!1H#x?gx]OTm$|͜s_Iss :L;<Sz==׾f`*_`ɫڟk3'iѴ}=M;7rfnj-eSӵOLg~8 )ok A8 $`I\3`Af<Z]! xNky"7 _㓧q H`nḱRONH=CpB:# =%888QA~!*zƜАT?!~> tw8y*sύ }nFE>7*QύR>7G];~<6OIyktg>O:yұϓN|I/|yIg>O:y҅ϓ.}2 L> stream xmUMo:W5?$R. d9M eCkmCp;;w~>|3E_?O]5߶w]Occ]=~?}Oyh9%?۹׬B|Ɯ>);vw%g43>\ 6 EJ78 1{~`W(-;]%=xe_,b+-O;q\L}UI--=BKE1p[! Mߊyu>.N5K)Wb٬8i[_uʕMzQ)V(Txޢjy!Z2P="Zd0\ÃGR\).2*Шa!U,H`+j.5Nα@VK-x%3%AYӀzΚ>kP#5m0Woþj.ZT$X/)n)#Wo(oRZ $Kp4Z-b\1ܰJ P"GXQi/8k^Zq:Zs9dB )sL-7xJ`aɽ)f$1 dъcCZC<73JgznHȰYɚTa,_-O87}KԴܗLloK+gJ.GZyVc48Wt]:P~`rZq.n1] S/Pu7Ue:?&?!d&1yHn5)yғBx#1ޞ]Go׏M?X endstream endobj 2351 0 obj << /Length 900 /Filter /FlateDecode >> stream xmUMo:W5?$R. d9M eCkmCp;;w~>|3E_?O]5߶w]Occ]=~?}Oyh9%?۹׬B|Ɯ>);vw7{>oaI> ѲH8U/RǾ0ñ_x0ӅxBiE.͏S=/b_ixމbc4fi|8EXD_R4.GRQhV̪xvqڎXJfUıkM;rͭSlҏ֋jU,N2@ ",   T[<5 1"àcvG@mg K | +T|5flxZ1YP^ꠦdb}[ה_Q>kUbw88]k|'%Ǿjց{ g䈏rsqk:n87xIue.Aft0!?4ɳ4mFtӔ^z1?z .~lP}L endstream endobj 2352 0 obj << /Length 665 /Filter /FlateDecode >> stream xmTMk0WhFG*! miʲVZCcYy#9햅ļ{3񸟤e&Oo]&C]]Mq>zwt߉Ǯ)n.pCx?nڽVgx=itO"i [\l\WM}'ԭ̚t4pXeȉeU oq yM\-CnCW_Ey}wP dZz891euB)] W-\v\]~[S!8&+Zce"'2Ɍ5I@|"B2AQhSlLء28a}ɑFq5ҍnnbfǮCG= Wܢe$g;A,:sx l=NOTƘ$0_س/vЧQ%~Zx pX2]$^qnaK??q FqMyc0=) &l(mi,3|d &\c ]͹&ӈ9w{d-tx\ \cΜekqLJs?<@>qhx .׷8wl~1V<*m"mmDa endstream endobj 2353 0 obj << /Length 664 /Filter /FlateDecode >> stream xmTMo0WxvB+8l[jWHL7RI;onDo3ތ?n~<&Y$ŝK_IsE77E[^N\5sߖ;7|[lzmS_*7F?h3΃;mc-bB`ew\_7oK׽;(2Z.ETz}ܟ~o9V^MVK7-\f\S}[S!pcSs|TXo1/ȡ aeuC> stream xmTMo0WxvB+8l[+ML7RI;onDo3ތ?n~<&YվI|/ŋ;t硋nn\3<:Wj\=?-wn6pGۦ|Tnʽgxté7~qzxKlqrnX7UޞMjuSAxHiQ,'wͱ 1}hW7q{UEݥ-rG*F>NNL7u]tNhWS;wE )b,#TTHy=)9>*QKr7P:MȡQ^s$LD6aȑ*s.$S56`>ƄmÁ#TL 5kd}WXssc*zRh/#? bE$L|ږ8^y>eSQc̯bV̯cNa'_OAJ195kd3EH@8ܰ%~As*=F 0`{RLPh33Y$LƹǬ oqMsȼ tx\ \cΜ-eksL ?"@>qhx ׷=l~1֍>*]!MBa endstream endobj 2355 0 obj << /Length 665 /Filter /FlateDecode >> stream xmTn0C6U@"mTt@;olvR3ތm~<&YվI|+œ;t羋<]3;Wj|{}[ mmᆂMv{Kt=c_~B?zxoBS6wBJ)X7UaMuSxHiQV,4$O;nC-bD/OCnC_n^ѻs׽9X2Z.ET~{~ʶrn_~߼h!R,6ew*ؔb%k e+Kӄ$a"1x*s.$S56P>Ƅm„A Fs 5577vرϾ+uaя6R:!,əCxg+ѧy*JcL|*m:fvuiWUꧏɩ\g%<Ϛ"sÖ0_:3x0kjhyIYx0aCnOg3$cx0<<v5O#ܵu7A 6*sZ ZcΜ-ܠeYksL ?"@>qh|tngk;dGGM@c endstream endobj 2356 0 obj << /Length 665 /Filter /FlateDecode >> stream xmTn0C6U@"mTt@;olvR3ތm~<&YվI|+œ;t羋<]3;Wj|{}[ mmᆂMv{Kt=cߚ~B?zxoBS6wBJ)X7UaMuSxHiQV,4$O;nC-bD/OCnC_n^ѻs׽9X2Z.ET~{~ʶrn_~߼h!R,6ew*ؔb%k e+Kӄ$a"1x*s.$S56P>Ƅm„A Fs 5577vرϾ+uaя6R:!,əCxg+ѧy*JcL|*m:fvuiWUꧏɩ\g%<Ϛ"sÖ0_:3x0kjhyIYx0aCnOg3$cx0<<v5O#ܵu7A 6*sZ ZcΜ-ܠeYksL ?"@>qh|tngk;dGGMc endstream endobj 2357 0 obj << /Length 799 /Filter /FlateDecode >> stream xuUn@+HɁkc{!5&Q^ үル!zya/W7/~jyld}{9}N=C'u\W;oέO*k`~?''3Ɖt3\;WS]Q?SVk ]{9FSѤoG^ 32j$WC0h޼O~wC4Sy<&>U]Rn·ÛB~,{_=ڰfhm_}4zu|sH]Wb MLD!E!B FAC\dQQ(%T<#h^QqKƊL0cF F͌a._Q mPG9'+X38)+ι7\'~5:r%%Β뤧$1$܋a %aN*Atg&W̡`92/X[B|fAlI)dKdgI$[d$[H$[hv-|9~ddK%[w-t--d ~)BO)Rd dK|ɖNK)K)++Ζ]Rd]Oz͜|x8?<ᤥNO]?p@}_:h? endstream endobj 2358 0 obj << /Length 720 /Filter /FlateDecode >> stream x}TMo0+J6*ħöUSEj9߯ IVcf͏睟ݛ{)^؝}]u:vzyu|CW$nmmΑmq5)M{`qjS5M2үxO%r^q &\TƦkR@YwDoYia) SZM5_$$>kxq4|;o4vhwqB؝Bf#j{p7P_?{+4}+VYu}e}n.ˍggfjj{k:lF #QhJq  HQ/e.!Pp #]gQtVTv)#l-g!7'uӾ:[sI r.39uf *gQNxEqV11V啣Yq:54kDCZ+)]Ws8:а/9R\Qrz\8Ç]按Sp/ d8D(B!4׳030 =;fzÞJmw&^0C~/nS0GKW皠NdzG5cC)!=E^K<3Iò8ȿ q3NOg{ACt~Qn~ɸ\ %1.: *4hH`<4̶E hS endstream endobj 2359 0 obj << /Length 719 /Filter /FlateDecode >> stream x}TMo0+J6*ħöUSEj9߯ IVcf͏睟ݛ{)^؝}]u:vzyu|CW$nmmΑmq5)M{`qjS5MJJWG> stream xmSˎ0+$1$#8h@Bܰp`~ +8*=SJ]sCM&ESݮ`w z\ħmbo'ޚr028~}uHXz_z.XA_`1o"xR:bct\$7҈٘TmH@ ]W0ywznͩV+1r]oś}X 6g1ͭnm{!^ ' bނP48YhC`୤\UY=0ZĎiơ 7([4r;"A"e"qDgs"2dK$#В%#KDDNs5&]J[/G endstream endobj 2302 0 obj << /Type /ObjStm /N 100 /First 937 /Length 3309 /Filter /FlateDecode >> stream x[YoF~ׯ]R˖#9d 5$pH3#o&YEŅ.!\QX"q, Q0^c<0fVc8pB8#Rp,bíh-#N^Ñq̈0V"BØ9",!@bzN$`OFk jF+80ljb8fDBc=Q dcg" 1\dh a K$<p+P()E l-2E ;ZK& oP&S*(Ȕ^`TE PYI`y!9rDk.J&PgQ bBwuf,@H[J罁)A(|7PA>x.[#Pyk{%l(#oӋhЭt~vx4tˁ 0lq>$k|2@ {3&e@O$ngJ&:[Vr\RK|uͅHxw^ZZb0ifكWgn:Kֺu+ t>OO)=szH_П=//}MO)}C[GZjpS'V^qo6_@Nq3Ly `۰BwwG{?U*^6bE2/-f]"( 6+sV;-dɂVՇgoV'ˑ?=/W [M3WʳR1W(jwH?zUFv:1uhVb%&ؖ׆`%ll#4_c? Ǐg_/x掐C=#`s!g9&}kѣW{|˜<~ۊ]k=waQ4Qҙ~9~$vOp/x/֮_+b\H:A0Ɲ$.|nhڍV'Gϟ=[bZ~Q9F>0*D.6'} pU6_?{E.}um̧ƝN[?g @0asyY^=!O$/H&3-@TKvI|G,U/1X44ybSE.%MXR2LsH9]Oo1 Xaw 3br7zwH[xst<O4lja^"inɽ}MT.[oqz)*ĄWWk/-Pg0I(Igohzl=hƓ)VPUi`wz" ׾ !//BZ~߅iK@$LnsL /H:"&[LZH~sH21II."6GH,*m4Iv V=vuD͕!œrJƏ̺xxz\:-sQBl=r wEwRv2 endstream endobj 2366 0 obj << /Type /ObjStm /N 100 /First 866 /Length 1618 /Filter /FlateDecode >> stream xڝъFE+vu`yIH[ȃ!KX0v!LM 2e5j]uH>QjA@ (ؖV鳕"ߊlʘ^̮smnUvJ}`䠕i3sTec,8y:ɳ3qjLnv&WN޸^9y&VP v*KݹѸvl{;'2vAw~0"0Tĥ`iЬ䡧=TW&kM\4jL6k`c2 cdM-p^_;Y`ߖfYjaى-Zh-.' 171xT d+muvm?'o<@Qh}r467 [3,MQspu}cUSp\c5@8y&e66rxh,oegljM]=9,m&U wMa-krE2&â:*TK9o_zU!YMlB)ղ:'Yʒ+kz=_/z9Jk}+ǽܫ޾ܭ ~郆}sec[O{~S΍g?qԭq=|?*6 yXwaʖXXK~v^]X]Jpa=|۰:  `F90#   9qF@ D9H# G` @4fZ94rhfj:-P @TF>ކo60(L,,vY]&aÅ`E]l. 3$H0 #0I&a0" $\pF$aKNˆ$ 0r IaF.a8 #0L% 'aDI$H0 #0I&a0" $\pF$aKNˆ$ 0r IaF.a8 #0L% 'aDI$H0 #0I&a0" $BVo" 7]&avIVna5 ۶:}ow> stream xڕ\]#}_GO._͏q -CϨWӰFR$n~}AحNX$O*[>-@GHЋ9|Ev2WН6  aW苪zh.×^Xi|z.7,s Wp&rpIwAȄ 9E^x`X2 o5م4&̢n~F{),B`GD)-—Sj ZqJ/,3)1-q_"uh)Hq)q3ҧD'@;OM ;b\kcѻQю!iznNP4 1|mզ#z!LA[YJYa2CެKxFԡ7 PMIs̗ޜ'^zs6K06Ku c,|,'aPzd7KuȩtxM5C' ړz]vFFCQoAA.nbP:7Gb]-$zZ62P#QGK]H}z#ga)Td)x.3ʅHu+zKY[Je0 TΣ]bHUd?ԌV!4x\ֈ_?|B_9bY师?rşw>ߎ,#w~ߧ헁9~-M+fhq7T7 uJ7JBGU%+l ?7dom~Smc~4JeKM%? O4TV!fT5g8,jm>aD+MǏꕖ<|joSyT8.KM+LR̶yKBH͑n!TjFpD7Z%rX퇁pΆ~{>XilZWi^7(twtx-Cgk7MiFU6pO33s?.A+z `E ld- '7QSFYiZU?AZjؾrqێXC_zx^v{|2RH'g*Mۮ*HRjY ]V*Rf¼Ο~UiSpզA9ufۦm Zh@l8Yջ7Ex5׬-w~ai =8 9#;+Gw T!W ߣZY&VpJM)\.#M{=@br}-Ɯ'^jxG ŶK,a<.S&œƉݣl\;)tTғ(;H=Ǐ_FԬ7%Vnnjrhe4Vp19ɨYgֹ8ZVM=wGX~d/nˈh0MaNu6=\SMqv1oc{\m<Ği%v85T% E[w"& g5uZ?K~8pدt&l{G^3s~qڣtnr5WȠ2x8.kҽ]U)C8>jfrmqvN/[$kePmoOi{$c*jrKv80^\r1nk8wm.*ܶ#^_xrO_GLlD|.QV:=X/Z D>'36Y, D%?ØS3l4\rB j.hs+͍Mt4a EM5@S|ЅEUV4LOAs-AݪOp>uKᩀN3K[fUr3~Bg}R! uh&s.V!GjWQl?+e@mxm=;71 5Ѝ |n [W0s^66u,w^WX&ZY]?:KB ҄I~O~;{%Êx\׶Q6_A~BCrHt`՜"G=Y3v}5n#ST tņtTsNaGsQBsEOxӴSmMH|<}}0p*`??~fjzWRnU~E.njLrm0ͮv{dxSN˺Uۨ,_ QF-|\_|un?9zY.vICznE|y;9.i#w$\!1'oP}l7~ M.'*6 jhW!'&a"Ӕ䛅+Þ~YT]UA3ljm4vݸY]/5[w+0d5pAQ]8I܈Py9`.tT5Wo[ *:b'YI j2X&a攒4}9{F\ܩMT(=Ȳbro.Y,"ލ++!/ Ƿ`,iʋ+~X|t)OۘE^1iE? QeJgœ)k'K3/ڤv6YZ5ݧ-37Y׿xqXj_i#Yu((sT|o†V[P~7_2*/uyY63 [YS6cÔ¨*M.Ź//^WKBGeF䴛<`ZK2%1W u)qխۮ4iG[:ٶܢ#6gymynpo&g<=VEaҮyb}ߞǏ|?/R5Yo|Z W2e>Ʋ/)[hlt6 }ܴ,+2녇ޞ]U8o'rqǣl-6yT Ѵ>ϡa׿>mbXZ:AAۆLyUl,Wݪ07WFu@t(}T۔;5ITgey\غ\pa\!З|Y&IsU |vʀoZ Jrԛ;'ʎ{=o̔|Z}B4rUoҐiׯW,Px%*7U|~|%HUkr&;R%xV J!2(AdUo &T󳼊@)IpUpcTcJxqY|uPխʪ[Pt9"!F% bdQEmX`)y-Iy\[&vt{Qk#H*$#[r2R(qbО 4!U6_[ܪ;\lvajs ɥ$c?E7J 0۞ ?MZl몽97\KpPZgwYԱI&60!gIR,(+jO`8eJSTtd X9 L$L*Hب!m_K*MmT 'jO9ax8\]*j!zVXRaپXbHHjW煹{e#? Tњ )~re )H_0cT3Í ~D1 ctHtH9*ĠLTp\$qyL,1 7cjH ~DbiX" Km'T`I -b.|'XAq‡!ɩ<D7HFcq~PGNy$Ɋ=YadV!}Hv?0sh+ NEr$V(#H.73$'YJ,2ԉ $u N 2$:kL`Kk($z0-@t%9ugC:)QFƌd" L;ҙ$w04)!l|(%ȉÂ| !_Sf_Ga6I)ᩜ;)%" 3Q GJ$I`({A%`Qs(Ο׌Ȝ՗)eg"Pq6\L y̹\9Rxnf[uXgÊpĜ˕21rLu$%&Hsbʽ)kbꚘr&<ϬN/&6e/?xZ#< "1GA8F(80?gBhyDˣ(DGAH*> endobj 2469 0 obj << /Type /ObjStm /N 83 /First 852 /Length 3119 /Filter /FlateDecode >> stream xڝ[MoW1IYE`@abO!dxӔC+Q5MV#lY,.7RzF^j/( Y᧺d[mI.Z-InF> I}4ѭ5~,7V]Jj>pYJ MR+ƳhmÇoHKOGRL`e>z]j*ۖZ Ԛ=nK>zP_]ץ쁯ii%'od*KӤޒTUMkV[xNFUnFW/ϥXvjʋIm*%Y̲x.}ȩ-=uХC#}󺌉A+-cUVoL ic*<_`1󫊻0؀uגY-[J2ӒRP/2_9py^cĔmsekrO 33.F)g,or2Ûtoʭux+kgk՛oyiǯNOw~;{K}xi7{[cO wxqm;pW2ɰ؅{%{^O#v+++1mK+0\xN7&It`--yt`n|= la0c.rFr2'+(d2\tAY3c7v!!*Gyq)v"vaLD4cN&ܹҞ`S]'Ilbt$sgK7;Qsry՗vsG0Kc8Z1'Ws*[%ƣ'I7&Id`8,`0;sx|gr= laFqi=`nl\S[)"Ilx~Chn ;MEq[f{ǮMroOr>h%NI24 ,@Pn&lȶfib"r!V9[LB6@0Is`+0+00<0otxvm;捖mU*sn9=݀9׹N$̕0o=0Հ8 ͶmhGh s. ;?̶C-Ps v1Wޮ@,j,)҅NИ(,טAcK{ ErC,jܺ~tIИ9\`9\`|: n?lp94B bQYs@,j!0 L^T)uCbpT\8*@BSDGZq2}e T [ 06t2 PJ)P:ßY KmfqY`gIi@^*1@^*b9 t* ĕvگgS4 @Ng+y$RI tRI`^Z^_'Il6a[y;91@'*1@'*q@'j~dȶfi8r;ap]'rЉF /ЉΒl$ K[iB^m[ap@(Zla00K^ PF-PV-RR&Il6a7 7 NR(E#(P69Bd49G;\4rR4lR4l(E$6;0I*(LV4h̩P&Kʛ4cN3iLF_JјIJAȕLЗ hLƜݤ@cZ /Ҙ!/sL@:ј:OfBn? / ҸB^gNtxHQDk[LE eJyٙq!/;ijNLЉ}' I~H̬=qX-^7Y(y57*d^ˍJQEBnTǽ~ܛ">^3Y34k~gtcOLo|zYY;(E݇d1oFFFm;{|>>? ?t@~/hhh4,6~tx's_}~<طEZdxшt6{4Ow;D)[c:zˇ_ELjgzd#av/ޞ?:;g' wt:;>ONG/gq9- FĘvל~?G #E)Nk4"ִOvXR$adZZ%|]9G9b΁o0VI"G%B.r JDQdC{ɡ7P"p%Cq72WY["l%eRϷ׫RY[K/ kSHo_F5D =<,6ۻq,w?᷈b9 _} } endstream endobj 2553 0 obj << /Type /XRef /Index [0 2554] /Size 2554 /W [1 3 1] /Root 2551 0 R /Info 2552 0 R /ID [ ] /Length 6057 /Filter /FlateDecode >> stream x%y$y>}|}>‘ Ip'-`SVB;2H I@L6jɂC@HDAD&R@}[U{4k6Fj44g53XGؙwm{9 -]bo4g@[k͙0K+0GK͹0O @sͅhdbk.%b Ği.ebqO5 bO4W*#b5Wb4:b5?b/hn|iMYl}-Ul=)&v!vEN%6-v[s7{&vKs/Ǻ gnhCbKŮk#bq41bW5 }bW4O)b5OKb4B./jب)vA3pQ,׌\ ?*v@,׌.vN,eMbg4kKS!jl0{S VЌy$],.S$b4#1uKI\,ftbq,':Ӹeyb4#$juḳZ _هMGbrc3b4uḳONWC} {4u,brr爅]:p|̓byEهĞ C}82m:pa1hW䭚:pX>8هou"6kubqaߡ>\/Rl>(M,b5m;%&N3Np88Ģcь GXBHj5*z@lX[!BS6 2.L2MY<0qK_`C;_p_md0 -m `6́0X`1, X)5@ tk9 /=C IeSm.xz2M]>6& [`+L6;`'ݰ> p18'$pB<\'sUqoML=XKLx 8p>uq.XY8ȒO (RW\J2=r Kd@ P;?9Ÿf?xh!R` R`9ǩ)@{e}Z Kl lyМwж85N"w-|j,Y{Y axLa,c[0>bĞc ;1|aKjd;vbкq><OөGS7tJy )Օ]ѝH߾'];TѤۆ sw]<lu7IlK|Wt]oU]λw9ryGb/8ݬt7S[c LwcAntcƁn3q鄓 ۍY1W@c܂өi.+@h]p $wIsG!@tAuߍca{;5+%]Lw]CO1ez)/n#1Gh{]?7#{DHOL]c$iFzH-+2|5@hwuE H #G(^$1GR`$Ffr~G2b$Fa$Fa٩n5rI~>9+cWrc$7F1qD(.ALp)iomIQLȫQL?bDHŻM-#G8W fxL<s-&3aVJ,n\a,/9;] K`)M01`G6F<毶n؜R);a}p\x?pCGS9~wN)8 g,p.?[\pǃp n OfJKb"/fBc0ocxRZ xd b~Lշ)l|y?&SߋXfo}V3R-}r/R/$@9緿8_t|D|3NKK^6-)[l)З]v }g~QƵ[;З #}bt7ޢ]3DVP5YNOmK_O#&s&?bҧ/}}Iӿ2/s2/KzaWr$R_" x/-wSwr/ҧ#vS/ŏMT~T4a2bm/4|Yqn|ь`Ի̔/ۘv &[U$Z'Nz 8qrj9lͰ0JX k`-`#l]0NLfS >8 )}wb/0p . :܀p"_{<9<3wnm>L#Z=vy5|2~|WJӛ|cVtKGt&S":m;3R=  ґБ* -:K%mEGZtKg5DaNnt'7:]le-Ű~JZt@'iR5ݶuM;twyW?-LBw8;G]DWC^g,K߉9 2s0ݑi?}' s۹ q@qFvHð0?wcW$wE)| vXP;l淼Tx[QA6So~&bnKIRm)߶o[ØʎWBf[j-ٖgk45߈qڊr"k+J(F-UT5VHUF[Sʨg+j*OoaKY5<-ʙĘZVI % ?R`l)+[-0Ibc3y0 -UZ`K-Rk)Z8;;2Є ̀6̄Y0¼ۮfFs,% *X # kR7ielͰlbƧS'5c/CpQ8'$[ө9B p || >o$6 4U(>(>x;"?WI%2 XS0XL^G$ \\@F @騠X \\\\\RX PF @Z{`/ZV V V V V Vc@mAmAm!7@rAr"VZZZX*PZZZZZH R(C````xRx/%yyPEgM0 2[i Z͂0g&3SIl!,`r/S_ȖEڗg@.xަH3?l3e[\_ g;`'әkW̭93!8 'lf/;'ov Ueg,`73e>3)Oe2"2su>"3n0t˼f*GT~G`X=/TY,0 (e``f(g웰oWWWWWWWWWWWWWWWWWWWWWWWWWWW*ZejYjU2U_aeXԎO1fffff55555u ٯٯٯٯٯٯٯٯٯٯٯٯٯٯٯٯc~o:~~~w1s~~~~~~~~~~(kkkkkkkkkkkk:M̙n5gi+3_:Qv|cQwxq|{~o}it|ڟ&z﬋Ot(M|_ŧ)[!v$ewњt,e^ŧ)t"eSd\t*MYc|ߏC3_~x=㯜'vc|c?id8AH_{/6m>`b>,gB,1|/$VWI a,%`q_ngY-̭Dͭͭ:1_V[| - wun4; 7 Vu斷jZܒܚ4k,0 8 NWXv[[Ϛ߂`hn-b~uùuծ5ֹuS42V+VoAFW,/////////////////////////////////////////////////////////////////////////////////_;6?3* endstream endobj startxref 378485 %%EOF GGally/build/stage23.rdb0000644000176200001440000002173614562736305014515 0ustar liggesusers]vȖvkBN$؄Ф @BNwb+2aC<{^b~<ļ5pzjK,%$+gMU`{޻v*姁T*Nuuwy;IxgvR IϕbȖRv$C?<**KRA*%)բJrJulv,({zzi e1Lٟ4\˾j #RysnJ^/GwWbz~o {o \2F_krڭ?-WW>RX F郂_sUCgFnO aŜ.oqAknVn*Wnnsj[)d粦9BA{CMpZOp7du!$F)8 kebɖW$"m2Ve0wlVNCd,ldCk8DS&qnf ޯn~#^|vo;˗mp` C=(.A )Ɨk϶8ZL B9D ,zXNX-C= in؃p X=A'obCAt{Œ#IBK>#3H7 W1WM|`;ZlY֩~ ȞzQwYۉ3k,e䊈\~"K/O4ݺ- 9籙k?DJ.U"}xcTK /I>RC"l8ݛO֟C`(Pv:nT!Jx|Il3-jˊU ;#G"m0')gC 1 D%P~Er4FvWA& q\;>&R՛jV{# QUT[@ P-֘L\΀iC&v_gA϶!] o| "79DIZ3Ѐi}nR:lh8H+DTZg@Ț ۨ9,o`stDNI!MtJ%BlAkkݪE@O%cFjCS_h%RM >LzOy+Q8A y1*fwbb (mLZUn| â΍/u/41,S:()"Y%}Y)jJ%>cs{Ðv&ǁoAm_gnJˉ;Q~ yy݋\o!|}1Y/Ͼx^~b{'SPbh'c&ݞ>ތdsB&k4%qe1x5=ؿMcEz8z>8z3g'y+,;$ 5בezh;N^(ק5f02M*3Yl*3)G?=ÙG-8$Z$kDOWJ .FU*&@o o%MR D)vt8~ ͼc^}OzRq$ժ[!a]$:ɹj=]Wz0fW5Upl{fcuKK,jr^5àszlu,\h;ࢹuלcv׼u\4^[}0B_md?nJxaq\[ަr+5=jr۰ iQcp1mtmqYHIn;aqāmmu@GzcKю^ȔM_ɄrBQqU+geIz8'"<{sNb;0>rg"˿"@EMF*DQX}!|WX32=kYyWeeh&+ZYgL[*ܚU3Zwr7^@tb+£U$t%˪K)dyMF1'̙\T,fZ9dqTo Z}3VrJYs?F?5/%I֬?rrDڻYsKqv~(!h(բlb_n7c־4m@O4>,^@(v07ta$6\+(T[^Rt/!}jR`"3;s?z.=iQ++N`zG9 ƒ&92] TVhjTȹ(H3uOR&9܇y-nt#=[9qGۉ"#tMGtXj $e x$jlDm<'^˜wKKbue˒ΆW2&8=-Krhe9eAI^Jʽ'o6j{0^ }ѤIM(C>TcE"h3EW\t+r25˂BrD*grEѲ r $,U٣ RFS%kW)Y?A߃~rLVfnlkʞn e| 'AOFrh2^q'.pWwYN+H__fZ}ɨRvK , Μ/zQ׿`cDnʲڡִk(1Ct⣈uyqNF5~Z\>Z(3It܉Gt[@??6{nʜwl*lLjYZ2EqE5kyU3C%V[k uܑ0} gAFCrGkGGfjӯ1]dUdQ/J8>lK 鈲u 4Mp'-tN/mP~S[߂[)D iYEpmw.{̆6A ]FpŽ3͓nEybjқj |/w:@%gAiǽ9 H -D#1|8}l.t+8tl X@n߃>8DIZ nV#bt\9릅;vmh=-l{S!o{Cj߷m*z@r@)WFROs(2>emOvJMFOY:?A\KGhAwuCۛܧ#O-ys^<bL~{d;C曚n)cGXk*Ϸ+P@4 3gZd*+VI/pGiGw~CVϮQ4pGVLٳV9e$[no֫s痰mg:սhUz|)y^hvkoWԿ=z7:*[^}ݯp12l˯zzꢔ#jާ5S.ʾ[ay oYM緎EvE92q_oD+MMnķZ57Pa>-kS|sph<w'Vs-]Vt3A27vfmq(6IɖqtаoLfc/]W*RbT9*^Kou-ɽZ)]1)M[Yx4̿9~OSۨ!7:\/j2qӷی̽O TSj A/Va?\ymY]{B瓻~;9ϴhC[&YE?PٮOe 2+I㺗l/̒_&P[oEW!-gUjp-H5;(yy-{א֑{Zᯠ-5շO6_llX.r&N`} L&=zXA W3L}5&KK-?=Q-+-gm+7?ǐu&%\[a:R3Qv>"VCQw~(^{\ZZ)w}^QoO"ƁSK"v@  9s{L5nj2gxB6bEPhX !']$^@J#qpQi;#kZ&lO=̕ lwϥZ΃tDP*M5IU\N9"WA 7-J?7˲ԒޥS,2!A?L>>%HgLE($<7v0ZiSuޅkJ/&ǀ#\;$QŽ8 $uGS^Bȟ¹(\nI%ŰttoEnb)i،Tq[olBwcV^Nq6//?>gI^|i33zx3l=*C;97I2#9 >jGF9\SX(q^oWnHÉQ4/$=\>z#gI7V" .A v,i:XppڈHdFy,?nGyMR]}ŰKX`$;-4w{[> A ;5 i>x| a6lzE )N*lw٫Y"Ko/$(Cb=0}#%ʡ|˙"& nl&dX2L̬ݖ/ALnkגO+Q +cAm<հ2?TX!F b/V*bбtIGKjh?j RՂRJҪ/Iy%bn6FTlld)c5t8nR,(.߯2KzM+O|PVtu;cqZ_@q=X>!J'/Ρ*S%xkϟ5šFTgSgE5NC`7v8=L%i1"qKw(VV6=Qh/5/Ȭ3}"LBxN@jg]7lLnhL߀(m6-R"Bc ̃'cBv =" ` t)BEl F26Q&hGm6Z{%b_%i1^9ƒ$L9"a}q|(Pa*1YG`{'Qրމ3SI7-bbIw;`Po$ "$JdlRIGm6h8DMڶGRQ;H* iQBWTqWٗylɒ=4cH$؉0ڑx!AoB0 :d7:EMgJ89OMM|]ԩ6xb|&wpEP+:'9bfY}ڋPwoW7_<\4 L()FJy5J'ֻJV96AFv+2!R]k4~[vmFfk}blX*3g[Rm?PAG$[*2g+(j9\dZ*'/OKT_`f^WKyM4lj6qH{I{-' =`YJŹaWEJL4JL\PMSU*BBOxo)a&tVO>qVr$ѵ&M%W.`=K2%ΦjZ,8H!ev! nl+`He3B/ m=s#۲,'`/A PLA7&p fx߁{Nni=ϠMzPB{Md`t/=/=B/"1`t96-p7]~Sz="OsG%%Z&e#Xg,jI KQ'@ Vt]}LKt&H}-X7!l(̉g섷&]wUDDq(.A^yH8j -k}/ .{k= (R͞za,y 2rQ%qk.XsrZӞ\)jJކ\28ٶNwBr:qrl\X8 &i:Uo\n{ƽ.c̸iL=mm,o4c1waY}a񞚷WZ;] qdu9qV._'nev1vY"$!yk 0$0# ]ǐSǝXZF8z*wm9fغg[{Lm95YlEJB6&͈8xtN"Aޠ0y&~!] -3H,VEfeMgn܄}^!(!7(tfzZ*i_SR)R?6?@8 LdAIeyT~o *i*׬j͢WDT5ThB/c$$4%˶[9UMw۫Xzا9DӀQH ~Q7wTcdC֤ ղ 3IVE~ƱqEb GGally/tests/0000755000176200001440000000000014527265752012612 5ustar liggesusersGGally/tests/spelling.R0000644000176200001440000000044514527265752014555 0ustar liggesusers# `devtools::spell_check()` # only check spelling if on CI and spelling is available if (requireNamespace("spelling", quietly = TRUE)) { if (isTRUE(as.logical(Sys.getenv("CI")))) { spelling::spell_check_test( vignettes = TRUE, error = FALSE, skip_on_cran = TRUE ) } } GGally/tests/testthat/0000755000176200001440000000000014563007414014437 5ustar liggesusersGGally/tests/testthat/test-ggmatrix_add.R0000644000176200001440000000255214562447013020177 0ustar liggesusers data(tips) test_that("add", { pm <- ggpairs(tips) expect_true(is.null(pm$title)) expect_true(is.null(pm$xlab)) expect_true(is.null(pm$ylab)) pm1 <- pm + labs(title = "my title", x = "x label", y = "y label") expect_equal(pm1$title, "my title") expect_equal(pm1$xlab, "x label") expect_equal(pm1$ylab, "y label") expect_true(is.null(pm$gg)) # first add pm2 <- pm + ggplot2::theme_bw() expect_true(!is.null(pm2$gg)) # second to nth add pm3 <- pm + ggplot2::theme_bw() expect_true(!is.null(pm3$gg)) # bad add expect_error(pm + 3, "'ggmatrix' does not know how to add") # adding scale pm4 <- pm + ggplot2::scale_fill_brewer() expect_false(identical(pm$plots[[1]], pm4$plots[[1]])) expect_false(identical(pm$plots[[2]], pm4$plots[[2]])) # change only some subplots pm5 <- add_to_ggmatrix(pm, ggplot2::coord_equal(), cols = 1) expect_false(identical(pm$plots[[1]], pm5$plots[[1]])) expect_true(identical(pm$plots[[2]], pm5$plots[[2]])) }) test_that("add_list", { pm <- ggpairs(tips, 1:2) pm1 <- pm + list( ggplot2::labs(x = "x title"), ggplot2::labs(title = "list title") ) expect_equal(pm1$xlab, "x title") expect_equal(pm1$title, "list title") }) test_that("v1_ggmatrix_theme", { pm <- ggpairs(tips, 1:2) pm1 <- pm + v1_ggmatrix_theme() expect_true(is.null(pm$gg)) expect_true(!is.null(pm1$gg)) }) GGally/tests/testthat/test-wrap.R0000644000176200001440000000211614562447013016512 0ustar liggesusers test_that("errors", { fn <- ggally_points # named params expect_error(wrap(fn, NA), "all parameters") expect_error(wrap(fn, y = TRUE, 5), "all parameters") # named params to wrapp expect_error(wrapp(fn, list(5)), "'params' must") expect_error(wrapp(fn, table(1:10, 1:10)), "'params' must") expect_error(wrapp(fn, list(A = 4, 5)), "'params' must") # if the character fn doesn't exist expect_error(wrap("does not exist", A = 5), "Function provided") expect_error(wrapp("does not exist", list(A = 5)), "Function provided") }) test_that("wrap", { (regularPlot <- ggally_points( iris, ggplot2::aes(Sepal.Length, Sepal.Width), size = 5, color = "red" )) # Wrap ggally_points to have parameter values size = 5 and color = 'red' w_ggally_points <- wrap(ggally_points, size = 5, color = "red") (wrappedPlot <- w_ggally_points( iris, ggplot2::aes(Sepal.Length, Sepal.Width) )) # Double check the aes parameters are the same for the geom_point layer expect_true(identical(regularPlot$layers[[1]]$aes_params, wrappedPlot$layers[[1]]$aes_params)) }) GGally/tests/testthat/test-ggmatrix_getput.R0000644000176200001440000000234014562447013020752 0ustar liggesusers data(tips) test_that("stops", { pm <- ggpairs(tips) p <- ggally_blankDiag() expect_error(pm["total_bill", 1], "'i' may only be a single") expect_error(pm[1, "total_bill"], "'j' may only be a single") expect_error(pm["total_bill", 1] <- p, "'i' may only be a single") expect_error(pm[1, "total_bill"] <- p, "'j' may only be a single") pm <- ggduo(tips, 1:3, 1:4) expect_error(pm[0, 1], "'i' may only be in the range") expect_error(pm[1, 0], "'j' may only be in the range") expect_error(pm[5, 1], "'i' may only be in the range") expect_error(pm[1, 4], "'j' may only be in the range") for (i in 1:4) { for (j in 1:3) { expect_silent({ p <- pm[i, j] }) } } }) test_that("get", { a <- ggpairs( tips, 1:4, axisLabels = "show" ) p <- a[2, 1] expect_equal(p$labels$x, "total_bill") expect_equal(p$labels$y, "tip") # test odd input and retrieve it a[2, 1] <- 1:4 expect_error( { a[2, 1] }, "unknown plot object type" ) # nolint }) test_that("put", { a <- ggpairs( tips, 1:4, axisLabels = "show" ) txt <- "My Custom Plot" a[2, 1] <- ggally_text(txt) p <- a[2, 1] expect_equal(get("aes_params", envir = p$layers[[1]])$label, txt) }) GGally/tests/testthat/test-ggally_trends.R0000644000176200001440000000617314562447013020406 0ustar liggesusers test_that("example", { data(tips) vdiffr::expect_doppelganger( "point", ggplot(tips) + aes(x = day, y = total_bill) + geom_point() ) vdiffr::expect_doppelganger( "geom-default", ggplot(tips) + aes(x = day, y = total_bill) + stat_weighted_mean() ) vdiffr::expect_doppelganger( "geom-line", ggplot(tips) + aes(x = day, y = total_bill, group = 1) + stat_weighted_mean(geom = "line") ) vdiffr::expect_doppelganger( "geom-line-grouped", ggplot(tips) + aes(x = day, y = total_bill, colour = sex, group = sex) + stat_weighted_mean(geom = "line") ) vdiffr::expect_doppelganger( "geom-bar-dodge", ggplot(tips) + aes(x = day, y = total_bill, fill = sex) + stat_weighted_mean(geom = "bar", position = "dodge") ) # computing a proportion on the fly vdiffr::expect_doppelganger( "geom-bar-dodge-percent", ggplot(tips) + aes(x = day, y = as.integer(smoker == "Yes"), fill = sex) + stat_weighted_mean(geom = "bar", position = "dodge") + scale_y_continuous(labels = scales::percent) ) # taking into account some weights d <- as.data.frame(Titanic) vdiffr::expect_doppelganger( "titanic", ggplot(d) + aes(x = Class, y = as.integer(Survived == "Yes"), weight = Freq, fill = Sex) + geom_bar(stat = "weighted_mean", position = "dodge") + scale_y_continuous(labels = scales::percent) + labs(y = "Survived") ) tips_f <- tips tips_f$day <- factor(tips$day, c("Thur", "Fri", "Sat", "Sun")) # Numeric variable vdiffr::expect_doppelganger( "trends", ggally_trends(tips_f, mapping = aes(x = day, y = total_bill)) ) vdiffr::expect_doppelganger( "trends-color", ggally_trends(tips_f, mapping = aes(x = day, y = total_bill, colour = time)) ) # Binary variable vdiffr::expect_doppelganger( "trends-binary", ggally_trends(tips_f, mapping = aes(x = day, y = smoker)) ) vdiffr::expect_doppelganger( "trends-binary-color", ggally_trends(tips_f, mapping = aes(x = day, y = smoker, colour = sex)) ) # Discrete variable with 3 or more categories vdiffr::expect_doppelganger( "trends-many", ggally_trends(tips_f, mapping = aes(x = smoker, y = day)) ) vdiffr::expect_doppelganger( "trends-many-color", ggally_trends(tips_f, mapping = aes(x = smoker, y = day, color = sex)) ) # Include zero on Y axis vdiffr::expect_doppelganger( "trends-incl-zero-false", ggally_trends(tips_f, mapping = aes(x = day, y = total_bill), include_zero = TRUE) ) vdiffr::expect_doppelganger( "trends-incl-zero-true", ggally_trends(tips_f, mapping = aes(x = day, y = smoker), include_zero = TRUE) ) # Change line size vdiffr::expect_doppelganger( "trends-size-3", ggally_trends(tips_f, mapping = aes(x = day, y = smoker, colour = sex), linewidth = 3) ) # Define weights with the appropriate aesthetic d <- as.data.frame(Titanic) vdiffr::expect_doppelganger( "trends-titanic", ggally_trends( d, mapping = aes(x = Class, y = Survived, weight = Freq, color = Sex), include_zero = TRUE ) ) }) GGally/tests/testthat/test-ggnet.R0000644000176200001440000001600314562447013016645 0ustar liggesusers if ("package:igraph" %in% search()) { detach("package:igraph") } rq(network) # network objects rq(sna) # placement and centrality rq(ggplot2) # grammar of graphics rq(grid) # arrows rq(scales) # sizing rq(intergraph) # test igraph conversion test_that("examples", { ### --- start: documented examples set.seed(54321) # random adjacency matrix x <- 10 ndyads <- x * (x - 1) density <- x / ndyads m <- matrix(0, nrow = x, ncol = x) dimnames(m) <- list(letters[1:x], letters[1:x]) m[row(m) != col(m)] <- runif(ndyads) < density m # random undirected network n <- network::network(m, directed = FALSE) n ggnet(n, label = TRUE, alpha = 1, color = "white", segment.color = "black") # random groups g <- sample(letters[1:3], 10, replace = TRUE) # color palette p <- c("a" = "steelblue", "b" = "forestgreen", "c" = "tomato") p <- ggnet(n, node.group = g, node.color = p, label = TRUE, color = "white") expect_equal(length(p$layers), 3) expect_true(!is.null(p$mapping$colour)) ### --- end: documented examples ### --- test deprecations # test mode = "geo" xy <- gplot.layout.circle(n) # nolint n %v% "lon" <- xy[, 1] n %v% "lat" <- xy[, 2] expect_warning(ggnet(n, mode = "geo"), "deprecated") # test names = c(x, y) expect_warning(ggnet(n, names = c("a", "b")), "deprecated") # test quantize.weights with_options(list(warn = 2), { expect_error(ggnet(n, quantize.weights = TRUE)) }) # test subset.threshold suppressMessages({ expect_warning(ggnet(n, subset.threshold = 2)) }) # test top8.nodes expect_warning(ggnet(n, top8.nodes = TRUE)) # test trim.labels expect_warning(ggnet(n, trim.labels = TRUE)) # # test subset.threshold by removing all nodes # expect_warning( # expect_error( # ggnet(n, subset.threshold = 11), # "NA/NaN/Inf" # ), # "NaNs produced" # ) # # p <- ggnet(n, mode = "geo") # expect_equal(p$data$X1, xy[, 1]) # expect_equal(p$data$X2, xy[, 2]) # test user-submitted weights ggnet(n, weight = sample(1:2, 10, replace = TRUE)) # test segment.label x <- sample(letters, network.edgecount(n)) p <- ggnet(n, segment.label = x) expect_true(mapping_string(p$layers[[2]]$mapping$x) == "midX") expect_true(mapping_string(p$layers[[2]]$mapping$y) == "midY") # test weight.cut n %v% "weights" <- 1:10 ggnet(n, weight.method = "weights", weight.cut = TRUE) ### --- test errors in set_node expect_error(ggnet(n, group = NA), "incorrect") expect_error(ggnet(n, group = 1:3), "incorrect") expect_error(ggnet(n, label = TRUE, label.size = -10:-1), "incorrect") expect_error(ggnet(n, size = "phono"), "incorrect") ggnet(n, group = "weights") ### --- test errors in set_edges expect_error(ggnet(n, segment.label = NA), "incorrect") expect_error(ggnet(n, segment.label = 1:3), "incorrect") expect_error(ggnet(n, segment.label = -11:-1), "incorrect") # unnecessary # expect_error(ggnet(n, size = "phono"), "incorrect") n %e% "weights" <- sample(1:2, network.edgecount(n), replace = TRUE) ggnet(n, segment.label = "weights") ggnet(n, segment.label = "a") ### --- test mode = c(x, y) ggnet(n, mode = matrix(1, ncol = 2, nrow = 10)) ggnet(n, mode = c("lon", "lat")) expect_error(ggnet(n, mode = c("xx", "yy")), "not found") n %v% "abc" <- "abc" expect_error(ggnet(n, mode = c("abc", "abc")), "not numeric") expect_error(ggnet(n, mode = matrix(1, ncol = 2, nrow = 9)), "coordinates length") ### --- test arrow.size expect_error(ggnet(n, arrow.size = -1), "incorrect arrow.size") expect_warning(ggnet(n, arrow.size = 1), "arrow.size ignored") ### --- test arrow.gap suppressWarnings(expect_error( ggnet(n, arrow.size = 12, arrow.gap = -1), "incorrect arrow.gap" )) suppressWarnings(expect_warning( ggnet(n, arrow.size = 12, arrow.gap = 0.1), "arrow.gap ignored" # network is undirected; arrow.gap ignored )) suppressWarnings(expect_warning( ggnet(n, arrow.size = 12, arrow.gap = 0.1), "arrow.size ignored" # network is undirected; arrow.size ignored )) m <- network::network(m, directed = TRUE) ggnet(m, arrow.size = 12, arrow.gap = 0.05) ### --- test degree centrality ggnet(n, weight = "degree") ### --- test weight.min, weight.max and weight.cut # test weight.min suppressMessages({ expect_error(ggnet(n, weight = "degree", weight.min = -1), "incorrect weight.min") expect_message(ggnet(n, weight = "degree", weight.min = 1), "weight.min removed") expect_warning(ggnet(n, weight = "degree", weight.min = 99), "removed all nodes") }) # test weight.max expect_error(ggnet(n, weight = "degree", weight.max = -1), "incorrect weight.max") expect_message(ggnet(n, weight = "degree", weight.max = 99), "weight.max removed") suppressMessages({ expect_warning(ggnet(n, weight = 1:10, weight.max = 0.5), "removed all nodes") }) expect_error(ggnet(n, weight = "abc"), "incorrect weight.method") # test weight.cut expect_error(ggnet(n, weight.cut = NA), "incorrect weight.cut") expect_error(ggnet(n, weight.cut = "a"), "incorrect weight.cut") expect_warning(ggnet(n, weight.cut = 3), "weight.cut ignored") ggnet(n, weight = "degree", weight.cut = 3) ### --- test node.group and node.color expect_warning(ggnet(n, group = 1:10, node.color = "blue"), "unequal length") ### --- test node labels and label sizes ggnet(n, label = letters[1:10], color = "white") ggnet(n, label = "abc", color = "white", label.size = 4, size = 12) expect_error(ggnet(n, label = letters[1:10], label.size = "abc"), "incorrect label.size") ### --- test node placement expect_error(ggnet(n, mode = "xyz"), "unsupported") expect_error(ggnet(n, mode = letters[1:3]), "incorrect mode") ### --- test label.trim expect_error(ggnet(n, label = TRUE, label.trim = "xyz"), "incorrect label.trim") ggnet(n, label = TRUE, color = "white", label.trim = 1) ggnet(n, label = TRUE, color = "white", label.trim = toupper) ### --- test layout.exp expect_error(ggnet(n, layout.exp = "xyz")) ggnet(n, layout.exp = 0.1) ### --- test bipartite functionality # weighted adjacency matrix bip <- data.frame( event1 = c(1, 2, 1), event2 = c(0, 0, 3), event3 = c(1, 1, 0), row.names = letters[1:3] ) # weighted bipartite network bip <- network( bip, matrix.type = "bipartite", ignore.eval = FALSE # names.eval = "weights" ) # test bipartite mode ggnet(bip, group = "mode") ### --- test network coercion expect_warning(ggnet(network(matrix(1, nrow = 2, ncol = 2), loops = TRUE)), "self-loops") expect_error(ggnet(1:2), "network object") expect_error(ggnet(network(data.frame(1:2, 3:4), hyper = TRUE)), "hyper") expect_error(ggnet(network(data.frame(1:2, 3:4), multiple = TRUE)), "multiplex graphs") ### --- test igraph functionality if (rq(igraph) && rq(intergraph)) { # test igraph conversion p <- ggnet(asIgraph(n)) expect_null(p$guides$colour) expect_equal(length(p$layers), 2) # test igraph degree ggnet(n, weight = "degree") expect_true(TRUE) } }) GGally/tests/testthat/test-ggally_cross.R0000644000176200001440000000561314562447013020236 0ustar liggesusers test_that("example", { # ggally_cross data(tips) # Custom fill vdiffr::expect_doppelganger("tips-fill-red", ggally_cross(tips, mapping = aes(x = smoker, y = sex), fill = "red")) # Custom shape vdiffr::expect_doppelganger("tips-shape", ggally_cross(tips, mapping = aes(x = smoker, y = sex), shape = 21)) # Fill squares according to standardized residuals d <- as.data.frame(Titanic) vdiffr::expect_doppelganger( "titanic-fill-steps2", ggally_cross( d, mapping = aes(x = Class, y = Survived, weight = Freq, fill = after_stat(std.resid)) ) + scale_fill_steps2(breaks = c(-3, -2, 2, 3), show.limits = TRUE) ) # Add labels vdiffr::expect_doppelganger( "tips-label", ggally_cross( tips, mapping = aes( x = smoker, y = sex, colour = smoker, label = scales::percent(after_stat(prop)) ) ) ) # Customize labels' appearance and same size for all squares vdiffr::expect_doppelganger( "tips-label-custom", ggally_cross( tips, mapping = aes( x = smoker, y = sex, size = NULL, # do not map size to a variable label = scales::percent(after_stat(prop)) ), size = 40, # fix value for points size fill = "darkblue", geom_text_args = list(colour = "white", fontface = "bold", size = 6) ) ) vdiffr::expect_doppelganger("tips-sex", ggally_cross(tips, mapping = aes(x = smoker, y = sex))) vdiffr::expect_doppelganger("tips-time", ggally_cross(tips, mapping = aes(x = day, y = time))) vdiffr::expect_doppelganger("tips-time-color", ggally_table(tips, mapping = aes(x = smoker, y = sex, colour = smoker))) # colour is kept only if equal to x or y vdiffr::expect_doppelganger("tips-color-equal", ggally_table(tips, mapping = aes(x = smoker, y = sex, colour = day))) # diagonal version vdiffr::expect_doppelganger("tips-diagonal", ggally_tableDiag(tips, mapping = aes(x = smoker))) # custom label size and color vdiffr::expect_doppelganger("tips-red-size16", ggally_table(tips, mapping = aes(x = smoker, y = sex), size = 16, color = "red")) # display column proportions vdiffr::expect_doppelganger("table-label", ggally_table( tips, mapping = aes(x = day, y = sex, label = scales::percent(after_stat(col.prop))) )) # draw table cells vdiffr::expect_doppelganger("table-color-fill", ggally_table( tips, mapping = aes(x = smoker, y = sex), geom_tile_args = list(colour = "black", fill = "white") )) # Use standardized residuals to fill table cells vdiffr::expect_doppelganger("table-fill-steps2", ggally_table( as.data.frame(Titanic), mapping = aes( x = Class, y = Survived, weight = Freq, fill = after_stat(std.resid), label = scales::percent(after_stat(col.prop), accuracy = .1) ), geom_tile_args = list(colour = "black") ) + scale_fill_steps2(breaks = c(-3, -2, 2, 3), show.limits = TRUE)) }) GGally/tests/testthat/data/0000755000176200001440000000000013663637143015360 5ustar liggesusersGGally/tests/testthat/data/airports.csv0000644000176200001440000010545013663637143017745 0ustar liggesusers"iata","airport","city","state","country","lat","long" "00M","Thigpen ","Bay Springs","MS","USA",31.95376472,-89.23450472 "00R","Livingston Municipal","Livingston","TX","USA",30.68586111,-95.01792778 "00V","Meadow Lake","Colorado Springs","CO","USA",38.94574889,-104.5698933 "01G","Perry-Warsaw","Perry","NY","USA",42.74134667,-78.05208056 "01J","Hilliard Airpark","Hilliard","FL","USA",30.6880125,-81.90594389 "01M","Tishomingo County","Belmont","MS","USA",34.49166667,-88.20111111 "02A","Gragg-Wade ","Clanton","AL","USA",32.85048667,-86.61145333 "02C","Capitol","Brookfield","WI","USA",43.08751,-88.17786917 "02G","Columbiana County","East Liverpool","OH","USA",40.67331278,-80.64140639 "03D","Memphis Memorial","Memphis","MO","USA",40.44725889,-92.22696056 "04M","Calhoun County","Pittsboro","MS","USA",33.93011222,-89.34285194 "04Y","Hawley Municipal","Hawley","MN","USA",46.88384889,-96.35089861 "05C","Griffith-Merrillville ","Griffith","IN","USA",41.51961917,-87.40109333 "05F","Gatesville - City/County","Gatesville","TX","USA",31.42127556,-97.79696778 "05U","Eureka","Eureka","NV","USA",39.60416667,-116.0050597 "06A","Moton Municipal","Tuskegee","AL","USA",32.46047167,-85.68003611 "06C","Schaumburg","Chicago/Schaumburg","IL","USA",41.98934083,-88.10124278 "06D","Rolla Municipal","Rolla","ND","USA",48.88434111,-99.62087694 "06M","Eupora Municipal","Eupora","MS","USA",33.53456583,-89.31256917 "06N","Randall ","Middletown","NY","USA",41.43156583,-74.39191722 "06U","Jackpot/Hayden ","Jackpot","NV","USA",41.97602222,-114.6580911 "07C","Dekalb County","Auburn","IN","USA",41.30716667,-85.06433333 "07F","Gladewater Municipal","Gladewater","TX","USA",32.52883861,-94.97174556 "07G","Fitch H Beach","Charlotte","MI","USA",42.57450861,-84.81143139 "07K","Central City Municipal","Central City","NE","USA",41.11668056,-98.05033639 "08A","Wetumpka Municipal","Wetumpka","AL","USA",32.52943944,-86.32822139 "08D","Stanley Municipal","Stanley","ND","USA",48.30079861,-102.4063514 "08K","Harvard State","Harvard","NE","USA",40.65138528,-98.07978667 "08M","Carthage-Leake County","Carthage","MS","USA",32.76124611,-89.53007139 "09A","Butler-Choctaw County","Butler","AL","USA",32.11931306,-88.1274625 "09J","Jekyll Island","Jekyll Island","GA","USA",31.07447222,-81.42777778 "09K","Sargent Municipal","Sargent","NE","USA",41.63695083,-99.34038139 "09M","Charleston Municipal","Charleston","MS","USA",33.99150222,-90.078145 "09W","South Capitol Street","Washington","DC","USA",38.86872333,-77.00747583 "0A3","Smithville Municipal","Smithville","TN","USA",35.98531194,-85.80931806 "0A8","Bibb County","Centreville","AL","USA",32.93679056,-87.08888306 "0A9","Elizabethton Municipal","Elizabethton","TN","USA",36.37094306,-82.17374111 "0AK","Pilot Station","Pilot Station","AK","USA",61.93396417,-162.8929358 "0B1","Col. Dyke ","Bethel","ME","USA",44.42506444,-70.80784778 "0B4","Hartington Municipal","Hartington","NE","USA",42.60355556,-97.25263889 "0B5","Turners Falls","Montague","MA","USA",42.59136361,-72.52275472 "0B7","Warren-Sugar Bush","Warren","VT","USA",44.11672722,-72.82705806 "0B8","Elizabeth ","Fishers Island","NY","USA",41.25130806,-72.03161139 "0C0","Dacy","Chicago/Harvard","IL","USA",42.40418556,-88.63343222 "0C4","Pender Municipal","Pender","NE","USA",42.11388722,-96.72892556 "0D1","South Haven Municipal","South Haven","MI","USA",42.35083333,-86.25613889 "0D8","Gettysburg Municipal","Gettysburg","SD","USA",44.98730556,-99.9535 "0E0","Moriarty","Moriarty","NM","USA",34.98560639,-106.0094661 "0E8","Crownpoint","Crownpoint","NM","USA",35.71765889,-108.2015961 "0F2","Bowie Municipal","Bowie","TX","USA",33.60166667,-97.77556 "0F4","Loup City Municipal","Loup City","NE","USA",41.29028694,-98.99064278 "0F7","Fountainhead Lodge Airpark","Eufaula","OK","USA",35.38898833,-95.60165111 "0F8","William R Pogue Municipal","Sand Springs","OK","USA",36.17528,-96.15181028 "0F9","Tishomingo Airpark","Tishomingo","OK","USA",34.19592833,-96.67555694 "0G0","North Buffalo Suburban","Lockport","NY","USA",43.10318389,-78.70334583 "0G3","Tecumseh Municipal","Tecumseh","NE","USA",40.39944417,-96.17139694 "0G6","Williams County","Bryan","OH","USA",41.46736111,-84.50655556 "0G7","Finger Lakes Regional","Seneca Falls","NY","USA",42.88062278,-76.78162028 "0H1","Trego Wakeeney ","Wakeeney","KS","USA",39.0044525,-99.89289917 "0I8","Cynthiana-Harrison County","Cynthiana","KY","USA",38.36674167,-84.28410056 "0J0","Abbeville Municipal","Abbeville","AL","USA",31.60016778,-85.23882222 "0J4","Florala Municipal","Florala","AL","USA",31.04247361,-86.31156111 "0J6","Headland Municipal","Headland","AL","USA",31.364895,-85.30965556 "0K7","Humboldt Municipal","Humboldt","IA","USA",42.7360825,-94.24524167 "0L5","Goldfield","Goldfield","NV","USA",37.71798833,-117.2384119 "0L7","Jean","Jean","NV","USA",35.76827222,-115.3296378 "0L9","Echo Bay","Overton","NV","USA",36.31108972,-114.4638672 "0M0","Dumas Municipal","Dumas","AR","USA",33.8845475,-91.53429111 "0M1","Scott ","Parsons","TN","USA",35.63778,-88.127995 "0M4","Benton County","Camden","TN","USA",36.01122694,-88.12328833 "0M5","Humphreys County","Waverly","TN","USA",36.11659972,-87.73815889 "0M6","Panola County","Batesville","MS","USA",34.36677444,-89.90008917 "0M8","Byerley","Lake Providence","LA","USA",32.82587917,-91.187665 "0O3","Calaveras Co-Maury Rasmussen ","San Andreas","CA","USA",38.14611639,-120.6481733 "0O4","Corning Municipal","Corning","CA","USA",39.94376806,-122.1713781 "0O5","University","Davis","CA","USA",38.53146222,-121.7864906 "0Q5","Shelter Cove","Shelter Cove","CA","USA",40.02764333,-124.0733639 "0Q6","Shingletown","Shingletown","CA","USA",40.52210111,-121.8177683 "0R0","Columbia-Marion County","Columbia","MS","USA",31.29700806,-89.81282944 "0R1","Atmore Municipal","Atmore","AL","USA",31.01621528,-87.44675972 "0R3","Abbeville Chris Crusta Memorial","Abbeville","LA","USA",29.97576083,-92.08415167 "0R4","Concordia Parish","Vidalia","LA","USA",31.56683278,-91.50011889 "0R5","David G Joyce","Winnfield","LA","USA",31.96366222,-92.66026056 "0R7","Red River","Coushatta","LA","USA",31.99071694,-93.30739306 "0S7","Dorothy Scott","Oroville","WA","USA",48.958965,-119.4119622 "0S9","Jefferson County International","Port Townsend","WA","USA",48.04981361,-122.8012792 "0V2","Harriet Alexander ","Salida","CO","USA",38.53916389,-106.0458483 "0V3","Pioneer Village ","Minden","NE","USA",40.5149125,-98.94565083 "0V4","Brookneal/Campbell County","Brookneal","VA","USA",37.14172222,-79.01638889 "0V6","Mission Sioux","Mission","SD","USA",43.30694778,-100.6281936 "0V7","Kayenta","Kayenta","AZ","USA",36.70972139,-110.2367978 "10C","Galt","Chicago/Greenwood/Wonderlake","IL","USA",42.40266472,-88.37588917 "10D","Winsted Municipal","Winsted","MN","USA",44.94996278,-94.0669175 "10G","Holmes County","Millersburg","OH","USA",40.53716667,-81.95436111 "10N","Wallkill","Wallkill","NY","USA",41.62787111,-74.13375583 "10U","Owyhee","Owyhee","NV","USA",41.95323306,-116.1876014 "11A","Clayton Municipal","Clayton","AL","USA",31.88329917,-85.48491361 "11D","Clarion Cty","Clarion","PA","USA",41.22581222,-79.44098972 "11IS","Schaumburg Heliport","Chicago/Schaumburg","IL","USA",42.04808278,-88.05257194 "11J","Early County","Blakely","GA","USA",31.39698611,-84.89525694 "11R","Brenham Municipal","Brenham","TX","USA",30.219,-96.37427778 "12C","Rochelle Municipal","Rochelle","IL","USA",41.89300139,-89.07829 "12D","Tower Municipal","Tower","MN","USA",47.81833333,-92.29166667 "12J","Brewton Municipal","Brewton","AL","USA",31.05126306,-87.06796833 "12K","Superior Municipal","Superior","NE","USA",40.04636111,-98.06011111 "12Y","Le Sueur Municipal","Le Sueur","MN","USA",44.43746472,-93.91274083 "13C","Lakeview","Lakeview","MI","USA",43.45213722,-85.26480333 "13K","Eureka Municipal","Eureka","KS","USA",37.8515825,-96.29169806 "13N","Trinca","Andover","NJ","USA",40.96676444,-74.78016556 "14J","Carl Folsom","Elba","AL","USA",31.40988861,-86.08883583 "14M","Hollandale Municipal","Hollandale","MS","USA",33.18262167,-90.83065444 "14Y","Todd Field ","Long Prairie","MN","USA",45.89857556,-94.87391 "15F","Haskell Municipal","Haskell","TX","USA",33.19155556,-99.71793056 "15J","Cook County","Adel","GA","USA",31.13780556,-83.45308333 "15M","Luka ","Luka","MS","USA",34.7723125,-88.16587444 "15Z","McCarthy 2","McCarthy","AK","USA",61.43706083,-142.9037372 "16A","Nunapitchuk","Nunapitchuk","AK","USA",60.90582833,-162.4391158 "16G","Seneca County","Tiffin","OH","USA",41.09405556,-83.2125 "16J","Dawson Municipal","Dawson","GA","USA",31.74328472,-84.419285 "16S","Myrtle Creek Municipal","Myrtle Creek","OR","USA",42.99845056,-123.3095092 "17G","Port Bucyrus-Crawford County","Bucyrus","OH","USA",40.78141667,-82.97469444 "17J","Donalsonville Municipal","Donalsonville","GA","USA",31.00694444,-84.87761111 "17K","Boise City","Boise City","OK","USA",36.77430028,-102.5104364 "17M","Magee Municipal","Magee","MS","USA",31.86127139,-89.80285361 "17N","Cross Keys","Cross Keys","NJ","USA",39.70547583,-75.03300306 "17Z","Manokotak","Manokotak","AK","USA",58.98896583,-159.0499739 "18A","Franklin County","Canon","GA","USA",34.34010472,-83.13348333 "18I","McCreary County ","Pine Knot","KY","USA",36.69591306,-84.39160389 "19A","Jackson County","Jefferson","GA","USA",34.17402472,-83.56066528 "19M","C A Moore","Lexington","MS","USA",33.12546111,-90.02555694 "19N","Camden","Berlin","NJ","USA",39.77842056,-74.94780389 "19P","Port Protection SPB","Port Protection","AK","USA",56.32880417,-133.6100844 "1A3","Martin Campbell ","Copperhill","TN","USA",35.01619111,-84.34631083 "1A5","Macon County","Franklin","NC","USA",35.222595,-83.41904389 "1A6","Middlesboro-Bell County","Middlesboro","KY","USA",36.6106375,-83.73741611 "1A7","Jackson County","Gainesboro","TN","USA",36.39728139,-85.64164278 "1A9","Autauga County","Prattville","AL","USA",32.438775,-86.51044778 "1B0","Dexter Regional","Dexter","ME","USA",45.00839444,-69.23976722 "1B1","Columbia Cty","Hudson","NY","USA",42.29130028,-73.71031944 "1B3","Fair Haven","Fair Haven","VT","USA",43.61534389,-73.27455556 "1B9","Mansfield Municipal","Mansfield","MA","USA",42.00013306,-71.19677139 "1C5","Clow","Chicago/Plainfield","IL","USA",41.69597444,-88.12923056 "1D1","Milbank Municipal","Milbank","SD","USA",45.23053806,-96.56596556 "1D2","Canton -Plymouth - Mettetal","Plymouth","MI","USA",42.35003667,-83.45826833 "1D3","Platte Municipal","Platte","SD","USA",43.40332833,-98.82952972 "1D6","Hector Municipal","Hector","MN","USA",44.73107278,-94.71471333 "1D7","Webster Municipal","Webster","SD","USA",45.29329111,-97.51369889 "1D8","Redfield Municipal","Redfield","SD","USA",44.86247611,-98.52953972 "1F0","Downtown Ardmore","Ardmore","OK","USA",34.14698917,-97.12265194 "1F1","Lake Murray State Park","Overbrook","OK","USA",34.07509694,-97.10667917 "1F4","Madill Municipal","Madill","OK","USA",34.14040194,-96.81203222 "1F9","Bridgeport Municipal","Bridgeport","TX","USA",33.17533333,-97.82838889 "1G0","Wood County","Bowling Green","OH","USA",41.391,-83.63013889 "1G3","Kent State University","Kent","OH","USA",41.15186167,-81.41658306 "1G4","Grand Canyon West","Peach Springs","AZ","USA",35.99221,-113.8166164 "1G5","Freedom ","Medina","OH","USA",41.13144444,-81.76491667 "1G6","Michael ","Cicero","NY","USA",43.18166667,-76.12777778 "1H0","Creve Coeur","St Louis","MO","USA",38.72752,-90.50830417 "1H2","Effingham County Memorial","Effingham","IL","USA",39.07045083,-88.53351972 "1H3","Linn State Tech. College","Linn","MO","USA",38.47149444,-91.81531667 "1H8","Casey Municipal","Casey","IL","USA",39.30250917,-88.00406194 "1I5","Freehold","Freehold","NY","USA",42.36425,-74.06596806 "1I9","Delphi Municipal","Delphi","IN","USA",40.54281417,-86.68167194 "1J0","Tri-County","Bonifay","FL","USA",30.84577778,-85.60138889 "1K2","Lindsay Municipal","Lindsay","OK","USA",34.85007333,-97.58642028 "1K4","David J. Perry","Goldsby","OK","USA",35.1550675,-97.47039389 "1K5","Waynoka Municipal","Waynoka","OK","USA",36.56670028,-98.85231333 "1K9","Satanta Municipal","Satanta","KS","USA",37.45419111,-100.9921119 "1L0","St. John the Baptist Parish","Reserve","LA","USA",30.08720833,-90.58266528 "1L1","Lincoln Co","Panaca","NV","USA",37.78746444,-114.4216567 "1L7","Escalante Municipal","Escalante","UT","USA",37.74532639,-111.5701653 "1L9","Parowan","Parowan","UT","USA",37.85969694,-112.816055 "1M1","North Little Rock Municipal","No Lit Rock","AR","USA",34.83398056,-92.25792778 "1M2","Belzoni Municipal","Belzoni","MS","USA",33.14518056,-90.51528472 "1M4","Posey ","Haleyville","AL","USA",34.28034806,-87.60044139 "1M5","Portland Municipal","Portland","TN","USA",36.59287528,-86.47691028 "1M7","Fulton","Fulton","KY","USA",36.52589417,-88.91561611 "1MO","Mountain Grove Memorial","Mountain Grove","MO","USA",37.12071889,-92.311245 "1N2","Spadaro ","East Moriches","NY","USA",40.82787639,-72.74871083 "1N4","Woodbine Muni ","Woodbine","NJ","USA",39.21915,-74.794765 "1N7","Blairstown","Blairstown","NJ","USA",40.97114556,-74.99747556 "1N9","Allentown Queen City Muni","Allentown","PA","USA",40.57027778,-75.48830556 "1ND3","Hamry ","Kindred","ND","USA",46.6485775,-97.00564306 "1O1","Grandfield Municipal","Grandfield","OK","USA",34.23758944,-98.74200917 "1O2","Lampson ","Lakeport","CA","USA",38.99017472,-122.8997175 "1O3","Lodi","Lodi","CA","USA",38.20241667,-121.2684167 "1O4","Thomas Municipal","Thomas","OK","USA",35.73338222,-98.73063833 "1O6","Dunsmuir Municipal-Mott","Dunsmuir","CA","USA",41.26320889,-122.2719528 "1R1","Jena","Jena","LA","USA",31.671005,-92.15846722 "1R7","Brookhaven-Lincoln County","Brookhaven","MS","USA",31.6058475,-90.40931583 "1R8","Bay Minette Municipal","Bay Minette","AL","USA",30.87046278,-87.81738167 "1S0","Pierce County ","Puyallup","WA","USA",47.10391667,-122.2871944 "1S3","Tillitt ","Forsyth","MT","USA",46.27110639,-106.6239206 "1S5","Sunnyside Municipal","Sunnyside","WA","USA",46.32763139,-119.9705964 "1S6","Priest River Muni","Priest River","ID","USA",48.19018611,-116.9093644 "1U7","Bear Lake County","Paris","ID","USA",42.24714972,-111.33826 "1V0","Navajo State Park ","Navajo Dam","NM","USA",36.80833833,-107.6514444 "1V2","Grant County ","Hyannis","NE","USA",42.00942944,-101.7693439 "1V5","Boulder Muni","Boulder","CO","USA",40.03942972,-105.2258217 "1V6","Fremont County","Canon City","CO","USA",38.42838111,-105.1054994 "1V9","Blake ","Delta","CO","USA",38.78539722,-108.0636611 "20A","Robbins ","Oneonta","AL","USA",33.97231972,-86.37942722 "20M","Macon Municipal","Macon","MS","USA",33.13345889,-88.53559806 "20N","Kingston-Ulster","Kingston","NY","USA",41.9852525,-73.96409722 "20U","Beach","Beach","ND","USA",46.92362444,-103.9785389 "20V","McElroy Airfield","Kremmling","CO","USA",40.05367972,-106.3689467 "21D","Lake Elmo","St Paul","MN","USA",44.99748861,-92.85568111 "21F","Jacksboro Municipal","Jacksboro","TX","USA",33.228725,-98.14671083 "22B","Mountain Meadow Airstrip","Burlington","CT","USA",41.77287528,-73.01121667 "22I","Vinton County","McArthur","OH","USA",39.328125,-82.44182167 "22M","Pontotoc County","Pontotoc","MS","USA",34.27593833,-89.03839694 "22N","Carbon Cty-Jake Arner Memorial","Lehighton","PA","USA",40.80950889,-75.76149639 "23J","Herlong","Jacksonville","FL","USA",30.27778889,-81.80594722 "23M","Clarke County","Quitman","MS","USA",32.08487111,-88.73893389 "23N","Bayport Aerodrome","Bayport","NY","USA",40.75843139,-73.05372083 "23R","Devine Municipal","Devine","TX","USA",29.1384075,-98.94189028 "24A","Jackson County","Sylva","NC","USA",35.3168625,-83.20936806 "24J","Suwannee County","Live Oak","FL","USA",30.30105583,-83.02318778 "24N","Jicarilla Apache Nation","Dulce","NM","USA",36.828535,-106.8841914 "25J","Cuthbert-Randolph","Cuthbert","GA","USA",31.70016583,-84.82492194 "25M","Ripley ","Ripley","MS","USA",34.72226778,-89.01504944 "25R","International","Edinburg","TX","USA",26.44201083,-98.12945306 "26A","Ashland/Lineville","Ashland/Lineville","AL","USA",33.28761417,-85.80412861 "26N","Ocean City Muni cipal","Ocean City","NJ","USA",39.26347222,-74.60747222 "26R","Jackson County","Edna/Ganado","TX","USA",29.00101,-96.58194667 "26U","McDermitt State","McDermitt","OR","USA",42.00211083,-117.7231972 "27A","Elbert County-Patz ","Elberton","GA","USA",34.09519722,-82.81586417 "27D","Myers ","Canby","MN","USA",44.72801889,-96.26309972 "27J","Newberry Municipal","Newberry","SC","USA",34.30927778,-81.63972222 "27K","Georgetown-Scott County","Georgetown","KY","USA",38.23442528,-84.43468667 "28J","Kay Larkin","Palatka","FL","USA",29.65863889,-81.68855556 "29D","Grove City","Grove City","PA","USA",41.14597611,-80.16592194 "29G","Portage County","Ravenna","OH","USA",41.210195,-81.25163083 "29S","Gardiner","Gardiner","MT","USA",45.04993556,-110.7466008 "2A0","Mark Anton","Dayton","TN","USA",35.48624611,-84.93109722 "2A1","Jamestown Municipal","Jamestown","TN","USA",36.34970833,-84.94664472 "2A3","Larsen Bay","Larsen Bay","AK","USA",57.53510667,-153.9784169 "2A9","Kotlik","Kotlik","AK","USA",63.03116111,-163.5299278 "2AK","Lime Village","Lime Village","AK","USA",61.35848528,-155.4403508 "2B3","Parlin ","Newport","NH","USA",43.38812944,-72.18925417 "2B7","Pittsfield Municipal","Pittsfield","ME","USA",44.76852778,-69.37441667 "2B9","Post Mills","Post Mills","VT","USA",43.884235,-72.25370333 "2D1","Barber","Alliance","OH","USA",40.97089139,-81.09981889 "2D5","Oakes Municipal","Oakes","ND","USA",46.17301972,-98.07987556 "2F5","Lamesa Municipal","Lamesa","TX","USA",32.75627778,-101.9194722 "2F6","Skiatook Municipal","Skiatook","OK","USA",36.357035,-96.01138556 "2F7","Commerce Municipal","Commerce","TX","USA",33.29288889,-95.89641806 "2F8","Morehouse Memorial","Bastrop","LA","USA",32.75607944,-91.88057194 "2G2","Jefferson County Airpark","Steubenville","OH","USA",40.35944306,-80.70007806 "2G3","Connellsville","Connellsville","PA","USA",39.95893667,-79.65713306 "2G4","Garrett County","Oakland","MD","USA",39.58027778,-79.33941667 "2G9","Somerset County","Somerset","PA","USA",40.03911111,-79.01455556 "2H0","Shelby County","Shelbyville","IL","USA",39.41042861,-88.8454325 "2H2","Aurora Memorial Municipal","Aurora","MO","USA",36.96230778,-93.69531111 "2I0","Madisonville Municipal","Madisonville","KY","USA",37.35502778,-87.39963889 "2I5","Chanute","Rantoul","IL","USA",40.29355556,-88.14236111 "2IS","Airglades","Clewiston","FL","USA",26.74200972,-81.04978917 "2J2","Liberty County","Hinesville","GA","USA",31.78461111,-81.64116667 "2J3","Louisville Municipal","Louisville","GA","USA",32.98654083,-82.38568139 "2J5","Millen","Millen","GA","USA",32.89376972,-81.96511583 "2J9","Quincy Municipal","Quincy","FL","USA",30.59786111,-84.55741667 "2K3","Stanton County Municipal","Johnson","KS","USA",37.58271111,-101.73281 "2K4","Scott ","Mangum","OK","USA",34.89172583,-99.52675667 "2K5","Telida","Telida","AK","USA",63.39387278,-153.2689733 "2M0","Princeton-Caldwell County","Princeton","KY","USA",37.11560444,-87.85556944 "2M2","Lawrenceburg Municipal","Lawrenceburg","TN","USA",35.2343025,-87.25793222 "2M3","Sallisaw Municipal","Sallisaw","OK","USA",35.43816667,-94.80277778 "2M4","G. V. Montgomery","Forest","MS","USA",32.35347778,-89.48867944 "2M8","Charles W. Baker","Millington","TN","USA",35.27897583,-89.93147611 "2O1","Gansner ","Quincy","CA","USA",39.94378056,-120.9468983 "2O3","Angwin-Parrett ","Angwin","CA","USA",38.57851778,-122.4352572 "2O6","Chowchilla","Chowchilla","CA","USA",37.11244417,-120.2468406 "2O7","Independence","Independence","CA","USA",36.81382111,-118.2050956 "2O8","Hinton Municipal","Hinton","OK","USA",35.50592472,-98.34236111 "2P2","Washington Island","Washington Island","WI","USA",45.38620833,-86.92448056 "2Q3","Yolo Co-Davis/Woodland/Winters","Davis/Woodland/Winters","CA","USA",38.5790725,-121.8566322 "2R0","Waynesboro Municipal","Waynesboro","MS","USA",31.64599472,-88.63475667 "2R4","Peter Prince ","Milton","FL","USA",30.63762083,-86.99365278 "2R5","St Elmo","St Elmo","AL","USA",30.50190833,-88.27511667 "2R9","Karnes County","Kenedy","TX","USA",28.8250075,-97.86558333 "2S1","Vashon Municipal","Vashon","WA","USA",47.45815333,-122.4773506 "2S6","Sportsman Airpark","Newberg","OR","USA",45.29567333,-122.9553783 "2S7","Chiloquin State","Chiloquin","OR","USA",42.58319167,-121.8761261 "2S8","Wilbur","Wilbur","WA","USA",47.75320639,-118.7438936 "2T1","Muleshoe Municipal","Muleshoe","TX","USA",34.18513639,-102.6410981 "2V1","Stevens ","Pagosa Springs","CO","USA",37.277505,-107.0558742 "2V2","Vance Brand","Longmont","CO","USA",40.16367139,-105.1630369 "2V5","Wray Municipal","Wray","CO","USA",40.10032333,-102.24096 "2V6","Yuma Municipal","Yuma","CO","USA",40.10415306,-102.7129869 "2W5","Maryland","Indian Head","MD","USA",38.60053667,-77.07296917 "2W6","Captain Walter Francis Duke Regional ","Leonardtown","MD","USA",38.31536111,-76.55011111 "2Y3","Yakutat SPB","Yakutat","AK","USA",59.5624775,-139.7410994 "2Y4","Rockwell City Municipal","Rockwell City","IA","USA",42.38748056,-94.61803333 "31F","Gaines County","Seminole","TX","USA",32.67535389,-102.652685 "32M","Norfolk","Norfolk","MA","USA",42.12787528,-71.37033556 "32S","Stevensville","Stevensville","MT","USA",46.52511111,-114.0528056 "33J","Geneva Municipal","Geneva","AL","USA",31.05527778,-85.88033333 "33M","Water Valley ","Water Valley","MS","USA",34.16677639,-89.68619722 "33N","Delaware Airpark","Dover","DE","USA",39.21837556,-75.59642667 "33S","Pru ","Ritzville","WA","USA",47.12487194,-118.3927539 "34A","Laurens County","Laurens","SC","USA",34.50705556,-81.94719444 "35A","Union County, Troy Shelton ","Union","SC","USA",34.68680111,-81.64121167 "35D","Padgham ","Allegan","MI","USA",42.53098278,-85.82513556 "35S","Wasco State","Wasco","OR","USA",45.58944444,-120.6741667 "36K","Lakin","Lakin","KS","USA",37.96946389,-101.2554472 "36S","Happy Camp","Happy Camp","CA","USA",41.79067944,-123.3889444 "36U","Heber City Municipal/Russ McDonald ","Heber","UT","USA",40.48180556,-111.4288056 "37T","Calico Rock-Izard County","Calico Rock","AR","USA",36.16565278,-92.14523611 "37W","Harnett County","Erwin","NC","USA",35.37880028,-78.73362917 "38A","Shaktoolik","Shaktoolik","AK","USA",64.36263194,-161.2025369 "38S","Deer Lodge-City-County","Deer Lodge","MT","USA",46.38881583,-112.7669842 "38U","Wayne Wonderland","Loa","UT","USA",38.36247972,-111.5960164 "39N","Princeton","Princeton","NJ","USA",40.39834833,-74.65760361 "3A0","Grove Hill Municipal","Grove Hill","AL","USA",31.68932389,-87.7613875 "3A1","Folsom ","Cullman","AL","USA",34.26870833,-86.85833611 "3A2","New Tazewell Municipal","Tazewell","TN","USA",36.41008417,-83.55546167 "3A3","Anson County","Wadesboro","NC","USA",35.02397611,-80.08127333 "3AU","Augusta Municipal","Augusta","KS","USA",37.67162778,-97.07787222 "3B0","Southbridge Municipal","Southbridge","MA","USA",42.10092806,-72.03840833 "3B1","Greenville Municipal","Greenville","ME","USA",45.46302778,-69.55161111 "3B2","Marshfield","Marshfield","MA","USA",42.09824111,-70.67212083 "3B9","Chester","Chester","CT","USA",41.38390472,-72.50589444 "3BS","Jack Barstow","Midland","MI","USA",43.66291528,-84.261325 "3CK","Lake In The Hills","Lake In The Hills","IL","USA",42.20680306,-88.32304028 "3CM","James Clements Municipal","Bay City","MI","USA",43.54691667,-83.89550222 "3CU","Cable Union","Cable","WI","USA",46.19424889,-91.24640972 "3D2","Ephraim/Gibraltar","Ephraim","WI","USA",45.13535778,-87.18586556 "3D4","Frankfort Dow Memorial","Frankfort","MI","USA",44.62506389,-86.20061944 "3F3","De Soto Parish","Mansfield","LA","USA",32.07345972,-93.76551889 "3F4","Vivian","Vivian","LA","USA",32.86133333,-94.01015361 "3F7","Jones Memorial","Bristow","OK","USA",35.80685278,-96.42185556 "3FM","Fremont Municipal","Fremont","MI","USA",43.43890528,-85.99478 "3FU","Faulkton Municipal","Faulkton","SD","USA",45.03191861,-99.11566417 "3G3","Wadsworth Municipal","Wadsworth","OH","USA",41.00158222,-81.75513111 "3G4","Ashland County","Ashland","OH","USA",40.90297222,-82.25563889 "3G7","Williamson/Sodus","Williamson","NY","USA",43.23472222,-77.12097222 "3GM","Grand Haven Memorial Airpark","Grand Haven","MI","USA",43.03404639,-86.1981625 "3I2","Mason County","Point Pleasant","WV","USA",38.91463889,-82.09858333 "3I7","Phillipsburg","Phillipsburg","OH","USA",39.91344194,-84.40030889 "3J1","Ridgeland","Ridgeland","SC","USA",32.49268694,-80.99233028 "3J7","Greene County Airpark","Greensboro","GA","USA",33.59766667,-83.139 "3JC","Freeman ","Junction City","KS","USA",39.04327556,-96.84328694 "3K3","Syracuse-Hamilton County Municipal","Syracuse","KS","USA",37.99167972,-101.7462822 "3K6","St Louis-Metro East","Troy/Marine/St. Louis","IL","USA",38.73290861,-89.80656722 "3K7","Mark Hoard Memorial","Leoti","KS","USA",38.45696333,-101.3532161 "3LC","Logan County","Lincoln","IL","USA",40.15847222,-89.33497222 "3LF","Litchfield Municipal","Litchfield","IL","USA",39.16635306,-89.67489694 "3M7","Lafayette Municipal","Lafayette","TN","USA",36.518375,-86.05828083 "3M8","North Pickens ","Reform","AL","USA",33.38900611,-88.00557806 "3M9","Warren Municipal","Warren","AR","USA",33.56044333,-92.08538861 "3MY","Mt. Hawley Auxiliary","Peoria","IL","USA",40.79525917,-89.6134025 "3N6","Old Bridge","Old Bridge","NJ","USA",40.32988667,-74.34678694 "3N8","Mahnomen County ","Mahnomen","MN","USA",47.25996056,-95.92809778 "3ND0","Northwood Municipal","Northwood","ND","USA",47.72423333,-97.59042222 "3O1","Gustine","Gustine","CA","USA",37.26271722,-120.9632586 "3O3","Municipal","Purcell","OK","USA",34.97979444,-97.38586167 "3O4","Sayre Municipal","Sayre","OK","USA",35.16755222,-99.65787361 "3O5","Walters Municipal","Walters","OK","USA",34.37258444,-98.40588583 "3O7","Hollister Municipal","Hollister","CA","USA",36.89334528,-121.4102706 "3O9","Grand Lake Regional","Afton","OK","USA",36.5775775,-94.86190028 "3R0","Beeville Municipal","Beeville","TX","USA",28.36455528,-97.79208194 "3R1","Bay City Municipal","Bay City","TX","USA",28.973255,-95.86345528 "3R2","Le Gros Memorial","Crowley","LA","USA",30.16173611,-92.48396111 "3R4","Hart","Many","LA","USA",31.54489667,-93.48645306 "3R7","Jennings","Jennings","LA","USA",30.24269333,-92.67344778 "3S4","Illinois Valley","Illinois Valley (Cave Junction)","OR","USA",42.10372417,-123.6822911 "3S8","Grants Pass","Grants Pass","OR","USA",42.51011722,-123.3879894 "3S9","Condon State-Pauling ","Condon","OR","USA",45.24651889,-120.1664233 "3SG","Harry W Browne","Saginaw - H.Browne","MI","USA",43.43341028,-83.86245833 "3SQ","St Charles","St Charles","MO","USA",38.84866139,-90.50011833 "3T3","Boyceville Municipal ","Boyceville","WI","USA",45.042185,-92.0293475 "3T5","Fayette Regional Air Center","La Grange","TX","USA",29.90930556,-96.9505 "3TR","Jerry Tyler Memorial","Niles","MI","USA",41.83590806,-86.22517611 "3U3","Bowman ","Anaconda","MT","USA",46.15313278,-112.86784 "3U7","Benchmark","Benchmark","MT","USA",47.48133194,-112.8697678 "3U8","Big Sandy","Big Sandy","MT","USA",48.16247972,-110.1132631 "3V4","Fort Morgan Municipal","Fort Morgan","CO","USA",40.33423194,-103.8039508 "3WO","Shawano Municipal","Shawano","WI","USA",44.78777778,-88.56152444 "3Y2","George L Scott Municipal","West Union","IA","USA",42.98508917,-91.79060417 "3Y3","Winterset Madison County","Winterset","IA","USA",41.36276778,-94.02106194 "3Z9","Haines SPB","Haines","AK","USA",59.23495111,-135.4407181 "40J","Perry-Foley","Perry","FL","USA",30.06927778,-83.58058333 "40N","Chester Cty-G O Carlson","Coatesville","PA","USA",39.97897222,-75.86547222 "40U","Manila","Manila","UT","USA",40.98607,-109.6784811 "41U","Manti-Ephraim","Manti","UT","USA",39.32912833,-111.6146397 "42A","Melbourne Municipal","Melbourne","AR","USA",36.07079222,-91.82914667 "42C","White Cloud","White Cloud","MI","USA",43.55974139,-85.77421944 "42J","Keystone Airpark","Keystone Heights","FL","USA",29.84475,-82.04752778 "42S","Poplar","Poplar","MT","USA",48.11595861,-105.1821928 "43A","Montgomery County","Star","NC","USA",35.38819528,-79.79281667 "44B","Dover/Foxcroft","Dover-Foxcroft","ME","USA",45.18338806,-69.2328225 "44N","Sky Acres","Millbrook","NY","USA",41.70742861,-73.73802889 "45J","Rockingham-Hamlet","Rockingham","NC","USA",34.89107083,-79.75905806 "45OH","North Bass Island","North Bass Island","OH","USA",41.71932528,-82.82196917 "45R","Kountz - Hawthorne ","Kountze/Silsbee","TX","USA",30.33633806,-94.25754361 "46A","Blairsville","Blairsville","GA","USA",34.85508722,-83.996855 "46D","Carrington Municipal","Carrington","ND","USA",47.45111111,-99.15111111 "46N","Sky Park","Red Hook","NY","USA",41.98458333,-73.83596556 "47A","Cherokee County","Canton","GA","USA",34.31058333,-84.42391667 "47J","Cheraw Municipal","Cheraw","SC","USA",34.71258333,-79.95794444 "47N","Central Jersey Regional","Manville","NJ","USA",40.52438417,-74.59839194 "47V","Curtis Municipal","Curtis","NE","USA",40.63750778,-100.4712539 "48A","Cochran","Cochran","GA","USA",32.39936111,-83.27591667 "48D","Clare Municipal","Clare","MI","USA",43.83111111,-84.74133333 "48I","Braxton County","Sutton","WV","USA",38.68704444,-80.65176083 "48K","Ness City Municipal","Ness City","KS","USA",38.47110278,-99.90806667 "48S","Harlem","Harlem","MT","USA",48.56666472,-108.7729339 "48V","Tri-County","Erie","CO","USA",40.010225,-105.047975 "49A","Gilmer County","Ellijay","GA","USA",34.62786417,-84.52492889 "49T","Downtown Heliport","Dallas","TX","USA",32.77333333,-96.80027778 "49X","Chemehuevi Valley","Chemehuevi Valley","CA","USA",34.52751083,-114.4310697 "49Y","Fillmore County","Preston","MN","USA",43.67676,-92.17973444 "4A2","Atmautluak","Atmautluak","AK","USA",60.86674556,-162.2731389 "4A4","Cornelius-Moore ","Cedartown","GA","USA",34.01869444,-85.14647222 "4A5","Marshall-Searcy County","Marshall","AR","USA",35.89893667,-92.65588611 "4A6","Scottsboro Municipal","Scottsboro","AL","USA",34.68897278,-86.0058125 "4A7","Clayton County","Hampton","GA","USA",33.38911111,-84.33236111 "4A9","Isbell ","Fort Payne","AL","USA",34.4728925,-85.72221722 "4B0","South Albany","South Bethlehem","NY","USA",42.56072611,-73.83395639 "4B1","Duanesburg","Duanesburg","NY","USA",42.75840889,-74.13290472 "4B6","Ticonderoga Muni","Ticonderoga","NY","USA",43.87700278,-73.41317639 "4B7","Schroon Lake","Schroon Lake","NY","USA",43.86256083,-73.74262972 "4B8","Robertson ","Plainville","CT","USA",41.69037667,-72.8648225 "4B9","Simsbury Tri-Town","Simsbury","CT","USA",41.91676389,-72.77731778 "4C8","Albia Municipal","Albia","IA","USA",40.99445361,-92.76297194 "4D0","Abrams Municipal","Grandledge","MI","USA",42.77420167,-84.73309806 "4D9","Alma Municipal","Alma","NE","USA",40.11389972,-99.34565306 "4F2","Panola County-Sharpe ","Carthage","TX","USA",32.17608333,-94.29880556 "4F4","Gilmer-Upshur County","Gilmer","TX","USA",32.699,-94.94886111 "4G1","Greenville Muni","Greenville","PA","USA",41.44683167,-80.39126167 "4G2","Hamburg Inc.","Hamburg","NY","USA",42.7008925,-78.91475694 "4G5","Monroe County","Woodsfield","OH","USA",39.77904472,-81.10277222 "4G6","Hornell Muni","Hornell","NY","USA",42.38214444,-77.6821125 "4G7","Fairmont Muni","Fairmont","WV","USA",39.44816667,-80.16702778 "4I0","Mingo County","Williamson","WV","USA",37.68760139,-82.26097306 "4I3","Knox County","Mount Vernon","OH","USA",40.32872222,-82.52377778 "4I7","Putnam County","Greencastle","IN","USA",39.63359556,-86.8138325 "4I9","Morrow County","Mt. Gilead","OH","USA",40.52452778,-82.85005556 "4J1","Brantley County","Nahunta","GA","USA",31.21272417,-81.90539083 "4J2","Berrien County","Nashville","GA","USA",31.21255556,-83.22627778 "4J5","Quitman-Brooks County","Quitman","GA","USA",30.80575139,-83.58654889 "4J6","St Marys","St Marys","GA","USA",30.75468028,-81.55731917 "4K0","Pedro Bay","Pedro Bay","AK","USA",59.78960972,-154.1238331 "4K5","Ouzinkie","Ouzinkie","AK","USA",57.92287611,-152.5005111 "4K6","Bloomfield Municipal","Bloomfield","IA","USA",40.73210556,-92.42826889 "4KA","Tununak","Tununak","AK","USA",60.57559667,-165.2731272 "4M1","Carroll County","Berryville","AR","USA",36.38340333,-93.61685667 "4M3","Carlisle Municipal","Carlisle","AR","USA",34.80823,-91.71205083 "4M4","Clinton Municipal","Clinton","AR","USA",35.59785528,-92.45182472 "4M7","Russellville-Logan County","Russellville","KY","USA",36.79991667,-86.81016667 "4M8","Clarendon Municipal","Clarendon","AR","USA",34.64870694,-91.39457111 "4M9","Corning Municipal","Corning","AR","USA",36.40423139,-90.64792639 "4N1","Greenwood Lake","West Milford","NJ","USA",41.12854806,-74.34584611 "4O3","Blackwell-Tonkawa Municipal","Blackwell-Tonkawa","OK","USA",36.74511583,-97.34959972 "4O4","McCurtain County Regional","Idabel","OK","USA",33.909325,-94.85835278 "4O5","Cherokee Municipal","Cherokee","OK","USA",36.78336306,-98.35035083 "4PH","Polacca","Polacca","AZ","USA",35.79167222,-110.4234653 "4R1","I H Bass Jr Memorial","Lumberton","MS","USA",31.01546028,-89.48256556 "4R3","Jackson Municipal","Jackson","AL","USA",31.47210861,-87.89472083 "4R4","Fairhope Municipal","Fairhope","AL","USA",30.4621125,-87.87801972 "4R5","Madeline Island","La Pointe","WI","USA",46.78865556,-90.75866944 "4R7","Eunice","Eunice","LA","USA",30.46628389,-92.42379917 "4R9","Dauphin Island","Dauphin Island","AL","USA",30.26048083,-88.12749972 "4S1","Gold Beach Muni","Gold Beach","OR","USA",42.41344444,-124.4242742 "4S2","Hood River","Hood River","OR","USA",45.67261833,-121.5364625 "4S3","Joseph State","Joseph","OR","USA",45.35709583,-117.2532244 "4S9","Portland-Mulino","Mulino (Portland)","OR","USA",45.21632417,-122.5900839 "4SD","Reno/Stead","Reno","NV","USA",39.66738111,-119.8754169 "4T6","Mid-Way","Midlothian-Waxahachie","TX","USA",32.45609722,-96.91240972 "4U3","Liberty County","Chester","MT","USA",48.51072222,-110.9908639 "4U6","Circle Town County","Circle","MT","USA",47.41861972,-105.5619431 "4V0","Rangely","Rangely","CO","USA",40.09469917,-108.7612172 "4V1","Johnson ","Walsenburg","CO","USA",37.69640056,-104.7838747 "4V9","Antelope County","Neligh","NE","USA",42.11222889,-98.0386775 "4W1","Elizabethtown Municipal","Elizabethtown","NC","USA",34.60183722,-78.57973306 "4Z4","Holy Cross","Holy Cross","AK","USA",62.18829583,-159.7749503 "4Z7","Hyder SPB","Hyder","AK","USA",55.90331972,-130.0067031 "50I","Kentland Municipal","Kentland","IN","USA",40.75873222,-87.42821917 "50J","Berkeley County","Moncks Corner","SC","USA",33.18605556,-80.03563889 "50K","Pawnee City Municipal","Pawnee City","NE","USA",40.11611111,-96.19445278 "50R","Lockhart Municipal","Lockhart","TX","USA",29.85033333,-97.67241667 "51D","Edgeley Municipal ","Edgeley","ND","USA",46.34858333,-98.73555556 "51Z","Minto (New)","Minto","AK","USA",65.14370889,-149.3699647 "52A","Madison Municipal","Madison","GA","USA",33.61212528,-83.46044333 "52E","Timberon ","Timberon","NM","USA",32.63388889,-105.6863889 "52J","Lee County","Bishopville","SC","USA",34.24459889,-80.23729333 "53A","Dr. C.P. Savage, Sr.","Montezuma","GA","USA",32.302,-84.00747222 "53K","Osage City Municipal","Osage City","KS","USA",38.63334222,-95.80859806 "54J","Defuniak Springs","Defuniak Springs","FL","USA",30.7313,-86.15160833 "55D","Grayling Army Airfield","Grayling","MI","USA",44.68032028,-84.72886278 "55J","Fernandina Beach Municipal","Fernandina Beach","FL","USA",30.61170083,-81.462345 "55S","Packwood","Packwood","WA","USA",46.60400083,-121.6778664 "56D","Wyandot County","Upper Sandusky","OH","USA",40.88336139,-83.3145325 "56M","Warsaw Municipal","Warsaw","MO","USA",38.34688889,-93.345425 "56S","Seaside Municipal","Seaside","OR","USA",46.01649694,-123.9054167 "57B","Islesboro","Islesboro","ME","USA",44.30285556,-68.91058722 "57C","East Troy Municipal","East Troy","WI","USA",42.79711111,-88.3725 "59B","Newton ","Jackman","ME","USA",45.63199111,-70.24728944 "5A4","Okolona Mun.-Richard M. Stovall ","Okolona","MS","USA",34.01580528,-88.72618944 GGally/tests/testthat/test-ggtable.R0000644000176200001440000000235314562447013017151 0ustar liggesusers suppressMessages(require(broom)) test_that("example", { reg <- lm(Sepal.Length ~ Sepal.Width + Petal.Length + Petal.Width, data = iris) vdiffr::expect_doppelganger("lm", ggcoef(reg)) data(tips) vdiffr::expect_doppelganger("tips", ggtable(tips, "smoker", c("day", "time", "sex"))) # displaying row proportions vdiffr::expect_doppelganger("tips-cells", ggtable(tips, "smoker", c("day", "time", "sex"), cells = "row.prop")) # filling cells with residuals vdiffr::expect_doppelganger( "tips-fill-std_resid", ggtable(tips, "smoker", c("day", "time", "sex"), fill = "std.resid", legend = 1) ) vdiffr::expect_doppelganger( "tips-fill-resid", ggtable(tips, "smoker", c("day", "time", "sex"), fill = "resid", legend = 1) ) # if continuous variables are provided, just displaying some summary statistics vdiffr::expect_doppelganger( "tips-continuous", ggtable(tips, c("smoker", "total_bill"), c("day", "time", "sex", "tip")) ) # specifying weights d <- as.data.frame(Titanic) vdiffr::expect_doppelganger( "titanic-weight-freq", ggtable( d, "Survived", c("Class", "Sex", "Age"), mapping = aes(weight = Freq), cells = "row.prop", fill = "std.resid" ) ) }) GGally/tests/testthat/test-ggmatrix.R0000644000176200001440000001035714562447013017371 0ustar liggesusers data(tips) test_that("stops", { expect_error(ggmatrix(plots = matrix(), nrow = 2, ncol = 3), "'plots' must be a list()") expect_error(ggmatrix(plots = list(), nrow = "2", ncol = 3), "'nrow' must be a numeric value") expect_error(ggmatrix(plots = list(), nrow = 2, ncol = "3"), "'ncol' must be a numeric value") expect_error( ggmatrix(plots = list(), nrow = c(2, 3), ncol = 3), "'nrow' must be a single numeric value" ) expect_error( ggmatrix(plots = list(), nrow = 2, ncol = c(2, 3)), "'ncol' must be a single numeric value" ) }) test_that("expression labels", { chars <- c("col1", "col2") exprs <- c("alpha[0]", "gamma[x + y ^ z]") p <- ggpairs(tips, 1:2, columnLabels = exprs, labeller = "label_parsed") vdiffr::expect_doppelganger("expression-labels", p) expect_error(print(ggpairs(tips, 1:2, columnLabels = expression(alpha, beta))), "xAxisLabels") }) test_that("byrow", { plotList <- list() for (i in 1:6) { p <- ggally_text(paste("Plot #", i, sep = "")) p$ggally_check_val <- i plotList[[i]] <- p } a <- ggmatrix( plotList, 2, 3, c("A", "B", "C"), c("D", "E"), byrow = TRUE ) k <- 1 for (i in 1:2) { for (j in 1:3) { expect_equal(a[i, j]$ggally_check_val, k) k <- k + 1 } } a <- ggmatrix( plotList, 2, 3, c("A", "B", "C"), c("D", "E"), byrow = FALSE ) k <- 1 for (j in 1:3) { for (i in 1:2) { expect_equal(a[i, j]$ggally_check_val, k) k <- k + 1 } } a }) test_that("missing plot", { plotList <- list() for (i in c(1, 3, 5)) { p <- ggally_text(paste("Plot #", i, sep = "")) p$ggally_check_val <- i plotList[[i]] <- p } a <- ggmatrix( plotList, 2, 3, c("A", "B", "C"), c("D", "E"), byrow = TRUE ) # reaches code where there are more cells than plots vdiffr::expect_doppelganger("not-enough-plots", a) expect_equal(a[1, 1]$ggally_check_val, 1) expect_equal(a[1, 3]$ggally_check_val, 3) expect_equal(a[2, 2]$ggally_check_val, 5) }) test_that("str.ggmatrix", { pm <- ggpairs(tips, 1:3, upper = "blank") pm[1, 1] <- pm[1, 1] txt <- capture.output({ str(pm) }) expect_true(any(str_detect(txt, "Custom str.ggmatrix output:"))) txt <- capture.output({ str(pm, raw = TRUE) }) expect_false(any(str_detect(txt, "Custom str.ggmatrix output:"))) }) test_that("blank", { pm <- ggpairs(tips, 1:2) pm[1, 2] <- "blank" vdiffr::expect_doppelganger("blank-1_2", pm) pm[2, 1] <- NULL vdiffr::expect_doppelganger("blank-1_2-2_1", pm) expect_equal(length(pm$plots), 4) expect_error({ pm[2, 2] <- "not blank" }, "character values \\(besides 'blank'\\)") # nolint }) test_that("proportions", { pm <- ggpairs(iris, 1:2, mapping = ggplot2::aes(color = Species)) pm[2, 2] <- pm[2, 2] + ggplot2::coord_flip() pm2 <- ggmatrix( data = iris, pm$plots, ncol = 2, nrow = 2, xProportions = c(2, 1), yProportions = c(1, 2), title = "big plot, small marginals" ) vdiffr::expect_doppelganger("proportions", pm2) # turn on progress for a quick plot # TODO - turn test back on when it uses message properly # testthat::expect_message(print(pm2, progress = TRUE)) }) test_that("ggmatrix_gtable progress", { pm <- ggpairs(iris, 1:2) expect_silent({ pg <- ggmatrix_gtable(pm) }) expect_warning({ ggmatrix_gtable(pm, progress = TRUE) }) expect_warning({ ggmatrix_gtable(pm, progress_format = "asdfasdf :plot_i") }) }) # # printShowStrips <- c(TRUE, FALSE) # if (i <= length(printShowStrips)) { # printShowStrip <- printShowStrips[i] # } else { # printShowStrip <- NULL # } # test_that("ggmatrix proportions", { expect_error({ ggmatrix_proportions("not auto", tips, 1:ncol(tips)) }, "need to be non-NA") expect_error({ ggmatrix_proportions(NA, tips, 1:ncol(tips)) }, "need to be non-NA") expect_error({ ggmatrix_proportions(c(1, NA, 1, 1, 1, 1, 1), tips, 1:ncol(tips)) }, "need to be non-NA") expect_equal( ggmatrix_proportions("auto", tips, 1:ncol(tips)), c(2.5, 2.5, 2, 2, 4, 2, 2.5) ) expect_equal( ggmatrix_proportions(1, tips, 1:ncol(tips)), c(1, 1, 1, 1, 1, 1, 1) ) expect_equal( ggmatrix_proportions(NULL, tips, 1:ncol(tips)), NULL ) }) GGally/tests/testthat/test-gg-plots.R0000644000176200001440000001735614562447013017311 0ustar liggesusers# This file takes too long testthat::skip_on_cran() data(tips) data(nasa) nas <- subset(nasa, x <= 2 & y == 1) test_that("denstrip", { expect_message( suppressWarnings(print(ggally_denstrip(tips, mapping = aes(!!as.name("sex"), !!as.name("tip"))))), "`stat_bin()` using `bins = 30`", fixed = TRUE ) expect_message( suppressWarnings(print(ggally_denstrip(tips, mapping = aes(!!as.name("tip"), !!as.name("sex"))))), "`stat_bin()` using `bins = 30`", fixed = TRUE ) }) test_that("density", { p <- ggally_density( tips, mapping = ggplot2::aes(x = !!as.name("total_bill"), y = !!as.name("tip"), fill = after_stat(level)) ) + ggplot2::scale_fill_gradient(breaks = c(0.05, 0.1, 0.15, 0.2)) expect_equal(p$labels$fill, "level") }) test_that("cor", { ti <- tips class(ti) <- c("NOTFOUND", "data.frame") p <- ggally_cor(ti, ggplot2::aes(x = total_bill, y = tip, color = day), use = "complete.obs") expect_equal(mapping_string(get("mapping", envir = p$layers[[2]])$colour), "labelp") p <- ggally_cor( ti, ggplot2::aes(x = total_bill, y = tip, color = I("blue")), use = "complete.obs" ) expect_equal(mapping_string(get("mapping", envir = p$layers[[1]])$colour), "I(\"blue\")") expect_err <- function(..., msg = NULL) { expect_error( ggally_cor( ti, ggplot2::aes(x = total_bill, y = tip), ... ), msg ) } vdiffr::expect_doppelganger( "cor-green", ggally_cor(ti, ggplot2::aes(x = total_bill, y = tip, color = I("green"))) ) ti3 <- ti2 <- ti ti2[2, "total_bill"] <- NA ti3[2, "total_bill"] <- NA ti3[3, "tip"] <- NA ti3[4, "total_bill"] <- NA ti3[4, "tip"] <- NA expect_warn <- function(data, msg) { expect_warning( ggally_cor(data, ggplot2::aes(x = total_bill, y = tip)), msg ) } expect_warn(ti2, "Removing 1 row that") expect_warn(ti3, "Removed 3 rows containing") expect_error( ggally_cor( ti, ggplot2::aes(x = total_bill, y = tip, color = size) ), "must be categorical" ) expect_silent( ggally_cor( ti, ggplot2::aes(x = total_bill, y = tip, color = as.factor(size)) ) ) }) test_that("diagAxis", { p <- ggally_diagAxis(iris, ggplot2::aes(x = Petal.Width)) pDat1 <- get("data", envir = p$layers[[2]]) attr(pDat1, "out.attrs") <- NULL testDt1 <- data.frame( xPos = c(0.076, 0.076, 0.076, 0.076, 0.076, 0.076, 0.500, 1.000, 1.500, 2.000, 2.500), yPos = c(0.500, 1.000, 1.500, 2.000, 2.500, 0.076, 0.076, 0.076, 0.076, 0.076, 0.076), lab = as.character(c(0.5, 1, 1.5, 2, 2.5, 0, 0.5, 1, 1.5, 2, 2.5)), hjust = c(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.5, 0.5, 0.5), vjust = c(0.5, 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), stringsAsFactors = FALSE ) rownames(testDt1) <- 2:12 expect_equal(pDat1, testDt1) p <- ggally_diagAxis(iris, ggplot2::aes(x = Species)) pDat2 <- get("data", envir = p$layers[[2]]) attr(pDat2, "out.attrs") <- NULL testDt2 <- data.frame( x = c(0.125, 0.500, 0.875), y = c(0.875, 0.500, 0.125), lab = c("setosa", "versicolor", "virginica") ) expect_equal(pDat2, testDt2) expect_error( { ggally_diagAxis(iris, mapping = ggplot2::aes(y = Sepal.Length)) }, "mapping\\$x is null." ) # nolint }) test_that("dates", { class(nas) <- c("NOTFOUND", "data.frame") p <- ggally_cor(nas, ggplot2::aes(x = date, y = ozone)) expect_equal(get("aes_params", envir = p$layers[[1]])$label, "Corr:\n0.278***") p <- ggally_barDiag(nas, ggplot2::aes(x = date)) expect_equal(mapping_string(p$mapping$x), "date") expect_equal(as.character(p$labels$y), "count") }) test_that("cor stars are aligned", { p <- ggally_cor(iris, ggplot2::aes(x = Sepal.Length, y = Petal.Width, color = as.factor(Species))) expect_equal(get("aes_params", envir = p$layers[[1]])$label, "Corr: 0.818***") # expect_equal(get("aes_params", envir = p$layers[[1]])$family, "mono") labels <- eval_data_col(p$layers[[2]]$data, p$layers[[2]]$mapping$label) expect_equal(as.character(labels), c(" setosa: 0.278. ", "versicolor: 0.546***", " virginica: 0.281* ")) }) test_that("ggally_statistic handles factors", { simple_chisq <- function(x, y) { scales::number(chisq.test(x, y)$p.value, accuracy = .001) } expect_silent({ p <- ggally_statistic(tips, aes(x = sex, y = day), text_fn = simple_chisq, title = "Chi^2") }) }) test_that("rescale", { p <- ggally_densityDiag(tips, mapping = ggplot2::aes(x = day), rescale = FALSE) expect_true(p$labels$y == "density") vdiffr::expect_doppelganger("rescale-false", p) p <- ggally_densityDiag(tips, mapping = ggplot2::aes(x = day), rescale = TRUE) expect_true(!identical(p$labels$y, "density")) vdiffr::expect_doppelganger("rescale-true", p) p <- ggally_barDiag(tips, mapping = ggplot2::aes(x = tip), binwidth = 0.25, rescale = FALSE) expect_true(p$labels$y == "count") vdiffr::expect_doppelganger("rescale-false-binwidth", p) p <- ggally_barDiag(tips, mapping = ggplot2::aes(x = tip), binwidth = 0.25, rescale = TRUE) expect_true(!identical(p$labels$y, "count")) vdiffr::expect_doppelganger("rescale-true-binwidth", p) }) test_that("shrink", { p <- ggally_smooth_loess(iris, mapping = ggplot2::aes(Sepal.Width, Petal.Length)) expect_true(!is.null(p$coordinates$limits$y)) vdiffr::expect_doppelganger("shrink-true", p) p <- ggally_smooth_loess(iris, mapping = ggplot2::aes(Sepal.Width, Petal.Length), shrink = FALSE) expect_true(is.null(p$coordinates$limits$y)) vdiffr::expect_doppelganger("shrink-false", p) }) test_that("smooth_se", { p <- ggally_smooth_loess(iris, mapping = ggplot2::aes(Sepal.Width, Petal.Length), se = TRUE) expect_equal(p$layers[[2]]$stat_params$se, TRUE) vdiffr::expect_doppelganger("smooth-se-true", p) p <- ggally_smooth_loess(iris, mapping = ggplot2::aes(Sepal.Width, Petal.Length), se = FALSE) expect_equal(p$layers[[2]]$stat_params$se, FALSE) vdiffr::expect_doppelganger("smooth-se-false", p) }) test_that("ggally_count", { p <- ggally_count( as.data.frame(Titanic), ggplot2::aes(x = Class, y = Survived, weight = Freq) ) vdiffr::expect_doppelganger("titanic-count", p) p <- ggally_count( as.data.frame(Titanic), ggplot2::aes(x = Class, y = Survived, weight = Freq), fill = "red" ) vdiffr::expect_doppelganger("titanic-count-red", p) p <- ggally_count( as.data.frame(Titanic), ggplot2::aes(x = Class, y = Survived, weight = Freq, fill = Sex) ) vdiffr::expect_doppelganger("titanic-count-sex", p) p <- ggally_count( as.data.frame(Titanic), ggplot2::aes(x = Class, y = Survived, weight = Freq, fill = Class) ) vdiffr::expect_doppelganger("titanic-count-class", p) p <- ggally_count( as.data.frame(Titanic), ggplot2::aes(x = Survived, y = interaction(Sex, Age), weight = Freq, fill = Class) ) vdiffr::expect_doppelganger("titanic-count-interaction", p) # check that y character vectors are rendering p <- ggally_count( as.data.frame(Titanic), ggplot2::aes(x = Class, y = toupper(Survived), weight = Freq, fill = Class) ) vdiffr::expect_doppelganger("titanic-count-toupper", p) # check countDiag p <- ggally_countDiag( as.data.frame(Titanic), ggplot2::aes(x = Survived, weight = Freq, fill = Class) ) vdiffr::expect_doppelganger("titanic-count-diag", p) # change size of tiles p <- ggally_count( as.data.frame(Titanic), ggplot2::aes(x = Class, y = Survived, weight = Freq, fill = Class), x.width = .5 ) vdiffr::expect_doppelganger("titanic-count-diag-class", p) # no warnings expected if na.rm = TRUE p <- ggally_count( as.data.frame(Titanic), ggplot2::aes(x = interaction(Class, Age), y = Survived, weight = Freq, fill = Class), na.rm = TRUE ) vdiffr::expect_doppelganger("titanic-count-diag-interaction", p) }) GGally/tests/testthat/test-zzz_ggpairs.R0000644000176200001440000005665514562447013020133 0ustar liggesusers# This file takes too long testthat::skip_on_cran() data(tips) facethistBindwidth1 <- list(combo = wrap("facethist", binwidth = 1)) facethistBindwidth1Duo <- list( comboHorizontal = wrap("facethist", binwidth = 1), comboVertical = wrap("facethist", binwidth = 1) ) test_that("structure", { expect_null <- function(x) { expect_true(is.null(x)) } expect_obj <- function(x) { expect_s3_class(x$data, "data.frame") expect_type(x$plots, "list") expect_equal(length(x$plots), ncol(tips)^2) expect_null(x$title) expect_null(x$xlab) expect_null(x$ylab) expect_type(x$xAxisLabels, "character") expect_type(x$yAxisLabels, "character") expect_type(x$showXAxisPlotLabels, "logical") expect_type(x$showYAxisPlotLabels, "logical") expect_null(x$legend) expect_type(x$byrow, "logical") expect_null(x$gg) expect_true("gg" %in% names(x)) } expect_obj(ggduo(tips)) expect_obj(ggpairs(tips)) }) test_that("columns", { expect_obj <- function(pm, columnsX, columnsY) { expect_equal(length(pm$plots), length(columnsX) * length(columnsY)) expect_equal(pm$xAxisLabels, columnsX) expect_equal(pm$yAxisLabels, columnsY) expect_equal(pm$ncol, length(columnsX)) expect_equal(pm$nrow, length(columnsY)) } columnsUsed <- c("total_bill", "tip", "sex") pm <- ggpairs(tips, columns = columnsUsed) expect_obj(pm, columnsUsed, columnsUsed) columnsX <- c("total_bill", "tip", "sex") columnsY <- c("smoker", "day", "time", "size") pm <- ggduo(tips, columnsX, columnsY) expect_obj(pm, columnsX, columnsY) }) test_that("column labels", { expect_obj <- function(pm, columnLabelsX, columnLabelsY) { expect_equal(pm$xAxisLabels, columnLabelsX) expect_equal(pm$yAxisLabels, columnLabelsY) } columnTitles <- c("A", "B", "C") pm <- ggpairs(tips, 1:3, columnLabels = columnTitles) expect_obj(pm, columnTitles, columnTitles) columnTitles <- c("Total Bill %", "Tip 123456", "Sex ( /a asdf)") pm <- ggpairs(tips, 1:3, columnLabels = columnTitles) expect_obj(pm, columnTitles, columnTitles) columnLabelsX <- c("Total Bill %", "Tip 123456", "Sex ( /a asdf)") columnLabelsY <- c("Smoker !#@", "Day 678", "1", "NULL") pm <- ggduo(tips, 1:3, 4:7, columnLabelsX = columnLabelsX, columnLabelsY = columnLabelsY) expect_obj(pm, columnLabelsX, columnLabelsY) }) test_that("character", { expect_obj <- function(pm) { expect_true(is.factor(pm$data$sex)) expect_true(is.factor(pm$data$smoker)) } tips2 <- tips tips2$sex <- as.character(tips2$sex) tips2$smoker <- as.character(tips2$smoker) expect_obj(ggpairs(tips2)) expect_obj(ggduo(tips2)) }) test_that("upper/lower/diag = blank", { columnsUsed <- 1:3 au <- ggpairs(tips, columnsUsed, upper = "blank") ad <- ggpairs(tips, columnsUsed, diag = "blank") al <- ggpairs(tips, columnsUsed, lower = "blank") for (i in 1:3) { for (j in 1:3) { if (i < j) { expect_true(is_blank_plot(au[i, j])) expect_false(is_blank_plot(ad[i, j])) expect_false(is_blank_plot(al[i, j])) } if (i > j) { expect_false(is_blank_plot(au[i, j])) expect_false(is_blank_plot(ad[i, j])) expect_true(is_blank_plot(al[i, j])) } if (i == j) { expect_false(is_blank_plot(au[i, j])) expect_true(is_blank_plot(ad[i, j])) expect_false(is_blank_plot(al[i, j])) } } } a <- ggpairs(tips, columnsUsed) a[1, 1] <- ggplot(tips, aes(total_bill)) + geom_histogram() expect_false(is_blank_plot(a[1, 1])) }) test_that("stops", { expect_warning( { pm <- ggpairs(tips, axisLabels = "not_a_chosen", lower = facethistBindwidth1) }, "'axisLabels' not in " ) # nolint expect_warning( { pm <- ggduo(tips, axisLabels = "not_a_chosen", types = facethistBindwidth1Duo) }, "'axisLabels' not in " ) # nolint expect_warning( { pm <- ggpairs(tips, color = "sex") }, "Extra arguments: " ) # nolint expect_warning( { pm <- ggduo(tips, 2:3, 2:3, types = list(combo = "facetdensity")) }, "Setting:\n\ttypes" ) # nolint expect_error( { ggpairs(tips, columns = c("tip", "day", "not in tips")) }, "Columns in 'columns' not found in data" ) # nolint expect_error( { ggduo(tips, columnsX = c("tip", "day", "not in tips"), columnsY = "smoker") }, "Columns in 'columnsX' not found in data" ) # nolint expect_error( { ggduo(tips, columnsX = c("tip", "day", "smoker"), columnsY = "not in tips") }, "Columns in 'columnsY' not found in data" ) # nolint expect_warning( { pm <- ggpairs(tips, legends = TRUE) }, "'legends' will be deprecated" ) # nolint expect_error( { ggpairs(tips, params = c(size = 2)) }, "'params' is a deprecated" ) # nolint expect_error( { ggpairs(tips, columns = 1:10) }, "Make sure your numeric 'columns' values are less than or equal to" ) # nolint expect_error( { ggduo(tips, columnsX = 1:10) }, "Make sure your numeric 'columnsX' values are less than or equal to" ) # nolint expect_error( { ggduo(tips, columnsY = 1:10) }, "Make sure your numeric 'columnsY' values are less than or equal to" ) # nolint expect_error( { ggpairs(tips, columns = -5:5) }, "Make sure your numeric 'columns' values are positive" ) # nolint expect_error( { ggduo(tips, columnsX = -5:5) }, "Make sure your numeric 'columnsX' values are positive" ) # nolint expect_error( { ggduo(tips, columnsY = -5:5) }, "Make sure your numeric 'columnsY' values are positive" ) # nolint expect_error( { ggpairs(tips, columns = (2:10) / 2) }, "Make sure your numeric 'columns' values are integers" ) # nolint expect_error( { ggduo(tips, columnsX = (2:10) / 2) }, "Make sure your numeric 'columnsX' values are integers" ) # nolint expect_error( { ggduo(tips, columnsY = (2:10) / 2) }, "Make sure your numeric 'columnsY' values are integers" ) # nolint expect_error( { ggpairs(tips, columns = 1:3, columnLabels = c("A", "B", "C", "Extra")) }, "The length of the 'columnLabels' does not match the length of the 'columns'" ) # nolint expect_error( { ggduo(tips, columnsX = 1:3, columnLabelsX = c("A", "B", "C", "Extra")) }, "The length of the 'columnLabelsX' does not match the length of the 'columnsX'" ) # nolint expect_error( { ggduo(tips, columnsY = 1:3, columnLabelsY = c("A", "B", "C", "Extra")) }, "The length of the 'columnLabelsY' does not match the length of the 'columnsY'" ) # nolint expect_error( { ggpairs(tips, upper = c("not_a_list")) }, "'upper' is not a list" ) # nolint expect_error( { ggpairs(tips, diag = c("not_a_list")) }, "'diag' is not a list" ) # nolint expect_error( { ggpairs(tips, lower = c("not_a_list")) }, "'lower' is not a list" ) # nolint expect_error( { ggduo(tips, types = c("not_a_list")) }, "'types' is not a list" ) # nolint # # couldn't get correct error message # # variables: 'colour' have non standard format: 'total_bill + tip'. # expect_error({ # ggpairs(tips, mapping = ggplot2::aes(color = total_bill + tip)) # }, "variables\\: \"colour\" have non standard format") # nolint # expect_error({ # ggduo(tips, mapping = ggplot2::aes(color = total_bill + tip)) # }, "variables\\: \"colour\" have non standard format") # nolint errorString <- "'aes_string' is a deprecated element" expect_error( { ggpairs(tips, upper = list(aes_string = ggplot2::aes(color = day))) }, errorString ) # nolint expect_error( { ggpairs(tips, lower = list(aes_string = ggplot2::aes(color = day))) }, errorString ) # nolint expect_error( { ggpairs(tips, diag = list(aes_string = ggplot2::aes(color = day))) }, errorString ) # nolint expect_error( { ggduo(tips, types = list(aes_string = ggplot2::aes(color = day))) }, errorString ) # nolint expect_diag_warn <- function(key, value) { warnString <- str_c("Changing diag\\$", key, " from '", value, "' to '", value, "Diag'") diagObj <- list() diagObj[[key]] <- value expect_warning( { pm <- ggpairs(tips, diag = diagObj) }, warnString ) } # diag # continuous # densityDiag # barDiag # blankDiag # discrete # barDiag # blankDiag expect_diag_warn("continuous", "density") expect_diag_warn("continuous", "bar") expect_diag_warn("continuous", "blank") expect_diag_warn("discrete", "bar") expect_diag_warn("discrete", "blank") }) test_that("cardinality", { expect_silent(stop_if_high_cardinality(tips, 1:ncol(tips), NULL)) expect_silent(stop_if_high_cardinality(tips, 1:ncol(tips), FALSE)) expect_error( stop_if_high_cardinality(tips, 1:ncol(tips), "not numeric"), "'cardinality_threshold' should" ) expect_error( stop_if_high_cardinality(tips, 1:ncol(tips), 2), "Column 'day' has more levels" ) }) test_that("blank types", { columnsUsed <- 1:3 pmUpper <- ggpairs(tips, columnsUsed, upper = "blank", lower = facethistBindwidth1) pmDiag <- ggpairs(tips, columnsUsed, diag = "blank", lower = facethistBindwidth1) pmLower <- ggpairs(tips, columnsUsed, lower = "blank") for (i in columnsUsed) { for (j in columnsUsed) { if (i < j) { # upper expect_true(is_blank_plot(pmUpper[i, j])) expect_false(is_blank_plot(pmDiag[i, j])) expect_false(is_blank_plot(pmLower[i, j])) } else if (i > j) { # lower expect_false(is_blank_plot(pmUpper[i, j])) expect_false(is_blank_plot(pmDiag[i, j])) expect_true(is_blank_plot(pmLower[i, j])) } else { # diag expect_false(is_blank_plot(pmUpper[i, j])) expect_true(is_blank_plot(pmDiag[i, j])) expect_false(is_blank_plot(pmLower[i, j])) } } } columnsUsedX <- 1:3 columnsUsedY <- 4:5 pmDuo <- ggduo(tips, columnsUsedX, columnsUsedY, types = "blank") for (i in seq_along(columnsUsedX)) { for (j in seq_along(columnsUsedY)) { expect_true(is_blank_plot(pmDuo[j, i])) } } }) test_that("axisLabels", { expect_axis_labels <- function(pm, prefix, axisLabel) { expect_true(is.null(pm$showStrips)) if (axisLabel == "show") { expect_true(pm$showXAxisPlotLabels) expect_true(pm$showYAxisPlotLabels) expect_false(is.null(pm$xAxisLabels)) expect_false(is.null(pm$yAxisLabels)) } else if (axisLabel == "internal") { for (i in 1:(pm$ncol)) { p <- pm[i, i] expect_true(inherits(p$layers[[1]]$geom, "GeomText")) expect_true(inherits(p$layers[[2]]$geom, "GeomText")) expect_equal(length(p$layers), 2) } expect_false(pm$showXAxisPlotLabels) expect_false(pm$showYAxisPlotLabels) expect_true(is.null(pm$xAxisLabels)) expect_true(is.null(pm$yAxisLabels)) } else if (axisLabel == "none") { expect_false(pm$showXAxisPlotLabels) expect_false(pm$showYAxisPlotLabels) expect_false(is.null(pm$xAxisLabels)) expect_false(is.null(pm$yAxisLabels)) } vdiffr::expect_doppelganger(paste0("axisLabels-", prefix, "-", axisLabel), pm) } fn <- function(axisLabels) { pm <- ggpairs( iris, c(3, 4, 5, 1), upper = "blank", lower = facethistBindwidth1, axisLabels = axisLabels, title = str_c("axisLabels = ", axisLabels), progress = FALSE ) pm } for (axisLabels in c("show", "internal", "none")) { expect_axis_labels(fn(axisLabels), "ggpairs", axisLabels) } plots <- ggpairs(iris, 1:3)$plots for (val in c(TRUE, FALSE)) { pm <- ggmatrix( plots, 3, 3, showAxisPlotLabels = val ) expect_equal(pm$showXAxisPlotLabels, val) expect_equal(pm$showYAxisPlotLabels, val) } fn <- function(axisLabels) { a <- ggduo( iris, c(4, 5), c(5, 1), types = facethistBindwidth1Duo, axisLabels = axisLabels, title = str_c("axisLabels = ", axisLabels) ) a } for (axisLabels in c("show", "none")) { expect_axis_labels(fn(axisLabels), "ggduo", axisLabels) } }) test_that("strips and axis", { # axis should line up with left side strips pm <- ggpairs( tips, c(3, 1, 4), showStrips = TRUE, title = "Axis should line up even if strips are present", lower = list(combo = wrap("facethist", binwidth = 1)) ) vdiffr::expect_doppelganger("show-strips", pm) # default behavior. tested in other places # expect_silent({ # pm <- ggpairs(tips, c(3, 1, 4), showStrips = FALSE) # print(pm) # }) }) test_that("dates", { startDt <- as.POSIXct("2000-01-01", tz = "UTC") endDt <- as.POSIXct("2000-04-01", tz = "UTC") dts <- seq(startDt, endDt, 86400) # 86400 = as.numeric(ddays(1)) x <- data.frame( date = dts, x1 = rnorm(length(dts)), x2 = rnorm(length(dts)), cat = sample(c("a", "b", "c"), length(dts), replace = TRUE) ) class(x) <- c("NOT_data.frame", "data.frame") a <- ggpairs( x, c(2, 1, 4, 3), mapping = ggplot2::aes(color = cat), lower = "blank", diag = list(continuous = "densityDiag"), upper = list(continuous = "cor") ) p <- a[1, 2] expect_true(inherits(p$layers[[1]]$geom, "GeomText")) expect_true(inherits(p$layers[[2]]$geom, "GeomText")) expect_equal(length(p$layers), 2) a <- ggpairs( x, c(2, 1, 4, 3), mapping = ggplot2::aes(color = cat), lower = "blank", diag = list(continuous = "barDiag"), upper = list(continuous = "cor") ) p <- a[1, 1] expect_true(inherits(p$layers[[1]]$geom, "GeomBar")) expect_equal(length(p$layers), 1) }) test_that("mapping", { pm <- ggpairs(tips, mapping = 1:3) expect_equal(pm$xAxisLabels, names(tips)[1:3]) pm <- ggpairs(tips, columns = 1:3) expect_equal(pm$xAxisLabels, names(tips)[1:3]) expect_error( { ggpairs(tips, columns = 1:3, mapping = 1:3) }, "'mapping' should not be numeric" ) # nolint }) test_that("user functions", { p0 <- ggally_points(tips, ggplot2::aes(x = total_bill, y = tip)) pm1 <- ggpairs(tips, 1:2, lower = list(continuous = "points")) p1 <- pm1[2, 1] pm2 <- ggpairs(tips, 1:2, lower = list(continuous = ggally_points)) p2 <- pm2[2, 1] expect_equal_plots <- function(x, y) { expect_equal(length(x$layers), 1) expect_equal(length(y$layers), 1) expect_true( "GeomPoint" %in% class(x$layers[[1]]$geom) ) expect_true( "GeomPoint" %in% class(y$layers[[1]]$geom) ) expect_equal(x$labels, list(x = "total_bill", y = "tip")) expect_equal(x$labels, y$labels) } expect_equal_plots(p0, p1) expect_equal_plots(p0, p2) }) test_that("NA data", { expect_is_na_plot <- function(p) { expect_true(identical(as.character(p$data$label), "NA")) expect_true(inherits(p$layers[[1]]$geom, "GeomText")) expect_equal(length(p$layers), 1) } expect_not_na_plot <- function(p) { expect_false(identical(as.character(p$data$label), "NA")) } expect_is_blank <- function(p) { expect_true(is_blank_plot(p)) } dd <- data.frame(x = c(1:5, rep(NA, 5)), y = c(rep(NA, 5), 2:6), z = 1:10, w = NA) pm <- ggpairs(dd) test_pm <- function(pm, na_mat) { for (i in 1:4) { for (j in 1:4) { if (na_mat[i, j]) { expect_is_na_plot(pm[i, j]) } else { if (j == 3 && i < 3) { expect_warning( { p <- pm[i, j] }, "Removed 5 rows" ) } else { p <- pm[i, j] } expect_not_na_plot(p) } } } } na_mat <- matrix(FALSE, ncol = 4, nrow = 4) na_mat[1, 2] <- TRUE na_mat[2, 1] <- TRUE na_mat[1:4, 4] <- TRUE na_mat[4, 1:4] <- TRUE test_pm(pm, na_mat) }) test_that("strip-top and strip-right", { data(tips) double_strips <- function(data, mapping, ...) { dt <- plyr::count(data, c(mapping_string(mapping$x), mapping_string(mapping$y))) ggplot(dt, aes(xmin = 0.25, xmax = 0.75, ymin = 1, ymax = freq)) + geom_rect() + ggplot2::facet_grid(paste0(mapping_string(mapping$y), " ~ ", mapping_string(mapping$x))) + ggplot2::scale_x_continuous(breaks = 0.5, labels = NULL) } pm <- ggpairs( tips, 3:6, lower = "blank", diag = "blank", upper = list(discrete = double_strips), progress = FALSE ) vdiffr::expect_doppelganger("nested-strips-default", pm) pm <- ggpairs( tips, 3:6, lower = "blank", diag = "blank", upper = list(discrete = double_strips), showStrips = TRUE, progress = FALSE ) vdiffr::expect_doppelganger("nested-strips-true", pm) }) test_that("subtypes", { testthat::skip_on_cran() testthat::skip_if_not_installed("Hmisc") # list of the different plot types to check # continuous # points # smooth # smooth_loess # density # cor # blank # combo # box # dot plot # facethist # facetdensity # denstrip # blank # discrete # ratio # facetbar # blank gn <- function(x) { fnName <- attr(x, "name") ifnull(fnName, x) } ggpairs_fn1 <- function(title, types, diag, ...) { ggpairs( tips, 1:4, axisLabels = "show", title = paste( "upper = c(cont = ", gn(types$continuous), ", combo = ", gn(types$combo), ", discrete = ", gn(types$discrete), "); diag = c(cont = ", gn(diag$continuous), ", discrete = ", gn(diag$discrete), ")", sep = "" ), upper = types, lower = types, diag = diag, progress = FALSE, ... ) + ggplot2::theme(plot.title = ggplot2::element_text(size = 9)) } ggpairs_fn2 <- function(...) { ggpairs_fn1(..., mapping = ggplot2::aes(color = day), legend = c(1, 3)) } ggduo_fn1 <- function(title, types, diag, ...) { types$comboHorizontal <- types$combo types$comboVertical <- types$combo types$combo <- NULL ggduo( tips, 1:3, 1:4, axisLabels = "show", title = paste( "types = c(cont = ", gn(types$continuous), ", combo = ", gn(types$comboHorizontal), ", discrete = ", gn(types$discrete), ")", sep = "" ), types = types, progress = FALSE, ... ) + ggplot2::theme(plot.title = ggplot2::element_text(size = 9)) } ggduo_fn2 <- function(...) { ggduo_fn1(..., mapping = ggplot2::aes(color = day), legend = 3) + theme(legend.position = "bottom") } # re ordered the subs so that density can have no binwidth param conSubs <- list( "autopoint", "density", "points", "smooth", "smooth_lm", "smooth_loess", "cor", "blank" ) comSubs <- list( "autopoint", "box", "dot", "box_no_facet", "dot_no_facet", wrap("facethist", binwidth = 1), "facetdensity", "facetdensitystrip", # "summarise_by", # Issues with grid printing wrap("denstrip", binwidth = 1), "blank" ) disSubs <- list( "autopoint", "colbar", "count", "cross", "crosstable", "facetbar", "ratio", "rowbar", "table", # "trends", # Issues with grid printing "blank" ) conDiagSubs <- c("autopointDiag", "densityDiag", wrap("barDiag", binwidth = 1), "blankDiag") disDiagSubs <- c("autopointDiag", "barDiag", "countDiag", "tableDiag", "blankDiag") # for (fn in list(ggpairs_fn1, ggpairs_fn2, ggduo_fn1, ggduo_fn2)) { for (fn_info in list( list(fn = ggpairs_fn1, title = "ggpairs"), list(fn = ggpairs_fn2, title = "ggpairs_color"), list(fn = ggduo_fn1, title = "ggduo"), list(fn = ggduo_fn2, title = "ggduo_color") )) { fn <- fn_info$fn fn_name <- fn_info$title for (i in 1:max(c( length(conSubs), length(comSubs), length(disSubs), length(conDiagSubs), length(disDiagSubs) ))) { conSub <- if (i <= length(conSubs)) conSubs[[i]] else "blank" comSub <- if (i <= length(comSubs)) comSubs[[i]] else "blank" disSub <- if (i <= length(disSubs)) disSubs[[i]] else "blank" diagConSub <- if (i <= length(conDiagSubs)) conDiagSubs[[i]] else "blankDiag" diagDisSub <- if (i <= length(disDiagSubs)) disDiagSubs[[i]] else "blankDiag" # print(list( # fn_num = fn_num, # types = list( # continuous = conSub, # combo = comSub, # discrete = disSub # ), # diag = list( # continuous = diagConSub, # discrete = diagDisSub # ) # )) # expect_silent({ pm <- fn( types = list( continuous = conSub, combo = comSub, discrete = disSub ), diag = list( continuous = diagConSub, discrete = diagDisSub ) ) }) type_name <- function(x) { if (is.function(x)) { sub("ggally_", "", attr(x, "name")) } else { x } } type_names <- vapply(c(conSub, comSub, disSub, diagConSub, diagDisSub), type_name, character(1)) if (all(grepl("blank", type_names))) { # vdiffr can't handle blank plots next } pm_name <- paste0(type_names, collapse = "-") pm_name <- paste0(fn_name, "-", pm_name) tryCatch( { set.seed(123456) # keep jitter consistent suppressWarnings({ built_pm <- ggmatrix_gtable(pm) }) vdiffr::expect_doppelganger(pm_name, built_pm) }, error = function(e) { message("failed to create doppelganger: ", pm_name) print(e) barret <<- pm expect_silent(print(c("failed to create doppelganger", pm_name))) } ) } } expect_error({ ggpairs(tips, 1:2, lower = "blank", diag = "blank", upper = list(continuous = "BAD_TYPE")) }) }) # pm <- ggpairs(tips, upper = "blank") # # pm # # Custom Example # pm <- ggpairs( # tips[, c(1, 3, 4, 2)], # upper = list(continuous = "density", combo = "box"), # lower = list(continuous = "points", combo = "dot") # ) # # pm # # Use sample of the diamonds data # data(diamonds, package = "ggplot2") # diamonds.samp <- diamonds[sample(1:dim(diamonds)[1], 200), ] # # Custom Example # pm <- ggpairs( # diamonds.samp[, 1:5], # upper = list(continuous = "density", combo = "box"), # lower = list(continuous = "points", combo = "dot"), # color = "cut", # alpha = 0.4, # title = "Diamonds" # ) # # pm # # Will plot four "Incorrect Plots" # bad_plots <- ggpairs( # tips[, 1:3], # upper = list(continuous = "wrongType1", combo = "wrongType2"), # lower = list(continuous = "IDK1", combo = "IDK2", discrete = "mosaic"), # ) # # bad_plots # # Only Variable Labels on the diagonal (no axis labels) # pm <- ggpairs(tips[, 1:3], axisLabels = "internal") # # pm # # Only Variable Labels on the outside (no axis labels) # pm <- ggpairs(tips[, 1:3], axisLabels = "none") # # pm # # Custom Examples # custom_car <- ggpairs(mtcars[, c("mpg", "wt", "cyl")], upper = "blank", title = "Custom Example") # #' # ggplot example taken from example(geom_text) # #' plot <- ggplot2::ggplot(mtcars, ggplot2::aes(x = wt, y = mpg, label = rownames(mtcars))) # #' plot <- plot + # #' ggplot2::geom_text(ggplot2::aes(colour = factor(cyl)), size = 3) + # #' ggplot2::scale_colour_discrete(l = 40) # #' custom_car <- putPlot(custom_car, plot, 1, 2) # #' personal_plot <- ggally_text( # #' "ggpairs allows you\nto put in your\nown plot.\nLike that one.\n <---" # #' ) # #' custom_car <- putPlot(custom_car, personal_plot, 1, 3) # #' # custom_car GGally/tests/testthat/test-ggfacet.R0000644000176200001440000000136414562447013017145 0ustar liggesusers skip_if_not_installed("chemometrics") data(NIR, package = "chemometrics") NIR_sub <- data.frame(NIR$yGlcEtOH, NIR$xNIR[, 1:3]) test_that("warnings", { expect_warning( ggfacet(iris, columnsX = 1:5, columnsY = 1), "1 factor variables are being removed from X columns" ) expect_warning( ggfacet(iris, columnsX = 1, columnsY = 1:5), "1 factor variables are being removed from Y columns" ) }) test_that("generally works", { # factor variables vdiffr::expect_doppelganger( "factor", ggfacet( NIR_sub, columnsY = 1:2, columnsX = 3:5, fn = ggally_smooth_loess ) ) vdiffr::expect_doppelganger( "pigs", ggts(pigs, "time", c("gilts", "profit", "s_per_herdsz", "production", "herdsz")) ) }) GGally/tests/testthat/test-gglyph.R0000644000176200001440000000710014562447013017031 0ustar liggesusers data(nasa) nasaLate <- nasa[ nasa$date >= as.POSIXct("1998-01-01") & nasa$lat >= 20 & nasa$lat <= 40 & nasa$long >= -80 & nasa$long <= -60, ] do_glyph <- function(...) { glyphs( nasaLate, # no lint "long", "day", "lat", "surftemp", height = 2.37, width = 2.38, ... ) } do_gg <- function(dt) { ggplot2::ggplot(dt, ggplot2::aes(gx, gy, group = gid)) + # nolint add_ref_lines(dt, color = "red", size = 0.5) + add_ref_boxes(dt, color = "blue") + ggplot2::geom_path() + ggplot2::theme_bw() + ggplot2::labs(x = "", y = "") + ggplot2::xlim(-80, -60) + ggplot2::ylim(20, 40) } test_that("examples", { dt <- do_glyph() expect_true(all(c("gx", "gy", "gid") %in% names(dt))) expect_true(all(names(nasaLate) %in% names(dt))) p <- do_gg(dt) expect_equal(length(p$layers), 3) expect_equal(as.character(get("aes_params", envir = p$layers[[1]])$colour), "red") expect_equal(as.character(get("aes_params", envir = p$layers[[2]])$colour), "blue") }) test_that("message", { expect_message(glyphs(nasaLate, "long", "day", "lat", "surftemp", height = 1), "Using width 2.38") expect_message(glyphs(nasaLate, "long", "day", "lat", "surftemp", width = 1), "Using height 2.37") }) test_that("scales", { dt <- do_glyph(x_scale = log) dt$dayLog <- dt$day dt$day <- NULL dtm <- merge(dt, nasaLate) expect_true(all(dtm$dayLog == log(dtm$day))) dt <- do_glyph(y_scale = log) dt$surftempLog <- dt$surftemp dt$surftemp <- NULL dtm <- merge(dt, nasaLate) expect_true(all(dtm$surftempLog == log(dtm$surftemp))) for (scale_fn in c(range01, max1, mean0, min0, rescale01, rescale11)) { dt <- do_glyph(y_scale = scale_fn) dt$surftempScaled <- dt$surftemp dt$surftemp <- NULL dtm <- merge(dt, nasaLate) expect_true(all(dtm$surftempScaled != dtm$surftemp)) } for (scale_fn in c(rescale01, rescale11)) { scale_fn2 <- function(x) { scale_fn(x, xlim = c(1 / 4, 3 / 4)) } dt <- do_glyph(y_scale = scale_fn2) dt$surftempScaled <- dt$surftemp dt$surftemp <- NULL dtm <- merge(dt, nasaLate) expect_true(all(dtm$surftempScaled != dtm$surftemp)) } }) test_that("polar", { dt <- do_glyph(polar = TRUE) expect_equal(attr(dt, "polar"), TRUE) # idk how to test that polar happened p <- do_gg(dt) expect_equal(length(p$layers), 3) }) test_that("fill", { dt <- do_glyph() # idk how to test that polar happened do_gg_fill <- function(...) { ggplot2::ggplot(dt, ggplot2::aes(gx, gy, group = gid)) + add_ref_lines(dt, color = "red", size = 0.5) + add_ref_boxes(dt, color = "blue", ...) + ggplot2::geom_path() + ggplot2::theme_bw() + ggplot2::labs(x = "", y = "") + ggplot2::xlim(-80, -60) + ggplot2::ylim(20, 40) } p <- do_gg_fill(fill = "green") expect_equal(mapping_string(get("aes_params", envir = p$layers[[2]])$fill), "\"green\"") p <- do_gg_fill(var_fill = "gid") expect_equal(mapping_string(get("mapping", envir = p$layers[[2]])$fill), "fill") }) test_that("print", { dt <- do_glyph() txt <- capture.output(print(dt)) expect_equal(txt[length(txt) - 2], "Cartesian glyphplot: ") expect_equal(txt[length(txt) - 1], " Size: [2.38, 2.37]") expect_equal(txt[length(txt) - 0], " Major axes: long, lat") dt <- do_glyph(polar = TRUE) txt <- capture.output(print(dt)) expect_equal(txt[length(txt) - 2], "Polar glyphplot: ") expect_equal(txt[length(txt) - 1], " Size: [2.38, 2.37]") expect_equal(txt[length(txt) - 0], " Major axes: long, lat") txt <- capture.output(print(rel(0.95))) expect_equal(txt, "[1] 0.95 *") }) GGally/tests/testthat/test-ggcoef.R0000644000176200001440000000115214562447013016772 0ustar liggesusers suppressMessages(require(broom)) test_that("example", { reg <- lm(Sepal.Length ~ Sepal.Width + Petal.Length + Petal.Width, data = iris) p <- ggcoef(reg) vdiffr::expect_doppelganger("lm", p) skip_if_not_installed("MASS") d <- as.data.frame(Titanic) reg2 <- glm(Survived ~ Sex + Age + Class, family = binomial, data = d, weights = d$Freq) p <- ggcoef(reg2, exponentiate = TRUE) vdiffr::expect_doppelganger("lm-expo", p) p <- ggcoef( reg2, exponentiate = TRUE, exclude_intercept = TRUE, errorbar_height = .2, color = "blue" ) vdiffr::expect_doppelganger("lm-expo-blue", p) }) GGally/tests/testthat/test-ggsave.R0000644000176200001440000000042014562447013017011 0ustar liggesusers test_that("ggsave", { pm <- ggpairs(iris, 1:2) test_file <- "test.pdf" on.exit({ unlink(test_file) }) expect_true(!file.exists(test_file)) expect_silent({ ggsave(test_file, pm, width = 7, height = 7) }) expect_true(file.exists(test_file)) }) GGally/tests/testthat/helper-options.R0000644000176200001440000000031014562447013017526 0ustar liggesusersrq <- function(...) { suppressPackageStartupMessages(require(..., quietly = TRUE)) } with_options <- function(opts, expr) { old_opts <- options(opts) on.exit(options(old_opts)) force(expr) } GGally/tests/testthat/test-ggparcoord.R0000644000176200001440000002262214562447013017674 0ustar liggesusers set.seed(123) data(diamonds, package = "ggplot2") diamonds.samp <- diamonds[sample(1:dim(diamonds)[1], 100), ] iris2 <- iris iris2$alphaLevel <- c("setosa" = 0.2, "versicolor" = 0.3, "virginica" = 0)[iris2$Species] test_that("stops", { # basic parallel coordinate plot, using default settings # ggparcoord(data = diamonds.samp, columns = c(1, 5:10)) # this time, color by diamond cut expect_error( ggparcoord(data = diamonds.samp, columns = c(1, 5:10), groupColumn = NULL, order = "anyClass"), "can't use the 'order' methods " ) expect_error( ggparcoord(data = diamonds.samp, columns = c(1, 5:10), groupColumn = NULL, order = "allClass"), "can't use the 'order' methods " ) expect_error( ggparcoord(data = diamonds.samp, columns = c(1, 5:10), groupColumn = c(1, 2)), "invalid value for 'groupColumn'" ) expect_error( ggparcoord(data = diamonds.samp, columns = c(1, 5:10), groupColumn = 1i), "invalid value for 'groupColumn'" ) expect_error( ggparcoord(data = diamonds.samp, columns = c(1, 5:10), groupColumn = 2, scale = "notValid"), "invalid value for 'scale'" ) expect_error( ggparcoord( data = diamonds.samp, columns = c(1, 5:10), groupColumn = 2, centerObsID = nrow(diamonds.samp) + 10 ), "invalid value for 'centerObsID'" ) expect_error( ggparcoord(data = diamonds.samp, columns = c(1, 5:10), groupColumn = 2, missing = "notValid"), "invalid value for 'missing'" ) expect_error( ggparcoord(data = diamonds.samp, columns = c(1, 5:10), groupColumn = 2, order = "notValid"), "invalid value for 'order'" ) expect_error( ggparcoord(data = diamonds.samp, columns = c(1, 5:10), groupColumn = 2, order = 1i), "invalid value for 'order'" ) expect_error( ggparcoord(data = diamonds.samp, columns = c(1, 5:10), groupColumn = 2, showPoints = 1), "invalid value for 'showPoints'" ) expect_error( ggparcoord( data = diamonds.samp, columns = c(1, 5:10), groupColumn = 2, alphaLines = "notAColumn" ), "'alphaLines' column is missing in data" ) tmpDt <- diamonds.samp tmpDt$price[1] <- NA range(tmpDt$price) expect_error( ggparcoord( data = tmpDt, columns = c(1, 5:10), groupColumn = 2, alphaLines = "price" ), "missing data in 'alphaLines' column" ) expect_error( ggparcoord(data = diamonds.samp, columns = c(1, 5:10), groupColumn = 2, alphaLines = "price"), "invalid value for 'alphaLines' column; max range " ) expect_error( ggparcoord(data = diamonds.samp, columns = c(1, 5:10), groupColumn = 2, alphaLines = -0.1), "invalid value for 'alphaLines'; must be a scalar value" ) expect_error( ggparcoord(data = diamonds.samp, columns = c(1, 5:10), groupColumn = 2, alphaLines = 1.1), "invalid value for 'alphaLines'; must be a scalar value" ) expect_error( ggparcoord(data = diamonds.samp, columns = c(1, 5:10), groupColumn = 2, boxplot = 1), "invalid value for 'boxplot'" ) expect_error( ggparcoord(data = diamonds.samp, columns = c(1, 5:10), groupColumn = 2, shadeBox = c(1, 2)), "invalid value for 'shadeBox'; must be a single color" ) expect_error( ggparcoord(data = diamonds.samp, columns = c(1, 5:10), groupColumn = 2, shadeBox = "notacolor"), "invalid value for 'shadeBox'; must be a valid R color" ) expect_error( ggparcoord(diamonds.samp, columns = c(1, 5:10), groupColumn = 2, splineFactor = NULL), "invalid value for 'splineFactor'" ) }) test_that("alphaLines", { p <- ggparcoord( data = iris2, columns = 1:4, groupColumn = 5, order = "anyClass", showPoints = TRUE, title = "Parallel Coordinate Plot for the Iris Data", alphaLines = "alphaLevel" ) expect_equal(length(p$layers), 2) expect_equal(mapping_string(get("mapping", envir = p$layers[[1]])$alpha), "alphaLevel") }) test_that("splineFactor", { ## Use splines on values, rather than lines (all produce the same result) columns <- c(1, 5:10) p1 <- ggparcoord(diamonds.samp, columns, groupColumn = 2, splineFactor = TRUE) p2 <- ggparcoord(diamonds.samp, columns, groupColumn = 2, splineFactor = 3) pList <- list(p1, p2) for (p in pList) { expect_equal(mapping_string(get("mapping", envir = p$layers[[1]])$x), "spline.x") expect_equal(mapping_string(get("mapping", envir = p$layers[[1]])$y), "spline.y") tmp <- unique(as.numeric(get("data", envir = p$layers[[1]])$ggally_splineFactor)) expect_true((tmp == 3) || (tmp == 21)) } p <- ggparcoord( data = iris2, columns = 1:4, groupColumn = 5, splineFactor = 3, alphaLines = "alphaLevel" ) expect_equal(mapping_string(get("mapping", p$layers[[1]])$alpha), "alphaLevel") p <- ggparcoord( data = iris2, columns = 1:4, groupColumn = 5, splineFactor = 3, showPoints = TRUE ) expect_equal(length(p$layers), 2) expect_equal(mapping_string(get("mapping", p$layers[[1]])$x), "spline.x") expect_equal(mapping_string(get("mapping", p$layers[[2]])$y), "value") }) test_that("groupColumn", { ds2 <- diamonds.samp ds2$color <- mapping_string(ds2$color) # column 3 has a character # column 4 has a factor p <- ggparcoord(data = ds2, columns = c(1, 3:10), groupColumn = 2) expect_true("color" %in% levels(p$data$variable)) expect_true("clarity" %in% levels(p$data$variable)) expect_true(is.numeric(p$data$value)) expect_equal(mapping_string(p$mapping$colour), colnames(ds2)[2]) p <- ggparcoord( data = ds2, columns = c( "carat", "color", "clarity", "depth", "table", "price", "x", "y", "z" ), order = c(1, 3:10), groupColumn = "cut" ) expect_true("color" %in% levels(p$data$variable)) expect_true("clarity" %in% levels(p$data$variable)) expect_true(is.numeric(p$data$value)) expect_equal(levels(p$data$cut), levels(ds2$cut)) # group column is a regular column ## factor # p <- ggparcoord(data = ds2, columns = c(1, 3:10), groupColumn = 4) # expect_true("clarity" %in% levels(p$data$variable)) ## character # p <- ggparcoord(data = ds2, columns = c(1, 3:10), groupColumn = 3) # expect_true("color" %in% levels(p$data$variable)) ## numeric # p <- ggparcoord(data = ds2, columns = c(1, 3:10), groupColumn = 1) # expect_true("carat" %in% levels(p$data$variable)) }) test_that("scale", { for (scale in c("std", "robust", "uniminmax", "globalminmax", "center", "centerObs")) { p <- ggparcoord(data = diamonds.samp, columns = c(1, 5:10), groupColumn = 2, scale = scale) } expect_true(TRUE) }) test_that("missing", { ds2 <- diamonds.samp ds2[3, 1] <- NA for (missing in c("exclude", "mean", "median", "min10", "random")) { p <- ggparcoord(data = ds2, columns = c(1, 5:10), groupColumn = 2, missing = missing) } expect_true(TRUE) }) test_that("order", { if (requireNamespace("scagnostics", quietly = TRUE)) { for (ordering in c( "Outlying", "Skewed", "Clumpy", "Sparse", "Striated", "Convex", "Skinny", "Stringy", "Monotonic" )) { p <- ggparcoord(data = diamonds.samp, columns = c(1, 5:10), groupColumn = 2, order = ordering) expect_true(all(levels(p$data) != c("carat", "depth", "table", "price", "x", "y", "z"))) } } for (ordering in c("skewness", "allClass", "anyClass")) { p <- ggparcoord(data = diamonds.samp, columns = c(1, 5:10), groupColumn = 2, order = ordering) expect_true(all(levels(p$data) != c("carat", "depth", "table", "price", "x", "y", "z"))) } }) test_that("basic", { # no color supplied p <- ggparcoord(data = diamonds.samp, columns = c(1, 5:10)) expect_true(is.null(p$mapping$colour)) # color supplied p <- ggparcoord(data = diamonds.samp, columns = c(1, 5:10), groupColumn = 2) expect_false(is.null(p$mapping$colour)) # title supplied ttl <- "Parallel Coord. Plot of Diamonds Data" p <- ggparcoord(data = diamonds.samp, columns = c(1, 5:10), title = ttl) expect_equal(p$labels$title, ttl) col <- "blue" p <- ggparcoord(data = diamonds.samp, columns = c(1, 5:10), shadeBox = col) expect_equal(length(p$layers), 2) expect_equal(get("aes_params", envir = p$layers[[1]])$colour, col) p <- ggparcoord(data = diamonds.samp, columns = c(1, 5:10), mapping = ggplot2::aes(size = 1)) expect_equal(length(p$layers), 1) expect_equal(p$mapping$size, 1) }) test_that("size", { p <- ggparcoord(data = diamonds.samp, columns = c(1, 5:10), mapping = ggplot2::aes(size = gear)) expect_equal(mapping_string(p$mapping$size), "gear") p <- ggparcoord(data = diamonds.samp, columns = c(1, 5:10)) + ggplot2::aes(size = gear) expect_equal(mapping_string(p$mapping$size), "gear") }) test_that("columns containing only a single value do not cause an scaling error", { df <- data.frame(obs = 1:5, var1 = sample(10, 5), var2 = rep(3, 5)) # no scaling expect_silent(ggparcoord(data = df, columns = 1:3, scale = "globalminmax")) # requires scaling, must not throw an errror due to scaling the single values (to NaN) expect_silent(ggparcoord(data = df, columns = 1:3, scale = "uniminmax")) df2 <- data.frame(df, var3 = factor(c("a", "b", "c", "a", "c"))) # requires scaling, must not throw an errror due to scaling the single values (to NaN) expect_silent(ggparcoord(data = df2, columns = 1:4, scale = "uniminmax")) df3 <- data.frame(df2, var4 = factor(c("d", "d", "d", "d", "d"))) expect_silent(ggparcoord(data = df3, columns = 1:4, scale = "uniminmax")) expect_silent(ggparcoord(data = df3, columns = 1:4, scale = "robust")) expect_silent(ggparcoord(data = df3, columns = 1:4, scale = "std")) }) GGally/tests/testthat/test-gglegend.R0000644000176200001440000000511414562447013017316 0ustar liggesuserslibrary(ggplot2) test_that("examples", { histPlot <- ggplot(diamonds, aes(price, fill = cut)) + geom_histogram(binwidth = 500) (right <- histPlot) (bottom <- histPlot + theme(legend.position = "bottom")) (top <- histPlot + theme(legend.position = "top")) (left <- histPlot + theme(legend.position = "left")) expect_legend <- function(name, p) { plotLegend <- grab_legend(p) expect_true(inherits(plotLegend, "gtable")) expect_true(inherits(plotLegend, "gTree")) expect_true(inherits(plotLegend, "grob")) vdiffr::expect_doppelganger(paste0("pos-", name), plotLegend) } expect_legend("right", right) expect_legend("bottom", bottom) expect_legend("top", top) expect_legend("left", left) }) test_that("legend", { # display regular plot vdiffr::expect_doppelganger( "legend", ggally_points(iris, ggplot2::aes(Sepal.Length, Sepal.Width, color = Species)) ) # Make a function that will only print the legend points_legend <- gglegend(ggally_points) l <- points_legend( iris, ggplot2::aes(Sepal.Length, Sepal.Width, color = Species) ) vdiffr::expect_doppelganger("points", l) # produce the sample legend plot, but supply a string that 'wrap' understands same_points_legend <- gglegend("points") expect_identical( attr(attr(points_legend, "fn"), "original_fn"), attr(attr(same_points_legend, "fn"), "original_fn") ) # Complicated examples custom_legend <- wrap(gglegend("points"), size = 6) p <- custom_legend( iris, ggplot2::aes(Sepal.Length, Sepal.Width, color = Species) ) vdiffr::expect_doppelganger("custom", p) expect_true(inherits(p, "gtable")) expect_true(inherits(p, "gTree")) expect_true(inherits(p, "grob")) # Use within ggpairs expect_silent({ pm <- ggpairs( iris, 1:2, mapping = ggplot2::aes(color = Species), upper = list(continuous = gglegend("points")) ) }) vdiffr::expect_doppelganger("legend-pm", pm) # Use within ggpairs expect_silent({ pm <- ggpairs( iris, 1:2, mapping = ggplot2::aes(color = Species) ) pm[1, 2] <- points_legend(iris, ggplot2::aes(Sepal.Width, Sepal.Length, color = Species)) }) vdiffr::expect_doppelganger("internal-legend", pm) }) test_that("plotNew", { points_legend <- gglegend(ggally_points) vdiffr::expect_doppelganger( "plotNew-default", points_legend( iris, ggplot2::aes(Sepal.Length, Sepal.Width, color = Species) ) ) expect_silent( print( points_legend( iris, ggplot2::aes(Sepal.Length, Sepal.Width, color = Species) ), plotNew = TRUE ) ) }) GGally/tests/testthat/test-utils.R0000644000176200001440000000143114562447013016700 0ustar liggesusers# test_that("require_namespaces", { # skip("This test is too error prone") # if ("Hmisc" %in% loadedNamespaces()) unloadNamespace("Hmisc") # #NB: survival is required by Hmisc, so Hmisc must be unloaded before # if ("multcomp" %in% loadedNamespaces()) unloadNamespace("multcomp") # #NB: survival is required by multcomp, so multcomp must be unloaded before # if ("survival" %in% loadedNamespaces()) unloadNamespace("survival") # expect_false("package:survival" %in% search()) # suppressMessages(require_namespaces(c("survival"))) # expect_false("package:survival" %in% search()) # expect_false(is.null(getNamespace("survival"))) # expect_error( # suppressWarnings(suppressMessages( # require_namespaces("DOES_NOT_EXIST_qweqweqweqwe") # )) # ) # }) GGally/tests/testthat/test-crosstalk.R0000644000176200001440000000210114562447013017540 0ustar liggesusers test_that("crosstalk works with ggduo and ggpairs", { skip_if_not_installed("crosstalk") sd <- try(crosstalk::SharedData$new(iris[1:4]), silent = TRUE) if (inherits(sd, "try-error")) { skip("crosstalk data can not be initialized") } expect_silent({ pm <- ggpairs(sd) }) expect_error( { pm <- ggpairs(sd, 3:5) }, "Make sure your numeric" ) expect_error( { pm <- ggpairs(sd, c("Petal.Length", "Petal.Width", crosstalk_key())) }, "Columns in 'columns' not" ) expect_silent({ pm <- ggduo(sd) }) expect_error( { pm <- ggduo(sd, c(1:2, 5), 3:5) }, "Make sure your numeric 'columnsX'" ) expect_error( { pm <- ggduo( sd, c("Sepal.Length", "Sepal.Width", crosstalk_key()), c("Petal.Length", "Petal.Width") ) }, "Columns in 'columnsX' not" ) expect_error( { pm <- ggduo( sd, c("Sepal.Length", "Sepal.Width"), c("Petal.Length", "Petal.Width", crosstalk_key()) ) }, "Columns in 'columnsY' not" ) }) GGally/tests/testthat/test-ggnostic.R0000644000176200001440000000467114562447013017366 0ustar liggesusers test_that("fn_switch", { fn1 <- function(data, mapping, ...) { return(1) } fn2 <- function(data, mapping, ...) { return(2) } fn3 <- function(data, mapping, ...) { return(3) } fn5 <- function(data, mapping, ...) { return(5) } fn <- fn_switch(list(A = fn1, B = fn2, C = fn3), "value") dummy_dt <- data.frame(A = rnorm(100), B = rnorm(100), C = rnorm(100)) chars <- c("A", "B", "C") for (i in 1:3) { mapping <- ggplot2::aes(value = !!as.name(chars[i])) expect_equal(fn(dummy_dt, mapping), i) } fn <- fn_switch(list(A = fn1, default = fn5), "value") expect_equal(fn(dummy_dt, ggplot2::aes(value = !!as.name("A"))), 1) expect_equal(fn(dummy_dt, ggplot2::aes(value = !!as.name("B"))), 5) expect_equal(fn(dummy_dt, ggplot2::aes(value = !!as.name("C"))), 5) fn <- fn_switch(list(A = fn1), "value") expect_equal(fn(dummy_dt, ggplot2::aes(value = !!as.name("A"))), 1) expect_error(fn(dummy_dt, ggplot2::aes(value = !!as.name("B"))), "function could not be found") }) test_that("model_beta_label", { mod <- lm(mpg ~ wt + qsec + am, mtcars) expect_equal(model_beta_label(mod), c("wt***", "qsec***", "am*")) expect_equal(model_beta_label(mod, lmStars = FALSE), c("wt", "qsec", "am")) }) test_that("ggnostic mtcars", { mtc <- mtcars mtc$am <- c("0" = "automatic", "1" = "manual")[as.character(mtc$am)] mod <- lm(mpg ~ wt + qsec + am, data = mtc) continuous_type <- list( .resid = wrap(ggally_nostic_resid, method = "loess"), .std.resid = wrap(ggally_nostic_std_resid, method = "loess") ) pm <- ggnostic( mod, mapping = ggplot2::aes(), columnsY = c("mpg", ".fitted", ".se.fit", ".resid", ".std.resid", ".sigma", ".hat", ".cooksd"), continuous = continuous_type, progress = FALSE ) vdiffr::expect_doppelganger("custom-y", pm) pm <- ggnostic( mod, mapping = ggplot2::aes(color = am), legend = c(1, 3), continuous = continuous_type, progress = FALSE ) vdiffr::expect_doppelganger("legend", pm) }) test_that("error checking", { get_cols <- function(cols) { match_nostic_columns( cols, c("mpg", broom_columns()), "columnsY" ) } expect_equal( get_cols(c(".resid", ".sig", ".hat", ".c")), c(".resid", ".sigma", ".hat", ".cooksd") ) expect_error( get_cols(c( "not_there", ".fitted", ".se.fit", ".resid", ".std.resid", ".sigma", ".hat", ".cooksd" )), "Could not match 'columnsY'" ) }) GGally/tests/testthat/test-deprecated.R0000644000176200001440000000022714562447013017642 0ustar liggesusers data(tips) test_that("ggally-cor", { expect_silent( p <- ggally_cor_v1_5(tips, ggplot2::aes(!!as.name("total_bill"), !!as.name("tip"))) ) }) GGally/tests/testthat/test-ggsurv.R0000644000176200001440000001054214562447013017060 0ustar liggesuserssuppressMessages(require(survival)) suppressMessages(require(scales)) lung <- survival::lung kidney <- survival::kidney sf.lung <- survival::survfit(Surv(time, status) ~ 1, data = lung) sf.kid <- survival::survfit(Surv(time, status) ~ disease, data = kidney) test_that("single", { a <- ggsurv(sf.lung) expect_equal(mapping_string(a$mapping$x), "time") expect_equal(mapping_string(a$mapping$y), "surv") expect_true(is.null(a$labels$group)) expect_true(is.null(a$labels$colour)) expect_true(is.null(a$labels$linetype)) }) test_that("multiple", { a <- ggsurv(sf.kid) expect_equal(mapping_string(a$mapping$x), "time") expect_equal(mapping_string(a$mapping$y), "surv") expect_true(!is.null(a$labels$group)) expect_true(!is.null(a$labels$colour)) expect_true(!is.null(a$labels$linetype)) }) test_that("adjust plot", { a <- ggsurv(sf.kid, plot.cens = FALSE) expect_equal(length(a$layers), 1) a <- ggsurv(sf.kid, plot.cens = TRUE) expect_equal(length(a$layers), 2) }) test_that("stops", { noCensor <- subset(lung, status == 1) lungNoCensor <- survival::survfit(Surv(time, status) ~ 1, data = noCensor) # check that the surv.col and lty.est are of the correct length expect_error(ggsurv(lungNoCensor, surv.col = c("black", "red"))) expect_error(ggsurv(lungNoCensor, lty.est = 1:2)) # must have censor to plot expect_error(ggsurv(lungNoCensor, plot.cens = TRUE)) noCensor <- subset(kidney, status == 1) kidneyNoCensor <- survival::survfit(Surv(time, status) ~ disease, data = noCensor) # check that the surv.col and lty.est are of the correct length. should be 4 expect_error(ggsurv(kidneyNoCensor, surv.col = c("black", "red", "blue"))) expect_error(ggsurv(kidneyNoCensor, lty.est = 1:3)) # must have censor to plot expect_error(ggsurv(kidneyNoCensor, plot.cens = TRUE)) # must have censor to plot expect_silent( ggsurv(sf.kid, CI = TRUE, surv.col = c("black", "red", "blue", "green")) ) expect_silent( ggsurv(sf.kid, CI = TRUE, lty.est = 1:4) ) ggsurv(sf.kid, CI = TRUE, surv.col = "red") }) test_that("back.white", { sf.lung <- survival::survfit(Surv(time, status) ~ 1, data = lung) sf.kid <- survival::survfit(Surv(time, status) ~ disease, data = kidney) a <- ggsurv(sf.lung, back.white = FALSE) expect_true(length(a$theme) == 0) a <- ggsurv(sf.lung, back.white = TRUE) expect_true(length(a$theme) != 0) a <- ggsurv(sf.kid, back.white = FALSE) expect_true(length(a$theme) == 0) a <- ggsurv(sf.kid, back.white = TRUE) expect_true(length(a$theme) != 0) }) test_that("surv.col", { ggsurv(sf.lung, surv.col = "red") ggsurv(sf.kid, surv.col = "red") ggsurv(sf.kid, surv.col = c("black", "red", "blue", "green")) ggsurv(sf.kid, lty.est = 1) ggsurv(sf.kid, lty.est = 1:4) expect_true("idk how to test it happened" != "fail") }) test_that("CI", { a <- ggsurv(sf.lung, CI = FALSE) b <- ggsurv(sf.lung, CI = TRUE) expect_equal(length(b$layers) - length(a$layers), 2) a <- ggsurv(sf.kid, CI = FALSE) b <- ggsurv(sf.kid, CI = TRUE) expect_equal(length(b$layers) - length(a$layers), 2) }) test_that("multiple colors", { p <- ggsurv(sf.kid, plot.cens = TRUE) vdiffr::expect_doppelganger("plot-cens-true", p) expect_warning( { ggsurv(sf.kid, plot.cens = TRUE, cens.col = c("red", "blue")) }, "Color scales for censored points" ) # nolint p <- ggsurv(sf.kid, plot.cens = TRUE, cens.col = "blue") vdiffr::expect_doppelganger("plot-cens-true-blue", p) custom_color <- c("green", "blue", "purple", "orange") p <- ggsurv(sf.kid, plot.cens = TRUE, cens.col = custom_color) vdiffr::expect_doppelganger("plot-cens-true-custom", p) expect_warning( { ggsurv( sf.kid, plot.cens = TRUE, cens.col = custom_color, cens.shape = c(1, 2) ) }, "The length of the censored shapes" ) # nolint p <- ggsurv( sf.kid, plot.cens = TRUE, cens.col = custom_color, cens.shape = c(1, 2, 3, 4) ) vdiffr::expect_doppelganger("plot-cens-true-custom-shape", p) }) test_that("cens.size", { a <- ggsurv(sf.lung) b <- ggsurv(sf.lung, cens.size = 5) expect_true(a$layers[[4]]$aes_params$size == 2) expect_true(b$layers[[4]]$aes_params$size != 2) a <- ggsurv(sf.kid) b <- ggsurv(sf.lung, cens.size = 5) expect_true(a$layers[[2]]$aes_params$size == 2) expect_true(b$layers[[4]]$aes_params$size != 2) }) GGally/tests/testthat/test-ggbivariate.R0000644000176200001440000000261114562447013020025 0ustar liggesusers test_that("example", { data(tips) p <- ggbivariate(tips, "smoker", c("day", "time", "sex", "tip")) vdiffr::expect_doppelganger("tips", p) # Personalize plot title and legend title p <- ggbivariate( tips, "smoker", c("day", "time", "sex", "tip"), title = "Custom title" ) + labs(fill = "Smoker ?") vdiffr::expect_doppelganger("tips-title", p) # Customize fill colour scale p <- ggbivariate(tips, "smoker", c("day", "time", "sex", "tip")) + scale_fill_brewer(type = "qual") vdiffr::expect_doppelganger("tips-fill-qual", p) # Customize labels p <- ggbivariate( tips, "smoker", c("day", "time", "sex", "tip"), rowbar_args = list( colour = "white", size = 4, fontface = "bold", label_format = scales::label_percent(accurary = 1) ) ) vdiffr::expect_doppelganger("tips-rowbar", p) # Choose the sub-plot from which get legend p <- ggbivariate(tips, "smoker") vdiffr::expect_doppelganger("tips-legend-default", p) ggbivariate(tips, "smoker", legend = 3) vdiffr::expect_doppelganger("tips-legend-3", p) # Use mapping to indicate weights d <- as.data.frame(Titanic) p <- ggbivariate(d, "Survived", mapping = aes(weight = Freq)) vdiffr::expect_doppelganger("titanic-weight-freq", p) # outcome can be numerical p <- ggbivariate(tips, outcome = "tip", title = "tip") vdiffr::expect_doppelganger("tips-numeric", p) }) GGally/tests/testthat/test-vig_ggally.R0000644000176200001440000000052014562447013017662 0ustar liggesuserstest_that("all vignetts are accounted for", { testthat::skip_on_cran() # make sure vig dir exists vig_dir <- file.path("..", "..", "vignettes") testthat::skip_if_not(dir.exists(vig_dir)) vigs <- dir(vig_dir, pattern = "\\.Rmd$") vigs <- sub(".Rmd", "", vigs, fixed = TRUE) expect_setequal(vignettes_for_ggally, vigs) }) GGally/tests/testthat/test-ggnetworkmap.R0000644000176200001440000001646614562447013020263 0ustar liggesusers if ("package:igraph" %in% search()) { detach("package:igraph") } skip_if(!rq(network)) skip_if(!rq(sna)) skip_if(!rq(maps)) skip_if(!rq(ggplot2)) skip_if(!rq(intergraph)) # test igraph conversion skip_if_not_installed("geosphere") # first 500 rows of http://datasets.flowingdata.com/tuts/maparcs/airports.csv # avoids downloading the dataset to test the package airports <- read.csv(test_path("data/airports.csv"), header = TRUE) rownames(airports) <- airports$iata # select some random flights set.seed(123) flights <- data.frame( origin = sample(airports[200:400, ]$iata, 200, replace = TRUE), destination = sample(airports[200:400, ]$iata, 200, replace = TRUE) ) # convert to network flights <- network(flights, directed = TRUE) # add geographic coordinates flights %v% "lat" <- airports[network.vertex.names(flights), "lat"] # nolint flights %v% "lon" <- airports[network.vertex.names(flights), "long"] # nolint # drop isolated airports delete.vertices(flights, which(degree(flights) < 2)) # compute degree centrality flights %v% "degree" <- degree(flights, gmode = "digraph") # add random groups flights %v% "mygroup" <- sample(letters[1:4], network.size(flights), replace = TRUE) # create a map of the USA usa <- ggplot(map_data("usa"), aes(x = long, y = lat)) + geom_polygon(aes(group = group), color = "grey65", fill = "#f9f9f9", linewidth = 0.2 ) test_that("basic drawing", { # no map p <- ggnetworkmap(net = flights, size = 2) expect_true(is.null(nrow(p$data))) # overlay network data to map p <- ggnetworkmap(usa, flights, size = 2) expect_false(is.null(nrow(p$data))) }) test_that("great circles", { p <- ggnetworkmap(usa, flights, size = 2, great.circles = TRUE) expect_equal(length(p$layers), 3) expect_equal(get("aes_params", envir = p$layers[[3]])$colour, "black") }) test_that("node groups", { p <- ggnetworkmap(usa, flights, size = 2, great.circles = TRUE, node.group = degree ) expect_equal(length(p$layers), 3) expect_true(is.null(get("aes_params", envir = p$layers[[3]])$colour)) expect_equal(mapping_string(get("mapping", envir = p$layers[[3]])$colour), ".ngroup") p <- ggnetworkmap(usa, flights, size = 2, great.circles = TRUE, node.color = "red") expect_equal(mapping_string(get("aes_params", envir = p$layers[[3]])$colour), "\"red\"") }) test_that("ring groups", { p <- ggnetworkmap(usa, flights, size = 2, great.circles = TRUE, node.group = degree, ring.group = mygroup ) expect_equal(length(p$layers), 3) expect_true(is.null(get("aes_params", envir = p$layers[[3]])$colour)) expect_equal(mapping_string(get("mapping", envir = p$layers[[3]])$colour), ".rgroup") expect_equal(mapping_string(get("mapping", envir = p$layers[[3]])$fill), ".ngroup") }) test_that("segment color", { p <- ggnetworkmap(usa, flights, size = 2, great.circles = TRUE, node.group = degree, ring.group = mygroup, segment.color = "cornflowerblue" ) expect_equal(length(p$layers), 3) expect_true(is.null(get("aes_params", envir = p$layers[[3]])$colour)) expect_equal(mapping_string(get("mapping", envir = p$layers[[3]])$colour), ".rgroup") expect_equal(mapping_string(get("mapping", envir = p$layers[[3]])$fill), ".ngroup") expect_equal( mapping_string(get("aes_params", envir = p$layers[[2]])$colour), "\"cornflowerblue\"" ) }) test_that("weight", { p <- ggnetworkmap(usa, flights, size = 2, great.circles = TRUE, node.group = degree, ring.group = mygroup, segment.color = "cornflowerblue", weight = degree ) expect_equal(length(p$layers), 3) expect_true(is.null(get("aes_params", envir = p$layers[[3]])$colour)) expect_equal(mapping_string(get("mapping", envir = p$layers[[3]])$colour), ".rgroup") expect_equal(mapping_string(get("mapping", envir = p$layers[[3]])$fill), ".ngroup") expect_equal( mapping_string(get("aes_params", envir = p$layers[[2]])$colour), "\"cornflowerblue\"" ) expect_equal(mapping_string(get("mapping", envir = p$layers[[3]])$size), ".weight") }) test_that("labels", { p <- ggnetworkmap(usa, flights, size = 2, great.circles = TRUE, node.group = degree, ring.group = mygroup, segment.color = "cornflowerblue", weight = degree, label.nodes = TRUE ) expect_equal(length(p$layers), 4) expect_true(is.null(get("aes_params", envir = p$layers[[3]])$colour)) expect_equal(mapping_string(get("mapping", envir = p$layers[[3]])$colour), ".rgroup") expect_equal(mapping_string(get("mapping", envir = p$layers[[3]])$fill), ".ngroup") expect_equal( mapping_string(get("aes_params", envir = p$layers[[2]])$colour), "\"cornflowerblue\"" ) expect_equal(mapping_string(get("mapping", envir = p$layers[[3]])$size), ".weight") expect_equal(mapping_string(get("mapping", envir = p$layers[[4]])$label), ".label") expect_true(is.null(get("aes_params", envir = p$layers[[2]])$arrow)) }) test_that("arrows", { p <- ggnetworkmap(usa, flights, size = 2, great.circles = TRUE, node.group = degree, ring.group = mygroup, segment.color = "cornflowerblue", weight = degree, label.nodes = TRUE, arrow.size = 0.2 ) expect_equal(length(p$layers), 4) expect_true(is.null(get("aes_params", envir = p$layers[[3]])$colour)) expect_equal(mapping_string(get("mapping", envir = p$layers[[3]])$colour), ".rgroup") expect_equal(mapping_string(get("mapping", envir = p$layers[[3]])$fill), ".ngroup") expect_equal( mapping_string(get("aes_params", envir = p$layers[[2]])$colour), "\"cornflowerblue\"" ) expect_equal(mapping_string(get("mapping", envir = p$layers[[3]])$size), ".weight") expect_equal(mapping_string(get("mapping", envir = p$layers[[4]])$label), ".label") # look at geom_params for arrow info expect_true(is.list(get("geom_params", envir = p$layers[[2]])$arrow)) }) test_that("labels", { expect_error(ggnetworkmap(usa, flights, label.nodes = c("A", "B"))) testLabels <- paste("L", 1:network.size(flights), sep = "") # does logical check p <- ggnetworkmap(usa, flights, label.nodes = testLabels) ## PROBLEM HERE: why would vertex.names be equal to testLabels? ## expect_equal(get("data", p$layers[[4]])$.label, testLabels) # does vertex.names check p <- ggnetworkmap(usa, flights, label.nodes = TRUE) expect_true(!is.null(get("data", p$layers[[4]])$.label)) # does id check flights2 <- flights flights2 %v% "id" <- testLabels p <- ggnetworkmap(usa, flights2, label.nodes = TRUE) expect_true(!is.null(get("data", p$layers[[4]])$.label)) }) ### --- test arrow.size test_that("arrow.size", { expect_error(ggnetworkmap(net = flights, arrow.size = -1), "incorrect arrow.size") expect_warning(ggnetworkmap( net = network(as.matrix(flights), directed = FALSE), arrow.size = 1 ), "arrow.size ignored") }) ### --- test network coercion test_that("network coercion", { expect_warning( ggnetworkmap(net = network(matrix(1, nrow = 2, ncol = 2), loops = TRUE)), "self-loops" ) expect_error(ggnetworkmap(net = 1:2), "network object") expect_error(ggnetworkmap(net = network(data.frame(1:2, 3:4), hyper = TRUE)), "hyper") expect_error( ggnetworkmap(net = network(data.frame(1:2, 3:4), multiple = TRUE)), "multiplex graphs" ) }) ### --- test igraph functionality test_that("igraph conversion", { if (rq(igraph) && rq(intergraph)) { n <- asIgraph(flights) p <- ggnetworkmap(net = n) expect_equal(length(p$layers), 2) } }) GGally/tests/testthat/test-ggcorr.R0000644000176200001440000000566614562447013017041 0ustar liggesusers # nba <- read.csv("http://datasets.flowingdata.com/ppg2008.csv") data(flea) test_that("limits", { vdiffr::expect_doppelganger("flea", ggcorr(flea[, -1])) vdiffr::expect_doppelganger("flea-limits", ggcorr(flea[, -1], limits = TRUE)) vdiffr::expect_doppelganger("flea-no-limits", ggcorr(flea[, -1], limits = FALSE)) vdiffr::expect_doppelganger("flea-null-limits", ggcorr(flea[, -1], limits = NULL)) vdiffr::expect_doppelganger("flea-big-limits", ggcorr(flea[, -1], limits = c(-5, 5))) vdiffr::expect_doppelganger("flea-small-limits", ggcorr(flea[, -1], limits = c(-0.5, 0.5))) }) test_that("examples", { # Default output. p <- ggcorr(flea[, -1]) expect_equal(length(p$layers), 2) # Labelled output, with coefficient transparency. p <- ggcorr(flea[, -1], label = TRUE, label_alpha = TRUE, name = "" ) expect_equal(length(p$layers), 3) # Custom options. p <- ggcorr( flea[, -1], geom = "circle", max_size = 6, size = 3, hjust = 0.75, nbreaks = 6, angle = -45, palette = "PuOr" # colorblind safe, photocopy-able ) expect_equal(length(p$layers), 3) p <- ggcorr(flea[, -1], label = TRUE, name = "" ) expect_equal(length(p$layers), 3) # test other combinations of geoms + color scales ggcorr(flea[, -1], nbreaks = 4, palette = "PuOr") ggcorr(flea[, -1], nbreaks = 4, geom = "circle") ggcorr(flea[, -1], geom = "text") ggcorr(flea[, -1], geom = "text", limits = FALSE) ggcorr(flea[, -1], nbreaks = 4, geom = "text") ggcorr(flea[, -1], nbreaks = 4, palette = "PuOr", geom = "text") ggcorr(flea[, -1], label = TRUE, label_alpha = 0.5) }) test_that("non-numeric data", { expect_warning(ggcorr(flea), "not numeric") }) test_that("null midpoint", { expect_message(ggcorr(flea[, -1], midpoint = NULL), "Color gradient") }) test_that("further options", { vdiffr::expect_doppelganger("geom-circle", ggcorr(flea[, -1], geom = "circle")) vdiffr::expect_doppelganger("geom-circle-no-limits", ggcorr(flea[, -1], geom = "circle", limits = FALSE)) vdiffr::expect_doppelganger("geom-tile", ggcorr(flea[, -1], geom = "tile", nbreaks = 3)) vdiffr::expect_doppelganger("geom-tile-no-limits", ggcorr(flea[, -1], geom = "tile", limits = FALSE)) expect_error(ggcorr(flea[, -1], layout.exp = "a"), "incorrect layout.exp") vdiffr::expect_doppelganger("layout.exp", ggcorr(flea[, -1], layout.exp = 1)) }) test_that("data.matrix", { p <- ggcorr(data.matrix(flea[, -1])) expect_equal(length(p$layers), 2) }) test_that("cor_matrix", { p <- ggcorr(data = NULL, cor_matrix = cor(flea[, -1], use = "pairwise")) expect_equal(length(p$layers), 2) }) test_that("other geoms", { expect_error(ggcorr(flea[, -1], geom = "hexbin"), "incorrect geom") vdiffr::expect_doppelganger( "geom-blank", ggcorr(flea[, -1], geom = "blank") ) }) test_that("backwards compatibility", { vdiffr::expect_doppelganger( "method-everything", ggcorr(flea[, -1], method = "everything") ) }) GGally/tests/testthat/test-ggscatmat.R0000644000176200001440000000203114562447013017507 0ustar liggesusers data(flea) test_that("example", { flea2 <- flea flea2$species2 <- as.character(flea2$species) expect_warning(p <- ggscatmat(flea2, c(1:3)), "Factor variables are omitted in plot") expect_warning(p <- ggscatmat(flea2, c(2:3, 8)), "Factor variables are omitted in plot") expect_true(is.null(p$labels$colour)) vdiffr::expect_doppelganger("flea", p) p <- ggscatmat(flea, columns = 2:4, color = "species") expect_true(!is.null(p$labels$colour)) vdiffr::expect_doppelganger("flea-color", p) }) test_that("corMethod", { p <- ggscatmat(flea, columns = 2:3, corMethod = "pearson") vdiffr::expect_doppelganger("flea-pearson", p) p <- ggscatmat(flea, columns = 2:3, corMethod = "rsquare") vdiffr::expect_doppelganger("flea-rsquare", p) }) test_that("stops", { expect_error(ggscatmat(flea, columns = c(1, 2)), "Not enough numeric variables to") expect_error(ggscatmat(flea, columns = c(1, 1, 1)), "All of your variables are factors") expect_error(scatmat(flea, columns = c(1, 1, 1)), "All of your variables are factors") }) GGally/tests/testthat/test-ggmatrix_location.R0000644000176200001440000001000614527265752021261 0ustar liggesusersexpect_loc_grid <- function(loc, to_loc) { testthat::expect_equal( colnames(loc), colnames(to_loc) ) testthat::expect_equal( nrow(loc), nrow(to_loc) ) loc <- loc[order(loc$row, loc$col), ] to_loc <- to_loc[order(to_loc$row, to_loc$col), ] testthat::expect_equal( loc$row, to_loc$row ) testthat::expect_equal( loc$col, to_loc$col ) } expect_rows_cols <- function(loc, rows, cols) { to_loc <- expand.grid(row = rows, col = cols) expect_loc_grid(loc, to_loc) } test_that("rows work", { pm <- ggpairs(tips) expect_rows_cols( ggmatrix_location(pm, rows = c(3, 5)), rows = c(3, 5), cols = 1:7 ) expect_rows_cols( ggmatrix_location(pm, rows = 1), rows = 1, cols = 1:7 ) expect_error( ggmatrix_location(pm, rows = TRUE), "numeric" ) expect_error( ggmatrix_location(pm, rows = "1"), "numeric" ) }) test_that("cols work", { pm <- ggpairs(tips) expect_rows_cols( ggmatrix_location(pm, cols = c(3, 5)), rows = 1:7, cols = c(3, 5) ) expect_rows_cols( ggmatrix_location(pm, cols = 1), rows = 1:7, cols = 1 ) expect_error( ggmatrix_location(pm, cols = TRUE), "numeric" ) expect_error( ggmatrix_location(pm, cols = "1"), "numeric" ) }) test_that("location logical", { pm <- ggpairs(tips) expect_loc_grid( ggmatrix_location(pm, location = TRUE), expand.grid(row = 1:7, col = 1:7) ) expect_warning( ggmatrix_location(pm, location = FALSE) ) }) test_that("location character", { pm <- ggpairs(tips) to_loc <- expand.grid(row = 1:7, col = 1:7) expect_loc_grid( ggmatrix_location(pm, location = "all"), to_loc ) expect_loc_grid( ggmatrix_location(pm, location = "none"), subset(to_loc, FALSE) ) expect_loc_grid( ggmatrix_location(pm, location = "upper"), subset(to_loc, col > row) ) expect_loc_grid( ggmatrix_location(pm, location = "lower"), subset(to_loc, col < row) ) expect_loc_grid( ggmatrix_location(pm, location = "diag"), subset(to_loc, col == row) ) expect_error( ggmatrix_location(pm, location = "unknown") ) }) test_that("location matrix", { pm <- ggpairs(tips) to_loc <- subset(expand.grid(row = 1:7, col = 1:7), row %in% c(3, 5) | col %in% c(3, 5)) mat <- matrix(FALSE, nrow = 7, ncol = 7, byrow = TRUE) mat[, c(3, 5)] <- TRUE mat[c(3, 5), ] <- TRUE expect_loc_grid( ggmatrix_location(pm, location = mat), to_loc ) expect_loc_grid( ggmatrix_location(pm, location = as.data.frame(mat)), to_loc ) mat2 <- mat mat2[TRUE] <- FALSE expect_loc_grid( ggmatrix_location(pm, location = mat2), subset(to_loc, FALSE) ) expect_error( ggmatrix_location(pm, location = mat[, 1:6]) ) expect_error( ggmatrix_location(pm, location = mat[1:6, ]) ) expect_error( ggmatrix_location(pm, location = cbind(mat, 1)) ) expect_error( ggmatrix_location(pm, location = rbind(mat, 1)) ) }) test_that("location matrix", { pm <- ggpairs(tips) to_loc <- expand.grid(row = 1:7, col = 1:7) expect_loc_grid( ggmatrix_location(pm), expand.grid(row = 1:7, col = 1:7) ) expect_error( ggmatrix_location(pm, location = expand.grid(row = 1:7, col = 2:8)) ) expect_error( ggmatrix_location(pm, location = expand.grid(row = 2:8, col = 1:7)) ) expect_error( ggmatrix_location(pm, location = expand.grid(row = 1:7, col = 0:6)) ) expect_error( ggmatrix_location(pm, location = expand.grid(row = 0:6, col = 1:7)) ) expect_error( ggmatrix_location(pm, location = expand.grid(row = 1:7, col = c(1:6, NA))) ) expect_error( ggmatrix_location(pm, location = expand.grid(row = c(1:6, NA), col = 1:7)) ) }) test_that("location recursion", { pm <- ggpairs(tips) to_loc <- expand.grid(row = 1:7, col = 1:7) expect_loc_grid( ggmatrix_location(pm), expand.grid(row = 1:7, col = 1:7) ) expect_loc_grid( ggmatrix_location(pm, location = ggmatrix_location(pm)), expand.grid(row = 1:7, col = 1:7) ) }) GGally/tests/testthat/test-ggnet2.R0000644000176200001440000002066114562447013016734 0ustar liggesusers if ("package:igraph" %in% search()) { detach("package:igraph") } rq(network) # network objects rq(sna) # placement and centrality rq(ggplot2) # grammar of graphics rq(grid) # arrows rq(scales) # sizing rq(intergraph) # test igraph conversion rq(RColorBrewer) # test ColorBrewer palettes test_that("examples", { ### --- start: documented examples set.seed(54321) # random adjacency matrix x <- 10 ndyads <- x * (x - 1) density <- x / ndyads m <- matrix(0, nrow = x, ncol = x) dimnames(m) <- list(letters[1:x], letters[1:x]) m[row(m) != col(m)] <- runif(ndyads) < density m # random undirected network n <- network::network(m, directed = FALSE) n ggnet2(n, label = TRUE) # ggnet2(n, label = TRUE, shape = 15) # ggnet2(n, label = TRUE, shape = 15, color = "black", label.color = "white") # add vertex attribute x <- network.vertex.names(n) # nolint x <- ifelse(x %in% c("a", "e", "i"), "vowel", "consonant") n %v% "phono" <- x ggnet2(n, color = "phono") ggnet2(n, color = "phono", palette = c("vowel" = "gold", "consonant" = "grey")) ggnet2(n, shape = "phono", color = "phono") # random groups n %v% "group" <- sample(LETTERS[1:3], 10, replace = TRUE) ggnet2(n, color = "group", palette = "Set2") # random weights n %e% "weight" <- sample(1:3, network.edgecount(n), replace = TRUE) ggnet2(n, edge.size = "weight", edge.label = "weight") # Padgett's Florentine wedding data data(flo, package = "network") flo ggnet2(flo, label = TRUE) ggnet2(flo, label = TRUE, label.trim = 4, vjust = -1, size = 3, color = 1) # ggnet2(flo, label = TRUE, size = 12, color = "white") ### --- end: documented examples # test node assignment errors expect_error(ggnet2(n, color = NA)) expect_error(ggnet2(n, color = -1)) expect_error(ggnet2(n, color = rep("red", network.size(n) - 1))) # test node assignment ggnet2(n, color = rep("red", network.size(n))) # test node assignment errors expect_error(ggnet2(n, edge.color = NA)) expect_error(ggnet2(n, edge.color = -1)) expect_error(ggnet2(n, edge.color = rep("red", network.edgecount(n) - 1))) # test edge assignment ggnet2(n, edge.color = rep("red", network.edgecount(n))) # ggnet2(n, edge.color = "weight") # test mode = c("x", "y") ggnet2(n, mode = matrix(1, ncol = 2, nrow = 10)) n %v% "x" <- sample(1:10) n %v% "y" <- sample(1:10) ggnet2(n, mode = c("x", "y")) expect_error(ggnet2(n, mode = c("xx", "yy")), "not found") expect_error(ggnet2(n, mode = c("phono", "phono")), "not numeric") expect_error(ggnet2(n, mode = matrix(1, ncol = 2, nrow = 9)), "coordinates length") # test arrow.size expect_error(ggnet2(n, arrow.size = -1), "incorrect arrow.size") expect_warning(ggnet2(n, arrow.size = 1), "arrow.size ignored") # test arrow.gap suppressWarnings(expect_error( ggnet(n, arrow.size = 12, arrow.gap = -1), "incorrect arrow.gap" )) suppressWarnings(expect_warning( ggnet(n, arrow.size = 12, arrow.gap = 0.1), "arrow.gap ignored" # network is undirected; arrow.gap ignored )) suppressWarnings(expect_warning( ggnet(n, arrow.size = 12, arrow.gap = 0.1), "arrow.size ignored" # network is undirected; arrow.size ignored )) m <- network::network(m, directed = TRUE) ggnet2(m, arrow.size = 12, arrow.gap = 0.05) # test max_size expect_error(ggnet2(n, max_size = NA), "incorrect max_size") # test na.rm expect_error(ggnet2(n, na.rm = 1:2), "incorrect na.rm") expect_error(ggnet2(n, na.rm = "xyz"), "not found") n %v% "missing" <- ifelse(n %v% "phono" == "vowel", NA, n %v% "phono") expect_message(ggnet2(n, na.rm = "missing"), "removed") n %v% "missing" <- NA suppressMessages({ expect_warning(ggnet2(n, na.rm = "missing"), "removed all nodes") }) # test size = "degree" ggnet2(n, size = "degree") # test size.min expect_error(ggnet2(n, size = "degree", size.min = -1), "incorrect size.min") expect_message(ggnet2(n, size = "degree", size.min = 1), "size.min removed") suppressMessages({ expect_warning(ggnet2(n, size = "abc", size.min = 1), "not numeric") expect_warning(ggnet2(n, size = 4, size.min = 5), "removed all nodes") }) # test size.max expect_error(ggnet2(n, size = "degree", size.max = -1), "incorrect size.max") expect_message(ggnet2(n, size = "degree", size.max = 99), "size.max removed") suppressMessages({ expect_warning(ggnet2(n, size = "abc", size.max = 1), "not numeric") expect_warning(ggnet2(n, size = 4, size.max = 3), "removed all nodes") }) # test size.cut ggnet2(n, size = 1:10, size.cut = 3) ggnet2(n, size = 1:10, size.cut = TRUE) expect_error(ggnet2(n, size = 1:10, size.cut = NA), "incorrect size.cut") expect_error(ggnet2(n, size = 1:10, size.cut = "xyz"), "incorrect size.cut") expect_warning(ggnet2(n, size = "abc", size.cut = 3), "not numeric") expect_warning(ggnet2(n, size = 1, size.cut = 3), "ignored") # test alpha.palette ggnet2(n, alpha = "phono", alpha.palette = c("vowel" = 1, "consonant" = 0.5)) ggnet2(n, alpha = factor(1:10)) expect_error( ggnet2(n, alpha = "phono", alpha.palette = c("vowel" = 1)), "no alpha.palette value" ) # test color.palette # ggnet2(n, color = "phono", color.palette = c("vowel" = 1, "consonant" = 2)) ggnet2(n, color = factor(1:10)) ggnet2(n, color = "phono", palette = "Set1") # only 2 groups, palette has min. 3 expect_error(ggnet2(n, color = factor(1:10), palette = "Set1"), "too many node groups") expect_error( ggnet2(n, color = "phono", color.palette = c("vowel" = 1)), "no color.palette value" ) # test shape.palette ggnet2(n, shape = "phono", shape.palette = c("vowel" = 15, "consonant" = 19)) expect_warning(ggnet2(n, shape = factor(1:10)), "discrete values") expect_error( ggnet2(n, shape = "phono", shape.palette = c("vowel" = 1)), "no shape.palette value" ) # test size.palette ggnet2(n, size = "phono", size.palette = c("vowel" = 1, "consonant" = 2)) ggnet2(n, size = factor(1:10)) expect_error(ggnet2(n, size = "phono", size.palette = c("vowel" = 1)), "no size.palette value") # test node.label ggnet2(n, label = sample(letters, 10)) ggnet2(n, label = "phono") # test label.alpha expect_error(ggnet2(n, label = TRUE, label.alpha = "xyz"), "incorrect label.alpha") # test label.color expect_error(ggnet2(n, label = TRUE, label.color = "xyz"), "incorrect label.color") # test label.size expect_error(ggnet2(n, label = TRUE, label.size = "xyz"), "incorrect label.size") # test label.trim expect_error(ggnet2(n, label = TRUE, label.trim = "xyz"), "incorrect label.trim") ggnet2(n, label = TRUE, label.trim = toupper) # test mode expect_error(ggnet2(n, mode = "xyz"), "unsupported") expect_error(ggnet2(n, mode = letters[1:3]), "incorrect mode") # test edge.node shared colors ggnet2(n, color = "phono", edge.color = c("color", "grey")) # test edge.color expect_error(ggnet2(n, edge.color = "xyz"), "incorrect edge.color") # test edge.label.alpha expect_error( ggnet2(n, edge.label = "xyz", edge.label.alpha = "xyz"), "incorrect edge.label.alpha" ) # test edge.label.color expect_error( ggnet2(n, edge.label = "xyz", edge.label.color = "xyz"), "incorrect edge.label.color" ) # test edge.label.size expect_error(ggnet2(n, edge.label = "xyz", edge.label.size = "xyz"), "incorrect edge.label.size") # test edge.size expect_error(ggnet2(n, edge.size = "xyz"), "incorrect edge.size") # test layout.exp expect_error(ggnet2(n, layout.exp = "xyz")) ggnet2(n, layout.exp = 0.1) ### --- test bipartite functionality # weighted adjacency matrix bip <- data.frame( event1 = c(1, 2, 1), event2 = c(0, 0, 3), event3 = c(1, 1, 0), row.names = letters[1:3] ) # weighted bipartite network bip <- network( bip, matrix.type = "bipartite", ignore.eval = FALSE, # names.eval = "weights" ) # test bipartite mode ggnet2(bip, color = "mode") ### --- test network coercion expect_warning(ggnet2(network(matrix(1, nrow = 2, ncol = 2), loops = TRUE)), "self-loops") expect_error(ggnet2(1:2), "network object") expect_error(ggnet2(network(data.frame(1:2, 3:4), hyper = TRUE)), "hyper") expect_error(ggnet2(network(data.frame(1:2, 3:4), multiple = TRUE)), "multiplex graphs") ### --- test igraph functionality if (rq(igraph) && rq(intergraph)) { # test igraph conversion p <- ggnet2(asIgraph(n), color = "group") expect_null(p$guides$colour) # test igraph degree ggnet2(n, size = "degree") expect_true(TRUE) } }) GGally/tests/testthat/test-ggally_colbar.R0000644000176200001440000000466514562447013020355 0ustar liggesusers test_that("example", { d <- as.data.frame(Titanic) p <- ggplot(d) + aes(x = Class, fill = Survived, weight = Freq, by = Class) + geom_bar(position = "fill") + geom_text(stat = "prop", position = position_fill(.5)) vdiffr::expect_doppelganger("titanic", p) vdiffr::expect_doppelganger("titanic-facet", p + facet_grid(~Sex)) vdiffr::expect_doppelganger("titanic-dodge", ggplot(d) + aes(x = Class, fill = Survived, weight = Freq) + geom_bar(position = "dodge") + geom_text( aes(by = Survived), stat = "prop", position = position_dodge(0.9), vjust = "bottom" )) vdiffr::expect_doppelganger("titanic-stack", ggplot(d) + aes(x = Class, fill = Survived, weight = Freq, by = 1) + geom_bar() + geom_text( aes(label = scales::percent(after_stat(prop), accuracy = 1)), stat = "prop", position = position_stack(.5) )) data(tips) vdiffr::expect_doppelganger("tips", ggally_rowbar(tips, mapping = aes(x = smoker, y = sex))) # change labels' size vdiffr::expect_doppelganger("tips-size8", ggally_colbar(tips, mapping = aes(x = smoker, y = sex), size = 8)) # change labels' colour and use bold vdiffr::expect_doppelganger("tips-color-white", ggally_colbar(tips, mapping = aes(x = smoker, y = sex), colour = "white", fontface = "bold" )) # display number of observations instead of proportions vdiffr::expect_doppelganger("tips-label", ggally_colbar(tips, mapping = aes(x = smoker, y = sex, label = after_stat(count)))) # custom bar width vdiffr::expect_doppelganger("tips-bar-width", ggally_colbar(tips, mapping = aes(x = smoker, y = sex), geom_bar_args = list(width = .5))) # change format of labels vdiffr::expect_doppelganger("tips-label-custom", ggally_colbar(tips, mapping = aes(x = smoker, y = sex), label_format = scales::label_percent(accuracy = .01, decimal.mark = ",") )) vdiffr::expect_doppelganger("ggduo-titanic", ggduo( data = as.data.frame(Titanic), mapping = aes(weight = Freq), columnsX = "Survived", columnsY = c("Sex", "Class", "Age"), types = list(discrete = "rowbar"), legend = 1 )) }) test_that("stat_prop() works with an y aesthetic", { d <- as.data.frame(Titanic) p <- ggplot(d) + aes(y = Class, fill = Survived, weight = Freq, by = Class) + geom_bar(position = "fill") + geom_text(stat = "prop", position = position_fill(.5)) vdiffr::expect_doppelganger("titanic-stat-prop", p) }) GGally/tests/testthat.R0000644000176200001440000000016414527265752014576 0ustar liggesusersif (requireNamespace("testthat", quietly = TRUE)) { library(testthat) library(GGally) test_check("GGally") } GGally/R/0000755000176200001440000000000014562736311011642 5ustar liggesusersGGally/R/ggally_cross.R0000644000176200001440000002253214527265752014470 0ustar liggesusers#' Plots the number of observations #' #' Plot the number of observations by using square points #' with proportional areas. Could be filled according to chi-squared #' statistics computed by [stat_cross()]. Labels could also #' be added (see examples). #' #' @param data data set using #' @param mapping aesthetics being used #' @param ... other arguments passed to [ggplot2::geom_point()] #' @param scale_max_size `max_size` argument supplied to [ggplot2::scale_size_area()] #' @param geom_text_args other arguments passed to [ggplot2::geom_text()] #' @author Joseph Larmarange #' @keywords hplot #' @export #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' data(tips) #' p_(ggally_cross(tips, mapping = aes(x = smoker, y = sex))) #' p_(ggally_cross(tips, mapping = aes(x = day, y = time))) #' #' # Custom max size #' p_(ggally_cross(tips, mapping = aes(x = smoker, y = sex)) + #' scale_size_area(max_size = 40)) #' #' # Custom fill #' p_(ggally_cross(tips, mapping = aes(x = smoker, y = sex), fill = "red")) #' #' # Custom shape #' p_(ggally_cross(tips, mapping = aes(x = smoker, y = sex), shape = 21)) #' #' # Fill squares according to standardized residuals #' d <- as.data.frame(Titanic) #' p_(ggally_cross( #' d, #' mapping = aes(x = Class, y = Survived, weight = Freq, fill = after_stat(std.resid)) #' ) + #' scale_fill_steps2(breaks = c(-3, -2, 2, 3), show.limits = TRUE)) #' #' # Add labels #' p_(ggally_cross( #' tips, #' mapping = aes( #' x = smoker, y = sex, colour = smoker, #' label = scales::percent(after_stat(prop)) #' ) #' )) #' #' # Customize labels' appearance and same size for all squares #' p_(ggally_cross( #' tips, #' mapping = aes( #' x = smoker, y = sex, #' size = NULL, # do not map size to a variable #' label = scales::percent(after_stat(prop)) #' ), #' size = 40, # fix value for points size #' fill = "darkblue", #' geom_text_args = list(colour = "white", fontface = "bold", size = 6) #' )) ggally_cross <- function(data, mapping, ..., scale_max_size = 20, geom_text_args = NULL) { mapping <- remove_color_unless_equal(mapping, to = c("x", "y")) mapping <- mapping_color_to_fill(mapping) args <- list(...) # default values for geom_point if (!"size" %in% names(mapping)) { mapping$size <- aes(size = after_stat(!!as.name("observed")))$size } if (is.null(mapping$shape) && is.null(args$shape)) { args$shape <- 22 } if (is.null(mapping$fill) && is.null(args$fill)) { args$fill <- GeomRect$default_aes$fill } args$keep.zero.cells <- FALSE p <- ggplot(data = data, mapping) + do.call(stat_cross, args) + scale_size_area(max_size = scale_max_size) # default values for geom_text geom_text_args$stat <- "cross" geom_text_args$keep.zero.cells <- FALSE if (is.null(geom_text_args$mapping)) { geom_text_args$mapping <- aes(colour = NULL, size = NULL) } if (is.null(geom_text_args$show.legend)) { geom_text_args$show.legend <- FALSE } if (!is.null(mapping$label)) { p <- p + do.call(geom_text, geom_text_args) } p } #' Display a table of the number of observations #' #' Plot the number of observations as a table. Other statistics computed #' by \code{\link{stat_cross}} could be used (see examples). #' #' @param data data set using #' @param mapping aesthetics being used #' @param keep.zero.cells If \code{TRUE}, display cells with no observation. #' @param ... other arguments passed to \code{\link[ggplot2]{geom_text}(...)} #' @param geom_tile_args other arguments passed to \code{\link[ggplot2]{geom_tile}(...)} #' @note The \strong{colour} aesthetic is taken into account only if equal to #' \strong{x} or \strong{y}. #' @author Joseph Larmarange #' @keywords hplot #' @export #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' data(tips) #' p_(ggally_table(tips, mapping = aes(x = smoker, y = sex))) #' p_(ggally_table(tips, mapping = aes(x = day, y = time))) #' p_(ggally_table(tips, mapping = aes(x = smoker, y = sex, colour = smoker))) #' #' # colour is kept only if equal to x or y #' p_(ggally_table(tips, mapping = aes(x = smoker, y = sex, colour = day))) #' #' # diagonal version #' p_(ggally_tableDiag(tips, mapping = aes(x = smoker))) #' #' # custom label size and color #' p_(ggally_table(tips, mapping = aes(x = smoker, y = sex), size = 16, color = "red")) #' #' # display column proportions #' p_(ggally_table( #' tips, #' mapping = aes(x = day, y = sex, label = scales::percent(after_stat(col.prop))) #' )) #' #' # draw table cells #' p_(ggally_table( #' tips, #' mapping = aes(x = smoker, y = sex), #' geom_tile_args = list(colour = "black", fill = "white") #' )) #' #' # Use standardized residuals to fill table cells #' p_(ggally_table( #' as.data.frame(Titanic), #' mapping = aes( #' x = Class, y = Survived, weight = Freq, #' fill = after_stat(std.resid), #' label = scales::percent(after_stat(col.prop), accuracy = .1) #' ), #' geom_tile_args = list(colour = "black") #' ) + #' scale_fill_steps2(breaks = c(-3, -2, 2, 3), show.limits = TRUE)) ggally_table <- function(data, mapping, keep.zero.cells = FALSE, ..., geom_tile_args = NULL) { mapping <- remove_color_unless_equal(mapping, to = c("x", "y")) # default values geom_text if (!"label" %in% names(mapping)) { mapping$label <- aes(label = after_stat(!!as.name("observed")))$label } geom_text_args <- list(...) geom_text_args$stat <- "cross" geom_text_args$keep.zero.cells <- keep.zero.cells # default values geom_tile geom_tile_args$stat <- "cross" geom_tile_args$keep.zero.cells <- keep.zero.cells geom_tile_args$mapping <- aes(colour = NULL)$colour if (is.null(geom_tile_args$colour)) { geom_tile_args$colour <- "transparent" } if (is.null(mapping$fill) && is.null(geom_tile_args$fill)) { geom_tile_args$fill <- "transparent" } ggplot(data = data, mapping) + do.call(geom_tile, geom_tile_args) + do.call(geom_text, geom_text_args) } #' @export #' @rdname ggally_table ggally_tableDiag <- function(data, mapping, keep.zero.cells = FALSE, ..., geom_tile_args = NULL) { mapping$y <- mapping$x ggally_table( data = data, mapping = mapping, keep.zero.cells = keep.zero.cells, ..., geom_tile_args = geom_tile_args ) } #' Display a cross-tabulated table #' #' \code{ggally_crosstable} is a variation of \code{\link{ggally_table}} with few modifications: (i) table cells are drawn; (ii) x and y axis are not expanded (and therefore are not aligned with other \code{ggally_*} plots); (iii) content and fill of cells can be easily controlled with dedicated arguments. #' @param data data set using #' @param mapping aesthetics being used #' @param cells Which statistic should be displayed in table cells? #' @param fill Which statistic should be used for filling table cells? #' @param ... other arguments passed to \code{\link[ggplot2]{geom_text}(...)} #' @param geom_tile_args other arguments passed to \code{\link[ggplot2]{geom_tile}(...)} #' @export #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' data(tips) #' #' # differences with ggally_table() #' p_(ggally_table(tips, mapping = aes(x = day, y = time))) #' p_(ggally_crosstable(tips, mapping = aes(x = day, y = time))) #' #' # display column proportions #' p_(ggally_crosstable(tips, mapping = aes(x = day, y = sex), cells = "col.prop")) #' #' # display row proportions #' p_(ggally_crosstable(tips, mapping = aes(x = day, y = sex), cells = "row.prop")) #' #' # change size of text #' p_(ggally_crosstable(tips, mapping = aes(x = day, y = sex), size = 8)) #' #' # fill cells with standardized residuals #' p_(ggally_crosstable(tips, mapping = aes(x = day, y = sex), fill = "std.resid")) #' #' # change scale for fill #' p_(ggally_crosstable(tips, mapping = aes(x = day, y = sex), fill = "std.resid") + #' scale_fill_steps2(breaks = c(-2, 0, 2), show.limits = TRUE)) ggally_crosstable <- function( data, mapping, cells = c("observed", "prop", "row.prop", "col.prop", "expected", "resid", "std.resid"), fill = c("none", "std.resid", "resid"), ..., geom_tile_args = list(colour = "grey50")) { fill <- match.arg(fill) if (fill == "std.resid") { mapping$fill <- aes(fill = after_stat(!!as.name("std.resid")))$fill } if (fill == "resid") { mapping$fill <- aes(fill = after_stat(!!as.name("resid")))$fill } if (fill == "none") { geom_tile_args$fill <- "white" } cells <- match.arg(cells) if (!"label" %in% names(mapping) && cells %in% c("observed", "expected")) { mapping$label <- aes(label = scales::number(after_stat(!!as.name(cells)), accuracy = 1))$label } if (!"label" %in% names(mapping) && cells %in% c("prop", "row.prop", "col.prop")) { mapping$label <- aes(label = scales::percent(after_stat(!!as.name(cells)), accuracy = .1))$label } if (!"label" %in% names(mapping) && cells %in% c("resid", "std.resid")) { mapping$label <- aes(label = scales::number(after_stat(!!as.name(cells)), accuracy = .1))$label } p <- ggally_table(data = data, mapping = mapping, keep.zero.cells = TRUE, geom_tile_args = geom_tile_args, ...) + scale_x_discrete(expand = expansion(0, 0)) + scale_y_discrete(expand = expansion(0, 0)) + theme(axis.ticks = element_blank()) if (fill == "std.resid") { p <- p + scale_fill_steps2(breaks = c(-Inf, -3, -2, 2, 3, Inf)) } p } GGally/R/data-twitter_spambots.R0000644000176200001440000000141614526737233016314 0ustar liggesusers#' Twitter spambots #' #' A network of spambots found on Twitter as part of a data mining project. #' #' Each node of the network is identified by the Twitter screen name of the #' account and further carries five vertex attributes: #' #' @details \itemize{ #' \item location user's location, as provided by the user #' \item lat latitude, based on the user's location #' \item lon longitude, based on the user's location #' \item followers number of Twitter accounts that follow this account #' \item friends number of Twitter accounts followed by the account #' } #' #' @docType data #' @author Amos Elberg #' @keywords datasets #' @name twitter_spambots #' @usage data(twitter_spambots) #' @format An object of class \code{network} with 120 edges and 94 vertices. NULL GGally/R/ggnet2.R0000644000176200001440000010532214562447013013154 0ustar liggesusersif (getRversion() >= "2.15.1") { utils::globalVariables(c("X1", "X2", "Y1", "Y2", "midX", "midY")) } #' Network plot #' #' Function for plotting network objects using \pkg{ggplot2}, with additional control #' over graphical parameters that are not supported by the \code{\link{ggnet}} #' function. Please visit \url{https://github.com/briatte/ggnet} for the latest #' version of ggnet2, and \url{https://briatte.github.io/ggnet/} for a vignette #' that contains many examples and explanations. #' #' @export #' @param net an object of class \code{\link[network]{network}}, or any object #' that can be coerced to this class, such as an adjacency or incidence matrix, #' or an edge list: see \link[network]{edgeset.constructors} and #' \link[network]{network} for details. If the object is of class #' [igraph][igraph::igraph-package] and the #' [intergraph][intergraph::intergraph-package] package is installed, #' it will be used to convert the object: see #' \code{\link[intergraph]{asNetwork}} for details. #' @param mode a placement method from those provided in the #' \code{\link[sna]{sna}} package: see \link[sna:gplot.layout]{gplot.layout} for #' details. Also accepts the names of two numeric vertex attributes of #' \code{net}, or a matrix of numeric coordinates, in which case the first two #' columns of the matrix are used. #' Defaults to the Fruchterman-Reingold force-directed algorithm. #' @param layout.par options to be passed to the placement method, as listed in #' \link[sna]{gplot.layout}. #' Defaults to \code{NULL}. #' @param layout.exp a multiplier to expand the horizontal axis if node labels #' get clipped: see \link[scales]{expand_range} for details. #' Defaults to \code{0} (no expansion). #' @param alpha the level of transparency of the edges and nodes, which might be #' a single value, a vertex attribute, or a vector of values. #' Also accepts \code{"mode"} on bipartite networks (see 'Details'). #' Defaults to \code{1} (no transparency). #' @param color the color of the nodes, which might be a single value, a vertex #' attribute, or a vector of values. #' Also accepts \code{"mode"} on bipartite networks (see 'Details'). #' Defaults to \code{grey75}. #' @param shape the shape of the nodes, which might be a single value, a vertex #' attribute, or a vector of values. #' Also accepts \code{"mode"} on bipartite networks (see 'Details'). #' Defaults to \code{19} (solid circle). #' @param size the size of the nodes, in points, which might be a single value, #' a vertex attribute, or a vector of values. Also accepts \code{"indegree"}, #' \code{"outdegree"}, \code{"degree"} or \code{"freeman"} to size the nodes by #' their unweighted degree centrality (\code{"degree"} and \code{"freeman"} are #' equivalent): see \code{\link[sna]{degree}} for details. All node sizes must #' be strictly positive. #' Also accepts \code{"mode"} on bipartite networks (see 'Details'). #' Defaults to \code{9}. #' @param max_size the \emph{maximum} size of the node when \code{size} produces #' nodes of different sizes, in points. #' Defaults to \code{9}. #' @param na.rm whether to subset the network to nodes that are \emph{not} #' missing a given vertex attribute. If set to any vertex attribute of #' \code{net}, the nodes for which this attribute is \code{NA} will be removed. #' Defaults to \code{NA} (does nothing). #' @param palette the palette to color the nodes, when \code{color} is not a #' color value or a vector of color values. Accepts named vectors of color #' values, or if [RColorBrewer][RColorBrewer::RColorBrewer] is installed, any #' ColorBrewer palette name: see [RColorBrewer::brewer.pal()] and #' \url{https://colorbrewer2.org/} for details. #' Defaults to \code{NULL}, which will create an array of grayscale color values #' if \code{color} is not a color value or a vector of color values. #' @param alpha.palette the palette to control the transparency levels of the #' nodes set by \code{alpha} when the levels are not numeric values. #' Defaults to \code{NULL}, which will create an array of alpha transparency #' values if \code{alpha} is not a numeric value or a vector of numeric values. #' @param alpha.legend the name to assign to the legend created by #' \code{alpha} when its levels are not numeric values. #' Defaults to \code{NA} (no name). #' @param color.palette see \code{palette} #' @param color.legend the name to assign to the legend created by #' \code{palette}. #' Defaults to \code{NA} (no name). #' @param shape.palette the palette to control the shapes of the nodes set by #' \code{shape} when the shapes are not numeric values. #' Defaults to \code{NULL}, which will create an array of shape values if #' \code{shape} is not a numeric value or a vector of numeric values. #' @param shape.legend the name to assign to the legend created by #' \code{shape} when its levels are not numeric values. #' Defaults to \code{NA} (no name). #' @param size.palette the palette to control the sizes of the nodes set by #' \code{size} when the sizes are not numeric values. #' @param size.legend the name to assign to the legend created by #' \code{size}. #' Defaults to \code{NA} (no name). #' @param size.zero whether to accept zero-sized nodes based on the value(s) of #' \code{size}. #' Defaults to \code{FALSE}, which ensures that zero-sized nodes are still #' shown in the plot and its size legend. #' @param size.cut whether to cut the size of the nodes into a certain number of #' quantiles. Accepts \code{TRUE}, which tries to cut the sizes into quartiles, #' or any positive numeric value, which tries to cut the sizes into that many #' quantiles. If the size of the nodes do not contain the specified number of #' distinct quantiles, the largest possible number is used. #' See \code{\link[stats]{quantile}} and \code{\link[base]{cut}} for details. #' Defaults to \code{FALSE} (does nothing). #' @param size.min whether to subset the network to nodes with a minimum size, #' based on the values of \code{size}. #' Defaults to \code{NA} (preserves all nodes). #' @param size.max whether to subset the network to nodes with a maximum size, #' based on the values of \code{size}. #' Defaults to \code{NA} (preserves all nodes). #' @param label whether to label the nodes. If set to \code{TRUE}, nodes are #' labeled with their vertex names. If set to a vector that contains as many #' elements as there are nodes in \code{net}, nodes are labeled with these. If #' set to any other vector of values, the nodes are labeled only when their #' vertex name matches one of these values. #' Defaults to \code{FALSE} (no labels). #' @param label.alpha the level of transparency of the node labels, as a #' numeric value, a vector of numeric values, or as a vertex attribute #' containing numeric values. #' Defaults to \code{1} (no transparency). #' @param label.color the color of the node labels, as a color value, a vector #' of color values, or as a vertex attribute containing color values. #' Defaults to \code{"black"}. #' @param label.size the size of the node labels, in points, as a numeric value, #' a vector of numeric values, or as a vertex attribute containing numeric #' values. #' Defaults to \code{max_size / 2} (half the maximum node size), which defaults #' to \code{4.5}. #' @param label.trim whether to apply some trimming to the node labels. Accepts #' any function that can process a character vector, or a strictly positive #' numeric value, in which case the labels are trimmed to a fixed-length #' substring of that length: see \code{\link[base]{substr}} for details. #' Defaults to \code{FALSE} (does nothing). #' @param node.alpha see \code{alpha} #' @param node.color see \code{color} #' @param node.label see \code{label} #' @param node.shape see \code{shape} #' @param node.size see \code{size} #' @param edge.alpha the level of transparency of the edges. #' Defaults to the value of \code{alpha}, which defaults to \code{1}. #' @param edge.color the color of the edges, as a color value, a vector of color #' values, or as an edge attribute containing color values. #' Defaults to \code{"grey50"}. #' @param edge.lty the linetype of the edges, as a linetype value, a vector of #' linetype values, or as an edge attribute containing linetype values. #' Defaults to \code{"solid"}. #' @param edge.size the size of the edges, in points, as a numeric value, a #' vector of numeric values, or as an edge attribute containing numeric values. #' All edge sizes must be strictly positive. #' Defaults to \code{0.25}. #' @param edge.label the labels to plot at the middle of the edges, as a single #' value, a vector of values, or as an edge attribute. #' Defaults to \code{NULL} (no edge labels). #' @param edge.label.alpha the level of transparency of the edge labels, as a #' numeric value, a vector of numeric values, or as an edge attribute #' containing numeric values. #' Defaults to \code{1} (no transparency). #' @param edge.label.color the color of the edge labels, as a color value, a #' vector of color values, or as an edge attribute containing color values. #' Defaults to \code{label.color}, which defaults to \code{"black"}. #' @param edge.label.fill the background color of the edge labels. #' Defaults to \code{"white"}. #' @param edge.label.size the size of the edge labels, in points, as a numeric #' value, a vector of numeric values, or as an edge attribute containing numeric #' values. All edge label sizes must be strictly positive. #' Defaults to \code{max_size / 2} (half the maximum node size), which defaults #' to \code{4.5}. #' @param arrow.size the size of the arrows for directed network edges, in #' points. See \code{\link[grid]{arrow}} for details. #' Defaults to \code{0} (no arrows). #' @param arrow.gap a setting aimed at improving the display of edge arrows by #' plotting slightly shorter edges. Accepts any value between \code{0} and #' \code{1}, where a value of \code{0.05} will generally achieve good results #' when the size of the nodes is reasonably small. #' Defaults to \code{0} (no shortening). #' @param arrow.type the type of the arrows for directed network edges. See #' \code{\link[grid]{arrow}} for details. #' Defaults to \code{"closed"}. #' @param legend.size the size of the legend symbols and text, in points. #' Defaults to \code{9}. #' @param legend.position the location of the plot legend(s). Accepts all #' \code{legend.position} values supported by \code{\link[ggplot2]{theme}}. #' Defaults to \code{"right"}. #' @param ... other arguments passed to the \code{geom_text} object that sets #' the node labels: see \code{\link[ggplot2]{geom_text}} for details. #' @seealso \code{\link{ggnet}} in this package, #' \code{\link[sna]{gplot}} in the \code{\link[sna]{sna}} package, and #' \code{\link[network]{plot.network}} in the \code{\link[network]{network}} #' package #' @author Moritz Marbach and Francois Briatte, with help from Heike Hofmann, #' Pedro Jordano and Ming-Yu Liu #' @details The degree centrality measures that can be produced through the #' \code{size} argument will take the directedness of the network into account, #' but will be unweighted. To compute weighted network measures, see the #' \code{tnet} package by Tore Opsahl (\code{help("tnet", package = "tnet")}). #' #' The nodes of bipartite networks can be mapped to their mode by passing the #' \code{"mode"} argument to any of \code{alpha}, \code{color}, \code{shape} and #' \code{size}, in which case the nodes of the primary mode will be mapped as #' \code{"actor"}, and the nodes of the secondary mode will be mapped as #' \code{"event"}. #' @importFrom utils installed.packages #' @importFrom grDevices gray.colors #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' library(network) #' #' # random adjacency matrix #' x <- 10 #' ndyads <- x * (x - 1) #' density <- x / ndyads #' m <- matrix(0, nrow = x, ncol = x) #' dimnames(m) <- list(letters[1:x], letters[1:x]) #' m[row(m) != col(m)] <- runif(ndyads) < density #' m #' #' # random undirected network #' n <- network::network(m, directed = FALSE) #' n #' #' p_(ggnet2(n, label = TRUE)) #' p_(ggnet2(n, label = TRUE, shape = 15)) #' p_(ggnet2(n, label = TRUE, shape = 15, color = "black", label.color = "white")) #' #' # add vertex attribute #' x = network.vertex.names(n) #' x = ifelse(x %in% c("a", "e", "i"), "vowel", "consonant") #' n %v% "phono" = x #' #' p_(ggnet2(n, color = "phono")) #' p_(ggnet2(n, color = "phono", palette = c("vowel" = "gold", "consonant" = "grey"))) #' p_(ggnet2(n, shape = "phono", color = "phono")) #' #' if (require(RColorBrewer)) { #' #' # random groups #' n %v% "group" <- sample(LETTERS[1:3], 10, replace = TRUE) #' #' p_(ggnet2(n, color = "group", palette = "Set2")) #' #' } #' #' # random weights #' n %e% "weight" <- sample(1:3, network.edgecount(n), replace = TRUE) #' p_(ggnet2(n, edge.size = "weight", edge.label = "weight")) #' #' # edge arrows on a directed network #' p_(ggnet2(network(m, directed = TRUE), arrow.gap = 0.05, arrow.size = 10)) #' #' # Padgett's Florentine wedding data #' data(flo, package = "network") #' flo #' #' p_(ggnet2(flo, label = TRUE)) #' p_(ggnet2(flo, label = TRUE, label.trim = 4, vjust = -1, size = 3, color = 1)) #' p_(ggnet2(flo, label = TRUE, size = 12, color = "white")) ggnet2 <- function( net, mode = "fruchtermanreingold", layout.par = NULL, layout.exp = 0, alpha = 1, color = "grey75", shape = 19, size = 9, max_size = 9, na.rm = NA, palette = NULL, alpha.palette = NULL, alpha.legend = NA, color.palette = palette, color.legend = NA, shape.palette = NULL, shape.legend = NA, size.palette = NULL, size.legend = NA, size.zero = FALSE, size.cut = FALSE, size.min = NA, size.max = NA, label = FALSE, label.alpha = 1, label.color = "black", label.size = max_size / 2, label.trim = FALSE, node.alpha = alpha, node.color = color, node.label = label, node.shape = shape, node.size = size, edge.alpha = 1, edge.color = "grey50", edge.lty = "solid", edge.size = .25, edge.label = NULL, edge.label.alpha = 1, edge.label.color = label.color, edge.label.fill = "white", edge.label.size = max_size / 2, arrow.size = 0, arrow.gap = 0, arrow.type = "closed", legend.size = 9, legend.position = "right", ... ) { # -- packages ---------------------------------------------------------------- require_namespaces(c("network", "sna", "scales")) # -- conversion to network class --------------------------------------------- if (inherits(net, "igraph") && "intergraph" %in% rownames(installed.packages())) { net = intergraph::asNetwork(net) } else if (inherits(net, "igraph")) { stop("install the 'intergraph' package to use igraph objects with ggnet2") } if (!network::is.network(net)) { net = try(network::network(net), silent = TRUE) } if (!network::is.network(net)) { stop("could not coerce net to a network object") } # -- network functions ------------------------------------------------------- get_v = get("%v%", envir = getNamespace("network")) get_e = get("%e%", envir = getNamespace("network")) set_mode = function(x, mode = network::get.network.attribute(x, "bipartite")) { c(rep("actor", mode), rep("event", n_nodes - mode)) } set_node = function(x, value, mode = TRUE) { if (is.null(x) || any(is.na(x)) || any(is.infinite(x)) || any(is.nan(x))) { stop(paste("incorrect", value, "value")) } else if (is.numeric(x) && any(x < 0)) { stop(paste("incorrect", value, "value")) } else if (length(x) == n_nodes) { x } else if (length(x) > 1) { stop(paste("incorrect", value, "length")) } else if (any(x %in% v_attr)) { get_v(net, x) } else if (mode && identical(x, "mode") && is_bip) { set_mode(net) } else { x } } set_edge = function(x, value) { if (is.null(x) || any(is.na(x)) || any(is.infinite(x)) || any(is.nan(x))) { stop(paste("incorrect", value, "value")) } else if (is.numeric(x) && any(x < 0)) { stop(paste("incorrect", value, "value")) } else if (length(x) == n_edges) { x } else if (length(x) > 1) { stop(paste("incorrect", value, "length")) } else if (any(x %in% e_attr)) { get_e(net, x) } else { x } } set_attr = function(x) { if (length(x) == n_nodes) { x } else if (length(x) > 1) { stop(paste("incorrect coordinates length")) } else if (!x %in% v_attr) { stop(paste("vertex attribute", x, "was not found")) } else if (!is.numeric(get_v(net, x))) { stop(paste("vertex attribute", x, "is not numeric")) } else { get_v(net, x) } } set_name = function(x, y) { z = length(x) == 1 && x %in% v_attr z = ifelse(is.na(y), z, y) z = ifelse(isTRUE(z), x, z) ifelse(is.logical(z), "", z) } set_size = function(x) { y = x + (0 %in% x) * !size.zero y = scales::rescale_max(y) y = scales::abs_area(max_size)(y) if (is.null(names(x))) names(y) = x else names(y) = names(x) y } is_one = function(x) length(unique(x)) == 1 is_col = function(x) all(is.numeric(x)) | all(network::is.color(x)) # -- network structure ------------------------------------------------------- n_nodes = network::network.size(net) n_edges = network::network.edgecount(net) v_attr = network::list.vertex.attributes(net) e_attr = network::list.edge.attributes(net) is_bip = network::is.bipartite(net) is_dir = ifelse(network::is.directed(net), "digraph", "graph") if (!is.numeric(arrow.size) || arrow.size < 0) { stop("incorrect arrow.size value") } else if (arrow.size > 0 && is_dir == "graph") { warning("network is undirected; arrow.size ignored") arrow.size = 0 } if (!is.numeric(arrow.gap) || arrow.gap < 0 || arrow.gap > 1) { stop("incorrect arrow.gap value") } else if (arrow.gap > 0 && is_dir == "graph") { warning("network is undirected; arrow.gap ignored") arrow.gap = 0 } if (network::is.hyper(net)) { stop("ggnet2 cannot plot hyper graphs") } if (network::is.multiplex(net)) { stop("ggnet2 cannot plot multiplex graphs") } if (network::has.loops(net)) { warning("ggnet2 does not know how to handle self-loops") } # -- check max_size ---------------------------------------------------------- x = max_size if (!is.numeric(x) || is.infinite(x) || is.nan(x) || x < 0) { stop("incorrect max_size value") } # -- initialize dataset ------------------------------------------------------ data = data.frame(label = get_v(net, "vertex.names"), stringsAsFactors = FALSE) data$alpha = set_node(node.alpha , "node.alpha") data$color = set_node(node.color , "node.color") data$shape = set_node(node.shape , "node.shape") data$size = set_node(node.size , "node.size") # -- node removal ------------------------------------------------------------ if (length(na.rm) > 1) { stop("incorrect na.rm value") } else if (!is.na(na.rm)) { if (!na.rm %in% v_attr) { stop(paste("vertex attribute", na.rm, "was not found")) } x = which(is.na(get_v(net, na.rm))) message(paste("na.rm removed", length(x), "nodes out of", nrow(data))) if (length(x) > 0) { data = data[-x, ] network::delete.vertices(net, x) if (!nrow(data)) { warning("na.rm removed all nodes; nothing left to plot") return(invisible(NULL)) } } } # -- weight methods ---------------------------------------------------------- x = size if (length(x) == 1 && x %in% c("indegree", "outdegree", "degree", "freeman")) { # prevent namespace conflict with igraph if ("package:igraph" %in% search()) { y = ifelse(is_dir == "digraph", "directed", "undirected") z = c("indegree" = "in", "outdegree" = "out", "degree" = "all", "freeman" = "all")[x] data$size = igraph::degree(igraph_graph_adjacency_matrix(as.matrix(net), mode = y), mode = z) } else { data$size = sna::degree(net, gmode = is_dir, cmode = ifelse(x == "degree", "freeman", x)) } size.legend = ifelse(is.na(size.legend), x, size.legend) } # -- weight thresholds ------------------------------------------------------- x = ifelse(is.na(size.min), 0, size.min) if (length(x) > 1 || !is.numeric(x) || is.infinite(x) || is.nan(x) || x < 0) { stop("incorrect size.min value") } else if (x > 0 && !is.numeric(data$size)) { warning("node.size is not numeric; size.min ignored") } else if (x > 0) { x = which(data$size < x) message(paste("size.min removed", length(x), "nodes out of", nrow(data))) if (length(x) > 0) { data = data[-x, ] network::delete.vertices(net, x) if (!nrow(data)) { warning("size.min removed all nodes; nothing left to plot") return(invisible(NULL)) } } } x = ifelse(is.na(size.max), 0, size.max) if (length(x) > 1 || !is.numeric(x) || is.infinite(x) || is.nan(x) || x < 0) { stop("incorrect size.max value") } else if (x > 0 && !is.numeric(data$size)) { warning("node.size is not numeric; size.max ignored") } else if (x > 0) { x = which(data$size > x) message(paste("size.max removed", length(x), "nodes out of", nrow(data))) if (length(x) > 0) { data = data[-x, ] network::delete.vertices(net, x) if (!nrow(data)) { warning("size.max removed all nodes; nothing left to plot") return(invisible(NULL)) } } } # -- weight quantiles -------------------------------------------------------- x = size.cut if (length(x) > 1 || is.null(x) || is.na(x) || is.infinite(x) || is.nan(x)) { stop("incorrect size.cut value") } else if (isTRUE(x)) { x = 4 } else if (is.logical(x) && !x) { x = 0 } else if (!is.numeric(x)) { stop("incorrect size.cut value") } if (x >= 1 && !is.numeric(data$size)) { warning("node.size is not numeric; size.cut ignored") } else if (x >= 1) { x = unique(quantile(data$size, probs = seq(0, 1, by = 1 / as.integer(x)))) if (length(x) > 1) { data$size = cut(data$size, unique(x), include.lowest = TRUE) } else { warning("node.size is invariant; size.cut ignored") } } # -- alpha palette ----------------------------------------------------------- if (!is.null(alpha.palette)) { x = alpha.palette } else if (is.factor(data$alpha)) { x = levels(data$alpha) } else { x = unique(data$alpha) } if (!is.null(names(x))) { y = unique(na.omit(data$alpha[!data$alpha %in% names(x)])) if (length(y) > 0) { stop(paste("no alpha.palette value for", paste0(y, collapse = ", "))) } } else if (is.factor(data$alpha) || !is.numeric(x)) { data$alpha = factor(data$alpha) x = scales::rescale_max(1:length(levels(data$alpha))) names(x) = levels(data$alpha) } alpha.palette = x # -- color palette ----------------------------------------------------------- if (!is.null(color.palette)) { x = color.palette } else if (is.factor(data$color)) { x = levels(data$color) } else { x = unique(data$color) } if (length(x) == 1 && "RColorBrewer" %in% rownames(installed.packages()) && x %in% rownames(RColorBrewer::brewer.pal.info)) { data$color = factor(data$color) n_groups = length(levels(data$color)) n_colors = RColorBrewer::brewer.pal.info[x, "maxcolors"] if (n_groups > n_colors) { stop(paste0("too many node groups (", n_groups, ") for ", "ColorBrewer palette ", x, " (max: ", n_colors, ")")) } else if (n_groups < 3) { n_groups = 3 } x = RColorBrewer::brewer.pal(n_groups, x)[1:length(levels(data$color))] names(x) = levels(data$color) } if (!is.null(names(x))) { y = unique(na.omit(data$color[!data$color %in% names(x)])) if (length(y) > 0) { stop(paste("no color.palette value for", paste0(y, collapse = ", "))) } } else if (is.factor(data$color) || !is_col(x)) { data$color = factor(data$color) x = gray.colors(length(x)) names(x) = levels(data$color) } color.palette = x # -- shape palette ----------------------------------------------------------- if (!is.null(shape.palette)) { x = shape.palette } else if (is.factor(data$shape)) { x = levels(data$shape) } else { x = unique(data$shape) } if (!is.null(names(x))) { y = unique(na.omit(data$shape[!data$shape %in% names(x)])) if (length(y) > 0) { stop(paste("no shape.palette value for", paste0(y, collapse = ", "))) } } else if (is.factor(data$shape) || !is.numeric(x)) { data$shape = factor(data$shape) x = scales::shape_pal()(length(levels(data$shape))) names(x) = levels(data$shape) } shape.palette = x # -- size palette ------------------------------------------------------------ if (!is.null(size.palette)) { x = size.palette } else if (is.factor(data$size)) { x = levels(data$size) } else { x = unique(data$size) } if (!is.null(names(x))) { y = unique(na.omit(data$size[!data$size %in% names(x)])) if (length(y) > 0) { stop(paste("no size.palette value for", paste0(y, collapse = ", "))) } } else if (is.factor(data$size) || !is.numeric(x)) { data$size = factor(data$size) x = 1:length(levels(data$size)) names(x) = levels(data$size) } size.palette = x # -- node labels ------------------------------------------------------------- l = node.label if (isTRUE(l)) { l = data$label } else if (length(l) > 1 && length(l) == n_nodes) { data$label = l } else if (length(l) == 1 && l %in% v_attr) { l = get_v(net, l) } else { l = ifelse(data$label %in% l, data$label, "") } # -- node placement ---------------------------------------------------------- if (is.character(mode) && length(mode) == 1) { mode = paste0("gplot.layout.", mode) if (!exists(mode, where = getNamespace("sna"))) { stop(paste("unsupported placement method:", mode)) } else { mode <- get(mode, getNamespace("sna")) } # sna placement algorithm xy = network::as.matrix.network.adjacency(net) xy = do.call(mode, list(xy, layout.par)) xy = data.frame(x = xy[, 1], y = xy[, 2]) } else if (is.character(mode) && length(mode) == 2) { # fixed coordinates from vertex attributes xy = data.frame(x = set_attr(mode[1]), y = set_attr(mode[2])) } else if (is.numeric(mode) && is.matrix(mode)) { # fixed coordinates from matrix xy = data.frame(x = set_attr(mode[, 1]), y = set_attr(mode[, 2])) } else { stop("incorrect mode value") } xy$x = scale(xy$x, min(xy$x), diff(range(xy$x)))[, 1] xy$y = scale(xy$y, min(xy$y), diff(range(xy$y)))[, 1] data = cbind(data, xy) # -- edge colors ------------------------------------------------------------- edges = network::as.matrix.network.edgelist(net) if (edge.color[1] == "color" && length(edge.color) == 2) { # edge colors from node source and target edge.color = ifelse(data$color[edges[, 1]] == data$color[edges[, 2]], as.character(data$color[edges[, 1]]), edge.color[2]) if (!is.null(names(color.palette))) { x = which(edge.color %in% names(color.palette)) edge.color[x] = color.palette[edge.color[x]] } edge.color[is.na(edge.color)] = edge.color[2] } edge.color = set_edge(edge.color, "edge.color") if (!is_col(edge.color)) { stop("incorrect edge.color value") } # -- edge list --------------------------------------------------------------- edges = data.frame(xy[edges[, 1], ], xy[edges[, 2], ]) names(edges) = c("X1", "Y1", "X2", "Y2") # -- edge labels, colors and sizes ------------------------------------------- if (!is.null(edge.label)) { edges$midX = (edges$X1 + edges$X2) / 2 edges$midY = (edges$Y1 + edges$Y2) / 2 edges$label = set_edge(edge.label, "edge.label") edge.label.alpha = set_edge(edge.label.alpha, "edge.label.alpha") if (!is.numeric(edge.label.alpha)) { stop("incorrect edge.label.alpha value") } edge.label.color = set_edge(edge.label.color, "edge.label.color") if (!is_col(edge.label.color)) { stop("incorrect edge.label.color value") } edge.label.size = set_edge(edge.label.size, "edge.label.size") if (!is.numeric(edge.label.size)) { stop("incorrect edge.label.size value") } } # -- edge linetype ----------------------------------------------------------- edge.lty = set_edge(edge.lty, "edge.lty") # -- edge size --------------------------------------------------------------- edge.size = set_edge(edge.size, "edge.size") if (!is.numeric(edge.size) || any(edge.size <= 0)) { stop("incorrect edge.size value") } # -- plot edges -------------------------------------------------------------- p = ggplot(data, aes(x = x, y = y)) if (nrow(edges) > 0) { if (arrow.gap > 0) { x.dir = with(edges, (X2 - X1)) # do not use absolute value y.dir = with(edges, (Y2 - Y1)) arrow.gap = with(edges, arrow.gap / sqrt(x.dir ^ 2 + y.dir ^ 2)) edges = transform(edges, X1 = X1 + arrow.gap * x.dir, Y1 = Y1 + arrow.gap * y.dir, X2 = X1 + (1 - arrow.gap) * x.dir, Y2 = Y1 + (1 - arrow.gap) * y.dir) } p = p + geom_segment( data = edges, aes(x = X1, y = Y1, xend = X2, yend = Y2), linewidth = edge.size, color = edge.color, alpha = edge.alpha, lty = edge.lty, arrow = arrow( type = arrow.type, length = unit(arrow.size, "pt") ) ) } if (nrow(edges) > 0 && !is.null(edge.label)) { p = p + geom_point( data = edges, aes(x = midX, y = midY), alpha = edge.alpha, color = edge.label.fill, size = edge.label.size * 1.5 ) + geom_text( data = edges, aes(x = midX, y = midY, label = label), alpha = edge.label.alpha, color = edge.label.color, size = edge.label.size ) } # -- plot nodes -------------------------------------------------------------- x = list() if (is.numeric(data$alpha) && is_one(data$alpha)) { x = c(x, alpha = unique(data$alpha)) } if (!is.factor(data$color) && is_one(data$color)) { x = c(x, colour = unique(data$color)) # must be English spelling } if (is.numeric(data$shape) && is_one(data$shape)) { x = c(x, shape = unique(data$shape)) } if (is.numeric(data$size) && is_one(data$size)) { x = c(x, size = unique(data$size)) } else { x = c(x, size = max_size) } p = p + geom_point(aes(alpha = factor(alpha), color = factor(color), shape = factor(shape), size = factor(size))) # -- legend: alpha ----------------------------------------------------------- if (is.numeric(data$alpha)) { v_alpha = unique(data$alpha) names(v_alpha) = unique(data$alpha) p = p + scale_alpha_manual("", values = v_alpha) + guides(alpha = "none") } else { p = p + scale_alpha_manual(set_name(node.alpha, alpha.legend), values = alpha.palette, breaks = names(alpha.palette), guide = guide_legend(override.aes = x)) } # -- legend: color ----------------------------------------------------------- if (!is.null(names(color.palette))) { p = p + scale_color_manual(set_name(node.color, color.legend), values = color.palette, breaks = names(color.palette), guide = guide_legend(override.aes = x)) } else { v_color = unique(data$color) names(v_color) = unique(data$color) p = p + scale_color_manual("", values = v_color) + guides(color = "none") } # -- legend: shape ----------------------------------------------------------- if (is.numeric(data$shape)) { v_shape = unique(data$shape) names(v_shape) = unique(data$shape) p = p + scale_shape_manual("", values = v_shape) + guides(shape = "none") } else { p = p + scale_shape_manual(set_name(node.shape, shape.legend), values = shape.palette, breaks = names(shape.palette), guide = guide_legend(override.aes = x)) } # -- legend: size ------------------------------------------------------------ x = x[names(x) != "size"] if (is.numeric(data$size)) { v_size = set_size(unique(data$size)) if (length(v_size) == 1) { v_size = as.numeric(names(v_size)) p = p + scale_size_manual("", values = v_size) + guides(size = "none") } else { p = p + scale_size_manual(set_name(node.size, size.legend), values = v_size, guide = guide_legend(override.aes = x)) } } else { p = p + scale_size_manual(set_name(node.size, size.legend), values = set_size(size.palette), guide = guide_legend(override.aes = x)) } # -- plot node labels -------------------------------------------------------- if (!is_one(l) || unique(l) != "") { label.alpha = set_node(label.alpha, "label.alpha", mode = FALSE) if (!is.numeric(label.alpha)) { stop("incorrect label.alpha value") } label.color = set_node(label.color, "label.color", mode = FALSE) if (!is_col(label.color)) { stop("incorrect label.color value") } label.size = set_node(label.size, "label.size", mode = FALSE) if (!is.numeric(label.size)) { stop("incorrect label.size value") } x = label.trim if (length(x) > 1 || (!is.logical(x) && !is.numeric(x) && !is.function(x))) { stop("incorrect label.trim value") } else if (is.numeric(x) && x > 0) { l = substr(l, 1, x) } else if (is.function(x)) { l = x(l) } p = p + geom_text( label = l, alpha = label.alpha, color = label.color, size = label.size, ... ) } # -- horizontal scale expansion ---------------------------------------------- x = range(data$x) if (!is.numeric(layout.exp) || layout.exp < 0) { stop("incorrect layout.exp value") } else if (layout.exp > 0) { x = scales::expand_range(x, layout.exp / 2) } # -- finalize ---------------------------------------------------------------- p = p + scale_x_continuous(breaks = NULL, limits = x) + scale_y_continuous(breaks = NULL) + theme( panel.background = element_blank(), panel.grid = element_blank(), axis.title = element_blank(), legend.key = element_blank(), legend.position = legend.position, legend.text = element_text(size = legend.size), legend.title = element_text(size = legend.size) ) return(p) } GGally/R/ggsave.R0000644000176200001440000000016614527265752013253 0ustar liggesusers#' @export # @examples # ggsave("test.pdf", ggpairs(iris, 1:2)) grid.draw.ggmatrix <- function(x, ...) { print(x) } GGally/R/data-australia-pisa-2012.R0000644000176200001440000000502314526737215016201 0ustar liggesusers#' Programme for International Student Assessment (PISA) 2012 Data for Australia #' #' About PISA #' #' The Programme for International Student Assessment (PISA) is a triennial international survey which aims to evaluate education systems worldwide by testing the skills and knowledge of 15-year-old students. To date, students representing more than 70 economies have participated in the assessment. #' #' While 65 economies took part in the 2012 study, this data set only contains information from the country of Australia. #' #' @details \itemize{ #' \item gender : Factor w/ 2 levels "female","male": 1 1 2 2 2 1 1 1 2 1 ... #' \item age : Factor w/ 4 levels "4","5","6","7": 2 2 2 4 3 1 2 2 2 2 ... #' \item homework : num 5 5 9 3 2 3 4 3 5 1 ... #' \item desk : num 1 0 1 1 1 1 1 1 1 1 ... #' \item room : num 1 1 1 1 1 1 1 1 1 1 ... #' \item study : num 1 1 1 1 1 1 1 1 1 1 ... #' \item computer : num 1 1 1 1 1 1 1 1 1 1 ... #' \item software : num 1 1 1 1 1 1 1 1 1 1 ... #' \item internet : num 1 1 1 1 1 1 1 1 1 1 ... #' \item literature : num 0 0 1 0 1 1 1 1 1 0 ... #' \item poetry : num 0 0 1 0 1 1 0 1 1 1 ... #' \item art : num 1 0 1 0 1 1 0 1 1 1 ... #' \item textbook : num 1 1 1 1 1 0 1 1 1 1 ... #' \item dictionary : num 1 1 1 1 1 1 1 1 1 1 ... #' \item dishwasher : num 1 1 1 1 0 1 1 1 1 1 ... #' \item PV1MATH : num 562 565 602 520 613 ... #' \item PV2MATH : num 569 557 594 507 567 ... #' \item PV3MATH : num 555 553 552 501 585 ... #' \item PV4MATH : num 579 538 526 521 596 ... #' \item PV5MATH : num 548 573 619 547 603 ... #' \item PV1READ : num 582 617 650 554 605 ... #' \item PV2READ : num 571 572 608 560 557 ... #' \item PV3READ : num 602 560 594 517 627 ... #' \item PV4READ : num 572 564 575 564 597 ... #' \item PV5READ : num 585 565 620 572 598 ... #' \item PV1SCIE : num 583 627 668 574 639 ... #' \item PV2SCIE : num 579 600 665 612 635 ... #' \item PV3SCIE : num 593 574 620 571 666 ... #' \item PV4SCIE : num 567 582 592 598 700 ... #' \item PV5SCIE : num 587 625 656 662 670 ... #' \item SENWGT_STU : num 0.133 0.133 0.141 0.141 0.141 ... #' \item possessions: num 10 8 12 9 11 11 10 12 12 11 ... #' } #' #' @docType data #' @keywords datasets #' @name australia_PISA2012 #' @usage data(australia_PISA2012) #' @format A data frame with 8247 rows and 32 variables #' @source \url{https://www.oecd.org/pisa/pisaproducts/database-cbapisa2012.htm} NULL GGally/R/gglyph.R0000644000176200001440000002214214527265752013267 0ustar liggesusers#' Create \code{\link{glyphplot}} data #' #' Create the data needed to generate a glyph plot. #' #' @param data A data frame containing variables named in \code{x_major}, #' \code{x_minor}, \code{y_major} and \code{y_minor}. #' @param x_major,x_minor,y_major,y_minor The name of the variable (as a #' string) for the major and minor x and y axes. Together, each unique # combination of \code{x_major} and \code{y_major} specifies a grid cell. #' @param polar A logical of length 1, specifying whether the glyphs should #' be drawn in polar coordinates. Defaults to \code{FALSE}. #' @param height,width The height and width of each glyph. Defaults to 95% of #' the \code{\link[ggplot2]{resolution}} of the data. Specify the width #' absolutely by supplying a numeric vector of length 1, or relative to the # resolution of the data by using \code{\link[ggplot2]{rel}}. #' @param y_scale,x_scale The scaling function to be applied to each set of #' minor values within a grid cell. Defaults to \code{\link{identity}} so #' that no scaling is performed. #' @export #' @author Di Cook, Heike Hofmann, Hadley Wickham #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' data(nasa) #' nasaLate <- nasa[ #' nasa$date >= as.POSIXct("1998-01-01") & #' nasa$lat >= 20 & #' nasa$lat <= 40 & #' nasa$long >= -80 & #' nasa$long <= -60, #' ] #' temp.gly <- glyphs(nasaLate, "long", "day", "lat", "surftemp", height = 2.5) #' p_(ggplot2::ggplot(temp.gly, ggplot2::aes(gx, gy, group = gid)) + #' add_ref_lines(temp.gly, color = "grey90") + #' add_ref_boxes(temp.gly, color = "grey90") + #' ggplot2::geom_path() + #' ggplot2::theme_bw() + #' ggplot2::labs(x = "", y = "")) glyphs <- function( data, x_major, x_minor, y_major, y_minor, polar = FALSE, height = ggplot2::rel(0.95), width = ggplot2::rel(0.95), y_scale = identity, x_scale = identity) { data$gid <- interaction(data[[x_major]], data[[y_major]], drop = TRUE) if (is.rel(width)) { width <- resolution(data[[x_major]], zero = FALSE) * unclass(width) message("Using width ", format(width, digits = 3)) } if (is.rel(height)) { height <- resolution(data[[y_major]], zero = FALSE) * unclass(height) message("Using height ", format(height, digits = 3)) } if (!identical(x_scale, identity) || !identical(y_scale, identity)) { data <- ddply(data, "gid", function(df) { df[[x_minor]] <- x_scale(df[[x_minor]]) df[[y_minor]] <- y_scale(df[[y_minor]]) df }) } if (polar) { theta <- 2 * pi * rescale01(data[[x_minor]]) r <- rescale01(data[[y_minor]]) data$gx <- data[[x_major]] + width / 2 * r * sin(theta) data$gy <- data[[y_major]] + height / 2 * r * cos(theta) data <- data[order(data[[x_major]], data[[x_minor]]), ] } else { data$gx <- data[[x_major]] + rescale11(data[[x_minor]]) * width / 2 data$gy <- data[[y_major]] + rescale11(data[[y_minor]]) * height / 2 } structure( data, width = width, height = height, polar = polar, x_major = x_major, y_major = y_major, class = c("glyphplot", "data.frame") ) } # Create reference lines for a glyph plot ref_lines <- function(data) { stopifnot(is.glyphplot(data)) glyph <- attributes(data) cells <- unique(data[c(glyph$x_major, glyph$y_major, "gid")]) if (glyph$polar) { ref_line <- function(df) { theta <- seq(0, 2 * pi, length.out = 30) data.frame( gid = df$gid, gx = df[[glyph$x_major]] + glyph$width / 4 * sin(theta), gy = df[[glyph$y_major]] + glyph$height / 4 * cos(theta) ) } } else { ref_line <- function(df) { data.frame( gid = df$gid, gx = df[[glyph$x_major]] + c(-1, 1) * glyph$width / 2, gy = df[[glyph$y_major]] ) } } ddply(cells, "gid", ref_line) } # Create reference boxes for a glyph plot ref_boxes <- function(data, fill = NULL) { stopifnot(is.glyphplot(data)) glyph <- attributes(data) cells <- data.frame(unique(data[c(glyph$x_major, glyph$y_major, "gid", fill)])) df <- data.frame( xmin = cells[[glyph$x_major]] - glyph$width / 2, xmax = cells[[glyph$x_major]] + glyph$width / 2, ymin = cells[[glyph$y_major]] - glyph$height / 2, ymax = cells[[glyph$y_major]] + glyph$height / 2 ) if (!is.null(fill)) { df$fill <- cells[[fill]] } df } # Glyph plot class ----------------------------------------------------------- #' Glyph plot class #' #' @param data A data frame containing variables named in \code{x_major}, #' \code{x_minor}, \code{y_major} and \code{y_minor}. #' @param height,width The height and width of each glyph. Defaults to 95% of #' the \code{\link[ggplot2]{resolution}} of the data. Specify the width #' absolutely by supplying a numeric vector of length 1, or relative to the # resolution of the data by using \code{\link[ggplot2]{rel}}. #' @param polar A logical of length 1, specifying whether the glyphs should #' be drawn in polar coordinates. Defaults to \code{FALSE}. #' @param x_major,y_major The name of the variable (as a #' string) for the major x and y axes. Together, the # combination of \code{x_major} and \code{y_major} specifies a grid cell. #' @export #' @author Di Cook, Heike Hofmann, Hadley Wickham glyphplot <- function(data, width, height, polar, x_major, y_major) { structure( data, width = width, height = height, polar = polar, x_major = x_major, y_major = y_major, class = c("glyphplot", "data.frame") ) } #' @export #' @rdname glyphplot is.glyphplot <- function(x) { inherits(x, "glyphplot") } #' @export #' @rdname glyphplot "[.glyphplot" <- function(x, ...) { glyphplot( NextMethod(), width = attr(x, "width"), height = attr(x, "height"), x_major = attr(x, "x_major"), y_major = attr(x, "y_major"), polar = attr(x, "polar") ) } #' @param x glyphplot to be printed #' @param ... ignored #' @export #' @rdname glyphplot #' @method print glyphplot print.glyphplot <- function(x, ...) { NextMethod() if (attr(x, "polar")) { cat("Polar ") } else { cat("Cartesian ") } width <- format(attr(x, "width"), digits = 3) height <- format(attr(x, "height"), digits = 3) cat("glyphplot: \n") cat(" Size: [", width, ", ", height, "]\n", sep = "") cat( " Major axes: ", attr(x, "x_major"), ", ", attr(x, "y_major"), "\n", sep = "" ) # cat("\n") } # Relative dimensions -------------------------------------------------------- # Relative dimensions # # @param x numeric value between 0 and 1 # rel <- function(x) { # structure(x, class = "rel") # } # @export # rel <- ggplot2::rel # @rdname rel # @param ... ignored # print.rel <- function(x, ...) { # print(noquote(paste(x, " *", sep = ""))) # } ## works even though it is not exported # @export # ggplot2::print.rel # @rdname rel # is.rel <- function(x) { # inherits(x, "rel") # } ## only used internally. and ggplot2 has this exported # @export # ggplot2:::is.rel is.rel <- ggplot2:::is.rel # Rescaling functions -------------------------------------------------------- #' Rescaling functions #' #' @param x numeric vector #' @param xlim value used in \code{range} #' @name rescale01 #' @export #' @rdname rescale01 range01 <- function(x) { rng <- range(x, na.rm = TRUE) (x - rng[1]) / (rng[2] - rng[1]) } #' @export #' @rdname rescale01 max1 <- function(x) { x / max(x, na.rm = TRUE) } #' @export #' @rdname rescale01 mean0 <- function(x) { x - mean(x, na.rm = TRUE) } #' @export #' @rdname rescale01 min0 <- function(x) { x - min(x, na.rm = TRUE) } #' @export #' @rdname rescale01 rescale01 <- function(x, xlim = NULL) { if (is.null(xlim)) { rng <- range(x, na.rm = TRUE) } else { rng <- xlim } (x - rng[1]) / (rng[2] - rng[1]) } #' @export #' @rdname rescale01 rescale11 <- function(x, xlim = NULL) { 2 * rescale01(x, xlim) - 1 } #' Add reference lines for each cell of the glyphmap. #' #' @param data A glyphmap structure. #' @param color Set the color to draw in, default is "white" #' @param size Set the line size, default is 1.5 #' @param ... other arguments passed onto [ggplot2::geom_line()] #' @export add_ref_lines <- function(data, color = "white", size = 1.5, ...) { rl <- ref_lines(data) geom_path(data = rl, color = color, linewidth = size, ...) } #' Add reference boxes around each cell of the glyphmap. #' #' @param data A glyphmap structure. #' @param var_fill Variable name to use to set the fill color #' @param color Set the color to draw in, default is "white" #' @param size Set the line size, default is 0.5 #' @param fill fill value used if \code{var_fill} is \code{NULL} #' @param ... other arguments passed onto [ggplot2::geom_rect()] #' @export add_ref_boxes <- function(data, var_fill = NULL, color = "white", size = 0.5, fill = NA, ...) { rb <- ref_boxes(data, var_fill) if (!is.null(var_fill)) { geom_rect(aes_all(names(rb)), data = rb, color = color, linewidth = size, inherit.aes = FALSE, ... ) } else { geom_rect(aes_all(names(rb)), data = rb, color = color, linewidth = size, inherit.aes = FALSE, fill = fill, ... ) } } GGally/R/ggmatrix.R0000644000176200001440000001056514527265752013625 0ustar liggesusers#' \pkg{ggplot2} plot matrix #' #' Make a generic matrix of \pkg{ggplot2} plots. #' #' @section Memory usage: #' Now that the \code{\link{print.ggmatrix}} method uses a large \pkg{gtable} object, rather than print each plot independently, memory usage may be of concern. From small tests, memory usage flutters around \code{object.size(data) * 0.3 * length(plots)}. So, for a 80Mb random noise dataset with 100 plots, about 2.4 Gb of memory needed to print. For the 3.46 Mb diamonds dataset with 100 plots, about 100 Mb of memory was needed to print. The benefits of using the \pkg{ggplot2} format greatly outweigh the price of about 20% increase in memory usage from the prior ad-hoc print method. #' #' @param plots list of plots to be put into matrix #' @param nrow,ncol number of rows and columns #' @param xAxisLabels,yAxisLabels strip titles for the x and y axis respectively. Set to \code{NULL} to not be displayed #' @param title,xlab,ylab title, x label, and y label for the graph. Set to \code{NULL} to not be displayed #' @param byrow boolean that determines whether the plots should be ordered by row or by column #' @param showStrips boolean to determine if each plot's strips should be displayed. \code{NULL} will default to the top and right side plots only. \code{TRUE} or \code{FALSE} will turn all strips on or off respectively. #' @param showAxisPlotLabels,showXAxisPlotLabels,showYAxisPlotLabels booleans that determine if the plots axis labels are printed on the X (bottom) or Y (left) part of the plot matrix. If \code{showAxisPlotLabels} is set, both \code{showXAxisPlotLabels} and \code{showYAxisPlotLabels} will be set to the given value. #' @template ggmatrix-labeller-param #' @template ggmatrix-switch-param #' @param xProportions,yProportions Value to change how much area is given for each plot. Either \code{NULL} (default), numeric value matching respective length, or \code{grid::\link[grid]{unit}} object with matching respective length #' @template ggmatrix-progress #' @param data data set using. This is the data to be used in place of 'ggally_data' if the plot is a string to be evaluated at print time #' @param gg \pkg{ggplot2} theme objects to be applied to every plot #' @template ggmatrix-legend-param #' @keywords hplot #' @author Barret Schloerke #' @importFrom rlang %||% #' @export #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' plotList <- list() #' for (i in 1:6) { #' plotList[[i]] <- ggally_text(paste("Plot #", i, sep = "")) #' } #' pm <- ggmatrix( #' plotList, #' 2, 3, #' c("A", "B", "C"), #' c("D", "E"), #' byrow = TRUE #' ) #' p_(pm) #' #' pm <- ggmatrix( #' plotList, #' 2, 3, #' xAxisLabels = c("A", "B", "C"), #' yAxisLabels = NULL, #' byrow = FALSE, #' showXAxisPlotLabels = FALSE #' ) #' p_(pm) ggmatrix <- function( plots, nrow, ncol, xAxisLabels = NULL, yAxisLabels = NULL, title = NULL, xlab = NULL, ylab = NULL, byrow = TRUE, showStrips = NULL, showAxisPlotLabels = TRUE, showXAxisPlotLabels = TRUE, showYAxisPlotLabels = TRUE, labeller = NULL, switch = NULL, xProportions = NULL, yProportions = NULL, progress = NULL, data = NULL, gg = NULL, legend = NULL) { if (!is.list(plots)) { stop("'plots' must be a list()") } check_nrow_ncol(nrow, "nrow") check_nrow_ncol(ncol, "ncol") if (!missing(showAxisPlotLabels)) { showXAxisPlotLabels <- showAxisPlotLabels showYAxisPlotLabels <- showAxisPlotLabels } progress <- as_ggmatrix_progress(progress, nrow * ncol) plotMatrix <- list( data = data, plots = plots, title = title, xlab = xlab, ylab = ylab, showStrips = showStrips, xAxisLabels = xAxisLabels, yAxisLabels = yAxisLabels, showXAxisPlotLabels = showXAxisPlotLabels, showYAxisPlotLabels = showYAxisPlotLabels, labeller = labeller, switch = switch, xProportions = xProportions, yProportions = yProportions, progress = progress, legend = legend, gg = gg, nrow = nrow, ncol = ncol, byrow = byrow ) attributes(plotMatrix)$class <- c("gg", "ggmatrix") plotMatrix } check_nrow_ncol <- function(x, title) { if (!is.numeric(x)) { stop(paste("'", title, "' must be a numeric value", sep = "")) } if (length(x) != 1) { stop(paste("'", title, "' must be a single numeric value", sep = "")) } } GGally/R/data-tips.R0000644000176200001440000000145514526737231013662 0ustar liggesusers#' Tipping data #' #' #' One waiter recorded information about each tip he received over a #' period of a few months working in one restaurant. He collected several #' variables: #' #' \itemize{ #' \item tip in dollars, #' \item bill in dollars, #' \item sex of the bill payer, #' \item whether there were smokers in the party, #' \item day of the week, #' \item time of day, #' \item size of the party. #' } #' #' In all he recorded 244 tips. The data was reported in a collection of #' case studies for business statistics (Bryant & Smith 1995). #' #' @references Bryant, P. G. and Smith, M (1995) \emph{Practical Data #' Analysis: Case Studies in Business Statistics}. Homewood, IL: Richard D. #' Irwin Publishing: #' @format A data frame with 244 rows and 7 variables #' @keywords datasets "tips" GGally/R/utils.R0000644000176200001440000000222214527265752013132 0ustar liggesusers#' Print if not CRAN #' #' Small function to print a plot if the R session is interactive or in a CI build #' #' @param p plot to be displayed #' @export print_if_interactive <- function(p) { if (interactive() || nzchar(Sys.getenv("CAN_PRINT")) || on_ci()) { print(p) } } on_ci <- function() { isTRUE(as.logical(Sys.getenv("CI"))) } #' Loads package namespaces #' #' Loads package namespaces or yells at user... loudly #' #' @param pkgs vector of character values #' @keywords internal require_namespaces <- function(pkgs) { for (pkg in pkgs) { if (!requireNamespace(pkg, quietly = TRUE)) { stop(str_c("please install the package '", pkg, "'. install.packages('", pkg, "') ")) } } } str_c <- function(..., sep = "", collapse = NULL) { paste(..., sep = sep, collapse = collapse) } str_detect <- function(string, pattern, ...) { grepl(pattern, string, ...) } # str_replace <- function(string, pattern, replacement) { # sub(pattern, replacement, string) # } ifnull <- function(a, b) { if (!is.null(a)) { a } else { b } } hf <- function(field) { eval(parse(text = read.dcf(".helper_functions", fields = field))) } GGally/R/deprecated.R0000644000176200001440000002015314527265752014075 0ustar liggesusers#' Modify a \code{\link{ggmatrix}} object by adding an \pkg{ggplot2} object to all #' # \lifecycle{deprecated} #' #' @export #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' p_(ggpairs(iris, 1:2) + v1_ggmatrix_theme()) #' # move the column names to the left and bottom #' p_(ggpairs(iris, 1:2, switch = "both") + v1_ggmatrix_theme()) v1_ggmatrix_theme <- function() { theme( strip.background = element_rect(fill = "white"), strip.placement = "outside" ) } #' Correlation value plot #' # \lifecycle{deprecated} #' #' (Deprecated. See \code{\link{ggally_cor}}.) #' #' Estimate correlation from the given data. #' #' @param data data set using #' @param mapping aesthetics being used #' @param alignPercent right align position of numbers. Default is 60 percent across the horizontal #' @param method \code{method} supplied to cor function #' @param use \code{use} supplied to cor function #' @param corAlignPercent deprecated. Use parameter \code{alignPercent} #' @param corMethod deprecated. Use parameter \code{method} #' @param corUse deprecated. Use parameter \code{use} #' @param displayGrid if TRUE, display aligned panel gridlines #' @param ... other arguments being supplied to geom_text #' @author Barret Schloerke #' @importFrom stats complete.cases cor #' @seealso \code{\link{ggally_cor}} #' @export #' @keywords hplot #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' data(tips) #' p_(ggally_cor_v1_5(tips, mapping = ggplot2::aes(total_bill, tip))) #' #' # display with no grid #' p_(ggally_cor_v1_5( #' tips, #' mapping = ggplot2::aes(total_bill, tip), #' displayGrid = FALSE #' )) #' #' # change text attributes #' p_(ggally_cor_v1_5( #' tips, #' mapping = ggplot2::aes(x = total_bill, y = tip), #' size = 15, #' colour = I("red") #' )) #' #' # split by a variable #' p_(ggally_cor_v1_5( #' tips, #' mapping = ggplot2::aes(total_bill, tip, color = sex), #' size = 5 #' )) ggally_cor_v1_5 <- function( data, mapping, alignPercent = 0.6, method = "pearson", use = "complete.obs", corAlignPercent = NULL, corMethod = NULL, corUse = NULL, displayGrid = TRUE, ...) { if (!is.null(corAlignPercent)) { stop("'corAlignPercent' is deprecated. Please use argument 'alignPercent'") } if (!is.null(corMethod)) { stop("'corMethod' is deprecated. Please use argument 'method'") } if (!is.null(corUse)) { stop("'corUse' is deprecated. Please use argument 'use'") } useOptions <- c( "all.obs", "complete.obs", "pairwise.complete.obs", "everything", "na.or.complete" ) use <- pmatch(use, useOptions) if (is.na(use)) { warning("correlation 'use' not found. Using default value of 'all.obs'") use <- useOptions[1] } else { use <- useOptions[use] } cor_fn <- function(x, y) { # also do ddply below if fn is altered cor(x, y, method = method, use = use) } # xVar <- data[[as.character(mapping$x)]] # yVar <- data[[as.character(mapping$y)]] # x_bad_rows <- is.na(xVar) # y_bad_rows <- is.na(yVar) # bad_rows <- x_bad_rows | y_bad_rows # if (any(bad_rows)) { # total <- sum(bad_rows) # if (total > 1) { # warning("Removed ", total, " rows containing missing values") # } else if (total == 1) { # warning("Removing 1 row that contained a missing value") # } # # xVar <- xVar[!bad_rows] # yVar <- yVar[!bad_rows] # } # mapping$x <- mapping$y <- NULL xData <- eval_data_col(data, mapping$x) yData <- eval_data_col(data, mapping$y) if (is_date(xData)) { xData <- as.numeric(xData) } if (is_date(yData)) { yData <- as.numeric(yData) } colorData <- eval_data_col(data, mapping$colour) if (is.numeric(colorData)) { stop("ggally_cor: mapping color column must be categorical, not numeric") } if (use %in% c("complete.obs", "pairwise.complete.obs", "na.or.complete")) { if (!is.null(colorData) && (length(colorData) == length(xData))) { rows <- complete.cases(xData, yData, colorData) } else { rows <- complete.cases(xData, yData) } if (any(!rows)) { total <- sum(!rows) if (total > 1) { warning("Removed ", total, " rows containing missing values") } else if (total == 1) { warning("Removing 1 row that contained a missing value") } } if (!is.null(colorData) && (length(colorData) == length(xData))) { colorData <- colorData[rows] } xData <- xData[rows] yData <- yData[rows] } xVal <- xData yVal <- yData # if the mapping has to deal with the data, remove it if (packageVersion("ggplot2") > "2.2.1") { for (mappingName in names(mapping)) { itemData <- eval_data_col(data, mapping[[mappingName]]) if (!inherits(itemData, "AsIs")) { mapping[[mappingName]] <- NULL } } } else { if (length(names(mapping)) > 0) { for (i in length(names(mapping)):1) { # find the last value of the aes, such as cyl of as.factor(cyl) tmp_map_val <- deparse(mapping[names(mapping)[i]][[1]]) if (tmp_map_val[length(tmp_map_val)] %in% colnames(data)) { mapping[[names(mapping)[i]]] <- NULL } if (length(names(mapping)) < 1) { mapping <- NULL break } } } } if ( !is.null(colorData) && !inherits(colorData, "AsIs") ) { cord <- ddply( data.frame(x = xData, y = yData, color = colorData), "color", function(dt) { cor_fn(dt$x, dt$y) } ) colnames(cord)[2] <- "correlation" cord$correlation <- signif(as.numeric(cord$correlation), 3) # put in correct order lev <- levels(as.factor(colorData)) ord <- rep(-1, nrow(cord)) for (i in 1:nrow(cord)) { for (j in seq_along(lev)) { if (identical(as.character(cord$color[i]), as.character(lev[j]))) { ord[i] <- j } } } # print(order(ord[ord >= 0])) # print(lev) cord <- cord[order(ord[ord >= 0]), ] cord$label <- str_c(cord$color, ": ", cord$correlation) # calculate variable ranges so the gridlines line up xmin <- min(xVal, na.rm = TRUE) xmax <- max(xVal, na.rm = TRUE) xrange <- c(xmin - 0.01 * (xmax - xmin), xmax + 0.01 * (xmax - xmin)) ymin <- min(yVal, na.rm = TRUE) ymax <- max(yVal, na.rm = TRUE) yrange <- c(ymin - 0.01 * (ymax - ymin), ymax + 0.01 * (ymax - ymin)) # print(cord) p <- ggally_text( label = str_c("Corr: ", signif(cor_fn(xVal, yVal), 3)), mapping = mapping, xP = 0.5, yP = 0.9, xrange = xrange, yrange = yrange, ... ) xPos <- rep(alignPercent, nrow(cord)) * diff(xrange) + min(xrange, na.rm = TRUE) yPos <- seq( from = 0.9, to = 0.2, length.out = nrow(cord) + 1 ) yPos <- yPos * diff(yrange) + min(yrange, na.rm = TRUE) yPos <- yPos[-1] # print(range(yVal)) # print(yPos) cordf <- data.frame(xPos = xPos, yPos = yPos, labelp = cord$label) cordf$labelp <- factor(cordf$labelp, levels = cordf$labelp) # print(cordf) # print(str(cordf)) p <- p + geom_text( data = cordf, aes( x = xPos, y = yPos, label = labelp, color = labelp ), hjust = 1, ... ) } else { # calculate variable ranges so the gridlines line up xmin <- min(xVal, na.rm = TRUE) xmax <- max(xVal, na.rm = TRUE) xrange <- c(xmin - 0.01 * (xmax - xmin), xmax + 0.01 * (xmax - xmin)) ymin <- min(yVal, na.rm = TRUE) ymax <- max(yVal, na.rm = TRUE) yrange <- c(ymin - 0.01 * (ymax - ymin), ymax + 0.01 * (ymax - ymin)) p <- ggally_text( label = paste( "Corr:\n", signif( cor_fn(xVal, yVal), 3 ), sep = "", collapse = "" ), mapping, xP = 0.5, yP = 0.5, xrange = xrange, yrange = yrange, ... ) } if (!isTRUE(displayGrid)) { p <- p + theme( panel.grid.major = element_blank(), panel.grid.minor = element_blank() ) } p + theme(legend.position = "none") } GGally/R/GGally-package.R0000644000176200001440000000072214527407231014533 0ustar liggesusers#' @keywords internal "_PACKAGE" # The following block is used by usethis to automatically manage # roxygen namespace tags. Modify with care! ## usethis namespace: start #' @importFrom lifecycle deprecate_soft ## usethis namespace: end NULL # \lifecycle{experimental} # \lifecycle{maturing} # \lifecycle{stable} # \lifecycle{superseded} # \lifecycle{questioning} # \lifecycle{soft-deprecated} # \lifecycle{deprecated} # \lifecycle{defunct} # \lifecycle{archived} GGally/R/ggaly_trends.R0000644000176200001440000001035614527265752014463 0ustar liggesusers#' Trends line plot #' #' Plot trends using line plots. #' For continuous y variables, plot the evolution of the mean. #' For binary y variables, plot the evolution of the proportion. #' #' @param data data set using #' @param mapping aesthetics being used #' @param ... other arguments passed to [ggplot2::geom_line()] #' @param include_zero Should 0 be included on the y-axis? #' @author Joseph Larmarange #' @keywords hplot #' @export #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' data(tips) #' tips_f <- tips #' tips_f$day <- factor(tips$day, c("Thur", "Fri", "Sat", "Sun")) #' #' # Numeric variable #' p_(ggally_trends(tips_f, mapping = aes(x = day, y = total_bill))) #' p_(ggally_trends(tips_f, mapping = aes(x = day, y = total_bill, colour = time))) #' #' # Binary variable #' p_(ggally_trends(tips_f, mapping = aes(x = day, y = smoker))) #' p_(ggally_trends(tips_f, mapping = aes(x = day, y = smoker, colour = sex))) #' #' # Discrete variable with 3 or more categories #' p_(ggally_trends(tips_f, mapping = aes(x = smoker, y = day))) #' p_(ggally_trends(tips_f, mapping = aes(x = smoker, y = day, color = sex))) #' #' # Include zero on Y axis #' p_(ggally_trends(tips_f, mapping = aes(x = day, y = total_bill), include_zero = TRUE)) #' p_(ggally_trends(tips_f, mapping = aes(x = day, y = smoker), include_zero = TRUE)) #' #' # Change line size #' p_(ggally_trends(tips_f, mapping = aes(x = day, y = smoker, colour = sex), size = 3)) #' #' # Define weights with the appropriate aesthetic #' d <- as.data.frame(Titanic) #' p_(ggally_trends( #' d, #' mapping = aes(x = Class, y = Survived, weight = Freq, color = Sex), #' include_zero = TRUE #' )) ggally_trends <- function( data, mapping, ..., include_zero = FALSE) { if (is.null(mapping$x)) stop("'x' aesthetic is required.") if (is.null(mapping$y)) stop("'y' aesthetic is required.") # computing group g <- list() if (!is.null(mapping$alpha)) g <- append(g, list(eval_data_col(data, mapping$alpha))) if (!is.null(mapping$colour)) g <- append(g, list(eval_data_col(data, mapping$colour))) if (!is.null(mapping$linetype)) g <- append(g, list(eval_data_col(data, mapping$linetype))) if (!is.null(mapping$size)) g <- append(g, list(eval_data_col(data, mapping$size))) if (length(g) == 0) { mapping$group <- aes(group = 1)$group } else { data$.group <- interaction(g) mapping$group <- aes(group = !!as.name(".group"))$group } # considering the different situations regarding y y <- eval_data_col(data, mapping$y) if (is.factor(y) || is.character(y) || is.logical(y)) { y <- as.factor(y) if (length(levels(y)) == 2) { # Binary variable data[[".ggally_y"]] <- as.integer(y == levels(y)[2]) mapping$y <- aes(y = !!as.name(".ggally_y"))$y p <- ggplot(data, mapping) + stat_weighted_mean(geom = "line", ...) + scale_y_continuous(labels = scales::percent) + ylab("") } else { # 3 or more categories yname <- mapping_string(mapping$y) # we need to duplicate date for each level of y # and to map y to linetype d <- data.frame() for (l in levels(y)) { tmp <- data tmp[[".ggally_y"]] <- as.integer(y == l) tmp$y <- l d <- plyr::rbind.fill(d, tmp) } mapping$linetype <- aes(y = !!as.name("y"))$y mapping$y <- aes(y = !!as.name(".ggally_y"))$y # recomputing groups g <- list() if (!is.null(mapping$alpha)) g <- append(g, list(eval_data_col(d, mapping$alpha))) if (!is.null(mapping$colour)) g <- append(g, list(eval_data_col(d, mapping$colour))) if (!is.null(mapping$linetype)) g <- append(g, list(eval_data_col(d, mapping$linetype))) if (!is.null(mapping$size)) g <- append(g, list(eval_data_col(d, mapping$size))) d$.group <- interaction(g) mapping$group <- aes(group = !!as.name(".group"))$group p <- ggplot(d, mapping) + stat_weighted_mean(geom = "line", ...) + scale_y_continuous(labels = scales::percent) + ylab("") + labs(linetype = yname) } } else { # Numeric variable p <- ggplot(data, mapping) + stat_weighted_mean(geom = "line", ...) } if (include_zero) { p <- p + expand_limits(y = 0) } p } GGally/R/ggfacet.R0000644000176200001440000001056414527265752013402 0ustar liggesusers#' Single \pkg{ggplot2} plot matrix with \code{\link[ggplot2]{facet_grid}} #' #' #' @param data data.frame that contains all columns to be displayed. This data will be melted before being passed into the function \code{fn} #' @param mapping aesthetic mapping (besides \code{x} and \code{y}). See \code{\link[ggplot2]{aes}()} #' @param fn function to be executed. Similar to \code{\link{ggpairs}} and \code{\link{ggduo}}, the function may either be a string identifier or a real function that \code{\link{wrap}} understands. #' @param ... extra arguments passed directly to \code{fn} #' @param columnsX columns to be displayed in the plot matrix #' @param columnsY rows to be displayed in the plot matrix #' @param columnLabelsX,columnLabelsY column and row labels to display in the plot matrix #' @param xlab,ylab,title plot matrix labels #' @param scales parameter supplied to \code{ggplot2::\link[ggplot2]{facet_grid}}. Default behavior is \code{"free"} #' @export #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' if (requireNamespace("chemometrics", quietly = TRUE)) { #' data(NIR, package = "chemometrics") #' NIR_sub <- data.frame(NIR$yGlcEtOH, NIR$xNIR[, 1:3]) #' str(NIR_sub) #' x_cols <- c("X1115.0", "X1120.0", "X1125.0") #' y_cols <- c("Glucose", "Ethanol") #' #' # using ggduo directly #' p <- ggduo(NIR_sub, x_cols, y_cols, types = list(continuous = "points")) #' p_(p) #' #' # using ggfacet #' p <- ggfacet(NIR_sub, x_cols, y_cols) #' p_(p) #' #' # add a smoother #' p <- ggfacet(NIR_sub, x_cols, y_cols, fn = "smooth_loess") #' p_(p) #' # same output #' p <- ggfacet(NIR_sub, x_cols, y_cols, fn = ggally_smooth_loess) #' p_(p) #' #' # Change scales to be the same in for every row and for every column #' p <- ggfacet(NIR_sub, x_cols, y_cols, scales = "fixed") #' p_(p) #' } ggfacet <- function( data, mapping = NULL, columnsX = 1:ncol(data), columnsY = 1:ncol(data), fn = ggally_points, ..., columnLabelsX = names(data[columnsX]), columnLabelsY = names(data[columnsY]), xlab = NULL, ylab = NULL, title = NULL, scales = "free") { data <- fix_data(data) fn <- wrap(fn) # fix args if ( !missing(mapping) && !is.list(mapping) && !missing(columnsX) && missing(columnsY) ) { columnsY <- columnsX columnsX <- mapping mapping <- NULL } stop_if_bad_mapping(mapping) columnsX <- fix_column_values(data, columnsX, columnLabelsX, "columnsX", "columnLabelsX") columnsY <- fix_column_values(data, columnsY, columnLabelsY, "columnsY", "columnLabelsY") # could theoretically work like # mtc <- mtcars # mtc$am <- as.factor(mtc$am) # mtc$cyl <- as.factor(mtc$cyl) # ggfacet( # mtc, # columnsY = c(1, 3, 4, 5), columnsX = c("am", "cyl"), # fn = function(data, mapping) {ggplot(data, mapping) + geom_boxplot()} # ) is_factor_x <- sapply(data[columnsX], is.factor) if (sum(is_factor_x) != 0) { warning(paste(sum(is_factor_x), " factor variables are being removed from X columns", sep = "")) columnsX <- columnsX[!is_factor_x] columnLabelsX <- columnLabelsX[!is_factor_x] } is_factor_y <- sapply(data[columnsY], is.factor) if (sum(is_factor_y) != 0) { warning(paste(sum(is_factor_y), " factor variables are being removed from Y columns", sep = "")) columnsY <- columnsY[!is_factor_y] columnLabelsY <- columnLabelsY[!is_factor_y] } tall_data <- ddply( expand.grid(.x_col = columnsX, .y_col = columnsY), c(".x_col", ".y_col"), function(row) { x_var <- row$.x_col[1] y_var <- row$.y_col[1] ret <- data ret[[".x_val"]] <- data[[x_var]] ret[[".y_val"]] <- data[[y_var]] ret } ) if (is.null(mapping)) { mapping <- aes() } mapping[c("x", "y")] <- aes(x = !!as.name(".x_val"), y = !!as.name(".y_val")) names(columnLabelsX) <- as.character(columnsX) names(columnLabelsY) <- as.character(columnsY) labeller <- function(vals) { val_names <- names(vals) if (".x_col" %in% val_names) { vals[[".x_col"]] <- columnLabelsX[as.character(vals[[".x_col"]])] } if (".y_col" %in% val_names) { vals[[".y_col"]] <- columnLabelsY[as.character(vals[[".y_col"]])] } vals } p <- fn(tall_data, mapping, ...) + facet_grid(.y_col ~ .x_col, labeller = labeller, scales = scales) + labs(title = title, x = xlab, y = ylab) p } GGally/R/ggally_colbar.R0000644000176200001440000001101514527265752014573 0ustar liggesusers#' Column and row bar plots #' #' Plot column or row percentage using bar plots. #' #' @param data data set using #' @param mapping aesthetics being used #' @param label_format formatter function for displaying proportions, not taken into account if a label aesthetic is provided in \code{mapping} #' @param ... other arguments passed to \code{\link[ggplot2]{geom_text}(...)} #' @param remove_percentage_axis should percentage axis be removed? Removes the y-axis for \code{ggally_colbar()} and x-axis for \code{ggally_rowbar()} #' @param remove_background should the \code{panel.background} be removed? #' @param reverse_fill_levels should the levels of the fill variable be reversed? #' @param geom_bar_args other arguments passed to \code{\link[ggplot2]{geom_bar}(...)} #' @author Joseph Larmarange #' @keywords hplot #' @export #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' data(tips) #' p_(ggally_colbar(tips, mapping = aes(x = smoker, y = sex))) #' p_(ggally_rowbar(tips, mapping = aes(x = smoker, y = sex))) #' #' # change labels' size #' p_(ggally_colbar(tips, mapping = aes(x = smoker, y = sex), size = 8)) #' #' # change labels' colour and use bold #' p_(ggally_colbar(tips, #' mapping = aes(x = smoker, y = sex), #' colour = "white", fontface = "bold" #' )) #' #' # display number of observations instead of proportions #' p_(ggally_colbar(tips, mapping = aes(x = smoker, y = sex, label = after_stat(count)))) #' #' # custom bar width #' p_(ggally_colbar(tips, mapping = aes(x = smoker, y = sex), geom_bar_args = list(width = .5))) #' #' # change format of labels #' p_(ggally_colbar(tips, #' mapping = aes(x = smoker, y = sex), #' label_format = scales::label_percent(accuracy = .01, decimal.mark = ",") #' )) #' #' p_(ggduo( #' data = as.data.frame(Titanic), #' mapping = aes(weight = Freq), #' columnsX = "Survived", #' columnsY = c("Sex", "Class", "Age"), #' types = list(discrete = "rowbar"), #' legend = 1 #' )) ggally_colbar <- function( data, mapping, label_format = scales::label_percent(accuracy = .1), ..., remove_background = FALSE, remove_percentage_axis = FALSE, reverse_fill_levels = FALSE, geom_bar_args = NULL) { if (is.null(mapping$x)) stop("'x' aesthetic is required.") if (is.null(mapping$y)) stop("'y' aesthetic is required.") # y should be mapped to fill and x to by mapping$fill <- mapping$y mapping$y <- NULL mapping$by <- mapping$x # colour should not be mapped in aes if (!is.null(mapping$colour)) { mapping$colour <- NULL } # label mapping if (!is.null(mapping$label)) { mapping_text <- aes() mapping_text$label <- mapping$label } else { mapping_text <- aes(label = label_format(after_stat(!!as.name("prop")))) } # position for geom_bar geom_bar_args$position <- position_fill(reverse = reverse_fill_levels) p <- ggplot(data, mapping) + do.call(geom_bar, geom_bar_args) + geom_text( mapping = mapping_text, stat = "prop", position = position_fill(.5, reverse = reverse_fill_levels), ... ) + scale_y_continuous( labels = scales::percent, expand = expansion(ifelse(remove_background, 0, .05), 0) ) + scale_x_discrete(expand = expansion(0, ifelse(remove_background, 0, .6))) + ylab("") + guides(fill = guide_legend(reverse = reverse_fill_levels)) if (isTRUE(remove_background)) { p <- p + theme( panel.background = element_blank() ) } if (isTRUE(remove_percentage_axis)) { p <- p + theme( panel.grid = element_blank(), axis.text.y = element_blank(), axis.ticks.y = element_blank() ) } p } #' @rdname ggally_colbar #' @export ggally_rowbar <- function( data, mapping, label_format = scales::label_percent(accuracy = .1), ..., remove_background = FALSE, remove_percentage_axis = FALSE, reverse_fill_levels = TRUE, geom_bar_args = NULL) { mapping <- mapping_swap_x_y(mapping) p <- ggally_colbar( data = data, mapping = mapping, label_format = label_format, ..., remove_background = remove_background, remove_percentage_axis = FALSE, reverse_fill_levels = reverse_fill_levels, geom_bar_args = geom_bar_args ) + coord_flip() + guides(fill = guide_legend(reverse = !reverse_fill_levels)) if (isTRUE(remove_percentage_axis)) { p <- p + theme( panel.grid = element_blank(), axis.text.x = element_blank(), axis.ticks.x = element_blank() ) } p } GGally/R/data-pigs.R0000644000176200001440000000214614526737226013647 0ustar liggesusers#' United Kingdom Pig Production #' #' This data contains about the United Kingdom Pig Production from the book 'Data' by Andrews and Herzberg. The original data can be on Statlib: http://lib.stat.cmu.edu/datasets/Andrews/T62.1 #' #' The time variable has been added from a combination of year and quarter #' #' @details \itemize{ #' \item time year + (quarter - 1) / 4 #' \item year year of production #' \item quarter quarter of the year of production #' \item gilts number of sows giving birth for the first time #' \item profit ratio of price to an index of feed price #' \item s_per_herdsz ratio of the number of breeding pigs slaughtered to the total breeding herd size #' \item production number of pigs slaughtered that were reared for meat #' \item herdsz breeding herd size #' } #' #' @docType data #' @keywords datasets #' @name pigs #' @usage data(pigs) #' @format A data frame with 48 rows and 8 variables #' @references #' Andrews, David F., and Agnes M. Herzberg. Data: a collection of problems from many fields for the student and research worker. Springer Science & Business Media, 2012. NULL GGally/R/ggsurv.R0000644000176200001440000002664614527265752013327 0ustar liggesusersif (getRversion() >= "2.15.1") { utils::globalVariables(c("cens", "surv", "up", "low")) } #' Survival curves #' #' This function produces Kaplan-Meier plots using \pkg{ggplot2}. #' As a first argument it needs a \code{survfit} object, created by the #' \code{survival} package. Default settings differ for single stratum and #' multiple strata objects. #' #' @export #' @param s an object of class \code{survfit} #' @param CI should a confidence interval be plotted? Defaults to \code{TRUE} #' for single stratum objects and \code{FALSE} for multiple strata objects. #' @param plot.cens mark the censored observations? #' @param surv.col colour of the survival estimate. Defaults to black for #' one stratum, and to the default \pkg{ggplot2} colours for multiple #' strata. Length of vector with colour names should be either 1 or equal #' to the number of strata. #' @param cens.col colour of the points that mark censored observations. #' @param lty.est linetype of the survival curve(s). Vector length should be #' either 1 or equal to the number of strata. #' @param lty.ci linetype of the bounds that mark the 95% CI. #' @param size.est line width of the survival curve #' @param size.ci line width of the 95% CI #' @param cens.size point size of the censoring points #' @param cens.shape shape of the points that mark censored observations. #' @param back.white if TRUE the background will not be the default #' grey of \code{ggplot2} but will be white with borders around the plot. #' @param xlab the label of the x-axis. #' @param ylab the label of the y-axis. #' @param main the plot label. #' @param order.legend boolean to determine if the legend display should be ordered by final survival time #' @return An object of class \code{ggplot} #' @author Edwin Thoen #' @importFrom stats time #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' if (require(survival) && require(scales)) { #' lung <- survival::lung #' sf.lung <- survival::survfit(Surv(time, status) ~ 1, data = lung) #' p_(ggsurv(sf.lung)) #' #' # Multiple strata examples #' sf.sex <- survival::survfit(Surv(time, status) ~ sex, data = lung) #' pl.sex <- ggsurv(sf.sex) #' p_(pl.sex) #' #' # Adjusting the legend of the ggsurv fit #' p_(pl.sex + #' ggplot2::guides(linetype = "none") + #' ggplot2::scale_colour_discrete( #' name = "Sex", #' breaks = c(1, 2), #' labels = c("Male", "Female") #' )) #' #' # Multiple factors #' lung2 <- dplyr::mutate(lung, older = as.factor(age > 60)) #' sf.sex2 <- survival::survfit(Surv(time, status) ~ sex + older, data = lung2) #' pl.sex2 <- ggsurv(sf.sex2) #' p_(pl.sex2) #' #' # Change legend title #' p_(pl.sex2 + labs(color = "New Title", linetype = "New Title")) #' #' # We can still adjust the plot after fitting #' kidney <- survival::kidney #' sf.kid <- survival::survfit(Surv(time, status) ~ disease, data = kidney) #' pl.kid <- ggsurv(sf.kid, plot.cens = FALSE) #' p_(pl.kid) #' #' # Zoom in to first 80 days #' p_(pl.kid + ggplot2::coord_cartesian(xlim = c(0, 80), ylim = c(0.45, 1))) #' #' # Add the diseases names to the plot and remove legend #' p_(pl.kid + #' ggplot2::annotate( #' "text", #' label = c("PKD", "Other", "GN", "AN"), #' x = c(90, 125, 5, 60), #' y = c(0.8, 0.65, 0.55, 0.30), #' size = 5, #' colour = scales::hue_pal( #' h = c(0, 360) + 15, #' c = 100, #' l = 65, #' h.start = 0, #' direction = 1 #' )(4) #' ) + #' ggplot2::guides(color = "none", linetype = "none")) #' } ggsurv <- function( s, CI = "def", plot.cens = TRUE, surv.col = "gg.def", cens.col = "gg.def", lty.est = 1, lty.ci = 2, size.est = 0.5, size.ci = size.est, cens.size = 2, cens.shape = 3, back.white = FALSE, xlab = "Time", ylab = "Survival", main = "", order.legend = TRUE) { require_namespaces(c("survival", "scales")) strata <- ifelse(is.null(s$strata) == TRUE, 1, length(s$strata)) stopifnot(length(surv.col) == 1 | length(surv.col) == strata) stopifnot(length(lty.est) == 1 | length(lty.est) == strata) if (strata == 1) { fn <- ggsurv_s } else { fn <- ggsurv_m } pl <- fn( s, CI, plot.cens, surv.col, cens.col, lty.est, lty.ci, size.est, size.ci, cens.size, cens.shape, back.white, xlab, ylab, main, strata, order.legend ) pl } # survival function for single survival ggsurv_s <- function( s, CI = "def", plot.cens = TRUE, surv.col = "gg.def", cens.col = "gg.def", lty.est = 1, lty.ci = 2, size.est = 0.5, size.ci = size.est, cens.size = 2, cens.shape = 3, back.white = FALSE, xlab = "Time", ylab = "Survival", main = "", strata = 1, order.legend = TRUE) { dat <- data.frame( time = c(0, s$time), surv = c(1, s$surv), up = c(1, s$upper), low = c(1, s$lower), cens = c(0, s$n.censor) ) dat.cens <- subset(dat, cens != 0) col <- ifelse(surv.col == "gg.def", "black", surv.col) pl <- ggplot(dat, aes(x = time, y = surv)) + geom_step(col = col, lty = lty.est, linewidth = size.est) + xlab(xlab) + ylab(ylab) + ggtitle(main) if (identical(CI, TRUE) | identical(CI, "def")) { pl <- pl + geom_step(aes(y = up), color = col, lty = lty.ci, linewidth = size.ci) + geom_step(aes(y = low), color = col, lty = lty.ci, linewidth = size.ci) } if (identical(plot.cens, TRUE)) { if (nrow(dat.cens) == 0) { stop("There are no censored observations") } col <- ifelse(cens.col == "gg.def", "red", cens.col) pl <- pl + geom_point( data = dat.cens, mapping = aes(y = surv), shape = cens.shape, col = col, size = cens.size ) } if (back.white == TRUE) { pl <- pl + theme_bw() } pl } # survival function for multiple survivals ggsurv_m <- function( s, CI = "def", plot.cens = TRUE, surv.col = "gg.def", cens.col = "gg.def", lty.est = 1, lty.ci = 2, size.est = 0.5, size.ci = size.est, cens.size = 2, cens.shape = 3, back.white = FALSE, xlab = "Time", ylab = "Survival", main = "", strata = length(s$strata), order.legend = TRUE) { n <- s$strata has_many <- all(grepl(",", names(s$strata))) if (has_many) { gr.name <- "combination" ugroups <- names(s$strata) } else { # singular strataEqualNames <- strsplit(names(s$strata), "=") gr.name <- strataEqualNames[[1]][[1]] ugroups <- vapply(strataEqualNames, `[[`, character(1), 2) } getlast <- function(x) { res <- NULL maxTime <- max(x$time) for (mo in names(x$strata)) { sur <- x[mo]$surv n <- length(sur) # grab the last survival value surValue <- sur[n] if (isTRUE(all.equal(surValue, 0))) { # if they die, order by percent complete of max observation. # tie value of 0 if the last person dies at the last time surTime <- x[mo]$time[n] surValue <- (surTime / maxTime) - 1 } res <- append(res, surValue) } return(res) } if (isTRUE(order.legend)) { group_order <- order(getlast(s), decreasing = TRUE) lastv <- ugroups[group_order] if (length(surv.col) == length(n)) { surv.col <- surv.col[group_order] } if (length(cens.col) == length(n)) { cens.col <- cens.col[group_order] } } else { lastv <- ugroups } groups <- factor(ugroups, levels = lastv) gr.df <- vector("list", strata) n.ind <- cumsum(c(0, n)) for (i in 1:strata) { indI <- (n.ind[i] + 1):n.ind[i + 1] gr.df[[i]] <- data.frame( time = c(0, s$time[indI]), surv = c(1, s$surv[indI]), up = c(1, s$upper[indI]), low = c(1, s$lower[indI]), cens = c(0, s$n.censor[indI]), group = rep(groups[i], n[i] + 1) ) } dat <- do.call(rbind, gr.df) pl <- ggplot(dat, aes(x = time, y = surv, group = group)) + geom_step(aes(col = group, lty = group), linewidth = size.est) + xlab(xlab) + ylab(ylab) + ggtitle(main) pl <- if (surv.col[1] != "gg.def") { scaleValues <- if (length(surv.col) == 1) { rep(surv.col, strata) } else { surv.col } pl + scale_colour_manual(values = scaleValues) } else { pl + scale_colour_discrete() } lineScaleValues <- if (length(lty.est) == 1) { rep(lty.est, strata) } else { lty.est } pl <- pl + scale_linetype_manual(values = lineScaleValues) if (identical(CI, TRUE)) { stepLty <- if ((length(surv.col) > 1 | surv.col == "gg.def")[1]) { lty.ci } else { surv.col } pl <- pl + geom_step(aes(y = up, lty = group, col = group), lty = stepLty, linewidth = size.ci) + geom_step(aes(y = low, lty = group, col = group), lty = stepLty, linewidth = size.ci) } if (identical(plot.cens, TRUE)) { dat.cens <- subset(dat, cens != 0) dat.cens <- subset(dat.cens, group != "PKD") if (nrow(dat.cens) == 0) { stop("There are no censored observations") } if (length(cens.col) == 1) { if (identical(cens.col, "gg.def")) { # match the colors of the lines pl <- pl + geom_point( data = dat.cens, mapping = aes(y = surv, col = group), shape = cens.shape, size = cens.size, show.legend = FALSE ) } else { # supply the raw color value pl <- pl + geom_point( data = dat.cens, mapping = aes(y = surv), shape = cens.shape, color = cens.col, size = cens.size ) } } else if (length(cens.col) > 0) { # if (!(identical(cens.col, surv.col) || is.null(cens.col))) { # warning ("Color scales for survival curves and censored points don't match.\nOnly one color scale can be used. Defaulting to surv.col") # } if (!identical(cens.col, "gg.def")) { if (length(cens.col) != strata) { warning("Color scales for censored points don't match the number of groups. Defaulting to ggplot2 default color scale") cens.col <- "gg.def" } } if (identical(cens.col, "gg.def")) { # match the group color value pl <- pl + geom_point( data = dat.cens, mapping = aes(y = surv, col = group), shape = cens.shape, show.legend = FALSE, size = cens.size ) } else { # custom colors and maybe custom shape uniqueGroupVals <- levels(dat.cens$group) if (length(cens.shape) == 1) { cens.shape <- rep(cens.shape, strata) } if (length(cens.shape) != strata) { warning("The length of the censored shapes does not match the number of groups (or 1). Defaulting shape = 3 (+)") cens.shape <- rep(3, strata) } for (i in seq_along(uniqueGroupVals)) { groupVal <- uniqueGroupVals[i] dtGroup <- subset(dat.cens, group == groupVal) if (nrow(dtGroup) == 0) { next } pl <- pl + geom_point( data = dtGroup, mapping = aes(y = surv), color = I(cens.col[i]), shape = cens.shape[i], show.legend = FALSE, size = cens.size ) } } } } if (identical(back.white, TRUE)) { pl <- pl + theme_bw() } pl <- pl + labs( color = gr.name, linetype = gr.name ) pl } GGally/R/ggmatrix_gtable_helpers.R0000644000176200001440000000774214527265752016670 0ustar liggesusersplot_gtable <- function(p) { ggplot_gtable(ggplot_build(p)) } # axis_size_left(p) # axis_size_bottom(p) # axis_size_left(g) # axis_size_bottom(g) axis_list <- (function() { axis_label_size_wrapper <- function(fn, filter_val, select_val, unitTo, valueOnly) { function(pg) { pg_axis <- gtable::gtable_filter(pg, filter_val) items <- pg_axis[[select_val]] if (!inherits(items, "unit.list")) { ret <- fn(items, unitTo = unitTo, valueOnly = valueOnly) } else { ret <- vapply(items, fn, numeric(1), unitTo = unitTo, valueOnly = valueOnly) } max(ret) } } axis_size_left <- axis_label_size_wrapper( grid::convertWidth, "axis-l", "widths", unitTo = "cm", valueOnly = TRUE ) axis_size_bottom <- axis_label_size_wrapper( grid::convertHeight, "axis-b", "heights", unitTo = "cm", valueOnly = TRUE ) list(axis_size_left, axis_size_bottom) })() axis_size_left <- axis_list[[1]] axis_size_bottom <- axis_list[[2]] # add_correct_label <- function(pmg, pm, plot_panel <- function( pg, row_pos, col_pos, matrix_show_strips, matrix_ncol, plot_show_axis_labels) { # ask about strips layout_names <- c("panel") strip_right_name <- "strip-r|strip-l" strip_top_name <- "strip-t|strip-b" legend_name <- "guide-box" all_layout_names <- c(layout_names, strip_right_name, strip_top_name, legend_name) if (is.null(matrix_show_strips)) { # make sure it's on the outer right and top edge if (col_pos == (matrix_ncol)) { layout_names <- c(layout_names, strip_right_name) } if (row_pos == 1) { layout_names <- c(layout_names, strip_top_name) } } else if (matrix_show_strips) { layout_names <- c(layout_names, strip_right_name, strip_top_name) } # if they have a custom plot, make sure it shows up if (!is.null(plot_show_axis_labels)) { # pShowStrips <- ! identical(p$axisLabels, FALSE) # copied from old code. want to replace it to something like above if (plot_show_axis_labels %in% c("internal", "none")) { layout_names <- all_layout_names } } # get correct panel (and strips) layout_rows <- str_detect(pg$layout$name, paste(layout_names, collapse = "|")) layout_info <- pg$layout[layout_rows, ] top_bottom <- layout_info[, c("t", "b")] left_right <- layout_info[, c("l", "r")] plot_panel <- pg[ min(top_bottom):max(top_bottom), min(left_right):max(left_right) ] plot_panel } add_left_axis <- function(pmg, pg, show_strips, grob_pos) { layout <- pg$layout layout_name <- layout$name # axis layout info al <- layout[str_detect(layout_name, "axis-l"), ] if (show_strips) { alx <- layout[str_detect(layout_name, "axis-l|strip-t|strip-b"), ] } else { alx <- al } # get only the axis left objects (and maybe strip top spacer) axis_panel <- pg[min(alx$b):max(alx$t), min(al$l)] # force to align left axis_panel <- gtable::gtable_add_cols(axis_panel, grid::unit(1, "null"), 0) pmg$grobs[[grob_pos]] <- axis_panel pmg } add_bottom_axis <- function(pmg, pg, show_strips, grob_pos) { layout <- pg$layout layout_name <- layout$name # axis layout info al <- layout[str_detect(layout_name, "axis-b"), ] if (show_strips) { alx <- layout[str_detect(layout_name, "axis-b|strip-r|strip-l"), ] } else { alx <- al } # get only the axis left objects (and maybe strip top spacer) axis_panel <- pg[min(al$t), min(alx$l):max(alx$r)] # force to align top axis_panel <- gtable::gtable_add_rows(axis_panel, grid::unit(1, "null"), 1) pmg$grobs[[grob_pos]] <- axis_panel pmg } set_max_axis_size <- function(pmg, axis_sizes, layout_name, layout_cols, pmg_key) { m_axis_size <- max(axis_sizes, na.rm = TRUE) grob_pos_vals <- which(str_detect(pmg$layout$name, layout_name)) val_pos <- pmg$layout[grob_pos_vals, layout_cols] val_pos <- unique(unlist(val_pos)) # if (length(val_pos) > 1) { # stop(stop_msg) # } pmg[[pmg_key]][[val_pos]] <- unit(m_axis_size, "cm") pmg } GGally/R/data-baseball.R0000644000176200001440000000255214526737217014453 0ustar liggesusers#' Yearly batting records for all major league baseball players #' #' This data frame contains batting statistics for a subset of players #' collected from \url{http://www.baseball-databank.org/}. There are a total #' of 21,699 records, covering 1,228 players from 1871 to 2007. Only players #' with more 15 seasons of play are included. #' #' @section Variables: #' Variables: #' \itemize{ #' \item id, unique player id #' \item year, year of data #' \item stint #' \item team, team played for #' \item lg, league #' \item g, number of games #' \item ab, number of times at bat #' \item r, number of runs #' \item h, hits, times reached base because of a batted, fair ball without #' error by the defense #' \item X2b, hits on which the batter reached second base safely #' \item X3b, hits on which the batter reached third base safely #' \item hr, number of home runs #' \item rbi, runs batted in #' \item sb, stolen bases #' \item cs, caught stealing #' \item bb, base on balls (walk) #' \item so, strike outs #' \item ibb, intentional base on balls #' \item hbp, hits by pitch #' \item sh, sacrifice hits #' \item sf, sacrifice flies #' \item gidp, ground into double play #' } #' @docType data #' @name baseball #' @usage baseball #' @format A 21699 x 22 data frame #' @references \url{http://www.baseball-databank.org/} #' @keywords datasets "baseball" GGally/R/data-nasa.R0000644000176200001440000000156214526737225013627 0ustar liggesusers#' Data from the Data Expo JSM 2006. #' #' This data was provided by NASA for the competition. #' #' The data shows 6 years of monthly measurements of a 24x24 spatial grid #' from Central America: #' #' @details \itemize{ #' \item time integer specifying temporal order of measurements #' \item x, y, lat, long spatial location of measurements. #' \item cloudhigh, cloudlow, cloudmid, ozone, pressure, surftemp, temperature #' are the various satellite measurements. #' \item date, day, month, year specifying the time of measurements. #' \item id unique ide for each spatial position. #' } #' #' @docType data #' @keywords datasets #' @name nasa #' @usage data(nasa) #' @format A data frame with 41472 rows and 17 variables #' @references #' Murrell, P. (2010) The 2006 Data Expo of the American Statistical Association. #' Computational Statistics, 25:551-554. NULL GGally/R/ggpairs_add.R0000644000176200001440000002457314527265752014253 0ustar liggesusers#' Modify a \code{\link{ggmatrix}} object by adding an \pkg{ggplot2} object to all plots #' #' This operator allows you to add \pkg{ggplot2} objects to a \code{\link{ggmatrix}} object. #' #' If the first object is an object of class \code{\link{ggmatrix}}, you can add #' the following types of objects, and it will return a modified \pkg{ggplot2} #' object. #' #' \itemize{ ###### \item \code{data.frame}: replace current data.frame ###### (must use \code{%+%}) ###### \item \code{uneval}: replace current aesthetics ###### \item \code{layer}: add new layer #' \item \code{theme}: update plot theme #' \item \code{scale}: replace current scale #' \item \code{coord}: override current coordinate system ###### \item \code{facet}: override current coordinate faceting #' } #' #' The \code{+} operator completely replaces elements #' with elements from e2. #' #' @param e1 An object of class \code{\link{ggnostic}} or \code{ggplot} #' @param e2 A component to add to \code{e1} #' #' @export #' @seealso [ggplot2::+.gg] and [ggplot2::theme()] #' @method + gg #' @rdname gg-add #' @examples #' # small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' data(tips) #' #' pm <- ggpairs(tips[, 2:4], ggplot2::aes(color = sex)) #' ## change to black and white theme #' pm + ggplot2::theme_bw() #' ## change to linedraw theme #' p_(pm + ggplot2::theme_linedraw()) #' ## change to custom theme #' p_(pm + ggplot2::theme(panel.background = ggplot2::element_rect(fill = "lightblue"))) #' ## add a list of information #' extra <- list(ggplot2::theme_bw(), ggplot2::labs(caption = "My caption!")) #' p_(pm + extra) "+.gg" <- function(e1, e2) { if (!is.ggmatrix(e1)) { return(e1 %+% e2) } if (is.null(e1$gg)) { e1$gg <- list() } if (inherits(e2, "labels")) { add_labels_to_ggmatrix(e1, e2) } else if (is.theme(e2)) { add_theme_to_ggmatrix(e1, e2) } else if (is.list(e2)) { add_list_to_ggmatrix(e1, e2) } else if (is.ggproto(e2)) { add_to_ggmatrix(e1, e2) } else { stop( "'ggmatrix' does not know how to add objects that do not have class 'theme', 'labels' or 'ggproto'.", " Received object with class: '", paste(class(e2), collapse = ", "), "'" ) } } add_gg_info <- function(p, gg) { if (!is.null(gg)) { if (!is.null(gg$theme)) { p <- p + gg$theme } if (!is.null(gg$labs)) { p <- p + gg$labs } } p } add_labels_to_ggmatrix <- function(e1, e2) { label_names <- names(e2) if ("x" %in% label_names) { e1$xlab <- e2$x } if ("y" %in% label_names) { e1$ylab <- e2$y } if ("title" %in% label_names) { e1$title <- e2$title } non_ggmatrix_labels <- label_names[!label_names %in% c("x", "y", "title")] if (length(non_ggmatrix_labels) > 0) { if (is.null(e1$gg$labs)) { e1$gg$labs <- structure(list(), class = "labels") } e1$gg$labs[non_ggmatrix_labels] <- e2[non_ggmatrix_labels] } e1 } add_theme_to_ggmatrix <- function(e1, e2) { # Get the name of what was passed in as e2, and pass along so that it # can be displayed in error messages # e2name <- deparse(substitute(e2)) if (is.null(e1$gg$theme)) { e1$gg$theme <- e2 } else { # calls ggplot2 add method and stores the result in gg e1$gg$theme <- e1$gg$theme %+% e2 } e1 } #' @export #' @rdname gg-add #' @inheritParams ggmatrix_location #' @details #' \code{add_to_ggmatrix} gives you more control to modify #' only some subplots. This function may be replaced and/or removed in the future. \Sexpr[results=rd, stage=render]{lifecycle::badge("experimental")} #' @seealso \code{\link{ggmatrix_location}} #' @examples #' ## modify scale #' p_(pm + scale_fill_brewer(type = "qual")) #' ## only first row #' p_(add_to_ggmatrix(pm, scale_fill_brewer(type = "qual"), rows = 1:2)) #' ## only second col #' p_(add_to_ggmatrix(pm, scale_fill_brewer(type = "qual"), cols = 2:3)) #' ## only to upper triangle of plot matrix #' p_(add_to_ggmatrix( #' pm, #' scale_fill_brewer(type = "qual"), #' location = "upper" #' )) add_to_ggmatrix <- function( e1, e2, location = NULL, rows = NULL, cols = NULL) { if (!is.ggmatrix(e1)) { stop("e1 should be a ggmatrix.") } if (!is.ggproto(e2)) { stop("e2 should be a ggproto object.") } pm <- e1 gg <- e2 loc <- ggmatrix_location(pm, location = location, rows = rows, cols = cols) row_vals <- loc$row col_vals <- loc$col for (i in seq_along(row_vals)) { row <- row_vals[i] col <- col_vals[i] # wrap in try to not let one plot fail, but also print the error try({ pm[row, col] <- pm[row, col] + gg }) } pm } #' \code{\link{ggmatrix}} plot locations #' #' \lifecycle{experimental} #' #' Convert many types of location values to a consistent \code{data.frame} of \code{row} and \code{col} values. #' #' @param pm \code{\link{ggmatrix}} plot object #' @param location \describe{ #' \item{\code{"all"}, \code{TRUE}}{All row and col combinations} #' \item{\code{"none"}}{No row and column combinations} #' \item{\code{"upper"}}{Locations where the column value is higher than the row value} #' \item{\code{"lower"}}{Locations where the row value is higher than the column value} #' \item{\code{"diag"}}{Locations where the column value is equal to the row value} #' \item{\code{matrix} or \code{data.frame}}{ #' \code{matrix} values will be converted into \code{data.frame}s. #' \itemize{ #' \item A \code{data.frame} with the exact column names \code{c("row", "col")} #' \item A \code{data.frame} with the number of rows and columns matching the plot matrix object provided. Each cell will be tested for a "truthy" value to determine if the location should be kept. #' } #' } #' } #' @param rows numeric vector of the rows to be used. Will be used with \code{cols} if \code{location} is \code{NULL} #' @param cols numeric vector of the cols to be used. Will be used with \code{rows} if \code{location} is \code{NULL} #' @return Data frame with columns \code{c("row", "col")} containing locations for the plot matrix #' @export #' @examples #' pm <- ggpairs(tips, 1:3) #' #' # All locations #' ggmatrix_location(pm, location = "all") #' ggmatrix_location(pm, location = TRUE) #' #' # No locations #' ggmatrix_location(pm, location = "none") #' #' # "upper" triangle locations #' ggmatrix_location(pm, location = "upper") #' #' # "lower" triangle locations #' ggmatrix_location(pm, location = "lower") #' #' # "diag" locations #' ggmatrix_location(pm, location = "diag") #' #' # specific rows #' ggmatrix_location(pm, rows = 2) #' #' # specific columns #' ggmatrix_location(pm, cols = 2) #' #' # row and column combinations #' ggmatrix_location(pm, rows = c(1, 2), cols = c(1, 3)) #' #' # matrix locations #' mat <- matrix(TRUE, ncol = 3, nrow = 3) #' mat[1, 1] <- FALSE #' locs <- ggmatrix_location(pm, location = mat) #' ## does not contain the 1, 1 cell #' locs #' #' # Use the output of a prior ggmatrix_location #' ggmatrix_location(pm, location = locs) ggmatrix_location <- function( pm, location = NULL, rows = NULL, cols = NULL) { if (!is.ggmatrix(pm)) stop("pm should be a ggmatrix.") if (!is.null(location)) { if (is.logical(location) && !(is.matrix(location) || is.data.frame(location))) { if (length(location) != 1) { stop("`location` logical value must be of length 1") } location <- if (isTRUE(location)) { "all" } else { warning("Not `TRUE` logical `location` value. Setting to `'none'`") "none" } } if (is.character(location)) { location <- match.arg(location, c("all", "upper", "lower", "diag", "none"), several.ok = FALSE) locs <- expand.grid(row = seq_len(pm$nrow), col = seq_len(pm$ncol)) location <- switch(location, "all" = locs, "none" = subset(locs, FALSE), "diag" = subset(locs, row == col), "upper" = subset(locs, col > row), "lower" = subset(locs, col < row), stop(location, " not implemented") ) } else { if (is.matrix(location)) { location <- as.data.frame(location) } if (is.data.frame(location)) { if (!identical(c("row", "col"), colnames(location))) { # using data.frame of locations as truthy vals if (ncol(location) != pm$ncol) { stop("location provided does not have the same size of columns") } if (nrow(location) != pm$nrow) { stop("location provided does not have the same size of rows") } # turn wide matrix into a tall data.frame of row/col combos tmp_locs <- data.frame(row = numeric(0), col = numeric(0)) for (i in seq_len(nrow(location))) { for (j in seq_len(ncol(location))) { val <- location[i, j] if (val) { tmp_locs[nrow(tmp_locs) + 1, ] <- list(row = i, col = j) } } } location <- tmp_locs } # end (location is data.frame) } # end (location not character) } # end (location not null) } else { # location is null if (is.null(rows)) { rows <- seq_len(pm$nrow) } if (!is.numeric(rows)) { stop("rows must be numeric") } if (is.null(cols)) { cols <- seq_len(pm$ncol) } if (!is.numeric(cols)) { stop("cols must be numeric") } location <- expand.grid(row = rows, col = cols) } # location will be a 2d data.frame with colnames of `'row'` and `'col'` locs <- as.data.frame(location) if (ncol(locs) < 2) { utils::str(locs) stop("not enough columns to inspect for a location") } if (!all(c("row", "col") %in% colnames(locs))) { stop("invalid location row / col object") } row <- locs$row if (any(row > pm$nrow) || any(row <= 0) || any(is.na(row))) { stop( "`row` must be non-NA / positive numeric values `<= pm$nrow`", "\n", "pm$nrow: ", dput_val(pm$nrow), "\n", "row: ", dput_val(row) ) } col <- locs$col if (any(col > pm$ncol) || any(col <= 0) || any(is.na(col))) { stop( "`col` must be non-NA / positive numeric values `<= pm$ncol`", "\n", "pm$ncol: ", dput_val(pm$ncol), "\n", "col: ", dput_val(col) ) } # typical case return( locs[, c("row", "col")] ) } add_list_to_ggmatrix <- function(e1, e2) { for (item in e2) { e1 <- e1 + item } e1 } is.ggmatrix <- function(x) { inherits(x, "ggmatrix") } GGally/R/utils-pipe.R0000644000176200001440000000055314527407231014060 0ustar liggesusers#' Pipe operator #' #' See \code{magrittr::\link[magrittr:pipe]{\%>\%}} for details. #' #' @name %>% #' @rdname pipe #' @keywords internal #' @export #' @importFrom magrittr %>% #' @usage lhs \%>\% rhs #' @param lhs A value or the magrittr placeholder. #' @param rhs A function call using the magrittr semantics. #' @return The result of calling `rhs(lhs)`. NULL GGally/R/ggpairs.R0000644000176200001440000011107514527265752013435 0ustar liggesusers# list of the different plot types to check # continuous # points # smooth # smooth_loess # density # cor # blank # combo # box # box_no_facet # dot # dot_no_facet # facethist # facetdensity # denstrip # blank # discrete # ratio # count # facetbar # blank # diag # continuous # densityDiag # barDiag # blankDiag # discrete # barDiag # blankDiag crosstalk_key <- function() { ".crossTalkKey" } fortify_SharedData <- function(model, data, ...) { key <- model$key() set <- model$groupName() data <- model$origData() # need a consistent name so we know how to access it in ggplotly() # MUST be added last. can NOT be done first data[[crosstalk_key()]] <- key structure(data, set = set) } fix_data <- function(data) { if (inherits(data, "SharedData")) { data <- fortify_SharedData(data) } data <- fortify(data) data <- as.data.frame(data) for (i in 1:dim(data)[2]) { if (is.character(data[[i]])) { data[[i]] <- as.factor(data[[i]]) } } data } fix_data_slim <- function(data, isSharedData) { if (isSharedData) { data[[crosstalk_key()]] <- NULL } data } fix_column_values <- function( data, columns, columnLabels, columnsName, columnLabelsName, isSharedData = FALSE) { colnamesData <- colnames(data) if (is.character(columns)) { colNumValues <- lapply(columns, function(colName) { which(colnamesData == colName) }) isFound <- as.logical(unlist(lapply(colNumValues, length))) if (any(!isFound)) { stop( "Columns in '", columnsName, "' not found in data: c(", str_c(str_c("'", columns[!isFound], "'"), collapse = ", "), "). Choices: c('", paste(colnamesData, collapse = "', '"), "')" ) } columns <- unlist(colNumValues) } if (any(columns > ncol(data))) { stop( "Make sure your numeric '", columnsName, "'", " values are less than or equal to ", ncol(data), ".\n", "\t", columnsName, " = c(", str_c(columns, collapse = ", "), ")" ) } if (any(columns < 1)) { stop( "Make sure your numeric '", columnsName, "' values are positive.", "\n", "\t", columnsName, " = c(", paste(columns, collapse = ", "), ")" ) } if (any((columns %% 1) != 0)) { stop( "Make sure your numeric '", columnsName, "' values are integers.", "\n", "\t", columnsName, " = c(", paste(columns, collapse = ", "), ")" ) } if (!is.null(columnLabels)) { if (length(columnLabels) != length(columns)) { stop( "The length of the '", columnLabelsName, "'", " does not match the length of the '", columnsName, "' being used.", " Labels: c('", paste(columnLabels, collapse = ", "), "')\n", " Columns: c('", paste(columns, collapse = ", "), "')" ) } } columns } warn_deprecated <- function(is_supplied, title) { if (is_supplied) { warning(paste( "'", title, "' will be deprecated in future versions. Please remove it from your code", sep = "" )) } } stop_if_bad_mapping <- function(mapping) { if (is.numeric(mapping)) { stop( "'mapping' should not be numeric", " unless 'columns' is missing from function call." ) } } warn_if_args_exist <- function(args) { if (length(args) > 0) { argNames <- names(args) warning(str_c( "Extra arguments: ", str_c(shQuote(argNames), collapse = ", "), " are being ignored.", " If these are meant to be aesthetics, submit them using the", " 'mapping' variable within ggpairs with ggplot2::aes or ggplot2::aes_string." )) } } fix_axis_label_choice <- function(axisLabels, axisLabelChoices) { if (length(axisLabels) > 1) { axisLabels <- axisLabels[1] } axisLabelChoice <- pmatch(axisLabels, axisLabelChoices) if (is.na(axisLabelChoice)) { warning(str_c( "'axisLabels' not in c(", str_c(str_c("'", axisLabelChoices, "'"), collapse = ", "), "). Reverting to '", axisLabelChoices[1], "'" )) axisLabelChoice <- 1 } axisLabels <- axisLabelChoices[axisLabelChoice] } stop_if_high_cardinality <- function(data, columns, threshold) { if (is.null(threshold)) { return() } if (identical(threshold, FALSE)) { return() } if (!is.numeric(threshold)) { stop("'cardinality_threshold' should be a numeric or NULL") } for (col in names(data[columns])) { data_col <- data[[col]] if (!is.numeric(data_col)) { level_length <- length(levels(data_col)) if (level_length > threshold) { stop( "Column '", col, "' has more levels (", level_length, ")", " than the threshold (", threshold, ") allowed.\n", "Please remove the column or increase the 'cardinality_threshold' parameter. Increasing the cardinality_threshold may produce long processing times" # nolint ) } } } } #' \pkg{ggplot2} generalized pairs plot for two columns sets of data #' #' Make a matrix of plots with a given data set with two different column sets #' #' @details #' \code{types} is a list that may contain the variables #' 'continuous', 'combo', 'discrete', and 'na'. Each element of the list may be a function or a string. If a string is supplied, If a string is supplied, it must be a character string representing the tail end of a \code{ggally_NAME} function. The list of current valid \code{ggally_NAME} functions is visible in a dedicated vignette. #' \describe{ #' \item{continuous}{This option is used for continuous X and Y data.} #' \item{comboHorizontal}{This option is used for either continuous X and categorical Y data or categorical X and continuous Y data.} #' \item{comboVertical}{This option is used for either continuous X and categorical Y data or categorical X and continuous Y data.} #' \item{discrete}{This option is used for categorical X and Y data.} #' \item{na}{This option is used when all X data is \code{NA}, all Y data is \code{NA}, or either all X or Y data is \code{NA}.} #' } #' #' If 'blank' is ever chosen as an option, then ggduo will produce an empty plot. #' #' If a function is supplied as an option, it should implement the function api of \code{function(data, mapping, ...){#make ggplot2 plot}}. If a specific function needs its parameters set, \code{\link{wrap}(fn, param1 = val1, param2 = val2)} the function with its parameters. #' #' @export #' @param data data set using. Can have both numerical and categorical data. #' @param mapping aesthetic mapping (besides \code{x} and \code{y}). See \code{\link[ggplot2]{aes}()}. If \code{mapping} is numeric, \code{columns} will be set to the \code{mapping} value and \code{mapping} will be set to \code{NULL}. #' @param columnsX,columnsY which columns are used to make plots. Defaults to all columns. #' @param title,xlab,ylab title, x label, and y label for the graph #' @param types see Details #' @param axisLabels either "show" to display axisLabels or "none" for no axis labels #' @param columnLabelsX,columnLabelsY label names to be displayed. Defaults to names of columns being used. #' @template ggmatrix-labeller-param #' @template ggmatrix-switch-param #' @param showStrips boolean to determine if each plot's strips should be displayed. \code{NULL} will default to the top and right side plots only. \code{TRUE} or \code{FALSE} will turn all strips on or off respectively. #' @template ggmatrix-legend-param #' @param cardinality_threshold maximum number of levels allowed in a character / factor column. Set this value to NULL to not check factor columns. Defaults to 15 #' @template ggmatrix-progress #' @param legends deprecated #' @param xProportions,yProportions Value to change how much area is given for each plot. Either \code{NULL} (default), numeric value matching respective length, \code{grid::\link[grid]{unit}} object with matching respective length or \code{"auto"} for automatic relative proportions based on the number of levels for categorical variables. #' @export #' @examples #' # small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' data(baseball) #' #' # Keep players from 1990-1995 with at least one at bat #' # Add how many singles a player hit #' # (must do in two steps as X1b is used in calculations) #' dt <- transform( #' subset(baseball, year >= 1990 & year <= 1995 & ab > 0), #' X1b = h - X2b - X3b - hr #' ) #' # Add #' # the player's batting average, #' # the player's slugging percentage, #' # and the player's on base percentage #' # Make factor a year, as each season is discrete #' dt <- transform( #' dt, #' batting_avg = h / ab, #' slug = (X1b + 2 * X2b + 3 * X3b + 4 * hr) / ab, #' on_base = (h + bb + hbp) / (ab + bb + hbp), #' year = as.factor(year) #' ) #' #' #' pm <- ggduo( #' dt, #' c("year", "g", "ab", "lg"), #' c("batting_avg", "slug", "on_base"), #' mapping = ggplot2::aes(color = lg) #' ) #' # Prints, but #' # there is severe over plotting in the continuous plots #' # the labels could be better #' # want to add more hitting information #' p_(pm) #' #' # address overplotting issues and add a title #' pm <- ggduo( #' dt, #' c("year", "g", "ab", "lg"), #' c("batting_avg", "slug", "on_base"), #' columnLabelsX = c("year", "player game count", "player at bat count", "league"), #' columnLabelsY = c("batting avg", "slug %", "on base %"), #' title = "Baseball Hitting Stats from 1990-1995", #' mapping = ggplot2::aes(color = lg), #' types = list( #' # change the shape and add some transparency to the points #' continuous = wrap("smooth_loess", alpha = 0.50, shape = "+") #' ), #' showStrips = FALSE #' ) #' #' p_(pm) #' #' # Use "auto" to adapt width of the sub-plots #' pm <- ggduo( #' dt, #' c("year", "g", "ab", "lg"), #' c("batting_avg", "slug", "on_base"), #' mapping = ggplot2::aes(color = lg), #' xProportions = "auto" #' ) #' #' p_(pm) #' #' # Custom widths & heights of the sub-plots #' pm <- ggduo( #' dt, #' c("year", "g", "ab", "lg"), #' c("batting_avg", "slug", "on_base"), #' mapping = ggplot2::aes(color = lg), #' xProportions = c(6, 4, 3, 2), #' yProportions = c(1, 2, 1) #' ) #' #' p_(pm) #' #' # Example derived from: #' ## R Data Analysis Examples | Canonical Correlation Analysis. UCLA: Institute for Digital #' ## Research and Education. #' ## from http://www.stats.idre.ucla.edu/r/dae/canonical-correlation-analysis #' ## (accessed May 22, 2017). #' # "Example 1. A researcher has collected data on three psychological variables, four #' # academic variables (standardized test scores) and gender for 600 college freshman. #' # She is interested in how the set of psychological variables relates to the academic #' # variables and gender. In particular, the researcher is interested in how many #' # dimensions (canonical variables) are necessary to understand the association between #' # the two sets of variables." #' data(psychademic) #' summary(psychademic) #' #' (psych_variables <- attr(psychademic, "psychology")) #' (academic_variables <- attr(psychademic, "academic")) #' #' ## Within correlation #' p_(ggpairs(psychademic, columns = psych_variables)) #' p_(ggpairs(psychademic, columns = academic_variables)) #' #' ## Between correlation #' loess_with_cor <- function(data, mapping, ..., method = "pearson") { #' x <- eval_data_col(data, mapping$x) #' y <- eval_data_col(data, mapping$y) #' cor <- cor(x, y, method = method) #' ggally_smooth_loess(data, mapping, ...) + #' ggplot2::geom_label( #' data = data.frame( #' x = min(x, na.rm = TRUE), #' y = max(y, na.rm = TRUE), #' lab = round(cor, digits = 3) #' ), #' mapping = ggplot2::aes(x = x, y = y, label = lab), #' hjust = 0, vjust = 1, #' size = 5, fontface = "bold", #' inherit.aes = FALSE # do not inherit anything from the ... #' ) #' } #' pm <- ggduo( #' psychademic, #' rev(psych_variables), academic_variables, #' types = list(continuous = loess_with_cor), #' showStrips = FALSE #' ) #' suppressWarnings(p_(pm)) # ignore warnings from loess #' #' # add color according to sex #' pm <- ggduo( #' psychademic, #' mapping = ggplot2::aes(color = sex), #' rev(psych_variables), academic_variables, #' types = list(continuous = loess_with_cor), #' showStrips = FALSE, #' legend = c(5, 2) #' ) #' suppressWarnings(p_(pm)) #' #' #' # add color according to sex #' pm <- ggduo( #' psychademic, #' mapping = ggplot2::aes(color = motivation), #' rev(psych_variables), academic_variables, #' types = list(continuous = loess_with_cor), #' showStrips = FALSE, #' legend = c(5, 2) #' ) + #' ggplot2::theme(legend.position = "bottom") #' suppressWarnings(p_(pm)) # pm <- ggduo( #' # dt, #' # c("year", "g", "ab", "lg", "lg"), #' # c("batting_avg", "slug", "on_base", "hit_type"), #' # columnLabelsX = c("year", "player game count", "player at bat count", "league", ""), #' # columnLabelsY = c("batting avg", "slug %", "on base %", "hit type"), #' # title = "Baseball Hitting Stats from 1990-1995 (player strike in 1994)", #' # mapping = aes(color = year), #' # types = list( #' # continuous = wrap("smooth_loess", alpha = 0.50, shape = "+"), #' # comboHorizontal = wrap(display_hit_type_combo, binwidth = 15), #' # discrete = wrap(display_hit_type_discrete, color = "black", size = 0.15) #' # ), #' # showStrips = FALSE # ); #' ## make the 5th column blank, except for the legend # pm[1, 5] <- NULL # pm[2, 5] <- grab_legend(pm[2, 1]) # pm[3, 5] <- NULL # pm[4, 5] <- NULL # pm # ggduo( #' # australia_PISA2012, #' # c("gender", "age", "homework", "possessions"), #' # c("PV1MATH", "PV2MATH", "PV3MATH", "PV4MATH", "PV5MATH"), #' # types = list( #' # continuous = "points", #' # combo = "box", #' # discrete = "ratio" #' # ) # ) # ggduo( #' # australia_PISA2012, #' # c("gender", "age", "homework", "possessions"), #' # c("PV1MATH", "PV2MATH", "PV3MATH", "PV4MATH", "PV5MATH"), #' # mapping = ggplot2::aes(color = gender), #' # types = list( #' # continuous = wrap("smooth", alpha = 0.25, method = "loess"), #' # combo = "box", #' # discrete = "ratio" #' # ) # ) # ggduo(australia_PISA2012, c("gender", "age", "homework", "possessions"), c("PV1MATH", "PV1READ", "PV1SCIE"), types = list(continuous = "points", combo = "box", discrete = "ratio")) # ggduo(australia_PISA2012, c("gender", "age", "homework", "possessions"), c("PV1MATH", "PV1READ", "PV1SCIE"), types = list(continuous = wrap("smooth", alpha = 0.25, method = "loess"), combo = "box", discrete = "ratio"), mapping = ggplot2::aes(color = gender)) ggduo <- function( data, mapping = NULL, columnsX = 1:ncol(data), columnsY = 1:ncol(data), title = NULL, types = list( continuous = "smooth_loess", comboVertical = "box_no_facet", comboHorizontal = "facethist", discrete = "count" ), axisLabels = c("show", "none"), columnLabelsX = colnames(data[columnsX]), columnLabelsY = colnames(data[columnsY]), labeller = "label_value", switch = NULL, xlab = NULL, ylab = NULL, showStrips = NULL, legend = NULL, cardinality_threshold = 15, progress = NULL, xProportions = NULL, yProportions = NULL, legends = stop("deprecated")) { warn_deprecated(!missing(legends), "legends") isSharedData <- inherits(data, "SharedData") data_ <- fix_data(data) data <- fix_data_slim(data_, isSharedData) # fix args if ( !missing(mapping) && !is.list(mapping) && !missing(columnsX) && missing(columnsY) ) { columnsY <- columnsX columnsX <- mapping mapping <- NULL } stop_if_bad_mapping(mapping) columnsX <- fix_column_values(data, columnsX, columnLabelsX, "columnsX", "columnLabelsX") columnsY <- fix_column_values(data, columnsY, columnLabelsY, "columnsY", "columnLabelsY") stop_if_high_cardinality(data, columnsX, cardinality_threshold) stop_if_high_cardinality(data, columnsY, cardinality_threshold) xProportions <- ggmatrix_proportions(xProportions, data, columnsX) yProportions <- ggmatrix_proportions(yProportions, data, columnsY) types <- check_and_set_ggpairs_defaults( "types", types, continuous = "smooth_loess", discrete = "count", na = "na", isDuo = TRUE ) if (!is.null(types[["combo"]])) { warning(str_c( "\nSetting:\n", "\ttypes$comboHorizontal <- types$combo\n", "\ttypes$comboVertical <- types$combo" )) types$comboHorizontal <- types$combo types$comboVertical <- types$combo types$combo <- NULL } if (is.null(types[["comboVertical"]])) { types$comboVertical <- "box_no_facet" } if (is.null(types[["comboHorizontal"]])) { types$comboHorizontal <- "facethist" } axisLabels <- fix_axis_label_choice(axisLabels, c("show", "none")) # get plot type information dataTypes <- plot_types(data, columnsX, columnsY, allowDiag = FALSE) ggduoPlots <- lapply(seq_len(nrow(dataTypes)), function(i) { plotType <- dataTypes[i, "plotType"] # posX <- dataTypes[i, "posX"] # posY <- dataTypes[i, "posY"] xColName <- dataTypes[i, "xVar"] yColName <- dataTypes[i, "yVar"] sectionAes <- add_and_overwrite_aes( add_and_overwrite_aes( aes(x = !!as.name(xColName), y = !!as.name(yColName)), mapping ), types$mapping ) if (plotType == "combo") { if (dataTypes[i, "isVertical"]) { plotTypesList <- list(combo = types$comboVertical) } else { plotTypesList <- list(combo = types$comboHorizontal) } } else { plotTypesList <- types } args <- list(types = plotTypesList, sectionAes = sectionAes) plot_fn <- ggmatrix_plot_list(plotType) plotObj <- do.call(plot_fn, args) return(plotObj) }) plotMatrix <- ggmatrix( plots = ggduoPlots, byrow = TRUE, nrow = length(columnsY), ncol = length(columnsX), xAxisLabels = columnLabelsX, yAxisLabels = columnLabelsY, labeller = labeller, switch = switch, showStrips = showStrips, showXAxisPlotLabels = identical(axisLabels, "show"), showYAxisPlotLabels = identical(axisLabels, "show"), title = title, xlab = xlab, ylab = ylab, data = data_, gg = NULL, progress = progress, legend = legend, xProportions = xProportions, yProportions = yProportions ) plotMatrix } ### Example removed due to not using facet labels anymore # #Sequence to show how to change label size # make_small_strip <- function(plot_matrix, from_top, from_left, new_size = 7){ # up <- from_left > from_top # p <- getPlot(plot_matrix, from_top, from_left) # if (up) # p <- p + opts(strip.text.x = element_text(size = new_size)) # else # p <- p + opts(strip.text.y = element_text(angle = -90, size = new_size)) # # putPlot(plot_matrix, p, from_top, from_left) # } # small_label_diamond <- make_small_strip(diamondMatrix, 2, 1) # small_label_diamond <- make_small_strip(small_label_diamond, 1, 2) # small_label_diamond <- make_small_strip(small_label_diamond, 2, 2) # #small_label_diamond # now with much smaller strip text #' ggplot2 generalized pairs plot #' #' Make a matrix of plots with a given data set #' #' @details #' \code{upper} and \code{lower} are lists that may contain the variables #' 'continuous', 'combo', 'discrete', and 'na'. Each element of the list may be a function or a string. If a string is supplied, it must be a character string representing the tail end of a \code{ggally_NAME} function. The list of current valid \code{ggally_NAME} functions is visible in a dedicated vignette. #' \describe{ #' \item{continuous}{This option is used for continuous X and Y data.} #' \item{combo}{This option is used for either continuous X and categorical Y data or categorical X and continuous Y data.} #' \item{discrete}{This option is used for categorical X and Y data.} #' \item{na}{This option is used when all X data is \code{NA}, all Y data is \code{NA}, or either all X or Y data is \code{NA}.} #' } #' #' \code{diag} is a list that may only contain the variables 'continuous', 'discrete', and 'na'. Each element of the diag list is a string implementing the following options: #' \describe{ #' \item{continuous}{exactly one of ('densityDiag', 'barDiag', 'blankDiag'). This option is used for continuous X data.} #' \item{discrete}{exactly one of ('barDiag', 'blankDiag'). This option is used for categorical X and Y data.} #' \item{na}{exactly one of ('naDiag', 'blankDiag'). This option is used when all X data is \code{NA}.} #' } #' #' If 'blank' is ever chosen as an option, then ggpairs will produce an empty plot. #' #' If a function is supplied as an option to \code{upper}, \code{lower}, or \code{diag}, it should implement the function api of \code{function(data, mapping, ...){#make ggplot2 plot}}. If a specific function needs its parameters set, \code{\link{wrap}(fn, param1 = val1, param2 = val2)} the function with its parameters. #' #' @export #' @seealso wrap v1_ggmatrix_theme #' @param data data set using. Can have both numerical and categorical data. #' @param mapping aesthetic mapping (besides \code{x} and \code{y}). See \code{\link[ggplot2]{aes}()}. If \code{mapping} is numeric, \code{columns} will be set to the \code{mapping} value and \code{mapping} will be set to \code{NULL}. #' @param columns which columns are used to make plots. Defaults to all columns. #' @param title,xlab,ylab title, x label, and y label for the graph #' @param upper see Details #' @param lower see Details #' @param diag see Details #' @param params deprecated. Please see \code{\link{wrap_fn_with_param_arg}} #' @param ... deprecated. Please use \code{mapping} #' @param axisLabels either "show" to display axisLabels, "internal" for labels in the diagonal plots, or "none" for no axis labels #' @param columnLabels label names to be displayed. Defaults to names of columns being used. #' @param proportions Value to change how much area is given for each plot. Either \code{NULL} (default), numeric value matching respective length, \code{grid::\link[grid]{unit}} object with matching respective length or \code{"auto"} for automatic relative proportions based on the number of levels for categorical variables. #' @template ggmatrix-labeller-param #' @template ggmatrix-switch-param #' @param showStrips boolean to determine if each plot's strips should be displayed. \code{NULL} will default to the top and right side plots only. \code{TRUE} or \code{FALSE} will turn all strips on or off respectively. #' @template ggmatrix-legend-param #' @param cardinality_threshold maximum number of levels allowed in a character / factor column. Set this value to NULL to not check factor columns. Defaults to 15 #' @template ggmatrix-progress #' @param legends deprecated #' @keywords hplot #' @import ggplot2 #' @references John W Emerson, Walton A Green, Barret Schloerke, Jason Crowley, Dianne Cook, Heike Hofmann, Hadley Wickham. The Generalized Pairs Plot. Journal of Computational and Graphical Statistics, vol. 22, no. 1, pp. 79-91, 2012. #' @author Barret Schloerke, Jason Crowley, Di Cook, Heike Hofmann, Hadley Wickham #' @return \code{\link{ggmatrix}} object that if called, will print #' @examples #' # small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' #' ## Quick example, with and without colour #' data(flea) #' ggpairs(flea, columns = 2:4) #' pm <- ggpairs(flea, columns = 2:4, ggplot2::aes(colour = species)) #' p_(pm) #' # Note: colour should be categorical, else you will need to reset #' # the upper triangle to use points instead of trying to compute corr #' #' data(tips) #' pm <- ggpairs(tips[, 1:3]) #' p_(pm) #' pm <- ggpairs(tips, 1:3, columnLabels = c("Total Bill", "Tip", "Sex")) #' p_(pm) #' pm <- ggpairs(tips, upper = "blank") #' p_(pm) #' #' ## Plot Types #' # Change default plot behavior #' pm <- ggpairs( #' tips[, c(1, 3, 4, 2)], #' upper = list(continuous = "density", combo = "box_no_facet"), #' lower = list(continuous = "points", combo = "dot_no_facet") #' ) #' p_(pm) #' # Supply Raw Functions (may be user defined functions!) #' pm <- ggpairs( #' tips[, c(1, 3, 4, 2)], #' upper = list(continuous = ggally_density, combo = ggally_box_no_facet), #' lower = list(continuous = ggally_points, combo = ggally_dot_no_facet) #' ) #' p_(pm) #' #' # Use sample of the diamonds data #' data(diamonds, package = "ggplot2") #' diamonds.samp <- diamonds[sample(1:dim(diamonds)[1], 1000), ] #' #' # Different aesthetics for different plot sections and plot types #' pm <- ggpairs( #' diamonds.samp[, 1:5], #' mapping = ggplot2::aes(color = cut), #' upper = list(continuous = wrap("density", alpha = 0.5), combo = "box_no_facet"), #' lower = list(continuous = wrap("points", alpha = 0.3), combo = wrap("dot_no_facet", alpha = 0.4)), #' title = "Diamonds" #' ) #' p_(pm) #' #' ## Axis Label Variations #' # Only Variable Labels on the diagonal (no axis labels) #' pm <- ggpairs(tips[, 1:3], axisLabels = "internal") #' p_(pm) #' # Only Variable Labels on the outside (no axis labels) #' pm <- ggpairs(tips[, 1:3], axisLabels = "none") #' p_(pm) #' #' ## Facet Label Variations #' # Default: #' df_x <- rnorm(100) #' df_y <- df_x + rnorm(100, 0, 0.1) #' df <- data.frame(x = df_x, y = df_y, c = sqrt(df_x^2 + df_y^2)) #' pm <- ggpairs( #' df, #' columnLabels = c("alpha[foo]", "alpha[bar]", "sqrt(alpha[foo]^2 + alpha[bar]^2)") #' ) #' p_(pm) #' # Parsed labels: #' pm <- ggpairs( #' df, #' columnLabels = c("alpha[foo]", "alpha[bar]", "sqrt(alpha[foo]^2 + alpha[bar]^2)"), #' labeller = "label_parsed" #' ) #' p_(pm) #' #' ## Plot Insertion Example #' custom_car <- ggpairs(mtcars[, c("mpg", "wt", "cyl")], upper = "blank", title = "Custom Example") #' # ggplot example taken from example(geom_text) #' plot <- ggplot2::ggplot(mtcars, ggplot2::aes(x = wt, y = mpg, label = rownames(mtcars))) #' plot <- plot + #' ggplot2::geom_text(ggplot2::aes(colour = factor(cyl)), size = 3) + #' ggplot2::scale_colour_discrete(l = 40) #' custom_car[1, 2] <- plot #' personal_plot <- ggally_text( #' "ggpairs allows you\nto put in your\nown plot.\nLike that one.\n <---" #' ) #' custom_car[1, 3] <- personal_plot #' p_(custom_car) #' #' ## Remove binwidth warning from ggplot2 #' # displays warning about picking a better binwidth #' pm <- ggpairs(tips, 2:3) #' p_(pm) #' # no warning displayed #' pm <- ggpairs(tips, 2:3, lower = list(combo = wrap("facethist", binwidth = 0.5))) #' p_(pm) #' # no warning displayed with user supplied function #' pm <- ggpairs(tips, 2:3, lower = list(combo = wrap(ggally_facethist, binwidth = 0.5))) #' p_(pm) #' #' ## Remove panel grid lines from correlation plots #' pm <- ggpairs( #' flea, #' columns = 2:4, #' upper = list(continuous = wrap(ggally_cor, displayGrid = FALSE)) #' ) #' p_(pm) #' #' ## Custom with/height of subplots #' pm <- ggpairs(tips, columns = c(2, 3, 5)) #' p_(pm) #' #' pm <- ggpairs(tips, columns = c(2, 3, 5), proportions = "auto") #' p_(pm) #' #' pm <- ggpairs(tips, columns = c(2, 3, 5), proportions = c(1, 3, 2)) #' p_(pm) #' ggpairs <- function( data, mapping = NULL, columns = 1:ncol(data), title = NULL, upper = list(continuous = "cor", combo = "box_no_facet", discrete = "count", na = "na"), lower = list(continuous = "points", combo = "facethist", discrete = "facetbar", na = "na"), diag = list(continuous = "densityDiag", discrete = "barDiag", na = "naDiag"), params = NULL, ..., xlab = NULL, ylab = NULL, axisLabels = c("show", "internal", "none"), columnLabels = colnames(data[columns]), labeller = "label_value", switch = NULL, showStrips = NULL, legend = NULL, cardinality_threshold = 15, progress = NULL, proportions = NULL, legends = stop("deprecated")) { warn_deprecated(!missing(legends), "legends") warn_if_args_exist(list(...)) stop_if_params_exist(params) isSharedData <- inherits(data, "SharedData") data_ <- fix_data(data) data <- fix_data_slim(data_, isSharedData) if ( !missing(mapping) && !is.list(mapping) && missing(columns) ) { columns <- mapping mapping <- NULL } stop_if_bad_mapping(mapping) columns <- fix_column_values(data, columns, columnLabels, "columns", "columnLabels") stop_if_high_cardinality(data, columns, cardinality_threshold) upper <- check_and_set_ggpairs_defaults( "upper", upper, continuous = "cor", combo = "box_no_facet", discrete = "count", na = "na" ) lower <- check_and_set_ggpairs_defaults( "lower", lower, continuous = "points", combo = "facethist", discrete = "facetbar", na = "na" ) diag <- check_and_set_ggpairs_defaults( "diag", diag, continuous = "densityDiag", discrete = "barDiag", na = "naDiag", isDiag = TRUE ) axisLabels <- fix_axis_label_choice(axisLabels, c("show", "internal", "none")) proportions <- ggmatrix_proportions(proportions, data, columns) # get plot type information dataTypes <- plot_types(data, columns, columns, allowDiag = TRUE) # make internal labels on the diag axis if (identical(axisLabels, "internal")) { dataTypes$plotType[dataTypes$posX == dataTypes$posY] <- "label" } ggpairsPlots <- lapply(seq_len(nrow(dataTypes)), function(i) { plotType <- dataTypes[i, "plotType"] posX <- dataTypes[i, "posX"] posY <- dataTypes[i, "posY"] xColName <- dataTypes[i, "xVar"] yColName <- dataTypes[i, "yVar"] if (posX > posY) { types <- upper } else if (posX < posY) { types <- lower } else { types <- diag } sectionAes <- add_and_overwrite_aes( add_and_overwrite_aes( aes(x = !!as.name(xColName), y = !!as.name(yColName)), mapping ), types$mapping ) args <- list(types = types, sectionAes = sectionAes) if (plotType == "label") { args$label <- columnLabels[posX] } plot_fn <- ggmatrix_plot_list(plotType) p <- do.call(plot_fn, args) return(p) }) plotMatrix <- ggmatrix( plots = ggpairsPlots, byrow = TRUE, nrow = length(columns), ncol = length(columns), xAxisLabels = (if (axisLabels == "internal") NULL else columnLabels), yAxisLabels = (if (axisLabels == "internal") NULL else columnLabels), labeller = labeller, switch = switch, showStrips = showStrips, showXAxisPlotLabels = identical(axisLabels, "show"), showYAxisPlotLabels = identical(axisLabels, "show"), title = title, xlab = xlab, ylab = ylab, data = data_, gg = NULL, progress = progress, legend = legend, xProportions = proportions, yProportions = proportions ) plotMatrix } #' Add new aes #' #' Add new aesthetics to a previous aes. #' #' @keywords internal #' @author Barret Schloerke #' @return aes_ output #' @import ggplot2 #' @rdname add_and_overwrite_aes #' @examples #' data(diamonds, package = "ggplot2") #' diamonds.samp <- diamonds[sample(1:dim(diamonds)[1], 1000), ] #' pm <- ggpairs(diamonds.samp, #' columns = 5:7, #' mapping = ggplot2::aes(color = color), #' upper = list(continuous = "cor", mapping = ggplot2::aes(color = clarity)), #' lower = list(continuous = "cor", mapping = ggplot2::aes(color = cut)), #' title = "Diamonds Sample" #' ) #' str(pm) #' add_and_overwrite_aes <- function(current, new) { if (length(new) >= 1) { for (i in 1:length(new)) { current[names(new)[i]] <- new[i] } } for (curName in names(current)) { if (is.null(current[[curName]])) { current[[curName]] <- NULL } } current } #' Aesthetic mapping color fill #' #' Replace the fill with the color and make color NULL. #' #' @param current the current aesthetics #' @export mapping_color_to_fill <- function(current) { if (is.null(current)) { return(aes()) } currentNames <- names(current) color <- c("color", "colour") if (any(color %in% currentNames) && "fill" %in% currentNames) { # do nothing } else if (any(color %in% currentNames)) { # fill <- current[["fill" %in% currentNames]] # col <- current[[color %in% currentNames]] # current <- add_and_overwrite_aes(current, aes_string(fill = col, color = NA)) current$fill <- current$colour current$colour <- NULL } # if (!is.null(mapping$colour) && !is.null(mapping$fill)) { # # do nothing # } else if (!is.null(mapping$colour)) { # } current } set_to_blank_list_if_blank <- function( val, combo = TRUE, blank = "blank", isDuo = FALSE) { isBlank <- is.null(val) if (!isBlank) { isBlank <- (!is.list(val) && (val == blank || val == "blank")) } if (isBlank) { val <- list() val$continuous <- blank if (combo) { val$combo <- blank } if (isDuo) { val$comboVertical <- blank val$comboHorizontal <- blank } val$discrete <- blank val$na <- blank } val } check_and_set_ggpairs_defaults <- function( name, obj, continuous = NULL, combo = NULL, discrete = NULL, na = NULL, isDiag = FALSE, isDuo = FALSE) { blankVal <- ifelse(isDiag, "blankDiag", "blank") obj <- set_to_blank_list_if_blank( obj, combo = !isDiag && !isDuo, blank = blankVal, isDuo = isDuo ) if (!is.list(obj)) { stop("'", name, "' is not a list") } stop_if_params_exist(obj$params) if (is.null(obj$continuous) && (!is.null(continuous))) { obj$continuous <- continuous } if (is.null(obj$combo) && (!is.null(combo))) { obj$combo <- combo } if (is.null(obj$discrete) && (!is.null(discrete))) { obj$discrete <- discrete } if (is.null(obj$na) && (!is.null(na))) { obj$na <- na } if (!is.null(obj$aes_string)) { stop( "'aes_string' is a deprecated element for the section ", name, ".\n", "Please use 'mapping' instead. " ) } if (isDiag) { for (key in c("continuous", "discrete", "na")) { val <- obj[[key]] if (is.character(val)) { if (!str_detect(val, "Diag$")) { newVal <- paste(val, "Diag", sep = "") warning(paste( "Changing diag$", key, " from '", val, "' to '", newVal, "'", sep = "" )) obj[[key]] <- newVal } } } } obj } get_subtype_name <- function(.subType) { fn <- wrapp(.subType) ret <- attr(fn, "name") if (ret == ".subType") { ret <- "custom_function" } ret } stop_if_params_exist <- function(params) { if (!is.null(params)) { stop( "'params' is a deprecated argument. ", "Please 'wrap' the function to supply arguments. ", "help(\"wrap\", package = \"GGally\")" ) } } ggmatrix_proportions <- function(proportions, data, columns) { if (is.null(proportions)) { return(proportions) } # relative proportions if "auto" # wrap in isTRUE for safe guarding if (isTRUE(length(proportions) == 1 && proportions == "auto")) { proportions <- c() for (v in columns) { if (is.numeric(data[[v]])) { proportions <- c(proportions, NA) } else { proportions <- c(proportions, length(levels(as.factor(data[[v]])))) } } # for numeric variables, the average proportions[is.na(proportions)] <- mean(proportions, na.rm = TRUE) proportions[is.na(proportions)] <- 1 # in case all are numeric } else { is_valid_type <- vapply(proportions, function(x) { (!is.na(x)) && ( grid::is.unit(x) || is.numeric(x) ) }, logical(1)) if (!all(is_valid_type)) { stop("proportions need to be non-NA numeric values or 'auto'. proportions: ", dput_val(proportions)) } } if (length(proportions) == 1 && length(columns) > 1) { proportions <- replicate(length(columns), proportions) } proportions } dput_val <- function(x) { f <- file() on.exit({ close(f) }) dput(x, f) ret <- paste0(readLines(f), collapse = "\n") ret } # diamondMatrix <- ggpairs( # diamonds, # columns = 8:10, # upper = list(points = "scatterplot", aes_string = aes_string(color = "cut")), # lower = list(points = "scatterplot", aes_string = aes_string(color = "cut")), # diag = "blank", ## color = "color", # title = "Diamonds" # ) # if(TRUE) # { # # d <- diamonds[runif(floor(nrow(diamonds)/10), 0, nrow(diamonds)), ] # # diamondMatrix <- ggpairs( # d, # columns = 8:10, # upper = list(continuous = "points", aes_string = aes_string(color = "clarity")), # lower = list(continuous = "points", aes_string = aes_string(color = "cut")), # diag = "blank", ## color = "color", # title = "Diamonds" # ) # # # m <- mtcars ## m$vs <- as.factor(m$vs) ## m$cyl <- as.factor(m$cyl) ## m$qsec <- as.factor(m$qsec) # carsMatrix <- ggpairs( # mtcars, # columns = c(1, 3, 4), # upper = list(continuous = "points", aes_string = aes_string(shape = "cyl", size = 5)), # lower = list(continuous = "points", aes_string = aes_string(size = "cyl")), # diag = "blank", # color = "cyl", # title = "mtcars", # ) # # # carsMatrix <- ggpairs( # mtcars, # columns = c(1, 3, 4), # upper = list(aes_string = aes_string(shape = "as.factor(cyl)", size = 5)), # lower = list(aes_string = aes_string(size = "as.factor(cyl)")), # diag = "blank", # color = "cyl", # title = "Custom Cars", # ) # # # } GGally/R/ggparcoord.R0000644000176200001440000006224014527407231014115 0ustar liggesusers#' @importFrom dplyr all_of if (getRversion() >= "2.15.1") { utils::globalVariables(c("variable", "value", "ggally_splineFactor", ".ggally_ggcorr_row_names")) } #' Parallel coordinate plot #' #' A function for plotting static parallel coordinate plots, utilizing #' the \code{ggplot2} graphics package. #' #' \code{scale} is a character string that denotes how to scale the variables #' in the parallel coordinate plot. Options: #' \describe{ #' \item{\code{std}}{: univariately, subtract mean and divide by standard deviation} #' \item{\code{robust}}{: univariately, subtract median and divide by median absolute deviation} #' \item{\code{uniminmax}}{: univariately, scale so the minimum of the variable is zero, and the maximum is one} #' \item{\code{globalminmax}}{: no scaling is done; the range of the graphs is defined #' by the global minimum and the global maximum} #' \item{\code{center}}{: use \code{uniminmax} to standardize vertical height, then #' center each variable at a value specified by the \code{scaleSummary} param} #' \item{\code{centerObs}}{: use \code{uniminmax} to standardize vertical height, then #' center each variable at the value of the observation specified by the \code{centerObsID} param} #' } #' #' \code{missing} is a character string that denotes how to handle missing #' missing values. Options: #' \describe{ #' \item{\code{exclude}}{: remove all cases with missing values} #' \item{\code{mean}}{: set missing values to the mean of the variable} #' \item{\code{median}}{: set missing values to the median of the variable} #' \item{\code{min10}}{: set missing values to 10% below the minimum of the variable} #' \item{\code{random}}{: set missing values to value of randomly chosen observation on that variable} #' } #' #' \code{order} is either a vector of indices or a character string that denotes how to #' order the axes (variables) of the parallel coordinate plot. Options: #' \describe{ #' \item{\code{(default)}}{: order by the vector denoted by \code{columns}} #' \item{\code{(given vector)}}{: order by the vector specified} #' \item{\code{anyClass}}{: order variables by their separation between any one class and #' the rest (as opposed to their overall variation between classes). This is accomplished #' by calculating the F-statistic for each class vs. the rest, for each axis variable. #' The axis variables are then ordered (decreasing) by their maximum of k F-statistics, #' where k is the number of classes.} #' \item{\code{allClass}}{: order variables by their overall F statistic (decreasing) from #' an ANOVA with \code{groupColumn} as the explanatory variable (note: it is required #' to specify a \code{groupColumn} with this ordering method). Basically, this method #' orders the variables by their variation between classes (most to least).} #' \item{\code{skewness}}{: order variables by their sample skewness (most skewed to #' least skewed)} #' \item{\code{Outlying}}{: order by the scagnostic measure, Outlying, as calculated #' by the package \code{scagnostics}. Other scagnostic measures available to order #' by are \code{Skewed}, \code{Clumpy}, \code{Sparse}, \code{Striated}, \code{Convex}, \code{Skinny}, \code{Stringy}, and #' \code{Monotonic}. Note: To use these methods of ordering, you must have the \code{scagnostics} #' package loaded.} #' } #' #' @param data the dataset to plot #' @param columns a vector of variables (either names or indices) to be axes in the plot #' @param groupColumn a single variable to group (color) by #' @param scale method used to scale the variables (see Details) #' @param scaleSummary if scale=="center", summary statistic to univariately #' center each variable by #' @param centerObsID if scale=="centerObs", row number of case plot should #' univariately be centered on #' @param missing method used to handle missing values (see Details) #' @param order method used to order the axes (see Details) #' @param showPoints logical operator indicating whether points should be #' plotted or not #' @param splineFactor logical or numeric operator indicating whether spline interpolation should be used. Numeric values will multiplied by the number of columns, \code{TRUE} will default to cubic interpolation, \code{\link[base]{AsIs}} to set the knot count directly and \code{0}, \code{FALSE}, or non-numeric values will not use spline interpolation. #' @param alphaLines value of alpha scaler for the lines of the parcoord plot or a column name of the data #' @param boxplot logical operator indicating whether or not boxplots should #' underlay the distribution of each variable #' @param shadeBox color of underlying box which extends from the min to the #' max for each variable (no box is plotted if \code{shadeBox == NULL}) #' @param mapping aes string to pass to ggplot object #' @param title character string denoting the title of the plot #' @author Jason Crowley, Barret Schloerke, Dianne Cook, Heike Hofmann, Hadley Wickham #' @return ggplot object that if called, will print #' @importFrom plyr ddply summarize #' @importFrom stats complete.cases sd median mad lm spline #' @importFrom tidyr pivot_longer #' @export #' @examples #' # small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' # use sample of the diamonds data for illustrative purposes #' data(diamonds, package = "ggplot2") #' diamonds.samp <- diamonds[sample(1:dim(diamonds)[1], 100), ] #' #' # basic parallel coordinate plot, using default settings #' p <- ggparcoord(data = diamonds.samp, columns = c(1, 5:10)) #' p_(p) #' #' # this time, color by diamond cut #' p <- ggparcoord(data = diamonds.samp, columns = c(1, 5:10), groupColumn = 2) #' p_(p) #' #' # underlay univariate boxplots, add title, use uniminmax scaling #' p <- ggparcoord( #' data = diamonds.samp, columns = c(1, 5:10), groupColumn = 2, #' scale = "uniminmax", boxplot = TRUE, title = "Parallel Coord. Plot of Diamonds Data" #' ) #' p_(p) #' #' # utilize ggplot2 aes to switch to thicker lines #' p <- ggparcoord( #' data = diamonds.samp, columns = c(1, 5:10), groupColumn = 2, #' title = "Parallel Coord. Plot of Diamonds Data", mapping = ggplot2::aes(linewidth = 1) #' ) + #' ggplot2::scale_linewidth_identity() #' p_(p) #' #' # basic parallel coord plot of the msleep data, using 'random' imputation and #' # coloring by diet (can also use variable names in the columns and groupColumn #' # arguments) #' data(msleep, package = "ggplot2") #' p <- ggparcoord( #' data = msleep, columns = 6:11, groupColumn = "vore", missing = #' "random", scale = "uniminmax" #' ) #' p_(p) #' #' # center each variable by its median, using the default missing value handler, #' # 'exclude' #' p <- ggparcoord( #' data = msleep, columns = 6:11, groupColumn = "vore", scale = #' "center", scaleSummary = "median" #' ) #' p_(p) #' #' # with the iris data, order the axes by overall class (Species) separation using #' # the anyClass option #' p <- ggparcoord(data = iris, columns = 1:4, groupColumn = 5, order = "anyClass") #' p_(p) #' #' # add points to the plot, add a title, and use an alpha scalar to make the lines #' # transparent #' p <- ggparcoord( #' data = iris, columns = 1:4, groupColumn = 5, order = "anyClass", #' showPoints = TRUE, title = "Parallel Coordinate Plot for the Iris Data", #' alphaLines = 0.3 #' ) #' p_(p) #' #' # color according to a column #' iris2 <- iris #' iris2$alphaLevel <- c("setosa" = 0.2, "versicolor" = 0.3, "virginica" = 0)[iris2$Species] #' p <- ggparcoord( #' data = iris2, columns = 1:4, groupColumn = 5, order = "anyClass", #' showPoints = TRUE, title = "Parallel Coordinate Plot for the Iris Data", #' alphaLines = "alphaLevel" #' ) #' p_(p) #' #' ## Use splines on values, rather than lines (all produce the same result) #' columns <- c(1, 5:10) #' p <- ggparcoord(diamonds.samp, columns, groupColumn = 2, splineFactor = TRUE) #' p_(p) #' p <- ggparcoord(diamonds.samp, columns, groupColumn = 2, splineFactor = 3) #' p_(p) ggparcoord <- function( data, columns = 1:ncol(data), groupColumn = NULL, scale = "std", scaleSummary = "mean", centerObsID = 1, missing = "exclude", order = columns, showPoints = FALSE, splineFactor = FALSE, alphaLines = 1, boxplot = FALSE, shadeBox = NULL, mapping = NULL, title = "") { if (!identical(class(data), "data.frame")) { data <- as.data.frame(data) } saveData <- data ### Error Checking ### if (is.null(groupColumn)) { if (any(tolower(order) %in% c("anyclass", "allclass"))) { stop("can't use the 'order' methods anyClass or allClass without specifying groupColumn") } } else if ( !((length(groupColumn) == 1) && (is.numeric(groupColumn) || is.character(groupColumn))) ) { stop("invalid value for 'groupColumn'; must be a single numeric or character index") } if (!(tolower(scale) %in% c( "std", "robust", "uniminmax", "globalminmax", "center", "centerobs" ))) { stop(str_c( "invalid value for 'scale'; must be one of ", "'std', 'robust', 'uniminmax', 'globalminmax', 'center', or 'centerObs'" )) } if (!(centerObsID %in% 1:dim(data)[1])) { stop("invalid value for 'centerObsID'; must be a single numeric row index") } if (!(tolower(missing) %in% c("exclude", "mean", "median", "min10", "random"))) { stop( "invalid value for 'missing'; must be one of 'exclude', 'mean', 'median', 'min10', 'random'" ) } if (!( is.numeric(order) || ( is.character(order) && ( order %in% c( "skewness", "allClass", "anyClass", "Outlying", "Skewed", "Clumpy", "Sparse", "Striated", "Convex", "Skinny", "Stringy", "Monotonic" ) ) ) ) ) { stop(str_c( "invalid value for 'order'; must either be a vector of column indices or one of ", "'skewness', 'allClass', 'anyClass', 'Outlying', 'Skewed', 'Clumpy', 'Sparse', 'Striated', ", "'Convex', 'Skinny', 'Stringy', 'Monotonic'" )) } if (!(is.logical(showPoints))) { stop("invalid value for 'showPoints'; must be a logical operator") } alphaLinesIsCharacter <- is.character(alphaLines) if (alphaLinesIsCharacter) { if (!(alphaLines %in% names(data))) { stop("'alphaLines' column is missing in data") } alphaVar <- data[[alphaLines]] alphaRange <- range(alphaVar) if (any(is.na(alphaRange))) { stop("missing data in 'alphaLines' column") } if (alphaRange[1] < 0 || alphaRange[2] > 1) { stop("invalid value for 'alphaLines' column; max range must be from 0 to 1") } } else if ((alphaLines < 0) || (alphaLines > 1)) { # nolint stop("invalid value for 'alphaLines'; must be a scalar value between 0 and 1") } if (!(is.logical(boxplot))) { stop("invalid value for 'boxplot'; must be a logical operator") } if (!is.null(shadeBox) && length(shadeBox) != 1) { stop("invalid value for 'shadeBox'; must be a single color") } else { valid_color <- tryCatch(is.matrix(grDevices::col2rgb(shadeBox)), error = function(e) FALSE ) if (!valid_color) { stop("invalid value for 'shadeBox'; must be a valid R color") } } if (is.logical(splineFactor)) { if (splineFactor) { splineFactor <- 3 } else { splineFactor <- 0 } } else if (!is.numeric(splineFactor)) { stop("invalid value for 'splineFactor'; must be a logical or numeric value") } ### Setup ### if (is.numeric(groupColumn)) { groupColumn <- names(data)[groupColumn] } if (!is.null(groupColumn)) { groupVar <- data[[groupColumn]] } if (is.character(columns)) { columns_ <- c() for (colPos in seq_along(columns)) { columns_[colPos] <- which(colnames(data) == columns[colPos]) } columns <- columns_ } # data <- data[columns] # Change character vars to factors char.vars <- column_is_character(data) if (length(char.vars) >= 1) { for (char.var in char.vars) { data[[char.var]] <- factor(data[[char.var]]) } } # Change factors to numeric fact.vars <- column_is_factor(data) fact.vars <- setdiff(fact.vars, groupColumn) if (length(fact.vars) >= 1) { for (fact.var in fact.vars) { data[[fact.var]] <- as.numeric(data[[fact.var]]) } } # Save this form of the data for order calculations (don't want imputed # missing values affecting order, but do want any factor/character vars # being plotted as numeric) saveData2 <- data if (!is.null(groupColumn)) { saveData2[[groupColumn]] <- as.numeric(saveData2[[groupColumn]]) } p <- c(ncol(data) + 1, ncol(data) + 2) data$.ID <- as.factor(1:nrow(data)) data$anyMissing <- apply(is.na(data[, columns]), 1, any) columnsPlusTwo <- c(columns, p) inner_rescaler_default <- function(x, type = "sd", ...) { # copied directly from reshape because of import difficulties :-( # rescaler.default switch(type, rank = rank(x, ...), var = , # nolint sd = (x - mean(x, na.rm = TRUE)) / sd(x, na.rm = TRUE), robust = (x - median(x, na.rm = TRUE)) / mad(x, na.rm = TRUE), I = x, range = (x - min(x, na.rm = TRUE)) / diff(range(x, na.rm = TRUE)) ) } inner_rescaler <- function(x, type = "sd", ...) { # copied directly from reshape because of import difficulties :-( # rescaler.data.frame continuous <- sapply(x, is.numeric) if (any(continuous)) { if (type %in% c("sd", "robust", "range")) { # indicating columns containing only one single value singleVal <- sapply(x, function(col) { if (length(unique(col)) == 1) { TRUE } else { FALSE } }) ind <- continuous & !singleVal x[ind] <- lapply(x[ind], inner_rescaler_default, type = type, ...) x[singleVal] <- 1 } else { x[continuous] <- lapply(x[continuous], inner_rescaler_default, type = type, ...) } } x } ### Scaling ### if (tolower(scale) %in% c("std", "robust", "uniminmax", "center")) { rescalerType <- c( "std" = "sd", "robust" = "robust", "uniminmax" = "range", "center" = "range" )[tolower(scale)] data[columnsPlusTwo] <- inner_rescaler(data[columnsPlusTwo], type = rescalerType) if (tolower(scale) == "center") { data[columns] <- apply(data[columns], 2, function(x) { x <- x - eval( parse(text = paste( scaleSummary, "(x, na.rm=TRUE)", sep = "" )) ) }) } } ### Imputation ### if (tolower(missing) == "exclude") { dataCompleteCases <- complete.cases(data[columnsPlusTwo]) if (!is.null(groupColumn)) { groupVar <- groupVar[dataCompleteCases] } if (alphaLinesIsCharacter) { alphaVar <- alphaVar[dataCompleteCases] } data <- data[dataCompleteCases, ] } else if (tolower(missing) %in% c("mean", "median", "min10", "random")) { missingFns <- list( mean = function(x) { mean(x, na.rm = TRUE) }, median = function(x) { median(x, na.rm = TRUE) }, min10 = function(x) { 0.9 * min(x, na.rm = TRUE) }, random = function(x) { num <- sum(is.na(x)) idx <- sample(which(!is.na(x)), num, replace = TRUE) x[idx] } ) missing_fn <- missingFns[[tolower(missing)]] data[columns] <- apply(data[columns], 2, function(x) { if (any(is.na(x))) { x[is.na(x)] <- missing_fn(x) } return(x) }) } ### Scaling (round 2) ### # Centering by observation needs to be done after handling missing values # in case the observation to be centered on has missing values if (tolower(scale) == "centerobs") { data[columnsPlusTwo] <- inner_rescaler(data[columnsPlusTwo], type = "range") data[columns] <- apply(data[columns], 2, function(x) { x <- x - x[centerObsID] }) } # meltIDVars <- c(".ID", "anyMissing") meltIDVars <- colnames(data)[-columns] if (!is.null(groupColumn)) { # data <- cbind(data, groupVar) # names(data)[dim(data)[2]] <- groupCol meltIDVars <- union(groupColumn, meltIDVars) } if (alphaLinesIsCharacter) { data <- cbind(data, alphaVar) names(data)[dim(data)[2]] <- alphaLines meltIDVars <- union(meltIDVars, alphaLines) } # if (is.list(mapping)) { # mappingNames <- names(mapping) # } # data.m <- melt(data, id.vars = meltIDVars, measure.vars = columns) # Return a data.frame for freqparcoord::freqparcoord. # The method uses vector recycling, which is not allowed in a tibble data.m <- as.data.frame(pivot_longer( data, cols = all_of(columns), names_to = "variable", values_to = "value" )) ### Ordering ### if (length(order) > 1 && is.numeric(order)) { data.m$variable <- factor(data.m$variable, levels = names(saveData)[order]) } else if (order %in% c( "Outlying", "Skewed", "Clumpy", "Sparse", "Striated", "Convex", "Skinny", "Stringy", "Monotonic" )) { require_namespaces("scagnostics") scag <- scagnostics::scagnostics(saveData2) data.m$variable <- factor(data.m$variable, levels = scag_order(scag, names(saveData2), order)) } else if (tolower(order) == "skewness") { abs.skew <- abs(apply(saveData2, 2, skewness)) data.m$variable <- factor( data.m$variable, levels = names(abs.skew)[order(abs.skew, decreasing = TRUE)] ) } else if (tolower(order) == "allclass") { f.stats <- rep(NA, length(columns)) names(f.stats) <- names(saveData2[columns]) for (i in 1:length(columns)) { f.stats[i] <- summary(lm(saveData2[, i] ~ groupVar))$fstatistic[1] } data.m$variable <- factor( data.m$variable, levels = names(f.stats)[order(f.stats, decreasing = TRUE)] ) } else if (tolower(order) == "anyclass") { axis.order <- singleClassOrder(groupVar, saveData2) data.m$variable <- factor(data.m$variable, levels = axis.order) } if (!is.null(groupColumn)) { mapping2 <- aes( x = !!as.name("variable"), y = !!as.name("value"), group = !!as.name(".ID"), colour = !!as.name(groupColumn) ) } else { mapping2 <- aes( x = !!as.name("variable"), y = !!as.name("value"), group = !!as.name(".ID") ) } mapping2 <- add_and_overwrite_aes(mapping2, mapping) # mapping2 <- add_and_overwrite_aes(aes(size = I(0.5)), mapping2) p <- ggplot(data = data.m, mapping = mapping2) if (!is.null(shadeBox)) { # Fix so that if missing = "min10", the box only goes down to the true min d.sum <- ddply(data.m, c("variable"), summarize, min = min(value), max = max(value) ) p <- p + geom_linerange( data = d.sum, linewidth = I(10), col = shadeBox, inherit.aes = FALSE, mapping = aes( x = !!as.name("variable"), ymin = !!as.name("min"), ymax = !!as.name("max"), group = !!as.name("variable") ) ) } if (boxplot) { p <- p + geom_boxplot(mapping = aes(group = !!as.name("variable")), alpha = 0.8) } if (!is.null(mapping2$linewidth)) { lineSize <- mapping2$linewidth } else { lineSize <- 0.5 } if (splineFactor > 0) { data.m$ggally_splineFactor <- splineFactor if (inherits(splineFactor, "AsIs")) { data.m <- ddply( data.m, ".ID", transform, spline = spline(variable, value, n = ggally_splineFactor[1]) ) } else { data.m <- ddply( data.m, ".ID", transform, spline = spline(variable, value, n = length(variable) * ggally_splineFactor[1]) ) } linexvar <- "spline.x" lineyvar <- "spline.y" if (alphaLinesIsCharacter) { p <- p + geom_line( aes(x = !!as.name(linexvar), y = !!as.name(lineyvar), alpha = !!as.name(alphaLines)), linewidth = lineSize, data = data.m ) + scale_alpha(range = alphaRange) } else { p <- p + geom_line( aes(x = !!as.name(linexvar), y = !!as.name(lineyvar)), alpha = alphaLines, linewidth = lineSize, data = data.m ) } if (showPoints) { p <- p + geom_point(aes(x = as.numeric(variable), y = value)) } xAxisLabels <- levels(data.m$variable) # while continuous data, this makes it present like it's discrete p <- p + scale_x_continuous( breaks = seq_along(xAxisLabels), labels = xAxisLabels, minor_breaks = FALSE ) } else { if (alphaLinesIsCharacter) { p <- p + geom_line(aes(alpha = !!as.name(alphaLines)), linewidth = lineSize, data = data.m) + scale_alpha(range = alphaRange) } else { # p <- p + geom_line(alpha = alphaLines, linewidth = lineSize) p <- p + geom_line(alpha = alphaLines) } if (showPoints) { p <- p + geom_point() } } if (title != "") { p <- p + labs(title = title) } p } #' Get vector of variable types from data frame #' #' @keywords internal #' @param df data frame to extract variable types from #' @author Jason Crowley #' @return character vector with variable types, with names corresponding to #' the variable names from df column_is_character <- function(df) { x <- unlist(lapply(unclass(df), is.character)) names(x)[x] } #' @rdname column_is_character column_is_factor <- function(df) { x <- unlist(lapply(unclass(df), is.factor)) names(x)[x] } #' Find order of variables #' #' Find order of variables based on a specified scagnostic measure #' by maximizing the index values of that measure along the path. #' #' @param scag \code{scagnostics} object #' @param vars character vector of the variables to be ordered #' @param measure scagnostics measure to order according to #' @author Barret Schloerke #' @return character vector of variable ordered according to the given #' scagnostic measure scag_order <- function(scag, vars, measure) { scag <- sort(scag[measure, ], decreasing = TRUE) scagNames <- names(scag) # retrieve all names. assume name doesn't contain a space nameLocs <- regexec("^([^ ]+) \\* ([^ ]+)$", scagNames) colNames <- lapply(seq_along(nameLocs), function(i) { nameLoc <- nameLocs[[i]] scagName <- scagNames[[i]] # retrieve the column name from "FIRSTNAME * SECONDNAME" substr(rep(scagName, 2), nameLoc[-1], nameLoc[-1] + attr(nameLoc, "match.length")[-1] - 1) }) ret <- c() colNamesLength <- length(colNames) colNameValues <- unlist(colNames) for (i in seq_along(colNames)) { cols <- colNames[[i]] colsUsed <- cols %in% ret # if none of the columns have been added... if (colsUsed[1] == FALSE && colsUsed[2] == FALSE) { # find out which column comes next in the set, append that one first if (i < colNamesLength) { remainingColumns <- colNameValues[(2 * (i + 1)):(2 * colNamesLength)] col1Pos <- which.min(cols[1] == remainingColumns) col2Pos <- which.min(cols[2] == remainingColumns) if (col2Pos < col1Pos) { cols <- rev(cols) } ret <- append(ret, cols) } else { # nothing left in set, append both ret <- append(ret, cols) } # if only the first hasn't been added... } else if (colsUsed[1] == FALSE) { ret <- append(ret, cols[1]) # if only the second hasn't been added... } else if (colsUsed[2] == FALSE) { ret <- append(ret, cols[2]) } } if (length(ret) != length(vars)) { stop(str_c( "Could not compute a correct ordering: ", length(vars) - length(ret), " values are missing. ", "Missing: ", paste0(vars[!(vars %in% ret)], collapse = ", ") )) } return(ret) } #' Order axis variables #' #' Order axis variables by separation between one class and the rest #' (most separation to least). #' #' @param classVar class variable (vector from original dataset) #' @param axisVars variables to be plotted as axes (data frame) #' @param specClass character string matching to level of \code{classVar}; instead #' of looking for separation between any class and the rest, will only look for #' separation between this class and the rest #' @author Jason Crowley #' @importFrom stats lm #' @return character vector of names of axisVars ordered such that the first #' variable has the most separation between one of the classes and the rest, and #' the last variable has the least (as measured by F-statistics from an ANOVA) singleClassOrder <- function(classVar, axisVars, specClass = NULL) { if (!is.null(specClass)) { # for when user is interested in ordering by variation between one class and # the rest...will add this later } else { var.names <- colnames(axisVars) class.names <- levels(classVar) f.stats <- matrix(NA, nrow = length(class.names), ncol = length(var.names), dimnames = list(class.names, var.names) ) for (i in 1:length(class.names)) { f.stats[i, ] <- apply(axisVars, 2, function(x) { return(summary(lm(x ~ as.factor(classVar == class.names[i])))$fstatistic[1]) }) } var.maxF <- apply(f.stats, 2, max) return(names(var.maxF)[order(var.maxF, decreasing = TRUE)]) } } #' Sample skewness #' #' Calculate the sample skewness of a vector #' while ignoring missing values. #' #' @param x numeric vector #' @author Jason Crowley #' @return sample skewness of \code{x} skewness <- function(x) { x <- x[!is.na(x)] xbar <- mean(x) n <- length(x) skewness <- (1 / n) * sum((x - xbar)^3) / ((1 / n) * sum((x - xbar)^2))^(3 / 2) return(skewness) } GGally/R/ggcoef.R0000644000176200001440000001034714527407231013221 0ustar liggesusers#' Model coefficients with \pkg{broom} and \pkg{ggplot2} #' #' Plot the coefficients of a model with \pkg{broom} and \pkg{ggplot2}. #' For an updated and improved version, see [ggcoef_model()]. #' #' @param x a model object to be tidied with [broom::tidy()] or a data frame (see Details) #' @param mapping default aesthetic mapping #' @param conf.int display confidence intervals as error bars? #' @param conf.level level of confidence intervals (passed to [broom::tidy()] #' if \code{x} is not a data frame) #' @param exponentiate if \code{TRUE}, x-axis will be logarithmic (also passed to [broom::tidy()] #' if \code{x} is not a data frame) #' @param exclude_intercept should the intercept be excluded from the plot? #' @param vline print a vertical line? #' @param vline_intercept \code{xintercept} for the vertical line. #' \code{"auto"} for \code{x = 0} (or \code{x = 1} if \code{exponentiate} is \code{TRUE}) #' @param vline_color color of the vertical line #' @param vline_linetype line type of the vertical line #' @param vline_size size of the vertical line #' @param errorbar_color color of the error bars #' @param errorbar_height height of the error bars #' @param errorbar_linetype line type of the error bars #' @param errorbar_size size of the error bars #' @param sort \code{"none"} (default) do not sort, \code{"ascending"} sort by increasing coefficient value, or \code{"descending"} sort by decreasing coefficient value #' @param ... additional arguments sent to [ggplot2::geom_point()] #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' library(broom) #' reg <- lm(Sepal.Length ~ Sepal.Width + Petal.Length + Petal.Width, data = iris) #' p_(ggcoef(reg)) #' \donttest{ #' d <- as.data.frame(Titanic) #' reg2 <- glm(Survived ~ Sex + Age + Class, family = binomial, data = d, weights = d$Freq) #' ggcoef(reg2, exponentiate = TRUE) #' ggcoef( #' reg2, #' exponentiate = TRUE, exclude_intercept = TRUE, #' errorbar_height = .2, color = "blue", sort = "ascending" #' ) #' } #' @export ggcoef <- function( x, mapping = aes(!!as.name("estimate"), !!as.name("term")), conf.int = TRUE, conf.level = 0.95, exponentiate = FALSE, exclude_intercept = FALSE, vline = TRUE, vline_intercept = "auto", vline_color = "gray50", vline_linetype = "dotted", vline_size = 1, errorbar_color = "gray25", errorbar_height = 0, errorbar_linetype = "solid", errorbar_size = .5, sort = c("none", "ascending", "descending"), ...) { if (!is.data.frame(x)) { require_namespaces("broom") x <- broom::tidy( x, conf.int = conf.int, conf.level = conf.level, exponentiate = exponentiate ) } if (!("term" %in% names(x))) { stop("x doesn't contain a column names 'term'.") } if (!("estimate" %in% names(x))) { stop("x doesn't contain a column names 'estimate'.") } if (exclude_intercept) { x <- x[x$term != "(Intercept)", ] } sort <- match.arg(sort) if (sort != "none") { x$term <- as.factor(x$term) if (sort == "ascending") { new_order <- order(x$estimate, decreasing = FALSE) } else { new_order <- order(x$estimate, decreasing = TRUE) } x$term <- as.character(x$term) x$term <- factor(x$term, levels = x$term[new_order]) } p <- ggplot(x, mapping = mapping) if (vline) { if (exponentiate) { if (vline_intercept == "auto") { vline_intercept <- 1 } p <- p + geom_vline( xintercept = vline_intercept, color = vline_color, linetype = vline_linetype, linewidth = vline_size ) + scale_x_log10() } else { if (vline_intercept == "auto") { vline_intercept <- 0 } p <- p + geom_vline( xintercept = vline_intercept, color = vline_color, linetype = vline_linetype, linewidth = vline_size ) } } if (conf.int && "conf.low" %in% names(x) && "conf.high" %in% names(x)) { p <- p + geom_errorbarh( aes(xmin = !!as.name("conf.low"), xmax = !!as.name("conf.high")), color = errorbar_color, height = errorbar_height, linetype = errorbar_linetype, linewidth = errorbar_size ) } p + geom_point(...) } GGally/R/ggscatmat.R0000644000176200001440000003363114527265752013754 0ustar liggesusersif (getRversion() >= "2.15.1") { utils::globalVariables(c("xvalue", "yvalue", "scaled")) } #' lowertriangle - rearrange dataset as the preparation of \code{\link{ggscatmat}} function #' #' function for making the melted dataset used to plot the lowertriangle scatterplots. #' #' @export #' @param data a data matrix. Should contain numerical (continuous) data. #' @param columns an option to choose the column to be used in the raw dataset. Defaults to \code{1:ncol(data)} #' @param color an option to choose a factor variable to be grouped with. Defaults to \code{(NULL)} #' @author Mengjia Ni, Di Cook #' @examples #' data(flea) #' head(lowertriangle(flea, columns = 2:4)) #' head(lowertriangle(flea)) #' head(lowertriangle(flea, color = "species")) lowertriangle <- function(data, columns = 1:ncol(data), color = NULL) { # why do we need to ocheck this again? # data <- upgrade_scatmat_data(data) data.choose <- data[columns] dn <- data.choose[sapply(data.choose, is.numeric)] factor <- data[sapply(data, is.factor)] p <- ncol(dn) q <- nrow(dn) newdata <- as.data.frame(matrix(NA, nrow = q * p * p, ncol = 6 + ncol(factor)), stringsAsFactors = FALSE) newdata[5:6] <- as.data.frame(matrix("", nrow = q * p * p, ncol = 2), stringsAsFactors = FALSE) r <- 1 for (i in 1:p) { for (j in 1:p) { newdata[r:(r + q - 1), 1:6] <- cbind(dn[[i]], dn[[j]], i, j, colnames(dn)[i], colnames(dn)[j]) r <- r + q } } if (ncol(newdata) > 6) { newdata[7:ncol(newdata)] <- factor } colnames(newdata) <- c("xvalue", "yvalue", "xslot", "yslot", "xlab", "ylab", colnames(factor)) rp <- data.frame(newdata) rp$xvalue <- suppressWarnings(as.numeric(as.character(rp$xvalue))) rp$yvalue <- suppressWarnings(as.numeric(as.character(rp$yvalue))) rp$xslot <- suppressWarnings(as.numeric(as.character(rp$xslot))) rp$yslot <- suppressWarnings(as.numeric(as.character(rp$yslot))) rp$xlab <- factor(rp$xlab, levels = unique(rp$xlab)) rp$ylab <- factor(rp$ylab, levels = unique(rp$ylab)) rp[[2]][rp[[3]] >= rp[[4]]] <- NA rp[[1]][rp[[3]] > rp[[4]]] <- NA if (is.null(color)) { rp.new <- rp[1:6] } else { colorcolumn <- rp[[which(colnames(rp) == color)]] rp.new <- cbind(rp[1:6], colorcolumn) } return(rp.new) } #' Rearrange dataset as the preparation of \code{\link{ggscatmat}} function #' #' Function for making the dataset used to plot the uppertriangle plots. #' #' @export #' @param data a data matrix. Should contain numerical (continuous) data. #' @param columns an option to choose the column to be used in the raw dataset. Defaults to \code{1:ncol(data)} #' @param color an option to choose a factor variable to be grouped with. Defaults to \code{(NULL)} #' @param corMethod method argument supplied to \code{\link[stats]{cor}} #' @author Mengjia Ni, Di Cook #' @importFrom stats cor #' @importFrom dplyr group_by summarise #' @examples #' data(flea) #' head(uppertriangle(flea, columns = 2:4)) #' head(uppertriangle(flea)) #' head(uppertriangle(flea, color = "species")) uppertriangle <- function(data, columns = 1:ncol(data), color = NULL, corMethod = "pearson") { # data <- upgrade_scatmat_data(data) data.choose <- data[columns] # why do we need to check this again? dn <- data.choose[sapply(data.choose, is.numeric)] factor <- data[sapply(data, is.factor)] p <- ncol(dn) newdata <- NULL for (i in 1:p) { for (j in 1:p) { newdata <- rbind( newdata, cbind( dn[, i], dn[, j], i, j, colnames(dn)[i], colnames(dn)[j], min(dn[, i]) + 0.5 * (max(dn[, i]) - min(dn[, i])), min(dn[, j]) + 0.5 * (max(dn[, j]) - min(dn[, j])), factor ) ) } } colnames(newdata) <- c( "xvalue", "yvalue", "xslot", "yslot", "xlab", "ylab", "xcenter", "ycenter", colnames(factor) ) rp <- data.frame(newdata, stringsAsFactors = TRUE) rp$xvalue <- suppressWarnings(as.numeric(as.character(rp$xvalue))) rp$yvalue <- suppressWarnings(as.numeric(as.character(rp$yvalue))) rp[[2]][rp[[3]] <= rp[[4]]] <- NA rp[[1]][rp[[3]] < rp[[4]]] <- NA if (is.null(color)) { rp.new <- rp[1:8] } else { colorcolumn <- rp[[which(colnames(rp) == color)]] rp.new <- cbind(rp[1:8], colorcolumn) } b <- rp.new[!is.na(rp.new$xvalue) & !is.na(rp.new$yvalue), ] b$xlab <- factor(b$xlab, levels = unique(b$xlab)) b$ylab <- factor(b$ylab, levels = unique(b$ylab)) if (is.null(color)) { data.cor <- b %>% dplyr::group_by(xlab, ylab) %>% dplyr::summarise( r = cor(xvalue, yvalue, use = "pairwise.complete.obs", method = "pearson" ), xvalue = min(xvalue) + 0.5 * (max(xvalue) - min(xvalue)), yvalue = min(yvalue) + 0.5 * (max(yvalue) - min(yvalue)) ) if (identical(corMethod, "rsquare")) { data.cor$r <- data.cor$r^2 } data.cor$r <- paste(round(data.cor$r, digits = 2)) # data.cor <- ddply( # b, .(xlab, ylab), # function(subsetDt) { # xlab <- subsetDt$xlab # ylab <- subsetDt$ylab # xvalue <- subsetDt$xvalue # yvalue <- subsetDt$yvalue # if (identical(corMethod, "rsquare")) { # r <- cor( # xvalue, yvalue, # use = "pairwise.complete.obs", # method = "pearson" # ) # r <- r ^ 2 # } else { # r <- cor( # xvalue, yvalue, # use = "pairwise.complete.obs", # method = corMethod # ) # } # r <- paste(round(r, digits = 2)) # # data.frame( # xlab = unique(xlab), ylab = unique(ylab), # r = r, # xvalue = min(xvalue) + 0.5 * (max(xvalue) - min(xvalue)), # yvalue = min(yvalue) + 0.5 * (max(yvalue) - min(yvalue)) # ) # } # ) return(data.cor) } else { c <- b data.cor1 <- c %>% dplyr::group_by(xlab, ylab, colorcolumn) %>% dplyr::summarise(r = cor(xvalue, yvalue, use = "pairwise.complete.obs", method = "pearson" )) if (identical(corMethod, "rsquare")) { data.cor1$r <- data.cor1$r^2 } data.cor1$r <- paste(round(data.cor1$r, digits = 2)) # data.cor1 <- ddply( # c, .(ylab, xlab, colorcolumn), # function(subsetDt) { # xlab <- subsetDt$xlab # ylab <- subsetDt$ylab # colorcolumn <- subsetDt$colorcolumn # xvalue <- subsetDt$xvalue # yvalue <- subsetDt$yvalue # if (identical(corMethod, "rsquare")) { # r <- cor( # xvalue, yvalue, # use = "pairwise.complete.obs", # method = "pearson" # ) # r <- r ^ 2 # } else { # r <- cor( # xvalue, yvalue, # use = "pairwise.complete.obs", # method = corMethod # ) # } # r <- paste(round(r, digits = 2)) # data.frame( # ylab = unique(ylab), xlab = unique(xlab), colorcolumn = unique(colorcolumn), # r = r # ) # } # ) n <- nrow(data.frame(unique(b$colorcolumn))) position <- b %>% dplyr::group_by(xlab, ylab) %>% dplyr::summarise( xvalue = min(xvalue) + 0.5 * (max(xvalue) - min(xvalue)), ymin = min(yvalue), ymax = max(yvalue), range = max(yvalue) - min(yvalue) ) # position <- ddply(b, .(ylab, xlab), summarise, # xvalue = min(xvalue) + 0.5 * (max(xvalue) - min(xvalue)), # ymin = min(yvalue), # ymax = max(yvalue), # range = max(yvalue) - min(yvalue)) df <- data.frame() for (i in 1:nrow(position)) { for (j in 1:n) { row <- position[i, ] df <- rbind(df, cbind(row[, 3], (row[, 4] + row[, 6] * j / (n + 1)))) } } data.cor <- cbind(data.cor1, df) colnames(data.cor) <- c("xlab", "ylab", "colorcolumn", "r", "xvalue", "yvalue") return(data.cor) } } #' Plots the lowertriangle and density plots of the scatter plot matrix. #' #' Function for making scatterplots in the lower triangle and diagonal density plots. #' #' @export #' @param data a data matrix. Should contain numerical (continuous) data. #' @param columns an option to choose the column to be used in the raw dataset. Defaults to \code{1:ncol(data)} #' @param color an option to group the dataset by the factor variable and color them by different colors. Defaults to \code{NULL} #' @param alpha an option to set the transparency in scatterplots for large data. Defaults to \code{1}. #' @author Mengjia Ni, Di Cook #' @examples #' # small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' data(flea) #' #' p_(scatmat(flea, columns = 2:4)) #' p_(scatmat(flea, columns = 2:4, color = "species")) scatmat <- function(data, columns = 1:ncol(data), color = NULL, alpha = 1) { # data <- upgrade_scatmat_data(data) data.choose <- data[columns] dn <- data.choose[sapply(data.choose, is.numeric)] if (ncol(dn) == 0) { stop("All of your variables are factors. Need numeric variables to make scatterplot matrix.") } ltdata.new <- lowertriangle(data, columns = columns, color = color) ## set up the plot r <- ggplot( ltdata.new, mapping = aes(x = !!as.name("xvalue"), y = !!as.name("yvalue")) ) + theme( axis.title.x = element_blank(), axis.title.y = element_blank() ) + facet_grid(ylab ~ xlab, scales = "free") + theme(aspect.ratio = 1) if (is.null(color)) { ## b/w version densities <- do.call("rbind", lapply(1:ncol(dn), function(i) { data.frame( xlab = names(dn)[i], ylab = names(dn)[i], x = dn[, i], stringsAsFactors = TRUE ) })) for (m in 1:ncol(dn)) { j <- subset(densities, xlab == names(dn)[m]) r <- r + stat_density( aes( x = !!as.name("x"), y = after_stat(scaled) * diff(range(!!as.name("x"))) + min(!!as.name("x")) # nolint ), data = j, position = "identity", geom = "line", color = "black" ) } ## add b/w points r <- r + geom_point(alpha = alpha, na.rm = TRUE) return(r) } else { ## do the colored version densities <- do.call("rbind", lapply(1:ncol(dn), function(i) { data.frame( xlab = names(dn)[i], ylab = names(dn)[i], x = dn[, i], colorcolumn = data[, which(colnames(data) == color)], stringsAsFactors = TRUE ) })) for (m in 1:ncol(dn)) { j <- subset(densities, xlab == names(dn)[m]) r <- r + # r is the facet grid plot stat_density( aes( x = !!as.name("x"), y = after_stat(scaled) * diff(range(!!as.name("x"))) + min(!!as.name("x")), colour = !!as.name("colorcolumn") ), data = j, position = "identity", geom = "line" ) } ## add color points r <- r + geom_point( data = ltdata.new, aes(colour = !!as.name("colorcolumn")), alpha = alpha, na.rm = TRUE ) return(r) } } #' Traditional scatterplot matrix for purely quantitative variables #' #' This function makes a scatterplot matrix for quantitative variables with density plots on the diagonal #' and correlation printed in the upper triangle. #' #' @export #' @param data a data matrix. Should contain numerical (continuous) data. #' @param columns an option to choose the column to be used in the raw dataset. Defaults to \code{1:ncol(data)}. #' @param color an option to group the dataset by the factor variable and color them by different colors. #' Defaults to \code{NULL}, i.e. no coloring. If supplied, it will be converted to a factor. #' @param alpha an option to set the transparency in scatterplots for large data. Defaults to \code{1}. #' @param corMethod method argument supplied to \code{\link[stats]{cor}} #' @author Mengjia Ni, Di Cook #' @examples #' # small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' data(flea) #' #' p_(ggscatmat(flea, columns = 2:4)) #' p_(ggscatmat(flea, columns = 2:4, color = "species")) ggscatmat <- function(data, columns = 1:ncol(data), color = NULL, alpha = 1, corMethod = "pearson") { ## if 'color' is not a factor, mold it into one if (!is.null(color)) { if (is.null(data[[color]])) { stop(paste0("Non-existent column <", color, "> requested")) } data[[color]] <- as.factor(data[[color]]) } ## do we really need this next line? data <- upgrade_scatmat_data(data) data.choose <- data[columns] dn <- data.choose[sapply(data.choose, is.numeric)] if (ncol(dn) == 0) { stop("All of your variables are factors. Need numeric variables to make scatterplot matrix.") } if (ncol(dn) < 2) { stop("Not enough numeric variables to make a scatter plot matrix") } a <- uppertriangle(data, columns = columns, color = color, corMethod = corMethod) if (is.null(color)) { plot <- scatmat(data, columns = columns, alpha = alpha) + geom_text(data = a, aes(label = !!as.name("r")), colour = "black") } else { plot <- scatmat(data, columns = columns, color = color, alpha = alpha) + geom_text(data = a, aes(label = !!as.name("r"), color = !!as.name("colorcolumn"))) + labs(color = color) } is.factor.or.character <- function(x) { is.factor(x) | is.character(x) } factor <- data.choose[sapply(data.choose, is.factor.or.character)] if (ncol(factor) == 0) { return(plot) } else { warning("Factor variables are omitted in plot") return(plot) } } upgrade_scatmat_data <- function(data) { data <- as.data.frame(data) dataIsCharacter <- sapply(data, is.factor) if (any(dataIsCharacter)) { dataCharacterColumns <- names(dataIsCharacter[dataIsCharacter]) for (dataCol in dataCharacterColumns) { data[[dataCol]] <- as.factor(data[[dataCol]]) } } data } GGally/R/ggmatrix_make_plot.R0000644000176200001440000000271214527265752015653 0ustar liggesusersmake_label_plot <- function(types, sectionAes, label) { sectionAes$y <- NULL p <- make_ggmatrix_plot_obj( wrapp( "diagAxis", params = c("label" = label), funcArgName = "ggally_diagAxis" ), mapping = sectionAes ) return(p) } ggmatrix_plot_list <- (function() { make_diag_plot_wrapper <- function(sub_type_val) { plot_fn <- make_plot_wrapper(sub_type_val) function(types, sectionAes) { sectionAes$y <- NULL plot_fn(types, sectionAes) } } make_plot_wrapper <- function(sub_type_val) { function(types, sectionAes) { sub_type <- types[[sub_type_val]] sub_type_name <- get_subtype_name(sub_type) p <- make_ggmatrix_plot_obj( wrapp(sub_type, funcArgName = sub_type_name), mapping = sectionAes ) return(p) } } na_fn <- make_plot_wrapper("na") na_diag_fn <- make_plot_wrapper("na") continuous_fn <- make_plot_wrapper("continuous") combo_fn <- make_plot_wrapper("combo") discrete_fn <- make_plot_wrapper("discrete") continuous_diag_fn <- make_diag_plot_wrapper("continuous") discrete_diag_fn <- make_diag_plot_wrapper("discrete") function(type) { switch(type, "na" = na_fn, "na-diag" = na_diag_fn, "continuous" = continuous_fn, "combo" = combo_fn, "discrete" = discrete_fn, "continuous-diag" = continuous_diag_fn, "discrete-diag" = discrete_diag_fn, "label" = make_label_plot ) } })() GGally/R/ggbivariate.R0000644000176200001440000000715214527265752014265 0ustar liggesusers#' Display an outcome using several potential explanatory variables #' #' \code{ggbivariate} is a variant of \code{\link{ggduo}} for plotting #' an outcome variable with several potential explanatory variables. #' #' @param data dataset to be used, can have both categorical and #' numerical variables #' @param outcome name or position of the outcome variable (one variable only) #' @param explanatory names or positions of the explanatory variables (if \code{NULL}, #' will take all variables other than \code{outcome}) #' @param mapping additional aesthetic to be used, for example to indicate #' weights (see examples) #' @param types custom types of plots to use, see \code{\link{ggduo}} #' @param ... additional arguments passed to \code{\link{ggduo}} (see examples) #' @param rowbar_args additional arguments passed to \code{\link{ggally_rowbar}} #' (see examples) #' @author Joseph Larmarange #' @export #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' data(tips) #' p_(ggbivariate(tips, "smoker", c("day", "time", "sex", "tip"))) #' #' # Personalize plot title and legend title #' p_(ggbivariate( #' tips, "smoker", c("day", "time", "sex", "tip"), #' title = "Custom title" #' ) + #' labs(fill = "Smoker ?")) #' #' # Customize fill colour scale #' p_(ggbivariate(tips, "smoker", c("day", "time", "sex", "tip")) + #' scale_fill_brewer(type = "qual")) #' #' # Customize labels #' p_(ggbivariate( #' tips, "smoker", c("day", "time", "sex", "tip"), #' rowbar_args = list( #' colour = "white", #' size = 4, #' fontface = "bold", #' label_format = scales::label_percent(accurary = 1) #' ) #' )) #' #' # Choose the sub-plot from which get legend #' p_(ggbivariate(tips, "smoker")) #' p_(ggbivariate(tips, "smoker", legend = 3)) #' #' # Use mapping to indicate weights #' d <- as.data.frame(Titanic) #' p_(ggbivariate(d, "Survived", mapping = aes(weight = Freq))) #' #' # outcome can be numerical #' p_(ggbivariate(tips, outcome = "tip", title = "tip")) ggbivariate <- function( data, outcome, explanatory = NULL, mapping = NULL, types = NULL, ..., rowbar_args = NULL) { if (length(outcome) != 1) { stop("You should provide only one `outcome`.") } if (is.numeric(outcome)) { outcome <- names(data)[outcome] } if (is.null(explanatory)) { explanatory <- names(data)[!names(data) %in% c(outcome, mapping_string(mapping$weight))] } if (!is.numeric(data[[outcome]])) { # mapping outcome to colour mapping$colour <- aes(colour = !!as.name(outcome))$colour } # default behavior if (is.null(rowbar_args$remove_percentage_axis)) { rowbar_args$remove_percentage_axis <- TRUE } if (is.null(rowbar_args$remove_background)) { rowbar_args$remove_background <- TRUE } if (is.null(types$discrete)) { types$discrete <- wrapp(ggally_rowbar, rowbar_args) } if (is.null(types$comboVertical)) { types$comboVertical <- "box_no_facet" } if (is.null(types$continuous)) { types$continuous <- "smooth_lm" } if (is.null(types$comboHorizontal)) { types$comboHorizontal <- "box_no_facet" } ggduo_args <- list(...) ggduo_args$data <- data ggduo_args$mapping <- mapping ggduo_args$types <- types ggduo_args$columnsX <- outcome ggduo_args$columnsY <- explanatory if (!"yProportions" %in% names(ggduo_args)) { ggduo_args$yProportions <- "auto" } if (!is.numeric(data[[outcome]]) && !"legend" %in% names(list(...))) { ggduo_args$legend <- 1 } p <- do.call(ggduo, ggduo_args) + theme( legend.position = "top", strip.text.x = element_blank() ) p } GGally/R/ggtable.R0000644000176200001440000000463414527265752013410 0ustar liggesusers#' Cross-tabulated tables of discrete variables #' #' \code{ggtable} is a variant of \code{\link{ggduo}} for quick #' cross-tabulated tables of discrete variables. #' #' @param data dataset to be used, can have both categorical and #' numerical variables #' @param columnsX,columnsY names or positions of which columns are used to make plots. Defaults to all columns. #' @param cells Which statistic should be displayed in table cells? #' @param fill Which statistic should be used for filling table cells? #' @param mapping additional aesthetic to be used, for example to indicate #' weights (see examples) #' @param ... additional arguments passed to \code{\link{ggduo}} (see examples) #' @author Joseph Larmarange #' @export #' @examples #' # small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' data(tips) #' p_(ggtable(tips, "smoker", c("day", "time", "sex"))) #' #' # displaying row proportions #' p_(ggtable(tips, "smoker", c("day", "time", "sex"), cells = "row.prop")) #' #' # filling cells with standardized residuals #' p_(ggtable(tips, "smoker", c("day", "time", "sex"), fill = "std.resid", legend = 1)) #' #' # if continuous variables are provided, just displaying some summary statistics #' p_(ggtable(tips, c("smoker", "total_bill"), c("day", "time", "sex", "tip"))) #' #' # specifying weights #' d <- as.data.frame(Titanic) #' p_(ggtable( #' d, #' "Survived", #' c("Class", "Sex", "Age"), #' mapping = aes(weight = Freq), #' cells = "row.prop", #' fill = "std.resid" #' )) ggtable <- function( data, columnsX = 1:ncol(data), columnsY = 1:ncol(data), cells = c("observed", "prop", "row.prop", "col.prop", "expected", "resid", "std.resid"), fill = c("none", "std.resid", "resid"), mapping = NULL, ...) { fill <- match.arg(fill) cells <- match.arg(cells) types <- list( discrete = wrapp(ggally_crosstable, list(cells = cells, fill = fill)), continuous = "cor", comboVertical = "summarise_by", comboHorizontal = "summarise_by" ) ggduo_args <- list(...) ggduo_args$data <- data ggduo_args$mapping <- mapping ggduo_args$types <- types ggduo_args$columnsX <- columnsX ggduo_args$columnsY <- columnsY if (!"xProportions" %in% names(ggduo_args)) { ggduo_args$xProportions <- "auto" } if (!"yProportions" %in% names(ggduo_args)) { ggduo_args$yProportions <- "auto" } p <- do.call(ggduo, ggduo_args) p } GGally/R/ggnetworkmap.R0000644000176200001440000003655314527265752014515 0ustar liggesusersif (getRversion() >= "2.15.1") { utils::globalVariables(c( "lon", "lat", "group", "id", "lon1", "lat1", "lon2", "lat2", ".label" )) } #' Network plot map overlay #' #' Plots a network with \pkg{ggplot2} suitable for overlay on a \pkg{ggmap} plot or \pkg{ggplot2} #' #' This is a descendant of the original \code{ggnet} function. \code{ggnet} added the innovation of plotting the network geographically. #' However, \code{ggnet} needed to be the first object in the ggplot chain. \code{ggnetworkmap} does not. If passed a \code{ggplot} object as its first argument, #' such as output from \code{ggmap}, \code{ggnetworkmap} will plot on top of that chart, looking for vertex attributes \code{lon} and \code{lat} as coordinates. #' Otherwise, \code{ggnetworkmap} will generate coordinates using the Fruchterman-Reingold algorithm. #' #' @export #' @param gg an object of class \code{ggplot}. #' @param net an object of class \code{\link[network]{network}}, or any object #' that can be coerced to this class, such as an adjacency or incidence matrix, #' or an edge list: see \link[network]{edgeset.constructors} and #' \link[network]{network} for details. If the object is of class #' [igraph][igraph::igraph-package] and the #' [intergraph][intergraph::intergraph-package] package is installed, #' it will be used to convert the object: see #' \code{\link[intergraph]{asNetwork}} for details. #' @param size size of the network nodes. Defaults to 3. If the nodes are weighted, their area is proportionally scaled up to the size set by \code{size}. #' @param alpha a level of transparency for nodes, vertices and arrows. Defaults to 0.75. #' @param weight if present, the unquoted name of a vertex attribute in \code{data}. Otherwise nodes are unweighted. #' @param node.group \code{NULL}, the default, or the unquoted name of a vertex attribute that will be used to determine the color of each node. #' @param ring.group if not \code{NULL}, the default, the unquoted name of a vertex attribute that will be used to determine the color of each node border. #' @param node.color If \code{node.group} is null, a character string specifying a color. #' @param node.alpha transparency of the nodes. Inherits from \code{alpha}. #' @param segment.alpha transparency of the vertex links. Inherits from \code{alpha} #' @param segment.color color of the vertex links. Defaults to \code{"grey"}. #' @param segment.size size of the vertex links, as a vector of values or as a single value. Defaults to 0.25. #' @param great.circles whether to draw edges as great circles using the \code{geosphere} package. Defaults to \code{FALSE} #' @param arrow.size size of the vertex arrows for directed network plotting, in centimeters. Defaults to 0. #' @param label.nodes label nodes with their vertex names attribute. If set to \code{TRUE}, all nodes are labelled. Also accepts a vector of character strings to match with vertex names. #' @param label.size size of the labels. Defaults to \code{size / 2}. #' @param ... other arguments supplied to geom_text for the node labels. Arguments pertaining to the title or other items can be achieved through \pkg{ggplot2} methods. #' @author Amos Elberg. Original by Moritz Marbach, Francois Briatte #' @details This is a function for plotting graphs generated by \code{network} or \code{igraph} in a more flexible and elegant manner than permitted by ggnet. The function does not need to be the first plot in the ggplot chain, so the graph can be plotted on top of a map or other chart. Segments can be straight lines, or plotted as great circles. Note that the great circles feature can produce odd results with arrows and with vertices beyond the plot edges; this is a \pkg{ggplot2} limitation and cannot yet be fixed. Nodes can have two color schemes, which are then plotted as the center and ring around the node. The color schemes are selected by adding scale_fill_ or scale_color_ just like any other \pkg{ggplot2} plot. If there are no rings, scale_color sets the color of the nodes. If there are rings, scale_color sets the color of the rings, and scale_fill sets the color of the centers. Note that additional arguments in the ... are passed to geom_text for plotting labels. #' @importFrom utils installed.packages #' @examples #' # small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' invisible(lapply(c("ggplot2", "maps", "network", "sna"), base::library, character.only = TRUE)) #' #' ## Example showing great circles on a simple map of the USA #' ## http://flowingdata.com/2011/05/11/how-to-map-connections-with-great-circles/ #' \donttest{ #' airports <- read.csv("http://datasets.flowingdata.com/tuts/maparcs/airports.csv", header = TRUE) #' rownames(airports) <- airports$iata #' #' # select some random flights #' set.seed(123) #' flights <- data.frame( #' origin = sample(airports[200:400, ]$iata, 200, replace = TRUE), #' destination = sample(airports[200:400, ]$iata, 200, replace = TRUE) #' ) #' #' # convert to network #' flights <- network(flights, directed = TRUE) #' #' # add geographic coordinates #' flights %v% "lat" <- airports[network.vertex.names(flights), "lat"] #' flights %v% "lon" <- airports[network.vertex.names(flights), "long"] #' #' # drop isolated airports #' delete.vertices(flights, which(degree(flights) < 2)) #' #' # compute degree centrality #' flights %v% "degree" <- degree(flights, gmode = "digraph") #' #' # add random groups #' flights %v% "mygroup" <- sample(letters[1:4], network.size(flights), replace = TRUE) #' #' # create a map of the USA #' usa <- ggplot(map_data("usa"), aes(x = long, y = lat)) + #' geom_polygon(aes(group = group), #' color = "grey65", #' fill = "#f9f9f9", linewidth = 0.2 #' ) #' #' # overlay network data to map #' p <- ggnetworkmap( #' usa, flights, #' size = 4, great.circles = TRUE, #' node.group = mygroup, segment.color = "steelblue", #' ring.group = degree, weight = degree #' ) #' p_(p) #' #' ## Exploring a community of spambots found on Twitter #' ## Data by Amos Elberg: see ?twitter_spambots for details #' #' data(twitter_spambots) #' #' # create a world map #' world <- fortify(map("world", plot = FALSE, fill = TRUE)) #' world <- ggplot(world, aes(x = long, y = lat)) + #' geom_polygon(aes(group = group), #' color = "grey65", #' fill = "#f9f9f9", linewidth = 0.2 #' ) #' #' # view global structure #' p <- ggnetworkmap(world, twitter_spambots) #' p_(p) #' #' # domestic distribution #' p <- ggnetworkmap(net = twitter_spambots) #' p_(p) #' #' # topology #' p <- ggnetworkmap(net = twitter_spambots, arrow.size = 0.5) #' p_(p) #' #' # compute indegree and outdegree centrality #' twitter_spambots %v% "indegree" <- degree(twitter_spambots, cmode = "indegree") #' twitter_spambots %v% "outdegree" <- degree(twitter_spambots, cmode = "outdegree") #' #' p <- ggnetworkmap( #' net = twitter_spambots, #' arrow.size = 0.5, #' node.group = indegree, #' ring.group = outdegree, size = 4 #' ) + #' scale_fill_continuous("Indegree", high = "red", low = "yellow") + #' labs(color = "Outdegree") #' p_(p) #' #' # show some vertex attributes associated with each account #' p <- ggnetworkmap( #' net = twitter_spambots, #' arrow.size = 0.5, #' node.group = followers, #' ring.group = friends, #' size = 4, #' weight = indegree, #' label.nodes = TRUE, vjust = -1.5 #' ) + #' scale_fill_continuous("Followers", high = "red", low = "yellow") + #' labs(color = "Friends") + #' scale_color_continuous(low = "lightgreen", high = "darkgreen") #' p_(p) #' } #' ggnetworkmap <- function( gg, net, size = 3, alpha = 0.75, weight, node.group, node.color = NULL, node.alpha = NULL, ring.group, segment.alpha = NULL, segment.color = "grey", great.circles = FALSE, segment.size = 0.25, arrow.size = 0, label.nodes = FALSE, label.size = size / 2, ...) { require_namespaces(c("network", "sna")) # sna # node placement if there is no ggplot object in function call # -- conversion to network class --------------------------------------------- if (inherits(net, "igraph") && "intergraph" %in% rownames(installed.packages())) { net <- intergraph::asNetwork(net) } else if (inherits(net, "igraph")) { stop("install the 'intergraph' package to use igraph objects with ggnet") } if (!network::is.network(net)) { net <- try(network::network(net), silent = TRUE) } if (!network::is.network(net)) { stop("could not coerce net to a network object") } # -- network functions ------------------------------------------------------- get_v <- utils::getFromNamespace("%v%", ns = "network") # -- network structure ------------------------------------------------------- vattr <- network::list.vertex.attributes(net) is_dir <- ifelse(network::is.directed(net), "digraph", "graph") if (!is.numeric(arrow.size) || arrow.size < 0) { stop("incorrect arrow.size value") } else if (arrow.size > 0 && is_dir == "graph") { warning("network is undirected; arrow.size ignored") arrow.size <- 0 } if (network::is.hyper(net)) { stop("ggnetworkmap cannot plot hyper graphs") } if (network::is.multiplex(net)) { stop("ggnetworkmap cannot plot multiplex graphs") } if (network::has.loops(net)) { warning("ggnetworkmap does not know how to handle self-loops") } # -- ... ------------------------------------------------------- # get arguments labels <- label.nodes # alpha default inherit <- function(x) ifelse(is.null(x), alpha, x) # get sociomatrix m <- network::as.matrix.network.adjacency(net) if (missing(gg)) { # mapproj doesn't need to be loaded, but # it needs to exist for ggplot2::coord_map() to work properly if (!("mapproj" %in% installed.packages())) { require_namespaces("mapproj") } gg <- ggplot() + coord_map() plotcord <- sna::gplot.layout.fruchtermanreingold(net, list(m, layout.par = NULL)) plotcord <- data.frame(plotcord) colnames(plotcord) <- c("lon", "lat") } else { plotcord <- data.frame( lon = as.numeric(get_v(net, "lon")), lat = as.numeric(get_v(net, "lat")) ) } # Correct vertex labels if (!is.logical(labels)) { stopifnot(length(labels) == nrow(plotcord)) plotcord$.label <- labels } else if ("id" %in% vattr) { plotcord$.label <- as.character(get_v(net, "id")) } else if ("vertex.names" %in% vattr) { plotcord$.label <- network::network.vertex.names(net) } point_aes <- list( x = substitute(lon), y = substitute(lat) ) point_args <- list( alpha = substitute(inherit(node.alpha)) ) # get node groups if (!missing(node.group)) { plotcord$.ngroup <- get_v(net, as.character(substitute(node.group))) if (missing(ring.group)) { point_aes$color <- substitute(.ngroup) } else { point_aes$fill <- substitute(.ngroup) } } else if (!missing(node.color)) { point_args$color <- substitute(node.color) } else { point_args$color <- substitute("black") } # rings if (!missing(ring.group)) { plotcord$.rgroup <- get_v(net, as.character(substitute(ring.group))) point_aes$color <- substitute(.rgroup) point_args$pch <- substitute(21) } # # # Plot edges # # # get edgelist edges <- network::as.matrix.network.edgelist(net) edges <- data.frame( lat1 = plotcord[edges[, 1], "lat"], lon1 = plotcord[edges[, 1], "lon"], lat2 = plotcord[edges[, 2], "lat"], lon2 = plotcord[edges[, 2], "lon"] ) edges <- subset(na.omit(edges), (!(lat1 == lat2 & lon2 == lon2))) edge_args <- list( linewidth = substitute(segment.size), alpha = substitute(inherit(segment.alpha)), color = substitute(segment.color) ) edge_aes <- list() # -- edge arrows ------------------------------------------------------------- if (!missing(arrow.size) && arrow.size > 0) { edge_args$arrow <- substitute(arrow( type = "closed", length = unit(arrow.size, "cm") )) } # -- great circles ----------------------------------------------------------- if (great.circles) { # geosphere # great circles require_namespaces("geosphere") pts <- 25 # number of intermediate points for drawing great circles i <- 0 # used to keep track of groups when getting intermediate points for great circles edges <- ddply( .data = edges, .variables = c("lat1", "lat2", "lon1", "lon2"), .parallel = FALSE, .fun = function(x) { p1Mat <- x[, c("lon1", "lat1")] colnames(p1Mat) <- NULL p2Mat <- x[, c("lon2", "lat2")] colnames(p2Mat) <- NULL inter <- geosphere::gcIntermediate( p1 = p1Mat, p2 = p2Mat, n = pts, addStartEnd = TRUE, breakAtDateLine = TRUE ) if (!is.list(inter)) { i <<- i + 1 inter <- data.frame(inter) inter$group <- i return(inter) } else { if (is.matrix(inter[[1]])) { i <<- i + 1 ret <- data.frame(inter[[1]]) ret$group <- i i <<- i + 1 ret2 <- data.frame(inter[[2]]) ret2$group <- i return(rbind(ret, ret2)) } else { ret <- data.frame(lon = numeric(0), lat = numeric(0), group = numeric(0)) for (j in 1:length(inter)) { i <<- i + 1 ret1 <- data.frame(inter[[j]][[1]]) ret1$group <- i i <<- i + 1 ret2 <- data.frame(inter[[j]][[2]]) ret2$group <- i ret <- rbind(ret, ret1, ret2) } return(ret) } } } ) edge_aes$x <- substitute(lon) edge_aes$y <- substitute(lat) edge_aes$group <- substitute(group) edge_args$data <- substitute(edges) edge_args$mapping <- do.call(aes, edge_aes) gg <- gg + do.call(geom_path, edge_args) } else { edge_aes$x <- substitute(lon1) edge_aes$y <- substitute(lat1) edge_aes$xend <- substitute(lon2) edge_aes$yend <- substitute(lat2) edge_args$data <- substitute(edges) edge_args$mapping <- do.call(aes, edge_aes) gg <- gg + do.call(geom_segment, edge_args) } # # # Done drawing edges, time to draws nodes # # # custom weights: vertex attribute # null weighting sizer <- NULL if (missing(weight)) { point_args$size <- substitute(size) } else { # Setup weight-sizing plotcord$.weight <- get_v(net, as.character(substitute(weight))) # proportional scaling if (is.factor(plotcord$.weight)) { sizer <- scale_size_discrete(name = substitute(weight), range = c(size / nlevels(plotcord$weight), size)) } else { sizer <- scale_size_area(name = substitute(weight), max_size = size) } point_aes$size <- substitute(.weight) } # Add points to plot point_args$data <- substitute(plotcord) point_args$mapping <- do.call(aes, point_aes) gg <- gg + do.call(geom_point, point_args) if (!is.null(sizer)) { gg <- gg + sizer } # -- node labels ------------------------------------------------------------- if (isTRUE(labels)) { gg <- gg + geom_text( data = plotcord, aes(x = lon, y = lat, label = .label), size = label.size, ... ) } gg <- gg + scale_x_continuous(breaks = NULL) + scale_y_continuous(breaks = NULL) + labs(color = "", fill = "", size = "", y = NULL, x = NULL) + theme( panel.background = element_blank(), legend.key = element_blank() ) return(gg) } GGally/R/ggcorr.R0000644000176200001440000003511214527265752013261 0ustar liggesusersif (getRversion() >= "2.15.1") { utils::globalVariables(c("x", "y", "coefficient", "breaks", "label")) } #' Correlation matrix #' #' Function for making a correlation matrix plot, using \pkg{ggplot2}. #' The function is directly inspired by Tian Zheng and Yu-Sung Su's #' \code{corrplot} function in the 'arm' package. #' Please visit \url{https://github.com/briatte/ggcorr} for the latest version #' of \code{ggcorr}, and see the vignette at #' \url{https://briatte.github.io/ggcorr/} for many examples of how to use it. #' #' @export #' @param data a data frame or matrix containing numeric (continuous) data. If #' any of the columns contain non-numeric data, they will be dropped with a #' warning. #' @param method a vector of two character strings. The first value gives the #' method for computing covariances in the presence of missing values, and must #' be (an abbreviation of) one of \code{"everything"}, \code{"all.obs"}, #' \code{"complete.obs"}, \code{"na.or.complete"} or #' \code{"pairwise.complete.obs"}. The second value gives the type of #' correlation coefficient to compute, and must be one of \code{"pearson"}, #' \code{"kendall"} or \code{"spearman"}. #' See \code{\link[stats]{cor}} for details. #' Defaults to \code{c("pairwise", "pearson")}. #' @param cor_matrix the named correlation matrix to use for calculations. #' Defaults to the correlation matrix of \code{data} when \code{data} is #' supplied. #' @param palette if \code{nbreaks} is used, a ColorBrewer palette to use #' instead of the colors specified by \code{low}, \code{mid} and \code{high}. #' Defaults to \code{NULL}. #' @param name a character string for the legend that shows the colors of the #' correlation coefficients. #' Defaults to \code{""} (no legend name). #' @param geom the geom object to use. Accepts either \code{"tile"}, #' \code{"circle"}, \code{"text"} or \code{"blank"}. #' @param min_size when \code{geom} has been set to \code{"circle"}, the minimum #' size of the circles. #' Defaults to \code{2}. #' @param max_size when \code{geom} has been set to \code{"circle"}, the maximum #' size of the circles. #' Defaults to \code{6}. #' @param label whether to add correlation coefficients to the plot. #' Defaults to \code{FALSE}. #' @param label_alpha whether to make the correlation coefficients increasingly #' transparent as they come close to 0. Also accepts any numeric value between #' \code{0} and \code{1}, in which case the level of transparency is set to that #' fixed value. #' Defaults to \code{FALSE} (no transparency). #' @param label_color the color of the correlation coefficients. #' Defaults to \code{"grey75"}. #' @param label_round the decimal rounding of the correlation coefficients. #' Defaults to \code{1}. #' @param label_size the size of the correlation coefficients. #' Defaults to \code{4}. #' @param nbreaks the number of breaks to apply to the correlation coefficients, #' which results in a categorical color scale. See 'Note'. #' Defaults to \code{NULL} (no breaks, continuous scaling). #' @param digits the number of digits to show in the breaks of the correlation #' coefficients: see \code{\link[base]{cut}} for details. #' Defaults to \code{2}. #' @param low the lower color of the gradient for continuous scaling of the #' correlation coefficients. #' Defaults to \code{"#3B9AB2"} (blue). #' @param mid the midpoint color of the gradient for continuous scaling of the #' correlation coefficients. #' Defaults to \code{"#EEEEEE"} (very light grey). #' @param high the upper color of the gradient for continuous scaling of the #' correlation coefficients. #' Defaults to \code{"#F21A00"} (red). #' @param midpoint the midpoint value for continuous scaling of the #' correlation coefficients. #' Defaults to \code{0}. #' @param limits bounding of color scaling for correlations, set \code{limits = NULL} or \code{FALSE} to remove #' @param drop if using \code{nbreaks}, whether to drop unused breaks from the #' color scale. #' Defaults to \code{FALSE} (recommended). #' @param layout.exp a multiplier to expand the horizontal axis to the left if #' variable names get clipped. #' Defaults to \code{0} (no expansion). #' @param legend.position where to put the legend of the correlation #' coefficients: see \code{\link[ggplot2]{theme}} for details. #' Defaults to \code{"bottom"}. #' @param legend.size the size of the legend title and labels, in points: see #' \code{\link[ggplot2]{theme}} for details. #' Defaults to \code{9}. #' @param ... other arguments supplied to \code{\link[ggplot2]{geom_text}} for #' the diagonal labels. #' @note Recommended values for the \code{nbreaks} argument are \code{3} to #' \code{11}, as values above 11 are visually difficult to separate and are not #' supported by diverging ColorBrewer palettes. #' #' @seealso \code{\link[stats]{cor}} and \code{corrplot} in the #' \code{arm} package. #' @author Francois Briatte, with contributions from Amos B. Elberg and #' Barret Schloerke #' @importFrom stats cor #' @importFrom dplyr rename #' @importFrom tidyr pivot_longer #' @importFrom grDevices colorRampPalette #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' # Basketball statistics provided by Nathan Yau at Flowing Data. #' dt <- read.csv("http://datasets.flowingdata.com/ppg2008.csv") #' #' # Default output. #' p_(ggcorr(dt[, -1])) #' #' # Labeled output, with coefficient transparency. #' p_(ggcorr(dt[, -1], #' label = TRUE, #' label_alpha = TRUE #' )) #' #' # Custom options. #' p_(ggcorr( #' dt[, -1], #' name = expression(rho), #' geom = "circle", #' max_size = 10, #' min_size = 2, #' size = 3, #' hjust = 0.75, #' nbreaks = 6, #' angle = -45, #' palette = "PuOr" # colorblind safe, photocopy-able #' )) #' #' # Supply your own correlation matrix #' p_(ggcorr( #' data = NULL, #' cor_matrix = cor(dt[, -1], use = "pairwise") #' )) ggcorr <- function( data, method = c("pairwise", "pearson"), cor_matrix = NULL, nbreaks = NULL, digits = 2, name = "", low = "#3B9AB2", mid = "#EEEEEE", high = "#F21A00", midpoint = 0, palette = NULL, geom = "tile", min_size = 2, max_size = 6, label = FALSE, label_alpha = FALSE, label_color = "black", label_round = 1, label_size = 4, limits = c(-1, 1), drop = is.null(limits) || identical(limits, FALSE), layout.exp = 0, legend.position = "right", legend.size = 9, ...) { if (is.numeric(limits)) { if (length(limits) != 2) { stop("'limits' must be of length 2 if numeric") } } if (is.logical(limits)) { if (limits) { limits <- c(-1, 1) } else { limits <- NULL } } # -- check geom argument ----------------------------------------------------- if (length(geom) > 1 || !geom %in% c("blank", "circle", "text", "tile")) { stop("incorrect geom value") } # -- correlation method ------------------------------------------------------ if (length(method) == 1) { method <- c(method, "pearson") # for backwards compatibility } # -- check data columns ------------------------------------------------------ if (!is.null(data)) { if (!is.data.frame(data)) { data <- as.data.frame(data) } x <- which(!sapply(data, is.numeric)) if (length(x) > 0) { warning(paste( "data in column(s)", paste0(paste0("'", names(data)[x], "'"), collapse = ", "), "are not numeric and were ignored" )) data <- data[, -x] } } # -- correlation matrix ------------------------------------------------------ if (is.null(cor_matrix)) { cor_matrix <- cor(data, use = method[1], method = method[2]) } m <- cor_matrix colnames(m) <- rownames(m) <- gsub(" ", "_", colnames(m)) # protect spaces # -- correlation data.frame -------------------------------------------------- m <- data.frame(m * lower.tri(m)) rownames(m) <- names(m) m$.ggally_ggcorr_row_names <- rownames(m) # m = reshape::melt(m, id.vars = ".ggally_ggcorr_row_names") # names(m) = c("x", "y", "coefficient") m_long <- m %>% tidyr::pivot_longer( cols = -.ggally_ggcorr_row_names, names_to = "y", values_to = "coefficient" ) %>% dplyr::rename(x = .ggally_ggcorr_row_names) %>% dplyr::mutate(y = factor(y, levels = rownames(m))) m_long$coefficient[m_long$coefficient == 0] <- NA # -- correlation quantiles --------------------------------------------------- if (!is.null(nbreaks)) { x <- seq(-1, 1, length.out = nbreaks + 1) if (!nbreaks %% 2) { x <- sort(c(x, 0)) } m_long$breaks <- cut(m_long$coefficient, breaks = unique(x), include.lowest = TRUE, dig.lab = digits ) } # -- gradient midpoint ------------------------------------------------------- if (is.null(midpoint)) { midpoint <- median(m_long$coefficient, na.rm = TRUE) message(paste( "Color gradient midpoint set at median correlation to", round(midpoint, 2) )) } # -- plot structure ---------------------------------------------------------- m_long$label <- round(m_long$coefficient, label_round) p <- ggplot(na.omit(m_long), aes(x, y)) if (geom == "tile") { if (is.null(nbreaks)) { # -- tiles, continuous --------------------------------------------------- p <- p + geom_tile(aes(fill = coefficient), color = "white") } else { # -- tiles, ordinal ------------------------------------------------------ p <- p + geom_tile(aes(fill = breaks), color = "white") } # -- tiles, color scale ---------------------------------------------------- if (is.null(nbreaks) && !is.null(limits)) { p <- p + scale_fill_gradient2(name, low = low, mid = mid, high = high, midpoint = midpoint, limits = limits ) } else if (is.null(nbreaks)) { p <- p + scale_fill_gradient2(name, low = low, mid = mid, high = high, midpoint = midpoint ) } else if (is.null(palette)) { x <- colorRampPalette(c(low, mid, high))(length(levels(m_long$breaks))) p <- p + scale_fill_manual(name, values = x, drop = drop) } else { p <- p + scale_fill_brewer(name, palette = palette, drop = drop) } } else if (geom == "circle") { p <- p + geom_point(aes(size = abs(coefficient) * 1.25), color = "grey50") # border if (is.null(nbreaks)) { # -- circles, continuous ------------------------------------------------- p <- p + geom_point(aes(size = abs(coefficient), color = coefficient)) } else { # -- circles, ordinal ---------------------------------------------------- p <- p + geom_point(aes(size = abs(coefficient), color = breaks)) } p <- p + scale_size_continuous(range = c(min_size, max_size)) + guides(size = "none") r <- list(size = (min_size + max_size) / 2) # -- circles, color scale -------------------------------------------------- if (is.null(nbreaks) && !is.null(limits)) { p <- p + scale_color_gradient2(name, low = low, mid = mid, high = high, midpoint = midpoint, limits = limits ) } else if (is.null(nbreaks)) { p <- p + scale_color_gradient2(name, low = low, mid = mid, high = high, midpoint = midpoint ) } else if (is.null(palette)) { x <- colorRampPalette(c(low, mid, high))(length(levels(m_long$breaks))) p <- p + scale_color_manual(name, values = x, drop = drop) + guides(color = guide_legend(override.aes = r)) } else { p <- p + scale_color_brewer(name, palette = palette, drop = drop) + guides(color = guide_legend(override.aes = r)) } } else if (geom == "text") { if (is.null(nbreaks)) { # -- text, continuous ---------------------------------------------------- p <- p + geom_text(aes(label = label, color = coefficient), size = label_size) } else { # -- text, ordinal ------------------------------------------------------- p <- p + geom_text(aes(label = label, color = breaks), size = label_size) } # -- text, color scale ---------------------------------------------------- if (is.null(nbreaks) && !is.null(limits)) { p <- p + scale_color_gradient2(name, low = low, mid = mid, high = high, midpoint = midpoint, limits = limits ) } else if (is.null(nbreaks)) { p <- p + scale_color_gradient2(name, low = low, mid = mid, high = high, midpoint = midpoint ) } else if (is.null(palette)) { x <- colorRampPalette(c(low, mid, high))(length(levels(m_long$breaks))) p <- p + scale_color_manual(name, values = x, drop = drop) } else { p <- p + scale_color_brewer(name, palette = palette, drop = drop) } } # -- coefficient labels ------------------------------------------------------ if (label) { if (isTRUE(label_alpha)) { p <- p + geom_text(aes(x, y, label = label, alpha = abs(coefficient)), color = label_color, size = label_size, show.legend = FALSE ) } else if (label_alpha > 0) { p <- p + geom_text( aes(x, y, label = label), show.legend = FALSE, alpha = label_alpha, color = label_color, size = label_size ) } else { p <- p + geom_text(aes(x, y, label = label), color = label_color, size = label_size ) } } # -- horizontal scale expansion ---------------------------------------------- textData <- m_long[m_long$x == m_long$y & is.na(m_long$coefficient), ] xLimits <- levels(textData$y) textData$diagLabel <- textData$x if (!is.numeric(layout.exp) || layout.exp < 0) { stop("incorrect layout.exp value") } else if (layout.exp > 0) { layout.exp <- as.integer(layout.exp) # copy to fill in spacer info textData <- rbind(textData[1:layout.exp, ], textData) spacer <- paste(".ggally_ggcorr_spacer_value", 1:layout.exp, sep = "") textData$x[1:layout.exp] <- spacer textData$diagLabel[1:layout.exp] <- NA xLimits <- c(spacer, levels(m_long$y)) } p <- p + geom_text(data = textData, aes(label = !!as.name("diagLabel")), ..., na.rm = TRUE) + scale_x_discrete(breaks = NULL, limits = xLimits) + scale_y_discrete(breaks = NULL, limits = levels(m_long$y)) + labs(x = NULL, y = NULL) + coord_equal() + theme( panel.background = element_blank(), legend.key = element_blank(), legend.position = legend.position, legend.title = element_text(size = legend.size), legend.text = element_text(size = legend.size) ) return(p) } GGally/R/find-combo.R0000644000176200001440000000611414527265752014013 0ustar liggesusers#' Plot Types #' #' Retrieves the type of plot that should be used for all combinations #' #' @param data data set to be used #' @author Barret Schloerke #' @keywords internal plot_types <- function(data, columnsX, columnsY, allowDiag = TRUE) { plotTypesX <- lapply(data[columnsX], plotting_data_type) plotTypesY <- lapply(data[columnsY], plotting_data_type) columnNamesX <- names(data)[columnsX] columnNamesY <- names(data)[columnsY] isNaData <- as.data.frame(is.na(data)) lenX <- length(plotTypesX) lenY <- length(plotTypesY) n <- lenX * lenY plotType <- character(n) xVar <- character(n) yVar <- character(n) posX <- integer(n) posY <- integer(n) # horizontal then vertical for (yI in seq_len(lenY)) { yColName <- columnNamesY[yI] for (xI in seq_len(lenX)) { xColName <- columnNamesX[xI] yVarVal <- ifelse(xColName == yColName && allowDiag, NA, yColName) pos <- (yI - 1) * lenX + xI plotType[pos] <- find_plot_type( xColName, yColName, plotTypesX[xI], plotTypesY[yI], isAllNa = all(isNaData[[xColName]] | isNaData[[yColName]]), allowDiag = allowDiag ) xVar[pos] <- xColName yVar[pos] <- yVarVal posX[pos] <- xI posY[pos] <- yI } } dataInfo <- data.frame( plotType = plotType, xVar = xVar, yVar = yVar, posX = posX, posY = posY, isVertical = NA, stringsAsFactors = FALSE ) isCombo <- dataInfo$plotType == "combo" if (any(isCombo)) { dataInfo$isVertical[isCombo] <- unlist(plotTypesX[xVar[isCombo]]) == "discrete" } dataInfo } #' Find plot types #' #' Retrieves the type of plot for the specific columns #' #' @param col1Name x column name #' @param col2Name y column name #' @param type1 x column type #' @param type2 y column type #' @param isAllNa is.na(data) #' @param allowDiag allow for diag values to be returned #' @author Barret Schloerke #' @keywords internal find_plot_type <- function(col1Name, col2Name, type1, type2, isAllNa, allowDiag) { # diag calculations if (col1Name == col2Name && allowDiag) { if (type1 == "na") { return("na-diag") } else if (type1 == "continuous") { return("continuous-diag") } else { return("discrete-diag") } } if (type1 == "na" || type2 == "na") { return("na") } # cat(names(data)[col2Name],": ", type2,"\t",names(data)[col1Name],": ",type1,"\n") isCats <- c(type1, type2) %in% "discrete" if (any(isCats)) { if (all(isCats)) { return("discrete") } return("combo") } # check if any combo of the two columns is all na if (isAllNa) { return("na") } return("continuous") } #' Check if object is a date #' #' @keywords internal #' @param x vector is_date <- function(x) { inherits(x, c("POSIXt", "POSIXct", "POSIXlt", "Date")) } #' Get plotting data type #' #' @keywords internal #' @param x vector plotting_data_type <- function(x) { if (all(is.na(x))) { return("na") } if (is_date(x)) { "continuous" } else if (any(is.factor(x), is.character(x), is.logical(x))) { "discrete" } else { "continuous" } } GGally/R/ggmatrix_gtable.R0000644000176200001440000002264714561203030015122 0ustar liggesusers#' \code{\link{ggmatrix}} \pkg{gtable} object #' #' Specialized method to print the \code{\link{ggmatrix}} object. #' #' @param pm \code{\link{ggmatrix}} object to be plotted #' @param ... ignored #' @param progress,progress_format Please use the 'progress' parameter in your \code{\link{ggmatrix}}-like function. See \code{\link{ggmatrix_progress}} for a few examples. These parameters will soon be deprecated. #' @author Barret Schloerke #' @importFrom grid gpar grid.layout grid.newpage grid.text grid.rect popViewport pushViewport viewport grid.draw #' @export #' @examples #' data(tips) #' pm <- ggpairs(tips, c(1, 3, 2), mapping = ggplot2::aes(color = sex)) #' ggmatrix_gtable(pm) ggmatrix_gtable <- function( pm, ..., progress = NULL, progress_format = formals(ggmatrix_progress)$format) { # pm is for "plot matrix" # init progress bar handle if (missing(progress) && missing(progress_format)) { # only look at plot matrix for progress bar hasProgressBar <- !isFALSE(pm$progress) progress_fn <- pm$progress } else { warning("Please use the 'progress' parameter in your ggmatrix-like function call. See ?ggmatrix_progress for a few examples. ggmatrix_gtable 'progress' and 'progress_format' will soon be deprecated.", immediate = TRUE) # has progress variable defined # overrides pm$progress if (missing(progress_format)) { progress_fn <- as_ggmatrix_progress(progress) } else { progress_fn <- as_ggmatrix_progress( progress, pm$ncol * pm$nrow, format = progress_format ) } hasProgressBar <- !isFALSE(progress_fn) ggmatrix_progress } if (hasProgressBar) { pb <- progress_fn(pm) # pb$tick(tokens = list(plot_i = 1, plot_j = 1)) } # make a fake facet grid to fill in with proper plot panels get_labels <- function(labels, length_out, name) { if (is.expression(labels)) { stop( "'", name, "' can only be a character vector or NULL.", " Character values can be parsed using the 'labeller' parameter." ) } ifnull(labels, as.character(seq_len(length_out))) } fake_data <- expand.grid( Var1 = get_labels(pm$xAxisLabels, pm$ncol, "xAxisLabels"), Var2 = get_labels(pm$yAxisLabels, pm$nrow, "yAxisLabels") ) fake_data$x <- 1 fake_data$y <- 1 # make the smallest plot possible so the guts may be replaced pm_fake <- ggplot(fake_data, mapping = aes(!!as.name("x"), !!as.name("y"))) + geom_point() + # make the 'fake' strips for x and y titles facet_grid(Var2 ~ Var1, labeller = ifnull(pm$labeller, "label_value"), switch = pm$switch) + # remove both x and y titles labs(x = pm$xlab, y = pm$ylab) # add all custom ggplot2 things pm_fake <- add_gg_info(pm_fake, pm$gg) # add the title or remove the location completely if (is.null(pm$title)) { pm_fake <- pm_fake + theme(plot.title = element_blank()) } else { pm_fake <- pm_fake + labs(title = pm$title) } # if there are no labels, then there should be no strips if (is.null(pm$xAxisLabels)) { pm_fake <- pm_fake + theme(strip.text.x = element_blank()) } if (is.null(pm$yAxisLabels)) { pm_fake <- pm_fake + theme(strip.text.y = element_blank()) } # if there is a legend, make a fake legend that will be replaced later if (!is.null(pm$legend)) { pm_fake <- pm_fake + geom_point(mapping = aes(color = !!as.name("Var1"))) } # make a gtable of the plot matrix (to be filled in) pmg <- plot_gtable(pm_fake) ############### ## Everything beyond this point is only to fill in the correct information. ## No grobs should be appended or removed. It should be done with themes or geoms above ############### # help with grob positions pmg$layout$grob_pos <- seq_along(pmg$grobs) pmg_layout <- pmg$layout pmg_layout_name <- pmg_layout$name pmg_layout_grob_pos <- pmg_layout$grob_pos # zero out rest of the plotting area (just in case it is not replaced) zero_pos_vals <- pmg_layout_grob_pos[ str_detect( pmg_layout_name, paste(c("panel", "axis-l", "axis-b", "guide-box"), collapse = "|") ) ] for (zero_pos in zero_pos_vals) { pmg$grobs[[zero_pos]] <- ggplot2::zeroGrob() } pmg # insert legend if (!is.null(pm$legend)) { legend <- pm$legend if (is.numeric(legend)) { if (length(legend) == 1) { legend <- get_pos_rev(pm, legend) } else if (length(legend) > 2) { stop("'legend' must be a single or double numberic value. Or 'legend' must be an object produced from 'grab_legend()'") # nolint } legend_obj <- grab_legend(pm[legend[1], legend[2]]) } else if (inherits(legend, "legend_guide_box")) { legend_obj <- legend } legend_layout <- pmg_layout[grepl("guide-box", pmg_layout_name), ] class(legend_obj) <- setdiff(class(legend_obj), "legend_guide_box") index <- legend_layout$grob_pos[match(legend_obj$layout$name, legend_layout$name)] pmg$grobs[index] <- legend_obj$grobs if ("guide-box" %in% legend_layout$name) { legend_position <- ifnull(pm_fake$theme$legend.position, "right") if (legend_position %in% c("right", "left")) { pmg$widths[[legend_layout$l]] <- legend_obj$widths[1] } else if (legend_position %in% c("top", "bottom")) { pmg$heights[[legend_layout$t]] <- legend_obj$heights[1] } else { stop(paste("ggmatrix does not know how display a legend when legend.position with value: '", legend_position, "'. Valid values: c('right', 'left', 'bottom', 'top')", sep = "")) # nolint } } else { # From ggplot 3.5.0 onwards, a plot can have multiple legends lr <- intersect(c("guide-box-left", "guide-box-right"), legend_obj$layout$name) if (length(lr) > 0) { width <- legend_obj$widths[legend_obj$layout$l[match(lr, legend_obj$layout$name)]] pmg$widths[legend_layout$l[match(lr, legend_layout$name)]] <- width } tb <- intersect(c("guide-box-bottom", "guide-box-right"), legend_obj$layout$name) if (length(tb) > 0) { height <- legend_obj$heights[legend_obj$layout$t[match(tb, legend_obj$layout$name)]] pmg$heights[legend_layout$t[match(tb, legend_layout$name)]] <- height } } } # Get all 'panel' grob_pos in the pmg panel_layout <- pmg_layout[str_detect(pmg_layout_name, "panel"), ] panel_locations_order <- order(panel_layout$t, panel_layout$l, decreasing = FALSE) panel_locations <- panel_layout[panel_locations_order, "grob_pos"] # init the axis sizes left_axis_sizes <- numeric(pm$nrow + 1) bottom_axis_sizes <- numeric(pm$ncol + 1) axis_l_grob_pos <- pmg_layout_grob_pos[str_detect(pmg_layout_name, "axis-l")] axis_b_grob_pos <- pmg_layout_grob_pos[str_detect(pmg_layout_name, "axis-b")] # change the plot size ratios x_proportions <- pm$xProportions if (!is.null(x_proportions)) { panel_width_pos <- sort(unique(panel_layout$l)) if (!inherits(x_proportions, "unit")) { x_proportions <- grid::unit(x_proportions, "null") } pmg$widths[panel_width_pos] <- x_proportions } y_proportions <- pm$yProportions if (!is.null(y_proportions)) { panel_height_pos <- sort(unique(panel_layout$t)) if (!inherits(y_proportions, "unit")) { y_proportions <- grid::unit(y_proportions, "null") } pmg$heights[panel_height_pos] <- y_proportions } # build and insert all plots and axis labels plot_number <- 0 for (i in seq_len(pm$nrow)) { for (j in seq_len(pm$ncol)) { plot_number <- plot_number + 1 grob_pos_panel <- panel_locations[plot_number] # update the progress bar is possible if (hasProgressBar) { pb$tick(tokens = list(plot_i = i, plot_j = j)) } # retrieve plot p <- pm[i, j] # ignore all blank plots. all blank plots do not draw anything else if (is_blank_plot(p)) { next } # if it's not a ggplot2 obj, insert it and pray it works if (!is.ggplot(p)) { pmg$grobs[[grob_pos_panel]] <- p next } # get the plot's gtable to slice and dice pg <- plot_gtable(p) # if the left axis should be added if (j == 1 && pm$showYAxisPlotLabels) { left_axis_sizes[i] <- axis_size_left(pg) pmg <- add_left_axis( pmg, pg, show_strips = ( (i == 1) && is.null(pm$showStrips) ) || isTRUE(pm$showStrips), grob_pos = axis_l_grob_pos[i] ) } # if the bottom axis should be added if (i == pm$nrow && pm$showXAxisPlotLabels) { bottom_axis_sizes[j] <- axis_size_bottom(pg) pmg <- add_bottom_axis( pmg, pg, show_strips = ( (j == pm$ncol) && is.null(pm$showStrips) ) || isTRUE(pm$showStrips), grob_pos = axis_b_grob_pos[j] ) } # grab plot panel and insert pmg$grobs[[grob_pos_panel]] <- plot_panel( pg = pg, row_pos = i, col_pos = j, matrix_show_strips = pm$showStrips, matrix_ncol = pm$ncol, plot_show_axis_labels = p$showLabels ) } } # make sure the axes have enough room pmg <- set_max_axis_size( pmg, axis_sizes = left_axis_sizes, layout_name = "axis-l", layout_cols = c("l", "r"), pmg_key = "widths" # stop_msg = "left axis width issue!! Fix!" ) pmg <- set_max_axis_size( pmg, axis_sizes = bottom_axis_sizes, layout_name = "axis-b", layout_cols = c("t", "b"), pmg_key = "heights" # stop_msg = "bottom axis height issue!! Fix!" ) pmg } GGally/R/reexports.R0000644000176200001440000000172714526737445014040 0ustar liggesusers# reexports from ggstats ------------------- #' @importFrom ggstats ggcoef_model #' @export ggstats::ggcoef_model #' @importFrom ggstats ggcoef_compare #' @export ggstats::ggcoef_compare #' @importFrom ggstats ggcoef_multinom #' @export ggstats::ggcoef_multinom #' @importFrom ggstats ggcoef_plot #' @export ggstats::ggcoef_plot #' @importFrom ggstats signif_stars #' @export ggstats::signif_stars #' @importFrom ggstats geom_stripped_cols #' @export ggstats::geom_stripped_cols #' @importFrom ggstats geom_stripped_rows #' @export ggstats::geom_stripped_rows #' @importFrom ggstats stat_cross #' @export ggstats::stat_cross #' @importFrom ggstats StatCross #' @export ggstats::StatCross #' @importFrom ggstats stat_prop #' @export ggstats::stat_prop #' @importFrom ggstats StatProp #' @export ggstats::StatProp #' @importFrom ggstats stat_weighted_mean #' @export ggstats::stat_weighted_mean #' @importFrom ggstats StatWeightedMean #' @export ggstats::StatWeightedMean GGally/R/ggpairs_getput.R0000644000176200001440000001053314561477101015011 0ustar liggesusers#' Insert a plot into a \code{\link{ggmatrix}} object #' #' Function to place your own plot in the layout. #' #' @param pm ggally object to be altered #' @param value ggplot object to be placed #' @param i row from the top #' @param j column from the left #' @keywords hplot #' @author Barret Schloerke #' @seealso \code{\link{getPlot}} #' @export #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' custom_car <- ggpairs(mtcars[, c("mpg", "wt", "cyl")], upper = "blank", title = "Custom Example") #' # ggplot example taken from example(geom_text) #' plot <- ggplot2::ggplot(mtcars, ggplot2::aes(x = wt, y = mpg, label = rownames(mtcars))) #' plot <- plot + #' ggplot2::geom_text(ggplot2::aes(colour = factor(cyl)), size = 3) + #' ggplot2::scale_colour_discrete(l = 40) #' custom_car[1, 2] <- plot #' personal_plot <- ggally_text( #' "ggpairs allows you\nto put in your\nown plot.\nLike that one.\n <---" #' ) #' custom_car[1, 3] <- personal_plot #' # custom_car #' #' # remove plots after creating a plot matrix #' custom_car[2, 1] <- NULL #' custom_car[3, 1] <- "blank" # the same as storing null #' custom_car[3, 2] <- NULL #' p_(custom_car) putPlot <- function(pm, value, i, j) { pos <- get_pos(pm, i, j) if (is.null(value)) { pm$plots[[pos]] <- make_ggmatrix_plot_obj(wrap("blank", funcArgName = "ggally_blank")) } else if (mode(value) == "character") { if (value == "blank") { pm$plots[[pos]] <- make_ggmatrix_plot_obj(wrap("blank", funcArgName = "ggally_blank")) } else { stop("character values (besides 'blank') are not allowed to be stored as plot values.") } } else { pm$plots[[pos]] <- value } pm } #' Subset a \code{\link{ggmatrix}} object #' #' Retrieves the ggplot object at the desired location. #' #' @param pm \code{\link{ggmatrix}} object to select from #' @param i row from the top #' @param j column from the left #' @keywords hplot #' @author Barret Schloerke #' @importFrom utils capture.output #' @seealso \code{\link{putPlot}} #' @export #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' data(tips) #' plotMatrix2 <- ggpairs(tips[, 3:2], upper = list(combo = "denstrip")) #' p_(plotMatrix2[1, 2]) getPlot <- function(pm, i, j) { if (FALSE) { cat("i: ", i, " j: ", j, "\n") } pos <- get_pos(pm, i, j) if (pos > length(pm$plots)) { plotObj <- NULL } else { plotObj <- pm$plots[[pos]] } if (is.null(plotObj)) { p <- ggally_blank() } else { if (ggplot2::is.ggplot(plotObj)) { p <- plotObj } else if (inherits(plotObj, "ggmatrix_plot_obj")) { fn <- plotObj$fn p <- fn(pm$data, plotObj$mapping) } else if (inherits(plotObj, "legend_guide_box")) { p <- plotObj } else { firstNote <- str_c("Position: i = ", i, ", j = ", j, "\nstr(plotObj):\n", sep = "") strObj <- capture.output({ str(plotObj) }) stop(str_c("unknown plot object type.\n", firstNote, strObj)) } p <- add_gg_info(p, pm$gg) } p } get_pos <- function(pm, i, j) { if (isTRUE(pm$byrow)) { pos <- j + (pm$ncol * (i - 1)) } else { pos <- i + (pm$nrow * (j - 1)) } pos } get_pos_rev <- function(pm, pos) { if (isTRUE(pm$byrow)) { i <- ceiling(pos / pm$ncol) j <- (pos - 1) %% pm$ncol + 1 } else { i <- (pos - 1) %% pm$nrow + 1 j <- ceiling(pos / pm$nrow) } c(i, j) } check_i_j <- function(pm, i, j) { if ((length(i) > 1) || (mode(i) != "numeric")) { stop("'i' may only be a single numeric value") } if ((length(j) > 1) || (mode(j) != "numeric")) { stop("'j' may only be a single numeric value") } if (i > pm$nrow || i < 1) { stop("'i' may only be in the range from 1:", pm$nrow) } if (j > pm$ncol || j < 1) { stop("'j' may only be in the range from 1:", pm$ncol) } invisible() } #' @rdname getPlot #' @usage \method{[}{ggmatrix}(pm, i, j, ...) #' @param ... ignored #' @export `[.ggmatrix` <- function(pm, i, j, ...) { # print(list(x = i, y = j)) check_i_j(pm, i, j) getPlot(pm, i, j) } #' @rdname putPlot #' @usage \method{[}{ggmatrix}(pm, i, j, ...) <- value #' @param ... ignored #' @export `[<-.ggmatrix` <- function(pm, i, j, ..., value) { # x = matrix # i = first subset # j = second subset # y = value check_i_j(pm, i, j) putPlot(pm, value, i, j) } GGally/R/ggmatrix_progress.R0000644000176200001440000000302414527265752015541 0ustar liggesusers#' \code{\link{ggmatrix}} default progress bar #' #' @param format,clear,show_after,... parameters supplied directly to \code{progress::\link[progress]{progress_bar}$new()} #' @return function that accepts a plot matrix as the first argument and \code{...} for future expansion. Internally, the plot matrix is used to determine the total number of plots for the progress bar. #' @export #' @examples #' p_ <- GGally::print_if_interactive #' #' pm <- ggpairs(iris, 1:2, progress = ggmatrix_progress()) #' p_(pm) #' #' # does not clear after finishing #' pm <- ggpairs(iris, 1:2, progress = ggmatrix_progress(clear = FALSE)) #' p_(pm) ggmatrix_progress <- function( format = " plot: [:plot_i, :plot_j] [:bar]:percent est::eta ", clear = TRUE, show_after = 0, ...) { ret <- function(pm, ...) { progress::progress_bar$new( format = format, clear = clear, show_after = show_after, total = pm$ncol * pm$nrow, ... ) } ret } as_ggmatrix_progress <- function(x, total, ...) { if (isFALSE(x)) { return(FALSE) } if (isTRUE(x)) { return(ggmatrix_progress(...)) } if (is.null(x)) { shouldDisplay <- interactive() && total > 15 if (!shouldDisplay) { return(FALSE) } else { return(ggmatrix_progress(...)) } } if (is.function(x)) { return(x) } stop( "as_ggmatrix_progress only knows how to handle TRUE, FALSE, NULL, or a function.", " If a function, it must return a new progress_bar" ) } isFALSE <- function(x) { identical(FALSE, x) } GGally/R/ggnet.R0000644000176200001440000005753614562447013013107 0ustar liggesusersif (getRversion() >= "2.15.1") { utils::globalVariables(c("X1", "X2", "Y1", "Y2", "midX", "midY")) } #' Network plot #' #' Function for plotting network objects using \pkg{ggplot2}, now replaced by the #' \code{\link{ggnet2}} function, which provides additional control over #' plotting parameters. Please visit \url{https://github.com/briatte/ggnet} for #' the latest version of ggnet2, and \url{https://briatte.github.io/ggnet/} for a #' vignette that contains many examples and explanations. #' #' @export #' @param net an object of class \code{\link[network]{network}}, or any object #' that can be coerced to this class, such as an adjacency or incidence matrix, #' or an edge list: see \link[network]{edgeset.constructors} and #' \link[network]{network} for details. If the object is of class #' [igraph][igraph::igraph-package] and the #' [intergraph][intergraph::intergraph-package] package is installed, #' it will be used to convert the object: see #' \code{\link[intergraph]{asNetwork}} for details. #' @param mode a placement method from those provided in the #' \code{\link[sna]{sna}} package: see \link[sna:gplot.layout]{gplot.layout} for #' details. Also accepts the names of two numeric vertex attributes of #' \code{net}, or a matrix of numeric coordinates, in which case the first two #' columns of the matrix are used. #' Defaults to the Fruchterman-Reingold force-directed algorithm. #' @param layout.par options to be passed to the placement method, as listed in #' \link[sna]{gplot.layout}. #' Defaults to \code{NULL}. #' @param layout.exp a multiplier to expand the horizontal axis if node labels #' get clipped: see \link[scales]{expand_range} for details. #' Defaults to \code{0} (no expansion). #' @param size size of the network nodes. If the nodes are weighted, their area is proportionally scaled up to the size set by \code{size}. #' Defaults to \code{9}. #' @param alpha a level of transparency for nodes, vertices and arrows. #' Defaults to \code{1}. #' @param weight the weighting method for the nodes, which might be a vertex #' attribute or a vector of size values. Also accepts \code{"indegree"}, #' \code{"outdegree"}, \code{"degree"} or \code{"freeman"} to size the nodes by #' their unweighted degree centrality (\code{"degree"} and \code{"freeman"} are #' equivalent): see \code{\link[sna]{degree}} for details. All node weights must #' be positive. #' Defaults to \code{"none"} (no weighting). #' @param weight.method see \code{weight} #' @param weight.legend the name to assign to the legend created by #' \code{weight}. #' Defaults to \code{NA} (no name). #' @param weight.min whether to subset the network to nodes with a minimum size, #' based on the values of \code{weight}. #' Defaults to \code{NA} (preserves all nodes). #' @param weight.max whether to subset the network to nodes with a maximum size, #' based on the values of \code{weight}. #' Defaults to \code{NA} (preserves all nodes). #' @param weight.cut whether to cut the size of the nodes into a certain number #' of quantiles. Accepts \code{TRUE}, which tries to cut the sizes into #' quartiles, or any positive numeric value, which tries to cut the sizes into #' that many quantiles. If the size of the nodes do not contain the specified #' number of distinct quantiles, the largest possible number is used. #' See \code{\link[stats]{quantile}} and \code{\link[base]{cut}} for details. #' Defaults to \code{FALSE} (does nothing). #' @param group the groups of the nodes, either as a vector of values or as a #' vertex attribute. If set to \code{mode} on a bipartite network, the nodes #' will be grouped as \code{"actor"} if they belong to the primary mode and #' \code{"event"} if they belong to the secondary mode. #' @param group.legend the name to assign to the legend created by #' \code{group}. #' @param node.group see \code{group} #' @param node.color a vector of character strings to color the nodes with, #' holding as many colors as there are levels in \code{node.group}. #' Defaults to \code{NULL}, which will assign grayscale colors to each group. #' @param node.alpha transparency of the nodes. Inherits from \code{alpha}. #' @param segment.alpha the level of transparency of the edges. #' Defaults to \code{alpha}, which defaults to \code{1}. #' @param segment.color the color of the edges, as a color value, a vector of #' color values, or as an edge attribute containing color values. #' Defaults to \code{"grey50"}. #' @param segment.size the size of the edges, in points, as a single numeric #' value, a vector of values, or as an edge attribute. #' Defaults to \code{0.25}. #' @param segment.label the labels to plot at the middle of the edges, as a #' single value, a vector of values, or as an edge attribute. #' Defaults to \code{NULL} (no edge labels). #' @param arrow.size the size of the arrows for directed network edges, in #' points. See \code{\link[grid]{arrow}} for details. #' Defaults to \code{0} (no arrows). #' @param arrow.gap a setting aimed at improving the display of edge arrows by #' plotting slightly shorter edges. Accepts any value between \code{0} and #' \code{1}, where a value of \code{0.05} will generally achieve good results #' when the size of the nodes is reasonably small. #' Defaults to \code{0} (no shortening). #' @param arrow.type the type of the arrows for directed network edges. See #' \code{\link[grid]{arrow}} for details. #' Defaults to \code{"closed"}. #' @param label whether to label the nodes. If set to \code{TRUE}, nodes are #' labeled with their vertex names. If set to a vector that contains as many #' elements as there are nodes in \code{net}, nodes are labeled with these. If #' set to any other vector of values, the nodes are labeled only when their #' vertex name matches one of these values. #' Defaults to \code{FALSE} (no labels). #' @param label.nodes see \code{label} #' @param label.size the size of the node labels, in points, as a numeric value, #' a vector of numeric values, or as a vertex attribute containing numeric #' values. #' Defaults to \code{size / 2} (half the maximum node size), which defaults to #' \code{6}. #' @param label.trim whether to apply some trimming to the node labels. Accepts #' any function that can process a character vector, or a strictly positive #' numeric value, in which case the labels are trimmed to a fixed-length #' substring of that length: see \code{\link[base]{substr}} for details. #' Defaults to \code{FALSE} (does nothing). #' @param legend.size the size of the legend symbols and text, in points. #' Defaults to \code{9}. #' @param legend.position the location of the plot legend(s). Accepts all #' \code{legend.position} values supported by \code{\link[ggplot2]{theme}}. #' Defaults to \code{"right"}. #' @param names deprecated: see \code{group.legend} and \code{size.legend} #' @param quantize.weights deprecated: see \code{weight.cut} #' @param subset.threshold deprecated: see \code{weight.min} #' @param top8.nodes deprecated: this functionality was experimental and has #' been removed entirely from \code{ggnet} #' @param trim.labels deprecated: see \code{label.trim} #' @param ... other arguments passed to the \code{geom_text} object that sets #' the node labels: see \code{\link[ggplot2]{geom_text}} for details. #' @seealso \code{\link{ggnet2}} in this package, #' \code{\link[sna]{gplot}} in the \code{\link[sna]{sna}} package, and #' \code{\link[network]{plot.network}} in the \code{\link[network]{network}} #' package #' @author Moritz Marbach and Francois Briatte, with help from Heike Hofmann, #' Pedro Jordano and Ming-Yu Liu #' @details The degree centrality measures that can be produced through the #' \code{weight} argument will take the directedness of the network into account, #' but will be unweighted. To compute weighted network measures, see the #' \code{tnet} package by Tore Opsahl (\code{help("tnet", package = "tnet")}). #' @importFrom stats quantile na.omit #' @importFrom utils head installed.packages #' @importFrom grDevices gray.colors #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' library(network) #' #' # random adjacency matrix #' x <- 10 #' ndyads <- x * (x - 1) #' density <- x / ndyads #' m <- matrix(0, nrow = x, ncol = x) #' dimnames(m) <- list(letters[1:x], letters[1:x]) #' m[row(m) != col(m)] <- runif(ndyads) < density #' m #' #' # random undirected network #' n <- network::network(m, directed = FALSE) #' n #' #' ggnet(n, label = TRUE, alpha = 1, color = "white", segment.color = "black") #' #' # random groups #' g <- sample(letters[1:3], 10, replace = TRUE) #' g #' #' # color palette #' p <- c("a" = "steelblue", "b" = "forestgreen", "c" = "tomato") #' #' p_(ggnet(n, node.group = g, node.color = p, label = TRUE, color = "white")) #' #' # edge arrows on a directed network #' p_(ggnet(network(m, directed = TRUE), arrow.gap = 0.05, arrow.size = 10)) ggnet <- function( net, mode = "fruchtermanreingold", layout.par = NULL, layout.exp = 0, size = 9, alpha = 1, weight = "none", weight.legend = NA, weight.method = weight, weight.min = NA, weight.max = NA, weight.cut = FALSE, group = NULL, group.legend = NA, node.group = group, node.color = NULL, node.alpha = alpha, segment.alpha = alpha, segment.color = "grey50", segment.label = NULL, segment.size = 0.25, arrow.size = 0, arrow.gap = 0, arrow.type = "closed", label = FALSE, label.nodes = label, label.size = size / 2, label.trim = FALSE, legend.size = 9, legend.position = "right", # -- deprecated arguments ---------------------------------------------------- names = c("", ""), quantize.weights = FALSE, subset.threshold = 0, top8.nodes = FALSE, trim.labels = FALSE, ... ) { # -- packages ---------------------------------------------------------------- require_namespaces(c("network", "sna", "scales")) # -- deprecations ------------------------------------------------------------ if (length(mode) == 1 && mode == "geo") { warning("mode = 'geo' is deprecated; please use mode = c('lon', 'lat') instead") mode = c("lon", "lat") } if (!identical(names, c("", ""))) { warning("names is deprecated; please use group.legend and size.legend instead") group.legend = names[1] size.legend = names[2] } if (isTRUE(quantize.weights)) { warning("quantize.weights is deprecated; please use weight.cut instead") weight.cut = TRUE } if (subset.threshold > 0) { warning("subset.threshold is deprecated; please use weight.min instead") weight.min = subset.threshold } if (isTRUE(top8.nodes)) { warning("top8.nodes is deprecated") } if (isTRUE(trim.labels)) { warning("trim.labels is deprecated; please use label.trim instead") label.trim = function(x) gsub("^@|^http://(www\\.)?|/$", "", x) } # -- conversion to network class --------------------------------------------- if (inherits(net, "igraph") && "intergraph" %in% rownames(installed.packages())) { net = intergraph::asNetwork(net) } else if (inherits(net, "igraph")) { stop("install the 'intergraph' package to use igraph objects with ggnet") } if (!network::is.network(net)) { net = try(network::network(net), silent = TRUE) } if (!network::is.network(net)) { stop("could not coerce net to a network object") } # -- network functions ------------------------------------------------------- get_v = utils::getFromNamespace("%v%", ns = "network") get_e = utils::getFromNamespace("%e%", ns = "network") set_mode = function(x, mode = network::get.network.attribute(x, "bipartite")) { c(rep("actor", mode), rep("event", n_nodes - mode)) } set_node = function(x, value, mode = TRUE) { if (is.null(x) || any(is.na(x)) || any(is.infinite(x)) || any(is.nan(x))) { stop(paste("incorrect", value, "value")) } else if (is.numeric(x) && any(x < 0)) { stop(paste("incorrect", value, "value")) } else if (length(x) == n_nodes) { x } else if (length(x) > 1) { stop(paste("incorrect", value, "length")) } else if (any(x %in% v_attr)) { get_v(net, x) } else if (mode && identical(x, "mode") && is_bip) { set_mode(net) } else { x } } set_edge = function(x, value) { if (is.null(x) || any(is.na(x)) || any(is.infinite(x)) || any(is.nan(x))) { stop(paste("incorrect", value, "value")) } else if (is.numeric(x) && any(x < 0)) { stop(paste("incorrect", value, "value")) } else if (length(x) == n_edges) { x } else if (length(x) > 1) { stop(paste("incorrect", value, "length")) } else if (any(x %in% e_attr)) { get_e(net, x) } else { x } } set_attr = function(x) { if (length(x) == n_nodes) { x } else if (length(x) > 1) { stop(paste("incorrect coordinates length")) } else if (!x %in% v_attr) { stop(paste("vertex attribute", x, "was not found")) } else if (!is.numeric(get_v(net, x))) { stop(paste("vertex attribute", x, "is not numeric")) } else { get_v(net, x) } } set_name = function(x, y) ifelse(length(x) == 1, x, ifelse(is.na(y), "", y)) is_one = function(x) length(unique(x)) == 1 is_col = function(x) all(is.numeric(x)) | all(network::is.color(x)) # -- network structure ------------------------------------------------------- n_nodes = network::network.size(net) n_edges = network::network.edgecount(net) v_attr = network::list.vertex.attributes(net) e_attr = network::list.edge.attributes(net) is_bip = network::is.bipartite(net) is_dir = ifelse(network::is.directed(net), "digraph", "graph") if (!is.numeric(arrow.size) || arrow.size < 0) { stop("incorrect arrow.size value") } else if (arrow.size > 0 && is_dir == "graph") { warning("network is undirected; arrow.size ignored") arrow.size = 0 } if (!is.numeric(arrow.gap) || arrow.gap < 0 || arrow.gap > 1) { stop("incorrect arrow.gap value") } else if (arrow.gap > 0 && is_dir == "graph") { warning("network is undirected; arrow.gap ignored") arrow.gap = 0 } if (network::is.hyper(net)) { stop("ggnet cannot plot hyper graphs") } if (network::is.multiplex(net)) { stop("ggnet cannot plot multiplex graphs") } if (network::has.loops(net)) { warning("ggnet does not know how to handle self-loops") } # -- check size -------------------------------------------------------------- x = size if (!is.numeric(x) || is.infinite(x) || is.nan(x) || x < 0 || length(x) > 1) { stop("incorrect size value") } # -- initialize dataset ------------------------------------------------------ data = data.frame(label = get_v(net, "vertex.names"), stringsAsFactors = FALSE) # -- weight methods ---------------------------------------------------------- x = weight.method if (length(x) == 1 && x %in% c("indegree", "outdegree", "degree", "freeman")) { # prevent namespace conflict with igraph if ("package:igraph" %in% search()) { y = ifelse(is_dir == "digraph", "directed", "undirected") z = c("indegree" = "in", "outdegree" = "out", "degree" = "all", "freeman" = "all")[x] data$weight = igraph::degree(igraph_graph_adjacency_matrix(as.matrix(net), mode = y), mode = z) } else { data$weight = sna::degree(net, gmode = is_dir, cmode = ifelse(x == "degree", "freeman", x)) } } else if (length(x) > 1 && length(x) == n_nodes) { data$weight = x } else if (length(x) == 1 && x %in% v_attr) { data$weight = get_v(net, x) } if (!is.null(data$weight) && !is.numeric(data$weight)) { stop("incorrect weight.method value") } # -- weight thresholds ------------------------------------------------------- x = ifelse(is.na(weight.min), 0, weight.min) if (length(x) > 1 || !is.numeric(x) || is.infinite(x) || is.nan(x) || x < 0) { stop("incorrect weight.min value") } else if (x > 0) { x = which(data$weight < x) message(paste("weight.min removed", length(x), "nodes out of", nrow(data))) if (length(x) > 0) { data = data[-x, ] network::delete.vertices(net, x) if (!nrow(data)) { warning("weight.min removed all nodes; nothing left to plot") return(invisible(NULL)) } } } x = ifelse(is.na(weight.max), 0, weight.max) if (length(x) > 1 || !is.numeric(x) || is.infinite(x) || is.nan(x) || x < 0) { stop("incorrect weight.max value") } else if (x > 0) { x = which(data$weight > x) message(paste("weight.max removed", length(x), "nodes out of", nrow(data))) if (length(x) > 0) { data = data[-x, ] network::delete.vertices(net, x) if (!nrow(data)) { warning("weight.max removed all nodes; nothing left to plot") return(invisible(NULL)) } } } # -- weight quantiles -------------------------------------------------------- x = weight.cut if (length(x) > 1 || is.null(x) || is.na(x) || is.infinite(x) || is.nan(x)) { stop("incorrect weight.cut value") } else if (isTRUE(x)) { x = 4 } else if (is.logical(x) && !x) { x = 0 } else if (!is.numeric(x)) { stop("incorrect weight.cut value") } if (x >= 1) { x = unique(quantile(data$weight, probs = seq(0, 1, by = 1 / as.integer(x)))) if (length(x) > 1) { data$weight = cut(data$weight, unique(x), include.lowest = TRUE) } else { warning("node weight is invariant; weight.cut ignored") } } # -- node sizing ------------------------------------------------------------- if (is.factor(data$weight)) { sizer = scale_size_area( set_name(weight.method, weight.legend), max_size = size, breaks = sort(unique(as.integer(data$weight))), labels = levels(data$weight)[sort(unique(as.integer(data$weight)))] ) data$weight = as.integer(data$weight) } else { sizer = scale_size_area( set_name(weight.method, weight.legend), max_size = size ) } # -- node grouping ----------------------------------------------------------- if (!is.null(node.group)) { data$group = factor(set_node(node.group, "node.group")) x = length(unique(na.omit(data$group))) if (length(node.color) != x) { if (!is.null(node.color)) { warning("node groups and colors are of unequal length; using grayscale colors") } node.color = gray.colors(x) names(node.color) = unique(na.omit(data$group)) } } # -- node labels ------------------------------------------------------------- l = label.nodes if (isTRUE(l)) { l = data$label } else if (length(l) > 1 && length(l) == n_nodes) { data$label = l } else if (length(l) == 1 && l %in% v_attr) { l = get_v(net, l) } else { l = ifelse(data$label %in% l, data$label, "") } # -- node placement ---------------------------------------------------------- if (is.character(mode) && length(mode) == 1) { mode = paste0("gplot.layout.", mode) snaNamespace = asNamespace("sna") if (!exists(mode, envir = snaNamespace)) { stop(paste("unsupported placement method:", mode)) } mode = get(mode, envir = snaNamespace) # sna placement algorithm xy = network::as.matrix.network.adjacency(net) xy = do.call(mode, list(xy, layout.par)) xy = data.frame(x = xy[, 1], y = xy[, 2]) } else if (is.character(mode) && length(mode) == 2) { # fixed coordinates from vertex attributes xy = data.frame(x = set_attr(mode[1]), y = set_attr(mode[2])) } else if (is.numeric(mode) && is.matrix(mode)) { # fixed coordinates from matrix xy = data.frame(x = set_attr(mode[, 1]), y = set_attr(mode[, 2])) } else { stop("incorrect mode value") } xy$x = scale(xy$x, min(xy$x), diff(range(xy$x)))[, 1] xy$y = scale(xy$y, min(xy$y), diff(range(xy$y)))[, 1] data = cbind(data, xy) # -- edge list --------------------------------------------------------------- edges = network::as.matrix.network.edgelist(net) edges = data.frame(xy[edges[, 1], ], xy[edges[, 2], ]) names(edges) = c("X1", "Y1", "X2", "Y2") # -- edge labels ------------------------------------------------------------- if (!is.null(segment.label)) { edges$midX = (edges$X1 + edges$X2) / 2 edges$midY = (edges$Y1 + edges$Y2) / 2 edges$label = set_edge(segment.label, "segment.label") } # -- plot edges -------------------------------------------------------------- p = ggplot(data, aes(x = x, y = y)) if (nrow(edges) > 0) { if (arrow.gap > 0) { x.length = with(edges, abs(X2 - X1)) y.length = with(edges, abs(Y2 - Y1)) arrow.gap = with(edges, arrow.gap / sqrt(x.length ^ 2 + y.length ^ 2)) edges = transform(edges, X1 = X1 + arrow.gap * x.length, Y1 = Y1 + arrow.gap * y.length, X2 = X1 + (1 - arrow.gap) * x.length, Y2 = Y1 + (1 - arrow.gap) * y.length) } p = p + geom_segment( data = edges, aes(x = X1, y = Y1, xend = X2, yend = Y2), alpha = segment.alpha, linewidth = segment.size, color = segment.color, arrow = arrow( type = arrow.type, length = unit(arrow.size, "pt") ) ) } if (nrow(edges) > 0 && !is.null(segment.label)) { p = p + geom_point( data = edges, aes(x = midX, y = midY), color = "white", size = size ) + geom_text( data = edges, aes(x = midX, y = midY, label = label), alpha = segment.alpha, color = segment.color, size = size / 2 ) } # -- plot nodes -------------------------------------------------------------- if (length(weight.method) == 1 && weight.method == "none") { p = p + geom_point( alpha = node.alpha, size = size ) } else { p = p + geom_point( aes(size = weight), alpha = node.alpha ) + sizer } # -- plot node colors -------------------------------------------------------- if (!is.null(node.group)) { p = p + aes(color = group) + scale_color_manual( set_name(node.group, group.legend), values = node.color, guide = guide_legend(override.aes = list(size = legend.size)) ) } # -- plot node labels -------------------------------------------------------- if (!is_one(l) || unique(l) != "") { label.size = set_node(label.size, "label.size", mode = FALSE) if (!is.numeric(label.size)) { stop("incorrect label.size value") } x = label.trim if (length(x) > 1 || (!is.logical(x) && !is.numeric(x) && !is.function(x))) { stop("incorrect label.trim value") } else if (is.numeric(x) && x > 0) { l = substr(l, 1, x) } else if (is.function(x)) { l = x(l) } p = p + geom_text( label = l, size = label.size, show.legend = FALSE, # required by ggplot2 >= 1.0.1.9003 ... ) } # -- horizontal scale expansion ---------------------------------------------- x = range(data$x) if (!is.numeric(layout.exp) || layout.exp < 0) { stop("incorrect layout.exp value") } else if (layout.exp > 0) { x = scales::expand_range(x, layout.exp / 2) } # -- finalize ---------------------------------------------------------------- p = p + scale_x_continuous(breaks = NULL, limits = x) + scale_y_continuous(breaks = NULL) + theme( panel.background = element_blank(), panel.grid = element_blank(), axis.title = element_blank(), legend.key = element_blank(), legend.position = legend.position, legend.text = element_text(size = legend.size), legend.title = element_text(size = legend.size) ) return(p) } igraph_graph_adjacency_matrix <- function(...) { if (packageVersion("igraph") >= "2.0.0") { igraph::graph_from_adjacency_matrix(...) } else { igraph::graph.adjacency(...) } } GGally/R/ggmatrix_legend.R0000644000176200001440000000707514561203030015120 0ustar liggesusers#' Grab the legend and print it as a plot #' #' @param p ggplot2 plot object #' @param x legend object that has been grabbed from a ggplot2 object #' @param ... ignored #' @param plotNew boolean to determine if the `grid.newpage()` command and a new blank rectangle should be printed #' @import ggplot2 #' @export #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' library(ggplot2) #' histPlot <- #' ggplot(iris, aes(Sepal.Length, fill = Species)) + #' geom_histogram(binwidth = 1 / 4) #' (right <- histPlot) #' (bottom <- histPlot + theme(legend.position = "bottom")) #' (top <- histPlot + theme(legend.position = "top")) #' (left <- histPlot + theme(legend.position = "left")) #' #' p_(grab_legend(right)) #' p_(grab_legend(bottom)) #' p_(grab_legend(top)) #' p_(grab_legend(left)) grab_legend <- function(p) { builtP <- ggplot_build(p) pTable <- ggplot_gtable(builtP) ret <- get_legend_from_gtable(pTable) return(ret) } get_legend_from_gtable <- function(pTable) { ret <- ggplot2::zeroGrob() if (inherits(pTable, "gtable")) { if (any(grepl("guide-box", pTable$layout$name))) { ret <- gtable_filter(pTable, "guide-box") keep <- !vapply(ret$grobs, inherits, what = "zeroGrob", logical(1)) keep <- paste0(ret$layout$name[keep], collapse = "|") ret <- gtable_filter(ret, keep) } } class(ret) <- c("legend_guide_box", class(ret)) ret } #' @importFrom grid grid.newpage grid.draw gpar #' @importFrom gtable gtable_filter #' @rdname grab_legend #' @export print.legend_guide_box <- function(x, ..., plotNew = FALSE) { if (identical(plotNew, TRUE)) { grid.newpage() } grid::grid.rect(gp = grid::gpar(fill = "white", col = "white")) grid.draw(x) } #' Plot only legend of plot function #' #' @param fn this value is passed directly to an empty \code{\link{wrap}} call. Please see \code{?\link{wrap}} for more details. #' @return a function that when called with arguments will produce the legend of the plotting function supplied. #' @export #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' # display regular plot #' p_(ggally_points(iris, ggplot2::aes(Sepal.Length, Sepal.Width, color = Species))) #' #' # Make a function that will only print the legend #' points_legend <- gglegend(ggally_points) #' p_(points_legend(iris, ggplot2::aes(Sepal.Length, Sepal.Width, color = Species))) #' #' # produce the sample legend plot, but supply a string that 'wrap' understands #' same_points_legend <- gglegend("points") #' identical( #' attr(attr(points_legend, "fn"), "original_fn"), #' attr(attr(same_points_legend, "fn"), "original_fn") #' ) #' #' # Complicated examples #' custom_legend <- wrap(gglegend("points"), size = 6) #' p_(custom_legend(iris, ggplot2::aes(Sepal.Length, Sepal.Width, color = Species))) #' #' # Use within ggpairs #' pm <- ggpairs( #' iris, 1:2, #' mapping = ggplot2::aes(color = Species), #' upper = list(continuous = gglegend("points")) #' ) #' p_(pm) #' #' # Place a legend in a specific location #' pm <- ggpairs(iris, 1:2, mapping = ggplot2::aes(color = Species)) #' # Make the legend #' pm[1, 2] <- points_legend(iris, ggplot2::aes(Sepal.Width, Sepal.Length, color = Species)) #' p_(pm) gglegend <- function(fn) { # allows users to supply a character just like in ggpairs fn <- wrapp(fn, list()) fn <- attr(fn, "fn") ret <- function(...) { p <- fn(...) grab_legend(p) } # attach function so people can see what it is attr(ret, "fn") <- fn attr(ret, "name") <- "gglegend" ret } GGally/R/data-psychademic.R0000644000176200001440000000162314526737230015170 0ustar liggesusers#' UCLA canonical correlation analysis data #' #' This data contains 600 observations on eight variables #' #' @details \itemize{ #' \item locus_of_control - psychological #' \item self_concept - psychological #' \item motivation - psychological. Converted to four character groups #' \item read - academic #' \item write - academic #' \item math - academic #' \item science - academic #' \item female - academic. Dropped from original source #' \item sex - academic. Added as a character version of female column #' } #' #' @docType data #' @keywords datasets #' @name psychademic #' @usage data(psychademic) #' @format A data frame with 600 rows and 8 variables #' @references #' R Data Analysis Examples | Canonical Correlation Analysis. UCLA: Institute for Digital Research and Education. from http://www.stats.idre.ucla.edu/r/dae/canonical-correlation-analysis (accessed May 22, 2017). NULL GGally/R/ggpairs_internal_plots.R0000644000176200001440000002100514562447013016532 0ustar liggesusers#' Wrap a function with different parameter values #' #' Wraps a function with the supplied parameters to force different default behavior. This is useful for functions that are supplied to ggpairs. It allows you to change the behavior of one function, rather than creating multiple functions with different parameter settings. #' #' \code{wrap} is identical to \code{wrap_fn_with_params}. These function take the new parameters as arguments. #' #' \code{wrapp} is identical to \code{wrap_fn_with_param_arg}. These functions take the new parameters as a single list. #' #' The \code{params} and \code{fn} attributes are there for debugging purposes. If either attribute is altered, the function must be re-wrapped to have the changes take effect. #' #' @param funcVal function that the \code{params} will be applied to. The function should follow the api of \code{function(data, mapping, ...)\{\}}. \code{funcVal} is allowed to be a string of one of the \code{ggally_NAME} functions, such as \code{"points"} for \code{ggally_points} or \code{"facetdensity"} for \code{ggally_facetdensity}. #' @param ... named parameters to be supplied to \code{wrap_fn_with_param_arg} #' @param params named vector or list of parameters to be applied to the \code{funcVal} #' @param funcArgName name of function to be displayed #' @return a \code{function(data, mapping, ...)\{\}} that will wrap the original function with the parameters applied as arguments #' @export #' @rdname wrap #' @examples #' # small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' # example function that prints 'val' #' fn <- function(data, mapping, val = 2) { #' print(val) #' } #' fn(data = NULL, mapping = NULL) # 2 #' #' # wrap function to change default value 'val' to 5 instead of 2 #' wrapped_fn1 <- wrap(fn, val = 5) #' wrapped_fn1(data = NULL, mapping = NULL) # 5 #' # you may still supply regular values #' wrapped_fn1(data = NULL, mapping = NULL, val = 3) # 3 #' #' # wrap function to change 'val' to 5 using the arg list #' wrapped_fn2 <- wrap_fn_with_param_arg(fn, params = list(val = 5)) #' wrapped_fn2(data = NULL, mapping = NULL) # 5 #' #' # change parameter settings in ggpairs for a particular function #' ## Goal output: #' regularPlot <- ggally_points( #' iris, #' ggplot2::aes(Sepal.Length, Sepal.Width), #' size = 5, color = "red" #' ) #' p_(regularPlot) #' #' # Wrap ggally_points to have parameter values size = 5 and color = 'red' #' w_ggally_points <- wrap(ggally_points, size = 5, color = "red") #' wrappedPlot <- w_ggally_points( #' iris, #' ggplot2::aes(Sepal.Length, Sepal.Width) #' ) #' p_(wrappedPlot) #' #' # Double check the aes parameters are the same for the geom_point layer #' identical(regularPlot$layers[[1]]$aes_params, wrappedPlot$layers[[1]]$aes_params) #' #' # Use a wrapped function in ggpairs #' pm <- ggpairs(iris, 1:3, lower = list(continuous = wrap(ggally_points, size = 5, color = "red"))) #' p_(pm) #' pm <- ggpairs(iris, 1:3, lower = list(continuous = w_ggally_points)) #' p_(pm) wrap_fn_with_param_arg <- function( funcVal, params = NULL, funcArgName = deparse(substitute(funcVal))) { if (missing(funcArgName)) { fnName <- attr(funcVal, "name") if (!is.null(fnName)) { funcArgName <- fnName } } if (!is.null(params)) { if (is.vector(params)) { params <- as.list(params) } if (length(params) > 0) { if (!is.list(params)) { stop("'params' must be a named list, named vector, or NULL") } if (is.null(names(params))) { stop("'params' must be a named list, named vector, or NULL") } if (any(nchar(names(params)) == 0)) { stop("'params' must be a named list, named vector, or NULL") } } } if (mode(funcVal) == "character") { if (missing(funcArgName)) { funcArgName <- str_c("ggally_", funcVal) } tryCatch( { funcVal <- get( str_c("ggally_", funcVal), mode = "function" ) }, error = function(e) { stop(str_c( "Error retrieving `GGally` function.\n", "Please provide a string such as `'points'` for `ggally_points()`\n", "For a list of all predefined functions, check out `vig_ggally(\"ggally_plots\")`\n", "A custom function may be supplied directly: `wrap(my_fn, param = val)`\n", "Function provided: ", funcVal )) } ) } allParams <- ifnull(attr(funcVal, "params"), list()) allParams[names(params)] <- params original_fn <- funcVal ret_fn <- function(data, mapping, ...) { allParams$data <- data allParams$mapping <- mapping argsList <- list(...) allParams[names(argsList)] <- argsList rlang::inject(original_fn(!!!allParams)) } class(ret_fn) <- "ggmatrix_fn_with_params" attr(ret_fn, "name") <- as.character(funcArgName) attr(ret_fn, "params") <- allParams attr(ret_fn, "fn") <- original_fn ret_fn } #' @export #' @rdname wrap wrapp <- wrap_fn_with_param_arg #' @export #' @rdname wrap wrap <- function(funcVal, ..., funcArgName = deparse(substitute(funcVal))) { if (missing(funcArgName)) { fnName <- attr(funcVal, "name") if (!is.null(fnName)) { funcArgName <- fnName } else if (is.character(funcVal)) { funcArgName <- str_c("ggally_", funcVal) } } params <- list(...) if (length(params) > 0) { if (is.null(names(params))) { stop("all parameters must be named arguments") } if (any(nchar(names(params)) == 0)) { stop("all parameters must be named arguments") } } wrap_fn_with_param_arg(funcVal, params = params, funcArgName = funcArgName) } #' @export #' @rdname wrap wrap_fn_with_params <- wrap #' @export as.character.ggmatrix_fn_with_params <- function(x, ...) { params <- attr(x, "params") fnName <- attr(x, "name") if (length(params) == 0) { txt <- str_c("wrap: '", fnName, "'") } else { txt <- str_c("wrap: '", attr(x, "name"), "'; params: ", mapping_as_string(params)) } txt } make_ggmatrix_plot_obj <- function(fn, mapping = ggplot2::aes(), dataPos = 1, gg = NULL) { # nonCallVals <- which(lapply(mapping, mode) == "call") # if (length(nonCallVals) > 0) { # nonCallNames <- names(mapping)[nonCallVals] # browser() # stop( # paste( # "variables: ", # paste(shQuote(nonCallNames, type = "cmd"), sep = ", "), # " have non standard format: ", # paste(shQuote(unlist(mapping[nonCallVals]), type = "cmd"), collapse = ", "), # ". Please rename the columns or make a new column.", # sep = "" # ) # ) # } ret <- list( fn = fn, mapping = mapping, dataPos = dataPos, gg = gg ) class(ret) <- "ggmatrix_plot_obj" ret } blank_plot_string <- function() { "PM; (blank)" } mapping_as_string <- function(mapping) { str_c("c(", str_c(names(mapping), as.character(mapping), sep = " = ", collapse = ", "), ")") } #' @export as.character.ggmatrix_plot_obj <- function(x, ...) { hasGg <- (!is.null(x$gg)) mappingTxt <- mapping_as_string(x$mapping) fnTxt <- ifelse(inherits(x$fn, "ggmatrix_fn_with_params"), as.character(x$fn), "custom_function") if (inherits(x$fn, "ggmatrix_fn_with_params")) { if (attr(x$fn, "name") %in% c("ggally_blank", "ggally_blankDiag")) { return(blank_plot_string()) } } str_c( "PM", "; aes: ", mappingTxt, "; fn: {", fnTxt, "}", # "; dataPos: ", x$dataPos, "; gg: ", as.character(hasGg) ) } #' \code{\link{ggmatrix}} structure #' #' View the condensed version of the \code{\link{ggmatrix}} object. The attribute "class" is ALWAYS altered to "_class" to avoid recursion. #' #' @param object \code{\link{ggmatrix}} object to be viewed #' @param ... passed on to the default \code{str} method #' @param raw boolean to determine if the plots should be converted to text or kept as original objects #' @method str ggmatrix #' @importFrom utils str #' @export str.ggmatrix <- function(object, ..., raw = FALSE) { objName <- deparse(substitute(object)) obj <- object if (identical(raw, FALSE)) { cat(str_c( "\nCustom str.ggmatrix output: \nTo view original object use ", "'str(", objName, ", raw = TRUE)'\n\n" )) obj$plots <- lapply(obj$plots, function(plotObj) { if (ggplot2::is.ggplot(plotObj)) { str_c("PM; ggplot2 object; mapping: ", mapping_as_string(plotObj$mapping)) } else if (inherits(plotObj, "ggmatrix_plot_obj")) { as.character(plotObj) } else { plotObj } }) } attr(obj, "_class") <- attr(obj, "class") class(obj) <- NULL str(obj, ...) } GGally/R/vig_ggally.R0000644000176200001440000000247514527265752014130 0ustar liggesusers#' View GGally vignettes #' #' This function will open the directly to the vignette requested. If no \code{name} is provided, the index of all \pkg{GGally} vignettes will be opened. #' #' This method allows for vignettes to be hosted remotely, reducing \pkg{GGally}'s package size, and installation time. #' #' @param name Vignette name to open. If no name is provided, the vignette index will be opened #' @export #' @examples #' \donttest{ #' # View `ggnostic` vignette #' vig_ggally("ggnostic") #' #' # View all vignettes by GGally #' vig_ggally() #' } vig_ggally <- function(name) { vig_url <- if (missing(name) || is.null(name)) { "https://ggobi.github.io/ggally/articles/" } else { tryCatch( { paste0( "https://ggobi.github.io/ggally/articles/", match.arg(name, vignettes_for_ggally), ".html" ) }, error = function(e) { message("Unknown vignette: ", name, ". Opening Vignette index page") "https://ggobi.github.io/ggally/articles/" } ) } browseURL(vig_url) } vignettes_for_ggally <- c( "ggally_plots", "ggally_stats", "ggbivariate", "ggcoef_model", "ggcoef", "ggduo", "ggmatrix", "ggnetworkmap", "ggnostic", "ggpairs", "ggscatmat", "ggsurv", "ggtable", "glyph" ) GGally/R/data-happy.R0000644000176200001440000000334014526737223014020 0ustar liggesusers#' Data related to happiness from the General Social Survey, 1972-2006. #' #' This data extract is taken from Hadley Wickham's \code{productplots} package. #' The original description follows, with minor edits. #' #' The data is a small sample of variables related to #' happiness from the General Social Survey (GSS). The GSS #' is a yearly cross-sectional survey of Americans, run from #' 1972. We combine data for 25 years to yield 51,020 #' observations, and of the over 5,000 variables, we select #' nine related to happiness: #' #' @details \itemize{ #' \item age. age in years: 18--89. #' \item degree. highest education: lt high school, high school, junior college, bachelor, graduate. #' \item finrela. relative financial status: far above, above average, average, below average, far below. #' \item happy. happiness: very happy, pretty happy, not too happy. #' \item health. health: excellent, good, fair, poor. #' \item marital. marital status: married, never married, divorced, widowed, separated. #' \item sex. sex: female, male. #' \item wtsall. probability weight. 0.43--6.43. #' } #' #' @docType data #' @keywords datasets #' @name happy #' @usage data(happy) #' @format A data frame with 51020 rows and 10 variables #' @references #' Smith, Tom W., Peter V. Marsden, Michael Hout, Jibum Kim. \emph{General Social Surveys, 1972-2006}. #' \[machine-readable data file\]. Principal Investigator, Tom W. Smith; Co-Principal Investigators, #' Peter V. Marsden and Michael Hout, NORC ed. #' Chicago: National Opinion Research Center, producer, 2005; #' Storrs, CT: The Roper Center for Public Opinion Research, University of Connecticut, distributor. #' 1 data file (57,061 logical records) and 1 codebook (3,422 pp). NULL GGally/R/data-flea.R0000644000176200001440000000165714526737221013615 0ustar liggesusers#' Historical data used for classification examples. #' #' This data contains physical measurements on three species of flea beetles. #' #' @details \itemize{ #' \item species Ch. concinna, Ch. heptapotamica, Ch. heikertingeri #' \item tars1 width of the first joint of the first tarsus in microns #' \item tars2 width of the second joint of the first tarsus in microns #' \item head the maximal width of the head between the external edges of the eyes in 0.01 mm #' \item aede1 the maximal width of the aedeagus in the fore-part in microns #' \item aede2 the front angle of the aedeagus (1 unit = 7.5 degrees) #' \item aede3 the aedeagus width from the side in microns #' } #' #' @docType data #' @keywords datasets #' @name flea #' @usage data(flea) #' @format A data frame with 74 rows and 7 variables #' @references #' Lubischew, A. A. (1962), On the Use of Discriminant Functions in #' Taxonomy, Biometrics 18:455-477. NULL GGally/R/gg-plots.R0000644000176200001440000015414014561213570013522 0ustar liggesusers# add global variable if (getRversion() >= "2.15.1") { utils::globalVariables(unique(c( "labelp", # cor plot c("x"), # facetdensitystrip plot c("x"), # density diagonal plot c("x", "y", "lab"), # internal axis plot c("x", "y", "result", "freq"), # fluctuation plot c("weight") # ggally_summarise_by ))) } # retrieve the evaulated data column given the aes (which could possibly do operations) #' Evaluate data column #' @param data data set to evaluate the data with #' @param aes_col Single value from an \code{ggplot2::\link[ggplot2]{aes}(...)} object #' @return Aes mapping with the x and y values switched #' @export #' @examples #' mapping <- ggplot2::aes(Petal.Length) #' eval_data_col(iris, mapping$x) eval_data_col <- function(data, aes_col) { rlang::eval_tidy(aes_col, data) } #' Aes name #' @param aes_col Single value from \code{ggplot2::\link[ggplot2]{aes}(...)} #' @return character string #' @export #' @examples #' mapping <- ggplot2::aes(Petal.Length) #' mapping_string(mapping$x) mapping_string <- function(aes_col) { gsub("^~", "", deparse(aes_col, 500L)) } # is categories on the left? #' Check if plot is horizontal #' #' @param data data used in ggplot2 plot #' @param mapping ggplot2 \code{aes()} mapping #' @param val key to retrieve from \code{mapping} #' @return Boolean determining if the data is a character-like data #' @export #' @rdname is_horizontal #' @examples #' is_horizontal(iris, ggplot2::aes(Sepal.Length, Species)) # TRUE #' is_horizontal(iris, ggplot2::aes(Sepal.Length, Species), "x") # FALSE #' is_horizontal(iris, ggplot2::aes(Sepal.Length, Sepal.Width)) # FALSE is_horizontal <- function(data, mapping, val = "y") { yData <- eval_data_col(data, mapping[[val]]) is.factor(yData) || is.character(yData) || is.logical(yData) } #' @export #' @rdname is_horizontal is_character_column <- is_horizontal #' Swap x and y mapping #' @param mapping output of \code{ggplot2::\link[ggplot2]{aes}(...)} #' @return Aes mapping with the x and y values switched #' @export #' @examples #' mapping <- ggplot2::aes(Petal.Length, Sepal.Width) #' mapping #' mapping_swap_x_y(mapping) mapping_swap_x_y <- function(mapping) { tmp <- mapping$x mapping$x <- mapping$y mapping$y <- tmp mapping } #' Remove colour mapping unless found in select mapping keys #' @param mapping output of \code{ggplot2::\link[ggplot2]{aes}(...)} #' @param to set of mapping keys to check #' @return Aes mapping with colour mapping kept only if found in selected mapping keys. #' @export #' @examples #' mapping <- aes(x = sex, y = age, colour = sex) # remove_color_unless_equal(mapping, to = c("x", "y")) # remove_color_unless_equal(mapping, to = c("y")) #' #' mapping <- aes(x = sex, y = age, colour = region) #' remove_color_unless_equal(mapping) remove_color_unless_equal <- function(mapping, to = c("x", "y")) { if (!is.null(mapping$colour)) { color_str <- mapping_string(mapping$colour) for (to_val in to) { to_str <- mapping_string(mapping[[to_val]]) if (color_str == to_str) { # found! return return(mapping) } } # not found. Remove color value mapping <- mapping[names(mapping) != "colour"] } mapping } #' Scatter plot #' #' Make a scatter plot with a given data set. #' #' @param data data set using #' @param mapping aesthetics being used #' @param ... other arguments are sent to geom_point #' @author Barret Schloerke #' @export #' @keywords hplot #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' data(mtcars) #' p_(ggally_points(mtcars, mapping = ggplot2::aes(disp, hp))) #' p_(ggally_points(mtcars, mapping = ggplot2::aes(disp, hp))) #' p_(ggally_points( #' mtcars, #' mapping = ggplot2::aes( #' x = disp, #' y = hp, #' color = as.factor(cyl), #' size = gear #' ) #' )) ggally_points <- function(data, mapping, ...) { p <- ggplot(data = data, mapping = mapping) + geom_point(...) p } #' Scatter plot with a smoothed line #' #' Add a smoothed condition mean with a given scatter plot. #' #' Y limits are reduced to match original Y range with the goal of keeping the Y axis the same across plots. #' #' @param data data set using #' @param mapping aesthetics being used #' @param formula,... other arguments to add to geom_smooth #' @param method,se parameters supplied to \code{\link[ggplot2]{geom_smooth}} #' @param shrink boolean to determine if y range is reduced to range of points or points and error ribbon #' @author Barret Schloerke #' @export #' @keywords hplot #' @rdname ggally_smooth #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' data(tips) #' p_(ggally_smooth(tips, mapping = ggplot2::aes(x = total_bill, y = tip))) #' p_(ggally_smooth(tips, mapping = ggplot2::aes(total_bill, tip, color = sex))) ggally_smooth <- function(data, mapping, ..., method = "lm", formula = y ~ x, se = TRUE, shrink = TRUE) { p <- ggplot(data = data, mapping) p <- p + geom_point(...) if (!is.null(mapping$color) || !is.null(mapping$colour)) { p <- p + geom_smooth(method = method, se = se, formula = formula) } else { p <- p + geom_smooth(method = method, se = se, formula = formula, colour = I("black")) } if (isTRUE(shrink)) { p <- p + coord_cartesian( ylim = range(eval_data_col(data, mapping$y), na.rm = TRUE) ) } p } #' @export #' @rdname ggally_smooth ggally_smooth_loess <- function(data, mapping, ...) { ggally_smooth(data = data, mapping = mapping, ..., method = "loess") } #' @export #' @rdname ggally_smooth ggally_smooth_lm <- function(data, mapping, ...) { ggally_smooth(data = data, mapping = mapping, ..., method = "lm") } #' Bivariate density plot #' #' Make a 2D density plot from a given data. #' #' The aesthetic "fill" determines whether or not \code{stat_density2d} (filled) or \code{geom_density2d} (lines) is used. #' #' @param data data set using #' @param mapping aesthetics being used #' @param ... parameters sent to either stat_density2d or geom_density2d #' @author Barret Schloerke #' @export #' @keywords hplot #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' data(tips) #' p_(ggally_density(tips, mapping = ggplot2::aes(x = total_bill, y = tip))) #' p_(ggally_density( #' tips, #' mapping = ggplot2::aes(total_bill, tip, fill = after_stat(level)) #' )) #' p_(ggally_density( #' tips, #' mapping = ggplot2::aes(total_bill, tip, fill = after_stat(level)) #' ) + ggplot2::scale_fill_gradient(breaks = c(0.05, 0.1, 0.15, 0.2))) ggally_density <- function(data, mapping, ...) { rangeX <- range(eval_data_col(data, mapping$x), na.rm = TRUE) rangeY <- range(eval_data_col(data, mapping$y), na.rm = TRUE) p <- ggplot(data = data) + geom_point( data = data.frame(rangeX = rangeX, rangeY = rangeY), mapping = aes(x = !!as.name("rangeX"), y = !!as.name("rangeY")), alpha = 0 ) if (!is.null(mapping$fill)) { p <- p + stat_density2d(mapping = mapping, geom = "polygon", ...) } else { p <- p + geom_density2d(mapping = mapping, ...) } p } #' Correlation value plot #' #' Estimate correlation from the given data. If a color variable is supplied, the correlation will also be calculated per group. #' #' @param data data set using #' @param mapping aesthetics being used #' @param ... other arguments being supplied to \code{\link[ggplot2]{geom_text}()} for the title and groups #' @param stars logical value which determines if the significance stars should be displayed. Given the \code{\link[stats]{cor.test}} p-values, display \describe{ #' \item{\code{"***"}}{if the p-value is \verb{< 0.001}} #' \item{\code{"**"}}{if the p-value is \verb{< 0.01}} #' \item{\code{"*"}}{if the p-value is \verb{< 0.05}} #' \item{\code{"."}}{if the p-value is \verb{< 0.10}} #' \item{\code{""}}{otherwise} #' } #' @param method \code{method} supplied to cor function #' @param use \code{use} supplied to \code{\link[stats]{cor}} function #' @param display_grid if \code{TRUE}, display aligned panel grid lines. If \code{FALSE} (default), display a thin panel border. #' @param digits number of digits to be displayed after the decimal point. See \code{\link[base]{formatC}} for how numbers are calculated. #' @param title_args arguments being supplied to the title's \code{\link[ggplot2]{geom_text}()} #' @param group_args arguments being supplied to the split-by-color group's \code{\link[ggplot2]{geom_text}()} #' @param justify_labels \code{justify} argument supplied when \code{\link[base]{format}}ting the labels #' @param align_percent relative align position of the text. When \code{justify_labels = 0.5}, this should not be needed to be set. #' @param alignPercent,displayGrid deprecated. Please use their snake-case counterparts. #' @param title title text to be displayed #' @author Barret Schloerke #' @importFrom stats complete.cases cor #' @seealso \code{\link{ggally_statistic}}, \code{\link{ggally_cor_v1_5}} #' @export #' @keywords hplot #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' data(tips) #' p_(ggally_cor(tips, mapping = ggplot2::aes(total_bill, tip))) #' # display with grid #' p_(ggally_cor( #' tips, #' mapping = ggplot2::aes(total_bill, tip), #' display_grid = TRUE #' )) #' # change text attributes #' p_(ggally_cor( #' tips, #' mapping = ggplot2::aes(x = total_bill, y = tip), #' size = 15, #' colour = I("red"), #' title = "Correlation" #' )) #' # split by a variable #' p_(ggally_cor( #' tips, #' mapping = ggplot2::aes(total_bill, tip, color = sex), #' size = 5 #' )) ggally_cor <- function( data, mapping, ..., stars = TRUE, method = "pearson", use = "complete.obs", display_grid = FALSE, digits = 3, title_args = list(...), group_args = list(...), justify_labels = "right", align_percent = 0.5, title = "Corr", alignPercent = warning("deprecated. Use `align_percent`"), displayGrid = warning("deprecated. Use `display_grid`")) { if (!missing(alignPercent)) { warning("`alignPercent` is deprecated. Please use `align_percent` if alignment still needs to be adjusted") align_percent <- alignPercent } if (!missing(displayGrid)) { warning("`displayGrid` is deprecated. Please use `display_grid`") display_grid <- displayGrid } na.rm <- if (missing(use)) { # display warnings NA } else { (use %in% c("complete.obs", "pairwise.complete.obs", "na.or.complete")) } ggally_statistic( data = data, mapping = mapping, na.rm = na.rm, align_percent = align_percent, display_grid = display_grid, title_args = title_args, group_args = group_args, justify_labels = justify_labels, justify_text = "left", sep = if ("colour" %in% names(mapping)) ": " else ":\n", title = title, text_fn = function(x, y) { if (is_date(x)) { x <- as.numeric(x) } if (is_date(y)) { y <- as.numeric(y) } corObj <- stats::cor.test(x, y, method = method, use = use) # make sure all values have X-many decimal places cor_est <- as.numeric(corObj$estimate) cor_txt <- formatC(cor_est, digits = digits, format = "f") # if stars should be added if (isTRUE(stars)) { cor_txt <- str_c( cor_txt, signif_stars(corObj$p.value) ) } cor_txt } ) } #' Generalized text display #' #' @param data data set using #' @param mapping aesthetics being used #' @param title title text to be displayed #' @param text_fn function that takes in \code{x} and \code{y} and returns a text string #' @param na.rm logical value which determines if \code{NA} values are removed. If \code{TRUE}, no warning message will be displayed. #' @param display_grid if \code{TRUE}, display aligned panel grid lines. If \code{FALSE} (default), display a thin panel border. #' @param justify_labels \code{justify} argument supplied when \code{\link[base]{format}}ting the labels #' @param justify_text \code{justify} argument supplied when \code{\link[base]{format}}ting the returned \code{text_fn(x, y)} values #' @param sep separation value to be placed between the labels and text #' @param family font family used when displaying all text. This value will be set in \code{title_args} or \code{group_args} if no \code{family} value exists. By using \code{"mono"}, groups will align with each other. #' @param title_args arguments being supplied to the title's \code{\link[ggplot2]{geom_text}()} #' @param group_args arguments being supplied to the split-by-color group's \code{\link[ggplot2]{geom_text}()} #' @param align_percent relative align position of the text. When \code{title_hjust = 0.5} and \code{group_hjust = 0.5}, this should not be needed to be set. #' @param title_hjust,group_hjust \code{hjust} sent to \code{\link[ggplot2]{geom_text}()} for the title and group values respectively. Any \code{hjust} value supplied in \code{title_args} or \code{group_args} will take precedence. #' @seealso \code{\link{ggally_cor}} #' @export ggally_statistic <- function( data, mapping, text_fn, title, na.rm = NA, display_grid = FALSE, justify_labels = "right", justify_text = "left", sep = ": ", family = "mono", title_args = list(), group_args = list(), align_percent = 0.5, title_hjust = 0.5, group_hjust = 0.5) { set_if_not_there <- function(obj, key, value) { obj <- as.list(obj) # if (! "family" %in% rlang::names2(obj)) { # obj$family <- family # } obj } # title_args <- set_if_not_there(title_args, "family", family) # group_args <- set_if_not_there(group_args, "family", family) title_args <- set_if_not_there(title_args, "hjust", title_hjust) group_args <- set_if_not_there(group_args, "hjust", group_hjust) xData <- eval_data_col(data, mapping$x) yData <- eval_data_col(data, mapping$y) colorData <- eval_data_col(data, mapping$colour) if (is.numeric(colorData)) { stop("`mapping` color column must be categorical, not numeric") } display_na_rm <- is.na(na.rm) if (display_na_rm) { na.rm <- TRUE } if (isTRUE(na.rm)) { if (!is.null(colorData) && (length(colorData) == length(xData))) { rows <- complete.cases(xData, yData, colorData) } else { rows <- complete.cases(xData, yData) } if (any(!rows)) { if (!is.null(colorData) && (length(colorData) == length(xData))) { colorData <- colorData[rows] } xData <- xData[rows] yData <- yData[rows] if (isTRUE(display_na_rm)) { total <- sum(!rows) if (total > 1) { warning("Removed ", total, " rows containing missing values") } else if (total == 1) { warning("Removing 1 row that contained a missing value") } } } } xVal <- xData yVal <- yData # if the mapping has to deal with the data, remove it ### IDK what this does. inherited from old code. for (mappingName in names(mapping)) { itemData <- eval_data_col(data, mapping[[mappingName]]) if (!inherits(itemData, "AsIs")) { mapping[[mappingName]] <- NULL } } ### END IDK # calculate variable ranges so the gridlines line up xValNum <- as.numeric(xVal) yValNum <- as.numeric(yVal) xmin <- min(xValNum, na.rm = TRUE) xmax <- max(xValNum, na.rm = TRUE) xrange <- c(xmin - 0.01 * (xmax - xmin), xmax + 0.01 * (xmax - xmin)) ymin <- min(yValNum, na.rm = TRUE) ymax <- max(yValNum, na.rm = TRUE) yrange <- c(ymin - 0.01 * (ymax - ymin), ymax + 0.01 * (ymax - ymin)) # if there is a color grouping... if (!is.null(colorData) && !inherits(colorData, "AsIs")) { cord <- ddply( data.frame(x = xData, y = yData, color = colorData), "color", function(dt) { text_fn(dt$x, dt$y) } ) colnames(cord)[2] <- "text" # put in correct order lev <- levels(as.factor(colorData)) ord <- rep(-1, nrow(cord)) for (i in 1:nrow(cord)) { for (j in seq_along(lev)) { if (identical(as.character(cord$color[i]), as.character(lev[j]))) { ord[i] <- j } } } cord <- cord[order(ord[ord >= 0]), ] # make labels align together cord$label <- str_c( format(cord$color, justify = justify_labels), sep, format(cord$text, justify = justify_text) ) # title ggally_text_args <- append( list( label = str_c(title, sep, text_fn(xVal, yVal)), mapping = mapping, xP = 0.5, yP = 0.9, xrange = xrange, yrange = yrange ), title_args ) p <- do.call(ggally_text, ggally_text_args) xPos <- rep(align_percent, nrow(cord)) * diff(xrange) + min(xrange, na.rm = TRUE) yPos <- seq(from = 0.9, to = 0.2, length.out = nrow(cord) + 1) yPos <- yPos * diff(yrange) + min(yrange, na.rm = TRUE) yPos <- yPos[-1] cordf <- data.frame(xPos = xPos, yPos = yPos, labelp = cord$label) cordf$labelp <- factor(cordf$labelp, levels = cordf$labelp) # group text values geom_text_args <- append( list( data = cordf, aes( x = !!as.name("xPos"), y = !!as.name("yPos"), label = !!as.name("labelp"), color = !!as.name("labelp") ) ), group_args ) p <- p + do.call(geom_text, geom_text_args) } else { ggally_text_args <- append( list( label = paste0(title, sep, text_fn(xVal, yVal), collapse = ""), mapping, xP = 0.5, yP = 0.5, xrange = xrange, yrange = yrange ), title_args ) p <- do.call(ggally_text, ggally_text_args) } if (!isTRUE(display_grid)) { p <- p + theme( panel.grid.major = element_blank(), panel.grid.minor = element_blank(), panel.border = element_rect( linetype = "solid", color = theme_get()$panel.background$fill, fill = "transparent" ) ) } p + theme(legend.position = "none") } #' Box plot #' #' Make a box plot with a given data set. \code{ggally_box_no_facet} will be a single panel plot, while \code{ggally_box} will be a faceted plot #' #' @param data data set using #' @param mapping aesthetics being used #' @param ... other arguments being supplied to geom_boxplot #' @author Barret Schloerke #' @keywords hplot #' @export #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' data(tips) #' p_(ggally_box(tips, mapping = ggplot2::aes(x = total_bill, y = sex))) #' p_(ggally_box( #' tips, #' mapping = ggplot2::aes(sex, total_bill, color = sex), #' outlier.colour = "red", #' outlier.shape = 13, #' outlier.size = 8 #' )) ggally_box <- function(data, mapping, ...) { mapping <- mapping_color_to_fill(mapping) ggally_dot_and_box(data, mapping, ..., boxPlot = TRUE) } #' @export #' @rdname ggally_box ggally_box_no_facet <- function(data, mapping, ...) { mapping <- mapping_color_to_fill(mapping) ggally_dot_and_box_no_facet(data, mapping, ..., boxPlot = TRUE) } #' Grouped dot plot #' #' Add jittering with the box plot. \code{ggally_dot_no_facet} will be a single panel plot, while \code{ggally_dot} will be a faceted plot #' #' @param data data set using #' @param mapping aesthetics being used #' @param ... other arguments being supplied to geom_jitter #' @author Barret Schloerke #' @keywords hplot #' @export #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' data(tips) #' p_(ggally_dot(tips, mapping = ggplot2::aes(x = total_bill, y = sex))) #' p_(ggally_dot( #' tips, #' mapping = ggplot2::aes(sex, total_bill, color = sex) #' )) #' p_(ggally_dot( #' tips, #' mapping = ggplot2::aes(sex, total_bill, color = sex, shape = sex) #' ) + ggplot2::scale_shape(solid = FALSE)) ggally_dot <- function(data, mapping, ...) { ggally_dot_and_box(data, mapping, ..., boxPlot = FALSE) } #' @export #' @rdname ggally_dot ggally_dot_no_facet <- function(data, mapping, ...) { ggally_dot_and_box_no_facet(data, mapping, ..., boxPlot = FALSE) } #' Box and dot plot #' #' Place box plots or dot plots on the graph #' #' @param data data set using #' @param mapping aesthetics being used #' @param ... parameters passed to either geom_jitter or geom_boxplot #' @param boxPlot boolean to decide to plot either box plots (TRUE) or dot plots (FALSE) #' @author Barret Schloerke #' @keywords internal #' @export #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' data(tips) #' p_(ggally_dot_and_box( #' tips, #' mapping = ggplot2::aes(x = total_bill, y = sex, color = sex), #' boxPlot = TRUE #' )) #' p_(ggally_dot_and_box( #' tips, #' mapping = ggplot2::aes(x = total_bill, y = sex, color = sex), #' boxPlot = FALSE #' )) ggally_dot_and_box <- function(data, mapping, ..., boxPlot = TRUE) { horizontal <- is_horizontal(data, mapping) if (horizontal) { mapping <- mapping_swap_x_y(mapping) } xVal <- mapping_string(mapping$x) p <- ggplot(data = data) if (boxPlot) { p <- p + geom_boxplot(mapping, ...) } else { p <- p + geom_jitter(mapping, ...) } if (!horizontal) { p <- p + facet_grid(paste(". ~ ", xVal, sep = ""), scales = "free_x") + theme(panel.spacing = unit(0.1, "lines")) } else { p <- p + coord_flip() + facet_grid(paste(xVal, " ~ .", sep = ""), scales = "free_y") + theme(panel.spacing = unit(0.1, "lines")) } p } ggally_dot_and_box_no_facet <- function(data, mapping, ..., boxPlot = TRUE) { horizontal <- is_horizontal(data, mapping) if (horizontal) { mapping <- mapping_swap_x_y(mapping) } p <- ggplot(data = data) if (boxPlot) { p <- p + geom_boxplot(mapping, ...) } else { p <- p + geom_jitter(mapping, ...) } if (horizontal) { p <- p + scale_x_discrete( limits = rev(levels(as.factor(eval_data_col(data, mapping$x)))) ) + coord_flip() } p } #' Faceted histogram #' #' Display subsetted histograms of the data in different panels. #' #' @param data data set using #' @param mapping aesthetics being used #' @param ... parameters sent to stat_bin() #' @author Barret Schloerke #' @keywords hplot #' @export #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' data(tips) #' p_(ggally_facethist(tips, mapping = ggplot2::aes(x = tip, y = sex))) #' p_(ggally_facethist(tips, mapping = ggplot2::aes(x = tip, y = sex), binwidth = 0.1)) ggally_facethist <- function(data, mapping, ...) { mapping <- mapping_color_to_fill(mapping) horizontal <- is_horizontal(data, mapping) if (!horizontal) { mapping <- mapping_swap_x_y(mapping) } xVal <- mapping_string(mapping$x) yVal <- mapping_string(mapping$y) mapping$y <- NULL p <- ggplot(data = data, mapping) p <- p + stat_bin(...) if (horizontal) { p <- p + facet_grid(paste(yVal, " ~ .", sep = "")) + theme(panel.spacing = unit(0.1, "lines")) } else { p <- p + facet_grid(paste(". ~", yVal, sep = "")) + theme(panel.spacing = unit(0.1, "lines")) + coord_flip() } p <- p + labs(x = xVal, y = yVal) p } #' Faceted density plot #' #' Make density plots by displaying subsets of the data in different panels. #' #' @param data data set using #' @param mapping aesthetics being used #' @param ... other arguments being sent to stat_density #' @author Barret Schloerke #' @keywords hplot #' @export #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' data(tips) #' p_(ggally_facetdensity(tips, mapping = ggplot2::aes(x = total_bill, y = sex))) #' p_(ggally_facetdensity( #' tips, #' mapping = ggplot2::aes(sex, total_bill, color = sex) #' )) ggally_facetdensity <- function(data, mapping, ...) { ggally_facetdensitystrip(data, mapping, ..., den_strip = FALSE) } #' Tile plot with facets #' #' Displays a Tile Plot as densely as possible. #' #' @param data data set using #' @param mapping aesthetics being used #' @param ... other arguments being sent to stat_bin #' @author Barret Schloerke #' @keywords hplot #' @export #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' data(tips) #' p_(ggally_denstrip(tips, mapping = ggplot2::aes(x = total_bill, y = sex))) #' p_(ggally_denstrip( #' tips, #' mapping = ggplot2::aes(sex, tip), binwidth = 0.2 #' ) + ggplot2::scale_fill_gradient(low = "grey80", high = "black")) ggally_denstrip <- function(data, mapping, ...) { mapping <- mapping_color_to_fill(mapping) ggally_facetdensitystrip(data, mapping, ..., den_strip = TRUE) } #' Density or tiles plot with facets #' #' Make tile plot or density plot as compact as possible. #' #' @param data data set using #' @param mapping aesthetics being used #' @param ... other arguments being sent to either geom_histogram or stat_density #' @param den_strip boolean to decide whether or not to plot a density strip(TRUE) or a facet density(FALSE) plot. #' @author Barret Schloerke #' @keywords hplot #' @export #' @examples #' example(ggally_facetdensity) #' example(ggally_denstrip) ggally_facetdensitystrip <- function(data, mapping, ..., den_strip = FALSE) { horizontal <- is_horizontal(data, mapping) if (!horizontal) { mapping <- mapping_swap_x_y(mapping) } xVal <- mapping_string(mapping$x) yVal <- mapping_string(mapping$y) mappingY <- mapping$y # nolint mapping$y <- NULL # will be faceted p <- ggplot(data = data, mapping) + labs(x = xVal, y = yVal) if (identical(den_strip, TRUE)) { p <- p + geom_histogram( mapping = aes(fill = after_stat(!!as.name("density"))), # nolint position = "fill", ... ) + scale_y_continuous( breaks = c(0.5), labels = "1" ) } else { p <- p + stat_density( aes( y = after_stat(!!as.name("scaled")) * diff(range(x, na.rm = TRUE)) + min(x, na.rm = TRUE) # nolint ), position = "identity", geom = "line", ... ) } if (horizontal) { p <- p + facet_grid(paste(yVal, " ~ .", sep = "")) if (identical(den_strip, TRUE)) { p <- p + theme(axis.text.y = element_blank()) } } else { p <- p + coord_flip() p <- p + facet_grid(paste(". ~ ", yVal, sep = "")) if (identical(den_strip, TRUE)) { p <- p + theme(axis.text.x = element_blank()) } } p } #' Univariate density plot #' #' Displays a density plot for the diagonal of a \code{\link{ggpairs}} plot matrix. #' #' @param data data set using #' @param mapping aesthetics being used. #' @param ... other arguments sent to stat_density #' @param rescale boolean to decide whether or not to rescale the count output #' @author Barret Schloerke #' @keywords hplot #' @export #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' data(tips) #' p_(ggally_densityDiag(tips, mapping = ggplot2::aes(x = total_bill))) #' p_(ggally_densityDiag(tips, mapping = ggplot2::aes(x = total_bill, color = day))) ggally_densityDiag <- function(data, mapping, ..., rescale = FALSE) { mapping <- mapping_color_to_fill(mapping) p <- ggplot(data, mapping) + scale_y_continuous() if (identical(rescale, TRUE)) { p <- p + stat_density( aes( y = after_stat(!!as.name("scaled")) * diff(range(x, na.rm = TRUE)) + min(x, na.rm = TRUE) # nolint ), position = "identity", geom = "line", ... ) } else { p <- p + geom_density(...) } p } #' Bar plot #' #' Displays a bar plot for the diagonal of a \code{\link{ggpairs}} plot matrix. #' #' @param data data set using #' @param mapping aesthetics being used #' @param ... other arguments are sent to geom_bar #' @param rescale boolean to decide whether or not to rescale the count output. Only applies to numeric data #' @author Barret Schloerke #' @keywords hplot #' @export #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' data(tips) #' p_(ggally_barDiag(tips, mapping = ggplot2::aes(x = day))) #' p_(ggally_barDiag(tips, mapping = ggplot2::aes(x = tip), binwidth = 0.25)) ggally_barDiag <- function(data, mapping, ..., rescale = FALSE) { mapping <- mapping_color_to_fill(mapping) mapping$y <- NULL x_data <- eval_data_col(data, mapping$x) numer <- ("continuous" == plotting_data_type(x_data)) p <- ggplot(data = data, mapping) if (is_date(x_data)) { p <- p + geom_histogram(...) # TODO make y axis lines match date positions # buildInfo <- ggplot_build(p + geom_bar(...)) # histBarPerc <- buildInfo$data[[1]]$ncount } else if (numer) { if (identical(rescale, TRUE)) { p <- p + geom_histogram( aes( y = after_stat(!!as.name("density")) / max(after_stat(!!as.name("density"))) * diff(range(x, na.rm = TRUE)) + min(x, na.rm = TRUE) # nolint ), ... ) + coord_cartesian(ylim = range(eval_data_col(data, mapping$x), na.rm = TRUE)) } else { p <- p + geom_histogram(...) } } else { p <- p + geom_bar(...) } p } #' Text plot #' #' Plot text for a plot. #' #' @param label text that you want to appear #' @param mapping aesthetics that don't relate to position (such as color) #' @param xP horizontal position percentage #' @param yP vertical position percentage #' @param xrange range of the data around it. Only nice to have if plotting in a matrix #' @param yrange range of the data around it. Only nice to have if plotting in a matrix #' @param ... other arguments for geom_text #' @author Barret Schloerke #' @keywords hplot #' @export #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' p_(ggally_text("Example 1")) #' p_(ggally_text("Example\nTwo", mapping = ggplot2::aes(size = 15), color = I("red"))) ggally_text <- function( label, mapping = ggplot2::aes(color = I("black")), xP = 0.5, yP = 0.5, xrange = c(0, 1), yrange = c(0, 1), ...) { theme <- theme_get() p <- ggplot() + xlim(xrange) + ylim(yrange) + theme( panel.grid.minor = element_blank(), panel.grid.major = element_line( colour = ifnull(theme$panel.background$fill, NA) ), panel.background = element_rect( fill = ifnull(theme$panel.grid.major$colour, NA) ) ) + labs(x = NULL, y = NULL) new_mapping <- aes( x = !!xP * diff(xrange) + min(xrange, na.rm = TRUE), y = !!yP * diff(yrange) + min(yrange, na.rm = TRUE) ) if (is.null(mapping)) { mapping <- new_mapping } else { mapping <- add_and_overwrite_aes(mapping, new_mapping) } # dont mess with color if it's already there if (!is.null(mapping$colour)) { p <- p + geom_text(label = label, mapping = mapping, ...) + guides(colour = "none") } else if ("colour" %in% names(aes(...))) { p <- p + geom_text(label = label, mapping = mapping, ...) } else { bg <- ifnull(theme$panel.background$fill, "grey92") fg <- ifnull(theme$axis.text$colour, "gray30") colour <- scales::colour_ramp(c(bg, fg))(0.75) p <- p + geom_text(label = label, mapping = mapping, colour = colour, ...) } p <- p + theme(legend.position = "none") p } #' Get x axis labels #' #' Retrieves x axis labels from the plot object directly. #' #' @importFrom gtable gtable_filter #' @param p plot object #' @param xRange range of x values #' @keywords internal get_x_axis_labels <- function(p, xRange) { pGrob <- ggplotGrob(p) axisTable <- gtable_filter(pGrob, "axis-b")$grobs[[1]]$children$axis # have to do a function as filter doesn't work get_raw_grob_by_name <- function(g, name) { for (item in g$grobs) { if (str_detect(item$name, name)) { return(item$children[[1]]) } } NULL } xAxisGrob <- get_raw_grob_by_name(axisTable, "title") axisBreaks <- as.numeric(xAxisGrob$label) axisLabs <- rbind( expand.grid(xPos = axisBreaks[1], yPos = axisBreaks), expand.grid(xPos = axisBreaks, yPos = axisBreaks[1]) )[-1, ] axisLabs <- as.data.frame(axisLabs) axisLabs$lab <- as.character(apply(axisLabs, 1, max)) axisLabs$hjust <- 0.5 axisLabs$vjust <- 0.5 minPos <- xRange[1] maxPos <- xRange[2] for (i in seq_len(nrow(axisLabs))) { xPos <- axisLabs[i, "xPos"] yPos <- axisLabs[i, "yPos"] if (yPos < minPos) { axisLabs[i, "yPos"] <- minPos axisLabs[i, "vjust"] <- 0 } else if (yPos > maxPos) { axisLabs[i, "yPos"] <- maxPos axisLabs[i, "vjust"] <- 1 } if (xPos < minPos) { axisLabs[i, "xPos"] <- minPos axisLabs[i, "hjust"] <- 0 } else if (xPos > maxPos) { axisLabs[i, "xPos"] <- maxPos axisLabs[i, "hjust"] <- 1 } } axisLabs } #' Internal axis labels for ggpairs #' #' This function is used when \code{axisLabels == "internal"}. #' #' @param data dataset being plotted #' @param mapping aesthetics being used (x is the variable the plot will be made for) #' @param label title to be displayed in the middle. Defaults to \code{mapping$x} #' @param labelSize size of variable label #' @param labelXPercent percent of horizontal range #' @param labelYPercent percent of vertical range #' @param labelHJust hjust supplied to label #' @param labelVJust vjust supplied to label #' @param gridLabelSize size of grid labels #' @param ... other arguments for geom_text #' @author Jason Crowley and Barret Schloerke #' @export #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' data(tips) #' p_(ggally_diagAxis(tips, ggplot2::aes(x = tip))) #' p_(ggally_diagAxis(tips, ggplot2::aes(x = sex))) ggally_diagAxis <- function( data, mapping, label = mapping$x, labelSize = 5, labelXPercent = 0.5, labelYPercent = 0.55, labelHJust = 0.5, labelVJust = 0.5, gridLabelSize = 4, ...) { if (is.null(mapping$x)) { stop("mapping$x is null. There must be a column value in this location.") } mapping$y <- NULL numer <- !is_horizontal(data, mapping, "x") if (!is.character(label)) { label <- mapping_string(mapping$x) } xData <- eval_data_col(data, mapping$x) if (numer) { xmin <- min(xData, na.rm = TRUE) xmax <- max(xData, na.rm = TRUE) # add a lil fluff... it looks better xrange <- c(xmin - .01 * (xmax - xmin), xmax + .01 * (xmax - xmin)) # xrange <- c(xmin, xmax) p <- ggally_text( label = label, mapping = aes(col = I("grey50")), xrange = xrange, yrange = xrange, size = labelSize, xP = labelXPercent, yP = labelYPercent, hjust = labelHJust, vjust = labelVJust ) axisBreaks <- get_x_axis_labels(p, xrange) # print(axisBreaks) p <- p + geom_text( data = axisBreaks, mapping = aes( x = !!as.name("xPos"), y = !!as.name("yPos"), label = !!as.name("lab"), hjust = !!as.name("hjust"), vjust = !!as.name("vjust") ), col = "grey50", size = gridLabelSize ) } else { breakLabels <- levels(as.factor(xData)) numLvls <- length(breakLabels) p <- ggally_text( label = label, mapping = aes(col = I("grey50")), xrange = c(0, 1), yrange = c(0, 1), size = labelSize, yP = labelYPercent, xP = labelXPercent, hjust = labelHJust, vjust = labelVJust ) # axisBreaks <- (1+2*0:(numLvls-1))/(2*numLvls) axisBreaks <- 0:(numLvls - 1) * (0.125 + (1 - 0.125 * (numLvls - 1)) / numLvls) + (1 - 0.125 * (numLvls - 1)) / (2 * numLvls) axisLabs <- data.frame( x = axisBreaks[1:numLvls], y = axisBreaks[numLvls:1], lab = breakLabels ) p <- p + geom_text( data = axisLabs, mapping = aes( x = !!as.name("x"), y = !!as.name("y"), label = !!as.name("lab") ), col = "grey50", size = gridLabelSize ) # hack to remove warning message... cuz it doesn't listen to suppress messages p$scales$scales[[1]]$breaks <- axisBreaks p$scales$scales[[2]]$breaks <- axisBreaks # pLabs <- pLabs + # scale_x_continuous(breaks = axisBreaks, limits = c(0, 1)) + # scale_y_continuous(breaks = axisBreaks, limits = c(0, 1)) } p } #' Faceted bar plot #' #' X variables are plotted using \code{geom_bar} and are faceted by the Y variable. #' #' @param data data set using #' @param mapping aesthetics being used #' @param ... other arguments are sent to geom_bar #' @author Barret Schloerke #' @keywords hplot #' @export #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' data(tips) #' p_(ggally_facetbar(tips, ggplot2::aes(x = sex, y = smoker, fill = time))) #' p_(ggally_facetbar(tips, ggplot2::aes(x = smoker, y = sex, fill = time))) ggally_facetbar <- function(data, mapping, ...) { mapping <- mapping_color_to_fill(mapping) # numer <- is.null(attributes(data[, as.character(mapping$x)])$class) # xVal <- mapping$x yVal <- mapping_string(mapping$y) mapping$y <- NULL p <- ggplot(data, mapping) + geom_bar(...) + facet_grid(paste(yVal, " ~ .", sep = "")) p } #' Mosaic plot #' #' Plots the mosaic plot by using fluctuation. #' #' @param data data set using #' @param mapping aesthetics being used. Only x and y will used and both are required #' @param ... passed to \code{\link[ggplot2]{geom_tile}(...)} #' @param floor don't display cells smaller than this value #' @param ceiling max value to scale frequencies. If any frequency is larger than the ceiling, the fill color is displayed darker than other rectangles #' @author Barret Schloerke #' @keywords hplot #' @export #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' data(tips) #' p_(ggally_ratio(tips, ggplot2::aes(sex, day))) #' p_(ggally_ratio(tips, ggplot2::aes(sex, day)) + ggplot2::coord_equal()) #' # only plot tiles greater or equal to 20 and scale to a max of 50 #' p_(ggally_ratio( #' tips, ggplot2::aes(sex, day), #' floor = 20, ceiling = 50 #' ) + ggplot2::theme(aspect.ratio = 4 / 2)) ggally_ratio <- function( data, mapping = ggplot2::aes(!!!stats::setNames(lapply(colnames(data)[1:2], as.name), c("x", "y"))), ..., floor = 0, ceiling = NULL) { # capture the original names xName <- mapping_string(mapping$x) yName <- mapping_string(mapping$y) countData <- plyr::count(data, vars = c(xName, yName)) # overwrite names so name clashes don't happen colnames(countData)[1:2] <- c("x", "y") xNames <- levels(countData[["x"]]) yNames <- levels(countData[["y"]]) countData <- subset(countData, freq >= floor) if (is.null(ceiling)) { ceiling <- max(countData$freq) } countData[["freqSize"]] <- sqrt(pmin(countData[["freq"]], ceiling) / ceiling) countData[["col"]] <- ifelse(countData[["freq"]] > ceiling, "grey30", "grey50") countData[["xPos"]] <- as.numeric(countData[["x"]]) + (1 / 2) * countData[["freqSize"]] countData[["yPos"]] <- as.numeric(countData[["y"]]) + (1 / 2) * countData[["freqSize"]] p <- ggplot( data = countData, mapping = aes( x = !!as.name("xPos"), y = !!as.name("yPos"), height = !!as.name("freqSize"), width = !!as.name("freqSize"), fill = !!as.name("col") ) ) + geom_tile(...) + scale_fill_identity() + scale_x_continuous( name = xName, limits = c(0.9999, length(xNames) + 1), breaks = 1:(length(xNames) + 1), labels = c(xNames, ""), minor_breaks = FALSE ) + scale_y_continuous( name = yName, limits = c(0.9999, length(yNames) + 1), breaks = 1:(length(yNames) + 1), labels = c(yNames, ""), minor_breaks = FALSE ) + theme( axis.text.x = element_text( hjust = 0, vjust = 1, colour = "grey50" ), axis.text.y = element_text( hjust = 0, vjust = 0, angle = 90, colour = "grey50" ) ) p } #' Display counts of observations #' #' Plot the number of observations by using rectangles #' with proportional areas. #' #' @param data data set using #' @param mapping aesthetics being used #' @param ... other arguments passed to \code{\link[ggplot2]{geom_tile}(...)} #' @details #' You can adjust the size of rectangles with the \code{x.width} argument. #' @author Joseph Larmarange #' @keywords hplot #' @export #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' data(tips) #' p_(ggally_count(tips, mapping = ggplot2::aes(x = smoker, y = sex))) #' p_(ggally_count(tips, mapping = ggplot2::aes(x = smoker, y = sex, fill = day))) #' #' p_(ggally_count( #' as.data.frame(Titanic), #' mapping = ggplot2::aes(x = Class, y = Survived, weight = Freq) #' )) #' p_(ggally_count( #' as.data.frame(Titanic), #' mapping = ggplot2::aes(x = Class, y = Survived, weight = Freq), #' x.width = 0.5 #' )) ggally_count <- function(data, mapping, ...) { mapping <- mapping_color_to_fill(mapping) if (is.null(mapping$x)) stop("'x' aesthetic is required.") if (is.null(mapping$y)) stop("'y' aesthetic is required.") # for stat_ggally_count(), y should be mapped to base_y # and always be a factor count_col <- ".ggally_y" data[[count_col]] <- as.factor(eval_data_col(data, mapping$y)) # Reverse the y axis here. I'd like to perform this in the # `scale_y_continuous(trans="reverse")`, but the trans is applied after # `breaks/labels` data[[count_col]] <- factor(data[[count_col]], levels = rev(levels(data[[count_col]]))) ylabel <- mapping_string(mapping$y) mapping$base_y <- aes(base_y = !!as.name(count_col))$base_y mapping$y <- NULL # default values args <- list(...) if (!"fill" %in% names(args)) { if (is.null(mapping$fill)) { args$fill <- GeomRect$default_aes$fill } } ggplot(data, mapping) + do.call(stat_ggally_count, args) + scale_y_continuous( breaks = seq_along(levels(data[[count_col]])), labels = levels(data[[count_col]]) ) + theme(panel.grid.minor = element_blank()) + ylab(ylabel) } #' @export #' @rdname ggally_count #' @format NULL #' @usage NULL #' @export # na.rm = TRUE to remove warnings if NA (cf. stat_count) # x.width to control size of tiles stat_ggally_count <- function( mapping = NULL, data = NULL, geom = "tile", position = "identity", ..., x.width = .9, na.rm = FALSE, show.legend = NA, inherit.aes = TRUE) { params <- list( x.width = x.width, na.rm = na.rm, ... ) if (!is.null(params$y)) { stop("stat_ggally_count() must not be used with a y aesthetic, but with a base_y aesthetic instead.", call. = FALSE) } layer( data = data, mapping = mapping, stat = StatGGallyCount, geom = geom, position = position, show.legend = show.legend, inherit.aes = inherit.aes, params = params ) } #' @rdname ggally_count #' @format NULL #' @usage NULL #' @export StatGGallyCount <- ggproto("StatGGallyCount", Stat, required_aes = c("x", "base_y"), default_aes = aes( weight = 1, width = after_stat(width), height = after_stat(height), y = after_stat(y) ), setup_params = function(data, params) { params }, extra_params = c("na.rm"), compute_panel = function(self, data, scales, x.width = NULL) { if (is.null(data$weight)) { data$weight <- rep(1, nrow(data)) } if (is.null(x.width)) { x.width <- .9 } # sum weights for each combination of aesthetics # the use of . allows to consider all aesthetics defined in data panel <- stats::aggregate(weight ~ ., data = data, sum, na.rm = TRUE) names(panel)[which(names(panel) == "weight")] <- "n" # Reverse both the y and fill values here. # This makes the colors appear the correct order # If it is a single color, it won't make any difference in the cum_height panel <- panel[rev(seq_len(nrow(panel))), ] # compute proportions by x and y f <- function(n) { sum(abs(n), na.rm = TRUE) } panel$n_xy <- stats::ave(panel$n, panel$x, panel$base_y, FUN = f) panel$prop <- panel$n / panel$n_xy panel$width <- sqrt(panel$n_xy) / max(sqrt(panel$n_xy)) * x.width panel$height <- panel$width * panel$prop panel$cum_height <- stats::ave(panel$height, panel$x, panel$base_y, FUN = cumsum) panel$y <- as.numeric(panel$base_y) + panel$cum_height - panel$height / 2 - panel$width / 2 panel } ) #' @rdname ggally_count #' @export #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' p_(ggally_countDiag(tips, mapping = ggplot2::aes(x = smoker))) #' p_(ggally_countDiag(tips, mapping = ggplot2::aes(x = smoker, fill = sex))) ggally_countDiag <- function(data, mapping, ...) { mapping$y <- mapping$x ggally_count(data = data, mapping = mapping, ...) } #' Blank plot #' #' Draws nothing. #' #' Makes a "blank" ggplot object that will only draw white space #' #' @author Barret Schloerke #' @param ... other arguments ignored #' @seealso [ggplot2::element_blank()] #' @export #' @keywords hplot ggally_blank <- function(...) { aes(...) # ignored a <- data.frame(X = 1:2, Y = 1:2) p <- ggplot(data = a, aes(x = !!as.name("X"), y = !!as.name("Y"))) + geom_point(colour = "transparent") + theme( axis.line = element_blank(), axis.text.x = element_blank(), axis.text.y = element_blank(), axis.ticks = element_blank(), axis.title.x = element_blank(), axis.title.y = element_blank(), legend.background = element_blank(), legend.key = element_blank(), legend.text = element_blank(), legend.title = element_blank(), panel.background = element_blank(), panel.border = element_blank(), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), plot.background = element_blank(), plot.title = element_blank(), strip.background = element_blank(), strip.text.x = element_blank(), strip.text.y = element_blank() ) class(p) <- c(class(p), "ggmatrix_blank") p } #' @rdname ggally_blank #' @export ggally_blankDiag <- function(...) { ggally_blank(...) } #' NA plot #' #' Draws a large \code{NA} in the middle of the plotting area. This plot is useful when all X or Y data is \code{NA} #' #' @author Barret Schloerke #' @param data ignored #' @param mapping ignored #' @param size size of the geom_text 'NA' #' @param color color of the geom_text 'NA' #' @param ... other arguments sent to geom_text #' @export #' @keywords hplot ggally_na <- function(data = NULL, mapping = NULL, size = 10, color = "grey20", ...) { a <- data.frame(x = 1, y = 1, label = "NA") p <- ggplot(data = a, aes(x = !!as.name("X"), y = !!as.name("Y"), label = !!as.name("label"))) + geom_text(color = color, size = size, ...) + theme( axis.line = element_blank(), axis.text.x = element_blank(), axis.text.y = element_blank(), axis.ticks = element_blank(), axis.title.x = element_blank(), axis.title.y = element_blank(), legend.background = element_blank(), legend.key = element_blank(), legend.text = element_blank(), legend.title = element_blank(), panel.background = element_blank(), panel.border = element_blank(), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), plot.background = element_blank(), plot.title = element_blank(), strip.background = element_blank(), strip.text.x = element_blank(), strip.text.y = element_blank() ) p } #' @rdname ggally_na #' @export ggally_naDiag <- function(...) { ggally_na(...) } #' Scatterplot for continuous and categorical variables #' #' Make scatterplots compatible with both continuous and categorical variables #' using \code{\link[ggforce]{geom_autopoint}} from package \pkg{ggforce}. #' #' @param data data set using #' @param mapping aesthetics being used #' @param ... other arguments passed to \code{\link[ggforce]{geom_autopoint}(...)} #' @author Joseph Larmarange #' @keywords hplot #' @export #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' data(tips) #' p_(ggally_autopoint(tips, mapping = aes(x = tip, y = total_bill))) #' p_(ggally_autopoint(tips, mapping = aes(x = tip, y = sex))) #' p_(ggally_autopoint(tips, mapping = aes(x = smoker, y = sex))) #' p_(ggally_autopoint(tips, mapping = aes(x = smoker, y = sex, color = day))) #' p_(ggally_autopoint(tips, mapping = aes(x = smoker, y = sex), size = 8)) #' p_(ggally_autopoint(tips, mapping = aes(x = smoker, y = sex), alpha = .9)) #' #' p_(ggpairs( #' tips, #' mapping = aes(colour = sex), #' upper = list(discrete = "autopoint", combo = "autopoint", continuous = "autopoint"), #' diag = list(discrete = "autopointDiag", continuous = "autopointDiag") #' )) ggally_autopoint <- function(data, mapping, ...) { require_namespaces("ggforce") args <- list(...) if (!"alpha" %in% names(args) && is.null(mapping$alpha)) { args$alpha <- .5 } # mapping needs to be sent directly to geom_autopoint args$mapping <- mapping ggplot(data, mapping) + do.call(ggforce::geom_autopoint, args) } #' @rdname ggally_autopoint #' @export ggally_autopointDiag <- function(data, mapping, ...) { mapping$y <- mapping$x ggally_autopoint(data = data, mapping = mapping, ...) } #' Summarize a continuous variable by each value of a discrete variable #' #' Display summary statistics of a continuous variable for each value of a discrete variable. #' #' @param data data set using #' @param mapping aesthetics being used #' @param text_fn function that takes an x and weights and returns a text string #' @param text_fn_vertical function that takes an x and weights and returns a text string, used when \code{x} is discrete and \code{y} is continuous. If not provided, will use \code{text_fn}, replacing spaces by carriage returns. #' @param ... other arguments passed to \code{\link[ggplot2]{geom_text}(...)} #' @author Joseph Larmarange #' @keywords hplot #' @export #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' if (require(Hmisc)) { #' data(tips) #' p_(ggally_summarise_by(tips, mapping = aes(x = total_bill, y = day))) #' p_(ggally_summarise_by(tips, mapping = aes(x = day, y = total_bill))) #' #' # colour is kept only if equal to the discrete variable #' p_(ggally_summarise_by(tips, mapping = aes(x = total_bill, y = day, color = day))) #' p_(ggally_summarise_by(tips, mapping = aes(x = total_bill, y = day, color = sex))) #' p_(ggally_summarise_by(tips, mapping = aes(x = day, y = total_bill, color = day))) #' #' # custom text size #' p_(ggally_summarise_by(tips, mapping = aes(x = total_bill, y = day), size = 6)) #' #' # change statistic to display #' p_(ggally_summarise_by(tips, mapping = aes(x = total_bill, y = day), text_fn = weighted_mean_sd)) #' #' # custom stat function #' weighted_sum <- function(x, weights = NULL) { #' if (is.null(weights)) weights <- 1 #' paste0("Total : ", round(sum(x * weights, na.rm = TRUE), digits = 1)) #' } #' p_(ggally_summarise_by(tips, mapping = aes(x = total_bill, y = day), text_fn = weighted_sum)) #' } ggally_summarise_by <- function( data, mapping, text_fn = weighted_median_iqr, text_fn_vertical = NULL, ...) { if (is.null(mapping$x)) stop("'x' aesthetic is required.") if (is.null(mapping$y)) stop("'y' aesthetic is required.") horizontal <- is_horizontal(data, mapping) if (horizontal) { res <- ddply( data.frame( x = eval_data_col(data, mapping$x), y = eval_data_col(data, mapping$y), weight = eval_data_col(data, mapping$weight) %||% 1, stringsAsFactors = FALSE ), c("y"), plyr::here(summarize), label = text_fn(x, weight) ) # keep colour if matching the discrete variable if (mapping_string(mapping$colour) == mapping_string(mapping$y)) { col <- as.name("y") } else { col <- NULL } ggplot(res) + aes(y = !!as.name("y"), x = 1, label = !!as.name("label"), colour = !!col) + geom_text(...) + xlab("") + ylab(mapping_string(mapping$y)) + # theme_minimal() + theme( panel.grid.major = element_blank(), panel.grid.minor = element_blank(), axis.ticks.x = element_blank(), axis.text.x = element_blank(), legend.position = "none", panel.background = element_blank(), panel.border = element_rect( linetype = "solid", color = theme_get()$panel.background$fill, fill = "transparent" ) ) } else { if (is.null(text_fn_vertical)) { text_fn_vertical <- function(x, weights) { gsub(" ", "\n", text_fn(x, weights)) } } ggally_summarise_by(data, mapping_swap_x_y(mapping), text_fn_vertical, ...) + coord_flip() + theme( axis.ticks.y = element_blank(), axis.text.y = element_blank(), axis.text.x = theme_get()$axis.text, axis.ticks.x = theme_get()$axis.ticks ) + theme(axis.text.x = element_text(size = 9)) } } #' @rdname ggally_summarise_by #' @param x a numeric vector #' @param weights an optional numeric vectors of weights. If \code{NULL}, equal weights of 1 will be taken into account. #' @details #' \code{weighted_median_iqr} computes weighted median and interquartile range. #' @export weighted_median_iqr <- function(x, weights = NULL) { require_namespaces("Hmisc") s <- round(Hmisc::wtd.quantile(x, weights = weights, probs = c(.25, .5, .75), na.rm = TRUE), digits = 1) paste0("Median: ", s[2], " [", s[1], "-", s[3], "]") } #' @rdname ggally_summarise_by #' @details #' \code{weighted_mean_sd} computes weighted mean and standard deviation. #' @export weighted_mean_sd <- function(x, weights = NULL) { require_namespaces("Hmisc") m <- round(Hmisc::wtd.mean(x, weights = weights, na.rm = TRUE), digits = 1) sd <- round(sqrt(Hmisc::wtd.var(x, weights = weights, na.rm = TRUE)), digits = 1) paste0("Mean: ", m, " (", sd, ")") } GGally/R/ggmatrix_print.R0000644000176200001440000000315614527265752015037 0ustar liggesusersggplot2_set_last_plot <- utils::getFromNamespace("set_last_plot", "ggplot2") #' Print \code{\link{ggmatrix}} object #' #' Print method taken from \code{ggplot2:::print.ggplot} and altered for a \code{\link{ggmatrix}} object #' #' @param x plot to display #' @param newpage draw new (empty) page first? #' @param vp viewport to draw plot in #' @param ... arguments passed onto \code{\link{ggmatrix_gtable}} #' @method print ggmatrix #' @author Barret Schloerke #' @import utils #' @importFrom grid grid.newpage grid.draw seekViewport pushViewport upViewport #' @export #' @examples #' data(tips) #' pMat <- ggpairs(tips, c(1, 3, 2), mapping = ggplot2::aes(color = sex)) #' pMat # calls print(pMat), which calls print.ggmatrix(pMat) print.ggmatrix <- function(x, newpage = is.null(vp), vp = NULL, ...) { if (newpage) { grid.newpage() } grDevices::recordGraphics( requireNamespace("GGally", quietly = TRUE), list(), getNamespace("GGally") ) gtable <- ggmatrix_gtable(x, ...) # must be done after gtable, as gtable calls many ggplot2::print.ggplot methods ggplot2_set_last_plot(x) if (is.null(vp)) { grid.draw(gtable) } else { if (is.character(vp)) { seekViewport(vp) } else { pushViewport(vp) } grid.draw(gtable) upViewport() } invisible(data) } #' Is Blank Plot? #' Find out if the plot equals a blank plot #' #' @keywords internal #' @examples #' GGally:::is_blank_plot(ggally_blank()) #' GGally:::is_blank_plot(ggally_points(mtcars, ggplot2::aes(disp, hp))) #' is_blank_plot <- function(p) { is.null(p) || identical(p, "blank") || inherits(p, "ggmatrix_blank") } GGally/R/ggnostic.R0000644000176200001440000006731114527407231013607 0ustar liggesusers# cooksd # on all predicted values # important to prediction # sigma # how much of a problem it is to the model ## .hat: Diagonal of the hat matrix ## .sigma: Estimate of residual standard deviation when corresponding observation is dropped from model ## .fitted: Fitted values of model ## .cooksd: Cooks distance, 'cooks.distance' ## .se.fit: Standard errors of fitted values ## .resid: Residuals ## .std.resid: Standardized residuals (Some unusual "lm" objects, such as "rlm" from MASS, may omit '.cooksd' and '.std.resid'. "gam" from mgcv omits '.sigma') #' Broomify a model #' #' broom::augment a model and add broom::glance and broom::tidy output as attributes. X and Y variables are also added. #' #' @param model model to be sent to [broom::augment()], [broom::glance()], and [broom::tidy()] #' @param lmStars boolean that determines if stars are added to labels #' @return broom::augmented data frame with the broom::glance data.frame and broom::tidy data.frame as 'broom_glance' and 'broom_tidy' attributes respectively. \code{var_x} and \code{var_y} variables are also added as attributes #' @export #' @examples #' data(mtcars) #' model <- stats::lm(mpg ~ wt + qsec + am, data = mtcars) #' broomified_model <- broomify(model) #' str(broomified_model) broomify <- function(model, lmStars = TRUE) { if (inherits(model, "broomify")) { return(model) } require_namespaces("broom") broom_glance_info <- broom::glance(model) broom_tidy_coef <- broom::tidy(model) broom_augment_rows <- broom::augment(model, se_fit = TRUE) attr(broom_augment_rows, "broom_glance") <- broom_glance_info attr(broom_augment_rows, "broom_tidy") <- broom_tidy_coef attr(broom_augment_rows, "var_x") <- model_beta_variables(data = broom_augment_rows) attr(broom_augment_rows, "var_y") <- model_response_variables(data = broom_augment_rows) attr(broom_augment_rows, "var_x_label") <- model_beta_label( model, data = broom_augment_rows, lmStars ) class(broom_augment_rows) <- c(class(broom_augment_rows), "broomify") return(broom_augment_rows) } model_variables <- function(model, data = broom::augment(model)) { augment_names <- names(data) augment_names <- augment_names[!grepl("^\\.", augment_names)] } #' Model term names #' #' Retrieve either the response variable names, the beta variable names, or beta variable names. If the model is an object of class 'lm', by default, the beta variable names will include anova significance stars. #' #' @param model model in question #' @param data equivalent to \code{broom::augment(model)} #' @param lmStars boolean that determines if stars are added to labels #' @return character vector of names #' @rdname model_terms #' @export #' @importFrom stats terms model_response_variables <- function(model, data = broom::augment(model)) { model_variables(model = model, data = data)[1] } #' @rdname model_terms #' @export model_beta_variables <- function(model, data = broom::augment(model)) { model_variables(model = model, data = data)[-1] } #' @importFrom stats symnum beta_stars <- function(p_val) { unclass(symnum( p_val, corr = FALSE, na = FALSE, cutpoints = c(0, 0.001, 0.01, 0.05, 0.1, 1), symbols = c("***", "**", "*", ".", " ") )) } #' @export #' @rdname model_terms #' @importFrom stats anova model_beta_label <- function(model, data = broom::augment(model), lmStars = TRUE) { beta_vars <- model_beta_variables(model, data = data) if ((!identical(class(model), "lm")) || (!isTRUE(lmStars))) { return(beta_vars) } # for lm models only tidy_anova <- broom::tidy(anova(model)) tidy_anova <- tidy_anova[tidy_anova$term %in% beta_vars, ] p_vals <- tidy_anova$p.value names(p_vals) <- tidy_anova$term p_vals <- p_vals[beta_vars] x_labs <- paste(beta_vars, beta_stars(p_vals), sep = "") gsub("\\s+$", "", x_labs) } broom_columns <- function() { c(".fitted", ".se.fit", ".resid", ".hat", ".sigma", ".cooksd", ".std.resid") } #' RColorBrewer Set1 colors #' #' @param col standard color name used to retrieve hex color value #' @import RColorBrewer #' @export brew_colors <- function(col) { brew_cols <- RColorBrewer::brewer.pal(n = 9, "Set1") names(brew_cols) <- c( "red", "blue", "green", "purple", "orange", "yellow", "brown", "pink", "grey" ) brew_cols <- as.list(brew_cols) ret <- brew_cols[[col]] if (is.null(ret)) { stop( paste( "color '", col, "' not found in: c(", paste(names(brew_cols), collapse = ", "), ")", sep = "" ) ) } ret } #' \code{\link{ggnostic}} background line with geom #' #' If a non-null \code{linePosition} value is given, a line will be drawn before the given \code{continuous_geom} or \code{combo_geom} is added to the plot. #' #' Functions with a color in their name have different default color behavior. #' #' @param data,mapping supplied directly to [ggplot2::ggplot()] #' @param ... parameters supplied to \code{continuous_geom} or \code{combo_geom} #' @param linePosition,lineColor,lineSize,lineAlpha,lineType parameters supplied to #' [ggplot2::geom_line()] #' @param continuous_geom \pkg{ggplot2} geom that is executed after the line is (possibly) #' added and if the x data is continuous #' @param combo_geom \pkg{ggplot2} geom that is executed after the line is (possibly) added and #' if the x data is discrete #' @param mapColorToFill boolean to determine if combo plots should cut the color mapping to the fill mapping #' @return \pkg{ggplot2} plot object #' @rdname ggally_nostic_line ggally_nostic_line <- function( data, mapping, ..., linePosition = NULL, lineColor = "red", lineSize = 0.5, lineAlpha = 1, lineType = 1, continuous_geom = ggplot2::geom_point, combo_geom = ggplot2::geom_boxplot, mapColorToFill = TRUE) { x_is_character <- is_character_column(data, mapping, "x") if (x_is_character && isTRUE(mapColorToFill)) { mapping <- mapping_color_to_fill(mapping) } p <- ggplot(data = data, mapping = mapping) if (!is.null(linePosition)) { p <- p + geom_hline( yintercept = linePosition, color = lineColor, linewidth = lineSize, alpha = lineAlpha, linetype = lineType ) } if (x_is_character) { p <- p + combo_geom(...) } else { p <- p + continuous_geom(...) } p } #' \code{\link{ggnostic}} residuals #' #' If non-null \code{pVal} and \code{sigma} values are given, confidence interval lines will be added to the plot at the specified \code{pVal} percentiles of a N(0, sigma) distribution. #' #' @param data,mapping,... parameters supplied to \code{\link{ggally_nostic_line}} #' @param linePosition,lineColor,lineSize,lineAlpha,lineType parameters supplied to #' [ggplot2::geom_line()] #' @param lineConfColor,lineConfSize,lineConfAlpha,lineConfType parameters supplied to the #' confidence interval lines #' @param pVal percentiles of a N(0, sigma) distribution to be drawn #' @param sigma sigma value for the \code{pVal} percentiles #' @param se boolean to determine if the confidence intervals should be displayed #' @param method,formula parameters supplied to [ggplot2::geom_smooth()]. #' Defaults to \code{"auto"} and \code{"y ~ x"} #' @return \pkg{ggplot2} plot object #' @seealso \code{stats::\link[stats]{residuals}} #' @export #' @importFrom stats qnorm #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' dt <- broomify(stats::lm(mpg ~ wt + qsec + am, data = mtcars)) #' p_(ggally_nostic_resid(dt, ggplot2::aes(wt, .resid))) ggally_nostic_resid <- function( data, mapping, ..., linePosition = 0, lineColor = brew_colors("grey"), lineSize = 0.5, lineAlpha = 1, lineType = 1, lineConfColor = brew_colors("grey"), lineConfSize = lineSize, lineConfAlpha = lineAlpha, lineConfType = 2, pVal = c(0.025, 0.975), sigma = attr(data, "broom_glance")$sigma, se = TRUE, method = "auto", formula = y ~ x) { if (!is.null(linePosition) && !is.null(pVal) && !is.null(sigma)) { scaled_sigmas <- qnorm(pVal, lower.tail = TRUE, sd = sigma) linePosition <- c(linePosition, linePosition + scaled_sigmas) lineColor <- c(lineColor, lineConfColor, lineConfColor) lineType <- c(lineType, lineConfType, lineConfType) lineSize <- c(lineSize, lineConfSize, lineConfSize) lineAlpha <- c(lineAlpha, lineConfAlpha, lineConfAlpha) } p <- ggally_nostic_line( data, mapping, ..., linePosition = linePosition, lineColor = lineColor, lineType = lineType, lineSize = lineSize, lineAlpha = lineAlpha ) if (!is_character_column(data, mapping, "x")) { p <- p + geom_smooth(se = se, method = method, formula = formula) } p + coord_cartesian( ylim = range( c(linePosition, eval_data_col(data, mapping$y)), na.rm = TRUE ) ) } #' \code{\link{ggnostic}} standardized residuals #' #' If non-null \code{pVal} and \code{sigma} values are given, confidence interval lines will be added to the plot at the specified \code{pVal} locations of a N(0, 1) distribution. #' #' @param data,mapping,... parameters supplied to \code{\link{ggally_nostic_resid}} #' @param sigma sigma value for the \code{pVal} percentiles. Set to 1 for standardized residuals #' @seealso [stats::rstandard()] #' @return \pkg{ggplot2} plot object #' @rdname ggally_nostic_std_resid #' @export #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' dt <- broomify(stats::lm(mpg ~ wt + qsec + am, data = mtcars)) #' p_(ggally_nostic_std_resid(dt, ggplot2::aes(wt, .std.resid))) ggally_nostic_std_resid <- function( data, mapping, ..., sigma = 1) { ggally_nostic_resid( data, mapping, ..., sigma = sigma ) } #' \code{\link{ggnostic}} fitted value's standard error #' #' A function to display \code{stats::\link[stats]{predict}}'s standard errors #' #' @details #' As stated in \code{stats::\link[stats]{predict}} documentation: #' #' If the logical 'se.fit' is 'TRUE', standard errors of the predictions are calculated. If the numeric argument 'scale' is set (with optional ''df'), it is used as the residual standard deviation in the computation of the standard errors, otherwise this is extracted from the model fit. #' #' Since the se.fit is \code{TRUE} and scale is unset by default, the standard errors are extracted from the model fit. #' #' A base line of 0 is added to give reference to a perfect fit. #' #' @param data,mapping,...,lineColor parameters supplied to \code{\link{ggally_nostic_line}} #' @param linePosition base comparison for a perfect fit #' @seealso [stats::influence()] #' @return \pkg{ggplot2} plot object #' @export #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' dt <- broomify(stats::lm(mpg ~ wt + qsec + am, data = mtcars)) #' p_(ggally_nostic_se_fit(dt, ggplot2::aes(wt, .se.fit))) ggally_nostic_se_fit <- function( data, mapping, ..., lineColor = brew_colors("grey"), linePosition = NULL) { ggally_nostic_line( data, mapping, ..., lineColor = lineColor, linePosition = linePosition ) } #' \code{\link{ggnostic}} leave one out model sigma #' #' A function to display [stats::influence()]'s sigma value. #' #' @details #' As stated in [stats::influence()] documentation: #' #' sigma: a vector whose i-th element contains the estimate of the residual standard deviation obtained when the i-th case is dropped from the regression. (The approximations needed for GLMs can result in this being 'NaN'.) #' #' A line is added to display the overall model's sigma value. This gives a baseline for comparison #' #' @param data,mapping,...,lineColor parameters supplied to \code{\link{ggally_nostic_line}} #' @param linePosition line that is drawn in the background of the plot. Defaults to the overall model's sigma value. #' @seealso [stats::influence()] #' @return \pkg{ggplot2} plot object #' @export #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' dt <- broomify(stats::lm(mpg ~ wt + qsec + am, data = mtcars)) #' p_(ggally_nostic_sigma(dt, ggplot2::aes(wt, .sigma))) ggally_nostic_sigma <- function( data, mapping, ..., lineColor = brew_colors("grey"), linePosition = attr(data, "broom_glance")$sigma) { ggally_nostic_line( data, mapping, ..., lineColor = lineColor, linePosition = linePosition ) } #' \code{\link{ggnostic}} Cook's distance #' #' A function to display [stats::cooks.distance()]. #' #' @details #' A line is added at \eqn{F_{p,n-p}(0.5)}{F[p,n-p](0.5)} to display the general cutoff point for Cook's Distance. #' #' Reference: Michael H. Kutner, Christopher J. Nachtsheim, John Neter, and William Li. Applied linear statistical models. The McGraw-Hill / Irwin series operations and decision sciences. McGraw-Hill Irwin, 2005, p. 403 #' #' @param data,mapping,...,lineColor,lineType parameters supplied to \code{\link{ggally_nostic_line}} #' @param linePosition 4 / n is the general cutoff point for Cook's Distance #' @seealso [stats::cooks.distance()] #' @return \pkg{ggplot2} plot object #' @rdname ggally_nostic_cooksd #' @export #' @importFrom stats pf #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' dt <- broomify(stats::lm(mpg ~ wt + qsec + am, data = mtcars)) #' p_(ggally_nostic_cooksd(dt, ggplot2::aes(wt, .cooksd))) ggally_nostic_cooksd <- function( data, mapping, ..., linePosition = pf(0.5, length(attr(data, "var_x")), nrow(data) - length(attr(data, "var_x"))), lineColor = brew_colors("grey"), lineType = 2) { ggally_nostic_line( data, mapping, ..., linePosition = linePosition, lineColor = lineColor, lineType = lineType ) } #' \code{\link{ggnostic}} leverage points #' #' A function to display stats::influence's hat information against a given explanatory variable. #' #' @details #' As stated in [stats::influence()] documentation: #' #' hat: a vector containing the diagonal of the 'hat' matrix. #' #' The diagonal elements of the 'hat' matrix describe the influence each response value has on the fitted value for that same observation. #' #' A suggested "cutoff" line is added to the plot at a height of 2 * p / n and an expected line at a height of p / n. #' If either \code{linePosition} or \code{avgLinePosition} is \code{NULL}, the respective line will not be drawn. #' #' @param data,mapping,... supplied directly to \code{\link{ggally_nostic_line}} #' @param linePosition,lineColor,lineSize,lineAlpha,lineType parameters supplied to #' [ggplot2::geom_line()] for the cutoff line #' @param avgLinePosition,avgLineColor,avgLineSize,avgLineAlpha,avgLineType parameters supplied #' to [ggplot2::geom_line()] for the average line #' @seealso [stats::influence()] #' @return \pkg{ggplot2} plot object #' @export #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' dt <- broomify(stats::lm(mpg ~ wt + qsec + am, data = mtcars)) #' p_(ggally_nostic_hat(dt, ggplot2::aes(wt, .hat))) ggally_nostic_hat <- function( data, mapping, ..., linePosition = 2 * sum(eval_data_col(data, mapping$y)) / nrow(data), lineColor = brew_colors("grey"), lineSize = 0.5, lineAlpha = 1, lineType = 2, avgLinePosition = sum(eval_data_col(data, mapping$y)) / nrow(data), avgLineColor = brew_colors("grey"), avgLineSize = lineSize, avgLineAlpha = lineAlpha, avgLineType = 1) { if (is.null(linePosition)) { lineColor <- lineSize <- lineAlpha <- lineType <- NULL } if (is.null(avgLinePosition)) { avgLineColor <- avgLineSize <- avgLineAlpha <- avgLineType <- NULL } ggally_nostic_line( data, mapping, ..., linePosition = c(linePosition, avgLinePosition), lineColor = c(lineColor, avgLineColor), lineSize = c(lineSize, avgLineSize), lineType = c(lineType, avgLineType), lineAlpha = c(lineAlpha, avgLineAlpha) ) } #' Function switch #' #' Function that allows you to call different functions based upon an aesthetic variable value. #' #' @param types list of functions that follow the \code{\link{ggmatrix}} function standard: \code{function(data, mapping, ...){ #make ggplot2 object }}. One key should be a 'default' key for a default switch case. #' @param mapping_val mapping value to switch on. Defaults to the 'y' variable of the aesthetics list. #' @export #' @examples #' ggnostic_continuous_fn <- fn_switch(list( #' default = ggally_points, #' .fitted = ggally_points, #' .se.fit = ggally_nostic_se_fit, #' .resid = ggally_nostic_resid, #' .hat = ggally_nostic_hat, #' .sigma = ggally_nostic_sigma, #' .cooksd = ggally_nostic_cooksd, #' .std.resid = ggally_nostic_std_resid #' )) #' #' ggnostic_combo_fn <- fn_switch(list( #' default = ggally_box_no_facet, #' fitted = ggally_box_no_facet, #' .se.fit = ggally_nostic_se_fit, #' .resid = ggally_nostic_resid, #' .hat = ggally_nostic_hat, #' .sigma = ggally_nostic_sigma, #' .cooksd = ggally_nostic_cooksd, #' .std.resid = ggally_nostic_std_resid #' )) fn_switch <- function( types, mapping_val = "y") { function(data, mapping, ...) { var <- mapping_string(mapping[[mapping_val]]) fn <- ifnull(types[[var]], types[["default"]]) if (is.null(fn)) { stop(str_c( "function could not be found for ", mapping_val, " or 'default'. ", "Please include one of these two keys as a function." )) } fn(data = data, mapping = mapping, ...) } } check_and_set_nostic_types <- function( types, default, .fitted, .resid, .std.resid, # nolint .sigma, .se.fit, # nolint .hat, .cooksd) { types_names <- names(types) set_type_value <- function(name, value) { if (is.null(types[[name]])) { # value is not set if (!(name %in% types_names)) { # set suggested fn types[[name]] <<- value } else { # does not plot displayed types[[name]] <<- ggally_blank } } } set_type_value("default", default) set_type_value(".fitted", .fitted) set_type_value(".resid", .resid) set_type_value(".std.resid", .std.resid) # nolint set_type_value(".sigma", .sigma) set_type_value(".se.fit", .se.fit) # nolint set_type_value(".hat", .hat) set_type_value(".cooksd", .cooksd) types } #' Plot matrix of statistical model diagnostics #' #' #' @section `columnsY`: #' [broom::augment()] collects data from the supplied model and returns a data.frame with the following columns (taken directly from broom documentation). These columns are the only allowed values in the \code{columnsY} parameter to \code{\link{ggnostic}}. #' #' \describe{ #' \item{.resid}{Residuals} #' \item{.hat}{Diagonal of the hat matrix} #' \item{.sigma}{Estimate of residual standard deviation when #' corresponding observation is dropped from model} #' \item{.cooksd}{Cooks distance, [stats::cooks.distance()]} #' \item{.fitted}{Fitted values of model} #' \item{.se.fit}{Standard errors of fitted values} #' \item{.std.resid}{Standardized residuals} #' \item{response variable name}{The response variable in the model may be added. Such as \code{"mpg"} in the model \code{lm(mpg ~ ., data = mtcars)}} #' } #' #' @section `continuous`, `combo`, `discrete` types: #' Similar to \code{\link{ggduo}} and \code{\link{ggpairs}}, functions may be supplied to display the different column types. However, since the Y rows are fixed, each row has it's own corresponding function in each of the plot types: continuous, combo, and discrete. Each plot type list can have keys that correspond to the [broom::augment()] output: \code{".fitted"}, \code{".resid"}, \code{".std.resid"}, \code{".sigma"}, \code{".se.fit"}, \code{".hat"}, \code{".cooksd"}. An extra key, \code{"default"}, is used to plot the response variables of the model if they are included. Having a function for each diagnostic allows for very fine control over the diagnostics plot matrix. The functions for each type list are wrapped into a switch function that calls the function corresponding to the y variable being plotted. These switch functions are then passed directly to the \code{types} parameter in \code{\link{ggduo}}. #' #' @param model statistical model object such as output from \code{stats::\link[stats]{lm}} or \code{stats::\link[stats]{glm}} #' @param ... arguments passed directly to \code{\link{ggduo}} #' @param columnsX columns to be displayed in the plot matrix. Defaults to the predictor columns of the \code{model} #' @param columnsY rows to be displayed in the plot matrix. Defaults to residuals, leave one out sigma value, diagonal of the hat matrix, and Cook's Distance. The possible values are the response variables in the model and the added columns provided by [broom::augment()]. See details for more information. #' @param columnLabelsX,columnLabelsY column and row labels to display in the plot matrix #' @param xlab,ylab,title plot matrix labels passed directly to \code{\link{ggmatrix}} #' @param continuous,combo,discrete list of functions for each y variable. See details for more information. #' @template ggmatrix-progress #' @param data data defaults to a 'broomify'ed model object. This object will contain information about the X variables, Y variables, and multiple broom outputs. See \code{\link{broomify}(model)} for more information #' @export #' @examples #' # small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' data(mtcars) #' #' # use mtcars dataset and alter the 'am' column to display actual name values #' mtc <- mtcars #' mtc$am <- c("0" = "automatic", "1" = "manual")[as.character(mtc$am)] #' #' # step the complete model down to a smaller model #' mod <- stats::step(stats::lm(mpg ~ ., data = mtc), trace = FALSE) #' #' # display using defaults #' pm <- ggnostic(mod) #' p_(pm) #' #' # color by am value #' pm <- ggnostic(mod, mapping = ggplot2::aes(color = am)) #' p_(pm) #' #' # turn resid smooth error ribbon off #' pm <- ggnostic(mod, continuous = list(.resid = wrap("nostic_resid", se = FALSE))) #' p_(pm) #' #' #' ## plot residuals vs fitted in a ggpairs plot matrix #' dt <- broomify(mod) #' pm <- ggpairs( #' dt, c(".fitted", ".resid"), #' columnLabels = c("fitted", "residuals"), #' lower = list(continuous = ggally_nostic_resid) #' ) #' p_(pm) ggnostic <- function( model, ..., columnsX = attr(data, "var_x"), # columnsY = c(".fitted", ".se.fit", ".resid", ".std.resid", ".sigma", ".hat", ".cooksd"), columnsY = c(".resid", ".sigma", ".hat", ".cooksd"), columnLabelsX = attr(data, "var_x_label"), columnLabelsY = gsub("\\.", " ", gsub("^\\.", "", columnsY)), xlab = "explanatory variables", ylab = "diagnostics", title = paste(deparse(model$call, width.cutoff = 500L), collapse = "\n"), continuous = list( default = ggally_points, .fitted = ggally_points, .se.fit = ggally_nostic_se_fit, .resid = ggally_nostic_resid, .hat = ggally_nostic_hat, .sigma = ggally_nostic_sigma, .cooksd = ggally_nostic_cooksd, .std.resid = ggally_nostic_std_resid ), combo = list( default = ggally_box_no_facet, .fitted = ggally_box_no_facet, .se.fit = ggally_nostic_se_fit, .resid = ggally_nostic_resid, .hat = ggally_nostic_hat, .sigma = ggally_nostic_sigma, .cooksd = ggally_nostic_cooksd, .std.resid = ggally_nostic_std_resid ), discrete = list( default = ggally_ratio, .fitted = ggally_ratio, .se.fit = ggally_ratio, .resid = ggally_ratio, .hat = ggally_ratio, .sigma = ggally_ratio, .cooksd = ggally_ratio, .std.resid = ggally_ratio ), progress = NULL, data = broomify(model)) { continuous_types <- check_and_set_nostic_types( continuous, default = ggally_nostic_line, .fitted = ggally_nostic_line, .se.fit = ggally_nostic_se_fit, .resid = ggally_nostic_resid, .hat = ggally_nostic_hat, .sigma = ggally_nostic_sigma, .cooksd = ggally_nostic_cooksd, .std.resid = ggally_nostic_std_resid ) combo_types <- check_and_set_nostic_types( combo, default = ggally_nostic_line, .fitted = ggally_nostic_line, .se.fit = ggally_nostic_se_fit, .resid = ggally_nostic_resid, .hat = ggally_nostic_hat, .sigma = ggally_nostic_sigma, .cooksd = ggally_nostic_cooksd, .std.resid = ggally_nostic_std_resid ) discrete_types <- check_and_set_nostic_types( discrete, default = ggally_ratio, .fitted = ggally_ratio, .se.fit = ggally_ratio, .resid = ggally_ratio, .hat = ggally_ratio, .sigma = ggally_ratio, .cooksd = ggally_ratio, .std.resid = ggally_ratio ) continuous_fn <- fn_switch(continuous_types, "y") combo_fn <- fn_switch(combo_types, "y") discrete_fn <- fn_switch(discrete_types, "y") columnsX <- match_nostic_columns(columnsX, attr(data, "var_x"), "columnsX") columnsY <- match_nostic_columns( columnsY, c(attr(data, "var_y"), broom_columns()), "columnsY" ) ggduo( data = data, columnsX = columnsX, columnsY = columnsY, columnLabelsX = columnLabelsX, columnLabelsY = columnLabelsY, types = list( continuous = continuous_fn, comboVertical = combo_fn, comboHorizontal = combo_fn, discrete = discrete_fn ), ..., progress = progress, title = title, xlab = xlab, ylab = ylab ) } # https://github.com/ggobi/ggobi/blob/master/data/pigs.xml #' Multiple time series #' #' GGally implementation of ts.plot. Wraps around the ggduo function and removes the column strips #' @param ... supplied directly to \code{\link{ggduo}} #' @param columnLabelsX remove top strips for the X axis by default #' @param xlab defaults to "time" #' @return \code{\link{ggmatrix}} object #' @export #' @examples #' # Small function to display plots only if it's interactive #' p_ <- GGally::print_if_interactive #' #' p_(ggts(pigs, "time", c("gilts", "profit", "s_per_herdsz", "production", "herdsz"))) ggts <- function( ..., columnLabelsX = NULL, xlab = "time") { pm <- ggduo( ..., # remove the "time" strip columnLabelsX = columnLabelsX, xlab = xlab ) pm } # if (!is.null(group)) { # column_type <- unlist(lapply( # data[setdiff(names(data), broom_columns())], # plotting_data_type # )) # is_discrete <- column_type[column_type == "discrete"] # group_names <- names(is_discrete) # } else { # group_names <- deparse(mapping$group) # } # # line_mapping <- mapping # line_mapping[c("x", "y", "xend", "yend")] <- # aes_string(x = "xmin", y = "ymin", xend = "xmax", yend = "ymax") # # color_group <- c(group_names) # # if (!is.null(mapping$colour)) { # # set the colors to the mapping colors # color_group[length(color_group) + 1] <- deparse(mapping$colour) # } else { # # set the default color to the line color # line_mapping$colour <- I(lineColor) # } # # color_group <- unique(color_group) # # print(line_mapping) # print(color_group) # hline_data <- ddply( # data, color_group, # function(subsetDt) { # ret <- data.frame( # ymax = mean(subsetDt[[deparse(mapping$y)]], na.rm = TRUE), # ymin = mean(subsetDt[[deparse(mapping$y)]], na.rm = TRUE), # xmin = min(subsetDt[[deparse(mapping$x)]], na.rm = TRUE), # xmax = max(subsetDt[[deparse(mapping$x)]], na.rm = TRUE) # ) # # transfer the unique columns that need to be there # for (col in color_group) { # ret[[col]] <- unique(subsetDt[[col]]) # } # ret # } # ) match_nostic_columns <- function(columns, choices, name) { column_matches <- pmatch(columns, choices, nomatch = NA, duplicates.ok = TRUE) if (any(is.na(column_matches))) { stop(paste( "Could not match '", name, "': c(", paste("'", columns[is.na(column_matches)], "'", collapse = ", ", sep = ""), ") to choices: c(", paste("'", choices, "'", collapse = ", ", sep = ""), ")", sep = "" )) } columns <- choices[column_matches] columns } GGally/NEWS.md0000644000176200001440000003766614562447255012567 0ustar liggesusers# GGally 2.2.1 * Fix compatibility with ggplot2 3.5.0 (@teunbrand, #481) # GGally 2.2.0 ### Bug fixes * Removed dependency on reshape2 (#475) * Reverse ordering of y-axis in `ggally_count()` (#420) * Facets ordering in `ggcoef_compare()` (#426) * Fix in `ggcoef_compare()` when using tidy selectors for `no_reference_row` (#430) * Fix in `ggcoef_compare()` regarding `no_reference_row` option (#430) * Fix in `ggcoef_compare()` with an `include` argument (#447) * New default tidier for `ggcoef_model()`, now using `broom.helpers::tidy_with_broom_or_parameters()` (#432) * Re-export methods from and redirect vignettes to the `{ggstats}` package (#452, #457) * Replaced `..scaled..` with `after_stat(scaled)` in ggscatmat (#467) # GGally 2.1.2 ### Bug fixes * Replace `ggplot2` usage of `*_guide = FALSE` with `*_guide = "none"` (@larmarange, #418) * Require `network >= 1.17.1` (#418) # GGally 2.1.1 ### Bug fixes * Ignore `colour` aesthetic if all values are `NA`. (@larmarange, #404) * Avoid all duplicates within `stat_cross()`. (@larmarange, #402) * Avoid an error when tidiers do not return p-values. (@larmarange, #400) * Suggest `emmeans` to allow `ggcoef()` example to execute. (#407) # GGally 2.1.0 ### Breaking changes * Following version 7.0.0 of `broom`, computed residuals in `stat_cross()` are now named `"resid"` and `"std.resid"`. `cells` and `fill` arguments of `ggally_crosstable()` and `ggtable()` have been updated accordingly (@larmarange, #391) ### Other changes * `ggcoef()` redesign based on `broom.helpers` with four new functions: `ggcoef_model()`, `ggcoef_compare()`, `ggcoef_multinom()` and `ggcoef_plot()` (more informations in the dedicated vignette, @larmarange, #392) * New geometries: `geom_stripped_rows()` and `geom_stripped_cols()` (#392, @larmarange) * New option `reverse_fill_labels` for `ggally_colbar()` and `ggally_rowbar()` (@larmarange, #374) * `stat_prop()` now accepts a **x** or a **y** aesthetic (#395, @larmarange) * Temporarily not listening to `ggally_statistic(family)` to avoid monospaced font issues. See #373 for more details. (#387) # GGally 2.0.0 ### New Vignettes * [`vig_ggally("ggally_plots")`](https://ggobi.github.io/ggally/articles/ggally_plots.html) - ggally_*(): List of available high-level plots * [`vig_ggally("ggally_stats")`](https://ggobi.github.io/ggally/articles/ggally_stats.html) - stat_*(): Additional statistics for ggplot2 * [`vig_ggally("ggbivariate")`](https://ggobi.github.io/ggally/articles/ggbivariate.html) - ggbivariate(): Plot an outcome with several potential explanatory variables * [`vig_ggally("ggtable")`](https://ggobi.github.io/ggally/articles/ggtable.html) - ggtable(): Cross-tabulated tables * To view all vignettes for `GGally`, call `GGally::vig_ggally()` ### New functions `ggbivariate()` (@larmarange, #324) * Display an outcome using several potential explanatory variables * [`vig_ggally("ggbivariate")`](https://ggobi.github.io/ggally/articles/ggbivariate.html) `ggtable()` (@larmarange, #351) * Cross-tabulated tables of discrete variables * [`vig_ggally("ggtable")`](https://ggobi.github.io/ggally/articles/ggtable.html) `add_to_ggmatrix()` (#362) * Add ggplot2 objects to `ggmatrix` objects at selected locations * Locations can be rows, columns, matrices, or other shorthand values. `ggally_autopoint()`, `ggally_autopointDiag()` (@larmarange, #325) * Make scatterplots compatible with both continuous and categorical variables using `ggforce::geom_autopoint()`. `ggally_colbar()`, `ggally_rowbar()` (@larmarange, #324) * Plot column or row percentage using bar plots. `ggally_count()`, `ggally_countDiag()` (@larmarange, #321) * Plot the number of observations by using rectangles with proportional areas. `ggally_cross()` (@larmarange, #326) * Plot the number of observations by using square points with proportional areas. `ggally_crosstable()` (@larmarange, #351) * Display a cross-tabulated table. `ggally_statistic()` (#327) * A generalized version of `ggally_cor()` * Use this method to create functions similar to `ggally_cor()` that return any text value given and `x` and `y` vector of data `ggally_summarise_by()` (@larmarange, #325) * Display summary statistics of a continuous variable for each value of a discrete variable. `ggally_table()` (@larmarange, #326) * Plot the number of observations as a table. `ggally_trends()` (@larmarange, #333) * Plot trends using line plots. `signif_stars()` (@larmarange, #327) * Return the appropriate number of significance stars as a character vector for the provided numeric input values. ### New `ggplot2` plot statistics: `stat_cross()` (@larmarange, #326) * Computes statistics of a 2-dimensional matrix using `broom::augment.htest`. `stat_prop()` (@larmarange, #324) * Compute proportions according to custom denominator. `stat_weighted_mean()` (@larmarange, #333) * Compute the mean of y aesthetic for each unique value of x, taking into account weight aesthetic if provided. ### Major updates `ggally_cor()` (#327) * New implementation using `ggally_statistic()` * Will now hide the grid by default and add a border (`displayGrid = FALSE`) * Added the ability to display significance stars (`stars = TRUE`) * Alignment has been fixed so both short and long names should be displayed within view. `alignPercent` now corresponds to the center of the text. * Added the ability to separate the arguments sent to the title and the groups (`title_args` and `group_args`) * Digits now represents the total number of digits after the decimal place. * To use the old version, change your `ggally_cor()` function calls to `ggally_cor_v1_5()`. * Previously deprecated parameters have been removed Website * Updated to use `pkgdown` (#335) ### Features and bug fixes: `ggpairs()` (#331) * New `proportion` argument to control relative size of sub-plots * option `proportion = "auto"` for automatic guess based on the number of levels for discrete variables `ggduo()` (#331) * New `xProportion` and `yProportion` arguments to control relative size of sub-plots * Set option `xProportion = "auto"` and `yProportion = "auto"` for automatic guess based on the number of levels for discrete variables `ggscatmat()` * `lowertriangle()` now preallocates it's memory usage for a 2-5x speed improvement. (@vlepori, #328) * Fixed `facet`'ing error where the factor order was not preserved. This error caused the facets to be alphabetically sorted, cause plots to appear in unexpected locations. (#355) # GGally 1.5.0 * Updated to work with ggplot2 v3.3.0 (#308) `ggnet` and `ggnet2` * Fixed some logic bugs from newer R versions `ggally_box` and `ggally_dot` * Label now appears axis and is displayed in a plot matrix. (#253) `ggsurv` * Provide sensible legend values when multiple factors are present. (#310) `ggally_cor` * Added `displayGrid` argument to turn of the background grid. (#312) GGally 1.3.3 ---------------- `ggpairs` and `ggduo` * Become ggplot2 v2.2.2 compliant (#266) * When retrieving functions with wrap, `ggally_*` functions do not require the GGally namespace (#269) * Exported `eval_data_col`, `mapping_string`, and `mapping_swap_x_y` (5d157f6) * Exported `is_horizontal` and `is_character_column` (#270) * Logical values are now treated as discrete (#272) `ggmatrix` * `progress` parameter added to ggmatrix (and appropriate parent functions). Allows for `TRUE`, `FALSE`, `NULL`, and `function(pm){...}` (#271) `ggnostic` * Cooks distance cutoff is now at F_{p, n - p}(0.5) (#274) `ggnet2` * Replaced loading packages with loading namespaces(#262) `ggally_smooth` * Added `shrink` and `se` parameters to `ggally_smooth` (#247) `ggcoef` * Added `sort` parameter to sort by beta values (#273) `ggparcoord` * Fixed bug where x axis breaks and labels did not appear when `splineFactor = TRUE` (#279) GGally 1.3.2 ----------------- `ggpairs` and `ggduo` * Removed warning where pure numeric names gave a warning (#238, @lepennec) * Fixed ordering issue with horizontal boxplots (#239) `ggparcoord` * Fixed missing `x` aes requirement when shadebox is provided (#237, @treysp) Package * Made igraph a non required dependency for tests (#240) GGally 1.3.1 ----------------- Added new dataset `psychademic` * See `?psychademic` for more details * (And updated the broken UCLA links) Added original ggmatrix theme * added function to set theme to have clear strip background and rearrange the strip positions * added parameter `switch` to ggmatrix (and friends) to allow for strip repositioning. See `?ggplot::facet_grid` for more documentation on `switch` (#223, #224) `ggsurv` error reporting * removed a one error check that is covered in other places (#222) `+.gg` * allow to add a list of items to a ggmatrix (#228) `ggmatrix.print` * fix strip issues with ggplot2 name update GGally 1.3.0 ----------------- `ggmatrix.print` - massive update! * Now prints with a ggplot2 facet'ed structure * Column titles are now placed in the strip of a plot matrix * If there are 16 plots or more, a progress bar is displayed automatically (if interactive). Please look at the documentation for `ggmatrix_gtable` more details. `ggmatrix` legend * A legend may be added with the `legend` parameter in `ggduo`, `ggpairs`, and `ggmatrix` * May specify a (length two) numeric plot coordinate * May specify a (length one) numeric plot position * May specify a legend object retrieved from `grab_legend` `ggnostic` - New function! * Produces a `ggmatrix` of diagnostic plots from a model object * Uses broom to retrieve model information * Each column of the plot matrix is a predictor variable. The rows can display the response variables, fitted points, residuals, standardized residuals, leave one out model sigma values, diagonals of the hat matrix, and cook's distance for each point. `ggfacet` - New function! * Produces single ggplot2 object * interface is very similar to `ggduo` and `ggpairs` `fn_switch` - New function! * Provide many functions in a list but only call one function at run time according to a mapping value * Useful for `ggnostic` for different behavior depending on the y variable * Allows for a 'default' value for the default switch case `ggmatrix` - allow custom labellers for facet labels * Added labeller parameter which is supplied to `ggplot2::facet_grid()` * Allows for labels with plotmath expressions `ggmatrix` and `ggplot2::last_plot()` * If a `ggmatrix` object is printed, `ggplot2::last_plot()` will return the plot matrix `ggmatrix` and ggplot2 labels * `ggplot2::labs` `+`'ed to a ggmatrix object * `ggplot2::xlab` and `ggplot2::ylab` may be `+`'ed to a ggmatrix object * `ggplot2::ggtitle` `+`'ed to a ggmatrix object * (anything that returns a class of "labels" may be added to a ggmatrix object) `ggmatrix` and `ggplot2::ggsave()` * `ggsave` now works with `ggmatrix` objects `ggpairs` and `ggduo` check for cardinality (#197) * Before creating a ggmatrix object, a check is made for character/factor columns * If there are more than 15 (default) unique combinations, an error is thrown. * Setting `cardinality_threshold` parameter to a higher value can fix the problem (knowing single cell plots may take more time to produce) * Setting `cardinality_threshold` parameter to `NULL` can stop the check `ggmatrix` plot proportions * `ggmatrix` can set the plot proportions with the parameters `xProportions` and `yProportions` * These will change the relative size of the plot panels produced. `ggally_cor` colour aesthetic * color must be a non-numeric value `ggsurv` * added boolean to allow for legend to not be sorted * fixed bug where censored points with custom color didn't match properly (#185) Vignettes * vignettes are now displayed using `packagedocs`. More info at http://hafen.github.io/packagedocs/ `ggally_box_no_facet` and `ggally_dot_no_facet` * New methods added as defaults to pair with new ggmatrix print method GGally 1.2.0 ----------------- install requirements * relaxed install requirements on grid (5d06dfc, d57469a, 933bb14, 73b314d) ggduo - New! * plot two grouped data in a plot matrix (#173) * helpful for plotting two sets of columns, multivariate analysis, and canonical correlation analysis * be sure to check out the examples! ggally_smooth_loess - New! * uses the loess method with drawing a line (1552f96) ggally_smooth_lm - New! * uses the lm method with drawing a line (1552f96) * alias of ggally_smooth ggmatrix.print * fixed bug strips where causing spacing issue when printing axis labels (174630d) ggnetworkmap * fixed bug where checking for the package 'intergraph' couldn't be reached ggsurv * changed default of plotting multiple censored data color to match the survival line package testing * added many more tests! GGally 1.1.0 ----------------- ggcoef - New! * plot model coefficients with broom and ggplot2 PR#162 * Plotting model coefficients (http://www.r-statistics.com/2010/07/visualization-of-regression-coefficients-in-r/) gglegend - New! * pull out the legend of a plot which can also be used in ggpairs PR#155, PR#169 ggally_densityDiag * fixed bug where '...' was not respected (d0fe633) ggally_smooth * added 'method' parameter (411213c) ggally_ratio * Does not call ggfluctuation2 anymore. PR#165 ggcorr * fixed issue with unnamed correlation matrix used as input PR#146 * fixed issue undesired shifting when layout.exp was > 0 PR#171 ggfluctuation2 * is being deprecated. Please use ggally_ratio instead PR#165 ggnetworkmap * fixed issue with overlaying network on a world map PR#157 ggparcoord * Fixed odd bug where a list was trying to be forced as a double PR#162 ggpairs * Fixed improperly rotated axes with ggally_ratio PR#165 ggscatmat * added 'corMethod' parameter for use in upper triangle PR#145 ggsurv * size.est and size.ci parameters added PR#153 * ordering changed to reflect survival time PR#147 * added a vignette PR#154 wrap * documentation updated PR#152 * changes default behavior only. If an argument is supplied, the argument will take precedence github chat * https://gitter.im/ggobi/ggally is the place to visit for general questions. travis-ci * cache packages for faster checking * install covr and lintr from github for testing purposes GGally 1.0.1 ----------------- ggparcoord * fix handling of factor group variable PR#131 ggscatmat * force all char columns to factors PR#134 print.ggmatrix * add boolean for grid.newpage ggmatrix print method PR#126 GGally 1.0.0 ----------------- ggplot2 * GGally has been upgraded to run on the latest ggplot2 v1.1.0. PR#109 New functions * ggmatrix. Make a generic matrix of ggplot2 plots * ggnetworkmap. Plot a network with ggplot2 suitable for overlay on a ggmap::map ggplot, or other ggplot * ggnet2. Function for plotting network objects using ggplot2, with additional control over graphical parameters that are not supported by the ggnet function Vignettes * glyph - new! * ggmatrix - new! * ggnetworkmap - new! * ggpairs - new! * ggscatmat - new! ggmatrix * allows for bracket notation when getting or setting plots. PR#61 * full control over axis labels and axis text. PR#107, PR#111 ggpairs * is now wrapper to ggmatrix * takes in 'wrapped' functions. This better handles the case of many different parameters being supplied to different plot types. PR#90 * dates are better handled in ggpairs. Still room for improvement for default behavior, but they do not cause errors. PR#58, PR#59 * displays a 'NA' plot when all or a combination of the data is NA. PR#119 ggcorr * legend title expressions may be used. PR#55 * handles objects that may be coerced into a data.frame PR#70 gglyph * changed geom_line to geom_path in gglyph. Fixes ordering issue. PR#51 ggparcoord * remaining columns are passed through so aesthetics may be added later. PR#54 * fixed parcoord ordering issues with odd names. PR#106 * fixed scaling when unique length equals 1. PR#122 ggsurv * color censored marks the same color as the line. PR#74 * allow for different censored color marks. PR#113 ggally_density * add fake data points to extend the limits of the stat_density2d. PR#114 ggally_na * new plot type! Data * removed cityServiceFirms * added twitter_spambots GGally/MD50000644000176200001440000002547114563007414011756 0ustar liggesusers79526a597065d304fd31da3c1f7eccd6 *DESCRIPTION 2323d99ae7040fa627af14cf01a1e92d *NAMESPACE 47e0d76dd0df10f686abe1482ed95880 *NEWS.md fedaac9d2432e7a744ec148ee7e26ea3 *R/GGally-package.R fe023d1b299a98d2b59777015babcbe5 *R/data-australia-pisa-2012.R bb20f46690d71fd8bb30da3aea572862 *R/data-baseball.R 040a3753cbc5934d39c690be2df943ae *R/data-flea.R 6855f0bd7808ec56f495a80016d319a2 *R/data-happy.R 1a857c1deb41349c1238f3fa93e38fa7 *R/data-nasa.R 53bf3cbe28642ebaa5499f14cc23ae52 *R/data-pigs.R 8e06efe84025094992bd469e708538c9 *R/data-psychademic.R 114cc1a3df0dd0c59b80282c25d2d5ed *R/data-tips.R f0212d247c0c0145a7f37da9e39820f3 *R/data-twitter_spambots.R f14fde38567b1361ec8bcc591ceace95 *R/deprecated.R 7a2d4cf2745eac0686c3d37f6b262974 *R/find-combo.R 70879f52c7f0958a17441dccac948a0a *R/gg-plots.R d5bb94b166d6a0a79822c83378a7491c *R/ggally_colbar.R c386cf7be1933e05f8981b7a6be87ecd *R/ggally_cross.R 1de2a98812b68f314ba41ad969737e89 *R/ggaly_trends.R 108b18e9265cb0ac4cf646c61f2fee5d *R/ggbivariate.R aca3e3de5ff1309a235450f6df1bbcba *R/ggcoef.R af4e4ac9ccaec922960f05c6ee1d4b6b *R/ggcorr.R 31e0f349b50490eb67d9e5abf5eca882 *R/ggfacet.R c2a90195dcef7060eab637ad2a0a40f5 *R/gglyph.R 04b8f93a82f304dfaa00ae36e1e5b85f *R/ggmatrix.R cd9e504b590c30112ca0a520da0d6645 *R/ggmatrix_gtable.R c80c212d5864b8593c81937a9b89281f *R/ggmatrix_gtable_helpers.R e7dfb57ff493180cf56e4c46d483a7ad *R/ggmatrix_legend.R 88bdca85de6cc53d31f09eaf08f8a42e *R/ggmatrix_make_plot.R bc168818f92871c99944e90a2a6977b8 *R/ggmatrix_print.R ae2e842ea2c9f89127704cf43d79c667 *R/ggmatrix_progress.R 7c568a29c56d8ada1fa93065e822aa7b *R/ggnet.R 0bfec0a864531a3dc182f438148f8269 *R/ggnet2.R e7100658a4fc9f8154918554a18a9d25 *R/ggnetworkmap.R 7dabda5af2e479dc6f362a26c5e2d4c6 *R/ggnostic.R a4faada42e6533d749e23c2f0ba65f10 *R/ggpairs.R 587a39b1c470f1eea33f87f9c6034852 *R/ggpairs_add.R 8c1543e30494ed163fe5a5c63e553dea *R/ggpairs_getput.R 75493b59969afc4de0178535abd8e267 *R/ggpairs_internal_plots.R 9d4dcf84399f32da5d4d13cf6d5d5c66 *R/ggparcoord.R df690603a9acd0e3c3e88a13b86f5c1a *R/ggsave.R 3509073c672b27645b12c261fec9c19e *R/ggscatmat.R f9ddb1a4b753a395fa0591abcd3f29c5 *R/ggsurv.R f018823d31aa38e847874b644320813a *R/ggtable.R 490535b22ead7265bb2587a0af34b06b *R/reexports.R b56ff2b193ecba52f9ec7f3b10cca008 *R/utils-pipe.R 57a6dd43a8c98e5a74d4727a8337df5b *R/utils.R ff87947b764e49c98599862ec3de3191 *R/vig_ggally.R 6c1c73128c972fb58001839d42e14e95 *README.md a5a2f450fc4e9e487bb062a28147370c *build/GGally.pdf 1990d4e0df06729765fda9565bd6b41d *build/stage23.rdb 65c02cbc1793d76534f54142a9074573 *data/australia_PISA2012.rda 9b2d63a08f6c4d1718642d2c904c230a *data/baseball.rda 6fd42916be1426cb25e43fdec13fab51 *data/flea.rda 3eb6b88fcd8a095e3c5fa15ad242edf4 *data/happy.rda 7a121e6c90535716c3276dde47de36c7 *data/nasa.rda 24f257996f1963af78909cbf777b0dd3 *data/pigs.rda 0fa100acd2b9fc9893090e2cfcd6e9b4 *data/psychademic.rda 6a3f0a74f813cd68547e665f42b8a3cb *data/tips.rda 367c722d81b37120a120efaa1875dda2 *data/twitter_spambots.rda 662dd4d4985bcc9f7a3d0dc66b872fc2 *inst/WORDLIST 9c7d2ad26340e2403914454db7432f16 *man/GGally-package.Rd 162094033ed15419ccdcd1b7858e379d *man/add_and_overwrite_aes.Rd 18261a1145ae8a1492a634a834517f13 *man/add_ref_boxes.Rd b24b20ab6c78fc645f04bc463018267d *man/add_ref_lines.Rd 953f2bba0b7bca339c674a60fd24c9c6 *man/australia_PISA2012.Rd 3866a6caca6f0b215ad8b9336ba36db4 *man/baseball.Rd 9658083025d94f544042320c128a01ef *man/brew_colors.Rd 8ed351ce64c1134278edc46607ca4e3a *man/broomify.Rd a2984c095b5b91c509908af15e5f586f *man/column_is_character.Rd bc11181f44873ea5925ca2d80a0b712a *man/eval_data_col.Rd 81923b2be588fcc5dfd9aa3b6e328c7f *man/find_plot_type.Rd 39b138b2488f2f74dae4d700b070aa6e *man/flea.Rd ef2193f3b1b556972e922eca679a700c *man/fn_switch.Rd 52c540309c3a641a4615273d885f132c *man/getPlot.Rd 17c6fc6d258e79fd6a485dba92464f57 *man/get_x_axis_labels.Rd 26defe699f10f60e7938822f0a9dfaa0 *man/gg-add.Rd 878016ec32b1f5234d0f3aae1054c060 *man/ggally_autopoint.Rd fa77e75c201ae40d87a8eabd7285a50a *man/ggally_barDiag.Rd c78f81dade5b9053fd880bb59b697348 *man/ggally_blank.Rd eadeb1b4f548a5e9feef4331c027e5c3 *man/ggally_box.Rd f1f8b592ffbd3713a00364734dbf6f8a *man/ggally_colbar.Rd 38b417563f5b2e4140a8b3c1527a933b *man/ggally_cor.Rd 42a21835c6f666e9fce223f5070eb287 *man/ggally_cor_v1_5.Rd c347835f1d0c59c5cc11251233273cf8 *man/ggally_count.Rd 52dc451d794c2166b6b0352a025d20f7 *man/ggally_cross.Rd 9b3251afc1d829cd0872bccfa1657458 *man/ggally_crosstable.Rd 6ebae489f30f32515fe49cca6d201f37 *man/ggally_density.Rd a569bf6c78fc1f6b97ff70d0726b55e5 *man/ggally_densityDiag.Rd 92ed336c45bfcaeebbc68e6ecd95fdad *man/ggally_denstrip.Rd 605cc6cecca15fe4d57c3fc36e47e82e *man/ggally_diagAxis.Rd 5f54a7811a62d18eebb9b7212d847052 *man/ggally_dot.Rd 070c894b7d77415b9e64f8fdedfd28fe *man/ggally_dot_and_box.Rd 784fb5bfc889ab54315abe22d87d6536 *man/ggally_facetbar.Rd b925733e39d5661e5c0297c71a8cc41a *man/ggally_facetdensity.Rd 09964f4d2694a0a8f459b43cc1fa92cf *man/ggally_facetdensitystrip.Rd 4b46de0fa8ab7c3dfd64ac14b95586fe *man/ggally_facethist.Rd d063db9255b26f92564ec7862c7767db *man/ggally_na.Rd ebca882d2aad9ba03217aa0068a79293 *man/ggally_nostic_cooksd.Rd a3217c303371cca0228af9de872eac50 *man/ggally_nostic_hat.Rd 6d4797ef22b49ea47034e8e41686cfb8 *man/ggally_nostic_line.Rd 8ecd42b643b3e89001e5befd33f10242 *man/ggally_nostic_resid.Rd 836d0d6d142a990614dc203be31ab0e0 *man/ggally_nostic_se_fit.Rd a7a1ea2178a34f5c3ca5ad782a722d93 *man/ggally_nostic_sigma.Rd ef0d0fd2d28065a03b669eb8fdec4809 *man/ggally_nostic_std_resid.Rd 2d18d084c52a0c6a64c92649ab18f092 *man/ggally_points.Rd eba5a6c2bb54819677cd49794f03b33f *man/ggally_ratio.Rd ec821101a946c94a1e6f7debf687fdf1 *man/ggally_smooth.Rd 9bb9170cbc581fe0b12cfc58cf72a9ed *man/ggally_statistic.Rd f02201f162c928741929a21ec33f6104 *man/ggally_summarise_by.Rd a478209eadb8409bb707f33a544d68cc *man/ggally_table.Rd 8bb2bb3f127ebfd7fcb2b0b033afc672 *man/ggally_text.Rd 260b6f1a3aca0f45104d6532dde6cb32 *man/ggally_trends.Rd 7653bd1c941a07dbec78807f0dc208cd *man/ggbivariate.Rd 04bbc447afc973716a589574c899acad *man/ggcoef.Rd f7feb8607e2d9493b6639b1d2c2b1538 *man/ggcorr.Rd b0616049b549eb8d37078b8827b9e99d *man/ggduo.Rd 5ba743df725bc16da9b0961ed763927f *man/ggfacet.Rd ee75199ddbae4c8be2564271c42cd57a *man/gglegend.Rd 6fd6ee868cdab39c54d62d21bb83bf8c *man/ggmatrix.Rd 15096a035053575cb57996cdbee6e97e *man/ggmatrix_gtable.Rd cadcc4f1e0aa14564aab0402c1e413be *man/ggmatrix_location.Rd 1c8f85d261abb26110ee177fda6b9aae *man/ggmatrix_progress.Rd b7da05e552fb5c3799c12fa6ece2f8df *man/ggnet.Rd 8a9eb16884cd6f7d712a9d12fe507d2e *man/ggnet2.Rd 929fdb60b2387e7ad282cbf44a2a9a2f *man/ggnetworkmap.Rd bf3553ca6704c57ef2b36c4bcf0e6e60 *man/ggnostic.Rd ee90dfcdcf8dc37e2bd54d2a211139c6 *man/ggpairs.Rd 1051c25bc743aa20b44f76b7f668bb7d *man/ggparcoord.Rd 917862b9dcde65670eab1265751a252d *man/ggscatmat.Rd f442dcf428da3c93193b3a54792f73e5 *man/ggsurv.Rd cfd31ce96d1baf5b1b9388cb3924d205 *man/ggtable.Rd 0500aec2073247bb42d3ca1fbb3f9841 *man/ggts.Rd a696e6d7bb227bb33d3ac0b634385bb2 *man/glyphplot.Rd 5485c99c9c75469b618865b1efecf47f *man/glyphs.Rd e6ece236169acc0324c11038b7a3648e *man/grab_legend.Rd 28893fe20f76351104c13ebaeba18f6a *man/happy.Rd 4d88520abbdecc1e599f1646c1cba59c *man/is_blank_plot.Rd be1f8fe5db0d0c9d51974196a85061d0 *man/is_date.Rd 55d306069f4f123f3ce8fd9c2fc9601b *man/is_horizontal.Rd 775348650b3734614c802bcd200ce18f *man/lowertriangle.Rd 14e2dce5846392e116237df589dfeb32 *man/mapping_color_to_fill.Rd 0d432bdcf9299be35c5b363dbbc64f05 *man/mapping_string.Rd d02972d593e54c3cb51de2e49cb30053 *man/mapping_swap_x_y.Rd d8af662435affcb043a73ddb94bc2e83 *man/model_terms.Rd 783045db095103c24a5026a9cd516b57 *man/nasa.Rd 8080159689196b1bbb3cedafde981e5b *man/pigs.Rd 8f4aad003a999fae004ba9361f9a99d6 *man/pipe.Rd e16c96a58d59002cea25781fc649fcaa *man/plot_types.Rd 6cbaa828dbbfc062f797d7cc9abd87fc *man/plotting_data_type.Rd 18a0a38bfc06b01e9ef537431426adfd *man/print.ggmatrix.Rd 8aeae61731697ad035b83bf24bc9dbb5 *man/print_if_interactive.Rd 0135c93fdec59d4d375b6edf0c1cf134 *man/psychademic.Rd 75898788fbf1359f8892a248f8767937 *man/putPlot.Rd 7c1889ade41dfbadd2b3266e91a6b9a1 *man/reexports.Rd e436ad91b858415de99301ff6c2ec38a *man/remove_color_unless_equal.Rd d35494061c24badf1b5d68461961f454 *man/require_namespaces.Rd ffac1d44e1c0606b9e884a27fa29c0b4 *man/rescale01.Rd 31363eeaa15c717367f1245a95db12ec *man/scag_order.Rd 106b5e4f0bfa0f54c65c01ab85e7fc97 *man/scatmat.Rd 67474385131500b211522f1ea55719cd *man/singleClassOrder.Rd 25c66ede127b5706227c780f3078dcd2 *man/skewness.Rd fa652c1bb1100d688d8a3a1d2b70a76e *man/str.ggmatrix.Rd c299367e7440ec45a0f60859d679bb96 *man/tips.Rd 5e328e96e1363f38468d558d5fa94b89 *man/twitter_spambots.Rd 6c026085737bcf7ee20bbcfadc0dbc17 *man/uppertriangle.Rd 6651c6e074ba57977d211d419cbbfe95 *man/v1_ggmatrix_theme.Rd 778ad32efebd7eee73cf5b60e6254dbf *man/vig_ggally.Rd c356d65e2dde13d47ebd3bacead8e7cc *man/wrap.Rd c8574c0ac0ca6add722faf05350df2af *tests/spelling.R 2626aece02bc8f70280203564641263d *tests/testthat.R 2c7748f1ee4d74df72fcf9096088a947 *tests/testthat/data/airports.csv 67338d429bc797f56a30aff4bb83bea8 *tests/testthat/helper-options.R 744d3bc2f2e142011a22bfa837ab541e *tests/testthat/test-crosstalk.R 1724163ee9be2d26622e33a8dbc12653 *tests/testthat/test-deprecated.R c0ccc9927a6481ed93579c8ba189167a *tests/testthat/test-gg-plots.R 3553bb2a2af0919aa2f5a259571920fb *tests/testthat/test-ggally_colbar.R 4c26da59a22baaa7694f0d4e10a87a42 *tests/testthat/test-ggally_cross.R b86e26de3e6c1bd9201322a50ec2ffb1 *tests/testthat/test-ggally_trends.R 326c016a02d3195746250734c9b70173 *tests/testthat/test-ggbivariate.R ac5dc98384fe89f66fdbafe21e94a1f2 *tests/testthat/test-ggcoef.R a75cc9e43e3cde16e454e23a8e4ddb4d *tests/testthat/test-ggcorr.R 18da86c87e1044a0abde25b14da6ba3b *tests/testthat/test-ggfacet.R c7cbc5ab799e98230194f63b3e94896d *tests/testthat/test-gglegend.R 5acfee8b7344f5b4148279a224df69df *tests/testthat/test-gglyph.R ea43eb6f1329ce68c7015637a29c87db *tests/testthat/test-ggmatrix.R c006b79b122bbe6264e476e7084f8193 *tests/testthat/test-ggmatrix_add.R 835f5dfbbfd28a998db1f9e8965a5226 *tests/testthat/test-ggmatrix_getput.R 31da47cefd04ab979f7d6e8e41534303 *tests/testthat/test-ggmatrix_location.R fa447d503f4f1672f6aeabeffd97feb0 *tests/testthat/test-ggnet.R aed0346bb6b6a3e11d025c957b02f9dc *tests/testthat/test-ggnet2.R 56b4ea84f4942d2428cf25820636ce82 *tests/testthat/test-ggnetworkmap.R 1c19c98e74222f97a663c3adc922f0a9 *tests/testthat/test-ggnostic.R df620275cb8df0cdd6781dddd01aa8a4 *tests/testthat/test-ggparcoord.R 312a02772aed6e40bbde2f740191c8b0 *tests/testthat/test-ggsave.R 3051d0f860c860e9cde8804bbb9d735e *tests/testthat/test-ggscatmat.R 971a2a286a2bbe7c56d3c2ccf4602dac *tests/testthat/test-ggsurv.R bd8374a956102a416e65bc93371262a5 *tests/testthat/test-ggtable.R 3555d24c34934f91fcb3e5f67d54f100 *tests/testthat/test-utils.R ec25b33a14014d7cbf2e4abaa5d9edc8 *tests/testthat/test-vig_ggally.R 39a14e13cacb70f2055d42850573b547 *tests/testthat/test-wrap.R 07a7429da0ebd947d53a2c8f5bb61190 *tests/testthat/test-zzz_ggpairs.R GGally/inst/0000755000176200001440000000000014527407231012413 5ustar liggesusersGGally/inst/WORDLIST0000644000176200001440000000253114527407231013606 0ustar liggesusersaede aedeagus aes Aes anova api axisLabels axisVars barDiag bb behaviour Biometrics blankDiag Broomify broomify'ed cardinality centerObs ci cityServiceFirms cloudhigh cloudlow cloudmid cmu codebook codecov ColorBrewer colour colours columnsY concinna corMethod covr dae densityDiag df dfc diag directedness DOI edu Environmetrics exponentiate facet'ed fe finrela formatter Fruchterman Gb geocoded geoms ggally ggbivariate ggcoef ggcorr ggduo ggfluctuation gglegend gglyph ggmap ggmatrix ggnet ggnetworkmap ggnostic ggpairs ggparcoord ggplot ggscatmat ggsurv ggtable github glyphmap glyphplot glyphs gplot grayscale grey gridlines GSS heikertingeri Heptapot heptapotamica herdsz Herzberg hjust Hout http ide idre igraph ing intergraph io Jibum jitter Jordano JSM Kaplan Kutner larmarange labelled labeller labellers linetype lintr Liu lm loess lon lowertriangle lt Lubischew Marsden McGraw Mengjia Murrell na Nachtsheim naDiag NaN Neter newpage NORC num Opsahl param parcoord plotmath preallocates Programme PV quartiles RColorBrewer rdocumentation Reingold rescale Rescaling resid RStudio scagnostic scagnostics scaler SCIE se SENWGT shadebox shadeBox spambots Springer Statlib stdres Storrs stratums Su's Summarise surftemp th Tian travis truthy ucla univariately uppertriangle vjust Wickham's wtsall www Yau Yu Zheng tidiers CMD gidp hbp Homewood ibb rbi sb magrittr