alakazam/0000755000176200001440000000000013514052755012042 5ustar liggesusersalakazam/NAMESPACE0000644000176200001440000001116113513671663013265 0ustar liggesusers# Generated by roxygen2: do not edit by hand export(ABBREV_AA) export(DNA_COLORS) export(IG_COLORS) export(IMGT_REGIONS) export(IUPAC_AA) export(IUPAC_DNA) export(TR_COLORS) export(aliphatic) export(alphaDiversity) export(aminoAcidProperties) export(baseTheme) export(buildPhylipLineage) export(bulk) export(calcCoverage) export(calcDiversity) export(charge) export(checkColumns) export(collapseDuplicates) export(combineIgphyml) export(countClones) export(countGenes) export(countPatterns) export(cpuCount) export(estimateAbundance) export(extractVRegion) export(getAAMatrix) export(getAllele) export(getDNAMatrix) export(getFamily) export(getGene) export(getMRCA) export(getPathLengths) export(getSegment) export(graphToPhylo) export(gravy) export(gridPlot) export(groupGenes) export(isValidAASeq) export(makeChangeoClone) export(makeTempDir) export(maskSeqEnds) export(maskSeqGaps) export(nonsquareDist) export(padSeqEnds) export(pairwiseDist) export(pairwiseEqual) export(permuteLabels) export(phyloToGraph) export(plotAbundanceCurve) export(plotDiversityCurve) export(plotDiversityTest) export(plotEdgeTest) export(plotMRCATest) export(plotSubtrees) export(polar) export(progressBar) export(rarefyDiversity) export(readChangeoDb) export(readIgphyml) export(seqDist) export(seqEqual) export(sortGenes) export(stoufferMeta) export(summarizeSubtrees) export(tableEdges) export(testDiversity) export(testEdges) export(testMRCA) export(translateDNA) export(translateStrings) export(writeChangeoDb) exportClasses(AbundanceCurve) exportClasses(ChangeoClone) exportClasses(DiversityCurve) exportClasses(EdgeTest) exportClasses(MRCATest) exportMethods(plot) exportMethods(print) import(ggplot2) import(graphics) import(methods) import(utils) importFrom(Matrix,rowSums) importFrom(Matrix,sparseMatrix) importFrom(Rcpp,evalCpp) importFrom(ape,di2multi) importFrom(ape,ladderize) importFrom(ape,read.tree) importFrom(ape,reorder.phylo) importFrom(ape,root) importFrom(dplyr,"%>%") importFrom(dplyr,arrange) importFrom(dplyr,bind_cols) importFrom(dplyr,bind_rows) importFrom(dplyr,combine) importFrom(dplyr,desc) importFrom(dplyr,do) importFrom(dplyr,filter) importFrom(dplyr,group_by) importFrom(dplyr,if_else) importFrom(dplyr,mutate) importFrom(dplyr,mutate_at) importFrom(dplyr,n) importFrom(dplyr,one_of) importFrom(dplyr,rename) importFrom(dplyr,right_join) importFrom(dplyr,rowwise) importFrom(dplyr,select) importFrom(dplyr,slice) importFrom(dplyr,summarize) importFrom(dplyr,summarize_at) importFrom(dplyr,transmute) importFrom(dplyr,ungroup) importFrom(igraph,E) importFrom(igraph,V) importFrom(igraph,all_shortest_paths) importFrom(igraph,as_data_frame) importFrom(igraph,as_edgelist) importFrom(igraph,components) importFrom(igraph,degree) importFrom(igraph,distances) importFrom(igraph,graph_from_adjacency_matrix) importFrom(igraph,graph_from_data_frame) importFrom(igraph,groups) importFrom(igraph,make_directed_graph) importFrom(igraph,make_graph) importFrom(igraph,make_undirected_graph) importFrom(igraph,set_vertex_attr) importFrom(igraph,shortest_paths) importFrom(igraph,vertex_attr) importFrom(lazyeval,interp) importFrom(progress,progress_bar) importFrom(readr,cols) importFrom(readr,read_delim) importFrom(readr,read_tsv) importFrom(readr,write_delim) importFrom(readr,write_tsv) importFrom(scales,log10_trans) importFrom(scales,log2_trans) importFrom(scales,math_format) importFrom(scales,percent) importFrom(scales,pretty_breaks) importFrom(scales,scientific) importFrom(scales,trans_breaks) importFrom(scales,trans_format) importFrom(seqinr,translate) importFrom(stats,cor) importFrom(stats,cov) importFrom(stats,dbinom) importFrom(stats,dmultinom) importFrom(stats,dnorm) importFrom(stats,ecdf) importFrom(stats,mad) importFrom(stats,median) importFrom(stats,na.omit) importFrom(stats,pbinom) importFrom(stats,pnorm) importFrom(stats,qbinom) importFrom(stats,qnorm) importFrom(stats,rbinom) importFrom(stats,rmultinom) importFrom(stats,rnorm) importFrom(stats,sd) importFrom(stats,setNames) importFrom(stringi,stri_count_boundaries) importFrom(stringi,stri_count_fixed) importFrom(stringi,stri_count_regex) importFrom(stringi,stri_detect_fixed) importFrom(stringi,stri_dup) importFrom(stringi,stri_extract_all_regex) importFrom(stringi,stri_extract_first_regex) importFrom(stringi,stri_flatten) importFrom(stringi,stri_join) importFrom(stringi,stri_length) importFrom(stringi,stri_pad_left) importFrom(stringi,stri_pad_right) importFrom(stringi,stri_paste) importFrom(stringi,stri_replace_all_regex) importFrom(stringi,stri_replace_first_regex) importFrom(stringi,stri_split_fixed) importFrom(tibble,tibble) importFrom(tidyr,complete) importFrom(tidyr,gather) useDynLib(alakazam, .registration=TRUE) alakazam/README.md0000644000176200001440000000273113402556374013326 0ustar liggesusersAlakazam ------------------------------------------------------------------------------- Alakazam is part of the [Immcantation](http://immcantation.readthedocs.io) analysis framework for Adaptive Immune Receptor Repertoire sequencing (AIRR-seq) and provides a set of tools to investigate lymphocyte receptor clonal lineages, diversity, gene usage, and other repertoire level properties, with a focus on high-throughput immunoglobulin (Ig) sequencing. Alakazam serves five main purposes: 1. Providing core functionality for other R packages in the Immcantation framework. This includes common tasks such as file I/O, basic DNA sequence manipulation, and interacting with V(D)J segment and gene annotations. 2. Providing an R interface for interacting with the output of the [pRESTO](http://presto.readthedocs.io) and [Change-O](http://changeo.readthedocs.io) tool suites. 3. Performing lineage reconstruction on clonal populations of Ig sequences and analyzing the topology of the resultant lineage trees. 4. Performing clonal abundance and diversity analysis on lymphocyte repertoires. 5. Performing physicochemical property analyses of lymphocyte receptor sequences. Contact ------------------------------------------------------------------------------- For help and questions please contact the [Immcantation Group](mailto:immcantation@googlegroups.com) or use the [issue tracker](https://bitbucket.org/kleinstein/alakazam/issues?status=new&status=open). alakazam/data/0000755000176200001440000000000013402556374012755 5ustar liggesusersalakazam/data/ExampleDb.rda0000644000176200001440000035112313402556374015313 0ustar liggesusers[sݖjh/ A謸8G8 PPPP $PtRL*qRI'$.\`/Z?ZkL)tP̽}QHKs1z?ÿ_,_ɿ/?W{'7(헧C[jkr-su>o5_Li|u ~j~5yLSwuƻf^uf{Ck|;yޞؽ:~Ya^]??m: C/=_:ٹ/dtXF0}nMGč3p뫁%m:M.ɯ9pvs֝LW@olnZ^mSyXK=e|VT{z:Ogasӟ>֯񵗀ӣ{?;mCyy:ut7rۛ11O/ýcܦI}p>,nCg4zigǞөɼpv1t3j߻Wnutji}m~h=9/ni^-hpWXjK?to+N.ڣ0|swܛz`r^HY,.~-&oahqsI&;#vgۭ ygҟW[ǾtZ8쎇&iw7=zߨÓBݑpFg:4^:x|u}}s^wzuuybꌝW-|ct?;j}hv&7={Ԟ8f/n]78Oas]{x^y g/osVۭǎEo6rm&wGhi 7Y{4=yh;ntw N۷޵{# zO|ixtMxÇ#ԛnJPXK?KWI۝L37=WN{08rPm_&OPk<iw3ziz/^dnvI:>x_n'sogLN хoώ|kt``ަK7KUP7(r&r OחL3yscC7xVLF|MӧDz0g={Eq>|Kxwm7wryMNxwWhmw.>ƙ?ݎO.C{zS߯bٝu{[߭bt/Nwƃ'[]~qp[^&<~+6j]w h fi^{8zuK\?=gxu9kox7g}HNJqvs{/LJCFo W>6ͼ5wӃ<;];Wo c'm~9_Ur?`z}WWa<|q>ff 5=?9B"qoO#XO}g*'fri{K"]p`k`x-Y{$ aֺ2Ilw59{xsr;a41è%sr6%$枼Х;t6'X$r 2v So&Q-Z"NӧϜqu'6Jolj ߎtypNo.cXޱ5zz!M7wԟܶu:'vWnh Ɖkarb0:(_u{U;DV1||ߝ+?"OƓZ 򙑥6~p6`x.㖖]'yЗہ*ӻ'qr!kf[_\zA`~Ƚ.=v'acgrpzr6',^/}3_N?g &cz}͏/}7y$ dȔ=>zIB;tm.|Mx4$Au$k8_K,: <}ٚ>έW1$vn=}bM/3_حitsW2TmuzJ&ONti8]z_7뛏/>q:3Zq#sJvs2wg}__9 $ɭaړ٫θ]uu{3_w_w+W{y}<~՗{>OUoř/'DO,#ڈ:S{1S7K+򚨞M%!W/Yǭ;90w_U-/OD|п uyO{oۋG'ӹ:QB I>S6|GBk/ZݝOn㷾Ù<Ŭr`gtubu篽NP%O}gQ^yw}fzy7wNo^ rvc7s#=.۵Vӗ'_˟%Nz]Ћ,ZL}]7?۝:;sk_bdvz~kסb9ID3n׾={8Adq?Qs=լ.2>Oô ?ը,]j`~ެuѧ'ϯKq$N{|^/omnc;Q铯5f|+_K SvxͭQ:PZHqoL'{CO]o/:Hx\Ek_K34o zc_y>'ZVwW xku'K~fDkTy?ewyg|&5yo+opm7 =ӫG_Ξ|xsQw~lp֓Df{:h}޼س'>RDN_;F4<}KtJ|>\:de=ŝĦ7sR2j7w o:xKT[b3ƾכD|g9#N%ǡ\^J׈m&zG-_K3pv\:Coq;YZ4|T׷~~ucy{g:g5<8g֝,|ge ۛugV`{D5~i{4 W ~Aw0D<$q5431L߮`w|m0$|Z΁GNыCyW;(w2!!^?3Ϸs=>>9~>ǝDf{zgJI:tɬ;oWx0褢;ܾ]=F&2Oq"wM~Ը3kJ'7m߅ԓMZ+չ'wcHW]`^kߑ˾מCof}[[Yx_;;-U\|j◷:,%Cw/,=Dž1 r4_:K #`>ݥ[Ʒh;Wawx v78=KU%GRg=vGO;>ĎKp=eG_v_;E]>᧮ϸ $,O>ۓc+a7n}_pѺ&n|Egr~\F~WL@z{{>߹Vo 6;å_3q_nF=pqg_s~'OĮl-z_~ݹwzt|?k=bNBs'&3c{z|z܎}?z5~=5ݿ=-(O9^y X:O'?ĊK;;q~{6lyt0 Q^%ы==goYbOͥ }ˋgg+N|=-S/Ӈn ?%t}9Ao{my=~oq&>SJ,\tճNF;6=ɬ-}_%vp\ twMl;T$<*PW>̇wOa0^m'Ov-~|%-o]ߑ;>բמ^tkm̽ujGOOuv=Jx+kg][ӣ/_~|zuW2:_'lt#;[_q,D c߅ӕ%>?|}~>_Js|'5?}w},M>VtB]Ѽ;*{3{L|El% 7CtZ~ r+,߅ڝuΛbة};l5'zڃDomm^޴zU˟ n-?&γz{;ܛ\HxwϷZ2OT/ocHT=;﯉?N?HXw_oۣ9GwU9>K\%zKTK~ߞ/}*?cb~'w-U;optc^μY; qqFW>/xb~޸{,hK;OH/I_Z,&{JtN.G:?Sc|n4y^acfrNy=L٨w:u}nEDGB:qnO a{4{]k"W<P;_xIwG3p<{o $t}dB.Γ:NBOv_ei;I:xLԻ^“緗~R|[;Ӛt߫[NtOn/Gl]u9x;mco8gwx)i7cۮCww>1:_&f/ӳ?mm8{I(KOa&ޢvߟ.滑Vd/-R;xƃ{ N;']w>ݧ8!ǃ硫/'̥ճl05@qg gݫD<;$v89ޡS˓2̓ ~'ww;KW|\W\~b?__ny}Oү~8Op;z=͹ ap:/S_꛶^ƉϽDߕ>SK$zF~MekG"Nj4 s/p{7SBhywGݑL$QY{L}7w}:<={}H$'!>YQoVn=t'{1 En|u7{ox' ׾ίkKR_ݚ|D_u'~bljCk^|fo4r2W%\/י?)j9>R/&7~_]..{l2կ1o%3#x0tJ<;3dxMD3u8DM^vF.BW>ϦD~1Iy8>EݰEz仂6S.оt_.no}S,E+1)kj']F0qfe1&vDNNY<\}5%z4Jg,x8K.?~b;SsكnjgU/ZD'R]2w,c06=L}>?}{}W]߼&Δ=$UKm{7ަW/@fv8O?q8jio1ˑu|gF=%-r;aMG햯f#rcO׾sv8_.nǡi n}\\ܟePdY}.~>{Lۡb,J 'y:o#OcWkr!>^]xx8ytxN gkrMo:x題)qbւ *L||A ?ެ3_LFl&eoo^/|4.?~.[~/|zg(qM7t}ePTQiq[Qw`N ^۾$j_׉2?yL}ƐE~-~ H<)K '7o!//ۺ|Ot-#;ߥ8׶K_?^L\E{IU>^D'qO}ؗ=n%ΡQN3{~M՟=_]>wࣺ٨o{<1u݌|u0}v0RgyuFt{8q;>i'a;o9m>J<m_QgO^}5zݗm:&/|`v3TfsNs$KmJ^.Ư}tpz7Mv6u-Q#J^oz?g,uGq2x7KD_mGwDnM|@Ȳ#OtȟLܛ?W/C"|t=~%|?;~\Eo>yyvI]̅^OvxSҒ:#!B`qЈOT?=dž?r~'2ৄ_'^.+cx,#JbWc6ߋ7fg}''K$.#E_g{rwrgwgd{2&rНI2?:tYh8|8|}LhǙf/7ݏ}<4ElQ[\Esmm~'%ǫ`7>o_ _yz峷w,-õc|1%=Χ_&\u1O5~]_g鶮 ؓe|cFa$ss-{\]ҍ͞]y O͡OP[~2q3IֿНw|@kvʼnȪ=}&;%zFk[k ftv i{n=(̼Oyzt˜==tn4Q>/ݳ^uA|~?xOx?C>#PfKwoq8=.KiكwL[ nޖ6՟;=_n}$1I}YބwA-ĽWxuZ;E't<7N9?h83~ymQ/1ysKv~fmN\ۣēf>6޽ҥK˼e{X yj{۽Xty0q]:ѝ7=GHwtHo1 7_Άi-JCAb˥EE`^҉drO}]_)Ng7v҇YJ}{[8Ke0+ [[<"_ٙ['^} pʽE—{>AG>I?ܒ[I pŹD/?'f軺OO+^ָswwwud'Eu:q~ץ=ٙ?y8n^3Mw~x\g;v/qJۛ%йݟ ߟ:ѫK >՟/CQ>W1{Z.<%{{rK޾.uē OtqqO2=UH<)v"3ji'!Os`h<@z4KWlX;ptqOs]nO{NJ ^|f(/ӗtKqG׉s^|5LlL`$;?a6I쁾~ +4$S]*̨8\+2{i[Թu oԟo}rd>3қ/>ǹz`ywYx^䵗x"QN2?O<h9\/o3Oz.u՟I+#b2Jhˡigy̺wd/ns;GwdF ?oZb{zNš}^o~b.61?9\d~GWދMmN7uo~{3OAOdˋijq(qҟVH_}|I!qr?ǥKDbOOJ\L~Wߧ֟fWS\1u[?Cþsv-˶5n%Nl}?y/#U,-KYfӛ[ы>haOSn`Kkɮ1p5y/sq{r2yZ$q`x8Od}8s'M.5jOn??vIg]5O}Vb<|Y6ΐ37}tyH-8qx|"ݽ?7g.LwZ^bO΂zagܿ{.zxtD'w 狖god޼~kޒ]qk<]Ύ~}uSׇzr{?ߞLo'.şZ0%|ĹmQ|8UU)$Q.zz'_}26yb26k8m-fxMߡ8{.V,Oxp8c}"xu@.8Qx9%*1|K<fNa>ѭMDMj'r܃ e^<of 7! Oٙ,_.^gZߊIo-~Y?Haρ*[^xx+cT|G~WEBq1HX?_--Ơ#*8 =DSR\,nx^@^Lo_Xrsye*&/Ng1osX^Y̘8_0d+pf\ &'B BbcŅ<ZL}K%Im!ʋ.!%T nʋMF7b{%Meyq\)%CWf`y Kžvf}MU1|.60*5꾚R6 ߛJ:>NfdAh8:Bkq=Yމd9 dFAAcGqsB:gYv1~"9N8:Nؖmq32a̲Lv2Zԃ>9jO::fWȊNqu]XDiֺtBNdGc$jKW 1m k󨵣waH8(7`v5K#Œqe]Mġ XP;qKͶ\$F:Hsո\Įo\(úb+G[_ )lͶ? ^Pw`Jv|5\s؞|\c.:&Npaǥj}J}Sf^ghG m|򒹜 z,l Yz&@Wڑ&1k1n} CZ$ɭW\[8`F~S+e\M[njejBȻ7;{&/4;Nz\ 6Sc꒡C M!@Z%1A&ĜAYI@pŕ@^*2q遽@lp0_pV6A"B !$D@bD D\'V/)s~Tլ$b BE"qe B瀨H B5F1-Zo#P{HS]@P̪ a]ٶw& 6x&Z," tLA Sn%\Gf~<@8P  ń07c䄪 5cu&v"Gf%Er \S0؅`E+غaTL~3{;ړU/eLdVLd<#3Ҧ<y~yQg 9FQJ9t^5Ѽ<2?` $'~OZmH#).f SdKBtÎ";H쫲*@^Re N u )U7U"1'mHXcC6C P u 4@Qר[ R @8/j@)?:B^f%6dbyKo)CspeAC,Oy,7D^iKVTc~BQJ3ed vUz@AOZh;J}i$> &9+%" 8|vnd*E*PaUFv-xbL,YΆ(ɢwFu8C ]U#Bwa50MDG:3̫̰t~L_ 2l1P"fNVݐUfxXh9bD'cGfXJd6[" `b$Rܔ96yC8 y8fq(",q3l#M*z!bP a# {=z q-c$q8V.**eeɾ WDZG5v84M< UKf^bf1AhPG 4Xoi #F7$ Uߪ㺂  !-ģ0MrЄg/TzcLPd0.M%2˩JZiMʍGy=k)M{n_E [#B$-FZMB3)J~~ն k€DITs"*dy2f49XrK%܌lJʄYZʪ'E$,l!etābfg l g(T^AbyIE*CɒP(s0P8mi(~[ _5P; Zg2 05YRPRZ 7Zc"aP2W`;QZ ~J ooWZ-G-@TIKd;YIml({EҐavdAAȞ ʈlW,_Bvśf،@7AP]"*MO`mkO0y7\* 8-X%j0{=4EGaK1@W1VkMA|S5}K9b c4#b|s U@&a3)A0@4:K8 /$A໥>$tͧ@U* D]@ LV2@ȁ > @Y5SX4]jT$"&xjӢ9Ǥ1֏/(FE;HQ}Ʀ DQ^J@5"IQ6&Q0TSՒJd) ݪ^S1zpԲj;9fPO5f@l{M|=EI@V$HXRtHJ@(Q iVP/ {Ĉ/Cobyq Z'A; 7qPhx3$@ ?Ԕ V$ (Ae@Pt8c hh 6 m$HiNBPvtep%TTQ;Y֫8lDTJn8( >I'͖ V:@Pkŧ@Нk H Uv?B tRbtmxhv1%P[mMyskft#䉉Zt2gdrh'd ƙї2 .a G:w}=kv4DKd(!(2/fS\ܸnout"3U_dƮӇ]AClmP 1ʌzn$XQ ~|4>B h8OW]RG_(l\o? '2<ű4bX5QF i 1@AHAn>]`VNF]( ZލbV-'k85w+P|ug(Uݻ'T H44QdDTHwB|C%J{ 𢀔B̔|LeYRqgۊ=ԯbrDS]bES!~6z1(`x22_Y(},` ftjMtlYRoM,XBtI@B8Ql7r t JJ>TРDVL,TP$Er#7;E#PKo"&k]LHB^dAGW9TƌX|d 1֑YÉi-OW >iE9XBd+H7Jq8&\F? %1n B N^$&6laRO,C ~]bَc4(-/[tWkXOŻX@ B :/z!x&" U(HBsl]%1=|,[ \fȖ#L:JJnP:[1*T!f e(ܳLѷci'=мֳ;CUFHYȥA`ϢIɑņ:ԠfuPW- eΒl2Qք Y5a/fdĮU|:'; #U_l樓pBF8^4321 V;.3=bqI~ F9zDF H5զ>~ H*%U3*^٣AeTH0 H,[]\-HҌ͗>6 i671 4r*V %V2#a"uq%c:5&5&52¤c×x/MgS # hHV%ۦcΖ61锘Pܷ)`u2SKSq?j؁‡XtBL/SxYN-Mm0֜?u 5".5̃۸N4Xie.y0)VPUj ԄӻԘ 6$Ω7V}KǕ\r$&bD;k,/P6pм. kPք=no\˸HWdE,3r!Kq .{\0p96ђKHrME_l0̇Kmw]f3PyPLHM"3%pc㾯8ԘXLͼ>gͼgss:U+$1f7μ6!5<^؀ ̇U urձ/311zLbH01})&rKFz(xyM,ZvԗAZz)L#{;p-a iCn.cWt|Өwc h{,XqDh1f7ο[>["+dXQGqy:AVB!NB!鼅f7yUv)DCVERVOJ(-(i֐h+JT%YccP3%$]QBII*eq L(IVr`\*Q$MJ@Ɣ1eL;`JRa1eGG<(YSsyt,w\+gfWޟ)RDR(/6ʔNHZԞ9(]j6nbϔP(EL 2b!4BjC'YƋDZgCdY:,UpZ](5:BqhRRgm͔NO)ۥ@)k](#t@dEmE)(&!RykH#R :S{:@I({&P Z0[ª';9( ZKJ!QZ9Ũ6%a/e,D)ďNjloEe]r BxT|։Y2SQ*Lsohu$=ϸ=pkQhӉreRl z?/)'N;0oeRTA(S&P0܌VW[~F)*JRK>X!'k-&;\ qSdqPqޅj0z bP-ST :;dR8mMWw?xiRpLTLJ@,4u>ґ`M]6ȓ j&YI RΓաwjDȶ@:Xx*0W4'Qَ87pPGrqGU:5 8+q/#B#p~* (J@UbJY*_R,DYb{Ua+ئ)F%\|MqqQyyjv7ln*:`oQtPlGp#̬L/YD# 7>}=e ;#QtqStNF'U~"#̿]ApDb6`/:[:f$E7`lJIB %1bpH[ *^UfUlj8KoCY'g$Җ±|"Cqh# =ɷtҁIЀ,$0a#ճ:L:,Ҡ>1{kS%Pf,Sg~&9dmT`h;V(3I[wg" b1מDeiYFwUƝc jbb1N6"U6S˺vࣸ[z50f6G%1߀\&PQeKG?!)Ԓa'S7U_*~6>+n6`mqX]?:1|>Kl5#vJv)AO#L8\:VTdv(ve4c.nQo-; ; YW]N>x* uYg~;`tl Z~MԝJ&weD ߹d G37̕4h% ;ע<.J+vB(g%--3:j뮥%2eV O-- ,Gc{F)Gs_it]U(AY|rC-!zg8$bӃt32HOqgu!ʌNI:\EY>ڝP$!WY$JwȲ}!^2\|D[E/~TQ'Y%5PhYr(2@iz iD@Cs?q\,eI D[)u՟Oط3#Yr& UAܖ UɼZ4Ǩdd# :x Qŗ!4a({YF#2Ŭ2{>'4gdKX٤HM4֤i/he'Gg+)PA/"h1 3#xqjְʋFX٩mk|eepI-YMdMQl(]l ɶWbIm= @Fކ &M`PiJLtOqM]6ʊXFVAFWKVmg##vPLz:6 #в-;52Fh#2^%}QR*ep?pt: {0rtΧqG/Ǩw5O(hQl՞ !˚ړ$5<54$ /PT^a Shbq}xQ&t5o<Ͱ 6lJ6$"qx8u @c`}4w9 ca`ґ:bPu9(^WC_IGtIG6Б@,ܚNl39҉Љ~`3SCٌ*: h{d*hЏX{fVtpi@E"`G? *<*O $YَbVS>C:OW1oPLqJ#MQ"r2:xY~b)"q[TM?f,XOqoElOa/[!PCd()D(A Nؿ2s9 z/R≩ )^٧\8\Joh xEgNsם"@ 'cKu GymM_X6cOƔeg";pnZ= Ag/.+)6.ʳ 5:l1q )ѢT, W\=* E;]qA:%&tᰍhςUU;,%߶:(f!}[>2A(^׃C^'loO獤ި3"kUE6dޥ)(n{u/Tcj֫+C4TЫ}]N)Nu0`ʰEST;99.V{aJ|4Z6Jw~4͕ YJSnoa 0e@n_$fjm.5|;ˀd9ZvEXufW>IPo=yfj$Yŝ @f0o/AB wDkIx4`&8{eUN^JCVb@M.)ǔ)dw@|@nWC}mP6HPAaa.;[~LS=Na ׼) O;KЩ Gh3 )8d`kPVI`!nC`UqU'Kf6nG{E +c]vd;h G@v vP6%d5TYJ1(dҩ|]PW`cK>^KQDMv>+9N` eI[2THdG'9 u`ʪ |(9 +MR'uG9JSng޻.t~]:eAl'xSs:I~GMu:!؁Ff:>m5F:>*t#5UHhN+|AvsV]Q<]&;Z{ ίhw`SG0>sStԼ}:W.*HG<NБ43{%*1TtYTrP{﫩gGLSDJ#H-yeHHSET `L a]TkKaT#BdFiBҧyE+"԰ ?WݲxGS93A^L@L!ԺAIuR]`fP'VۡdIS"$i%M6#fwzPBVe,~iPp PY6(&[TAnIA 0 J*4l@mlkU”16ivc d= P%꫽>u>Rh ZF'ۨd:C`bьPA^+8PEvDuA PYVq:H " ueƛ> R)'(WRdu\,8( +,4VZZbЪ*'ˬkw `TX?$+<ʲl5"vVLN$p:ubYCKH闭 $[h ¤)4AMZ튈ZY6hCM -2Z[1c%Z+E&4eK񨵫 Zf;̧֝lyC|s(whRKhM|20sW%::5 "R0G|irf9:-S _sٗa6Gs)Q\\un,,~`2: (:͘cc΍YB )Bas J6{t=/Li$- TB\C|$@aax-wMBC{` #XiHfɩEr:@JIM5~ DQM?O5@TD% UD+@1EZY]Oj)5(áJ΅ĬX0G92ՃEXڪ *A%uuRvtLzKi#X1rl*g9ԎpEYZkw"r3kxW s<ۊI52rp6KRCQ &7עZ80@6W?5oCW]-ͲjUJ#B#d喽ݠ Z4HF/0k?H)#!#\DB` [[v+Doc!9SA/7D ޡ5/+b?#`e"U^=69ʆA7].-;D7$BߚHFwL$DU#[5AU s[x&-5+C5M_UV@D"ǵ؂D4H "vVA-p$UVDV]vA Kܸ UbGܕ*DJ;8)M$~SqAkTX@hdBBZ~.1 J(xDOT GPč mqPBB(K @k,(@6J^G@kGvFBFl)$HuY@>DPR"hl1 a |Lmfc  :5#ȹGo@CŰr46q>jlw AV%FZWc#e(zYL8IˣDt9`6x-r>*6qIU4x NTn pɖUSE.R"=;%%\=ؖaQhXn?r\hFe(l1PA(¶("Ct%Ӌ}>,>i8:pvGw%7}v]m6R9;:j50bƅ2+}э{pR\-sx[I#ő7hs?"RHqIJezS9ȗ)ı Ԉ=)pxQiaIdF8[UbLtrj{RB.Fd6d5GLR7NN$sPLD`XdjԭD~#uIO> SVOeN8jf0zpp$ejk0ŧ3GBFVX ܃&m` #)Nd04hS '"_EVX8E>²J|z"8̸ b4OX$j˪۽ XN -h*!=F3 YZNU+'ivR}_K"u6RR2ɬ%6Zg-um_J3S-B.%@hN$͖̟l^.@1u-eP'[&xL!S@w_Ň5..ImR6J i=Hf(@',l+M͸X1,VhiwQ2 ёƔ | ry!3Z(|6zslH:[~/F8Y MCwňKnRaTq,-*mq=nƁ9Ũ',1G&FjRVےA-*'l>!=XXA:^zR!E*@*oixqʘbnjěQi1g54Hk@P].Klh/0ɏ¤ζ- )Bm @!ptLA:@ S1a*(eLSUIP ܚztSIP* ʇ&Au퓠'~8eTAQ}=$')BɔwTPk3%%ڂDnO)ۗ7(ٔ%]J=ڿݤl\Mf#J氂`-fX*jHSɒ~dTZLDysp[*b1J)H{n,}%4}oc#dJ+JgS"&j:%jRm)'xZC{'d#I$[S,Knj# <,"fӳ'~l+:s\gkWmzxM!+ʀ5W=_8 VV=_}bV+; iˉ~pmϗB2ZFc\>ʍU2'TwahlW*sgrwhFZ``|hƦ%='x4+h5Nm~OX<}we$jFtʸ@Uy:DsۗWG4z׌l)=K3؈ݹhtϮnalb.$3Cpnj4 R@})|=.ɸ‡ jEAek'\GQb!Z30DV G͆-sd sVUfiѬ0%r >7PvIB4 {2q] 3p)(YHze\WƵ.X:nv ӊd\.e#R6spe\ۻ )hR2a?΃zVlx7 g\'.ʔGJBe\zM-zA\QʸN5se4Ht3m̡EQm-W4 =ɸN,]dfxk sƕq/.Y ט?Yߦ_cԏHuͬAZk.q4LFO]96|'X%.ٺ2\k뗸d\má-|Xm3PCn,a2g"MqC<<5ls-HpD+H\-ؿ$ɈZC퓞oGtCeDF061'PV&r"$[{8ȩ|!ꐍWZ|3"WFYLU:Z'# pabqD$91,#J{cKeal+/DgɈ$#Ms(AgZ+(Byy2r " ->s,#_M$bgO;"fD|["gz#Č|=JD+To ZouxF_3FKgVGRִ Y&&!CTv:C_+MS%Wδ;D;)gqDm:1;z*A@ 2uO3C.UMCեgmLei: Dj] qm/].tlNB聓iL-+3Pܱ:ө0쯸!$&- 5.D1!V8A*$Ki Ly1ە=Sg!=mz&9P[BEW$Q LJ a$PX)g!NmHNe U[e_trL:)TԪ⦾'aBC ͠sZntƴoNWINat-<+#>tWtPM&̫X)|mgQ|4z\Uʏ:/c:^zy g#e=vqjT!i WI׌glMB/dL'Ǥ[,j (9ՍB]INPHnqbyͶJkHz^a,Mn uҡm1uV9Ӫ|ItPY@oRxW[yi]1/6 M'cyh^IƖW `5ץ,FPu l+OTpX{_ c e@U%|dWJ1w?LxjGWCTEε'TwC* &CI$(S8^i2/PIP ОQ:5阫)0NU_+BI!D lf Ah W(}j2@!k=4q`-"L c B8i(da(Q B(H; 00 a3R i؅*vKm tS/0Y(3K?B1]QЬN{IAfc pnj$F.+\.\ ZtҊB[g(-}/uP58LaS VX欑G^o'S_b%Sr ,3[V  ڕ6HSeKÆzIA߂{)uB1lVWB!jCF $C]O!!F엠}4lGڥH0))`JɺŤAkFRյ[mAJr'9 i]-)DNFZ$IaFckv0 IY :P4m.dSvHمА3eR>V&9jrFG)F @(H;QhjbPʃz#U ;#ŶYOfoX[OifK7)`yMwlP͗]Wo$bNTt&gQwT\W˫gan V{bk!t9+w3)cJ*=6:׬2٦*0)q3Wbb  X8h9W_/2&1N"i?gd(c: 'N"/S:}YNc (*@b02lnO.J>4_(dL_ oqESS_4"nRLś@gw,ޚZ )?I>DVoX)&-s  vyL6^bWUzeJťBY&X{I4}mJSVz'i_[w٢yC.l1l|09Q 6GTAfI0&]Aի$crPk- _#M7tQ}}:&v-& I(u OEXЌ1AVեI Ia{FPC[wAGH^ԕJW`t?Y0kyT]q׿J =7-,uLoC.t`|dvCEId^=jD>s`SQRD8D2L`"{Kgo #@#*}d"GDDtdHSP#BDND,Bg#kk1+DjbA_(}B` `2"f @\.KXAFx=n^hеHHxZ6FP#:,5d]/# "4 f@e$<>IJDeKJFzF-*p-:4U˂m#^!f"H&JdC"(Զ^ZezK;>[\ b?d{#Ya"-JdLo5U6&02J F_d V~cš|*@@\'@e3L7hZ4h|? k:sNboH7&?r S0h)@VW%VQ5-cQT+$JC1 YSRLa# ޢB @}SȘݫA\! ܛ*8spp-\f"5.침"M.!E\/>F.hcR!>ir!E2$s9Mk~|}o_ &xof3~沞MG;2殬i:pA~M O d*gJʳ|;[T5s)P ?B f@&ժ@&/ᝏ\B@->5ߧ~{+T@wXUeMZ.1h姀Cjkq5DDPiv"Z8DI5f]|.qly<MF|!lJ%ֺX!N![VaAa>lD#4jk0+F4!5M(tXI#iF#`Y\*RD^1oFcu*z%U: 55 Kd4&+ZLc}^"$N~O4zNŕz:Bj8Afwz(,|XMRs<4 /.XPAww]\gg;IBCp48h 4v3wi &:7NR%+*FCEIߦ[=ց R/۹߭[IE;ivVNS0.š,b=B < YPBXPE( }) ,[Gѡڂ̂¦/͂W,B%GP2*`9baCecT, :\fQb {QYսaIqh_oDZɆ q]n/Yc\P/.RPl`R?ʾ$BSSuJV ߃w 49$"tR ك -X0A+(YpdzאBBΔ- f,\4 3i[Lu<9m[MM@ W[qTg:N!C,TAGCDHV,F6:EiWfUr@u.QhUPS*ڑblXM\Ns\쬈xŦ[y}6;e+G>-:H ZC %j'5W` \q!յ`1.jքlb+s6} &dOMsNpsEM'0|*A|![P1/ Ő5C>XHG[QZ ꯥŐbP,xV-Aa1Bb^m#h1de1XWTVbHATajԡ%0k%(_A*kR8+Nk3*.jMt+[{4@HɎa.nRmd 2' Tp MZ 4"a5H%v}XEG![mk(jo[df т_Pv?T촅1.SzRs4نfHAղl=JE!R,h2wAC+4g!9$И;ZGC54AO~}冉Ur?xCCu4Єմ:M&Иh ?xsg0^sVhV3URCiA?9E?!ه ΦԨo9S8^j,ruTEK;1LIlQepc|l87sUٸ FݻxikPnM^")WښokJ4BCGCCٻpJ4YxUV8~Ǧhs#1DR58XջSw; l=VGbK~xa¦hm/5F^l3D&" ?hӻkFFv 2.(ű %-ŇST"ředFKR׆ȪVvWFWHʖnS}¿ڈ"' ^WětV:`TRX5֒DeNEA0P9N(;/b, -TäkmPXЦޓUr-^1T݇ J>tUr1+R:Kd\4ZZE/l2U**t,PճqA*#ZdhFk;1RHTdd_DI\$j8$<̃a*)yR32ih2|!{AH!}2s4 I{MCaRO9:$*&aCـCDм'$K*ۡh3ydFxg?mb>z^=Bִ۟ ;1eXNbX-X<-v68::Z j5m] B3lawU{ѡscV#&,fX=MSft0#uǁcU**#Ό>PFL ICL\ߡb,>f]r"pNDG~74gТ[-Ocab puS|$Uv7JB|RLB5l6归!oG+ɢFQ6wP)FʽD1Ty: -(q(}[Y4 qv֙M!)eJk) C6P JRQj0>%^QHҔJ)"5%ܫcJɠq<߲$Mi<:z9PjJ=ۥL)Sʔ~GhiIBxt لqXm\J|$J܇S R(Ɏ$:' kQ_dY:,\ioi Lt/RUT1gJ'+֑`.eJR1)SƔ~,%oֶxy3Uu+yr^5I)a{˺.teJ'%lw}wՌxm\!y<pϫmա7Ymq ^ڈHs^@cΉP) *>:cJ@b 7b%FoD!(s(Sʔ~iJ((;*S~;SR]:%ud5fрW=CYNi6+L L#;*S:-%VMo)S:]BN!Jm) ckfk&LJgҖ2dY:&#qYK))J!NhIDiJX]H(1PbQ)(WEF{o&oaqnBPNE<Қ14~5J(!C9}ŴDC:-n7(p|(ePsp VP BbXXg V !iZ )`GnP Lzu0G(JDm6&W@JmPNK(/-%cʸ43ώg^sv71;0{8N方enCEp_5Iƥ(*7UP )gKi4yXW 1b#:zgj6ݱu*g$aZM{DF.E .3JP fNj.-A T,BO6U,-@}J ;8̨kdTwkψ$39t,-Ῑɧ. ԡVwLP0L$$D\KGjLgj5|CÐPNAqM5oaORP> 9&dUI0Z1)B<LgI&Re]EIJj)Ū'rr%K]Vj`fd&jt)|f &o y?8~q<]PF " Һ=p}3kteI2̸2GJђҕqe\xWgjhZ`S˸U\H\Q,:˸~#&ĠK Jdcb0 a̩h1ǂ=:voՄS*P-dԲJ[Za/b櫸MJ+f"$h#,}+04uaIWaVFY0P_+0eiXf`CfS&egb y[ d֒G,^#YNE&Y^,NdlB!4X7 C Yڰ?C`P^Ȕ`;R֞ew\A̔m˰ ՟MrZ',O#a)TxĽWCՋ:!Y ~da{OZޠ!Ba}nH 0YA]1VYfAL139>I4FJL<[Va 5}< &[0٨Qj%Ku3I$"1˥fX_%XCB2|$g0Nu T_BYf,Y_ K/w&D2YQldw0J/*0: GT,*7+| װKgDqw `d &+4:z[z) KjM"b*9.Z7MӶ?5d̀eF8XˌX\|9`GPXŠJˌvHKUXm`n]jjq瀅."njP1 I%p%If, Ҷ (pp U!gG N,*0n d8,r]3@_#96** GLYf$ 58a7!`]|J~[͏H D8%H_VMUk1".K!9ٶؿ&9кƋ{:5Ab)YD8P{[q%'m($8t渵gZhomMXPc**e Ȗ,|nf C4Jdun4ؒhwBjcQ5 IRa1E]Q2x \ 9+8bW;%& C{5f^—GPGD W ?3/Ӈ(PyQTO?ϲ0QzϥK"i"μָP [\Gk!`˼&A`~=ԟ4/CC\\vu/EM^xּatc/Abr-Uh=ՀCB@?yJ/F(_7K`KE%/cE|Q?[`I|P^dxيutԘ6lWےMאڝa*eo8,a$:>#q)#;*:*&˦ 3R)q\RceG15S*P :G/BשI:5ZG-4_/>HlzɰDmRf]F @_J]C9O6b^ΐBZEWlGrz ޠEA**"5d5 Ը`t8g۝|%Sj)vBԐ5dl;ב4K2OuG#dO3Z8֕@Ra '?T-v_j Kkz_ђFM!AUl#1͛k~dSӅCK>?KNN-;СQ'ىc̃-&JjҩavdQv&١ֻ[KGmEݶfCN# {"*ad/8v8de GHqudD_JL,nJP "?B 4҄6 /;P:dt"Tt kɘ-XXJr8z3/A>ƱAY텣6ÒԊItYW= )?g%>pU+޿g'My#S.ޔl(p SN+r.MTMyC{R:5p[2&ztXik4R4pSVa# "tb-z8f>rձmNk;, #^Uqt?RVdA%@RכrʊC*#4C8* uK6 j\F:xtwL~QJm .j|/ܘa|Vp '+0 ײeQjCq$:+|)%˥#*ͬN*`z4oEU{C/C*cթ jYgm8gV~^ի"Io>=|VND#<[(+J=d*%&Dm`XI)E3w[ o2- aT07c~Fsb.,c2BDG*tv UG4ThgE ݓae[RS Y tƯvqhE|*?mͩ,8< F*DR#16p }* k't4]昴&#KWͮZQgBz4+YdeqpB M)'>KW %~; 8&M[Q=mIgAM|98 G&k-5+񦴘GBsTYoZ'd4'@PW{HVr;&d6hL#fltC=3Z3qFsBjV'gt ,5O=h݀S)4+!vWLMn!Ҙ՚wVQSv7hZjC uY6,u`vN 'h(ăv=B349.(ھk,sنvN\,mPNBI+h|_ERl31V֌M QׅRׅںΒoIRTDdEM[f3ZSЀϸJM% B-4u)54S@ ktR fj_ rׂP-T%%k jgOLR3} ɦ! R!e ֮(zEw=f^BE4y1aK ecBZ%0ᲶrDm'kIof5p}%dPJƻQhP,k]և>$_FZ3]sPpPeX%@̕NMDj1ɪK-*j%H"}[46bC?EՇ %C^)!궰8XɴN򱞚t66luUYZ5mT3t]\JLg00\zwM,JL~vv@9:]Ij7∳8n@;* *olӧhϊ 5-N c"6EJ@>"j N0v&q4:١izzI:&jŐ,`*̏G?@_Z?^vv"Y;tZyC_=V5 I#̤jej_O"\lUYL픲 -b l1JX"vrpݴ}dj>(B ]FTΚz/nڛ_k,S"hbI:2 Y @T5fʼNEq6Ì%kq=5#+jVkTa5ύ'R"V ~{:쌃k5߫3%H]t1:LU)ꌰ`*Bft,Ff&B ڻџqE12EFJF\1FtYK'#c7 , D0\yed~:*0V鈂;L{ZG!Fe}dM(FjJ,/Z8!HXcTD2ID"zj10A8ԨĠ֪A\kaPa=|Poo!"5+||qq%']j&7KǧIG@h+VZ8Nm6mGٔ58NY ,g+{V'T/FtD:ʼȧKG@#TqqM8SwEf SGT] ^-phr W7ϪH+_`鐯Y+ tVdO(?ͳc&p,_C^O=;-`6q}mX*(ԛVVV_^q2vN*Ԛ`HC%(d8K{q,NASC7esa4/{N*8,ħ݂ {ZT:JAlM)qhP2,͓a%te ^Qfz=c}1}(絍-oEtK ׉E N&u()?9Q? q^G ԉH _X4e,us'eHHsGH)nI11 )c0FAl2F0F_*zö+TpAX^Dw8vr)&nufD.zp8Cnrx8 uÝuըZѨF; R尅Q fK8Ng;!2Vj%dsSmwYrF_83 I{\F .-pAY7BĪُѿQ!PY8CQߤ3 #nW"1F0f_8%d1!2 5FHz\WErzgħu ! DaSTr̈́#n[փ"]qOD5XP.VVKj&BR?S"|LATv:cD ߡLQ/:-$"@&c3 tD,ADG; lDR*XD8$ƛeN *pDI ^l5QO2- ,U3s@p4 Ntagc@5^e?PY"|=#+EIVM_mo=@h⶘ b!:뼦 TMP_ F+AIDB "DA@  EہXe_AЛ\&Y"5ݠ]VM R6158w3/b|p"留b{lY|B.:@ЎI? Qd#t<V6sGW4JDpDB".!D )-%Bwݏ% `1s ՔADHۈjRYL) I?5Q-鷾B'loU5pB5lW"kݜmnlC2 #P|J'8» }M8>}{#i EVM_"#Ҙ\N'Y'ֹf ;~cATC@U64mh_+"5 P^}>@PDp${_G}/jRz[K!mgY5Tj+imk .9n B<2AzR)l(n6 "@R , [tl.ДV[+R`c( f{t\A1},%%%Bn8}H a`!#լ%ŊeA gԟ߆ 8&AZT3)".An V>gqpƱ%t*K [&sҁ'<Nā!d[ }L M " Ï;n5S UGAK/$D$Co&,0a>C4G&.`޵j(K]bcAh B`l%,KNޥfv4]xCbmuvw^KJjJq)6"'SETr bRewQ dt,Ih*9X򏤪`d>!$mu~& ȇjRfV9`_*!?ȑ%x_AeB2ZFV@8բP dB $4m $RZ猬jG{Δ6Pifu9Yz8Tt(wd x 'vᤥ)mRșgSo{JI%F\JS%d'(QY`m'(EnV+> j2*ѫvxW\.Th0zӍa{`Uv`kA(H G(S[x-dz*,gz_Iä́Q=%V @ޮzG,f}/W6!b?(6'~c hTt᫪^2C^J4αXa]-ad',lG1N ),;' ر騙 ,;)@i4ɲ숥dF4[-eGd}>A,K bCtiڞN8+(PSIlwN`wwZ@>[-UEi6tVt0*+gI)!jrP@s$:{H?sNKI ^_¦XB*&+>AQ (cOM(lv;X*5B%8M p;E6U*(4wWt[v[kvq~)}妑uM#AMzUjfۜ =xaad}{inrtd}THL_Ẅ́$ :pJ Hedg:Ld؅< 3uFm-{ʹ(%vU0W]'s\2het~ZL<5\LfD` qP9gԍN[q5(tЌ]ftNnQ zVJ.\:cY3KNfT"dfDLfe#JDK44$P-ޡQqF x'3MjRp-@n~#,%UW BSrp:95Ӧ*}X ؁U DH&*AzT6g, m6{W:ۍi(tHo!Uj 5JǠLGh,n BM5 " >F0`6.n`X+߹h"4vD{AA ǝ3lH2|(-VE/g FA5L!Uդ&p@: yTA)jbhcl:}2ԃ.v E$D. ńU36xe<+P<% I\ 6jy-nj~1hLA5אMNU@"${2wekFz&eZnX2g&WVoZIek ] U/؅Z,9 HӀf B. SjRӑ/YL, ǕA*!FoCGe)jd/U+WpVB̈#T/9Cs?r?,#;-ӜҮJ&N"m_JgokQ9&MUf%Kׄ|TuR;]u5Q Z|v*!lS kٻA"XN.*UtI{3O̹Yv$[o{AНv>Ӂ7`()87m3yPTu6B!YDV dci>Z DK8ؾS()&M@xk T4A` , -TW#s D|DX$ahS"LųU NAM9 Qk¢lb(J1gF ЩpV`0#)+UjıFTk~X41%Vv|2Ghʈ|M~N΍'M>2L1$yt͉/'ڛ?|@xXakkԔ%7'֬5+{| ͕O|>d-W;3ɗ5jG_gjleKj-M6:՟ivq\lZ3bRZS&R R]F4 [^Z 3ZTn0v2/V\&bTW.|.;L췔L,+;2,c1>"1s ><ԉ D1%EPno[_1KE/@VHl bЪՉ5?*(]= Mbzm#lĄXvELcOLF\fa3 N,s+[" c 2fKv,iȲ!dz /Gl$Pbc8x25[EN5G.yGVzj?. \ h>zႰXNpѵjٗ,o%8. E6pSj(`LݘJ k]@.Zmh'7hP3=q )[?;˔%%IMPĠ,Ҥ$4źDJ)S| [/rBII#&'i5A{s HP"r7%jĬiמO][U)RUۥP%!vKRxJF,eO|<%*LV&}|d)U)1RHEH}.9AAmIYʔ>RC)ۥCRR t g\đٲLihӉLSBA"*HAfJC"4בcW[)XDc#$tjcJ( *%$mYn+XK |:Y+8wƐ<`#!{# S#p>>\ VVMl05Q|fsɶmwUŲ>N3$YZ/;+e unl'eVm"eBTYk-v#@<4NmWmL9t ?"k9JFa4e%؄'-atU2ԻGUqQso6Ȭ#Y!|J/ՈRM-gPB "6i_9&/jw^THѪ "Du-ԡdzFdT].VR6K(V FPBFQd,SlP/mk#ƐJ}=#FWbr΄}ٲy_abh;Flt*Ԋdh0-U;)2r A_Bw A b ryj"l7d2M-g7Rȃёm#egY-Afz$vjN,KYEY?) 35\VB]&5)?ٯ!e t,bpZ1JٶBD# 2Yyid?2!Cf Ś9RvŨJ+QBވX"#KCr4mx|22%AjәCFBYN15a:P]5XJXH Zj7 jLL+,.aۨRBg,iba*fJX:.ܐ׏(Kg~m-[,IW,x|IE‡ՄdqMMddqC(%Y,Hjct~(dE=2H ^v.Dla_vr! l F fڼ഑⺑ ΅q:X Vfcאp}Sh#OA|L\.لL9r"8AZZᢽpe:@BJ"їKD|\.K,؂bκ[l.v1u*mvlĎ-!+c>ޱe qVs1U̴fHXHdvmp5#S :*p=pgq9yW@'IEx9>/kHLTJd6!ީqQGdsdm0RD!/pH)]zCE| d,,T7}Mǂ.zi̪7^|Ւ ڰ}B.%p i. ]up4|. \dIˋ"p"K]w/oYmPr܈mՉsk[roprP* R#Eĥ4r:`m( n2FՂRc*<.9f_p=̥%|.le_‡\ .O>d?+e{.Dy)K \_h?.k:kǂ'V' b=!g PҴH3e3Z ץmg z:VY'@.VRtDZc 86.͞8` (3f'N=qƲ7d#yжH؞%눈Y ȪKQp4m[A٥" cF5ͱJeDD:>S%ed9U;8b֩cB};y#Di-*DԠWD+%H44Bu"$1 &ѝSз#;;,#HHw\a]FaqcIN/)s`V+ < sMy*#j:Xe3ކe[zBc̪~K( .42&A 7Ѣ26W.2<] SƔ1k@M %4gt L y*ƫf.nVÈ>(,XϘN0Js-$ 342Ge/LL;*vvd!ksp2 X*1{=mbUztD8C5Gy9VGz'>{׻w#!tH$HNh:@k"tfk6~(_2at1J"Jw{ӡ&P6Qotc:ن;yp̻gν?_vh١eBGSUo4<SMR^EBv8ړXODtxEtt&:GG5u? t0I):|R:YvtVm!j蘨mK+cSsS 9SgJ5РSsWv'SB$jMmbҡKÍ\$4C#WP l:V HG]|]EɊN͚ʀOFOonXֵ :q1e:ߑNF ƿ=t~gǒ|k|͖ѣEˡV/RNBvxgesr*G ;F1aKUj붤#1t Hdri z zSfA? Ջ xKЮ{i B8N!4ёѯ]=`.*3fKkUxi6iб I%T3Q݁N71knLR5tYE9duvX*d97`_(;)GAv#L&`H?F5{yG2)5,&[JJ.V"Dyxu,UBM)-BېItXC6#d"Po]dVHp,г\΢*ևrjr! %z\J`,RTFNkgAΦ;0$zήc  )Y΂;N%2G5tRM[AIFлK e \+C9-LNb^bkk`AikYhμ ښ7XHTܳE!lB,P3kXoWjV0ً5,BQ|\:of,|Vߌ 'E ifI3a;Ŋ8Fвo:h" ,~}[Qi6GQՏESG{Bda:J} >P 3RɸFtF?*X-ˢFS^ y ̓ܜ\pJb~ӧUZWzygBQ. T>nP/P< \8GjLNy!ډ5=PhJz"@ӠC b6X^Q jDP_\1"V];6qA)c( U\X9RTЛ2*)Ro* j4F!5NjeJP*թW"x::\ʠјO/¬gP'bhd1DؓY߃%!0DZ- 2#IT8qGAԧQS, _@9sUsFUߑ>̛7c3`3vl-:"(hM dCujҚ YIr|"TLPʹ >]EPLb^%(mF"Y//4Cǫjn7n!՛9A@bZ(=\X\[v pmTYκ~J_tu.2ML!*'\yr+f>PIT+ILu{G1H,3KRP)o"ރO[9rIĤW8r'WNnvSWgk[o'sȑa);CV8Gf0GN?r*kM#v ՟On1NP0O3(zb[H[2Dk`PiӀHV$zڬZQ)O[y)nBB敀[6 PXKJ,Aַ~ $(l 9(%( \y1J k :I'ElHZ@WiR)APM($oD) uUsXUqQXĖOHj"AճqU&#QNFXrn楺}d%(4$S^*qiL  D %AjCM d=: %O*Rs l$h59+ʾ# ׉HLI@X߫,lJvV6H%C{]r԰A# cBi[~śԥU WUvpPV"+(16I \}kUjBJj.5KIF)5+%5M1P#Vu J@Lle1 "Ro 넥%|అmHk^\ O\2o%K撹P mX铸^bE\%lxlQ9\(%$/Q^;ʋThNpAT"z.hCb\B-dyEZd.2]^}\ByO7p"=&p .eO.g˷e q\EgFGFlʁ fa?Vi06`Xo(݇\h=eLއg_Y;?pzO]T*.RUy}ÈC!9~=S #gicchhh ZpA!fD iO뒱23232wsudOK2.|[+xuoq%gqq.׶/Xr5ʉ9\dbT}c_bY8rjɡO)7OCvO\&0$|.^4pKm.OO*/xrSF`KX]^t/.o˴} m.\ \;־% ٗ7tƾo߱7q|eR.@tccG6\*Eq)KMr l 6B^"l \.e#\ /F^H`.K|\XVl/0n ,5\ lC^6Ń&dyI.pe\N,/>۠-p\p Y^".Bcʓr oR^ϥV^:f}2Ŗ\\Fes\cG6ʋ۸U.[c..p9a.(/7XocqYQEp$ I.m)wǶ /=a.~!,y r@^. _\Ge.i}e`.QÅxOfD⨭0ސ% ]Aj&K]o\Ng_\s-y{U^ȋSBҨ\m'Ih; Kr.y&&A~:ˠW].g?ʥ-.'nX,A;vqz/M\ɋR q].~qE.싮+!k_ҐĞ}4gľ+ٗf]l_ ز/NK^˦&EL-=҃q2zL8Lq8&K]0[./...0~HdŻ/id; t~'1N_js 8r_ԭpl.~/\dcm.e4/f%pc\X n28OW.QUߧ_yYK)_y\K.Ͼ@^޸zKc.2ޟ&\%`K{zzl\K /pp]=FX./%"^걷-/rq\% .\ =+zOvm.N,#/.ujD vRj(s<))udߩopIyz}V] Jvߏ0[^d] y\CA^ \⹹~z4z˄++ǹ8\~rʅY.o-{Go?4L%bK!ۗ$/7 ոܜUz\&/o TpMr[3_&WѬ++ica|\R^'o \r I.ے򖹄tk~c\ /۔}8uF?q3Kl "@^\\' oK|;\EpyrK#@^.~ҞXFDNXZ.'_{nx.oE|I^? W bK|S\ތ}.h<) m*`ct$7 \k6@^\qypY l9r/gˋ K B]y$Krb%H NWW.UaZX_l~jzDK=yrz!s\ް\e}_ /-s y\?K"˹.U\ɹ e\6ONX6*㖐mr)/\V /䲒I.]xו)&+a2c1pO%s#vm.Wsm.7%i.mrY,/7[rS_6rM?R!\N//p[w!e pM&DÅ(";L[ z+K"ة yg"8#.rqr\܅p\ܜ: s%v%.Cx@<9Y.xrlǓ'Ћ'싉' %t~e,/2ŵ֕G;\&d%֕y٦tt`ʥ|3\Ƕe\Ni__9/^0.tK/~.~[\ǮH^'/am/[^e$M.[&yp[K'aRTS\QJ.77%.b#.%h ,/-.j.~9 .%@^/C^KcW%˱eS\\'_%,/=6;p" \`\ /7~6 y^.[ -p|zеpK{..noDV"HHs:-4}撺Iu2`-!.gr ,.p)\}.ppt.Wh_f˴ p yB=֖r=..eUs>1p msqRHPrq%.tp?s)H^, Py8b\C }7/&u1Խ. 5JZK^,Wέ\5_٩Kk\\sz[.n?%^e"crF}1\;fذ?NYƲw!y9?vU\™S%p].[X;} PT K)FƓV=F~Hd2oKW^%cyE.}=F^mKEؗ>,K\|ǾKbC.sq+1p9lˠ}˕p9K9.ry/k>^ꏹ㖮2nYw8 k_K_5 =v8 !Kc땗r︹ѢkX0V&&\W*닣u}~c=XQo .p p%B^6v\ /r/\p,k=g=vzf\nPir\n W.W cW^^˥o-S-/↸pg/+KҺr}l`QfKj,ߑ^x;qBL%㾹!.ŸH1:n:׍J_*TF^1%׸/ҍ[z \H):\\`a_<[E++s<yٔh_ /S%B^N /r!2Ń >k]W6 /MۗɳȾ%Nq cu.=\F-yՍKՍ;S7c_ ԩ=%(ؗ0)/Ս>7_i\a\B"ss Y` /⒱.|5.xp 1mؗp$ T..])/rxr@>7,eK\ޠ6\[\1k_Wހ&9yr"r<2.gp@ޚ[mr_Hzg.4l\-aȾ~w{sq+\h; c\R4򹤰ݏ-.4.-/.z,Vcq-=veṤs[.KG.ٗtI)'=s\hrQsYuD嘹k?Kl1X\\}q .b_ޫ8`_ \gf.<'G82{I.pay?l]XKDå//rq?<'ˋ/K|ٻ6?V#/3X싇kE9.r\Vn\ e rSXWB^e%pu61}ppt./rjyyؗcrVi+6p .rJyy$.X`\=ƃ1ø6t' w&s)ԍ̥ye.RwSԍVxKJ?̅<2,}X%K˅saqx>OG_&G{\py_r}1\ %ۗ8l_\\!ߵ/aM7zľ2\J%}˹@^6%ۗ8LnԾ̱NJT_/KeKZ̒m+/XF lb=˿lI^B4.cy&mqy=vZ.~\ҥH4Xwnb\*I.oXkue-pIFh\$/r.7/Mq1\+a˛\vOvjȍ+M[j)UY妸'6?MiJx8Ѻ?p}MtY(UauKj)|<}ú @'`AhI,?O.n\ oxD4P%^mET,h 6iJYpTe|W, Z5ku#YεHEZa5/1|~nE8'J/G6AdDq)[+Y)Hmzd}#RWHs.t>9iأ"Hxє1n/с]uH (E5Y=QWul ](3* &,tms+.6(OCobۜr``m Z%G+:%"W +RE|E^iFRR\@O3xvWtӀ/9[kMd@ !R و@ef QRzP/׭ A_oԯ Ҩ04DJAH_ĕںk -(œ PDjtVZ|涔Vpp 0JL3plLJqq plD:f|09#F@qBҾ!Ҿz.N:A< \^*8mzu;3Wb!`=E #8݆+w[MS(dN(/ϸ醝w:\~~#ׂ4l d'ANP\b@v^[? GG0a md?OXdt8us_/m?\zb}4!v·<֑5?);YU+?)GEh>("ot \(tliĴ-r@bK+|$;JHB:*F ?Dq6 J^lLE nZyXJ#k |38V(?r~+h. &Nʈ 6̨,3m[9\529: D=>öu|{$(Hv2#BJOtPҳ=1#:?jzv#u!7+h#?A5̳*"??\m:v6t]_F@! ~?RJΤ]!LKRq,4'87 b`T艛){/Jih"7:Jf(Ua8?mYpJr h8o(SF#lvé_aCQ"4b-z vbbnICmWsӲJE^ I-4.6BW G 5]/Q]] /'bRK}bF LpPԘ9~OdM['K2~r1͚&,6O/F=0F+G4X˞^0FW$GWr(<׮\-]# ۷G`t6F ݇+u`}F۳GHގ#0hjsJzFIdfF4F(9b#J9%w<7>a1JR/D1E`Zrq!' J i=L) Z&` |1ԋ(ũzv̓)4EŠ4<<W:!21iMSn)Sj!SjNV}~JF'}J-Sj&HzM)5y_i RA\fJ @^eo~&\)/-,ґO F#׍|cO=<_ ?%wb ȷ_&INc[|,#Ű5b9]8, 1-W?=izJ#_CӉd#7E8 …P]'[.hu1͉kccBTa) L3#ג(Q-LOQ1c S4ﱚ >c$sc3&Bp.'Nr4'RnO_ľIOn5TUWkp({1us:,-_v s!:F~)$P]l <  -w7z~q':hXP,:oE-ƀXl<'pDċ~XN/PJ JGh0B)000mC0U^m.ZDMJJ[6L P%P:%(U$P,(((Aܔ& d `.%J@IX-GܵWJ~1JGgNi:4Q(9~2}7Bt.Uq(F8q-JZ<3?FI*)d&iBCz>%}%}q\xV bR81ˀ1f2)^M &WeO:So1)^pdI< D3 #Z?5HjReR7jitKCd뚎a8c!hVXRί_+*`-лzX:SхjEvkFѱzHcD65/HQVtW)܀#L'|nctEѩhfgJ[djD-?Zli:s+`v)Y]`s49礃: 8' a2'p@:޶,])4\"Kr_ "oHDR1^ty?#@%wJ^ݰ%#mkqzo6rF9PɱI.CZo6 |*7KTUF"vlyț" CDz ,J<* /a|[kBlD0 fyjv`a鲣;c~wN\}jN (=r=<2;l3c$tfbfn8@xIח(q;xEQOײw`Fa/Cg;. G@!BئNCm-K7ӡa(ϛȒP~ 8LD'3o3`CC9B50 r#D Jߺ/)nX~ -]1.5.pgv0.s9 -?ǮJLހۖTEk`_b_&efM :CU!8.Q7 %:1e.p _䇪"h8Dp8SWDE6j nG<QqVGb7RaEքBXVaeMmV%+Uա`_4ԤV[f :VǼtVSdmᐁȉ2lqͲz#yebh"rD2 H,[\+!&L!kw^pR􅴢ijiU"+M%}Фsaƒ\lIW#G!R$"+cr5 o,Σ]ȑI\I<LA6&AAwZPq Ž@SqKP 8Ax6i'*nytßrUA@ P_,MCLw~4rPU4N9hUUUS{5Kө::StD l[v|@t@vg2Υ1Lǁ5,[f/fIQ:7YEhܕtBNibt>_A/ =糨^[TX Ϗۿ(%ec3-vXT@gwF9]3MKLbz"\5o*H&u#R #xJ3K5BdX6ێs]"qH,̓aHh&m̄nq_yt#\ٖ'L7#"qa,3p>Rr;?Ӳ/0K/D!1]U>%9ÜZplueӓ0}if/Z70w.B0aN@9$( *Q{Lu"PZ4RY]VU}/HQ%Hi,5|N@Zxe8A..kYִlah=)!Yh<%rSjf.PN\BW6޼[o00_`ʟ?̅:,Q$Y: Z-stj+APqVBQ&oe م)e PƁ^l cթny,AyvA)#dfGyv. X6m D&@"a>P"lDqTK ddcDj̨hzDVZ[Z##Z 2d$DjU5ai1dde`AD@D@D~2vk>]>tw}">"!U DtD& Q==̘ " LESG)[)x̰@@GA0e#|KcUYwAq ?y kHcD>ta|@Pl`þzuu\\h$n+Dz齓E;+#UxxILj)ѲeE8(A(b- AQ; HEMoT[7N7oԚppAR NBL`6CQk=W] ӵE.(VX0qz_@Qyn%ګ¯ՖpmeLc[ri{7eKX\ X΂o]VC!t}4ƹ |*>ë Ҵ3VlR6oFZ*>U|4sP)Xygu4.F 1f42%{g߮# o,覓ND9G)-hkp(\8q V0KMJ%宖迬#U&HLb;46gRy]#gCyeokEaYn L$ _X/ u ] 2 ?4 "ctJa:8r JJuJtx((SȒ((((o۔oK@i95 zM'/GgXJ(wzv\ǁpajn ~ǼY2 />W.fj*"+f/ƭ(s.:u!p5KU"pmYzĀk˸ 7k` dpA. yq͓-خsK<^? \fpGܸxpm3W sm⯦m(w%ZLжjq.DciE4KF@dkDZt@D@Z D:6'# " _k[DPv,;ydr=3G!)HҞzԲKoi>if0mXO 0-bJLkb: wJ `e VKd@ M&F.B޶4000-btD^ !tLiM`%b:D+=`:\3&H%`:4&J0PDC~Uo}[ʂSA&jse;Y3f{-=IY75Ă@ӡ6> =tw.\P˞{yiX!83.6\HMDiS) s_U +SPsS,BI#PZ 4dW[ H3A`vܲЧYkʑBxH[ pv zpD e#mC#:o4&(@@>ҹ) O>(9 >(c Y8,:o֬$v@\ݣ9_3@[ \ ]۹DZbo7;R] {϶)Ӻ<<Ldc#L0Ӏқ 06{B?`:0m|J2\p!6 ҄u0! eL?+yz^E`:Hvr6u[/.L$0˅w.LSԣԴ _h)PiVS߼Ы1Jn]?]St}\6v뻢"s'J'ݬӯg%:I]9ףtP]`V ,H"K'KtM&a\VX@+8eZKNi-uF SZa[j #4d]lR@na᩟TZJ,(4)4Q4di'O28"}qT.>Pmv'ݜ̅*XxT}Nj.pK5c")#QHrzn=UbșH-X Wt9N_ɥBDCn؅N` (S7BDBLY(G~=Aa"BDTM ]dv^}l/#i=`J_v,c`+ AYK ,@Je#5HZ[UϢyhBM(qwЈKC.wR$${MF2J9HIhh4PLaklkNRs"7*r,Nq4( AQNPF9 N4z>!R'Jc,9MbTAֳ&,"04Ȁ f-P 7yo['iDOK4m0N].y@R0uLYW+Gxz ~P /7K椇꽰,K(KYKDr[ o,hjWCy#Jه+#-A6Sˮ$yI-t⿅~㿩Jyz Z:Y. 4J=r~ Nhq o|  0#0jb`:0#0{pN"GA Ku_4 Yv™';AYA8Y(FF3^R} T'MJ4N Q((-x@ {4((];%6G!KZMB@ @ v @ @iYL(m< Y~&eiOς24ĩIO+y6y#@g}O\0t,7KT`( | oSVf#& QD$pu$kb!Bs5%PjJ @ Z$`@ "(P]zJӲJJ'Dq>XM󚡨0:›VY;ǘLpppppppSgPe2p5B`pswckCGʄ\oT! *z3rOԸ4Mk4\$.7ŗ*҄9 Jw*Ta.6_6iCX|{G*`kd_`ցdmO ~ MU}Xq0O/Yi}H`m_ buAD Y(,Z_ ɂ~A`],HD0 Y``uKU/Y&ݞ)1/57Q|SZ2C׉R2C?RCXb{aڈ4oJf:&K Ipӗ楆^ay,͈H{VdXaq_/5DF ,S+IE8 i l *s\Ӓ# %_к.8n{랷$SC1i8 IXŤ#M,E?63Ăn(Fke =VӰ،"G+[R ^:,Y ^g88/óC%  kAbΤa.Qf! xxxxmߜ7E/7+yqn+bnKx9^r[aB^sa LYG@veXEк3#vihSS'p%)rL-o4~W(^z_奡JNй@=aD[WS$|ʸ5PظḢuQ0ю?ߌ;hcy?)ޱO)Aq_Cs{8>;H7-Y)i;-bv _6xDz< *̈Co)u(ԤZNSl0}R,p ަ{IKy><%yhk~oFFbXHFtgQ  #ց^ 2ˈFݠeĊsGg唔w孇b^1t+.#QtʚH{sӍ+K pcS8 [1`}HD8!8Yp\(+xV1ұ%M@/^HV$MyV50PV9QB0foyCvzPo8BzņL)Ey3~ccs[K=gL3EfOoR H$?6Կ?1 ecؐcIdZec1 %cK(VH( 8k Fnep)7z +_xt|w4j:vopX WA{8d8m#2 ~+_e$H8\V4^LgJ(bj&)}F⃥4R aߘ?B.oC@C҇b(Q ,tM[ Y#F`X>C0aHaDq~օ1T0#>n~k!+6׳%PAJU ёqAJKFУ'Ґ}z<{i^Ap"[&rhL|$+3$]ӧD,4RܺG8/g9\ NN >nh1()]oA|>'#B'"a"%/{o|;M5Qw @ǟx"?!x ,Y .qk<d%^MFB=ŕywsd̔.W?^7^ccRcBy2؞Zګ|7u}8Q 7Eѹk\+\w,И <edޝOѐp}suk( Ie!,{Z8V0S3jBq4~8&]ǬiNAa8N%{K'$N0or =&2.p@WM* 7TU\Q$" I_0j#z"AU6tBLԣ.ϧ w BS}*9P(:)RX[rA'>uc@K(incx/\XA6,G) F'd4A}ml1~Yf$98#1efyuqI11j"(p-sKx0?;0o"u6Q23NB;4% j"~ԩiUR4$7AF[@ @ @ @ @쒈-?K#v} #İ ;}8X<>bKi煼.629A[DBT*44>IUCC,t/FhI&椊z9yr5 \'ӱ_85MtNS_#wɌ[VHF1 |6?x'G3@mňf<F#:0#0N2J}i3 Z_RF(9b#y:~1F(ty-,Fh|2L+bZDtBL3Pp&H0YLK#Ɣz%g}yJ^9 LSn)b}4ĖΡI4XLC?^)ջvr0/ q,NJ}Å0 \! Rc4hӀ;) ңPQ:9Å nJ?Opj^0E`z"U00ZL)cS1`^7}Pay4{z/ w}lMZ/rdMyj͗JSMtLusb:5P ;:a1@g{q99JYL/(\U,X^4Pe)EZRСަ 4vX-kSaѲn,^,K}O]Ȝ‚'T@@JSTA$ @iiORJJEҥ(%PpJv @ @ @)QFJ"K @ \JuJYJ@ @)bPJ!b#5q[c 1 ,8Iou1 5q Ubr8*2qE pTјS3PVPV#פތt+?FJ뀔(ೀPx# Q,-ݜwOttcv`:BQr :Ϗ; VD9F.DTz+ԱaDrb)@mCk]ᓀQ м0:믿d$l&/A 2SQlLT;\y@vQfjB ; Ĉ]]xّ=FH Ȁ쪐C Ȯ_M";s4d|}Pȹk< XX-XKy6ܩnɣz!$ RvՒ}P ,'5ltqg9EtJl|t9r:= X(h5]. ,⸾Z.5lXNn iӨ "EJl԰QO*C٠szm_q|=(5h:T"ۦNS3 l2n:1ҡj[)|m3z:!wT`Dԓq߱W[g|HF2R3,6RFʷTxl"9yۉD)=1ݫu%\!].åǞӭЩ-SRSOlW9@qqBK'bቭ.'&bᡉ;GhDҗnŰ(V/S Kڋɘ+-yI{`yq=...͊]17#/)!.Rr#5qmR!KMKq1=F^:\[>yK3`5qo0Ĺ9iHh^A "Hpwz ysD@F.XF\5Lq4X>BBDn9'$ì8<&]Z\+D|S E!^R4rj*4hJѯkS1̃@%RN#}IYP00&0́LW/M/*h`ZNp.̦]mEh0-ژi?$$h 7!AT$=@6mPq73I @UqmR9'g@p*bA ]S7shQr՛qiޯ%Ii! 3I=+CrU=Q=4 ķwwzGU-w!tt@tښ 4yl t-;٨й(:sc9 @t@t@t@t@t@ Fe:: dbЩBz^lUAv@tN3vt(4FC]xK't2'g1%"`qR1s2E1̢dAHw*,\~#7m rdQ`1┶8,겈.{Vu,"?,Jq,G.X=G?B悴D󙅋 (AS^^E.Lς]4|ϲMpHaY2gYE\'I#\H%T43Di IRG%$aλGcyarXX)בԦ1InW@X3@mvI@@]((N*Fj QU%H Q$f9qJ ( !q71RDYAqLvJcM 6(oE7ӀLŦǚT깣+|9ezOMGJ6FAaEcM x(5LLȎ:T,0y ,\Psr>S\ ?g3.3k"9~9~JGL it:#MX&9r^.....eYi\*1pppppU!.pppppppppppppppppppp) ˥s}pppppp\\\\\\\\\\\\\\\\\e\sqWY?...........R%\=q؄\@ dppz\T}..c..............................................................................ᒹLp{z \\\\'?pc.......p ..e ˥pF.........pppppppppppppp/pppppppppppppppppppppppppppppppppprppppp孬_. ˋ|pppY > q|% u./] J(/..}../Wl_.Kppp.o_& Kd.HJppp...............r\sqWY.....................................................r\ @ 8.......................rr.\\\\\\\\\\\\\\\\\\\\\\\\\\\\墟....& ˥ۗ ..............%.'Ixݽ>>vkӧR86r֎ lֱסQ9%7 {|96Hv⼺cA{Ck}jπ96oZw_#i@c#:wcmw1bc#nLu'<2IG{vX]߱oc޾ON7{ԎwsuyKu{?-R0t5mw>P ne .;U:t4$woOqh:aװCrCkP7YU &[n?h+>ۡ.O_v;wcw#c86~{c?7V0qPtl=t2g]' F"ܡsȻy#'l$sPs\Ywkc :\ZB{-=4doG&pymd١oemѵm-Om&hͼf ma RGǻSeKܷ4ft&B5N 8';V<(tp[ڗ-nJmsn}4SA|ނR_2Η`'ZrySy-ԇ=%u6O}E9sK֖ӶyaƟM9Ckrl9zHW:نl[<() ߄] [h|te\uBcEKm#'t)m:K߶V/udv8rc} pːMR/-j\:ޡ9kDZgbj},K8ƃ~lˏv쐧O*7{:6B;66ՂO󶛠Xzݧvs/V1#4c UqpCʏR9e #dS1Nu%bz?//~J|zȪ^:p s=K;wn8Vsli_^W}GVP3.MgzFC+=W ~ݷM;w1eu?:S??ϚnZ7Sï}hw^JHcx$'}8_pWV]lǎ(1J7Umr C84~J CtI?N 8֋ԱU`.cG1c`4 0 8c8cM~/O[il8'lHVp vK19ñÎFo<>؆59ԖcXb$wb FqpN 8'p¹O8c8c81T"O[miFˊnppN u–%11;1ñ-۠[pN 8a4.ñ۠Ddns ˠn8a''~_wjwݽۉ]#loa.MykGm7^ۿyziwuǭ]{9SeXϱnb^uz]w{c]/uS[Gņ]>4zz7U7+iWװS]eiE,޵߿}9.z='NY5{jZ%sU>YmP:xI^p@LІiOeh`,O < :x/ YB.{~Nz^dM:n|W]JZ+jzZK? f`ygX#A9Y}l`j[W3 Zaw3-|ӹWxu.E4l"{:lj >嚻H0/N&nA-nhA=G|J~Nt ,.#;quFnZkb#ĕqƜ1);6>kL~.‘ں~6b@/KiVOs,9)'uerpl)scKU* U)6qv"nؘ^owtn82hSFwݧ܀#, kX|+/7#q^ ɈYbg)ls<&c&']#Zc:,sd+F| g~,4,^ Xkӳ+Xޱ ՈC5vcxLI49'pB/󯠻g9Fp:zzEX7Gcmk$;YaψvZ1hZXʗk}e$#r%kaRNvN/{d?F-ʜ(WTί_ Ho X,y\/XlqiG-vߖ]UMNDH0,YY>ݠ;4o1Q7ZZ&sʽj'xm`}Tks{p5i=#!mhd§=4$cF@?6crT4p0F0+TKo?=To9]4',rW'p \k-1k,rqib0:KW?K%o쑸~< s+96ҵXrbΚUk¥:'x5Bﴑ .YUulZ?ߴ4l|aE?s$\߷RZ_Z2YV`zYVsJʪ*Q:M=+}xx>cT+(5oZv nNXFjKp͗7p9> ݥS?cu1%j=cna`$0<icWr$O>f.9,55JjRsu\#{e:fgGWX-=5vH~\9BQix/+TX֏Y\:=#B0#9rx0uϜ,}Pv r]okIcg~>8˲–S//| w̨OYVFpuvd҈d^bvҸ7k /qtןbmJZs㬹֮Ra߼-{_;u{sCs뼧ws *@G團ru޲>'bI%- q]bXu8c8c86jՅFzQ mЖf,v5#4C8Ctjձb.RÝ6G-9Fm̖aq p p p p .T8vͺ9ﶶǎ 81Hqphj p pJm,汍 8C?rmU^>rzŰos5iMQr:DN@: %@>>wߏ!;6v1G|t1a~o־ߴEo E . 3 }f邑/oÙ?Hvkmk?t ]1[uPL9`inqKHM:n37gθtKH@㖮N7int;`N+90q?iv@BL( 45PaHN; Fw!Y QNON\44fڤQy8i/M$t?.L7k԰̦p[QԆiGϥQL2X#pm[Ww&_Ap"## 55@< 5R׏tHAdڒ"Mce*;i Qُ[Iܬ&YJPI?% ȤqR|eKixIѷ:JZ"IQg:u~eTY3'6d~-8dTУkYifaa2v:u&kY6\k@&Q$Kӽy`4γ wD2cf$6>i@c}Ǯ|L `=+D쥐ٲ?+<=QyƶCSf86 x42Ȟ<e$F^:Gh@ ۱{'b6ɝxԣg;plc:[l+6=ݞolўv}kM];;*c}C~L߃Z9E{ӂE/ h  /΢_"2t^Siha) LN:}PS}R:}UǧE#Ƌ>շO S@M 9ճ ׾ZP[!{NF]{٭v-s-'KQs?rȈzYF[Y[^&)d:$%EB1ŗky0Svq,d߁cn?N9^xI/F$yVҴM7 vl׽h,֩ˬ]d۞.3uNh7x;)/^#oM73bDY8YMҩW&ѲjfL6ͻ  'S9e,-S%ZYăx+}8:n~b#|W"G3{*!U[C2EZ[" Z:&#NvOӶy9t%ᆲ 8F{'2"Gaŗag(ƋvK/^/OsfPҏGy,dq1H,/M7,6m|%Ν(w;2,eQuB6qdFz.PuM<_$6"YY/PyME DHw8%KD?أk{e$LMshS9FYw*W?_ohEdF?4N#q+MMT!^^ZP/$TozM4f*<Ux/;2.Ȫy!iX28rp^M\HOdb F/®vOh8Gzit(NDPm@5[-H޵g /9(b6GBd*>2zzQu: ׃NYuN=B;Lǖ< =-;q^dVoIРsEOINnW]@yzc+Oxc3zF{l9n $辊Cy3:Hӭ155K+HB[yΚoM{GLb x*ѝI2=V$Z"~ƒ;a=b;z ٮEحQM{`ߠFow` ^*@yPYǶB^<G0;_^@cc_ƒQF:-*:reOGd)">tWn< vtYK)AjgRrN8sPBΫ՞wz+%8,Z‹ޤ8&5mmCk.96k* p8ƠiĞ-|u<5^J']ɃWe0VG6ݎū3ȃ;ߵy M YX-Yż~[c>)^&42DZ(Vg44 DيPdHƮL06;BV=iNQwc\}Ԥ=4*lV&S qzęE+F 0<-۱A9$#Blq%8$J?^FS},-~J.Vjc4)jcNTHqi}({Mʹn.YpdyYhA5/cqQ|Mj"s$T^GH_ooȝQ9pGgK|x4f6%ZsE:س*e~z ^٤֊S|&JQsvƔ"C0:9sTT-qm*Y3ڼ&YhdD|DMFY3Dua>&&s$lpvXjy𣩡NPO(l,_ {88zZdvDl:W͵eiʧnaOj; -QڰabIwEh9F¤։bq`~eF>jQ[cnͻGqs %N\.#5/iZDc$b͚^bd<5푊d'sjU9;KxsSvNjT%2`HA )+٥9$;&Ƒ]3[$X"Es-a?0Kt_v弎gߩcsIVSQҗ:E$\!!伅W疽.q]FN~kbgxZH.]gW!=+4Jq`$& AJpϓe}&f?>*Sm^u[h 51)v@=E[]0Ht]{IqOnjtJT\|ԺVY:K!\HL975͜Ȩ$\9 kRID$CgEXnlI O ÖH{ᄙQg푛gZ,p(F~9Lq\9 uI5eKResey78I>LvxG)rV$:dhWCsȓb,˒}}a 6PqeZ8NįJ"-qA و蠰hLRStMq]68UwVK#3K-q\y,]ExM ʒߒDi_p~Q滝XT(JГ3$z6hLZ5hC 2#43XJƖ e .6XFmL N>mcIJ1 ċ c}L2ͽ&$&4E§ǃ$qc# bm:\8!cen߷/1A'ˎ$\8RP $ݔ8y0МMrkeTBul( hl,6g黪V%L"R^c–bϣQOy :i@=r gJU$*QN:6mBj"g'On,r|h^41ma!|3~J4{#z jgnpLMݦgzt9TG5fyR;P]&5Q63\+MQ8IX{N(Πbc?Tkb8-њ6n"ATu+/Fi6&Kp*N^UZT~fEs Yג4 *c"{OG~HF{^9rbtXL_sawhg^\ي4Q|ߨjgN&6z \e! ̸''ӱ8s`#gk=O]y/!^WyDy5X^}̐k;_~EF(]CP<<65:>/QO-ɪݦyV5/2T>Oqvc<jԴ`<ޕ4yxNC]( 1:u \3_)2hf1Mt`,3I:Kr<ah d֑BqAeתqeU<雷W˓2ijTm#{\Aⴻ"G+~2F`_;Y֓`u9APսx}{D߷ :js)0cQARJsŐz+aLJdtE C1Q4c?QOϋFd)Z:n akTXoyH٨ "ˍ) |:ڜ|ѷQ&%9|uT8IQa g Ͱ@E Fl! ;FF8'?ȶKtPM//mxE:s 5Dه>~&yޝ=*- qzT_,.HԡW.#ι5-0N֮ddsc՘q~iGq[$車zԲ;^;e5+$頞w(Ϗy~lvr ղ3$g`¤)}1JKh,Ugt::[`dd){=ufgW%sVD)#=;VS&KDKA^; rmRtj^IJe8VW8i4;;oҫMXhwn&!49Q舊 rZqX#g&Q>]UM:M5\ X>&Y26Fn,Ф'PI/뇱&kxĹ"xJY-s ךKj&miWEogl/RxC]rlO/S L ǦkUnV'poYC+FC7ƪmUq1.F#s RC>f3ԗ58܅GcmYxM/bc5g[mg!T O})%N?i/h/T[1;Q@8U}d"o` {h]{H\B+UU~rg8 %{YLIhs`l㴄}Moެ Q3/q92q4-`+vtnpl"J!d%ˁ+L`PvYd7^@3O8nh%?3Xǵ@em,=Wıo' ;ʹ QÀ`t%7qʹ'Fhx<ԺҤ`kZquq44r(:O'Ѫ]qr$\3Б"0[m@)j9_!Ogz4"\f`/Xi,Lf1  kΈRd}0#^+0(~L.$(GC/]vOyIk:.{QV4CZ75~b-|g}AKٿAn~+eˣ8R=flݩ9F,fթʡ z}\y"2I{͸ॠ;-ڊJ׌a I5J!,Y]Т&Yjka{Mt^L3x$UhpiJ6Xp"BIREglcvD8n>]xi-N4f^V50<=Zu͂CDÎ%Vy}몈_F .+|y饫 GAHQTYmg4ԬXk\1/z%\ ~V&s2,d/sl{#5+.CXt0(6 ߺ&_(M2s 90BWz]SanRߝC^X&Yt\L*ϖ&)%)QtԞi>ϹNܦKEI)r\Nθ5f]W^e8űIa'u U_3eaK#ˊ3d[tK}ORT4 WD@iƲJƻi@,PNJ=xpvOG]v|pM Izjh&\y'rqRງmEhi7DbWCmd Jv)^P~&JuMU^WԌW61ޭB]˃ikW+հ\mY$lXN87 #)^8/uJ4cy"7obv! I*K00CM 9~v#0BH6L"J\,@zL E \)-LJRǔC,o4F9<>Ǝ394?#W4:B2ny5ތ|^/H5E GsGt4$ x\^ArC-p<ؿUULg/pb La,]k!Qi#z't=rH5vUs{/FZTE>"U5h%-9z$̺-g -lCַ/peQDKSiT0r#5Pޑwu_R aCTל82X䉄C qzuOijžPU!Wᩤ]_iS%h볞u!^T?bĺa vԶڰSs>Xme״C+^4zN{(Ade*Y OXpR+*iVly 6mw\ư~ [NCD x7g0*ّ 'm~[s \%Y+ .HCI^V_-//3A qbga`7tRZ3ЕG\;4zQF/Ԏ;Q-~bj r2dGg.[f=^1s3NgBk'',h1JNwG]ON#BK 䚓$Ɂ$~tufc {rYp:yhxDp/5ʢFJ=6V/?J!!yH.;KqB䕔JUÍ b# LCȻ&b7^B,ay:QcN2'15MdB2/N8IUxT#3"_Jp$لqΔeT:8RțSy )f~̍)pRC,h)8 یטʅMF¥칊(.=lk^f悢 ,򭌮DnVS8MQF7HӐwFdO<\k]Z$GjM4Y įAv&*eU[٤Dpn–lTԈPM:IC$aT%-CumHaTУ5_[*B4&4ɾdDGy B(@|kqkdR^p;9W)u1,n) Q 3'&idU7K Os$d;ךsɑΔB+(˲ [FMhZŋ~!##rn["Z%sL;y o$;!tR(ؑH?2C6 BQZ$<č'M%KCBȑߡi)4 bUoK}tiWQy~.[҄OqfݝT|"Ψ> gIHݩZ tF<҄%rgawG+:vsh8oEϴښOmYVy0t~&A7P6 \* ϪXdN!Yw&-A6 Q$i䵜%%jx |>e?oDYy;`AD0i'm]5=Z Zr}ᘘDždhlZt2&wgڰ TQtBKYpxԪZYp^hKs+үiP7Z5d9SS5_Z6jLq(u?ObKx(^9wpT #>Ir=K'DUIC{\8 + x84\nUōyY=/AxYG> }*+r8/:DKm G6@#󺢯,>ZmVnў?w l^rats#}W4Tkv61d8ouN:a^iĴW-=q?yfV#}jpOWReж<,TZON&-cI?2S򅼒 y-5j-U?]uzԖ7yٙTU]aHm{ѥ}*B1&{&T#>Kb^t⾑E] >DhǛ)m훢 QA&qg׫ G %ȡv~em]I804P>MxZymӜ.+'Vyᢄ-B3 mZ]"O8\Q, þpo\Av,f14c.RLRIl4^r8JF }BBZa3Q ZH93@c4#>Ǔ"/yq5gcT&q$3R$dw_ofxvS#q^_L4!+E'7~4Ƚ,th/_pe^\ޏ<k^SK!t}P[¿c%8>}r6QZ5~Ru-.1eEJ [ ̇5 ћ|IEbkO2O.@䐳L%oK8t%!%SkJW@)ӁjcH"K4(sNB)AZwr*2:}CꍟR>ޮ5X({\^!y2E[z`d7 M{UO+JDSɶ'y⮗V+r%4D'C,HQsueRd( _j_sW'%k,ޯ<11M ?΂5D ml=)AHh [%roV>KbcA8 uN4Y 3ef2j$GZ+{)`.$EOJ`pa.̅0] ͘3RFG ^^m#+mp( (=lTwk嶴Fu\&CDvЪt:Q9_ -y%]lp=UDo~rx(bd/eA"o5CyYקZ(i|Q`B}bWw#y; ?nvJ,:KO`K+ps_,2rc.C8U]0ѹM柍/I:}V Z*3pAMSӪQ%W?^<_n0K=v4m 7yQ[$L|7)fSE߼xKW=oIjGuX3}>:9P8iztUp "FM6Z8ucyNF2L܋ڡt*vSe_uO~b֥R2 S=/,bkM5ZKkꪑXsDt] Ԡk(:YƔ .6^4XF۱sm۲VnXKZ%*9O^Le']#I C #x(v2(ԑ5WK!jȀL94*NT=#C˃{YSL22D|Fk>IՇWb|iD haK ȀojkWC^P ئ;:M dlY%9OA<בDJ:և65Dd5G7}?ժ^Q^īs㸵Zu~ی[b9Be=E#m/2ȷ3r42Ś&{6Z,Aq~r"q.̶lw(@az8.66KKu<"?X|zbn7[i)}Pօҿ<1^kpJJO,+2jzϢ<c7sRtg`א\Y)&9 OKt'U<5Mڕ5, +5,HZ[rN*QMMtL)A4Y'MġbYq1+X4A[] '}n`uw(AMyC4``sYkK‰OY=xn)" -y t4xtƅԨ]CXe#߉[OZ6eb|oI6O7oZI :c6HLNGL);zM+7zQW/MixIh ۈ:Ÿ WncݏN^n4j<1i/\G@+\;CnGh׷PSV)/ތK7jId}~ze˺BA_kcV$H]k~>!KFBC/(9l8d]NmY~g;eⶴ%е=y b%CGjOܤ>7bx0VÞ'e򌉍- kjLUx`x&5[ȳ,SdHsZQט;o,FEy-@)pOkz<'RsDcu9V3f^sO!$+hi@|O &GO[/QY4[`u/2GMߦ<ђZ{me$ ڇ^'65Y(q&0fNȜ,(+&:*Knl gd$pgEf6F?FJ.s9 2:)h$Liq;ԣT<RPHX\Z҅z;A 9ۺ#-9Z*ulxc˖H(B,F|}KqBcimD(3I]8ҒDa4OZ:7 Z:cK^ KTQFs¢!Gerjxld$&F ,IYdg8 w^Kۚć5ƺqjKr-&lIvO]kvK|QZRg KLߎ.ߛd\/ISQE%0p=ru `t 1+c+!HW͸ ̨OAcalq^Ԉ;f*iEW Fh>DVƞAKVrTOU* 'Us$*T0sD ha*[uTbUdu'+%}Xrj<}i_j-=lxoچGhc^VnÀy*MP[vie+mfOYpKg<4fWЅhm 6@hm vhRƥ^kui0c;cڎխن>c/ F%.K!6f1_ƄX{&jX\A 6@c_ork3,hmћu6@hp@h:[ŗS):(i+܋[}8(GqXXJuvHM4dqN\{m̛Mmo̭-iYR^f]6@hm 6@hm 6@hm 6F7 u(Fj,T^hK8(6Vm#tO)Ms:{ν 6@WF2:%Ztp3Vƨ[ hx6?63#k?+6@Wn?q nkߘ iZS}#j>z;}-K[ߞw:̶u>ys%ߟqSYNfq~jJ|t@f<}j]yo>|T/RVgsJϯuf잇s=omYgN,غmp;Xd\6]9{~w|/|?ܬnZox+( m_>KuI?Sk>$?؍c~U~,{K>_9;vw;դ?kCHekz|j];5m.笧KksSk^Ԭq]Z>]bs ?mLvؘ.Ivk%)dw뚵fS_\syzut [{ >>ϩ>GK'Oȿ/Ϛ~N}I|vr~~B}A3ϻ#9lw+}^>w>_=~E|w~ e]sʿ/|^s/=IXlF%tlyeik'IoKڟ5(lkEszߓ}~"鿎ǦoddΣN]{|l(q|^<'>:vߐ{rǦ礭O{ߔퟖs#NNm|71%vS=_Y|Ugoqi2K}H}"_.sߖ{ǻN9w, :~B|>g3'L{_mQY\Iq9]s^gwOu] 799|k;e]cNS">6c3rM VyWߩ^Ry}صꉯ첬d>?aߕ5ӾGvfu?GjtlHVV̏- X11}'UXx|Sug;ǕQoI;c:sMuǦʟjTJշd&V>ʊʨ|ִ5IiQ:Kʊ?OϷ̶8.k>޵ھuu.|$TIsfUsOV՞eݯH?u!+{~w>]뿨lZ:t~동v=vy}y[z~NTH?_>v[zޗL{ys|cjw5h;eۯkOl+l/Tu\y9_}Kmڐ5ʻ޻cGsub%z\_0y׹u7ڕg|\|OYXY|GltZI]:6~UNW&;sۮYXwm2.˕]O|˶O\nuOXfz4e`mvW{K _`{6wi_}2Kvf\o;mComXj74\R}_R G>WOI_d]EzK`~3_TyֿC?%msuOe1=7mI熮1./ 쳟./Q;3vTuk-il~zWtsOIo}jtަkQi,~5~dwEW_3]秱]);w׃6V㻬\9U~Tm]S_>k]ƩR֛7 >zmsI;[Ԏ&>{-o35.c4ߓ-Ɂ~|~cOgJFam{Z]7S3>Kc!cӝ3mk̇R3-9㜾g;ﭭ4b)&v $ɯOk}QYccz{/5uuM]{}|w3ucUJv]\Qiߒ/i+R{9_4veMuwycrc%q8wxC6,4%z]~\5i|޿-9-s]}O]su\KMzO}˜>{u]Иw]?k.u}]y ox}**IYUn|M==3r<@Y߱ ~O.I^4w_5r{.cUۿ#ۻgvy>.*I}ncT?-.GcdWz[ԟiYytc)+ӚvfK2n?nk,P*6Ϯ>*|4US?*o_~{2_W6\Z[9?_ N}gm7v9ǪV֪Cִr]ڥIf~`s\K`sW/˿4rO$oJJ.4?w'Y>?%].ԿkO} Ge83[hcyi?.uh.D]@qzM~F1ΡgeTYYѿr+lUuWw9:zϻ]փzʼvmQʠm wY~rV~k:ex]@[ʈOz5~fׯaq[vۻ׳oi:m.s鵩b1]3j>﫝yvrm#=O./Se[}΃4ҿMՅ+sG}or$:J\ Zi={rt/k?˾K1U_ o˿%cMv__wwM.sTy&]kv9s^X系<|Tkuz]!q1v|19[3wvroi?x 9OvWs^jt}]OczʫO(!E]]CSv[z˻\:1W_e[c]QR̮3ULǮ++Ѷu߫mJ´~e{VNJiN|wswy=9F']v׮g1W]yen??ktKjgզtc^_4\Cs+OKZھ0?˵}5鐞לB'}*]3}ZQZ&|ܗO[+q)՝|ߒKqytߩTvvk?=^?Sk~sOvFc̓kmܜYSch?|NuO(&6Mlb&6Mlb&6Mlb&6Mlb&6Mlb?x?c&6Mlb&6Mlb&6Mlb&6Mlb&6Mlb?36sif0{%&7˷f|osf/ia,6ú8L 䌚3i'g6{Rkg_X6$ {!Ço-ܜ#g-tI19`ڞ8y;Л<_Uuڪ^d&g*~}4us9䜜3[-®7f/V|0 7r{LOÕ㤖[8 lñ m^m&-T-ɅKTU.O㓇ñ:9çѪi#9yQvv8Jx]J>}wЇ9A(XfC4gey?j%VͱnњCs/9j[nkr<]^fᚠ杣Wxƕ66gst%F|X.ժפ uBᝣ@dB]hHy;@gs}` Nž1؇G\&: -$͹ȜVu-,:Z['ꅥ!`^-'76gi[2W_8frNnaa~i9Poa$l%7nc5OϳI@ ߋnl 7{'m:Psd\AAK]&umnAٜ@1\سozMmnhl:j B}>|ls3>i]5K?7\3Ϙ}}gnGw켚1M3&{>I~{lf׆x统/O c5vx{BfnV_8];]P?<>]yN|wtLR{|ye`sChL~ӷ,drm FsOt9SR^m/}]}>t{j?c.uڝԗTN.?*ajN~+٬Pvd;^_)?olNvu9ʚx7,yz-<7a6/<6-<9>o6]~j.7 //潍x򐿐e7󨿼7K6jkrOSy35KkקXQϺv3#wyoZ~f۷ p{kvnx7my}1_޿7/yl>ݛsOO\n?ܟ|Gsg΋ixpl>n?<'|[6|4z4sOf\׌󓑻ӶosoLGӎsKv;׳gs<Ϗy<}~61|%}1z1}y2./F||KFf~|ov'sW#fn6~{^{o8ܽ4Lwޛ|gu_l￘v^̹;ynnf9my۷fa`;n`|?Ͻv@l}޾3vw<}~4y~010s|̇?YMM0Fe8m? '3Oӝo)먻gs_Y=;}_6u˝ѫms]3'ӟm3V/F_LZfv^q}ܽ_><l~ѽ򶑋W^N{cro~5ogYދ~-og}{omfھڋ߿<'Mw0y0y6m17}x6kv37besޛ{|;"oߛ~~-odɴd7'{_Yo?=6w7h}6mngټ~xlKfbKf>yy0;f܋roh}2y6ftjy5skFf_8><Ϭ'kn_r?ﲌ<`<&헼r;m.>?e6g~lv~0v7w5wۦ3f=,wF٧zxsK}=aOfWov̽Ysrt}0'm<>Ɵ|x>~l?Mߞ?ww̘?1~007sۗlSl? l?%9~2m>s̾m#G/ٯxx5r|_]od{db_L޵y^_S=0=dO&dv}Oه2{slsG3'>v5_!ѓinԽzk'lo?6M{ml:MLe|mSﷳod1}6ӓ's-:voOw}2}3wfl{7>S.o6bd'N2䃞^M?_͸gkO?&dt!{~`lolL;;fs~26z6vn6ϙg=9lg3/nLy |b~~6[ΌӞXel~|ٴl"rkw]~6y{3Hgl䌞?61LammʳѱϏF_lb&l&6lbmsn9y~2^Ebb^?Y??g? &v۳WMLg>?٬_ z6kgK_vg6k'ӾOo7y1N/]x1k_L>q^?sw-x1:ŬyßK;Yjo?? Gvu/wwyݴ߾5f;ݣ6n|ї\C~5g^b|vu<ɗ{Ml?~f[b_X.z19}19vn|n<ҋyK.cMYOykYvۓSm^si#43L3ȶl>ɪ\yE˛w4W˅"MebYܳ,s sNk:ܻ쎴6.rcz!W\a˛9).w\c.Γc[~4޹Iʼqw9 .G}Q)sc#ѻleC.Z岏fӳ]^{i\rKoIleC.~ ;^M ܾ7ﳹ[NSMޭ s|kҋf)`۔R@cvoMm+?ʌMiq^r/kSK mSxgeM?2ޔ_>d{k1Tkrk}[SqkRmSZlЭqoM٧1mSvj+s&rkJ/ۦ4Ըuf>Jg\˔>}2۶|7ߣIޚ~۔gB.Tٶ?br6带\Ŕ~ }1fqkvfqkB7FN_2){oL΄ޛr֔]~x,R{s)5ͤn_o+MI)3)5e&qgy3K;SvwgnM;SrW{mSVjRWw1;o?Muwdx0M:l}WS0mJj_͜1eowhJRM9y΄5L)5Fgn4ߝqLyhwyz+o'ɔ>rhS0m~Yg˳-6%yh׳iKy۔U?gvgҔwnhmYo䱽mJ|M)#f^ѝw&~g~ۜk ݙ<:qoB=&}o|{CwLy97Jۦ *Xn9`ʤ߿Nnߚclc{ہ;}?sbi`헁m#GTs0e'~vo$Eqg3ך=w!(0P@[O26u뵿rbFey>/shUp,kpB %Pb]`a{m;:Ҋ5Yؐ[%l 2w7o(kP[?feжz( f c ׷6(Zb1|aޡ20:oUqiJ;w7E9Vt(۟)0GG/)7+;ycjo2bFz~b#z$OUq?>ZܗY?[/(OoF`Ȣ,:Ȧp<[,z?_lm', alakazam/data/ExampleTrees.rda0000644000176200001440000004247013402556374016052 0ustar liggesusersBZh91AY&SYs 3$=D0A@>$j+lԥʛ`% ޲ܸ^\862 p" )@4d(@@m@ (`X@V 7d/;}RdSSA@CME=M?TOHƧhPѦM2dɁ0L0#`0 b`FT444ш42@QDM?L"d5=&hd A$A1M2S6I虧=b@`CLG$u'V~^̫,ӱeKThu_,:_,,N>_XL22 !H<-pYzEK=7Mʥqk5r6ZmQяi}~ƿO3 Uu?aq9p uaRlʪѬ0i8r:NZ?}rg&Yy~s3hd>fVXM0UnUʮF71&eZk3Ye 3'9?aLf_x)U>&¤f0a\2c3~2NENy[¸PV`H|X&+Lf^ěd~ ,IbW b^҅N%A|*E+0WI\D!$dI2P.$E!4|QZЛbDIvj0ݗ0t&Wi ܯ1q=۷n>2ULCOxq+:m\lȮ$eU[k|)5s'r*HeHIYE鲸L;ʛ+Y4Q[5Nuld>ӻ5`фљjNusr[oȏ$g9݂>p"oN\:덽}9c JztDݖ>cz2~i֬W$l75m${LAcEr9HBYH_ZDLaK+>\ĔXz*'URVڭߘXZϡ;ys;8+Z#?*jkw۾q6ΈUeCκY~KWcY'Ilݹs&cZe^̚"d !EI&ړA"q<,=Vx8xqfFhimpgnmrrssil~1,29¦*|UƩWٻ)aFPG#vQfYk6lٳfVZv\l&#TƭT6w d,,пگȳ feX ?\ʓ:$hQDI%Xmu9В@{zx)&QZYb 2BʵTe& 5kP֭ek! G+]Lk 5,UV,e^*|??a$oHpjphIܚ$q Rn r0}_U>yYu/V $'l/Qrr&J#dիDVCaYhՆTs+ UUOI*:fIѣ D/d`̭S*H#*JQ$I"IXQT*'C8B i; T`sa1p13,3 ̬ɘg ?H_'mfٛUKP*%$@!BI&?rj8A=}^ w}K&p;ZJqab )Ad 8F%|f<v*hL3333I333333333_ U:ﻮV^CV!:¶I$3j (I$I&gr`rI-ZM.իV55M]Ulܪٲbŋ(*TJ*qRJ*TRetgTcJ:TShѣGM#χe*+z*F9^~)05p!`e5⩣&p`Vh+;/}n߆z;v=^h/:GG(M,ZbOtP HwEFEKJT *W#(m?JPD0D:i{7ǿq6Ϥ`8z~ӓs|5{ag/CݷQ|^( ZrˣvޜzHשypC&ܯӝGQ)ërw NJ@ PK!AbU0ZJ`{TFU6؋bjJlAJګ`l efUl[1m-fb)?,q8c1eY=Oم)Yp1 ,aLef,df#1Y?f&Fc39˘73/qG8n<9ܹpYbg8yc>s2̣yfK1fdff/3a3 !jPBZB G ('wOyf=z"?YQOAq2Q<)70|!93zF!{Ƨyzz=70p)tgp(>7wyyb~c%zl:̼sg-9&iĸk,6J4#!m7qaSAv DL\vC`5,< yo<#9s7ҲGl,>D~9QLęQKVh:&`l3sY FXi.: e(v(g9/$l&s8"axE rC4 LIM% N9i#P>ө\u>Gqe9Rܸh< #4:Ʋ)g6 Ih#QYyZV{Ϭj3<O36:L|TIH<&z38eW/.Xf̙_IqģuuGyaʮ0UIΨI:JĦTRMTUpQTu8T̳3&9>e?̪u*TŪjQ#/У**,#2R!X,H2's9aK.#1'fzS_,ϙc3q\̈dy*1,ıe3 d̅ʙ)fT#R~0YbV,O%&xYAYW))ZBа ?ƨXg/0ZYR"c!E4/ iٴ3lvkk| OYUNfb*UEU,1+,&Rd,IT9>ħd̅&fkkb-68NٳflٷDCdB>nug}7Da.*=saQ1ٲ\6jƻ- qB!#>tgmuYHFbEDB* #"; IČV=6բto(2H MjAщeZݕ V."Z]FODq:["RwJNDR<; J\L&r.Ecڷ羹IWÍy]oK_HDuDDDDDڪ^Ԙf%u^1#2)/a:!H<% NtQP!Jq٧oBAaVvcˎ5of=5|e MxQFi=<}*\G M:O~ޱ3fq1j5VV||N1$">|V|CX|Fcwwwv+axO)e-^̵(ZXz3c ,>Yz[nSJi͆]1,-UԪl5,k+&>q đH#QĴ72Cd3ɻֺ|6Wٚ|D# Ն'>Qٻ1\L"fhՖAQ`իq2qN2Tդшֵlٲ!~Ee)#bT4mA" le-kOu͜Lk hc3,eՖY(dy9rÌrkswϙrκֿk$ Z|~9\?1fff,YG5r3 c?ݶf5m5̙?uYLg Qkyf_p 3%?u0Ki9g5_|d12e~WJ2?gz=]kXbVfbW鮵# Zu5e,ԯ1sJ櫙Řҫ|̰?sܿd~2ɉݔWVY$n g,늹۝d7?󴗟9v2O>rd3(um+grsV2cc=ea31ffBf`!K+v~T褤=w̚XPh=D@@}rD{DMRJOUH0NL!Ire&N\XIW%ˑ̩9L\&?9b+C1EL \1qE8aC̞O9$̪aeNfT W 3e烔<y.N`f '&L\IXy31)̲30%,Y2GUce|sʼʲ+*L< c2̦e3Uc$8  ̼&,8IWLy8O8xx\QA0Xyc9N"3__,rp)SW*82N^Y1K_3S.Oe'/̼r(|,8É^^C+Y & d22c*,dFaGÖXLqʇTyxN<<We~埊_>U|2p22Wσ?/2W8qe\Lኬ9Y^×*Ð9Ĺ,Oҥ^/৆QqHrħG/Ǘ,e~(YdO)2b3E1U *e:a a6&yFOb2( ,0 FL^QfS,FY2LO18$YqLb0r"BrǓs̤//+9ryxxL\e_9rY2̬12?| 2%VysH#̧#%LN~/aˇ>+YY,ɏ1#*9y˖,c*xc|H|AFOBnP9*0?QP{VV;$o$n6V6+9N EO5?Qr5LbᔼBv&҅ >FRf$#Ám?Hf>ILVښA"fEd(\H5YS'Ar2K9 9bd2)̘&NUrU<ILr痌<<3'#9)LFY2+1,YCF_qA0JVj8DrITax<̦#\#X2p',UX<xS21$Tt#Q5e*L# ^TOrfS<_/~*^eTd1K&rSrg痖s+f1Q<eJ00e>@jHYg a<_,.efG82.q1+ryN*3,O,BL*c1<92< dR<"^FARr$939ʗ,d)ʮd̞\RryˌdeYFc,,,dbc332̬201Vfq2r~̩x32&8y>,EO&r\fc`)rr>g9<\|˕W<1)Ip/'W2'99Hʥ˞yG<<#3"̊Ybd2䣓eLQSE ".fp|c 3Y1,L+*eUbLˎsYrd`\a1y8q1|ˑ ʌa>e'3eX+09'1EH ^IbLΥj/L)),p3#9^X%Jxg2C,^Ydg \#p/+28sx\Y%yp\d 0 X,3#!!fbG9W Fy2*1Vr^aOT#dK+3NXd0+\ b*=! SDjDYUW1rr&+9ᘎWYWfYs*9́3`e2<8G&#y`dÓAO\Xa>xxLʣ eVq',e,<|2Ta99898Vq' \20eJG>NX?oL2|)eUs ̈r!9a 99圔.8ɌeǓ 8R18q0|ǟdq^^sO'>b2bܬ+s2S,,~ )xx3YgQ',ȎT3e2d'L9r2yːL&"̑a,,$&p/r.rTb>/YR +c3aeC,1, b Ic|XX|9WC `+?)$d2ęr\Ǘ8'1*9,S 0^%#"9e2egJ_1>qC8qs*t|Y)Ó81U1*(yT?O>dGɌ1#%̲eɉ0YpL' ^yYTa'4$Q@ ϟ<8rYO8xxL1eϔ!cW |LU3<3*OaW<9rÜ8YaPaeX1O0N/IYe8`1fS2390S řS2+$sɈ32a#(ɀ\?p~|¦'?9'\ęfV f\q',W)L~!|#9qG?NL3y|1s38r1T(33Lsas,X1a 3bfc13,g#_''rePp'd圿L>XbUc21K,NYYcU.g˙g Nr< QsLer~̣唯1ee ,c0! *Ėad3#fV+1s3+21̗afe2y0,f0(1Pl; 3#jpJRY}fSys=FF$DLLm$Xg0>&GQ}B^Hi"lġY#v..&ZPHX82҄ gqCq3!#!2FcQQQ0*0*&Xy*1**9G<'Q ibsNNsLLHeepA7fxɱ@!RL32YRD@sHŶdðlQ$D7cG#q#i9KJ(LQag+++.2($k&ioG)JNsz#A5 F3!r5#A#).; 9r*>F!PL{ y8 IÙb&L9'9s{ ͤf1p3#i-*Pg+4#yXLwFa`uk3MfA8 Ȉq!BQEI$֚: h&u8LIb&Tq#|U!2 0P+!πqfK*<+1FXR,3e2Od22>qU898pX?e̤fNe0+(YFeGcT91ݓϦjjaJlɔQe;GA<gQ"y< aXe(s3#A/7ƣ!YxρC!p,7El5K (t*5bn1ĸ2#s9T:۬| Qz ʉ gJR⣴p4xL灤rog-_2.Hy1q\''',e?O~*PY3.X0|r|yĞ H~2)r8<2bO)S !)W dyNYyNqOeœYpdyXEa*YR9Qe/N\ 8e<|g_aVLÎU3# >yʜ`,qR0a'>JeUQ32eR|ʑ$9E,2y8?I˓G2dxd)2b2,Jş1qLb.1ea0# eO>+LVG&rJs,>`bώVc T"^.dN'^(3.NX.VX2Ń.V9rap9FO*Gbrry.^a|2e8&22p|8ˌ&eʬ\X'̱fI30Ö$吲0|T9e9eJ)s̞1&Y019V`1#23^ +Y1f &C1yY<)L$̳3,1f U31fE&*fL1Ff3&Usc3f Ya#*X̬33&%yra,0f1rL39G U!G)8 N\吳*+!EN9كlJs'9dDC)jhp̯.s82& <1aC2qq|xY(U,d21!\Q,K(x2Jr^0+G<e,x9HD"!2Hy+4Ϣl?vG#q8 BQz5rHy:bCi8QX`Xe.9ecy%̅eʍהw*VZbn-+9ʋV3emVyғ< if4 3Efsa^u< M%iн)J]9d=ƣ-qq(n-&s2Gx*8M&)x5M(t=Mѝ؍&c9P eeċޒaqu:#p6cw#vs?0Or}w{}.C/xoT> (bKrUjG4lxDjq8D}:smg!uU}m6څMΕP]# -6_T eKHUsesp ֕ZLb`wbfPEu7 K,'ѡ[uZdBFZb,KDȃDAveE0^d~]@3ȦeUD)f;2Y 2Β iƯֳIk\qU$+-h4̡+6m:] F؂ D.6h͚ JB)fK(?l\vҡֽJĴ#F^m: !h'΂~ OA: "y]Ͼ]>ۆ޷sQcf3䏲ʹUNl_j6I#J^mpuW9 s H%('̂}~f 5!L;%('τ͂/*[~Ti$t]&=A>Tz jMSA?߉7~G?3y#_Z?yjի$bة/M-\*?eST]')w,l$I¨ʣC|g7BH:UIRT$6mmmȏ/nb d N9]惖X/i@0+2 ^h XYD'"(H9lalakazam/man/0000755000176200001440000000000013513132306012603 5ustar liggesusersalakazam/man/aliphatic.Rd0000644000176200001440000000215613445225137015045 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/AminoAcids.R \name{aliphatic} \alias{aliphatic} \title{Calculates the aliphatic index of amino acid sequences} \usage{ aliphatic(seq, normalize = TRUE) } \arguments{ \item{seq}{vector of strings containing amino acid sequences.} \item{normalize}{if \code{TRUE} then divide the aliphatic index of each amino acid sequence by the number of informative positions. Non-informative position are defined by the presence any character in \code{c("X", "-", ".", "*")}. If \code{FALSE} then return the raw aliphatic index.} } \value{ A vector of the aliphatic indices for the sequence(s). } \description{ \code{aliphatic} calculates the aliphatic index of amino acid sequences using the method of Ikai. Non-informative positions are excluded, where non-informative is defined as any character in \code{c("X", "-", ".", "*")}. } \examples{ seq <- c("CARDRSTPWRRGIASTTVRTSW", NA, "XXTQMYVRT") aliphatic(seq) } \references{ \enumerate{ \item Ikai AJ. Thermostability and aliphatic index of globular proteins. J Biochem. 88, 1895-1898 (1980). } } alakazam/man/MRCATest-class.Rd0000644000176200001440000000327713445225137015601 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Classes.R \docType{class} \name{MRCATest-class} \alias{MRCATest-class} \alias{MRCATest} \alias{print,MRCATest-method} \alias{MRCATest-method} \alias{plot,MRCATest,missing-method} \title{S4 class defining edge significance} \usage{ \S4method{print}{MRCATest}(x) \S4method{plot}{MRCATest,missing}(x, y, ...) } \arguments{ \item{x}{MRCATest object.} \item{y}{ignored.} \item{...}{arguments to pass to \link{plotMRCATest}.} } \description{ \code{MRCATest} defines the significance of enrichment for annotations appearing at the MRCA of the tree. } \section{Slots}{ \describe{ \item{\code{tests}}{data.frame describing the significance test results with columns: \itemize{ \item \code{ANNOTATION}: annotation value. \item \code{COUNT}: observed count of MRCA positions with the given annotation. \item \code{EXPECTED}: expected mean count of MRCA occurance for the annotation. \item \code{PVALUE}: one-sided p-value for the hypothesis that the observed annotation abundance is greater than expected. }} \item{\code{permutations}}{data.frame containing the raw permutation test data with columns: \itemize{ \item \code{ANNOTATION}: annotation value. \item \code{COUNT}: count of MRCA positions with the given annotation. \item \code{ITER}: numerical index define which permutation realization each observation corresponds to. }} \item{\code{nperm}}{number of permutation realizations.} }} alakazam/man/isValidAASeq.Rd0000644000176200001440000000164113445225137015353 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/AminoAcids.R \name{isValidAASeq} \alias{isValidAASeq} \title{Validate amino acid sequences} \usage{ isValidAASeq(seq) } \arguments{ \item{seq}{character vector of sequences to check.} } \value{ A logical vector with \code{TRUE} for each valid amino acid sequences and \code{FALSE} for each invalid sequence. } \description{ \code{isValidAASeq} checks that a set of sequences are valid non-ambiguous amino acid sequences. A sequence is considered valid if it contains only characters in the the non-ambiguous IUPAC character set or any characters in \code{c("X", ".", "-", "*")}. } \examples{ seq <- c("CARDRSTPWRRGIASTTVRTSW", "XXTQMYVR--XX", "CARJ", "10") isValidAASeq(seq) } \seealso{ See \link{ABBREV_AA} for the set of non-ambiguous amino acid characters. See \link{IUPAC_AA} for the full set of ambiguous amino acid characters. } alakazam/man/alakazam.Rd0000644000176200001440000001161113513133770014661 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Alakazam.R \docType{package} \name{alakazam} \alias{alakazam} \alias{alakazam-package} \title{The alakazam package} \description{ \code{alakazam} in a member of the Change-O suite of tools and serves five main purposes: \itemize{ \item Providing core functionality for other R packages in the Change-O suite. This includes common tasks such as file I/O, basic DNA sequence manipulation, and interacting with V(D)J segment and gene annotations. \item Providing an R interface for interacting with the output of the pRESTO tool suite. \item Performing lineage reconstruction on clonal populations of immunoglobulin (Ig) sequences. \item Performing clonal abundance and diversity analysis on lymphocyte repertoires. \item Performing physicochemical property analyses of lymphocyte receptor sequences. } For additional details regarding the use of the \code{alakazam} package see the vignettes:\cr \code{browseVignettes("alakazam")} } \section{File I/O}{ \itemize{ \item \link{readChangeoDb}: Input Change-O style files. \item \link{writeChangeoDb}: Output Change-O style files. } } \section{Sequence cleaning}{ \itemize{ \item \link{maskSeqEnds}: Mask ragged ends. \item \link{maskSeqGaps}: Mask gap characters. \item \link{collapseDuplicates}: Remove duplicate sequences. } } \section{Lineage reconstruction}{ \itemize{ \item \link{makeChangeoClone}: Clean sequences for lineage reconstruction. \item \link{buildPhylipLineage}: Perform lineage reconstruction of Ig sequences. } } \section{Lineage topology analysis}{ \itemize{ \item \link{tableEdges}: Tabulate annotation relationships over edges. \item \link{testEdges}: Significance testing of annotation edges. \item \link{testMRCA}: Significance testing of MRCA annotations. \item \link{summarizeSubtrees}: Various summary statistics for subtrees. \item \link{plotSubtrees}: Plot distributions of summary statistics for a population of trees. } } \section{Diversity analysis}{ \itemize{ \item \link{countClones}: Calculate clonal abundance. \item \link{estimateAbundance}: Bootstrap clonal abundance curves. \item \link{alphaDiversity}: Generate clonal alpha diversity curves. \item \link{plotAbundanceCurve}: Plot clone size distribution as a rank-abundance \item \link{plotDiversityCurve}: Plot clonal diversity curves. \item \link{plotDiversityTest}: Plot testing at given diversity hill indicex. } } \section{Ig and TCR sequence annotation}{ \itemize{ \item \link{countGenes}: Calculate Ig and TCR allele, gene and family usage. \item \link{extractVRegion}: Extract CDRs and FWRs sub-sequences. \item \link{getAllele}: Get V(D)J allele names. \item \link{getGene}: Get V(D)J gene names. \item \link{getFamily}: Get V(D)J family names. } } \section{Sequence distance calculation}{ \itemize{ \item \link{seqDist}: Calculate Hamming distance between two sequences. \item \link{seqEqual}: Test two sequences for equivalence. \item \link{pairwiseDist}: Calculate a matrix of pairwise Hamming distances for a set of sequences. \item \link{pairwiseEqual}: Calculate a logical matrix of pairwise equivalence for a set of sequences. } } \section{Amino acid propertes}{ \itemize{ \item \link{translateDNA}: Translate DNA sequences to amino acid sequences. \item \link{aminoAcidProperties}: Calculate various physicochemical properties of amino acid sequences. \item \link{countPatterns}: Count patterns in sequences. } } \section{General data manipulation}{ \itemize{ \item \link{translateStrings}: Perform multiple string replacement operations. } } \references{ \enumerate{ \item Vander Heiden JA, Yaari G, et al. pRESTO: a toolkit for processing high-throughput sequencing raw reads of lymphocyte receptor repertoires. Bioinformatics. 2014 30(13):1930-2. \item Stern JNH, Yaari G, Vander Heiden JA, et al. B cells populating the multiple sclerosis brain mature in the draining cervical lymph nodes. Sci Transl Med. 2014 6(248):248ra107. \item Wu Y-CB, et al. Influence of seasonal exposure to grass pollen on local and peripheral blood IgE repertoires in patients with allergic rhinitis. J Allergy Clin Immunol. 2014 134(3):604-12. \item Gupta NT, Vander Heiden JA, et al. Change-O: a toolkit for analyzing large-scale B cell immunoglobulin repertoire sequencing data. Bioinformatics. 2015 Oct 15;31(20):3356-8. } } alakazam/man/DiversityCurve-class.Rd0000644000176200001440000000524213512442170017171 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Classes.R \docType{class} \name{DiversityCurve-class} \alias{DiversityCurve-class} \alias{DiversityCurve} \alias{print,DiversityCurve-method} \alias{DiversityCurve-method} \alias{plot,DiversityCurve,missing-method} \alias{plot,DiversityCurve,numeric-method} \title{S4 class defining a diversity curve} \usage{ \S4method{print}{DiversityCurve}(x) \S4method{plot}{DiversityCurve,missing}(x, y, ...) \S4method{plot}{DiversityCurve,numeric}(x, y, ...) } \arguments{ \item{x}{DiversityCurve object} \item{y}{diversity order to plot (q).} \item{...}{arguments to pass to \link{plotDiversityCurve} or \link{plotDiversityTest}.} } \description{ \code{DiversityCurve} defines diversity (\eqn{D}) scores over multiple diversity orders (\eqn{Q}). } \section{Slots}{ \describe{ \item{\code{diversity}}{data.frame defining the diversity curve with the following columns: \itemize{ \item \code{GROUP}: group label. \item \code{Q}: diversity order. \item \code{D}: mean diversity index over all bootstrap realizations. \item \code{D_SD}: standard deviation of the diversity index over all bootstrap realizations. \item \code{D_LOWER}: diversity lower confidence inverval bound. \item \code{D_UPPER}: diversity upper confidence interval bound. \item \code{E}: evenness index calculated as \code{D} divided by \code{D} at \code{Q=0}. \item \code{E_LOWER}: evenness lower confidence inverval bound. \item \code{E_UPPER}: eveness upper confidence interval bound. }} \item{\code{tests}}{data.frame describing the significance test results with columns: \itemize{ \item \code{TEST}: string listing the two groups tested. \item \code{DELTA_MEAN}: mean of the \eqn{D} bootstrap delta distribution for the test. \item \code{DELTA_SD}: standard deviation of the \eqn{D} bootstrap delta distribution for the test. \item \code{PVALUE}: p-value for the test. }} \item{\code{group_by}}{string specifying the name of the grouping column in diversity calculation.} \item{\code{groups}}{vector specifying the names of unique groups in group column in diversity calculation.} \item{\code{method}}{string specifying the type of diversity calculated.} \item{\code{q}}{vector of diversity hill diversity indices used for computing diversity.} \item{\code{n}}{numeric vector indication the number of sequences sampled in each group.} \item{\code{ci}}{confidence interval defining the upper and lower bounds (a value between 0 and 1).} }} alakazam/man/estimateAbundance.Rd0000644000176200001440000000522313512442170016512 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Diversity.R \name{estimateAbundance} \alias{estimateAbundance} \title{Estimates the complete clonal relative abundance distribution} \usage{ estimateAbundance(data, clone = "CLONE", copy = NULL, group = NULL, min_n = 30, max_n = NULL, uniform = TRUE, ci = 0.95, nboot = 200, progress = FALSE) } \arguments{ \item{data}{data.frame with Change-O style columns containing clonal assignments.} \item{clone}{name of the \code{data} column containing clone identifiers.} \item{copy}{name of the \code{data} column containing copy numbers for each sequence. If \code{copy=NULL} (the default), then clone abundance is determined by the number of sequences. If a \code{copy} column is specified, then clone abundances is determined by the sum of copy numbers within each clonal group.} \item{group}{name of the \code{data} column containing group identifiers. If \code{NULL} then no grouping is performed and the \code{GROUP} column of the output will contain the value \code{NA} for each row.} \item{min_n}{minimum number of observations to sample. A group with less observations than the minimum is excluded.} \item{max_n}{maximum number of observations to sample. If \code{NULL} then no maximum is set.} \item{uniform}{if \code{TRUE} then uniformly resample each group to the same number of observations. If \code{FALSE} then allow each group to be resampled to its original size or, if specified, \code{max_size}.} \item{ci}{confidence interval to calculate; the value must be between 0 and 1.} \item{nboot}{number of bootstrap realizations to generate.} \item{progress}{if \code{TRUE} show a progress bar.} } \value{ A \link{AbundanceCurve} object summarizing the abundances. } \description{ \code{estimateAbundance} estimates the complete clonal relative abundance distribution and confidence intervals on clone sizes using bootstrapping. } \examples{ abund <- estimateAbundance(ExampleDb, group="SAMPLE", nboot=100) } \references{ \enumerate{ \item Chao A. Nonparametric Estimation of the Number of Classes in a Population. Scand J Stat. 1984 11, 265270. \item Chao A, et al. Rarefaction and extrapolation with Hill numbers: A framework for sampling and estimation in species diversity studies. Ecol Monogr. 2014 84:45-67. \item Chao A, et al. Unveiling the species-rank abundance distribution by generalizing the Good-Turing sample coverage theory. Ecology. 2015 96, 11891201. } } \seealso{ See \link{plotAbundanceCurve} for plotting of the abundance distribution. See \link{alphaDiversity} for a similar application to clonal diversity. } alakazam/man/getAAMatrix.Rd0000644000176200001440000000125013445225137015247 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Sequence.R \name{getAAMatrix} \alias{getAAMatrix} \title{Build an AA distance matrix} \usage{ getAAMatrix(gap = 0) } \arguments{ \item{gap}{value to assign to characters in the set \code{c("-", ".")}.} } \value{ A \code{matrix} of amino acid character distances with row and column names indicating the character pair. } \description{ \code{getAAMatrix} returns a Hamming distance matrix for IUPAC ambiguous amino acid characters. } \examples{ getAAMatrix() } \seealso{ Creates an amino acid distance matrix for \link{seqDist}. See \link{getDNAMatrix} for nucleotide distances. } alakazam/man/seqEqual.Rd0000644000176200001440000000221713445225137014665 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/RcppExports.R \name{seqEqual} \alias{seqEqual} \title{Test DNA sequences for equality.} \usage{ seqEqual(seq1, seq2, ignore = as.character(c("N", "-", ".", "?"))) } \arguments{ \item{seq1}{character string containing a DNA sequence.} \item{seq2}{character string containing a DNA sequence.} \item{ignore}{vector of characters to ignore when testing for equality. Default is to ignore c("N",".","-","?")} } \value{ Returns \code{TRUE} if sequences are equal and \code{FALSE} if they are not. Sequences of unequal length will always return \code{FALSE} regardless of their character values. } \description{ \code{seqEqual} checks if two DNA sequences are identical. } \examples{ # Ignore gaps seqEqual("ATG-C", "AT--C") seqEqual("ATGGC", "ATGGN") seqEqual("AT--T", "ATGGC") # Ignore only Ns seqEqual("ATG-C", "AT--C", ignore="N") seqEqual("ATGGC", "ATGGN", ignore="N") seqEqual("AT--T", "ATGGC", ignore="N") } \seealso{ Used by \link{pairwiseEqual} within \link{collapseDuplicates}. See \link{seqDist} for calculation Hamming distances between sequences. } alakazam/man/graphToPhylo.Rd0000644000176200001440000000443413512442170015521 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Lineage.R \name{graphToPhylo} \alias{graphToPhylo} \title{Convert a tree in igraph \code{graph} format to ape \code{phylo} format.} \usage{ graphToPhylo(graph) } \arguments{ \item{graph}{An igraph \code{graph} object.} } \value{ A \code{phylo} object representing the input tree. Tip and internal node names are stored in the \code{tip.label} and \code{node.label} vectors, respectively. } \description{ \code{graphToPhylo} a tree in igraph \code{graph} format to ape \code{phylo} format. } \details{ Convert from igraph \code{graph} object to ape \code{phylo} object. If \code{graph} object was previously rooted with the germline as the direct ancestor, this will re-attach the germline as a descendant node with a zero branch length to a new universal common ancestor (UCA) node and store the germline node ID in the \code{germid} attribute and UCA node number in the \code{uca} attribute. Otherwise these attributes will not be specified in the \code{phylo} object. Using \code{phyloToGraph(phylo, germline=phylo$germid)} creates a \code{graph} object with the germline back as the direct ancestor. Tip and internal node names are stored in the \code{tip.label} and \code{node.label} vectors, respectively. } \examples{ \dontrun{ library(igraph) library(ape) #convert to phylo phylo = graphToPhylo(graph) #plot tree using ape plot(phylo,show.node.label=TRUE) #store as newick tree write.tree(phylo,file="tree.newick") #read in tree from newick file phylo_r = read.tree("tree.newick") #convert to igraph graph_r = phyloToGraph(phylo_r,germline="Germline") #plot graph - same as before, possibly rotated plot(graph_r,layout=layout_as_tree) } } \references{ \enumerate{ \item Hoehn KB, Lunter G, Pybus OG - A Phylogenetic Codon Substitution Model for Antibody Lineages. Genetics 2017 206(1):417-427 https://doi.org/10.1534/genetics.116.196303 \item Hoehn KB, Vander Heiden JA, Zhou JQ, Lunter G, Pybus OG, Kleinstein SHK - Repertoire-wide phylogenetic models of B cell molecular evolution reveal evolutionary signatures of aging and vaccination. bioRxiv 2019 https://doi.org/10.1101/558825 } } alakazam/man/readIgphyml.Rd0000644000176200001440000001153613512442170015347 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Lineage.R \name{readIgphyml} \alias{readIgphyml} \title{Read in output from IgPhyML} \usage{ readIgphyml(file, id = NULL, format = c("graph", "phylo"), collapse = TRUE) } \arguments{ \item{file}{IgPhyML output file (.tab).} \item{id}{ID to assign to output object.} \item{format}{if \code{"graph"} return trees as igraph \code{graph} objects. if \code{"phylo"} return trees as ape \code{phylo} objects.} \item{collapse}{if \code{TRUE} transform branch lengths to units of substitutions, rather than substitutions per site, and collapse internal nodes separated by branches < 0.1 substitutions.} } \value{ A list containing IgPhyML model parameters and estimated lineage trees. Object attributes: \itemize{ \item \code{param}: Data.frame of parameter estimates for each clonal lineage. Columns include: \code{CLONE}, which is the clone id; \code{NSEQ}, the total number of sequences in the lineage; \code{NSITE}, the number of codon sites; \code{TREE_LENGTH}, the sum of all branch lengths in the estimated lineage tree; and \code{LHOOD}, the log likelihood of the clone's sequences given the tree and parameters. Subsequent columns are parameter estimates from IgPhyML, which will depend on the model used. Parameter columns ending with \code{_MLE} are maximum likelihood estimates; those ending with \code{_LCI} are the lower 95%% confidence interval estimate; those ending with \code{_UCI} are the upper 95%% confidence interval estimate. The first line of \code{param} is for clone \code{REPERTOIRE}, which is a summary of all lineages within the repertoire. For this row, \code{NSEQ} is the total number of sequences, \code{NSITE} is the average number of sites, and \code{TREE_LENGTH} is the mean tree length. For most applications, parameter values will be the same for all lineages within the repertoire, so access them simply by: \code{$param$OMEGA_CDR_MLE[1]} to, for instance, get the estimate of dN/dS on the CDRs at the repertoire level. \item \code{trees}: List of tree objects estimated by IgPhyML. If \code{format="graph"} these are igraph \code{graph} objects. If \code{format="phylo"}, these are ape \code{phylo} objects. \item \code{command}: Command used to run IgPhyML. } } \description{ \code{readIgphyml} reads output from the IgPhyML phylogenetics inference package for B cell repertoires } \details{ \code{readIgphyml} reads output from the IgPhyML repertoire phylogenetics inference package. The resulting object is divded between parameter estimates (usually under the HLP19 model), which provide information about mutation and selection pressure operating on the sequences. Trees returned from this function are either igraph objects or phylo objects, and each may be visualized accordingly. Futher, branch lengths in tree may represent either the expected number of substitutions per site (codon, if estimated under HLP or GY94 models), or the total number of expected substitutions per site. If the latter, internal nodes - but not tips - separated by branch lengths less than 0.1 are collapsed to simplify viewing. } \examples{ \dontrun{ # Read in and plot a tree from an igphyml run library(igraph) s1 <- readIgphyml("IB+7d_lineages_gy.tsv_igphyml_stats_hlp.tab", id="+7d") print(s1$param$OMEGA_CDR_MLE[1]) plot(s1$trees[[1]], layout=layout_as_tree, edge.label=E(s1$trees[[1]])$weight) } } \references{ \enumerate{ \item Hoehn KB, Lunter G, Pybus OG - A Phylogenetic Codon Substitution Model for Antibody Lineages. Genetics 2017 206(1):417-427 https://doi.org/10.1534/genetics.116.196303 \item Hoehn KB, Vander Heiden JA, Zhou JQ, Lunter G, Pybus OG, Kleinstein SHK - Repertoire-wide phylogenetic models of B cell molecular evolution reveal evolutionary signatures of aging and vaccination. bioRxiv 2019 https://doi.org/10.1101/558825 } } alakazam/man/phyloToGraph.Rd0000644000176200001440000000334013512442170015514 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Lineage.R \name{phyloToGraph} \alias{phyloToGraph} \title{Convert a tree in ape \code{phylo} format to igraph \code{graph} format.} \usage{ phyloToGraph(phylo, germline = NULL) } \arguments{ \item{phylo}{An ape \code{phylo} object.} \item{germline}{If specified, places specified tip sequence as the direct ancestor of the tree} } \value{ A \code{graph} object representing the input tree. } \description{ \code{phyloToGraph} converts a tree in \code{phylo} format to and \code{graph} format. } \details{ Convert from phylo to graph object. Uses the node.label vector to label internal nodes. Nodes may rotate but overall topology will remain constant. } \examples{ \dontrun{ library(igraph) library(ape) #convert to phylo phylo = graphToPhylo(graph) #plot tree using ape plot(phylo,show.node.label=TRUE) #store as newick tree write.tree(phylo,file="tree.newick") #read in tree from newick file phylo_r = read.tree("tree.newick") #convert to igraph graph_r = phyloToGraph(phylo_r,germline="Germline") #plot graph - same as before, possibly rotated plot(graph_r,layout=layout_as_tree) } } \references{ \enumerate{ \item Hoehn KB, Lunter G, Pybus OG - A Phylogenetic Codon Substitution Model for Antibody Lineages. Genetics 2017 206(1):417-427 https://doi.org/10.1534/genetics.116.196303 \item Hoehn KB, Vander Heiden JA, Zhou JQ, Lunter G, Pybus OG, Kleinstein SHK - Repertoire-wide phylogenetic models of B cell molecular evolution reveal evolutionary signatures of aging and vaccination. bioRxiv 2019 https://doi.org/10.1101/558825 } } alakazam/man/plotAbundanceCurve.Rd0000644000176200001440000000363013512442170016662 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Diversity.R \name{plotAbundanceCurve} \alias{plotAbundanceCurve} \title{Plots a clonal abundance distribution} \usage{ plotAbundanceCurve(data, colors = NULL, main_title = "Rank Abundance", legend_title = NULL, xlim = NULL, ylim = NULL, annotate = c("none", "depth"), silent = FALSE, ...) } \arguments{ \item{data}{\link{AbundanceCurve} object returned by \link{estimateAbundance}.} \item{colors}{named character vector whose names are values in the \code{group} column of \code{data} and whose values are colors to assign to those group names.} \item{main_title}{string specifying the plot title.} \item{legend_title}{string specifying the legend title.} \item{xlim}{numeric vector of two values specifying the \code{c(lower, upper)} x-axis limits.} \item{ylim}{numeric vector of two values specifying the \code{c(lower, upper)} y-axis limits.} \item{annotate}{string defining whether to added values to the group labels of the legend. When \code{"none"} (default) is specified no annotations are added. Specifying (\code{"depth"}) adds sequence counts to the labels.} \item{silent}{if \code{TRUE} do not draw the plot and just return the ggplot2 object; if \code{FALSE} draw the plot.} \item{...}{additional arguments to pass to ggplot2::theme.} } \value{ A \code{ggplot} object defining the plot. } \description{ \code{plotAbundanceCurve} plots the results from estimating the complete clonal relative abundance distribution. The distribution is plotted as a log rank abundance distribution. } \examples{ # Estimate abundance by sample and plot abund <- estimateAbundance(ExampleDb, group="SAMPLE", nboot=100) plotAbundanceCurve(abund, legend_title="Sample") } \seealso{ See \link{AbundanceCurve} for the input object and \link{estimateAbundance} for generating the input abundance distribution. Plotting is performed with \link{ggplot}. } alakazam/man/sortGenes.Rd0000644000176200001440000000256213445225137015061 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Gene.R \name{sortGenes} \alias{sortGenes} \title{Sort V(D)J genes} \usage{ sortGenes(genes, method = c("name", "position")) } \arguments{ \item{genes}{vector of strings respresenting V(D)J gene names.} \item{method}{string defining the method to use for sorting genes. One of: \itemize{ \item \code{"name"}: sort in lexicographic order. Order is by family first, then gene, and then allele. \item \code{"position"}: sort by position in the locus, as determined by the final two numbers in the gene name. Non-localized genes are assigned to the highest positions. }} } \value{ A sorted character vector of gene names. } \description{ \code{sortGenes} sorts a vector of V(D)J gene names by either lexicographic ordering or locus position. } \examples{ # Create a list of allele names genes <- c("IGHV1-69D*01","IGHV1-69*01","IGHV4-38-2*01","IGHV1-69-2*01", "IGHV2-5*01","IGHV1-NL1*01", "IGHV1-2*01,IGHV1-2*05", "IGHV1-2", "IGHV1-2*02", "IGHV1-69*02") # Sort genes by name sortGenes(genes) # Sort genes by position in the locus sortGenes(genes, method="pos") } \seealso{ See \code{getAllele}, \code{getGene} and \code{getFamily} for parsing gene names. } alakazam/man/tableEdges.Rd0000644000176200001440000000352713445225137015151 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Topology.R \name{tableEdges} \alias{tableEdges} \title{Tabulate the number of edges between annotations within a lineage tree} \usage{ tableEdges(graph, field, indirect = FALSE, exclude = NULL) } \arguments{ \item{graph}{igraph object containing an annotated lineage tree.} \item{field}{string defining the annotation field to count.} \item{indirect}{if \code{FALSE} count direct connections (edges) only. If \code{TRUE} walk through any nodes with annotations specified in the \code{argument} to count indirect connections. Specifying \code{indirect=TRUE} with \code{exclude=NULL} will have no effect.} \item{exclude}{vector of strings defining \code{field} values to exclude from counts. Edges that either start or end with the specified annotations will not be counted. If \code{NULL} count all edges.} } \value{ A data.frame defining total annotation connections in the tree with columns: \itemize{ \item \code{PARENT}: parent annotation \item \code{CHILD}: child annotation \item \code{COUNT}: count of edges for the parent-child relationship } } \description{ \code{tableEdges} creates a table of the total number of connections (edges) for each unique pair of annotations within a tree over all nodes. } \examples{ # Define example graph graph <- ExampleTrees[[23]] # Count direct edges between isotypes including inferred nodes tableEdges(graph, "ISOTYPE") # Count direct edges excluding edges to and from germline and inferred nodes tableEdges(graph, "ISOTYPE", exclude=c("Germline", NA)) # Count indirect edges walking through germline and inferred nodes tableEdges(graph, "ISOTYPE", indirect=TRUE, exclude=c("Germline", NA)) } \seealso{ See \link{testEdges} for performed a permutation test on edge relationships. } alakazam/man/polar.Rd0000644000176200001440000000255013445225137014222 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/AminoAcids.R \name{polar} \alias{polar} \title{Calculates the average polarity of amino acid sequences} \usage{ polar(seq, polarity = NULL) } \arguments{ \item{seq}{vector of strings containing amino acid sequences.} \item{polarity}{named numerical vector defining polarity scores for each amino acid, where names are single-letter amino acid character codes. If \code{NULL}, then the Grantham, 1974 scale is used.} } \value{ A vector of bulkiness scores for the sequence(s). } \description{ \code{polar} calculates the average polarity score of amino acid sequences. Non-informative positions are excluded, where non-informative is defined as any character in \code{c("X", "-", ".", "*")}. } \examples{ # Default scale seq <- c("CARDRSTPWRRGIASTTVRTSW", "XXTQMYVRT") polar(seq) # Use the Zimmerman et al, 1968 polarity scale from the seqinr package library(seqinr) data(aaindex) x <- aaindex[["ZIMJ680103"]]$I # Rename the score vector to use single-letter codes names(x) <- translateStrings(names(x), ABBREV_AA) # Calculate polarity polar(seq, polarity=x) } \references{ \enumerate{ \item Grantham R. Amino acid difference formula to help explain protein evolution. Science 185, 862-864 (1974). } } \seealso{ For additional size related indices see \code{\link[seqinr]{aaindex}}. } alakazam/man/IMGT_REGIONS.Rd0000644000176200001440000000131013445225137015024 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Data.R \docType{data} \name{IMGT_REGIONS} \alias{IMGT_REGIONS} \title{IMGT V-segment regions} \format{A list with regions named one of \code{c("FWR1", "CDR1", "FWR2", "CDR2", "FWR3")} with values containing a numeric vector of length two defining the \code{c(start, end)} positions of the named region.} \usage{ IMGT_REGIONS } \description{ A list defining the boundaries of V-segment framework regions (FWRs) and complementarity determining regions (CDRs) for IMGT-gapped immunoglobulin (Ig) nucleotide sequences according to the IMGT numbering scheme. } \references{ \url{http://imgt.org} } \keyword{datasets} alakazam/man/getPathLengths.Rd0000644000176200001440000000261413445225137016027 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Topology.R \name{getPathLengths} \alias{getPathLengths} \title{Calculate path lengths from the tree root} \usage{ getPathLengths(graph, root = "Germline", field = NULL, exclude = NULL) } \arguments{ \item{graph}{igraph object containing an annotated lineage tree.} \item{root}{name of the root (germline) node.} \item{field}{annotation field to use for exclusion of nodes from step count.} \item{exclude}{annotation values specifying which nodes to exclude from step count. If \code{NULL} consider all nodes. This does not affect the weighted (distance) path length calculation.} } \value{ A data.frame with columns: \itemize{ \item \code{NAME}: node name \item \code{STEPS}: path length as the number of nodes traversed \item \code{DISTANCE}: path length as the sum of edge weights } } \description{ \code{getPathLengths} calculates the unweighted (number of steps) and weighted (distance) path lengths from the root of a lineage tree. } \examples{ # Define example graph graph <- ExampleTrees[[24]] # Consider all nodes getPathLengths(graph, root="Germline") # Exclude nodes without an isotype annotation from step count getPathLengths(graph, root="Germline", field="ISOTYPE", exclude=NA) } \seealso{ See \link{buildPhylipLineage} for generating input trees. } alakazam/man/testDiversity.Rd0000644000176200001440000001077013512442170015763 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Deprecated.R \name{testDiversity} \alias{testDiversity} \title{Pairwise test of the diversity index} \usage{ testDiversity(data, q, group, clone = "CLONE", copy = NULL, min_n = 30, max_n = NULL, nboot = 2000, progress = FALSE, ci = 0.95) } \arguments{ \item{data}{data.frame with Change-O style columns containing clonal assignments.} \item{q}{diversity order to test.} \item{group}{name of the \code{data} column containing group identifiers.} \item{clone}{name of the \code{data} column containing clone identifiers.} \item{copy}{name of the \code{data} column containing copy numbers for each sequence. If \code{copy=NULL} (the default), then clone abundance is determined by the number of sequences. If a \code{copy} column is specified, then clone abundances is determined by the sum of copy numbers within each clonal group.} \item{min_n}{minimum number of observations to sample. A group with less observations than the minimum is excluded.} \item{max_n}{maximum number of observations to sample. If \code{NULL} the maximum if automatically determined from the size of the largest group.} \item{nboot}{number of bootstrap realizations to perform.} \item{progress}{if \code{TRUE} show a progress bar.} \item{ci}{confidence interval to calculate; the value must be between 0 and 1.} } \value{ A \link{DiversityCurve} object containing slot test with p-values and summary statistics. } \description{ \code{testDiversity} performs pairwise significance tests of the diversity index (\eqn{D}) at a given diversity order (\eqn{q}) for a set of annotation groups via rarefaction and bootstrapping. } \details{ Clonal diversity is calculated using the generalized diversity index proposed by Hill (Hill, 1973). See \link{calcDiversity} for further details. Diversity is calculated on the estimated complete clonal abundance distribution. This distribution is inferred by using the Chao1 estimator to estimate the number of seen clones, and applying the relative abundance correction and unseen clone frequency described in Chao et al, 2014. Variability in total sequence counts across unique values in the \code{group} column is corrected by repeated resampling from the estimated complete clonal distribution to a common number of sequences. The diversity index estimate (\eqn{D}) for each group is the mean value of over all bootstrap realizations. Significance of the difference in diversity index (\eqn{D}) between groups is tested by constructing a bootstrap delta distribution for each pair of unique values in the \code{group} column. The bootstrap delta distribution is built by subtracting the diversity index \eqn{Da} in \eqn{group-a} from the corresponding value \eqn{Db} in \eqn{group-b}, for all bootstrap realizations, yeilding a distribution of \code{nboot} total deltas; where \eqn{group-a} is the group with the greater mean \eqn{D}. The p-value for hypothesis \eqn{Da != Db} is the value of \eqn{P(0)} from the empirical cumulative distribution function of the bootstrap delta distribution, multiplied by 2 for the two-tailed correction. } \note{ This method may inflate statistical significance when clone sizes are uniformly small, such as when most clones sizes are 1, sample size is small, and \code{max_n} is near the total count of the smallest data group. Use caution when interpreting the results in such cases. We are currently investigating this potential problem. } \examples{ \dontrun{ # Groups under the size threshold are excluded and a warning message is issued. testDiversity(ExampleDb, "SAMPLE", q=0, min_n=30, nboot=100) } } \references{ \enumerate{ \item Hill M. Diversity and evenness: a unifying notation and its consequences. Ecology. 1973 54(2):427-32. \item Chao A. Nonparametric Estimation of the Number of Classes in a Population. Scand J Stat. 1984 11, 265270. \item Wu Y-CB, et al. Influence of seasonal exposure to grass pollen on local and peripheral blood IgE repertoires in patients with allergic rhinitis. J Allergy Clin Immunol. 2014 134(3):604-12. \item Chao A, et al. Rarefaction and extrapolation with Hill numbers: A framework for sampling and estimation in species diversity studies. Ecol Monogr. 2014 84:45-67. \item Chao A, et al. Unveiling the species-rank abundance distribution by generalizing the Good-Turing sample coverage theory. Ecology. 2015 96, 11891201. } } \seealso{ \link{alphaDiversity} } alakazam/man/translateDNA.Rd0000644000176200001440000000154613445225137015431 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Sequence.R \name{translateDNA} \alias{translateDNA} \title{Translate nucleotide sequences to amino acids} \usage{ translateDNA(seq, trim = FALSE) } \arguments{ \item{seq}{vector of strings defining DNA sequence(s) to be converted to translated.} \item{trim}{boolean flag to remove 3 nts from both ends of seq (converts IMGT junction to CDR3 region).} } \value{ A vector of translated sequence strings. } \description{ \code{translateDNA} translates nucleotide sequences to amino acid sequences. } \examples{ # Translate a single sequence translateDNA("ACTGACTCGA") # Translate a vector of sequences translateDNA(ExampleDb$JUNCTION[1:3]) # Remove the first and last codon from the translation translateDNA(ExampleDb$JUNCTION[1:3], trim=TRUE) } \seealso{ \code{\link[seqinr]{translate}}. } alakazam/man/buildPhylipLineage.Rd0000644000176200001440000001554013445225137016662 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Lineage.R \name{buildPhylipLineage} \alias{buildPhylipLineage} \title{Infer an Ig lineage using PHYLIP} \usage{ buildPhylipLineage(clone, dnapars_exec, dist_mat = getDNAMatrix(gap = 0), rm_temp = FALSE, verbose = FALSE) } \arguments{ \item{clone}{\link{ChangeoClone} object containing clone data.} \item{dnapars_exec}{absolute path to the PHYLIP dnapars executable.} \item{dist_mat}{Character distance matrix to use for reassigning edge weights. Defaults to a Hamming distance matrix returned by \link{getDNAMatrix} with \code{gap=0}. If gap characters, \code{c("-", ".")}, are assigned a value of -1 in \code{dist_mat} then contiguous gaps of any run length, which are not present in both sequences, will be counted as a distance of 1. Meaning, indels of any length will increase the sequence distance by 1. Gap values other than -1 will return a distance that does not consider indels as a special case.} \item{rm_temp}{if \code{TRUE} delete the temporary directory after running dnapars; if \code{FALSE} keep the temporary directory.} \item{verbose}{if \code{FALSE} suppress the output of dnapars; if \code{TRUE} STDOUT and STDERR of dnapars will be passed to the console.} } \value{ An igraph \code{graph} object defining the Ig lineage tree. Each unique input sequence in \code{clone} is a vertex of the tree, with additional vertices being either the germline (root) sequences or inferred intermediates. The \code{graph} object has the following attributes. Vertex attributes: \itemize{ \item \code{name}: value in the \code{SEQUENCE_ID} column of the \code{data} slot of the input \code{clone} for observed sequences. The germline (root) vertex is assigned the name "Germline" and inferred intermediates are assigned names with the format {"Inferred1", "Inferred2", ...}. \item \code{sequence}: value in the \code{SEQUENCE} column of the \code{data} slot of the input \code{clone} for observed sequences. The germline (root) vertex is assigned the sequence in the \code{germline} slot of the input \code{clone}. The sequence of inferred intermediates are extracted from the dnapars output. \item \code{label}: same as the \code{name} attribute. } Additionally, each other column in the \code{data} slot of the input \code{clone} is added as a vertex attribute with the attribute name set to the source column name. For the germline and inferred intermediate vertices, these additional vertex attributes are all assigned a value of \code{NA}. Edge attributes: \itemize{ \item \code{weight}: Hamming distance between the \code{sequence} attributes of the two vertices. \item \code{label}: same as the \code{weight} attribute. } Graph attributes: \itemize{ \item \code{clone}: clone identifier from the \code{clone} slot of the input \code{ChangeoClone}. \item \code{v_gene}: V-segment gene call from the \code{v_gene} slot of the input \code{ChangeoClone}. \item \code{j_gene}: J-segment gene call from the \code{j_gene} slot of the input \code{ChangeoClone}. \item \code{junc_len}: junction length (nucleotide count) from the \code{junc_len} slot of the input \code{ChangeoClone}. } } \description{ \code{buildPhylipLineage} reconstructs an Ig lineage via maximum parsimony using the dnapars application of the PHYLIP package. } \details{ \code{buildPhylipLineage} builds the lineage tree of a set of unique Ig sequences via maximum parsimony through an external call to the dnapars application of the PHYLIP package. dnapars is called with default algorithm options, except for the search option, which is set to "Rearrange on one best tree". The germline sequence of the clone is used for the outgroup. Following tree construction using dnapars, the dnapars output is modified to allow input sequences to appear as internal nodes of the tree. Intermediate sequences inferred by dnapars are replaced by children within the tree having a Hamming distance of zero from their parent node. With the default \code{dist_mat}, the distance calculation allows IUPAC ambiguous character matches, where an ambiguous character has distance zero to any character in the set of characters it represents. Distance calculation and movement of child nodes up the tree is repeated until all parent-child pairs have a distance greater than zero between them. The germline sequence (outgroup) is moved to the root of the tree and excluded from the node replacement processes, which permits the trunk of the tree to be the only edge with a distance of zero. Edge weights of the resultant tree are assigned as the distance between each sequence. } \examples{ \dontrun{ # Preprocess clone db <- subset(ExampleDb, CLONE == 3138) clone <- makeChangeoClone(db, text_fields=c("SAMPLE", "ISOTYPE"), num_fields="DUPCOUNT") # Run PHYLIP and process output dnapars_exec <- "~/apps/phylip-3.69/dnapars" graph <- buildPhylipLineage(clone, dnapars_exec, rm_temp=TRUE) # Plot graph with a tree layout library(igraph) plot(graph, layout=layout_as_tree, vertex.label=V(graph)$ISOTYPE, vertex.size=50, edge.arrow.mode=0, vertex.color="grey80") # To consider each indel event as a mutation, change the masking character # and distance matrix clone <- makeChangeoClone(db, text_fields=c("SAMPLE", "ISOTYPE"), num_fields="DUPCOUNT", mask_char="-") graph <- buildPhylipLineage(clone, dnapars_exec, dist_mat=getDNAMatrix(gap=-1), rm_temp=TRUE) } } \references{ \enumerate{ \item Felsenstein J. PHYLIP - Phylogeny Inference Package (Version 3.2). Cladistics. 1989 5:164-166. \item Stern JNH, Yaari G, Vander Heiden JA, et al. B cells populating the multiple sclerosis brain mature in the draining cervical lymph nodes. Sci Transl Med. 2014 6(248):248ra107. } } \seealso{ Takes as input a \link{ChangeoClone}. Temporary directories are created with \link{makeTempDir}. Distance is calculated using \link{seqDist}. See \link{igraph} and \link{igraph.plotting} for working with igraph \code{graph} objects. } alakazam/man/plotEdgeTest.Rd0000644000176200001440000000330513445225137015507 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Topology.R \name{plotEdgeTest} \alias{plotEdgeTest} \title{Plot the results of an edge permutation test} \usage{ plotEdgeTest(data, color = "black", main_title = "Edge Test", style = c("histogram", "cdf"), silent = FALSE, ...) } \arguments{ \item{data}{\link{EdgeTest} object returned by \link{testEdges}.} \item{color}{color of the histogram or lines.} \item{main_title}{string specifying the plot title.} \item{style}{type of plot to draw. One of: \itemize{ \item \code{"histogram"}: histogram of the edge count distribution with a red dotted line denoting the observed value. \item \code{"cdf"}: cumulative distribution function of edge counts with a red dotted line denoting the observed value and a blue dotted line indicating the p-value. }} \item{silent}{if \code{TRUE} do not draw the plot and just return the ggplot2 object; if \code{FALSE} draw the plot.} \item{...}{additional arguments to pass to ggplot2::theme.} } \value{ A \code{ggplot} object defining the plot. } \description{ \code{plotEdgeTest} plots the results of an edge permutation test performed with \code{testEdges} as either a histogram or cumulative distribution function. } \examples{ \donttest{ # Define example tree set graphs <- ExampleTrees[1-10] # Perform edge test on isotypes x <- testEdges(graphs, "ISOTYPE", nperm=10) # Plot plotEdgeTest(x, color="steelblue", style="hist") plotEdgeTest(x, style="cdf") } } \seealso{ See \link{testEdges} for performing the test. } alakazam/man/collapseDuplicates.Rd0000644000176200001440000001447513445225137016736 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Sequence.R \name{collapseDuplicates} \alias{collapseDuplicates} \title{Remove duplicate DNA sequences and combine annotations} \usage{ collapseDuplicates(data, id = "SEQUENCE_ID", seq = "SEQUENCE_IMGT", text_fields = NULL, num_fields = NULL, seq_fields = NULL, add_count = FALSE, ignore = c("N", "-", ".", "?"), sep = ",", dry = FALSE, verbose = FALSE) } \arguments{ \item{data}{data.frame containing Change-O columns. The data.frame must contain, at a minimum, a unique identifier column and a column containg a character vector of DNA sequences.} \item{id}{name of the column containing sequence identifiers.} \item{seq}{name of the column containing DNA sequences.} \item{text_fields}{character vector of textual columns to collapse. The textual annotations of duplicate sequences will be merged into a single string with each unique value alphabetized and delimited by \code{sep}.} \item{num_fields}{vector of numeric columns to collapse. The numeric annotations of duplicate sequences will be summed.} \item{seq_fields}{vector of nucletoide sequence columns to collapse. The sequence with the fewest numer of non-informative characters will be retained. Where a non-informative character is one of \code{c("N", "-", ".", "?")}. Note, this is distinct from the \code{seq} parameter which is used to determine duplicates.} \item{add_count}{if \code{TRUE} add the column \code{COLLAPSE_COUNT} that indicates the number of sequences that were collapsed to build each unique entry.} \item{ignore}{vector of characters to ignore when testing for equality.} \item{sep}{character to use for delimiting collapsed annotations in the \code{text_fields} columns. Defines both the input and output delimiter.} \item{dry}{if \code{TRUE} perform dry run. Only labels the sequences without collapsing them.} \item{verbose}{if \code{TRUE} report the number input, discarded and output sequences; if \code{FALSE} process sequences silently.} } \value{ A modified \code{data} data.frame with duplicate sequences removed and annotation fields collapsed if \code{dry=FALSE}. If \code{dry=TRUE}, sequences will be labeled with the collapse action, but the input will be otherwise unmodifed (see Details). } \description{ \code{collapseDuplicates} identifies duplicate DNA sequences, allowing for ambiguous characters, removes the duplicate entries, and combines any associated annotations. } \details{ \code{collapseDuplicates} identifies duplicate sequences in the \code{seq} column by testing for character identity, with consideration of IUPAC ambiguous nucleotide codes. A cluster of sequences are considered duplicates if they are all equivalent, and no member of the cluster is equivalent to a sequence in a different cluster. Textual annotations, specified by \code{text_fields}, are collapsed by taking the unique set of values within in each duplicate cluster and delimiting those values by \code{sep}. Numeric annotations, specified by \code{num_fields}, are collapsed by summing all values in the duplicate cluster. Sequence annotations, specified by \code{seq_fields}, are collapsed by retaining the first sequence with the fewest number of N characters. Columns that are not specified in either \code{text_fields}, \code{num_fields}, or \code{seq_fields} will be retained, but the value will be chosen from a random entry amongst all sequences in a cluster of duplicates. An ambiguous sequence is one that can be assigned to two different clusters, wherein the ambiguous sequence is equivalent to two sequences which are themselves non-equivalent. Ambiguous sequences arise due to ambiguous characters at positions that vary across sequences, and are discarded along with their annotations when \code{dry=FALSE}. Thus, ambiguous sequences are removed as duplicates of some sequence, but do not create a potential false-positive annotation merger. Ambiguous sequences are not included in the \code{COLLAPSE_COUNT} annotation that is added when \code{add_count=TRUE}. If \code{dry=TRUE} sequences will not be removed from the input. Instead, the following columns will be appended to the input defining the collapse action that would have been performed in the \code{dry=FALSE} case. \itemize{ \item \code{COLLAPSE_ID}: an identifer for the group of identical sequences. \item \code{COLLAPSE_CLASS}: string defining how the sequence matches to the other in the set. one of \code{"duplicated"} (has duplicates), \code{"unique"} (no duplicates), \code{"ambiguous_duplicate"} (no duplicates after ambiguous sequences are removed), or \code{"ambiguous"} (matches multiple non-duplicate sequences). \item \code{COLLAPSE_PASS}: \code{TRUE} for the sequences that would be retained. } } \examples{ # Example Change-O data.frame db <- data.frame(SEQUENCE_ID=LETTERS[1:4], SEQUENCE_IMGT=c("CCCCTGGG", "CCCCTGGN", "NAACTGGN", "NNNCTGNN"), TYPE=c("IgM", "IgG", "IgG", "IgA"), SAMPLE=c("S1", "S1", "S2", "S2"), COUNT=1:4, stringsAsFactors=FALSE) # Annotations are not parsed if neither text_fields nor num_fields is specified # The retained sequence annotations will be random collapseDuplicates(db, verbose=TRUE) # Unique text_fields annotations are combined into a single string with "," # num_fields annotations are summed # Ambiguous duplicates are discarded collapseDuplicates(db, text_fields=c("TYPE", "SAMPLE"), num_fields="COUNT", verbose=TRUE) # Use alternate delimiter for collapsing textual annotations collapseDuplicates(db, text_fields=c("TYPE", "SAMPLE"), num_fields="COUNT", sep="/", verbose=TRUE) # Add count of duplicates collapseDuplicates(db, text_fields=c("TYPE", "SAMPLE"), num_fields="COUNT", add_count=TRUE, verbose=TRUE) # Masking ragged ends may impact duplicate removal db$SEQUENCE_IMGT <- maskSeqEnds(db$SEQUENCE_IMGT) collapseDuplicates(db, text_fields=c("TYPE", "SAMPLE"), num_fields="COUNT", add_count=TRUE, verbose=TRUE) } \seealso{ Equality is tested with \link{seqEqual} and \link{pairwiseEqual}. For IUPAC ambiguous character codes see \link{IUPAC_DNA}. } alakazam/man/plotDiversityTest.Rd0000644000176200001440000000372513512442170016624 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Diversity.R \name{plotDiversityTest} \alias{plotDiversityTest} \title{Plot the results of diversity testing} \usage{ plotDiversityTest(data, q, colors = NULL, main_title = "Diversity", legend_title = "Group", log_d = FALSE, annotate = c("none", "depth"), silent = FALSE, ...) } \arguments{ \item{data}{\link{DiversityCurve} object returned by \link{alphaDiversity}.} \item{q}{diversity order to plot the test for.} \item{colors}{named character vector whose names are values in the \code{group} column of the \code{data} slot of \code{data}, and whose values are colors to assign to those group names.} \item{main_title}{string specifying the plot title.} \item{legend_title}{string specifying the legend title.} \item{log_d}{if \code{TRUE} then plot the diversity scores \eqn{D} on a log scale; if \code{FALSE} plot on a linear scale.} \item{annotate}{string defining whether to added values to the group labels of the legend. When \code{"none"} (default) is specified no annotations are added. Specifying (\code{"depth"}) adds sequence counts to the labels.} \item{silent}{if \code{TRUE} do not draw the plot and just return the ggplot2 object; if \code{FALSE} draw the plot.} \item{...}{additional arguments to pass to ggplot2::theme.} } \value{ A \code{ggplot} object defining the plot. } \description{ \code{plotDiversityTest} plots summary data for a \code{DiversityCurve} object with mean and a line range indicating plus/minus one standard deviation. } \examples{ # Calculate diversity div <- alphaDiversity(ExampleDb, group="SAMPLE", min_q=0, max_q=2, step_q=1, nboot=100) # Plot results at q=0 (equivalent to species richness) plotDiversityTest(div, 0, legend_title="Sample") # Plot results at q=2 (equivalent to Simpson's index) plotDiversityTest(div, q=2, legend_title="Sample") } \seealso{ See \link{alphaDiversity} for generating input. Plotting is performed with \link{ggplot}. } alakazam/man/ABBREV_AA.Rd0000644000176200001440000000072413445225137014410 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Data.R \docType{data} \name{ABBREV_AA} \alias{ABBREV_AA} \title{Amino acid abbreviation translations} \format{Named character vector defining single-letter character codes to three-letter abbreviation mappings.} \usage{ ABBREV_AA } \description{ Mappings of amino acid abbreviations. } \examples{ aa <- c("Ala", "Ile", "Trp") translateStrings(aa, ABBREV_AA) } \keyword{datasets} alakazam/man/pairwiseEqual.Rd0000644000176200001440000000167613445225137015730 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/RcppExports.R \name{pairwiseEqual} \alias{pairwiseEqual} \title{Calculate pairwise equivalence between sequences} \usage{ pairwiseEqual(seq) } \arguments{ \item{seq}{character vector containing a DNA sequences.} } \value{ A logical matrix of equivalence between each entry in \code{seq}. Values are \code{TRUE} when sequences are equivalent and \code{FALSE} when they are not. } \description{ \code{pairwiseEqual} determined pairwise equivalence between a pairs in a set of sequences, excluding ambiguous positions (Ns and gaps). } \examples{ # Gaps and Ns will match any character seq <- c(A="ATGGC", B="ATGGG", C="ATGGG", D="AT--C", E="NTGGG") d <- pairwiseEqual(seq) rownames(d) <- colnames(d) <- seq d } \seealso{ Uses \link{seqEqual} for testing equivalence between pairs. See \link{pairwiseDist} for generating a sequence distance matrix. } alakazam/man/getDNAMatrix.Rd0000644000176200001440000000200113445225137015363 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Sequence.R \name{getDNAMatrix} \alias{getDNAMatrix} \title{Build a DNA distance matrix} \usage{ getDNAMatrix(gap = -1) } \arguments{ \item{gap}{value to assign to characters in the set \code{c("-", ".")}.} } \value{ A \code{matrix} of DNA character distances with row and column names indicating the character pair. By default, distances will be either 0 (equivalent), 1 (non-equivalent or missing), or -1 (gap). } \description{ \code{getDNAMatrix} returns a Hamming distance matrix for IUPAC ambiguous DNA characters with modifications for gap, \code{c("-", ".")}, and missing, \code{c("?")}, character values. } \examples{ # Set gap characters to Inf distance # Distinguishes gaps from Ns getDNAMatrix() # Set gap characters to 0 distance # Makes gap characters equivalent to Ns getDNAMatrix(gap=0) } \seealso{ Creates DNA distance matrix for \link{seqDist}. See \link{getAAMatrix} for amino acid distances. } alakazam/man/calcDiversity.Rd0000644000176200001440000000346613513133770015716 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Diversity.R \name{calcDiversity} \alias{calcDiversity} \title{Calculate the diversity index} \usage{ calcDiversity(p, q) } \arguments{ \item{p}{numeric vector of clone (species) counts or proportions.} \item{q}{numeric vector of diversity orders.} } \value{ A vector of diversity scores \eqn{D} for each \eqn{q}. } \description{ \code{calcDiversity} calculates the clonal diversity index for a vector of diversity orders. } \details{ This method, proposed by Hill (Hill, 1973), quantifies diversity as a smooth function (\eqn{D}) of a single parameter \eqn{q}. Special cases of the generalized diversity index correspond to the most popular diversity measures in ecology: species richness (\eqn{q = 0}), the exponential of the Shannon-Weiner index (\eqn{q} approaches \eqn{1}), the inverse of the Simpson index (\eqn{q = 2}), and the reciprocal abundance of the largest clone (\eqn{q} approaches \eqn{+\infty}). At \eqn{q = 0} different clones weight equally, regardless of their size. As the parameter \eqn{q} increase from \eqn{0} to \eqn{+\infty} the diversity index (\eqn{D}) depends less on rare clones and more on common (abundant) ones, thus encompassing a range of definitions that can be visualized as a single curve. Values of \eqn{q < 0} are valid, but are generally not meaningful. The value of \eqn{D} at \eqn{q=1} is estimated by \eqn{D} at \eqn{q=0.9999}. } \examples{ # May define p as clonal member counts p <- c(1, 1, 3, 10) q <- c(0, 1, 2) calcDiversity(p, q) # Or proportional abundance p <- c(1/15, 1/15, 1/5, 2/3) calcDiversity(p, q) } \references{ \enumerate{ \item Hill M. Diversity and evenness: a unifying notation and its consequences. Ecology. 1973 54(2):427-32. } } \seealso{ Used by \link{alphaDiversity}. } alakazam/man/pairwiseDist.Rd0000644000176200001440000000347013445225137015556 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Sequence.R \name{pairwiseDist} \alias{pairwiseDist} \title{Calculate pairwise distances between sequences} \usage{ pairwiseDist(seq, dist_mat = getDNAMatrix()) } \arguments{ \item{seq}{character vector containing a DNA sequences.} \item{dist_mat}{Character distance matrix. Defaults to a Hamming distance matrix returned by \link{getDNAMatrix}. If gap characters, \code{c("-", ".")}, are assigned a value of -1 in \code{dist_mat} then contiguous gaps of any run length, which are not present in both sequences, will be counted as a distance of 1. Meaning, indels of any length will increase the sequence distance by 1. Gap values other than -1 will return a distance that does not consider indels as a special case.} } \value{ A matrix of numerical distance between each entry in \code{seq}. If \code{seq} is a named vector, row and columns names will be added accordingly. Amino acid distance matrix may be built with \link{getAAMatrix}. Uses \link{seqDist} for calculating distances between pairs. See \link{pairwiseEqual} for generating an equivalence matrix. } \description{ \code{pairwiseDist} calculates all pairwise distance between a set of sequences. } \examples{ # Gaps will be treated as Ns with a gap=0 distance matrix pairwiseDist(c(A="ATGGC", B="ATGGG", C="ATGGG", D="AT--C"), dist_mat=getDNAMatrix(gap=0)) # Gaps will be treated as universally non-matching characters with gap=1 pairwiseDist(c(A="ATGGC", B="ATGGG", C="ATGGG", D="AT--C"), dist_mat=getDNAMatrix(gap=1)) # Gaps of any length will be treated as single mismatches with a gap=-1 distance matrix pairwiseDist(c(A="ATGGC", B="ATGGG", C="ATGGG", D="AT--C"), dist_mat=getDNAMatrix(gap=-1)) } alakazam/man/alphaDiversity.Rd0000644000176200001440000000724513512442170016074 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Diversity.R \name{alphaDiversity} \alias{alphaDiversity} \title{Calculate clonal alpha diversity} \usage{ alphaDiversity(data, min_q = 0, max_q = 4, step_q = 0.1, ci = 0.95, ...) } \arguments{ \item{data}{data.frame with Change-O style columns containing clonal assignments or a \link{AbundanceCurve} generate by \link{estimateAbundance} object containing a previously calculated bootstrap distributions of clonal abundance.} \item{min_q}{minimum value of \eqn{q}.} \item{max_q}{maximum value of \eqn{q}.} \item{step_q}{value by which to increment \eqn{q}.} \item{ci}{confidence interval to calculate; the value must be between 0 and 1.} \item{...}{additional arguments to pass to \link{estimateAbundance}. Additional arguments are ignored if a \link{AbundanceCurve} is provided as input.} } \value{ A \link{DiversityCurve} object summarizing the diversity scores. } \description{ \code{alphaDiversity} takes in a data.frame or \link{AbundanceCurve} and computes diversity scores (\eqn{D}) over an interval of diversity orders (\eqn{q}). } \details{ Clonal diversity is calculated using the generalized diversity index (Hill numbers) proposed by Hill (Hill, 1973). See \link{calcDiversity} for further details. Diversity is calculated on the estimated complete clonal abundance distribution. This distribution is inferred by using the Chao1 estimator to estimate the number of seen clones, and applying the relative abundance correction and unseen clone frequency described in Chao et al, 2015. To generate a smooth curve, \eqn{D} is calculated for each value of \eqn{q} from \code{min_q} to \code{max_q} incremented by \code{step_q}. When \code{uniform=TRUE} variability in total sequence counts across unique values in the \code{group} column is corrected by repeated resampling from the estimated complete clonal distribution to a common number of sequences. The diversity index (\eqn{D}) for each group is the mean value of over all resampling realizations. Confidence intervals are derived using the standard deviation of the resampling realizations, as described in Chao et al, 2015. Of note, the complete clonal abundance distribution is inferred by using the Chao1 estimator to estimate the number of seen clones, and then applying the relative abundance correction and unseen clone frequencies described in Chao et al, 2015. } \examples{ # Group by sample identifier in two steps abund <- estimateAbundance(ExampleDb, group="SAMPLE", nboot=100) div <- alphaDiversity(abund, step_q=1, max_q=10) plotDiversityCurve(div, legend_title="Sample") # Grouping by isotype rather than sample identifier in one step div <- alphaDiversity(ExampleDb, group="ISOTYPE", min_n=40, step_q=1, max_q=10, nboot=100) plotDiversityCurve(div, legend_title="Isotype") } \references{ \enumerate{ \item Hill M. Diversity and evenness: a unifying notation and its consequences. Ecology. 1973 54(2):427-32. \item Chao A. Nonparametric Estimation of the Number of Classes in a Population. Scand J Stat. 1984 11, 265270. \item Chao A, et al. Rarefaction and extrapolation with Hill numbers: A framework for sampling and estimation in species diversity studies. Ecol Monogr. 2014 84:45-67. \item Chao A, et al. Unveiling the species-rank abundance distribution by generalizing the Good-Turing sample coverage theory. Ecology. 2015 96, 11891201. } } \seealso{ See \link{calcDiversity} for the basic calculation and \link{DiversityCurve} for the return object. See \link{plotDiversityCurve} for plotting the return object. } alakazam/man/permuteLabels.Rd0000644000176200001440000000207313445225137015711 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Topology.R \name{permuteLabels} \alias{permuteLabels} \title{Permute the node labels of a tree} \usage{ permuteLabels(graph, field, exclude = c("Germline", NA)) } \arguments{ \item{graph}{igraph object containing an annotated lineage tree.} \item{field}{string defining the annotation field to permute.} \item{exclude}{vector of strings defining \code{field} values to exclude from permutation.} } \value{ A modified igraph object with vertex annotations permuted. } \description{ \code{permuteLabels} permutes the node annotations of a lineage tree. } \examples{ # Define and plot example graph library(igraph) graph <- ExampleTrees[[23]] plot(graph, layout=layout_as_tree, vertex.label=V(graph)$ISOTYPE, vertex.size=50, edge.arrow.mode=0, vertex.color="grey80") # Permute annotations and plot new tree g <- permuteLabels(graph, "ISOTYPE") plot(g, layout=layout_as_tree, vertex.label=V(g)$ISOTYPE, vertex.size=50, edge.arrow.mode=0, vertex.color="grey80") } \seealso{ \link{testEdges}. } alakazam/man/makeChangeoClone.Rd0000644000176200001440000001363013445225137016271 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Lineage.R \name{makeChangeoClone} \alias{makeChangeoClone} \title{Generate a ChangeoClone object for lineage construction} \usage{ makeChangeoClone(data, id = "SEQUENCE_ID", seq = "SEQUENCE_IMGT", germ = "GERMLINE_IMGT_D_MASK", vcall = "V_CALL", jcall = "J_CALL", junc_len = "JUNCTION_LENGTH", clone = "CLONE", mask_char = "N", max_mask = 0, pad_end = FALSE, text_fields = NULL, num_fields = NULL, seq_fields = NULL, add_count = TRUE, verbose = FALSE) } \arguments{ \item{data}{data.frame containing the Change-O data for a clone. See Details for the list of required columns and their default values.} \item{id}{name of the column containing sequence identifiers.} \item{seq}{name of the column containing observed DNA sequences. All sequences in this column must be multiple aligned.} \item{germ}{name of the column containing germline DNA sequences. All entries in this column should be identical for any given clone, and they must be multiple aligned with the data in the \code{seq} column.} \item{vcall}{name of the column containing V-segment allele assignments. All entries in this column should be identical to the gene level.} \item{jcall}{name of the column containing J-segment allele assignments. All entries in this column should be identical to the gene level.} \item{junc_len}{name of the column containing the length of the junction as a numeric value. All entries in this column should be identical for any given clone.} \item{clone}{name of the column containing the identifier for the clone. All entries in this column should be identical.} \item{mask_char}{character to use for masking and padding.} \item{max_mask}{maximum number of characters to mask at the leading and trailing sequence ends. If \code{NULL} then the upper masking bound will be automatically determined from the maximum number of observed leading or trailing Ns amongst all sequences. If set to \code{0} (default) then masking will not be performed.} \item{pad_end}{if \code{TRUE} pad the end of each sequence with \code{mask_char} to make every sequence the same length.} \item{text_fields}{text annotation columns to retain and merge during duplicate removal.} \item{num_fields}{numeric annotation columns to retain and sum during duplicate removal.} \item{seq_fields}{sequence annotation columns to retain and collapse during duplicate removal. Note, this is distinct from the \code{seq} and \code{germ} arguments, which contain the primary sequence data for the clone and should not be repeated in this argument.} \item{add_count}{if \code{TRUE} add an additional annotation column called \code{COLLAPSE_COUNT} during duplicate removal that indicates the number of sequences that were collapsed.} \item{verbose}{passed on to \code{collapseDuplicates}. If \code{TRUE}, report the numbers of input, discarded and output sequences; otherwise, process sequences silently.} } \value{ A \link{ChangeoClone} object containing the modified clone. } \description{ \code{makeChangeoClone} takes a data.frame with Change-O style columns as input and masks gap positions, masks ragged ends, removes duplicates sequences, and merges annotations associated with duplicate sequences. It returns a \code{ChangeoClone} object which serves as input for lineage reconstruction. } \details{ The input data.frame (\code{data}) must columns for each of the required column name arguments: \code{id}, \code{seq}, \code{germ}, \code{vcall}, \code{jcall}, \code{junc_len}, and \code{clone}. The default values are as follows: \itemize{ \item \code{id = "SEQUENCE_ID"}: unique sequence identifier. \item \code{seq = "SEQUENCE_IMGT"}: IMGT-gapped sample sequence. \item \code{germ = "GERMLINE_IMGT_D_MASK"}: IMGT-gapped germline sequence. \item \code{vcall = "V_CALL"}: V-segment allele call. \item \code{jcall = "J_CALL"}: J-segment allele call. \item \code{junc_len = "JUNCTION_LENGTH"}: junction sequence length. \item \code{clone = "CLONE"}: clone identifier. } Additional annotation columns specified in the \code{text_fields}, \code{num_fields} or \code{seq_fields} arguments will be retained in the \code{data} slot of the return object, but are not required. If the input data.frame \code{data} already contains a column named \code{SEQUENCE}, which is not used as the \code{seq} argument, then that column will not be retained. The default columns are IMGT-gapped sequence columns, but this is not a requirement. However, all sequences (both observed and germline) must be multiple aligned using some scheme for both proper duplicate removal and lineage reconstruction. The value for the germline sequence, V-segment gene call, J-segment gene call, junction length, and clone identifier are determined from the first entry in the \code{germ}, \code{vcall}, \code{jcall}, \code{junc_len} and \code{clone} columns, respectively. For any given clone, each value in these columns should be identical. } \examples{ # Example Change-O data.frame db <- data.frame(SEQUENCE_ID=LETTERS[1:4], SEQUENCE_IMGT=c("CCCCTGGG", "CCCCTGGN", "NAACTGGN", "NNNCTGNN"), V_CALL="Homsap IGKV1-39*01 F", J_CALL="Homsap IGKJ5*01 F", JUNCTION_LENGTH=2, GERMLINE_IMGT_D_MASK="CCCCAGGG", CLONE=1, TYPE=c("IgM", "IgG", "IgG", "IgA"), COUNT=1:4, stringsAsFactors=FALSE) # Without end masking makeChangeoClone(db, text_fields="TYPE", num_fields="COUNT") # With end masking makeChangeoClone(db, max_mask=3, text_fields="TYPE", num_fields="COUNT") } \seealso{ Executes in order \link{maskSeqGaps}, \link{maskSeqEnds}, \link{padSeqEnds}, and \link{collapseDuplicates}. Returns a \link{ChangeoClone} object which serves as input to \link{buildPhylipLineage}. } alakazam/man/IUPAC_CODES.Rd0000644000176200001440000000134013445225137014657 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Data.R \docType{data} \name{IUPAC_CODES} \alias{IUPAC_CODES} \alias{IUPAC_DNA} \alias{IUPAC_AA} \title{IUPAC ambiguous characters} \format{A list with single character codes as names and values containing character vectors that define the set of standard characters that match to each each ambiguous character. \itemize{ \item \code{IUPAC_DNA}: DNA ambiguous character translations. \item \code{IUPAC_AA}: Amino acid ambiguous character translations. }} \usage{ IUPAC_DNA IUPAC_AA } \description{ A translation list mapping IUPAC ambiguous characters code to corresponding nucleotide amino acid characters. } \keyword{datasets} alakazam/man/gridPlot.Rd0000644000176200001440000000074413445225137014674 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Core.R \name{gridPlot} \alias{gridPlot} \title{Plot multiple ggplot objects} \usage{ gridPlot(..., ncol = 1) } \arguments{ \item{...}{ggplot objects to plot.} \item{ncol}{number of columns in the plot.} } \description{ Plots multiple ggplot objects in an equally sized grid. } \references{ Modified from: http://www.cookbook-r.com/Graphs/Multiple_graphs_on_one_page_(ggplot2) } \seealso{ \link{ggplot}. } alakazam/man/progressBar.Rd0000644000176200001440000000053613445225137015400 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Core.R \name{progressBar} \alias{progressBar} \title{Standard progress bar} \usage{ progressBar(n) } \arguments{ \item{n}{maximum number of ticks} } \value{ A \link[progress]{progress_bar} object. } \description{ \code{progressBar} defines a common progress bar format. } alakazam/man/ExampleDb.Rd0000644000176200001440000000366413445225137014755 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Data.R \docType{data} \name{ExampleDb} \alias{ExampleDb} \title{Example Change-O database} \format{A data.frame with the following Change-O style columns: \itemize{ \item \code{SEQUENCE_ID}: Sequence identifier \item \code{SEQUENCE_IMGT}: IMGT-gapped observed sequence. \item \code{GERMLINE_IMGT_D_MASK}: IMGT-gapped germline sequence with N, P and D regions masked. \item \code{V_CALL}: V region allele assignments. \item \code{V_CALL_GENOTYPED}: TIgGER corrected V region allele assignment. \item \code{D_CALL}: D region allele assignments. \item \code{J_CALL}: J region allele assignments. \item \code{JUNCTION}: Junction region sequence. \item \code{JUNCTION_LENGTH}: Length of the junction region in nucleotides. \item \code{NP1_LENGTH}: Combined length of the N and P regions proximal to the V region. \item \code{NP2_LENGTH}: Combined length of the N and P regions proximal to the J region. \item \code{SAMPLE}: Sample identifier. Time in relation to vaccination. \item \code{ISOTYPE}: Isotype assignment. \item \code{DUPCOUNT}: Copy count (number of duplicates) of the sequence. \item \code{CLONE}: Change-O assignment clonal group identifier. }} \usage{ ExampleDb } \description{ A small example database subset from Laserson and Vigneault et al, 2014. } \references{ \enumerate{ \item Laserson U and Vigneault F, et al. High-resolution antibody dynamics of vaccine-induced immune responses. Proc Natl Acad Sci USA. 2014 111:4928-33. } } \seealso{ \link{ExampleTrees} } \keyword{datasets} alakazam/man/combineIgphyml.Rd0000644000176200001440000000415213512442170016044 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Lineage.R \name{combineIgphyml} \alias{combineIgphyml} \title{Combine IgPhyML object parameters into a dataframe} \usage{ combineIgphyml(iglist, format = c("wide", "long")) } \arguments{ \item{iglist}{list of igphyml objects returned by \link{readIgphyml}. Each must have an \code{ID} column in its \code{param} attribute, which can be added automatically using the \code{id} option of \code{readIgphyml}.} \item{format}{string specifying whether each column of the resulting data.frame should represent a parameter (\code{wide}) or if there should only be three columns; i.e. ID, varable, and value (\code{long}).} } \value{ A data.frame containing HLP model parameter estimates for all igphyml objects. Only parameters shared among all objects will be returned. } \description{ \code{combineIgphyml} combines IgPhyML object parameters into a data.frame. } \details{ \code{combineIgphyml} combines repertoire-wide parameter estimates from mutliple igphyml objects produced by readIgphyml into a dataframe that can be easily used for plotting and other hypothesis testing analyses. All igphyml objects used must have an "ID" column in their \code{param} attribute, which can be added automatically from the \code{id} flag of \code{readIgphyml}. } \examples{ \dontrun{ # Read in and combine two igphyml runs s1 <- readIgphyml("IB+7d_lineages_gy.tsv_igphyml_stats_hlp.tab", id="+7d") s2 <- readIgphyml("IB+7d_lineages_gy.tsv_igphyml_stats_hlp.tab", id="s2") combineIgphyml(list(s1, s2)) } } \references{ \enumerate{ \item Hoehn KB, Lunter G, Pybus OG - A Phylogenetic Codon Substitution Model for Antibody Lineages. Genetics 2017 206(1):417-427 https://doi.org/10.1534/genetics.116.196303 \item Hoehn KB, Vander Heiden JA, Zhou JQ, Lunter G, Pybus OG, Kleinstein SHK - Repertoire-wide phylogenetic models of B cell molecular evolution reveal evolutionary signatures of aging and vaccination. bioRxiv 2019 https://doi.org/10.1101/558825 } } \seealso{ \link{readIgphyml} } alakazam/man/aminoAcidProperties.Rd0000644000176200001440000001342713445225137017053 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/AminoAcids.R \name{aminoAcidProperties} \alias{aminoAcidProperties} \title{Calculates amino acid chemical properties for sequence data} \usage{ aminoAcidProperties(data, property = c("length", "gravy", "bulk", "aliphatic", "polarity", "charge", "basic", "acidic", "aromatic"), seq = "JUNCTION", nt = FALSE, trim = FALSE, label = NULL, ...) } \arguments{ \item{data}{\code{data.frame} containing sequence data.} \item{property}{vector strings specifying the properties to be calculated. Defaults to calculating all defined properties.} \item{seq}{\code{character} name of the column containing input sequences.} \item{nt}{boolean, TRUE if the sequences (or sequence) are DNA and will be translated.} \item{trim}{if \code{TRUE} remove the first and last codon/amino acids from each sequence before calculating properties. If \code{FALSE} do not modify input sequences.} \item{label}{name of sequence region to add as prefix to output column names.} \item{...}{additional named arguments to pass to the functions \link{gravy}, \link{bulk}, \link{aliphatic}, \link{polar} or \link{charge}.} } \value{ A modified \code{data} data.frame with the following columns: \itemize{ \item \code{*_AA_LENGTH}: number of amino acids. \item \code{*_AA_GRAVY}: grand average of hydrophobicity (GRAVY) index. \item \code{*_AA_BULK}: average bulkiness of amino acids. \item \code{*_AA_ALIPHATIC}: aliphatic index. \item \code{*_AA_POLARITY}: average polarity of amino acids. \item \code{*_AA_CHARGE}: net charge. \item \code{*_AA_BASIC}: fraction of informative positions that are Arg, His or Lys. \item \code{*_AA_ACIDIC}: fraction of informative positions that are Asp or Glu. \item \code{*_AA_AROMATIC}: fraction of informative positions that are His, Phe, Trp or Tyr. } Where \code{*} is the value from \code{label} or the name specified for \code{seq} if \code{label=NULL}. } \description{ \code{aminoAcidProperties} calculates amino acid sequence physicochemical properties, including length, hydrophobicity, bulkiness, polarity, aliphatic index, net charge, acidic residue content, basic residue content, and aromatic residue content. } \details{ For all properties except for length, non-informative positions are excluded, where non-informative is defined as any character in \code{c("X", "-", ".", "*")}. The scores for GRAVY, bulkiness and polarity are calculated as simple averages of the scores for each informative positions. The basic, acid and aromatic indices are calculated as the fraction of informative positions falling into the given category. The aliphatic index is calculated using the Ikai, 1980 method. The net charge is calculated using the method of Moore, 1985, excluding the N-terminus and C-terminus charges, and normalizing by the number of informative positions. The default pH for the calculation is 7.4. The following data sources were used for the default property scores: \itemize{ \item hydropathy: Kyte & Doolittle, 1982. \item bulkiness: Zimmerman et al, 1968. \item polarity: Grantham, 1974. \item pK: EMBOSS. } } \examples{ # Subset example data db <- ExampleDb[c(1,10,100), c("SEQUENCE_ID", "JUNCTION")] # Calculate default amino acid properties from amino acid sequences # Use a custom output column prefix db$JUNCTION_TRANS <- translateDNA(db$JUNCTION) aminoAcidProperties(db, seq="JUNCTION_TRANS", label="JUNCTION") # Calculate default amino acid properties from DNA sequences aminoAcidProperties(db, seq="JUNCTION", nt=TRUE) # Use the Grantham, 1974 side chain volume scores from the seqinr package # Set pH=7.0 for the charge calculation # Calculate only average volume and charge # Remove the head and tail amino acids from the junction, thus making it the CDR3 library(seqinr) data(aaindex) x <- aaindex[["GRAR740103"]]$I # Rename the score vector to use single-letter codes names(x) <- translateStrings(names(x), ABBREV_AA) # Calculate properties aminoAcidProperties(db, property=c("bulk", "charge"), seq="JUNCTION", nt=TRUE, trim=TRUE, label="CDR3", bulkiness=x, pH=7.0) } \references{ \enumerate{ \item Zimmerman JM, Eliezer N, Simha R. The characterization of amino acid sequences in proteins by statistical methods. J Theor Biol 21, 170-201 (1968). \item Grantham R. Amino acid difference formula to help explain protein evolution. Science 185, 862-864 (1974). \item Ikai AJ. Thermostability and aliphatic index of globular proteins. J Biochem 88, 1895-1898 (1980). \item Kyte J, Doolittle RF. A simple method for displaying the hydropathic character of a protein. J Mol Biol 157, 105-32 (1982). \item Moore DS. Amino acid and peptide net charges: A simple calculational procedure. Biochem Educ 13, 10-11 (1985). \item Wu YC, et al. High-throughput immunoglobulin repertoire analysis distinguishes between human IgM memory and switched memory B-cell populations. Blood 116, 1070-8 (2010). \item Wu YC, et al. The relationship between CD27 negative and positive B cell populations in human peripheral blood. Front Immunol 2, 1-12 (2011). \item \url{http://emboss.sourceforge.net/apps/cvs/emboss/apps/iep.html} } } \seealso{ See \link{countPatterns} for counting the occurance of specific amino acid subsequences. See \link{gravy}, \link{bulk}, \link{aliphatic}, \link{polar} and \link{charge} for functions that calculate the included properties individually. } alakazam/man/cpuCount.Rd0000644000176200001440000000051713445225137014706 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Core.R \name{cpuCount} \alias{cpuCount} \title{Available CPU cores} \usage{ cpuCount() } \value{ Count of available cores. Returns 1 if undeterminable. } \description{ \code{cpuCount} determines the number of CPU cores available. } \examples{ cpuCount() } alakazam/man/groupGenes.Rd0000644000176200001440000001031513513641535015221 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Gene.R \name{groupGenes} \alias{groupGenes} \title{Group sequences by gene assignment} \usage{ groupGenes(data, v_call = "V_CALL", j_call = "J_CALL", junc_len = NULL, cell_id = NULL, locus = NULL, only_igh = TRUE, first = FALSE) } \arguments{ \item{data}{data.frame containing sequence data.} \item{v_call}{name of the column containing the heavy chain V-segment allele calls.} \item{j_call}{name of the column containing the heavy chain J-segment allele calls.} \item{junc_len}{name of the column containing the heavy chain junction length. Optional.} \item{cell_id}{name of the column containing cell IDs. Only applicable and required for single-cell mode.} \item{locus}{name of the column containing locus information. Only applicable and required for single-cell mode.} \item{only_igh}{use only heavy chain (\code{IGH}) sequences for grouping, disregarding light chains. Only applicable and required for single-cell mode. Default is \code{TRUE}.} \item{first}{if \code{TRUE} only the first call of the gene assignments is used. if \code{FALSE} the union of ambiguous gene assignments is used to group all sequences with any overlapping gene calls.} } \value{ Returns a modified data.frame with disjoint union indices in a new \code{VJ_GROUP} column. Note that if \code{junc_len} is supplied, the grouping this \code{VJ_GROUP} will have been based on V, J, and L simultaneously despite the column name being \code{VJ_GROUP}. } \description{ \code{groupGenes} will group rows by shared V and J gene assignments, and optionally also by junction lengths. Both VH:VL paired single-cell BCR-seq and unpaired bulk-seq (heavy chain-only) are supported. In the case of ambiguous (multiple) gene assignments, the grouping may be specified to be a union across all ambiguous V and J gene pairs, analagous to single-linkage clustering (i.e., allowing for chaining). } \details{ To invoke single-cell mode, both \code{cell_id} and \code{locus} must be supplied. Otherwise, the function will run under non-single-cell mode, using all input sequences regardless of the value in the \code{locus} column. Under single-cell mode for VH:VL paired sequences, there is a choice of whether grouping should be done using only heavy chain (\code{IGH}) sequences only, or using both heavy chain (\code{IGH}) and light chain (\code{IGK}, \code{IGL}) sequences. This is governed by \code{only_igh}. Values in the \code{locus} column must be one of \code{"IGH"}, \code{"IGK"}, and \code{"IGL"}. By supplying \code{junc_len}, the call amounts to a 1-stage partitioning of the sequences/cells based on V annotation, J annotation, and junction length simultaneously. Without supplying this columns, the call amounts to the first stage of a 2-stage partitioning, in which sequences/cells are partitioned in the first stage based on V annotation and J annotation, and then in the second stage further split based on junction length. It is assumed that ambiguous gene assignments are separated by commas. All rows containing \code{NA} values in their any of the \code{v_call}, \code{j_call}, and, if specified, \code{junc_len}, columns will be removed. A warning will be issued when a row containing an \code{NA} is removed. } \section{Expectation for single-cell input}{ For single-cell BCR data with VH:VL pairing, it is assumed that \itemize{ \item every row represents a sequence (chain) \item heavy and light chains of the same cell are linked by \code{cell_id} \item value in \code{locus} column indicates whether the chain is heavy or light \item each cell possibly contains multiple heavy and/or light chains \item every chain has its own V(D)J annotation, in which ambiguous V(D)J annotations, if any, are separated by \code{,} (comma) } An example: \itemize{ \item A cell has 1 heavy chain and 2 light chains \item There should be 3 rows corresponding to this cell \item One of the light chain has ambiguous V annotation, which looks like \code{Homsap IGKV1-39*01 F,Homsap IGKV1D-39*01 F}. } } \examples{ # Group by genes db <- groupGenes(ExampleDb, v_call="V_CALL", j_call="J_CALL") } alakazam/man/checkColumns.Rd0000644000176200001440000000170513445225137015524 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Core.R \name{checkColumns} \alias{checkColumns} \title{Check data.frame for valid columns and issue message if invalid} \usage{ checkColumns(data, columns, logic = c("all", "any")) } \arguments{ \item{data}{data.frame to check.} \item{columns}{vector of column names to check.} \item{logic}{one of \code{"all"} or \code{"any"} controlling whether all, or at least one, of the columns must be valid, respectively.} } \value{ \code{TRUE} if columns are valid and a string message if not. } \description{ Check data.frame for valid columns and issue message if invalid } \examples{ df <- data.frame(A=1:3, B=4:6, C=rep(NA, 3)) checkColumns(df, c("A", "B"), logic="all") checkColumns(df, c("A", "B"), logic="any") checkColumns(df, c("A", "C"), logic="all") checkColumns(df, c("A", "C"), logic="any") checkColumns(df, c("A", "D"), logic="all") checkColumns(df, c("A", "D"), logic="any") } alakazam/man/testEdges.Rd0000644000176200001440000000275313445225137015041 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Topology.R \name{testEdges} \alias{testEdges} \title{Tests for parent-child annotation enchrichment in lineage trees} \usage{ testEdges(graphs, field, indirect = FALSE, exclude = c("Germline", NA), nperm = 200, progress = FALSE) } \arguments{ \item{graphs}{list of igraph objects with vertex annotations.} \item{field}{string defining the annotation field to permute.} \item{indirect}{if \code{FALSE} count direct connections (edges) only. If \code{TRUE} walk through any nodes with annotations specified in the \code{argument} to count indirect connections. Specifying \code{indirect=TRUE} with \code{exclude=NULL} will have no effect.} \item{exclude}{vector of strings defining \code{field} values to exclude from permutation.} \item{nperm}{number of permutations to perform.} \item{progress}{if \code{TRUE} show a progress bar.} } \value{ An \link{EdgeTest} object containing the test results and permutation realizations. } \description{ \code{testEdges} performs a permutation test on a set of lineage trees to determine the significance of an annotation's association with parent-child relationships. } \examples{ \donttest{ # Define example tree set graphs <- ExampleTrees[1-10] # Perform edge test on isotypes x <- testEdges(graphs, "ISOTYPE", nperm=10) print(x) } } \seealso{ Uses \link{tableEdges} and \link{permuteLabels}. See \link{plotEdgeTest} for plotting the permutation distributions. } alakazam/man/testMRCA.Rd0000644000176200001440000000245213445225137014530 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Topology.R \name{testMRCA} \alias{testMRCA} \title{Tests for MRCA annotation enrichment in lineage trees} \usage{ testMRCA(graphs, field, root = "Germline", exclude = c("Germline", NA), nperm = 200, progress = FALSE) } \arguments{ \item{graphs}{list of igraph object containing annotated lineage trees.} \item{field}{string defining the annotation field to test.} \item{root}{name of the root (germline) node.} \item{exclude}{vector of strings defining \code{field} values to exclude from the set of potential founder annotations.} \item{nperm}{number of permutations to perform.} \item{progress}{if \code{TRUE} show a progress bar.} } \value{ An \link{MRCATest} object containing the test results and permutation realizations. } \description{ \code{testMRCA} performs a permutation test on a set of lineage trees to determine the significance of an annotation's association with the MRCA position of the lineage trees. } \examples{ \donttest{ # Define example tree set graphs <- ExampleTrees[1-10] # Perform MRCA test on isotypes x <- testMRCA(graphs, "ISOTYPE", nperm=10) print(x) } } \seealso{ Uses \link{getMRCA} and \link{getPathLengths}. See \link{plotMRCATest} for plotting the permutation distributions. } alakazam/man/plotDiversityCurve.Rd0000644000176200001440000000442313513133770016771 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Diversity.R \name{plotDiversityCurve} \alias{plotDiversityCurve} \title{Plot the results of alphaDiversity} \usage{ plotDiversityCurve(data, colors = NULL, main_title = "Diversity", legend_title = "Group", log_x = FALSE, log_y = FALSE, xlim = NULL, ylim = NULL, annotate = c("none", "depth"), score = c("diversity", "evenness"), silent = FALSE, ...) } \arguments{ \item{data}{\link{DiversityCurve} object returned by \link{alphaDiversity}.} \item{colors}{named character vector whose names are values in the \code{group} column of the \code{data} slot of \code{data}, and whose values are colors to assign to those group names.} \item{main_title}{string specifying the plot title.} \item{legend_title}{string specifying the legend title.} \item{log_x}{if \code{TRUE} then plot \eqn{q} on a log scale; if \code{FALSE} plot on a linear scale.} \item{log_y}{if \code{TRUE} then plot the diversity/evenness scores on a log scale; if \code{FALSE} plot on a linear scale.} \item{xlim}{numeric vector of two values specifying the \code{c(lower, upper)} x-axis limits.} \item{ylim}{numeric vector of two values specifying the \code{c(lower, upper)} y-axis limits.} \item{annotate}{string defining whether to added values to the group labels of the legend. When \code{"none"} (default) is specified no annotations are added. Specifying (\code{"depth"}) adds sequence counts to the labels.} \item{score}{one of \code{"diversity"} or \code{"evenness"} specifying which score to plot on the y-asis.} \item{silent}{if \code{TRUE} do not draw the plot and just return the ggplot2 object; if \code{FALSE} draw the plot.} \item{...}{additional arguments to pass to ggplot2::theme.} } \value{ A \code{ggplot} object defining the plot. } \description{ \code{plotDiversityCurve} plots a \code{DiversityCurve} object. } \examples{ # Calculate diversity div <- alphaDiversity(ExampleDb, group="SAMPLE", nboot=100) # Plot diversity plotDiversityCurve(div, legend_title="Sample") #' # Plot diversity plotDiversityCurve(div, legend_title="Sample", score="evenness") } \seealso{ See \link{alphaDiversity} and \link{alphaDiversity} for generating \link{DiversityCurve} objects for input. Plotting is performed with \link{ggplot}. } alakazam/man/maskSeqGaps.Rd0000644000176200001440000000172413445225137015326 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Sequence.R \name{maskSeqGaps} \alias{maskSeqGaps} \title{Masks gap characters in DNA sequences} \usage{ maskSeqGaps(seq, mask_char = "N", outer_only = FALSE) } \arguments{ \item{seq}{character vector of DNA sequence strings.} \item{mask_char}{character to use for masking.} \item{outer_only}{if \code{TRUE} replace only contiguous leading and trailing gaps; if \code{FALSE} replace all gap characters.} } \value{ A modified \code{seq} vector with \code{"N"} in place of \code{c("-", ".")} characters. } \description{ \code{maskSeqGaps} substitutes gap characters, \code{c("-", ".")}, with \code{"N"} in a vector of DNA sequences. } \examples{ # Mask with Ns maskSeqGaps(c("ATG-C", "CC..C")) maskSeqGaps("--ATG-C-") maskSeqGaps("--ATG-C-", outer_only=TRUE) # Mask with dashes maskSeqGaps(c("ATG-C", "CC..C"), mask_char="-") } \seealso{ See \link{maskSeqEnds} for masking ragged edges. } alakazam/man/DEFAULT_COLORS.Rd0000644000176200001440000000247213445225137015255 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Data.R \docType{data} \name{DEFAULT_COLORS} \alias{DEFAULT_COLORS} \alias{DNA_COLORS} \alias{IG_COLORS} \alias{TR_COLORS} \title{Default colors} \format{Named character vectors with hexcode colors as values. \itemize{ \item \code{DNA_COLORS}: DNA character colors \code{c("A", "C", "G", "T")}. \item \code{IG_COLORS}: Ig isotype colors \code{c("IgA", "IgD", "IgE", "IgG", "IgM", "IgK", "IgL")}. \item \code{TR_COLORS}: TCR chain colors \code{c("TRA", "TRB", "TRD", "TRG")}. }} \usage{ DNA_COLORS IG_COLORS TR_COLORS } \description{ Default color palettes for DNA characters, Ig isotypes, and TCR chains. } \examples{ # IG_COLORS as an isotype color set for ggplot isotype <- c("IgG", "IgM", "IgM", "IgA") db <- data.frame(x=1:4, y=1:4, iso=isotype) g1 <- ggplot(db, aes(x=x, y=y, color=iso)) + scale_color_manual(name="Isotype", values=IG_COLORS) + geom_point(size=10) plot(g1) # DNA_COLORS to translate nucleotide values to a vector of colors # for use in base graphics plots seq <- c("A", "T", "T", "C") colors <- translateStrings(seq, setNames(names(DNA_COLORS), DNA_COLORS)) plot(1:4, 1:4, col=colors, pch=16, cex=6) } \keyword{datasets} alakazam/man/summarizeSubtrees.Rd0000644000176200001440000000431513445225137016637 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Topology.R \name{summarizeSubtrees} \alias{summarizeSubtrees} \title{Generate subtree summary statistics for a tree} \usage{ summarizeSubtrees(graph, fields = NULL, root = "Germline") } \arguments{ \item{graph}{igraph object containing an annotated lineage tree.} \item{fields}{annotation fields to add to the output.} \item{root}{name of the root (germline) node.} } \value{ A data.frame with columns: \itemize{ \item \code{NAME}: node name. \item \code{PARENT}: name of the parent node. \item \code{OUTDEGREE}: number of edges leading from the node. \item \code{SIZE}: total number of nodes within the subtree rooted at the node. \item \code{DEPTH}: the depth of the subtree that is rooted at the node. \item \code{PATHLENGTH}: the maximum pathlength beneath the node. \item \code{OUTDEGREE_NORM}: \code{OUTDEGREE} normalized by the total number of edges. \item \code{SIZE_NORM}: \code{SIZE} normalized by the largest subtree size (the germline). \item \code{DEPTH_NORM}: \code{DEPTH} normalized by the largest subtree depth (the germline). \item \code{PATHLENGTH_NORM}: \code{PATHLEGNTH} normalized by the largest subtree pathlength (the germline). } An additional column corresponding to the value of \code{field} is added when specified. } \description{ \code{summarizeSubtrees} calculates summary statistics for each node of a tree. Includes both node properties and subtree properties. } \examples{ # Summarize a tree graph <- ExampleTrees[[23]] summarizeSubtrees(graph, fields="ISOTYPE", root="Germline") } \seealso{ See \link{buildPhylipLineage} for generating input trees. See \link{getPathLengths} for calculating path length to nodes. } alakazam/man/countPatterns.Rd0000644000176200001440000000260213445225137015754 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/AminoAcids.R \name{countPatterns} \alias{countPatterns} \title{Count sequence patterns} \usage{ countPatterns(seq, patterns, nt = FALSE, trim = FALSE, label = "REGION") } \arguments{ \item{seq}{character vector of either DNA or amino acid sequences.} \item{patterns}{list of sequence patterns to count in each sequence. If the list is named, then names will be assigned as the column names of output data.frame.} \item{nt}{if \code{TRUE} then \code{seq} are DNA sequences and and will be translated before performing the pattern search.} \item{trim}{if \code{TRUE} remove the first and last codon or amino acid from each sequence before the pattern search. If \code{FALSE} do not modify the input sequences.} \item{label}{string defining a label to add as a prefix to the output column names.} } \value{ A data.frame containing the fraction of times each sequence pattern was found. } \description{ \code{countPatterns} counts the fraction of times a set of character patterns occur in a set of sequences. } \examples{ seq <- c("TGTCAACAGGCTAACAGTTTCCGGACGTTC", "TGTCAGCAATATTATATTGCTCCCTTCACTTTC", "TGTCAAAAGTATAACAGTGCCCCCTGGACGTTC") patterns <- c("A", "V", "[LI]") names(patterns) <- c("ARG", "VAL", "ISO_LEU") countPatterns(seq, patterns, nt=TRUE, trim=TRUE, label="CDR3") } alakazam/man/charge.Rd0000644000176200001440000000324213445225137014335 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/AminoAcids.R \name{charge} \alias{charge} \title{Calculates the net charge of amino acid sequences.} \usage{ charge(seq, pH = 7.4, pK = NULL, normalize = FALSE) } \arguments{ \item{seq}{vector strings defining of amino acid sequences.} \item{pH}{environmental pH.} \item{pK}{named vector defining pK values for each charged amino acid, where names are the single-letter amino acid character codes \code{c("R", "H", "K", "D", "E", "C", "Y")}). If \code{NULL}, then the EMBOSS scale is used.} \item{normalize}{if \code{TRUE} then divide the net charge of each amino acid sequence by the number of informative positions. Non-informative position are defined by the presence any character in \code{c("X", "-", ".", "*")}. If \code{FALSE} then return the raw net charge.} } \value{ A vector of net charges for the sequence(s). } \description{ \code{charge} calculates the net charge of amino acid sequences using the method of Moore, 1985, with exclusion of the C-terminus and N-terminus charges. } \examples{ seq <- c("CARDRSTPWRRGIASTTVRTSW", "XXTQMYVRT") # Unnormalized charge charge(seq) # Normalized charge charge(seq, normalize=TRUE) # Use the Murray et al, 2006 scores from the seqinr package library(seqinr) data(pK) x <- setNames(pK[["Murray"]], rownames(pK)) # Calculate charge charge(seq, pK=x) } \references{ \enumerate{ \item Moore DS. Amino acid and peptide net charges: A simple calculational procedure. Biochem Educ. 13, 10-11 (1985). \item \url{http://emboss.sourceforge.net/apps/cvs/emboss/apps/iep.html} } } \seealso{ For additional pK scales see \code{\link[seqinr]{pK}}. } alakazam/man/translateStrings.Rd0000644000176200001440000000242413445225137016454 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Core.R \name{translateStrings} \alias{translateStrings} \title{Translate a vector of strings} \usage{ translateStrings(strings, translation) } \arguments{ \item{strings}{vector of character strings to modify.} \item{translation}{named character vector or a list of character vectors specifying the strings to replace (values) and their replacements (names).} } \value{ A modified \code{strings} vector. } \description{ \code{translateStrings} modifies a character vector by substituting one or more strings with a replacement string. } \details{ Does not perform partial replacements. Each translation value must match a complete \code{strings} value or it will not be replaced. Values that do not have a replacement named in the \code{translation} parameter will not be modified. Replacement is accomplished using \link{gsub}. } \examples{ # Using a vector translation strings <- LETTERS[1:5] translation <- c("POSITION1"="A", "POSITION5"="E") translateStrings(strings, translation) # Using a list translation strings <- LETTERS[1:5] translation <- list("1-3"=c("A","B","C"), "4-5"=c("D","E")) translateStrings(strings, translation) } \seealso{ See \link{gsub} for single value replacement in the base package. } alakazam/man/writeChangeoDb.Rd0000644000176200001440000000125213445225137015770 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Core.R \name{writeChangeoDb} \alias{writeChangeoDb} \title{Write a Change-O tab-delimited database file} \usage{ writeChangeoDb(data, file) } \arguments{ \item{data}{data.frame of Change-O data.} \item{file}{output file name.} } \description{ \code{writeChangeoDb} is a simple wrapper around \link[readr]{write_delim} with defaults appropriate for writing a Change-O tab-delimited database file from a data.frame. } \examples{ \dontrun{ # Write a database writeChangeoDb(data, "changeo.tsv") } } \seealso{ Wraps \link[readr]{write_delim}. See \link{readChangeoDb} for reading to Change-O files. } alakazam/man/baseTheme.Rd0000644000176200001440000000115013445225137014775 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Core.R \name{baseTheme} \alias{baseTheme} \title{Standard ggplot settings} \usage{ baseTheme(sizing = c("figure", "window")) } \arguments{ \item{sizing}{defines the style and sizing of the theme. One of \code{c("figure", "window")} where \code{sizing="figure"} is appropriately sized for pdf export at 7 to 7.5 inch width, and \code{sizing="window"} is sized for an interactive session.} } \value{ A ggplot2 object. } \description{ \code{baseTheme} defines common ggplot theme settings for plotting. } \seealso{ \link[ggplot2]{theme}. } alakazam/man/AbundanceCurve-class.Rd0000644000176200001440000000326413512442170017071 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Classes.R \docType{class} \name{AbundanceCurve-class} \alias{AbundanceCurve-class} \alias{AbundanceCurve} \alias{print,AbundanceCurve-method} \alias{AbundanceCurve-method} \alias{plot,AbundanceCurve,missing-method} \title{S4 class defining a clonal abundance curve} \usage{ \S4method{print}{AbundanceCurve}(x) \S4method{plot}{AbundanceCurve,missing}(x, y, ...) } \arguments{ \item{x}{AbundanceCurve object} \item{y}{ignored.} \item{...}{arguments to pass to \link{plotDiversityCurve}.} } \description{ \code{AbundanceCurve} defines clonal abundance values. } \section{Slots}{ \describe{ \item{\code{abundance}}{data.frame with relative clonal abundance data and confidence intervals, containing the following columns: \itemize{ \item \code{GROUP}: group identifier. \item \code{CLONE}: clone identifier. \item \code{P}: relative abundance of the clone. \item \code{LOWER}: lower confidence inverval bound. \item \code{UPPER}: upper confidence interval bound. \item \code{RANK}: the rank of the clone abundance. }} \item{\code{bootstrap}}{data.frame of bootstrapped clonal distributions.} \item{\code{clone_by}}{string specifying the name of the clone column.} \item{\code{group_by}}{string specifying the name of the grouping column.} \item{\code{groups}}{vector specifying the names of unique groups in group column.} \item{\code{n}}{numeric vector indication the number of sequences sampled in each group.} \item{\code{nboot}}{numeric specifying the number of bootstrap iterations to use.} \item{\code{ci}}{confidence interval defining the upper and lower bounds (a value between 0 and 1).} }} alakazam/man/padSeqEnds.Rd0000644000176200001440000000231113445225137015127 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Sequence.R \name{padSeqEnds} \alias{padSeqEnds} \title{Pads ragged ends of aligned DNA sequences} \usage{ padSeqEnds(seq, len = NULL, start = FALSE, pad_char = "N") } \arguments{ \item{seq}{character vector of DNA sequence strings.} \item{len}{length to pad to. Only applies if longer than the maximum length of the data in \code{seq}.} \item{start}{if \code{TRUE} pad the beginning of each sequence instead of the end.} \item{pad_char}{character to use for padding.} } \value{ A modified \code{seq} vector with padded sequences. } \description{ \code{padSeqEnds} takes a vector of DNA sequences, as character strings, and appends the ends of each sequence with an appropriate number of \code{"N"} characters to create a sequence vector with uniform lengths. } \examples{ # Default behavior uniformly pads ragged ends seq <- c("CCCCTGGG", "ACCCTG", "CCCC") padSeqEnds(seq) # Pad to fixed length padSeqEnds(seq, len=15) # Add padding to the beginning of the sequences instead of the ends padSeqEnds(seq, start=TRUE) padSeqEnds(seq, len=15, start=TRUE) } \seealso{ See \link{maskSeqEnds} for creating uniform masking from existing masking. } alakazam/man/maskSeqEnds.Rd0000644000176200001440000000331213445225137015320 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Sequence.R \name{maskSeqEnds} \alias{maskSeqEnds} \title{Masks ragged leading and trailing edges of aligned DNA sequences} \usage{ maskSeqEnds(seq, mask_char = "N", max_mask = NULL, trim = FALSE) } \arguments{ \item{seq}{character vector of DNA sequence strings.} \item{mask_char}{character to use for masking.} \item{max_mask}{the maximum number of characters to mask. If set to 0 then no masking will be performed. If set to \code{NULL} then the upper masking bound will be automatically determined from the maximum number of observed leading or trailing \code{"N"} characters amongst all strings in \code{seq}.} \item{trim}{if \code{TRUE} leading and trailing characters will be cut rather than masked with \code{"N"} characters.} } \value{ A modified \code{seq} vector with masked (or optionally trimmed) sequences. } \description{ \code{maskSeqEnds} takes a vector of DNA sequences, as character strings, and replaces the leading and trailing characters with \code{"N"} characters to create a sequence vector with uniformly masked outer sequence segments. } \examples{ # Default behavior uniformly masks ragged ends seq <- c("CCCCTGGG", "NAACTGGN", "NNNCTGNN") maskSeqEnds(seq) # Does nothing maskSeqEnds(seq, max_mask=0) # Cut ragged sequence ends maskSeqEnds(seq, trim=TRUE) # Set max_mask to limit extent of masking and trimming maskSeqEnds(seq, max_mask=1) maskSeqEnds(seq, max_mask=1, trim=TRUE) # Mask dashes instead of Ns seq <- c("CCCCTGGG", "-AACTGG-", "---CTG--") maskSeqEnds(seq, mask_char="-") } \seealso{ See \link{maskSeqGaps} for masking internal gaps. See \link{padSeqEnds} for padding sequence of unequal length. } alakazam/man/ChangeoClone-class.Rd0000644000176200001440000000172213445225137016535 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Classes.R \docType{class} \name{ChangeoClone-class} \alias{ChangeoClone-class} \alias{ChangeoClone} \title{S4 class defining a clone} \description{ \code{ChangeoClone} defines a common data structure for perform lineage recontruction from Change-O data. } \section{Slots}{ \describe{ \item{\code{data}}{data.frame containing sequences and annotations. Contains the columns \code{SEQUENCE_ID} and \code{SEQUENCE}, as well as any additional sequence-specific annotation columns.} \item{\code{clone}}{string defining the clone identifier.} \item{\code{germline}}{string containing the germline sequence for the clone.} \item{\code{v_gene}}{string defining the V segment gene call.} \item{\code{j_gene}}{string defining the J segment gene call.} \item{\code{junc_len}}{numeric junction length (nucleotide count).} }} \seealso{ See \link{makeChangeoClone} and \link{buildPhylipLineage} for use. } alakazam/man/plotSubtrees.Rd0000644000176200001440000000547313445225137015607 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Topology.R \name{plotSubtrees} \alias{plotSubtrees} \title{Plots subtree statistics for multiple trees} \usage{ plotSubtrees(graphs, field, stat, root = "Germline", exclude = c("Germline", NA), colors = NULL, main_title = "Subtrees", legend_title = "Annotation", style = c("box", "violin"), silent = FALSE, ...) } \arguments{ \item{graphs}{list of igraph objects containing annotated lineage trees.} \item{field}{string defining the annotation field.} \item{stat}{string defining the subtree statistic to plot. One of: \itemize{ \item \code{outdegree}: distribution of normalized node outdegrees. \item \code{size}: distribution of normalized subtree sizes. \item \code{depth}: distribution of subtree depths. \item \code{pathlength}: distribution of maximum pathlength beneath nodes. }} \item{root}{name of the root (germline) node.} \item{exclude}{vector of strings defining \code{field} values to exclude from plotting.} \item{colors}{named vector of colors for values in \code{field}, with names defining annotation names \code{field} column and values being colors. Also controls the order in which values appear on the plot. If \code{NULL} alphabetical ordering and a default color palette will be used.} \item{main_title}{string specifying the plot title.} \item{legend_title}{string specifying the legend title.} \item{style}{string specifying the style of plot to draw. One of: \itemize{ \item \code{"histogram"}: histogram of the annotation count distribution with a red dotted line denoting the observed value. \item \code{"cdf"}: cumulative distribution function of annotation counts with a red dotted line denoting the observed value and a blue dotted line indicating the p-value. }} \item{silent}{if \code{TRUE} do not draw the plot and just return the ggplot2 object; if \code{FALSE} draw the plot.} \item{...}{additional arguments to pass to ggplot2::theme.} } \value{ A \code{ggplot} object defining the plot. } \description{ \code{plotSubtree} plots distributions of normalized subtree statistics for a set of lineage trees, broken down by annotation value. } \examples{ # Define example tree set graphs <- ExampleTrees[1-10] # Violin plots of node outdegree by sample plotSubtrees(graphs, "SAMPLE", "out", style="v") # Violin plots of subtree size by sample plotSubtrees(graphs, "SAMPLE", "size", style="v") # Boxplot of node depth by isotype plotSubtrees(graphs, "ISOTYPE", "depth", style="b") } \seealso{ Subtree statistics are calculated with \link{summarizeSubtrees}. } alakazam/man/readChangeoDb.Rd0000644000176200001440000000364413445225137015560 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Core.R \name{readChangeoDb} \alias{readChangeoDb} \title{Read a Change-O tab-delimited database file} \usage{ readChangeoDb(file, select = NULL, drop = NULL, seq_upper = TRUE) } \arguments{ \item{file}{tab-delimited database file output by a Change-O tool.} \item{select}{columns to select from database file.} \item{drop}{columns to drop from database file.} \item{seq_upper}{if \code{TRUE} convert sequence columns to upper case; if \code{FALSE} do not alter sequence columns. See Value for a list of which columns are effected.} } \value{ A data.frame of the database file. Columns will be imported as is, except for the following columns which will be explicitly converted into character values: \itemize{ \item SEQUENCE_ID \item CLONE \item SAMPLE } And the following sequence columns which will converted to upper case if \code{seq_upper=TRUE} (default). \itemize{ \item SEQUENCE_INPUT \item SEQUENCE_VDJ \item SEQUENCE_IMGT \item JUNCTION \item GERMLINE_IMGT \item GERMLINE_IMGT_D_MASK } } \description{ \code{readChangeoDb} reads a tab-delimited database file created by a Change-O tool into a data.frame. } \examples{ \dontrun{ # Read all columns in and convert sequence fields to upper case db <- readChangeoDb("changeo.tsv") # Subset columns and convert sequence fields to upper case db <- readChangeoDb("changeo.tsv", select=c("SEQUENCE_ID", "SEQUENCE_IMGT")) # Drop columns and do not alter sequence field case db <- readChangeoDb("changeo.tsv", drop=c("D_CALL", "DUPCOUNT"), seq_upper=FALSE) } } \seealso{ Wraps \link[readr]{read_delim}. See \link{writeChangeoDb} for writing to Change-O files. } alakazam/man/countClones.Rd0000644000176200001440000000377213512442170015401 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Diversity.R \name{countClones} \alias{countClones} \title{Tabulates clones sizes} \usage{ countClones(data, groups = NULL, copy = NULL, clone = "CLONE") } \arguments{ \item{data}{data.frame with Change-O style columns containing clonal assignments.} \item{groups}{character vector defining \code{data} columns containing grouping variables. If \code{groups=NULL}, then do not group data.} \item{copy}{name of the \code{data} column containing copy numbers for each sequence. If this value is specified, then total copy abundance is determined by the sum of copy numbers within each clonal group.} \item{clone}{name of the \code{data} column containing clone identifiers.} } \value{ A data.frame summarizing clone counts and frequencies with columns: \itemize{ \item \code{CLONE}: clone identifier. \item \code{SEQ_COUNT}: total number of sequences for the clone. \item \code{SEQ_FREQ}: frequency of the clone as a fraction of the total number of sequences within each group. \item \code{COPY_COUNT}: sum of the copy counts in the \code{copy} column. Only present if the \code{copy} argument is specified. \item \code{COPY_FREQ}: frequency of the clone as a fraction of the total copy number within each group. Only present if the \code{copy} argument is specified. } Also includes additional columns specified in the \code{groups} argument. } \description{ \code{countClones} determines the number of sequences and total copy number of clonal groups. } \examples{ # Without copy numbers clones <- countClones(ExampleDb, groups="SAMPLE") # With copy numbers and multiple groups clones <- countClones(ExampleDb, groups=c("SAMPLE", "ISOTYPE"), copy="DUPCOUNT") } alakazam/man/gravy.Rd0000644000176200001440000000267613445225137014246 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/AminoAcids.R \name{gravy} \alias{gravy} \title{Calculates the hydrophobicity of amino acid sequences} \usage{ gravy(seq, hydropathy = NULL) } \arguments{ \item{seq}{vector of strings containing amino acid sequences.} \item{hydropathy}{named numerical vector defining hydropathy index values for each amino acid, where names are single-letter amino acid character codes. If \code{NULL}, then the Kyte & Doolittle scale is used.} } \value{ A vector of GRAVY scores for the sequence(s). } \description{ \code{gravy} calculates the Grand Average of Hydrophobicity (GRAVY) index of amino acid sequences using the method of Kyte & Doolittle. Non-informative positions are excluded, where non-informative is defined as any character in \code{c("X", "-", ".", "*")}. } \examples{ # Default scale seq <- c("CARDRSTPWRRGIASTTVRTSW", "XXTQMYVRT") gravy(seq) # Use the Kidera et al, 1985 scores from the seqinr package library(seqinr) data(aaindex) x <- aaindex[["KIDA850101"]]$I # Rename the score vector to use single-letter codes names(x) <- translateStrings(names(x), ABBREV_AA) # Calculate hydrophobicity gravy(seq, hydropathy=x) } \references{ \enumerate{ \item Kyte J, Doolittle RF. A simple method for displaying the hydropathic character of a protein. J Mol Biol. 157, 105-32 (1982). } } \seealso{ For additional hydrophobicity indices see \code{\link[seqinr]{aaindex}}. } alakazam/man/extractVRegion.Rd0000644000176200001440000000345413445225137016055 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Sequence.R \name{extractVRegion} \alias{extractVRegion} \title{Extracts FWRs and CDRs from IMGT-gapped sequences} \usage{ extractVRegion(sequences, region = c("FWR1", "CDR1", "FWR2", "CDR2", "FWR3")) } \arguments{ \item{sequences}{character vector of IMGT-gapped nucleotide sequences.} \item{region}{string defining the region(s) of the V segment to extract. May be a single region or multiple regions (as a vector) from \code{c("FWR1", "CDR1", "FWR2", "CDR2" ,"FWR3")}. By default, all regions will be returned.} } \value{ If only one region is specified in the \code{region} argument, a character vector of the extracted sub-sequences will be returned. If multiple regions are specified, then a character matrix will be returned with columns corresponding to the specified regions and a row for each entry in \code{sequences}. } \description{ \code{extractVRegion} extracts the framework and complementarity determining regions of the V segment for IMGT-gapped immunoglobulin (Ig) nucleotide sequences according to the IMGT numbering scheme. } \examples{ # Assign example clone clone <- subset(ExampleDb, CLONE == 3138) # Get all regions extractVRegion(clone$SEQUENCE_IMGT) # Get single region extractVRegion(clone$SEQUENCE_IMGT, "FWR1") # Get all CDRs extractVRegion(clone$SEQUENCE_IMGT, c("CDR1", "CDR2")) # Get all FWRs extractVRegion(clone$SEQUENCE_IMGT, c("FWR1", "FWR2", "FWR3")) } \references{ \enumerate{ \item Lefranc M-P, et al. IMGT unique numbering for immunoglobulin and T cell receptor variable domains and Ig superfamily V-like domains. Dev Comp Immunol. 2003 27(1):55-77. } } \seealso{ IMGT-gapped region boundaries are defined in \link{IMGT_REGIONS}. } alakazam/man/nonsquareDist.Rd0000644000176200001440000000364313512442170015741 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Sequence.R \name{nonsquareDist} \alias{nonsquareDist} \title{Calculate pairwise distances between sequences} \usage{ nonsquareDist(seq, indx, dist_mat = getDNAMatrix()) } \arguments{ \item{seq}{character vector containing a DNA sequences. The sequence vector needs to be named.} \item{indx}{numeric vector contating the indices (a subset of indices of \code{seq}).} \item{dist_mat}{Character distance matrix. Defaults to a Hamming distance matrix returned by \link{getDNAMatrix}. If gap characters, \code{c("-", ".")}, are assigned a value of -1 in \code{dist_mat} then contiguous gaps of any run length, which are not present in both sequences, will be counted as a distance of 1. Meaning, indels of any length will increase the sequence distance by 1. Gap values other than -1 will return a distance that does not consider indels as a special case.} } \value{ A matrix of numerical distance between each entry in \code{seq} and sequences specified by \code{indx} indices. Note that the input subsampled indices will be ordered ascendingly. Therefore, it is necassary to assign unique names to the input sequences, \code{seq}, to recover the input order later. Row and columns names will be added accordingly. Amino acid distance matrix may be built with \link{getAAMatrix}. Uses \link{seqDist} for calculating distances between pairs. See \link{pairwiseEqual} for generating an equivalence matrix. } \description{ \code{nonsquareDist} calculates all pairwise distance between a set of sequences and a subset of it. } \examples{ # Gaps will be treated as Ns with a gap=0 distance matrix seq <- c(A="ATGGC", B="ATGGG", C="ATGGG", D="AT--C") pairwiseDist(seq, dist_mat=getDNAMatrix(gap=0)) nonsquareDist(seq, indx=c(1,3), dist_mat=getDNAMatrix(gap=0)) } alakazam/man/makeTempDir.Rd0000644000176200001440000000101213445225137015277 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Core.R \name{makeTempDir} \alias{makeTempDir} \title{Create a temporary folder} \usage{ makeTempDir(prefix) } \arguments{ \item{prefix}{prefix name for the folder.} } \value{ The path to the temporary folder. } \description{ \code{makeTempDir} creates a randomly named temporary folder in the system temp location. } \examples{ makeTempDir("Clone50") } \seealso{ This is just a wrapper for \link{tempfile} and \link{dir.create}. } alakazam/man/calcCoverage.Rd0000644000176200001440000000221413512442170015451 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Diversity.R \name{calcCoverage} \alias{calcCoverage} \title{Calculate sample coverage} \usage{ calcCoverage(x, r = 1) } \arguments{ \item{x}{numeric vector of abundance counts.} \item{r}{coverage order to calculate.} } \value{ The sample coverage of the given order \code{r}. } \description{ \code{calcCoverage} calculates the sample coverage estimate, a measure of sample completeness, for varying orders using the method of Chao et al, 2015, falling back to the Chao1 method in the first order case. } \examples{ # Calculate clone sizes clones <- countClones(ExampleDb, groups="SAMPLE") # Calculate 1first order coverage for a single sample calcCoverage(clones$SEQ_COUNT[clones$SAMPLE == "+7d"]) } \references{ \enumerate{ \item Chao A. Nonparametric Estimation of the Number of Classes in a Population. Scand J Stat. 1984 11, 265270. \item Chao A, et al. Unveiling the species-rank abundance distribution by generalizing the Good-Turing sample coverage theory. Ecology. 2015 96, 11891201. } } \seealso{ Used by \link{alphaDiversity}. } alakazam/man/stoufferMeta.Rd0000644000176200001440000000131413445225137015546 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Core.R \name{stoufferMeta} \alias{stoufferMeta} \title{Weighted meta-analysis of p-values via Stouffer's method} \usage{ stoufferMeta(p, w = NULL) } \arguments{ \item{p}{numeric vector of p-values.} \item{w}{numeric vector of weights.} } \value{ A named numeric vector with the combined Z-score and p-value in the form \code{c(Z, pvalue)}. } \description{ \code{stoufferMeta} combines multiple weighted p-values into a meta-analysis p-value using Stouffer's Z-score method. } \examples{ # Define p-value and weight vectors p <- c(0.1, 0.05, 0.3) w <- c(5, 10, 1) # Unweighted stoufferMeta(p) # Weighted stoufferMeta(p, w) } alakazam/man/countGenes.Rd0000644000176200001440000000750513512442170015215 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Gene.R \name{countGenes} \alias{countGenes} \title{Tabulates V(D)J allele, gene or family usage.} \usage{ countGenes(data, gene, groups = NULL, copy = NULL, clone = NULL, fill = FALSE, mode = c("gene", "allele", "family", "asis")) } \arguments{ \item{data}{data.frame with Change-O style columns.} \item{gene}{column containing allele assignments. Only the first allele in the column will be considered when \code{mode} is "gene", "family" or "allele". The value will be used as it is with \code{mode="asis"}.} \item{groups}{columns containing grouping variables. If \code{NULL} do not group.} \item{copy}{name of the \code{data} column containing copy numbers for each sequence. If this value is specified, then total copy abundance is determined by the sum of copy numbers within each gene. This argument is ignored if \code{clone} is specified.} \item{clone}{name of the \code{data} column containing clone identifiers for each sequence. If this value is specified, then one gene will be considered for each clone. Note, this is accomplished by using the most common gene within each \code{clone} identifier. As such, ambiguous alleles within a clone will not be accurately represented.} \item{fill}{logical of \code{c(TRUE, FALSE)} specifying when if groups (when specified) lacking a particular gene should be counted as 0 if TRUE or not (omitted)} \item{mode}{one of \code{c("gene", "family", "allele", "asis")} defining the degree of specificity regarding allele calls. Determines whether to return counts for genes (calling \code{getGene}), families (calling \code{getFamily}), alleles (calling \code{getAllele}) or using the value as it is in the column \code{gene}, without any processing.} } \value{ A data.frame summarizing family, gene or allele counts and frequencies with columns: \itemize{ \item \code{GENE}: name of the family, gene or allele \item \code{SEQ_COUNT}: total number of sequences for the gene. \item \code{SEQ_FREQ}: frequency of the gene as a fraction of the total number of sequences within each grouping. \item \code{COPY_COUNT}: sum of the copy counts in the \code{copy} column. for each gene. Only present if the \code{copy} argument is specified. \item \code{COPY_FREQ}: frequency of the gene as a fraction of the total copy number within each group. Only present if the \code{copy} argument is specified. \item \code{CLONE_COUNT}: total number of clones for the gene. \item \code{CLONE_FREQ}: frequency of the gene as a fraction of the total number of clones within each grouping. } Additional columns defined by the \code{groups} argument will also be present. } \description{ Determines the count and relative abundance of V(D)J alleles, genes or families within groups. } \examples{ # Without copy numbers genes <- countGenes(ExampleDb, gene="V_CALL", groups="SAMPLE", mode="family") genes <- countGenes(ExampleDb, gene="V_CALL", groups="SAMPLE", mode="gene") genes <- countGenes(ExampleDb, gene="V_CALL", groups="SAMPLE", mode="allele") # With copy numbers and multiple groups genes <- countGenes(ExampleDb, gene="V_CALL", groups=c("SAMPLE", "ISOTYPE"), copy="DUPCOUNT", mode="family") # Count by clone genes <- countGenes(ExampleDb, gene="V_CALL", groups=c("SAMPLE", "ISOTYPE"), clone="CLONE", mode="family") # Count absent genes genes <- countGenes(ExampleDb, gene="V_CALL", groups="SAMPLE", mode="allele", fill=TRUE) } alakazam/man/plotMRCATest.Rd0000644000176200001440000000323013445225137015362 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Topology.R \name{plotMRCATest} \alias{plotMRCATest} \title{Plot the results of a founder permutation test} \usage{ plotMRCATest(data, color = "black", main_title = "MRCA Test", style = c("histogram", "cdf"), silent = FALSE, ...) } \arguments{ \item{data}{\link{MRCATest} object returned by \link{testMRCA}.} \item{color}{color of the histogram or lines.} \item{main_title}{string specifying the plot title.} \item{style}{type of plot to draw. One of: \itemize{ \item \code{"histogram"}: histogram of the annotation count distribution with a red dotted line denoting the observed value. \item \code{"cdf"}: cumulative distribution function of annotation counts with a red dotted line denoting the observed value and a blue dotted line indicating the p-value. }} \item{silent}{if \code{TRUE} do not draw the plot and just return the ggplot2 object; if \code{FALSE} draw the plot.} \item{...}{additional arguments to pass to ggplot2::theme.} } \value{ A \code{ggplot} object defining the plot. } \description{ \code{plotMRCATest} plots the results of a founder permutation test performed with \code{testMRCA}. } \examples{ \donttest{ # Define example tree set graphs <- ExampleTrees[1-10] # Perform MRCA test on isotypes x <- testMRCA(graphs, "ISOTYPE", nperm=10) # Plot plotMRCATest(x, color="steelblue", style="hist") plotMRCATest(x, style="cdf") } } \seealso{ See \link{testEdges} for performing the test. } alakazam/man/rarefyDiversity.Rd0000644000176200001440000001007213512442170016267 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Deprecated.R \name{rarefyDiversity} \alias{rarefyDiversity} \title{Generate a clonal diversity index curve} \usage{ rarefyDiversity(data, group, clone = "CLONE", copy = NULL, min_q = 0, max_q = 4, step_q = 0.05, min_n = 30, max_n = NULL, ci = 0.95, nboot = 2000, uniform = TRUE, progress = FALSE) } \arguments{ \item{data}{data.frame with Change-O style columns containing clonal assignments.} \item{group}{name of the \code{data} column containing group identifiers.} \item{clone}{name of the \code{data} column containing clone identifiers.} \item{copy}{name of the \code{data} column containing copy numbers for each sequence. If \code{copy=NULL} (the default), then clone abundance is determined by the number of sequences. If a \code{copy} column is specified, then clone abundances is determined by the sum of copy numbers within each clonal group.} \item{min_q}{minimum value of \eqn{q}.} \item{max_q}{maximum value of \eqn{q}.} \item{step_q}{value by which to increment \eqn{q}.} \item{min_n}{minimum number of observations to sample. A group with less observations than the minimum is excluded.} \item{max_n}{maximum number of observations to sample. If \code{NULL} then no maximum is set.} \item{ci}{confidence interval to calculate; the value must be between 0 and 1.} \item{nboot}{number of bootstrap realizations to generate.} \item{uniform}{if \code{TRUE} then uniformly resample each group to the same number of observations. If \code{FALSE} then allow each group to be resampled to its original size or, if specified, \code{max_size}.} \item{progress}{if \code{TRUE} show a progress bar.} } \value{ A \link{DiversityCurve} object summarizing the diversity scores. } \description{ \code{rarefyDiversity} divides a set of clones by a group annotation, resamples the sequences from each group, and calculates diversity scores (\eqn{D}) over an interval of diversity orders (\eqn{q}). } \details{ Clonal diversity is calculated using the generalized diversity index (Hill numbers) proposed by Hill (Hill, 1973). See \link{calcDiversity} for further details. Diversity is calculated on the estimated complete clonal abundance distribution. This distribution is inferred by using the Chao1 estimator to estimate the number of seen clones, and applying the relative abundance correction and unseen clone frequency described in Chao et al, 2015. To generate a smooth curve, \eqn{D} is calculated for each value of \eqn{q} from \code{min_q} to \code{max_q} incremented by \code{step_q}. When \code{uniform=TRUE} variability in total sequence counts across unique values in the \code{group} column is corrected by repeated resampling from the estimated complete clonal distribution to a common number of sequences. The diversity index (\eqn{D}) for each group is the mean value of over all resampling realizations. Confidence intervals are derived using the standard deviation of the resampling realizations, as described in Chao et al, 2015. } \examples{ \dontrun{ # Group by sample identifier div <- rarefyDiversity(ExampleDb, "SAMPLE", step_q=1, max_q=10, nboot=100) plotDiversityCurve(div, legend_title="Sample") # Grouping by isotype rather than sample identifier div <- rarefyDiversity(ExampleDb, "ISOTYPE", min_n=40, step_q=1, max_q=10, nboot=100) plotDiversityCurve(div, legend_title="Isotype") } } \references{ \enumerate{ \item Hill M. Diversity and evenness: a unifying notation and its consequences. Ecology. 1973 54(2):427-32. \item Chao A. Nonparametric Estimation of the Number of Classes in a Population. Scand J Stat. 1984 11, 265270. \item Chao A, et al. Rarefaction and extrapolation with Hill numbers: A framework for sampling and estimation in species diversity studies. Ecol Monogr. 2014 84:45-67. \item Chao A, et al. Unveiling the species-rank abundance distribution by generalizing the Good-Turing sample coverage theory. Ecology. 2015 96, 11891201. } } \seealso{ \link{alphaDiversity} } alakazam/man/bulk.Rd0000644000176200001440000000264513445225137014047 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/AminoAcids.R \name{bulk} \alias{bulk} \title{Calculates the average bulkiness of amino acid sequences} \usage{ bulk(seq, bulkiness = NULL) } \arguments{ \item{seq}{vector of strings containing amino acid sequences.} \item{bulkiness}{named numerical vector defining bulkiness scores for each amino acid, where names are single-letter amino acid character codes. If \code{NULL}, then the Zimmerman et al, 1968 scale is used.} } \value{ A vector of bulkiness scores for the sequence(s). } \description{ \code{bulk} calculates the average bulkiness score of amino acid sequences. Non-informative positions are excluded, where non-informative is defined as any character in \code{c("X", "-", ".", "*")}. } \examples{ # Default bulkiness scale seq <- c("CARDRSTPWRRGIASTTVRTSW", "XXTQMYVRT") bulk(seq) # Use the Grantham, 1974 side chain volumn scores from the seqinr package library(seqinr) data(aaindex) x <- aaindex[["GRAR740103"]]$I # Rename the score vector to use single-letter codes names(x) <- translateStrings(names(x), ABBREV_AA) # Calculate average volume bulk(seq, bulkiness=x) } \references{ \enumerate{ \item Zimmerman JM, Eliezer N, Simha R. The characterization of amino acid sequences in proteins by statistical methods. J Theor Biol 21, 170-201 (1968). } } \seealso{ For additional size related indices see \link[seqinr]{aaindex}. } alakazam/man/getSegment.Rd0000644000176200001440000000614513476256754015230 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Gene.R \name{getSegment} \alias{getSegment} \alias{getAllele} \alias{getGene} \alias{getFamily} \title{Get Ig segment allele, gene and family names} \usage{ getSegment(segment_call, segment_regex, first = TRUE, collapse = TRUE, strip_d = TRUE, omit_nl = FALSE, sep = ",") getAllele(segment_call, first = TRUE, collapse = TRUE, strip_d = TRUE, omit_nl = FALSE, sep = ",") getGene(segment_call, first = TRUE, collapse = TRUE, strip_d = TRUE, omit_nl = FALSE, sep = ",") getFamily(segment_call, first = TRUE, collapse = TRUE, strip_d = TRUE, omit_nl = FALSE, sep = ",") } \arguments{ \item{segment_call}{character vector containing segment calls delimited by commas.} \item{segment_regex}{string defining the segment match regular expression.} \item{first}{if \code{TRUE} return only the first call in \code{segment_call}; if \code{FALSE} return all calls delimited by commas.} \item{collapse}{if \code{TRUE} check for duplicates and return only unique segment assignments; if \code{FALSE} return all assignments (faster). Has no effect if \code{first=TRUE}.} \item{strip_d}{if \code{TRUE} remove the "D" from the end of gene annotations (denoting a duplicate gene in the locus); if \code{FALSE} do not alter gene names.} \item{omit_nl}{if \code{TRUE} remove non-localized (NL) genes from the result. Only applies at the gene or allele level.} \item{sep}{character defining both the input and output segment call delimiter.} } \value{ A character vector containing allele, gene or family names. } \description{ \code{getSegment} performs generic matching of delimited segment calls with a custom regular expression. \link{getAllele}, \link{getGene} and \link{getFamily} extract the allele, gene and family names, respectively, from a character vector of immunoglobulin (Ig) or TCR segment allele calls in IMGT format. } \examples{ # Light chain examples kappa_call <- c("Homsap IGKV1D-39*01 F,Homsap IGKV1-39*02 F,Homsap IGKV1-39*01", "Homsap IGKJ5*01 F") getAllele(kappa_call) getAllele(kappa_call, first=FALSE) getAllele(kappa_call, first=FALSE, strip_d=FALSE) getGene(kappa_call) getGene(kappa_call, first=FALSE) getGene(kappa_call, first=FALSE, strip_d=FALSE) getFamily(kappa_call) getFamily(kappa_call, first=FALSE) getFamily(kappa_call, first=FALSE, collapse=FALSE) getFamily(kappa_call, first=FALSE, strip_d=FALSE) # Heavy chain examples heavy_call <- c("Homsap IGHV1-69*01 F,Homsap IGHV1-69D*01 F", "Homsap IGHD1-1*01 F", "Homsap IGHJ1*01 F") getAllele(heavy_call, first=FALSE) getAllele(heavy_call, first=FALSE, strip_d=FALSE) getGene(heavy_call, first=FALSE) getGene(heavy_call, first=FALSE, strip_d=FALSE) # Filtering non-localized genes nl_call <- c("IGHV3-NL1*01,IGHV3-30-3*01,IGHV3-30*01", "Homosap IGHV3-30*01 F,Homsap IGHV3-NL1*01 F", "IGHV1-NL1*01") getAllele(nl_call, first=FALSE, omit_nl=TRUE) getGene(nl_call, first=FALSE, omit_nl=TRUE) getFamily(nl_call, first=FALSE, omit_nl=TRUE) } \references{ \url{http://imgt.org} } \seealso{ \link{countGenes} } alakazam/man/seqDist.Rd0000644000176200001440000000427713445225137014531 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Sequence.R \name{seqDist} \alias{seqDist} \title{Calculate distance between two sequences} \usage{ seqDist(seq1, seq2, dist_mat = getDNAMatrix()) } \arguments{ \item{seq1}{character string containing a DNA sequence.} \item{seq2}{character string containing a DNA sequence.} \item{dist_mat}{Character distance matrix. Defaults to a Hamming distance matrix returned by \link{getDNAMatrix}. If gap characters, \code{c("-", ".")}, are assigned a value of -1 in \code{dist_mat} then contiguous gaps of any run length, which are not present in both sequences, will be counted as a distance of 1. Meaning, indels of any length will increase the sequence distance by 1. Gap values other than -1 will return a distance that does not consider indels as a special case.} } \value{ Numerical distance between \code{seq1} and \code{seq2}. } \description{ \code{seqDist} calculates the distance between two DNA sequences. } \examples{ # Ungapped examples seqDist("ATGGC", "ATGGG") seqDist("ATGGC", "ATG??") # Gaps will be treated as Ns with a gap=0 distance matrix seqDist("ATGGC", "AT--C", dist_mat=getDNAMatrix(gap=0)) # Gaps will be treated as universally non-matching characters with gap=1 seqDist("ATGGC", "AT--C", dist_mat=getDNAMatrix(gap=1)) # Gaps of any length will be treated as single mismatches with a gap=-1 distance matrix seqDist("ATGGC", "AT--C", dist_mat=getDNAMatrix(gap=-1)) # Gaps of equivalent run lengths are not counted as gaps seqDist("ATG-C", "ATG-C", dist_mat=getDNAMatrix(gap=-1)) # Overlapping runs of gap characters are counted as a single gap seqDist("ATG-C", "AT--C", dist_mat=getDNAMatrix(gap=-1)) seqDist("A-GGC", "AT--C", dist_mat=getDNAMatrix(gap=-1)) seqDist("AT--C", "AT--C", dist_mat=getDNAMatrix(gap=-1)) # Discontiguous runs of gap characters each count as separate gaps seqDist("-TGGC", "AT--C", dist_mat=getDNAMatrix(gap=-1)) } \seealso{ Nucleotide distance matrix may be built with \link{getDNAMatrix}. Amino acid distance matrix may be built with \link{getAAMatrix}. Used by \link{pairwiseDist} for generating distance matrices. See \link{seqEqual} for testing sequence equivalence. } alakazam/man/ExampleTrees.Rd0000644000176200001440000000140513445225137015501 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Data.R \docType{data} \name{ExampleTrees} \alias{ExampleTrees} \title{Example Ig lineage trees} \format{A list of igraph objects output by \link{buildPhylipLineage}. Each node of each tree has the following annotations (vertex attributes): \itemize{ \item \code{SAMPLE}: Sample identifier(s). Time in relation to vaccination. \item \code{ISOTYPE}: Isotype assignment(s). \item \code{DUPCOUNT}: Copy count (number of duplicates) of the sequence. }} \usage{ ExampleTrees } \description{ A set of Ig lineage trees generated from the \code{ExampleDb} file, subset to only those trees with at least four nodes. } \seealso{ \link{ExampleTrees} } \keyword{datasets} alakazam/man/getMRCA.Rd0000644000176200001440000000356413445225137014335 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Topology.R \name{getMRCA} \alias{getMRCA} \title{Retrieve the first non-root node of a lineage tree} \usage{ getMRCA(graph, path = c("distance", "steps"), root = "Germline", field = NULL, exclude = NULL) } \arguments{ \item{graph}{igraph object containing an annotated lineage tree.} \item{path}{string defining whether to use unweighted (steps) or weighted (distance) measures for determining the founder node set..} \item{root}{name of the root (germline) node.} \item{field}{annotation field to use for both unweighted path length exclusion and consideration as an MRCA node. If \code{NULL} do not exclude any nodes.} \item{exclude}{vector of annotation values in \code{field} to exclude from the potential MRCA set. If \code{NULL} do not exclude any nodes. Has no effect if \code{field=NULL}.} } \value{ A data.frame of the MRCA node(s) containing the columns: \itemize{ \item \code{NAME}: node name \item \code{STEPS}: path length as the number of nodes traversed \item \code{DISTANCE}: path length as the sum of edge weights } Along with additional columns corresponding to the annotations of the input graph. } \description{ \code{getMRCA} returns the set of lineage tree nodes with the minimum weighted or unweighted path length from the root (germline) of the lineage tree, allowing for exclusion of specific groups of nodes. } \examples{ # Define example graph graph <- ExampleTrees[[23]] # Use unweighted path length and do not exclude any nodes getMRCA(graph, path="steps", root="Germline") # Exclude nodes without an isotype annotation and use weighted path length getMRCA(graph, path="distance", root="Germline", field="ISOTYPE", exclude=NA) } \seealso{ Path lengths are determined with \link{getPathLengths}. } alakazam/man/EdgeTest-class.Rd0000644000176200001440000000340113445225137015710 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Classes.R \docType{class} \name{EdgeTest-class} \alias{EdgeTest-class} \alias{EdgeTest} \alias{print,EdgeTest-method} \alias{EdgeTest-method} \alias{plot,EdgeTest,missing-method} \title{S4 class defining edge significance} \usage{ \S4method{print}{EdgeTest}(x) \S4method{plot}{EdgeTest,missing}(x, y, ...) } \arguments{ \item{x}{EdgeTest object.} \item{y}{ignored.} \item{...}{arguments to pass to \link{plotEdgeTest}.} } \description{ \code{EdgeTest} defines the significance of parent-child annotation enrichment. } \section{Slots}{ \describe{ \item{\code{tests}}{data.frame describing the significance test results with columns: \itemize{ \item \code{PARENT}: parent node annotation. \item \code{CHILD}: child node annotation \item \code{COUNT}: count of observed edges with the given parent-child annotation set. \item \code{EXPECTED}: mean count of expected edges for the given parent-child relationship. \item \code{PVALUE}: one-sided p-value for the hypothesis that the observed edge abundance is greater than expected. }} \item{\code{permutations}}{data.frame containing the raw permutation test data with columns: \itemize{ \item \code{PARENT}: parent node annotation. \item \code{CHILD}: child node annotation \item \code{COUNT}: count of edges with the given parent-child annotation set. \item \code{ITER}: numerical index define which permutation realization each observation corresponds to. }} \item{\code{nperm}}{number of permutation realizations.} }} alakazam/DESCRIPTION0000644000176200001440000000532713514052755013557 0ustar liggesusersPackage: alakazam Type: Package Version: 0.3.0 Date: 2019-07-17 Authors@R: c(person("Jason", "Vander Heiden", role=c("aut", "cre"), email="jason.vanderheiden@yale.edu"), person("Namita", "Gupta", role=c("aut"), email="namita.gupta@yale.edu"), person("Susanna", "Marquez", role=c("ctb"), email="susanna.marquez@yale.edu"), person("Daniel", "Gadala-Maria", role=c("ctb"), email="daniel.gadala-maria@yale.edu"), person("Ruoyi", "Jiang", role=c("ctb"), email="ruoyi.jiang@yale.edu"), person("Nima", "Nouri", role=c("ctb"), email="nima.nouri@yale.edu"), person("Kenneth", "Hoehn", role=c("ctb"), email="kenneth.hoehn@yale.edu"), person("Julian", "Zhou", role=c("ctb"), email="julian.zhou@bulldogs.yale.edu"), person("Steven", "Kleinstein", role=c("aut", "cph"), email="steven.kleinstein@yale.edu")) Title: Immunoglobulin Clonal Lineage and Diversity Analysis Description: Provides methods for high-throughput adaptive immune receptor repertoire sequencing (AIRR-Seq; Rep-Seq) analysis. In particular, immunoglobulin (Ig) sequence lineage reconstruction, lineage topology analysis, diversity profiling, amino acid property analysis and gene usage. Citations: Gupta and Vander Heiden, et al (2017) , Stern, Yaari and Vander Heiden, et al (2014) . License: CC BY-SA 4.0 URL: http://alakazam.readthedocs.org BugReports: https://bitbucket.org/kleinstein/alakazam/issues LazyData: true BuildVignettes: true VignetteBuilder: knitr Encoding: UTF-8 SystemRequirements: C++11 Depends: R (>= 3.1.2), ggplot2 (>= 2.0.0) Imports: ape, dplyr (>= 0.8.1), graphics, grid, igraph (>= 1.0.0), lazyeval, Matrix, methods, progress, Rcpp (>= 0.12.12), readr, rlang, scales, seqinr, stats, stringi, tibble, tidyr, utils LinkingTo: Rcpp Suggests: knitr, rmarkdown, testthat RoxygenNote: 6.1.1 Collate: 'Alakazam.R' 'AminoAcids.R' 'Classes.R' 'Core.R' 'Data.R' 'Diversity.R' 'Deprecated.R' 'Gene.R' 'Lineage.R' 'RcppExports.R' 'Sequence.R' 'Topology.R' NeedsCompilation: yes Packaged: 2019-07-17 19:15:47 UTC; vandej27 Author: Jason Vander Heiden [aut, cre], Namita Gupta [aut], Susanna Marquez [ctb], Daniel Gadala-Maria [ctb], Ruoyi Jiang [ctb], Nima Nouri [ctb], Kenneth Hoehn [ctb], Julian Zhou [ctb], Steven Kleinstein [aut, cph] Maintainer: Jason Vander Heiden Repository: CRAN Date/Publication: 2019-07-18 11:20:13 UTC alakazam/build/0000755000176200001440000000000013513671743013144 5ustar liggesusersalakazam/build/vignette.rds0000644000176200001440000000051313513671743015502 0ustar liggesusersN0ƻ-1Q2/˜im4 wXfVͼi{:! xd虡75adڹi׋qHXn_XAk󘽁TLWN8<+Kz`~f+Q\dcl7;rW)rW \iܒD3zl#<+Pgl3g=tW5QsM>$c}#& ,BiXMK.X1x'1S|Pm4Ec)^v[&u'Jrjof_;>alakazam/src/0000755000176200001440000000000013513671743012634 5ustar liggesusersalakazam/src/RcppDistance.cpp0000644000176200001440000002204613512442156015714 0ustar liggesusers#include #include #include using namespace Rcpp; // [[Rcpp::plugins(cpp11)]] //' Test DNA sequences for equality. //' //' \code{seqEqual} checks if two DNA sequences are identical. //' //' @param seq1 character string containing a DNA sequence. //' @param seq2 character string containing a DNA sequence. //' @param ignore vector of characters to ignore when testing for equality. //' Default is to ignore c("N",".","-","?") //' //' @return Returns \code{TRUE} if sequences are equal and \code{FALSE} if they are not. //' Sequences of unequal length will always return \code{FALSE} regardless of //' their character values. //' //' @seealso Used by \link{pairwiseEqual} within \link{collapseDuplicates}. //' See \link{seqDist} for calculation Hamming distances between sequences. //' //' @examples //' # Ignore gaps //' seqEqual("ATG-C", "AT--C") //' seqEqual("ATGGC", "ATGGN") //' seqEqual("AT--T", "ATGGC") //' //' # Ignore only Ns //' seqEqual("ATG-C", "AT--C", ignore="N") //' seqEqual("ATGGC", "ATGGN", ignore="N") //' seqEqual("AT--T", "ATGGC", ignore="N") //' //' @export // [[Rcpp::export]] bool seqEqual(std::string seq1, std::string seq2, CharacterVector ignore=CharacterVector::create("N","-",".","?")) { int ig_len = ignore.length(); ig_len = ignore.length(); int len_seq1 = seq1.length(); int len_seq2 = seq2.length(); if (len_seq1 != len_seq2) { return (FALSE); } else { for(int i = 0; i < len_seq1; i++) { char seq1_char = (char)seq1[i]; char seq2_char = (char)seq2[i]; if (seq1_char != seq2_char) { bool ignore_seq1 = FALSE; bool ignore_seq2 = FALSE; for(int j = 0; j < ig_len; j++) { char ig = *(char*)ignore[j]; if (ig == seq1_char) { ignore_seq1 = TRUE; } if (ig == seq2_char) { ignore_seq2 = TRUE; } } if (!ignore_seq1 & !ignore_seq2) { return FALSE; } } } return TRUE; } } //' Calculate pairwise equivalence between sequences //' //' \code{pairwiseEqual} determined pairwise equivalence between a pairs in a //' set of sequences, excluding ambiguous positions (Ns and gaps). //' //' @param seq character vector containing a DNA sequences. //' //' @return A logical matrix of equivalence between each entry in \code{seq}. //' Values are \code{TRUE} when sequences are equivalent and \code{FALSE} //' when they are not. //' //' @seealso Uses \link{seqEqual} for testing equivalence between pairs. //' See \link{pairwiseDist} for generating a sequence distance matrix. //' //' @examples //' # Gaps and Ns will match any character //' seq <- c(A="ATGGC", B="ATGGG", C="ATGGG", D="AT--C", E="NTGGG") //' d <- pairwiseEqual(seq) //' rownames(d) <- colnames(d) <- seq //' d //' //' @export // [[Rcpp::export]] LogicalMatrix pairwiseEqual(StringVector seq) { // allocate the matrix we will return LogicalMatrix rmat(seq.length(), seq.length()); for (int i = 0; i < rmat.nrow(); i++) { for (int j = 0; j <= i; j++) { // check seq equal std::string row_seq = as(seq[i]); std::string col_seq = as(seq[j]); bool is_equal = seqEqual(row_seq, col_seq); // write to output matrix rmat(i,j) = is_equal; rmat(j,i) = is_equal; } } // Add row and column names Rcpp::List dimnames = Rcpp::List::create(seq.attr("names"), seq.attr("names")); rmat.attr("dimnames") = dimnames; return rmat; } // seqDist // [[Rcpp::export]] double seqDistRcpp(std::string seq1, std::string seq2, NumericMatrix dist_mat) { // Check that seq1 and seq2 have same length int len_seq1 = seq1.length(); int len_seq2 = seq2.length(); if (len_seq1 != len_seq2) { throw std::range_error("Sequences of different length."); } int len_seqs = len_seq1; List dist_mat_dims = dist_mat.attr("dimnames"); //print (dist_mat_dims); CharacterVector dist_mat_rownames = dist_mat_dims[0]; CharacterVector dist_mat_colnames = dist_mat_dims[1]; int num_rows = dist_mat_rownames.size(); int num_cols = dist_mat_colnames.size(); List row_key_idx; List col_key_idx; std::map rows_map; std::map cols_map; for (int i = 0; i < num_rows; i++) { //const char *this_col = dist_mat_colnames[i].c_str(); std::string this_row = as(dist_mat_rownames[i]); rows_map[this_row] = i; } for (int i = 0; i < num_cols; i++) { //const char *this_col = dist_mat_colnames[i].c_str(); std::string this_col = as(dist_mat_colnames[i]); cols_map[this_col] = i; } int d_seen = 0; int indels = 0; // sum(d[d>0]) double d_sum = 0; for (int i = 0; i < len_seqs; i++) { // find row index int row_idx; char row_char = (char)seq1[i]; std::string row_string; row_string+=row_char; auto search_row = rows_map.find(row_string); if(search_row != rows_map.end()) { row_idx = search_row->second; } else { throw std::range_error("Character not found in dist_mat."); } // find col index int col_idx; char col_char = (char)seq2[i]; std::string col_string; col_string+=col_char; auto search_col = cols_map.find(col_string); if(search_col != cols_map.end()) { col_idx = search_col->second; } else { throw std::range_error("Character not found in dist_mat."); } // distance for current i double d_i = dist_mat(row_idx, col_idx); if (d_i > 0){ // Sum distance d_sum = d_sum + d_i; } else if ( (d_i == -1 ) & (d_seen != -1) ) { // Count indel indels++; } d_seen = d_i; } double distance = d_sum + indels; return (distance); } // pairwiseDist // [[Rcpp::export]] NumericMatrix pairwiseDistRcpp(StringVector seq, NumericMatrix dist_mat) { // allocate the matrix we will return NumericMatrix rmat(seq.length(), seq.length()); for (int i = 0; i < rmat.nrow(); i++) { for (int j = 0; j < i; j++) { // check seq equal std::string row_seq = as(seq[i]); std::string col_seq = as(seq[j]); double distance = seqDistRcpp(row_seq, col_seq, dist_mat); // write to output matrix rmat(i,j) = distance; rmat(j,i) = distance; } } // Add row and column names Rcpp::List dimnames = Rcpp::List::create(seq.attr("names"), seq.attr("names")); rmat.attr("dimnames") = dimnames; return rmat; } // nonsquareDist // [[Rcpp::export]] NumericMatrix nonsquareDistRcpp(StringVector seq, NumericVector indx, NumericMatrix dist_mat) { // defien variables int m, n, i, j; std::string row_seq, col_seq; // extract the sizes. Note: This should be satisfied (n<=m) m = indx.size(); //number of rows n = seq.size(); //number of columns // allocate the main matrix NumericMatrix rmat(m,n); std::fill(rmat.begin(), rmat.end(), NA_REAL); // sort and push indices back by 1 to match c++ indexing std::sort(indx.begin(), indx.end()); indx = indx - 1; // find the position of the column ids in the indx vector NumericVector pos(n); for (j = 0; j < n; j++) { pos[j] = std::find(indx.begin(), indx.end(), j) - indx.begin(); } // begin filling rmat for (i = 0; i < m; i++) { row_seq = as(seq[indx[i]]); //row sequence for (j = 0; j < n; j++) { if (!R_IsNA(rmat(i,j))) continue; if (indx[i] == j) rmat(i,j) = 0; else { col_seq = as(seq[j]); //col sequence rmat(i,j) = seqDistRcpp(row_seq, col_seq, dist_mat); if (pos[j] < m) rmat(pos[j],indx[i]) = rmat(i,j); } } } // Add row and column names StringVector subSeq = seq[indx]; Rcpp::List dimnames = Rcpp::List::create(subSeq.attr("names"), //rownames seq.attr("names")); //colnames rmat.attr("dimnames") = dimnames; // return matrix return rmat; } alakazam/src/RcppExports.cpp0000644000176200001440000000655713510700301015622 0ustar liggesusers// Generated by using Rcpp::compileAttributes() -> do not edit by hand // Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393 #include using namespace Rcpp; // seqEqual bool seqEqual(std::string seq1, std::string seq2, CharacterVector ignore); RcppExport SEXP _alakazam_seqEqual(SEXP seq1SEXP, SEXP seq2SEXP, SEXP ignoreSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< std::string >::type seq1(seq1SEXP); Rcpp::traits::input_parameter< std::string >::type seq2(seq2SEXP); Rcpp::traits::input_parameter< CharacterVector >::type ignore(ignoreSEXP); rcpp_result_gen = Rcpp::wrap(seqEqual(seq1, seq2, ignore)); return rcpp_result_gen; END_RCPP } // pairwiseEqual LogicalMatrix pairwiseEqual(StringVector seq); RcppExport SEXP _alakazam_pairwiseEqual(SEXP seqSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< StringVector >::type seq(seqSEXP); rcpp_result_gen = Rcpp::wrap(pairwiseEqual(seq)); return rcpp_result_gen; END_RCPP } // seqDistRcpp double seqDistRcpp(std::string seq1, std::string seq2, NumericMatrix dist_mat); RcppExport SEXP _alakazam_seqDistRcpp(SEXP seq1SEXP, SEXP seq2SEXP, SEXP dist_matSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< std::string >::type seq1(seq1SEXP); Rcpp::traits::input_parameter< std::string >::type seq2(seq2SEXP); Rcpp::traits::input_parameter< NumericMatrix >::type dist_mat(dist_matSEXP); rcpp_result_gen = Rcpp::wrap(seqDistRcpp(seq1, seq2, dist_mat)); return rcpp_result_gen; END_RCPP } // pairwiseDistRcpp NumericMatrix pairwiseDistRcpp(StringVector seq, NumericMatrix dist_mat); RcppExport SEXP _alakazam_pairwiseDistRcpp(SEXP seqSEXP, SEXP dist_matSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< StringVector >::type seq(seqSEXP); Rcpp::traits::input_parameter< NumericMatrix >::type dist_mat(dist_matSEXP); rcpp_result_gen = Rcpp::wrap(pairwiseDistRcpp(seq, dist_mat)); return rcpp_result_gen; END_RCPP } // nonsquareDistRcpp NumericMatrix nonsquareDistRcpp(StringVector seq, NumericVector indx, NumericMatrix dist_mat); RcppExport SEXP _alakazam_nonsquareDistRcpp(SEXP seqSEXP, SEXP indxSEXP, SEXP dist_matSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< StringVector >::type seq(seqSEXP); Rcpp::traits::input_parameter< NumericVector >::type indx(indxSEXP); Rcpp::traits::input_parameter< NumericMatrix >::type dist_mat(dist_matSEXP); rcpp_result_gen = Rcpp::wrap(nonsquareDistRcpp(seq, indx, dist_mat)); return rcpp_result_gen; END_RCPP } static const R_CallMethodDef CallEntries[] = { {"_alakazam_seqEqual", (DL_FUNC) &_alakazam_seqEqual, 3}, {"_alakazam_pairwiseEqual", (DL_FUNC) &_alakazam_pairwiseEqual, 1}, {"_alakazam_seqDistRcpp", (DL_FUNC) &_alakazam_seqDistRcpp, 3}, {"_alakazam_pairwiseDistRcpp", (DL_FUNC) &_alakazam_pairwiseDistRcpp, 2}, {"_alakazam_nonsquareDistRcpp", (DL_FUNC) &_alakazam_nonsquareDistRcpp, 3}, {NULL, NULL, 0} }; RcppExport void R_init_alakazam(DllInfo *dll) { R_registerRoutines(dll, NULL, CallEntries, NULL, NULL); R_useDynamicSymbols(dll, FALSE); } alakazam/vignettes/0000755000176200001440000000000013513671743014055 5ustar liggesusersalakazam/vignettes/Topology-Vignette.Rmd0000644000176200001440000003056713402556375020133 0ustar liggesusers--- title: 'Alakazam: Topology analysis of lineage trees' author: "Jason Anthony Vander Heiden" date: '`r Sys.Date()`' output: pdf_document: dev: pdf fig_height: 4 fig_width: 7.5 highlight: pygments toc: yes html_document: fig_height: 4 fig_width: 7.5 highlight: pygments theme: readable toc: yes md_document: fig_height: 4 fig_width: 7.5 preserve_yaml: no toc: yes geometry: margin=1in fontsize: 11pt vignette: > %\VignetteEngine{knitr::rmarkdown} %\VignetteIndexEntry{Topology analysis} %\usepackage[utf8]{inputenc} --- This vignette covers the basics of analyzing the topologies of Ig lineage trees built using `buildPhylipLineage`, using some built-in alakazam functions that focus on quantifying annotation relationships within lineages. ## Example data A small set of annotated example trees are included in the `alakazam` package. The trees are `igraph` objects with the following tree annotations (graph attributes): * `clone`: An identifier for the clonal group. These entries correspond to the `CLONE` column in the `ExampleDb` data.frame from which the trees were generated. * `v_gene`: IGHV gene name. * `j_gene`: IGHJ gene name. * `junc_len`: Length of the junction region (nucleotides). And the following node annotations (vertex attributes): * `SAMPLE`: Time point in relation to influenza vaccination. * `ISOTYPE`: The isotype(s) assigned to the sequence. Multiple isotypes are delimited by comma, and reflect identical V(D)J sequences observed with more than one isotype. * `DUPCOUNT`: The copy number (duplicate count), which indicates the total number of reads with the same V(D)J sequence. ```{r, eval=TRUE, warning=FALSE, message=FALSE} # Load required packages library(alakazam) library(igraph) library(dplyr) # Load example trees data(ExampleTrees) # Select one tree for example purposes graph <- ExampleTrees[[24]] # And add some annotation complexity to the tree V(graph)$SAMPLE[c(2, 7)] <- "-1h" V(graph)$ISOTYPE[c(2, 7)] <- "IgM" # Make a list of example trees excluding multi-isotype trees graph_list <- ExampleTrees[sapply(ExampleTrees, function(x) !any(grepl(",", V(x)$ISOTYPE)))] ``` ## Plotting annotations on a tree There are many options for configuring how an igrpah object is plotted which are helpful for visualing annotation topologies. Below is an extensive example of how to plot a tree by configuring the colors, labels, shapes and sizes of different visual elements according to annotations embedded in the graph. ```{r, eval=TRUE} # Set node colors V(graph)$color[V(graph)$SAMPLE == "-1h"] <- "seagreen" V(graph)$color[V(graph)$SAMPLE == "+7d"] <- "steelblue" V(graph)$color[V(graph)$name == "Germline"] <- "black" V(graph)$color[grepl("Inferred", V(graph)$name)] <- "white" # Set node labels V(graph)$label <- paste(V(graph)$SAMPLE, V(graph)$ISOTYPE, sep=", ") V(graph)$label[V(graph)$name == "Germline"] <- "" V(graph)$label[grepl("Inferred", V(graph)$name)] <- "" # Set node shapes V(graph)$shape <- "crectangle" V(graph)$shape[V(graph)$name == "Germline"] <- "circle" V(graph)$shape[grepl("Inferred", V(graph)$name)] <- "circle" # Set node sizes V(graph)$size <- 60 V(graph)$size[V(graph)$name == "Germline"] <- 30 V(graph)$size[grepl("Inferred", V(graph)$name)] <- 15 # Remove large default margins par(mar=c(0, 0, 0, 0) + 0.05) # Plot the example tree plot(graph, layout=layout_as_tree, vertex.frame.color="grey", vertex.label.color="black", edge.label.color="black", edge.arrow.mode=0) # Add legend legend("topleft", c("Germline", "Inferred", "-1h", "+7d"), fill=c("black", "white", "seagreen", "steelblue"), cex=0.75) ``` ## Summarizing node properties Various annotation dependent node statistics can be calculated using the `summarizeSubstrees` and `getPathLengths` functions. `getPathLengths` calculates distances from the root (germline) *to child nodes*, whereas `summarizeSubtrees` calculates paths and subtree statistics *from child nodes*. ### Calculating distance from the germline To determine the shortest path from the germline sequence to any node, we use `getPathLengths`, which returns the distance both as the number of "hops" (`STEPS`) and the number of mutational events (`DISTANCE`). ```{r, eval=TRUE} # Consider all nodes getPathLengths(graph, root="Germline") ``` Note, the `STEPS` counted in the above example include traversal of inferred intermediates. If you want to exclude such nodes, and consider only nodes associated with observed sequences, you can specify an annotation field and value that will be excluded from the number of steps. In the example below we are excluding `NA` values in the `ISOTYPE` annotation (`field="ISOTYPE", exclude=NA`). ```{r, eval=TRUE} # Exclude nodes without an isotype annotation from step count getPathLengths(graph, root="Germline", field="ISOTYPE", exclude=NA) ``` Note, `STEPS` has changed with respect to the previous example, but `DISTANCE` remains the same. ### Calculating subtree properties The `summarizeSubtrees` function returns a table of each node with the following properties for each node: * `NAME`: The node identifier. * `PARENT`: The identifier of the node's parent. * `OUTDEGREE`: The number of edges leading from the node. * `SIZE`: The total number of nodes within the subtree rooted at the node. * `DEPTH`: The depth of the subtree that is rooted at the node. * `PATHLENGTH`: The maximum path length beneath the node. * `OUTDEGREE_NORM`: The `OUTDEGREE` normalized by the total number of edges. * `SIZE_NORM`: The `SIZE` normalized by the total tree size. * `DEPTH_NORM`: The `DEPTH` normalized by the total tree depth. * `PATHLENGTH_NORM`: The `PATHLENGTH` normalized by the longest path. The `fields=c("SAMPLE", "ISOTYPE")` argument in the example below simply defines which annotations we wish to retain in the output. This argument has no effect on the results, in constast to the behavior of `getPathLengths`. ```{r, eval=TRUE} # Summarize tree df <- summarizeSubtrees(graph, fields=c("SAMPLE", "ISOTYPE"), root="Germline") print(df[1:4]) print(df[c(1, 5:8)]) print(df[c(1, 9:12)]) ``` Distributions of normalized subtree statistics for a population of trees can be plotted using the `plotSubtrees` function. In the example below, we have specified `silent=TRUE` which causes `plotSubtrees` to return the ggplot object without rendering the plot. The ggplot object are then plotting using the `gridPlot` function which places each individual plot in a separate panel of the same figure. ```{r, eval=TRUE} # Set sample colors sample_colors <- c("-1h"="seagreen", "+7d"="steelblue") # Box plots of node outdegree by sample p1 <- plotSubtrees(graph_list, "SAMPLE", "outdegree", colors=sample_colors, main_title="Node outdegree", legend_title="Time", style="box", silent=TRUE) # Box plots of subtree size by sample p2 <- plotSubtrees(graph_list, "SAMPLE", "size", colors=sample_colors, main_title="Subtree size", legend_title="Time", style="box", silent=TRUE) # Violin plots of subtree path length by isotype p3 <- plotSubtrees(graph_list, "ISOTYPE", "pathlength", colors=IG_COLORS, main_title="Subtree path length", legend_title="Isotype", style="violin", silent=TRUE) # Violin plots of subtree depth by isotype p4 <- plotSubtrees(graph_list, "ISOTYPE", "depth", colors=IG_COLORS, main_title="Subtree depth", legend_title="Isotype", style="violin", silent=TRUE) # Plot in a 2x2 grid gridPlot(p1, p2, p3, p4, ncol=2) ``` ## Counting and testing node annotation relationships Given a set of annotated trees, you can determine the abundance of specific parent-child relationships within individual trees using the `tableEdges` function and the signficance of these relationships in population of trees using the `testEdges` function. Annotation relationships over edges can be calculated as direct or indirect relationships, where a direct relationship is a parent-child pair and an indirect relationship is a decent relationship that travels through another node (or nodes) first. ### Tabulating edges for a single tree Tabulating all directparent-child annotation relationships in the tree by isotype annotation can be performed like so: ```{r, eval=TRUE} # Count direct edges between isotypes tableEdges(graph, "ISOTYPE") ``` The above output is cluttered with the `NA` annotations from the germline and inferred nodes. We can perform the same direct tabulation, but exclude any nodes annotated with either `Germline` or `NA` for isotype using the `exclude` argument: ```{r, eval=TRUE} # Direct edges excluding germline and inferred nodes tableEdges(graph, "ISOTYPE", exclude=c("Germline", NA)) ``` As there are inferred nodes in the tree, we might want to consider indirect parent-child relationships that traverse through inferred nodes. This is accomplished using the same arguments as above, but with the addition of the `indirect=TRUE` argument which will skip over the excluded nodes when tabulating annotation pairs: ```{r, eval=TRUE} # Count indirect edges walking through germline and inferred nodes tableEdges(graph, "ISOTYPE", indirect=TRUE, exclude=c("Germline", NA)) ``` ### Significance testing of edges in a population of trees Given a population of trees, as a list of annotated igraph objects, you can determine if there is enrichment for specific annotation pairs using the `testEdges` function. This has the same options as `tableEdges`, except that the values `c("Germline", NA)` are excluded by default. `testEdges` performs a permutation test to generated a null distribution, excluding permutation of of any annotations specified to the `exclude` argument (these annotation remain fix in the tree). P-values output by `testEdges` are one-sided tests that the annotation pair is observed more often than expected. ```{r, eval=TRUE} # Test isotype relationships edge_test <- testEdges(graph_list, "ISOTYPE", nperm=20) # Print p-value table print(edge_test) # Plot null distributions for each annotation pair plotEdgeTest(edge_test, color="steelblue", main_title="Isotype Edges", style="hist") ``` ## Counting and testing MRCA annotations The most recent common ancestor (MRCA) of an Ig lineage we define herein as the most ancestral observed, or inferred, sequences in the lineage tree. Meaning, the node that is most proximal, by some measure, to the germline (root) node. The `getMRCA` and `testMRCA` functions provide extraction and significance testing of MRCA sequences by annotation value, respectively. ### Extracting MRCAs from a tree Extracting the MRCA from a tree is accomplished using the `getMRCA` function. The germline distance criteria are as described above for `getPathLengths` and can be either node hops or mutational events, with or without exclusion of nodes with specific annotations. To simply extract the annotations for the node(s) immediately below the germline, you can use the `path=steps` argument without any node exclusion: ```{r, eval=TRUE} # Use unweighted path length and do not exclude any nodes mrca_df <- getMRCA(graph, path="steps", root="Germline") # Print subset of the annotation data.frame print(mrca_df[c("NAME", "SAMPLE", "ISOTYPE", "STEPS", "DISTANCE")]) ``` To use mutational distance and consider only observed (ie, non-germline and non-inferred) nodes, we specify the exclusion field (`field="ISOTYPE"`) and exclusion value within that field (`exclude=NA`): ```{r, eval=TRUE} # Exclude nodes without an isotype annotation and use weighted path length mrca_df <- getMRCA(graph, path="distance", root="Germline", field="ISOTYPE", exclude=NA) # Print excluding sequence, label, color, shape and size annotations print(mrca_df[c("NAME", "SAMPLE", "ISOTYPE", "STEPS", "DISTANCE")]) ``` ### Significance testing of MRCA annotations Similar to `testEdges`, the function `testMRCA` will perform a permutation test to determine the significance of an annotation appearing at the MRCA over a population of trees. P-values output by `testMRCA` are one-sided tests that the annotation is observed more often than expected in the MRCA position. ```{r, eval=TRUE} # Test isotype MRCA annotations mrca_test <- testMRCA(graph_list, "ISOTYPE", nperm=20) # Print p-value table print(mrca_test) # Plot null distributions for each annotation plotMRCATest(mrca_test, color="steelblue", main_title="Isotype MRCA", style="hist") ``` alakazam/vignettes/Diversity-Vignette.Rmd0000644000176200001440000001514513513664120020263 0ustar liggesusers--- title: 'Alakazam: Analysis of clonal abundance and diversity' author: "Jason Anthony Vander Heiden" date: '`r Sys.Date()`' output: pdf_document: dev: pdf fig_height: 4 fig_width: 7.5 highlight: pygments toc: yes html_document: fig_height: 4 fig_width: 7.5 highlight: pygments theme: readable toc: yes md_document: fig_height: 4 fig_width: 7.5 preserve_yaml: no toc: yes geometry: margin=1in fontsize: 11pt vignette: > %\VignetteEngine{knitr::rmarkdown} %\VignetteIndexEntry{Diversity analysis} %\usepackage[utf8]{inputenc} --- The clonal diversity of the repertoire can be analyzed using the general form of the diversity index, as proposed by Hill in: Hill, M. Diversity and evenness: a unifying notation and its consequences. Ecology 54, 427-432 (1973). Coupled with resampling strategies to correct for variations in sequencing depth, as well as inferrence of complete clonal abundance distributions as described in: Chao A, et al. Rarefaction and extrapolation with Hill numbers: A framework for sampling and estimation in species diversity studies. Ecol Monogr. 2014 84:45-67. Chao A, et al. Unveiling the species-rank abundance distribution by generalizing the Good-Turing sample coverage theory. Ecology. 2015 96, 11891201. This package provides methods for the inferrence of a complete clonal abundance distribution, using the `estimateAbundance` function, along with two approaches to assess diversity of these distributions: 1. Generation of a smooth diversity (D) curve over a range of diversity orders (q) using `alphaDiversity`. 2. A significance test of the diversity (D) at a fixed diversity order (q). ## Example data A small example Change-O database, `ExampleDb`, is included in the `alakazam` package. Diversity calculation requires the `CLONE` field (column) to be present in the Change-O file, as well as an additional grouping column. In this example we will use the grouping columns `SAMPLE` and `ISOTYPE`. ```{r, eval=TRUE, warning=FALSE, message=FALSE} # Load required packages library(alakazam) # Load example data data(ExampleDb) ``` ## Generate a clonal abundance curve A simple table of the observed clonal abundance counts and frequencies may be generated using the `countClones` function either without copy numbers, where the size of each clone is determined by the number of sequence members: ```{r, eval=TRUE, warning=FALSE} # Partitions the data based on the SAMPLE column clones <- countClones(ExampleDb, group="SAMPLE") head(clones, 5) ``` You may also specify a column containing the abundance count of each sequence (usually copy numbers), that will including weighting of each clone size by the corresponding abundance count. Furthermore, multiple grouping columns may be specified such that `SEQ_FREQ` (unwieghted clone size as a fraction of total sequences in the group) and `COPY_FREQ` (weighted faction) are normalized to within multiple group data partitions. ```{r, eval=TRUE, warning=FALSE} # Partitions the data based on both the SAMPLE and ISOTYPE columns # Weights the clone sizes by the DUPCOUNT column clones <- countClones(ExampleDb, group=c("SAMPLE", "ISOTYPE"), copy="DUPCOUNT") head(clones, 5) ``` While `countClones` will report observed abundances, it will not provide confidence intervals. A complete clonal abundance distribution may be inferred using the `estimateAbundance` function with confidence intervals derived via bootstrapping. This output may be visualized using the `plotAbundanceCurve` function. ```{r, eval=TRUE, results='hide', warning=FALSE, fig.width=6, fig.height=4} # Partitions the data on the SAMPLE column # Calculates a 95% confidence interval via 200 bootstrap realizations curve <- estimateAbundance(ExampleDb, group="SAMPLE", ci=0.95, nboot=200) ``` ```{r, eval=TRUE, warning=FALSE, fig.width=6, fig.height=4} # Plots a rank abundance curve of the relative clonal abundances sample_colors <- c("-1h"="seagreen", "+7d"="steelblue") plot(curve, colors = sample_colors, legend_title="Sample") ``` ## Generate a diversity curve The function `alphaDiversity` performs uniform resampling of the input sequences and recalculates the clone size distribution, and diversity, with each resampling realization. Diversity (D) is calculated over a range of diversity orders (q) to generate a smooth curve. ```{r, eval=TRUE, results='hide'} # Compare diversity curve across values in the "SAMPLE" column # q ranges from 0 (min_q=0) to 4 (max_q=4) in 0.05 incriments (step_q=0.05) # A 95% confidence interval will be calculated (ci=0.95) # 200 resampling realizations are performed (nboot=200) sample_curve <- alphaDiversity(ExampleDb, group="SAMPLE", min_q=0, max_q=4, step_q=0.1, ci=0.95, nboot=200) # Compare diversity curve across values in the "ISOTYPE" column # Analyse is restricted to ISOTYPE values with at least 30 sequences by min_n=30 # Excluded groups are indicated by a warning message isotype_curve <- alphaDiversity(ExampleDb, group="ISOTYPE", min_q=0, max_q=4, step_q=0.1, ci=0.95, nboot=200) ``` ```{r, eval=TRUE, fig.width=6, fig.height=4} # Plot a log-log (log_q=TRUE, log_d=TRUE) plot of sample diversity # Indicate number of sequences resampled from each group in the title sample_main <- paste0("Sample diversity") sample_colors <- c("-1h"="seagreen", "+7d"="steelblue") plot(sample_curve, colors=sample_colors, main_title=sample_main, legend_title="Sample") # Plot isotype diversity using default set of Ig isotype colors isotype_main <- paste0("Isotype diversity") plot(isotype_curve, colors=IG_COLORS, main_title=isotype_main, legend_title="Isotype") ``` ## View diversity tests at a fixed diversity order Significance testing across groups is performed using the delta of the bootstrap distributions between groups when running `alphaDiversity` for all values of `q` specified. ```{r, eval=TRUE, fig.width=6, fig.height=3} # Test diversity at q=0, q=1 and q=2 (equivalent to species richness, Shannon entropy, # Simpson's index) across values in the "SAMPLE" column # 200 bootstrap realizations are performed (nboot=200) isotype_test <- alphaDiversity(ExampleDb, group="ISOTYPE", min_q=0, max_q=2, step_q=1, nboot=200) # Print P-value table print(isotype_test) # Plot results at q=0 and q=2 # Plot the mean and standard deviations at q=0 and q=2 plot(isotype_test, 0, colors=IG_COLORS, main_title=isotype_main, legend_title="Isotype") plot(isotype_test, 2, colors=IG_COLORS, main_title=isotype_main, legend_title="Isotype") ``` alakazam/vignettes/GeneUsage-Vignette.Rmd0000644000176200001440000001614413512442156020146 0ustar liggesusers--- title: 'Alakazam: Gene usage analysis' author: "Susanna Marquez" date: '`r Sys.Date()`' output: pdf_document: dev: pdf fig_height: 4 fig_width: 7.5 highlight: pygments toc: yes md_document: fig_height: 4 fig_width: 7.5 preserve_yaml: no toc: yes html_document: fig_height: 4 fig_width: 7.5 highlight: pygments theme: readable toc: yes geometry: margin=1in fontsize: 11pt vignette: > %\VignetteEngine{knitr::rmarkdown} %\VignetteIndexEntry{Gene usage analysis} %\usepackage[utf8]{inputenc} --- The 'alakazam' package provides basic gene usage quantification by either sequence count or clonal grouping; with or without consideration of duplicate reads/mRNA. Additionally, a set of accessory functions for sorting and parsing V(D)J gene names are also provided. ## Example data A small example Change-O database, `ExampleDb`, is included in the `alakazam` package. Gene usages analysis requires only the following columns: * `V_CALL` * `D_CALL` * `J_CALL` However, the optional clonal clustering (`CLONE`) and duplicate count (`DUPCOUNT`) columns may be used to quanitify usage by different abundance criteria. ```{r, eval=TRUE, warning=FALSE, message=FALSE} # Load required packages library(alakazam) library(dplyr) library(scales) # Subset example data data(ExampleDb) ``` ## Tabulate V(D)J allele, gene or family usage by sample The relative abundance of V(D)J alleles, genes or families within groups can be obtained with the function `countGenes`. To analyze differences in the V gene usage across different samples we will set `gene="V_CALL"` (the column containing gene data) and `groups="SAMPLE"` (the columns containing grouping variables). To quanitify abundance at the gene level we set `mode="gene"`: ```{r, eval=TRUE, warning=FALSE} # Quantify usage at the gene level gene <- countGenes(ExampleDb, gene="V_CALL", groups="SAMPLE", mode="gene") head(gene, n=4) ``` In the resultant `data.frame` the `SEQ_COUNT` columns is the number of raw sequences within each `SAMPLE` group for the given `GENE`. `SEQ_FREQ` is the frequency of each `GENE` within the given `SAMPLE`. Below we plot only the IGHV1 abundance by filtering on the `GENE` column to only rows containing IGHV1 family genes. We extract the family portion of the gene name using the `getFamily` function. Also, we take advantage of the `sortGenes` function to convert the `GENE` column to a factor with gene name lexicographically ordered in the factor levels (`method="name"`) for axis ordering using the `ggplot2` package. Alternatively, we could have ordered the genes by genomic position by passing `method="position"` to `sortGenes`. ```{r, eval=TRUE, warning=FALSE} # Assign sorted levels and subset to IGHV1 ighv1 <- gene %>% mutate(GENE=factor(GENE, levels=sortGenes(unique(GENE), method="name"))) %>% filter(getFamily(GENE) == "IGHV1") # Plot V gene usage in the IGHV1 family by sample g1 <- ggplot(ighv1, aes(x=GENE, y=SEQ_FREQ)) + theme_bw() + ggtitle("IGHV1 Usage") + theme(axis.text.x=element_text(angle=45, hjust=1, vjust=1)) + ylab("Percent of repertoire") + xlab("") + scale_y_continuous(labels=percent) + scale_color_brewer(palette="Set1") + geom_point(aes(color=SAMPLE), size=5, alpha=0.8) plot(g1) ``` Alternatively, usage can be quantified at the allele (`mode="allele"`) or family level (`mode="family"`): ```{r, eval=TRUE, warning=FALSE} # Quantify V family usage by sample family <- countGenes(ExampleDb, gene="V_CALL", groups="SAMPLE", mode="family") # Plot V family usage by sample g2 <- ggplot(family, aes(x=GENE, y=SEQ_FREQ)) + theme_bw() + ggtitle("Family Usage") + theme(axis.text.x=element_text(angle=45, hjust=1, vjust=1)) + ylab("Percent of repertoire") + xlab("") + scale_y_continuous(labels=percent) + scale_color_brewer(palette="Set1") + geom_point(aes(color=SAMPLE), size=5, alpha=0.8) plot(g2) ``` ## Tabulating gene abundance using additional groupings The `groups` argument to `countGenes` can accept multiple grouping columns and will calculated abundance within each unique combination. In the examples below groupings will be perform by unique sample and isotype pairs (`groups=c("SAMPLE", "ISOTYPE")`). Furthermore, instead of quantifying abundance by sequence count we will quantify it by clone count. Meaning, each clone will be counted only once regardless of how many sequences the clone represents. Clonal citeria are added by passing a value to the `clone` argument of `countGenes` (`clone="CLONE"`). For each clonal group, only the most common family/gene/allele will be considered for counting. ```{r, eval=TRUE, warning=FALSE} # Quantify V family clonal usage by sample and isotype family <- countGenes(ExampleDb, gene="V_CALL", groups=c("SAMPLE", "ISOTYPE"), clone="CLONE", mode="family") head(family, n=4) ``` The output `data.frame` contains the additional grouping column (`ISOTYPE`) along with the `CLONE_COUNT` and `CLONE_FREQ` columns that represent the count of clones for each V family and the frequencies within the given `SAMPLE` and `ISOTYPE` pair, respectively. ```{r, eval=TRUE, warning=FALSE} # Subset to IgM and IgG for plotting family <- filter(family, ISOTYPE %in% c("IgM", "IgG")) # Plot V family clonal usage by sample and isotype g3 <- ggplot(family, aes(x=GENE, y=CLONE_FREQ)) + theme_bw() + ggtitle("Clonal Usage") + theme(axis.text.x=element_text(angle=45, hjust=1, vjust=1)) + ylab("Percent of repertoire") + xlab("") + scale_y_continuous(labels=percent) + scale_color_brewer(palette="Set1") + geom_point(aes(color=SAMPLE), size=5, alpha=0.8) + facet_grid(. ~ ISOTYPE) plot(g3) ``` Instead of calculating abundance by sequence or clone count, abundance can be calculated using copy numbers for the individual sequences. This is accomplished by passing a copy number column to the `copy` argument (`copy="DUPCOUNT"`). Specifying both `clone` and `copy` arguments is not meaningful and will result in the `clone` argument being ignored. ```{r, eval=TRUE, warning=FALSE} # Calculate V family copy numbers by sample and isotype family <- countGenes(ExampleDb, gene="V_CALL", groups=c("SAMPLE", "ISOTYPE"), mode="family", copy="DUPCOUNT") head(family, n=4) ``` The output `data.frame` includes the `SEQ_COUNT` and `SEQ_FREQ` columns as previously defined, as well as the additional copy number columns `COPY_COUNT` and `COPY_FREQ` reflected the summed copy number (`DUPCOUNT`) for each sequence within the given `GENE`, `SAMPLE` and `ISOTYPE`. ```{r, eval=TRUE, warning=FALSE} # Subset to IgM and IgG for plotting family <- filter(family, ISOTYPE %in% c("IgM", "IgG")) # Plot V family copy abundance by sample and isotype g4 <- ggplot(family, aes(x=GENE, y=COPY_FREQ)) + theme_bw() + ggtitle("Copy Number") + theme(axis.text.x=element_text(angle=45, hjust=1, vjust=1)) + ylab("Percent of repertoire") + xlab("") + scale_y_continuous(labels=percent) + scale_color_brewer(palette="Set1") + geom_point(aes(color=SAMPLE), size=5, alpha=0.8) + facet_grid(. ~ ISOTYPE) plot(g4) ``` alakazam/vignettes/AminoAcids-Vignette.Rmd0000644000176200001440000001712713402556374020322 0ustar liggesusers--- title: 'Alakazam: Amino acid physicochemical property analysis' author: "Susanna Marquez" date: '`r Sys.Date()`' output: pdf_document: dev: pdf fig_height: 4 fig_width: 7.5 highlight: pygments toc: yes md_document: fig_height: 4 fig_width: 7.5 preserve_yaml: no toc: yes html_document: fig_height: 4 fig_width: 7.5 highlight: pygments theme: readable toc: yes geometry: margin=1in fontsize: 11pt vignette: > %\VignetteEngine{knitr::rmarkdown} %\VignetteIndexEntry{Amino acid property analysis} %\usepackage[utf8]{inputenc} --- The `alakazam` package includes a set of function to analyze the physicochemical properties of Ig and TCR amino acid sequences. Of particular interest is the analysis of CDR3 properties, which this vignette will demonstate. However, the same process can be applied to other regions simply by altering the sequence data column used. Wu YC, et al. High-throughput immunoglobulin repertoire analysis distinguishes between human IgM memory and switched memory B-cell populations. Blood 116, 1070-8 (2010). Wu YC, et al. The relationship between CD27 negative and positive B cell populations in human peripheral blood. Front Immunol 2, 1-12 (2011). ## Example data A small example Change-O database, `ExampleDb`, is included in the `alakazam` package. ```{r, eval=TRUE, warning=FALSE, message=FALSE} # Load required packages library(alakazam) library(dplyr) # Subset example data data(ExampleDb) db <- ExampleDb[ExampleDb$SAMPLE == "+7d", ] ``` ## Calculate the properties of amino acid sequences Multiple amino acid physicochemical properties can be obtained with the function `aminoAcidProperties`. The available properties are: * `length`: total amino acid count * `gravy`: grand average of hydrophobicity * `bulkiness`: average bulkiness * `polarity`: average polarity * `aliphatic`: normalized aliphatic index * `charge`: normalized net charge * `acidic`: acidic side chain content * `basic`: basic side chain residue content * `aromatic`: aromatic side chain content This example demonstrates how to calculate all of the available amino acid properties from DNA sequences found in `JUNCTION` column of the Change-O file previously loaded. Translation of the DNA sequences to amino acid sequences is accomplished by specifying the `nt=TRUE` argument. To reduce the junction sequence to the CDR3 sequence we specify the argument `trim=TRUE` which will strip the first and last codon (the conserved residues) prior to analysis. The prefix `CDR3` is added to the output column names using the `label="CDR3"` argument. ```{r, eval=TRUE, warning=FALSE, fig.width=7.5, fig.height=6} db_props <- aminoAcidProperties(db, seq="JUNCTION", nt=TRUE, trim=TRUE, label="CDR3") # The full set of properties are calculated by default dplyr::select(db_props[1:3, ], starts_with("CDR3")) # Define a ggplot theme for all plots tmp_theme <- theme_bw() + theme(legend.position="bottom") # Generate plots for a four of the properties g1 <- ggplot(db_props, aes(x=ISOTYPE, y=CDR3_AA_LENGTH)) + tmp_theme + ggtitle("CDR3 length") + xlab("Isotype") + ylab("Amino acids") + scale_fill_manual(name="Isotype", values=IG_COLORS) + geom_boxplot(aes(fill=ISOTYPE)) g2 <- ggplot(db_props, aes(x=ISOTYPE, y=CDR3_AA_GRAVY)) + tmp_theme + ggtitle("CDR3 hydrophobicity") + xlab("Isotype") + ylab("GRAVY") + scale_fill_manual(name="Isotype", values=IG_COLORS) + geom_boxplot(aes(fill=ISOTYPE)) g3 <- ggplot(db_props, aes(x=ISOTYPE, y=CDR3_AA_BASIC)) + tmp_theme + ggtitle("CDR3 basic residues") + xlab("Isotype") + ylab("Basic residues") + scale_y_continuous(labels=scales::percent) + scale_fill_manual(name="Isotype", values=IG_COLORS) + geom_boxplot(aes(fill=ISOTYPE)) g4 <- ggplot(db_props, aes(x=ISOTYPE, y=CDR3_AA_ACIDIC)) + tmp_theme + ggtitle("CDR3 acidic residues") + xlab("Isotype") + ylab("Acidic residues") + scale_y_continuous(labels=scales::percent) + scale_fill_manual(name="Isotype", values=IG_COLORS) + geom_boxplot(aes(fill=ISOTYPE)) # Plot in a 2x2 grid gridPlot(g1, g2, g3, g4, ncol=2) ``` ### Obtaining properties individually A subset of the properties may be calculated using the `property` argument of `aminoAcidProperties`. For example, calculations may be restricted to only the grand average of hydrophobicity (`gravy`) index and normalized net charge (`charge`) by specifying `property=c("gravy", "charge")`. ```{r, eval=TRUE, warning=FALSE} db_props <- aminoAcidProperties(db, seq="JUNCTION", property=c("gravy", "charge"), nt=TRUE, trim=TRUE, label="CDR3") dplyr::select(db_props[1:3, ], starts_with("CDR3")) ``` ### Using user defined scales Each property has a default scale setting, but users may specify alternate scales if they wish. The following example shows how to import and use the Kidera et al, 1985 hydrophobicity scale and the Murrary et al, 2006 pK values from the `seqinr` package instead of the defaults for calculating the GRAVY index and net charge. ```{r, eval=TRUE, warning=FALSE, message=FALSE} # Load the relevant data objects from the seqinr package library(seqinr) data(aaindex) data(pK) h <- aaindex[["KIDA850101"]]$I p <- setNames(pK[["Murray"]], rownames(pK)) # Rename the hydrophobicity vector to use single-letter codes names(h) <- translateStrings(names(h), ABBREV_AA) db_props <- aminoAcidProperties(db, seq="JUNCTION", property=c("gravy", "charge"), nt=TRUE, trim=TRUE, label="CDR3", hydropathy=h, pK=p) dplyr::select(db_props[1:3, ], starts_with("CDR3")) ``` ### Getting vectors of individual properties The `aminoAcidProperties` function provides a convenient wrapper for calculating multiple properties at once from a data.frame. If a vector of a specific property is required this may be accomplished using one of the worker functions: * `gravy`: grand average of hydrophobicity * `bulk`: average bulkiness * `polar`: average polarity * `aliphatic`: aliphatic index * `charge`: net charge * `countPatterns`: counts the occurrence of patterns in amino acid sequences The input to each function must be vector of amino acid sequences. ```{r, eval=TRUE, warning=FALSE, message=FALSE} # Translate junction DNA sequences to amino acids and trim first and last codons cdr3 <- translateDNA(db$JUNCTION[1:3], trim=TRUE) # Grand average of hydrophobicity gravy(cdr3) # Average bulkiness bulk(cdr3) # Average polarity polar(cdr3) # Normalized aliphatic index aliphatic(cdr3) # Unnormalized aliphatic index aliphatic(cdr3, normalize=FALSE) # Normalized net charge charge(cdr3) # Unnormalized net charge charge(cdr3, normalize=FALSE) # Count of acidic amino acids # Takes a named list of regular expressions countPatterns(cdr3, c(ACIDIC="[DE]"), label="CDR3") ``` ## Default scales The following references were used for the default physicochemical scales: * Aliphatic index: Ikai AJ. Thermostability and aliphatic index of globular proteins. J Biochem 88, 1895-1898 (1980). * Bulkiness scale: Zimmerman JM, Eliezer N, Simha R. The characterization of amino acid sequences in proteins by statistical methods. J Theor Biol 21, 170-201 (1968). * Hydrophobicity scale: Kyte J, Doolittle RF. A simple method for displaying the hydropathic character of a protein. J Mol Biol 157, 105-32 (1982). * pK values: \url{http://emboss.sourceforge.net/apps/cvs/emboss/apps/iep.html} * Polarity scale: Grantham R. Amino acid difference formula to help explain protein evolution. Science 185, 862-864 (1974). alakazam/vignettes/Lineage-Vignette.Rmd0000644000176200001440000002030713512442156017643 0ustar liggesusers--- title: 'Alakazam: Reconstruction of Ig lineage trees' author: "Jason Anthony Vander Heiden" date: '`r Sys.Date()`' output: pdf_document: dev: pdf fig_height: 4 fig_width: 7.5 highlight: pygments toc: yes html_document: fig_height: 4 fig_width: 7.5 highlight: pygments theme: readable toc: yes md_document: fig_height: 4 fig_width: 7.5 preserve_yaml: no toc: yes geometry: margin=1in fontsize: 11pt vignette: > %\VignetteEngine{knitr::rmarkdown} %\VignetteIndexEntry{Lineage reconstruction} %\usepackage[utf8]{inputenc} --- Reconstruction of an Ig lineage requires the following steps: 1. Load a Change-O tab-delimited database file and select a clone 2. Preprocess the clone to remove gap characters and duplicate sequences 3. Run PHYLIP, parse the output, and modify the tree topology ## Example data A small example Change-O database, `ExampleDb`, is included in the `alakazam` package. Lineage reconstruction requires the following fields (columns) to be present in the Change-O file: * `SEQUENCE_ID` * `SEQUENCE_IMGT` * `CLONE` * `GERMLINE_IMGT_D_MASK` * `V_CALL` * `J_CALL` * `JUNCTION_LENGTH` ```{r, eval=TRUE, warning=FALSE, message=FALSE} # Load required packages library(alakazam) library(igraph) library(dplyr) # Select clone from example database data(ExampleDb) sub_db <- subset(ExampleDb, CLONE == 3138) ``` ## Preprocess a clone Before a lineage can be constructed the sequences must first be cleaned of gap (-, .) characters added by IMGT, duplicate sequences must be removed, and annotations must be combined for each cluster of duplicate sequences. Optionally, "ragged" ends of sequences, such as may occur from primer template switching, may also be cleaned by masking mismatched positions and the leading and trailing ends of each sequence. The function `makeChangeoClone` is a wrapper function which combines these steps and returns a `ChangeoClone` object which may then be passed into the lineage reconstruction function. Two arguments to `makeChangeoClone` control which annotations are retained following duplicate removal. Unique values appearing within columns given by the `text_fields` arguments will be concatenated into a single string delimited by a "," character. Values appearing within columns given by the `num_fields` arguments will be summed. ```{r, eval=TRUE} # This example data set does not have ragged ends # Preprocess clone without ragged end masking (default) clone <- makeChangeoClone(sub_db, text_fields=c("SAMPLE", "ISOTYPE"), num_fields="DUPCOUNT") # Show combined annotations clone@data[, c("SAMPLE", "ISOTYPE", "DUPCOUNT")] ``` ## Run PHYLIP Lineage construction uses the `dnapars` (maximum parsimony) application of the PHYLIP package. The function `buildPhylipLineage` performs a number of steps to execute `dnapars`, parse its output, and modify the tree topology to meet the criteria of an Ig lineage. This function takes as input a `ChangeoClone` object output by `makeChangeoClone` and returns an igraph `graph` object. The igraph `graph` object will contain clone annotations as graph attributes, sequence annotations as vertex attributes, and mutations along edges as edge attributes. The system call to `dnapars` requires a temporary folder to store input and output. This is created in the system temporary location (according to `base::tempfile`), and is not deleted by default (only because automatically deleting files is somewhat rude). In most cases, you will want to set `rm_temp=TRUE` to delete this folder. ```{r, eval=FALSE} # Run PHYLIP and parse output dnapars_exec <- "~/apps/phylip-3.69/dnapars" graph <- buildPhylipLineage(clone, dnapars_exec, rm_temp=TRUE) ``` ```{r, echo=FALSE, warning=FALSE, message=FALSE} # Load data insted of running phylip # Clone 3138 is at index 23 graph <- ExampleTrees[[23]] ``` ```{r, eval=TRUE, warning=FALSE, message=FALSE} # The graph has shared annotations for the clone data.frame(CLONE=graph$clone, JUNCTION_LENGTH=graph$junc_len, V_GENE=graph$v_gene, J_GENE=graph$j_gene) # The vertices have sequence specific annotations data.frame(SEQUENCE_ID=V(graph)$name, ISOTYPE=V(graph)$ISOTYPE, DUPCOUNT=V(graph)$DUPCOUNT) ``` ## Plotting of the lineage tree Plotting of a lineage tree may be done using the built-in functions of the igraph package. The default edge and vertex labels are edge weights and sequence identifiers, respectively. ```{r, eval=TRUE} # Plot graph with defaults plot(graph) ``` The default layout and attributes are not very pretty. We can modify the graphical parameter in the usual igraph ways. A tree layout can be built using the `layout_as_tree` layout with assignment of the root position to the germline sequence, which is named "Germline" in the object returned by `buildPhylipLineage`. ```{r, eval=TRUE} # Modify graph and plot attributes V(graph)$color <- "steelblue" V(graph)$color[V(graph)$name == "Germline"] <- "black" V(graph)$color[grepl("Inferred", V(graph)$name)] <- "white" V(graph)$label <- V(graph)$ISOTYPE E(graph)$label <- "" # Remove large default margins par(mar=c(0, 0, 0, 0) + 0.1) # Plot graph plot(graph, layout=layout_as_tree, edge.arrow.mode=0, vertex.frame.color="black", vertex.label.color="black", vertex.size=40) # Add legend legend("topleft", c("Germline", "Inferred", "Sample"), fill=c("black", "white", "steelblue"), cex=0.75) ``` Which is much better. ## Batch processing lineage trees Multiple lineage trees may be generated at once, by splitting the Change-O data.frame on the clone column. ```{r, eval=TRUE, warning=FALSE, results="hide"} # Preprocess clones clones <- ExampleDb %>% group_by(CLONE) %>% do(CHANGEO=makeChangeoClone(., text_fields=c("SAMPLE", "ISOTYPE"), num_fields="DUPCOUNT")) ``` ```{r, eval=FALSE} # Build lineages dnapars_exec <- "~/apps/phylip-3.69/dnapars" graphs <- lapply(clones$CHANGEO, buildPhylipLineage, dnapars_exec=dnapars_exec, rm_temp=TRUE) ``` ```{r, echo=FALSE, warning=FALSE, message=FALSE} # Load data insted of running phylip graphs <- ExampleTrees ``` ```{r, eval=TRUE} # Note, clones with only a single sequence will not be processed. # A warning will be generated and NULL will be returned by buildPhylipLineage # These entries may be removed for clarity graphs[sapply(graphs, is.null)] <- NULL # The set of tree may then be subset by node count for further # analysis, if desired. graphs <- graphs[sapply(graphs, vcount) >= 5] ``` ## Converting between graph, phylo, and newick formats While much of analysis in `alakazam` focuses on using `igraph` `graph` objects, R `phylo` objects are capable of being used by a rich set of phylogenetic analysis tools in R. Further, stand-alone phylogenetics programs typically import and export trees in Newick format. To convert to trees in `graph` format to `phylo` format, use `graphToPhylo`. These objects can now be used by functions detailed in other R phylogenetics packages such as `ape`. To export lineage trees as a Newick file, use the `write.tree` function provided in `ape`. ```{r, eval=TRUE, show=FALSE} # Modify graph and plot attributes V(graph)$color <- categorical_pal(8)[1] V(graph)$label <- V(graph)$name E(graph)$label <- E(graph)$weight ``` ```{r, eval=TRUE, warning=FALSE, message=FALSE} ##plot lineage tree using igraph plot(graph, layout=layout_as_tree) # convert to phylo phylo <- graphToPhylo(graph) #plot using ape plot(phylo, show.node.label=TRUE) #write tree file in Newick format ape::write.tree(phylo, file="example.tree") ``` To import lineage trees as `phylo` objects from Newick files, use the `read.tree` function provided in the `ape` package. To convert this `phylo` object to a `graph` object, use the `phyloToGraph` function with the germline sequence ID specified using the `germline` option. Note that while some of the nodes in more complex trees may rotate during this process, their topological relationships will remain the same. ```{r, eval=TRUE} #read in tree as phylo object phylo_r <- ape::read.tree("example.tree") #convert to graph object graph_r <- phyloToGraph(phylo_r, germline="Germline") #plot converted form using igraph - it's the same as before plot(graph_r,layout=layout_as_tree) ``` alakazam/R/0000755000176200001440000000000013513671660012244 5ustar liggesusersalakazam/R/sysdata.rda0000644000176200001440000000176513402556374014416 0ustar liggesusersBZh91AY&SY,/h0 @!,F%(Tzjhf4&3@4ڞ44 4Pha$SSMMPh2djbd M0=@T|.fƣ)  O &p(.<' y94 C @_y!G#́) e*Ժ뼰V!/uXlsdiM@JM7ΰ՚pH͹Uv EI3NIA \Zi5Kv!mfJW18EbbvwI_H !.T.'x̜LEL$ yHI)DI|DdP$R I p'a1%-WIֹS˧D`4N\P؈GA50Ӊ.u:jǛ [zj bfBǗӺ!Fp`צGFfbu*,O,@2gB* 0) })) } #' Count sequence patterns #' #' \code{countPatterns} counts the fraction of times a set of character patterns occur #' in a set of sequences. #' #' @param seq character vector of either DNA or amino acid sequences. #' @param patterns list of sequence patterns to count in each sequence. If the #' list is named, then names will be assigned as the column names of #' output data.frame. #' @param nt if \code{TRUE} then \code{seq} are DNA sequences and and will be #' translated before performing the pattern search. #' @param trim if \code{TRUE} remove the first and last codon or amino acid from #' each sequence before the pattern search. If \code{FALSE} do #' not modify the input sequences. #' @param label string defining a label to add as a prefix to the output #' column names. #' #' @return A data.frame containing the fraction of times each sequence pattern was #' found. #' #' @examples #' seq <- c("TGTCAACAGGCTAACAGTTTCCGGACGTTC", #' "TGTCAGCAATATTATATTGCTCCCTTCACTTTC", #' "TGTCAAAAGTATAACAGTGCCCCCTGGACGTTC") #' patterns <- c("A", "V", "[LI]") #' names(patterns) <- c("ARG", "VAL", "ISO_LEU") #' countPatterns(seq, patterns, nt=TRUE, trim=TRUE, label="CDR3") #' #' @export countPatterns <- function(seq, patterns, nt=FALSE, trim=FALSE, label="REGION") { # Translate sequences if nucleotide region_aa <- if (nt) { translateDNA(seq, trim=trim) } else { seq } # TODO: Check that NA is passed through correctly. # TODO: What is the proper length normalization? With or without non-informative position? # Calculate region lengths aa_length <- stri_length(region_aa) # Count occurrence of each amino acid pattern for each sequence out_df <- data.frame(matrix(0, nrow=length(region_aa), ncol=length(patterns))) # If patterns are unnamed, make the names X1...Xn if(is.null(names(patterns))) { names(patterns) <- names(out_df) } # If region name, append to names of patterns if(label != '') { names(out_df) <- paste(label, names(patterns), sep="_") } else { names(out_df) <- names(patterns) } # Iterate over patterns for(i in 1:length(patterns)) { out_df[, i] <- countOccurrences(region_aa, patterns[i]) / aa_length } return(out_df) } #' Calculates amino acid chemical properties for sequence data #' #' \code{aminoAcidProperties} calculates amino acid sequence physicochemical properties, including #' length, hydrophobicity, bulkiness, polarity, aliphatic index, net charge, acidic residue #' content, basic residue content, and aromatic residue content. #' #' @param data \code{data.frame} containing sequence data. #' @param property vector strings specifying the properties to be calculated. Defaults #' to calculating all defined properties. #' @param seq \code{character} name of the column containing input #' sequences. #' @param nt boolean, TRUE if the sequences (or sequence) are DNA and will be translated. #' @param trim if \code{TRUE} remove the first and last codon/amino acids from each #' sequence before calculating properties. If \code{FALSE} do #' not modify input sequences. #' @param label name of sequence region to add as prefix to output column names. #' @param ... additional named arguments to pass to the functions #' \link{gravy}, \link{bulk}, \link{aliphatic}, \link{polar} or \link{charge}. #' #' @return A modified \code{data} data.frame with the following columns: #' \itemize{ #' \item \code{*_AA_LENGTH}: number of amino acids. #' \item \code{*_AA_GRAVY}: grand average of hydrophobicity (GRAVY) index. #' \item \code{*_AA_BULK}: average bulkiness of amino acids. #' \item \code{*_AA_ALIPHATIC}: aliphatic index. #' \item \code{*_AA_POLARITY}: average polarity of amino acids. #' \item \code{*_AA_CHARGE}: net charge. #' \item \code{*_AA_BASIC}: fraction of informative positions that are #' Arg, His or Lys. #' \item \code{*_AA_ACIDIC}: fraction of informative positions that are #' Asp or Glu. #' \item \code{*_AA_AROMATIC}: fraction of informative positions that are #' His, Phe, Trp or Tyr. #' #' } #' #' Where \code{*} is the value from \code{label} or the name specified for #' \code{seq} if \code{label=NULL}. #' #' @details #' For all properties except for length, non-informative positions are excluded, #' where non-informative is defined as any character in \code{c("X", "-", ".", "*")}. #' #' The scores for GRAVY, bulkiness and polarity are calculated as simple averages of the #' scores for each informative positions. The basic, acid and aromatic indices are #' calculated as the fraction of informative positions falling into the given category. #' #' The aliphatic index is calculated using the Ikai, 1980 method. #' #' The net charge is calculated using the method of Moore, 1985, excluding the N-terminus and #' C-terminus charges, and normalizing by the number of informative positions. The default #' pH for the calculation is 7.4. #' #' The following data sources were used for the default property scores: #' \itemize{ #' \item hydropathy: Kyte & Doolittle, 1982. #' \item bulkiness: Zimmerman et al, 1968. #' \item polarity: Grantham, 1974. #' \item pK: EMBOSS. #' } #' #' @references #' \enumerate{ #' \item Zimmerman JM, Eliezer N, Simha R. The characterization of amino acid sequences #' in proteins by statistical methods. J Theor Biol 21, 170-201 (1968). #' \item Grantham R. Amino acid difference formula to help explain protein evolution. #' Science 185, 862-864 (1974). #' \item Ikai AJ. Thermostability and aliphatic index of globular proteins. #' J Biochem 88, 1895-1898 (1980). #' \item Kyte J, Doolittle RF. A simple method for displaying the hydropathic character #' of a protein. J Mol Biol 157, 105-32 (1982). #' \item Moore DS. Amino acid and peptide net charges: A simple calculational procedure. #' Biochem Educ 13, 10-11 (1985). #' \item Wu YC, et al. High-throughput immunoglobulin repertoire analysis distinguishes #' between human IgM memory and switched memory B-cell populations. #' Blood 116, 1070-8 (2010). #' \item Wu YC, et al. The relationship between CD27 negative and positive B cell #' populations in human peripheral blood. #' Front Immunol 2, 1-12 (2011). #' \item \url{http://emboss.sourceforge.net/apps/cvs/emboss/apps/iep.html} #' } #' #' @seealso #' See \link{countPatterns} for counting the occurance of specific amino acid subsequences. #' See \link{gravy}, \link{bulk}, \link{aliphatic}, \link{polar} and \link{charge} for functions #' that calculate the included properties individually. #' #' @examples #' # Subset example data #' db <- ExampleDb[c(1,10,100), c("SEQUENCE_ID", "JUNCTION")] #' #' # Calculate default amino acid properties from amino acid sequences #' # Use a custom output column prefix #' db$JUNCTION_TRANS <- translateDNA(db$JUNCTION) #' aminoAcidProperties(db, seq="JUNCTION_TRANS", label="JUNCTION") # #' # Calculate default amino acid properties from DNA sequences #' aminoAcidProperties(db, seq="JUNCTION", nt=TRUE) #' #' # Use the Grantham, 1974 side chain volume scores from the seqinr package #' # Set pH=7.0 for the charge calculation #' # Calculate only average volume and charge #' # Remove the head and tail amino acids from the junction, thus making it the CDR3 #' library(seqinr) #' data(aaindex) #' x <- aaindex[["GRAR740103"]]$I #' # Rename the score vector to use single-letter codes #' names(x) <- translateStrings(names(x), ABBREV_AA) #' # Calculate properties #' aminoAcidProperties(db, property=c("bulk", "charge"), seq="JUNCTION", nt=TRUE, #' trim=TRUE, label="CDR3", bulkiness=x, pH=7.0) #' #' @export aminoAcidProperties <- function(data, property=c("length", "gravy", "bulk", "aliphatic","polarity","charge", "basic","acidic", "aromatic"), seq="JUNCTION", nt=FALSE, trim=FALSE, label=NULL, ...) { # Check arguments property <- match.arg(property, several.ok=TRUE) # Define the data.frame that will be returned with amino acid properties prop_colnames <- list( "length" = "AA_LENGTH", "gravy" = "AA_GRAVY", "bulk" = "AA_BULK", "aliphatic" = "AA_ALIPHATIC", "polarity" = "AA_POLARITY", "charge" = "AA_CHARGE", "basic" = "AA_BASIC", "acidic" = "AA_ACIDIC", "aromatic" = "AA_AROMATIC" ) # If no label, use sequence column name if (is.null(label)) { label <- seq } prop_colnames <- lapply(prop_colnames, function(x) { paste(label,x,sep="_") }) out_df <- data.frame(matrix(NA, nrow=nrow(data), ncol=length(property))) colnames(out_df) <- prop_colnames[property] # Check if out_df column names already existed in data # if yes, throw warning check <- checkColumns(data, colnames(out_df)) if (any(check == TRUE)) { warning("Duplicated columns found. Overwriting previous values.")} # Check input if (length(seq) > 1) { stop("You may specify only one sequence column; seq must be a vector of length 1.") } check <- checkColumns(data, seq) if (check != TRUE) { stop(check) } # Assign ellipsis arguments to correct function dots <- list(...) args_gravy <- dots[names(dots) %in% names(formals(gravy))] args_bulk <- dots[names(dots) %in% names(formals(bulk))] args_aliphatic <- dots[names(dots) %in% names(formals(aliphatic))] args_polar <- dots[names(dots) %in% names(formals(polar))] args_charge <- dots[names(dots) %in% names(formals(charge))] # Get sequence vector and translate if required region <- as.character(data[[seq]]) region_aa <- if (nt) { translateDNA(region, trim=trim) } else { region } ## Will retrieve properties for valid sequences only ## keep index to fill results data.frame valid_seq <- isValidAASeq(region_aa) if (any(valid_seq == F) ){ not_valid_num <- sum(!valid_seq) warning(paste0("Found ", not_valid_num , " sequences with non valid amino acid symbols")) } valid_seq_idx <- which(valid_seq) region_aa <- region_aa[valid_seq_idx] # Calculate region lengths if ("length" %in% property) { aa_length <- stri_length(region_aa) out_df[valid_seq_idx , prop_colnames$length] <- aa_length } # Average hydrophobicity if ("gravy" %in% property) { #aa_gravy <- gravy(region_aa, hydropathy) aa_gravy <- do.call('gravy', c(list(seq=region_aa), args_gravy)) out_df[valid_seq_idx , prop_colnames$gravy] <- aa_gravy } # Average bulkiness if ("bulk" %in% property) { #aa_bulk <- bulk(region_aa) aa_bulk <- do.call('bulk', c(list(seq=region_aa), args_bulk)) out_df[valid_seq_idx , prop_colnames$bulk] <- aa_bulk } if ("aliphatic" %in% property) { # Normalizes aliphatic index aa_aliphatic <- do.call('aliphatic', c(list(seq=region_aa), args_aliphatic)) out_df[valid_seq_idx , prop_colnames$aliphatic] <- aa_aliphatic } # Average polarity if ("polarity" %in% property) { #aa_polarity <- polar(region_aa) aa_polarity <- do.call('polar', c(list(seq=region_aa), args_polar)) out_df[valid_seq_idx , prop_colnames$polarity] <- aa_polarity } # Normalized net charge if ("charge" %in% property) { #aa_charge <- charge(region_aa) aa_charge <- do.call('charge', c(list(seq=region_aa), args_charge)) out_df[valid_seq_idx , prop_colnames$charge] <- aa_charge } # Count of informative positions aa_info <- stri_length(gsub("[X\\.\\*-]", "", region_aa)) # Fraction of amino acid that are basic if ("basic" %in% property) { aa_basic <- countOccurrences(region_aa, "[RHK]") / aa_info out_df[valid_seq_idx , prop_colnames$basic] <- aa_basic } # Fraction of amino acid that are acidic if ("acidic" %in% property) { aa_acidic <- countOccurrences(region_aa, "[DE]") / aa_info out_df[valid_seq_idx , prop_colnames$acidic] <- aa_acidic } # Count fraction of aa that are aromatic if ("aromatic" %in% property) { aa_aromatic <- countOccurrences(region_aa, "[FWHY]") / aa_info out_df[valid_seq_idx , prop_colnames$aromatic] <- aa_aromatic } data_cols <- colnames(data) %in% colnames(out_df) == FALSE return(cbind(data[, data_cols], out_df)) } alakazam/R/Sequence.R0000644000176200001440000010461513512442156014141 0ustar liggesusers# Common DNA, amino acid, and gene annotation operations for Alakazam #### Sequence distance functions #### #' Build a DNA distance matrix #' #' \code{getDNAMatrix} returns a Hamming distance matrix for IUPAC ambiguous #' DNA characters with modifications for gap, \code{c("-", ".")}, and missing, #' \code{c("?")}, character values. #' #' @param gap value to assign to characters in the set \code{c("-", ".")}. #' #' @return A \code{matrix} of DNA character distances with row and column names #' indicating the character pair. By default, distances will be either 0 #' (equivalent), 1 (non-equivalent or missing), or -1 (gap). #' #' @seealso Creates DNA distance matrix for \link{seqDist}. #' See \link{getAAMatrix} for amino acid distances. #' #' @examples #' # Set gap characters to Inf distance #' # Distinguishes gaps from Ns #' getDNAMatrix() #' #' # Set gap characters to 0 distance #' # Makes gap characters equivalent to Ns #' getDNAMatrix(gap=0) #' #' @export getDNAMatrix <- function(gap=-1) { # Define Hamming distance matrix sub_mat <- diag(18) colnames(sub_mat) <- rownames(sub_mat) <- c(names(IUPAC_DNA), c("-", ".", "?")) for (i in 1:length(IUPAC_DNA)) { for (j in i:length(IUPAC_DNA)) { sub_mat[i, j] <- sub_mat[j, i] <- any(IUPAC_DNA[[i]] %in% IUPAC_DNA[[j]]) } } # Add gap characters sub_mat[c("-", "."), c("-", ".")] <- 1 sub_mat[c("-", "."), 1:15] <- 1 - gap sub_mat[1:15, c("-", ".")] <- 1 - gap return(1 - sub_mat) } #' Build an AA distance matrix #' #' \code{getAAMatrix} returns a Hamming distance matrix for IUPAC ambiguous #' amino acid characters. #' #' @param gap value to assign to characters in the set \code{c("-", ".")}. #' #' @return A \code{matrix} of amino acid character distances with row and column names #' indicating the character pair. #' #' @seealso Creates an amino acid distance matrix for \link{seqDist}. #' See \link{getDNAMatrix} for nucleotide distances. #' #' @examples #' getAAMatrix() #' #' @export getAAMatrix <- function(gap=0) { # Define Hamming distance matrix sub_mat <- diag(27) colnames(sub_mat) <- rownames(sub_mat) <- c(names(IUPAC_AA), c("-", ".")) for (i in 1:length(IUPAC_AA)) { for (j in i:length(IUPAC_AA)) { sub_mat[i, j] <- sub_mat[j, i] <- any(IUPAC_AA[[i]] %in% IUPAC_AA[[j]]) } } # Add gap characters sub_mat[c("-", "."), c("-", ".")] <- 1 sub_mat[c("-", "."), c(1:27)] <- 1 - gap sub_mat[c(1:27), c("-", ".")] <- 1 - gap return(1 - sub_mat) } #### Sequence manipulation functions #### #' Translate nucleotide sequences to amino acids #' #' \code{translateDNA} translates nucleotide sequences to amino acid sequences. #' #' @param seq vector of strings defining DNA sequence(s) to be converted to translated. #' @param trim boolean flag to remove 3 nts from both ends of seq #' (converts IMGT junction to CDR3 region). #' #' @return A vector of translated sequence strings. #' #' @seealso \code{\link[seqinr]{translate}}. #' #' @examples #' # Translate a single sequence #' translateDNA("ACTGACTCGA") #' #' # Translate a vector of sequences #' translateDNA(ExampleDb$JUNCTION[1:3]) #' #' # Remove the first and last codon from the translation #' translateDNA(ExampleDb$JUNCTION[1:3], trim=TRUE) #' #' @export translateDNA <- function (seq, trim=FALSE) { # Function to translate a single string .translate <- function(x) { if (stri_length(x) >= 3) { stri_join(seqinr::translate(unlist(strsplit(x, "")), ambiguous=TRUE), collapse="") } else { NA } } # Remove 3 nucleotides from each end # Eg, "ACTGACTCGA" -> "GACT" (with "ACT" and "CGA" removed) if (trim) { seq <- substr(seq, 4, stri_length(seq) - 3) } # Replace gaps with N seq <- gsub("[-.]", "N", seq) # Apply translation aa <- sapply(seq, .translate, USE.NAMES=FALSE) return(aa) } #' Masks gap characters in DNA sequences #' #' \code{maskSeqGaps} substitutes gap characters, \code{c("-", ".")}, with \code{"N"} #' in a vector of DNA sequences. #' #' @param seq character vector of DNA sequence strings. #' @param mask_char character to use for masking. #' @param outer_only if \code{TRUE} replace only contiguous leading and trailing gaps; #' if \code{FALSE} replace all gap characters. #' #' @return A modified \code{seq} vector with \code{"N"} in place of \code{c("-", ".")} #' characters. #' #' @seealso See \link{maskSeqEnds} for masking ragged edges. #' #' @examples #' # Mask with Ns #' maskSeqGaps(c("ATG-C", "CC..C")) #' maskSeqGaps("--ATG-C-") #' maskSeqGaps("--ATG-C-", outer_only=TRUE) #' #' # Mask with dashes #' maskSeqGaps(c("ATG-C", "CC..C"), mask_char="-") #' #' @export maskSeqGaps <- function(seq, mask_char="N", outer_only=FALSE) { if (outer_only) { for (i in 1:length(seq)) { head_match <- attr(regexpr("^[-\\.]+", seq[i]), "match.length") tail_match <- attr(regexpr("[-\\.]+$", seq[i]), "match.length") if (head_match > 0) { seq[i] <- gsub("^[-\\.]+", paste(rep(mask_char, head_match), collapse=""), seq[i]) } if (tail_match > 0) { seq[i] <- gsub("[-\\.]+$", paste(rep(mask_char, tail_match), collapse=""), seq[i]) } } } else { seq <- gsub("[-\\.]", mask_char, seq) } return(seq) } #' Masks ragged leading and trailing edges of aligned DNA sequences #' #' \code{maskSeqEnds} takes a vector of DNA sequences, as character strings, #' and replaces the leading and trailing characters with \code{"N"} characters to create #' a sequence vector with uniformly masked outer sequence segments. #' #' @param seq character vector of DNA sequence strings. #' @param mask_char character to use for masking. #' @param max_mask the maximum number of characters to mask. If set to 0 then #' no masking will be performed. If set to \code{NULL} then the upper #' masking bound will be automatically determined from the maximum #' number of observed leading or trailing \code{"N"} characters amongst #' all strings in \code{seq}. #' @param trim if \code{TRUE} leading and trailing characters will be cut rather #' than masked with \code{"N"} characters. #' @return A modified \code{seq} vector with masked (or optionally trimmed) sequences. #' #' @seealso See \link{maskSeqGaps} for masking internal gaps. #' See \link{padSeqEnds} for padding sequence of unequal length. #' #' @examples #' # Default behavior uniformly masks ragged ends #' seq <- c("CCCCTGGG", "NAACTGGN", "NNNCTGNN") #' maskSeqEnds(seq) #' #' # Does nothing #' maskSeqEnds(seq, max_mask=0) #' #' # Cut ragged sequence ends #' maskSeqEnds(seq, trim=TRUE) #' #' # Set max_mask to limit extent of masking and trimming #' maskSeqEnds(seq, max_mask=1) #' maskSeqEnds(seq, max_mask=1, trim=TRUE) #' #' # Mask dashes instead of Ns #' seq <- c("CCCCTGGG", "-AACTGG-", "---CTG--") #' maskSeqEnds(seq, mask_char="-") #' #' @export maskSeqEnds <- function(seq, mask_char="N", max_mask=NULL, trim=FALSE) { # Find length of leading and trailing Ns left_lengths <- attr(regexpr(paste0("(^", mask_char, "*)"), seq, perl=T), "capture.length") right_lengths <- attr(regexpr(paste0("(", mask_char, "*$)"), seq, perl=T), "capture.length") # Mask to minimal inner sequence length left_mask <- min(max(left_lengths[, 1]), max_mask) right_mask <- min(max(right_lengths[, 1]), max_mask) seq_lengths <- stri_length(seq) if (trim) { seq <- substr(seq, left_mask + 1, seq_lengths - right_mask) } else { substr(seq, 0, left_mask) <- paste(rep(mask_char, left_mask), collapse='') substr(seq, seq_lengths - right_mask + 1, seq_lengths + 1) <- paste(rep(mask_char, right_mask), collapse='') } return(seq) } #' Pads ragged ends of aligned DNA sequences #' #' \code{padSeqEnds} takes a vector of DNA sequences, as character strings, #' and appends the ends of each sequence with an appropriate number of \code{"N"} #' characters to create a sequence vector with uniform lengths. #' #' @param seq character vector of DNA sequence strings. #' @param len length to pad to. Only applies if longer than the maximum length of #' the data in \code{seq}. #' @param start if \code{TRUE} pad the beginning of each sequence instead of the end. #' @param pad_char character to use for padding. #' #' @return A modified \code{seq} vector with padded sequences. #' #' @seealso See \link{maskSeqEnds} for creating uniform masking from existing masking. #' #' @examples #' # Default behavior uniformly pads ragged ends #' seq <- c("CCCCTGGG", "ACCCTG", "CCCC") #' padSeqEnds(seq) #' #' # Pad to fixed length #' padSeqEnds(seq, len=15) #' #' # Add padding to the beginning of the sequences instead of the ends #' padSeqEnds(seq, start=TRUE) #' padSeqEnds(seq, len=15, start=TRUE) #' #' @export padSeqEnds <- function(seq, len=NULL, start=FALSE, pad_char="N") { # Set length to max input length width <- max(stri_length(seq),len) # Pad if (!start) { seq <- stri_pad_right(seq, width=width, pad="N") } else { seq <- stri_pad_left(seq, width=width, pad="N") } return(seq) } #' Remove duplicate DNA sequences and combine annotations #' #' \code{collapseDuplicates} identifies duplicate DNA sequences, allowing for ambiguous #' characters, removes the duplicate entries, and combines any associated annotations. #' #' @param data data.frame containing Change-O columns. The data.frame #' must contain, at a minimum, a unique identifier column #' and a column containg a character vector of DNA sequences. #' @param id name of the column containing sequence identifiers. #' @param seq name of the column containing DNA sequences. #' @param text_fields character vector of textual columns to collapse. The textual #' annotations of duplicate sequences will be merged into a single #' string with each unique value alphabetized and delimited by #' \code{sep}. #' @param num_fields vector of numeric columns to collapse. The numeric annotations #' of duplicate sequences will be summed. #' @param seq_fields vector of nucletoide sequence columns to collapse. The sequence #' with the fewest numer of non-informative characters will be #' retained. Where a non-informative character is one of #' \code{c("N", "-", ".", "?")}. Note, this is distinct from the #' \code{seq} parameter which is used to determine duplicates. #' @param add_count if \code{TRUE} add the column \code{COLLAPSE_COUNT} that #' indicates the number of sequences that were collapsed to build #' each unique entry. #' @param ignore vector of characters to ignore when testing for equality. #' @param sep character to use for delimiting collapsed annotations in the #' \code{text_fields} columns. Defines both the input and output #' delimiter. #' @param dry if \code{TRUE} perform dry run. Only labels the sequences without #' collapsing them. #' @param verbose if \code{TRUE} report the number input, discarded and output #' sequences; if \code{FALSE} process sequences silently. #' #' @return A modified \code{data} data.frame with duplicate sequences removed and #' annotation fields collapsed if \code{dry=FALSE}. If \code{dry=TRUE}, #' sequences will be labeled with the collapse action, but the input will be #' otherwise unmodifed (see Details). #' #' @details #' \code{collapseDuplicates} identifies duplicate sequences in the \code{seq} column by #' testing for character identity, with consideration of IUPAC ambiguous nucleotide codes. #' A cluster of sequences are considered duplicates if they are all equivalent, and no #' member of the cluster is equivalent to a sequence in a different cluster. #' #' Textual annotations, specified by \code{text_fields}, are collapsed by taking the unique #' set of values within in each duplicate cluster and delimiting those values by \code{sep}. #' Numeric annotations, specified by \code{num_fields}, are collapsed by summing all values #' in the duplicate cluster. Sequence annotations, specified by \code{seq_fields}, are #' collapsed by retaining the first sequence with the fewest number of N characters. #' #' Columns that are not specified in either \code{text_fields}, \code{num_fields}, or #' \code{seq_fields} will be retained, but the value will be chosen from a random entry #' amongst all sequences in a cluster of duplicates. #' #' An ambiguous sequence is one that can be assigned to two different clusters, wherein #' the ambiguous sequence is equivalent to two sequences which are themselves #' non-equivalent. Ambiguous sequences arise due to ambiguous characters at positions that #' vary across sequences, and are discarded along with their annotations when \code{dry=FALSE}. #' Thus, ambiguous sequences are removed as duplicates of some sequence, but do not create a potential #' false-positive annotation merger. Ambiguous sequences are not included in the #' \code{COLLAPSE_COUNT} annotation that is added when \code{add_count=TRUE}. #' #' If \code{dry=TRUE} sequences will not be removed from the input. Instead, the following columns #' will be appended to the input defining the collapse action that would have been performed in the #' \code{dry=FALSE} case. #' #' \itemize{ #' \item \code{COLLAPSE_ID}: an identifer for the group of identical sequences. #' \item \code{COLLAPSE_CLASS}: string defining how the sequence matches to the other in the set. #' one of \code{"duplicated"} (has duplicates), #' \code{"unique"} (no duplicates), \code{"ambiguous_duplicate"} #' (no duplicates after ambiguous sequences are removed), #' or \code{"ambiguous"} (matches multiple non-duplicate sequences). #' \item \code{COLLAPSE_PASS}: \code{TRUE} for the sequences that would be retained. #' } #' #' @seealso Equality is tested with \link{seqEqual} and \link{pairwiseEqual}. #' For IUPAC ambiguous character codes see \link{IUPAC_DNA}. #' #' @examples #' # Example Change-O data.frame #' db <- data.frame(SEQUENCE_ID=LETTERS[1:4], #' SEQUENCE_IMGT=c("CCCCTGGG", "CCCCTGGN", "NAACTGGN", "NNNCTGNN"), #' TYPE=c("IgM", "IgG", "IgG", "IgA"), #' SAMPLE=c("S1", "S1", "S2", "S2"), #' COUNT=1:4, #' stringsAsFactors=FALSE) #' #' # Annotations are not parsed if neither text_fields nor num_fields is specified #' # The retained sequence annotations will be random #' collapseDuplicates(db, verbose=TRUE) #' #' # Unique text_fields annotations are combined into a single string with "," #' # num_fields annotations are summed #' # Ambiguous duplicates are discarded #' collapseDuplicates(db, text_fields=c("TYPE", "SAMPLE"), num_fields="COUNT", #' verbose=TRUE) #' #' # Use alternate delimiter for collapsing textual annotations #' collapseDuplicates(db, text_fields=c("TYPE", "SAMPLE"), num_fields="COUNT", #' sep="/", verbose=TRUE) #' #' # Add count of duplicates #' collapseDuplicates(db, text_fields=c("TYPE", "SAMPLE"), num_fields="COUNT", #' add_count=TRUE, verbose=TRUE) #' #' # Masking ragged ends may impact duplicate removal #' db$SEQUENCE_IMGT <- maskSeqEnds(db$SEQUENCE_IMGT) #' collapseDuplicates(db, text_fields=c("TYPE", "SAMPLE"), num_fields="COUNT", #' add_count=TRUE, verbose=TRUE) #' #' @export collapseDuplicates <- function(data, id="SEQUENCE_ID", seq="SEQUENCE_IMGT", text_fields=NULL, num_fields=NULL, seq_fields=NULL, add_count=FALSE, ignore=c("N", "-", ".", "?"), sep=",", dry=FALSE, verbose=FALSE) { # Stop if ids are not unique if (any(duplicated(data[[id]]))) { stop("All values in the id column are not unique") } # Verify column classes and exit if they are incorrect if (!is.null(text_fields)) { if (!all(sapply(subset(data, select=text_fields), is.character))) { stop("All text_fields columns must be of type 'character'") } } if (!is.null(num_fields)) { if (!all(sapply(subset(data, select=num_fields), is.numeric))) { stop("All num_fields columns must be of type 'numeric'") } } if (!is.null(seq_fields)) { if (!all(sapply(subset(data, select=seq_fields), is.character))) { stop("All seq_fields columns must be of type 'character'") } } seq_len <- stri_length(data[[seq]]) if (any(seq_len != seq_len[1])) { warning("All sequences are not the same length for data with first ", id, " = ", data[[id]][1]) } # Define verbose reporting function .printVerbose <- function(n_total, n_unique, n_discard) { cat(" FUNCTION> collapseDuplicates\n", sep="") cat(" FIRST_ID> ", data[[id]][1], "\n", sep="") cat(" TOTAL> ", n_total, "\n", sep="") cat(" UNIQUE> ", n_unique, "\n", sep="") cat("COLLAPSED> ", n_total - n_unique - n_discard, "\n", sep="") cat("DISCARDED> ", n_discard, "\n", sep="") cat("\n") } # Define function to count informative positions in sequences .informativeLength <- function(x) { stri_length(gsub("[N\\-\\.\\?]", "", x, perl=TRUE)) } # Initialize COLLAPSE_COUNT with 1 for each sequence if(add_count) { data[["COLLAPSE_COUNT"]] <- rep(1, nrow(data)) num_fields <- c(num_fields, "COLLAPSE_COUNT") } # Initialize dry run columns if (dry) { data$COLLAPSE_ID <- NA data$COLLAPSE_CLASS <- NA data$COLLAPSE_PASS <- TRUE } # Return input if there are no sequences to collapse nseq <- nrow(data) if (nseq <= 1) { if (verbose) { .printVerbose(nseq, 1, 0) } if (dry) { data$COLLAPSE_ID <- 1 data$COLLAPSE_CLASS <- "unique" data$COLLAPSE_PASS <- TRUE } return(data) } # Build distance matrix d_mat <- pairwiseEqual(data[[seq]]) colnames(d_mat) <- rownames(d_mat) <- data[[id]] # Return input if no sequences are equal if (!any(d_mat[lower.tri(d_mat, diag=F)])) { if (verbose) { .printVerbose(nseq, nseq, 0) } if (dry) { data$COLLAPSE_ID <- 1:nrow(data) data$COLLAPSE_CLASS <- "unique" data$COLLAPSE_PASS <- TRUE } return(data) } # Find sequences that will cluster ambiguously ambig_rows <- numeric() for (i in 1:nseq) { idx <- which(d_mat[i, ]) tmp_mat <- d_mat[idx, idx] if (!all(tmp_mat)) { ambig_rows <- append(ambig_rows, i) } } discard_count <- length(ambig_rows) if (dry & length(ambig_rows)>0) { data[["COLLAPSE_CLASS"]][ambig_rows] <- "ambiguous" data[["COLLAPSE_PASS"]][ambig_rows] <- FALSE } # Return single sequence if all sequence belong to ambiguous clusters if (discard_count == nrow(d_mat)) { inform_len <- data.frame(list("inform_len"=.informativeLength(data[[seq]]))) # For each ambiguous cluster, return the best sequence g <- igraph::simplify(igraph::graph_from_adjacency_matrix(d_mat)) inform_len$clusters <- igraph::components(g)$membership[data[[id]]] inform_len$select_id <- 1:nrow(inform_len) selected <- inform_len %>% dplyr::group_by(!!rlang::sym("clusters")) %>% dplyr::slice(which.max(!!rlang::sym("inform_len"))) %>% dplyr::ungroup() %>% dplyr::select(!!rlang::sym("select_id")) %>% unlist() if (verbose) { .printVerbose(nseq, 0, discard_count - 1) } if (dry) { data[["COLLAPSE_ID"]] <- inform_len$clusters data[["COLLAPSE_PASS"]][selected] <- TRUE } else { return(data[selected, ]) } } # Exclude ambiguous sequences from clustering if (!dry & discard_count > 0) { d_mat <- d_mat[-ambig_rows, -ambig_rows] data <- data[-ambig_rows,] } # Cluster remaining sequences into unique and duplicate sets dup_taxa <- list() uniq_taxa <- character() done_taxa <- character() taxa_names <- rownames(d_mat) collapse_id <- 1 for (taxa_i in 1:length(taxa_names)) { taxa <- taxa_names[taxa_i] # Skip taxa if previously assigned to a cluster # or if ambiguous # (ambiguous taxa don't get their own COLLAPSE_ID) if (taxa %in% done_taxa) { next } if (dry & taxa_i %in% ambig_rows) { next } # Find all zero distance taxa idx <- which(d_mat[taxa, ]) # Update vector of clustered taxa done_taxa <- c(done_taxa, taxa_names[idx]) # Update collapse group if (dry) { data[["COLLAPSE_ID"]][idx] <- paste(data[["COLLAPSE_ID"]][idx], collapse_id, sep=",") } if (dry) { idx_copy <- idx idx <- idx[idx %in% ambig_rows == FALSE] } if (length(idx) == 1) { # Assign unique sequences to unique vector uniq_taxa <- append(uniq_taxa, taxa_names[idx]) if (dry) { if (length(idx_copy)==1) { ## 'truly' unique data[["COLLAPSE_CLASS"]][taxa_i] <- "unique" } else { ## unique after ambiguous removal data[["COLLAPSE_CLASS"]][taxa_i] <- "ambiguous_duplicate" } data[["COLLAPSE_PASS"]][taxa_i] <- TRUE } } else if (length(idx) > 1) { # Assign clusters of duplicates to duplicate list dup_taxa <- c(dup_taxa, list(taxa_names[idx])) if (dry) { # Keep COLLAPSE_PASS==TRUE for the sequence with the # larger number of informative positions # (the first one if ties) max_info_idx <- which.max(.informativeLength(data[[seq]][idx]))[1] data[["COLLAPSE_CLASS"]][idx] <- "duplicated" data[["COLLAPSE_PASS"]][idx[-max_info_idx]] <- FALSE } } else { # Report error (should never occur) stop("Error in distance matrix of collapseDuplicates") } collapse_id <- collapse_id + 1 } if (dry) { data[["COLLAPSE_ID"]] <- sub("^NA,","",data[["COLLAPSE_ID"]]) return(data) } # Collapse duplicate sets and append entries to unique data.frame unique_list <- list(data[data[[id]] %in% uniq_taxa, ]) for (taxa in dup_taxa) { # Define row indices of identical sequences idx <- which(data[[id]] %in% taxa) tmp_df <- data[idx[1], ] if (length(idx) > 1) { # Initialize with data from most informative sequence seq_set <- data[idx, c(id, seq)] inform_len <- .informativeLength(seq_set[[seq]]) max_inform <- which.max(inform_len)[1] # if ties, pick first tmp_df <- data[idx[max_inform], ] # Define set of text fields for row for (f in text_fields) { f_set <- na.omit(data[[f]][idx]) if (length(f_set) > 0) { f_set <- unlist(strsplit(f_set, sep)) f_set <- sort(unique(f_set)) f_val <- paste(f_set, collapse=sep) } else { f_val <- NA } tmp_df[, f] <- f_val } # Sum numeric fields for (f in num_fields) { f_set <- na.omit(data[[f]][idx]) if (length(f_set) > 0) { f_val <- sum(f_set) } else { f_val <- NA } tmp_df[, f] <- f_val } # Select sequence fields with fewest Ns for (f in seq_fields) { f_set <- na.omit(data[[f]][idx]) if (length(f_set) > 0) { f_len <- .informativeLength(f_set) f_val <- f_set[which.max(f_len)] } else { f_val <- NA } tmp_df[, f] <- f_val } } # Add row to unique list unique_list <- c(unique_list, list(tmp_df)) } # Combine all rows into unique data.frame unique_df <- as.data.frame(bind_rows(unique_list)) if (verbose) { .printVerbose(nseq, nrow(unique_df), discard_count) } return(unique_df) } #### Annotation functions #### #' Extracts FWRs and CDRs from IMGT-gapped sequences #' #' \code{extractVRegion} extracts the framework and complementarity determining regions of #' the V segment for IMGT-gapped immunoglobulin (Ig) nucleotide sequences according to the #' IMGT numbering scheme. #' #' @param sequences character vector of IMGT-gapped nucleotide sequences. #' @param region string defining the region(s) of the V segment to extract. #' May be a single region or multiple regions (as a vector) from #' \code{c("FWR1", "CDR1", "FWR2", "CDR2" ,"FWR3")}. By default, all #' regions will be returned. #' #' @return If only one region is specified in the \code{region} argument, a character #' vector of the extracted sub-sequences will be returned. If multiple regions #' are specified, then a character matrix will be returned with columns #' corresponding to the specified regions and a row for each entry in #' \code{sequences}. #' #' @seealso IMGT-gapped region boundaries are defined in \link{IMGT_REGIONS}. #' #' @references #' \enumerate{ #' \item Lefranc M-P, et al. IMGT unique numbering for immunoglobulin and T cell #' receptor variable domains and Ig superfamily V-like domains. #' Dev Comp Immunol. 2003 27(1):55-77. #' } #' #' @examples #' # Assign example clone #' clone <- subset(ExampleDb, CLONE == 3138) #' #' # Get all regions #' extractVRegion(clone$SEQUENCE_IMGT) #' #' # Get single region #' extractVRegion(clone$SEQUENCE_IMGT, "FWR1") #' #' # Get all CDRs #' extractVRegion(clone$SEQUENCE_IMGT, c("CDR1", "CDR2")) #' #' # Get all FWRs #' extractVRegion(clone$SEQUENCE_IMGT, c("FWR1", "FWR2", "FWR3")) #' #' @export extractVRegion <- function(sequences, region=c("FWR1", "CDR1", "FWR2", "CDR2", "FWR3")) { # Check region argument region <- match.arg(region, several.ok=TRUE) if (length(region) == 1) { sub_sequences <- substr(sequences, IMGT_REGIONS[[region]][1], IMGT_REGIONS[[region]][2]) } else { sub_sequences <- sapply(region, function(x) substr(sequences, IMGT_REGIONS[[x]][1], IMGT_REGIONS[[x]][2])) } return(sub_sequences) } #### Rcpp distance wrappers #### #' Calculate distance between two sequences #' #' \code{seqDist} calculates the distance between two DNA sequences. #' #' @param seq1 character string containing a DNA sequence. #' @param seq2 character string containing a DNA sequence. #' @param dist_mat Character distance matrix. Defaults to a Hamming distance #' matrix returned by \link{getDNAMatrix}. If gap #' characters, \code{c("-", ".")}, are assigned a value of -1 #' in \code{dist_mat} then contiguous gaps of any run length, #' which are not present in both sequences, will be counted as a #' distance of 1. Meaning, indels of any length will increase #' the sequence distance by 1. Gap values other than -1 will #' return a distance that does not consider indels as a special case. #' #' @return Numerical distance between \code{seq1} and \code{seq2}. #' #' @seealso Nucleotide distance matrix may be built with #' \link{getDNAMatrix}. Amino acid distance matrix may be built #' with \link{getAAMatrix}. Used by \link{pairwiseDist} for generating #' distance matrices. See \link{seqEqual} for testing sequence equivalence. #' #' @examples #' # Ungapped examples #' seqDist("ATGGC", "ATGGG") #' seqDist("ATGGC", "ATG??") #' #' # Gaps will be treated as Ns with a gap=0 distance matrix #' seqDist("ATGGC", "AT--C", dist_mat=getDNAMatrix(gap=0)) #' #' # Gaps will be treated as universally non-matching characters with gap=1 #' seqDist("ATGGC", "AT--C", dist_mat=getDNAMatrix(gap=1)) #' #' # Gaps of any length will be treated as single mismatches with a gap=-1 distance matrix #' seqDist("ATGGC", "AT--C", dist_mat=getDNAMatrix(gap=-1)) #' #' # Gaps of equivalent run lengths are not counted as gaps #' seqDist("ATG-C", "ATG-C", dist_mat=getDNAMatrix(gap=-1)) #' #' # Overlapping runs of gap characters are counted as a single gap #' seqDist("ATG-C", "AT--C", dist_mat=getDNAMatrix(gap=-1)) #' seqDist("A-GGC", "AT--C", dist_mat=getDNAMatrix(gap=-1)) #' seqDist("AT--C", "AT--C", dist_mat=getDNAMatrix(gap=-1)) #' #' # Discontiguous runs of gap characters each count as separate gaps #' seqDist("-TGGC", "AT--C", dist_mat=getDNAMatrix(gap=-1)) #' #' @export seqDist <- function(seq1, seq2, dist_mat=getDNAMatrix()) { seqDistRcpp(seq1, seq2, dist_mat) } #' Calculate pairwise distances between sequences #' #' \code{pairwiseDist} calculates all pairwise distance between a set of sequences. #' #' @param seq character vector containing a DNA sequences. #' @param dist_mat Character distance matrix. Defaults to a Hamming distance #' matrix returned by \link{getDNAMatrix}. If gap #' characters, \code{c("-", ".")}, are assigned a value of -1 #' in \code{dist_mat} then contiguous gaps of any run length, #' which are not present in both sequences, will be counted as a #' distance of 1. Meaning, indels of any length will increase #' the sequence distance by 1. Gap values other than -1 will #' return a distance that does not consider indels as a special case. #' #' @return A matrix of numerical distance between each entry in \code{seq}. #' If \code{seq} is a named vector, row and columns names will be added #' accordingly. #' #' Amino acid distance matrix may be built with \link{getAAMatrix}. #' Uses \link{seqDist} for calculating distances between pairs. #' See \link{pairwiseEqual} for generating an equivalence matrix. #' #' @examples #' # Gaps will be treated as Ns with a gap=0 distance matrix #' pairwiseDist(c(A="ATGGC", B="ATGGG", C="ATGGG", D="AT--C"), #' dist_mat=getDNAMatrix(gap=0)) #' #' # Gaps will be treated as universally non-matching characters with gap=1 #' pairwiseDist(c(A="ATGGC", B="ATGGG", C="ATGGG", D="AT--C"), #' dist_mat=getDNAMatrix(gap=1)) #' #' # Gaps of any length will be treated as single mismatches with a gap=-1 distance matrix #' pairwiseDist(c(A="ATGGC", B="ATGGG", C="ATGGG", D="AT--C"), #' dist_mat=getDNAMatrix(gap=-1)) #' #' @export pairwiseDist <- function(seq, dist_mat=getDNAMatrix()) { pairwiseDistRcpp(seq, dist_mat) } #' Calculate pairwise distances between sequences #' #' \code{nonsquareDist} calculates all pairwise distance between a set of sequences and a subset of it. #' #' @param seq character vector containing a DNA sequences. The sequence vector needs to #' be named. #' @param indx numeric vector contating the indices (a subset of indices of \code{seq}). #' @param dist_mat Character distance matrix. Defaults to a Hamming distance #' matrix returned by \link{getDNAMatrix}. If gap #' characters, \code{c("-", ".")}, are assigned a value of -1 #' in \code{dist_mat} then contiguous gaps of any run length, #' which are not present in both sequences, will be counted as a #' distance of 1. Meaning, indels of any length will increase #' the sequence distance by 1. Gap values other than -1 will #' return a distance that does not consider indels as a special case. #' #' @return A matrix of numerical distance between each entry in \code{seq} and #' sequences specified by \code{indx} indices. #' #' Note that the input subsampled indices will be ordered ascendingly. Therefore, #' it is necassary to assign unique names to the input sequences, \code{seq}, #' to recover the input order later. Row and columns names will be added accordingly. #' #' Amino acid distance matrix may be built with \link{getAAMatrix}. #' Uses \link{seqDist} for calculating distances between pairs. #' See \link{pairwiseEqual} for generating an equivalence matrix. #' #' @examples #' # Gaps will be treated as Ns with a gap=0 distance matrix #' seq <- c(A="ATGGC", B="ATGGG", C="ATGGG", D="AT--C") #' pairwiseDist(seq, #' dist_mat=getDNAMatrix(gap=0)) #' #' nonsquareDist(seq, indx=c(1,3), #' dist_mat=getDNAMatrix(gap=0)) #' #' @export nonsquareDist <- function(seq, indx, dist_mat=getDNAMatrix()) { nonsquareDistRcpp(seq, indx, dist_mat) }alakazam/R/Core.R0000644000176200001440000003612713512442156013263 0ustar liggesusers# Common input/output and data structure manipulation functions for Alakazam #### File I/O functions #### #' Read a Change-O tab-delimited database file #' #' \code{readChangeoDb} reads a tab-delimited database file created by a Change-O tool #' into a data.frame. #' #' @param file tab-delimited database file output by a Change-O tool. #' @param select columns to select from database file. #' @param drop columns to drop from database file. #' @param seq_upper if \code{TRUE} convert sequence columns to upper case; #' if \code{FALSE} do not alter sequence columns. See Value #' for a list of which columns are effected. #' #' @return A data.frame of the database file. Columns will be imported as is, except for #' the following columns which will be explicitly converted into character #' values: #' \itemize{ #' \item SEQUENCE_ID #' \item CLONE #' \item SAMPLE #' } #' And the following sequence columns which will converted to upper case if #' \code{seq_upper=TRUE} (default). #' \itemize{ #' \item SEQUENCE_INPUT #' \item SEQUENCE_VDJ #' \item SEQUENCE_IMGT #' \item JUNCTION #' \item GERMLINE_IMGT #' \item GERMLINE_IMGT_D_MASK #' } #' #' @seealso Wraps \link[readr]{read_delim}. #' See \link{writeChangeoDb} for writing to Change-O files. #' #' @examples #' \dontrun{ #' # Read all columns in and convert sequence fields to upper case #' db <- readChangeoDb("changeo.tsv") #' #' # Subset columns and convert sequence fields to upper case #' db <- readChangeoDb("changeo.tsv", select=c("SEQUENCE_ID", "SEQUENCE_IMGT")) #' #' # Drop columns and do not alter sequence field case #' db <- readChangeoDb("changeo.tsv", drop=c("D_CALL", "DUPCOUNT"), #' seq_upper=FALSE) #' } #' #' @export readChangeoDb <- function(file, select=NULL, drop=NULL, seq_upper=TRUE) { # Define column data types seq_columns <- c("SEQUENCE_INPUT", "SEQUENCE_VDJ", "SEQUENCE_IMGT", "JUNCTION", "JUNCTION_AA", "CDR3_IGBLAST_NT", "CDR3_IGBLAST_AA", "GERMLINE_VDJ", "GERMLINE_VDJ_V_REGION", "GERMLINE_VDJ_D_MASK", "GERMLINE_IMGT", "GERMLINE_IMGT_V_REGION", "GERMLINE_IMGT_D_MASK", "FWR1_IMGT", "FWR2_IMGT", "FWR3_IMGT", "FWR4_IMGT", "CDR1_IMGT", "CDR2_IMGT", "CDR3_IMGT") # Define types header <- names(suppressMessages(readr::read_tsv(file, n_max=1))) types <- do.call(readr::cols, CHANGEO[intersect(names(CHANGEO), header)]) # Read file db <- suppressMessages(readr::read_tsv(file, col_types=types, na=c("", "NA", "None"))) # Select columns select_columns <- colnames(db) if(!is.null(select)) { select_columns <- intersect(select_columns, select) } if(!is.null(drop)) { select_columns <- setdiff(select_columns, drop) } db <- select(db, select_columns) # Convert sequence fields to upper case upper_cols <- intersect(seq_columns, names(db)) if (seq_upper & length(upper_cols) > 0) { db <- mutate_at(db, upper_cols, toupper) } return(db) } #' Write a Change-O tab-delimited database file #' #' \code{writeChangeoDb} is a simple wrapper around \link[readr]{write_delim} with defaults #' appropriate for writing a Change-O tab-delimited database file from a data.frame. #' #' @param data data.frame of Change-O data. #' @param file output file name. #' #' @return NULL #' #' @seealso Wraps \link[readr]{write_delim}. See \link{readChangeoDb} for reading to Change-O files. #' #' @examples #' \dontrun{ #' # Write a database #' writeChangeoDb(data, "changeo.tsv") #' } #' #' @export writeChangeoDb <- function(data, file) { write_tsv(data, file, na="NA") } #' Create a temporary folder #' #' \code{makeTempDir} creates a randomly named temporary folder in the #' system temp location. #' #' @param prefix prefix name for the folder. #' #' @return The path to the temporary folder. #' #' @seealso This is just a wrapper for \link{tempfile} and #' \link{dir.create}. #' #' @examples #' makeTempDir("Clone50") #' #' @export makeTempDir <- function(prefix) { temp_path <- tempfile(paste0(prefix, "-temp-")) dir.create(temp_path) return(temp_path) } #### Data manipulation functions #### #' Translate a vector of strings #' #' \code{translateStrings} modifies a character vector by substituting one or more #' strings with a replacement string. #' #' @param strings vector of character strings to modify. #' @param translation named character vector or a list of character vectors specifying #' the strings to replace (values) and their replacements (names). #' #' @return A modified \code{strings} vector. #' #' @details #' Does not perform partial replacements. Each translation value must match a complete #' \code{strings} value or it will not be replaced. Values that do not have a replacement #' named in the \code{translation} parameter will not be modified. #' #' Replacement is accomplished using \link{gsub}. #' #' @seealso See \link{gsub} for single value replacement in the base package. #' #' @examples #' # Using a vector translation #' strings <- LETTERS[1:5] #' translation <- c("POSITION1"="A", "POSITION5"="E") #' translateStrings(strings, translation) #' #' # Using a list translation #' strings <- LETTERS[1:5] #' translation <- list("1-3"=c("A","B","C"), "4-5"=c("D","E")) #' translateStrings(strings, translation) #' #' @export translateStrings <- function(strings, translation) { # TODO: use match instead for complete matching? Currently regex characters in values will mess up the matching. for (n in names(translation)) { rep_regex <- paste(translation[[n]], collapse='|') strings <- gsub(paste0("^(", rep_regex, ")$"), n, strings) } return(strings) } #' Check data.frame for valid columns and issue message if invalid #' #' @param data data.frame to check. #' @param columns vector of column names to check. #' @param logic one of \code{"all"} or \code{"any"} controlling whether all, #' or at least one, of the columns must be valid, respectively. #' @return \code{TRUE} if columns are valid and a string message if not. # #' @examples #' df <- data.frame(A=1:3, B=4:6, C=rep(NA, 3)) #' checkColumns(df, c("A", "B"), logic="all") #' checkColumns(df, c("A", "B"), logic="any") #' checkColumns(df, c("A", "C"), logic="all") #' checkColumns(df, c("A", "C"), logic="any") #' checkColumns(df, c("A", "D"), logic="all") #' checkColumns(df, c("A", "D"), logic="any") #' #' @export checkColumns <- function(data, columns, logic=c("all", "any")) { ## DEBUG # data=df; columns=c("A", "D"); logic="any" # Check arguments logic <- match.arg(logic) data_names <- names(data) if (logic == "all") { # Check that all columns exist for (f in columns) { if (!(f %in% data_names)) { msg <- paste("The column", f, "was not found") return(msg) } } # Check that all values are not NA for (f in columns) { if (all(is.na(data[[f]]))) { msg <- paste("The column", f, "contains no data") return(msg) } } } else if (logic == "any") { # Check that columns exist if (!any(columns %in% data_names)) { msg <- paste("Input must contain at least one of the columns:", paste(columns, collapse=", ")) return(msg) } # Check that all values are not NA columns_found <- columns[columns %in% data_names] invalid <- sapply(columns_found, function(f) all(is.na(data[[f]]))) if (all(invalid)) { msg <- paste("None of the columns", paste(columns_found, collapse=", "), "contain data") return(msg) } } # Return TRUE if all checks pass return(TRUE) } #### Plotting and progress functions #### #' Standard progress bar #' #' \code{progressBar} defines a common progress bar format. #' #' @param n maximum number of ticks #' #' @return A \link[progress]{progress_bar} object. #' #' @export progressBar <- function(n) { pb <- progress::progress_bar$new(format=" PROGRESS> [:bar] :percent :elapsed", width=40, clear=FALSE, stream=stdout(), force=TRUE, total=n) return(pb) } #' Standard ggplot settings #' #' \code{baseTheme} defines common ggplot theme settings for plotting. #' #' @param sizing defines the style and sizing of the theme. One of #' \code{c("figure", "window")} where \code{sizing="figure"} is appropriately #' sized for pdf export at 7 to 7.5 inch width, and \code{sizing="window"} #' is sized for an interactive session. #' #' @return A ggplot2 object. #' #' @seealso \link[ggplot2]{theme}. #' #' @export baseTheme <- function(sizing=c("figure", "window")) { # Check arguments sizing <- match.arg(sizing) # Define universal plot settings appropriate for PDF figures if (sizing == "figure") { base_theme <- theme_bw() + theme(text=element_text(size=8)) + theme(plot.title=element_text(size=8)) + theme(plot.background=element_blank(), panel.grid.major=element_blank(), panel.grid.minor=element_blank()) + theme(strip.background=element_blank(), strip.text=element_text(size=7, face='bold')) + theme(axis.title=element_text(size=8, vjust=0.25), axis.text.x=element_text(size=8, vjust=0.5, hjust=0.5), axis.text.y=element_text(size=8)) + theme(legend.text=element_text(size=7), legend.title=element_text(size=7), legend.key.height=grid::unit(10, "points"), legend.key.width=grid::unit(10, "points")) } else if (sizing == "window") { # Define universal plot settings appropriate for an interactive session base_theme <- theme_bw() + theme(text=element_text(size=14)) + theme(plot.title=element_text(size=16)) + theme(strip.background=element_rect(fill='white'), strip.text=element_text(size=14, face='bold')) + theme(axis.title=element_text(size=16, vjust=0.25), axis.text.x=element_text(size=16, vjust=0.5, hjust=0.5), axis.text.y=element_text(size=16)) + theme(legend.text=element_text(size=14), legend.title=element_text(size=14), legend.key.height=grid::unit(18, "points"), legend.key.width=grid::unit(18, "points")) } return(base_theme) } #' Plot multiple ggplot objects #' #' Plots multiple ggplot objects in an equally sized grid. #' #' @param ... ggplot objects to plot. #' @param ncol number of columns in the plot. #' @return NULL #' #' @seealso \link{ggplot}. #' #' @references #' Modified from: #' http://www.cookbook-r.com/Graphs/Multiple_graphs_on_one_page_(ggplot2) #' #' @export gridPlot <- function(..., ncol=1) { p <- list(...) n <- length(p) layout <- matrix(seq(1, ncol*ceiling(n/ncol)), ncol=ncol, nrow=ceiling(n/ncol)) # Plot if (n == 1) { plot(p[[1]]) } else { grid::grid.newpage() grid::pushViewport(grid::viewport(layout=grid::grid.layout(nrow(layout), ncol(layout)))) for (i in 1:n) { idx <- as.data.frame(which(layout == i, arr.ind=T)) plot(p[[i]], vp=grid::viewport(layout.pos.row = idx$row, layout.pos.col=idx$col)) } } } #### Multiprocessing functions #### #' Available CPU cores #' #' \code{cpuCount} determines the number of CPU cores available. #' #' @return Count of available cores. Returns 1 if undeterminable. #' #' @examples #' cpuCount() #' #' @export cpuCount <-function(){ if (.Platform$OS.type == "windows") { nproc <- as.numeric(Sys.getenv('NUMBER_OF_PROCESSORS')) } else if (.Platform$OS.type == "unix") { nproc <- parallel::detectCores() } else { nproc <- 1 } return(nproc) } #### Generic statistical functions #### #' Weighted meta-analysis of p-values via Stouffer's method #' #' \code{stoufferMeta} combines multiple weighted p-values into a meta-analysis p-value #' using Stouffer's Z-score method. #' #' @param p numeric vector of p-values. #' @param w numeric vector of weights. #' #' @return A named numeric vector with the combined Z-score and p-value in the form #' \code{c(Z, pvalue)}. #' #' @examples #' # Define p-value and weight vectors #' p <- c(0.1, 0.05, 0.3) #' w <- c(5, 10, 1) #' #' # Unweighted #' stoufferMeta(p) #' #' # Weighted #' stoufferMeta(p, w) #' #' @export stoufferMeta <- function(p, w=NULL) { if (is.null(w)) { w <- rep(1, length(p))/length(p) } else { if (length(w) != length(p)) { stop("Length of p and w must equal.") } w <- w/sum(w) } x <- qnorm(1 - p) Z <- sum(w*x) / sqrt(sum(w^2)) pvalue <- 1 - pnorm(Z) return(c(Z=Z, pvalue=pvalue)) } # Stirling's approximation of the binomial coefficient # # Calculates Stirling's approximation of the binomial coefficient for large numbers. # # @param n a vector of n. # @param k a vector of k. # # @return The approximation of log(n choose k). For n < 100 \link{lchoose} is used. lchooseStirling <- function(n, k) { if (any(n < k)) { stop("n must be >= k") } n_len <- length(n) k_len <- length(k) nCk <- rep(NA, max(n_len, k_len)) nCk[n == k] <- 0 # a = index n_small # i = index k_small # x = index nCk_small # # b = index n_large # j = index k_large # y = index nCk_large # # Check for vector inputs and assign indexing if (n_len >= 1 & k_len >= 1 & n_len == k_len) { a <- i <- x <- (n < 100 & n != k) b <- j <- y <- (n >= 100 & n != k) } else if (n_len > 1 & k_len == 1) { a <- x <- (n < 100 & n != k) b <- y <- (n >= 100 & n != k) i <- j <- TRUE } else if (n_len == 1 & k_len > 1) { a <- (n < 100) b <- !a i <- j <- (n != k) x <- if (n < 100) { i } else { NULL } y <- if (n >= 100) { i } else { NULL } } else { stop("Inputs are wrong. n and k must have the same length or be length one.") } # Small n nCk[x] <- lchoose(n[a], k[i]) # Large n indices nCk[y] <- n[b]*log(n[b]) - k[j]*log(k[j]) - (n[b] - k[j])*log(n[b] - k[j]) + 0.5*(log(n[b]) - log(k[j]) - log(n[b] - k[j]) - log(2*pi)) # .nCk <- function(n, k) { # n*log(n) - k*log(k) - (n - k)*log(n - k) + # 0.5*(log(n) - log(k) - log(n - k) - log(2*pi)) # } return(nCk) } alakazam/R/Alakazam.R0000644000176200001440000001633513513133604014107 0ustar liggesusers# Alakazam package documentation and import directives #' The alakazam package #' #' \code{alakazam} in a member of the Change-O suite of tools and serves five main #' purposes: #' \itemize{ #' \item Providing core functionality for other R packages in the Change-O suite. This #' includes common tasks such as file I/O, basic DNA sequence manipulation, and #' interacting with V(D)J segment and gene annotations. #' \item Providing an R interface for interacting with the output of the pRESTO #' tool suite. #' \item Performing lineage reconstruction on clonal populations of immunoglobulin #' (Ig) sequences. #' \item Performing clonal abundance and diversity analysis on lymphocyte repertoires. #' \item Performing physicochemical property analyses of lymphocyte receptor sequences. #' } #' For additional details regarding the use of the \code{alakazam} package see the #' vignettes:\cr #' \code{browseVignettes("alakazam")} #' #' @section File I/O: #' \itemize{ #' \item \link{readChangeoDb}: Input Change-O style files. #' \item \link{writeChangeoDb}: Output Change-O style files. #' } #' #' @section Sequence cleaning: #' \itemize{ #' \item \link{maskSeqEnds}: Mask ragged ends. #' \item \link{maskSeqGaps}: Mask gap characters. #' \item \link{collapseDuplicates}: Remove duplicate sequences. #' } #' #' @section Lineage reconstruction: #' \itemize{ #' \item \link{makeChangeoClone}: Clean sequences for lineage reconstruction. #' \item \link{buildPhylipLineage}: Perform lineage reconstruction of Ig sequences. #' } #' #' @section Lineage topology analysis: #' \itemize{ #' \item \link{tableEdges}: Tabulate annotation relationships over edges. #' \item \link{testEdges}: Significance testing of annotation edges. #' \item \link{testMRCA}: Significance testing of MRCA annotations. #' \item \link{summarizeSubtrees}: Various summary statistics for subtrees. #' \item \link{plotSubtrees}: Plot distributions of summary statistics #' for a population of trees. #' } #' #' @section Diversity analysis: #' \itemize{ #' \item \link{countClones}: Calculate clonal abundance. #' \item \link{estimateAbundance}: Bootstrap clonal abundance curves. #' \item \link{alphaDiversity}: Generate clonal alpha diversity curves. #' \item \link{plotAbundanceCurve}: Plot clone size distribution as a rank-abundance #' \item \link{plotDiversityCurve}: Plot clonal diversity curves. #' \item \link{plotDiversityTest}: Plot testing at given diversity hill indicex. #' } #' #' @section Ig and TCR sequence annotation: #' \itemize{ #' \item \link{countGenes}: Calculate Ig and TCR allele, gene and family usage. #' \item \link{extractVRegion}: Extract CDRs and FWRs sub-sequences. #' \item \link{getAllele}: Get V(D)J allele names. #' \item \link{getGene}: Get V(D)J gene names. #' \item \link{getFamily}: Get V(D)J family names. #' } #' #' @section Sequence distance calculation: #' \itemize{ #' \item \link{seqDist}: Calculate Hamming distance between two sequences. #' \item \link{seqEqual}: Test two sequences for equivalence. #' \item \link{pairwiseDist}: Calculate a matrix of pairwise Hamming distances for a #' set of sequences. #' \item \link{pairwiseEqual}: Calculate a logical matrix of pairwise equivalence for a #' set of sequences. #' } #' #' @section Amino acid propertes: #' \itemize{ #' \item \link{translateDNA}: Translate DNA sequences to amino acid sequences. #' \item \link{aminoAcidProperties}: Calculate various physicochemical properties of amino acid #' sequences. #' \item \link{countPatterns}: Count patterns in sequences. #' #' } #' #' @section General data manipulation: #' \itemize{ #' \item \link{translateStrings}: Perform multiple string replacement operations. #' } #' #' @name alakazam #' @docType package #' @references #' \enumerate{ #' \item Vander Heiden JA, Yaari G, et al. pRESTO: a toolkit for processing #' high-throughput sequencing raw reads of lymphocyte receptor repertoires. #' Bioinformatics. 2014 30(13):1930-2. #' \item Stern JNH, Yaari G, Vander Heiden JA, et al. B cells populating the multiple #' sclerosis brain mature in the draining cervical lymph nodes. #' Sci Transl Med. 2014 6(248):248ra107. #' \item Wu Y-CB, et al. Influence of seasonal exposure to grass pollen on local and #' peripheral blood IgE repertoires in patients with allergic rhinitis. #' J Allergy Clin Immunol. 2014 134(3):604-12. #' \item Gupta NT, Vander Heiden JA, et al. Change-O: a toolkit for analyzing #' large-scale B cell immunoglobulin repertoire sequencing data. #' Bioinformatics. 2015 Oct 15;31(20):3356-8. #' } #' #' @import ggplot2 #' @import graphics #' @import methods #' @import utils #' @importFrom ape read.tree di2multi reorder.phylo root ladderize #' @importFrom dplyr do n desc %>% #' bind_cols bind_rows combine arrange #' group_by ungroup #' filter slice select #' mutate mutate_at #' one_of if_else #' right_join rowwise #' summarize summarize_at #' transmute rename #' @importFrom igraph V E graph_from_data_frame as_data_frame as_edgelist #' make_graph make_directed_graph make_undirected_graph #' vertex_attr set_vertex_attr #' degree shortest_paths all_shortest_paths distances #' graph_from_adjacency_matrix components groups #' @importFrom lazyeval interp #' @importFrom Matrix sparseMatrix rowSums #' @importFrom progress progress_bar #' @importFrom readr read_delim read_tsv write_delim write_tsv cols #' @importFrom scales log2_trans log10_trans trans_breaks trans_format #' math_format percent scientific pretty_breaks #' @importFrom seqinr translate #' @importFrom stats na.omit setNames ecdf sd cor cov median mad #' dbinom pbinom qbinom rbinom #' dnorm pnorm qnorm rnorm #' dmultinom rmultinom #' @importFrom stringi stri_dup stri_flatten stri_join stri_length #' stri_count_boundaries stri_count_fixed #' stri_count_regex stri_extract_all_regex #' stri_extract_first_regex stri_replace_all_regex #' stri_replace_first_regex stri_split_fixed #' stri_pad_left stri_pad_right #' stri_detect_fixed stri_paste #' @importFrom tibble tibble #' @importFrom tidyr complete gather #' @importFrom Rcpp evalCpp #' @useDynLib alakazam, .registration=TRUE NULL alakazam/R/Diversity.R0000644000176200001440000015505313513145240014350 0ustar liggesusers# Clonal diversity analysis #' @include Classes.R NULL #### Coverage functions #### #' Calculate sample coverage #' #' \code{calcCoverage} calculates the sample coverage estimate, a measure of sample #' completeness, for varying orders using the method of Chao et al, 2015, falling back #' to the Chao1 method in the first order case. #' #' @param x numeric vector of abundance counts. #' @param r coverage order to calculate. #' #' @return The sample coverage of the given order \code{r}. #' #' @references #' \enumerate{ #' \item Chao A. Nonparametric Estimation of the Number of Classes in a Population. #' Scand J Stat. 1984 11, 265270. #' \item Chao A, et al. Unveiling the species-rank abundance distribution by #' generalizing the Good-Turing sample coverage theory. #' Ecology. 2015 96, 11891201. #' } #' #' @seealso #' Used by \link{alphaDiversity}. #' #' @examples #' # Calculate clone sizes #' clones <- countClones(ExampleDb, groups="SAMPLE") #' #' # Calculate 1first order coverage for a single sample #' calcCoverage(clones$SEQ_COUNT[clones$SAMPLE == "+7d"]) #' #' @export calcCoverage <- function(x, r=1) { # Use traditional calculation for 1st order coverage if (r == 1) { return(calcChao1Coverage(x)) } # Use general form for 2nd order and higher coverage x <- x[x >= 1] n <- sum(x) fr <- sum(x == r) fs <- sum(x == r + 1) if (fr == 0) { stop("Cannot calculate coverage of order ", r, ". No abundance data with count=", r, ".") } if (fs == 0) { stop("Cannot calculate coverage of order ", r, ". No abundance data with count=", r + 1, ".") } a <- factorial(r)*fr / sum(x[x >= r]^r) b <- ((n - r)*fr / ((n - r)*fr + (r + 1)*fs))^r rC <- 1 - a*b return(rC) } # Calculate first order coverage # # @param x a numeric vector of species abundance as counts # # @returns Coverage estimate. calcChao1Coverage <- function(x) { x <- x[x >= 1] n <- sum(x) f1 <- sum(x == 1) f2 <- sum(x == 2) if (f2 > 0) { rC1 <- 1 - (f1 / n) * (((n - 1) * f1) / ((n - 1) * f1 + 2 * f2)) } else { rC1 <- 1 - (f1 / n) * (((n - 1) * (f1 - 1)) / ((n - 1) * (f1 - 1) + 2)) } return(rC1) } # Calculates diversity under rarefaction # # Calculates Hill numbers under rarefaction # # @param x vector of observed abundance counts. # @param m the sequence count to rarefy to. # # @return The first order coverage estimate inferRarefiedCoverage <- function(x, m) { x <- x[x >= 1] n <- sum(x) if (m > n) { stop("m must be <= the total count of observed sequences.") } # Unrarefied case if (m == n) { return(calcCoverage(x, r=1)) } # Calculate rarefied coverage # TODO: Read up on this and fix #rC1 <- iNEXT:::Chat.Ind(x, m) y <- x[(n - x) >= m] rC1 <- 1 - sum(y/n * exp(lgamma(n - y + 1) - lgamma(n - m - y + 1) - lgamma(n) + lgamma(n - m))) return(rC1) } #### Abundance functions #### # Calculate undetected species # # Calculates the lower bound of undetected species counts using the Chao1 estimator. # # @param x vector of observed abundance counts. # # @return The count of undetected species. inferUnseenCount <- function(x) { x <- x[x >= 1] n <- sum(x) f1 <- sum(x == 1) f2 <- sum(x == 2) if (f2 > 0) { f0 <- ceiling(((n - 1) * f1^2) / (n * 2 * f2)) } else { f0 <- ceiling(((n - 1) * f1 * (f1 - 1)) / (n * 2)) } return(f0) } # Define undetected species relative abundances # # @param x vector of detected species abundance counts. # # @return An adjusted detected species relative abundance distribution. inferUnseenAbundance <- function(x) { x <- x[x >= 1] # Coverage rC1 <- calcCoverage(x, r=1) # Unseen count f0 <- inferUnseenCount(x) # Assign unseen relative abundance p <- rep((1 - rC1) / f0, f0) return(p) } # Adjustement to observed relative abundances # # @param x vector of observed abundance counts # # @return An adjusted observed species relative abundance distribution. adjustObservedAbundance <- function(x) { x <- x[x >= 1] n <- sum(x) # Coverage rC1 <- calcCoverage(x, r=1) # Calculate tuning parameter lambda <- (1 - rC1) / sum(x/n * exp(-x)) # Define adjusted relative abundance p <- x/n * (1 - lambda * exp(-x)) return(p) } # Combined unseen inferrence and observed abundance adjustment # # @param x named vector of observed abundance counts by clone. # # @return A vector containing the complete inferred abundance distribution. # Unseen species will be denote by a clone name starting with "U". inferCompleteAbundance <- function(x) { # Infer complete abundance distribution p1 <- adjustObservedAbundance(x) p2 <- inferUnseenAbundance(x) names(p2) <- if (length(p2) > 0) { paste0("U", 1:length(p2)) } else { NULL } return(c(p1, p2)) } #' Tabulates clones sizes #' #' \code{countClones} determines the number of sequences and total copy number of #' clonal groups. #' #' @param data data.frame with Change-O style columns containing clonal assignments. #' @param groups character vector defining \code{data} columns containing grouping #' variables. If \code{groups=NULL}, then do not group data. #' @param copy name of the \code{data} column containing copy numbers for each #' sequence. If this value is specified, then total copy abundance #' is determined by the sum of copy numbers within each clonal group. #' @param clone name of the \code{data} column containing clone identifiers. #' #' @return A data.frame summarizing clone counts and frequencies with columns: #' \itemize{ #' \item \code{CLONE}: clone identifier. #' \item \code{SEQ_COUNT}: total number of sequences for the clone. #' \item \code{SEQ_FREQ}: frequency of the clone as a fraction of the total #' number of sequences within each group. #' \item \code{COPY_COUNT}: sum of the copy counts in the \code{copy} column. #' Only present if the \code{copy} argument is #' specified. #' \item \code{COPY_FREQ}: frequency of the clone as a fraction of the total #' copy number within each group. Only present if #' the \code{copy} argument is specified. #' } #' Also includes additional columns specified in the \code{groups} argument. #' #' @examples #' # Without copy numbers #' clones <- countClones(ExampleDb, groups="SAMPLE") #' #' # With copy numbers and multiple groups #' clones <- countClones(ExampleDb, groups=c("SAMPLE", "ISOTYPE"), copy="DUPCOUNT") #' #' @export countClones <- function(data, groups=NULL, copy=NULL, clone="CLONE") { # Check input check <- checkColumns(data, c(clone, copy, groups)) if (check != TRUE) { stop(check) } # Tabulate clonal abundance if (is.null(copy)) { clone_tab <- data %>% group_by(!!!rlang::syms(c(groups, clone))) %>% dplyr::summarize(SEQ_COUNT=n()) %>% dplyr::mutate(SEQ_FREQ=!!rlang::sym("SEQ_COUNT")/sum(!!rlang::sym("SEQ_COUNT"), na.rm=TRUE)) %>% dplyr::arrange(desc(!!rlang::sym("SEQ_COUNT"))) %>% dplyr::rename("CLONE"=clone) } else { clone_tab <- data %>% group_by(!!!rlang::syms(c(groups, clone))) %>% dplyr::summarize(SEQ_COUNT=length(.data[[clone]]), COPY_COUNT=sum(.data[[copy]], na.rm=TRUE)) %>% dplyr::mutate(SEQ_FREQ=!!rlang::sym("SEQ_COUNT")/sum(!!rlang::sym("SEQ_COUNT"), na.rm=TRUE), COPY_FREQ=!!rlang::sym("COPY_COUNT")/sum(!!rlang::sym("COPY_COUNT"), na.rm=TRUE)) %>% dplyr::arrange(desc(!!rlang::sym("COPY_COUNT"))) %>% dplyr::rename("CLONE"=clone) } return(clone_tab) } # Perform boostrap abundance calculation # # @param x named vector of observed abundance values. # @param n number of samples to draw from the estimate complete abundance distribution. # @param nboot number of bootstrap realizations. # @param method complete abundance inferrence method. # One of "before", "after" or "none" for complete abundance distribution # inferrence before sampling, after sampling, or uncorrected, respectively. # # @return A matrix of bootstrap results. bootstrapAbundance <- function(x, n, nboot=200, method="before") { ## DEBUG # x=abund_obs; method="before" # Check argumets method <- match.arg(method) if (method == "before") { # Calculate estimated complete abundance distribution p <- inferCompleteAbundance(x) # Bootstrap abundance boot_mat <- rmultinom(nboot, n, p) / n } else if (method == "after") { # Calculate estimated complete abundance distribution p <- x / sum(x, na.rm=TRUE) boot_sam <- rmultinom(nboot, n, p) boot_list <- apply(boot_sam, 2, inferCompleteAbundance) # Convert to matrix boot_names <- unique(unlist(sapply(boot_list, names))) boot_mat <- matrix(0, nrow=length(boot_names), ncol=nboot) rownames(boot_mat) <- boot_names for (i in 1:nboot) { boot_mat[names(boot_list[[i]]), i] <- boot_list[[i]] } } else if (method == "none") { # Raw sampling of input p <- x / sum(x, na.rm=TRUE) boot_sam <- rmultinom(nboot, n, p) } else { stop("Invalid method: ", method) } return(boot_mat) } #' Estimates the complete clonal relative abundance distribution #' #' \code{estimateAbundance} estimates the complete clonal relative abundance distribution #' and confidence intervals on clone sizes using bootstrapping. #' #' @param data data.frame with Change-O style columns containing clonal assignments. #' @param clone name of the \code{data} column containing clone identifiers. #' @param copy name of the \code{data} column containing copy numbers for each #' sequence. If \code{copy=NULL} (the default), then clone abundance #' is determined by the number of sequences. If a \code{copy} column #' is specified, then clone abundances is determined by the sum of #' copy numbers within each clonal group. #' @param group name of the \code{data} column containing group identifiers. #' If \code{NULL} then no grouping is performed and the \code{GROUP} #' column of the output will contain the value \code{NA} for each row. #' @param min_n minimum number of observations to sample. #' A group with less observations than the minimum is excluded. #' @param max_n maximum number of observations to sample. If \code{NULL} then no #' maximum is set. #' @param uniform if \code{TRUE} then uniformly resample each group to the same #' number of observations. If \code{FALSE} then allow each group to #' be resampled to its original size or, if specified, \code{max_size}. #' @param ci confidence interval to calculate; the value must be between 0 and 1. #' @param nboot number of bootstrap realizations to generate. #' @param progress if \code{TRUE} show a progress bar. #' #' @return A \link{AbundanceCurve} object summarizing the abundances. #' #' @references #' \enumerate{ #' \item Chao A. Nonparametric Estimation of the Number of Classes in a Population. #' Scand J Stat. 1984 11, 265270. #' \item Chao A, et al. Rarefaction and extrapolation with Hill numbers: #' A framework for sampling and estimation in species diversity studies. #' Ecol Monogr. 2014 84:45-67. #' \item Chao A, et al. Unveiling the species-rank abundance distribution by #' generalizing the Good-Turing sample coverage theory. #' Ecology. 2015 96, 11891201. #' } #' #' @seealso #' See \link{plotAbundanceCurve} for plotting of the abundance distribution. #' See \link{alphaDiversity} for a similar application to clonal diversity. #' #' @examples #' abund <- estimateAbundance(ExampleDb, group="SAMPLE", nboot=100) #' #' @export estimateAbundance <- function(data, clone="CLONE", copy=NULL, group=NULL, min_n=30, max_n=NULL, uniform=TRUE, ci=0.95, nboot=200, progress=FALSE) { ## DEBUG # data=ExampleDb; group="SAMPLE"; clone="CLONE"; copy=NULL; min_n=1; max_n=NULL; ci=0.95; uniform=F; nboot=100 # copy="DUPCOUNT" # group=NULL # Hack for visibility of dplyr variables . <- NULL # Check input if (!is.data.frame(data)) { stop("Input data is not a data.frame") } # Check columns that are reported are real columns (can be NULL) check <- checkColumns(data, c(clone, copy, group)) if (check != TRUE) { stop(check) } # Set confidence interval ci_z <- ci + (1 - ci) / 2 ci_x <- qnorm(ci_z) # Tabulate clonal abundance count_col <- if (!is.null(copy)) { "COPY_COUNT" } else { "SEQ_COUNT" } clone_tab <- countClones(data, copy=copy, clone=clone, groups=group) %>% dplyr::mutate(CLONE_COUNT=!!rlang::sym(count_col)) # Tabulate group sizes if (!is.null(group)) { # Summarize groups group_tab <- clone_tab %>% group_by(!!rlang::sym(group)) %>% dplyr::summarize(COUNT=sum(!!rlang::sym("CLONE_COUNT"), na.rm=TRUE)) %>% rename(GROUP=!!rlang::sym(group)) } else { group_tab <- data.frame(V="All", COUNT=sum(clone_tab$CLONE_COUNT, na.rm=T)) names(group_tab)[1] <- "GROUP" } group_all <- as.character(group_tab$GROUP) group_tab <- group_tab[group_tab$COUNT >= min_n, ] group_keep <- as.character(group_tab$GROUP) # Set number of sampled sequence if (uniform) { nsam <- min(group_tab$COUNT, max_n) nsam <- setNames(rep(nsam, length(group_keep)), group_keep) } else { nsam <- if (is.null(max_n)) { group_tab$COUNT } else { pmin(group_tab$COUNT, max_n) } nsam <- setNames(nsam, group_keep) } # Warn if groups removed if (length(group_keep) < length(group_all)) { warning("Not all groups passed threshold min_n=", min_n, ".", " Excluded: ", paste(setdiff(group_all, group_keep), collapse=", ")) } # Generate abundance bootstrap if (progress) { pb <- progressBar(length(group_keep)) } boot_list <- list() abund_list <- list() for (g in group_keep) { n <- nsam[g] # Extract abundance vector if (!is.null(group)) { abund_obs <- clone_tab$CLONE_COUNT[clone_tab[[group]] == g] names(abund_obs) <- clone_tab[[clone]][clone_tab[[group]] == g] } else { # Extract abundance vector abund_obs <- clone_tab$CLONE_COUNT names(abund_obs) <- clone_tab[[clone]] } # Infer complete abundance distribution boot_mat <- bootstrapAbundance(abund_obs, n, nboot=nboot, method="before") # Assign confidence intervals based on variance of bootstrap realizations p_mean <- apply(boot_mat, 1, mean) p_sd <- apply(boot_mat, 1, sd) p_err <- ci_x * p_sd p_lower <- pmax(p_mean - p_err, 0) p_upper <- p_mean + p_err # Assemble and sort abundance data.frame abund_df <- tibble::tibble(CLONE=rownames(boot_mat), P=p_mean, P_SD=p_sd, LOWER=p_lower, UPPER=p_upper) %>% dplyr::arrange(desc(!!rlang::sym("P"))) %>% dplyr::mutate(RANK=1:n()) # Save summary abund_list[[g]] <- abund_df # Save bootstrap boot_list[[g]] <- as.data.frame(boot_mat) %>% tibble::rownames_to_column("CLONE") if (progress) { pb$tick() } } id_col <- if_else(is.null(group), "GROUP", group) abundance_df <- as.data.frame(bind_rows(abund_list, .id=id_col)) bootstrap_df <- as.data.frame(bind_rows(boot_list, .id=id_col)) # Create a new diversity object with bootstrap abund_obj <- new("AbundanceCurve", bootstrap=bootstrap_df, abundance=abundance_df, clone_by=clone, group_by=id_col, #groups=if_else(is.null(group), as.character(NA), group_keep), groups=group_keep, n=nsam, nboot=nboot, ci=ci) return(abund_obj) } #### Diversity functions #### #' Calculate the diversity index #' #' \code{calcDiversity} calculates the clonal diversity index for a vector of diversity #' orders. #' #' @param p numeric vector of clone (species) counts or proportions. #' @param q numeric vector of diversity orders. #' #' @return A vector of diversity scores \eqn{D} for each \eqn{q}. #' #' @details #' This method, proposed by Hill (Hill, 1973), quantifies diversity as a smooth function #' (\eqn{D}) of a single parameter \eqn{q}. Special cases of the generalized diversity #' index correspond to the most popular diversity measures in ecology: species richness #' (\eqn{q = 0}), the exponential of the Shannon-Weiner index (\eqn{q} approaches \eqn{1}), the #' inverse of the Simpson index (\eqn{q = 2}), and the reciprocal abundance of the largest #' clone (\eqn{q} approaches \eqn{+\infty}). At \eqn{q = 0} different clones weight equally, #' regardless of their size. As the parameter \eqn{q} increase from \eqn{0} to \eqn{+\infty} #' the diversity index (\eqn{D}) depends less on rare clones and more on common (abundant) #' ones, thus encompassing a range of definitions that can be visualized as a single curve. #' #' Values of \eqn{q < 0} are valid, but are generally not meaningful. The value of \eqn{D} #' at \eqn{q=1} is estimated by \eqn{D} at \eqn{q=0.9999}. #' #' @references #' \enumerate{ #' \item Hill M. Diversity and evenness: a unifying notation and its consequences. #' Ecology. 1973 54(2):427-32. #' } #' #' @seealso Used by \link{alphaDiversity}. #' #' @examples #' # May define p as clonal member counts #' p <- c(1, 1, 3, 10) #' q <- c(0, 1, 2) #' calcDiversity(p, q) #' #' # Or proportional abundance #' p <- c(1/15, 1/15, 1/5, 2/3) #' calcDiversity(p, q) #' #' @export calcDiversity <- function(p, q) { # Add jitter to q=1 q[q == 1] <- 0.9999 # Remove zeros p <- p[p > 0] # Convert p to proportional abundance p <- p / sum(p) # Calculate D for each q D <- sapply(q, function(x) sum(p^x)^(1 / (1 - x))) return(D) } # Calculate the inferred diversity index # # \code{calcInferredDiversity} calculates the clonal diversity index for a vector of diversity # orders with a correction for the presence of unseen species. Does not take proportional abundance. # # @param p numeric vector of clone (species) counts. # @param q numeric vector of diversity orders. # # @return A vector of diversity scores \eqn{D} for each \eqn{q}. # # @details # This method, proposed by Hill (Hill, 1973), quantifies diversity as a smooth function # (\eqn{D}) of a single parameter \eqn{q}. Special cases of the generalized diversity # index correspond to the most popular diversity measures in ecology: species richness # (\eqn{q = 0}), the exponential of the Shannon-Weiner index (\eqn{q} approaches \eqn{1}), the # inverse of the Simpson index (\eqn{q = 2}), and the reciprocal abundance of the largest # clone (\eqn{q} approaches \eqn{+\infty}). At \eqn{q = 0} different clones weight equally, # regardless of their size. As the parameter \eqn{q} increase from \eqn{0} to \eqn{+\infty} # the diversity index (\eqn{D}) depends less on rare clones and more on common (abundant) # ones, thus encompassing a range of definitions that can be visualized as a single curve. # # Values of \eqn{q < 0} are valid, but are generally not meaningful. The value of \eqn{D} # at \eqn{q=1} is estimated by \eqn{D} at \eqn{q=0.9999}. # # An adjusted detected species relative abundance distribution is applied before calculating diversity. # # @references # \enumerate{ # \item Hill M. Diversity and evenness: a unifying notation and its consequences. # Ecology. 1973 54(2):427-32. # } # # @seealso Used by \link{alphaDiversity} # # @examples # # May define p as clonal member counts # p <- c(1, 1, 3, 10) # q <- c(0, 1, 2) # calcInferredDiversity(p, q) # # # @export # calcInferredDiversity <- function(p, q) { # # Correct abundance # .infer <- function(y) { # # Infer complete abundance distribution # p1 <- adjustObservedAbundance(y) # p2 <- inferUnseenAbundance(y) # names(p2) <- if (length(p2) > 0) { paste0("U", 1:length(p2)) } else { NULL } # return(c(p1, p2)) # } # # # Correct abundance # p <- .infer(p) # # Add jitter to q=1 # q[q == 1] <- 0.9999 # # Remove zeros # p <- p[p > 0] # # Convert p to proportional abundance # p <- p / sum(p) # # Calculate D for each q # D <- sapply(q, function(x) sum(p^x)^(1 / (1 - x))) # # return(D) # } # Calculates diversity under rarefaction # # Calculates Hill numbers under rarefaction # # @param x vector of observed abundance counts. # @param q numeric vector of diversity orders. # @param m the sequence count to rarefy to. # # @return A vector of diversity scores \eqn{D} for each \eqn{q}. inferRarefiedDiversity <- function(x, q, m) { x <- x[x >= 1] n <- sum(x) if (m > n) { stop("m must be <= the total count of observed sequences.") } q[q == 1] <- 0.9999 # Tabulate frequency counts from 1:n fk_n <- tabulate(x, nbins=n) # Calculate estimated fk(m) fk_m <- sapply(1:m, function(k) sum(exp(lchoose(k:m, k) + lchoose(n - k:m, m - k) - lchoose(n, m))*fk_n[k:m])) # Calculate diversity D <- sapply(q, function(r) sum((1:m / m)^r * fk_m)^(1 / (1 - r))) return(D) } # Helper function for computing alpha diversity from bootrstrap outputs # # \code{helperAlpha} divides a set of bootstrapped clones by group annotation, # and computes the diversity of each set. # # @param boot_output data.frame from\link{AbundanceCurve} object containing bootstrapped clonal # abundance curves. # @param q vector of Hill Diversity indices to test for diversity calculations. # @param clone name of the \code{boot_output} column containing clone identifiers. # @param group name of the \code{boot_output} column containing grouping information for # diversity calculation. # # @return data.frame containing diversity calculations for each bootstrap iteration. helperAlpha <- function(boot_output, q, clone="CLONE", group=NULL) { ## DEBUG # abundance <- estimateAbundance(ExampleDb, group="SAMPLE", nboot=100) # clone <- abundance@clone_by # group <- abundance@group_by # Compute diversity from a column of each bootstrap output <- boot_output %>% dplyr::ungroup() %>% dplyr::select(-one_of(c(clone, group))) %>% as.matrix() %>% apply(2, calcDiversity, q=q) %>% data.frame() %>% mutate(Q=q) return(output) } # Helper function for computing beta diversity from bootrstrap outputs # # \code{helperBeta} divides a set of bootstrapped clones by group annotation, # and computes the alpha diversity. Group annotations are then ignored and # gamma diversity is computed. A multiplicative beta diversity is used corresponding # to the gamma diversity divided by the average alpha diversity of each group. # # @param boot_output data.frame from\link{AbundanceCurve} object containing bootstrapped clonal abundance curves. # @param q vector of Hill Diversity indices to test for diversity calculations. # @param ci_z numeric value corresponding to confidence interval for calculating beta diversity. # @param clone name of the \code{boot_output} column containing clone identifiers. # @param group name of the \code{boot_output} column containing grouping information for diversity # calculation. # # @return data.frame containing diversity calculations for each bootstrap iteration. helperBeta <- function(boot_output, q, ci_x, clone="CLONE", group="GROUP") { # Hack for visibility of dplyr variables . <- NULL # Compute gamma diversity metrics gamma <- boot_output %>% dplyr::group_by(!!rlang::sym(clone)) %>% dplyr::select(-one_of(c(group))) %>% dplyr::summarize_all(sum) %>% dplyr::do(helperAlpha(., q=q, clone=clone)) %>% tidyr::gather(key="N", value="GAMMA", -!!rlang::sym("Q")) %>% dplyr::mutate(GAMMA=as.numeric(!!rlang::sym("GAMMA"))) # Compute alpha diversity metrics alpha <- boot_output %>% dplyr::group_by(!!rlang::sym(group)) %>% dplyr::do(helperAlpha(., q=q, clone=clone, group=group)) %>% dplyr::group_by(!!rlang::sym("Q")) %>% dplyr::select(-one_of(c(group))) %>% dplyr::summarize_all(mean) %>% tidyr::gather(key="N", value="ALPHA", -!!rlang::sym("Q")) %>% dplyr::mutate(ALPHA=as.numeric(!!rlang::sym("ALPHA"))) # Perform comparisons of alpha and gamma to extract beta beta <- bind_cols(gamma, alpha) %>% dplyr::group_by(!!rlang::sym("Q")) %>% dplyr::mutate(X=!!rlang::sym("GAMMA") / !!rlang::sym("ALPHA")) %>% dplyr::summarize(D=mean(!!rlang::sym("X"), na.rm=TRUE), D_SD=sd(!!rlang::sym("X"), na.rm=TRUE)) %>% dplyr::mutate(D_LOWER=pmax(!!rlang::sym("D") - !!rlang::sym("D_SD") * ci_x, 0), D_UPPER=!!rlang::sym("D") + !!rlang::sym("D_SD") * ci_x) return(beta) } # Helper function for computing statistical significance # # \code{helperTest} computes the pairwise statistical significance of differences # in bootstrapped diversity values between two sets defined by the group column. # A p-value is computed using the ECDF distribution as the frequency of bootstrap iterations # for which no difference is observed. # # @param div_df data.frame from\link{DiversityCurve} object containing bootstrapped # diversity curves. # @param group name of the \code{boot_output} column containing grouping information # for diversity calculation. # @param q vector of Hill Diversity indices to test for diversity calculations. # # @return data.frame containing test results for each value of q. helperTest <- function(div_df, q, group="GROUP") { # Hack for visibility of dplyr variables . <- NULL # Pairwise test group_pairs <- combn(unique(div_df[[group]]), 2, simplify=F) pvalue_list <- list() for (group_pair in group_pairs) { pair_list <- list() for(q_i in q) { # Currently just testing for one diversity order mat1 <- div_df %>% dplyr::filter(!!rlang::sym(group) == group_pair[1], !!rlang::sym("Q") == q_i) %>% dplyr::select(-one_of(c(group, "Q"))) %>% unlist() mat2 <- div_df %>% dplyr::filter(!!rlang::sym(group) == group_pair[2], !!rlang::sym("Q") == q_i) %>% dplyr::select(-one_of(c(group, "Q"))) %>% unlist() if (mean(mat1) >= mean(mat2)) { g_delta <- mat1 - mat2 } else { g_delta <- mat2 - mat1 } # Compute p-value from ecdf p <- ecdf(g_delta)(0) p <- ifelse(p <= 0.5, p * 2, (1 - p) * 2) pair_list[[as.character(q_i)]] <- list(DELTA_MEAN=mean(g_delta), DELTA_SD=sd(g_delta), PVALUE=p) } pvalue_list[[paste(group_pair, collapse=" != ")]] <- bind_rows(pair_list, .id="Q") } test_df <- bind_rows(pvalue_list, .id="TEST") return(test_df) } #' Calculate clonal alpha diversity #' #' \code{alphaDiversity} takes in a data.frame or \link{AbundanceCurve} and computes #' diversity scores (\eqn{D}) over an interval of diversity orders (\eqn{q}). #' #' @param data data.frame with Change-O style columns containing clonal assignments or #' a \link{AbundanceCurve} generate by \link{estimateAbundance} object #' containing a previously calculated bootstrap distributions of clonal abundance. #' @param min_q minimum value of \eqn{q}. #' @param max_q maximum value of \eqn{q}. #' @param step_q value by which to increment \eqn{q}. #' @param ci confidence interval to calculate; the value must be between 0 and 1. #' @param ... additional arguments to pass to \link{estimateAbundance}. Additional arguments #' are ignored if a \link{AbundanceCurve} is provided as input. #' #' @return A \link{DiversityCurve} object summarizing the diversity scores. #' #' @references #' \enumerate{ #' \item Hill M. Diversity and evenness: a unifying notation and its consequences. #' Ecology. 1973 54(2):427-32. #' \item Chao A. Nonparametric Estimation of the Number of Classes in a Population. #' Scand J Stat. 1984 11, 265270. #' \item Chao A, et al. Rarefaction and extrapolation with Hill numbers: #' A framework for sampling and estimation in species diversity studies. #' Ecol Monogr. 2014 84:45-67. #' \item Chao A, et al. Unveiling the species-rank abundance distribution by #' generalizing the Good-Turing sample coverage theory. #' Ecology. 2015 96, 11891201. #' } #' #' @seealso See \link{calcDiversity} for the basic calculation and #' \link{DiversityCurve} for the return object. #' See \link{plotDiversityCurve} for plotting the return object. #' #' @details #' Clonal diversity is calculated using the generalized diversity index (Hill numbers) #' proposed by Hill (Hill, 1973). See \link{calcDiversity} for further details. #' #' Diversity is calculated on the estimated complete clonal abundance distribution. #' This distribution is inferred by using the Chao1 estimator to estimate the number #' of seen clones, and applying the relative abundance correction and unseen clone #' frequency described in Chao et al, 2015. #' #' To generate a smooth curve, \eqn{D} is calculated for each value of \eqn{q} from #' \code{min_q} to \code{max_q} incremented by \code{step_q}. When \code{uniform=TRUE} #' variability in total sequence counts across unique values in the \code{group} column #' is corrected by repeated resampling from the estimated complete clonal distribution to a #' common number of sequences. #' #' The diversity index (\eqn{D}) for each group is the mean value of over all resampling #' realizations. Confidence intervals are derived using the standard deviation of the #' resampling realizations, as described in Chao et al, 2015. #' #' Of note, the complete clonal abundance distribution is inferred by using the Chao1 #' estimator to estimate the number of seen clones, and then applying the relative abundance #' correction and unseen clone frequencies described in Chao et al, 2015. #' #' #' @examples #' # Group by sample identifier in two steps #' abund <- estimateAbundance(ExampleDb, group="SAMPLE", nboot=100) #' div <- alphaDiversity(abund, step_q=1, max_q=10) #' plotDiversityCurve(div, legend_title="Sample") #' #' # Grouping by isotype rather than sample identifier in one step #' div <- alphaDiversity(ExampleDb, group="ISOTYPE", min_n=40, step_q=1, max_q=10, #' nboot=100) #' plotDiversityCurve(div, legend_title="Isotype") #' #' @export alphaDiversity <- function(data, min_q=0, max_q=4, step_q=0.1, ci=0.95, ...) { # Hack for visibility of dplyr variables . <- NULL # Check input object and call estimateAbundance if required if (is(data, "AbundanceCurve")) { abundance <- data } else if (is(data, "data.frame")) { abundance <- estimateAbundance(data, ci=0.95, ...) } else { stop("Input must be either a data.frame or AbundanceCurve object.") } # Set diversity orders and confidence interval ci_z <- ci + (1 - ci) / 2 ci_x <- qnorm(ci_z) q <- seq(min_q, max_q, step_q) if (!(0 %in% q)) { q <- c(0, q) } # Set grouping variables clone <- abundance@clone_by group <- abundance@group_by # Compute diversity metric for bootstrap instances boot_df <- abundance@bootstrap %>% dplyr::group_by(!!rlang::sym(group)) %>% dplyr::do(helperAlpha(., q=q, clone=clone, group=group)) %>% dplyr::ungroup() # Summarize diversity div_df <- boot_df %>% tidyr::gather(key="N", value="X", -one_of(c(group, "Q"))) %>% dplyr::mutate(X=as.numeric(!!rlang::sym("X"))) %>% dplyr::group_by(!!!rlang::syms(c(group, "Q"))) %>% dplyr::summarize(D=mean(!!rlang::sym("X"), na.rm=TRUE), D_SD=sd(!!rlang::sym("X"), na.rm=TRUE)) %>% dplyr::mutate(D_LOWER=pmax(!!rlang::sym("D") - !!rlang::sym("D_SD") * ci_x, 0), D_UPPER=!!rlang::sym("D") + !!rlang::sym("D_SD") * ci_x) # Compute evenness div_qi <- div_df %>% filter(!!rlang::sym("Q") == 0) %>% select(one_of(c(group, "D"))) div_df <- div_df %>% dplyr::right_join(div_qi, by=group, suffix=c("", "_0")) %>% mutate(E=!!rlang::sym("D")/!!rlang::sym("D_0"), E_LOWER=!!rlang::sym("D_LOWER")/!!rlang::sym("D_0"), E_UPPER=!!rlang::sym("D_UPPER")/!!rlang::sym("D_0")) %>% select(-!!rlang::sym("D_0")) # Test if (length(abundance@groups) > 1) { print(q) test_df <- helperTest(boot_df, q=q, group=group) } else { test_df <- NULL } # Build return object group_set <- unique(div_df[[group]]) div_obj <- new("DiversityCurve", diversity=div_df, tests=test_df, method="alpha", group_by=group, groups=group_set, q=q, n=abundance@n, ci=ci) return(div_obj) } # Calculates the pairwise beta diversity # # \code{betaDiversity} takes in a data.frame or \link{AbundanceCurve} and computes # the multiplicative beta diversity across a range of Hill diversity indices. # # @param data data.frame with Change-O style columns containing clonal assignments or # an \link{AbundanceCurve} object generate by \link{estimateAbundance}. # containing a previously calculated bootstrap distributions of clonal abundance. # @param comparisons named list of comparisons between group members for computing beta diversity. # @param min_q minimum value of \eqn{q}. # @param max_q maximum value of \eqn{q}. # @param step_q value by which to increment \eqn{q}. # @param ci confidence interval to calculate; the value must be between 0 and 1. # @param ... additional arguments to pass to \link{estimateAbundance}. Additional arguments # are ignored if a \link{AbundanceCurve} is provided as input. # # @return A \link{DiversityCurve} object summarizing the diversity scores. # # @details # Beta diversity or the comparative difference between two samples as quantified using Hill # diversity indices proposed by Jost (Jost, 2007). # # Briefly, the alpha and gamma diversity components are calculated for each comparison. # Alpha diversity is calculated as the average hill diversity across each independent sample # while Gamma diversity is calculated as the total diversity without distinguishing between # samples. Beta diversity is computed as Gamma/Alpha. # # Diversity is calculated on the estimated clonal abundance distribution with a correction # for unseen species much like the calculation for alpha diversity \link{alphaDiversity}. # A smooth curve is generated in the same manner as in \link{alphaDiversity}. # Confidence intervals are derived using the standard deviation of the resampling realizations. # # \enumerate{ # \item Hill M. Diversity and evenness: a unifying notation and its consequences. # Ecology. 1973 54(2):427-32. # \item Jost L. Partitioning Diversity Into Independent Alpha and Beta Components. # Ecology. 2007 88(10):2427–2439. # \item Jost L, et al. Partitioning diversity for conservation analyses. # Diversity Distrib. 2010 16(1):65–76 # } # # @examples # div <- betaDiversity(ExampleDb, comparisons=list("TIME"=c("-1h", "+7d")), group="SAMPLE", # min_n=40, step_q=1, max_q=10, nboot=100) # # plotDiversityCurve(div, legend_title="Isotype") # # @export betaDiversity <- function(data, comparisons, min_q=0, max_q=4, step_q=0.1, ci=0.95, ...) { # Hack for visibility of dplyr variables . <- NULL if (!is.list(comparisons) || is.null(names(comparisons))) { stop("'comparisons' must be a named list") } # Check input object and call estimateAbundance if required if (is(data, "AbundanceCurve")) { abundance <- data } else if (is(data, "data.frame")) { abundance <- estimateAbundance(data, ci=0.95, ...) } else { stop("Input must be either a data.frame or AbundanceCurve object.") } # Set diversity orders and confidence interval ci_z <- ci + (1 - ci) / 2 ci_x <- qnorm(ci_z) q <- seq(min_q, max_q, step_q) if (!(0 %in% q)) { q <- c(0, q) } # Compute pairwise beta diversity for bootstrap instances beta_diversity_list <- list() for (comparison in names(comparisons)) { beta_diversity_list[[comparison]] <- abundance@bootstrap %>% dplyr::ungroup() %>% dplyr::filter(.[[abundance@group_by]] %in% comparisons[[comparison]]) %>% dplyr::do(helperBeta(., q=q, clone=abundance@clone_by, group=abundance@group_by, ci_x=ci_x)) } # Generate summary diversity output div_df <- bind_rows(beta_diversity_list, .id = "COMPARISON") # Beta groups group_set <- unique(div_df[["COMPARISON"]]) # Compute evenness div_qi <- div_df %>% filter(!!rlang::sym("Q") == 0) %>% select(one_of(c("COMPARISON", "D"))) div <- div_df %>% right_join(div_qi, by = "COMPARISON", suffix = c("", "_0")) %>% mutate(E = !!rlang::sym("D")/!!rlang::sym("D_0"), E_LOWER = !!rlang::sym("D_LOWER")/!!rlang::sym("D_0"), E_UPPER = !!rlang::sym("D_UPPER")/!!rlang::sym("D_0")) %>% select(-!!rlang::sym("D_0")) # Test if (length(group_set) > 1) { test_df <- helperTest(div_df, q=q, group="COMPARISON") } else { test_df <- NULL } # Build return object div_obj <- new("DiversityCurve", diversity=div, tests=test_df, method="beta", group_by="COMPARISON", groups=group_set, n=abundance@n, q=q, ci=ci) return(div_obj) } #### Plotting functions #### #' Plots a clonal abundance distribution #' #' \code{plotAbundanceCurve} plots the results from estimating the complete clonal #' relative abundance distribution. The distribution is plotted as a log rank abundance #' distribution. #' #' @param data \link{AbundanceCurve} object returned by \link{estimateAbundance}. #' @param colors named character vector whose names are values in the #' \code{group} column of \code{data} and whose values are #' colors to assign to those group names. #' @param main_title string specifying the plot title. #' @param legend_title string specifying the legend title. #' @param xlim numeric vector of two values specifying the #' \code{c(lower, upper)} x-axis limits. #' @param ylim numeric vector of two values specifying the #' \code{c(lower, upper)} y-axis limits. #' @param annotate string defining whether to added values to the group labels #' of the legend. When \code{"none"} (default) is specified no #' annotations are added. Specifying (\code{"depth"}) adds #' sequence counts to the labels. #' @param silent if \code{TRUE} do not draw the plot and just return the ggplot2 #' object; if \code{FALSE} draw the plot. #' @param ... additional arguments to pass to ggplot2::theme. #' #' @return A \code{ggplot} object defining the plot. #' #' @seealso #' See \link{AbundanceCurve} for the input object and \link{estimateAbundance} for #' generating the input abundance distribution. #' Plotting is performed with \link{ggplot}. #' #' @examples #' # Estimate abundance by sample and plot #' abund <- estimateAbundance(ExampleDb, group="SAMPLE", nboot=100) #' plotAbundanceCurve(abund, legend_title="Sample") #' #' @export plotAbundanceCurve <- function(data, colors=NULL, main_title="Rank Abundance", legend_title=NULL, xlim=NULL, ylim=NULL, annotate=c("none", "depth"), silent=FALSE, ...) { # Check if abundance is in data if (is.null(data@abundance)) { stop("Missing abundance data.") } # Check arguments annotate <- match.arg(annotate) # Define group label annotations if (all(is.na(data@groups)) || length(data@groups) == 1) { group_labels <- NA } else if (annotate == "none") { group_labels <- setNames(data@groups, data@groups) } else if (annotate == "depth") { group_labels <- setNames(paste0(data@groups, " (N=", data@n, ")"), data@groups) } # Stupid hack for check NOTE about `.x` in math_format .x <- NULL if (!all(is.na(group_labels))) { # Define grouped plot p1 <- ggplot(data@abundance, aes_string(x="RANK", y="P", group=data@group_by)) + ggtitle(main_title) + baseTheme() + xlab("Rank") + ylab("Abundance") + scale_x_log10(limits=xlim, breaks=scales::trans_breaks("log10", function(x) 10^x), labels=scales::trans_format("log10", scales::math_format(10^.x))) + scale_y_continuous(labels=scales::percent) + geom_ribbon(aes_string(ymin="LOWER", ymax="UPPER", fill=data@group_by), alpha=0.4) + geom_line(aes_string(color=data@group_by)) # Set colors and legend if (!is.null(colors)) { p1 <- p1 + scale_color_manual(name=legend_title, labels=group_labels, values=colors) + scale_fill_manual(name=legend_title, labels=group_labels, values=colors) } else { p1 <- p1 + scale_color_discrete(name=legend_title, labels=group_labels) + scale_fill_discrete(name=legend_title, labels=group_labels) } } else { # Set color if (!is.null(colors) & length(colors) == 1) { line_color <- colors } else { line_color <- "black" } # Define plot p1 <- ggplot(data@abundance, aes_string(x="RANK", y="P")) + ggtitle(main_title) + baseTheme() + xlab("Rank") + ylab("Abundance") + scale_x_log10(limits=xlim, breaks=scales::trans_breaks("log10", function(x) 10^x), labels=scales::trans_format("log10", scales::math_format(10^.x))) + scale_y_continuous(labels=scales::percent) + geom_ribbon(aes_string(ymin="LOWER", ymax="UPPER"), fill=line_color, alpha=0.4) + geom_line(color=line_color) } # Add additional theme elements p1 <- p1 + do.call(theme, list(...)) # Plot if (!silent) { plot(p1) } invisible(p1) } #' Plot the results of alphaDiversity #' #' \code{plotDiversityCurve} plots a \code{DiversityCurve} object. #' #' @param data \link{DiversityCurve} object returned by #' \link{alphaDiversity}. #' @param colors named character vector whose names are values in the #' \code{group} column of the \code{data} slot of \code{data}, #' and whose values are colors to assign to those group names. #' @param main_title string specifying the plot title. #' @param legend_title string specifying the legend title. #' @param log_x if \code{TRUE} then plot \eqn{q} on a log scale; #' if \code{FALSE} plot on a linear scale. #' @param log_y if \code{TRUE} then plot the diversity/evenness scores #' on a log scale; if \code{FALSE} plot on a linear scale. #' @param xlim numeric vector of two values specifying the #' \code{c(lower, upper)} x-axis limits. #' @param ylim numeric vector of two values specifying the #' \code{c(lower, upper)} y-axis limits. #' @param annotate string defining whether to added values to the group labels #' of the legend. When \code{"none"} (default) is specified no #' annotations are added. Specifying (\code{"depth"}) adds #' sequence counts to the labels. #' @param score one of \code{"diversity"} or \code{"evenness"} specifying which #' score to plot on the y-asis. #' @param silent if \code{TRUE} do not draw the plot and just return the ggplot2 #' object; if \code{FALSE} draw the plot. #' @param ... additional arguments to pass to ggplot2::theme. #' #' @return A \code{ggplot} object defining the plot. #' #' @seealso See \link{alphaDiversity} and \link{alphaDiversity} for generating #' \link{DiversityCurve} objects for input. Plotting is performed with \link{ggplot}. #' #' @examples #' # Calculate diversity #' div <- alphaDiversity(ExampleDb, group="SAMPLE", nboot=100) #' #' # Plot diversity #' plotDiversityCurve(div, legend_title="Sample") #' #' #' # Plot diversity #' plotDiversityCurve(div, legend_title="Sample", score="evenness") #' #' @export plotDiversityCurve <- function(data, colors=NULL, main_title="Diversity", legend_title="Group", log_x=FALSE, log_y=FALSE, xlim=NULL, ylim=NULL, annotate=c("none", "depth"), score=c("diversity", "evenness"), silent=FALSE, ...) { # Check arguments annotate <- match.arg(annotate) score <- match.arg(score) # Define group label annotations if (all(is.na(data@groups)) || length(data@groups) == 1) { group_labels <- NA } else if (annotate == "none") { group_labels <- setNames(data@groups, data@groups) } else if (annotate == "depth") { group_labels <- setNames(paste0(data@groups, " (N=", data@n, ")"), data@groups) } # Define y-axis scores if (score == "diversity") { y_value <- "D" y_min <- "D_LOWER" y_max <- "D_UPPER" y_label <- expression(''^q * D) } else if (score == "evenness") { y_value <- "E" y_min <- "E_LOWER" y_max <- "E_UPPER" y_label <- expression(''^q * E) } # Stupid hack for check NOTE about `.x` in math_format .x <- NULL if (!all(is.na(group_labels))) { # Define grouped plot p1 <- ggplot(data@diversity, aes_string(x="Q", y=y_value, group=data@group_by)) + ggtitle(main_title) + baseTheme() + xlab('q') + ylab(y_label) + geom_ribbon(aes_string(ymin=y_min, ymax=y_max, fill=data@group_by), alpha=0.4) + geom_line(aes_string(color=data@group_by)) # Set colors and legend if (!is.null(colors)) { p1 <- p1 + scale_color_manual(name=legend_title, labels=group_labels, values=colors) + scale_fill_manual(name=legend_title, labels=group_labels, values=colors) } else { p1 <- p1 + scale_color_discrete(name=legend_title, labels=group_labels) + scale_fill_discrete(name=legend_title, labels=group_labels) } } else { # Set color if (!is.null(colors) & length(colors) == 1) { line_color <- colors } else { line_color <- "black" } # Define ungrouped plot p1 <- ggplot(data@diversity, aes_string(x="Q", y=y_value)) + ggtitle(main_title) + baseTheme() + xlab('q') + ylab(y_label) + geom_ribbon(aes_string(ymin=y_min, ymax=y_max), fill=line_color, alpha=0.4) + geom_line(color=line_color) } # Set x-axis style if (log_x) { p1 <- p1 + scale_x_continuous(trans=scales::log2_trans(), limits=xlim, breaks=scales::trans_breaks('log2', function(x) 2^x), labels=scales::trans_format('log2', scales::math_format(2^.x))) } else { p1 <- p1 + scale_x_continuous(limits=xlim) } # Set y-axis style if (log_y) { p1 <- p1 + scale_y_continuous(trans=scales::log2_trans(), limits=ylim, breaks=scales::trans_breaks('log2', function(x) 2^x), labels=scales::trans_format('log2', scales::math_format(2^.x))) } else { p1 <- p1 + scale_y_continuous(limits=ylim) } # Add additional theme elements p1 <- p1 + do.call(theme, list(...)) # Plot if (!silent) { plot(p1) } invisible(p1) } #' Plot the results of diversity testing #' #' \code{plotDiversityTest} plots summary data for a \code{DiversityCurve} object #' with mean and a line range indicating plus/minus one standard deviation. #' #' @param data \link{DiversityCurve} object returned by #' \link{alphaDiversity}. #' @param q diversity order to plot the test for. #' @param colors named character vector whose names are values in the #' \code{group} column of the \code{data} slot of \code{data}, #' and whose values are colors to assign to those group names. #' @param main_title string specifying the plot title. #' @param legend_title string specifying the legend title. #' @param log_d if \code{TRUE} then plot the diversity scores \eqn{D} #' on a log scale; if \code{FALSE} plot on a linear scale. #' @param annotate string defining whether to added values to the group labels #' of the legend. When \code{"none"} (default) is specified no #' annotations are added. Specifying (\code{"depth"}) adds #' sequence counts to the labels. #' @param silent if \code{TRUE} do not draw the plot and just return the ggplot2 #' object; if \code{FALSE} draw the plot. #' @param ... additional arguments to pass to ggplot2::theme. #' #' @return A \code{ggplot} object defining the plot. #' #' @seealso See \link{alphaDiversity} for generating input. #' Plotting is performed with \link{ggplot}. #' #' @examples #' # Calculate diversity #' div <- alphaDiversity(ExampleDb, group="SAMPLE", min_q=0, max_q=2, step_q=1, nboot=100) #' #' # Plot results at q=0 (equivalent to species richness) #' plotDiversityTest(div, 0, legend_title="Sample") #' #' # Plot results at q=2 (equivalent to Simpson's index) #' plotDiversityTest(div, q=2, legend_title="Sample") #' #' @export plotDiversityTest <- function(data, q, colors=NULL, main_title="Diversity", legend_title="Group", log_d=FALSE, annotate=c("none", "depth"), silent=FALSE, ...) { # Stupid hack for check NOTE about `.x` in math_format .x <- NULL # Check arguments annotate <- match.arg(annotate) # Check if abundance is in data if (is.null(data@tests)) { stop("Test data missing from input object.") } # Check if q is in data if (!(q %in% data@q)) { stop("Test for order q=", q, " not found in input object.") } # Define group label annotations if (annotate == "none") { group_labels <- setNames(data@groups, data@groups) } else if (annotate == "depth") { group_labels <- setNames(paste0(data@groups, " (N=", data@n, ")"), data@groups) } # Define plot values df <- data@diversity %>% dplyr::filter(!!rlang::sym("Q") == q) %>% dplyr::mutate(LOWER=!!rlang::sym("D") - !!rlang::sym("D_SD"), UPPER=!!rlang::sym("D") + !!rlang::sym("D_SD")) # Define base plot elements p1 <- ggplot(df, aes_string(x=data@group_by)) + ggtitle(main_title) + baseTheme() + xlab("") + ylab(bquote("Mean " ^ .(q) * D %+-% "SD")) + geom_linerange(aes_string(ymin="LOWER", ymax="UPPER", color=data@group_by), alpha=0.8) + geom_point(aes_string(y="D", color=data@group_by)) # Set colors and legend if (!is.null(colors)) { p1 <- p1 + scale_color_manual(name=legend_title, labels=group_labels, values=colors) } else { p1 <- p1 + scale_color_discrete(name=legend_title, labels=group_labels) } # Set x-axis style if (log_d) { p1 <- p1 + scale_y_continuous(trans=scales::log2_trans(), breaks=scales::trans_breaks('log2', function(x) 2^x), labels=scales::trans_format('log2', scales::math_format(2^.x))) } else { p1 <- p1 + scale_y_continuous() } # Add additional theme elements p1 <- p1 + do.call(theme, list(...)) # Plot if (!silent) { plot(p1) } invisible(p1) } alakazam/R/Deprecated.R0000644000176200001440000002347013512442156014430 0ustar liggesusers# Deprecated and defunct functions #' @include Classes.R #' @include Diversity.R NULL #### Deprecated #### #' Generate a clonal diversity index curve #' #' \code{rarefyDiversity} divides a set of clones by a group annotation, #' resamples the sequences from each group, and calculates diversity #' scores (\eqn{D}) over an interval of diversity orders (\eqn{q}). #' #' @param data data.frame with Change-O style columns containing clonal assignments. #' @param group name of the \code{data} column containing group identifiers. #' @param clone name of the \code{data} column containing clone identifiers. #' @param copy name of the \code{data} column containing copy numbers for each #' sequence. If \code{copy=NULL} (the default), then clone abundance #' is determined by the number of sequences. If a \code{copy} column #' is specified, then clone abundances is determined by the sum of #' copy numbers within each clonal group. #' @param min_q minimum value of \eqn{q}. #' @param max_q maximum value of \eqn{q}. #' @param step_q value by which to increment \eqn{q}. #' @param min_n minimum number of observations to sample. #' A group with less observations than the minimum is excluded. #' @param max_n maximum number of observations to sample. If \code{NULL} then no #' maximum is set. #' @param ci confidence interval to calculate; the value must be between 0 and 1. #' @param nboot number of bootstrap realizations to generate. #' @param uniform if \code{TRUE} then uniformly resample each group to the same #' number of observations. If \code{FALSE} then allow each group to #' be resampled to its original size or, if specified, \code{max_size}. #' @param progress if \code{TRUE} show a progress bar. #' #' @return A \link{DiversityCurve} object summarizing the diversity scores. #' #' @details #' Clonal diversity is calculated using the generalized diversity index (Hill numbers) #' proposed by Hill (Hill, 1973). See \link{calcDiversity} for further details. #' #' Diversity is calculated on the estimated complete clonal abundance distribution. #' This distribution is inferred by using the Chao1 estimator to estimate the number #' of seen clones, and applying the relative abundance correction and unseen clone #' frequency described in Chao et al, 2015. #' #' To generate a smooth curve, \eqn{D} is calculated for each value of \eqn{q} from #' \code{min_q} to \code{max_q} incremented by \code{step_q}. When \code{uniform=TRUE} #' variability in total sequence counts across unique values in the \code{group} column #' is corrected by repeated resampling from the estimated complete clonal distribution to a #' common number of sequences. #' #' The diversity index (\eqn{D}) for each group is the mean value of over all resampling #' realizations. Confidence intervals are derived using the standard deviation of the #' resampling realizations, as described in Chao et al, 2015. #' #' @references #' \enumerate{ #' \item Hill M. Diversity and evenness: a unifying notation and its consequences. #' Ecology. 1973 54(2):427-32. #' \item Chao A. Nonparametric Estimation of the Number of Classes in a Population. #' Scand J Stat. 1984 11, 265270. #' \item Chao A, et al. Rarefaction and extrapolation with Hill numbers: #' A framework for sampling and estimation in species diversity studies. #' Ecol Monogr. 2014 84:45-67. #' \item Chao A, et al. Unveiling the species-rank abundance distribution by #' generalizing the Good-Turing sample coverage theory. #' Ecology. 2015 96, 11891201. #' } #' #' @seealso \link{alphaDiversity} #' #' @examples #' \dontrun{ #' # Group by sample identifier #' div <- rarefyDiversity(ExampleDb, "SAMPLE", step_q=1, max_q=10, nboot=100) #' plotDiversityCurve(div, legend_title="Sample") #' #' # Grouping by isotype rather than sample identifier #' div <- rarefyDiversity(ExampleDb, "ISOTYPE", min_n=40, step_q=1, max_q=10, #' nboot=100) #' plotDiversityCurve(div, legend_title="Isotype") #' } #' @export rarefyDiversity <- function(data, group, clone="CLONE", copy=NULL, min_q=0, max_q=4, step_q=0.05, min_n=30, max_n=NULL, ci=0.95, nboot=2000, uniform=TRUE, progress=FALSE) { .Deprecated("alphaDiversity") bootstrap_obj <- estimateAbundance(data, group=group, clone=clone, copy=copy, nboot=nboot, min_n=min_n, max_n=max_n, uniform=uniform, ci=ci) diversity_obj <- alphaDiversity(bootstrap_obj, ci=ci, min_q=min_q, max_q=max_q, step_q) return(diversity_obj) } #' Pairwise test of the diversity index #' #' \code{testDiversity} performs pairwise significance tests of the diversity index #' (\eqn{D}) at a given diversity order (\eqn{q}) for a set of annotation groups via #' rarefaction and bootstrapping. #' #' @param data data.frame with Change-O style columns containing clonal assignments. #' @param q diversity order to test. #' @param group name of the \code{data} column containing group identifiers. #' @param clone name of the \code{data} column containing clone identifiers. #' @param copy name of the \code{data} column containing copy numbers for each #' sequence. If \code{copy=NULL} (the default), then clone abundance #' is determined by the number of sequences. If a \code{copy} column #' is specified, then clone abundances is determined by the sum of #' copy numbers within each clonal group. #' @param min_n minimum number of observations to sample. #' A group with less observations than the minimum is excluded. #' @param max_n maximum number of observations to sample. If \code{NULL} the maximum #' if automatically determined from the size of the largest group. #' @param nboot number of bootstrap realizations to perform. #' @param ci confidence interval to calculate; the value must be between 0 and 1. #' @param progress if \code{TRUE} show a progress bar. #' #' @return A \link{DiversityCurve} object containing slot test with p-values and summary #' statistics. #' #' @details #' Clonal diversity is calculated using the generalized diversity index proposed by #' Hill (Hill, 1973). See \link{calcDiversity} for further details. #' #' Diversity is calculated on the estimated complete clonal abundance distribution. #' This distribution is inferred by using the Chao1 estimator to estimate the number #' of seen clones, and applying the relative abundance correction and unseen clone #' frequency described in Chao et al, 2014. #' #' Variability in total sequence counts across unique values in the \code{group} column is #' corrected by repeated resampling from the estimated complete clonal distribution to #' a common number of sequences. The diversity index estimate (\eqn{D}) for each group is #' the mean value of over all bootstrap realizations. #' #' Significance of the difference in diversity index (\eqn{D}) between groups is tested by #' constructing a bootstrap delta distribution for each pair of unique values in the #' \code{group} column. The bootstrap delta distribution is built by subtracting the diversity #' index \eqn{Da} in \eqn{group-a} from the corresponding value \eqn{Db} in \eqn{group-b}, #' for all bootstrap realizations, yeilding a distribution of \code{nboot} total deltas; where #' \eqn{group-a} is the group with the greater mean \eqn{D}. The p-value for hypothesis #' \eqn{Da != Db} is the value of \eqn{P(0)} from the empirical cumulative distribution #' function of the bootstrap delta distribution, multiplied by 2 for the two-tailed correction. #' #' @note #' This method may inflate statistical significance when clone sizes are uniformly small, #' such as when most clones sizes are 1, sample size is small, and \code{max_n} is near #' the total count of the smallest data group. Use caution when interpreting the results #' in such cases. We are currently investigating this potential problem. #' #' @references #' \enumerate{ #' \item Hill M. Diversity and evenness: a unifying notation and its consequences. #' Ecology. 1973 54(2):427-32. #' \item Chao A. Nonparametric Estimation of the Number of Classes in a Population. #' Scand J Stat. 1984 11, 265270. #' \item Wu Y-CB, et al. Influence of seasonal exposure to grass pollen on local and #' peripheral blood IgE repertoires in patients with allergic rhinitis. #' J Allergy Clin Immunol. 2014 134(3):604-12. #' \item Chao A, et al. Rarefaction and extrapolation with Hill numbers: #' A framework for sampling and estimation in species diversity studies. #' Ecol Monogr. 2014 84:45-67. #' \item Chao A, et al. Unveiling the species-rank abundance distribution by #' generalizing the Good-Turing sample coverage theory. #' Ecology. 2015 96, 11891201. #' } #' #' @seealso \link{alphaDiversity} #' #' @examples #' \dontrun{ #' # Groups under the size threshold are excluded and a warning message is issued. #' testDiversity(ExampleDb, "SAMPLE", q=0, min_n=30, nboot=100) #' } #' #' @export testDiversity <- function(data, q, group, clone="CLONE", copy=NULL, min_n=30, max_n=NULL, nboot=2000, progress=FALSE, ci=0.95) { .Deprecated("alphaDiversity") abundance_obj <- estimateAbundance(data, group=group, clone=clone, copy=copy, nboot=nboot, min_n=min_n, max_n=max_n, ci=ci) diversity_obj <- alphaDiversity(abundance_obj, min_q=q, max_q=q, step_q=1, ci=ci) return(diversity_obj) } #### Defunct #### alakazam/R/RcppExports.R0000644000176200001440000000477513513671660014675 0ustar liggesusers# Generated by using Rcpp::compileAttributes() -> do not edit by hand # Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393 #' Test DNA sequences for equality. #' #' \code{seqEqual} checks if two DNA sequences are identical. #' #' @param seq1 character string containing a DNA sequence. #' @param seq2 character string containing a DNA sequence. #' @param ignore vector of characters to ignore when testing for equality. #' Default is to ignore c("N",".","-","?") #' #' @return Returns \code{TRUE} if sequences are equal and \code{FALSE} if they are not. #' Sequences of unequal length will always return \code{FALSE} regardless of #' their character values. #' #' @seealso Used by \link{pairwiseEqual} within \link{collapseDuplicates}. #' See \link{seqDist} for calculation Hamming distances between sequences. #' #' @examples #' # Ignore gaps #' seqEqual("ATG-C", "AT--C") #' seqEqual("ATGGC", "ATGGN") #' seqEqual("AT--T", "ATGGC") #' #' # Ignore only Ns #' seqEqual("ATG-C", "AT--C", ignore="N") #' seqEqual("ATGGC", "ATGGN", ignore="N") #' seqEqual("AT--T", "ATGGC", ignore="N") #' #' @export seqEqual <- function(seq1, seq2, ignore = as.character( c("N","-",".","?"))) { .Call(`_alakazam_seqEqual`, seq1, seq2, ignore) } #' Calculate pairwise equivalence between sequences #' #' \code{pairwiseEqual} determined pairwise equivalence between a pairs in a #' set of sequences, excluding ambiguous positions (Ns and gaps). #' #' @param seq character vector containing a DNA sequences. #' #' @return A logical matrix of equivalence between each entry in \code{seq}. #' Values are \code{TRUE} when sequences are equivalent and \code{FALSE} #' when they are not. #' #' @seealso Uses \link{seqEqual} for testing equivalence between pairs. #' See \link{pairwiseDist} for generating a sequence distance matrix. #' #' @examples #' # Gaps and Ns will match any character #' seq <- c(A="ATGGC", B="ATGGG", C="ATGGG", D="AT--C", E="NTGGG") #' d <- pairwiseEqual(seq) #' rownames(d) <- colnames(d) <- seq #' d #' #' @export pairwiseEqual <- function(seq) { .Call(`_alakazam_pairwiseEqual`, seq) } seqDistRcpp <- function(seq1, seq2, dist_mat) { .Call(`_alakazam_seqDistRcpp`, seq1, seq2, dist_mat) } pairwiseDistRcpp <- function(seq, dist_mat) { .Call(`_alakazam_pairwiseDistRcpp`, seq, dist_mat) } nonsquareDistRcpp <- function(seq, indx, dist_mat) { .Call(`_alakazam_nonsquareDistRcpp`, seq, indx, dist_mat) } alakazam/R/Classes.R0000644000176200001440000003024113512442156013757 0ustar liggesusers# Classes, Generics and Methods #### Generics #### # @exportMethod print #setGeneric("print") # @exportMethod plot #setGeneric("plot") setClassUnion("DfNULL", members=c("data.frame", "NULL")) setClassUnion("CharNULL", members=c("character", "NULL")) #### Diversity classes #### #' S4 class defining a clonal abundance curve #' #' \code{AbundanceCurve} defines clonal abundance values. #' #' @slot abundance data.frame with relative clonal abundance data and confidence intervals, #' containing the following columns: #' \itemize{ #' \item \code{GROUP}: group identifier. #' \item \code{CLONE}: clone identifier. #' \item \code{P}: relative abundance of the clone. #' \item \code{LOWER}: lower confidence inverval bound. #' \item \code{UPPER}: upper confidence interval bound. #' \item \code{RANK}: the rank of the clone abundance. #' } #' @slot bootstrap data.frame of bootstrapped clonal distributions. #' @slot clone_by string specifying the name of the clone column. #' @slot group_by string specifying the name of the grouping column. #' @slot groups vector specifying the names of unique groups in group column. #' @slot n numeric vector indication the number of sequences sampled in each group. #' @slot nboot numeric specifying the number of bootstrap iterations to use. #' @slot ci confidence interval defining the upper and lower bounds #' (a value between 0 and 1). #' #' @name AbundanceCurve-class #' @rdname AbundanceCurve-class #' @aliases AbundanceCurve #' @exportClass AbundanceCurve setClass("AbundanceCurve", slots=c(abundance="data.frame", bootstrap="data.frame", clone_by="character", group_by="character", groups="character", n="numeric", ci="numeric", nboot="numeric")) #' S4 class defining a diversity curve #' #' \code{DiversityCurve} defines diversity (\eqn{D}) scores over multiple diversity #' orders (\eqn{Q}). #' #' @slot diversity data.frame defining the diversity curve with the following columns: #' \itemize{ #' \item \code{GROUP}: group label. #' \item \code{Q}: diversity order. #' \item \code{D}: mean diversity index over all bootstrap #' realizations. #' \item \code{D_SD}: standard deviation of the diversity index #' over all bootstrap realizations. #' \item \code{D_LOWER}: diversity lower confidence inverval bound. #' \item \code{D_UPPER}: diversity upper confidence interval bound. #' \item \code{E}: evenness index calculated as \code{D} #' divided by \code{D} at \code{Q=0}. #' \item \code{E_LOWER}: evenness lower confidence inverval bound. #' \item \code{E_UPPER}: eveness upper confidence interval bound. #' } #' @slot tests data.frame describing the significance test results with columns: #' \itemize{ #' \item \code{TEST}: string listing the two groups tested. #' \item \code{DELTA_MEAN}: mean of the \eqn{D} bootstrap delta #' distribution for the test. #' \item \code{DELTA_SD}: standard deviation of the \eqn{D} #' bootstrap delta distribution for the test. #' \item \code{PVALUE}: p-value for the test. #' } #' @slot group_by string specifying the name of the grouping column in diversity calculation. #' @slot groups vector specifying the names of unique groups in group column in diversity calculation. #' @slot method string specifying the type of diversity calculated. #' @slot q vector of diversity hill diversity indices used for computing diversity. #' @slot n numeric vector indication the number of sequences sampled in each group. #' @slot ci confidence interval defining the upper and lower bounds #' (a value between 0 and 1). #' #' @name DiversityCurve-class #' @rdname DiversityCurve-class #' @aliases DiversityCurve #' @exportClass DiversityCurve setClass("DiversityCurve", slots=c(diversity="data.frame", tests="DfNULL", method="character", group_by="character", groups="character", q="numeric", n="numeric", ci="numeric")) #### Diversity methods #### #' @param x AbundanceCurve object #' #' @rdname AbundanceCurve-class #' @aliases AbundanceCurve-method #' @export setMethod("print", c(x="AbundanceCurve"), function(x) { print(x@abundance) }) #' @param y ignored. #' @param ... arguments to pass to \link{plotDiversityCurve}. #' #' @rdname AbundanceCurve-class #' @aliases AbundanceCurve-method #' @export setMethod("plot", c(x="AbundanceCurve", y="missing"), function(x, y, ...) { plotAbundanceCurve(x, ...) }) #' @param x DiversityCurve object #' #' @rdname DiversityCurve-class #' @aliases DiversityCurve-method #' @export setMethod("print", c(x="DiversityCurve"), function(x) { print(x@diversity) }) #' @param y diversity order to plot (q). #' @param ... arguments to pass to \link{plotDiversityCurve} or \link{plotDiversityTest}. #' #' @rdname DiversityCurve-class #' @aliases DiversityCurve-method #' @export setMethod("plot", c(x="DiversityCurve", y="missing"), function(x, y, ...) { plotDiversityCurve(x, ...) }) #' @rdname DiversityCurve-class #' @aliases DiversityCurve-method #' @export setMethod("plot", c(x="DiversityCurve", y="numeric"), function(x, y, ...) { plotDiversityTest(x, y, ...) }) #### Lineage classes #### #' S4 class defining a clone #' #' \code{ChangeoClone} defines a common data structure for perform lineage recontruction #' from Change-O data. #' #' @slot data data.frame containing sequences and annotations. Contains the #' columns \code{SEQUENCE_ID} and \code{SEQUENCE}, as well as any additional #' sequence-specific annotation columns. #' @slot clone string defining the clone identifier. #' @slot germline string containing the germline sequence for the clone. #' @slot v_gene string defining the V segment gene call. #' @slot j_gene string defining the J segment gene call. #' @slot junc_len numeric junction length (nucleotide count). #' #' @seealso See \link{makeChangeoClone} and \link{buildPhylipLineage} for use. #' #' @name ChangeoClone-class #' @rdname ChangeoClone-class #' @aliases ChangeoClone #' @exportClass ChangeoClone setClass("ChangeoClone", slots=c(data="data.frame", clone="character", germline="character", v_gene="character", j_gene="character", junc_len="numeric")) #### Topology classes #### #' S4 class defining edge significance #' #' \code{MRCATest} defines the significance of enrichment for annotations appearing at #' the MRCA of the tree. #' #' @slot tests data.frame describing the significance test results with columns: #' \itemize{ #' \item \code{ANNOTATION}: annotation value. #' \item \code{COUNT}: observed count of MRCA positions #' with the given annotation. #' \item \code{EXPECTED}: expected mean count of MRCA occurance #' for the annotation. #' \item \code{PVALUE}: one-sided p-value for the hypothesis that #' the observed annotation abundance is greater #' than expected. #' } #' @slot permutations data.frame containing the raw permutation test data with columns: #' \itemize{ #' \item \code{ANNOTATION}: annotation value. #' \item \code{COUNT}: count of MRCA positions with the #' given annotation. #' \item \code{ITER}: numerical index define which #' permutation realization each #' observation corresponds to. #' } #' @slot nperm number of permutation realizations. #' #' @name MRCATest-class #' @rdname MRCATest-class #' @aliases MRCATest #' @exportClass MRCATest setClass("MRCATest", slots=c(tests="data.frame", permutations="data.frame", nperm="numeric")) #' S4 class defining edge significance #' #' \code{EdgeTest} defines the significance of parent-child annotation enrichment. #' #' @slot tests data.frame describing the significance test results with columns: #' \itemize{ #' \item \code{PARENT}: parent node annotation. #' \item \code{CHILD}: child node annotation #' \item \code{COUNT}: count of observed edges with the given #' parent-child annotation set. #' \item \code{EXPECTED}: mean count of expected edges for the #' given parent-child relationship. #' \item \code{PVALUE}: one-sided p-value for the hypothesis that #' the observed edge abundance is greater #' than expected. #' } #' @slot permutations data.frame containing the raw permutation test data with columns: #' \itemize{ #' \item \code{PARENT}: parent node annotation. #' \item \code{CHILD}: child node annotation #' \item \code{COUNT}: count of edges with the given parent-child #' annotation set. #' \item \code{ITER}: numerical index define which permutation #' realization each observation corresponds #' to. #' } #' @slot nperm number of permutation realizations. #' #' @name EdgeTest-class #' @rdname EdgeTest-class #' @aliases EdgeTest #' @exportClass EdgeTest setClass("EdgeTest", slots=c(tests="data.frame", permutations="data.frame", nperm="numeric")) #### Topology methods #### #' @param x MRCATest object. #' #' @rdname MRCATest-class #' @aliases MRCATest-method #' @export setMethod("print", c(x="MRCATest"), function(x) { print(x@tests) }) #' @param y ignored. #' @param ... arguments to pass to \link{plotMRCATest}. #' #' @rdname MRCATest-class #' @aliases MRCATest-method #' @export setMethod("plot", c(x="MRCATest", y="missing"), function(x, y, ...) { plotMRCATest(x, ...) }) #' @param x EdgeTest object. #' #' @rdname EdgeTest-class #' @aliases EdgeTest-method #' @export setMethod("print", c(x="EdgeTest"), function(x) { print(x@tests) }) #' @param y ignored. #' @param ... arguments to pass to \link{plotEdgeTest}. #' #' @rdname EdgeTest-class #' @aliases EdgeTest-method #' @export setMethod("plot", c(x="EdgeTest", y="missing"), function(x, y, ...) { plotEdgeTest(x, ...) })alakazam/R/Data.R0000644000176200001440000002021113402556374013235 0ustar liggesusers# Documentation and definitions for data and constants #### Sysdata #### # 1x20 vector of default amino acid hydropathy scores # HYDROPATHY_KYTJ82 # 1x20 vector of default amino acid bulkiness scores # BULKINESS_ZIMJ68 # 1x20 vector of default amino acid polarity scores # POLARITY_GRAR74 # 1x7 vector of default amino acid pK values # PK_EMBOSS #### Data #### #' Example Change-O database #' #' A small example database subset from Laserson and Vigneault et al, 2014. #' #' @format A data.frame with the following Change-O style columns: #' \itemize{ #' \item \code{SEQUENCE_ID}: Sequence identifier #' \item \code{SEQUENCE_IMGT}: IMGT-gapped observed sequence. #' \item \code{GERMLINE_IMGT_D_MASK}: IMGT-gapped germline sequence with N, P and #' D regions masked. #' \item \code{V_CALL}: V region allele assignments. #' \item \code{V_CALL_GENOTYPED}: TIgGER corrected V region allele assignment. #' \item \code{D_CALL}: D region allele assignments. #' \item \code{J_CALL}: J region allele assignments. #' \item \code{JUNCTION}: Junction region sequence. #' \item \code{JUNCTION_LENGTH}: Length of the junction region in nucleotides. #' \item \code{NP1_LENGTH}: Combined length of the N and P regions proximal #' to the V region. #' \item \code{NP2_LENGTH}: Combined length of the N and P regions proximal #' to the J region. #' \item \code{SAMPLE}: Sample identifier. Time in relation to vaccination. #' \item \code{ISOTYPE}: Isotype assignment. #' \item \code{DUPCOUNT}: Copy count (number of duplicates) of the sequence. #' \item \code{CLONE}: Change-O assignment clonal group identifier. #' } #' #' @seealso \link{ExampleTrees} #' #' @references #' \enumerate{ #' \item Laserson U and Vigneault F, et al. High-resolution antibody dynamics of #' vaccine-induced immune responses. #' Proc Natl Acad Sci USA. 2014 111:4928-33. #' } "ExampleDb" #' Example Ig lineage trees #' #' A set of Ig lineage trees generated from the \code{ExampleDb} file, subset to #' only those trees with at least four nodes. #' #' @format A list of igraph objects output by \link{buildPhylipLineage}. #' Each node of each tree has the following annotations (vertex attributes): #' \itemize{ #' \item \code{SAMPLE}: Sample identifier(s). Time in relation to vaccination. #' \item \code{ISOTYPE}: Isotype assignment(s). #' \item \code{DUPCOUNT}: Copy count (number of duplicates) of the sequence. #' } #' #' @seealso \link{ExampleTrees} "ExampleTrees" #### Constants #### #' Default colors #' #' Default color palettes for DNA characters, Ig isotypes, and TCR chains. #' #' @format Named character vectors with hexcode colors as values. #' \itemize{ #' \item \code{DNA_COLORS}: DNA character colors #' \code{c("A", "C", "G", "T")}. #' \item \code{IG_COLORS}: Ig isotype colors #' \code{c("IgA", "IgD", "IgE", "IgG", "IgM", "IgK", "IgL")}. #' \item \code{TR_COLORS}: TCR chain colors #' \code{c("TRA", "TRB", "TRD", "TRG")}. #' } #' #' @examples #' # IG_COLORS as an isotype color set for ggplot #' isotype <- c("IgG", "IgM", "IgM", "IgA") #' db <- data.frame(x=1:4, y=1:4, iso=isotype) #' g1 <- ggplot(db, aes(x=x, y=y, color=iso)) + #' scale_color_manual(name="Isotype", values=IG_COLORS) + #' geom_point(size=10) #' plot(g1) #' #' # DNA_COLORS to translate nucleotide values to a vector of colors #' # for use in base graphics plots #' seq <- c("A", "T", "T", "C") #' colors <- translateStrings(seq, setNames(names(DNA_COLORS), DNA_COLORS)) #' plot(1:4, 1:4, col=colors, pch=16, cex=6) #' #' @name DEFAULT_COLORS NULL #' @rdname DEFAULT_COLORS #' @export DNA_COLORS <- c("A"="#64F73F", "C"="#FFB340", "G"="#EB413C", "T"="#3C88EE") #' @rdname DEFAULT_COLORS #' @export IG_COLORS <- c("IgA"="#377EB8", "IgD"="#FF7F00", "IgE"="#E41A1C", "IgG"="#4DAF4A", "IgM"="#984EA3", "IgK"="#E5C494", "IgL"="#FFD92F") #' @rdname DEFAULT_COLORS #' @export TR_COLORS <- c("TRA"="#CBD5E8", "TRB"="#F4CAE4", "TRD"="#FDCDAC", "TRG"="#E6F5C9") #' IUPAC ambiguous characters #' #' A translation list mapping IUPAC ambiguous characters code to corresponding nucleotide #' amino acid characters. #' #' @format A list with single character codes as names and values containing character #' vectors that define the set of standard characters that match to each each #' ambiguous character. #' \itemize{ #' \item \code{IUPAC_DNA}: DNA ambiguous character translations. #' \item \code{IUPAC_AA}: Amino acid ambiguous character translations. #' } #' #' @name IUPAC_CODES NULL #' @rdname IUPAC_CODES #' @export IUPAC_DNA <- list("A"="A", "C"="C", "G"="G", "T"="T", "M"=c("A","C"), "R"=c("A","G"), "W"=c("A","T"), "S"=c("C","G"), "Y"=c("C","T"), "K"=c("G","T"), "V"=c("A","C","G"), "H"=c("A","C","T"), "D"=c("A","G","T"), "B"=c("C","G","T"), "N"=c("A","C","G","T")) #' @rdname IUPAC_CODES #' @export IUPAC_AA <- list("A"="A", "B"=c("N","R"), "C"="C", "D"="D", "E"="E", "F"="F", "G"="G", "H"="H", "I"="I", "J"=c("I","L"), "K"="K", "L"="L", "M"="M", "N"="N", "P"="P", "Q"="Q", "R"="R", "S"="S", "T"="T", "V"="V", "W"="W", "X"=c("A","B","C","D","E","F","G","H", "I","J","K","L","M","N","P","Q", "R","S","T","V","W","X","Y","Z", "*"), "Y"="Y", "Z"=c("E","Q"), "*"="*") #' Amino acid abbreviation translations #' #' Mappings of amino acid abbreviations. #' #' @format Named character vector defining single-letter character codes to #' three-letter abbreviation mappings. #' #' @name ABBREV_AA #' #' @examples #' aa <- c("Ala", "Ile", "Trp") #' translateStrings(aa, ABBREV_AA) #' #' @export ABBREV_AA <- c("A"="Ala", "R"="Arg", "N"="Asn", "D"="Asp", "C"="Cys", "Q"="Gln", "E"="Glu", "G"="Gly", "H"="His", "I"="Ile", "L"="Leu", "K"="Lys", "M"="Met", "F"="Phe", "P"="Pro", "S"="Ser", "T"="Thr", "W"="Trp", "Y"="Tyr", "V"="Val") #' IMGT V-segment regions #' #' A list defining the boundaries of V-segment framework regions (FWRs) and complementarity #' determining regions (CDRs) for IMGT-gapped immunoglobulin (Ig) nucleotide sequences #' according to the IMGT numbering scheme. #' #' @format A list with regions named one of \code{c("FWR1", "CDR1", "FWR2", "CDR2", "FWR3")} #' with values containing a numeric vector of length two defining the #' \code{c(start, end)} positions of the named region. #' #' @references #' \url{http://imgt.org} #' #' @export IMGT_REGIONS <- list("FWR1"=c(1, 78), "CDR1"=c(79, 114), "FWR2"=c(115, 165), "CDR2"=c(166, 195), "FWR3"=c(196, 312))alakazam/R/Topology.R0000644000176200001440000010730313512442156014202 0ustar liggesusers# Ig lineage topology analysis #' @include Classes.R NULL #### Graph analysis functions #### #' Generate subtree summary statistics for a tree #' #' \code{summarizeSubtrees} calculates summary statistics for each node of a tree. Includes #' both node properties and subtree properties. #' #' @param graph igraph object containing an annotated lineage tree. #' @param fields annotation fields to add to the output. #' @param root name of the root (germline) node. #' #' @return A data.frame with columns: #' \itemize{ #' \item \code{NAME}: node name. #' \item \code{PARENT}: name of the parent node. #' \item \code{OUTDEGREE}: number of edges leading from the node. #' \item \code{SIZE}: total number of nodes within the subtree rooted #' at the node. #' \item \code{DEPTH}: the depth of the subtree that is rooted at #' the node. #' \item \code{PATHLENGTH}: the maximum pathlength beneath the node. #' \item \code{OUTDEGREE_NORM}: \code{OUTDEGREE} normalized by the total #' number of edges. #' \item \code{SIZE_NORM}: \code{SIZE} normalized by the largest #' subtree size (the germline). #' \item \code{DEPTH_NORM}: \code{DEPTH} normalized by the largest #' subtree depth (the germline). #' \item \code{PATHLENGTH_NORM}: \code{PATHLEGNTH} normalized by the largest #' subtree pathlength (the germline). #' } #' An additional column corresponding to the value of \code{field} is added when #' specified. #' #' @seealso See \link{buildPhylipLineage} for generating input trees. #' See \link{getPathLengths} for calculating path length to nodes. #' #' @examples #' # Summarize a tree #' graph <- ExampleTrees[[23]] #' summarizeSubtrees(graph, fields="ISOTYPE", root="Germline") #' #' @export summarizeSubtrees <- function(graph, fields=NULL, root="Germline") { ## DEBUG # root="Germline"; fields=NULL # TODO: should probably include a means to exclude inferred from substree size # Define node attribute data.frame node_df <- data.frame(NAME=V(graph)$name, stringsAsFactors=F) for (f in fields) { node_df[[f]] <- vertex_attr(graph, name=f) } # Get edges edges <- igraph::as_edgelist(graph) # Get unweighted paths paths_step <- suppressWarnings(igraph::distances(graph, mode="out", algorithm="unweighted")) paths_step[!is.finite(paths_step)] <- NA # Get weighted paths paths_length <- igraph::distances(graph, mode="out", algorithm="dijkstra") paths_length[!is.finite(paths_length)] <- NA # Define each node's parent node_df$PARENT <- edges[, 1][match(node_df$NAME, edges[, 2])] # Define each node's outdegree node_df$OUTDEGREE <- igraph::degree(graph, mode="out") # Define the number of nodes in each subtree (child count + 1) node_df$SIZE <- apply(paths_step, 1, function(x) length(na.omit(x))) # Define number of levels below each node node_df$DEPTH <- apply(paths_step, 1, max, na.rm=TRUE) + 1 # Define the maximum shortest path length (genetic distance) to a leaf from each node node_df$PATHLENGTH <- apply(paths_length, 1, max, na.rm=TRUE) # Normalize node_df <- node_df %>% dplyr::mutate( OUTDEGREE_NORM=!!rlang::sym("OUTDEGREE")/sum(!!rlang::sym("OUTDEGREE"), na.rm=TRUE), SIZE_NORM=!!rlang::sym("SIZE")/max(!!rlang::sym("SIZE"), na.rm=TRUE), DEPTH_NORM=!!rlang::sym("DEPTH")/max(!!rlang::sym("DEPTH"), na.rm=TRUE), PATHLENGTH_NORM=!!rlang::sym("PATHLENGTH")/max(!!rlang::sym("PATHLENGTH"), na.rm=TRUE)) return(node_df) } #' Calculate path lengths from the tree root #' #' \code{getPathLengths} calculates the unweighted (number of steps) and weighted (distance) #' path lengths from the root of a lineage tree. #' #' @param graph igraph object containing an annotated lineage tree. #' @param root name of the root (germline) node. #' @param field annotation field to use for exclusion of nodes from step count. #' @param exclude annotation values specifying which nodes to exclude from step count. #' If \code{NULL} consider all nodes. This does not affect the weighted #' (distance) path length calculation. #' #' @return A data.frame with columns: #' \itemize{ #' \item \code{NAME}: node name #' \item \code{STEPS}: path length as the number of nodes traversed #' \item \code{DISTANCE}: path length as the sum of edge weights #' } #' #' @seealso See \link{buildPhylipLineage} for generating input trees. #' #' @examples #' # Define example graph #' graph <- ExampleTrees[[24]] #' #' # Consider all nodes #' getPathLengths(graph, root="Germline") #' #' # Exclude nodes without an isotype annotation from step count #' getPathLengths(graph, root="Germline", field="ISOTYPE", exclude=NA) #' #' @export getPathLengths <- function(graph, root="Germline", field=NULL, exclude=NULL) { # Define path length data.frame path_df <- data.frame(NAME=V(graph)$name, stringsAsFactors=FALSE) # Get indices of excluded vertices skip_idx <- which(path_df$NAME == root) if (!is.null(field)) { g <- vertex_attr(graph, name=field) skip_idx <- union(skip_idx, which(g %in% exclude)) } # Get paths step_list <- shortest_paths(graph, root, mode="out", weights=NA, output="vpath") step_list <- step_list$vpath # Get path lengths for (i in 1:length(step_list)) { v <- step_list[[i]] path_df[i, "STEPS"] <- sum(!(v %in% skip_idx)) path_df[i, "DISTANCE"] <- sum(E(graph, path=v)$weight) } return(path_df) } #' Retrieve the first non-root node of a lineage tree #' #' \code{getMRCA} returns the set of lineage tree nodes with the minimum weighted or #' unweighted path length from the root (germline) of the lineage tree, allowing for #' exclusion of specific groups of nodes. #' #' @param graph igraph object containing an annotated lineage tree. #' @param path string defining whether to use unweighted (steps) or weighted (distance) #' measures for determining the founder node set.. #' @param root name of the root (germline) node. #' @param field annotation field to use for both unweighted path length exclusion and #' consideration as an MRCA node. If \code{NULL} do not exclude any nodes. #' @param exclude vector of annotation values in \code{field} to exclude from the potential #' MRCA set. If \code{NULL} do not exclude any nodes. Has no effect if #' \code{field=NULL}. #' #' @return A data.frame of the MRCA node(s) containing the columns: #' \itemize{ #' \item \code{NAME}: node name #' \item \code{STEPS}: path length as the number of nodes traversed #' \item \code{DISTANCE}: path length as the sum of edge weights #' } #' Along with additional columns corresponding to the #' annotations of the input graph. #' #' @seealso Path lengths are determined with \link{getPathLengths}. #' #' @examples #' # Define example graph #' graph <- ExampleTrees[[23]] #' #' # Use unweighted path length and do not exclude any nodes #' getMRCA(graph, path="steps", root="Germline") #' #' # Exclude nodes without an isotype annotation and use weighted path length #' getMRCA(graph, path="distance", root="Germline", field="ISOTYPE", exclude=NA) #' #' @export getMRCA <- function(graph, path=c("distance", "steps"), root="Germline", field=NULL, exclude=NULL) { # Check arguments path <- match.arg(path) # Get distance from root path_df <- getPathLengths(graph, root=root, field=field, exclude=exclude) # Get indices of excluded vertices skip_idx <- which(path_df$NAME == root) if (!is.null(field)) { g <- vertex_attr(graph, name=field) skip_idx <- union(skip_idx, which(g %in% exclude)) } # Get founder nodes if (path == "distance") { path_len <- setNames(path_df$DISTANCE, 1:nrow(path_df)) } else if (path == "steps") { path_len <- setNames(path_df$STEPS, 1:nrow(path_df)) } else { stop("Invalid value for 'path' parameter. Must be one of c('distance', 'steps').\n") } path_len <- path_len[-skip_idx] root_idx <- as.numeric(names(path_len)[which(path_len == min(path_len))]) root_df <- igraph::as_data_frame(graph, what="vertices")[root_idx, ] root_df$STEPS <- path_df$STEPS[root_idx] root_df$DISTANCE <- path_df$DISTANCE[root_idx] # Switch name column to uppercase names(root_df)[names(root_df) == "name"] <- "NAME" return(root_df) } #' Tabulate the number of edges between annotations within a lineage tree #' #' \code{tableEdges} creates a table of the total number of connections (edges) for each #' unique pair of annotations within a tree over all nodes. #' #' @param graph igraph object containing an annotated lineage tree. #' @param field string defining the annotation field to count. #' @param indirect if \code{FALSE} count direct connections (edges) only. If #' \code{TRUE} walk through any nodes with annotations specified in #' the \code{argument} to count indirect connections. Specifying #' \code{indirect=TRUE} with \code{exclude=NULL} will have no effect. #' @param exclude vector of strings defining \code{field} values to exclude from counts. #' Edges that either start or end with the specified annotations will not #' be counted. If \code{NULL} count all edges. #' #' @return A data.frame defining total annotation connections in the tree with columns: #' \itemize{ #' \item \code{PARENT}: parent annotation #' \item \code{CHILD}: child annotation #' \item \code{COUNT}: count of edges for the parent-child relationship #' } #' #' @seealso See \link{testEdges} for performed a permutation test on edge relationships. #' #' @examples #' # Define example graph #' graph <- ExampleTrees[[23]] #' #' # Count direct edges between isotypes including inferred nodes #' tableEdges(graph, "ISOTYPE") #' #' # Count direct edges excluding edges to and from germline and inferred nodes #' tableEdges(graph, "ISOTYPE", exclude=c("Germline", NA)) #' #' # Count indirect edges walking through germline and inferred nodes #' tableEdges(graph, "ISOTYPE", indirect=TRUE, exclude=c("Germline", NA)) #' #' @export tableEdges <- function(graph, field, indirect=FALSE, exclude=NULL) { # Function to retrieve the name if x is exactly one vertex index and NULL otherwise .getSingleVertex <- function(x) { if (length(x) == 1) { vertex_attr(graph, name=field, index=x[1]) } else { NULL } } if (indirect) { # Get indices of excluded and retained vertices if (!is.null(exclude)) { f <- vertex_attr(graph, name=field) skip_idx <- which(f %in% exclude) keep_idx <- as.numeric(V(graph))[-skip_idx] } else { skip_idx <- NULL keep_idx <- as.numeric(V(graph)) } # Iterate over nodes and count indirect parent-child connections edge_list <- list() for (i in keep_idx) { # Get parent annotation parent <- vertex_attr(graph, name=field, index=i) # Get indirect child node annotations step_list <- suppressWarnings(shortest_paths(graph, V(graph)[i], mode="out", weights=NA, output="vpath")) step_list <- unique(lapply(step_list$vpath, function(x) x[!(x %in% c(i, skip_idx))])) children <- unlist(lapply(step_list, .getSingleVertex)) # Define data.frame of connections if (length(children) > 0) { edge_list[[i]] <- data.frame("PARENT"=parent, "CHILD"=children, stringsAsFactors=FALSE) } } # Merge edge list into data.frame edge_df <- bind_rows(edge_list) } else { # Get adjacency list edge_mat <- as_edgelist(graph, names=FALSE) edge_mat <- vertex_attr(graph, name=field, index=edge_mat) edge_mat <- matrix(edge_mat, ncol=2, dimnames=list(NULL, c("PARENT", "CHILD"))) # Build and subset edge data.frame edge_df <- as.data.frame(edge_mat, stringsAsFactors=FALSE) edge_df <- edge_df[!(edge_df$PARENT %in% exclude) & !(edge_df$CHILD %in% exclude), ] } # Count edges edge_tab <- edge_df %>% group_by(!!!rlang::syms(c("PARENT", "CHILD"))) %>% dplyr::summarize(COUNT=n()) return(edge_tab) } #' Permute the node labels of a tree #' #' \code{permuteLabels} permutes the node annotations of a lineage tree. #' #' @param graph igraph object containing an annotated lineage tree. #' @param field string defining the annotation field to permute. #' @param exclude vector of strings defining \code{field} values to exclude #' from permutation. #' #' @return A modified igraph object with vertex annotations permuted. #' #' @seealso \link{testEdges}. #' #' @examples #' # Define and plot example graph #' library(igraph) #' graph <- ExampleTrees[[23]] #' plot(graph, layout=layout_as_tree, vertex.label=V(graph)$ISOTYPE, #' vertex.size=50, edge.arrow.mode=0, vertex.color="grey80") #' #' # Permute annotations and plot new tree #' g <- permuteLabels(graph, "ISOTYPE") #' plot(g, layout=layout_as_tree, vertex.label=V(g)$ISOTYPE, #' vertex.size=50, edge.arrow.mode=0, vertex.color="grey80") #' #' @export permuteLabels <- function(graph, field, exclude=c("Germline", NA)) { # Determine which nodes to permute labels <- vertex_attr(graph, name=field) i <- which(!(labels %in% exclude)) # Return input on insufficient number of nodes if (length(i) < 2) { warning("Only 1 node to permute\n") return(graph) } # Sample and reassign field values s <- sample(i) perm <- set_vertex_attr(graph, name=field, index=i, value=labels[s]) return(perm) } #### Test functions #### #' Tests for MRCA annotation enrichment in lineage trees #' #' \code{testMRCA} performs a permutation test on a set of lineage trees to determine #' the significance of an annotation's association with the MRCA position of the lineage #' trees. #' #' @param graphs list of igraph object containing annotated lineage trees. #' @param field string defining the annotation field to test. #' @param root name of the root (germline) node. #' @param exclude vector of strings defining \code{field} values to exclude from the #' set of potential founder annotations. #' @param nperm number of permutations to perform. #' @param progress if \code{TRUE} show a progress bar. #' #' @return An \link{MRCATest} object containing the test results and permutation #' realizations. #' #' @seealso Uses \link{getMRCA} and \link{getPathLengths}. #' See \link{plotMRCATest} for plotting the permutation distributions. #' #' @examples #' \donttest{ #' # Define example tree set #' graphs <- ExampleTrees[1-10] #' #' # Perform MRCA test on isotypes #' x <- testMRCA(graphs, "ISOTYPE", nperm=10) #' print(x) #' } #' #' @export testMRCA <- function(graphs, field, root="Germline", exclude=c("Germline", NA), nperm=200, progress=FALSE) { # Function to resolve ambiguous founders # @param x data.frame from getMRCA # @param field annotation field .resolveMRCA <- function(x, field) { x %>% filter(!duplicated(!!rlang::sym(field))) %>% filter(length(!!rlang::sym(field)) == 1) } # Function to count MRCAs # @param x list of graphs # @param field annotation field # @param exclude vector of annotation values to exclude .countMRCA <- function(x, field, exclude) { # Get MRCAs mrca_list <- lapply(x, getMRCA, path="distance", field=field, exclude=exclude) # Resolve ambiguous MRCAs mrca_list <- lapply(mrca_list, .resolveMRCA, field=field) # Summarize MRCA counts mrca_sum <- bind_rows(mrca_list, .id="GRAPH") %>% select(!!!rlang::syms(c("GRAPH", field))) %>% rename("ANNOTATION"=field) %>% group_by(!!rlang::sym("ANNOTATION")) %>% dplyr::summarize(COUNT=n()) return(mrca_sum) } # Assign numeric names if graphs is an unnamed list if (is.null(names(graphs))) { names(graphs) <- 1:length(graphs) } # Summarize observed MRCA counts obs_sum <- .countMRCA(graphs, field=field, exclude=exclude) # Generate edge null distribution via permutation if (progress) { pb <- progressBar(nperm) } perm_list <- list() for (i in 1:nperm) { # Permute labels tmp_list <- lapply(graphs, permuteLabels, field=field, exclude=exclude) # Summarize MRCA counts tmp_sum <- .countMRCA(tmp_list, field=field, exclude=exclude) # Update permutation set tmp_sum$ITER <- i perm_list[[i]] <- tmp_sum if (progress) { pb$tick() } } cat("\n") perm_sum <- bind_rows(perm_list) # Test observed against permutation distribution for (i in 1:nrow(obs_sum)) { x <- obs_sum$ANNOTATION[i] # Annotation count distribution d <- perm_sum$COUNT[perm_sum$ANNOTATION == x] # Expected mean obs_sum[i, "EXPECTED"] <- mean(d) # P-value for observed > expected f <- ecdf(d) obs_sum[i, "PVALUE"] <- 1 - f(obs_sum$COUNT[i]) } # Generate return object mrca_test <- new("MRCATest", tests=as.data.frame(obs_sum), permutations=as.data.frame(perm_sum), nperm=nperm) return(mrca_test) } #' Tests for parent-child annotation enchrichment in lineage trees #' #' \code{testEdges} performs a permutation test on a set of lineage trees to determine #' the significance of an annotation's association with parent-child relationships. #' #' @param graphs list of igraph objects with vertex annotations. #' @param field string defining the annotation field to permute. #' @param indirect if \code{FALSE} count direct connections (edges) only. If #' \code{TRUE} walk through any nodes with annotations specified in #' the \code{argument} to count indirect connections. Specifying #' \code{indirect=TRUE} with \code{exclude=NULL} will have no effect. #' @param exclude vector of strings defining \code{field} values to exclude from #' permutation. #' @param nperm number of permutations to perform. #' @param progress if \code{TRUE} show a progress bar. #' #' @return An \link{EdgeTest} object containing the test results and permutation #' realizations. #' #' @seealso Uses \link{tableEdges} and \link{permuteLabels}. #' See \link{plotEdgeTest} for plotting the permutation distributions. #' #' @examples #' \donttest{ #' # Define example tree set #' graphs <- ExampleTrees[1-10] #' #' # Perform edge test on isotypes #' x <- testEdges(graphs, "ISOTYPE", nperm=10) #' print(x) #' } #' #' @export testEdges <- function(graphs, field, indirect=FALSE, exclude=c("Germline", NA), nperm=200, progress=FALSE) { ## DEBUG # field="isotype"; exclude=c("Germline", NA); nperm=200 # Assign numeric names if graphs is an unnamed list if (is.null(names(graphs))) { names(graphs) <- 1:length(graphs) } # Function to count edge annotations # @param x list of graphs # @param field annotation field # @param exclude vector of annotation values to exclude .countEdges <- function(x, field, exclude) { edge_list <- lapply(x, tableEdges, field=field, indirect=indirect, exclude=exclude) edge_sum <- bind_rows(edge_list) %>% group_by(!!!rlang::syms(c("PARENT", "CHILD"))) %>% dplyr::summarize(COUNT=sum(!!rlang::sym("COUNT"), na.rm=TRUE)) return(edge_sum) } # Count edges of observed data obs_sum <- .countEdges(graphs, field, exclude) if (nrow(obs_sum) == 0) { stop("No valid edges found in graphs") } # Generate edge null distribution via permutation if (progress) { pb <- progressBar(nperm) } perm_list <- list() for (i in 1:nperm) { # Permute annotations tmp_list <- lapply(graphs, permuteLabels, field=field, exclude=exclude) # Count edges tmp_sum <- .countEdges(tmp_list, field, exclude) # Update permutation set tmp_sum$ITER <- i perm_list[[i]] <- tmp_sum if (progress) { pb$tick() } } perm_sum <- bind_rows(perm_list) # Test observed against permutation distribution for (i in 1:nrow(obs_sum)) { x <- obs_sum$PARENT[i] y <- obs_sum$CHILD[i] # Edge count distribution d <- perm_sum$COUNT[perm_sum$PARENT == x & perm_sum$CHILD == y] # Expected mean obs_sum[i, "EXPECTED"] <- mean(d) # P-value for observed > expected f <- ecdf(d) obs_sum[i, "PVALUE"] <- 1 - f(obs_sum$COUNT[i]) } # Generate return object edge_test <- new("EdgeTest", tests=as.data.frame(obs_sum), permutations=as.data.frame(perm_sum), nperm=nperm) return(edge_test) } #### Plotting functions ##### #' Plot the results of an edge permutation test #' #' \code{plotEdgeTest} plots the results of an edge permutation test performed with #' \code{testEdges} as either a histogram or cumulative distribution function. #' #' @param data \link{EdgeTest} object returned by \link{testEdges}. #' @param color color of the histogram or lines. #' @param main_title string specifying the plot title. #' @param style type of plot to draw. One of: #' \itemize{ #' \item \code{"histogram"}: histogram of the edge count #' distribution with a red dotted line #' denoting the observed value. #' \item \code{"cdf"}: cumulative distribution function #' of edge counts with a red dotted #' line denoting the observed value and #' a blue dotted line indicating the #' p-value. #' } #' @param silent if \code{TRUE} do not draw the plot and just return the ggplot2 #' object; if \code{FALSE} draw the plot. #' @param ... additional arguments to pass to ggplot2::theme. #' #' @return A \code{ggplot} object defining the plot. #' #' @seealso See \link{testEdges} for performing the test. #' #' @examples #' \donttest{ #' # Define example tree set #' graphs <- ExampleTrees[1-10] #' #' # Perform edge test on isotypes #' x <- testEdges(graphs, "ISOTYPE", nperm=10) #' #' # Plot #' plotEdgeTest(x, color="steelblue", style="hist") #' plotEdgeTest(x, style="cdf") #' } #' #' @export plotEdgeTest <- function(data, color="black", main_title="Edge Test", style=c("histogram", "cdf"), silent=FALSE, ...) { # Check arguments style <- match.arg(style) # Extract plot data obs_sum <- rename(data@tests, "Parent"="PARENT", "Child"="CHILD") perm_sum <- rename(data@permutations, "Parent"="PARENT", "Child"="CHILD") if (style == "histogram") { # Plot edge null distribution p1 <- ggplot(perm_sum, aes_string(x="COUNT")) + baseTheme() + ggtitle(main_title) + xlab("Number of edges") + ylab("Number of realizations") + geom_histogram(bins=50, fill=color, color=NA) + geom_vline(data=obs_sum, aes_string(xintercept="COUNT"), color="firebrick", linetype=3, size=0.75) + facet_grid("Child ~ Parent", labeller=label_both, scales="free") } else if (style == "cdf") { # Plot ECDF of edge null distribution p1 <- ggplot(perm_sum, aes_string(x="COUNT")) + baseTheme() + ggtitle(main_title) + xlab("Number of edges") + ylab("P-value") + stat_ecdf(color=color, size=1) + geom_vline(data=obs_sum, aes_string(xintercept="COUNT"), color="firebrick", linetype=3, size=0.75) + geom_hline(data=obs_sum, aes_string(yintercept="PVALUE"), color="steelblue", linetype=3, size=0.75) + facet_grid("Child ~ Parent", labeller=label_both, scales="free") } # Add additional theme elements p1 <- p1 + do.call(theme, list(...)) # Plot if (!silent) { plot(p1) } invisible(p1) } #' Plot the results of a founder permutation test #' #' \code{plotMRCATest} plots the results of a founder permutation test performed with #' \code{testMRCA}. #' #' @param data \link{MRCATest} object returned by \link{testMRCA}. #' @param color color of the histogram or lines. #' @param main_title string specifying the plot title. #' @param style type of plot to draw. One of: #' \itemize{ #' \item \code{"histogram"}: histogram of the annotation count #' distribution with a red dotted line #' denoting the observed value. #' \item \code{"cdf"}: cumulative distribution function #' of annotation counts with a red dotted #' line denoting the observed value and #' a blue dotted line indicating the #' p-value. #' } #' @param silent if \code{TRUE} do not draw the plot and just return the ggplot2 #' object; if \code{FALSE} draw the plot. #' @param ... additional arguments to pass to ggplot2::theme. #' #' @return A \code{ggplot} object defining the plot. #' #' @seealso See \link{testEdges} for performing the test. #' #' @examples #' \donttest{ #' # Define example tree set #' graphs <- ExampleTrees[1-10] #' #' # Perform MRCA test on isotypes #' x <- testMRCA(graphs, "ISOTYPE", nperm=10) #' #' # Plot #' plotMRCATest(x, color="steelblue", style="hist") #' plotMRCATest(x, style="cdf") #' } #' #' @export plotMRCATest <- function(data, color="black", main_title="MRCA Test", style=c("histogram", "cdf"), silent=FALSE, ...) { # Check arguments style <- match.arg(style) # Extract plot data obs_sum <- rename(data@tests, "Annotation"="ANNOTATION") perm_sum <- rename(data@permutations, "Annotation"="ANNOTATION") if (style == "histogram") { # Plot MRCA null distribution p1 <- ggplot(perm_sum, aes_string(x="COUNT")) + baseTheme() + ggtitle(main_title) + xlab("Number of MRCAs") + ylab("Number of realizations") + geom_histogram(fill=color, color=NA, bins=50) + geom_vline(data=obs_sum, aes_string(xintercept="COUNT"), color="firebrick", linetype=3, size=0.75) + facet_wrap("Annotation", ncol=1, scales="free_y") } else if (style == "cdf") { # Plot ECDF of MRCA null distribution p1 <- ggplot(perm_sum, aes_string(x="COUNT")) + baseTheme() + ggtitle(main_title) + xlab("Number of MRCAs") + ylab("P-value") + stat_ecdf(color=color, size=1) + geom_vline(data=obs_sum, aes_string(xintercept="COUNT"), color="firebrick", linetype=3, size=0.75) + geom_hline(data=obs_sum, aes_string(yintercept="PVALUE"), color="steelblue", linetype=3, size=0.75) + facet_wrap("Annotation", nrow=1, scales="free_y") } # Add additional theme elements p1 <- p1 + do.call(theme, list(...)) # Plot if (!silent) { plot(p1) } invisible(p1) } #' Plots subtree statistics for multiple trees #' #' \code{plotSubtree} plots distributions of normalized subtree statistics for a #' set of lineage trees, broken down by annotation value. #' #' @param graphs list of igraph objects containing annotated lineage trees. #' @param field string defining the annotation field. #' @param stat string defining the subtree statistic to plot. One of: #' \itemize{ #' \item \code{outdegree}: distribution of normalized node #' outdegrees. #' \item \code{size}: distribution of normalized subtree sizes. #' \item \code{depth}: distribution of subtree depths. #' \item \code{pathlength}: distribution of maximum pathlength #' beneath nodes. #' } #' @param root name of the root (germline) node. #' @param exclude vector of strings defining \code{field} values to exclude from #' plotting. #' @param colors named vector of colors for values in \code{field}, with #' names defining annotation names \code{field} column and values #' being colors. Also controls the order in which values appear on the #' plot. If \code{NULL} alphabetical ordering and a default color palette #' will be used. #' @param main_title string specifying the plot title. #' @param legend_title string specifying the legend title. #' @param style string specifying the style of plot to draw. One of: #' \itemize{ #' \item \code{"histogram"}: histogram of the annotation count #' distribution with a red dotted line #' denoting the observed value. #' \item \code{"cdf"}: cumulative distribution function #' of annotation counts with a red #' dotted line denoting the observed #' value and a blue dotted line #' indicating the p-value. #' } #' @param silent if \code{TRUE} do not draw the plot and just return the ggplot2 #' object; if \code{FALSE} draw the plot. #' @param ... additional arguments to pass to ggplot2::theme. #' #' @return A \code{ggplot} object defining the plot. #' #' @seealso Subtree statistics are calculated with \link{summarizeSubtrees}. #' #' @examples #' # Define example tree set #' graphs <- ExampleTrees[1-10] #' #' # Violin plots of node outdegree by sample #' plotSubtrees(graphs, "SAMPLE", "out", style="v") #' #' # Violin plots of subtree size by sample #' plotSubtrees(graphs, "SAMPLE", "size", style="v") #' #' # Boxplot of node depth by isotype #' plotSubtrees(graphs, "ISOTYPE", "depth", style="b") #' #' @export plotSubtrees <- function(graphs, field, stat, root="Germline", exclude=c("Germline", NA), colors=NULL, main_title="Subtrees", legend_title="Annotation", style=c("box", "violin"), silent=FALSE, ...) { # Hack for visibility of special ggplot variables ..x.. <- NULL ## DEBUG # graphs=ExampleTrees; field="ISOTYPE"; colors=IG_COLORS; main_title="Outdegree"; root="Germline"; exclude=c("Germline", NA); style="box" # Check arguments style <- match.arg(style, several.ok=FALSE) stat <- match.arg(stat, choices=c("outdegree", "size", "depth", "pathlength"), several.ok=FALSE) # Set stat column and axis labels if (stat == "outdegree") { stat_col <- "OUTDEGREE_NORM" y_lab <- "Node outdegree" } else if (stat == "size") { stat_col <- "SIZE_NORM" y_lab <- "Substree size" } else if (stat == "depth") { stat_col <- "DEPTH_NORM" y_lab <- "Depth under node" } else if (stat == "pathlength") { stat_col <- "PATHLENGTH_NORM" y_lab <- "Path length under node" } else { stop("Invalid value for 'stat'. How did you get here?") } # Assign numeric names if graphs is an unnamed list if (is.null(names(graphs))) { names(graphs) <- 1:length(graphs) } # Get subtree summarizes and filter excluded annotations sum_list <- lapply(graphs, summarizeSubtrees, fields=field, root=root) sum_df <- bind_rows(sum_list, .id="GRAPH") %>% filter(!(!!rlang::sym(field) %in% exclude), is.finite(!!rlang::sym(stat_col))) # Set ordering based on color names if (!is.null(colors)) { # Assign missing levels to grey x <- unique(sum_df[[field]]) x <- sort(x[!(x %in% names(colors))]) if (length(x) > 0) { warning("The following are missing from the 'colors' argument and will be colored grey: ", paste(x, collapse=" ")) x <- setNames(rep("grey", length(x)), x) colors <- c(colors, x) } # Cast to factor sum_df[[field]] <- factor(sum_df[[field]], levels=names(colors)) } else { sum_df[[field]] <- factor(sum_df[[field]]) } # Make plot object p1 <- ggplot(sum_df, aes_string(x=field, y=stat_col)) + baseTheme() + ggtitle(main_title) + xlab("") + ylab(y_lab) + scale_y_continuous(labels=percent) + expand_limits(y=0) # Add distributions style if (style == "box") { p1 <- p1 + geom_boxplot(aes_string(fill=field), width=0.7, alpha=0.8) } else if (style == "violin") { p1 <- p1 + geom_violin(aes_string(fill=field), adjust=1.5, scale="width", trim=T, width=0.7, alpha=0.8) + geom_errorbarh(aes(xmin=..x.. - 0.4, xmax=..x.. + 0.4), color="black", stat="summary", fun.y="mean", size=1.25, height=0, alpha=0.9) } # Set colors and legend if (!is.null(colors)) { p1 <- p1 + scale_fill_manual(name=legend_title, values=colors) } else { p1 <- p1 + scale_fill_discrete(name=legend_title) } # Add additional theme elements p1 <- p1 + do.call(theme, list(...)) # Plot if (!silent) { plot(p1) } invisible(p1) }alakazam/R/Gene.R0000644000176200001440000014600013513641370013241 0ustar liggesusers# Gene usage analysis #### Calculation functions #### #' Tabulates V(D)J allele, gene or family usage. #' #' Determines the count and relative abundance of V(D)J alleles, genes or families within #' groups. #' #' @param data data.frame with Change-O style columns. #' @param gene column containing allele assignments. Only the first allele in the #' column will be considered when \code{mode} is "gene", "family" or #' "allele". The value will be used as it is with \code{mode="asis"}. #' @param groups columns containing grouping variables. If \code{NULL} do not group. #' @param copy name of the \code{data} column containing copy numbers for each #' sequence. If this value is specified, then total copy abundance #' is determined by the sum of copy numbers within each gene. #' This argument is ignored if \code{clone} is specified. #' @param clone name of the \code{data} column containing clone identifiers for each #' sequence. If this value is specified, then one gene will be considered #' for each clone. Note, this is accomplished by using the most #' common gene within each \code{clone} identifier. As such, #' ambiguous alleles within a clone will not be accurately represented. #' @param mode one of \code{c("gene", "family", "allele", "asis")} defining #' the degree of specificity regarding allele calls. Determines whether #' to return counts for genes (calling \code{getGene}), #' families (calling \code{getFamily}), alleles (calling #' \code{getAllele}) or using the value as it is in the column #' \code{gene}, without any processing. #' @param fill logical of \code{c(TRUE, FALSE)} specifying when if groups (when specified) #' lacking a particular gene should be counted as 0 if TRUE or not (omitted) #' #' @return A data.frame summarizing family, gene or allele counts and frequencies #' with columns: #' \itemize{ #' \item \code{GENE}: name of the family, gene or allele #' \item \code{SEQ_COUNT}: total number of sequences for the gene. #' \item \code{SEQ_FREQ}: frequency of the gene as a fraction of the total #' number of sequences within each grouping. #' \item \code{COPY_COUNT}: sum of the copy counts in the \code{copy} column. #' for each gene. Only present if the \code{copy} #' argument is specified. #' \item \code{COPY_FREQ}: frequency of the gene as a fraction of the total #' copy number within each group. Only present if #' the \code{copy} argument is specified. #' \item \code{CLONE_COUNT}: total number of clones for the gene. #' \item \code{CLONE_FREQ}: frequency of the gene as a fraction of the total #' number of clones within each grouping. #' } #' Additional columns defined by the \code{groups} argument will also be present. #' #' @examples #' # Without copy numbers #' genes <- countGenes(ExampleDb, gene="V_CALL", groups="SAMPLE", mode="family") #' genes <- countGenes(ExampleDb, gene="V_CALL", groups="SAMPLE", mode="gene") #' genes <- countGenes(ExampleDb, gene="V_CALL", groups="SAMPLE", mode="allele") #' #' # With copy numbers and multiple groups #' genes <- countGenes(ExampleDb, gene="V_CALL", groups=c("SAMPLE", "ISOTYPE"), #' copy="DUPCOUNT", mode="family") #' #' # Count by clone #' genes <- countGenes(ExampleDb, gene="V_CALL", groups=c("SAMPLE", "ISOTYPE"), #' clone="CLONE", mode="family") #' #' # Count absent genes #' genes <- countGenes(ExampleDb, gene="V_CALL", groups="SAMPLE", #' mode="allele", fill=TRUE) #' #'@export countGenes <- function(data, gene, groups=NULL, copy=NULL, clone=NULL, fill=FALSE, mode=c("gene", "allele", "family", "asis")) { ## DEBUG # data=ExampleDb; gene="V_CALL"; groups=NULL; mode="gene"; clone="CLONE" # data=subset(db, CLONE == 3138) # Hack for visibility of dplyr variables . <- NULL # Check input mode <- match.arg(mode) check <- checkColumns(data, c(gene, groups, copy)) if (check != TRUE) { stop(check) } # Extract gene, allele or family assignments if (mode != "asis") { gene_func <- switch(mode, allele=getAllele, gene=getGene, family=getFamily) data[[gene]] <- gene_func(data[[gene]], first=TRUE) } # Tabulate abundance if (is.null(copy) & is.null(clone)) { # Tabulate sequence abundance gene_tab <- data %>% group_by(!!!rlang::syms(c(groups, gene))) %>% dplyr::summarize(SEQ_COUNT=n()) %>% mutate(., SEQ_FREQ=!!rlang::sym("SEQ_COUNT")/sum(!!rlang::sym("SEQ_COUNT"), na.rm=TRUE)) %>% arrange(desc(!!rlang::sym("SEQ_COUNT"))) } else if (!is.null(clone) & is.null(copy)) { # Find count of genes within each clone and keep first with maximum count gene_tab <- data %>% group_by(!!!rlang::syms(c(groups, clone, gene))) %>% dplyr::mutate(CLONE_GENE_COUNT=n()) %>% ungroup() %>% group_by(!!!rlang::syms(c(groups, clone))) %>% slice(which.max(!!rlang::sym("CLONE_GENE_COUNT"))) %>% ungroup() %>% group_by(!!!rlang::syms(c(groups, gene))) %>% dplyr::summarize(CLONE_COUNT=n()) %>% mutate(CLONE_FREQ=!!rlang::sym("CLONE_COUNT")/sum(!!rlang::sym("CLONE_COUNT"), na.rm=TRUE)) %>% arrange(!!rlang::sym("CLONE_COUNT")) } else { if (!is.null(clone) & !is.null(copy)) { warning("Specifying both 'copy' and 'clone' columns is not meaningful. ", "The 'clone' argument will be ignored.") } # Tabulate copy abundance gene_tab <- data %>% group_by(!!!rlang::syms(c(groups, gene))) %>% summarize(SEQ_COUNT=length(!!rlang::sym(gene)), COPY_COUNT=sum(!!rlang::sym(copy), na.rm=TRUE)) %>% mutate(SEQ_FREQ=!!rlang::sym("SEQ_COUNT")/sum(!!rlang::sym("SEQ_COUNT"), na.rm=TRUE), COPY_FREQ=!!rlang::sym("COPY_COUNT")/sum(!!rlang::sym("COPY_COUNT"), na.rm=TRUE)) %>% arrange(desc(!!rlang::sym("COPY_COUNT"))) } # If a gene is present in one GROUP but not another, will fill the COUNT and FREQ with 0s if (fill) { gene_tab <- gene_tab %>% ungroup() %>% tidyr::complete_(as.list(c(groups, gene))) %>% replace(is.na(.), 0) } # Rename gene column gene_tab <- rename(gene_tab, "GENE"=gene) return(gene_tab) } #### Annotation functions #### #' Get Ig segment allele, gene and family names #' #' \code{getSegment} performs generic matching of delimited segment calls with a custom #' regular expression. \link{getAllele}, \link{getGene} and \link{getFamily} extract #' the allele, gene and family names, respectively, from a character vector of #' immunoglobulin (Ig) or TCR segment allele calls in IMGT format. #' #' @param segment_call character vector containing segment calls delimited by commas. #' @param segment_regex string defining the segment match regular expression. #' @param first if \code{TRUE} return only the first call in #' \code{segment_call}; if \code{FALSE} return all calls #' delimited by commas. #' @param collapse if \code{TRUE} check for duplicates and return only unique #' segment assignments; if \code{FALSE} return all assignments #' (faster). Has no effect if \code{first=TRUE}. #' @param strip_d if \code{TRUE} remove the "D" from the end of gene annotations #' (denoting a duplicate gene in the locus); #' if \code{FALSE} do not alter gene names. #' @param omit_nl if \code{TRUE} remove non-localized (NL) genes from the result. #' Only applies at the gene or allele level. #' @param sep character defining both the input and output segment call #' delimiter. #' #' @return A character vector containing allele, gene or family names. #' #' @references #' \url{http://imgt.org} #' #' @seealso \link{countGenes} #' #' @examples #' # Light chain examples #' kappa_call <- c("Homsap IGKV1D-39*01 F,Homsap IGKV1-39*02 F,Homsap IGKV1-39*01", #' "Homsap IGKJ5*01 F") #' #' getAllele(kappa_call) #' getAllele(kappa_call, first=FALSE) #' getAllele(kappa_call, first=FALSE, strip_d=FALSE) #' #' getGene(kappa_call) #' getGene(kappa_call, first=FALSE) #' getGene(kappa_call, first=FALSE, strip_d=FALSE) #' #' getFamily(kappa_call) #' getFamily(kappa_call, first=FALSE) #' getFamily(kappa_call, first=FALSE, collapse=FALSE) #' getFamily(kappa_call, first=FALSE, strip_d=FALSE) #' #' # Heavy chain examples #' heavy_call <- c("Homsap IGHV1-69*01 F,Homsap IGHV1-69D*01 F", #' "Homsap IGHD1-1*01 F", #' "Homsap IGHJ1*01 F") #' #' getAllele(heavy_call, first=FALSE) #' getAllele(heavy_call, first=FALSE, strip_d=FALSE) #' #' getGene(heavy_call, first=FALSE) #' getGene(heavy_call, first=FALSE, strip_d=FALSE) #' #' # Filtering non-localized genes #' nl_call <- c("IGHV3-NL1*01,IGHV3-30-3*01,IGHV3-30*01", #' "Homosap IGHV3-30*01 F,Homsap IGHV3-NL1*01 F", #' "IGHV1-NL1*01") #' #' getAllele(nl_call, first=FALSE, omit_nl=TRUE) #' getGene(nl_call, first=FALSE, omit_nl=TRUE) #' getFamily(nl_call, first=FALSE, omit_nl=TRUE) #' #' @export getSegment <- function(segment_call, segment_regex, first=TRUE, collapse=TRUE, strip_d=TRUE, omit_nl=FALSE, sep=",") { # Define boundaries of individual segment calls edge_regex <- paste0("[^", sep, "]*") # Extract calls r <- gsub(paste0(edge_regex, "(", segment_regex, ")", edge_regex), "\\1", segment_call, perl=T) # Remove NL genes if (omit_nl) { nl_regex <- paste0('(IG[HLK]|TR[ABGD])[VDJ][0-9]+-NL[0-9]([-/\\w]*[-\\*][\\.\\w]+)*(', sep, "|$)") r <- gsub(nl_regex, "", r, perl=TRUE) } # Strip D from gene names if required if (strip_d) { strip_regex <- paste0("(?<=[A-Z0-9])D(?=\\*|-|", sep, "|$)") r <- gsub(strip_regex, "", r, perl=TRUE) } # Collapse to unique set if required if (first) { r <- gsub(paste0(sep, ".*$"), "", r) } else if (collapse) { r <- sapply(strsplit(r, sep), function(x) paste(unique(x), collapse=sep)) } return(r) } #' @rdname getSegment #' @export getAllele <- function(segment_call, first=TRUE, collapse=TRUE, strip_d=TRUE, omit_nl=FALSE, sep=",") { allele_regex <- '((IG[HLK]|TR[ABGD])[VDJ][A-Z0-9\\(\\)]+[-/\\w]*[-\\*]*[\\.\\w]+)' r <- getSegment(segment_call, allele_regex, first=first, collapse=collapse, strip_d=strip_d, omit_nl=omit_nl, sep=sep) return(r) } #' @rdname getSegment #' @export getGene <- function(segment_call, first=TRUE, collapse=TRUE, strip_d=TRUE, omit_nl=FALSE, sep=",") { gene_regex <- '((IG[HLK]|TR[ABGD])[VDJ][A-Z0-9\\(\\)]+[-/\\w]*)' r <- getSegment(segment_call, gene_regex, first=first, collapse=collapse, strip_d=strip_d, omit_nl=omit_nl, sep=sep) return(r) } #' @rdname getSegment #' @export getFamily <- function(segment_call, first=TRUE, collapse=TRUE, strip_d=TRUE, omit_nl=FALSE, sep=",") { family_regex <- '((IG[HLK]|TR[ABGD])[VDJ][A-Z0-9\\(\\)]+)' r <- getSegment(segment_call, family_regex, first=first, collapse=collapse, strip_d=strip_d, omit_nl=omit_nl, sep=sep) return(r) } #### Utility functions #### # Get all VJ(L) combinations from one or more chains of the same type # # Input: # V annotation, J annotation, and optionally junction length of # one of more chains of the same type # - v: V annotation # - j: J annotation # - l: junction length (optional) # - sep_chain: character separting multiple chains # - sep_anno: character separating multiple/ambiguous annotations within each chain # - first: to be passed to getGene() # # Output: # A vector containing all unique VJ(L) combinations represented # # Assumption: # 1) number of chains match across v, j, l # 2) if length value is supplied, each chain has a single length value # # Example input # v <- "Homsap IGLV2-20*09 F,Homsap IGLV3-30*09 F;Homsap IGKV1-27*01 F;Homsap IGKV1-25*01 F,Homsap IGKV1-25*38 F,Homsap IGKV1-32*02 F" # j <- "Homsap IGLJ3*02 F;Homsap IGKJ5*02 F;Homsap IGKJ3*03 F,Homsap IGKJ9*03 F" # l <- "36;39;60" # getAllVJL(v, j, l, ";", ",", FALSE) # - 3 light chains # - number of V annotations per chain: 2/1/3 # - number of J annotations per chain: 1/1/2 # - Expected supremum of the number of VJL combinations: 2*1 + 1*1 + 3*2 = 9 # - Note that this is the supremum because the ACTUAL number (7) CAN be lower due to presence # of different alleles from the SAME gene (since computation is performed at the gene level) getAllVJL <- function(v, j, l, sep_chain, sep_anno, first) { # is l NULL? l_NULL <- is.null(l) # are there multiple chains? # assumes that number of chains match across v, j, l # (pre-checked in groupGenes) multi_chain <- stringi::stri_detect_fixed(str=v, pattern=sep_chain) # are there multiple annotations per chain? multi_anno_v <- stringi::stri_detect_fixed(str=v, pattern=sep_anno) multi_anno_j <- stringi::stri_detect_fixed(str=j, pattern=sep_anno) # separate chains # gets a vector of strings # each vector entry corresponds to a chain if (multi_chain) { v <- stringi::stri_split_fixed(str=v, pattern=sep_chain)[[1]] j <- stringi::stri_split_fixed(str=j, pattern=sep_chain)[[1]] if (!l_NULL) { l <- stringi::stri_split_fixed(str=l, pattern=sep_chain)[[1]] } } # separate annotations # gets a list # each list entry has a vector of one or more strings if (multi_anno_v) { v <- stringi::stri_split_fixed(str=v, pattern=sep_anno) # take care of 'first' here because getGene will not split by "," if (first) { v <- lapply(v, function(x){x[1]}) } } if (multi_anno_j) { j <- stringi::stri_split_fixed(str=j, pattern=sep_anno) if (first) { j <- lapply(j, function(x){x[1]}) } } # get gene # gets a list # each list entry corresponds to a chain, and is a vector of one or more strings v <- sapply(v, getGene, collapse=TRUE, simplify=FALSE, USE.NAMES=FALSE) j <- sapply(j, getGene, collapse=TRUE, simplify=FALSE, USE.NAMES=FALSE) # if there is multiple chains and/or multiple annotations if ( multi_chain | (multi_anno_v & first) | (multi_anno_j & first) ) { # gets a list # each list entry is a vector of one or more strings # do if/else outside sapply so it only gets evaluated once if (!l_NULL) { exp <- sapply(1:length(v), function(i){ #eg_df <- expand.grid(v[[i]], j[[i]], l[i]) #eg_vec <- apply(eg_df, 1, stringi::stri_paste, collapse="@") n_v <- length(v[[i]]) n_j <- length(j[[i]]) eg_vec = stringi::stri_paste(rep.int(v[[i]], times=n_j), rep(j[[i]], each=n_v), rep.int(l[i], times=n_v*n_j), sep="@") return(eg_vec) }, simplify=FALSE, USE.NAMES=FALSE) } else { exp <- sapply(1:length(v), function(i){ #eg_df = expand.grid(v[[i]], j[[i]]) #eg_vec = apply(eg_df, 1, stringi::stri_paste, collapse="@") n_v <- length(v[[i]]) n_j <- length(j[[i]]) eg_vec <- stringi::stri_paste(rep.int(v[[i]], times=n_j), rep(j[[i]], each=n_v), sep="@") return(eg_vec) }, simplify=FALSE, USE.NAMES=FALSE) } # concat and convert to vector; keep distinct values exp <- unique(unlist(exp, use.names=FALSE)) } else { n_v <- length(v[[1]]) n_j <- length(j[[1]]) if (!l_NULL) { exp <- stringi::stri_paste(rep.int(v[[1]], times=n_j), rep(j[[1]], each=n_v), rep.int(l[1], times=n_v*n_j), sep="@") } else { exp <- stringi::stri_paste(rep.int(v[[1]], times=n_j), rep(j[[1]], each=n_v), sep="@") } } return(exp) } #' Group sequences by gene assignment #' #' \code{groupGenes} will group rows by shared V and J gene assignments, #' and optionally also by junction lengths. #' Both VH:VL paired single-cell BCR-seq and unpaired bulk-seq (heavy chain-only) #' are supported. #' In the case of ambiguous (multiple) gene assignments, the grouping may #' be specified to be a union across all ambiguous V and J gene pairs, #' analagous to single-linkage clustering (i.e., allowing for chaining). #' #' @param data data.frame containing sequence data. #' @param v_call name of the column containing the heavy chain V-segment #' allele calls. #' @param j_call name of the column containing the heavy chain J-segment #' allele calls. #' @param junc_len name of the column containing the heavy chain junction #' length. Optional. #' @param cell_id name of the column containing cell IDs. Only applicable #' and required for single-cell mode. #' @param locus name of the column containing locus information. Only applicable #' and required for single-cell mode. #' @param only_igh use only heavy chain (\code{IGH}) sequences for grouping, #' disregarding light chains. Only applicable and required for #' single-cell mode. Default is \code{TRUE}. #' @param first if \code{TRUE} only the first call of the gene assignments #' is used. if \code{FALSE} the union of ambiguous gene #' assignments is used to group all sequences with any #' overlapping gene calls. #' #' @return Returns a modified data.frame with disjoint union indices #' in a new \code{VJ_GROUP} column. #' #' Note that if \code{junc_len} is supplied, the grouping this \code{VJ_GROUP} #' will have been based on V, J, and L simultaneously despite the column name #' being \code{VJ_GROUP}. #' #' @details #' #' To invoke single-cell mode, both \code{cell_id} and \code{locus} must be supplied. Otherwise, #' the function will run under non-single-cell mode, using all input sequences regardless of the #' value in the \code{locus} column. #' #' Under single-cell mode for VH:VL paired sequences, there is a choice of whether grouping #' should be done using only heavy chain (\code{IGH}) sequences only, or using both heavy chain #' (\code{IGH}) and light chain (\code{IGK}, \code{IGL}) sequences. This is governed by #' \code{only_igh}. #' #' Values in the \code{locus} column must be one of \code{"IGH"}, \code{"IGK"}, and \code{"IGL"}. #' #' By supplying \code{junc_len}, the call amounts to a 1-stage partitioning of the sequences/cells #' based on V annotation, J annotation, and junction length simultaneously. Without supplying this #' columns, the call amounts to the first stage of a 2-stage partitioning, in which sequences/cells #' are partitioned in the first stage based on V annotation and J annotation, and then in the second #' stage further split based on junction length. #' #' It is assumed that ambiguous gene assignments are separated by commas. #' #' All rows containing \code{NA} values in their any of the \code{v_call}, \code{j_call}, and, #' if specified, \code{junc_len}, columns will be removed. A warning will be issued when a row #' containing an \code{NA} is removed. #' #' @section Expectation for single-cell input: #' #' For single-cell BCR data with VH:VL pairing, it is assumed that #' \itemize{ #' \item every row represents a sequence (chain) #' \item heavy and light chains of the same cell are linked by \code{cell_id} #' \item value in \code{locus} column indicates whether the chain is heavy or light #' \item each cell possibly contains multiple heavy and/or light chains #' \item every chain has its own V(D)J annotation, in which ambiguous V(D)J #' annotations, if any, are separated by \code{,} (comma) #' } #' #' An example: #' \itemize{ #' \item A cell has 1 heavy chain and 2 light chains #' \item There should be 3 rows corresponding to this cell #' \item One of the light chain has ambiguous V annotation, which looks like \code{Homsap IGKV1-39*01 F,Homsap IGKV1D-39*01 F}. #' } #' #' @examples #' # Group by genes #' db <- groupGenes(ExampleDb, v_call="V_CALL", j_call="J_CALL") #' #' @export groupGenes <- function(data, v_call="V_CALL", j_call="J_CALL", junc_len=NULL, cell_id=NULL, locus=NULL, only_igh=TRUE, first=FALSE) { # calling `data` `data` is hugely problematic b/c `data` is a default R function # data_orig <- data will cause downstream errors # Check input check <- checkColumns(data, c(v_call, j_call, junc_len, cell_id, locus)) if (check != TRUE) { stop(check) } # e.g.: "Homsap IGHV3-7*01 F,Homsap IGHV3-6*01 F;Homsap IGHV1-4*01 F" separator_within_seq <- "," separator_between_seq <- ";" # single-cell mode? if ( !is.null(cell_id) & !is.null(locus) ) { single_cell <- TRUE if (!all(data[[locus]] %in% c("IGH", "IGK", "IGL"))) { stop("The locus column must be one of {IGH, IGK, IGL}.") } } else { single_cell <- FALSE } # only set if `single_cell` & `only_igh` v_call_light <- NULL j_call_light <- NULL junc_len_light <- NULL # single-cell mode if (single_cell) { # regardless of using heavy only, or using both heavy and light # for each cell # - index wrt data of heavy chain # - index wrt data of light chain(s) cell_id_uniq <- unique(data[[cell_id]]) cell_seq_idx <- sapply(cell_id_uniq, function(x){ # heavy chain idx_h <- which( data[[cell_id]]==x & data[[locus]]=="IGH" ) # light chain idx_l <- which( data[[cell_id]]==x & data[[locus]]!="IGH" ) return(list(heavy=idx_h, light=idx_l)) }, USE.NAMES=FALSE, simplify=FALSE) # make a copy data_orig <- data; rm(data) if (only_igh) { # use heavy chains only # Straightforward subsetting like below won't work in cases # where multiple HCs are present for a cell # subset to heavy only # data <- data_orig[data_orig[[locus]]=="IGH", ] # flatten data cols <- c(cell_id, v_call, j_call, junc_len) data <- data.frame(matrix(NA, nrow=length(cell_seq_idx), ncol=length(cols))) colnames(data) <- cols for (i_cell in 1:length(cell_seq_idx)) { i_cell_h <- cell_seq_idx[[i_cell]][["heavy"]] data[[cell_id]][i_cell] <- cell_id_uniq[i_cell] # heavy chain V, J, junc_len data[[v_call]][i_cell] <- paste0(data_orig[[v_call]][i_cell_h], collapse=separator_between_seq) data[[j_call]][i_cell] <- paste0(data_orig[[v_call]][i_cell_h], collapse=separator_between_seq) if (!is.null(junc_len)) { data[[junc_len]][i_cell] <- paste0(data_orig[[junc_len]][i_cell_h], collapse=separator_between_seq) } } } else { # use heavy AND light chains for grouping v_call_light <- "v_call_light" j_call_light <- "j_call_light" # ifelse won't return NULL if (is.null(junc_len)) { junc_len_light <- NULL } else { junc_len_light <- "len_light" } # flatten data cols <- c(cell_id, v_call, j_call, junc_len, v_call_light, j_call_light, junc_len_light) data <- data.frame(matrix(NA, nrow=length(cell_seq_idx), ncol=length(cols))) colnames(data) <- cols for (i_cell in 1:length(cell_seq_idx)) { i_cell_h <- cell_seq_idx[[i_cell]][["heavy"]] i_cell_l <- cell_seq_idx[[i_cell]][["light"]] data[[cell_id]][i_cell] <- cell_id_uniq[i_cell] # heavy chain V, J, junc_len data[[v_call]][i_cell] <- paste0(data_orig[[v_call]][i_cell_h], collapse=separator_between_seq) data[[j_call]][i_cell] <- paste0(data_orig[[v_call]][i_cell_h], collapse=separator_between_seq) if (!is.null(junc_len)) { data[[junc_len]][i_cell] <- paste0(data_orig[[junc_len]][i_cell_h], collapse=separator_between_seq) } # light chain V, J, junc_len data[[v_call_light]][i_cell] <- paste0(data_orig[[v_call]][i_cell_l], collapse=separator_between_seq) data[[j_call_light]][i_cell] <- paste0(data_orig[[j_call]][i_cell_l], collapse=separator_between_seq) if (!is.null(junc_len_light)) { data[[junc_len_light]][i_cell] <- paste0(data_orig[[junc_len]][i_cell_l], collapse=separator_between_seq) } } # It cannot be the case that there are 2 V annotations but only 1 J annotation for # the two light chains. Both J annotations must be spelled out for each light chain, # separated by \code{separator_between_seq}, even if the annotated alleles are the same. # # This one-to-one annotation-to-chain correspondence for both V and J is explicitly # checked and an error raised if the requirement is not met. # one-to-one annotation-to-chain correspondence for both V and J (light) # for each cell/row, number of bewteen_seq separators in light V annotation and in light J annotation must match n_separator_btw_seq_v_light <- stringi::stri_count_fixed(str=data[[v_call_light]], pattern=separator_between_seq) n_separator_btw_seq_j_light <- stringi::stri_count_fixed(str=data[[j_call_light]], pattern=separator_between_seq) if (any( n_separator_btw_seq_v_light != n_separator_btw_seq_j_light )) { stop("Requirement not met: one-to-one annotation-to-chain correspondence for both V and J (light)") } } } # one-to-one annotation-to-chain correspondence for both V and J (heavy) # for each cell/row, number of bewteen_seq separators in heavy V annotation and in heavy J annotation must match # (in theory, there should be 1 heavy chain per cell; but 10x can return cell with >1 heavy chains and # you never know if the user will supply this cell as input) n_separator_btw_seq_v_heavy <- stringi::stri_count_fixed(str=data[[v_call]], pattern=separator_between_seq) n_separator_btw_seq_j_heavy <- stringi::stri_count_fixed(str=data[[j_call]], pattern=separator_between_seq) if (any( n_separator_btw_seq_v_heavy != n_separator_btw_seq_j_heavy )) { stop("Requirement not met: one-to-one annotation-to-chain correspondence for both V and J (heavy)") } # NULL will disappear when doing c() # c(NULL,NULL) gives NULL still cols_for_grouping_heavy <- c(v_call, j_call, junc_len) cols_for_grouping_light <- c(v_call_light, j_call_light, junc_len_light) # cols cannot be factor if (any( sapply(cols_for_grouping_heavy, function(x){class(data[[x]]) == "factor"}) )) { stop("one or more of { ", v_call, ", ", j_call, ifelse(is.null(junc_len), " ", ", "), junc_len, "} is factor. Must be character.\n") } if (single_cell & !only_igh) { if (any( sapply(cols_for_grouping_light, function(x) {class(data[[x]]) == "factor"}) )) { stop("one or more of { ", v_call_light, ", ", j_call_light, ifelse(is.null(junc_len_light), " ", ", "), junc_len_light, "} is factor. Must be character.\n") } } # Check NA(s) in columns bool_na <- rowSums( is.na( data[, c(cols_for_grouping_heavy, cols_for_grouping_light)] ) ) >0 if (any(bool_na)) { entityName <- ifelse(single_cell, " cell(s)", " sequence(s)") msg <- paste0("NA(s) found in one or more of { ", v_call, ", ", j_call, ifelse(is.null(junc_len), "", ", "), junc_len, ifelse(is.null(v_call_light), "", ", "), v_call_light, ifelse(is.null(j_call_light), "", ", "), j_call_light, ifelse(is.null(junc_len_light), "", ", "), junc_len_light, " } columns. ", sum(bool_na), entityName, " removed.\n") warning(msg) data <- data[!bool_na, ] if (single_cell) { # maintain one-to-one relationship between # rows of data, cell_id_uniq, and cell_seq_idx cell_id_uniq <- cell_id_uniq[!bool_na] cell_seq_idx <- cell_seq_idx[!bool_na] } } ### expand # speed-up strategy # compute expanded VJL combos for unique rows # then distribute back to all rows # unique combinations of VJL # heavy chain seqs only if ( (!single_cell) | (single_cell & only_igh) ) { combo_unique <- unique(data[, cols_for_grouping_heavy]) # unique components v_unique <- unique(combo_unique[[v_call]]) j_unique <- unique(combo_unique[[j_call]]) # map each row in full data to unique combo m_v <- match(data[[v_call]], v_unique) m_j <- match(data[[j_call]], j_unique) if (is.null(junc_len)) { combo_unique_full_idx <- sapply(1:nrow(combo_unique), function(i) { idx_v <- which (v_unique == combo_unique[[v_call]][i]) idx_j <- which (j_unique == combo_unique[[j_call]][i]) idx <- which(m_v==idx_v & m_j==idx_j) return(idx) }, simplify=FALSE, USE.NAMES=FALSE) } else { l_unique <- unique(combo_unique[[junc_len]]) m_l <- match(data[[junc_len]], l_unique) combo_unique_full_idx <- sapply(1:nrow(combo_unique), function(i) { idx_v <- which(v_unique == combo_unique[[v_call]][i]) idx_j <- which(j_unique == combo_unique[[j_call]][i]) idx_l <- which(l_unique == combo_unique[[junc_len]][i]) idx <- which(m_v==idx_v & m_j==idx_j & m_l==idx_l) return(idx) }, simplify=FALSE, USE.NAMES=FALSE) } # expand combo_unique if (is.null(junc_len)) { exp_lst <- sapply(1:nrow(combo_unique), function(i){ getAllVJL(v=combo_unique[[v_call]][i], j=combo_unique[[j_call]][i], l=NULL, first=first, sep_anno=separator_within_seq, sep_chain=separator_between_seq) }, simplify=F, USE.NAMES=FALSE) } else { exp_lst <- sapply(1:nrow(combo_unique), function(i){ getAllVJL(v=combo_unique[[v_call]][i], j=combo_unique[[j_call]][i], l=combo_unique[[junc_len]][i], first=first, sep_anno=separator_within_seq, sep_chain=separator_between_seq) }, simplify=F, USE.NAMES=FALSE) } } else { # single_cell & !only_igh # important: do not do this separately for heavy and light # must keep the pairing structure combo_unique <- unique(data[, c(cols_for_grouping_heavy, cols_for_grouping_light)]) # unique components v_unique_h <- unique(combo_unique[[v_call]]) j_unique_h <- unique(combo_unique[[j_call]]) v_unique_l <- unique(combo_unique[[v_call_light]]) j_unique_l <- unique(combo_unique[[j_call_light]]) # map each row in full data to unique combo m_v_h <- match(data[[v_call]], v_unique_h) m_j_h <- match(data[[j_call]], j_unique_h) m_v_l <- match(data[[v_call_light]], v_unique_l) m_j_l <- match(data[[j_call_light]], j_unique_l) if (!is.null(junc_len)) { l_unique_h <- unique(combo_unique[[junc_len]]) m_l_h <- match(data[[junc_len]], l_unique_h) } if (!is.null(junc_len_light)) { l_unique_l <- unique(combo_unique[[junc_len_light]]) m_l_l <- match(data[[junc_len_light]], l_unique_l) } # expand combo_unique if (is.null(junc_len) & is.null(junc_len_light)) { # map combo_unique_full_idx <- sapply(1:nrow(combo_unique), function(i){ idx_v_h <- which( v_unique_h == combo_unique[[v_call]][i] ) idx_j_h <- which( j_unique_h == combo_unique[[j_call]][i] ) idx_v_l <- which( v_unique_l == combo_unique[[v_call_light]][i] ) idx_j_l <- which( j_unique_l == combo_unique[[j_call_light]][i] ) idx <- which(m_v_h==idx_v_h & m_j_h==idx_j_h & m_v_l==idx_v_l & m_j_l==idx_j_l) return(idx) }, simplify=FALSE, USE.NAMES=FALSE) # heavy exp_h <- sapply(1:nrow(combo_unique), function(i){ getAllVJL(v=combo_unique[[v_call]][i], j=combo_unique[[j_call]][i], l=NULL, first=first, sep_anno=separator_within_seq, sep_chain=separator_between_seq) }, simplify=FALSE, USE.NAMES=FALSE) # light exp_l <- sapply(1:nrow(combo_unique), function(i){ getAllVJL(v=combo_unique[[v_call_light]][i], j=combo_unique[[j_call_light]][i], l=NULL, first=first, sep_anno=separator_within_seq, sep_chain=separator_between_seq) }, simplify=FALSE, USE.NAMES=FALSE) } else if (!is.null(junc_len) & !is.null(junc_len_light)) { # map combo_unique_full_idx <- sapply(1:nrow(combo_unique), function(i){ idx_v_h <- which( v_unique_h == combo_unique[[v_call]][i] ) idx_j_h <- which( j_unique_h == combo_unique[[j_call]][i] ) idx_l_h <- which( l_unique_h == combo_unique[[junc_len]][i] ) idx_v_l <- which( v_unique_l == combo_unique[[v_call_light]][i] ) idx_j_l <- which( j_unique_l == combo_unique[[j_call_light]][i] ) idx_l_l <- which( l_unique_l == combo_unique[[junc_len_light]][i] ) idx <- which(m_v_h==idx_v_h & m_j_h==idx_j_h & m_l_h==idx_l_h & m_v_l==idx_v_l & m_j_l==idx_j_l & m_l_l==idx_l_l) return(idx) }, simplify=FALSE, USE.NAMES=FALSE) # heavy exp_h <- sapply(1:nrow(combo_unique), function(i){ getAllVJL(v=combo_unique[[v_call]][i], j=combo_unique[[j_call]][i], l=combo_unique[[junc_len]][i], first=first, sep_anno=separator_within_seq, sep_chain=separator_between_seq) }, simplify=FALSE, USE.NAMES=FALSE) # light exp_l <- sapply(1:nrow(combo_unique), function(i){ getAllVJL(v=combo_unique[[v_call_light]][i], j=combo_unique[[j_call_light]][i], l=combo_unique[[junc_len_light]][i], first=first, sep_anno=separator_within_seq, sep_chain=separator_between_seq) }, simplify=FALSE, USE.NAMES=FALSE) } else if (is.null(junc_len) & !is.null(junc_len_light)) { # map combo_unique_full_idx <- sapply(1:nrow(combo_unique), function(i){ idx_v_h <- which( v_unique_h == combo_unique[[v_call]][i] ) idx_j_h <- which( j_unique_h == combo_unique[[j_call]][i] ) idx_v_l <- which( v_unique_l == combo_unique[[v_call_light]][i] ) idx_j_l <- which( j_unique_l == combo_unique[[j_call_light]][i] ) idx_l_l <- which( l_unique_l == combo_unique[[junc_len_light]][i] ) idx <- which(m_v_h==idx_v_h & m_j_h==idx_j_h & m_v_l==idx_v_l & m_j_l==idx_j_l & m_l_l==idx_l_l) return(idx) }, simplify=FALSE, USE.NAMES=FALSE) # heavy exp_h <- sapply(1:nrow(combo_unique), function(i){ getAllVJL(v=combo_unique[[v_call]][i], j=combo_unique[[j_call]][i], l=NULL, first=first, sep_anno=separator_within_seq, sep_chain=separator_between_seq) }, simplify=FALSE, USE.NAMES=FALSE) # light exp_l <- sapply(1:nrow(combo_unique), function(i){ getAllVJL(v=combo_unique[[v_call_light]][i], j=combo_unique[[j_call_light]][i], l=combo_unique[[junc_len_light]][i], first=first, sep_anno=separator_within_seq, sep_chain=separator_between_seq) }, simplify=FALSE, USE.NAMES=FALSE) } else if (!is.null(junc_len) & is.null(junc_len_light)) { # map combo_unique_full_idx <- sapply(1:nrow(combo_unique), function(i){ idx_v_h <- which( v_unique_h == combo_unique[[v_call]][i] ) idx_j_h <- which( j_unique_h == combo_unique[[j_call]][i] ) idx_l_h <- which( l_unique_h == combo_unique[[junc_len]][i] ) idx_v_l <- which( v_unique_l == combo_unique[[v_call_light]][i] ) idx_j_l <- which( j_unique_l == combo_unique[[j_call_light]][i] ) idx <- which(m_v_h==idx_v_h & m_j_h==idx_j_h & m_l_h==idx_l_h & m_v_l==idx_v_l & m_j_l==idx_j_l) return(idx) }, simplify=FALSE, USE.NAMES=FALSE) # heavy exp_h <- sapply(1:nrow(combo_unique), function(i){ getAllVJL(v=combo_unique[[v_call]][i], j=combo_unique[[j_call]][i], l=combo_unique[[junc_len]][i], first=first, sep_anno=separator_within_seq, sep_chain=separator_between_seq) }, simplify=FALSE, USE.NAMES=FALSE) # light exp_l <- sapply(1:nrow(combo_unique), function(i){ getAllVJL(v=combo_unique[[v_call_light]][i], j=combo_unique[[j_call_light]][i], l=NULL, first=first, sep_anno=separator_within_seq, sep_chain=separator_between_seq) }, simplify=FALSE, USE.NAMES=FALSE) } # pair heavy & light stopifnot( length(exp_h) == length(exp_l) ) exp_lst <- sapply(1:length(exp_h), function(i){ n_h <- length(exp_h[[i]]) n_l <- length(exp_l[[i]]) stringi::stri_paste(rep.int(exp_h[[i]], times=n_l), rep(exp_l[[i]], each=n_h), sep="@") }, simplify=FALSE, USE.NAMES=FALSE) } # one-to-one correspondence btw exp_lst and combo_unique_full_idx # exp_lst: VJL combinations # combo_unique_full_idx: rows in data carrying each exp_lst # exp_lst may not be all unique because gene-level info is kept instead of allele-level # make exp_lst unique exp_lst_uniq <- unique(exp_lst) exp_lst_uniq_full_idx <- sapply(exp_lst_uniq, function(x){ # wrt exp_lst, therefore also wrt combo_unique_full_idx idx_lst <- which(unlist(lapply(exp_lst, function(y){ length(y)==length(x) && all(y==x) }))) # merge unlist(combo_unique_full_idx[idx_lst], use.names=FALSE) }, simplify=FALSE, USE.NAMES=FALSE) stopifnot( length(unique(unlist(exp_lst_uniq_full_idx, use.names=FALSE))) == nrow(data) ) # tip: unlist with use.names=F makes it much faster (>100x) # https://www.r-bloggers.com/speed-trick-unlist-use-namesfalse-is-heaps-faster/ exp_uniq <- sort(unique(unlist(exp_lst_uniq, use.names=FALSE))) n_cells_or_seqs <- nrow(data) # notes on implementation # regular/dense matrix is more straightforward to implement but very costly memory-wise # sparse matrix is less straightforward to implement but way more memory efficient # sparse matrix is very slow to modify to on-the-fly (using a loop like for dense matrix) # way faster to construct in one go # (DO NOT DELETE) # for illustrating the concept # this is the way to go if using regular matrix (memory-intensive) # same concept implemented using sparse matrix # mtx_cell_VJL <- matrix(0, nrow=nrow(data), ncol=length(exp_uniq)) # colnames(mtx_cell_VJL) <- exp_uniq # # mtx_adj <- matrix(0, nrow=length(exp_uniq), ncol=length(exp_uniq)) # rownames(mtx_adj) <- exp_uniq # colnames(mtx_adj) <- exp_uniq # # outdated: # for (i_cell in 1:length(exp_lst)) { # #if (i_cell %% 1000 == 0) { cat(i_cell, "\n") } # cur_uniq <- unique(exp_lst[[i_cell]]) # mtx_cell_VJL[i_cell, cur_uniq] <- 1 # mtx_adj[cur_uniq, cur_uniq] <- 1 # } # actual implementation using sparse matrix from Matrix package ### matrix indicating relationship between cell and VJ(L) combinations # row: cell # col: unique heavy VJ(L) (and light VJ(L)) # row indices m1_i <- lapply(1:length(exp_lst_uniq), function(i){ rep(exp_lst_uniq_full_idx[[i]], each=length(exp_lst_uniq[[i]])) }) m1_i_v <- unlist(m1_i, use.names=FALSE) # column indices m1_j <- lapply(1:length(exp_lst_uniq), function(i){ # wrt exp_uniq idx <- match(exp_lst_uniq[[i]], exp_uniq) #stopifnot( all.equal( exp_uniq[idx], exp_lst_uniq[[i]] ) ) rep.int(idx, length(exp_lst_uniq_full_idx[[i]])) }) m1_j_v <- unlist(m1_j, use.names=FALSE) stopifnot( length(m1_i_v) == length(m1_j_v) ) # no particular need for this to be not of class "nsparseMatrix" # so no need to specify x=rep(1, length(m1_i)) # not specifying makes it even more space-efficient mtx_cell_VJL <- Matrix::sparseMatrix(i=m1_i_v, j=m1_j_v, dims=c(n_cells_or_seqs, length(exp_uniq)), symmetric=F, triangular=F, index1=T, dimnames=list(NULL, exp_uniq)) ### adjacency matrix # row and col: unique heavy VJ(L) (and light VJ(L)) # row indices m2_i <- lapply(1:length(exp_lst_uniq), function(i){ # wrt exp_uniq idx <- match(exp_lst_uniq[[i]], exp_uniq) #stopifnot( all.equal( exp_uniq[idx], exp_lst_uniq[[i]] ) ) rep(idx, each=length(exp_lst_uniq[[i]])) }) m2_i_v <- unlist(m2_i, use.names=FALSE) # col indices m2_j <- lapply(1:length(exp_lst_uniq), function(i){ # wrt exp_uniq idx <- match(exp_lst_uniq[[i]], exp_uniq) #stopifnot( all.equal( exp_uniq[idx], exp_lst_uniq[[i]] ) ) rep.int(idx, length(exp_lst_uniq[[i]])) }) m2_j_v <- unlist(m2_j, use.names=FALSE) stopifnot( length(m2_i_v) == length(m2_j_v) ) # important: x must be specified for mtx_adj in order to make it not of class "nsparseMatrix" # this is because igraph accepts sparse matrix from Matrix but not the "pattern" matrices variant mtx_adj <- Matrix::sparseMatrix(i=m2_i_v, j=m2_j_v, x=rep(1,length(m2_i_v)), dims=c(length(exp_uniq), length(exp_uniq)), symmetric=F, triangular=F, index1=T, dimnames=list(exp_uniq, exp_uniq)) rm(m1_i, m1_j, m2_i, m2_j, m1_i_v, m1_j_v, m2_i_v, m2_j_v, exp_lst) ### identify connected components based on adjcencey matrix # this is the grouping # source: https://stackoverflow.com/questions/35772846/obtaining-connected-components-in-r g <- igraph::graph_from_adjacency_matrix(adjmatrix=mtx_adj, mode="undirected", diag=FALSE) #plot(g, vertex.size=10, vertex.label.cex=1, vertex.color="skyblue", vertex.label.color="black", vertex.frame.color="transparent", edge.arrow.mode=0) connected <- igraph::components(g) VJL_groups <- igraph::groups(connected) names(VJL_groups) <- paste0("G", 1:length(VJL_groups)) ### identify cells associated with each connected component (grouping) # each entry corresponds to a group/partition # each element within an entry is a cell cellIdx_byGroup_lst <- lapply(VJL_groups, function(x){ if (length(x)>1) { # matrix # important to specify rowSums from Matrix package # base::rowSums will NOT work cell_idx <- which(Matrix::rowSums(mtx_cell_VJL[, x])>0) } else { # vector cell_idx <- which(mtx_cell_VJL[, x]>0) } return(cell_idx) }) # sanity check: there should be perfect/disjoint partitioning # (each cell has exactly one group assignment) stopifnot( n_cells_or_seqs == length(unique(unlist(cellIdx_byGroup_lst, use.names=FALSE))) ) # assign data$VJ_GROUP <- NA for (i in 1:length(cellIdx_byGroup_lst)) { data[["VJ_GROUP"]][cellIdx_byGroup_lst[[i]]] <- names(VJL_groups)[i] } stopifnot(!any(is.na(data[["VJ_GROUP"]]))) if (!single_cell) { return(data) } else { data_orig$VJ_GROUP <- NA # map back to data_orig for (i_cell in 1:nrow(data)) { # wrt data_orig i_orig_h <- cell_seq_idx[[i_cell]][["heavy"]] i_orig_l <- cell_seq_idx[[i_cell]][["light"]] # sanity check stopifnot( all( data_orig[[cell_id]][c(i_orig_h, i_orig_l)] == cell_id_uniq[i_cell] ) ) # grouping data_orig$VJ_GROUP[c(i_orig_h, i_orig_l)] <- data$VJ_GROUP[i_cell] } # remove rows with $VJ_GROUP values of NA # these had already been removed by the NA check for `data` data_orig <- data_orig[!is.na(data_orig$VJ_GROUP), ] return(data_orig) } } #' Sort V(D)J genes #' #' \code{sortGenes} sorts a vector of V(D)J gene names by either lexicographic ordering #' or locus position. #' #' @param genes vector of strings respresenting V(D)J gene names. #' @param method string defining the method to use for sorting genes. One of: #' \itemize{ #' \item \code{"name"}: sort in lexicographic order. Order is by #' family first, then gene, and then allele. #' \item \code{"position"}: sort by position in the locus, as #' determined by the final two numbers #' in the gene name. Non-localized genes #' are assigned to the highest positions. #' } #' #' @return A sorted character vector of gene names. #' #' @seealso See \code{getAllele}, \code{getGene} and \code{getFamily} for parsing #' gene names. #' #' @examples #' # Create a list of allele names #' genes <- c("IGHV1-69D*01","IGHV1-69*01","IGHV4-38-2*01","IGHV1-69-2*01", #' "IGHV2-5*01","IGHV1-NL1*01", "IGHV1-2*01,IGHV1-2*05", #' "IGHV1-2", "IGHV1-2*02", "IGHV1-69*02") #' #' # Sort genes by name #' sortGenes(genes) #' #' # Sort genes by position in the locus #' sortGenes(genes, method="pos") #' #' @export sortGenes <- function(genes, method=c("name", "position")) { ## DEBUG # method="name" # Check arguments method <- match.arg(method) # Build sorting table sort_tab <- tibble(CALL=sort(getAllele(genes, first=FALSE, strip_d=FALSE))) %>% # Determine the gene and family mutate(FAMILY=getFamily(!!rlang::sym("CALL"), first=TRUE, strip_d=FALSE), GENE=getGene(!!rlang::sym("CALL"), first=TRUE, strip_d=FALSE), ALLELE=getAllele(!!rlang::sym("CALL"), first=TRUE, strip_d=FALSE)) %>% # Identify first gene number, second gene number and allele number mutate(G1=gsub("[^-]+-([^-\\*D]+).*", "\\1", !!rlang::sym("GENE")), G1=as.numeric(gsub("[^0-9]+", "99", !!rlang::sym("G1"))), G2=gsub("[^-]+-[^-]+-?", "", !!rlang::sym("GENE")), G2=as.numeric(gsub("[^0-9]+", "99", !!rlang::sym("G2"))), A1=as.numeric(sub("[^\\*]+\\*|[^\\*]+$", "", !!rlang::sym("ALLELE"))) ) # Convert missing values to 0 sort_tab[is.na(sort_tab)] <- 0 # Sort if (method == "name") { sorted_genes <- arrange(sort_tab, !!!rlang::syms(c("FAMILY", "G1", "G2", "A1")))[["CALL"]] } else if (method == "position") { sorted_genes <- arrange(sort_tab, desc(!!rlang::sym("G1")), desc(!!rlang::sym("G2")), !!rlang::sym("FAMILY"), !!rlang::sym("A1"))[["CALL"]] } return(sorted_genes) } alakazam/R/Lineage.R0000644000176200001440000013320413513450447013734 0ustar liggesusers# Ig lineage reconstruction via maximum parsimony #' @include Classes.R NULL #### Preprocessing functions #### #' Generate a ChangeoClone object for lineage construction #' #' \code{makeChangeoClone} takes a data.frame with Change-O style columns as input and #' masks gap positions, masks ragged ends, removes duplicates sequences, and merges #' annotations associated with duplicate sequences. It returns a \code{ChangeoClone} #' object which serves as input for lineage reconstruction. #' #' @param data data.frame containing the Change-O data for a clone. See Details #' for the list of required columns and their default values. #' @param id name of the column containing sequence identifiers. #' @param seq name of the column containing observed DNA sequences. All #' sequences in this column must be multiple aligned. #' @param germ name of the column containing germline DNA sequences. All entries #' in this column should be identical for any given clone, and they #' must be multiple aligned with the data in the \code{seq} column. #' @param vcall name of the column containing V-segment allele assignments. All #' entries in this column should be identical to the gene level. #' @param jcall name of the column containing J-segment allele assignments. All #' entries in this column should be identical to the gene level. #' @param junc_len name of the column containing the length of the junction as a #' numeric value. All entries in this column should be identical #' for any given clone. #' @param clone name of the column containing the identifier for the clone. All #' entries in this column should be identical. #' @param mask_char character to use for masking and padding. #' @param max_mask maximum number of characters to mask at the leading and trailing #' sequence ends. If \code{NULL} then the upper masking bound will #' be automatically determined from the maximum number of observed #' leading or trailing Ns amongst all sequences. If set to \code{0} #' (default) then masking will not be performed. #' @param pad_end if \code{TRUE} pad the end of each sequence with \code{mask_char} #' to make every sequence the same length. #' @param text_fields text annotation columns to retain and merge during duplicate removal. #' @param num_fields numeric annotation columns to retain and sum during duplicate removal. #' @param seq_fields sequence annotation columns to retain and collapse during duplicate #' removal. Note, this is distinct from the \code{seq} and \code{germ} #' arguments, which contain the primary sequence data for the clone #' and should not be repeated in this argument. #' @param add_count if \code{TRUE} add an additional annotation column called #' \code{COLLAPSE_COUNT} during duplicate removal that indicates the #' number of sequences that were collapsed. #' @param verbose passed on to \code{collapseDuplicates}. If \code{TRUE}, report the #' numbers of input, discarded and output sequences; otherwise, process #' sequences silently. #' #' @return A \link{ChangeoClone} object containing the modified clone. #' #' @details #' The input data.frame (\code{data}) must columns for each of the required column name #' arguments: \code{id}, \code{seq}, \code{germ}, \code{vcall}, \code{jcall}, #' \code{junc_len}, and \code{clone}. The default values are as follows: #' \itemize{ #' \item \code{id = "SEQUENCE_ID"}: unique sequence identifier. #' \item \code{seq = "SEQUENCE_IMGT"}: IMGT-gapped sample sequence. #' \item \code{germ = "GERMLINE_IMGT_D_MASK"}: IMGT-gapped germline sequence. #' \item \code{vcall = "V_CALL"}: V-segment allele call. #' \item \code{jcall = "J_CALL"}: J-segment allele call. #' \item \code{junc_len = "JUNCTION_LENGTH"}: junction sequence length. #' \item \code{clone = "CLONE"}: clone identifier. #' } #' Additional annotation columns specified in the \code{text_fields}, \code{num_fields} #' or \code{seq_fields} arguments will be retained in the \code{data} slot of the return #' object, but are not required. If the input data.frame \code{data} already contains a #' column named \code{SEQUENCE}, which is not used as the \code{seq} argument, then that #' column will not be retained. #' #' The default columns are IMGT-gapped sequence columns, but this is not a requirement. #' However, all sequences (both observed and germline) must be multiple aligned using #' some scheme for both proper duplicate removal and lineage reconstruction. #' #' The value for the germline sequence, V-segment gene call, J-segment gene call, #' junction length, and clone identifier are determined from the first entry in the #' \code{germ}, \code{vcall}, \code{jcall}, \code{junc_len} and \code{clone} columns, #' respectively. For any given clone, each value in these columns should be identical. #' #' @seealso Executes in order \link{maskSeqGaps}, \link{maskSeqEnds}, #' \link{padSeqEnds}, and \link{collapseDuplicates}. #' Returns a \link{ChangeoClone} object which serves as input to #' \link{buildPhylipLineage}. #' #' @examples #' # Example Change-O data.frame #' db <- data.frame(SEQUENCE_ID=LETTERS[1:4], #' SEQUENCE_IMGT=c("CCCCTGGG", "CCCCTGGN", "NAACTGGN", "NNNCTGNN"), #' V_CALL="Homsap IGKV1-39*01 F", #' J_CALL="Homsap IGKJ5*01 F", #' JUNCTION_LENGTH=2, #' GERMLINE_IMGT_D_MASK="CCCCAGGG", #' CLONE=1, #' TYPE=c("IgM", "IgG", "IgG", "IgA"), #' COUNT=1:4, #' stringsAsFactors=FALSE) #' #' # Without end masking #' makeChangeoClone(db, text_fields="TYPE", num_fields="COUNT") #' #' # With end masking #' makeChangeoClone(db, max_mask=3, text_fields="TYPE", num_fields="COUNT") #' #' @export makeChangeoClone <- function(data, id="SEQUENCE_ID", seq="SEQUENCE_IMGT", germ="GERMLINE_IMGT_D_MASK", vcall="V_CALL", jcall="J_CALL", junc_len="JUNCTION_LENGTH", clone="CLONE", mask_char="N", max_mask=0, pad_end=FALSE, text_fields=NULL, num_fields=NULL, seq_fields=NULL, add_count=TRUE, verbose=FALSE) { # Check for valid fields check <- checkColumns(data, c(id, seq, germ, vcall, jcall, junc_len, clone, text_fields, num_fields, seq_fields)) if (check != TRUE) { stop(check) } # Replace gaps with Ns and masked ragged ends tmp_df <- data[, c(id, seq, text_fields, num_fields, seq_fields)] tmp_df[[seq]] <- maskSeqGaps(tmp_df[[seq]], mask_char=mask_char, outer_only=FALSE) tmp_df[[seq]] <- maskSeqEnds(tmp_df[[seq]], mask_char=mask_char, max_mask=max_mask, trim=FALSE) # Pad ends if (pad_end) { tmp_df[[seq]] <- padSeqEnds(tmp_df[[seq]], pad_char=mask_char) } seq_len <- stri_length(tmp_df[[seq]]) if (any(seq_len != seq_len[1])) { len_message <- paste0("All sequences are not the same length for data with first ", id, " = ", tmp_df[[id]][1], ".") if (!pad_end) { len_message <- paste(len_message, "Consider specifying pad_end=TRUE and verify the multiple alignment.") } else { len_message <- paste(len_message, "Verify that all sequences are properly multiple-aligned.") } stop(len_message) } # Remove duplicates tmp_df <- collapseDuplicates(tmp_df, id=id, seq=seq, text_fields=text_fields, num_fields=num_fields, seq_fields=seq_fields, add_count=add_count, verbose=verbose) # Define return object tmp_names <- names(tmp_df) if ("SEQUENCE" %in% tmp_names & seq != "SEQUENCE") { tmp_df <- tmp_df[, tmp_names != "SEQUENCE"] tmp_names <- names(tmp_df) } names(tmp_df)[tmp_names == seq] <- "SEQUENCE" names(tmp_df)[tmp_names == id] <- "SEQUENCE_ID" clone <- new("ChangeoClone", data=as.data.frame(tmp_df), clone=as.character(data[[clone]][1]), germline=maskSeqGaps(data[[germ]][1], mask_char=mask_char, outer_only=FALSE), v_gene=getGene(data[[vcall]][1]), j_gene=getGene(data[[jcall]][1]), junc_len=data[[junc_len]][1]) return(clone) } #### PHYLIP functions #### # Create PHYLIP input files in a temporary folder # # @param clone a ChangeoClone object # @param path a directory to store the write the output files to # @return a named vector translating SEQUENCE_ID (names) to PHYLIP taxa (values) writePhylipInput <- function(clone, path) { # Define PHYLIP columns nseq <- nrow(clone@data) v1 <- c(sprintf('%-9s', nseq + 1), sprintf("%-9s", "Germline"), sprintf("SAM%-6s", 1:nseq)) v2 <- c(stri_length(clone@germline), clone@germline, clone@data[["SEQUENCE"]]) phy_df <- data.frame(v1, v2, stringsAsFactors=F) # Define names vector mapping taxa names to original sequence identifiers id_map <- setNames(gsub("^\\s+|\\s+$", "", v1[-(1:2)]), clone@data[["SEQUENCE_ID"]]) # Create PHYLIP input file write.table(phy_df, file=file.path(path, "infile"), quote=F, sep=" ", col.names=F, row.names=F) return(id_map) } # Run PHYLIP dnapars application # # @param path temporary directory containing infile. # @param dnapars_exec path to the dnapars executable. # @param verbose if TRUE suppress phylip console output. # @return TRUE if phylip ran successfully and FALSE otherwise runPhylip <- function(path, dnapars_exec, verbose=FALSE) { # Expand shell variables dnapars_exec <- path.expand(dnapars_exec) # Remove old files if (file.exists(file.path(path, "outfile"))) { file.remove(file.path(path, "outfile")) } if (file.exists(file.path(path, "outtree"))) { file.remove(file.path(path, "outtree")) } # Set platform specific options if (.Platform$OS.type == "windows") { quiet_params <- list(ignore.stdout=TRUE, ignore.stderr=TRUE) invoke <- shell } else { quiet_params <- list(stdout=FALSE, stderr=FALSE) invoke <- system2 } # Set dnapars options phy_options <- c("S", "Y", "I", "4", "5", ".") params <- list(dnapars_exec, input=c(phy_options, "Y"), wait=TRUE) if (!verbose) { params <- append(params, quiet_params) } # Call phylip wd <- getwd() setwd(path) status <- tryCatch(do.call(invoke, params), error=function(e) e) setwd(wd) # Return TRUE if phylip ran successfully invisible(status == 0) } # Reads in the PHYLIP outfile # # @param path the temporary folder containing the dnapars outfile # @return a character vector with each item as a line in the outfile readPhylipOutput <- function(path) { phylip_out <- scan(file.path(path, "outfile"), what="character", sep="\n", blank.lines.skip=FALSE, strip.white=FALSE, quiet=TRUE) return(phylip_out) } # Test for successful PHYLIP dnapars run by checking the outfile # # @param phylip_out a character vector returned by readPhylipOut # @return TRUE if trees built # FALSE if no trees built checkPhylipOutput <- function(phylip_out) { # Check for failed tree build result <- !(any(grepl('-1 trees in all found', phylip_out))) return(result) } # Extracts inferred sequences from PHYLIP dnapars outfile # # @param phylip_out a character vector returned by readPhylipOutput # @return a list containing an id vector, a sequence vector and an annotation data.frame getPhylipInferred <- function(phylip_out) { # Process dnapars output seq_start <- min(grep("From\\s+To\\s+Any Steps\\?\\s+State at upper node", phylip_out, perl=T, fixed=F)) seq_empty <- grep("^\\s*$", phylip_out[seq_start:length(phylip_out)], perl=T, fixed=F) seq_len <- seq_empty[min(which(seq_empty[-1] == (seq_empty[-length(seq_empty)] + 1)))] seq_block <- paste(phylip_out[(seq_start + 2):(seq_start + seq_len - 2)], collapse="\n") seq_df <- read.table(textConnection(seq_block), as.is=T, fill=T, blank.lines.skip=F) # Correct first line of block and remove blank rows fix.row <- c(1, which(is.na(seq_df[,1])) + 1) end_col <- ncol(seq_df) - 2 #seq_df[fix.row, ] <- cbind(0, seq_df[fix.row, 1], "no", seq_df[fix.row, 2:5], stringsAsFactors=F) seq_df[fix.row, ] <- data.frame(cbind(0, seq_df[fix.row, 1], "no", seq_df[fix.row, 2:end_col]), stringsAsFactors=F) if (length(fix.row)>1) { seq_df <- seq_df[-(fix.row[-1] - 1), ] } # Create data.frame of inferred sequences inferred_num <- unique(grep("^[0-9]+$", seq_df[, 2], value=T)) inferred_seq <- sapply(inferred_num, function(n) { paste(t(as.matrix(seq_df[seq_df[, 2] == n, -c(1:3)])), collapse="") }) if (length(inferred_num)>0) { return(data.frame(SEQUENCE_ID=paste0("Inferred", inferred_num), SEQUENCE=inferred_seq, stringsAsFactors = FALSE)) } data.frame(SEQUENCE_ID=c(), SEQUENCE=c(), stringsAsFactors = FALSE) } # Extracts graph edge list from a PHYLIP dnapars outfile # # @param phylip_out character vector returned by readPhylipOutput # @param id_map named vector of PHYLIP taxa names (values) to sequence # identifiers (names) that will be translated. If NULL # no taxa name translation is performed # @return a data.frame of edges with columns (from, to, weight) getPhylipEdges <- function(phylip_out, id_map=NULL) { # Process dnapars output edge_start <- min(grep('between\\s+and\\s+length', phylip_out, perl=TRUE, fixed=FALSE)) edge_len <- min(grep('^\\s*$', phylip_out[edge_start:length(phylip_out)], perl=TRUE, fixed=FALSE)) edge_block <- paste(phylip_out[(edge_start + 2):(edge_start + edge_len - 2)], collapse='\n') edge_df <- read.table(textConnection(edge_block), col.names=c('from', 'to', 'weight'), as.is=TRUE) # Modify inferred taxa names to include "Inferred" inf_map <- unique(grep("^[0-9]+$", c(edge_df$from, edge_df$to), value=T)) names(inf_map) <- paste0("Inferred", inf_map) edge_df$from <- translateStrings(edge_df$from, inf_map) edge_df$to <- translateStrings(edge_df$to, inf_map) if (!is.null(id_map)) { # Reassign PHYLIP taxa names to sequence IDs edge_df$from <- translateStrings(edge_df$from, id_map) edge_df$to <- translateStrings(edge_df$to, id_map) } return(edge_df) } # Modify edges of phylip output # # @param edges data.frame of edges returned by getPhylipEdges # @param clone a ChangeoClone object containg sequence data # @param dist_mat DNA character distance matrix # @return a list of modified edges data.frame and clone object modifyPhylipEdges <- function(edges, clone, dist_mat=getDNAMatrix(gap=0)) { # Move germline to root position germ_idx <- which(edges$to == "Germline") edges[germ_idx, c('from', 'to')] <- edges[germ_idx, c('to', 'from')] # Calculate edge mutations for (i in 1:nrow(edges)) { if (edges$from[i] == "Germline") { seq1 <- clone@germline } else { seq1 <- clone@data[["SEQUENCE"]][clone@data[["SEQUENCE_ID"]] == edges$from[i]] } seq2 <- clone@data[["SEQUENCE"]][clone@data[["SEQUENCE_ID"]] == edges$to[i]] edges$weight[i] <- seqDist(seq1, seq2, dist_mat) } # Find rows zero weight edges with inferred parent nodes remove_row <- which(edges$weight == 0 & edges$from != "Germline" & grepl('^Inferred\\d+$', edges$from)) # Replace inferred parent nodes with child nodes when edge weight is zero while (length(remove_row) > 0) { # Remove first node with zero distance to parent r <- remove_row[1] r_idx <- which(edges[c('from', 'to')] == edges$from[r], arr.ind=T) edges[r_idx] <- edges$to[r] # Recalculate edge weights for modified rows r_mod <- r_idx[, 1][r_idx[, 1] != r] for (i in r_mod) { if (edges$from[i] == "Germline") { seq1 <- clone@germline } else { seq1 <- clone@data[["SEQUENCE"]][clone@data[["SEQUENCE_ID"]] == edges$from[i]] } seq2 <- clone@data[["SEQUENCE"]][clone@data[["SEQUENCE_ID"]] == edges$to[i]] edges$weight[i] <- seqDist(seq1, seq2, dist_mat) } # Remove row edges <- edges[-r, ] # Re-determine rows to remove remove_row <- which(edges$weight == 0 & edges$from != "Germline" & grepl('^Inferred\\d+$', edges$from)) } # Remove rows from clone keep_clone <- clone@data[["SEQUENCE_ID"]] %in% unique(c(edges$from, edges$to)) clone@data <- as.data.frame(clone@data[keep_clone, ]) return(list(edges=edges, clone=clone)) } # Convert edge data.frame and clone object to igraph graph object # # @param edges data.frame of edges returned by getPhylipEdges # @param clone a ChangeoClone object containg sequence data # @return an igraph graph object phylipToGraph <- function(edges, clone) { # Create igraph object g <- igraph::graph_from_data_frame(edges, directed=T) # Add germline sequence germ_idx <- which(igraph::V(g)$name == "Germline") g <- igraph::set_vertex_attr(g, "sequence", index=germ_idx, clone@germline) # Add sample sequences and names clone_idx <- match(clone@data[["SEQUENCE_ID"]], igraph::V(g)$name) g <- igraph::set_vertex_attr(g, "sequence", index=clone_idx, clone@data[["SEQUENCE"]]) # Add annotations ann_fields <- names(clone@data)[!(names(clone@data) %in% c("SEQUENCE_ID", "SEQUENCE"))] for (n in ann_fields) { g <- igraph::set_vertex_attr(g, n, index=germ_idx, NA) g <- igraph::set_vertex_attr(g, n, index=clone_idx, clone@data[[n]]) } # Add edge and vertex labels igraph::V(g)$label <- igraph::V(g)$name igraph::E(g)$label <- igraph::E(g)$weight # Add graph attributes g$clone <- clone@clone g$v_gene <- clone@v_gene g$j_gene <- clone@j_gene g$junc_len <- clone@junc_len return(g) } #' Infer an Ig lineage using PHYLIP #' #' \code{buildPhylipLineage} reconstructs an Ig lineage via maximum parsimony using the #' dnapars application of the PHYLIP package. #' #' @param clone \link{ChangeoClone} object containing clone data. #' @param dnapars_exec absolute path to the PHYLIP dnapars executable. #' @param dist_mat Character distance matrix to use for reassigning edge weights. #' Defaults to a Hamming distance matrix returned by \link{getDNAMatrix} #' with \code{gap=0}. If gap characters, \code{c("-", ".")}, are assigned #' a value of -1 in \code{dist_mat} then contiguous gaps of any run length, #' which are not present in both sequences, will be counted as a #' distance of 1. Meaning, indels of any length will increase #' the sequence distance by 1. Gap values other than -1 will #' return a distance that does not consider indels as a special case. #' @param rm_temp if \code{TRUE} delete the temporary directory after running dnapars; #' if \code{FALSE} keep the temporary directory. #' @param verbose if \code{FALSE} suppress the output of dnapars; #' if \code{TRUE} STDOUT and STDERR of dnapars will be passed to #' the console. #' #' @return An igraph \code{graph} object defining the Ig lineage tree. Each unique input #' sequence in \code{clone} is a vertex of the tree, with additional vertices being #' either the germline (root) sequences or inferred intermediates. The \code{graph} #' object has the following attributes. #' #' Vertex attributes: #' \itemize{ #' \item \code{name}: value in the \code{SEQUENCE_ID} column of the \code{data} #' slot of the input \code{clone} for observed sequences. #' The germline (root) vertex is assigned the name #' "Germline" and inferred intermediates are assigned #' names with the format {"Inferred1", "Inferred2", ...}. #' \item \code{sequence}: value in the \code{SEQUENCE} column of the \code{data} #' slot of the input \code{clone} for observed sequences. #' The germline (root) vertex is assigned the sequence #' in the \code{germline} slot of the input \code{clone}. #' The sequence of inferred intermediates are extracted #' from the dnapars output. #' \item \code{label}: same as the \code{name} attribute. #' } #' Additionally, each other column in the \code{data} slot of the input #' \code{clone} is added as a vertex attribute with the attribute name set to #' the source column name. For the germline and inferred intermediate vertices, #' these additional vertex attributes are all assigned a value of \code{NA}. #' #' Edge attributes: #' \itemize{ #' \item \code{weight}: Hamming distance between the \code{sequence} attributes #' of the two vertices. #' \item \code{label}: same as the \code{weight} attribute. #' } #' Graph attributes: #' \itemize{ #' \item \code{clone}: clone identifier from the \code{clone} slot of the #' input \code{ChangeoClone}. #' \item \code{v_gene}: V-segment gene call from the \code{v_gene} slot of #' the input \code{ChangeoClone}. #' \item \code{j_gene}: J-segment gene call from the \code{j_gene} slot of #' the input \code{ChangeoClone}. #' \item \code{junc_len}: junction length (nucleotide count) from the #' \code{junc_len} slot of the input \code{ChangeoClone}. #' } #' #' @details #' \code{buildPhylipLineage} builds the lineage tree of a set of unique Ig sequences via #' maximum parsimony through an external call to the dnapars application of the PHYLIP #' package. dnapars is called with default algorithm options, except for the search option, #' which is set to "Rearrange on one best tree". The germline sequence of the clone is used #' for the outgroup. #' #' Following tree construction using dnapars, the dnapars output is modified to allow #' input sequences to appear as internal nodes of the tree. Intermediate sequences #' inferred by dnapars are replaced by children within the tree having a Hamming distance #' of zero from their parent node. With the default \code{dist_mat}, the distance calculation #' allows IUPAC ambiguous character matches, where an ambiguous character has distance zero #' to any character in the set of characters it represents. Distance calculation and movement of #' child nodes up the tree is repeated until all parent-child pairs have a distance greater than zero #' between them. The germline sequence (outgroup) is moved to the root of the tree and #' excluded from the node replacement processes, which permits the trunk of the tree to be #' the only edge with a distance of zero. Edge weights of the resultant tree are assigned #' as the distance between each sequence. #' #' @references #' \enumerate{ #' \item Felsenstein J. PHYLIP - Phylogeny Inference Package (Version 3.2). #' Cladistics. 1989 5:164-166. #' \item Stern JNH, Yaari G, Vander Heiden JA, et al. B cells populating the multiple #' sclerosis brain mature in the draining cervical lymph nodes. #' Sci Transl Med. 2014 6(248):248ra107. #' } #' #' @seealso Takes as input a \link{ChangeoClone}. #' Temporary directories are created with \link{makeTempDir}. #' Distance is calculated using \link{seqDist}. #' See \link{igraph} and \link{igraph.plotting} for working #' with igraph \code{graph} objects. #' #' @examples #' \dontrun{ #' # Preprocess clone #' db <- subset(ExampleDb, CLONE == 3138) #' clone <- makeChangeoClone(db, text_fields=c("SAMPLE", "ISOTYPE"), #' num_fields="DUPCOUNT") #' #' # Run PHYLIP and process output #' dnapars_exec <- "~/apps/phylip-3.69/dnapars" #' graph <- buildPhylipLineage(clone, dnapars_exec, rm_temp=TRUE) #' #' # Plot graph with a tree layout #' library(igraph) #' plot(graph, layout=layout_as_tree, vertex.label=V(graph)$ISOTYPE, #' vertex.size=50, edge.arrow.mode=0, vertex.color="grey80") #' #' # To consider each indel event as a mutation, change the masking character #' # and distance matrix #' clone <- makeChangeoClone(db, text_fields=c("SAMPLE", "ISOTYPE"), #' num_fields="DUPCOUNT", mask_char="-") #' graph <- buildPhylipLineage(clone, dnapars_exec, dist_mat=getDNAMatrix(gap=-1), #' rm_temp=TRUE) #' } #' #' @export buildPhylipLineage <- function(clone, dnapars_exec, dist_mat=getDNAMatrix(gap=0), rm_temp=FALSE, verbose=FALSE) { # Check clone size if (nrow(clone@data) < 2) { warning("Clone ", clone@clone, " was skipped as it does not contain at least 2 unique sequences") return(NULL) } # Check fields seq_len = unique(stri_length(clone@data[["SEQUENCE"]])) germ_len = ifelse(length(clone@germline) == 0, 0, stri_length(clone@germline)) if(germ_len == 0) { stop("Clone ", clone@clone, "does not contain a germline sequence.") } if(length(seq_len) != 1) { stop("Clone ", clone@clone, "does not contain sequences of equal length.") } if(seq_len != germ_len) { stop("The germline and input sequences are not the same length for clone ", clone@clone) } # Check dnapars access if (file.access(dnapars_exec, mode=1) == -1) { stop("The file ", dnapars_exec, " cannot be executed.") } # Create temporary directory temp_path <- makeTempDir(paste0(clone@clone, "-phylip")) if (verbose) { cat("TEMP_DIR> ", temp_path, "\n", sep="") } # Run PHYLIP id_map <- writePhylipInput(clone, temp_path) runPhylip(temp_path, dnapars_exec, verbose=verbose) phylip_out <- readPhylipOutput(temp_path) # Remove temporary directory if (rm_temp) { unlink(temp_path, recursive=TRUE) } # Check output for trees if (!checkPhylipOutput(phylip_out)) { warning('PHYLIP failed to generate trees for clone ', clone) return(NULL) } # Extract inferred sequences from PHYLIP output inf_df <- getPhylipInferred(phylip_out) clone@data <- as.data.frame(bind_rows(clone@data, inf_df)) # Extract edge table from PHYLIP output edges <- getPhylipEdges(phylip_out, id_map=id_map) # Modify PHYLIP tree to remove 0 distance edges mod_list <- modifyPhylipEdges(edges, clone, dist_mat=dist_mat) # Convert edges and clone data to igraph graph object graph <- phylipToGraph(mod_list$edges, mod_list$clone) return(graph) } #' Convert a tree in ape \code{phylo} format to igraph \code{graph} format. #' #' \code{phyloToGraph} converts a tree in \code{phylo} format to and #' \code{graph} format. #' #' @param phylo An ape \code{phylo} object. #' @param germline If specified, places specified tip sequence as the direct #' ancestor of the tree #' #' @return A \code{graph} object representing the input tree. #' #' @details #' Convert from phylo to graph object. Uses the node.label vector to label internal nodes. Nodes #' may rotate but overall topology will remain constant. #' #' @references #' \enumerate{ #' \item Hoehn KB, Lunter G, Pybus OG - A Phylogenetic Codon Substitution Model for Antibody #' Lineages. Genetics 2017 206(1):417-427 #' https://doi.org/10.1534/genetics.116.196303 #' \item Hoehn KB, Vander Heiden JA, Zhou JQ, Lunter G, Pybus OG, Kleinstein SHK - #' Repertoire-wide phylogenetic models of B cell molecular evolution reveal #' evolutionary signatures of aging and vaccination. bioRxiv 2019 #' https://doi.org/10.1101/558825 #' } #' #' @examples #' \dontrun{ #' library(igraph) #' library(ape) #' #' #convert to phylo #' phylo = graphToPhylo(graph) #' #' #plot tree using ape #' plot(phylo,show.node.label=TRUE) #' #' #store as newick tree #' write.tree(phylo,file="tree.newick") #' #' #read in tree from newick file #' phylo_r = read.tree("tree.newick") #' #' #convert to igraph #' graph_r = phyloToGraph(phylo_r,germline="Germline") #' #' #plot graph - same as before, possibly rotated #' plot(graph_r,layout=layout_as_tree) #' } #' #' @export phyloToGraph <- function(phylo, germline=NULL) { names <- 1:length(unique(c(phylo$edge[, 1],phylo$edge[, 2]))) for(i in 1:length(phylo$tip.label)){ names[i] <- phylo$tip.label[i] } if(!is.null(phylo$node.label)){ for(j in 1:length(phylo$node.label)){ i <- i + 1 names[i] <- phylo$node.label[j] } } d <- data.frame(cbind(phylo$edge,phylo$edge.length)) names(d)=c("from", "to", "weight") if(!is.null(germline)){ germnode <- which(phylo$tip.label == germline) phylo$uca = phylo$edge[phylo$edge[,2] == germnode,1] if(sum(d$from == phylo$uca) == 2){ d[d$from == phylo$uca, ]$from <- germnode d <- d[!(d$from == germnode & d$to == germnode),] }else{ row <- which(d$from == phylo$uca & d$to == germnode) d[row,]$to <- phylo$uca d[row,]$from <- germnode } } d$to <- as.character(d$to) d$from <- as.character(d$from) g <- igraph::graph_from_data_frame(d) igraph::V(g)$name <- names[as.numeric(igraph::V(g)$name)] igraph::E(g)$label <- igraph::E(g)$weight return(g) } #' Convert a tree in igraph \code{graph} format to ape \code{phylo} format. #' #' \code{graphToPhylo} a tree in igraph \code{graph} format to ape \code{phylo} #' format. #' #' @param graph An igraph \code{graph} object. #' #' @return A \code{phylo} object representing the input tree. Tip and internal node names are #' stored in the \code{tip.label} and \code{node.label} vectors, respectively. #' #' @details #' Convert from igraph \code{graph} object to ape \code{phylo} object. If \code{graph} object #' was previously rooted with the germline as the direct ancestor, this will re-attach the #' germline as a descendant node with a zero branch length to a new universal common ancestor (UCA) #' node and store the germline node ID in the \code{germid} attribute and UCA node number in #' the \code{uca} attribute. Otherwise these attributes will not be specified in the \code{phylo} object. #' Using \code{phyloToGraph(phylo, germline=phylo$germid)} creates a \code{graph} object with the germline #' back as the direct ancestor. Tip and internal node names are #' stored in the \code{tip.label} and \code{node.label} vectors, respectively. #' #' @references #' \enumerate{ #' \item Hoehn KB, Lunter G, Pybus OG - A Phylogenetic Codon Substitution Model for Antibody #' Lineages. Genetics 2017 206(1):417-427 #' https://doi.org/10.1534/genetics.116.196303 #' \item Hoehn KB, Vander Heiden JA, Zhou JQ, Lunter G, Pybus OG, Kleinstein SHK - #' Repertoire-wide phylogenetic models of B cell molecular evolution reveal #' evolutionary signatures of aging and vaccination. bioRxiv 2019 #' https://doi.org/10.1101/558825 #' } #' #' @examples #' \dontrun{ #' library(igraph) #' library(ape) #' #' #convert to phylo #' phylo = graphToPhylo(graph) #' #' #plot tree using ape #' plot(phylo,show.node.label=TRUE) #' #' #store as newick tree #' write.tree(phylo,file="tree.newick") #' #' #read in tree from newick file #' phylo_r = read.tree("tree.newick") #' #' #convert to igraph #' graph_r = phyloToGraph(phylo_r,germline="Germline") #' #' #plot graph - same as before, possibly rotated #' plot(graph_r,layout=layout_as_tree) #' } #' #' @export graphToPhylo <- function(graph) { df <- igraph::as_data_frame(graph) node_counts <- table(c(df$to,df$from)) tips <- names(node_counts)[node_counts == 1] nodes <- names(node_counts)[node_counts > 1] germline <- tips[tips %in% df$from] if(length(germline) > 0){ ucanode <- paste0(germline,"_UCA")#max(as.numeric(nodes))+1 nodes <- c(ucanode,nodes) df[df$from == germline,]$from <- ucanode row <- c(ucanode,germline,0.0) names(row) <- c("from","to","weight") df <- rbind(df, row) } tipn <- 1:length(tips) names(tipn) <- tips noden <- (length(tips)+1):(length(tips)+length(nodes)) names(noden) <- nodes renumber <- c(tipn,noden) df$from <- as.numeric(renumber[df$from]) df$to <- as.numeric(renumber[df$to]) phylo <- list() phylo$edge <- matrix(cbind(df$from,df$to),ncol=2) phylo$edge.length <- as.numeric(df$weight) phylo$tip.label <- tips phylo$Nnode <- length(nodes) phylo$node.label <- nodes class(phylo) <- "phylo" if(length(germline) > 0){ phylo <- rerootGermline(phylo, germline) } phylo = ape::ladderize(phylo, right=FALSE) return(phylo) } # Reroot phylogenetic tree to have its germline sequence at a zero-length branch # to a node which is the direct ancestor of the tree's UCA. Assigns \code{uca} # to be the ancestral node to the tree's germline sequence, as \code{germid} as # the tree's germline sequence ID. # # @param tree An ape \code{phylo} object # @param germid ID of the tree's predicted germline sequence # @param resolve If \code{TRUE} reroots tree to specified germline sequnece. # usually not necessary with IgPhyML trees analyzed with HLP model. rerootGermline <- function(tree, germid, resolve=FALSE){ if(resolve) { tree <- ape::root(phy=tree, outgroup=germid, resolve.root=T, edge.label=TRUE) } tree <- ape::reorder.phylo(tree, "postorder") edges <- tree$edge rootnode <- which(tree$tip.label==germid) rootedge <- which(edges[, 2] == rootnode) rootanc <- edges[edges[, 2] == rootnode, 1] mrcaedge <- which(edges[, 1] == rootanc & edges[, 2] != rootnode) if(length(mrcaedge) > 1){ print("POLYTOMY AT ROOT?!") quit(save="no", status=1, runLast=FALSE) } tree$edge.length[mrcaedge] <- tree$edge.length[mrcaedge] + tree$edge.length[rootedge] tree$edge.length[rootedge] <- 0 tree$uca <- rootanc tree$germid <- germid return(tree) } #' Read in output from IgPhyML #' #' \code{readIgphyml} reads output from the IgPhyML phylogenetics inference package for #' B cell repertoires #' #' @param file IgPhyML output file (.tab). #' @param id ID to assign to output object. #' @param format if \code{"graph"} return trees as igraph \code{graph} objects. #' if \code{"phylo"} return trees as ape \code{phylo} objects. #' @param collapse if \code{TRUE} transform branch lengths to units of substitutions, #' rather than substitutions per site, and collapse internal nodes #' separated by branches < 0.1 substitutions. #' #' @return A list containing IgPhyML model parameters and estimated lineage trees. #' #' Object attributes: #' \itemize{ #' \item \code{param}: Data.frame of parameter estimates for each clonal #' lineage. Columns include: \code{CLONE}, which is the #' clone id; \code{NSEQ}, the total number of sequences in #' the lineage; \code{NSITE}, the number of codon sites; #' \code{TREE_LENGTH}, the sum of all branch lengths in #' the estimated lineage tree; and \code{LHOOD}, the log #' likelihood of the clone's sequences given the tree and #' parameters. Subsequent columns are parameter estimates #' from IgPhyML, which will depend on the model used. #' Parameter columns ending with \code{_MLE} are maximum #' likelihood estimates; those ending with \code{_LCI} are #' the lower 95%% confidence interval estimate; those ending #' with \code{_UCI} are the upper 95%% confidence interval #' estimate. The first line of \code{param} is for clone #' \code{REPERTOIRE}, #' which is a summary of all lineages within the repertoire. #' For this row, \code{NSEQ} is the total number of sequences, #' \code{NSITE} is the average number of sites, and #' \code{TREE_LENGTH} is the mean tree length. For most #' applications, parameter values will be the same for all #' lineages within the repertoire, so access them simply by: #' \code{$param$OMEGA_CDR_MLE[1]} to, for instance, #' get the estimate of dN/dS on the CDRs at the repertoire level. #' \item \code{trees}: List of tree objects estimated by IgPhyML. If #' \code{format="graph"} these are igraph \code{graph} objects. #' If \code{format="phylo"}, these are ape \code{phylo} objects. #' \item \code{command}: Command used to run IgPhyML. #' } #' #' @details #' \code{readIgphyml} reads output from the IgPhyML repertoire phylogenetics inference package. #' The resulting object is divded between parameter estimates (usually under the HLP19 model), #' which provide information about mutation and selection pressure operating on the sequences. #' #' Trees returned from this function are either igraph objects or phylo objects, and each may be #' visualized accordingly. Futher, branch lengths in tree may represent either the expected number of #' substitutions per site (codon, if estimated under HLP or GY94 models), or the total number of #' expected substitutions per site. If the latter, internal nodes - but not tips - separated by branch #' lengths less than 0.1 are collapsed to simplify viewing. #' #' @references #' \enumerate{ #' \item Hoehn KB, Lunter G, Pybus OG - A Phylogenetic Codon Substitution Model for Antibody #' Lineages. Genetics 2017 206(1):417-427 #' https://doi.org/10.1534/genetics.116.196303 #' \item Hoehn KB, Vander Heiden JA, Zhou JQ, Lunter G, Pybus OG, Kleinstein SHK - #' Repertoire-wide phylogenetic models of B cell molecular evolution reveal #' evolutionary signatures of aging and vaccination. bioRxiv 2019 #' https://doi.org/10.1101/558825 #' } #' #' @examples #' \dontrun{ #' # Read in and plot a tree from an igphyml run #' library(igraph) #' s1 <- readIgphyml("IB+7d_lineages_gy.tsv_igphyml_stats_hlp.tab", id="+7d") #' print(s1$param$OMEGA_CDR_MLE[1]) #' plot(s1$trees[[1]], layout=layout_as_tree, edge.label=E(s1$trees[[1]])$weight) #' } #' #' @export readIgphyml <- function(file, id=NULL, format=c("graph", "phylo"), collapse=TRUE) { # Check arguments format <- match.arg(format) out <- list() trees <- list() df <- read.table(file, sep="\t", header=TRUE, stringsAsFactors=FALSE) params <- df[, !names(df) %in% c("TREE")] out[["param"]] <- params out[["command"]] <- df[1, ]$TREE for (i in 2:nrow(df)) { tree <- ape::read.tree(text=df[i, ][["TREE"]]) rtree <- rerootGermline(tree,paste0(df[["CLONE"]][i], "_GERM"),resolve=TRUE) if (collapse) { rtree$edge.length <- round(rtree$edge.length*df[i, ]$NSITE, digits=1) rtree <- ape::di2multi(rtree, tol=0.1) } if (format == "graph") { ig <- phyloToGraph(rtree, germline=rtree$germid) trees[[df[["CLONE"]][i]]] <- ig } else if (format == "phylo") { trees[[df[["CLONE"]][i]]] <- tree } else { stop("Format must be either 'graph' or 'phylo'.") } } out[["trees"]] <- trees if (!is.null(id)) { out$param$ID <- id } return(out) } #' Combine IgPhyML object parameters into a dataframe #' #' \code{combineIgphyml} combines IgPhyML object parameters into a data.frame. #' #' @param iglist list of igphyml objects returned by \link{readIgphyml}. #' Each must have an \code{ID} column in its \code{param} attribute, #' which can be added automatically using the \code{id} option of #' \code{readIgphyml}. #' @param format string specifying whether each column of the resulting data.frame #' should represent a parameter (\code{wide}) or if #' there should only be three columns; i.e. ID, varable, and value #' (\code{long}). #' #' @return A data.frame containing HLP model parameter estimates for all igphyml objects. #' Only parameters shared among all objects will be returned. #' #' @details #' \code{combineIgphyml} combines repertoire-wide parameter estimates from mutliple igphyml #' objects produced by readIgphyml into a dataframe that can be easily used for plotting and #' other hypothesis testing analyses. #' #' All igphyml objects used must have an "ID" column in their \code{param} attribute, which #' can be added automatically from the \code{id} flag of \code{readIgphyml}. #' #' @references #' \enumerate{ #' \item Hoehn KB, Lunter G, Pybus OG - A Phylogenetic Codon Substitution Model for Antibody #' Lineages. Genetics 2017 206(1):417-427 #' https://doi.org/10.1534/genetics.116.196303 #' \item Hoehn KB, Vander Heiden JA, Zhou JQ, Lunter G, Pybus OG, Kleinstein SHK - #' Repertoire-wide phylogenetic models of B cell molecular evolution reveal #' evolutionary signatures of aging and vaccination. bioRxiv 2019 #' https://doi.org/10.1101/558825 #' } #' #' @seealso \link{readIgphyml} #' #' @examples #' \dontrun{ #' # Read in and combine two igphyml runs #' s1 <- readIgphyml("IB+7d_lineages_gy.tsv_igphyml_stats_hlp.tab", id="+7d") #' s2 <- readIgphyml("IB+7d_lineages_gy.tsv_igphyml_stats_hlp.tab", id="s2") #' combineIgphyml(list(s1, s2)) #' } #' #' @export combineIgphyml <- function(iglist, format=c("wide", "long")) { # Check arguments format <- match.arg(format) ordered_params <- c( "ID", "NSEQ", "NSITE", "LHOOD", "TREE_LENGTH", "OMEGA_FWR_MLE", "OMEGA_FWR_LCI", "OMEGA_FWR_UCI", "OMEGA_CDR_MLE", "OMEGA_CDR_LCI", "OMEGA_CDR_UCI", "KAPPA_MLE", "KAPPA_LCI", "KAPPA_UCI", "WRC_2_MLE", "WRC_2_LCI", "WRC_2_UCI", "GYW_0_MLE", "GYW_0_LCI", "GYW_0_UCI", "WA_1_MLE", "WA_1_LCI", "WA_1_UCI", "TW_0_MLE", "TW_0_LCI", "TW_0_UCI", "SYC_2_MLE", "SYC_2_LCI", "SYC_2_UCI", "GRS_0_MLE", "GRS_0_LCI", "GRS_0_UCI") paramCount <- table(unlist(lapply(iglist, function(x) names(x$param)))) params <- names(paramCount[paramCount == max(paramCount)]) params <- ordered_params[ordered_params %in% params] if (sum(params == "ID") == 0) { message <- "ID not specified in objects. Use 'id' flag in readIgphyml." stop(message) } repertoires <- lapply(iglist, function(x) x$param[1, params]) combined <- dplyr::bind_rows(repertoires) if (format == "long") { combined <- tidyr::gather(combined, "variable", "value", -!!rlang::sym("ID")) combined$variable <- factor(combined$variable, levels=params) } return(combined) }alakazam/NEWS.md0000644000176200001440000002736313513664047013155 0ustar liggesusersVersion 0.3.0: July 17, 2019 ------------------------------------------------------------------------------- Deprecated: + `rarefyDiversity` is deprecated in favor of `alphaDiversity`, which includes the same functionality. + `testDiversity` is deprecated. The test calculation have been added to the normal output of `alphaDiversity`. General: + Added `ape` and `tibble` dependencies. Lineage: + Added `readIgphyml` to read in IgPhyML output and `combineIgphyml` to combine parameter estimates across samples. + Added `graphToPhylo` and `phyloToGraph` to allow conversion between graph and phylo formats. Diversity: + Fixed a bug in `estimateAbundance` where setting the `clone` column to a non-default value produced an error. + Added rarefaction options to `estimateAbundance` through the `min_n`, `max_n`, and `uniform` arguments. + Moved the rarefaction calculation for the diversity functions into `estimateAbundance`. `alphaDiversity` will call `estimateAbundance` for bootstrapping if not provided an existing `AbundanceCurve` object. + Restructured the `DiversityCurve` and `AbundanceCurve` objects to accomodate the new diversity methods. Gene Usage: + `groupGenes` now supports grouping by V gene, J gene, and junction length (`junc_len`) as well, in addition to grouping by V gene and J gene without junction length. Also added support for single-cell input data with the addition of new arguments `cell_id`, `locus`, and `only_igh`. Version 0.2.11: September 12, 2018 ------------------------------------------------------------------------------- General: + Added `nonsquareDist` function to calculate the non-square distance matrix of sequences. + Exported some internal utility functions to make them available to dependent packages: `progressBar`, `baseTheme`, `checkColumns` and `cpuCount`. Diversity: + `estimateAbundance`, and `plotAbundanceCurve`, will now allow `group=NULL` to be specified to performance abundance calculations on ungrouped data. Gene Usage: + Added `fill` argument to `countGenes`. When set `TRUE` this adds zeroes to the `group` pairs that do not exist in the data. + Added new function `groupGenes` to group sequences sharing same V and J gene. Toplogy Analysis: + Fixed a bug in tableEdges causing it to fail when no parent/child relationships exist when specifying `indirect=TRUE`. + `makeChangeoClone` will now issue an error and terminate, instead of continuing with a warning, when all sequences are not the same length. Version 0.2.10: March 30, 2018 ------------------------------------------------------------------------------- General: + Fixed a bug in `IPUAC_AA` wherein X was not properly matching against Q. + Changed behavior in `getAAMatrix` to treat * (stop codon) as a mismatch. Version 0.2.9: March 21, 2018 ------------------------------------------------------------------------------- General: + Added explicit type casting for known columns to `readChangeoDb`. + Added the `padSeqEnds` function which pads sequences with Ns to make then equal in length. + Added verification of unique sequence IDs to `collapseDuplicates`. Diversity: + Added the `uniform` argument to `rarefyDiversity` allowing users to toggle uniform vs non-uniform sampling. + Renamed `plotAbundance` to `plotAbundanceCurve`. + Changed `estimateAbundance` return object from a data.frame to a new `AbundanceCurve` custom class. + Set default `plot` call for `AbundanceCurve` to `plotAbundanceCurve`. + Added the `annotate` argument from `plotDiversityCurve` to `plotAbundanceCurve`. + Added the `score` argument to `plotDiversityCurve` to toggle between plotting diversity or evenness. + Added the function `plotDiversityTest` to generate a simple plot of `DiversityTest` object summaries. Gene Usage: + Added the `omit_nl` argument to `getAllele`, `getGene` and `getFamily` to allow optional filtering of non-localized (NL) genes. Lineage: + Fixed a bug in `makeChangeoClone` preventing it from interpreting the `id` argument correctly. + Added the `pad_end` argument to `makeChangeoClone` to allow automatic padding of ends to make sequences the same length. Version 0.2.8: September 21, 2017 ------------------------------------------------------------------------------- General: + Updated Rcpp dependency to 0.12.12. + Added `dry` argument to `collapseDuplicates` which will annotate duplicate sequences but not remove them when set to `TRUE`. + Fixed a bug where `collapseDuplicates` was returning one sequence if all sequences were considered ambiguous. Lineage: + Added ability to change masking character and distance matrix used in `makeChangeoClone` and `buildPhylipLineage` for purposes of (optionally) treating indels as mismatches. + Fixed a bug in `buildPhylipLineage` when PHYLIP doesn't generate inferred sequences and has only one block. Version 0.2.7: June 12, 2017 ------------------------------------------------------------------------------- General: + Fixed a bug in `readChangeoDb` causing the `select` argument to do nothing. + Added progress package dependency. + Internal changes to support Rcpp 0.12.11. Gene Usage: + Renamed the count/frequency columns output by `countGenes` when the `clone` argument is specified to `CLONE_COUNT`/`CLONE_FREQ`. + Added a vignette describing basic gene usage analysis. Version 0.2.6: March 21, 2017 ------------------------------------------------------------------------------- General: + License changed to Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0). + Removed data.table dependency and added readr dependency. + Performance improvements in `readChangeoDb` and `writeChangeoDb`. Version 0.2.5: August 5, 2016 ------------------------------------------------------------------------------- General: + Fixed a bug in `seqDist()` wherein distance was not properly calculated in some sequences containing gap characters. + Added stop and gap characters to `getAAMatrix()` return matrix. Version 0.2.4: July 20, 2016 ------------------------------------------------------------------------------- General: + Added Rcpp and data.table dependencies. + Modified `readChangeoDb()` to wrap `data.table::fread()` instead of `utils::read.table()` if the input file is not compressed. + Ported `testSeqEqual()`, `getSeqDistance()` and `getSeqMatrix()` to C++ to improve performance of `collapseDuplicates()` and other dependent functions. + Renamed `testSeqEqual()`, `getSeqDistance()` and `getSeqMatrix()` to `seqEqual()`, `seqDist()` and `pairwiseDist()`, respectively. + Added `pairwiseEqual()` which creates a logical sequence distance matrix; TRUE if sequences are identical, FALSE if not, excluding Ns and gaps. + Added translation of ambiguous and gap characters to `X` in `translateDNA()`. + Fixed bug in `collapseDuplicates()` wherein the input data type sanity check would cause the vignette to fail to build under R 3.3. + Replaced the `ExampleDb.gz` file with a larger, more clonal, `ExampleDb` data object. + Replaced `ExampleTrees` with a larger set of trees. + Renamed `multiggplot()` to `gridPlot()`. Amino Acid Analysis: + Set default to `normalize=FALSE` for charge calculations to be more consistent with previously published repertoire sequencing results. Diversity Analysis: + Added a `progress` argument to `rarefyDiversity()` and `testDiversity()` to enable the (previously default) progress bar. + Fixed a bug in `estimateAbundance()` were the function would fail if there was only a single input sequence per group. + Changed column names in `data` and `summary` slots of `DiversityTest` to uppercase for consistency with other tools. + Added dispatching of `plot` to `plotDiversityCurve` for `DiversityCurve` objects. Gene Usage: + Added `sortGenes()` function to sort V(D)J genes by name or locus position. + Added `clone` argument to `countGenes()` to allow restriction of gene abundance to one gene per clone. Topology Analysis: + Added a set of functions for lineage tree topology analysis. + Added a vignette showing basic tree topology analysis. Version 0.2.3: February 22, 2016 ------------------------------------------------------------------------------- General: + Fixed a bug wherein the package would not build on R < 3.2.0 due to changes in `base::nchar()`. + Changed R dependency to R >= 3.1.2. Version 0.2.2: January 29, 2016 ------------------------------------------------------------------------------- General: + Updated license from CC BY-NC-SA 3.0 to CC BY-NC-SA 4.0. + Internal changes to conform to CRAN policies. Amino Acid Analysis: + Fixed bug where arguments for the `aliphatic()` function were not being passed through the ellipsis argument of `aminoAcidProperties()`. + Improved amino acid analysis vignette. + Added check for correctness of amino acids sequences to `aminoAcidProperties()`. + Renamed `AA_TRANS` to `ABBREV_AA`. Diversity: + Added evenness and bootstrap standard deviation to `rarefyDiversity()` output. Lineage: + Added `ExampleTrees` data with example output from `buildPhylipLineage()`. Version 0.2.1: December 18, 2015 ------------------------------------------------------------------------------- General: + Removed plyr dependency. + Added dplyr, lazyeval and stringi dependencies. + Added strict requirement for igraph version >= 1.0.0. + Renamed `getDNADistMatrix()` and `getAADistMatrix()` to `getDNAMatrix` and `getAAMatrix()`, respectively. + Added `getSeqMatrix()` which calculates a pairwise distance matrix for a set of sequences. + Modified default plot sizing to be more appropriate for export to PDF figures with 7-8 inch width. + Added `multiggplot()` function for performing multiple panel plots. Amino Acid Analysis: + Migrated amino acid property analysis from Change-O CTL to alakazam. Includes the new functions `gravy()`, `bulk()`, `aliphatic()`, `polar()`, `charge()`, `countPatterns()` and `aminoAcidProperties()`. Annotation: + Added support for unusual TCR gene names, such as 'TRGVA*01'. + Added removal of 'D' label (gene duplication) from gene names when parsed with `getSegment()`, `getAllele()`, `getGene()` and `getFamily()`. May be disabled by providing the argument `strip_d=FALSE`. + Added `countGenes()` to tabulate V(D)J allele, gene and family usage. Diversity: + Added several functions related to analysis of clone size distributions, including `countClones()`, `estimateAbundance()` and `plotAbundance()`. + Renamed `resampleDiversity()` to `rarefyDiversity()` and changed many of the internals. Bootstrapping is now performed on an inferred complete relative abundance distribution. + Added support for inclusion of copy number in clone size determination within `rarefyDiversity()` and `testDiversity()`. + Diversity scores and confiderence intervals within `rarefyDiversity()` and `testDiversity()` are now calculated using the mean and standard deviation of the bootstrap realizations, rather than the median and upper/lower quantiles. + Added ability to add counts to the legend in `plotDiversityCurve()`. Version 0.2.0: June 15, 2015 ------------------------------------------------------------------------------- Initial public release. General: + Added citations for the `citation("alakazam")` command. Version 0.2.0.beta-2015-05-30: May 30, 2015 ------------------------------------------------------------------------------- Lineage: + Added more error checking to `buildPhylipLineage()`. Version 0.2.0.beta-2015-05-26: May 26, 2015 ------------------------------------------------------------------------------- Lineage: + Fixed issue where `buildPhylipLineage()` would hang on R 3.2 due to R change request PR#15508. Version 0.2.0.beta-2015-05-05: May 05, 2015 ------------------------------------------------------------------------------- Prerelease for review. alakazam/MD50000644000176200001440000001432613514052755012360 0ustar liggesusers11a75b484b73ed66a746f534c2db425c *DESCRIPTION 7d8e716d5cad7f028b6eeb1df290a4cc *NAMESPACE 40a133c0e6e74b5a774686da001d1668 *NEWS.md ca71ac8c9f1d8edbc9b19e6401531916 *R/Alakazam.R 9bacdbf9fdf6b34d796247445fa65050 *R/AminoAcids.R 3d59eebf9943f3510b0ca93389977d1c *R/Classes.R 512ffc2aea484caf86ebec3d8935dc99 *R/Core.R befcaaa614d233f1ea8294feaec7d954 *R/Data.R 3b8d18e200096ccba9062f85669d750c *R/Deprecated.R b65ef59c839ec19943c1aca8854e1244 *R/Diversity.R 89e0f88b92632e7d2c40e26ea3a17cb2 *R/Gene.R afa0a87a2db30cb2e7dc8d1bdb99777e *R/Lineage.R 6f8a72642969fd382cd8f88bc18e6b24 *R/RcppExports.R 6dbca72f6a0edfbc98cacc5b593f0f86 *R/Sequence.R 4c9ebd4e7d82427be89c3dc5a1f6b9f3 *R/Topology.R 2be0a5362455c544103dcae08438ad32 *R/sysdata.rda 2615b26313f998cf9856f149f418f5d4 *README.md f8ece3b26c30a3bb6bd8ec44764ae1d9 *build/vignette.rds 3d37dbf47ab43f43b0333666b76a0698 *data/ExampleDb.rda 4eda2d480c143a6a24a4ac186eda1c86 *data/ExampleTrees.rda b034dfc6972e3bdd19b8801d55ac4b7e *inst/CITATION 769383a43ff88ff8ba46792363773a8c *inst/doc/AminoAcids-Vignette.R 5ef45c121608330c741efbe06f88024b *inst/doc/AminoAcids-Vignette.Rmd f84ac7d2f5f2f93a9ad02d9d605e272c *inst/doc/AminoAcids-Vignette.pdf 567e10dc479ec5913ac7ca35b40cb55f *inst/doc/Diversity-Vignette.R 97b1d8b038a585145d1bb47e2d6fed00 *inst/doc/Diversity-Vignette.Rmd 73c32e6b873e11a923169a6177d3205a *inst/doc/Diversity-Vignette.pdf ddc3b83b2023540dd65b3cecacd3d7d9 *inst/doc/GeneUsage-Vignette.R 83ad6dea398535ef25421c56d82cdc2e *inst/doc/GeneUsage-Vignette.Rmd dd4122c61b0446a2ed8588835528842d *inst/doc/GeneUsage-Vignette.pdf 2beeea3c76901926e254d5047e82bb50 *inst/doc/Lineage-Vignette.R 70e816fc27204bb6e2878b7a954c9d32 *inst/doc/Lineage-Vignette.Rmd 4db5cb06829e387c52ad300686001886 *inst/doc/Lineage-Vignette.pdf 992842730e2fb10e32081c3981f879cf *inst/doc/Topology-Vignette.R bf365971a4fd926b5ad1f3da4e19514a *inst/doc/Topology-Vignette.Rmd 633d71fa30b30469b11c09922467051b *inst/doc/Topology-Vignette.pdf a9d1d1d3adacad855a87f97122d7deee *man/ABBREV_AA.Rd 32a09fdb088b838a64d781bae48aeb1e *man/AbundanceCurve-class.Rd 13bf964a5e2d342c91185034bf2bb2cb *man/ChangeoClone-class.Rd 6f55697229268806bef6a10717678c02 *man/DEFAULT_COLORS.Rd 9dcdd69051851c5922d22691fd3bd016 *man/DiversityCurve-class.Rd 5f16cf4f12c48f70f290452943a8df4b *man/EdgeTest-class.Rd 7cbe9e01a367a38af1cb8c90f3e74e98 *man/ExampleDb.Rd f37509d5350c4a6b4b70a27547011fcb *man/ExampleTrees.Rd 10c34071f6e3ba2efde71291511649a7 *man/IMGT_REGIONS.Rd c3c727588288b411491b2de77713ec4a *man/IUPAC_CODES.Rd 9b2771f4bbe1ef992d9445d0571df1bb *man/MRCATest-class.Rd f2dd52bc42f506b23fb49a218f9d4325 *man/alakazam.Rd db19819685d940da24bd3022a9d4e8be *man/aliphatic.Rd e94ee14d55708e18402a5c49f2cbe73b *man/alphaDiversity.Rd f76f2555abccf60a8d955fc59b0fca0d *man/aminoAcidProperties.Rd a8d03c199086e18e26fd673624ffa1a4 *man/baseTheme.Rd fca083d63d31a36f2d65e950822b729b *man/buildPhylipLineage.Rd bbfdb6340b92a396e2b4bb5f15cd5633 *man/bulk.Rd cba7be37853cf41a680e3ebb75494efa *man/calcCoverage.Rd af307d6e0209dbd3acaf15c8ec4c8295 *man/calcDiversity.Rd f5d0c57b59e2dc17cc82c1d59e29d4dd *man/charge.Rd 995aabe2f257ba72862d5b226ce03c66 *man/checkColumns.Rd 0a92493d7bcbd1058510be35635a17b8 *man/collapseDuplicates.Rd 33503ba77fc27083b447048e18f39efc *man/combineIgphyml.Rd c98f78d37057c9c948764fe25cede62d *man/countClones.Rd 6817349daffe1c582f51da33d8e3f829 *man/countGenes.Rd c00a5a8c1ec08b6994ea5e81def0db99 *man/countPatterns.Rd 228c0d1d4a6fc2744f10623b6342ead8 *man/cpuCount.Rd 5c6082df3639a438d6bd66b3df6bf118 *man/estimateAbundance.Rd aa13061b337fd11847f4647661277e7f *man/extractVRegion.Rd d9bcf6fa4885d0682e7f951faf7f2254 *man/getAAMatrix.Rd f3d1c78e3419a6d133ac41d1b340edb6 *man/getDNAMatrix.Rd b0cca26c9b43a786937622e56253d96f *man/getMRCA.Rd fa963434d38a463062f82e0e2ad419e5 *man/getPathLengths.Rd 54a66931095fdf93778765e66b3fddbb *man/getSegment.Rd 76697bcf036a02fbe6ddb7f351926ca9 *man/graphToPhylo.Rd 32bb08194217d09ee7ed3a3baf8667e2 *man/gravy.Rd 43a957cfa4f3285543fad47363376786 *man/gridPlot.Rd cdee52b0e091f5e59e24005a1f07d4e7 *man/groupGenes.Rd 56bbb424640d95b6e9fcb109c76df6f5 *man/isValidAASeq.Rd ec1f214120321eb7bda794a7aa629313 *man/makeChangeoClone.Rd 16c622dc1a843365e20d348978727214 *man/makeTempDir.Rd 1eeab523917cc47d245c324644f4a387 *man/maskSeqEnds.Rd 18ef28997eb2cb4a67ae7f06c4856f6d *man/maskSeqGaps.Rd c4ee04b0eacd1e93066cc87c0520800d *man/nonsquareDist.Rd d4afa5c07e9908b4968e5a8d56053ff9 *man/padSeqEnds.Rd 1e23c90638621a4425fc49ced382dc0c *man/pairwiseDist.Rd a93f7fde10257f4d80ca1a3db58ebcaf *man/pairwiseEqual.Rd 89becaa4bdf1019397e451d162962d3b *man/permuteLabels.Rd 9992507f0b39b569c4eaac2c35e41ebc *man/phyloToGraph.Rd dc4de6f1164569906211f69f7e04d022 *man/plotAbundanceCurve.Rd d1ce553141b700218d62edce336dc484 *man/plotDiversityCurve.Rd 71367b7845074c59094daaddd4ba8df9 *man/plotDiversityTest.Rd a6f9379eee8e3d49d7ed6f0b950fe5cf *man/plotEdgeTest.Rd 6ab45372b605cabb0fb80b3d2a7b4cc6 *man/plotMRCATest.Rd 28947e62ead3a9d5ee9b4edd3ea8be86 *man/plotSubtrees.Rd 57f38289101ef92fa9db938e09766869 *man/polar.Rd 7c2c3846d5f429596501499da0c9aec9 *man/progressBar.Rd 7542a4c71c1f1c63031c18106ccf8f1c *man/rarefyDiversity.Rd 749b4b8b9daca586ea634d209ecbaf74 *man/readChangeoDb.Rd 2df8fafbb6ff33d56e13a4d7aee29b74 *man/readIgphyml.Rd 7cc1917257918b65d8ff2c5e0f47e93c *man/seqDist.Rd f5e27a7fa978350281f109893235c4d4 *man/seqEqual.Rd 1e0a5d095b881bde9dfa4603903b23e5 *man/sortGenes.Rd 4551455c0ab7d85eba44ccab82ddccd5 *man/stoufferMeta.Rd 636a225c9c90626bdeda60cb8c3f4d11 *man/summarizeSubtrees.Rd 6b7a7875c6dbd679c0c8bcb671581755 *man/tableEdges.Rd 8bccb70d88cb73c381dd1de03ba80455 *man/testDiversity.Rd 6afa9381da1049bfa5784d60a623b60b *man/testEdges.Rd 042d002aab3b14029a92891b9c4ce161 *man/testMRCA.Rd 4e82d224ec3508acc060e174c9e132a8 *man/translateDNA.Rd 8242a3df101301f23473a572115fc432 *man/translateStrings.Rd 0fae9e0a11ec04f6fc43723538408b95 *man/writeChangeoDb.Rd 3b377cf40c356ccde3fa098907bfd279 *src/RcppDistance.cpp abf7eb815358ba8bbf07451999ce055e *src/RcppExports.cpp 5ef45c121608330c741efbe06f88024b *vignettes/AminoAcids-Vignette.Rmd 97b1d8b038a585145d1bb47e2d6fed00 *vignettes/Diversity-Vignette.Rmd 83ad6dea398535ef25421c56d82cdc2e *vignettes/GeneUsage-Vignette.Rmd 70e816fc27204bb6e2878b7a954c9d32 *vignettes/Lineage-Vignette.Rmd bf365971a4fd926b5ad1f3da4e19514a *vignettes/Topology-Vignette.Rmd alakazam/inst/0000755000176200001440000000000013513671743013022 5ustar liggesusersalakazam/inst/doc/0000755000176200001440000000000013513671743013567 5ustar liggesusersalakazam/inst/doc/AminoAcids-Vignette.pdf0000644000176200001440000066262613513671705020074 0ustar liggesusers%PDF-1.5 % 20 0 obj << /Length 1760 /Filter /FlateDecode >> stream xXIo6Wibj 4I#c(8#zDD#Mر}iFc7^'||(,8~<8wQS\\S ,E#EJIYqtU"i(:wԺ8i>0Z, ή}# A e8qJ5+@J2!2" QJ݆w}+JagW8GfN"3ҀpxΠ8AnI] ;/Ip zF cbna \K1190@H`-ϲQ"f!bgQ\ɻDDV/*#ې.c YCfJReTn!Uhݵ8<Y0 $:CE$C@] . 2m"dqMH_i3A]KII.MB@|jQJ7s_]fgߺ}5Vc+HM+HZYq7 ; Z0Txo7#T&7aɹ#̅3&5bIͯ%kCue$Tϴnt:C7GԞ9,B[kV#pRJ7";²fYxl8esf4|YC]n9t#+O k1:^Zzƺ+LV36F-!nRSؼɼ@^NNiJ-aQ|]z3}}W۲w][PvM]y^ـ;`Љh:)p ,P ]h{zS&-`Gm+,Ā ydAa:sn mWH0>?9e>R~H0R0D;}2N;ej;J=ods3ak-\E&vx$ɡ4[ @,]?oR3->sCc _>[ ^:9 3<=0"<,̹a]wGgo_? +ųg;6~_ɮ~W>JL@<"ﺆk !hw`fA",D^> stream xZ[sJ~WE]htBBUK&dɫ ןl8~43==__G1M{wuFOaF=ٔҞ90>Y F?G=xMځ+:Ŕ oAF{8cey1<(1 >٦Ƿ)(hg5Lbndj!31Qq*Lrķ]v4[I[QpX"6ܯKj^}w-l6=l# PcV$mI-J| JF)sJY6R:34L@x ޿}|w2:|20yZ3uNP,̦|pFuhǿ$y]Kac1 ;6[}baV Xz@P_-^>r$Sc.(sx#yaI9p"lTT\/l(n !PU/GWO7!oޅ1orh=nH!$f B.x\G\+˿,RQ&;']BqGj0lo$lh"oEf l{Y0׺ITXw!^($WEY)Pka3RXψ!b1+yE+~:@ѢHBJ9a,R-DĻa<`R7BM0R)7)m`ma7ZIFQjQ7Y8W)ƱR~uﭒ:d@|*}IRE7pP ? ȦQXdRfcMP={*sK5+X3W6(o{d*S{Dg5',] \uB c̀0ORUԗ1( =mrSc7-C):[p:7"bmid>QQ_ß@q1fkb#JOmi ʕBg*Xfggn6\5+\`\F>//W'oWgS,mF4@$-5+AƝ~z3 vVE7pgw}"kж1Fkd쳋W@ES.IƁRb:!xͯLP=EB)sdMd>/-`zW<<*AEVKёm6kԔ> stream xXnF+B!&A|p 4FGs@6M )_nR"ٴc f/WU]$B i{oKC&ccS-ms/B f`E4LyXiCA̴"c>x?^3%1)?vӲbi5OYKSa9IE,8ۖ382.J&V?Rfkf#.uqDԴyLrgQmtXMI>/Ŏ]ٗ+XbmJ2DY3IQRg6l^<K/Ss#N'EIJ@'=O;/ [qQ3 ]VE* E缈fPgw[WFOn)?= 8!~.nqYgV{ "UöYZF"[ $~X@R ϦQbJ!L-VY&@m_)<l6@>%F\LO>/ProcSet [ /PDF ] >> /Length 34 /Filter /FlateDecode >> stream x+2T0BC]2RH5Tp Y endstream endobj 48 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./AminoAcids-Vignette_files/figure-latex/unnamed-chunk-2-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 49 0 R /BBox [ 0 0 540 432] /Resources << /ProcSet [/PDF/Text] /Font << /F2 50 0 R >> /ExtGState << >> /ColorSpace << /sRGB 51 0 R >> >> /Length 10324 /Filter /FlateDecode >> stream x][dq~_/w1{%2f% "{fzvglbxxx-~t_χϧ;lm;xO_;?W޼svϰ?i9o~{޹/ۿ?9s1cik=wpޟh Н؎'c ݉mrFxx{s<&/ג ģ+&&Aڏn3 6 v܂I@tOt'`ˣGL ?zg2$$EDREL5; 9sɸU]j/0ic&&ROIb{*S'ōphnVNTA>ths+\>C&@r,I;x'rLVLb3F1xՊ&<֐ZA1Uag.rLVckUn;]"ag.[Cre2Ds.RnkL;ma?]g-#nRLE1ln-z;n٣5?y-F|撁,j5zܵjI1d Y[b5ڊ*_1J-e/\4P@|_=4"׊4V$ekHzK̪iܪyPՃ@$\s[$!9k21_V\Vۢ95"喝@vaYi؏Jv@re2v}cL.}>v-}.O|)?!FKL/"ahˋ$jK ֶEQ"ah֐4Hdm!V@~[>lXc-chikwA%rJ;cQaTpC?9JR54= US.'kĸXw.86k(4isC M'K==\*Li>h@խq*7.v߮/Կ,_//KJЊZ_R>'V#"|UdB֗YlyF"|e݃/&Q`"F9Qփ壭*˔= `TYmTy3bYk^z<^) ѿR§rYz>m_IAKgKwW0e|_6/!;ӿM”Ed2MKH/r7Z/˗e|Y,_/˗'xGxLGzG1=2y;<倇u,#zvODD|"% ze up,Ŗ^m9uElZu~'xkkk'[E)'+bd-͛lZoח[ZO^,_/˗K3';ċkklFkVeJ F,n7׼v{'+>a!ТQLJ#2P1UU1jgXڽ|| v/hZi(Ve u[_ :l+cK%.vVk9x1"1lwbpjC޽GK^ezJ6fx0*fطB]{'hQao 2cTThHv{g 9FAs$ [*Tፇ ~s޻w۱z[=c:)$K>pDo2CG} 鿈-78#FAuOt3͟(t[@th6HD͵nD*i4i,hي=d#b55q6| ن/+\B " V*AN:vP9=nK{@# u=TdԘ/\vOm; Ta# >ۑPR΍Kh#uOݏ_s"'&W ' o|+Eؾ%Jw Dhdk_yP=@Ձ>Q@4_.Hf\ĴI>lb$h?{|_^02\T:Ii4'`$wppŔ(b~Dg6 k~dg4@|ԩƷMok<8otag C_+!a'Z*XQwq(-}jh _+ FšڤI>$.GrR- B7,01Flގ`>~\PVӢs@<#(rE+ԉ֐"hKo_bS~DY_O,S{zn/gX}Ӿ}qJX_/_'^/9[_؎FFKdc=Z//W/-[_T_"^lYPq&n/do&99}c/~)'y Fh| .]N9ᛨrʩ=ձǡC;OڱN_1{gE>Y,{gDP3^bև4=3Ez!_CjX`>;2:?q۰.M0bYk^E'D^β ℼ> 7=8/.&u\vYl^d-K XCFjx/7a<˗ߗ6? iWƠ"Oun|W)=+#2n]7RӼ2pv}_i=x^ t K5.0{XKp,Ьm]!jZFd'&&Z5`ְ֔B^dK0k}/b8YuM)vN S$jjv"ƲY s;1 xwNԎbd`7|/JD R|BX)O:ABݮ#rqgXڽ|Y,_ L{IqKJ^R:KJ^R^8Nܰ䇽pf_{qsX9y#Αccs9y#lȱӛ{;պWZ^RCc~UfD: Ne7[ND u:y{Iq :>u0meYP G6h_6t3{|Y,_/˗|Aɻ8Υ90[Fe}~mvj>Yke}/K'_~5bv[Eڽ|Y,_-'bo`a_0n^}هvsw/X}n/u}l´gnQnjND3=NޫW _Rm{|Y,_/˗e|Y,_/?/+~~/}/%^ 2 <{AYkeҷ|Y,_/˗e|Y,_/˗e|Y,_/˗0Gs~ᓭ"궾sN稺YkrXcpK[e4!v2>Ϝ1:4js ' w4}0:7.͈oB![T^nշxS-r[×no _n.=w-"ݶ+a ڻue5w*Wͺ,C07hu3_>Y|zrx}Nkv}ގnvpJPF=eǿ/_s#@''ϾU{'e;|_SZ蠭Ip n펭Tw/ N+v_UϷW=p%`ڦHx?HOAI6L>}8nC>. .c/КVhOx >)0OY& [y "nZg)m;_QE#|e ry>$)'/gHv{)R2,Z_JCWv8?/g[YV,K$ԼFުn/gHv{ 3Kā3[-MAl϶Pm7p8Jˡa>E˗+ic$Ґ_|aJB0RH 0"U}ѱyk|Mш(V*m,:8Au;XAf>E{^ʲB9XKXUS?1kvd(=LE_&e}a>ʲB,dP>TRlvn,8Io K}/Y_=˷]uMhx/Aj$m|ߋ.d^K3OGP:$J<{-{٤٭RIn/gHv{)n _R']K}@FTQ75o]$;ؽ||6y+}m;\+iDY_϶PeT; |do^6Xglkvu=l=T-xU㸔GV_$jەm)o՗[c-͑k:q_W K~DY_϶PR#Щl8>'"|dR1? X5XgcXVBXFX5bcXv{|Y<ח[s{ڽ99R|ΰRt[_RyM;DRÞ.bsUopCň϶P"5sic"b`d0)9g`Tװ0)lLqJ0*qJn㔈0SbilY`phv1ڱj} ucl}O0Lgim<{+89=qqr{,+Tă{061ze/˗eqN DF4Oq;ᰍ5M] "=? 2qt )%R{"t.xL$zPR ח"{HQ^JئN0ęiJ?_ӴF`A4'NJŴa`RC'[݄E&#\f58GDd=T}*{[P5o],k>_E#={'RZOIRcqps M']u꾃{j5|oh 2'xEu^tjx/2dEyaW@[F,Xzi KKpi }OcbR.Vl0N//[ZhӦ䉔gֹ?LKPZ•xUĿli(CJK^ZKK賥unۈUK%\.>ϕc>_f)†C{I%" " ^ iǪ %BZ+ h(,^ptAWjpD(? ĴMMZJ JDZ}. JL($6E[`% No\kF\%IM@M@III@{Ur>P%cQ "c, EV(?*!x貛Ub,+rTIu6CBaѕJ撙,DgAe{K.Z0f_ގ9B'6C5ILٚ|)gݶ&L;,l-%֤``E`7K50~jbuY2//ɜ'x \&^j_Ŗ}m|ܑ\,+궯iҀٮ`Te_ni' ~qe? -_/˗e|Y,_~_%L | ŕpi2=.[; 60TDs{'a.5 a0܀\L) >Ap2WQWQeW*>ʎv_@!e:[V$: )v೒ҤXfOhJ??> !qL? |Zy@/!+K赖c"GDj-Qer%kXJ6LEePE;n8g = r=ZnmOhJ??ۍu>-t{d7hܭ JVL -.M-t{w2h*kZ+C}E!CGd2g fxPuC͛lZoؗ|:>Xk%^Lj|a>ʲLrΖS.v? QpMm/)z@fJiR'4d-s`D?|Xccn/p̰p̰pnw/,]+f5s)$Ho)Gl{m06IXTo V2U|\fʄ?}xf.^le_ 9_nD0ſx/^} |lE!|B^t^. ˭YD^RJBe*%!OK̝ϗ0뀶|})E\Z}R"d-%& 28JRJ|})K#&K) N,rks_[f 6W@Vٽ*o; gtw-Z endstream endobj 53 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 56 0 obj << /Length 2048 /Filter /FlateDecode >> stream xY[s۶~Ф}f"W^2탓>($ ERTxXP"hYѥM3} o.nGdtyF? IHGg#.;*7ӟΈ+h z/@ ݙrrz@%c0Ziƍt {@$IfWUL55E Nw %n AD2<7x%܊ZUM>k;Cg-m=٫B՟n|`m .g-xB/_~ňt]u~}y %HtwCBf0L/C#\F !7aJ#N]JAây6.]mꬸOxN+N~ \iuiʨ?P|(YRU{؈ԃ9`::sՈڼ~mgi6kl(F2YYgsMZQөDt;fYp!3] e𗌨JXҧ}9]2Kecߣ S^h _mgK]V DE#ख़0,I+0ƎI(gYmn3l< Þ2p 5J-:axZ]!0b3%ar0K=j[YQm݈=̜0 6EYQ7iK9߀ҍ$ء.+l@6k/ְUpf!)-zIƝ;Ej3 nuMbA+ӉLe?awU-jTP$j"lߠ+fəemxlٮ:blUKئcbZhthvAaL5PH/iXS:U.p)]7WKg߿?_y}HB }Ton9};nc(6m~n@{ N[y!/T]t8vDVÎCUZ:UYj/}wy4KU^U5y:ᰑ9q |rۗhovvmk*n!?zIg~ig:/_^_GM:knr_5^w5ZfEyg$~sɬjsP?vbW7}%@+ᇓ: G^H*{x}thߟ{@ 'vi)M]33˴ YNQJKHXgRBg리lk|X{|+s?|mz{|Mʛ(Y얁׌\ ϟUu3ͣ+.MA NSqRKXY㚰RyhWdvq!_{t&8 PBt5CX"ӳ{_I endstream endobj 64 0 obj << /Length 1174 /Filter /FlateDecode >> stream xWo6_!t/23{7lŐz/KA,y6wQ4i:E^#wԑ{}D=tPlw|hwpX(T`t<"R`4 _CUx^)әAq,bl'܌.7,J &Б 8^M/h0d(щY~nzp&M@\|jN7+ 9¥{nC{_% ~bXX'B+yos7>xlnjװ_F;qTQyT$a\HE GhS&"KW`iOf¢DGQ;JkQ ?(ifL{&dv9Ok;ͧˮUhK+P[ A$DhTDEJ1c??G@Eh18љ'&um=;iG}\?WM\f8 MdpR8_ٵR!^<r-/$i[<0FW b^4i{D ^͎;S}=EKV=J3[/9[;&?Ӻ6eo>cI Qq{G$,yiz/N.u/wfPͻQұ'WǀeO 8't|e uR|ԴAx:8IѠ*.MW I X*ƥ! !"ˊ6TinMi+N7 ,{K1Q421tE endstream endobj 70 0 obj << /Length 517 /Filter /FlateDecode >> stream xڥR0+|)c6[eU'X25_ðmjR{ 3&AGDć*p(HvTrCHLPѷhQm (2yӥ\߸Sgethw2 Q$%C8]V<]@E]C$rxo7Fv7pp${w5,fOW18H q^vDצR#my}vy0r^2AO8BFk E9\~<s){",053}hNCG;ScZyP̃b 4ǰ^}g-oRLhqL`㠺 ߨ6C!޷sԐfOӃ* @L*(hC>W-ΞqhID2Ӓ@sL"K"\"\(#k.2LEjn( endstream endobj 83 0 obj << /Length1 1935 /Length2 22962 /Length3 0 /Length 24176 /Filter /FlateDecode >> stream xڴeP\k5wwwwи-8 s93{tK]]MNJ/ljo sgf`ɫ13ыۘX`EF.vbF.@@ K>cO>|qWVVgfsfOF jfN%PY8023:0;38Ond :m.i @h $aNr(˟6Jcahgdgab 0KRMuurC_*u;ӵ5rߎٹ:{6}&vΖ.G,m;陥_2yai qU5z_ 8l!3` |burwdw_ٟ:0Y:C9:&R5)%vw8}-̀Xog#7 O#XfNǐ, _ѥ?KkI?6` 4eTwvrI(kedkivc Cl,a4Ut1˥]>^ёDc`??gthbmtvp(F yeYQLM-,#''#OX`agx3)!02ٻ|\]|fN `#qFܜF .Їɿ3#hkf5+?ym?2~d`t`t]n /-SsVLaU'{k&F.N>C7J@#""l\znv3cVV5*G`=F27iBDAIвLG=ՆB ?(ѹ W"A(MuXoo*JSnc up [BڸTb lۏ'M"}Q, 0R@ M1h|,,ҫ3XtLD-اRmrLj' uH0>ZNjG@JyP%;MNvX '.j02Jν W!r׈Ԃ\8 ΟcK^ 0>T ٯ\QT(QgVnex,(}ȢU炼81ٓujcR1"KbLBCCe`Ps>kWoAPKŐ]Öty%)oRH}7Yo!Snik^K Az:@@N<[J^~$s*- k,VkMFR9N} TcOD9R,kjB4PmaNBGG vF[t||2Y.P>?Wްxrx{ gt yB㹈[Hl/ p}BNQ!!hwN5u,H*z3mUpc\T/tral<Q1+9kI?!ZѴE|Ҍ"/Ec)jkQ$4pWA=m+4E u >zZGn_Le{Op}t@ww͉vH/5y7s \O B+mI~d6S")] p-3<\֕_;<>n5FDOIшE|J`үU.>v]b<鳢C g!!;Yz$Sx9~µY=3󧥓ͻQE֯_⮎0~6 JYc 䳀i &t]>Ѱ~%&w~2RyGWrYH'|5B>Qm!*Jt;h K ']F"ƒuW)+yyERFn[Jqvbd* 9v&I]{-{:BOXT/Hi~,> i1dv6tzo5Z;S88I1n+Gv/1'FcBg\9icJ;}_2u |EO!UCKmӧdyH@g݂jKF#/!buM oZeU}jE|=1VBŪGx`~pƲ+Kv#vȩʩ+f*|ܑ@6Cb`(t4*Nb~Ժ%nZFr̒w8ԩAv6jV SWGҫD wǀǎQ&31Nh+iER9Uz\V&^kR|o_^p"%*(zE0"X}ȄUqn~<_*LTc;hיhn9D_7J$8%+ۨ[BTnw^hd#h aA_c u<DhjADS8^A#J7,ID۽Y!¶ӯhuӌ IϚZ[a-0=êMVvݡ`<&!2p~kcue /fA4GjZ.栥N{Y_i,!NI{qc[@PUȭr@J]b:3zqn}gP%m\ފf8UAyd6z6 ^Cm'>!jI+0BhMlLlGU<8W֩ 25rG;b/$m9">ZH&׏%%* Պ0ʽ&Yq߇qѤdBCS8agb7N bB>H{2$0Ϧj? .棴pVA QX3%VJhr)eBǵ=kCoF0ڝ̈́e\(`J_}],44|F]XYgцW%ƤomL*(ӯir*~ |o}x+KU.p&ђ -yx|BK‡݆h(,HA3Ʃ`J;27֎ Wm 9}TJAu&z5%A 0H\h#F^8b>l|k?*q{ГdAHm?2Nl؎Ĕkn?vIp_P,÷e,(x 7}FRF/ O&E z阢Y4YPF%˨VVV߱ 3M h65Eu۬ n j3F7ީ P5$E([v^p&x#߄g ltڤp@zKAPHK{q:;݃Zh.(a6#S;s7XBy1Kկ_g-`2f-'xuwzY~Bj/C;q\ʪ5:N6X,_-N3xY׷,10 " 1Vۍ)% KLOBidB/N;ZZKwg}S%: ЈKtYsu[.WKk>v[/&XdJc> }.L U%fͻhgˆÞ8Ml1[ELB衂)շYM<λ[MEiW#[f`%r<1f~yl{;tL: w-F]nI6_y-qfY I#tl>Uon5j=A_¢Ds)f7k[ݟ.-AsƸ6S+4" ?Mr_mKhRA;^U'wJ5V~ImAXE{EiH ,,j4O+-(_xcul=?ԠamIku׸@"rzPX˰]つgLHvTׅ7cR=UAvGkT)̐5{|PMD`fyc-/c>R,Si5ŸoGkIzN@:#hw!9x;Osi"L߃cygs&3%=Ym*|\=K5o;?kjD\M,u>L `8}E;G7` 7Q8z묛.U) E0.$d+ˍKk1JWpv$i|aw2^*CeOPMʆ7LL?P1Za.so˚R.3I!aMb'C++3vhBc 8I).Rx4 ^&s3lv͒fܙD䢟.9j|Co go7p6vynRP#ajl!j)RWddZٍk0! xHEUJ"Hv۶)QNoJҴx~>7 ;_+D Iݾ~Diߖ*/<#-&}拤ܢt NzqJ43 OҳҽRz,"޹) MH^Rc^"Aa> *u,Ѷ[#$d¨[[eDM_r0ԕ}u HAL'u!xiJ`be'wIִY -B:etRKyp.)kvN& %Bp+,ï7*[0)-m=aDP.Uޓs$H]ڪ%Q2&d"*q%n "ջY~>`*TVGײr#CVj}T$|pge7iߚp2!e;y=i+Xج9oNj$|wkW e3hxpAC&jÔT}=*f8U׏ovqA&SG.+e5fvy3Χ5|BT%Q&NIi`(2Mſ:RKP-J>afW4tTE^vLPKQl_r?m٘ JWr X UYR=aNS7i-[~>H~ W> ?PMdg+}wQ$ݜ1+ :+ioI*)2}T˧Բ=trkEnG: H:8M^fp.qpVEaEhK\,rc-߁ %EV2gLVF#1ɖ"n<'6. p>g^X%&\ızݿ o1> CGJn m][[:77t|< 57`]`Z]pLEk2;u$sU` e޾#0Wl%-5A K( k"ӱ/~-.dEʘ7ɱ-Dl>2npE4 ncư,dz#eNzc=ywBm@cbqNT )Fqvg32"&V8|#;#xݶ dM>E˶^PXup<x_}aޫ cI3RDSlji94k {mV  51Uw8C#/{Q+i,:Pw|Ǐ ʮy11ȭs`b?D=IlJSױ.z9GM!R$n\4]ĶW{4_t<<.׫2_2+wN=y| z+Z(";RQwѐkFuܼfL|-C bt<\ЪL>Yz)' :0O6cJG[9e8-&6ꅯ^3 뮍 7-lۻFv" sv W?<5')cfdF\sHc_${eia } FUX&a[**Zy]VT"zwߒ =gC7%&i)!,{訴s~ ëyeaB6dv$ťglg,Z)6K`+|{+/[N=M^jY6scZdZ:WʹO:8޴xYu'P޼CZy}œcw EjyDWg|$[^Wx3; 9mdCp3 ڎre#L3EZ\ۢi @6!>,hHF/ q2JM*K. 'N",j *6ἨBK̥[]rI,P1"ўK։A5wtz!SȂ3~R ƈ{lR[}"^Fvww*gy˰agtV"Ú^@ruWIO.IЧ*}? )'Ɉ-0M hA}#k4S7eA]1GZKTaޓDA=~Hf r|K[97-hU]ɮm w2NJT9Ӷȸ0JXxE: ԏJed86)啣3SzD0 .ݼ =ɻ :V甜?'46|vlHs%mڜ&Sk1ƂͳA3(&sZȏ9儨+_esONr+όo nn;fr/mOQkunՅjzjԾ[T:OA SQ=YY"JQ D`3YZpr#Д՗j>x[l:Y+ AٺOlj1(5f 7ޏ&zրX@*XuGz8;UJ'yqi_\JԤ)y>j;(P̱toN /Y$m@{e9}m":2yװ¶P-p$D$[P9F/-}"͡ӓil|F:D#eC;=3L[a>*968m,#>K4Oox5' \>vV0jҧ*oG: ɺ TS)&FEO3kIڑ(,[=f˷Ö3/&|#˿&o//+pi>ZG? i[䣝#j\M A#Y,/+ѷuNmcSdW.06Kpj mkr{:qfbW9.'PD/0&p(OhjCq{u!UۅG!0.2vvIwE^o}!o`N&i-}0mC T|?Q- l)J .Ȭ d@(Ac}>~4=7#I&-X)Hۃ$E߀—b-ţ>0jYL2-n^zʺj9nȝԬ3z*]m1V.\xQh!H !nPw +\dGzxZՌ(+Lar|#TRvJmWBH;Frp[`;ʚ9lz ͅrN%y8$7B:Ÿ4)+Q/>MY~k!MeMl@y|XItJB}BeIas3' k{8֪Aƅ]l'XuW|~Pb1 Te'p&Ϣd҅)s+))jA~dM?PrX+]7ΥUuÅeI7}=[ҩdzts]a9:'~0Ť"DalK&%P!5}FBo H*'gH$3cIJf:L-ܞhe?h%w05lV04 _ػOUsyTW×'Q$|U)f]= ><)>}͇5(i} - OƈHЬ,MUF1Vti(,s_#eg| ӌV&L+i}4ީ\̼V*׍-\u6x|xR1(k7 pQA@E="iد.q eude6cʫjtdlMڝ&L=s;j5,# rK)r$9 %tWx`}EG݁ґn"hh8Q$k;˦{/3rs wz*mGkFbˁ3bƾT|팿7qE- @P0v܇cyqKCf}Jׂ]_q K}ZGya|`”[ҫBÏHF+"U'!ն$ qEX2>u*rŔqE螫):Cd ^D-zn/飪inGLm(+GB5^_|/frCWÞ">Gej +Mu|2qRRͿ8lPx<Xx, /'Xr$!7Tҿ>WRQ-Y~Xk,vI%?- w7Q"~}JLRSL;':F @4-z^uPҪUWv .qDo0Bf,Ip8tZtOQFg/eDŽ^_<-ů4fگqP)b-2~b2ll躶4RtB+.MZx'iIL.xKQ@Ea!|' ZD1#앪 \Z_I#]!}>Vd-_ T:IiTp{9 ӃJA8 kd.Duz2^`FjZY׷`/鈓fxH_%0*v=ާQ+o@  ֈw=PXu姯VQ>AU9WJ@+`j ^N2<^ŧ!^FԜ+Tv<&ۙ3|TKXw\T4M ׭7_I_}cc_zYVTh)I,{܆"X0pٗ}5Hk>U ]>5`U쭎tI&RVaFQ^BA o]VNUCؘ$Vr+TA"!eO_Gwx#sfD*-"DX*҉tݕaIb0@dUvt(e$]MSM>uXQܰs4$3ƚD4jk6lGǺjTϻUqvKzO=P-}sh \Lx0 mR&V\1&o…i`Tkzt 'AEb!|{WZ 26 gksV~Ԣx׷L3!P|zf&@C,]e"ԭKw;ԩtKgUpŧ_Ԣ]x`oS咾fR9r3"34],Hn W[v揘bIH|&K )>9p6]'@;٫-DbZ(l3Zװf9.mTV+3!x,.k2;td)+iNTPU_:65WʨBc|(aq"D~níQ%d̎\,Hj/I iH(|9|Z(Ӻ--*hVtg@n4`" C5mq }he3/_x󦫤˜h tXƯOļ?$|CwU󟿕K(W h =綐=qKpY5v@4GOEEP⦡dEXZv6lj&`'rrNaɅ8&̸qfkOSehR-2=(vnw=_6(4=!˃,Fa MA]nW{EA$mWǒćr1"ZWOqxYV lpJBN?㳗dX<&hZ߸Y ) fpxgUg* K7:d>A/$eWM?ƾ&5 A9@wN,u? 4_~q2 HqG]o_K'S1ě*%9WuBt>4x| QҴ_#R-9<3ߘJQ9q6fr~d: w% Z|+(%ޜ6uWHK#CwI9ݐnvSG@t_ ̢G_ӹP*qJFQ љ!_b{5X-M`£*1q]iPVKQ!GLJ+:Web{dZD5g  C4OL;m͊|[ d$4OG9{vD, lo@F͔C|`1+B o$T'@MɴO _(P84ӉmFcNl6Ic۶Vc۶m{/;'&ÖAv%|~dVZA>Siޕڦ}Fq).wGUUVz0"\cSCl0,"A!|d%q$S!$<+I˛, u]5Z4:SP]\n΍w "2.wH6 ?hU{O%!́-bW)w_F@f9@hY*i3F.BJ]=a,mv[S6%:A6@' g ,_ ckX{nZj .N 'rph`wcHOő%Ԧ]3QH?\}*4՟|Q4[cjm>eo@d=]˕EeZ f-.2+~ngcH͚ .~ﯮt3])=koT,[Z iR}U&)ְx>(駬/wy F[O'_hӾ9c6Puy\:wkkl$Y挥3抖c@FO8RUθl4x:|*O@ _-B=tW[AF?nDNRQF[ju ~#mbN1R(\(|?k:N52lvw@sVqz6dO _ 6ʫ6]:p/c' YH!)P3{? ԧODeAٴz2Bn! R=>S=e;Cb,K"xdCW4ib]r>4c\f(hlXMYPg f-(9;Ccė㾈}lJl›y6Z%jP5 2ퟢh?y!~]ǘQ'|cA9œP]2,޷5C4[^҈'Xu^FiX`w+[Hr'p&ۀP&譊Df.e~-gղTƶ{(jR*Wtb!v=H"iipnQSORjkB032OB,J-F [>gTI`քme7R-<SGOXItQݽoBG$X(9W/Y|u4a#w=Oߵ+͆N(+ï؊N¬TzP"cǼ2ڐ鋅^ㅧaʇɛ;yh-Wss-k`|R~dsPMq໐6Ҟ&e0o>ֹL&[%Z"tX?fbuU;LbkKqh<,RPZ8W;oxCZi5[8; ։NQ*_$I2"Ҧh3 nTeyTۢ &3fځ =LC>?;ۿWi9rK[{~lTHѩXYpC/krBKHgDQGap867+ebNe.&?ʗ%6`Q+sBrɽ{ s)#2CQKG_eiqNZ<5Y`Ab|WvN*һ) q;/ޘVˑSRj& ҆#kbPto.`)nT&ƙ;LDbTiQnT م8K6RJh+žyѠ@ L{Ws$3 T-s25bskVs!幉=BB>]JdpeR 0]!~9})lgMUah]i갪s=Vyx ~+\noږwxt%[X=`UjWRC{TgBgڸ˔Zߩ7QҾRF yȿb|"Ůggq7)ԚÖv0\mGX>hy&RWG|.Fn\6u868HEi9 J7DEE}ǃp?fT4#)򫧔F)1(d-ljB§Ӷ 0h(,;c1? $Be&aS7;>*ڬ`Ԏ^޼G6 eWDV)ʤY]ͪma] s=e@eDkÞ"E+?~ Y4ץob"A.DxOw%Gl]DG76<>n4àQݴr(d2G+_ PbZc, !%qŋ{o lk׬PKCSAOt] ;6 EOui;_ QɁG7oqyt%e~nY6z*S;rm{jK}4R1@:6k-^aߙ@DX"fæHkMbmR)73Y/N{𼯳3[ASd6WBb%LPncޛl`x91//R4=岐$AԚ]ZӟJrվQ젬Tb{im;kEc8/:7#x1(^K&@msUҌKSh*D^ F$Yw`"01J=ZIט%e 7a HEj0\4F}4nX_Cx7Sн֞B.\lүǛIw( ^veZ 9.93]1P?#1kN ځuN19į i0?Pd tAϠ`m&_r9F@iNOJ̥#;+OMظ~lMÜաܒ,gb;gՐ{܄@TxK&uwR%Y>Jt!:lHE >'S8ebsGF3bݓ5 ~I[{e[\Bjg-5pII Xv}.uZLɠz)pϕDؔX ʎvA@3'E[tSaՓkj1+ն g-yBM kzr>O>)Vh&jGV`<h CcPߪh&37XO|+H㗈VںM7-MIQH/AҐIbH[[ %ŽX. x;zC7 EA^eO}ua_C9 (rH <:YUN!R50-J'wa(w+PK D8Xpd%&f,prN5 Tvb; cBrSxFq!p$ FadB>ΝiiՁåSZZ*3͠HYN\淽֭{F Oo`SP`miag ęλ?bf>ˌ_olY<S,H?_<Ꮗ5j98T!c~R!5j~m#tj{IC$}ܝqFY&(V ͺ!<:8Xyϡz}AT>JoU,2G PcܫNS%*drnt׭a-k xiG3GAxFK}{ſf"&8Y$-Ote'4xoϥ' XCkT/]$ڢ1 hC!L$94//r_ޚ4pKi3nO.ܝ}0G*!A0;8 G[,M8pҳŰ5woaԆЃW̤SXR,<`p+fCU=l6~r&3ojA08> stream xڴveT[-ww+ݝ%w=#ܾ}F=^VENJ/l`pwgf`ɫ83Ћ8ؚX`EƮVbƮ@%@ K?f/VusttpXDU%b j@R]Uϧ#~ :ڇχwyq5a5m%qf?w0܁.Vh+6/##+_YZ<mOg-ĸٛ}J2ڻ8I8HӇH3m6Aci򗯜holoaj0KQ  C_*W"7ӳ3ۻx#7ymS{+WO̭lwS3+d jrgO/{WO׿',&b0s>TL#j?ȓuKͭd͑Q (-?",& 4dCW3`nl2~<`}\݁Wg7?`9fVM1(.mo[ɿTS~cBmf@sXF׏f3c%fk`lτ&OT'L-v5hza{ [GE#ۏX:Vvthjctqpp~HhRҊҴ.ۛ:Y[X9^L=ahe3_M`dwpp8a(G70qqX}L131@? h?ݿ!??? +q]C^ϿHrk]aUWg/?L]C7 [DӇ@ `fs[N5{5/g{@O)Ҽ)ouJSxxd97iL߮q 1* Ƌ&|C:%2M(oj9KZnO+:9r6 Uq2|}@Z](2`<*Ks5'z(x!EgTx/Gjz30^ /Ȯ7.OՉn\;|Rv`qYoxcRsiJU>$8;R!td/wrN_ό*xPrv{RFƱ <7*81'mwVRoY߭&+qۉHLHM&{ AOo].<ᅼ1Dz=wc2B] \[>&s;4\QZNITpٛ#?HCZ~~as^x$vE-]cUm۳j'+t\q1"4}fW\>?",+oe}gcRsIW#xƉ̳6m1K g %Xh2R aߍf[t鸝 4Qs:퐆O%[ mB&ZF/WG%+7*:E>G((Ƈq(G=譠SҘ%KHsIU嘥fPd SukȄz29ovlr~É"o!FzSewhJShZ,>b50~k||xl9-,pv*oګ7EJ8 S@N镢{_2xOhˁ f '(x^ 1@E$#Ր$w8BgR}^h Q<_YE~f=bnFB<<)T[; 7.n>=`EQ)#0z!PږVOwV4%O/ wI:/JtRYa8'#?_TQhK2༰vs7}8tc { l$g}nHB10cQ76e_ 7VMN/لJj*zV+=C\XX!!~=zO̖5˔[yg|뤮HCUA/zdr֔w?F3@gY dzVB$۟g-]6O[ m?ږG1_%!B1D:V(Vv"ǧp3^N$#7HR|?@z2H5GpWr{Mߖa %ٝQМx1h .'/}d0Zp0 D<6I99ާ7϶컷*;#m嶫_Q 4gJ(+j뮗 pxZ[ֱ3ԀUш-ě'!2V#6Ig`+!|5$^My#7d||-f̆/cYcxEFRthl8P틨SI4]3ɨZOBy"oF,/ __[qu#ӝ+b4VYErӉeҨ>\3?=[Y:(VifӳC,ވ2t' i4b75z JnBsەo/Kp]}(8j\PR_U%cbh|z_a||'[E RMPNS<f8fj+AKF<{*o`y] C(vԋ-s^6)1*0 UD@'\ D~ lR㻗覢j5bqiVlQu,_Ie}:,VmRLj /uJ`>y- ?^14{ '+P;.W]*r)YݭYeZ !6/Y Bc)6>Bs^YU}v/_j2RFߔ?(9S䜌;FϠ6kb*N#B[*9=zJ-VYW%'$ M{rjT-PJT͐n)%qAolIoy0n|I:T =N88I!M䮃0\xH#z\#?>vVZs]Ww21ăX;R]`d?of9P 蘟~iR M:WV-8 ؇?DV參 iӠT.OtN X*@Ȏ}ʂ͂ oŋbɠTlI>}fiȃq $Tzx%2#sesCx?wj(m5D@"tcBwjH1']4=;;Mu)$4H}jbbX-0$}CTY57r < yxL $ב#̬:2&Ξۢ̊MCU$Fvx䎔ęlB=D (<~`n%6-u|X⑝;VM6Uh;yd<+ CDҪ nP}ELl,eW7W@l/PݰZ Z 'ԴHQ_=K~Zov=jq I˸ˑ!hcNv FDQ/7h8PC~)hSrqʵ>Z+TŊh5h-!ENzAXk-\;1w9mHjǝ_hߥكYu:mڐNsJgH>Lזm?4Ʈ[ åkJ(=!Kd'CdT 'c!&9eF5nat'ThH{**7d!t4\.251ZmUKs"Q{Mugw4<A.PJ +npA&r ="ei~vKZ>MigZO5Hp4R{h3&o]%%4 h ;J8TnO<[^q|pa;%bYѽO%A8,@Zv_6פ&_۞7.)xޗ{:Q4g_ۆ00nw{e P .H'Ae8kwL*C!TEQ)(O+tnŏulK6VV_ BtH1BնCk˳d+@6EY*=jm~:/3_4f,Ӎoq[ cd%P{_$S{3J~k7-JAr, ʂU4yn\6]^ڽU_rT;$q_ -֢%o( 7*Jghr^ \Ljmg}w%[(MqUZ q0Ve3<._56\FZNy+A/1|Żj5QLu~S6PHsPIk/dhsw O *J(Og7Y-(1^2ǧ΅p$.N&W@ZjRK/4>^CL)[m..p%|\SyDZɋJaեdcGmb$6J8opW['.1MlKlj%#e:k#^f:lREڠ F_UDĩ=$iJ^'g]3ZHm>ь :\'ah( J :ݧ}7AZ+U7@ԀyIg [{Q7G:\=n9mC1U*8Rm|=O ř^ >cXS^ @V47z={% #mn5$!R|~͵Hbx?+Ui[ifB)ASĐ]JC͆p|_vC񆮿-xoȳrOQ"`ܞfʏ>`ʤǎLX_|۰Ї8od%/RIbC<գ+N|[sK#y-Ql +l7)Gw@vh`0LL I)nD"agiy#٫ar» )#v=}0YvpS' {nTnCpLp*wGXM󿝇x"u("/I:㻽 w eOBVPFVk6H*VW*|.=: *5 Z*toZV-tM\{*q_X^XLV7Fx3\(t rvQ %gVɈY Xw }N%cQh!oXI#ԧFX^w+IVا'GCJ>XyS7w_R!|dˠ|g>%:-v}4⤭Y%nȞ'?<#NBD OsyCIýdC ΂ª_1pE9ҩP36A-Hz&7JMNk_rԒj)2VǵjpgV%[[v:*T^  . kLQ,t|嵟N?'n!ގ?饑A8;PshE}nd8C1ao' >VπZJ1UC^A;◎,1 Hz[Eظm[|PD^t-I2n%1CY$==^YAWlT+"9nxAV* I7b:@cW #py}Lb1aTNԾewkd>+^e֐Fдm&Nk{"Ѵ cg򯞵FuOWt[@Th ሧ Y矃E !g`okes(b:đbiA1&.vKo)&/H^llNcAm]%ټ A癕W 0Ut60 jgq+_mVkӵT)A>q3׍vGxd;+$Bn LL2 {peo߯rkl)~W8&j>Lƶp.${VVH.(򪚄-tQ|پow%!P0X>7yG i%\bwtH>% 26Z'/"5 al?TsQVAΆej Q D¤@̋ez#sőF12S|-JR.4pec _v&3*) 3߷_Ku}SzQArCObAw^AC7 w2ҕM{ Yw7 Y{TIJ jkPJixrL4 MT )wbrh!7K҈ϑlR7Lc>DQÅ*#xppg@z7:"#}`i۶fk3"~?SGk_#RXTo'LN3z-b[ItOw$]FL ;Vj^ CL0nEQa"6"<,6ɂ{0h$T@DTkX (2|=w&;/X('8`-'zk'3 $T"̗/BYuQ!xչ-ۏK\=p!kh(_"Wԩ߶R$d&lOִ1rcM_o%cA 4ڱykYc,є5 cW᜶iz: o&D6Sdž fN~klx۱/B _ʰ8xbrdiljlXGtDF 955Yy=ġ g3T^=%~w3*HPZGK*g$Q1!Dv`(g1$o|h 2]U!\7v&ʷr|DgD I;SAaQmM p~uyeHiQ#>A@4^g;.(5TO/(4֘XXJ<5~F/0J5d[%ғ֞ Hm`Lh?BL8< ?PWX3RB9\Ks8ȳr +8(k43} ݀$ɸ#~QQ`p87uba:r$p8}͕tXl9xaS>!N>x쥽,FIiޅC[¹'߇oe~&b_H5[P↢$͙PQ<)m Ib }`B2<.DeC%ƥYKC %U%ɥ,Y4P1eoAsj/(wB݊iN$%(}'`=6oN }Yv4~ ppz0&v#=9.8'I7D#sK'L$od#(s ؊-Xb8\_E2k>yM׷QYN>tKBfjdx-=)ՔRw {^DS|OX 8^KaJF9Ss!Fz"OD H5!#, u3liu=..yg"jp(@`Mp,^z=qP gD8k|}lS uC"nR("Z%}U!\4B=!QHIŻ3ËH=_`a긌t<+50U'Flq~˲_S(2Ϯ77ps.&Lha*ڥ8 1\h|I'mIʽF`@m?D%=|hIbͽ ϘmnI]ˠi5|w(:Trtek:s5徹Q5Ze,[)Lߟ-20R'[~0xi)XXgUg}|&cCnX.FA\u"RJ9:lCXՂa=ZOQ=!O|{ A` Ùak }]=`I?UWGUf3*io;Y+UV)Pe~J`GbIݦj [D [|)B|ycWsnLGo*]|90+fsVl½~IT[cUHшlȷ]V^Yev5#i P E5AElR'ЧzAK@vyZȑE Y8̦Q>fNgcLqiݴ y;aSo~VX["$ t>HoKE_+6hMDLS?b'׋舢vрuufD2u)=v2돔D0}[R&͟/l_'SmY'^ J#G0 8mu:V+x P8 V[Qôu.1VlNn,{\7 /{˃VOm svialmt/~(<*3C`Yuv|;%roH,(RRxi֑ncAm6?t2 Eն@5w_#л^CK%;+NN- 6͛ [eڥlx@Xnu@= B$ZOfR\DvJ >84#Yɺt_u8 a}J)S4[gɃAe1UsZ}I}& NX{2ye>UFĵxɞz2׈>aSt$ )pY$dl٬@bWJMo~WFR <ÑKYH̷> kFW=x* UbP\61~ =R8k +[U j=VUAuyd} !u2鵦&~"swsC$*xN]cU} Hq^rN'q1DkA]h;k Z0bG,T1$hdp~,P[l#0~r+7aVӛ\c~I{tGk1C-=HW:t8"GMxIdp,h- &(BC#hm4-Mu7EnW&헖09tja9+3uNKZ.HȢ,r'yß?#~gܰ?}8'A*f,YZ_0œ'Eٟ JG ’h3t>zE並ri Ё5,u. QCT .H")'NTTJUE6ܳ|cpkyTf#93 B竣DV yX %Yt^Shg:N4_w767%ԕTYS jw>8m$ijLA ,WU$uo>N8f*`]y-jq^<]NGO&բSvH`͖jX뒷1-#Q ܒGIi29 dKU+LᰟP8t}N-.9Da=TTD}ˆmu_x߼ ^"ώc9-".beHI;  ᨨ@,ri5D 氪iͷ4'ۊ|~%{6,]x<+I.}J 9=O\B{Q&cy`bLzQ}3Sk9ICt.$cF TCq'_杊3Xt[: MCujx;lXX_h+?-ҳb n1(ú]mHŕcD5L Bw7^GSnYqJƥ DStlK9"S*Ͽ&ۣA!&%g՜B,$ܔ y8CDh*4a^$l'{`:6v<$7AjVA1TWH8k*aMG= A[U8('PgUt0R8y K i߫$#jGW*Zg}um!q:UUYL-$d!Yy*Q`ykdY褄#dabhYVx;u 4e-߸TE9F#sk'KjR8 i絻PhL\r3~hΐq稘c_v0'FG-X?; ~*߳Y ?g^3>Am#}y%DHeW҈ߡBW_ϜW9hz"LaG!6 zVcNxlsAwWYP(rB(j<͒6fN2pi7LNM(N\}g5ҷ!\_(]7 )!eaD-rj80{*GF/B$t~aԺ,=Yt9x"Vx¨`3fmU'#Z:S|"if~W'.]3ƥ)mk@gH 8| `lFǰkGo $ X~Ϣpk]JdJ[5k~%ȺtbسUNAմ^>)~" Z;D˫e_. +[:MuT.`mXOkG9$bVN`m-NMyK%{NXZћZ[񞞗1׼ ]9N XR6v(ʁ4]m?GVϴJF3ꤘCa SKx{{ w$Z#5'?JSīla[]@PZbHPij ?苤L*D ysP y(@ m ViFYm,{7-j[Tybl G?\]Kj70JNFiILu-dHATsttUXЎBH$|٤|q=cTcH !#>$Wty\KO.hom R߹d_ ~O)J#e4C&N,).SbU[+(0?/]sïn\|%"9  `YDqBJ3>A+ꅇ?|I=z) Oѱnƽ4@ ܇DiVٺEd+i~LZ:9kh/f3X(y059[pm`(`2]eY`|TleK+ ͗}8fnėIfAtpASc0P&yĔ$y7(jj! yTnV2^˼.#۔n[̪ͬ?f杶?M_k6;΢vo0TSEI)r N`-9̽WaSSRmQ.Ӏ"TX'f=B 3B@Nַwc<񰣥ҿB7ϵxLH~=9GvY]?PW/>B: HP3b%#32]s5+@KÓ~Bb  Quj3=ۄnnTG?aW,5 Wenmq+oj x](b/UV*9ĀX65&ш x‡g]sJFWLEc6ʙ¹F:Ww,"]J7e )$3o0š @G+KpVfa&A̼;4FN[SIWsLY9zZ̫^BM^^L1Z3 . 2icBm 3bzCUZp;1#/=:x);cS`m+y;d"Yr#IU׃. W \)]A;8H8"9JWeO9Jի oĘOaa*1U~DlrAK{F!dHEl@-K΃z z?pt 7 `Qtcٷ}m'R J -γYl_C zzy7p_nq{zPԡn۸Fgy^to@rJ-nr[ x2|k:N]k?n(O1qes{y) s@R2 kgU-IQNf%aԢ*Ga/xݳ3'뒬(Kd:RwvȑH qO<eD{6f?2g!Aм+`i?b83*0K>.kX|=]yK6s;@-B_4KrjF#',ߟX՜$^Ϫt]y%|dUHIh=БYY(+ݨce<2ir? a}u9W6 P9=h0Yd'R+=̶F~A3zFcB+!*^uc8zy9-8x  f'|:ps)6`4;'WfzUGwZ Yݎf ']16=C!JnWgD)fA}B( V~{u,KMle.^5t78P:uW1l!C*HCLwuPZCuX2.3EHa9Jѽ.KM>$z O^xd4d)pgE=|-ȲhKg5\n 8ԇHWM1 pLT(e* X mRɧE@:nh/aj~渥b32emh/Ts΄JFӑ4sS3Ki5y 䠳H~)Aώ6J){ϋ׾CayQ@ e; w^2t֨5QOb/ `5U̎">چ8R0srsB=RڴdjVU7SqB_fg}?Hr0=3G3O KtI |9yƃic&P \Ȟ*ij^~Z¼)Tv޹c=3hqw.j3mByU} ~+%ubQ*KyЅN[ [BVZZܽx?m؞K5G1ߍv\3n$0̰PƕGBM<JaeU.@R.D λ4鴒Y}9*0z}nt-o$qy+}[~dK,#`t1&T$NnDLa[' &}h@4#Q=1q 8*VogC'lN@Z$ j\ /XOLJ~ddUW ?1_E3@θ>zKnJgXzJ^@zr@tJ* bO_s40K sG_r]5C]H  BȮD$H;}{; ?O~54.U1}b%[}='X)m3jKTގPf4nF=H3%]50:me&@+s\P|ݬrPn ϊu↓/3P/5aL>'0o$y6~~Pa[9ņ1WyLȗ~fZ\FOxLyT'2NuwE t렙MR!A%MG֔k_5nڪӘ.@X}fX~:Ӷ;0&~OBD̉˭0I`V)K7)} @Au?MϓiB^kR|N%ҌE>);JObsO(*O,prܥJqI^Se\4֯PqX[)~U R*N΁M픳`}Nq|.O~\Zbŵ{jv61u`Du1Z` ,g6U7I{'KU ;؆8־ö<^k4 !EjW] "[Y峀t 7ިɀ% KIi[Py{ȷ d$e/3] \ފ+~i!_ ޟ Y IDIƛA[0żu~%SЃo H' G@;OW' <32u+és)_؉|zґ1 3: ]U2sӿ|Xd1>;raҺp#K:, )>[$Ey%\ˈT>o\x 6;FTehً̘8"Lp4 ;&ܛiͶR )hZ_N9D76N8-:q, +z"=6j X"c Ewfd-Sˆd^@06-В)2,#;(N`-5~x<5]g +rfC~/ P]i۵FlB,qKa!MswxyŅ8ܮK :vy?.Jjo/0Q`T PaKJ]z’Hnnkl]ljolHFeKì1 V2nAcn8S:qcةDԠ=hĆ 2E4w'<%n;1-k`,Ag1%mxtzz! z7-~S-USe%7QuG~h6L.}hb2GlE}[n&v/L̯;0i psC}! ǚ.VpCh+e\'~+'Mumjfe$OJ}t>:i@,5V E| i΅Kj\JM bxr*?*.0PwM{3tȑD]ʔ`Hv噴VVP8q~0h> %[dx5.,| ?su:_N=z^gZ:t@[ *AW  <]]3(N ;bE҃JM.(h4 F҇ℓ-gcK&NBJFLVm*ʹzRo0䩨Vt8tP/?[Ƨ+Qv/@OJ, { bZ?XNo&)UEcZ;r/_073e!4_7Kg/J"^r)&~N ȑ)w64n 9o mx]sޜ!?"8l]2RXѤ:f+P/ﱍ'oh]/5@V$xֳ&bXϞ- 5g:t7e@BLviɹmP^% 8{uh0{@:CQmLh=ca5;wn`oibx{o ߑY a Nv>ǐ#^=&jtb\ ޴)si[>@OFr)S{K"zW2խъgrp0唶qma۠$-DO<kc2][HKQ#V*Dƥ0tFĬ[;A@٪> stream xڴeT\ͺ58!Kpww ww'nv}N>;GgzjɈil "6֎4 )i+}kz=Lhfc-9d Azz82(hr @G}%7[ R gHcrM̬@)6nf&k0;[ oha`aз6HJdl\@F35hoi 1(ʊ QYe9OŠN6EPQIY /$ PD~UZPd@}@ӥ~p;n_ARmi4ut夣sqq5qrp7Z$)_~ @h$b/HJPob !״W86JIͬֆ@G}G'?6/Ј_A'{=e6K]2-K/}1}k'eX;98:"`lf YcVT 5 HkZGWӳ8!6v-H'G{7;6.o퍜l锭윀B2jhJ? `o23><G{'ߎDp l#3CGШ ?ŭm2 tNl-F@c8:GHPsh߁Vfn_!l)el-g b 43s44;ږLʿ%hvAߏ/ 3@ciha tp0+ @'-$"+?qֆ6Ff&FV=hYX 63,:ZkGP `lc{CYYtMB:? @' =NbЉA:? @'1$ ?]u@eA P??OS@U@58@55 ?߈hDwdo7Z[d54 4bxZhl'7tp' BL JhWfq2 $ lѳ@Sj :AClnblAlA%@ c@Ghof % %҉l?\#_\tR(9 ]lJp t pkAٮAPy H+?@܁jߗ? 'm,fF7B\5AWٟ[lWf&z #10_65׋?Q ]ps6\I߿x MBqОcIľ[Lh"5Hqj{.T# İ|]kN1CRUO^- t(^<BP9h|d{pHUڲR0Јno꺀ێ0ͿH5sDNpʝ4{4a%ChPvx|0RRQEKj47Ȑq$|'\ À# Lמ|JI'I)V i_MZy]]Q br%jGӨo7^j4G^``ӎ;i!F򾾜I s&" nљ@~&0爁`,?9,ƦJ Ϙ L^iX^xchٺ _m6c͊#< Vѐrk vFvQcP:h[\1 T4Ñ[!NQ RD\1zlJ' jH*Ä1.֋jE6}Q{D, ^<w$ 5. |o$KMƤ:ˎ|gC}?o鵂+JS<9/qVNUG _jy:SzxDRE۲?IxgněS.5WZN>"kbyוKq36NQa9dy,C #Gt E#:GkL]Q8w/ ^PxwQcքQ:x<=`Ry47vP:z4$S_9>\|ܕrYȃeM!Otd!g[ɇ||䣯FiyLoNXFBhݧ0bL4j4o<;'[sgw`PR:ҷ:ʥL]W,Axm)!/ V~Vs*As14 'I^O:?Oke1mȃ7 X*})7'ҍOv}?|2oafSր p4O*| gjCԹp#_ևJH-%m-H4!.O R0;1MC" w,1|k 2׿+0*~%+-y2zo "4LgiZ0<{@ *-'{F *;#+ldoEOAUYGԞ~vq_aVG6u6ZPBUt ذ8ck7(4[|F}L ݯ[6a0i,e,Q:V=SY޻3qa!ij==gI-Ƒڝ]ↈ(,4+Ƶfp3y'Elm#d~(y= ";C~v@l'‹kD \{1aq(yρ ZEsk5yEA5}$Z_gV#ᆟ}My> [ӗW3-TȚJ7񑴇is@\xHr/YO 5|7ӟeǥ^Ǖ܄wfMsw3V24xun_AGUܠyَi_KԡD-|*VtLX%Қf!Bmbn,chƒhb"=K4ŋ{˫U/$RX&W&z0 B | 7rhLU:[Ӳ2`ydLy@ B1nmWdeRsb/(c"(Psv2mK5fOʟIʼnVrrQuYTɸrH\Mdkjы$Su7Ddj^lGm/5MMΤ5>̼Fv1s@<";hf*)Ts'iq)Ŋ $]Kō@2xuM-|s )f̌ǩTaTtNcyO,WIM|Ro~ѷ` ';iҗc~ًU7؀ ȨVG6)'~Y]g_5=~sN ޴p6ŧy6+G|hytxj&Ad,ʥ鲺KD[-_e}IK3&ULDks~69Aj=ahBlYW+3UK9oa b.ٱΜ M#=Y I.;)lr4{Mx7Z'U_hZX9 ZZQDBjðOx|wѾ ̬R0/Iem%Lm "sv^eibz(MLsJ9;>fHdQN+|FrwKȤᗺeպ,+{m\  CƨbքXResStɌ.&o# >b՟B8nD`i/EA^#Ț"6#9-}7Px4|b4!_u]dM\zl8!Q~[z`^D;s8f,!!f6`dh9Vأ ѓtӘ ~r>*xF[.YON'9%Wv{1/霳zCETruY-y~IVD|z:ۃ(%3 ;Xpw/_`1idGEu`tzDHo}9 fvәr)\B:nW3 !:R}ȼK ?թkB#FL#Y:TBMF`y]9X᜴vtL.#bv^g=E[kˍ86S鯄n~6-HAYȾZ=1C]ֻ|I9" }0*:ϐx?TSxѸ!r휀F |3Գ" E+F#]DVg='wpz69Y_ R@I)j]JLx;u?tba=FNj '@PxIE_m+?LRW;wnXb+Ba` nv*`BL@%,ib]'/.SRF]+n݄Uۧ-|Da9N8PW6μ7*|/L.[XE[H@3)Z|:R:Z>}I?Oip^ôIl׮y|DTtk7]2^ a:oloxn;gP7|xʸD"ښЀߴNŃ]BpD/7rtGl^jʻCLEϕ}ZD>A];Cq<}cxk:6'uk`Q+2gkUjt|#cGBLYLRh~ZVd3i~/+s;~ߗ$o.BevIHiF"q"stA~ 0zVg_v0,U%\SBF̯&xAV/txóPUZ;Is^'+N`5ZG v 5P2*w|MMC2d ~]@1d]oye3(gau_l*lDYBz7&P˱foNM8!w4O k!4O9JXJAP*YCn:lnꗺ: 8y|ώxQ*g q*IԎp3%ԒMW9Lis,گVYpXVz#>7DEiDJx,W=6klMMM);4< Y e4zֹz Ib珝Q+iЛwZvw_qF붷?+*u^xCeGʬFD=:k7YƇ@R#<`Ĺ~ACb9ڍIݺN9ǵe1X`d}c :}/yhH34S$AǪ=Cx/[X"ABjO~β%#$44 \/i⽯s@:lqU\uWViZօ>SB<#FDmTTۀh6u&~(ס=wH2OôBE9[ FӦz 'U *V4>y!-.Rq> =gY*zSzPb(b.fsdMFԼ$ N(bѵ.aV'-BDYG03.Wl߰sZyC3A H'BGfQD.<}p_‡(K=p.t]i!fSŭ9I$唫QkPxNxblzT4Zg|ؑV'541x8Yd4zoz?ܥ/1LGT(!4(d 0K-)BWGOX*΁q}Mį[pˤ>|)/ʸ1d0&W3wmwv3 $+mG=G=0Cp)L a)c G&e.dw8b F.A{2l($]1@i ,amuEۤ0Z-jQVn 橙Ie7/a%L@9\AEP6 *!3)i9y(@4t[q&Gs˧v٥S ٝK/βcO1 u 3F#X[/|i#X fEuI<^ 9vmY1nT#ɀA|`OIbEѦ򋓁 gp-D#(>o1+vé3?x7y+?.ZOϟt:ǹ/!u{_*|s.:r/1QNIlh |yν[1B2737].%pg O:-`? y;bµIMbU~D <9ɚRdt\(:N"ώ'åR&6eֵ*9YJo} 9#U~9q1˿JLG[MWk1/]nRc#T8Dd@”=~Nv=hjowNr򑧒dA)-U\Mz/Tv'K&A&\yWِFCwakp{5"YՃ`?*.g>bBCjG^(9lb"(Q֠οMSO?#bhޙN,_I<)>bNJsNk43EnGܛ+?SC2P_ LztmS؆8XGG*Cb*@>l [f}iA}eHU401yfqrȴR4%5޴鯉[J?]5y>bt' V%7S~)9hh/54U<JnF:v`|LlRcL@eηt#To͜1/ԝ_t>)6hM)mWQ+0nZuԍ#!qҧmx[*PbCRf7I^Zg͋#vchJ> MP(`'#2ýPU& U_d%EĴ9ůnЪb7lmpTަ( vw>}Bhޘ4QN?]] e;#Mhn]ܮ5%idbEO/LL&ϕyfVŰ1I-?j.IUgP^;)"VL,*\bZXĕגPce {ZO&ntj$"c}?ISu{ e._.O@kK 1*4RRcg rv~)ھLRa͂<5ƇÞ, śŮ7 Ŏ[e+y*~$ؽVQ)&SH+//wM3W|oB\k͎)%H/iURF@;IL"X<Ǯ31TKNğ;?JqU^m:b;s?Q^4uZuu;KKs'+sJu{zQ7B!(珞og3ZE5f0+rxn)ABv7d7 i'r  f$'_7V}VyϩkY%%6e!GQQH) Dj- z+$ٛtlH\WK7`Qb|zY] @v PY~h8|݆Bk=0d9 9_NH\z: HhW-ݕ=x9#+G4hG |i $o^NU*OrncE?v-n*4.q}Gֿ >~H+lX@B ikCi`ZFǨ3co>D- Oo+Լw3_ȌKB`iA ,V: 粔{ߙ&GͪG2ăj-~X$ٯC?a3 #^c!n4Q$`6!7?ru.XrOgdbeWl,Lgt}؜K=J nQ$ٔ" ݬ* hȱܲy) &=~HD-'dXP O(!?GQëU=]^k laJ^`s˷5m]LFSU/NB]y)AwcOOt7 ^.l%9 ҄:05B(c7Ĭ i%XЅkZm.H+.tZ@~[1;&ث 3("ƈլ%y<&zT.il{JZk$WR dͷGèOhR[R9Cn7j) s;i*K,BDDz(yнy6 ]fZw.^TV+.ˮ7N‹Y)]ue%aSZ&%/R38M%wcrCUE@:y\ơv }Xmxm C A.Н[~Mֿ_VjA4@:zTHKD+)>j>1=.DH[~W2w Q=r{9qT 8':D*C>e6_2rAeWWFc>g A ;в|z8 [*҇B,SGFo>݅rH8=n ^fhG+ l/f1uN<l次7lbJ{-ХsoRoe-:{2>3ۡZ٨Ov1SW/1s+IDB{z2Ijv7Fޫi>x)N<##x|KlF4:Cľ86ejG2!|Qd 8tf2ٿk xV ghRO]*nLk _DPXR|]p|'GΦor5Au WT*W@AV켡p֣U\!Ӵ(@}e{[uE[/kJp6dN3)Ƞ`edDOuyX:T%ڗ$uonxO}$G]},qܾ%NjTAŨ{8/"E7O$Iϴnk ASSfs(s(;Ð$,uQ̕"27E5RHs{M) H-Pp[{W\0Bv-@s YQTf[V=J:p%rxp̶Djf2U+*ȭ* `$asKMU/ֿH(>=:( }f ,.\x6F_WH"u 9?BB0,ݓuNYgڮ֦8)/7q'(,3=3]E%`-DJPɛ Bzg9H/b@qO+95;mr8}1`""hTO:Zx?f6NřY*b!'*3ajshT2"},DyU-*_B(oU8Mfx+#rh ͸/en kS6 Ӑ77I-W_>K*"_}I HQ]enŽٚAF $g:)&4XJ[m^O=V_}hik B; 6a]9hHAǛpmUAK_d=ǠB&$nY Csq汎GeJV[JHʋ ЮjeDUwΧn}=ldxK33O&jF.+ `nݺlH ,)x}N2@n[L9uo޿Lx1=x|!)EgIcJٞO\xxh,p;ޞl^$ x%KV qa`H4ICmwk"e//`1֎wie“%VFY2MB4Zt2T Vv[8< We1ؽt~-\)&<d Ams?8.4ۇS\ɵDB`OnOVv_fМK'O??5{뫹W+"BUtR2#UA#pYix]tKWC^W꠰DpN|c{%Zށڥ7Q'ndzj@VO65JP4-cɗ=9aLNކ|W^*:+p <-axD+w9,san5!Q+\͎;~)dϛ$ `ĺy!) 9 Yt©4Nǔr~9@CnZcgI7\& j{hݻ] Vɰ-2WQz3ݮLv9+cuT,|yہSJG'8#Y !|p#^C#"dFռ %(2BwYrj cUC'z" IGRA"zV[p"|bݠ]jO%HŽ7QyMMp HY#ҫW!&$~8[2aF0W˝cZq-vT=sA/`cɿFF^tt,UBD &%6Bbhik4}8!QGuoU PL1w (ˮ/Cw_b5sAXnīI F:}geWD4<ρ)ЪjW=r`R8{{cKXRW2< ʎCčp?4dL-G-c𝛲t>.@< %wipw +XNj3<& Q5(ʈ&Aߢ=1vOFs}Wo99}"n{wZ̯=Veb"5pZ#7N k H`|n1@ "|~[^6͉=jx k^Ij:㱝k˧0aUeFʃP]Դ%9 >ː5Y>-~\fqX5(>EArш%LW;S.0^Gmd;^2uKJWUJ2vXȃ#:p1jy5yİ̅8=Ư{Vb~ߍK-9EA5o&u7C�&՗%پ`]uϞBXS\O2{8SH q" >?6`sK3lz,23H^j4C׉ .(uuYq3uɘhZԧm?Y+U PC~>;\|jubv"܏)f8Y% ũo 9nE"=J%֠E0B$8;}Ën.OD`$V'{ŷ7݊8_?0OZp[1B,0>}% {:^:v{ z Zcݷ3\ڤ||έc~ 'sѺ 5&;'4fO[#q162Cyb5QG/iY"OTF Y,&+x0''VnLcyO=*<}U fQMPm  UX\)&ntMM5E|܋DcDx)yzN!)}GQHQ&ޒJ%R:"{_̈/Pрu@Xa,sz玜~|_r` 5)2`sM. p'#97\?K.ijOa<`_=AD(FxOK0cTuyͻ#,?APEǻ%8̆*FkX tqM/V\$Z,FVV.Guxif o%zJTjr\xOH~59:40mEccg+)pD0KAa>vb6>evQ5@7y`%KN #w[w{?P}ΏÏV`;tP,RnLt.+;ks&&}.A>]utYl̼XRV5צ+N HO(z_eW2&Sf26ׂ5>paG9Af<\`-0B/0]r['y\?qGL# D7l=${v"^"0} >U鼎 |T^v*ʄOMB剀G<֨}!:aWta@in-ӊ$r;dLRA9,f0:m۶mvmOm۶m}kSow.!$ZvW0\h? n_߭ W'ݛ7&x8ikG(O5%Ŝ\MUqN7yg`Gp@M1nP#HDwEEAjPZz['sJvH0:Z5F6[ ǍCDȳQ %HD@jqk L0 B8:N?Muefb}ۙ='"〶&ĥCP;BG޳||}kUΕ`p5~O1x;&D4wyA~jbm.op;SB@8|]D٪&]`BVWsZ񹛔Reα"Pdrtu >vzG\c$omv߉avz²њmF7<.{~FXVr-Ibjyj`="w@ܱH]a123ElJ\(U&6]kKR|#NwaqeG_2ٟ܃.~܌c*WcK? &<V8C}i siV2(u{}G{ +r05 h;|Lel7]?+(h_IYnBˊ_2r#'JA֚»/\ m?OPTC[~E(Ľa -B&ko`\a^r-sDTA[WLqJ+3P(o%}^;ܒS)[!o"$U2MlaEy/(Tl { .j=y]2(7[.}`XMÆA) 檢"Y~-EuA"eaŘƶcd/ yqw̜Rm_hՇ죤U?|Abe*﹗}cmKDڵWqh熏;-T0(TtX:'kWifL1 Yw!TE f:Ͼ5 {/$t !pi4IU9u# a0LvBЯrC7d:g{Hڀ|;"v{/]?L[kiTsܵS~N@<? kנT}Dv q䁹 n(0GOĮ:| "fϺX!urayOW}<9 \pas&MƊ?(c`? -/GV8lF2܊CBV Iqp\DjuJQ>Ri{C? ޼٧Ş Ѻqi2mO )s(X1o@+=YHނsuա2]G֮<ƪU75=8\Fl8Xii}o,pyI;Uq7ZR0M~;AA•~r3S-+%ϰwPA G*!d_E7E7 px]8C>| BCtP}vfT~F(JULjֻWMSѰ w>b%M,U ?9:U9VL'883Ehϩt(+C%u6aO;>kAp6LC ^KWGʫr[P.XR iG$Om¥8)ܕeJ򹸕y-r8$rkBl(ϕO^FaFrI5lI_qEс<߸O 5|fAgAGcE#M 6ַTGA|x%vѦyykVA?t1ޑV'@>a{"$!/(4Ӑ˥΂)6buw%G@~6u=͙*RF= 8E%ЙKJeS3LQ+%kvd>5Lf>`ퟚ}p햄hy )+v8 )lN[`Nq#!y3YC Q4d^VֻG:ظ9 +]ޔ3vמKpRMdg&.gEɌ9j|K cB^~lP0x{s|pZ8a NOb)NM׊zR+*g HZb2=z<9)"K4׸);*hЬE (Gy3Yz3 33#+nP(-mV^LZ8ҾV6z$dώ9b[tBKHTͥB֞"'H`yK.Y#gG#d;&;JeC}{#<h.uT !_]dt%}>kXrƄD @<%l / $=sm51*D`''ԕ _yYJEUdZ$c)X,)7h+aK|!"Fz&+md(ZDp M:.jz*=;+iwoӒCdP?\9uxgߑz>R/Qiá %C-FJ .k"*P=/rF`'c("] !+j_gl{G84JܕUJRde)S-p7тz36Gp,K=?`>j~] &'I6n@slPQK\Ô#o“?Fiґw<drjAZfW>23Weu6yKiJq`2ʩQdgIr=9xػY>622;q)pfgL|Gȍ<_=]]>f?Ynrn$OsS촑K,qfm ".|͕$Nt>_],^F4{ajwI]b0͜d;)fn tI 57}5K$d\9Yy+ݣ-| ے@:\;Ts6w: ̢ͽ’(xEYDO *ZLwvs. funšÀJ51VCNǔ>fU#(CML>рÊڇ̅~L9s+؁1UőtI'@~UV+*|5>[oZX) lUS-[kC#_Fs8=.>^-F|*.9Ƴ˧yiE!QY ɳv 3(ƠUA\wt,$%?B g`n58q ;a@,Ν#]Š{O=6L*0MJWDz] T^xQ6fGr8n-ޛb䡞ijў碓`@ p|wt rTυ;'"j cxLhuo [|ۖV\oUfv8` 9T~1 J B ʋ&?"}#DqW)TԠ!~ox⿐p$;hboM3kG_NRGۙx&VZNMc|?gVєjT@@BhUI"g{jiJef;nktWΦ[g6qJ>H1*](Qz|P!idH\|dl,}fs)JvtH+aeڕ# ġ>\eї }T [W9S8jI\K~>>]WiCIN 7C1K?"{rCJS-Q։[<^AqIU>%{+xȥ@.!bvc%xO&,~W/'0׋]].V͟=mACn~$^6`rm!l,jEx! $ E! ?CYMZp|j!lKb<,J7\&XfBޭ )nSLPkݫ}ߊv~q< iDW[SjUSۭ0R*On)J Wș|̀>#yxﵜۄn>Xm!^pc)'m$ }X s˵~,w1ÍZ^g 4+7ewֿׅ"tЩ !^.8wRGۉϑC2 33r>1K 45kc== W;'K _t싢xԥx9=a?Tl&/'LU~YkC6+~{3i'~%| Ad+2>OB賡\g|ї1,!nD)Q\~T}k6!H) J*T#^\ŶxA#ǑIogby-(IZԮpPNh)dR]#psI;e)(.=iA-wz.:ghoT0e"]οKxPH@[Zf;wп?<10/d,DKH쓼7h(daj$)xtYgFT^ݳ^^ ~wJױ|GqEHYzDމ5U߱{ح>n6!3/!sKRx\@`a=m8_6Y~0 Oɀ_N˜v~Ȍ)@)9WWs?D="MK*`n&H}rQ$4 MB@O>nxIM;]wѱs1څւړ71zÑ%y<G ѨZoȼ 짅1NNLXm3+~bS`X;YG ,bQOx?WhV di/ AθhmdaT1DWox%&Q[F-bOYe@ZEyL.MYpƳ~Ղp?ؓf=ߞ % ljPh>VlB EQS$&{JZBNh B/DmrʞTVz pH!%I40Yѩj}Ws}^׈w.$TF,ȕ7{ q*QXѮŃ{M?%==M, oneM ^4&M'>ؙwݺXm.gzFHڇ]y΂70G5╳͖ m5IkF 3ptue6I`͉Ǽ7׻Az;'2I;}#zуpB ..ǹVFXm |bS˴טDRvlUKEAR,hYޞ?{5 nvl>r.Y4wFhcZ',$Q Ie}ZPrsAcV0g WS?{D=n0EtLJ"Φj%)|@`\T~p0ijV`zp`aj=!pGB<;Cr\?\]P.|E>خ"!Fk0?5lۍi4qQov 6 ?j6*ӄHlblo"a Bc ɺ*a$gE<n/ogn0y-01eb}5 hq')ŠMJLIГX)*7Iz26sg5INm:-&^&gپ[6FN\/={ECk&=)GeLǼR>D_N.2e_ṾO<#Nlbubd\w-ؑr{[Y%69?!o1"/Vo,ᒧer Mw]1q1cIF?s$DAu˚-ʯ?:I@h&gw S墮x /SR|3ďuaA[ @g+)V}aRA'Zގ`iɣ5-ԐƦmjF-E;=tb)$b Mq^ߖT|)*5 DwK"ϓ8O ,ckYp,]7BkfNf;,TJO* G|&ߴg3B6j-U[VaL0{׺~^gÑO&]$_]}9[y N)pyxylcYV㬾FՅ`@!L=+- / 5)?cI7Wv-V18, xjn jsz gl: -hC2Cs"c!U/4M<ׄ#Z’u.`M|0t=ڡkL1yB)Y ?',̈a z#sJY1KmgDΟ~995n!@س,gyLu);IFq+jmj!y6瀜_:@ b d?1,w`<2#-R\wZ3$rmU//2t{j1D*v| 'kŎYU])E8ཬ\_}$ԎuMK S"VBA_hUnERs:vy_p5׺g3 g!#ӔEg\"Z<)vDExڵq`dfX2< he02F/wKpLu(}p%=: <[ujVyWb=7PЮѥ*Yޅ_X6уwa{s ]fǿG~vU^iFn,ͣz5AQ ]=BL{LyJ{S϶В-i8 QRXiv ˺ Tnq v?ſ_p0C;#P$Qg99%5mcWD,cXpg&l!;WT{rJ» "#3mLq@^ cWfi:: oNVqw[6y:!#ZDdak7Fe;"$2J0 Dk!h%w{O1v%rnX6lDl6/*_֣Sgo#UY[̒e'rG LD'=q# R\p0WZ$"-baIzUpڔA'С:Rb(_KԪD ;UXjօ0{v D`g!;<nte٥郛;&$O/O!h-GvZT (.}V|R L=V{iѷ|DHQpm;V^.5bVp!'ZX6w2k KNF/u}c[b5~ |rPxˆ,xbͷ[ o!w'2`6^,C{Pƣ 2f_BAڿ~=XǮWZpJ@bZzMLf7,hry? ɰ۵Ň2Q Ov  Pr]5!)]c|EͬLߌ'w-A+>a:hTܨGc>2~yueq<[ 3q|a1$ݴkK-[W!kݞXz .m6j cDy3릖#=:2>{d=,ӷFs>`40ij!'W}s3ݯWh 'x b̫$sy HV}fw* ^<g.MW'N*ǖ=d=AxWJNdɉY[~{YP񾌓j>Ѕ^jw_W]gLT| Hɏ`ܵ-ьg XJk.a>yFj4Js32Fqx$%%5wN=-D7 7 p e콊ڀU=7'. <Kqg&yMA˳NZAv[o&hygr4VfdAcQO jI>k"3}[)]ѓyf!pJ@pL(cagjd:RLXfjed (Eeϗj5[D:"--:0\r'ӧ,-ǷIǛW[ Kf@ SI:, ;W|-fW*X$)f;f9[ӝF>,KsI da),_\'b.ˡ:+j-Xlh'P)iSH;RlUq VxAgC=="]/eؓ-5Sf*56˿Sӝ&eQҤt#W KZԲ _ZsQѣ"tv5:FɆ/Ut !vswkV')Zܿ+@t@Z5L_XZr܌(^o\_O,='nϯQn{GJ[=OÖZ/%"柠P+;O ض!L xG) ذ㘦qyX}eήO]l\LO|Xhdp%,)y[a-yWlyw[Ʊq_f!}86%!wҲuo˜4_ìQy~2+;HS}N]QMHTIJh&u_g2KNHM3Zyxȅ,q!m-hhpU*", |j` ׆n+Jf(Ӹ.6޷P=F{@u&-2!-ޮ+oD˵RQ+i#YzQѝar|y`֞ زlrOf,V7}3Kh&$ɱex%r`Kz'E^Y < +A:y>YZ'^RtqNh$!Wae䶺$FP#^Buq[D<;s+\!nM+3p`;Vv.ŽdR<32=vުŗ_b=qkËG&<UzA , %ۈs%[C6nL\L|i^|dBx;WwL[uTGJLm%?~p}vЀ Re^°.,۽U̺O2wHtr|l8b1}r;MB!AmӤi+cˑ;%ֱ!c&m?7qx  `s_s1iM8k Pd+m#?&H\s5.b ¯lgYf.9FOK*ت>8ZB@)nBV4 !=_ȯN&W ,-,/7"FNs޳doYRF ,kp~ǜvMb,r-Ҏ~:Hٴ9DoJ4zC$?HHl [$HҶŴ0ZlzU Kp\%BXGZ~,nڿ/*h5G,7'JL-Y% I'ڣ5>XXє OיKI\n<XbTx餃~>GaCeUۼ2Og ~oh]o٦4¯Z ź,RO' ,^&guL3L) YR PTO&Wp a?sKAOC^C%Z&Ô}Bz_)^Tj)B ՞5y%4u(F_H{=u},I3xPy|'ID&@˃{A nE|SZ,:qGûPc(οOHq+YkdGiG?@7&1c2ȐȌV5Q& O}e=~J_W+VINnh( #LոNr<@-h"<69hDӗ-fb'gUw[,# ,O~;1GݮF7f#K^1&-]-UWhTz'r9T>8*LY9и<1MN2/ʖF%CMFѺ0N^{}n/گi CM#QH_fq$AVܸPK, HaC0M-CMЦzνD+)w3:T~Kj1Hɻ7O$ݲfXY&? IOp.!#- _yXձ4>ڬ绂aw9.` {"-`4\RN/O^Ӟ],&|q?I` ?eR5!5\&q?˔›MٿfX,:$\Z#.ѐʰ @X V!Eu }c3 2RuwVX] endstream endobj 89 0 obj << /Length1 1912 /Length2 22780 /Length3 0 /Length 23919 /Filter /FlateDecode >> stream xڴzeX]6R+E;$[q(w+^(nš9Μ]'{I+*jfPPTYU66&dJJq0v,ʦN,,Ȕi 4Nv@V_@hb-@` 8da';#HŘrƦWGklcRd(A\_  0Zۘ u@CMRU FX?kH3$D%O i 5?@k %WW?*`Ah#7JbɎՕщ `dgW~ G+zu*3최N+)$NrMNb_ ** [c 6:;9;>fHwvpáO3u1l<]snjΎͿ/v9:9#"`ϞEd$^̨y/?D%<,V^NkJ!Y;")NNw`+(A`3?7sc읁c*B`@7SK?1k!= vscG7zAt4vޞW;BfL^[u\. 6x!~䟪iFuN `wY 4&?mlm4ihl qw0ɖF `kl: hr2Gi!u2~Q u[i)}=@/#'^ ttp Z0+kK(߶Nl 1-l\ccwd^`x6f03!N.;g'o9φrqEBf!^"NWy]?%,,fAV3ol7||n7Jm/J7^W" ooo /o5_wCωרk{ 99@ ׏(;9tY^U;#׈[L ZfF6.+;;ϟrz?NͿfY h1Jn .VGt\+%f)[!DPs_:UDAO'3H2y5rȶ[IѱOLʾeis̤Ŷ4y;"&_0'镵¹α6c;`} $;:¸Wtn(/wLޮ CӻI9e yZK}sE*|_TJS7ٮq>ؚ%c$d-JXh%)=KP1O>]ZF]F~SQЪ<oC|G=2MQ6NI"Ps&M lk# &0'F%W u]S,˦k@ER.V]ocrʧm`+jJX&9X}҃&_3Ӂc+ͧm$܀7Y$&-oPz6 'mץWHc'2-w#i9}4p6Tԥ/0c4|yk2d 0GNn&RCIe/3qXi&=$ق^W iC?a*,ɩ4 _| NXX`ԹN[6_6.RY~r(-[dޡJ$Mqp2MD޴"tKVz)ddz[, ?̄an&x` v[pq}߲uƕP p:~Xx6x䵗6K-vn"s^ ˄&"ZDܟ׸ڗ٭}uR@ѩ=Ȉ06:6JY0c4[*l#fn~Ƶ̓)}b +ĠB1bkWBCLJ0}A񕰿ۊ%Fkr\&-JK2XjZּpvaGSz9>NI7 jn\V5CFsg K%k6GF3WЍ3jL>i1EQpH±FibtH5PJ󳺯q̠4P0v@X[K+CPdGkJe4ɣnȽiڄ}E7ANKzB0tV/քXQX'JY"6j$5/btP]epб\"NM], '~%yZ<8"9_ʇAKhCyp6ɟnผX=yO%&J}/Fw~rh]VWk^>2 qäRFEF/)0F!&l(H$0khEZ{&܎~V=tzFG0H䃳~hW<ۓxobE_T3#WCU{sȯv1.>X6A5c-q2HGsZNAnuHy:yJR՛|/m@-]BB7W:hGi۳xN@7uJYY RFM݁I*jEn oxh[9r2c߰VN͓6QY2gw~Ka H3V~+m嚓LxƬ˵Z*6m8ScT&i)=z2&CŢx%?_G އ_nkzo N@<#:6 lt׬_j?ypmvPbHǖ-=@0㑠 FIb Q}z6C!ʊУ܅Z& Yɦlo%Zͦ.oq$±1< PR6)4]$T N1'"5O˲7# bĽSC3";E[:GghĤH/ 6F|hsSWԚ5Ge#MV;,On-GΊ_ꂧǞYX:;C'I[ lЭ p3:x^/qd4/*9r8h MH\=]E6KG_D␂ dQhUnz8|  /Z䑦d&`:Nۍ#]CAG'&G[@ݝݸ|h-̑2|ič v7,MG6WΪ[UP;iYI-q3SO}137c%TȖąY ,U \BzH#_mbօETb,g3Q]jqxU ańB,z'?p=-jH_b-y;TO+eG2gqAlfaCRzɸDAdCwRͤMێ8 oU0@t? JW8H,?`;zNZJ%J}BJ'?zrE2Eŭ{_L'7~O:IW0S&j$;w7=]s}'yfpZVA%")Iͅ|;-߅+>'{\ZgqEt'=6Aį w=/|P[EL ׾j@@ۯ0p9v=-nJТ (}IAܫmКn Ǖ%NAHcU1,V@CNfwpQPPi`#6^i7ř=ߢ%5Sj]KFt'JͭD"< ͢"-ʽixA=+L#-GV)$* lrBjPDЋ0Kteu=EX52kR(^x5EL0oZّ|2>4Ud=O%[K]e ]Ķ\!MNpE%/2Xt7q@{#=hԻf{Hͣ1_(9(Qhǽ-dE(CJ}c@sϼUENaM=ʛSA#CQǺò8Gg? {˒[,

ve*Z-%X迏0\錧5Mj`ӹFJw,et c-i^!7]Yƥg/Oj_Ϝje:2}K['6OywfݳZڟozGDOTĘn2k[)iz &ՠy2rn}Sy`E6D?`??5^][$ Fټ|~ER55( P~jI޸M~ 㭥T?dZ< WuĦu QؽnJ{ _,Ly{aR!Q+wGqͼ:j"M?Oa>Gėj=dtDD4MN(-#tʆ`SYy]L>n${Z5t;:r=\ٓ8jŗ3SRe2U=D1Y7S{7LW6tfp-P >y`q936UMTs7Nzzm>oٞk-TGh0ڛ-> +E.0LnDdI_w䏖Woڸ[(sܥ!<:P3?Ϯo_.a9m(L԰[*,\"ħ$)0>{ ^ Ͳ%5H4:е7QTdgW{$w<;R$:w.hd 挐gc*54/>WbN|sIv4MRĥ]_g+ Gj:LE2߽gG%vFoE8rmVW:JE*F1^6ꗸa4ᶞD F d Hm=v۝J7`1lvW+WwdjP@4h0cZ+63(,'cOwɠRb\5 3z@CV5}Hnfw9ޚ\o%ʻ q(PՄxgckrm`n=.gP>#F {?wp-}'*q1yHPƮ ٯӠy|gGO3rѾ_"8iǫͲAy΂)yUI`>ȇr#k}cqE+p =h h8@X2j)үJ/flx>z cZdP`JԻ`IA88;XS@)ᠦOёԓ;8S22.L*[HnjJZ_fmn!A]ő $k}h'ŋQ#kub Ձ8|KClg#ЪuDR {Yt\RK ޼D7$=J&v=v}\["A&K L p9jY-ژ$ZT`y * UVZxeԊw" !*YvejKlCVC{MIh Ss}9 D|VG v%t|B$,骚V$#?AUFv]e~ Egh^9+]`OA~}hJV͜"sWxI0`t%Mg~O#H O3W0f߸ t7r3<$g3ۉe}ϵnFWپ'Oz]XNճplRom*ό\~=321{ϯˎ_Yw~695`iQ@$i$BǘBsS\N*HA#%o:(;x^blkqLT|=-}ivɎ*T%'jq$[at/Ynf%qdzЧX6>>T^2/QO]G<~?vLzP]8XvESڮ1uZ2 dYo<~$hE@b}G JZ;[Cf(ǒD&~- AS9'U2ޟވ:7b;#+{(T,\Fѯ>a>&Ș[6=:`~n")@a#=~(gNEM6|,N#_4L8l7*z5>0PmD?k>+zʝ ?:bk,(0njT' sFV'g֐+\(-NG:8y^|cJ?ĭ";z|sH{Q%go|MNg qX M׾$ݗ`EO u~(ejθEUdq%NQ*Z0 8 ,o>T!ۛJ)OY-Opv`G6aa Ϛ}=e Km$>՟>^3,x'"^-53#˜_dXG6|qB8(&J$KWe-ND~HOwEu?uv PL N0 Us)$>S j#5Lq_[!.-)re4"SB#F#8);K V4- Ya>;{V@ѭHA}1Ih1n媈{IBr9`[X1@0Dw+zM*W7΋GLo1xm8ܵ[6"n6, q+?y30Dﭓ|P8[AX?t^Z۳^C#g{^GCcA(h>_b%bۊZ!QtJz&lIWSIS4eFL~@C6lS޹r7CKd0게SmmOQ]fBfDPv+ieK)_$i(._0)-/ u1D6P’h 6%X1cJJEXIP-G/^,ıѐ " .ԏTraZ&CYJ*kU 0X7|ywyez.? W$TGUp堇8plHΠ]|fZkR>-Z+e 1$B{ ./.bH5T&u) DMgAb!ZGBT>DDvh9;e.)=YKqHQY\U5^ƾѧ*:ǵ~@1MEF7 :57X1knBz[{(|zAtBΚ&:oʧBJPf]gQETte81R|?ˉJCK?O` ,m#Yda\ij e`. 0lv7Xzs:4(~TT{jh*B;8Fɼ\e~vTw &Z&ZQSB)!Gcm >`X`?2}AAx_h ՝ڛGR_ tq3*XZ.x KdҲsjxW|Ъ'$v EAH%nR&6<>&;d"d]N9ᢦ43Q*۞_k5$a0B ZsX Vޣx.Xg?ȔP`)#tvb$c@>X6]#+ȩAߴX)%} ;.|<}(a6=d J"Ŭmހu<+>ŕfK7İ7^K!yiZ:Yī,ڴ6.4{^)/!O}IVFcki>TK9;2&w)k7FO2n<<157~Y(;pX4Y3?=; E Zd,|/i FEYhÂ[Da j:soKnlv%e_t`.!,^(o< | W0I A}Rp7'.Qp\!M]- lsj<\`EMOKC,O 2ՖML3}{ėu9K}&s1l.YU[ P9#puP~cسEP8 sz{=25v\Mm@rP@:r;F [óvl[A5F D)[N=3tiIj6&0=#7E(^߯ˤY-3#$L˒P|Duje?q!8;S 9L(Plre1WtSZ'lWwMQ}`dFW>~=_JvԖ*HV%0Əm.E~Y8TqUs˺uE:6Ho"?j6aE'-yoW3?)\ŕ27iq\o|3I-89X1YSff,iihK+ h)*%d7 aٰw袸MnW;6[(@)o'Mȡ8e⋣|I&1T='\Ff-alR4!hNd/_ v3N9'UMي =֟P άh5*,g轠gqZbtV[}xLi Qy˝2EXH KA gesWeF'&w{OD!Ow;k4C`2U / *DŽocw_>G#:Y>z,nNpT%ڒk{?AwrEhzȺdt[5.X{[m!dTNd{ [PC ܜԹ'_5FhQrտZVYu2)|&mp. -9A"z+l9wfO-"L5w_3ɳ5Hk&)lݼ}A7IZ=:š8MĤwMZM} Z-iBDC >~z.aalzhl؁JT_eaPlqצw}"y&+^cw+26 7μM)@CBm7C|OENIDY3=fG$vY-~DžYf`{jlde(QQX8VE3ղ&7DT/Kd,U1qu1k*v!3Z7jeaKŕWHmloA)>A;3}wRRN(1]"~3n輡@=ҥLIS{%F7#7W`G'*2h W&OM'gkQnEtpwgV3bHIv?;kղ8-STup{"TMe6gM|cgv ߪ-šp.ӳKGnLepkE_[L'5rޒwuj'[0䦱_ ID{7!N懇ᕃs!#R Ywb_[/eh|vPNyIDѭ>]\*\7,V$0yN] ii ~02.-4t?S%jL$5&B)mgՊQ$蒫vlݥKH5~>$_I%ّ}5"Ig|R&leď6A)KVF",KEei 43}?Yr]>D^xRr*/)a뙐ǮK({#D& vtkU^XCqqi)׻#8;LzAU?nZ3+ʤk縝VLr*ȽD,m(=Y卒VrR8s%s0D++.!~K&+V~ x. F7i\VR *BtVi$v:9[G씇{\ִ=Ş",:J-1Z5O裆K -mLUyN%; WznÁ7^.J?-׻MUvxSգXb7Q($(Fij%b-+ it5`&=ފ5PTk9.a1ВA?RZG}nUJmK9 bu5%nJ+|#ǯDiKš*z)ܬ6ؼuq!x^ eJIk=FP6]"-"^2ğ×}Lo~|1xYf&p sjO.?=72D}T96t!u S|шƇ;86$']Qeo٭ԊR}ly)1L@ͤFMbc! KQ_# =foON&t(~ )`(Q^x4@ Gߴ_=Q!©"MԼ?WŊ۸$:@p5:=t%10ZuW,ɛ#&3ȤUEOޝ޲R;ޝssG]}Xs }Ozt-wO&3E0}EyLMXfY;gKի .ݾz"[Ksˇe ;ܓ] Ԩc҅mM:FێCqbYVSze>GPHXa5 + ~PtOIrlaMYLfN嬇a _X'i?|B[FZܲj=\%K2A;☙JhAga*+= 4'o=W60RnbQT r:KVu'A2nge 뿏ߚ! _{l=H%Ai.4>ffq2Y~3W;ّ\|@y`QJHKv``*h}Ҋb_ ֞?q"y,8v[2iS4fz>CQ,RR'f$; ML&gLaN0,abQ(lbBJf ^tOjXg;Z3L\'k$W# "7&)T~}2c36\P?ŀ:SOyt\;MhH)(yXvm&ۑ:!#5:|Q1R0r\.~laT,Uu.b=6 ''Wٝllg˶mZmkv^Zu{?oy` Wx-MU1=ȃ y$S<j-h⡁-:x>.qrբYUT?VG-b&ͅ`T":%Kk{Cvqm cu3&wA"cݤ8̆c" _ZE}R>.ǪlG@"ڑ6ˍJ W KAwojX1Q͸M,5O{`x-4Bpe'D+&GnGOQt@C oƗ)3~ ) ?T}j5A #YT]nIR&)>?"4ї, wjY+q˟=KB;GYKѰ0$GHej%vNIdN Yl_K9eL?e8\?,׀H [U Le٧|j_ͧHt!v*ٝOOla.# >=W=kw2!ʌi|aHG^bwCSzt2V!&aF:H~Z8%΅,ɤ]0A_6y~!(R䈺C_53Dur& L~l[!k4䧱BϮoK ³V<ѦahCouiej)+V@}Ey&^mWw&= b~kF،̀N|1%k6tl?7,GմFbYMR_kip ahhXǒٌU{grJ  PϢ.^s]]]&l'NLO("$.L8 Aù2yR;1:Km>k J3+fOXmXE&Q)ŧfm,,4͘>QoXov}s>64^5ܣgȕ&)'y簰x.,3k+.Cג1`:uQz_vn*ᅌWԌWUNŔKZ:E$U'`T0Ip͆y0FFՍ9 Llfʗ_f=䬔Q B{cڎRȞ̪dO { CI*}9E[Zٱ?x{%+Tڑ|CvW.@ᚡ5 a7ЭFNHncd10:on#/^un~h`SVtN^$JI=BzovYdެiG1ɤV*yxq u QG-CT~B~LwpxXt.P ՘MuHFn " #UvU}> sDnsMFMf5p*Ի`5ǔu酂i15`BJ +RFϬ\F/ai#| DHjY_MDftAyj5r~L0gH=Z,dv#c懪_Y;d# H҅F%5%^vcU李)NLc*Oigy!U/̫@›)˽Ų`w"r\燄0S)y?y;Sj?[̅(A⯎1 =?n)ZNj!aIn_%ו]B RB1ĄjN]UB~_6 +gә<pTSbxxȒdqfs~/.lfADsILQ6ЭkZ{v"D`^\?TM@zNoؽMHjQJj{vx]@ifC{p:vfH6^!'19s$]7뭞FFt>4Q|;%jZ= A#t8adW*$#~aXֶ=Sii~bk@#ԵYM9y,k=?Y[LBL1אc"?YT:\SDjx877( ( コ .䔅ϒXq;hbRRT3>5K=g`,΃~0.rm._Ke w(T~ŭX;wZڙ10-i\:xQ653ew^1:D 4Lܯ#~MrV} ߦڙ6Dɰ ׬Ff vMݦϨKvZIn.wټ.&T ;HeZ[~'?z Mʣ; "0XWSat Iǻ@`mn/hAF=7- w9'29 g.ߪLw%!oɗE{k5Lҝ[B[lZ#и=}| 摹{k %Q ot,K*4O]+{D薲&-L,Ưo\T+Pwo[1O&?UHHԏT餢E g&/Z^7eizK.9l5:[:4"//PΨ>T_4g'ԌF )-ר1rc/BÙǀO;t_F 7 Č_\$69+$| R1dҼ2`bNRԻ\d)G=&LL~ nSߣaR` Sr!w t vkI,jS i%ux$_M.e}zZMTFm6u[bZ3SA#Ԇ57j KsA"GVwRnp$? ;B'T>Q"%lvqޏ:ru", 8?&\0˵d}l6- YDny>w6YڑJ<D74̡ ]ei%SϷ>hkkQsbCAu>œ`]{񿏵$DɷbN˙aɩ2.|.,Խ0Ng\6ʸޯV2d>5ֱDuۻaO F'|ʓ " pO&%EãX[3w؆,o% p}ֈ3V9uޫY'P_Y-m{tRƓ0:Dgyo&`wHq1Zxu#|ɉV.(6;znY-թjH` ܈jp%sLRζ> s҉e4mQ؆"!yV?,k>K˥ (B$WȔ xa췻5ٳ"#+b|7w:ΏRZIW8{@pL$>qbx}TdMa5KvO` ewH q1=r]D# p.R.Yfqحm2#Nޜؚ˵B#l*Cnۋ~-~tAr8qpiW1bq8pW0-R]82 "Dv15Mx" r v,p(/"FW:R}>:\PV44T'xϑ[ӸHe jYsy4΄KAh"VJU*E2*|(gڮx 3t9+)7_=;fSKU$ })y1N\&k=մNzˈ߳L2ӟ6t")Vxy=EѡLK+w[M;g'-< ;`׹"7s)8=H,*=!|jO) 0B(iߔA:fG2IU?L;ը58CFRL8p>Ⱥ8G9So5D$kK ?@OTD1fUFX{ ſ!u<*0f<{Y`5F?k U}"HOl)1:7Nmm 6WA-|nnk.U˨bABIYy\97Ӭ45&Z&yzBHl}&Ljx/`8Ul`"&;A1)qRC2뵇ɔ|Y'ZIpe_- 0]m-$G~3skHxx ,4zgUMYh1S^0 ĥC:^~TT_7iK:v$HIu?EWQD 5Hwi̭LG|2u HŒɖh>nsK"me?KjաVk%앜JDU$QI 﩯 o1a4޸+T8y`V ޕTeYV : 'Y.50ăS wC؇KDL Xڶ\m0Zx͋lʸ;d7j{;sUaI3i3=BkƑ1˅ތ3?-0{/Cac5z2-E~cGC8v`,_-ȓoL1;[ c!kHcm&hVɄT=يA?_6b2V>6l6IvД|-:\;qgj|˾"ƕk4K۪SzD0ܭHYw.Z1H*UaGzJ% $ICDz6?kRN:]菉]M2k`1GUODQOܳλjf= &)G7ɐZ!c]H+P7WL2xқ|tKyG.ϒ7lQyjQPCMyBQY˨_j}0!XKcc:Ok<4}GpVT)g{#6J Oh">doTNnYn n~ q>un ~恲~x&y\DUL}4`\Cl] |Z(^bX/Ȏ aL1!?̋ ?^kg4'7 [QNJ*cdwUϟy놨⃤Xx_9. ԑe cp$ Pd KɕQLQV%Q9`e/M0Zmfq JhdJ\M"`CK5p,D` 4P*[82t~|uGd,6[t p$;k`Pu  >&au[i\. r>*TFvc-qwq3Q ?K0aItY?/^$ sAY`ZXqMs10?` endstream endobj 91 0 obj << /Length1 1879 /Length2 12534 /Length3 0 /Length 13736 /Filter /FlateDecode >> stream xڵuX[۶>\(NbE Hw)PŊ(P){s9~~Ode;;ǘ++*ꌢ3 edeb((AMlPS;9Z h AP j P6:XXxQ@0h0(@V_ hfb@`q';#LŘr7g[lcRd(A^ - 0ZY @S]RM %jWДfH*iHZ iMu?@KV %?ኒ*`A`6j @k :131Y8C NVLvէa rAl/W'/b\/tB')9 $hBKЋow30֦*(MA`(l 6qB]&^@89PaUeev^>nc`g?m;g,Av?;3/K!/쀙пPpXy9,/M* ۿT> OPk[0  -\5 GxPYt7fWQQqX9}@ +urx?%Vn/ÂWvY%h/Sjy,(JKC3g%bgdjoJd S,l g);B5ٿcFV&v.-_ П#_4/tW/{l$靿$  0ur2@ayi6NNKo[3} 8@}'? `VKa0b3_ _l` `G| ^3dV89N& 8t784^]̞H@i?'_s%C @mm\MN w}I`}ѿ?{1r `eyYĚ}*5/=/ϑ݁(3s`oy?yKtHS3h! 2|:vO+Iec"D蒢ZLsm䲿qLd474y[>>c'S7-»L8aal>FvM| CplSjd-u?Ι \"qI`r[jJWb[W vuop0kugT m%Ni^߱c5f{C7 1aj\/~4sXjeێEb'5Gs33#uђ{chUR)%gRG Ua0pH5b0ZUq eRp a. \"~ fwg*znOsQc_/9 7Zuw~Fp~+c1GNb/2"'"ݬ+E`=O247*;' }!eW`"1_ÔX`Ȗ;*>qqÚk D%7j`em㌝)’ZAyze\B酧Մ.̅tH;GSf_K[GzO/~sF{D^I`7SŸдx[ -D'ޜk;h. V+YF1ˣO!VQ2ʅR1]495T=+gk2_n|X)R,bs"mz'/Lю!aND0)`l-= fDeӌ҅'vf** IŕEsGޠ[pkj Y$qW oȄIޱU#P2@gU+J5_1e'v¸%G_uxw6,.`{ ;LcXQ@m6f|e9L /l9l^!0}]"@Ѧ g5?r.dHE=@jM!V0}ePGgcl[Agl+<Ɩq3pB">b1a/Yv7HnUaZ*-P e0B_:{?_Gl Ǧ, }O w`Gf6y$T\8.&8i?AX|qk7-=b˸Pyݸ^G*)7I4'9<65~b/7|I"U v1gX9gWyz8<?-1':ʉLJ'Cܧe {} mn|Ыܟ0謩EWd8[܇ W/N4yG.75[nRG$@hP%:< nfl CFlxh?jD͡ 螎>]k'3uCio#X qHo=r|%p;(hk \8lm]Bi.h[=3I=4ιS\`}$YKh@j#1QMXn= V M+g`HfL:yvZη6kr/Q!It\GI[teifdαϖٛ'VһoJj/.kf +TWMՋpIݟ/NwI5} '5lzv]BqK(cNLD=V.k4k(V^r2Dn$2؟zZڼo[+kuq:oLѢt8[@<>ؼ kA_UK4:0ky[>JA95vt%$ʒ:{||WK<'GSDȊ wmK1iylj&1ߖ[ㆋ^ç1 s*l6Jb ȌB8ޱOOo7޽e_;apG\-SfE/滛 C:3NSf!! ÞdMc.A: ϳYuF m~i=/_s`W͜ËVn&? eY5{q4-l:Wg`j}ǐE=On٨V礅>3bߪ:חpWYV2?=nu/ iD{/$x~_ҟˬzQ 5bJ@LȤ+1lUPh}] Ix*S1^xA)%[6j(c_P7E'pGrhN^R]/8o>b񗲿sЃi9m/EK {. TvȮQ_ՠ\Ȝ֓d!]8V%o,mE5jﱘcYԛP50R^i,uh(\; o@> $<Ǘ:g+m0~oҳ°,57vٗN{FZ¸R,}۔emmIdB-{ѴKӔ۸'"VO!k{OB!jvR VNo:Ry>艳P;ѵ\Q# ?UPF"ї `qЯW`E - Mj)]sTI](:ؐ|qR٥̞$€6d׽tZ Ea^Bp1Jvݻ>нJjnf@=ذ+a53IZYKٶ@xF.4X`+R"S5E%S۬MH b67M=^7C7Hg9jk> (IdVgHૄd'VFw+;PTTodA G11ZY=m(o^WW8u, rpT:j)s@ꕘwq!ͫZ<>/Q8c~}li'׌Hwl=h>0Q'P֨IozNJӕxYz!Dbk9W.I 0/:`h`1Ol$ K*œ2ϢiՌP;x76y^2:?LnA̽b3pmWD0a>(᪑Po$!>V'XPo6sĀL}pфMBԏ[R/^sf4[,Z^a=7͎?bAa"!b>oVrJ<0!4lFX"X7.e%_.SB<8s)Ϭَ3$vU"{t\S8\l{jzMaq擄:-2@475O9C" :rq/+\1+>U3ġژ>A-i^QFD тVybt*x:/PZҘ/}y:_ ʔub}r aIo"QμQn:q`\hp$YU]}TTE_)U\@<>DMK+Ta 4co.6{]H7kNo, - !\ᚥjěԮQG7&{[>M./(/Dl0?^@_ X&$ʆb=qfIO,l )*nNnCUc'S9]S*s4Ԅ~=ķ_|R9"JOjH|!xi֞^}Ad0m`a͇8zSy> ZB~}0ah?Zd;ul }M?5V_vr[d0k.n}\՛Ѡh0%*tZ¿/)WK_ A |U<_nkAFht|m'ӦONg0rLɳ,wOxnD>e (gu~N\ُSQ%xeDYoe{!I&W螻qE:x['>Tl@'"tXiYtY zP{1u-Fyk(1׼ 1 ] g*5Xק+) U ;)p |e I Mf@ {ܙ+V~ ,M4ޔ(UG"QÀ29 EA'$>x/;yAnM`D pz:i_8n8e;OBY:v vB=jv 78:}QlsU3:V_woS̕qm񵱛c B{N SF=Ƿ-9iͼ GS 9x!MoZSk`#O\NQ߰$26=yْ  Z1ynekeyvw`w Z/bm&8D{]׍)";9J p̷p'Z IK|W5LC3^0XͶ+qDN CR {e%%ZC6%%/9$S̬O`^j0L3Liş{\d}T{Xݗ!E].eeTLZ%ʞUR^7GgMvPFX3M.I\>iߓ| &Z%X4Kko)ϔf& QHn2_&gEl7IL0_C1Kp\'eަkkM Ur뤼|)Dm%:~@iDžU}&IkWxp?_JJ ۴ahVJ ;W<|,t22-Gd['-ewܯ||>}=G U7P!D ^ߜ!pH޹%%Y&=<7ϵijk+/ |VQi1NTGC@kX=5\h 0sCyJ2x'CT~\gdfA*[L=<1CXD"Xh5?oZY?׉d7Ŕ=A欩Y=[< g`mbSק̄aCEb,Sț3QuC0\7@ƣ[5ڦ@iO wQUqHukzh4%Vq_U9dL봣\L3y֖zڨq_EN}T0E9v 5RKܫ)C1VMXhK\,NT+>?LEB#4J&y|%"AgBf5 4Y_?H^ ) #[旅3 qyAb]7%_m~͢o.OQ8Q MBo{/LiZyc1 |f~}5-)08:e٘:\4M«K]~h~C3bz=`iZawx0N"R`mTin-Bب~8'm1mm%V~5YZ9%;l':%C3*W6_c+S,Ԅ8 v.X-)JogR})$%U[t*0y,Frve'bאEK8=խ%_ؗ{"+aQ#r5-+{^QÇɵ y]TBg0j*9H`,.#P⻙Q~( kQJ?z25>= ;Q03ݜ8jR.-׸XlZ/Bm2nKEb[6^Zڼw7Z&S=ĕ>cs&lc~n܏=XHIe٩Sd=}:yk7>NVqȈ~{Oh%#[ഐ?>75DY0֖4qlX H;xr/Fpj</Ƹ&#$ fk%6LA"՝}2wBMߙ+pfRcEM19Eg~Tp0( ȈnmrVO xT3fJOn>@Ud9Bb8:q_HUl^h& .Pi -DBʋA4Y [;]C"+m(gW_[7~ɇӶʡRK|PU_&':ڪ#وA[{-.{ס #pֵ{ډWo@Qdԥ9?,M>9VѺ٥kP/BO CP<nU֮Ah}{|nPx;\k*&1 zdM]ţ-jG12'~z3WJĮβΩ𩖥 R(ڥ PA|y`QigԻJxXP}04|FƯ?k!b4--mpa;5j^hpFd^ O@Dhyn !y:}U8Z2ƑFusi{|=Zmܣ1S|ƚ•Ax^G1?d7phvd%B^_ -b3;WcPKWP ,j@*K9JР&tK-Yŕ4AN]ou}_J)ְ.T3XWo(Q;qCѴY$ aK ?_F}<rUQ|5EM[ԞTWN]*q8nZYSD-l\ 7jfƝGQ|2-rSn=SAhı5ˆD>WNa2)M~Ga;wTO+70wj;ܯX)FfގBeFzBq~C,AC\Z( Mˬ ޴: Y/W i#iJѯJm,{5n ZUmӖ2pz=&c-JZ/q VA>lЈO#oͷ;h|MV;VϢݸ\/?nZ75SQxS@Ҿz>:QιO}OUw|_/.s07dhLIq&y* ߗureCG!6br\W 4:gb<tߎ@3ߠ3M= ^WtV0ڌĞp~72fìuk.D^el5 ftgfYO iIEnѲR@7crلmC,"XfSA{H (N/ܧ Q!)i&הTU`͙ ZHCޙU.3`WpGK?E!٫W8:apXh(T\\S@=++Yrr^@,J#N\,S+9se'gu,`3 G)8n1|J#GNFD?oaԉjY>66e+/`j}u&9bhƏM(z0f,+ Q37ȁeZ]錋aк9E؈u09dYym)D3MrmAӻ ݫsaԒgdzi |E޳H⻇+^IeǨ#b66t1eBlr|HRbr>G/Ĝ+ e$FǽTKv8 -omGFêAI}6Z(Uu{ 4W-* m&w[%xD(#ds6mos0n <Hs;5 Jn ! CS 4a01O~P,/7yӈQ"ǺݠHpHOn0FR2M\<(w}0D6ml`!xtBcB=^US w׺GCx~fҠ>s;Lxq < Z٩`_DWP}\9nP)TWEauX%+"UEaYΝ.m6)oS1`XT*wk#."klFa?ݠ 0#m5B@'nMj:"Ч'$2㣒F?Za3:R=p IfBlh#rnosrrO XA5|;o8'R9HAGd@D -/Ƈ!ՈHFy ,Vc+qfXqf"'{YZ oD|pӪpnIpKQ;ᦍl+͙GԮKf??5=#W9=.)]pԱsS>3Iw> stream xڴeP[ҸCpA@ n=pəofΜ{ޢe=]]MA bbg102l@, v&VFffv 1!V0s30323 P@w YԆ%;Ghkfa yOws03k10'[ chlehe0503\ލj;[`g PjU%TTR*J4U=@\DAMԠH5:IPQ$g 3Op|g/TS;A {^&&F3'G_-.vV`lM9_@h$i/(ߓ{OMicnW55~_MEsrpC.7uQZ{xs m6]#_S k/ܻlާcr/ `~;kG?x韂sM-lMLɞIPZMAf+jl_Zcfc~=ia | x8: 'X&ƠwKۚxe~go J~:Ml&@S&;л9e%dm`hDfhcahȶpp(Y w݋ؚY߷/d{υ``d]V@GG7_.}DĔ4?S0EIۙXؚX98n*`xLLv`jg+99L"LB& w `R/b0p xLA,eLYLAV{Av;wwV,iӰ|a7No{_ǿANoWhl𷅲s|g_o_v3W2V9Y5-L@79X0[wϿr-*j``{2T]]7s{@W1Ҽ1_eR}`Dd 4IL Rd+!mRPoOe'^=_-l7&¿ Q$DF4}JIier>O54GxZ;#XЯIuKW]gY1\'AoXQ"K3_rqFd`:дr>.|+FU1ӍK:ܼxXVbGv~.1[r|gTjgiX*5#Pvoѷ boס"Qit>τV0FNh5󰦣ߓ*UKuX(_:|'s0K+ 5%u<^iSa9~T?0ޜ1El2B>C}TkD$S^!˃XB"tu }ID|>iڸn^Ƹ9 +L,{hm2#h^d Dt5d?Lٍ:rz eK#Y3dZv ˠ _5ϩbzERJX#KX&IN4SmS1m*۰#s8GBH tYuFqa: 9zDO>tTfߎ&GoЪO#X5f#9@v$yt50MȪ NqR1Zfm$߃N(+TQeB T8XG rAmI( 7Y(+1ቧ D9}#8 0OQVK lvQ78iGz*ɩ|)qd eNݪK ͺ'{.$)>ՊzKTnk_e({ڍKhݩ=}KGL8ZQp㝫7ӵ ozPНA[xk($.y\(7":PIvnn1cଚ*=0iRErrcPk]ㅵKᎅŷZQG(arL} p~tvc$(j# [J٬"+G6o*_O|)}d(Ttl0?z2Rq79q>jR Τ̚@@61z㞜NV knT01ciU=|T25;2aGlzV皦0^kc KQQΖ*]|ʧX3NGwXx")|wmXIrBAd@}FV(WX~(l6sZ}lV_.v8)chъ'JPGq6}z0Oњ`AmSH8,1v{dU^RՖ7o聭lqJ>41Q,eCm H6&|t >CP]T.[9ύAӍMuTus̙LL7A {L>^BC1%WRI!mlwOcN5R[5cv)Ӡ%EFOղԻi`SK+BlS$O\BA~?#sdYٗ !dhӐ:9AݼL5v6{3iE{%@ZT<%VԌy+-2>WD#!o}Mn{Ga8#O)'$ M. mϙ twtk JmK}XqF_B?xYn ]FğޫFh3:1Aj#<$g]wC=ؼ10w$%A h>~DGe!]̵f)WcAW̃ɻ(TPuűjUZ[1$D y<:"ʦ Lz?^3Y:Z:v%.F}/'vun/En71vyb2qyqaG2؏ q+c)aLA|=$Cmmq(Ť\ecir%gh'1.KkgLaI<#yil@&""4D;z LPYX_0U$cp)H+TgOԅ+8 }Or~S7ѭ+߽O6Ҍ]$u:2,_UOPoN`MM3={(0q6XO$4-Ds.EM+qW7jYI+$diKiqd(?;M#\X-tlJ,5JB.1UYzSoaHj@!@|* 'qm;:ܢL`.|>Zd(ejRZtϓXm ,Jm q÷<Ϥ^90?U\=j[Kz 7;2h3l? (G+g־NZyVvǕֆ;lTlyUA|x@A ؘ$ ֕:]uIUPHzu<'qn6\͇Q= vsmF:ᡉ Pta0aDjp6}ۥbjX&rQ|L a?iل]nxcH+ךs7p74:B aF r9|Gn;ҁ:/ix}irITzO K^ d,0ucZLs4ьH -W8kb >|'TB 3lilcNyHl$;d8.Sd=;&OhN(+v/P_,6Mqg,xɓ0GV;:OP2yO!NYȹ@O%y  V~av [ ZdlFc&Cb>I^`1s"aq`h&Óso!t{?*' Tб43zV2:Q`pK/s7ȔWiv[!HFL5٤M4o>fpCҏtqҔ%J# 汢FJדUYWv;lBpz59#NeR%ZPXDt.T &v.Rr%"4XKv,9~,01E|0CpZ#E؈yaP8B~.(HMYfǵݐ'`R(H6Rٗfȝ# !SKf]Bʱ8ΨBGZ*$T-{Cč7ٷͮ]3 yǼR^ByY=#4JAE-K /'!S6pW⃻TYN82F%xx62ˇ`!ҩ+O}4TcY`d° tE2;m g"vBbnaeȫ58.;C,c8^dx 4Wׄs%r HL|{Q R :$]Gc B+]Z7NƟZb:U su3[AC3X,Ss.B=kk2""SQ,z$ q?5iTcY&_ᾰa=J H:(+;),#&\2S4ll5/v吭vwF @pt6TD,H|zqBx~cZ~D ƞj~|y.'|e|b>0Gm (HRܮùLK'%J'/,'ڴ+f37¾9Zo|'xмk\?2[ ^R3/%D4^xvei1ޫ^TEuvACCT7oA8+!N2/d_==U< AvdwJ0ɋkNX4֒''W˔tq $k(gOx1Wj Ɔ=0bp2I oS (#EK;;'&KavCq7 $ NJ۵*h Fi 낟6=`9N K0FR 7^(_ϨLah- LU6jX0OW\!~;<8\]T)7旟>"Y3V|wY=#t'L2B?wiӖUtQN5ŠUbOj{lP`;kG gPA|p-bjoۭ"'?B\M6 0_rҖZLJW?渿Y.>zCx%\ EA` M|ќ^CaHY_56fD`=^d :O{SM7@ SpJezUcEx7$tV,%FrWZ 7F{ag9r *OCHoQ6[{_Шkg xL$k'r Ku }usX5) /sY3}4?\`@Tdt"%F5Y:+s+^$^[a.u e"7LȠ' XZڄ8f-$~5i w 7; Zg2p25(G{/~= jw}#=L߱X9QX#j=2|,Sj^A=|+:̝MPdor~[ <#q?1CV*5ųAҔŏ|/^Bә>׉ GĔM32'Îv z f kʐ.P i,Wsb{g񽩀h,|ͼKb`Nz;mS)뗔.R;XEVomY7FIĩxo/hBtxzJX|"2ANh/ݙ+]!V,$u>_jW(rW[uޝ&5ҹ)ApcLŠE{O&eFgYo NO\?wo]\B$`'#L?eNV0Yw:= MYOB55W=:U.%MQ/TM sQ[jz$M:~>So|f7"$hߣcm @^ LN%bA\i hQZx?WC2:ۈ[Cri؆s QiO|2_J07J'}jJ OpV7twhP\sڲy9^Q;I-?f_.v#KJn<@hm9οjU_a(U6CJʪܡ3589 ƨ$-1KZgUK1$`1dfǘ '-' Fj؄9Bvv¹ j>+i/~l62Xca9\QkJ`W2\Uģ/5d "h jiBEJ5|OOl7#dROd* ÿmt?rTo?PSB|Q2;p[*cuh{^2Ƹlv)ZL*{_-,*W#Rs`Uez/@EbC"jW$|9NS(}j`櫩N):j/' Rtl-ULQF)|td8nRȵѶ 6:d msaqN-N!UT{Lvȹ x%6P($c@g"2/,Yt&㪂]UQe~0 U]gڏD+PHb D1L?4솒Vt|2=+0m,UpB(f]]#c|yc ixYv]~QIOv4Z-&,Y :ƶm?]3ҷ_0|L]c_D ۈBm#>H8Ԉ?6ZV6YfћB={O 7~G (Ҿv -N'v$lc1^.ucwDgވ\`&ncȂi6_ɉ| ՞ /u(7j| loGB#HjcЖ=z8N?-J®)GR$J Fw*Ý9R*5Kg嫾qS%D{_>07 dfY|Q>X)w@zTr/-UOE]GzMk\lgB0)b-+HPZG]ywGZDA -$"˩ n\4r,~5^6 w*c%?vE,4?NOɗGF X"8wCnA=ymt>V1pKV@pURyt,Doevhe##j!c\~P/;)Ğcv [{?^(Y>sF+s5h|>yp:}91/CsU2ʼ[8"0= {ü8F<1܍zg$<⍣R%*"p]#2[NRBn=%ŴBLY佲ɿP_Lhl-%oP>D~S /v+^9AݻHgT d5k@xړӱB=݁oboZЫRJ}d"?+%jї%hn[ fDQgc|iy wq G(X@h *6y ukܒ*RKA:zxt6lz@K-}X NB%DfWTm\_z:kJHQ y[ǒ;yb ;biB:x$?rH(j WAT4>)HRFwzz?8a-rz-AiǓs?}`bM,C41+\~Sos񲫇$kt,R(RGIF~o-$_\ET.TXۿ~ȣ}Og3yL(;ҨY999@7 76")UyIsezؘ rO1D(f;SLYY&a%A:}m4H5TCw {~<~ӺQ"@-_HP5@Q\wC]Sm7O"3qy!eFNrJׅM %2 ȥHn%vtZ*#6.\$r"u&XgJe,>!WpvI@  DVhc1o_C$"2Bp ;imzE2]qu׼dj1{Z_*XoxO[=mݝJ絝N+88IMQhV`R v"kwl&f]w~7Zh>g[uޮ,i'0u]JA{<~@5@HE/1/imy2,0-0?voG>&zXd8fː5fL)fRb)ֆ:n1OOo =<<׫L|q=#"@?} ߿> Ӵ@Goc4fjdCNoXCp*!+>E+࿿#6['}u$׷rOlOrC%^' f`"r}5̑#O9Ȇ=3NCpkUNbǖiS9/QΈGi̼pb)xSK?>Yf y,N%| ™~vTF Q~(V*x @ ^<)ͺي>۫Ύe5;CET -uFL˳$3e8 xDtFR.K|EǀgFJI%+HY-BH0KDqaXTGXQvB^qB׹ 3h,•0 R#jw_4Pz-T28vu>m>STu_sW_ ސMT㳏C l+5IMv+MJq 9eB:Z:7 ik N~V9! dv7'U4ޯ)_r,7͎U#!RJo\T!¦Vy!sٵGWl|~Va)(vjI[ðvA ކ0S CF-N|lەl^%YǕ#ƅ&vT,5m$i^&0C1(>wϑ -50S]fϜI{PC}+<{.V^SA/8;-> &៌̚&9c4 z%TE&J포Eo`M ,S}΅fKm׬Sݔv^Eg3^2 pxt 7Or%j,t;vÕ(#~cT1!x/սq)<)4vP_ |1w/l|f)J*3z4 kmgD(OEnedHTIW٧_Ok4ՉoA~-vI6TH׹K.Bz`Ix҃rU$xz/0*= \Ņ9dž9}6 i6܉h`L ^7}Ԍ@MeKؤLA@v44=vPmnig"݊З74#ohIo4`<#0-7Kgؔ8RvK%;@:D!FJ[h"xmf%?~aWcc8ǒADk|#RުP>E闪 _>0ueMЬXnd X'Hن) FnҭCUDŽkS6U<8N2/^밈y][9#WfQd'˕u8fC5RPH+험m@<q\!WǞ&:*KߐKUQ# {uh2\FNPyv"iL#Y"vaXO8A&2>e)V]ę%N>6^oi5oaQ icz+ػv2ǟ+!ycrǻс!8F&S]D|M, ˙/Za5=, Z`X}}ncWRN 0'g׹qn?C(EEw- ́ ŀ\F㚬\8 h7:%Ԫ!`c+F4uQtm1n!,Ij&aqȘ\qXN8:}HjVP; pt`8& IQԢ˄8Ci)>|jHeOMޔeP4A奄ԣ<ڑeE ̎OV h8ۜl5dM6'nWml۶;k׵,IH8<ۅEݛ\7{SG*9dZW`pY ͅvͩՆ -erL*x|$^Ѡ^@0`|=k21Z3/[uӤf@Μ;A&&sj89˻yD[a-sǯI@ Wᅤ\u~LŘ\s>Tnl@Vv]%T-A8o5"!ĎiZѱDmFpogp3.˭BO-c`&!w"0)m8yf#M)vzgZPR4w ."` aNj5| fǫ@=X:%UO1nCAX YЍQɎd销'+)/ Zȟnj7T={ϴ[;gC Pb HQQU~Z`% 4uT<)*_pr (c3H|3nUl9TU̜ Kp@o|)aKpg{e#Bs0n@L9ءL٩^_'+?LшޮҤ;={>AeCQ88Y6r5hDZ#K5B{'N D(ɔ]:İ* ZsnC>V9RU&=ZShg鶫c;u\+&DWq2}Jt DZ}r\FwyX{Ē tz5Za)ÄF6i B]a7abO,sғ]z 渚&\nX I!"9F7!1~E|rv#H$;'4JbTP&j hs);&HT_rfA6JWZŸ{+1noIPުk[<'0[:njd8rs_ ;^lt 7csߥWXgxmPx# h{Xc??>7 [(195 E)1m[IF'ZhNp)~$:OG/=iy`Y4iUxȉg6-*sD$H frTY1<C.6皩Gi44SX#6Z꡽}&Ưd s>͡3f -Q^3H:T 2"qN?<+ifC#@\#4K8̷S&v0EY=`)bhYeQ ^21E1J/,B"cD騄G]ϻ~mύY@zU Kzm=N{vG۹M/xƧ<>n/̽Hg:SZNyJSK6+ ~={]V{-՟t&#Kɐ+d (H.f6?a.\95c6P_. 1+Ig=u!y>TSpy~;$9wq` 8)@%OA/tľG·wh\#xqn7??)΁Ѿ|\Ő(&x>f8~Ku?Q~E*G,K J7E{3,E;y|dcfRB1_AY:t/{[t6kfqA16twiq j(,~>- w,|osk$ 5D9xAI6jP> @>WX4;Aj.:-4׬򰸲vn _Obu= m< (mYkٮl%43)2 PuE,xcCL˂L|df+̴3Sݥ7—,䞧M<BaHwiχ~"9Z_7Ʒ  RI|TF;/3DccPTSYӜ2.Ϻp(o_ieqN7 cA"tgM&.9,Jm4遲x7E2BXz:+[CEns:.o.+crQI 1_Oj%{fw9ƦH[T`SXh^rcحHZb1e0QxF8qAC+#l#:s|ɘƒF}|9^gb9H#KQaXtsϼBY$߳T̞ pƎlojƛZ x:r "d">#3)׺i3:jG3GXyM'_['DJ~}2=^˴F6Ӯ>F+$;JzsZs J9=kX(ޅ0htMB ghֽ#  :%oqŧNHa{d|rf|ngmy-e3@scs }b̎EU*Y:=CYV}.FZA}^\KZI<' M{?˽,^κ^jQ  J 2 :1nur3( r6-KKdCI>ɏnT7q?Lr1@j2 RDdy__ɂ̲/`vDϙ&8_ozri|Hf~ϳ\=a]ʧc;+ݪNC4ggyS@bb.(+NH2 J2eKNjSmqES.<$YN{ϬtBg>ʬ1g"Qog?wGL( Y'qς^n/\+veAm1#);, ^Θ <~_KE Q|<#GЧ9:O>:N O=q 9,z^kWHD@pÚwFP/hNG9A$^ڡC AN.a{:ʵ%EM,/L{08=6Wd}Td|R=4(=2OLh 'xZx`&:`Nd4.SD=)9PUԚV;|=q6v_ Ճ X:©4r@hyQR*yv7cZS/q(zN?2`a#M-"Gi6 Bj3 =rVY]}-bAWzz7-/>^o~n^SNqv=/}Trۃ_༝KF+BPg&̨=uqa<4E=oR,F,!$ϝoD$|3 <[ȳ}4 _yKnmA~HtQ~DN_lolJ_U4ΏE(8My V襤|e{J ]Bת*EnX,|H8:ef/wR|𮸚MDJ )`UM;/oTH|^*ƅTK!K^p2M޻ $z݇t';xLkB%ǎhߠ^/o2.6 v6X߶+YJU:# A`=I*$M98h|T[@gۻ6"h$YZgQwbRDA+$".:*˯ħ·J}E%q_Șb*gM=r(͈7fK9lF% εrp7, /}urKoE0R G_b֠'OC -5.Q|fܢKëđgt{pSlO* ,fC(V4+x(Yc5g@@/GYv!OKWd5B ٛ+bP!oMox9_pTh(XG[+X/nRCˌ}"׿x)V6aCA>/qaeVmu39F/9YltsXaSAaT`;`K#OB5` OTLu;ҘӽMR ,kP"=%?h찊%X:[{Pux &f]D8[#JLDtldv!T/Ҍ if'1.nbb#XM&T1) Ld}NY׷9fIn{]P5֓` u-% 1 CoeȻNGz޺;ۼ56qm p@蜬^R4D/+KrZo Le+1czI US;R{ Uxk;fkė%%lbݥbN H *>J'mcow:Ry'CW s*!qNODհ,!D!J=(%Sq+!rT*hv%\@^FiɬTN~>YXsǠվJRC)S0R{IÏjIiN=L P2/n!!rSl,Dϡ+F +c+x_ԸO*-lm޸5pSU:ЪBA}X2$q~5sc!gDx[W'$񡹴p($TtL.n}XcA+kKk,OսibI_t` X&tZ~( g0)`CJ˘]]s4 R #edD,8Noy$q2۶ q1U6Ae \Qp'Uq5 uķ̫DSk?.ߨ4#0՜>1>V[+H-!ʹ'-6vi٢Bo: À1f:W~A"\qI?$k59ˍ2}U|ǘK.F&EԈ {¿ 9f0h6z󈗡~u~Merc[U`JɋDj6J0JSaR.yeqێu$^E蹴 n룇vnĹAm.~(T,HadbI$pcm6Af1Yx2frf D9p KVT*]p|T͜X4Ɩ;Oy?f1)g[:D=$8ظs9^' (dv؁cqKyo)#|:| 6(_խE?wɟbې bѻLv C?`U@rYD2 BHДj~ER9/ßX ηH_b ;$3 V t"a+xmm"On-q_í3tvU\BU}!/}\.IAg]ajB#ӬGo (^52,A(Z9U}iH| z=2=U΁HVQ]n *b;; <0N0wPe"1TN9 )Ǭ@˷K H4efk5u\6oڧK ӳle3v\GEƪZu˗3Eḡ 6A4;!5!rޓSЪ:,?avR 1A[=zY(_JsDSnB1_\׵q5R{%[8v/\5kG=?9ك q*KTXˏap{ gdm9"8.L繭n Q-!4eD5~VY㒛8ťoKC $y1v.KݛM,3%o`XOs)O +<VtuTAwDct$%ai/N^(4z;4(t8]q91S C~ ~o(%zٷdK5D+W׵OSm7i1TDeY\{O~:ٕlD_AKj*=;D喯}"3Id-tGn3P|) ګ+tWl1 ,\0JmˡW+/](LGУrn?Bzw8,e}SL̓J mS W*"C΂vZRL-௳2aqYR6nZ3bYH,8e؀Z9rld,UcǥoiWz}0L=gE Oz=FOqw5e,e7^m,(Փ5Ա.2skJÕ^IG"X8Mbՠk|׌#0*ya^>_zW|wP>/Q:r jzd9dL`bQ-Q=l_6·* H^aC7-a: ;{:(odL-Tk%\'8JTL,> stream xڴeT\ͺ5;h\C#!@pww %w };GgzjjrbE:!S;c3=#7@VN֎Nhbm`gddE 'q9[ي9gP*(  :cH2(999@[sK[ 5(Ew :ߕ~g Lܜ,Fiz9zh -vfU&@MELY BM*boo?\DTT$hBb:-@BME_U-9-@^;]NLUHUKQLWō (* gg{n777zs'gz;Gsz{ZX:OG5a\lMAr:[Ud-MNIvrڀ%&wMhcaO,hkdk t6rvqcM)EqqtC]nԅ@+ӵ1r3uqK\ӿ*f~?69!y)q1U:YفԱwvw'w=!QY(rp!5vB-%H'g;G3Vvn^nfikj[yS{5[KDLl@g#X0nϴ636d񲷳Y;},̀/'#W ?4ÂOu)[3;׿ &RNh o w7Rgdci͕J|N@SEKgTY4B@ОcR}Ac zX~r9H+[I-AFRIERlML-ml#GG#F0@#m tgP vΠf~ A0A\#F`  Ab0HA .2"A . F .Ajiq|FR4@gk;˿:vJYF--6621komjg{_y1y$hg԰4 3*wFЋ dzр;laa;w/:VTt, 8X~ vH5w"MLx?4LCsџVbkJA-Ou Z3( d%|l5Ƀ1_7Z&oMw||QĄӫf-wPIkdŵԾput?F3ON&-o[˃v+cjpFs_B_w~{Ĉl+L3k]ƾUcJ7Ԗ¹MmVLޢls":QNVSK #^D*+J TQEt?Ж:bѝ ^F;5}W);+ vV !Ag&\ta)T݊䳃Jy8e5|-a0>nGFcG11:ZyE?r_7fmNΏnC uQZhۿ,wiqBf069j?P1kþgV;NzP%̨Yv0Si_&samkHU+1,7xԞ"/nXwȦ"›LN}B0W5F*2˦VyB6_X &G>յj"S(r1q o ȝ(w"xH/sݥR:>˙Y;Qgw|W糧a0w5W3?Ǫz\ICNa V ".R2v`h r_I=mv3%jCjm=ZW䵞%Ok Gq]FMq]Qºd>Kt1W(lorXfա|oTC:ٗbN%劘Oxi~7;醝/a"MXhA3VA9} ,(|DY՞Os*g\}, 6qn|bIK0ga Oe(c p~^љ=~j5M?+]P"dǡ)fGWvsˠxOt?+kCϰ$בRĸEx$Aڅb1ҒVrfә؍4y B*TS)X.b]D$'e>@UAfL [.a㽯dN#\][K̑b:Dɥصb_墦]9劕_ڃL z? P8FGY iڞf8sy(>c Ҽ0:>8gb`%ы/eqLm>g_/qz'12a6Cw2BCaʞo0WJˍ[5;X/jRrgyriEʛ1YsId<7 ?z8C}ѭjԱ|XjM )l]L];Xd_\'V_I#uҿ/] {2‡6d8[bҳ#&I,pGJkT|`]: a:-$vPHX[4k9 (u߳`'xbV%7Q3Њaca8KD}Cx7tΩ0_ioe|d|iru빫pMACiےzކzQ<Vϴ]B5b3sk6qut.]L}կjҒ-9}l|w>;i+%܄ KdOlߕ3ff䒖vmqL~툔U샎d3^ub96JmmҫUEN67KEi+NRP,r}Љ@Jŏj|h)#t'M0~ xH4Z?T:p~;'aSmZt{\dakt ӊNp]:sBƝG՗Di2V}])8fp痼{7ECy!1sT|"w'OQztRJ+XrS˘X(WivG]_e}F? mM$}YjM/!eۻ0>Y5XM 0InVߥU6(_ nK(aƱЀ?X} ?81m Z!Sҳs" HLƟbZ5/;LuUUt\Xx: )8t>|꤁2OCF-;PėJr0axsF./OLw =l .JfGU>x:;KQt'yS'v"4G QKe66* ʹ*$6?rWwO~X|!}ʼnwhI y%ɸ.i {ATZ=y78znE [zDmVB9te֝Q>N8tc4!4ɯV+V9U)=f{Y^qY(x?"_/7]2?sZ+nsZ.rgE1FVmC* >KӼ-k'@h^FGZ4H!-s8W\G!Zc+F^;(K=}s9-'wtQlɓ!iat~/Ni;6Z6vz>i%zjs ,bo^AN W1gQpr?shց&\ +$ 2G8IVVY_pš@ W`ߚ<< (".Z,tb~+o|+r2SC 䩫; z#5J(7븡K ֟-pWi),I P|xw0s7*۳lY.y"C̐8d@rǍKAs|0=~JoPZmeZğCj4~|og\]mGa><3q٩XLT1,_Gg3OXEǪJnj"¥oM~l#'Ġ|k-pf8NX"VV~i-gy0OF^}a|HPS4mdٻ'3g^E,Ƭ݊ k3ץ ^/A>tVCDi-Q\ ;a2zt R$j#W:u.K OS x4YP,Og[Ϝ(BJa;fXR}4՚ [ۈPle]w2'rQLN r)TGVBգOXww޻Cau v m NvKTkO(O5%@MI_Jv*ڡc @!&0 }s_3Z*zNOP(M3u&#=}d5,zRWt.S2dD=/c1AF1*>̴pwj.tWd[aġ,(Kr;91;ܘW^t'MwhDhlޢ1ZyPdEO{z<*i<7 $@ipb:{hJLvCjsa^ G?d_%9u]R\ygZXw&n\5mNQPV1P*f3ـciS]A֞J$uڴCk>.V"13ܢm$%ɥc^Vg^\Q,+YƨR?3x6k9lxOE>9 x>硔##`{lPwd1f&#(ŒP[v+;T再rEiKz DIQ 0fbvu7}.$̲*%Q Ox.]+r&ުq m2"xj*`)`ñieatkÄ@hoZ W0ʧ0tH%b= a\Dor# J6d,ঢ8eCI0:4(/5eM V4g mV?gDUn(bRlX cIHXWOגA*@I\r\x2IҷFuY˨D,ۘQhck8\4āT5+k4?eՍ5ᬌڰH%B.h,K-kRhzVfٓbRs!2؏zzA̭A ng 2+Qa[/ L0eY[c:T[߂n/2p.I洓)oăҽW8p"H~X.74ܛM`솗<!g SXoHk} [Q:_'Y]^mPt5,5nu 0QF(bIw\5\ZKzj͌ѥ:Ǹ_M|;exʓ2_209gD+vCRq7hb߼вDۢ尋e= &֜>j od7'6V8UvAQzYulW9FB BQk_h'9z>M`fBizOnkt^Ӫ&L*8FމFH=-Y̱T6mkeφ(O`342f£_5­>|0.'1PFsE9u+3D~RUzqTuqbrỵub]v]b[X1v|Bcoy>Qƹf3{kD`y§thg!)NksnAl650q'`kZf({nd(Əo6'Zڟ ?|H*~)3LM@J`q/hj#̢[.z#c]kaM|02ǮY|Nm&k ɜ;W391[nn4`! XSO-/$׺%Vf(OT(2kҽ_"Fu/ t7?}} ;U'&/r#-9I*:<(] hu.yZ- A, ^ H${FnMYrDT;:0ǭęUಝwnĀESb\Ko[!A3)]jVbvG+fg:FXxrj\i4hnp}0,C/uX;!O-(mn8Bj&;;%kOXPmiŹ9-hBQ@Wϳb1dFkCOGRal[1zo9>5QϏ3FR=8Q٫wkjdU`dؓj,K-D,'P!B9,;"o$%\1. O QpS~Lu9G=qa̹k.r֘7$[VZ;vhZd7r4WOA&Th~x5Fn؋ۡ2أwͨM$jry9 pL|ؒSp:ZE6<3r,eNbt@/uXYuG'MQ]g E@G{/,)6ˋqIۣ~C/dtPUfB>z LAX ]{Px@]0#TCJE~Qg=WD9'\ K'QÃ*Su9$*ц 4 aeOU>N]qPkAL g'$ tӊaKi;$ 4> p ]k :}'xx'hϪdy3׋1*°/+}K!#Sr]I].[vrݣcWy>΅?H0ō4-`{%ѿy6 U 5ȫ=4@C{fɖ`qLj]` Fq9؍a &| T z 00 PH:B;voVT!^6b//tݬ_lxX_L^2JE--S"?wi\ O f&T">%!B%Rjvx,^vCԽnjFr2 gwfoG4)W΄1OM% D\KupZIVh\`e3tv^.W"c#P0Kȥ Z g7SOyCNA@vr跞Ӹ~"&椽k:i8S|f ^7<&VB)`ǙNev&z2 M[7Ea/50~z`K29֞ .eo&/q&uh98hmس :QӒVC5,Qn:$ yqCG>s6q-}1 c$"mpf!PV.z!&@s2mxqMԝ-WCӒ2?L>ڲcZ,1R6_XXP4&VN?o\O {=TJ(w-σ(bɅjRg~e)c BjE4sGQTAe(8=>y NklMxl ;ERt{ltU|:V_c27v22fb/GW,u C.&c' "=%\GNDK1;LS:n̉ 6Bb|rC#Q'=Wx]N,,O?T6~ȜWX-"ɱ"Hx~4gr5 jPI00#3CՏweZV_||︗DԼ<̩*s%oC*^2?/kA\ĥUj(wcp0 B'x$^ qq&zl `UPX8YbNW[2CUZN|${r 7͚[X& ?S_UA'[NΩW P]TS)N B3Lx?(lGU\Kى.ݑ|,UyAt3-4s<$8O Vj{Z"{^GVӆڌDAp}''4A=QgFz8_MWJ`ﰩؑR&(0[;Rc$Fw,+9yJp &Saոˠ ˙{UvseSSw6IckWT΀)4ھ\0ʛF&xcXP)r#E`#(2Ƹӄx)415!;dH MUA?a6)|3Eۃ#ў?-jojN 1"F;񳍸qdcdش?II2`عo OB.>H+^H*֨x<@ JV2K/WsI~TÝePPLS <\fHtbRIw>Q$!ќND0yY&XpvfHl3LMdn{i ?F`pwSD '2'Ұ{L{ xI@kEs G; mc(Xt/xvYZM^fVXb8<3(hqx|nI# e6tVLD {TY7'UvGV秠䁠ryYky@?GM\r̛֞6~|k^iNVz…;^%H]DOm4>ƾ5Ys:RUO/tR^Pi.C\=IrHo! &q+gfwLEEd~S}jb _@*Q]S_MǼ,zB8HuAʽ ْrp=pv(+icz}aE yUKH1NU;90 . z@] (Z[B۶WMl?>RN!0>ICu W>;T 11g A7œ[k/9G&;-wnNo8B-BQ1R l:\r|Bs9>+/8V ö>3ֽ_uř̢T$Bޜ3A]h=Ѐe:Ppa:Ox 3hU'5A&T)d_s-ؒR`(;a7_=D{HgDG% i~s43F9Oq  L+۾;1`_x_F+"L+„cƧL^U[ݐjK묡u*z6 t]%ɢQtڙ%fj}xLqjtx^*E^p*JJ\i]epv|VS~jb?lAψ9%9+!]ofdtyER C.2jF hxytxTܷ]g`}[<&\:ҰϭyxU7^`<4=Ƿ*0V6iha'/&˚CR"z-uKu;iӿL]ok0.^kZcqW!9.q=ҁ p^]SY@~}ac-t*^HRRľbh< A6u\02HZsoѨVx/kf;rЙs5er^sMVu*ڏ5M.v(R,=N>o-^HuaY^@ u3HH(fqPb! b꒠OҲەp4N:եnؐwK#zV#hK7lt(f̵gkYRn^?½DnziRQ (%dg0D1U*XhK8g.3;K_K=`TG- T GܑQC&\ y|4y}Jဢ:d{nU}lOaf:_¾5wx@:^-z:p/жeRZ񃩝hgmtq"rEyH*+ ʆAH5na$ktH.x92 -ї87uWY'&Ɣ,Ѣ|hv |JOC:?Sʧ ywͨ#2G˯FQL g>^3ESY|cCr)[8μ>>%ϧ|G㬌jIu1I$z+5A.^f)&2R/XKnחS7 C܅$w8/N~$+$I#mK3)?u|1$GMW*i8rݵᩳ\ߡ}U^:P9/ͩ~&eCpTWjGHΫ2sTtO z[Vn'&h'>S\% t~Ueޙ].3 GtkEl1LT> _wOk|Y*FVgW'5]XŭP5=$Ož7E[97&bg >wWDby2RSr"JOL; 4gQ)Yꮼzx4xw-eOGQUTt>;֔8`Sx^om=3pσ:غ?<_ vP6}7ZB2xAh3SE%[a~VZwd20Y gv"*ZhSoJ=!?_sJY>Ől,tLm>b) _ѼC 38lǃ ZeZHǡ~[lUA=hMۼ!DorēzS]W ti.j:fc:Vv6'dZE)ۓUH?V6gRQu.|v$ ãW ЅgA4 >t7 (@g.ד/>[eOX$8vK)gfw_aۦReQN" սOW[ R&pQ( |#FF(pKxtWi=%9lm_-+zw%W]|H[_V BXr='t{Hf&-lz?/_aYjTYϢ"qpCd~1"Wd sF^RO_?^˻twm|-i~=é#5.:)!L/cjm"4DҰ^J'3SGwEbOsҁ`6=33CC*L)"l0U'fi#/7b;fP$'3H#+c}7iuy]~kqꨤ%IE%?wR? rOG4Q3PUM$敠RQ~7`\@:,. $d (,qvyLa h%z2e-N N4঵0{w{؝ Qm@0Q:xF@f 1^q[c^3a܀2rb=gAM7W4("7=Hw͟Uy9œ9W||E1O|aNQ><1㐒q?J Vlis by^T26ikQe6mbyfnX\/(ftaEQb+6]ʶ?'UŒM&ry^5 \s h BGG?xϫ%kW\nf73PqHҫ%G DjF&+%?P5G gdQRP ~ܫb-aXQnVR47V&KvBHJpя6,b2'ܹq(qf%" !9AE7M@tκk..ʺb]uṚgk3ŵ 2E v2&eAxh n|uR#SS0 |sW͘G|jsn&wNv}}W:r{- ku,}ګr2$+m@t'!O;gUkG=f4I@;3}6 ,LyQ(Q޸oYU1 6-Zl|If:.Cik:qEd3ᗇFO%yIM#0Q/,%qYRT7=*Bͯ ЗZ1>!:@`r6ѱl'1=}O`*{U=t3=Ɛ)6Z+39ْm̆Wy(bX${G_3((Cw7,FJ,᳛]#3Z9, ⣷BlmK!@B󶁠w,R,1d( zOTsMB FŸ8=觜8.tWNf6mN#*r[8 zk9Қ2[%M5kf< 8xU;yH4s!7X!86^R#,P-D3ӏѦ<3.r.=+1S5.Lg%lrp5xc 4VQr2T V[N A-Xg`iz =j͡ݙ|m)=󵮷8)7xQ QM&]}wA?$Q^jrlk;ٍ*?nw 8%ͽ;S_`VpkMЏ44C urPE!/fjrR Ә{ PtjYë%.tB;ʒi"EWIsOCȒ.Ƣaq鱇*F^KOsҬo%W[$zWn&eMoѿgpp&/MmBUM]PYj-YYCs;W5xfʔ@2 la^ePZֹTn:lzDnkkvxC͌"yswgm~ߞfV@l0f 0 z>J7 @lq:ɩA.FB P>0Z=qa'uhB^Ofg݊ di_zL3@9uKݜR UgON< /_*=U|/bV@/!=ׁksF(82gD 2E먆6}2zM6*I!kUc)DP@"*L4Bm%1]H•ȆC{Hw{{?wp* 6{Ӳ_<|Gvu:-O'UԂ D`>I8$QnʘUvKzW_5݅;'M#@VOW7c=9~ f & YCB\b*,ЉBW!tx7-\NX~%llsPƫM8-Fyyыm֐-HÇ;W6+P Mߡu[Jj9A$v-tJh*qO?7l'L=jpq#oҳ MtO{qCE}MR g:GNJ:~vx-ΥCyɧdN1E( o~\`vCq.)AUl]O9GUFH;Źk Z]iMmDv1׽CT 3H.{>[FPi iښ9'a2pK|ᩱ8fگO\v*BZCV5Ʌ凎Kj[AI5Ž6~l2e6&z5zF@3O3=Uġfp]I˸ pܬISBjBϠUœ=CeGĐ4F_JIq?6X궚Y@4ӬS$(эڅ^<ԦR©+= ~.]L\9&G?̆oc ,aiqrOBI?P.} $εs*7Qo*uڽV 5@چ~2I^Ux)r?մFxvKG[ ^W&ykOOF&Gę|GjnsfEֵ8yҵ ܛI 1 (P=WNVa җڋU[~`2>3Y'JJdmacVz H)o'0CzA'KsXTY_۰$ UQ;q1ǠKNr@?,db]i`sA;~{N8w؊\EsSjT+/'Vg]y!uGܗi]z3e H\ vw86p*mxg{G9zςŬΒ+t?b%)2tqta"i=8$4yhݯTdnysӀEޯf}Kˮ~CyN vżLs*&j ]<609}F`4lݗ2 ӊUv78Vץ +iLY; fdH=P߆~BկDAԱJ]5(Wj\pob^y %aH::Asu{hQZCJ2#!f;@_d||7=Gl'[O|ڑ|6\Wl ,1>D\ǥpEԥfPld^%30JaSQ7_G7--ӃsJh/uNK]!w G5 -h*s6ft , -du:}{+y . t-;jjm3 7TtZB61#6}~̖S睼#ɖН!zBS :ҧ\H&mbfV1;ͽ.:D2,\N'ZT" FٹyxL\M[/[%̥u*ƊfĞؾdF~z@g.aIILɩNΚnX x(kƏ&]gvYԳО"ּ)t3كs^XN9ZN FղVb4WIIR&=~Z+GbTo͡<5Y57{~X!m&w=u vjڿn_3WW,|(֜~Tڵ_ڀ *v8P=?^&rA+k1I뮪gz3 mLf0{` R)* ;NynBpS͟BxN-QgפOxElv \%q\[`սoခa/mZUo{G-{R(M.Ղa()IBx ՚Vqn#ၹ QS%K S%^'%4SCz"XTX\txs._J?QY fĕ#A$/n֝f^S{ tEA֨!IՑ++xL Q{X-ߙ324 Jv$>Qw%gzXC6(xL6P~"@ 0B}:jN1adPq"(BŞI/k{:SNWxWcnqN`ӱx~c-y16Iko/k(_}64i'mJY kHzA'*BťՇOM 윫nc܍-*Bidn@h^рSES >i:dBpАL"F!pJ}!k"/ G^gO[[U?'Aa󠤕uhkϨJ@8"N[.G@b?o̷<TC&_ݴyRtcwv t{AA?vZ/;]C$2L6M#jb}ٖ[p@zts[bw\ݐQ'<)Jsp WēL5W`'ᙁҔF͠Vh`mjR&2rdb۸Xk;.;(b摼 Eu) #;yndx;J,4~"Q]6V|_?6JM+YxyK]32@,`@ViF"°oזz^s}FT;59J\,:w1|'SPD۳#|X~+%ڠq{nPՁd/x ¼{yS9&\;'͙}tsH3n/~Y:]ڸ뽋*/H*GRcR{!Fطc~XWQא9BcIjGz48j9j=Zl)"^V;AyHD1*Ȗ WE"7Sk.i^͉hC.Ò7e5}JvsDAϽy Ni!~}TޤHӼ0mk cWKlkމ4q{ S&PSjjUǤfp{f4I5~Y;nd5TU"6 oUb ,9$̵\)R'@W$Ga ^ AvATdnx*PNV틯(J$_@N+0%hn/zÎŕ]E?4$w+@(*\~g""LLy}:ExL>NO{QsHwzVܳ_Te%`>N!U6Ezd) ޮ?  AwAC*79GyW7zͶ6 w~e!KqJ o۰<@iVK.[r \[x?{&Hp#q Ve.[h D< I%]C)$wR]-prɲU?T-DD0,ՊT%Rܶy_!Xiٝ7Na9y.p[m.G{<KKj`@.$%6M(L^Q!εW62l1hR"+bw{> PBSy310 }ھ\Js`_-8U)5׵:$~@љUWخ_ټڭ]DZrHM;7?+$bE"ױ @lG>bIvp9@k%6ٍg{!/BR}q9Y.*mX\FHS$QŹ%4{%TRM$"ӋPw0@s/7?+M]rя[f[lljliү:8.Xybր)`;\3MPl\nRVw(FjsWT.fq1fL&Y^CAʤnX<ٳ7!0e˭['}N+or^9&X[l(,ҷ(K=BLY5F Ik*0S ~n]9&4<sji®?%gcCUu cZ 0Xgϛ?"eoI~Yz+0j+y6.@ROi>S`q #"l$)pp|D|P{=d\ƒ(<|"`QzDAkOT,C,^R|w-n27?qؘFc}Bx'$)0WkĘOaa*1Q|!Y=p|%6Cq03 'U(4iܔf\]%v$Z#ޡN{52`g:QY|(i]:{\,c%Xw+R.>75UNv'Qz:BDusX+UQEgRCi4JFPǠoJIvť <ƽ~ ]C% ] C3pfeO2'כ8ڡ?-1A[ÀKDHpH a Kps?*aȏb?<1Φ3tX<>Fe8z[y`/! 8%xzwcW`V"+|ǼUN׿^gw!M fSEԯ!/-$b:WGxH%(.gD\#@&FG "}1/aGe'{1T \η \k%H I),RwvgRwh8) ZC0H%r-ɋs%i&9 mP \|I | 0,_DBP_Z.W;`fTȍn1-%UZX !>n!@Og=BA3Hd V`t=q7h3k1"@,ˇӕ[Ck>'$܄3Cyb}/+sٛXD섣_G~5 Xy. ,)Ģ1AߢW;.7R0]vwG.Җv;b-ުCW6lnYK{|-FsW'$;[)!޵c2D') E8i BzGi1j$4ZJRx˴o6p6d&+ 7?}.cEe'*q3474w%e'=[A0^ aHZagnQ(1{;C1]d(rAm/jK2I}N1.' Y9w_IZW'@q3+J<#Ù=U,!Xj Y(eb|l'-g1B/귵|3V XI}PL# ~v W/0/Eӎ ^ȑu p&E\Vnzv2q/5- 0tc G}Z@y9E%;@"@OCx e>5h#_]WQW?{j\`:60o`A-u&Z~t_xHe @۞ tCn aIWj :ήZl$+: 6|;43}N8>F+-ڰ YgP.o2 ?ǴrZ/w>R{8(sb,z Ml/80z|  !,-" R wG3tZBg8 =n{ZmS2} DkwANE)Z_7 K3a _@Qgdr+Ȟs K= ,)}%3IqU-f ﯟPp(f"`J~T#kdi}T|Yy!gԵt Mvٯe/K}R5"f~to_+dſΜx02mC=Ay?)NhZ̓;rZs xf4_d(4 v):<k }#<+GGeft=;TV¯l8~ +X3H%f|O9 $T4DZN"^SOfu8ȽE(vYy') sc! 7$&ZUeؖD1}t0!4)Bp `\ޞ?Ҹ[Jdi~*%Fq_FLq<ϒ{OX ggC5Y_.O랷n)C"*0;ؙV+r3iummC$@G : š޵Fo}QdI/ v~-s;9bKȒjܚo5,P~e?%@{'vVG?4*Blo3; ׬+Yώ: 2``0Ѧ"_w|̒j@b)J*"$54GS2QK9R5zkMCr06 2iɸu&!q/St.]SՔ;.4MYB{C\ Ӫ2oj!!Ч!V~dRjqجw%cn')duG'!b{#얌ɟz$3wGA';@o9o#H,ʊe&HEϜs?0%LG4ȗC,l~@j)O[&yo  Gtr0qL=79IiF|@3ň0avXO8Զ}'G܅'v, s lr xLv*ǡk|ƚ-o1OX,m| SaUhKM2HDyŖC@Cςר]R+>7^ oA q@FL˩t A@-[b!O;Kt=X{oy1Jq? +ӖAyz5Sƺo`-*7d*5g76 }CJŌLt_ ,MdREd!slG>q/o!a¢CxMz cj%o`2'yV~L#qO̎$jwZ{>A,W,j&֡9A .,P7"uVI<f$H/z,b6aUD JHJ,z`mm}4rKк4#e!mpC4#88G@ ͛OSggtU.} fUcx~|kLzٌK\d` }%Vd[whe Q\5GGvuP*%ژFƍZM#j3uqu)h40A8WPXBGe|N]*8ND.Q qy]E)%k%8\.HI绣,f,Q sfg"ik;Ր[8I֟. 2^Y: 6{ϑEN!a5`S S762+~'j&|i-";!d7>l8sjþSltFKMU8#ߓt6u^U&Ra$/5BԆԙѿCQjcZhhgD>բ-~x[V@˗ub1#1sR?"( mҡ4Xӷ 7u~C֟g Ky-e ݊O +8 꼤~tUa>J4an%h܎(ܡ y%X_>#E_ߕ?,v(A>8" ]jU^Mp w&~DeXxSjumM,MoU]m]` /6䐹e+tKg# QsNPpĶvm zVۯљdtmkuG!UeV ~FF2zD`JD –&H$8_,/-O}7͠>g'ȉcynʢƢ{-#rA(zW`y!+L*Y(6g9f Kj-k{H_zŅE,r'i٫E9Jww\Xcpľ *#gEj[ts \\hEA*Er: iԧ뫚 sYwV*" _`wcǣa$s. > 'F5v ,܅Kp||,w̃SUni_<"g? d (q' (=fY_MGVaEO-5w&"1We QpglQuK)3+TV9L#Pɺ4]u8s;"u޷,uJQTGb?gXl=J`1\\ebw<Wt*9E ~]L./m UT'bej=J`q@<@ݴ>2]O~B"HZv[e޵<1C.e? y< S4HxImQ^%H}I2{=9{gٝs`cHGm,̂ώOv< <~e pXDm/Z||5l w]Q2 0 .n'Ipa$kcGgwQcd+څyT28Ib/O B;(WiC4T=2ZW,vPYuϓg˒aZu*l6ݝ󾹰SmbE2>9s#O!+$ YL7SQUWu0(YFzN8pd hZѬ'w =$q~pjz 2 y$瞙?p"*7ZH>W}^gڭ^;x2obWp > stream xڴeX[҆Ӹkp 4N%$8݃Ckpw'pȞofs V֪ަ"SVc1w0J:\ؘY  6V&W;k3;3++3$n pZ\W:YYyR@i0(]MԽlZ@ŕ YZtK-\'ӟբY3[[k  ˬ Ptx7Zh@ShIT49::815u )FPSWzoPTg˟g܁.6we/pvՑÃŕْ/}V.g[3Wc@t+=[A.?$ow7ON\*ceZyeey52i%ssvSC.tQ'ӷ33x7f kWe,Ի3k_6EI 5u&1)8wW|"`gg\] Ÿ[ً-AnȢvrʈ_ o% :fV,5+lMqtpXع->.&@矎&6nˀ,2+cJ~F@v^s8s=:a&v^?Z?RiMg"i 4Wv52`b`f/Ɵe>׏?4]\\G4EATNT]( 50qv6B`}vNNT= 3} `gG8,"L"n`qX&.a(MտEoMZ4CZL /?^|`|W`|`x`h#f|rLNP]ߙ?'ٛ9M(.?^㟩ŻŻwY^wYk9W_` Բ6#DSNa{?*@uբ>LlpR\ۿ=fKf6+%+xO|ԖMZʚ /E*j ̦.v3O jSb۽|1W6W'DdVX ";/)nKl#hvt?ƲO_W~(֌lṈFI8 c'D?g\3& ۍː^}b 3}q8&{17Ʈӝ#o4^k 6A/g> 'Yٖ"\΁LJq Sgkށb+s=cbHAOUv0˧~7q&4=~7)r6)Ѩ b t5- ԡh?IGok%oR2YQ:kIr`?iJPUYiڍ҆R;r9Fcmt? >I^"/ e=U0knE>NۡZtƼS5̬@Rk$̖.lAu;@糟J7Aaʄ7ޛ|ƒ? yc FN;*Bq&ZQUã)[9~UfW@Kio6"qtV47P¾R pp͆:_,|W qpIUj6Fd;GsɊ*SEy5LJێ;xAEMQA^$3 љ=f$b# t5s,{k,: ~܃Iy5iVZ҄= $/=k *ȳkr18sO>FucknC8_ m>sB&^+W;y%Zf*h0D'R$dZa$^4Fdh p[=lN:59xfXuX&GS1ʖ&a Cj{AM2 AIBi-|Qs B%LLjr]ITJ#,)W.S|Kr_RΦ‘1}0h[? 4t:U 'ZHxv1SYcC@'GAݪKO6KNx#[4rlQCv/圩mSa`bE##Ƥ Pj7FwobUjEDžSk=BAcy[ +yj_uH_kɣrn@g1TdG  |+T#Ĕyb_5lC5~)"TzFf-o=y#+C0jK0I.Կ~9]s.lsxҮ!x;r>BЄ$i36{I_HrJ1/S'KE<@էG#G}JY8 'OPLa겙S:c¶LǸmh6#g>ച3liϿM$~]y<"u Dh]k{3j3X'[YC腘٣4%Rgɮ]_xirx1L3l?EsHV(̳On7wڍ C8eP%F-+('w8uBSe@;?&őY:C'JT$sC#}LLLrhÕtHFsv01, }yC79AS'[f.昴铮;N*-}D/5<>c塺u`|UƮIxEla\Ϙ)36jD5&}16BB]1t qDTnygA/f^ JST6|:ƫACo8-[8|MpSF% W KK򯀸 ]8w_1əʘ$I!UZb-j5\64,AƆƸ!R+ ѻCWɟ/Pwq\R߄^`!QĂ*UDZ)d$"@qLԩq/_ȡus*U%,}SfrѸ%d7E7}䡹d8~H^z u.wR37l5i>30O n)!06\rtUGs1#鮅`",-$@E~Bcf# 2M%cEs plR)z|9Zrdn[ξ\g 7)fW5rY ᮣyxVFSW<;SpV6779Lz\B tsW O}?vAI!cfi`Bܵ锻'_5VʜJ !+PojEZ TgPCqidy x;t.&N[ 5:Xޤy8y-?#~biRDh!h DU'LUMbCȰPQt?U]&@Pe`:|¯G q)sǖ9B#ϹǷ:SPz y pJ^9CIpN2 J,hV$o&:8sd$4V!{ %08<%?Cj܍Yt URu[eSk.i|٭>Cg197*=4 {]ݪ{hV[0RsH2n 8d kdc]lyA12E;Z2؇mnc97 M(.wywIq&s`kHrPq1ȐHЕ,^88U$lgE; 7TkJ9țf7\iy 5L0| F./t?MV;x%xEEy.o?t5X0IYf¬z7[#X˔V>nힽ"juJd=}҈dˏǗHMQtxTd$+S{jT܀ z*'{J&Oy.9up90q:!T躹yIY/P3[pjBYϓQ1~\'0Gc1}$$vǀ<%8$x3߯8ϜxdW4r60S+/ &Z Caj <:J]OBq\C?`׵ךN:@DR!p_ms#GOCiq -GI= -% =1zk}@2l5KorZȥ3_~7)y֑-mǛs*VfY7,n%n{uZi#Ύp=E{|ӥS5ДOj+튺]BFssקhcCf3kN EBJľ"g-̲O4)} Iqs?XvqNWKLsn۩,:*!kŇs9 f AP.) ձօ)M*uğ&]DT:K R\6^˯cd^?ݏƗ<h@-9wDJeQj@;>bGbCSm5+7}h5-` lR LA),|~ƣӹ/?Oυd 7IaI0w HR5^I OBTSxr/1!@hNSqrŎgUyNyp6,}'׭[KnٗBʙjzyyeKs]ʐT[/NGT.LCAI` sUS'M& ^P-71ѯkAT3'10LJ#`*w6 |2nHd`wi(\]}o4ЖTaEdENzA2H{ZS2lw.Y$u ǻ](<3ck Ǚ :71zu˱Fu! E&e&|+럱tk *C'r0*!Ĩ~:6DKOG NaOFuؒy+ѷC,\0k j_&GqCHKOXbcP%nם{]E괢-:L ul,»f_BV|&)Iu8:Cى$1A_<J[#C1RP@q6C/l 8ǔ-Ue0gzZQ+>RTǗuE~aHb=gPݒDU2Vu!l`e[BSa qf^t+Þ1O<{GiAs,0V( WyhcB]x׭lA$f6ECJe+Lwd&6.\c> xv=)Vc ocLT%6"UP89?)"ȷJ'' c#sTԎ`Q &n2wϿ̻{;&NOckV.蛤 `آ|Ֆa:em+0 od%Ѡ b 3z,.g^-'pҳ0"GȔH|\NB >$Ru3L-|`JV􏢯NxQIaZŜgLHm2]?XN&Xyg@f-)6-ү:}oA$+\1UN{} %uu\)0 [si%TݪhaZפ輦!/S.\d+xכ)U(GȬ.Kdͮ$CTyf?FgYOR,YıEjy̹4z[>Ap7Q PȯVо=>pF*mm6L]CNJקۦ@vOW]@YUai/e;py~`<pcis(`pԟ7vA}ߙ4݀KI&@8El P"cQMUM{L/%5r yL=8_-13@1v ]tS8!x49y;ssh'ޏ-s??6(hG? {v ^/k6YM} C8g֎-NjaGU 1Q ~3ds\>ҬyWՈM݉~\hCZ8O:ݭww,=v [CrWD<(1@oL]@@*iB0u{Yy )'ͷgtC-7OgY?&Р(V>r3OV+`D MLjJf*:*S  ƏQ26lb-w$2fI`+|y0/iBF\S?!hjS 54O|pMIG C hL$-}T hj1㒼Gœ§Ft6 vX-~)OP+-U&a@'YuN<!岲tdxgV <)O x0/)9T dM5qTx7G1<eCG>$RrUc]d\ίXB ͤ˝DC@hv1;9)N=7D |̴=$fSвߓɓ~p#畅qٵ-F{~PZgC zz2D=bw4 xU$'W|kTB;/ZFgn/K.y9'P_~9y іjrN ߝ/R~, s?:"4 Cwq;dQ+*q~|cp8En@?bl,g,^d g}

Y|^# sOۻA玂浐\s5+˾Z+Z DߗhRJKu؎LbҊe^)b̖PZ/t8zJʹI}FF37B[FþeE!?NIeYsg1Ar+f~%}i1(H:S R!Y, QhyN oTC?{~[M`ƭ_]ˈ%ܸF-nVnEj9 vWokv]cKJs+M1?g M \YMڵ(X" OK1A\Q[q dޛ̔U,m H Y7QV'K :LlHָ_KĭG=g`UA|&A^JލWx!' m _Ú,|c5!shOmТ~iU,ۅ-[O!61 yAu?hۧϣLhY "\m׏J$ #&[E~~1Pcm"x K:yi)2WVfe3#tR0Ȩ>'2weHrN.SQp/bMi8rUcA h}lIh8*wpsc w.w 7 dXIgC=Gxy?f{ j^>b=]`m'Wfs#C/;%SJ- (e( Qn>0cJ^:H~a~<NRTD^UL?Jg L44t#^#_ο2<+(Id{^Y|ZB]mҪ3ۑZpdQ @3!˛$F 벛ǤrrO+s4o=?iܐ9uHQ&R`3=G KʋzTuC'txORJȤ_#?^]Ar9"ڴI^grK7{*Xk$7"Ds/Rjmо{?g2HG2$ ֺ3 F8aWFGE{)ݘ{!p9lVǴ}9)|?T= Pb-G[_ѶƇ]{YEdWLIKlc!ϕ'"3 ֨b#2RjX̌ۺz2m>CQB˿d{ ,~ď$(Aga!\QĿW3 Lh pvc0 B>{a~hHBJɦ~lae5b?ow؊vmϪ[0#JG+?<5\(_3Wz[*|U/ń:dyߍ=)'!28PC@+묲b8||!ߑH/b " H8]N} Һتm`O,lJ?E a}wUu+aF ͎yv{2p+ҹB`Sxd~o3çY4L ' xPGiO\H\QҕlWm7s,>qg;Q:rڃ(W|M0)0čM$1?JآQy!2 Gۤ?Z]-oIԫ36mZ+!F!4h-Jzwx:4"A5%-󨍼k~{")3-:gTn/Cd6l7M/ }(7ٻc!$T2UoBӗ8a8n_[= y(rƌ 1nRpmGRlHbB1EfmlIJlUQ̨T7FRwZ槎31%dCB- ri|I]_˩f&Dgk*tvcn[RoVRU .OeCg(b fa%Hy syc6$Ph{d-yϝQ݉p*lj ʩoLn͖|y+i22j]!Fobnϲnu@J<8߳h YL%gUvzncnMpAώs]u%({x+<[Ӣ8}*4s{`fzq6z0|{a7ZnZeV1B>ǘ[rUIXw4 o3)ƸDK:l?Nopd]kb9L^L.}e! "9}9+9ݡͅSBj*1z8qou6%yǧwyBȬqFqj8h'Ǽ}tuL#6 -1+AD>>6h-\ +g)Fl|Gz^ioBZ>?D7=Kք2p77uRЉi]fw%p&ؗ3PЙ:!X凊r2Pw]""L> 1R}wԴz쵩d(W@m]/:}۵Hh%r(&0bҳa*x4wT NGb`_Pw̥nŐEe㞒`.#/GݍyB4Y[2&.7ŧ(9W`0qf3Z0  anv NjPv S/Q~r\ӾoPӗEӥuN=yF7nh7ۈ^qiZ53vڐLx48~ FMT\7CC`=/jih7H!=%5_A龴uxݛӛQ]k/ tB8}#J^Rvxr-;iNH ꏇ8(-{[Q]sgeWq?R(u3;/o=тW4}l̰6}h)(eiEcMto* &3ŠR *E\)VFV?ԿL;fM]@%m$cbl*'!`sos!44Y}wwm)# 5KxM" ܟtW沛1٧p #v<"0i!z nxdTl܍_2ǓwcKuY__kE_":EY5 ҿ&˰%kcyV|QM:q檀<^󸼙U5ůWK*H.:$ݑ\cJ9(MwQw+&fnm즽vkǸ6(EyqPخ gD_$͖*6YC۴6 Opu# n7?K 'yv7f/H>FH4V!Qb^5wQV?8EZ3av]4Z}|~~ǛH@:83OJl`NIL7^17,N4t_t[['Ⱥ5Z1Dnj7_ʈDK`~k-6~"ҥo Fldz8o]P\wS*~ *{g *=_hZ@yDO׭va jY5ԣY_l@Ɖ&oBFپJѓ=BޣĬ/0"nGketNt~C &C,o>ޑ*'ȋuXqS9uoJ7SOȀb'aµ4;vSudYr>MjE~J*+@[ŪфjR7Lู:!x# i/?=FhfƄq 贾J-$f- C_go(g(ݖOXAS !K O8D9a3^MGB#Oh5 rn/]% }yyuO}h(lf쫸Eb)/3c> ~l, uUJ$4eRT=tYʡ!,WH⛡vT#`83/n27l̔2e:Ak@ >j ܸ_ʳ|imPx {xγ*|~8r1L[iK:>%WsTW̶G@ϡ vd tF_W`P 8T bQ"oxZv;&?Ni GʄUIT)-FV cTB8E%U.yѨ㩃`7w(pbA/$ߘĂU4&yg~5Y֝1;>_`9 ga .Fc;b})/U#4'9N$M42?۹ʻ 8]zrtqp*晅- GwVU+|l|Y H3VOq.w$i*g) f3AL4x+F4l8i}y)'7ƝjBX,,<=pXu#/#MEI'bxJ_x_ngҺO(Nr^a@c=c綖ytc,!5H8qڿ Mp:%-)Zc~.2FUν& I4`D0#EN븘x*:wGz <͙s]||s^ǹ\>^{3!ByX&\)Ӄ\:W#HwM6 *̅-'\^8EeRgrp E:|ᇊRZ#?ڀj!ͳ1n%_BYA\VSULͮYt>$? ׃&PN/D8 |2Z-G|}oJ~.QP/^Z{4}j~3WaËۦ8u]xuc=),tޚ7Aqm2DUI%->0I(Ѱ~6d-[$sŴ&_ꅱ$J!M:!LP.#$;rIZ YdUиT&p, BVR '5.V@|pMˢMw(-Rئ3 FNa(U u1:6Kfdtf Nޒ7Z z-D^2'GO rw;H9(od0xKL=LZ(|ƍMJ n&[.i{/ ki=.+2&b3apq@Ps1C ~ooKyz׵,P Ј-&r->~,\ Bd[ovwN\$ Csqz>/^a(`5 aqZ74kl#~G-Lnt[I!Las_A #]H4jcŐsjO*oY Î#xHuL}l=́4 XxˮSV-m&M6aWDzJ,9W4եc9W[>j8Yk\JZo;`].,kiTEL-Vߺ^j$3V7j=q<<­Hz^3AX\&$ 1M3Ox& ,݈p^?c;78T1mY Ze0~?:'Y kUetVա ONZp iݶG֝Twɡ4a{!-Ӵ'e^'yW1[OH;PDz$=Px"ŭfc2W ;OЋytC&V{c ?7+ǧY'|Wuq Ewik`&|5-JF$7Ț@&pX82Lȝ% e™1޺{:SbZfU !u:s"z~:ޠ;WGΈuW5wjkUH m@d~쇁l2hR-Gnl`~Bhꣴ49W#tSJ4D8{tkchC7sc~ݡ^6)} `Pr~SSy@QOeW< ~ ] &)ni6%Ld73.|Z7X{iZV#ުYfJN2"#O."sH *$74ʽ81*8E;'uޅ+9˟?ȉY4,[7.b^jM <%BdslfWj䭲S{m!Ã, kcm6&0 toq?PJ[|/SFM2n]Q0KKnϯx--WaEM=~vOmЇO(Ng">t ~<9u>&+dXۮ/)g{7@C+i @aaUEN@z+#~R[L4 6s'f5O6I$3/qCoL[=߉5ǞB)*OU4CnwG$1`71LO밗/K.wVNi _ͦ򖙒/ZfSs ՗!\JrLnBCDM򸎚B37c_UhEϗ%IwOY=H^Y<%|{?+;18:<ߴ<8n7bɶwhHeNbZM.4ȫ)@3P%ۿ9vht"JƵJCX{ i\ɡFlѢ!LFmfCf/tQ0v'.UoXRqaTVSSV!Eq68FXΎz5mp ?zSaECZedt= :&698jlF #e@zHs4ȉU)'sWOP:3&4 sH 8cruZL<聮@/X#P1߽XGH & OX|gqMKn{,mz%8V+fzXNa7Exsp2PL"CΑ}zҢړ{̅sam;㐴͸s*RN5ѶzHtT^ lD[öh6vxZ1ސy}2Llj߻[]([n$È_b}P_'{M%8F> endobj 2 0 obj << /Type /ObjStm /N 88 /First 708 /Length 3886 /Filter /FlateDecode >> stream x[[s8~ׯD#SJ⸓uDȢ"Rd~~$Jl'* s?$-X SY&r &ƍPLӝfFLfd2y!³B;&pd7X&AOτT)LKЕ@_ {`[pԠ@ `27CP{ q5j o#|d<AuB<@DL1P I\gEiX$)&+-sv,D59yT(JJ[!"!D*`)Vzq+{0bg  )iV8U5kd {Bˁr I֞E0|;r9T0f 3򾄔k ЖHMPF4ĉFPJBJ KH/QVnf!>)gs<LWjJj.S3SsNP] 3RW=Zccj -appAMc^}٨Pfk-`ҟk\dnj5Z+mGda~m^1<Q3Y"fW-0+H  y<0)؃٬%cp9l1vy҅?lj }wwBj1VeR0& ƙ[VOe#sV7~gX#=ALf1\_^|wJθ#ϖ>0D|i$,toKJ};X8;bIB9~^=0. ԗi~%vJǃCƏZY.Tegn.c#}l)6* (P'q`ӣHd:D1EUv f08(;E;aFKp/m Gr>&0C9mCHe2Z-Zf*uf$3}"B i>Jv0m|F] JQM15q^-d JKk4(eyAsl`I5z\ٸԳ3*i?{LVgfm>OO+EG g!ljZv54оmk~(/+^]b8V_yWO'(NjfO`RLj=>[!OSo>FNz|9;+ˋixs̪|\v^~Nyy EFm`eU%[{sy7Вڦ & gәm jn6C~ :á60ȰΖGZxBVsUwrX8ft. ,?r7l} ݕƾiuYLm)p(jmJ,PHݛwuq^]4mENYͪc?lMyw1nѺd; e$ma|Rʩi7{U*e2џS^e*M<闰Cx p*,󐶀pB+\Eӫ^V=:tb`ܙI5`#[!|2!b|O DF V}2z%vM7G?$5,kGzk\;|t< - VY5f[YZ8 Fc/D`%4wןpWZ$2RrcNѐr)ʤ.[S!Al {¦4p^rPYA7^D4yaLk6|;OĐF]9fgӊ8Luůo?$$48/tX;^>^S~Z3^)K~ɿ 5{?Yߦ'z_ޤ#=qA-.^?_$忬_>:|7rZ.r?vP-H?kot(nz+t?D A_"^78i_o'8 X=fc(m 7%l8"蜟W39tV*A;sz@BcoHͫEL+oe{Gt狪ݿ_7ojl}^vnON`>T-nSmǧڊO/>}Mʵ{6R}qomFh:vv7f%{$c,"~xC<|{Z/Y9KF* PE 2 k3H޵zu:bÒ/gjюEZ#[F?>Ye"PXVXlo]fkR |'C{<آrR?&ݼ6iqު/rvkl2lyqB/fwJvE<CNNzW}{]ã߸a=[7< UpFf_m_wSfq͎etqi<94DOw9f6>]؈-D/2M o[!"*AZ(^h$?Rҗ^NVʦ.y7/w[O_(ޘ&L7Bzҝa]uuT TmIOtG0\ۂɍ %ٶ`E+{'XڑKʥ>Oko#֕f_۟ aG+?#my;b] {ϋG˾dtJJFo[z] vՓv[t+}ΑHӝjM/I@ģOMdֈ+ r">["e׋-b³ђ/ŬWi5ki-T>JmW.!}OV7.cxFy5/]]tT^ԳfTɨ^6!}0'iv$hF߫i5]9Yu#.z6/ j!}k0gӓj36Ov4]]-½ξw{=`zvHw]qZ\eI*?U;C A0 L3uC@zْٗm!L&01~/'s8-< {@tU7#}Jy6g֟f $zVh&Vj^"4 endstream endobj 108 0 obj << /Type /XRef /Index [0 109] /Size 109 /W [1 3 1] /Root 106 0 R /Info 107 0 R /ID [ ] /Length 273 /Filter /FlateDecode >> stream xҹ2as!_$b_ ۗ$$](htJ`Fa4DPT=3ͩ>q^[(@AN*A-AZTķp {pMCh*TbV}WmhS'l ]*-_%{kc` 0R|wI mӰӰ 30 s0 KrkVT^?VUVk/V՟'uu7 u@pjE(9\%+͝" endstream endobj startxref 222085 %%EOF alakazam/inst/doc/Topology-Vignette.pdf0000644000176200001440000103751013513671743017670 0ustar liggesusers%PDF-1.5 % 30 0 obj << /Length 1970 /Filter /FlateDecode >> stream xY[o6~=@ő")J^4Zkz(dɒ+i_CJ4m.!|Jz zOPy_BꅔDQ(XBTĽ(I™7ͼsHL?G@ȟNTWIF~UT$42-M`o:]ha~[O 5gp#I"ehOP 9,mKMlUŁ%LU. eO$$a‘ THYP0=&=  8ql3&̲tg|JW͹m 2 $w$*QL0pzD?+"eզm^ 춵BXQRAT_mV?ϜeC6,x զ\ V7~ŎUt en蟴(?>1=OQFh-1O1AޒLAZӥ2N|Q؛WK݊v&giݠIkgp`yk^"znu_6q-m1mnzr1gfgmO {23bG)ICbMoTMrr]pu.6O0`KC$m$:|f;I]_l$+[, cvfǼ]"w!WUe% P:9 XL"OP1>UZ[lJg8ScLfZ[n3+ep G:,O"`: `'i?Tu^ Cn`5V^ f;S+ {n6*)rmkw>3ƻ Ҁ@BN97!Mj)0cWϋӘqP''?27\[^TA^fMqK !8fTul1+/dBb>o'_Z$!aWfՉ<IBB=pP\}o1Qqܩdz} IIX̺&<:bE]x>.s).꾸vQޮغ^R&$FĨ;.ߙw\'F6,@/)b͕|1ȧx3*$Y()sR4 ʭѤUK.FTg J&~盢3rc$6S,_`>Eʱ܁̮5 j+8aKNJ 1XUcM8 2- X/hy?MT CH$ԕiO@ \o6li}n~]y @ƈZC'sYCV B4JݴkE8@FL QՠK*j-s \}7PUasZTɦBn,Dr|#x8xhz{~ s8Vnuwt̘L\c!ttU> mݸ#+uah#Wڴm$ ^W@tPS$ ea@|dv"r~KJt#/n?)[9RCҖpf1vh!vw{6% ծ{`qa 3V&uD9xVgjL6}wC]ùyMs/郿Ê endstream endobj 47 0 obj << /Length 1591 /Filter /FlateDecode >> stream x[[oH~ϯ`xE u.̦# zfPӈh{oYoK r,]9Rޝ]>V|r.Ή֕;o X($̪8ͥ'\uoߘr{:]XыdĂ+CW .LS#b(l`!PA˰{bU560d쎀@Θ+NJUxELE&RL*f*b&i{-B%t xONۆޓ{|8³Q<`'K;H%zJ T*^j:gP޳|Qb|?x>$,4&vPf] Jmo 5kiH!ECn]8//N =]j=Fq$X]k.!MK4]wȴM <7{Mo^Rfӫ>2=e6>We$5΢r4}%{2B" DyjzժCSi_pķK/"';] s7:hՃrB=j#VŤy&!}bzy3OU3dUԛC2o21vI?j- Mݮ΅OBWL'v02卬1fcNJԿ%_sk7WGޱxLEyEᄂ%5kMrH|B݃hNMT[vؤX8eO̚ T443S#>q7U@߄lʒo[lJUUL&ey㭆~bgؖoV.מJS}5R;QӨIO(ѽT2щNsb7REk7Z m7g rS8p0 ]u0t|?Ď endstream endobj 52 0 obj << /Length 1368 /Filter /FlateDecode >> stream xڥWKo8WEbO:!MR7m7h]݃jӱ[Jh;䐎M^̇pfLۄ& &,y"3E(er79ڱ䢙|ZLN_s0F xX;R^DX%_ӛa+꟪DҺ+ǻspfiWx{ ba1"K$e$2Y@V)ique_55Wpze)lzYt}bveoVx:Ơ22?)YFR ߻5E@qN^i -ߚCoޛ<0L)EziȘbN3"Ej} lDVKA5A*ṲȉE{Wj` f&iXAS(C$|$YA3p<6M x"AMH7͏VWSn:$ԗ' d@.%49E`cxFHtS0BKk;< 8ll6.8<f~^s'%dxwW7˧| @i=rtB TF I D|iLOY jƁKr:S\U=-n׍B!+A4AJ`pT,̘S/( "5?p޶c2LpD7`J6MǑՙ#q鋹//"]m歎q3 \ybba ҇2S4צm < vqs\ͫ_T~% !;bH="012VO{ 2H($c>_ͽ%Q2O5~L3)MGyX;_#X@&_|aPԛ9{Ju4(𿙤d.v=V#Uĸl>DUh)z-ܛ_nkr;oKOc%`/X-V|= iwfU@>,Ls3^KElaܔy{Dyt*[d7,-O٢;A 8l53t۶WWajwEl¨釞ZK׼}\NGEDz V endstream endobj 44 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Topology-Vignette_files/figure-latex/unnamed-chunk-2-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 59 0 R /BBox [0 0 404 255] /Resources << /XObject << /Im1 60 0 R >>/ProcSet [ /PDF ] >> /Length 33 /Filter /FlateDecode >> stream x+2T0Bkl˥kT endstream endobj 60 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Topology-Vignette_files/figure-latex/unnamed-chunk-2-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 61 0 R /BBox [ 0 0 540 288] /Resources << /ProcSet [/PDF/Text] /Font << /F2 62 0 R /F7 63 0 R >> /ExtGState << >> /ColorSpace << /sRGB 64 0 R >> >> /Length 836 /Filter /FlateDecode >> stream xVMO@ WjqǞ+E QRӲE,Rп_{@y7KN~v}K?+ ݇/LJpt9LyqYVs_8NwۑCO`"X!傎.:)?ypJGEV S4H58E<:UuTJkF1!Ҏ?cp# 1{a$hM6EOS~LKSY10ۓ"UԠL,ְ>.Z,*m v{n$ky)69S b7bckZvp\ۑqn@SSo^&)]ƕƝ$ VBC{n)^O23yVݼZLl[2 M(A_L^2FW8J'hj2|d._kcHT ӇR 7E˽{}+qGYz+MrU"B/ș!t7;1&b[B͛!eYIt@8*Ǘ{ǫ}8ko}~^D!H'7"zxX]DY׼m/qh{K: endstream endobj 66 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 69 0 obj << /Length 1991 /Filter /FlateDecode >> stream xYoF=BpVBpq-uIQ0H"@II}(MJ`sx0}~􂁇Q#o0_`x !`c38,1 >Y~)8(oWqf S&҅4?GNi+=zHT>k r?{ z}Y Fpm "BoK-+-h^gK٦b'`fޏ8b\bzB( 0 3$[IpzC|@o.! <ȜVJldهn']E Iȟ0]yhT_&o јno8cȧ<$Ͻˆ POwn Iؘq`0&p0 MDӡ'YғÇZJOoR׭{iȹ69:G.4֢A ă<pV41أHSm\߉lUKz%B񪈷s#KkE >*><޴ R>uyx6&M2q܆iz,"'?imMR]HvolXPY?*n.O~ۙ^^7o5حǥc[ 1|6џ ]0oׇ>Nr}'6mQ(5gIV#Re9!>"4切].9tX>WB1%T(;$Ħ!qG80yؼ;%b(h(wM\$V/rݛ$ )HȪL er !ӟ* }XfarIZ,(-F)Ieʄ+=%Ky9W7F$o os*}ァ vzh6VgPm@qGsշwyy3D}GwPiØRg}k,DSه_痓ݤQ >-0B[ 0 "^h}N%p_pb,/y俩!mfnR=P D y_NnW uJ[@ AνaU2.=BhĜ 3 ps2{_L%OK1:b2^6Uu^5خ'Bhgm|{ūν^3Fqسf&N!/l@4_[&`pPyH B=wJW+^yTpoBYeF;efR7tL6Cb?/>:*^&ڧ^<ʓ~=!OHOs_>n}9*ҟ!]z(nVNx"Ĭ\ܸ{E>7s6xս LZrO <.VIuS}O ke_ᅐi]=l=:fXu:G7p|DCZ{f' *G EJs9>)man%hfJ&h]kmPҪ> stream xYYsH~P9/R%"s['Vde}DMR.,a-*@3B\@`cz>-!վ2Y #E.ny-FZ 2a4io?yZj3Ϭ #/%vϠgӥBA|i0kP԰LWutPy)ЧlRu÷~ Xǽ>y}?f-{@ ӄL[)K!n !ȠĔ,0%u=1lj#»ڸQe0T+xJEB6Za=֠abS,  ԏfjBmgG 3N'w{j8zG Xv/Y y`\uTj&4R?&,TBZ9y3Ut,S7'5£ 4gK : QD6 tqPrSq/VD +DC(r=NHzt=b|xzK`.v)|Dr 2qAc$9&q(ʻာ`S e&W"X[2],q٥"c%&E+hWT^26KeȖ(2"REoQyoGu=xB\JOe,&\AJ>ay>ɬ>ݣkC>VvSbLSR0`Qix$f:䚷n;Nҹup;LT A:+$_6 xb 9ٕP(si/0*Y ]_ xf$ք寗[otTXX!:gd"` J:|z[zMe&[HqQmDpmS70 Lf1],ssfҜ̊@0|Rs" iPfjyJi; e˾.L^c5)g2/I> stream xڭko6}XI= ih0tE K-LTN#EIf0`~ 8`X}ƝK6tbv6 4Hv$A! 7hU6UY#Vlq7K Brײo]+ϋ? {g狿?Y:AD$<*'1:.Zɛ_rNߝ_\>C`#e&++YJ~QwAٽJD]Ī3,2^1q_D-6|@T?t 1&|LMg4 9Μ&~֤kW.E`Օų΋ILaFѰhɾtQ ݺJt,m }4='du30̾|y88Λf'9髈r? x0CV#,7g d.bV` ɲq߉Ju~j'L8-o=]hBTeфWסB@F Go6HgFP!nZ>k6rSY A[XSWG _,T,9Y&"9= ZUw[A zP{kH,,6Y{M+Sj+lP.8l2[VXYKSh47unR b}(K\*X9TjhzC3J$)ѩV IܦTCT_: M odST|6 ߛGl Ų#v VR;/0X@%uYਾ`,t3%]v"ґm:‘*J J?vO4IXłYx T`ޏƪgtZWtkK-mAF:b͎T <CgyܪۊW?fdRXRWy- u`V'W!j3_O%>M؃=}N>mD,Gr ޼M7\خQ2r N"x|88yOch?{ƀ|z j`]pCpAF@dn| O[,J endstream endobj 77 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Topology-Vignette_files/figure-latex/unnamed-chunk-6-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 85 0 R /BBox [0 0 527 267] /Resources << /XObject << /Im1 86 0 R >>/ProcSet [ /PDF ] >> /Length 36 /Filter /FlateDecode >> stream x+2T0BC]#]C3\.}\C|@.Z2 endstream endobj 86 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Topology-Vignette_files/figure-latex/unnamed-chunk-6-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 87 0 R /BBox [ 0 0 540 288] /Resources << /ProcSet [/PDF/Text] /Font << /F2 88 0 R >> /ExtGState << /GS1 89 0 R /GS2 90 0 R /GS3 91 0 R /GS257 92 0 R /GS258 93 0 R >> /ColorSpace << /sRGB 94 0 R >> >> /Length 24602 /Filter /FlateDecode >> stream x[fqz߿1 !SbdȅmMK$~!5%iuw:׏_|_?v]TO;?Jls׬oĿ~wo~wzO}[7﮷|_IGӾz]ޥ׏~.]5[Wmە_z+^3'ԙhy+9Tۜϴ?uǻݏW0*%g2u3|Ku<:߬(_>rCWDVK7ي8.m >1]JCI_W?o$w㝿m} }Mx*<iI4ZR<ǻ;-)&ކvZ|< X/i[/w󁤝;@^ҽ-oZ6tp~uspAq*G5vޛx/\{IKqВ۾^nǻ;-9Fzix^5ty6 Y{\m%}q9Cb<+=\/zmpI^%Ʊ@v}&s]{k-pޟhQ)C[c@Lqܼx >dr7 /C&c< }~r.%AVڛ %}_ǵއxkKr !pޟ--uXжNqP ٽs嘡Ca].7}}.>}n_[_:oc@wx)=屿h6yFMB5@q)6,vv1E~st.0ok\SOɥ6=SOp\צ'M7Г*x\)]w]]|ܿ d޿ܫkkw]gVx=.>R%_wqt{gk.3]]KJ'1BW:dw=x }:v]1COncE-_Mw%Mƒ59\{r,I[&h~oCKNk~c#JgnεNLqJIYu]{ҲmaƵ{c\kn~C_׎׮_sv[oo׾x_h3sғէذ|yFLFq_c;/7SnM3t?_ZF3v=y]O:d6P#|~G=dד;Uv͹?ovvI>hve`|m{hd#x<]t0>: 1W&ma0k~|y^>f+`.m}꘏ׇ>_<\}x^|:F/3zoČvpmIU8t/ԅ#5~'[=pyϯ_{*exo q⻄}j8Vk~ח?}7A=)iM_~=W?|}wK{ʷ]-2.jڇ^]eh^-fOzWǯKh%2,`21>11kAYӿ|<AՓAz_7'uϬLoWW?>6QKvgQNd;~s)YN:/$I[޺COsXp_ju"jAV֎'jk~%R yW P5&GeHPŲ"?}?x>iH3jI\⪯{Kg̎3H~P:ZL|ۓ/ۿ^o!X=a GC{!?v}ۍiI jiKKWQ$&5<5=a .F-.sHj.5 ]n36v{^_^O/-R*@AL7;&E6>ZH#ܝ 8l&dH\tn|-;,;ngq@ǥ{{p~KGpާ䚏|iVЊ+iq_o>PU*'-7-{6\awSs g1j9nD%8uҴQ6nǧ_L0ß"?Ok$8 !7x/\{74+{K}glu'[ĺviV4FYWcx5%>nyh<&ӯ Ԩa_TygD˟.y,IOdǥq[mwlkA39e86jt,{nni|fcNtXX׮]ҝ`ec.QƊlMq.sY{#EVƟ?e-豋x-]'3j)K[v>QkR{'0-dri\ZJ&}n_/w٪Hh`Y `_m+!8~- 6؍?(ğ`([JjUiΰo*]PII?UvRҾ]4S/nzh.6$="hla4(Fa%Q`PeϪ\s5VG{Tj)^qR"3ZCҎ't0|3o s-m@(\c'0UE;űY)W~glϛzFϘ߰Ϡ Q3f` +wz3P>f{Ν{"ztzo'g Svӱf:V b/qc{co zUP<{ފ=ݴj64 zoaS0=ocj;))E;ӌm~C^͍Aoӽ0轱*d)XƠbL|zo,H1`Xsd N)wAo5&u(>eb~ W- ?>'Hrz±ErpA _U.Ao,瘯P@~67i1_C7n1~-O<_bzT(F z%Rp^]^^Icҫ5G_:&c~y̯}:o|߾+OzEɷx?Ƣ׾P6߾X9 76~Fzf;z%= [1?}~ C~ 7c~E5ׯ_7UĘA)U}GK=||~sk\sމމpc=ϠC>~: z;v3CjƈSi^Ao7 ƺjl^qt~,_\qo1_ #szŞ_)au^A%h+g%I1_Cq׀VQ1Ko1a|xq=wx?kWZNGz'\50X X=Z5Qw5[_zyV _0ң p̘>N1_Y ~-^կPq1Lz'ʢWp=Y+|܏JTd8w*ގގ^.zUϺO1ϗNV3.zu?u;W٬ށ#Iށ%ۢ-z|ml:&9IoOz'RID"׋\c~y̯1=cz#?c<~ ?߷?oc}7z7~&?+^[ckg,z^^f[c[Z0>{&&/Ƣ}.y#䕾䕧}s.Q's.z ||I45f.zm~4 ^j#^zsQ1'דނIok7zkiע7zқa{[?t+Iz/$MQ;t=p׷?pٰp>1}{x;1_&p̗ne_I58?s1zpoe8eHS+Gz+Gz+Gz+Gz Gz "VhEoA!2[a[ q4Lzˢ7wqbқ~78x̟_Sz}޿.zEuk_]v#eHoނފފފ"uW[@^m[03^yqg\Ozד^۱ڢײ۶~~Oäw _bI?pӋQakzŵ|-jXbMʘc~3|Πg|W/=mUO_6\OzOz[5Lz_6}HoIϦ_ OzƢWa+(t@z9Ֆ1cWa Ho`φI_9~1qJ<^Ǥ蛋^.z/j\W=W]ۿ_ o}jO^叴WkP6Ԯ HkN~NVNk;ߘV^+<ҫqO1/ Q-/h,Hz oW*ORZfxқ>K^5K^F΋ތBt78q~bm¸߆/newmfb{+P/=ozH޶\Hz z+@z}=^_õ-}[ra=\R7ylBq\7M) \]Ʌ\Kp> y*%jۅIok 1?m<Ӊc~??6zm[?clq~cmycћǦ޲78Q_q~>J}Gq!K>Oz%ߺk.ߨO}@n\8?ˢw\>+YX҇y^l\-b֨9r.Vb`}_q/I8OHyC+#Oq^yI8yG%C/q^D<% v[1Ÿw1.7EIm8^i7}.z#9˞s~{¤W¤WӉc>/z:Eo,zw)mo/ކYIa"n"n&Woۯx?[~Ez3Oʋ7·n_Ho=-z/H+I+I+KX=2S앙n|v{W{W6!^ZYp|I{듴'fMjlOaώkӯ*ޟֺ˱?.{:eoc^~s}` -oOg@?ZAC䊖HKj?Eq-aFI\+oDz6IL1^(P{ӯޫl s~e ^/Nz'^n7·?q>x39𗎇??ms?y<x=pXc>6~.O׉O~?#a^'z? ˱ψX".zo|ȓMx?қ>K^!~f+ī޼ǫ<,ތxқQfe[p?[pr-x?[~k?yEz->(/zHL_W\_Eo㥰x*oϋށ!CzޟNGމSoz $" ՊG>${G<$F}rIx:gVȊ׃~$x?A?>JB|ĵ$No|xDňtz3񎒡OD+{< *|" ~_Y^cGP,[B|/Y|{>D|YO~{ (>ߎ'##B#=GӇ:N,q}ϢV>RS7z|}w!Oʢw z"!Og:l|~E~.'#?Wo~=~?;'fX]|7n59_ox|Wx!"Q:O" #O)ȧe ԯ/|Mޑ)+_2|~!%P!Q{U|֞@~uW ["WOWb|bvc>oFo|=="{mw;0{W80y\~=O|#?*-Z^Os[7?ex|!//U?g>m>gWW@>U[OD?q}3=2Q1CDp~θq"*gW~N d⌈S,±Gr\=.GDlх+g ԏa=p59./w=#C&S?FFM~L:7|<ԏ"zԏwÝye+A@ޚNbLxrK8Ay;~L~ԏ:q'=bxS?&ĕwÒNljg1cpm'|>O\N\S|*ccǔdžǎ<.<^?^<&<^8^xciǗ%<^QMKK;<%S;<Ɣdž˒ǎ81,y}ucǔǎ)uucǔǎ) %UacǔǪM?vY.ߣ"CO +p|υ+2 yeP.,?mp}8zz]8=>+2)˓k_&**P^yVqNyp~eEӅSЯi{W{"•,|Yd~pg _Afs?\j?~p _}DZWT(~pט/ _Ge,}eN\QZj;}j=¥8] :q+'.nW0م˦/Ly1ǫeD-}}ac1XZѮn<(.1/+1?c>OQۻ3<͇m>qasc/^WÛ1Ͽy>vƋN<쥎ubǴu:q{̧1iԷ oj2Nc>y^0'=t;G>q򘟎yH'zO\}q<K9qytO1ێywc o}]/̱zbt=N|8:r%tq?*Ow_:O oc}ɛ~8Wc;~|͟1 }ϛ~Bc7_s>w8mte]λ~ܷx-yӏ<7X/yӏ<78筴oe^nӏ-cӏQbަy9mUcYœTul(+nq[./xϧac[T1T̡6Q *~\AqAǬh?.ߠ _cd3_R|Zq) R.Qq40|vujE~ ㊊@ԏ+WT~\qE~~wRjC|*5-ߪ _Kt1+o2ԏ jy.;wP?7~V{ꈊ4.'MxFE [k+C?n!C?nWTp0 y*~ҙ2*~r;B|;#bn+@~*YC?ơ9WTPv,[hT;J2;@2H y#+:Vkq!Vl{0z-jz)wҕ,ˡKy|cak㨸qT X|g0 XѝҢ|l y,rTtPǂ|;惋w(|qQX:X:*~|*[W`>|wѡ]Q!Q|z}˷W<|!V>*^1^u/ޙ?W׏ߕ u~_3rG5ˇfԞRL'GqC3ZhFWi%iOJ{JM[ql~}?}C_o~GJ_7~ח?}ׯ\ח?| *iܾj/׏^ܾ3lzqOg׋ӵp|qG}zedO/ 1-v͘^(37  }y֌x4?]L*_/\ {uZ39㓯 XeXl,]S$gz x ?߿uIeSIG_rbQc͞J0?ѿN?=a}ҥ{z*8T,TTV>V*ObGWXVFVIՎ:5j}WFP_M %ҪK  m WZ*^O ֳOmX^j* Q;`hQIv`Vzp+?)L3 ͦQ=Fa [uZ] Eu&F9xjsF` kf#ਮ?Y1]]XZPD%*_]0(,C,. bڅkAEvf`*Тb--ZDŬD-e+1K-zhRS(,-:i]L㗪2f܊& ku[I$NsFA(S+8i%*DUmQoXIQEbN{-VY4 :۩ef?UmҠP WRXⓙoc5:C<}Of-V;O1?wb5`#GWXd@=ZUs8\M3>9zzbyOO#m\q4;d32SݸiYZٸjeѕZMk5SM؎8T-<#v5=R<ɬSL5J/ hP'Lj#?mLϽ5Vem`1G4VeDOjĈSL5̈SL-uv E/꟬YSL+Bh8T38xuF-Y|hu;f͢54NPpxͺ#N16f 6ķfzqifqi [Lޞq (>Y0(/iƺl,tDWfS #N11|iւu bqiv)YsXf1#N1"A- q&ll_f_'X JGkFWN$h,s)bт`^4 G3N1͢/gbxfrٺqivʘqi893F8 6*C,5; Z]iϽFPMW+psoJS, S<6`fݴf-YY\+hvf3N16kFȾ~͎Q3,7qiշ*[BQz8(, sW~Iq"jh^دϯRRvWhS<_OvNk<_0;xCJ=R`O)G "p7\[<b'f'dŮt]VS<}}S ]Os9(} \R̊Tc'CT{v|_Fu`K'>O>7i{_14#"f=DvX?=Ed;9 4ݼ}OAp?A|'&H ? }_=X,^>^}דz&^b=N֫⺭g]|<|Ly"fZF-yGQW/y&o;<K,%OŔ%o"YS;[#o~aԧ6}K'1B_ds. 쿡*M_T<7}.oʀ o~[^)N;K_-iзeBBp,}^q}q^68/x!\Gd1;:#ܵg(zڌ㖘1V<x 1OL()Q#bRXO1,b)\L<֊+ނGbll[t4i 4قi\K1AaB,ވf 1K1b8&CχYaczieL &N2JnڭQI3v3[a.`m|Ln~vs#mvn-LQ0鷛)L$NdnoTnI91ݑeK*5[lNAl>g$ Urg[FZ?Ųůc٤-nW];ct |  5֜g1L1MȢHVš*sQE0 4 h Q.zw]䤝rHQ=^Hm;Iଐٝge 8"&AKߖ -OE\ŴmrgЛbTM<8'djjq/‰ۓA2fY ,1Zqц =F%azl~0[(L[:cwHV3FԜ5HsFi^6GpgY9gXZ ڒbh3(1*fBl?xB(Ϋa2ZQͨP;g3p(?B&<>xd91Ŗ}D+KZQ8v_2Fg{#+0 R{sv1-y0ja1Q W2o\&N],{\%FSX\)T~f)mY_& vrh;Gm䨹ޯmc'pt1PM5r0(ͳusvȃQkG qh̓'i71:Z]9j:q"hW=ܬxh"bJF 68 r˹-!-Maz/< Vsvǡ[b"F+1ڐBvexw3J1b1Iu$1-hQD;qQ!q1gfD,ªfN˚M[g`I #PkXn_!pc4YndpV9: 0[znl>1sY4';L ll0s0&[E~``S]fh֋ ghfѝn"<`R9j񈃣{qZX$G-h\$ZfLZ"U8B稜=FβA^q9Zv9:ѹ``{(Z,20稤+ ?Y}t.h9GIrq΍U,:q~/FbbO}cZ[q}8F$^1^ǚ헁0OzaUOz ~񤗰dhbb%xCl8? $dイ$q19$bܓX;J"(II1w_F$V 9$:c\7ѿHOʿ) Y&'b_,NC1;zR';^H2e Izyj'$#tI옜pv$ptI(I@5۔4nb)ڒHPbvx$pcĎxð&+f^K J)fmKJ @1ۚbv$ 3+ffKZ @XO( m}c5%[29xfiK@X[f[ (I!@B옮QA3bv$^t:.}IKBҥoqtk89_^H }f$}XdЗC߬G}FZ3lsgݚQt%ZN};RIo{Qaz-ЗCG{QyHyiw yq<Ԃ8Ԃqv-Ч<Ky^5;tq<} y;[_Q0-y jq g vP@(.:ꨦRMhMRщR-H.Z=ͽh.=S!7LN5?t U ]ӨjJRQ;J\Ϊj>te!. V-eNj BCi:L[ tUyGrEz)X=]3CZ[0Dk$*Qja7ts"dNj-!"k#KkWkRɅmfLmt6yzh_j)zt'W8ٌ~tEW˦Z0pr#._1rZ;]*1`yQ˝Njt8}h (l+jv D@x)T;2eP-R^Q| xQ-2TuM1: mf`p3J"Laq3Ëh >n&7|Y.MF+$ͲfN,-mzg(L9,ä́ Y'ě0`xJ .3o1\,뎁b.veP;ңeċD2\^.Ֆ}ڋ (-s#ÛAb?C,L302=@S Ċ0@fɴ1)Ǥ1Ŕ10B_#Ϟ Hm$ ALp3CWX*^g0D'HRLYp0ZV2X$SeP4(H4o`9StP < ԍ` ALڒ0% UG$t&eb*'b#Fa$+1 SPm Z(-\!016`ژŤ2dGym赒dx&D80;EawzЯ?\ xbLCT&I?RP"-PɤAeJ!2H(V#Ɋ"Ѥ,:VX, yr6NX L;T2RГ7b󙜉ͅbb&v)\ΤPw!CK>%y:&ӳNBLs$=V'[`X1^/AXW*&>J6\ endstream endobj 96 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 99 0 obj << /Length 2032 /Filter /FlateDecode >> stream xYoF ޿@SYa{žlɐGd(:`,@r/#6YMsg gqr>_OR1IY3UGә:}Ke\EBw$gkP9?km %y8)rc.Q 6WwhowjTojEes2QW쉃Sf1~2$K8C3gb2}Lf]ˢ ő5_7j4˥~r-\ q+%_K΍9| +XHWLUS֏΄g&`"<|7.IOI'ĸR fZ˶XO6T{( zݝϽ^Ր07ԇ_HD挚xLN'\4~>vyyŜV^_[>W\`vlźAD}e}:X><\E+tgy>1-|qd{ܻ]wNc :'7-Wkhh7r?ոE riO#)3[ uql5p]#b]Y2MvX .@`l]%,NeCaoZ@`BFX,nSkڔP ܓh飣`x|D ,TcJIۃQeQ}m~_Ds@)~D_'ߝ܉$!^Ԛs.jrrXݍUsyyo=F?و3F < qPw 0@€VS楎u|[g& tvu3S*n~AQs9fP-p*H*$(!h1 E]+h; x~HW/е5D:)zUTlBT@}pÏΙz9°L= AL_R,utx&PXD3>WAu*0>IeEޖqϢO1LC5ThN C;]+]Ka &]VV4t@l|L,?Y+GWljwc 䂬98b4Lh%{48@S.ZT{ѐmJk|O<}xG xs<_͕رFXB:&3 Ӂ0g]iKo?T0JjMC@(nT=[ 8A ҕ}o6ne;У#_;9 V8pẃV*+ c>ST{p?CA`"() ե1d.gk|.ZGRoO;{=VX12"ݟxyt~ݗߟ}EH"?wgnN&.QqTϑwۜ|sR4r>j endstream endobj 107 0 obj << /Length 1643 /Filter /FlateDecode >> stream xڭXn8}WĪH,4 hhBi[..I;álɛiY|O޼Cyn̚/[~ڙJ.mL9Bdf gg1dN Ve|FƦi@?HfN"0!:Ȁ44(#1pBZ5@ou['K#3PHWF3F]Ao/몠>l:ngQ% B_HEKy0s@ igZ-kFfG*@{"kcJU{ap cq֬IViki}ZB50ㆢjy/F/SDzpj,p\GE0O( (AxjjӐGP7Q*= b)՜SO: Ƅ.SDS=URCݧ9*6y9^$fRAj^ ed~DCvK`y"Ԧcl:L$1 nݩX9k'ZQEJCn< l-Ω:j⤮Q{cYq1 0-e7m/5lԫ@9EA`fr3@\NeuKI_0!yBo-$>|+Jôk+]z/6quRkDǘ#p72Ű٣ ؙL./!d]=ʱzvy% ]\5E Ϯ_λكYu "tEU7viHl> endstream endobj 104 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Topology-Vignette_files/figure-latex/unnamed-chunk-10-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 112 0 R /BBox [0 0 527 278] /Resources << /XObject << /Im1 113 0 R >>/ProcSet [ /PDF ] >> /Length 35 /Filter /FlateDecode >> stream x+2T0BC]#]S\.}\C|@.T endstream endobj 113 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Topology-Vignette_files/figure-latex/unnamed-chunk-10-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 114 0 R /BBox [ 0 0 540 288] /Resources << /ProcSet [/PDF/Text] /Font << /F2 115 0 R /F3 116 0 R >> /ExtGState << >> /ColorSpace << /sRGB 117 0 R >> >> /Length 1780 /Filter /FlateDecode >> stream xYMo69(i @Ai lS rw`'<>ɪʪ/)5GRT֌:Xu{~S7~}D[Ym Z]ݬ|X#et2C,u *hst6=M::%ZVDبmt60UmlEڧI'vkh¼Umk]N&m: ­:!ƭpN?j 6F=A)"=$az$  Iq g3Rh:D3^GD3 'дhNgL ❣:Hp0t@;uB; M.FfNyGi6YD8q; i1(Ռi-RʶTT p-%\ϟ"-gZheQ/W$@TVIMkUڎkSWwa}2Q:s%hN ߗ3*NQYmYQUPUUbzJ̚5g)kBdEȚX2ֆ5"bD,WXV/ejc]Dn,j1-ejc"YˊDkGXQ+*ejcT0ÊN1)0NJH,KTX9VԩHX\JZ4cKn4rƼ3&)S\75bh 32:x.h{ʌg,|Xx.pN8{  3 34 5$g,BXՈ3g,BX׈3g,l8'lD|+j0rA@ MB9 H<&L@ S0Qj:$B` S0LJ6x*UUK]{DgGoQc5515,sx Ex"gj:^wF2e%5Q4 `YFx_m5Bk(05Bkjc[^#tF-aQ$ `Yژ̱"Wj,VmL¨hU+NUXS0tc>L0b}yC(Z87pU/BuMO.ւF6LݏJ:?|I$L;ŵz}#:{{{y{ިg'|mi,<`T=4oSawC^pRl10gOt^@]|Z̞M'Z57V=x]"ǜK,s+?<͎5>\f49aKd}q1fz&Ołw̛:N;=k󋏥;NKWov{&˗(e7v^gR +Pw~Pz^޷\/sS3dƥY .55 fy6k\uz~YڦV:R9.Hf%3p\Gd;HN  6 zFFǑlFU%Y4VB|ݿդ,JV}.&s<^Ol-!ևn/^}O_nv=K>a.>/|K板?h6 endstream endobj 119 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 123 0 obj << /Length 1564 /Filter /FlateDecode >> stream xXmo6_!_dRIIpS/8Fnڢ- KD5~o8NzþXʻsF@z6>{ύ1ȃ]j|2_[9\ q9\߫:s_D.]N|,ċ"o1UES|oI@ף}[-}8o]:~ nY!}p~h+Cb ) Ԙ5U ͆%,+$4YRĉLTgeQg)$,;I/5Hجqq4G>#2FY* Z ūLx|]s͔JmTՎ:8k#f t]dK*,ojTn?#ףy7DXqIu3S{b6:a`{kɐsD@O|3mƖY]K} O |;rHV'niX2-*#=%_ӹdm`@yfI7XmQd]xLeW7烃{ 0šɢJ˗TK=BPߢz&JoZ'kqÛgP%;Ά Վ~bNо~hPPtwx<@hU/ZԱ%ma! PVǸ UXmMj($KUɔj=+RzlK\n}gG[a"_ BX"Sᓊm 6"g>3)"D{1@c 8V; z˶d:ӰBj>7ňL~}#O`K5/W]H4@NMD"q-n蚌Lzf9īNv!XI&+axv }L/&l1sX!.A)f`B^`{ >`b; ,ϥz{VZq *bX JJ]RKٹ߅BcŻX5}rera"#DXC +!ӚnG4NYsF -GaijUZD @^oθQXulfH{_ x g<#p&pՅ_s٧>k%{bPCS$pЉ!(d/{v &la4P\1?i0]ǃz$=;0@q<> stream x]= A D)dew[tbhuEO$ # Zۄ!ĜT\y\>hNo0DlF9WvҵK VV߱"5ń,o8/ˋ .#T endstream endobj 120 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Topology-Vignette_files/figure-latex/unnamed-chunk-13-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 131 0 R /BBox [0 0 533 278] /Resources << /XObject << /Im1 132 0 R >>/ProcSet [ /PDF ] >> /Length 35 /Filter /FlateDecode >> stream x+2T0BC]#]S\.}\C|@.T endstream endobj 132 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Topology-Vignette_files/figure-latex/unnamed-chunk-13-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 133 0 R /BBox [ 0 0 540 288] /Resources << /ProcSet [/PDF/Text] /Font << /F2 134 0 R /F3 135 0 R >> /ExtGState << >> /ColorSpace << /sRGB 136 0 R >> >> /Length 1145 /Filter /FlateDecode >> stream xMo7+xlaM11.Xvk_ߗ2Rl堕F,wfȇꕲe6.1/WJR6otFWmzenp7jyݽ\w#mN6yE}Wұ^۬z[=Kr{O4ȯlu{s:g%})h5kP:JQKc]>%1Dy6m$&$V $dV '(:u([1,WrH_/Mae2Z4wzcH_/C [GnŰzGV R܊aN!#R`[Œ# H_/;8!EmȭʣMQg' RFJ=DK%9cP??\//ɨoߕQvF),5.'҈"tNݨ5VWnrN1-bi(`4h>yuF+X`J2^j6+ $5x0kD1^#1aF55~ڀ/^#z׈]F5"xk-^#j-Ak5Bxk+^#\ъVF5B 55Na׈RF5bx[P#>-AL| -[5C> Ro>fn2N-IO_ \<ۥ{Һ;٪~jisQ0m33bֽQ9OEæEmGuMw bvGs?>9!֣>>~|+|9*X/X3РGs [eXxͳu=8ͮTW.՝TvN]O~j]u]YtI& W^gFpkX7>Wϓ&USעo0z@T, 3v:|4M!K>dκnG}0zuS7d.woh|@{@K?bci1VP8aRɚUlJTM\C)Em.+RͿ?ݵz0O[[hxyWn>Ӈۯ{fkӗ;][%} endstream endobj 138 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 2 0 obj << /Type /ObjStm /N 100 /First 812 /Length 2197 /Filter /FlateDecode >> stream xZ[o~篘z8K,q6F#6YJT;.eb`` gsf$I&eZ2Ǥ,2iĴ!F0iIϬLcdJe0/4 d0,a ŒǺgI1AK J^3p(vI44 l| (h (P 7`(@a?C5KY(Yz^M^Uÿpu~9yuÿB恚{jF ɩFP_PU`"BhQ75Cjnڲp)[,$6rzE/\̷b}9f~!~0[\[:_yS.znlnBtan[_._ ^oso[, %`|)D쌥EuM~,Iz\|XMP0II9 չzC/7$T룺N ` Nh8,!-DV;tB]'+ԬIz>\Ͽ/IqT\KY?]57JG֢Cudg[`8'~ `?g!rqWL'P4Ǒ(nws[~-渔pungls/V;qW&i5Vm4`+JAƳ i5IR\6K_eIv+nmAoK(Yy y?>&>n7?pR,OAGy:/ .}ZV p1iIގyUqoz3Ҫ>ay,YxNTLIQ'M:`0wm6i027e[SY!k%(N2Ǖ*nqݔwHi K*K=yyҿ ; }lddace݈("{BcBo!\:h˹6Kt.]I|\sR'‹s:zw^nh=bmr;oj#A/*Q?ZqBp; Ef"t)uJSxxoeMmS=]f]VnQ=V j g;ɄN]jaS7)=O0tI^t0b/tw> stream xڴeT6wwwwwNpwSkqw"Ž/V9g3޿H\S5\N2F(>*1;%@ ,̼yU{ 39Bhj7q\JfVff t~WL @Wu/G /`j,A@w1G/gkK+?1D-51up Ew50ZY,@m@JUICY=qSSא(K) 5?@;KzOw? ":,L`]nj`W#/+%_ԭ]ζ3Wa@tOKf@ JR;]Mbmp+_{k+d2{7t5qus%{ͩ&9;ɡ/|Lq::8{1Tۂ<@>+[# (#",f 4bI#f#~/#gm| n@?*!p̭\߇} ]d[_k?_};@ &EagO.I7;;E{ LLR?]$=֮fVWoЋ,Kgٽc0s}lA@na `V֠qHd`n rpLMg>@Ͽrp}w8,4$G70g7z)qTLjA&#w? n{#ff? ?w$OwvYyy8p|O^ =_;kG3g^VsuvjYa`lY39I-* ``p2s3fc/_忎s&@Oڲ_MzKXDl4yl"Zl'x.)P(-0A^?5TMe՞R=sk"gO"!2ɨXMJs"[S>ՑA И8ye~CN#կȇ(^dit\E"Xw}{Č1Y]0.ÞqAӥK/P7jY>6#$W!ixceBV'9"3E Oe?ح7ZÈhY-}6"T?6% 90TYE[\_Q@}#̾t[d(T!S c-ŜZDz`cG YGVvOɣTq:#}s6aт^xX L+[W Ł*HMC( _\Fe۹?h%[l`='~1V9ؔ^ɵ6rՉ= K]0ۘ)!S.s5܆ADF{+=:ep4(gӥ /q|wBhޔ#ݼ. krlbcӯʠ~|v7gS aV/ [g)wa;JnU?|gةG:콗9̃Ssҟ"}l#_#M^-U2)[, ]^Uv|I]M\kOL9R,kjF<Vf,X>8(v}{'6)!T_7=^,fTkFgs'}"t0ii45I)9Ɏ)>u1|;@to9 n(,dp(61!pZKڪ 0LP9b ?zf543f}|)NmaCrrN?I#Mo 5na oԶ7u9ƫďVGvGhjPԋ]\㋭H$,]hkެ|x!D,R{B*5ÎA 1M@a~]ү1/S}iHV 7IKϋ'geA(d[V@=}"jJ){9D%;.8Gv>vܛ'@F[G+GM$ƬdQp:ZP"bE;`,es2!N?/'A߇ S3)B/ !ؕ~X2y*si-V0jOŽ:ǭtqYcK/a4{¦{IS,%UPi;O^_Qn$ Oֆ b- [ʬW\{ 6}xs8Ҥ=NI)X[o &:D~u1y6~D\'I册Q]5۾z|qh zi֑%o"L{&E`-:q (řq1*g1yx>(A-H&n쩳6nYk=lVEc*Z؅9LFď$,pΫW>.?&[W)bAlՂ~ ms4;5{ dl5,B?b };Iu̠նX]?sR[v$u5Bk۪p:vvv6xCmQ=4@j^􈡆̤DhٳM5:.6_$QW q~fWpӆDٹqZ[??э:[V{ |*msKG+qYʃ}Hz1SF1MNSTG4dUpJR?oMb6<ȑhTs{6e}&=IE#O~ԟ9He"~w;,:I/ZsMQkͣ,e *sGqݳVc~ lɤ? 3%կ4X@f&2ha ~*6K%O] [8͚9MSnhdLv b DNS,npjQu"z4ujk@큋A{̱rƥ:59Z7R "8R#Dу֬ G!⼾'?[:T,:8wK%<8` JJËPk ֐%r?J~!P @vj"f5V} L'K2Èu.gHb#hֵ( hZv h(C%:#9a]`"*T;wi*{&1R+Ʃ= bTZm +F朇t_ps?|e Fʐ%b$p&5r=#rfr@S|3=Þ[xp720I*e_Bf~pqPA$ 5 k*yt>:#Jg^[nx̵zY'R0`EF z Wq:xU09~\|٭`h{+rٹwK4 {h2#׸;H^PEu F}6 @#6q }$FM* if.jW|iAZ6EpDnQ8e'ǦxЉ.Wq"`TYH"\}cQPlD<' (YuKq9'R<4t?I ^؍*_ȨKr nQ/()I=^ا >aJ'Źqe<c!f 'i: E~*bLtb{j$ޭk8W4=/3A @'[x]R=iMk)Q_z"u} J-AAX!a!)H};: LC= RqT5 nI j+ȨR |눚}^=c0l+a(Nۧ4F˻Yo0f!i3;&,WvVIEU'`бiՐfjQ-4#{~ 1,X.-eILƨ.qq;l_$#%JqJqRhM7BFb]/LdxWЂw UayD{^ޫSH l19&?vMGhJP?Y{=Za>yG3d^Cxg} ,{N,˰N\?}KG\e-/ w"Ӈ>l3Mk؊#ܩx d6K <.j'[?ɿZ >Waf7m_YwtOkJ8GyD?AɃ˜ujL.N$$lgM>uˏ"U4&: <]¡CK4,Ē{0DwDzL瘼z+|;yH[/$0x`˅ZM f%sv`DMk;F&e븓_4hsȯ q ?XUE>|b}fY}p,4}+LݼW/pg9ȗzM).M$g9MERq _hZW?ZC`,¡,AܬS J[2MU~\Ue;cZշJ<T t, ;Zsٹ~.ʪaQLRX`oǒ)ůPK2 BUD+_ +0~n >lsQgAM9_qdGTÇAMbc)˝!AzL$~u8BsFSÔ8 /uLRBUs+C!:\+ ̟&sJLm^fS-GΫEg!!="[/J|ԡXbN'fag%K^fZ1)_tM 8Vt#~xERO!mİÇ+Hȉ5Nه-#nݙ(4l1"i"jπͣz<<ȩReh *VdBX>#!OЏ.6@(u£T!/zw/ m5wpHJAiJeҀ,Q鲘i3 T"&ǥ/c\yG"Zl\$\.Er@SnKl-_8[xXJF4c7Teڠel>oexBd?G#7cb X%oli/ !]%odɓ 6{oόEٰ'0Yzg2Lnj7U^""6x i',n.GĦ`Q}bhq%bXFi| N:tƖvDkR!9hszmjB 3m5ASga(lZ>ݳ륻,2aO`{F+;18fA0ҟ.R }Rq6ݹ"8@#lwg}ػeacbf#0_Q} G3}lgZm5TL]Qc6R;i?t,/}nj%!2%j{A/qG}]]]U!5 z=:"$p1g?/|0:Tpbuthzw >v q NJdL  !ODM& HCzSK_aBVj)F-pTM?j;"D([^+Fޤ?9ZK  > asy>KMl@R5:el4GpքSmDyR{Z)^dݲo,kհhSu75QBy9NG8?=a[q.! QLL I+1䥇){>4{0Qo=r8bmg :r^kHV"N.:Vf#Xo$؋ jRE.İ OzIxDzkb~*:rp{6 ƥ*oV o#0o!;pԂ<qf*}>}07n,oLKOoQip,.ݙn(a!`aZ ە-cDV8 |wef1&c _R0f2BXS 8xPF#:u.Q70a#dШtb=-z3q([ GTs~%f1I6[?沧UP^u2jFM IBMXǑNTRh"`a`cf/cXgS h=y$X-$崬jN[jnO*aM>spN ;c2 YT C@*h X;~7(R(\8a@ofA1u+Y tɋ1K }!:vs,E ;/ula5Q3böoW32nņM1bȬFY鎕w^/hс&cМU{|"+-c%5 Ųnp/&'@u~y|2,}l_4CX02ʃ*FyK@ Y"a$uJw8Njxr@!.4f WzY۾ Z5 ʌb ˊ@˚rfM T+X }SìN.PV$r򊄩F5 ʘhwe&*ťꄪiёA  i/8"⮿C뱌c~a :#vɿ %zz*\ LJ 8DƉ46ɦWl. CPt-?wD `|6Ѐ1kƓ* Ϙ G InQ=}'D|&Eft O#wo2K|̼ 4@w/d,^ WQ^2&,\×.>$9^˱HYqVvbbQGY+vU݌U]"d347&w{w2[Lr7D4IڡlƌZ!^-\P\JJ[Wg\-U$(>zZ;hAgjDR6Nc5٥y+D]CyS&zʃ&3 h5/Dу4z$pąf1 V>J<Й/J]:75+"wCY ;M,53o]ˠ&ןX9fͷwF㓞9UAH$21q}[euLG,\6VBz[06yʔ(QO>KBy q_h. 4 ]{,bQnjI޹nkUMkbfLșjbwӘ( CCهg!.Whh[?A5P:ܵ i^L@'pͭ ntֵ@sǯ<<3:pnsNDë}(zTYf3y{Q/`,1RV{ N`4_.C{ʢ=R@*O/ (;QU-w}8,^:i"^]TM$:  ތ{$gnœ]_+W^qg(?㮋ŁȉVfd3FVN1{<ǂgR@ceKt\L6AUNQ4+JAtK-p(S496BdOR91+u[9PwmG%~$>_:1<ًD=+ȱj(fm${msH  )ydqG7z>j4@͇exDf|[TE:0j"OߚVX^`{]A>fO$u}GC=7Kh>EeLErVw|W- %QIM7JOUQI؉ff?Tߜۮzȹ|ʺX^'AOxpKfXz} aUԭIБ*1}]ˮpo𨺼kāGɮ;1琘ZwsBIuAV$FH47U:ssjjoV৴"3v89' AO!.q]m%a%b7uKkoK4]cIeuw$R؟0oYvH[o1gt~UjjvIjuMb#[Ds"B~ WUn)TIFf}tp|6<MިMhxdy_?ϿR(E5po#F3zbQFQ|Kڈ`&-ՙDa|V9+X鴅|3QW20c!^n_%dRJw}`WZ v6BũSC%;|T&/p t>̵b[~:%~3  D.*tq5Y˺!SHH0ORgv]!Wu SZ5) 0NHe.ЉCs'IjNU\YCD2OXf7d$KG1=G%ҐY|x@σRw +AVG~g$gŠR 8*|ɜ) M8|7+y(W$M.C!cꬁ( 7^. >'J+GVNm*edUD~@R8wZ 9T92 zt%>dm'Ϙ`hZ`L-V% ;5#wZgIˣ'.B1"wbO ;cwkN6鲍R$NR*Cic;b/1UOP m Z,pNq!mZZ:s8Zۍ1YZ~\iQ+aw]Kg֨Jԡ(ۀŔ5NLY*U%/HlrjQA g=MS)|vρٹgɜPi!iuIF4.2:u`qXY?Ĝ_u0x"3*3| $RgҙEQ*glҾb(Zݞ\hG^ƺ@ű;WP#NmT sZi 0ee]q6(v`Jta ?=8"q?j\l:1Uҭp ,#%R*MME> o)Br9]mW>%< zWһXc J2r㨆?otxo 6],9E~5 GKl6WxW=nM$FE-]ɫ2gA R$nE%6Qy S\Oa[-W:fNm RdL[L>A7f17d#!bkgM"3]qS;[GCt1A䣠eӆfT̯}r& V bg1?nsז~saѴJ&#.{uѪ?VѾ '07$Eq(v9˖\|+U-$K)$MOUk #` $h$ņ~31^:)U< kA}#ρl>tH*=7 =(m¾0"AU}ց:Ic\Ml S^,i=سD=s[*IHa rc oËC;<, VμvɈ ̤}X%)̶d>*yxV:DipnlPBtm{q!*\c׵q.U005, ZQ :0foiXL[$q!Gu]!23 .]$Fn54)Cٖj1&(4n&\ 8OqBgC"&e?x6.0`plP.C\ӣܳ(4ɪ^exœ=3WP78$My+RJ_¢ޓ/.z<7>[ Rӟ?bx?215akƌP*}%}`ϸ!  4. qۇKxOXmL0&NPdv.=7!Qcvﰬ-UY/, GO%46'\oj^E n'}~pVSVl;c';/b%:TͰ Ouq%[==bg@G?g$վLBozfyvӼ}ڙd;xWgm:Goqc1)u ^LmOp["MuZ(pC%OaXyVT~W987mu( ljC*n8\j/3zܮK vn l)F:qlqQ\^^s;I'>3UgG'( /J&،|e6hrS2 ʷ^%OC6Vy+[ *Aɕ}* qnf&V=?>rfqN/bq8:$BưTx5'6kKl xQAa%G X}^8(Ͳs@'?ՅWN3V<\Y1vRY"OXMu"COȉOS3*F#=Rw&?/1b$N yRxRk,C,E%0tߝ(Q^TeaP~ }؈qO(~ăA)iXdb_ɱ )wHh}X)2<+T6d !Yd8%f%| .2 vk;^oGy]8bnk0{NmB <0 ١$Ui[41%b,6tCn̷QZ\( } d c@dZScǕb͸lʭS=\G{W.BY ~$- 1T%VSծ0חa'Lӌq=j35|NM9N*畹EdH `a>U d"vwy=q#^tkſL($*JrG4WA>Ib3mb)E^&9%~TjC*g4X T6:[hݪh[A3}41J޿9D.=<Qq_T3'h,Cˌgm(I[$*TŠH[r~siTD!c3]:\=id KjJ/--"7|^b IZ/ڌx=(bDJ9}T+1{:FxLzӯDQz@5sׄ<̏賢f߹R ͒KSڳtO=`rp̬> Aj;λ=Kd%N[L#ŋ9>Pu7x1.h"$ISա} J9ۡz]uV0)cK <0 q5iy9SXyZ2kweQj,T$"yTdL k E}>*wCԕ":}9N`c {zuɠbxn![$u] ˫ýV)Z K"Loof?,%HDW)Х ȝXqe*kr;p &N0dAiPhĚR7ƋL#"uq0xCw5,7ߘ_i]zU&q4kN^tI$e-7:5|Z;/+x= vWrl˭0Vaqpߺ3';lh)^ΞdyFA6T''<d,WDq)/Q^!|\U?܇5r_2 *uY$k+%QNu7(?eiMF%B6ƏA7dmooRQ},;0X;Anz2-e* #e`8"7_XTA\ }q /UY.:}0ZWӱ ,3,Ʌp58G)8}Oqt^[Cr.yLbMy05ߘ <=z*@@EUT+A s78ʔN)k!fLzy{8P V={Zr>#?+˭\Rrõ}&J^-dħv/ CҒL2ӑU%'|@٥Xᅯ@U5ȒJ]2SãY~كhگP,<-dYOgF.#O|bfΐ37KFw.va-jqفw:`~=CJ#.cxU_cQˣF5 [*7AIdl_XhlG 3"$>e";D& qE+nzL0=csp < >MTEhoJ5.2Ϻ #zAH@ˣk:==7㮯Zar {8Ou@eo{CϞi &;iۅoMYelA\_{T~I*KpdX(r Kz~{/[x ő :Us]ǚ,!*;(YĊۭHdB_[*Յ8L3w |ƨ 㷂 y#FJs|']bސ4i-X(c'OFu߬ Ӡ 䜑m90)9UQ];>/t0Lnb~1ꐪ$;g>lɊF'h:+Lcbs/qÎj#;}5D=YNT. ށRC32XAddƌLRm2AY,JϛjcN/^nzI¼pND ">~셅d(a ;_p[ᛘOyb^vrǿC=tnGRTOX{A=t\OA ~F풨} -o/->DU+} ~d.?H]Mn27Y"moVXoNv>UYmjkјY:D1xؚ_cT03 ƹc%X;{(>oL=Nl)IlNog'TC0JRw221LE1#t̩V뼇}8F>l!K9&71>ll {g9ӣ0L\)/NigȿkYu'zʆ#}"lmD=@N)فfa=_R]iIG hl<*8=uW,SaْUg_Njw"@Mt%ߩEcO խnԮ۞Mӈy0_ds0Qw5]kY80oDdf""n^SuG"%hdDܙzN0DI&JT—H YBoy1GscLE3Y,&l 4rWK_xDB]%In95%yLn&VWO xsY_-0¾S(netm+/mU:@ Og]'PK Cn1+݃Iٵ߻ me3%\?om:j{.C}pH:Ce:2rM|4OyI V&FU :R#;'- Xa1*mI3g+ MŠ'3c9Tkj N+W᧶^["gl{3қJ:۹wۘX\Y@>?fǝ"@G{ rlǶ,U^56nE]2Ke9/}PBF炎[`=~h(XpUZF"[ a04N It` tASfjk.(ycHdNo40gt}o(YZ^f,SzizFٞoe;^#{)F\Վ,Y`enB?A:D(8/i:`_F 5{_Y˦֛s;l5l? !A Ȑ@)ܛ#+N`^*LmDpᙓmibV">LQi~?u4*h`w 1Θ 'ӷVR9!`0Sv  IbJ>tO!tϷʋ`VorH;4Iu]gbAhd͎z[^:C[\Lim Ң4Ӝ7MJ0 1}1dˢu2?}׉okIwiHTaW?N O?JњV #Gp" )7R7Aq? Ԍ˲¨oӓenh==e)-\R+ß8Vdz('6~Ҕ'̄R/ʹyYsZ 8&5|sDo.k踲B1?\')?*.󢹬k'R* o` eJ/;j} ]?ܟݸξ& G( x[ =ke 62=sdnFy}'d}FӜ4kZ厅|>Iszׅx1_3t^wfu[ՇgaDC46H,M%$z|^wzl݄~4#?Y, DgB%TV~d G2 tĥa4!;CU'<_=2[`7m*/q7t!Ee?y{^Dl'&w_ %(4964hĪ~g;Zk$&nX/ }swCM9PG{p&}n1=_\I+\{BHL\nݎdmc<^ =KHcHY5L۠p>zԗ^"5Ven+ (.ɤ*R »P$teW+mqYkM20YTeG17B `mjk耊8c2%[K?@ȩI jӹCuO|LxwaτfUn1JR U0@{5ԥ8F C_as,xc/ ʃأ)9%!}+x wG,?ԧ9129 :+qAJ-Gnս_6U4$+}1k+̉!SuZ.:weP(yMVHXT5\u (J3<K\&=WsCbeQsk_kބl3ȴHK2w I h뢩]XIco`?J*a E,۶ͧ],~ь&R\$9sq2\GZukZcƍ=pC HRlz'ź W_ny3H>YƝ̑7'ҋ0ĪyX8K̞T8e 4ᄀhY5] 1y6@n,A*}fx{,V^%6r瀡!L3'2D"p:s?^o i-;FVg=m1.HM}u^T1 C <q*B+E/1(,*1b-`ھ@p[ȮXmT LQ.[A`.jfޚ⧸7?vT%mtކӴ[M0 t^݄!RAQF)5sݮ$)KۤJp#HSiΚicMȯ%xW0& #wgK<1ƖAniowHgj hW_K j ML +M0]:<[LI\iݹ$dL *cȁ/_0D1i$q>qԗjfT#QZ2&nPgeoPbglb{i/*L"J\E6*{jtrۂ}GYI N.8`/KO(soQ*ְo EBI3E[~#/ez`a~SZ2n4vxMnh?#ny e22!]jqNu(P M| H$c%u7ZhkvOz_\Dޙ WāEd}/ 7@/$&cU]p[BFN8K-P*B#CΤH+L=q]p譔uv+L:{[{l2(1E0R'$# /u^Ո-ICד(+ܧ"JiQVNA!4@PBTAv1Tbt Oic$XƓ޻ۚ!+h"} *vSQ8kdIlH~sݮ7(Jgח]c}wInHL8GwIv?klWʮ :\N#?#/ endstream endobj 154 0 obj << /Length1 1962 /Length2 22702 /Length3 0 /Length 23890 /Filter /FlateDecode >> stream xڴ{eP--^ Z Phw/Zݥca GX2@I(b6J]YX `;{V6FQ9R hۋ.V%37G' /%@ htzSL= @uO +/ vva45q~S-A@71O vF?x2dMl6 9@I v4`{)jj)U% e5Zj`rSSאb(K ) 5??Ձo-o?y +H(K2y+ Q1ڛ+>ffwww&KWg&%_ԭ@w h 0ot#Af@{g'I?vo|sz[!\Ĵ94V&++L@.@{{7CWg_o9?bNNr(K4. ~{2}[o_혉jߏmw98#"`ag d "2jogϨ~=_≈xX!7ٽvFS>q[\N36`w{Z-TՁY ?2K t=̬kRYJvX:}Aog7 w#Vn9m2`?oLgiZRڷ 5ź̊`acKVH_+;U, +\̬Qe\Lކ^֑Dm`ߎ0rsml.T߷a `WqH lqrLL<Xf6@dvys8,N `#0%t F<,f 6;Y߈߈o |s0[  m%|K|c7o- o\y E w7?} 8mZ (8@"m,ۗksm?? lM& ŀ2Ch.nH8<5ϼ|gtBqA,PHsb#v]. mgB0)c-me{?'E[7Yt''!#H0Ӎ|cyEq'wN!YZHxSЮ_g|;͌LAF Kxb0,vgi)ZA٘<~->GWR|fu8PX z}~n8"sj#@(acO-_IykZjHVa owlQYC'(bDĩ;3?lhC}RLud"Ȑ+OkBys}KʢZm2%6z*;|3ob"g|Vz  ,86<#E^]!)E'WP ms#Sozvq&UZ`¯}]tFaQu||f4y# Jb>W1%ήݶ}0PEQ5橃Su@7  C>'eGP<&#Şga9L^I|wrb6XXun Xvk.N{FU)TǢ6lJ7WM᭫87˻W+<)b(PQ_̀e 7A=]-1#döf{:GhB,9ֿJr1Jŷ0% Ĝ|glpHqxdJwkyo]m~JQgm#YZَJ܊jt$ջ4#KؑJݯ`XVUiZ]. ^R~:*C2+&)K&@z  `w~\/sԓ h>{rcEq-S~;_w{Pc8">y_T BtJ4xLY(Ɩ},)v*dU,|v7dІpMSRI)ו`j2>V4zGex8`vaj(Ƥۘԕ7d2&yPu5mP'扇!_,/hiq~VRw^S'hbnO'qy!c0#!+ $\ C6QGᴚ2l-Ok$rL(#n`A`ܤ֏Ȝ aXu 6o9g'/(2/)#uZjJ't]70{cTYE4q̷-UZbm)mƒ Dz4!opЪj]<8B&gA ,Bӿ(Thm΢,aQy>4kl@8.Li2՗lLrbqi6*# |elj~|_3JB-sn}fJ5mx+0(kO#MȥUu}k'`r>NUg8~Zղ 5 mobDYfRt[t1QPFv"Yn@]>X(6b"dcB}˾3-='N|=t!;Topn w5"^yTs/gnc>* Mlx})c߃n.YPROӸ%z S|s9 a{Dze`i G=HxY@`ro"(ŊJ`蓉gRx"B׫uңǯ}GE z%-THn3S+VD&* Ѣ+fǓ۝O÷^D3LNMZHL'k -rR4tQ HSLm-lDWU5аFRNُBrBUQS~ŦEua~0(߮/^ǩC:k3VQ |zI^nԼ:킿8-ަfYloe%(Ԣ`9sMlp}6v*zG'wSV&t{?e0z\Jט7 5]䔂7Ȥ16:e"όZlAsZqSQ Kn-%-*o05.rYm͠8~ 9"i~O\鏲 6u.b(e(F0*Ah.|XpF\ !n:HJs-Ϯ#2:Bܬktg[z `4G HZx̷VQ)ov>[:!Fizb7lďN KYqZ"+9<3U}SNjrapH>&hY{pW &J"?[8#g`9|ǎ:;f)j4%ט FfO%1 9P :@[}jblH= ,}7Y.PcϋW$|k6Om!vfǖZ#J92c~ EU6wn T1/]؛I荐$mף&ΡKappZ4؎s_9Z>N䍦Ҵ⺋J*>g)yOڲ}\UG'nO[(Tݐߗ4qsR~57SvMU* <Ѧ%$U~΀|j_[aKzړ/vXr IˑX4Zѥ0,!IQfOWz;xpg:D;S*5ޘڌ?Wh|4)aTcI)7qךybn[Q'Թf.{ B de^8q+z\ZRtj~xm.XYLui=JV:. 5&-;v߆%%bZ`8]Ϥ#9[gD}т ϖFA#r,Lz*,eoFi4A7p.y.݆t>Mrgk3xt-NT}k!>D>#]W"T.#YvSB0ʑȽ^Am{vr yU Aj'JJܗn)nZF,}|"{U+~70WKY}.l١ ~R3El]-T}]:FΒ'fߟi2ʺ*A·{*)|0YPtub@US[7{ciX,!{N&@hV#0M4S*i!NRhتf^~hW(f og7/Jb}Qy=S&^0kӉGfs4U\[ԭgt?SL'һի1*qHn%QCr֖Aϰfzݞuۍ03xLRQf> ˶PNEbqRYV"-lezHu}*倫N`3L L!wHjmg -9V'aKõȏa~y\} D9̞`_TH,_p}Q{o*2%)L#"jV-vVsg-][Ը +}wGbq5ϤnC/W w翐Dņ9F_5xS-p0mL|S;| הtD&SzN9MAv'4øc.j.}0!%K̏ $ ~wZn.7`/5\猴SMNZ-VF!qOF 3<[!Fj-KվzO:3LrlҮKw d7x=UUn'"*^O]9ާdQ _$26&US1c0^lkizY*RI"y\/i|rd :O/A":^(ƘY?$VgAk"ֶ܌8V<΄Aȏ:dh4$D(a83tĒg}DwdWޏM#mc=MY'kFPCwԫ,K@!_-L,,*dǃ`CFZ<do~gH_%É)]wAm-g֘_[~R5%dR?+z-m1n:iś}f0_f"t<|Og&9;4Lg4oc;yOF:㵀fP`9~v\x1x;] unVngY}r&^g5{[Ҍj0%ʪeۗ_@WQCaP;>GClXi ~uX&2T~ey| G{6BӅKrN?&q~CRjVT͝s&˘P릩G~)e= sm}\. -j28Q*Tt JtugbwL#dq9i(Njk`u2mD7~_ciinw,V^_&DcaK r1: @1, 0,Lxg("u@DSvěF%G~O-G;cQgI]|:+xɇ,ohAЪd.}M !9%osIViIcKM%+zmFol5b. ﯮCۓ}T^ʷ*9rHk߿Oތ,/re4DȮbçϱT5̜4nSѿ7H1fJN@ATH\|jU+uV%KloT'zE;xL}e?A3Q:F~iRSn#KtF"xYYA1p唁CS wv_h[OKdEV&!wltsIVB`@ubs7X8.9׌(Ebe[5tny %xM ꒥7CG-В=qBoPӊiVQ^/s11$@ _녯D_3Hv6긤ҧW*C'D@&h; 2Ig]&Bȡ?Oi\Rz.ؠg1ZOZꧬa'MNڌCޭN)1T˻B/1H0{6kUb^",ԫVm{ѤToǮ!>θi ,${F샹E4WB8OT/`2M鈆Ld. >p}IV,p]^$VE{d]3x*M(4RU`UiPCg]XK!bѪ@Cc!O]il691?SzOIR?"Thd7L^Fv sG+5o6 XjyF8N##B(~OBPUKdSO)A<_V0e433, jrQ :%`JH=;ᬿS6ӴV>a 9n.Դ!m:.h=4,896^U6,bltMa` igUrvO'ʴ)V < HiGg"y`e&&C(&L~c0{{w׍u+E]` ؉T8\nkl>JuK%/S "Op2mw{|QTlqҲV̈́' vƬ1snlNe.GG̊)cbH Κ1F\7)G3R)õf8/k/U 9a? 6wSY-*a9͐քظ.HTϐ8q?l٪ ġ ο+|*R0`2f.$|2F!JcE* Ѱk~{{/ &-rSr!,Z Qُ,1.[z0-yՇt0p"Cՙ(e蘸Lձ:[= V1EFUK+1rGQiIr%͇:>)ya>B#EP@%DR1}J9N }56CNhNsZ ƆCJMP1/\T%Fpo,qу-{؎4f^Ɵ$AO,"y5F>IPCY3Y\#5Ebeۯ4ѵ()Z8 x*'yvaj{boLpKYDO7vi^yvr{H\Ү4{zŦd:*7p~ )%q^"([JP<By`3;tv+.ZrW|])Dq p.r d7{%}{oDHV!ea,Nzؿ|\Ï#B/ Fh$ Ek}Kkɸ]#XrD?H/&U*>m\(py/zTP ?yމ~Et {"pcV/!{v̔hH\8im 魨 a%д숔8_6`ub^rCp S0Jڊ\eZc50@+(@A2 !=~E~dR5t:S=ԽgsLXjc7ޗ<,O_iFKss+R-=; @@A KtĩCD8̡}@TPL[o_Yav72(57N @Z0JƧ2DW%/ͥT1u)qmp\H<BĢwipQZi<>Qb༭Q f$R@Et3/J&`]ktʥHOeJ:?BT33\Q8YŇȻY.YolaINf1h@>rHWxp Ҷ&ԕ"_-M#)o+ Zn`%WB#dz#0d[>\xH ܘkoW$1KJaCC"Οn141./O-Rw`_% :.}1_ɳrF#d'Р?_Lf1t kjdnDPxvI$&yڅ㪥GqG:s[%i ~="vhec}UP@#5FX3THQM[fyoR=hk~up[Uu8:zSLbuX^|#.Wxr &5d'е%\b9]p D+@qB5DdSr$cGz_6Ԍ+B5= 3LcP'Ɍ" }9a]3LNi-e1E;aڿ,(ͺfs0NqӐ͆w{Kh!H=9 T֊¦wC9bY0ʤg=o|uub0xJ kmArhtq}Apo"؀VȏC? i$% +L]*_I{FЧX.a}7ss2HK4y v]$^=>4:ė죜C[ߕb`2FuӃ$VH'6I}.\>z*y;?EC2']9T4M;Sl5;jET IlH-{,M1 {ixWHt i7(Mk?C+-kahK)Hfܘ}b) 0kĈwq̈)(5/W6G&ع._/)-$j)'խD^2Č$4JH6OBXL70)~LF ^-N:l]FT=?ZiZ,nAdeS -椓02pǷ'7B0bp;džwKrK\O^+Ϡ4ӠWW>o7RI2N7$#p-E.z 3cɶ]3\HK+33t勰K\}΂N\^MƐ۬CX3.f RB]>Jf^gl偟&c֏f|R/WFP5xe=+lһ |An/<àYpЀk$2A*#}$c^ Nj”G6ar~{O/? ~UnD >^փ!!됈?$FRU QS}S<=u|Mz3.k-́0A+|499A#jccex@1`(YN4=.n+K2̀n&pCVAo0&`y&ZȡO?*jI5D3㽓-@ T{ 0.+b-=n\シ(ݼ" YS5Կ7̧׊ѩw=lqGnA;4ܧφ',YZ'x4ٛA;q,$ :(r!XM}f8FDzMJgx*hzEAN 5=U-Ih:5wNُug S_W._ݛ>>ގpB뭰E5Xveu^1Bz==n6y}9 YסJ>ގSV硌qygך!}J̋p^` *%j ܟA_e=-lF@+2͓,nX=QĶQ V?qB#?vUo:ɶ@wxY xLW;U]2sUSl3SK)GU8g@:w򽪳^נ k)7R]6U+]cLmmfZiq6V(*$TMRcrEO ?QkvYm"j1l-И`(RJ. $py"GsmDyM*kx҉R.|sֈ$|_{1h\$J9зMu#!Zbb&G;M_t%Çmytìtex&pr`)2\ɔm:GeUyy0zP'cVbSٻ,DhѶnVIҴV?N6/`>\鄂t2(eG QvRE~5qE3U0H YIz Qշפ[{9*cLMB]A~4wE)& (~{u ,BXrӹGVHlT[[bD ҁx`:,4rR0ejA<{5Ž#o$N#EA_e V"!'n ;h|"zzIC-?wo ro7s`-uTsoA%M?wgV\5gV79"=:,BfP J.'ѨY')x- "z9@O:kT@&APA`2'`(V>doC(Ֆh]Q8`wRצ(Y܋S'Oup-6,]>7W*/okK& 1'"6A.͡Wc=v#^>5/`̴)if.=a⮠=V)nq'ܮv$օv$"vI#{^MuNN+V%证H<$Zgx3Ҿc6RN^ *|k :+s -* {' i!jF&m%R Y:KIYMO"ySf18C)ޟ.kܥ9.xq5؏ȭÿW6M ֮g,eb6%et49CbLO) $$yO_L;zbat"\mQ>w ܣb:  ϡFF\kPoXL6bLYNu֬R E9A3f\ڠ|+QVAXKgV ͱ7aM^gեa\. Ţ0]V6.!ʒڪdk'r)(,}[E0nYVjcKkń\絳EYpL<;(KOCql hzv%Q/BiGb [~ѕ 7;e$˵>Q4W)*gZPV}LPըyd⌨g^y *P?.;:5*J>1j٥+߭ҲDC _b)(SC^]yVk|TW9oKj:6̞3>, zɤ^Wkt :j^G=@ւ(TG´e#w!l\Bٷû$Ez4XQ}8_]TbfH-]Ds^'J*/*>l000т$1PJgZstœ"4,ۛb|cYRp>u&)Q؍ޠM#U7&PH?n$h ߛ;6ilr]Ǎ&Z8|4ܯїNLd@ʰp܎Vs8Ac fa*|'+>TPnŃ}dz3~`͋4gmWs'@9FE`T=*Kߕie7OR%-.TFDuHǽ[yBB;vM5?&ao߷]GxJ'hĄx=Cꩄ٣+t_7 9gqYmZq%,zs2AXINVY>jV]D({paD u JEЉ nxR=-oHGPH$'rQa׭YHRdHu'+w^+}R3~;z5 Ij`u2u>3E8_I>$o-˻>Q[Tv%f޲>gx,#:riNDRΒͬ:rc]A*$%&2tE$V}]-DԬH Dv#*#A>셍c$촰H _i5ڻHOYWDɎ tFa^LdߪWP|gzϢZy4.8͊rH:PKXZEΩՋ&ˈTtˬxԳƞ1v:q=WT q zN=-s}g2_% #ր!& + `p݆Q8qq~p '_bn-@h 4j:VHSѻH$bklsg1R⻈b >ZbgtD֤F?>JӀCq/I= -ކ91֨>pO12  Z1ff[HݷsP?bg AXmTo<.>=8qpzUmGuE33:r$CuM)u!պQɌ^T5}(Vل)MM=eO|EwY׆ 0fkvgn{fr1W4_#[d zZDV*z$hTN}hlޕ .Nf^ }"Oć "5<3$_z&Z\ͼ6.AƠ*5_ )BHyXu#%z2(D7oUuìZ ?ER^oy;>/=ڃ, *~e|/j+>|r@ ׭PFX.mSQI $e VwcmgJ/38Kir 7+FMghN3*s'.zBՠ1<Ǥuq}srQGв Ȟ[싉'oT"Qjg,iēE]/7Y ЦԞbG%lT| =;; aIm<3 #ȧ]Du )["q}x+J\籾7/L ^a?ƱMny0h@" 7ڊ j^2ltHg<< `DϚVD84!JJf$8nMX HTEy 8mO@Oq10!H^=oc`|$sYRZSZ x>PTCCӪmpe l1iS tEGdwB%=>jѿt:js," N[DI \Г ߬:%pd{2|wmS Μ;? P]ؙqc1T悒BZgF Mc6_}K]Ey! v"jAqn.m:`{`t.|+7zܷK| dJ.}p&] }[+?LYɺ8LC4gvF>bPt:LΝ^u<}A[\kHߚHs'+ҝnFԟL-<RzyqaIȉ?F G}HKz4u:=} 鋝q\mzp+GY@|dhIqxjRv`(MX63-\5 }\}=̲)F{ :}F_oJ E3nžvt:>}oK.BQ:ȅI<) e3VϾN/\wr4&|q> a|'г1Y݈v}/z8sg%3(:mR\Im9r?퉸d61o!TdKUݢj?J&?H&<'^ {Fl;QϝEr,"gC7Y}D*6 : &^)1]e ‰jd̒xv oDnE8߁̶{lE %YjdT1ߢǣ⧌'LP'P2rO]H΄,߯6qݰ)h`/V 8),r­""L d$ Q'-8̦_| kݡ7J )X]$bܒIR=MRu? <^{OVxHg̩yC߉?,U \89^\֧v)`1E+y88#R}EHbXXUCy_|Z∨= 1{;бXߚ#vp]SE"b v8eqݙb"^URlkouE.)#16VfCL)۫hv઼ Ѷ@()AR)/v"5i86z2l6]!gѬP궠U|o60#wIzo;S8XA״^;E_'FݚusyhKtjf*f d'ozmz<&k5'y 0pU髡Vt+•yb/󷁳8ŖBv4mv32p!qb16#&9蝅[w 쿎l`VJH`Q,@΀aֻ5#|a?u QLh"o&|霡A;AA-u>48Q6#'Y/q˂)bӑbxdx ܁[yCpJQ*%D ~p:Ű{텚I[?W=>'C`ؘ{ 6cc07'k3iK?FM6lqsίK1d!&nI+[_,`Jͺe3 \wJcZt&c+Gcz?[:ٱy&+{B..DD6U#-5_5խ4{i^m҃`E㙲۶ ?^?9ZR$i BI}pj@Ð]Chh(֢*AxDّ\&y٢tBvy`-oZN҄ˁc3dN='5tm{$@v5g*0"o,k(0D0CQ9(<*Mcݭ'8-RkTs fy࿣FA"(<49ʀ- e,%<ÈP )OzYF1H/$Lt !w(V{h.0nd^< .'K8`B e $$4kH':iIcSٸyaL5SWc&M|,~v2E/f] 5k#WG ,ٜ ?H| Y =j!`T?4pṋ\}}Gz'WPAj`cWMQےH\HgdM21ך<*ns_]9<4"]5+d-ܭ|OZ řmE*ZO ;V7A%~u:+u)j+ |}^p`dhQVg-wCb_ &W{x'owL JQ>cf }Mt]{:Cb TbYl8}`Cto _Шg}FB MZx!!4_;׊}M3$Y/fE_lw[a64jR$+&V0ecn\uz% 7oN_ *B偱h%o*^ M\GkM*,@]K؃"7g6.sdž"Lr&ʘχ::qIxГκu^=wdw#ݼ7%2 yXv2d$U팻 S*OXNv6*=l.O!jހ5᭲j:%ڢLZ~xW59%g(Kf=Z]}ۈvo_SE~|sJa7ã'85+^;~zfAgFsi,'hb++L|^o7NIE%udz'͔u'WG{L&:=+ S޲핬㧘&DjC2*\nR 3g\&u :_J ܵ"%hi0C-3E/t(GT)?8ͼ J Vh$xuQ`,eE B=53B[_f-\ƦfB~ m MX-2]Qd=Ѣ^94oo> GLƳ^B&Mj spQ 4H(LJ4ٚfY|8JVγƤIw N;vJ8k$W*ᆔ0W$iccrfK32᝿pI=eA:[vC^tA :x|t55@j<@HQ*Z (DЋ?dkJL6^`Niߊ hC$l.h 80 b`N+^3c12n..}?o̷C+S@OSNSN'[DCΟ1 戦{c]gQ j2̽kYk*5@0/L?ER]q$o̟(;1?8ݭڭ*{O^}.  y uW J;7XF4Ķ&Ӌ"CWz\ 8CVyg Rv+~ wb=͹Zɠ>a"g P@JrۼfA$Jiʚ{~:,j6 ]vL_s))IU[]|#ḅBC\C@zHzV\a1W!IUǮ{f!P}x9Vj;6 3FXH;+*~l'J 傓^/Ɉ\7?> MO}-b# Bx<g# |St$~/֥![YdLxJVh${6m)݉2 ^)-ixFN-55VϤ x܋ &Fe~5ou( @"$,byE)&/߶ʅE/;Lpz*IH̶XhUIgYA嘆F0M۳tcpr > Gs`~ژrq x`޸~,} uFjA7^i#U}OmT~•K-|`w$%k4FI(J]owRsڣ@aC!0s+Hzapb]8 endstream endobj 156 0 obj << /Length1 2684 /Length2 31933 /Length3 0 /Length 33389 /Filter /FlateDecode >> stream xڴuX=%=twtww34C ]HIIw )- |sE;^{bN@i'MhbgcVZ;8Xظ%\f`['(T,\H?25@Bsol dЙTfn7dm CR$]mmkp23;[ ofafo 0YYXN- 0ژ9X@]@F]EKURXHhhj0$Ŕ5@m&@5@Y;]IJSLSOUÍ $:0Yӓ j?M[7=Gw%DN _~ @rNv"%$ bD \EUUE- , `3hI/@JvͿ;AVfo;frwK^ @7{{f Ǧ$,'-ɬ<D Ozb>6;? 2R K 'GGk7IBt;zmrpXق,~ko̪uqI_8Ąf @†w巙"3 okBu3@߿y`ȨC ?@VN!L!CΩ` BfUvCF?'zI;8(9M7C'D-lݤm` I/ 2b k d[1i>Rم?/3; cia?! `Pӑc8)-0su5Ff772ؖ@rCR`+ 6 X ^`RAV?*qX .Ȃ H??OScAA:hA:AdAsAh/Od prl-\\-jAh[!:Tpg ,tz o'w_!)AE?!ol!  ;ܟܐTdCpC_nb!Ŝ σ`\gu/!j%\_w'o_%ٹx/!%:;DC?  w+RO9nȢ6&x_ Ae DJϿW3Hy Df?A*]o$߯? ۟+>5N@[KGB^lb|/j@+[\˗ 2 thWſ>9NA6Z /:Yڥ6HWSVՕO[o%z#A) .IQV(cD:y)jRMt,@)MJl(WE+8Si]E;|n^)dfsB3)@kh_.c<°y9޳xkh~ r!Ƭ[laʴ oH{ :X1n+S[euQk{6b(@* km!2gFG14"vq ڜ}z̉{~ ?=QͥTåT{*tGpF/aO R{%L+]}G! SĨdRPA Pa1<@ h:uVk cXL7$vhj5$a$ }' 擐FxycoQ:`R&;a~u{ '*Xq'28:m$!Xe#vq:Jea[MF:ŸsJ]gYs򒕽JdتZLZ=>a(K=^&lbD#bA$(6@ 89zR 41`$+@J O5Dm|\sUO=wvt%o_uO|ctLV{zqsi]D:W2biP V./a)}([tɬr1>v}+pc* ^Oҕ1Vg_$0=-s֌'4~_bAЎ4a3(f"xfT Mǩ<`'"h>Nρ YVGߴ1aۡp}-?O=JJ^(3#g" dɱTi:c!SR^e^ IQj+OH,/T _~7סO6iJQ9^^Ԛl}d+4Q(B&\8R\,Q58i)~ЅVaJ":Z9cv~%zpj}GWynjiaվ8L~jHVA.LdAOQHY+#/?xcDپD6a+^J}+ !%G/c}45Q,*:h{c]sѼΔT4냈2ࠧL~-ܣE Pr8opRx\Pyxq5 %P|StT7P;3&Qvszsc+}Mi゛j.[%|dy/|91*1.BG V/S۷\p)nD\;;ϙ\']_]=4'Dyg oDߓtYҔ{{Loxz5Ya4lJeكɜ R׈ F<2'1j* 2&dZT#Tb0ē.X6󙄁5Bg˹TJEdXVopۆR˔ڮ$u#[y2Lm ` ŝbtvlRo/cv }-]}*+Q׳WffzɧY߅􆡗deG-vׂkvAm(PbZ{MV/2`.Ns %XOj>*mn|H1oƨ4FxZŚu-F*9OX&.Zd9uie<'瑥$3c%SD \Ј(tpޣITޙNTJz84 :50OF4`|~ji",3u%՟y֙0 ywwQzS9]azvHɆjMjk *J=Θx Fc<\k)IVض_34x$[\ǫmT"&ZAyLlQ%"oPW r]xʂ]8Ti2M4LiL\/Y4 g׉wcE1d_y`܉Vo=-\/X6c#J\ X',9IV|DxE2g )LwKYFpP[{:M# !/3"Iv6я1%:jX-yl{,b3~z(PRi@)j].DsAJ(tHP#he߽fSKJ߈Ljtbkolvy7rBc2y352:/Ji[F8_TbgŏƾzƏ,%B)2١*ڕ_]Q#h,*:W5`_hD1vqvBUƲ|4h?{}|(~>[Odmk9 '%N ppjE )9pF]e|ϦEy^ &lסmHf1aX{"/A% uشpEiyV1TCмW4_Srx5"m` q3 [֢ea'u奛7VU굕|_CF=rMGu@ZNR7=oABϲ}O3~Ek|Xm GdvpgS}J"lZn1l*B 4g"mD^Iɔ`:%'0|hRwK'lLALb( 0 鵲-i! &l&~eܣc1pઠA:֏z7=tchlHT\%{N]]\)fcHK@:Fɩ(+l#zc; c/lx"˜4A܌؅}A!RY+ h#K̚|)ej\,ZG%KI n g8Oѹ">|Qtw] E̖6M#o3,Ci,o6I2L&~ cBMRJ<u1w/i2fMϤ4/Gg?n[Lv:@+ жb|3iGInIF^=D 3Ss:uُBiGqE~v%jG6Ilo8 箇ZW:zͳ`b,-ujI+Tblgd/CZeks Lkh4sՙ(UX ;RFaz(P1PgrA6Ve!t%l슺!mT| 'rP^e++$$=m7leDj>Px ioDzY!q86o c߶E}Tzy\Nn_g% 4^w7BpuL6Ph FL d 'z&u_he 3+GM'%Ix7&Ȼb 6K&ӦJH Y(v GObax`a;AR9v^qgF9-,z4F*:4Mhw$AMEZ۔_ew Ys()Ob EZ6AcL6p0iX,ɫkdQJvk ݳO3ۯԊ ˑ0r ;?y~ƱGPCuLOb(OU#s/A"{:Oy^Bx%@)~,zkG}F$$Dڛohc&v?ꕡ8@ɯkiΌ;k|l0RcH^cz~E-5?͢0+! ^3Vaɍ7ҺO!>cpWNݩ clEE̱b[y{\S*bĦs>PwVdp= Qҵ\Sku3jqv#\}?6-Lk)a"R $FJn–"(<}`JhQMn6 H͜mq C÷e:ծz%)eVY{P%ܺeSPvg}`/b$>( Mg~G|ɐ?03lmln+" g8Q0x1gGSn'Z.gG26s)/eZA KI:bH97bxWa4@گdGTFy)&7*pIBfu׀i(et&`[™/6˭-˜绪GĖ,vkhoe+Gtm}<&H|#'0#:pLXdYHI*HUhj7#Q#FϤʼn/W\ZnVWryX5i%sڔk)V &*p$U|+ ޅ¹}U/A[Ng?ti㧗Q)ST$ӹMцQLlb=erUt-k#TӒks |-~)ԗ_2PF;S k#d~5pR^,ak~ůI8G0iŹo,'Q̳H3u!ӑ6A!`buNMyj7Muo~ilW횻P#+M7^ }΅xm6kg, 7&x\SA$ 뵡2;b<>d#b8H=V=ÆYnVɫr}r>Q\*ia oq!  -1Zq!d֚$B/_5 mLQn۷B@K͟[:u(Rpt7~󆮨eqV+v6W׎aɄCw]}Wtn5kpǯ_gI?3{h~?eU{c6(qzb9 P>3Vd1z]7jR.Lj<8& NҐ& ؇MVkwƖFN!IY7H@}w zmm79.݁V{"20ZRU|9Ps!އ䕾]2m9 =E$"'%Bm>UaIk/Ue^P'ڶ@^pkf%R2N{EV;GfxQJ{74r "C6>T ?2)Z,>'Gyg&(J<&XkH'KQCC˜VqaKc Gh衻}pW̴eq/ҭ=6]s-ҿf䓦2Qe@rt20. ZnR;bnl`s9lU—vB_Shk* 9~C z^֒~?6}ÑIM}+kI #췣/ZxZfHu_#@] Q,Bٖ7K69ml;S^ˬu.4\ΈsSA?h-x_5\~{64>]-W NL,[m jnmN]@ٽRŪ6IMd$1xP(MzKa}9bFEYVL=7=JaucȬ ȋ02vV?< nu92|lPhHo`uT耸(Y"@=&W;|p^couäeѨhˈrjݑ X6dB7b_i7cS>o!d7q'`꿹{ΜWkzCj^Qg 1bl"m}:t*x8[.bgA"cDPڢ +1) R0=eOcǮq.B8^BwϘYWYRN"O5iNSf{Nnλٻ k;/S Ui7*d{  ] ~|#ppkk^Z%d^f5tToƤt=dmo7'#k᧚7܊ SĊ E\O[6լ6n^&-Su=ٕ쮌٤XXk#X0M*| y֠nv k`+'Mĕ*-0S/wJA^ǫ '],ҊWB&A;7t~p6ӻ=Y?qY #1 aA|{1K?7&osYN!$_}R;k[rQ䡚U.-WâC%A(JF́7Yy560Ű#~Nu*|"'RuB/rhkIdoC=|cQ/*[I*TR+G|un4W90=4?5^11hު2X9E$k= f4Q)}DE Ix1&xEj0j7p#?w8raR gOs;Ÿ QPc-D37ƭc:Y(?(.DF`ȏbFn0^vD"p^:O_9%nRg6>n:ݞmS79y˕ qunb}3Lxrb|c.0ʓð V5[|c =`<`}NKJ~uT*Yw`Sf*GvVYXewX=4{;&tBpFF1*S{(7g02ܷK1rۿˬ}HUϨ+AxV\_á*{&Qdzz)jzT^nk4C?t#~Af7 ǑOEaY{@ p/̳mzȟ~ܤ0?{k,!kstpB &D嶜ZIv:Zom6;f.Ohd=ԒJǶqO'alK.qrlΰ;f*LJGS.vtWO>coֆg}iENGR99f pmW ap=U6D~h6|ϛsݙ _]n;Ȕ~jg3,{NQz#"!d25~ѦK9kK'+=I Fqy~R^њE0Ui8&Pm\] ~fkOQoj0 S{}p̢pN6 ̫Gb8.oأ[!$bneCi-V"p{,ol2e ɈmruORW_=͍4O6;1wfDg(ax HJF ^ܠӏr{inƑ$kt`O[^aʑX_Z(3G{rVf_DJhP,ZUUܳý|[ǎjZ4+%6:@9*^: s &ⵊ(%E8W-Z~ |~Weese*:FJR&&!s$TUv٘dz9%(dߤ,JQSRv NStP)Anqr}TQ7~dHAW1c<ri%gzhLݟ]A%@t";'u h2<ɲZ0tOUc)UdIR1fa.0ڹƣX&yoѥYf?gҫOZ=}v\}A(D!Yےz/+8~DԾm۩.M"" wO:&2,U^8=<cK}8?Gj[{bqX[,z90q7E]~4LՕe !rTa}$|el#S߂x}w@&;}ꦟ9 19Faߞ|b#K2U.B2=^E3A2".BI_"+&2s&#e \<."O}mlp`:$Eai9P`V:lty7r8dhU7f8옺:ԃ?3!~,孴ևF 1F!#oʡ}X)­3ͯBWn5i`Od"cHNA|hYz/嘗/K/>q$!(8<*8:Ъ;$9mON(pv2Oy>=޾[&SxGLу՛s*$IF$zӵoOjɸvQŤgZ`W,+fJzpGQiJWs{rsH<ޡS i'MSCE?lݭ ;# >,?->]qUvL^#ϡx`3v7Z.=Ya͵m/WHM޺s&=iYћ>{~Ge>C`51lO|h\<]Qꃛy x`5q\~c{bjڼ;,sa4=[1S$e/`Z+ xKwy0eh̝gyPy9vgFo"͍AV=xޗi_}֘nڗ,ĉMi'2g?_;HRFatp"^mN :#$T r/sto_P/`#wYUAXQ1F7lSp7^c#Gm} ǗބPh{.M׳ݶo511mUe?" t.sBW#ؙYý-\ ~LĢbzv)1Î,^wWu7 7^8푚-ζYܮݦԪI&H̿4Y&zK=LWqy]khwN!Iy5DuËę1@$d.Onjq6Juh^Ѓj^Ґް/`07j Kӣ<18*-v^7J)k=6lVKMTk $u6#e;V`?_3tیaϯUQǚ0xu6V`@X 1)fCr%>9-]$FMdyBK&п֌iy;\xiS&< DYKO7,g_F{fd('f:z6yqMc"f=I*(y@؍+d)$`>4wr/c# O4Jb4ˡn~1S%rB#W̃7]1GP8aXchA{xևnB-*GEsH6Ev,oгz.ͅ ҷx^BgCqJU:KF>K])[]N9`=\XFfl`JG*-ye@l ^vN Vˡ]]@YWٰHǃQ]ўXՁeAO%ͮUmw(C`LƀV`J;9*:Q :)܃,-=8'#f#S)Dkȴ+FJ+) Ѝ~$Z3ږPn!{03oIφedp[ކO$X _G.|㏹nRݮ`:NJh Vz˃l\5`I^u,F9ۏYI&Oӎ†nhPPL q29[!qUy!. njj|#{&niP 6xQ߹YM7W NfN5F!cubVвP 2 t}5 '% n٭.X# Q`uC Jِ+zBnY9_:qNG%9ՏXWFO*#pi=keYuw`o(<\g96>vh=~lB{t@W]XGGc-iv}k|^lW<ͧGEp~-f\Xesk5D߀vІRLav:"vfQѠӽUr.4B*{(-ٽIْnY;wrE&ޭU0_FحT4 Vǫ)*9;BF$)e/5(if-=@zCqtcD{ږBA&+O j{.NrZq=QR$*^J#t9uUt+ +91Y"ëD8=f0YSZȱʰݯ}ɰK8vB2Vr) LׇP 0L]_K†Qh w>΍ѳ <3 %0/7LmBLNozúM8+&̭`Ϧ aLaPKn ' g/0^aWMJ{ƲzNfU$60d>l^M2"t%|5ZUXz&4mk'w1P,et{-=LkhTl7qp|a=1E 9vS! lH{&ZR#w2iȋ&M {pXd F?YiuDf;Cz Tim<9'""mF\$gc</f]p?Gw c&Ma}b-ym=s,{ AqaAuv.A-ڳQh|l55e+7.?H=m>_9xq pʗ( jF .=xkeog)^R/, ۥ> Y䢹U*M$1\0EqWqIs;e7YfyJ*=T'=!ƦJTmsI>y!v|YmUqkN2/ަ'>aaޑ=9F3;| زpH-.'rIbq=&۱j{P1޹^ཬpo¸nMU.~,oMi{KluNgߚtPyj0S P?'-R:D2h8@5h|<޼;*<5Ms[,=͋) _)n ͼF0BPռ:M%WLAu;.4w i^u%7VI3!$J*?;ث'KG֭> 5l~sȎ(868 jmk[SqՔAlJPWNH5ll$\Vd"RM|'e=#SŲJ:L/\[X2sH a]J Ӈ3) J%a榒k9\GiQ逡L̉S`;y bcּNũm}GR~{%ž#sq20XrU9駶 O;6oa{'r"ۦrz<Kl vpfՇtнkgفboD > ӋdS`WsFͳOHF*LOD#vbۜ~.C-ynzJ :|TЈ'aìQf:l_ ?8cZgCwsNp9p/N?k˽:e\"w T́VMdTҾPF% =9n: 9[RL`M d4y B[ t̮_|? h9޶-O Q( x]֥܌5{Ԕ/L]SrD 6xGun0rm9x_~XC7zf6e~%hVe.3dѨJ^6(1qlhab@AJ?z?u , S^e(>#x-2dThx$nG+c1 Z!*Nӌ{ 3ՐƋ1t+ZVvA?k _g펳-_icȄhDJ-BL ȩxjvUC)k+͏X DžDE3XZ=|vh.`!\މMd*뀴ߖ;x>~n وV.Jjh\|g߀J%0h>4 (ױ 9?9+"LIPm+$1^g#W^G.Em'%놀(3؛`9M|ҎzmF\wfZhw A3p/_&it4'}S%J1;F62},=ƐY:nXb@u QQYN!PB>g"[|>R 2}兜LlZD=Z}t 9bU͚,Frf3"ACID#}߰(6yu3 Qnֲ1]wD '0`#h'oQq j>kBЫ "ZAs{G'%/wڧ556EAb'pT+tߔE$%y帯Ts\2@Ϳ8x snaHDΥY-U4) g[ U2)⋈t m8],o3_cّdp2{=LB^X 'hOf`4$VXյ2&@@@A \BH! GbԈ@vl 4˕tW1e9ֳ&d!ѧ,`:Џu{"{aS|t* a^Rg¸J|fvt+\+`;, 즾OButru3O_ᣜG'O>f2l>PX M>l@7/S/N> 2t5a::뙟 & $zvx\}8qК=]O#RO`8T<-޵Y2}9f+Я3W,ko7&bԖݶoXDD=NۀC 4a Iznvf,s+.Z! /^r} %l~0e*8qm6AlLSf=]Xϰ ae+V. ԜI5I+x^"aG (ͺNb+ZTw؄P<ޙȃgk4m(AkRMrRh|S@Tl\LVGDzzTgFcu"82U#7G9Rj`t]#YkF]+'[\e#MaU\N@5բRO s|2FSiF4>h //CQ!z3{`Tz|X_:^ =/VSܖR_B@j;ۄ`0VMkюeJۀfᄕIAM~6ͼqZ~;Z kVu=D>IC Т`-H$PKVQ򝊌/,c?L1Vm/D9h톧wE[-2/2ց0&boJޞ_Ֆ]nH/˯}껨6v'Cg`,PnMeq~R$0շr Zg*~u~\AJ…PGo áEi:O匝7 g!js% lmDWw]١ '5 BhD˃,Ү>o4ddg[^ha(W%kB<,7 (ϏWkE%ρ88AV ~zy^/T0=a.(+g ioG{yA|@idW`YYGTNjz; *RRnv%]ݒ?Mi/Q-ƺ WG>vO&4^_ )dS牆h:@0„D̏^Z :Op 6s zN(aC81YBk(2# +7o+.jn}d ƿbYxUY&HJԄ0]릺, yjE" VVk }07Jٶ\o*/)G6**}Ohi^C(K\P-hp5Xpq $yIBqNC@DEr%Qʑ_ΓE$6@Hz$zڤc=]^U\Ed}ت~*2=4F+ދ@h.omʌU ((rOKaL%M/3`u+6%WYtx󸏍ɸ!>\}r>7,ڡr\(MCYY`f悬~9T,AT/gOHc`Q^MPsV\cEc#-c95qq Y빉_(۹}hmP>E}v-A#S^(/ET;/Yqm9S-hJ74> ! amXtv Ʌ. uQ>զ篛5j{ cYlH|/fvu={jTWJsi77ԷBcLǙ?S|,ňp?0mN7;݋j^<|`h pdg!.k[X9, P4Aղz{`^L2BtnGڷARAvfoL*!/7WUudz狖ݫ;L:'_GRzcCkgE栊`%$]ʒs31FfFPa4d;I}b[ m"Z,nz6YaL0h)|~ |Ԩ'tyS6P6?|Y,H(\BSZ.#~%+9(apjӜlβ0 ˶mIM\p5P`X44s! WVx aS]OK{Pgތw"rEu*v7bhgh G%֨ ٲRH,͹ wX:LZ⨧2xUnQy=Ai0j%(ջGjCρVil'~MBb,bv Лu =sF`mP$A_L^FAxp(۝+y$NAҗ{C1HX-"}uoWCuNyS7ɚCICB"4xV'ڑЭB ѯg4rR$a4R ,MVU׸q#ԲYG]?|&OI1=;;s =&zGW;h"tCUQB3(;}1^y% |6dDWiHosc=b$5wGCt JʃV1l[Z:BԈ02){K P9(<J GF>q.~@K KL;TC1 8NQfJ^b0_!G "bGbs^]^+eܨXj4 {%Q,h٨,/ sPvCi0ӔjI Od1]l w<6i PF4OSnz!0n\5k*w͏, d gɺA U\/f+="V gPZPmhQY;Z"J.5ukCD}9>c&L)0kFJ6fK/KX..MSm" 1lvㄝTbIJT6E,5h ~{fd3Kڈ[7ufJ HǬ҉ʦL2 e3ԖF!8lQYOT~8,W"kï&y{bH#+prq XSM_X8MY$+]vK]b Jge0LG(S'6/S[fKJ!#RKr>eoV@ URBT B3|5BU;l0@ Ryvc^ss Ar|4R GVYۆϥT]TCHuia^@D]_̲?X5k,m ]˒^RqjF,d,\t[vW' v~Ԧt{rF?bPemg-^x)!kH iym}`oCr'0P/ޝWOK7$El GPs.Iv1iDMz"s9[mZ3Y7 )Bޜ!.V*b5쵄:Ir_JN5!>=>p̛1@ I(0,3װ q}UVO DA,\xaތ}8{;ԅб+t /n7޽Gxr -Ř}y_UPRƝN5,?Dv 0Fb+v=?KD@K9&Lo8vC,oю7wLbz(µU*/5X}~IÇޙ2T*?cz9UU=ۋ2J"T$!L01Dܒ =F&vM>wzZQO/_15BPuO|bנxBcbx) X]}Y:6[+CLSFVcSn@\HᕡThohu?X͸Uj7\x͐ոd~*lC/=бjsxO`JohD DĀ_k7}H7=TÀ/&U^b ^Pڜ:Je=0 ;T aSQyUIQn})ԇpVdwTx~/{v4khDэ̓4಩vM>r ],֧*EW*7 77|#G91O$?ZB JDk Uͦ9A}7okL0F7+j թՂ*jI'p0 C//I7?ܻIZ\?*Ւ $"Lm5q VrM#;+:|zmlyT.y]Q4e(;jL27u1uмm>YOn>9 ..HEᶩaBo[ve!=,5*71 OҺRZ:DE)ޜ4LnnэY;VoijKʬ1 &Oّ{/)V_"Ş&! VȠ`dT(;0s)c,)p*h+k?jAL@=Pۖ~#`'(PjV,W`Fe:g ܭ' pұDf;F~FzΚf_Zrv'4@ A5_IJk#&p`B{#sWbd{9 me?s{?H 5gK}ɀ#3gbW0%N&F(Xz( KQEM8 \Ttfe3m A [t:R8Χ6@Tpl2v~QX6+:!^6~{FqРKhjRg̛Jus#ɀ%Q; Nd\yU(_) @MxgS`63|^s Jvz G83l}h?;2ՊXR?U܂`D;vz7|nuqwsZ9:fr\l345T\lI"C6izif o1O5~T́d+*b&Z6ѿQUkRcCER0=əӡ@Z\} <0OMD^Dkk045u^um4Zݍ&9>=Ri.fuGF9CSY؅-)')W e %HE\g:aQahT"aq܉e-ijU_v_Q#uDq@{ݘo];Ff٪, ҲT̮iKj㪴P4|u [Y {E?m J~=lPsһ@RW .g ]W9h5%c=%ɐsҖaK ^b#k!ȕ)6ck7ȔwӀn Xߚ6i>`&ed ES?z?LyCDz,z""Qj Z8dBdb sL}0o7]GPN0>!wsH<25KJ6&Hӏm @ s1axZ'Ǘso%Dp! B0M1, `qC<~%0g$u%%=d[Del Y|e $"Jw KX\,`lw|la| ՓYKFӐ`8Z=w>Gl_븶 <6ɵPkSgJV~uf>[1xDžl|cixRC)D8`Tz&µ e> RJ >Ysp^=z&1#XJbI]K[F眯--x#Ә7r $_07l\" v%ɼ]iqW5s#COΆ`Ou菋)r:HN(]QД үg& _RDKo=e_,|5ύ%Rų}J4͞9*:NOZUGMŹGH̱04{7aov1st3ÔvWg1K?5034Dl驙yt51ƴ0!4E%빛eAkGFIܟ|iǙz!(~2/C`uY%PPWT’6^%7c*|ՇSF`xTy"bn=Q' sYN0ZtjJ040^aYPz2+݃?釜ot /gNZ\AEƯ0)S7Nj6֖s:T !92e] 87\bg$pw7˗kPDk(vImy#_N0|P9Dq94s auI:J[8K,PZW6WU'o\/i6""τܟl ҝV.ֽ3߃q+N  IJ9֓6J1&}'<,M/UrqOPEˁgJJg00 ϴ ddo?/\<@ KH_CZпp8 LS4˪<*b3OD3geJ%䙔=6 z{ZɄl3*K}GzxRrL&]hq@O_rjGr^^Վ8%C.!8`t+ ! zC!i!RL)"+$SHV؜d!<2 4TBVq}Q&*tZ6&q/j2^mƑ`nEmEbvwޝxrN- w{Ј$:&B#4U/AS_iW-'DeEZU/kii&qBO8&rpz! k+ȥK*C,QJ.` |DV.E By=e~dY?^=)ڕPJOمE"-.x *lyrd]ڸws @"8`1eC V0遮2T.-kحyȚh J>9L9o>Kv k7bApY@Q IXq 9P!ʵy\UO~rƎRR.5fi>1C! .ڟmD)|'?! NAf*UMhĠTltae"V8~ FY[7ž}&7G{LQE^DV|~REX0y<֟p-cq'Zh`8k-V3)˷{ht@BߩY΃3tS~ei(’OLpU/*6 ܷ#a<Yh#&m3 ;5r@ɦ%T4>ʿY׏OY,p灅%燎֦j9]H E`3rjmU(EWm 9&eRa[_:5HCZ(R励[M`| !)G(\_u!^&G=*;Vw.qxCRF[ $d_ɝyZd? EAޡwWQU$R nsj .MY97|RN NDzl/"FA.8NFgtjt2T݈]Kž+ xH >箏K8Lq PtB ƃ}ƋЍa5EѨi- WZL[,.KU?A6@뷗'E)fzwd2?zPNzM@Mu2Z%f00U!Ŭ'"jFk&j>2ݗc.9r:]Vc vΏ!Zo[:Ks}Q?t` SVO.iK+6=GV[ju(PJ6K۠ endstream endobj 158 0 obj << /Length1 1912 /Length2 22963 /Length3 0 /Length 24132 /Filter /FlateDecode >> stream xڴeT\۶5S;;݂[pw#{s>~_Vc1W[U$j "掦@IG7Ff^ *GA!4qvt7qܬJfnq>9x3_b:8z:?zoĤ`ܿe@73 zY1I_Y?0s[[?.p&@;Dp,\sk3 _e,<?*H@ר|̩7hǤA &rI)OO?MD ZjEG{YJZ{͕̬nr78X?/Ɵc0rf@WWnFWS/IQTSFV/; 3GskK+' _b" pt&?7;I7cA0&@6?G&yL,ec.y]9Ln?Bs7H꿰-P67k/=9a?P{-*!nN rߧ_3?G,:|iT Q4S Ix^%-9Ӆ#K *n ʢ,v5H v(զô{lO3W3 PGdRXFJs"WS>ՑA?yezGF_ٱ^Yky#>Ƥ_dv޸ָ,S_&zF%}I9خ; Z~"҅(JŒTv;hl?1 :Ef4v'eI%XJS;(dII5Pw2vNɼ"8=< #W~T֮%8+r]@3+dN㘆gCv踫cK4˜!LV*{MeNas R9{'SIkĕw7eҟ6dyS` s 7{P3FмQówfu7(~ih}@AG[x_ΐ!x%0{e3YYD֦(V h0Y/-@Ku]hBԏ s$:28w9,@LrSxIU<~.xRsُk#uG`5T?($0Jk/YpP=ZZKV3X$ aV7苇8w yTڙk{R͎.=<݈;6^iReZ 9HM`L"3CF0gKƄ+\rK-E?kdzk۷`/N#p+3"Xg~0B;qQDWТ#֦gͮhҢ]@ [ps5D'N0( I>IqBC"_@U5)Z>˗d}~X#Gi Ǔ99,3ùʝ#u o.^.e˩6et`̺JgjR r;Rh,EGҙ绉y}t)eOǝf *BO( 8Q72|ι7 mљx&jډJ3ßƼ_3Oی} 1ja$itC_8gY 񫧃P~*Qo:Wj045lܲ6vysis,>3 `?b 4._˗M"^fʋ9h](/X[ [;ƽ)n} Lk-<WלBv2& $`mP :/Yp}=~**Iz]{ 0 eK ULRWTO2VPy½U'0٨O:Fg8'-PKbr@m=/%ZN!|)d) p=m-oꉼ{ >Q[7r2)\Z /묘@gFclKz0A_a#F9̧( ERv\6S@>Wo(=\.e`! I-Lq,!a: 4HnKv[C:d5o3!R&V`TV~)oI`& Z)'阗|BJY!O }:؇-q# J x19Mu'04c͛hK~ʟpp.+yODkv(6aݬʇ_"921ՅmnV=BI MmxK"wYmp^{Js!ٿrnxV穠6a5/{WG/hFarHRO~Rѭ^5s_ ~2G/޶c $l! Z Ő b kxpR;*~Lj|$k]w]C~ycD,6*h6NT}G_ty%92fY#;+4r/ղ' xx줩xay6,kYH%˫!+,e VOphxaVd2 yŰ<"eqq ESxheM>& UKe1/QˣFN2RA;g(nNvܵ*Jڲcf_c`b<_jĂJ.8}WN ؿ*ifd&\y N1DluD{ wm 6[ܤΠKdRSk<؞3T:Gctmq洝vpuc<2`=\FBU0keP0M*[^VnNSGv)T~M1쯢٘] :W4(&;-k+Zz9!:<_Tbӫ~R);~K'| 4d*̭ٚlba@1 62ta">_n:ЊhJ%mtݬdp <Č i@=3 v2)|8@0X~FY*4 H%ڋH&֟EbJF%:usKߛ%6V$$:{L(|8V8)S."Xr&zބ.C] ;Q E @ MFɄb+ͱ-)|_{A''W /<MUL&|\=S~E>C9fP?R)C.3Bُ-™x_ vC}E_?8 _xO 롼 a9di~1 d4(+^>2K6j៨.=J7&/#߼Jhl}Ld>caIp5z܀vHśX:>-y*:L D(2vDhvJ[$؋g066XV'Gr X@,]#9b?}o KC*j̪Fo̖<l!jM0W"~À4KGA1Fsi!RqpM~n o2H:jىeo]楩4z;-Hz` E ƌq#\!2ܝoqVJ`'ʪz}qP?cNn~MMIs{9¹`HZ82ve; ip}L)ٯ *=s$sQ >9V&aKzܪ|ɸq`}Rð/]Km*xNi GU*̊Sh6J;jv=LY&gJDA(euGLWRlCu=-Hm?ۑz !_7-;Q# ;oU{o[Ue[`\zˈs{,5oJ\Ľ[Q#o\ 75G|!SaHAcˡ$Ⱥ2ꣷڿ.oP#sUAHڼAk_ΜZ73YKT" 1(^.) ˃DX{Pl[zN2[CLM89KOLedjuQ^g]*6ӷ6]hzPXBOhRv!=RZôv/aqk&Bzsuay 71t*)ɣW¸bE\d6䖻K> (ME}M驺ZOz,"`׾台2=a70q%uJYq躷eǾe_ =qh_`prZ?7vdٕ*S~ o0 Qy\QX] Ux&b̥2XQjW;2ua;}5x {ir%ǕYuY!of@)Tu )'qdݛ%CBS~?V#f͔$ߎӎcy39ηlu0𦷐nj#Y #mզyә*ia^zY u%SvLclB"`Flkb|f)AEE,,m$27'GQ '߈K􊈋~l,KɏLy5+ylm†"'C}i1ĸ\;%C`<˶ڻ,w<֭|}T}i H !G|XVB հc}i7n[]SbQy0- /MkR}~7"XZK(I|E6@+>{P?HQ0<:tfq̧;ր3v0ޣl֨v@kҩt"S= D׼z\!gJm9 'G ɆY2SxdCjuqϪ%sLٰ̢"-THݫцɏvM`O(L+ae?.Ba/%x}r:`P47q/np-y^'Ewr" Qgw%U:gBV{۽{?DkfQw){Fw$D**j~7$/H~B|I):4OzPC|_>ulh%SfpuU%pQ' vʅ*;ڠzMԗXI "lu]郻P&b{τg,f*[=OǁT ]aMY Hn/ns'ZI2DďmNSXXuj2sfn,=X+UmΤ<+Χ1;^aeoƕ{Ә s3]9#iH E* a) ['&Bɥ9~ZȀi1 !7V4Qq6/+MIRпc|QcQY_mc#7+jaE5@$^'jHЂPїPR"`h +q4SMZsKÎI霢4XDH^QI'X5'(rU V 1|u0pQůBLQZUڌY϶: db1WB,$cH"qՌà#CJ*dD'Ç8[x2Ҕ }P#XF="PdȂMCV\?9nGuyd3BunHg%v4}61(XKa8uinڷPսd%0w)}x̃qe@oRp̋Y+ JB$+8zi|ʫkOy H[ DW $+8 &Fwo ;Gu8ok34J_TH[ Η9utZX, L>OPLZ$8HF#.ý#NH~ W\t"9!&5A" `6j&Ǹ63A2j4_MgsQE5kÐ`4'dX ,Hù k U52Af_M-u%+$:NK@Ha״ЍzW$A8N:`Ԗ="o0#]oj[guR8Ҷ2PdJ;ðP݅\,*N9L)U,F5q%!wWR(& +dM@..#!SZ-OEM81`!+ϝ7Y9|OnFǩ?h;L7j5Uݸ SiyD#NR<[W*\ksI,d1,u2#8Tǒl~EE[Pzkl$ elFz8OJ1k"Vd|_@Wx L>0)ń|ûW XABEmoŲ ⇄ mGi DZDȬ^xMGb<}m×BT=1--T8]ݤ,Jzmk+^zD~k3Zos83VU +IU("txɧe&R;ϥ>2 0g?pz y)$r KZDR䏊#.YX؋)({Ir:fLbOU Š&*ݞJϑ8g/q8r#߅li#~ODwOsRJl RxS6E~f[z" 51O?[<^yDT/%} 0QB h v9dwKog1;t VvgVR5Mh*d!aqR?d3Jzs}(jYSc'p;m71i37~}ۃIo3ɘէDGHVC`O P3[wil0%D̄O*k}Ǿ^^]}ẑ"EVg#=k^U>%eu v7qx $Ne%e±B{a2Vab#(_73,Lu qzv]\-dl/B(uӵ_up& O{jEHۅz~J""_iڢOⳭkgZilA ?Z͵y3܂4 s+å("k%o/V"{CڎFT"O1t_#~)4vzgj$''5]YIe9wE!88G%L3LW!Y\]Qo%O "3,'V}l6VܼۢsQzmh&o굧̔\IzͫHg@ {#xY Wa[* ܒ$H@=6u }v(-GKA8!GIA\~?F IaKtv9F]Cx׼ZWc 8NjrBL+>jxN|ŗKpnb 蓇y1Da"Q kҴOjHt-(k4bp,ekSla3-x x!?Hj:""J#4J))T5e]`]$FEScBNӕqD0"2aN>K.\c i2nqԲwwk)/S4F-Oi8)VU e}r$(MBZ`!/>R%%s\oN1](CA bǠW5')&q3۾9ܑd'+˽l$<͖ xK)RVۘWz^n{+j`v,;˱wqK,ڲのTGe].3 ^~gqm襰~z7(#I'ʥW'f\R:^i3Q舞^`)NpjB7 ژm埐 8\( C,5w$ vŔ&}?Qe;9f1vD\FeB5") 6Bs9+~#\siM ݴr*ER)RA앟R ZPT:Fbkvś6Ro:ML75$UyONhȸ<4G=c0R ?̼ TneId_9sX%F:HxEb[&wSž]*/yZZLLbj1i.EA໊i3kFetH{ $ZRcM& uo?V4wGdʑqLhHZGkܘ+~TmzҊtT}{+u$%ltJDD?˃8~ԑc=dN{&}Ζ;$Oe|VyKC4١W^qj"9I1W2cw4njվm(2""Dy݁0D֪,{. RN]9bLgťh2@wkstVoJ0R/P ` ^¼[/у˦bNg^ xfo٠2L)EK}nMފdU(S.M-wpjٶ~}{eVLs;zsMNjsjmcpRke>_ MA0UZ/#:<i+=eAEU-/ \ wDkFBΣ/AR!'.up'g2UJGUhZ6t.hV-la@g^w6m =ȓp5MfMed/QTfWSS(Rzf^.Xƙ >UPg8dfc ;8H_%l")FP {yDXEc I 1E}UK&aSIYM^] WB6D[_^AcW{Wu*jGvţ7?՗J0:uK.X>|ˎDsxдsˈYELVn}S(埍E;D%!GzІ5dc7vxZTpݘuk[|5aWѣ6cGȖMvDT H0d1sCvZ=',RR[SRI?I"*l 6|(E@J3j!asqZN1;g6InKH !*0>RIH0owuӁO>롉.wOſ=—nst 1SEI\GWer&abߛ;Sf<4&wG Luj,;njLBmՃr\; b,Tk&rPYo ~@@ɘ6懔]=U'gJ ;Nbne؍re0zyQ$q#ґ,WLCHgdb0vT}CIPb>x,X\. !ь0X͝ z}&&q7(je7w)#ӻEQ.Dnיyx"jo7)Fk^㚁>ُ<$슮#"}ǦDȑz1(B~pa/Ȳ~sh|z }woLnMO^9J8*ٴ&v7݆9% %ŭ9BS~C#$aw%K[;~W.|燍 7ժ0,flB8*LbDJq#+;NdO+Zy!TnU~W5GO,>DB@" $bU l3H[eLi${$ 1Zm:j~8ZE 5U&y끊+s vchqi Ă7F*+xwJK9n;P{5*Sm΋.38W.'U$ЮU+񟪓ZB>JIFKʶ.XGIW[xROm8.i.tY鋔L b}Ñ夁"F F.zTeasd0hfncx<`*/zL4[(ܼ:P!xP?uaK>bꤿkV eYr ~Gz37w6) %} Ůw˝R  -ۈc |!FCP%7h 4 OI/{^ g86 ڡduŸ"[p聯ϵ>-UORk#5 k9μ8~N8Hg)] ʼԐ|li89?<>AF;:j#SڔVq@/@ OmO7IH!aM6=4])SŧkFNy/xoҽ mKhv<O nn '5\odAs_h+51,7/Dn IRѱn690{ ӣ@X>OxT6qנM)Kr !S~jd.}4#LTUJ=|glIH/^iUUJW~1(]>Q™/P- _nݓAe/a^@IYwÌtm yyH\xZL.R{p6ֆٯ|غ QԀjm6:1ty(4ޞd"xuBW̞85ս^ y*a~3qR:ER-68Ч 8YW˱P6m?J`|j^X7)Jm:X%|V_l-)-| WI"!8?WXs䍓b围A;әc/ ~r;@'-_s-B2 Qj4nv3!4}(oY,`9?fa?f\"lSl:y? UZu  3f =;,ze/0Z^e "p8%=Ynqҩ3`LO6K%)I:lubjq_%U$۾c Z>}mO D9?)PBkʪt^R3¾0X$M(Q#.bFHM\W_kG}v]DyFƍ1Tǎb;9O7Q /i yQ h|{'?.Nc*t[0'hK p_K57x]u6ڔݔ}3opVƼ/a,i5 ɢ;@W[`%n Y\gKd\(]۷"%21K_$08!uX\PߘCUM&[Rvn9|K!e[Qxb:?e8"d% 'Gd5Ǿx#n71. g3VaG@zpv 4WhegkKN]ԁl# G.j6ZgW?!lF# a5 竰K{;˜m?c0ZJc^A >vS+X}x4 em"g).wL|Pƃ/n88ך^`B6X4Y({*̎V5S{! Tb蘐8SK$hTxo {ϻ*GXB`7Ɩ0zޱt:>绾{,0e0;_&/ޝ?Q6ǽ+'c.s}X`}q;bw#.\TC24NW(|B:-e07[H0 Rio{Ґ `G%o~7dx*0̈́eȌnXHaƒ2,v'(i^PG3;0 >!ձ@f=H>h|:m~]K:LQef 8y2&功JNoLЂ$;!3WB{tP |iw.R#>nT %)-) rinֻex| E+ByˤenTd_N@FyS!3sW'qMy.)f&y(![]扶kM?i$BvOCL_.ku8X&dYG KU[e]CZ&OM geeywN%NjD@ IF dEG Qk˺RWa3Z0?A*Ay*r$/1|'/q}&n ( z)͹OLYr ĕ5b)N0*}6Ƒ1eb? %l-o7b%i}4 >k'XWVMgJ3DtՕb4J% ca^ yYzWiDM9lfHVqAxJ^~x|ݞREt>-YMJW"&;';zfnZzӸ-ٷ7Lb}ӍX!Y=& i|g.[U`8 o2#BlDlt{(KK7`8 쮯0Τ Gr;`4?AjC4bxZx |/πv'rJED1(kѓb|61SW %]Xa&f9V`jzp'hGоnD26 fI՟hpL"Jb,4D%"- #6ux(%;X~de #KI/^gJl?6"[[隴45Z3s_md$pùefð?i%+wcy:C\{x#U>:d0jNS`"k֥nSuE-e"\H&,K?Md1uԫkQx|v<3郤ZƒVT fIR6^~uwˁ1w5klخzc"V}QpCI[#+iK~ߠQݷ 5rqbJiօwRF>eH?˜mLBEsYWjEu܊,Rx[ķ} >`MoO̭*47U,޸͎:\FL9:=kz"'IުԴ@gLZa;|x /pI`?*#0=īWwwX$@jŹްX2Mq?;]2rO<}fӐ{}HT+*̟ [茊qgc <ӿ1⒉V~d.MOa($A,gJIlTR NR&HS@Hz)/7ϱ;QG%>VG?%Sϓ4\wWra'rX:AH]*(}F7}}TCsoOHa܏- Żjx2s)2j K'WUU_:sZo'5}EGwA;+DJ׮!ʰŜ:'6#8xFJ& 8WR1FfX"+jy)-:.ju/C?a6Qpфrk8JS$k{]۟v#rp6 OcgP=^Msh\lŊ_9 ލ6PWtЬUNF| !X Z߃ㄇ7 Xhޤ1*ԕO){10?|{hfUG颰NOGÄrF4q|]Mi_k^gar0S)fe bhڭݣCwV Q`+mz7](}g{X*B`!f!& K긳K+Vpź::by0Vx^Hi\axsAT cJna9j{ #ڤ˨TX>ym`6@M[ck0<DhP` ͷ+%wgL+Dg1^Ɏ`#jC2"@#ΨgZPƃrC#:<ȪA<*t!/)|moUaP؄p. +Ww:^zN=>g("wik>FUSz(jR*nyI°bS s|!u圎Bcgp >@` A7M8JVpkݨ+_&O|젞-.~Αw + 6f9X@'G2iNg8y,fjij<1ɯt i-*y/3$A>ݹOU3x"ޱ9[4*2 M)͖[1ϭ dE.>#=qՌLLȃ(<(rNQ !/ݥ(v:߾L(e~尖:潺So4,m>_TJǿOMn%9mU?:H)M8y6lTFə{ sX6dg"W]9}ثN%Zᢌ;$XHUw25(]) Ka XUt΅!7Rā8[[Aa=B+ErnՀcލ̈&.RZ%IQ"atGȌ~ K׋u uP9+7k.U'a(=V""m CS cv͐krd}l_N࣡ۗcؔ=cw/L 7-RoP~++YR]H7@ZzXut"]Yj| >c;fm X `3ơ-tGnM]Ϥx<~Ҵ 騡>JD3߁k~ń#h "?f1j<ag* 1DH <VdR#ƨ&Ah`կ]9/cS9'RDZ=T>[;-l&M -ѷ|huwV[%f\=Ƅhs@H'/m҄Z+)FG3W4#o?!ہbQ]ٰDJ^E98z f7) O%Lݑë0JS).QJD\˾^ Az`JO{#_Xl+Dk E@eҢ4P@dZÙ[I>\ZAHƩK*mŤVneu-diɢ2v˳.r:c=z6FUl#^TX~䞡N[GwNe`?6 endstream endobj 160 0 obj << /Length1 1823 /Length2 12594 /Length3 0 /Length 13781 /Filter /FlateDecode >> stream xڵweT\k-அwwwZS\ A9oU=DIA(aob`adɫٱ03Hl,M)(DF K{;1# (])@;ӻ`<,j3] 3Ҽ;x8Y[`e`鏷#@`dg ag(ػ -vc $UՕTi88;O-j1a5qP W h^9=@A]'ϻwyq5a5m%q?`-(+wW3'{ۿ-@ &&777Fsg9_YX:읬W' /b\LYPr&@;g' T;A[;?1m68/_9%%9hgdgn28 T89!/W"wgc'fdnM-AG,mwsfv%UώA;F;/?x\n6{ۙھW >1w@NL.Lv.@i~[f@GĂO变/{3 ~r6r@N.@*pL-M@>,E3p-~_i}JMl<@3x&{{CP%bc`d oJ?-DXj{'[#Y:KXM,A&3\v6@ #3+ǧ5wG_4:;ؘRO&Y-9i;ۙ؛Zڙ>s<;;彷Mu pp*77/ `2d0?L&@.?{"CDv#;Gv0ɘҟP0YaU5Pqy#.{G? (=wb`c0|~}A|b__~V t,ڛY4LCQp3Ub h}XI% gPI&kQaڼn%VMݘ* # h0f/wkfǵND;{?M^%ꕷAͳ`8٠/u/Ow0bWh Cdz#3b 3o%Bb F^I?5j Sڡ!~c{d1cfۡC8#jkܤHsL0 /晬4ӷ#'51ȩ ^V-5+|!PF^dvhFnᥓ Ik5r@PՊXAguƉiwǔj)l™ʚʔ1 %|f1" b#~#&pL AtF{%wKf]֏K~;Ft;!U:H}z_ؗ1URVp &|St'&U/HՐ̒RXŃ1/[^Z><6 ҕ qJM)f0/JunOyISW0'k/صZ8Gwx9A&.LllޕFXO`TSq<<;4K*H=g/fc] Ghpgsl:ayjlL TNb 3՛qA'yLEhl˚گ08`Jl,ImK*eQ__sm65Gj3QȦpefjȰM+v?. ǐRcP&Dn$뀠E0_^7E!OOeYGRJfP}q8 >X"%Er>wk.%]!!REPƔ~Y5KJ 9.tjZSKS; p0&D 0Buo/j{;@5ʬ6<.3F%Xr:ᓵVR<99624:C!a yTOW;)Mfa܄1%Ą$r2-Rzf5htX^ C!nQ[5N-dzq1{<waW^# rd㷄lY<lEOM[aԵ**X:'ԟl78lnȍ|6gGmqB'Q'@Pp0{Y*ϑM?  vM]DG#K͖a) "++u njSMq.$щC!*wbޭ06 ѵusKӇ"p\U=4{pmKJmGsbR/W+riI YO.j'b(F=~j+6RoǮ }EwpIK05 r`p, 'yJO@aJuCqI>CWJ FH|+8U{`LewRs{쓾u۔u5و)~U^f ݫ'-׬P1S98j E>sbpxBZ.P!w14YP_ N!1o}+ocMOD SzSN?#aog㞾 KX'ds=s O+:Z2y~5M]L!%xȮܭ6q&8]{iOI*y#SZ^9&_dXʹ4LdC &+( %8(U]ϤGS]"~H`!+F>\d}(vWv/ wu-Euy4&m!@9ph/д ~ZK-~Az2Q8 =,n&0Af7j7*B(zMY21sDY8VO{s~+Ied`-PqfAwCK৖]hbRiYRv G4+hpй:F>u %y*U".4NY}Q DKGi5BZMK+f]CK" aXLٝrw!K)å~3X+쭙,ZJF2_m1%W5;ՏKARg]H]?kY቙q(@>dRZ=Ԓ5,igx ^JAS).Pvq`1ߒoqIxf]yw;-}HxjԻǡqW,~nnM &A񕷹ԍ,)q:ZJcVC>=:!Qܷx鳂q vsRz$x*۝:8D io+5F~t}<,>r1vkqcR"^E,nόMud[EE(KIduW{Z;P7$яEHCG))3ʼ:bjUt*=MmZZ#8b`]x E_95ƣ6FgGD^ql4Fʩ$j=˟AyO<f}K9rNCſLTQ̾`En"v0=U!Borƪ. .C4i W*?d1Phw:U!HcrLi`{,5E" F~&.b,cwW,nZM(/4gusWVW ON3Glwo{~I4 KZe)zNԧR~H,7[X i-2ҏF=`1Ls\fV|eލf%&;P{]$uVFSӂx'dGy/1D7݄+i6AԫZ;8&\XE(a`) 7vpGoæ?7Ih`]/꺯ZpeɸD~ 7v[׆mL#3gD?= m;gs# -p v.ꋈ'zKM {03jCfO܂II@uTA/6ͬ|-lܙ$wqEzp:-e`jhM5YC&ȓKI5--Lze[{ahJf`2CUBy2HezP>MCli)BH5D 6(XXʚ b^EU-y3NYGnyyO-}D 5, Og.x'l^Ϛ4>#̽hwwG+d~io,,9^hH9qvcȱLȀ'WIr%h.i ׯsL)μںI6:A NԶ$F7Oi2B clkjhv״6Agv5F\͝"J3%},G7rRKVefm!=v p0j/~ hόQGdǟ܍DJKyKm $\)bSȨ0xW~Gfp8Fm 2_ cvʉ)(N~ۚ8].aԚ6 k^JdP.~W>TtTHAa|+r 6е$t0uA먻ӗ꺒/'_>}b[1X2fojqC6_l[!H. װOuH"֓h5 XA|*{HUV81"NUEcCnn$O ȶX׈U$L 7Ȇw[ 2 fy+#뭵G"_y}T{7 5vZմ~m4 ID%#/.!O<9KN @ɍ7 htOC,(sH["_IH6bOM;.Z0Y `Pm O˷q.ϩ_T{J<$s7,<35>KPޘ{>(A٘W&jmZպ 1J,crun,$]Ƨhc8߅Xpзr*'rRK х| 2w6u|) rę?ر)^}QRA4v5L#Dm B0Ygt; n{ =kRfaJ|'`:$cznWcQ}T !">mfJz\.L߭r}$Xh<}A]oZɯ| cZC1pY3uwCƙ>GuA1U9^(WV@ z딆f_q[h1ֺmdXINvӐ0͐Pa>1IRཨR.8upkϽ{ՖXY6$`S%jjl~pM%O }á, ¿4!PbOۍ/꾪R;v[Б®]wOq,N[$N!J? =*t$h `+؟ػh84xw;>Gb&5_Kk[K;u<(G14}T {^3`D7鄪Jf3)KÎ>`uKLdHd jCύ8+։'<\ʊyø4Wbn@rz-6: gZҜwj#2J.AkFpa1- q`tZgDNZxz]rq*\ &t%PKцKׇ+;ĻC Ӈ1#"w1ԂsbPSqj*L@_C}zq i*%KG|kRUF?^A| uf4(fZ0I&$s- _%~ŠF͑c]>c5kؖj-1`d\8~Gʌ6cN%ojDxn>hp!ei@/iﷂ<"ȝ{k56DT *˔GZU NU;]E JlB2(Y$s9Zps1eMJt1-6%0 $3D؃ c$I:zkNhn^c8잤ߐIX5`iE{]) }fׄ{=NS' O\Aj 9rrPi~qpje'j$L2RJȋ=^pDrqIWůBw~|%H\1X(eX' @qGO%h 2zht]G2j?&0(:=&Jx: ^lV*k0?(ˊAd[fQFƯgUEor횂j8Z O ٽtA$`X G[mQ3g󩪦^:՞ui Sl~؏l%vSNJ-hNE<<*{媧b4:U (,I1{HppNTJW&Atj[eٛ8\P~hc~PtDlLxNU,[iyXgUO q7¨B|}pهPmZ9-e&Q}F[= Z \'4iSb![tjN(ׂ'ow[鉸(r soY4ެ5-d$5)ěg D8ySsߪ@iS;?A_q^xqh/l]JJ] ɿ\8ظܡ{z#2e2;|YܗS/11`? ~ Q f剋0M2޳cI]5L,2OI/[i'7il|oЉEϵAj7&BdDϱ|lT~#i-ePҎ| T?[Jwi8q$*f4""L#TB/)HuQ`Z 5(Tr`eDuu a"_MQ^c⣀_sd+33ELbҢ5*u9+/f* Bm ,$j%*_OIlmw$ʏw gH~&TT܀FvA86G9abwvKp0|1d xbl [3VZr[GKE[ڣ5~8b*ɝ0$Y?52jWG2Dva)itF@'IL y [@X$-Rg^=| CmC4&a按g!ꊍ鯎-}K|xI Dcj?#]{#*nXǴ9#`~Z%%=,/|r-( N 3^Z%y*4*bly_Qvr(ZM=?n"Ƨ^~f_uk'[bPZбy '|9sWtOBEjYqM0"kD pQOكܾ:ld |sFJl S5G0a}ێ셭lghU02_(o&ߴZ'n 8'/:@xGg%&R|(i+ah=~,E\'xhYalr*NlycȢw~Wͦ~FKž18mHwEp^|u]dƁpp8`)4#祒/ :tob}OhE뉍ovVkp5 uA[G&B);]BRs-`(YDJLqT~5v"qtl >p\ʡ|utlQdi3)/8ErU](_;-7$=d~4l,X]Nm֖<YFAA۝'nBu B MGشz-hכ{>X^MY;e; ej}ٯR!ylBT|͝ ?i,g $K^קN+1DM`a*t$F4BH>肇#v 0kn\w'/ې|-gÇ! X]Ysq@}30,Ԍu*CPak"gq-hvWZ]ʩX\EQwQb ݗT>婞UQ]H sot"nKx7;ȟKk(4DpƮ!JpQ Ɗ<~Ð' a7k`k]8ST9mU!s兿\Th94 Pq>,gH47=TW[s[s+Oz؛ޣl`׼`V7b'f/vF 4։e8rfRixWRyZJ` ԟ] ?^NU88ERh^>~@WA.Fݫ!Mh8>`hvsOv]LYSj ҨtS8UeUӯіq\QmIтک< +е{ВbSXܦ%5lK+ʖR,04:7,%/Ga/W]rꌃUnfsWf;Ȍm,ik9|rA] O13~Uې$8s{OF`^C_L,mJe㔴:շ%I1.tu <'9PYCRw(AIJteN#KR[Eڤ=4s=!-'vX'I6fu3b){H&`E:3q%YTo8fcrgTq,&=b9wz4%m.UW!bNMGC|?8%D O8,'/No5"YtmK"# XĚq*wK<"WdWķ伬!QxUTkd0|d!8 X'HͫSX*@ćS_lP.Wpc-iP0WAbyG8B/'J=X+agn"Cwgic(3Bo#n{er)W/K޽ϡXUAp9\'W);)i])> b# iqޒ?u1ߔ_IK Y4 ݏJT]us a<[^iލlS^&a Tg܂(ZZqxیݗh`j{=*G :IlI C1ybd endstream endobj 162 0 obj << /Length1 1952 /Length2 13976 /Length3 0 /Length 15233 /Filter /FlateDecode >> stream xڵueX\۲-!6ݥqqww  %.}}u5jԬYs.*2uFQ P redeb((LAl66&D**qg $a pZ]Bl,,Ti FZ̼@WS /G +/vqe43uy +-Dlce';#LŘrv`;) ǤP{m` hmjo [4:MuI5u:[bu7GG")UҐҚ~5Jo7?ኒ*`]lWmo)-ՑÃŕ lhW}6. 7[;]')s 'H 7ʷ7 {k럜\6u+VAEE`jrLAon.lo_n4r.~[)z6\l\\]XTgl@Ed$5Ĩ~/?D%<,\V^ېJ,oU i[\^g@`[ڀ,,t͑Yd7?6++t=ͭ5-̬omq;,M]~6;w?"+7m _eA`JҽR 0 `DdV s_ZRnJ@n:{hKvv0/Ehbjnwg% Y9Xعf4+}l\ao<7qoin88oOf1eyM3;I6 +' m 89>omkbL [` vF\f?7Y`0k rMXYXYo9$xYriޚo[~? yozߒ:\qxw'=+ۛ?j<fonʟSϝVwum,ghlvXogT-&ax#/mIl~kq~6 4G\6hV/Y4S KtR##5I'QM.j ̦.+Ju>bۿ|oOP1W'Db V\JNw$Ic.K8og},+EABXV,g{Let..H{>ѕ&p{TYc >b#} mҫK# /Xǹkĉq<ڼ78-`2q=٫Iі}~a7j, R&FxC69_NrXj/MDc|ffFX ǓѪwSXKZ/4E`mzi'.RoW^4msa@ Â~F֏.Lǥ6`AC5q* !%ﱽ-EE8Z_|ԅRU Aq1ى?koJ }Q`7*h\P}Ob 4SEԴxM8 }G9{0ZM95A9n:ey \; 38{ b×Zbo톄mX j5U5ڭآU(FPn Q+W/}\5ᘺ[z~,ȭgw_S۶A~8C+;*V'÷:ݞ频:;k[G_;y_3Aӄb#yk= J.c]tt!{q\gꔺ.zV&PQ/B7!Kۄ(6aQ1(%B1o5,!,9 OpC;'Mn}PN>-wOȅ!J(x:_|VO˞ H ;i} jN="e|)z%k-:.FkD/sS$inpRdABrk"v%`TlSƤph }.8OjKl xc;t}B 90_}z(E} ҵӳy%sԝD.אC)Ӎm,V9$gMWun00 nWX *>' P; Fn|1)/ (/cjm-CL e#I5S.f̣+(Uf2"UHnV76zfj==tZf1O/A^j?d}ظOs\KY$$R9ůgIc` ﺙ",y˻O:CiԘ-ʭ 8 {xtTNBeR1|{T(Ul"r,)}BBaF3k 5VjG9FUD9*>C>tާdB$b,ֹ#Pn9w\tB5HۦAh%]\{+,8'D(pcCy}D@/T\.yR)U;:=:hn;LhfGHX Fm1M!ഗ)xb,v-B <8e :{z~tXK''VP!&[=̻ȷa%>; jZu>Tvj;A+ 腥SI\>ymєNL<2hGtW#FyKd_ȩ%ӔNӔ+pgNs^ h㭣m׃/3Ld44|aFHl=f?Dvcg>6[^>.E}ĮEC,.GG! @xnq|.k2B6Ur%ͽIiV#߾1-S vSLsiW=F*.5`zl !KUB^8֑F JG$]Ȍh F^$Gn6dB;[^'"#f0WW+9Gx-;,!/h7Q)k{-[Hwx~Im͑\ȇF07UgbYYJj 6~fOD^|~ 0(m{ti]ͱKl&θbE0'ƯȕFc6ÝP,4} y.7w[XT1OB:u&g=Kһ U6ڥbC \ligmT𿖲/r(%o B5)Jɐ tƉ:^y6 ;cH^YF7菰WRMUIĕvF M8}Qw>jlq#UqeeV>{,sI$;x>3Z*8Z6a?Μ5Q,~{7_ewỘZba'ᰑJ'=êыAN$=* s^:g 6 ]ftlQťO14*ʯg_(OcV ^nPܠXΩӷ%`ߧ bGw꾅đP+z4lpӼ^n,*;-v沄2)rn8t}eM(O*õ^ޫ @(w U:~dWB_hkh˻._ fc3ND(^.N&Gք֭np'1<8pOi8C2݌dyy_ Ki;. i('R^fXUiSԽ2N(͎Fjv?LZÒ"ܲgrR*tG <ǂ- %^05՟նɳ~/1\;AMiȉ$,z%~7XKנd *KGNT<AΰWbfUۺU$mܹ:X3GAiWZ`Or2/${6,:zf ]L{9+}7F-Hy'{3F)Q?(wMw˳XqNd #}kUsAF~c* ʥYx˂cf2U Su{TWӞ˗m3*̈́v Aq j ߥP  /NK8hO%ekCJN3k6"1|G͌ͥ'%:> Z_**3 Ne]C7-q/xMV1I޳u\mXl$ jI&C|=GͥPJPF}qdho9p iYwnw>k3=-+ݵ>T vl"Y2F9vͤM-bv[lWyPUs`THq`y1d `b—;qF_+6^˦nάNܱeTz} KRSAg-+ptb(ZI&V^, Pb_G}+uЭCy _םƲ1`̟Wp;r$DS'I|LC[,[iX=9ΟGԨl\ؗfεSx)`cDu~ .%N3y͵cC2Q D\Gm}=𘳴*ӟ:([,ݡnZ/oimH9'?16| q]0WY) S.p58;l#Ho%g(63ÂX$aFܫ˓^UhXf#2 /PeP)?+;UqD 0wFqoVG 9TD6Ǐg?b ;aB0-^t 0(/ zV`5% W|Zj6Nc\tzcջuݭ##?,;I{OOp6?D|/GwʤƉ*<Zݫb5԰J].!+eHyFhO$37^;|p5L0P{[;^Dh\_YxAdX6ZI?c0:Z0*CJ+a{钴fw-;HnMtvK<`jGQnYjW"ASM+փg\wL$~.-f!Reoi3o# Iyj8ůi\PX̬aP"?6K4ՎI,=Yy(XP3oJIBPo=Nwۦ *TY(+2{u>dO27rC+5;[Wo6lKj|ُZGd8Tw=4۸Pl^W"8H`1É 3 Ze[QaK$d/*G2}G-5)n.efTI f><5d.yGɓU ?:CrbQWQ]8Y73+;B !KslFH"k&s|rJTB\II}VksϴAüFv;f GijcyE;.o޹Md`7[E~,\`ٶ0Aڎs#+Ny;2nx ަ3-2F-c5gyס=vZzǴ#\xe+JnIT9['۝HxA_v0A@RY9!6~JR4<+< ,phUf#w+Do|D͖>8j?_?J_/) ֹz,-jEQmmh1xU&g[y]W iorTmk#PKn$r78Vq:DJIѬGUFG}fWe}7=yǒ֭-CqX/\Au*16zS3AeF(q-HyTD^m]$gި,-GAjke.ˉ!iK(dAQiPvlY5u9?~dy1+HށS*3r?.ZuOfTgKܝOJiZ^%& 7,&_ :K},+궉 JΣHvrte(9+͈پ ܮӜ|TӀ_|IDOw)LY/%ulFGfaT+NrOcN@(kLr,Li$qXh6;<߆Nr,/ڼf1_,)_ *{7MRw/Actډ1U' r0և9gÐk]uQOOBnS`exLOL jMuf=vLNt4j*Mޛ@C%ix 3S% x Lհ(W-U승y{,=y1IM'g.N-Q4S)"p.| Z b)s ~rT56YVI#l^nB5\@uR HWq]RUV yO%6$k.@V@@%%rP#gw l_t2{eMׅN.>|/Vٯ8Sր6YnB\4璼 'ya=7J%ˬ&ڠ4E{ oD]qIpOc:5x%=%PIL>nk7'lz3B!sXaCC;pOZ %F+y?fFI=]2h@)g4'4b,8@ϝi6c![|9q_2 [REGXPc ȴhW-8NX(~C$Ec$ѱ,ɯC8]; ?vJI,A5utl9H&I1De_.rm&z;5Ic3] mNÚ0^ֈlٞCÈ,JhZƯ!fľID@j2낎lmNմ/UtleQa]^/>}Jθ6{L3Tyw'<}P c-'݊+^DA߸Yjɑ<ͳ&WbM:0MaWR+||Db[|W|ϵB<i;!n?\JHm:`y]&D~b]ٖٓbu3MZ8B&o:fNyjTU4S3K}ok1(u;ȩYaQt)V"M$(٦D J6Q`QcL1mtEB~~6jƊbv4 B$'AKx-aBv /c[͖IdJ^ M}X"G0AjȢixI tXmPlARc gaR7Y:LާkѰ;_~_v.ѱFzʍ-Z-+:L]T # 6%>,b?nÛ",\ }9f xZ3 vx9b:Wc*ӊιsa~Ft7F~ T-҆AhǺ)O/m"ReUx&0,YB4v"?MTNhNsA} xDiXjل'BT=?QWl%d>Gq^֪;^@tONU%m';XX72sПrcl?ex(\~Poj5{r|RWtr-6Ad#_t8Q]݄s'&cn#Ȕ<TMn˝ZGiZbX"d%FpRwS;IW:R?'D-7 .iCO'p1Ф\ m~k5fbKE0~*"2=lUwjQ950x.r,i!v@q4'S S1!ԇJ;e&iОN*U[Qoߟ WprŐ=ڝbT4ڟ_Јl\CJܠ B9& 7Xʧig$Pqg[7 e\Yfvda2\S_5eפ+MĂwY=a]Qވ%EOHWşѸҾPGz$ 5ȹ% ԻPTnӱ?BGtxF]wx/ԅrLAP&V&XT4`c#XtqXb nunva&PW 2<9iF{:4E.(J X Sgی{%J (aHZ1a>X[t !ցҳ<D.kڣ{t.̙ݾnsB u%dvyVn |{z]4ҍ%VSW,gKj!Rf[ϙ?/Cgm~٩*Q|-YЕ9i3qZ5 EjE2p$J-&H2+qH+0C*Vh(/._'& 3;Xm m+x!%3q;]` k up&{oL9R%(:@|6|p3aE.dԻX< wu;Кy?~d 4%REpʖZSSS|+E|g5\cGtkw)ކ.ŵ2Ae#5 ^U>sEjy}<&ujfUvr'X)5Wȹ8lm5ː9^VZ+lƥYK[291úʋr}=Si ʂ(Ry7+bjh}]nGǀoۛCd`#t;͸E߁jʔh]2YjusO0e2ګm(0s[kH6U Dh vXkyܻq;^uQ)`|r$[}mhh /_J`hpn<综ŘbʒrA9\9*mQ"V/^w] zq%8\jC$k5U:X{}hC.bH΍ƉBY;.2R|Z]a݈&m}䳙[o;HJ3$V_?\x1-wqeZ.i묙 7F =S{T^=sLθ!'Quƴd`;q 4ITBya4!!(4{UoM΅Z9+TytWD0ɼ pn{px[.8Z-sa,P*jp6xm1pW=P2rb!nЉ_büjSubʃӫLN FQ~Q93J#gI)p`V fG~nCa`q0vqBY-!|) gEb:f-ί;zK`9C4r2"&ױM!vy1N}CwBV yi2x`Ds4wd-OsFtWF*{ &Zi >geaW_Z`'x Qav6ϹP?3BIJd֨0c "~tqA%L7qz>[?G j$Cr =x1Bw9t`O_M#AD;؈;^=-0 y=7{$.I}yjRl/2y{5n:)J8d _z̤3~$tIsF q>v$AE F&0l5!{:ߵuKmj0˴/Fh/gDsQf )Ҿ19afESo  ,MMUku3B>GJ9Eu0\5&bDô6cY͖J6c/2Z0O/_MvEaD/0@fֽ&!2#.&l|[bhayxak` ߉2Jv?tM Jb7]ؕωsbdxAِ;-A8PcouTe :z%Wcw!x:|Lc2Oxa~WиVٲ%vWeK$}]'ӏu)O\˶4sC))V, 5VfL=~V $vp`ȼ;A&QY5ܟZn)jQm _T/k$XX {ŅAv @e ]׆Mi}LXuel~QY]ʏh##S9 }HjN`h<TN eaD-gO՞4]/`zrqE4{ Y@YE8H4TPq'^d[{m[i) mƀ)=8V\I{z%14`r05'݌5Rn1D{Hܽԥhr &'_ juo4;)D1 TV.fG1{K{M$}Qh'I !K\=p #{]T{xD̨rHlJ׻r*բY%wp%"Sn[se?ڭJfBLNcwD?dk"Ì]0fiUjH!7; R$O|g= \S4/PÈtVKkF5y/-fM1Ρ]-eGhfo8,]5l H e-\]OAfWbI?<܂1ykSgo>fDх]!JUKY#tA1/0v(UT혆 ?CF|f'M1+V+O endstream endobj 164 0 obj << /Length1 2045 /Length2 25345 /Length3 0 /Length 26607 /Filter /FlateDecode >> stream xڴeTK;=@N8{p݂[ \r9g޿we?]ի{5 1P :03٘X((DFΖv Q#g / ͦcH6 (9939 sK=E^O?Œi#k;7'kK (s{7Z@c )$Uh 9U5 zNPSQW2:UISRRca dp|g{_ LLnnn.NΌv6St9Zޟ@_qYK 'I_NQ'۝C}j+W #reeF g dl0 4A @OԅWkc;frql{&v 'K'gU,m;3K_69!y)q1UwɁާbtvw+O=!QY^7;.O1;k'?| d,AfnbϤtpJ_ o9 :&L?f?!x̌l>f+ ]GR 3;ϿL?Pu@iO` 4C`s~?zgfdki?C#Ihhlber6z׽%%w;;., 'hb :9Yr߇?|'-IFIMLBWd`9:y 0.gS_201S.>3;G?[`c0xLbA\&ٿ{73Io `RTF&տ{M F#n蝋 {C@?;w |oko?{#FNkw|_ߐ?{eϿkDg[4VqvjX:[3D]䲼5G;;}^\l_&4o@v&RC| gʡ)xO+5V2f: pE~Z3)d%y|@ŚX6m_Mw|| > 3f-wIhe'ƏEx:{bX.SHuݾ.`:ڠ/w,t;=`E bKjӥje,'hi#*&m_ܯ*@;yt]uG-T<#+uII|yJ9R=X3D, ;[? Jg],Vi{ jvY ࣌^iدը`G0SQ^K^l>">L@s! ˑXJR~}hWf*/| ݋HĽ6@V 8 = e'6w4=;}rUIJ$xb=]Pc]h  @t7b?J7a?سN/ HgÈEnvF-8I/ 2zuwSB-,򹂠2??/rl2 4mHB=hfL+e)틿" Uoq2CR\r\0O󗁪T:= > ');ctjCURɾӈdxXoE)k@esTpDg62k>Eܽٿlyg͘ltBɴ&eT)ۃe6OpcnK7 3N+IEL+YE-/$ULY !3 &O_ۥN|ַ .1R6tCEF\LSP1$a"/sX汁n!Wj=OTcNXTQ7|+z~JZ$;k5f]*S"3 _^C'9я;揺;+Z"F95:> y¡D!?4$5L?lɬD.~|nWk[FvBm@fXRZQX&J7[Sk澬S3"r×~8ModZ,ƬNڡyUsXL)V:O>>  s_S q H~]\ (@N xK*b5^? 3J)Gą3].wI5o=}_"/\vpP80=BSK䬝N"G}SSW^6~>1hWT ̔zv ]V|+Ϫi>|քA.ʊķMqA~%|C,:|orJNE{!5?^,\h4L)j:IC5RW/DS= nlzBIRCYhIN2iCu3[\"M&##ErT=4zc5ӮmRQ {'壖>FSMˆ``K6VkEUˤPi cS15JH?1Z g"PR6'~sG~;NPδ"wǸ]qqJƹ qW?2q*F@W\+/'vo7+O;.!Cj.3?gNKސwHr16 ^y، 9Y~}-vQ(mǕXGv CѪ9hԼ6ԣ"`vF/=4g Q7`?w~<vut"iI*eɩhL $rIa:Iў_!ymTh^^#$im~M;@Tթ}9C"Z,Uٗ-}|^!nFXݓSzJF\iaxo_0:/X'P; [z$i+̚5Fgc7T!#8R03dVD d"C0_cT^+k<0/i10z>lrgZILhRL?,6&ə{KI;~Xvk*>p3ϛD[M`fT54J<_8Ga+%d1ı9x|H JcaG"5z#Z;EڱiD/eJFA#P1o~oqtJLH8eVƇ<~|Wgrc4*L/ gBإ!֞fSeߞlC=2ޒ-=+F~>} V( { t DvSuOpnF]Qzh?&Újba?ZM+;eʘ}̞pyĐpV^K\ZI }q@$/+ Qn` f1w̵)){".]h㦑Ao'MBкt?zOi7r{!:oJ .қ NW9'~Hpv*翑($BQYu`B^Z!*_4ln0H§А ޸FUpUb7N"j_)W?g=8F՟CYe/1YK{LDR3䘴1ggq⑰4E+ Nn?TgB;94j^MYzpW鲃l:*sgcYpu V՞;"mLſ޳8+V+h@ &ȴ{c@l\u:"*ߺACL8 ؑ?+:| &5j@FA<"={3U\ԲT (m:/7DC#g2GW#R|.Sk&C}g>=0*ҷ̪fƪ{PNy'aڦ__%a SDw7ob jc4"}YRYVX`D "h2hV52^cOזHC`tX04cгwGaSg,THD,{_c ̀n |34'X,y5wȘڨ|)a+ zIR;% zYU kL$F}_ƦpʷѲkN\nhF!Xx+ɂ8y4+4@JgƟBhm`~E$>!<5Z+!lT cᖌ ((l[znC:{Hs_ #y=%a7o?IxNkss<9ɞ^)lX5B8<A"ijt^9?[QnWNȢHˌ+[ Fe0|R^= a .&a!#w$Ř;l6 ?xeotyEI}W]N'|krZ&@y1`:-Zy|ԭҳqN H@$EƼA3 6։@'&Y䉆NJ|6lj1kHǻi~ɑh "qZiol00Y2_scp~A@rZZZOy6lk2Z"M(>#ٲu~F֦"(OW xXH ֙at 7y b^17wdRu`CpKpX䂫RJArpc<.h2E[L~I:'9uKODRޒ+}g-Qs:#}\H-YLKC,u l?k[KBNKWK )_kj, RW)tMom/S,ra|p@RPrв,YMHCAzKMWb6Tkwn~$^=e5aYws(,GBҗd~j61>BA̗0:/VG:1ylrަ_'[v(dgSO_Fp Ga0/!x{,#ʶӺs;I$ϓLԄX?M[l}oT>]/B(սIw3 nJb!4y }B>ɓ~£+4Ha$%ScEh-1<{@!(d?89;aw/jp P"TYl e_$wVA*HnYԹi x =máE,j@ { ͝5>[~DdG/} ɟˇTy!d6w$\R p;-)_DXSV"+_dT[AEY*h?H\]S"-D%ƢA]9m% .K*k2&)dוC_*!ni(nw8HGlF{`vG >Pdf!4cNIi=.dvvKtmS:q}'. Y1D# n yTđэ/L/=W91s٠*SDkNˁ`x| _ (A)-#dm5#>NǢ'r-~L\1A\cKOR`cЩ9ZхY)Z/+$Y*iMU1OCGfj:p<ʅ4QŲc2[4LZ0бK$KkK[q/ӡ;999BSӴzy.[op> nOCqmKkl4}nEo16"',~?sY pH/d:1%VH>2i)}^$yRp&-?+gw W&r`xZƞ+*FD& JEz n;*hatRn_A_?$V4 X0k,v`' G]-N$7v@/2{oR\^P4L' Rfe$yvw@>x$JMg 7 P[X W_Ths\^+`TԱg3 H}{ܤ , UcOQػGۛf\x}mgK%t{[431ۮKàZEH,,iz1:*݄6KXP3ߏt/iU=mchu]^:ڢmNn%a&i#*AVqZM(=|\5 ;|yxHYᱰش]4ucSJ5vDs%ožpwwca%&`!jl Avwr]lvL6@v t:QVlB_(Qک]ѩY(dֲn ߯6T[S=l\Y;j%g>lGdoYCjw0GoUAagj]:'iOV)C.1[Srjz5%O5znͯpU=XS`u_vؙ`9A98AҚP`*6Q6lМ l[A_6EB\5CO(w|(/y|n\\AI릀~מyR%Ќg;+||DB #D4e_S:|,[.YsG0Lx:YY*μrnPz՜j Anpl xBIc8{Z Xok>?s̮O\$^?h @n%vsp? jfv b?#xwhD>PS3 _6!H7i!] U=tѿNQUIDaC8VD_qʳDE|Gm#{j^G=zfq+Bp^A!PrԡI,k`t?׉ZU*:OqB3}# 6{suRƐq\[ve$_HBw]Sz}r"rAu/(fqkGLېQs|dxSh[߈xCACKL:]'Rsgrފ = u[+ۤQZ-"ׄ Mf5,3M>ݝ!eq(8n|1؅P7a{dgx`dֵ  n&GJu$I{@C͑<\kէ$۬Ry@gkߪ.;l4J?˓j?$ ey3;˿icȅ»PDQ>ZT%~B+(`1=5Iw"Gռ\24s4 D>% bߛ>yb,n$wjRn42/=E؍}k@EO[~Ɓ=AfWN3~P}koyUqU dawAzGnd ^'9'l"Bkf70S8'j "؁Բ{+#`9OK81TOe_l$!9s^j̬W `ŒÁ"N!=Y3&OG(WEdlT,"p8{<;WqV?d_H[9$geA+9b]t$Rh㙤i_%qFTQސ{v}H UVHEb4CKIʙadzYPO6=,ZB 0QJ/*=DZY>Od7EOGL\6z^LDymFFYcipLPpI ;;X`Vf0P4P՗On\Ǹg@=yUp\~v04m\Ǩw ds5\pPgh"ɴy_}3@2bpQZ_9Ǟxx_yZxdcAȽ:Z!f 2E3MSI|e_{[BN\dz&:$+oŐJ8%/AяT6 تӧqPG-r'[Xs;`MɵᗢrP:Fhr]򉯯z?TUcTա,X΃0`LD|NN?UX"kVW *] v!2Y$o}$c[&S? PCN̆Bb)~c$LوV5i-0sJWK~Ybq8*jܘ`'$ JɯB,"y2{ĸx#[cl3*X /lH$+k``cpv1d2)=\.XgD rLuT#1Zԋ |\aibH/Tgи /o[N5MkV%U ߉/y~yv8S2 `MP.R5<,` Fԧ RPx0Bplq.A0H$ж`K2p')N7ggM 3Lmgi=8_bN+ZGYRUMG\mg}Chzp#ʦ_!c-/"őO PFP e҄ܵ[y]G2֦)^}wыӶ÷HE?gYT‹XRNˡ`R2;@qG bYnvۑ.m Ka*>CgD(Hِoxb u3Ygڝ#^mE <?)M Wy}Rr"gjXիR 6%i$芭SqR.B;5.pũȧ\ SΦU~uw欭x[ڧd*^π^n r 7l 9G)ݐA g3JB^/Y | L*(젭v%.ɝJho&"z=Me@PA6BaYM +aOlqܹ 3f"-|SY}[+] s4+iO 9XC``jZtVd&\P);[,,Є?ifɐ ݆Sm]P,d=JJaՋf >k"ˆE"m+Eԍ̠#ԟ`[Ʌ|X4]VYƚ=WD$Ow28"AMQ7-nb^NїAN95yTb>W {2?5 ًhf9#czlTT?}.jQ:F9NZ# _"& ]cȣ۫9eo]-\cq~-EʌB}k킢6onbx]\z+$ xZ9nuoQ$?R;ݠJ6F g0Bs:n3 ;\7C*NJ@׊a!:j7ꈎd]$9>Sg#藬xL O6HsM}XN !0nYFjT Z/67]- w&D=lzV!xnʘBjU;$A Oˑ獊Xh뒔oTSV~V j42חs'!bx rഄ7pkz v#~>Icj\κpBl =:Z%H#Q/[x1s# @7~EfxkNYz߈dZl*ի]䅖Žo"'V>+5}*w4F<ܬI$] Rr"4ф:'?02 #ͿR)3H~ؾ[O,F',J`.67 Y*FJmtX"ޖ3FҷЈdV08|ǥzFE[/*b*U%oV342gX=㄃*TDMm@_Gǥ,ɦ|(؏I>>E~u TݮU]77UG*_#,*#ۉVMI(Zu I iI<3I 1m@ү<71xdYg=2st{.Z)\t2ěe9Y](KԛckAr[PB/e+عlQ}` S/R{='ch>gbˈ6a Y&:kNoz&*o.`%˙i}i`z D"5wj}-dHdqAB60T/6fV2fW6 p ЕH hn^`iy1ܵp7;cDRd?NXDm IԢP:6/]ռ$I`ɻ<U`N1PR-I3:ݩOEYPԺhy]v*!S*AJ+ݲNK[P?N旄-DJ-:[BDLm%N&è3f24y fR33<:U̇,-_"[M G d|,m::Ӷc~+fW1u8p}c_"?¥'E {֝8(\t_ʡCHJ=UJN5cļDQ~5~H/5oۓ}}T1PT-SVl.E(S OCYܗacQ@'iPw/;óLJar:$]gu]bniߟ |ddc~)DQNiqi0w]g~=h$=2|;ؔ9 ԟ+ʍ_-H[tΖa!?nEM۪Ͼ+Zy|B3g&9УiM4%Bb4i*Cs|P[n{|WFd)Ն_."3RJ0AdM0&1g_ hvNӏgk9NxMR<,\3UJYHo(k=Z0|| )}FFH폡z}F!" 0PsdX#<?}^G{ nuH`% s8 G|7*7Q}4%j%(1=Y =M3a1$S;}qձUH'_Uw`|`4X3. LvYO;}iܴ.NI2]2q1|6F[%y=>R/ s>3A+\j(y,<\:!\Y7jTBwgzNJz>7xfSc?&s٘Srz7,*2axa5;L#lNJu ){=yYηzjfJ!׬3fb̄FI uiSR"O*8XDfjzHpjbI@'-7޼}Bl5oF蔒1Q]/R8GP+rܯ( !G㙷!3 llIJzlJ\SNBŮFa^ &]$D΂٨Y}ps3sD9,5}oęo笒ԀaTr.jZ"=u#*B2fpDogcgL<r\.?TlqAڈSd0[tAv Sl10alrjߒO:XHZ] 0y =l&3@3e慧wh}al'RԄƄBCNHBE;!Q:d{:iFUqv k"";~dRJ^g[d4?K8N%}Brf1V"%.'%!qlhVx֕K^ љ7rФU~^J6h1ﺠ">SQWeEf p"X)8ֱ 1L^.1;?m03\z1?8PE+SG9c5IʷaCC[dqr q"߭ : W䭮¥H;tҘɹ͹bB!R+u]NO2Vjx3LK({έ6C+%>jbs*˨f&8Ƽ05>Z+d(NlWF﵄t3 ſH60 wL >X^/r b!6gA!XȞIW!*7w;/_oxTVA9Rh(wR(1[RhJ!p)b6zz! z7-~S-Ura/m~ RQw8T `_$VT}u^ȿz(u@dcXk-SlO>o#.%em~[a4SJ1\5ޱeTКÍ|rn4kcDJ1'Sxf׳2vZe1̂Ϗsi\.@`5%^xa`~NTGj @ZR=˳`BX4B!g .*Y嵲vEYC FۈXRGxY\kK-. Eõܯs6L#+qOt4?5d?(CUXfPzϑ$o]حkTׁ?rqGD885.1B_GwDĭŨx1\_ m7Q r@[*H_]ƒarZ4PXY.@itD`l`+~pzb=T-Zyr cAd{>^P ZZ?)n{(GC˥AŽ.xkZ! ˫mAPeX܊K.Fl,WE~0$6(tNX,'̿4^T#Ka,$/։ЃIO ]$8 -Ԩzrbh/pT>5/ WzLK1^d8>aI/-m_YSrpU{ODuF B"4-k}Bdl x0Y:,Օg7"WL~2[ Npxfp~:0{y̳ZSAᯂQ=GPTdSc8 ?-Df-lx^z޽=ϝGԠJdD. ="oz _.r5鱺SΝ烾6QȹGR)Idʥc!{w7x+tI|uhV g}khqmo*(7ZE\+sMQ Y+(Hlb9T9F9: !չX2*(a=+|d4T;{T-&HTFzwn ܪ6\k 3gL0-9:XEo2y,?l;Xw~>4)80~:FԆJu.\ P'Yj#W//\\~zf"ɤ2SԁI?SQȜilp{b34Ec(;]A) _8nlf]y y!'hտy$Q8yI4_*G~8S^ۦrF5Z`&{ mrVւī"E8QiPZ8vߏW/$2!JgPӓ`y=K̬c.6Z_ي. %OC82&:6cyy ԵDK  \a+j֪5Y j&ksaǹ𖂇WgXt{wV]f,9u\H7*㷻nM G {M]Gyj['IU=`Ր)/؂)LT<V%*y0OJ` Baa5R56eK0k(OǦJax\BFx-PK* VZƳ dC v<%h[^:DB?O'k?Ce.ƼhKO\VzD8qH4{hgB)$;wX^vNCѐPX'xF WwYUz^ԸRh+СS)̰4!ڔϱmOPဵJZlUڅbV5aEO#0xC],㞖qҧRMÛ: úRu<{?tZ7<='Tud3(tݟd<ӎ)A=u~Ζ6tpmuTCHL*g.)z.C,2B5ųE_F)[ݕ+$K>"(HitfǰzDn r?] jÁo9OlsIl2NV4)]6/SoO&k(Vc-y'e>ۋrf T8L@Ŧ'+Ɏ [z3_*(թ'n|_49'(*]}`1d#dv``#.:Ἕ3R b32;De0WU/ 2֧7#̖t|OW.dD@Īm- :fCfσ4i%T4 30vω{1ʟv\?AWbJ.5nj0r!7&-V ewE9 8ܓl̊a7A?j{ѳsV_= +YvH*}[G5H*,^Aj`cWMK H:P֠W.(x~͜.r,!TFnN9 Uң7NP9Ԉ_.[\Np"jcYNT;~`٠ ~r+]_RR NwL~Qce]Y} $UvoyKާy0{Beaܜ:f8nYEQB,1_Pm?cӐg@fۭ<oWA7x})4H94%!{W;l"=_$_s<ӸT;@c4!l]6~Z*Y.Јa!قb rB|uoz#wSk&etuD)W6@Muf4Nh0[[ TH3=U|oAp׺TekB\YJP}r"u7e.&y# ͨ >e.1.0Һ=P,A d̓P+59ȃo5-]`U L8b܎@/uH~,e=&Riqԫ> z۳^Ah~dHDy3sUFa"N$}xuw rCV^e\m*23/銤e傃0"9>K?ãIV#UCY(!.&9o1~,~yBu=T76zy.t޳&&P*u7x6N> &QTdzVR:n藨5eb(vJC[r0{x7]xu,OI۠oM{ ֖'iGz"ʆsvN@\ mQ0$DuSosta^P&uu%6Rp3h7uŪy~`Ztr"WTD*$mnX?ڣ_8{Ex\*o%@5Ax-ݢPfUAMeBU曒Ao-NvJ2"A Ä]V@e_CM|պޚv¾DEUTx6>SMXaK-7Cw]GX`Wn/s@vFP/5aL>'0o+j5 =Z]ZMEfjqNɒpu9D@gt-HV3_zFVOJ{[fސbOiQ.Se!m5T**iTՌ4ϰFY*IԮ@*gq6LDjwZ|uIa& )0'MfF%C@DB+~i\uOi,(mV*0.L!`lrù9 (7N9_8A7UNd7t>= @rtVPSV{& z_HG}F?|Zdc?[s{#.-18>x (fJ԰BNx So1oKFJI&?S|ERvO@{U4pBy01LX 5M 9B<i P@ rAamGGP?YAp}> _Ad5"݆rn=2屈 bH#O ;^Vv$ED?/~ȢU*fL{;t;rʔg ډY֋Jq3ħBZeخ^MKb"Ht EbQIOvե=ig ȟ̳YR6L} )WIZhq`WAZ}MuKVXo]66 JPђyz#cbVn/> ٜb3SSOݒz}uսVNMs_z5$i@:bd@k6= 5.֗BU@89B\O" \T]Z3W9>\G 58vzN`fWS]%Śۇ qB16{ }o׍l\Oes:0ۙ?[.2֨".fFi\ZѦÊV*Ko|{[)UV#c zA`ufj\NmNZCg aa0tW"|WA>w(/;rPKd:d> Ir~`٬f5Ġ?/Z[^VEc~c+aiHj7n6 tՄhnH# : g^܋vHPon9(yIhj_!N"Yd,Zn|R8o΍giڰ$B qD ld 9z^/ f^|2(Ply8rD*fg=Vӝ;~c@2.ti-QQur ttv?|qH%;9UP|X;hț~d4//oV\FSA8ϥ& iª1IN1;s="lf!y[ -C@ݱ*z/P-/N |CKgYZ OC/WF<+:7{1WqpnmLѸϼseaxģeEP\3/rzB>Ȧ$6_٤Zhi ga6ըWpӭXԣRFC(X-X6a3buJf%8^gz/%%Wd㥈qXf+MV;h+rԅ7 E;88v/YF\g\ eLj6R6VOZ&*~EQ>wnWD ]gCQSZTįy39f%vp{E$SkBg䱌_*U} j;<ٷu |t]0! endstream endobj 166 0 obj << /Length1 2856 /Length2 30071 /Length3 0 /Length 31703 /Filter /FlateDecode >> stream xڴuX>LJwK % 1-tK4"] ")[~sZJSMl l\U550ɦ {lfEqZB YKP hXCNN!T:t:mV>5 R`h= lVP7d2ASd>v5x~W-Pv{y89,A6ev5v: jt0A+-l tu z:L:]]EFGWO ++b( A۱u}tt 58~{8n_ASm.40C ^^^v= `w;vW;xN;0A6P9!)Uk ;I/ TJh715?KYC!l_ ÿ2P_/ui0te&~^ci˶<< :8gljRJr:l!ސדU  R9 |P `w3N m@6yʡrp{ Th pn=vLo3o3T?W+` ~yXzP6C ?Օ@`пP&`2AO ڢr!Ё`W/.@,]}#"􁿹2],! tXJKK윁=Ǥ49Cqq :N _J-CZIK^J?ar ktwA7 :6@C)א-f8~ $rF\?8 ^AAjo$ \ (?Er\ (WbA AAAtV>D5!y=ryq;l˿B,ۘnڡ?4Z+[Z Z>c@o5Z$19)8UJlo"%Q?6y&*F M/C1-ّ+$gc*>*MЛe #NK3^4,YF)"V2QddF߇/@1F- /ɰ]ncuPV.߹­M 5*Z"k.`ef\5SvKkN.P16[WPᆛXJ(DǦ:kT},ҮLLuz;p>ԑқ j}źƳ>0v}6[5-?W:90b&ڽ뤝T :`+M~iğ. Vs,huuw$gѼ 4YˣFz"-2@~хYz|3#}X(k ydGHhszJ#Z 64Y( W sm~!pxݻt=K(>.̣JԸOO9^XwehO(x|D\D0ǨD#N;3C3KmU\8')ԿgI; ;g' x#Zcz5`>u\9%{9J{"RȚ !!KYagĉgKf2[wy$W_j ^li+nQ-zSZm c{SSG: 'TD7Iߧf%ZV `LTіպ؞v 6 wk[E2¸VH⾍Z۔vP`e ,q2 /)?tuT"I_~rTq̅ԹM!")1w_oT}& (џh Ҕeۜm$ |@AtsEF&=sҙ%.ϧwGHϫTz+Wb(fvF!-d>sjFf㖃~"=dH uZwzc['x`ԙt}UP3,Y$`?\?pO@Naru_Jt6!.vťLk.m6{ :.:fC+ɍ(@Fuo)ɠ͖I 4%g$8gí {//w<-܋br5}KH $ eh>82m' v pSbgoTԫ9 |ǒ52e]ÕKKg ,6R7TΆ\76Ӡe%50GeXЉs'a'VIocUuG!&b+}5d4CL51|U qV OZfdS4F3J8D!yRe1&Ug}1Y*tA§RRor+1$}sFI GmChwi,c<}uTz ̸Qbkcxü}Z=22sBsr[J"ں QD bPObt.Y.o#ٜ)%?1uSK3n,f9~iuNYV9yvIT WEř1Fxkk:$s>G[$4>#,ogI&Sk2;8-f7wl#ۻ>z$gvZ2{ydF 1&]lnyJ%%nvN.L_P Tv .ŧ:vTR[mrۅkee16S& ycx_ƙ:o8VmCt#;+hR#bN ͽ_m+wR=!j:kdwGz7tFvhOŤ/?ͯmNB4ۦĻ:R(4Q={TXs}fVYi1d6KuWšΥ^6ѠQr40'2ֽ`tO+ĸE?vI)B|ip3Nn #~TYEElQ󀟿D a77U&|cG>$98&tL=O`JBkQ }%ֲ't7 2eofa5Pz|7UC(z>dӲzre-1${EOQ1,Ə}wksƑ;02kF|ŒڜnC8Tw){H:ewUjӂb3l.MxkjHQ ֧TuL.$ƻ{|_9["@M~=z|zR/%~KcLx94p:θO̴̼&gٱZV sj\0$P2$J^qDWuG dtf+v,+bЈd(C7qG/yoXe'4w,bFt,niפʵKrd['-jd$G3dc-Yv7u_tsU8FDJ~p$S1ԛk>QVDHێj񢾂1eɜ0e~πzShG=#ˀ2 Ě- `0%vlK}?( /_=Y˺9 FėqlWT p!VKkV%m+s\6!-l^7:``m Id}Za'w _zL#VI3ޚ>X򗳰.Gg u+d9s"yv%-^R9DdLe]!|Ҡ2B˾ͅGne?!XoM-4N*5hmH)HrT.8i+j$ pu; yw ՂCYk7 88½1L!Y\g9^Dc-P#\v>'7Fx?3T_ER|ZǣkxBúנBs5=y8򺧢VtTs|Λa8 l`ޥ ,9ED}m0]< `{*-uGeq[|Eeݹg,M1NyL>qm/w4% 1 KCaj^=x-:$я/d- `gh@ܖ›%JZ$[ Y@X /0؇/؏3RLvL~G# qg>)A֛Tt}bUK,nC6E'?K1^cj-Qܝ$iޛ#)[bZpuTϿM+_?f lD|ǎv*Q˾=վ׊^BD@8I~ Ɇ(ݿї֞ =;^xąH8[Lm>~ 0d48fc-(m]ht}OxIψ%8Q>|`ǎMbڎl7Ɗٺjw1N Iáo%'17Ud!(z]Dd pOEn2 M_ }Cގ}-ck~K{ZN>`mWi^~j&6.+m#ˈ{˯)~7W'v*Z(%/kmPF:&25CW]9+q [wuB7>p"|Hj5[|ghVK,܆SM=yWJk Cr0RB9qL@siʪY/TIJwD;AsC |*7=f r~ERB)wbuqIv뻹YܝtI}7}{d%Tv9:n?b>Z8–_TSa3ݺ&2{*yv. KK!+_]۞oT;8iLc3u'6|33ஜ3б},jZE/{ekǥ][2*lzM3N\VB!FH寰pwPDQdLb$Gӻ*TPLӅ-`A`{)>tf6Z{߿}ۼk~ŕXOXbSO9Qc2"_:ÑJKVxPV+.Lս%(ZO=`nkÕ>9rUu=v'ǺNڒ|#wP*Oz@A}ڭmjDӤކxTUHKN"^XH7S~&/<3Ii>*@FZϵ`WKV}d1L8`)H~ 'c֠DR1?C<,o3 LPF7iFSRH\{;sjR"cK΀ٹUp^iNը8:$NAeM67i}Ǝ| ͠H +b`z:lM.C8(~mjZt;jEz7Ntei$)8 Y!^j>YvsҍūL҅\uuoH=c$w9,K"%X+Z׎&L:z(Q-"T_׼3d)vQy xΉpjō򶝇ɔ֫~h B~Em ;f:B'bEZ4@b]FZe}zRޭtRDsҢ ݠs@ 8j]HHO =q͎ԺVeZ5 -%T=zuIUݭil' {?ud1z CL(HDޑgj۶wr-#$MDl۞ LmX&ͭ?:9`CX|p TV'Q˾麵M)X[Ui{9>MN|laĀW)'ObIAz>5,~wXH@{G6,rԟ@nIw鞫p!T3$l8Ȃ?*VՅ:."[1tybQ\mc4 gcF%v7v{lN=mn.uKYD&#ɩ6NxVL)䲉3Vawmlf$/ Sdi8Xei=6DӏDj7$%clZ8 5y((0,(ju8]# lf1a2>\XLf5*Gx-qI6&/ʰrY1FN9-fp7j[hupݳ@i7##//h9,2g?S:ɋ +٨<$e+-]jx{llu?lŤߢ|sY=*P _Es|I,UL HR'zKM\r|[y6rNcaC^t$He9<1Fk\pX 2HZ!(ďxVe'ar-Kmhm#Տ>"RM+ryIyIu5Gu;Keڙ3} |y^=X-nfw!|18b=)m2%u}JW5w[cݩQδ\el ~rgh=LBIC&P$y|#^(v߱#KM7,*Z8љ \:jdnBG.*텄 (L%Y۞u] G?ZFZ~|Y)X zˠɸ~[~ÃlbsO%EXf#UOٕ~‰}Gb'8%MҚIc%Grprڂ'WCvMm`G3=!Z*!pԛ# {j{*ְAyOաpǪ;WyN(2ĮŚ6֐I[ڝBe!r`wޞ r,6XW!wU NI 0{~@.[lfrJS}Ui/*!ߓY!Vђ3AW%} 4Os ./<|K έ_A&;KTEua*e8qpZ]Nl}Z^J<WXD+N[oFV5N׳Z/^ʋ̡TX8ݪ[lݦۂ@tI]0G'K""2>k)~k+j^Gs`xφ6ƲAh0x< -Roj eX.4q 1T86Yɴd=! 9^6->#P7Ntfu"vX/A;Zi{.WByHa7?7!`c!~B|f`]ɹ&!x`T/}}AŒH2(j!8*Zj#z]b3T-#+(r~VZ,@²ǹnuT<*Q( |M4@Fc ~95:YXFXƐD9s 줈ϒ~7^L<Ȕ(mv^ڛ^Bw ݼoYWJ`'myt V:{\DVTz_ݞ3b !\ ҄āY[|tr$l8L᠗4p޿^?HQgqwd3ʢ@CЈc FLY@cTL-mOGƂ:2% y ت2GqxUX }uMߕx5V^Sh1eO^d?U NըLcbށۨX'q!ɆL+MGcRq/ 4;nГ7 $nb&PxNw-ɾ 4+V%fyGGm OsrtIm|{q@^iۣJCOwЇ_}R'B0nqЖdEsf7(@:Oz<ȓ7Z:ddTA5G*Msb )_;НXIfzxu:sR\UKx #?v Eh%Š;:~DvfGa2Bɪ;K& yB9F+0sgU7]:+w # QgXcMFz Q Zс6Ge Uwchyf?sT|cvr>rFK<:Uu5X&HA?H=|L>/tADPO;n,ԣH (j?9Aa5ɉ>~[›$+xGx~`GfS,UYGI*>GW jxf{7rzDrŰzYJ$U5{(o[Ud$%i=v䤄 U:ՓaQBIW*Ӣ cdJnx:pit|hk$%d@G?c@OxxQ]B`.{%m.Hm0;}bR&lDü9e?w^w94 R{Ps[vEXEힺ[ n59{B^9U@>;I7_^;y܅;7*jR+E*ϵQ}X_`1ޭ!iG uM mKzyns\ų̑[j/IQɧD49:* 3M",{EaGAӻdJ~W g[3]yo$Y^8H *gԚ94j‹,O/{ծz{.Ֆ7+GçqmNKB=uʨ.14YEV_ڮI/O:s]>H%ViMwmLdx(a4`Ȟ1WQD;ֹeSUaoa{hy -s$oo?$xW$3EZ󞣐XIဢ W}J%{wgNʆ+7 DNj7- Ya<R?#)aޠ 4n'כL$Et4:vĽlY+x[ح{X0 n ͧ Xikυ? 4vŏ͔$r dpstS[b~~eE4 3ڵ1P~`"k?8 9}^WNg@wWᏓG3d7g(;0"vkG[y1.\UU)umEܳ3#I4| 6e"1˙ g5\:oRkM-1h:5Hé擥x97ZRr1$vD\o%Dž8ΟX!Lm)s|z6x} sDR"jhb<r!R螃TIgِX3JA,5)EꛗN x{Mtơ=񬒿x)7~|CA?Aa0*DTα?g}ߔk foYPًS;cqAzô'Y܁sua%F/aW骝o1 D2+Gp'c |ly3IN!N=*6f٫ek R/oZTүtET>H:*ڨU\8vD0#tӎ#K>":ic);vJ)[8ؾ*;RщLou@̊dOf%{WK;DEG=.F N9RtzuuHzljBchXu5#,[;b g.ΊTп๧AxրM(mw"æ0;B]I0DZC)7㤾wliLJ@jۨi XNo ųJ/~ ? n{kchUCPrnKGpjbhX]Sj]8l__y$6;bߺ1mD,9{HpF :7wf*#yB>nxH~`Ж`-Sx0&t .debC%ܛr%ԋe߇31 7i䅒~vjq$Xٽo'Oͺ2mQ2!OAJD*%sΈCnҝ-,A*xF6͞P0 eQWY7G˴rwH=eu[2暲bLOSa :LO鶃!Xqo{#g@V*+Am.kEN.-4 %_wl MyKJGhfVsb}U7F8zʝO x-Ӊ+wb}ÚW壃g"LJyuSyVF$fy, ;Cm# l/A7]%ѣ{T%Y$RU}d6@C !mN}>oj"ǻ*v`Ly a# K[ u6CoTMH^\Tg˸tm&-ޒDW;(ע׺LmѠxl%^Ӷ/=P=Afe݃A ~t܄0<*3]QT?"Jߖphb'Ba/VV\$<=2&j~UB(@e'xSKoS;]O/-BB`%,o5K] 01A3!|HO 3ğCt|pa7(Qd3"a˅(-`b-eSY$G) t m ^bHQ HilhD dnS6TjZhP'j3*^_N踽Mub %qQ3xHxԑ@,x3Se$Væ+ηQ쒜@#pԟrb #qݒRok {'Kg{ue=)~~|mBŅ/"VT93*wrh\Bcz$Hߍ'=߄TǙB=[&/|Biv0iE-dśֽ󷇏EH,1-vFoA 1}6NHǏZy]*ɵ4K/ΣqݴМjQq0DRÉ%܉+"zFY+w2\R^ʚxN%["g,u!  [vcqisR%5) ͤܒUDr 3&†9?UȐ{=Z|e EʍcrhU3@چ"Đm:pygU>5=^89HdGKWUO(k.v DžEZ慕\z.5W,l2Sp6m(e^Ŋ^5+fLJՏ\4 }w'8 Moc׻J%4LxH@>+ uD<bC5<_74/s<9e_OR*$:Utܥ׃V p`T=`.k5`$dO{OM38@Pmi6yY@%J uc7mSB30bkCBڌ4,k"^0HE2kDFR| p[KMێ 9'D a[,|'o\B[Hݾ 8 ~3kȩ=m@wT¦]Z7CLt[0tT߯[Փ)W!-5W ̟¥|joZgobp  7 _(%>+ lL:̙D. Ty9Ci_U<:]XjF;VazgIʞYmC09d10v}Nhe m 1XMVs=T*D&djf!ׅ%7im1ɞ K&?o͕F1C25ux@=$@>Le&`!==(b'krS U?EnX|(fg~a*S.jcyzDG7;8tو )d{Pf&3 o5;>lCHme}b"Uf_Y=@x5X/@2'L'̽]ƔdeZ[hc;>CNSl(S.Za:ՉizT <ڂ6#Տ(8ӱYdKKf(cFy@z35͔w8`8yyUOK雴êU,]EZk}1KVXJa.W˒GS؋r"'|DX̼cO j;M©~l'yX[hGCfZuY0 @m)EWʹUۢ\ pήZP]<u&FٙghȇusO0 .v8+A/OSv,3*DfeJ.eYm7~AM`'U/JNN˞= !sT~/!1;}Y;3Wa/7]s\ReĨ Ga%XD9 j95BG SD$͘.*H<~\0 JÆT dNY "6@+ݦJg߅[qȬzkuwO;Q%$N5ɕ,gbqSu:Nw;b"nMy ҫ8HM{FijM!]]0Io୛g̿gb=me/N;il5( ?Q͚ LMS(Ă@8L)ym,z6z&/x`)JLMcM [ 9<e@OK"YӰ/21z֩m/ŊSj%u˸? ,E[m ^ \7Bo8>'ڍlƭmiσ. dq>ctbqCS)Oq$Ȭr1.Fkq).$ + ܾ_QvD{ -pƼSQAA#1Soiܔ ;y^Z4S Աo6`~3QȹGR\+5ά[y@#lXZGf֞;xLHJJe`JAFf6;5tS)_Z"( rNAb{,_\5e$Z8D2G4 畍$CwH1U^4Rq Hα'H&Jxlj"(m;lArbj‚>)r}= Qy !7KUH: a_~Vv Bc HJFd}b9mi9>7'h=_WDԥ8Kҥw }JXf ]L)dbz p= X_ aLU6V/&_i:Ug(hT]т2F Ar?yJiCN?BQ55{\]ς ǛlY$6ۘRxH{y@xqAuIEB*{a. VE;E$ۨ|^+U$+rȟ͜ !&/wρy1-L%E%xRjp&ٺirY0 ]Cfg>53CP7@*h%}JI G",k{ȣnRhu|nT0yg^5v=C+e!SK| \悶YR*ȴ!?B +u+gd[(xɚCHq=)-]F 3rpKk2X$ p +eM4K9 E79;}.cRgTĬ7K5{(@jNM>87ʫ۬u> v\p#eCöBbDyCI;Nq<֔EVzHCzm72yQ 1IDdfsS;LXc#=!OމIX+ QZ tT r-5Z1 LL%=뚙q T P"y0/(E*\1$o }\tH.T::w{hQi\u$c))n߀?eu7o r$ EX{gSBdX's_  d&Cm0 e_2M(bNcKf4F%@.l`rK" F 58rpbsg&=xIWhuk85*H)F ?!2U)#a82$n>?NQPτhn*bꝋj{ +9%Kc9I˺[oN8:Ort0B*EY!7 = :E+'*82N<5G?>O3hA]a5᰹ԻtVu~qY #Uĩf^rwh;2iGЦbBm1}}BdώּT8[J|T r] &]gvLȨŖ0B3OFw{~ݷY(ݑ,-ҾIuvZy"qAH-NLγ @n2#KCr}#q¥Lnw`"#De R'VQK~If rq5K&a_Nb+fzLxdT?7-Eq;qQC]K!Vi*&ɴ+Ďs.m_RZjZ~q?߱5jg?tz`en 9< ocZc午/-E_d(|$kn_~c=EyFHvMec!:hBS.oMfiS19E Й#o8w_Z z06z6Hwj@L2|cTW>5oN9XKKաO6Ŋ-iԤq]BJZutD`NTEjj2,2X+f̽_&Df"m4բ^mˣwZ)Avޚ,U[ҧ͡ 1c ->NeϜ_ӬVW|*BJeHJo!M^3u}86wڌ+e}IU-{Ś߶7%+Ro3;ò3w;ԛ+:;)[H@G 栝O\9)k (tAlfAcЦI|O$I?% -D=p!cX? O`%WS(yg> вtkHhowK*x3˃UqH.-Wh䖑Hӄo{am6hO xMPըϕ'4Ĺ\+ 6F}Ϋ)6..r dz6EX|rSPȮr(/ Qdm{/`Aj/auu6ǭT]d]H(*!~HQ}H؄_bqFDC1h7qz$6 "Ts 秜3>ձnB{ vfx5%.zs^H^m5zs^v[@:h+=΀f!5J^Q6Rφ/6OO~(zQ`PE[ZnV>FYR}a+04He>/[.L`I̓sݝ)T쑊;ߧ?*z eO8l2_ٍ }q[*:pbc`\i 9;CXgfjZ_rB ȭ jSCtR pS:GWB##VS(ʽk>g"nd'yO O^a?Ob+IaY%6/x;DJRi!ID _GgpdF3Ź}[4wni/F$MpzYyH_H:nDT77"x͉BZƩ.)m&LWQ L7)g ̌#/2 ŗ/||.Rpw,QQT?)y:T\rO`r)(~q^x7rT䃸ɨ K iޜ[jSٓtY*c 9[8}Xrud1Xmt _\G~D\Mό#B5Su$&\5uQ x0rq&6ǐ^l4z8SjOLkj\agZǘ7:o?l"̠=bg,X^*٤_I1t?qv aw*]@pv)n]^ su^I,CI 8w >Nm6#[*"ʢ!=nw u:g-x= Iz;c_w}_=%]xn!(9E_RGqrbYvP-P{hbq7y]c2OeC:7߫A:kleU8h8L¶gu¶wj-mq`4w%` nbӠ4K=wsRardMʲe,ȣLcSWUĎIJEClDR|bVm7ޞD'"`h|ˣW\w#3R`OdW:0UXeV,Ѱ:xSwTL(@o+-\z6;nNAMd/De`OS 0ZJvFs^@*$ ۉ  wA <*(IrǓ̠I4/r/l"վ,SZBcoSO+.Ô1U;$0QXĸԣ}lNߊx)Nl,8e$"K‚hJrs;yWEpj`蝂[;NwvǼ Z@ƿ|$-'%7o(42m>X($$͜ىyw+T_.e&˦Dͣ؋jwСB8fx K~S'=-Jv!Ţ\^PF[R[1؈t.i6 (*֘ ۊg'ti}` `y!\ENh=K=<`6跹FT8pIGD T?l,nƒ=cVsJ{R Mair[݅$腴\tJLqX)a,%·b#dTvkSK%+FOSݲ@ԿAJ_ko\ٷSW45 E2Lܼη1ijb 7Rն(5G\7x!A{0iʹDw][d,k 8 7m-40"[L#"~1-zgQCN$lallMaO iѺ5 gss(x omw*'TiIcc8aU7y5@%8Kn|'0&cU26@K6@/HY?9\qz)1}Lm卂r9 ֚)OsEM>n F {o B/9㽽`2.?"3b &Se_ Y $EDxʰ6f(~3v`uAb+p|HUh9#] p ]g`QX_ p5^v$'lSl9̔F3d_ ;[O'q.b^%զs (qƐwS]Y~ϧ?tORM:; g2dIRym5{xw ߎ2=V֖ƌ`_ؘ.r4'%g moSԄޜ[jS4N2Mҟ} A]F躊%˜O9k9Eh-8]!(n &u!+yՂݭ&x{)הg6˸w؁)U$2Q=Ru~`Sѹh_΂?b<)"z+tgRt 1h"5YAb{mʼMX/o0C6LFC6,8#Z_k{)wPQSЪp>]wM$5|Uy@Ƒ;yo0AF0}^|CP9H\g0녗r[\*N󞒦}33 H_Q@X|a2Yq,P[ '3 Re k"/{=,0-.2=0@D'-9^߽6Aa\x.'ue$]ek*sd_` y 0UNQЍȏ־6}óǰ@"Gkt(Q=URf}j,[-XEeJ3a킸vG^LcQV4N-~~E/^ _^GpQ0Go9`ܵI<ёh TI1 -0.EvEi\N_Uo5Ђб6@hҀ)-|-c_Qs7dOF8B`IJl0Axv- /}5]IJ~,lT6nu-ٌc9L~cY~PT=MC#thp=QOʩY]֋v%%(ݝ5¼D{14 no⁶mP]!3Ռ}C\B Bijf5c(y7s!2 cZ}63vZ|Ӏ^\ lS[fTM$ o؏U?Λr14,ZG$m,ͱ,߀ *b4;k@_Eph>tBf5FT{T_0ΣyW*SְPڃE7ߖFߑ3|5)BGj)mG*KouV!/=*A L&̌Cz:rP<#. `P ^w^Me`$f.V@-c:h)-'Oh,#EҦ~a|x o^]RR؀c\t 3twLY~P̨PH$]+@T< <{Bk*w<.d\.Eި羐Z͛CPey.uYVr&sUݑS5H'iFD5=M,+xOJf-*3T֛fɞJ)VnȈkG 5b|c9'LHg3\aK^[&e)#ݻ3Ϧ$Oџg[Bcu}0?>cYb)5L)~OZ;xFEjL)nda{+E,X\~'3a(ᩦAMRgO[]2&n'!<)/#.zZ(rgݷ_D$$yzin4yDxʙg͵@,#ՆjF^KrDq\[v~ m]n*Ui}Y'3sq@s!BH!jRxRi'Y&оN8n愙 eq&Y/]Kg>b= H0zv /j6} w~SQD96/ JA¤Mw#mrqEp'2/`ѥ#[*f'lUWIU. B\@ X[@/(#ƒk2QWhAa(2MJqKmp S$;]xPtx+;^1@/b7q ՑpfFW&U˘X1=1G 岝m.޶mZcz(bet i/mFt~%ro?MNJU1ͼJp$֑34\UD#4~s0t7dZޞ4n@JcSy V̚Rckv%,,qB`* xeucuJ#xxP#KnT)~Fu3/C^c EM<)\4_W+7Z i*[DKkn_WPKʑ t1xU;xk LtIckc/qG6)) endstream endobj 168 0 obj << /Length1 2270 /Length2 17299 /Length3 0 /Length 18687 /Filter /FlateDecode >> stream xڴeTk6 ڸCp'Cphi\;ݝ$hp |d;}V)HUM쌀v Ff^ 34OA!4Yي.9@`ef恧HmJ;@2Tu vN #Cw5H"jghafO?"Cc+;W'+ @Q o.P֦;S*P"TVPSTa|loo\DUT$b:=@RMEϧ*=@^]'ϻw9qUaU-Eq?5X.@G'?i;3]MlJ6y\]]͜@vfS5p9Z޿lkN9_ @h$a/{+ߝ{oOLJcn,55~7@D?iM]2kOoC=1C[g'6up9+"`ja ϙY%WQe}<[92@Y',&>\VVVۚؼv>1>ݙwl\m=?bS [?}7qgRppJo`@7cs??b?&x{L /xO'C < >Wti[S;ϿLkMiw`4g?[?$ m53v/J-ohch?: ' 7&KL¶f@ ;#3'4j6}t߯?׻tSile trph&U5Y5eUmL,lCGGCwxa`xO i01ځ] o#0  qDF\&ѿ7Io`zq3F&Io^蝙={ÿ;3;3 5 ;!@?;CphnoŻ?;Uw6Cwfb{dlcg坰?;a)ha Ykp|=?{ ;#?^?{=Cwow==5aP?L An_/%w߿t+?ED<yX l=fc3j_y4@71ʢ1_eJSpxt4ILJt>X6)Pk_eOWbM@L׍&JB;>r>H9jr~e]429Z%mqmD#Q(֩7dR Gl΁42 q[t bvɗ}(:qq2Q^į; ]zr_2k7cqQ(RSԟ̤TE}¥"~-pyQD봻+FP)X̌č[PaS|c=l.UUZwj܋҄P9t:郹pLeapxR.7 >技t'Ûמğ>*D#mBgtƤ$l)m-O<&U%.$ V7^lLkF=6](<1y`" Nu:}QL&[#=[RJ!%5w`7J;`Jr3a^ə@P˅ne6\gSqё$fTZuL\q(VzXnR(g7/͟ȉJ G{ :ǭ%,yS#x(r.b^1^ն`dl,{n'Iz s8iw`~%*NiXz Y%Sd~I9١e" O SaZ%*<1SzFb8kAj{`/|Aiޖm6P#0$A"7wF6O$U-Byyv)%x EesGM}Fu&q_Prj~uh,}pch+׹ ǔ57Fp_%''ί4Fh"657TQVZRgzc&&4t|:2TfwxOS|-Ut<بikG>h iޖ+չqssy*yC4-d I nVw ~|ZuosEp)|=tDx&=dJg$\?G|y<\k36.35-Jt (`הT mM}{6]4XV@wPKPȠo{vdW'D[)mk8&xF7E{uK?~f̑ ^S4gVY})@|m](X|Fn!c5y)#Mm7 E4EiWR_DᆐIڧ؆ĬagFDͨAybѵ85|%^={ҸtlW?kCz]qs~[ .>s.b!bSO ؈4/TZN{=FTQ%f^mn)R3 $`>TH)׼L3 .oޛ7yb"CtŲI[ {00h%UDXϸ/5UsYmy]!AlLN pnY~S>þc idGHGnxdoOg99X)d<<;F(oMO)uҹrxJ+LFG}ڣDWr%sF=Ù4_l^DVRXǂmN|f!e >9ŗSleW"cMuAv^h9U)W>gԭzDba51W߸ tRdXey#Db}p_L sIeM8f1bK#ѹ[vy^])pG$s;՛Ktdž<$LmhkвXc[„O)۹)_H͆%^W;)ee.MV]rV+Ln_kBEx1& ."/!qjF p0(;VTPw(Mr:A3=\i e 8u%P6|N2ͤ5<`v?X2><]#5 M*7p:~ D`/%ђ5'>:.$; LpE\LҖ*!x$zG7mѱ*սzE0c "Jh1Lrb>_,C;-#zP=l(l ._vY*Ʒ 7eECסY`/rR(~h&ժxy og%!pEYlF4h)zU);8 Sl rc8zzٝ"%Ecp{DI8j: lk#NV!vRPyY_!bz&Wm6HHB(DHW]iXmeD[tgbv8@0pX C:W. , U@mr bs5 [Wb]֙GN|PO3G 3bj" Y)2B!ض=d\0G4l d!,Pwk\1zwh-ZLV)KN]$B-at`rnH"X<3LFR Qd7Fq2k=.Ziк{h?Xz!Np8}ǡĂ}[YQ8?POk5_j>xY䪾cSpѦu"c=1困6%~bDbPzMjncޤ =q{ 3#W.h <%?d业(J\gh@dZ73 BO= s{NppߦJKV_o q<L뤳_h})QBS-u^?ph?2IK z~-vʏ$? \F)(n[lr%RLIb[G.nJe(|*:4IXe}fr ]TC1.YӁ7 UkmIT/4rB8#E||[ o>B7ֵch!]B}d=#Pb 3]s"FP, H,vV5wdAUh\&B8GBt^X4cC1П\U3l{f5o*O:u(xr4@^˱fϧ|tp\-㊄r ϧnHtj` 'Jՠ֍En!kŴm޶n6"-N}ImvLk94+\#%4v*u '+Ҷ$MmbaY2<;NC]8S$ j96 [M>sp\mކsJ`l&"Sz@lFL0 .ַ#jkYԅݎfOe<pt]3ݝq5SzLI"I}d2wM`L(GwZTPDړEW>3,CB?4P,5*]C]ErpIL;O2UuBߝ/*Vm&zBz~ G ֐f@!p S>AO_*Z׉ZeփoN (3̞H)/dmauM/[(}vNc2F{VV(5ppu(< @2ޯR/+uU@td̞V-_8ǚuWje'R2Q:#3 TW. sX+\6>Lz>#' h&!5ڻL/#u `ؒcX2 ){'G9LSiDA8QL\$/ M\ӎ`: q-2Ma+x攋iHk*{!C`IU8`:A(˙@Ȫydk3|6 EVfqYܓ}8ۡCS"3dcqG 3-_zm z}\^^6C*G5$j 8,+֕f*4 ʶ,xH0mk͉L|1vq"h|Zת*OBc@\WOj";rܽj!~*,5pv~a$1] 9e* }@h ' n2rġR˫ yLm fcṾI3hȋ ˭fL.| Bl!ύ>Iٞ@ p#O56jh [Ʉ=L$T!o$)K@8xr:fAgaqW/K| ĭ~ Nu5G"ϻ-ܖt{Rp=t}kb\ ʧ>3C-n?R=7؜3Td0=Ͻ,MuRU/ cq0e,;UyImAؒCvm9ڥwenHIEQsĦTg,XoD' yC J%C4'Zλyo/ zڢ_!ђerT^IGɨr)Т?'t SpDIBS.D) ^?jQERz26Rpy䙃Di0 w $hfaz6@F΄]3hREfGco2®d:lPfFO%TJNƉiݍrHJlĻ%Cg=zoyݦa46faPsy(YEps3Z1JNnIڕ&ٸwjP #jCI3C)Yf؏7la6&خc*Nɷ75 b-*B{ƋB~%b1sf FVz=  Xy/f֍%vɆxym<9QaL;qA4;+N1C *"vQ zq!$at0JL4'f4Z }8m\鴫Jqx[S9 G^IUInƍ0' 80BL#kƾ.D??IWɢY YMn#9rԱv$tVu>g*c t*AYoucKaGA 1MT o CHAKc09Fߪ=] qVoV[O (tRQ6%5 y?0cwŢTMh$С|\fA-ӐDh?S5oì)+衖~WqU׾39XK1to-&Q121*s9?~{(o$+Ox;|Fhݖ<{e`& 0ӌjPcW7X'<ù3y}6 Y`\>jq 9-J4į݀^ EC,d85'ellCE_C+G09ODs23,oRA?=:NjPmIyh^)=j򎚅uKi蒴^[Z-ƌTwtJ)b+4譁gHβM*G}-.%b*k;WͮTYOVm"]?o>NГubT -kI-w_k@$&!C0%bpům(Q>6%o0 jU-Hdۏb)i505Vtpi4GL7xqcϏP*܂Pk\dꮚۼ|ů QN6li+0]I(5#?ro'ݓb`=u˱S|(B1yLӈDS1j\BNY?ͪ,RJ*%Ѹ3ôzW64A}1<Tbr}^ɲ2Ta1c@`q qD*]I B_,>ArAbtMRtK!H~`@A1(OIDnȓ~lSR?.}{3FFZ8)ߵC$!O=؉u [7/[֙m?Y5U@O3n6EM ǡ%ϨD y9B^՟lЅ }@'1Tk;<8T?/$YwSEjZ n 5y+ d17Vؐm]sTrN ]'o57q]LkX"JLQ/S@(H~w o6M~TAW;-o*{dvme]dU:q7 '^'UHU86 &pXiMX߫]-yN̴0sj$l4weg~Q`_UHF]|Żv$$+r4K ;.wb;;-ĝvC)9y:ol'͘&tԼ6!vW"QC \1\+L2OSR%&&ax=i9Wh2q6IcPo>߾t/LE-Gݧu$}9A3'.{aVg?yDgyz? HoV;*S.7J{L*Y@Mrͪ6XK*1ȴIQX\URPZElfO2otYfyU~&Vm<%yzKrU#S/|Fkm/ۯEl>Wv~;{Alhn+ ]Vz 5.rł0vBCu'Yv{3 $fo (ќ3ݑ</tzO 7R MK]y9h\R:a݊֔iVʮ&(z nCV{2W4߯c/zPyA2K/wuR,eSަг5 }mbo89b q+!S\xd*N' S n-;Le`: [pe][# zg6u!|%: N .*zͼ n eS;3BhNvUkei-fbn[/mY+8N:LĥWa=lu:9g /,K@T[)3NSu4b7uձy:!Y?nIUh1)Dy]bd< .ifzh @Si##<`,u@JXˮ&"*3U6q~'辵Ֆ@ cĄ-H{B QVA67dGjVwbd*I 3޾]!NF;@;~%-J֜&YY\^ME% =q>B֥=뺄yE@'I%|f1K#LyAXF†snqGt&.2Ҍ|\]p)TyOZ=jK< ^c{84PGqc/ Pde8Pma|Y:} H ʾy EX\aQƫT&~`Z吃4,ÃU2n D9ɞVj4 aH5Rmwَ;4Tc~9*g5CkBIJD*>7El'=;ƽr}T4y ۬Xk$z8ԧ)2}Hx /YᵶFU1{X\R+ɮ?0tx89}dVvD/x)Yl:OaT-2w?F o t@<{̾^-ᯆ3vn("S@h >Y$ǔDG/g^ s!:58fgM#X}ϝpan#zyh&@ Pmn\h'ɼ[E3}Ĭ^@ǔvYR J ROͭ^a# 5Z={JKgUiʉ~e=ڊGn uC>LyNEVOG=ѵ*Fv ]ei䰵|̊OHcqJ} g0&ܦ| ZǮͣP/XM\į1az;w7V?4jvp,h%8{SqwR^I'@A2> 3Fz6` uCbZ8Q+Z0xj |_?6LvD\39lާo>sd!vζtR!ћrdJvK.zA-yC,{ e3xbkb5aT/m`8CgLlw~o ,"u$)?L~ 1QueA+2ejk61Gۉ)mt<T;q?… oOElMw !I)%j~3gW)1hNVGDX 5 v35 HK$xbLx\m;OӔ,ǧPByi(N1)O` kHL'5(~OXw5*԰[v._'?oϠUd?_&u) ne͙Iqv7Ч,LJRiLٴ ~O&c/.;Ԡ N? }(KX`` ō4*y]´(OyaSt:%*kp}{~tSȡ*Kv&K^Y8SqjL9=s`}j1X&B艳מ4tp䘦E4ӛ%#pOm) A!rrY| ?Dܬc4[ҷgPU | M"?}!GY[3 `/rY)ޡ,Œ`Lq(=H&FWd y-9uQZzK4 _Q>'_x%i%w7c 1nL7]n42u-RAVK^ e>|Κg`ޛ۴X9)SۖI*!)+0l}aWٲSruXc죢:jH1wY(W;WDu9O+V} Q6< Z@j}J$ EJkbP{!|hiЛ"]w4z!S#I"_i2?ࠉP2/hy>_=`#ف%5˙3"z?I{2z`=;M LGJ ]Ϲ3ѳ3zEYr8Q Xw{ ႺX&բ4:A.w #ZCV2C6^ FO˗E QZ^=I9_<솒kP=|?v](5sW# f(c0AbOX/ߚK@o庈w.ɁD=&q?WQ*9oC9c@ +f7>֖E ү` xՏ]QO,odrNDz.6G'`tfSg#c'8Tkt!ٞB)jUp'NY:XO+zZ~0I{ͤ*ZbĹ9i1^#p"tCB %kQVW/xq8 qYo4 pk1O ~zP)6 K܏FI cX2޶`KÙɥGD8Kq~G7tNr&.BmYX6ZYOċ#Yh<ˈx$@/(U9]a"G, Q3 i)-|ɓGO\\-C57cYMH1ʴV9T9\Ԯac8Ϫ/Q4Zh'z h:jDQwQnb2+&R'dySU2Z @Rh:^Z#l HûP <*GwGB x/ҢaR6FO<5g~DԷOH, 4 tcmgR .p [}`&`Ӥ\O snjP=5`^W:^xU9Z]?mΩ\idt N``u! E>\|ͳv$o}qUMekU!guz/FZ3,KΩc[=uu\Jr)$p)#z6d| ca%Z (u=ȿzJ{٤SdhA$ł;BR(NGs# o1lF,6D.'V߇ Fx 船sfkky9iniڜ|;=?xe;pgv}c rY\+(kwؗD%]tQ9 l7I~~BK%M16V/$fړa˿S93Eb%ʢh LvP]܎u 7aE*Bs̩-<2|s'{Wl >Rf8:ʥͮ"6D#d~Kw*?D$U.;y/%A8:JFi#^a44dYU0?'d𷩤kF_[ yB(+juB 19;vCeI_3ѧu7iNprI8L1GL)Ĝp`Gu3V@0S~zX_L!ΕnY@sf\!\GJ`ƔtK_6F_A(})a.SW}ۘVi!QU,v]\3 '`aP{UGu2s KB5 ڲ.Kw8Y?K { \ޅqG wP^joѥ1x,(6JCъmwQKU);Xx3Ϧ-Qdb˘ie>9rrBG@./4_.$tiYJ}+ؚ%'KwUtƤ0]XZۙZ'>RTo:b ׼8bp7IeNݼϲgGG endstream endobj 181 0 obj << /Author(\376\377\000J\000a\000s\000o\000n\000\040\000A\000n\000t\000h\000o\000n\000y\000\040\000V\000a\000n\000d\000e\000r\000\040\000H\000e\000i\000d\000e\000n)/Title(\376\377\000A\000l\000a\000k\000a\000z\000a\000m\000:\000\040\000T\000o\000p\000o\000l\000o\000g\000y\000\040\000a\000n\000a\000l\000y\000s\000i\000s\000\040\000o\000f\000\040\000l\000i\000n\000e\000a\000g\000e\000\040\000t\000r\000e\000e\000s)/Subject()/Creator(LaTeX with hyperref package)/Producer(pdfTeX-1.40.19)/Keywords() /CreationDate (D:20190717121547-07'00') /ModDate (D:20190717121547-07'00') /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.14159265-2.6-1.40.19 (TeX Live 2018) kpathsea version 6.3.0) >> endobj 143 0 obj << /Type /ObjStm /N 47 /First 398 /Length 2709 /Filter /FlateDecode >> stream xZYoH~ׯxrvvD˜HBR'~IY=0vfGuuWW W0•"B*x%:1v$8N&4;#É8Ma@5זH.5$Dj 7H'-t$QDI 'K@l%  rf FFp-51Z Sx$1IqbQpňL*GAGnna9@jFLX- r;bB8 XJ⤑#-YCHK4U1&.bt}ր?9h7"l=tG|OG2Pz@f 8ףy">Vvyz êԨiwW>[<|/#z}X֏jR櫺(G~*]o?=w"]r6>.S @y|\\cH2˥<ѣj-kIt4gWqژ'Yr6uL`SYx\&}Hӗ}OOiJ/NiF/eNgtNtI %hM $cƯw_?:}Q E(~X@T  7ð <z;` =9 :0.lۡ/y_c@}Jx8G^w_|:yu wp^ 371MꆭWawQɋOWaĤ%7Ş} !NkA`_={VŲ84ȎcBAI`~""(;,~SͦØ0w>9:p4kx$<^*>_Bo#Fg>$_/Ym ;Lbz?N4ӅC``Vf)J0ϪjSEVVlyʰN2W ̝JٻӍ&$Z(V[ٽ gm4le<Źkզ>7I1͗3P,"S\&DƭZkw$ nM~0 Grp {2:Upa}<@ ~ :|lmHNgy/3azCvW95#MoC;N Wvj~BeU741W\}CnE?Q1L3'܇`{١l݇l{Cْl j=ȶ.:hd7!-l"[P0P}o% v^ކ%Ľ5m+ )vd[A w!{Cv Sz[7,Q:?q9~O$$!I'k~= 8 v?cYCCްC"r$ qß 071G{ĕ7e rnUƸ{]Ȗu$Np1{.Do y𨘌iY`'5xWu eY,U6emv@_wƫ_g Bt\g/I ˢ9K/i֡ <556848000DB129E87347848D4C4D125F>] /Length 472 /Filter /FlateDecode >> stream x%;OQyϮvAE@TDTox_xAcb T|,uZ-VB++0v֖f'3gΞOKfd?o$ଗ*YoZkg=T5 m:h< dVoiu<Z OKvA'lxT嚣WKX-Hv^닸 `3n=٘~Yhw.!(tP6^]0 F0ӰG68#0 c~ 8 {9#cpe>2mE'e;cz N8 dVWٗbWa!pSm6܁pO#s0Ok? u$ɩS9{ITuJէꕞEՠy)Fel12W*(z;pd#CdD8pKʖ^UV\~IT endstream endobj startxref 277616 %%EOF alakazam/inst/doc/Topology-Vignette.Rmd0000644000176200001440000003056713402556375017645 0ustar liggesusers--- title: 'Alakazam: Topology analysis of lineage trees' author: "Jason Anthony Vander Heiden" date: '`r Sys.Date()`' output: pdf_document: dev: pdf fig_height: 4 fig_width: 7.5 highlight: pygments toc: yes html_document: fig_height: 4 fig_width: 7.5 highlight: pygments theme: readable toc: yes md_document: fig_height: 4 fig_width: 7.5 preserve_yaml: no toc: yes geometry: margin=1in fontsize: 11pt vignette: > %\VignetteEngine{knitr::rmarkdown} %\VignetteIndexEntry{Topology analysis} %\usepackage[utf8]{inputenc} --- This vignette covers the basics of analyzing the topologies of Ig lineage trees built using `buildPhylipLineage`, using some built-in alakazam functions that focus on quantifying annotation relationships within lineages. ## Example data A small set of annotated example trees are included in the `alakazam` package. The trees are `igraph` objects with the following tree annotations (graph attributes): * `clone`: An identifier for the clonal group. These entries correspond to the `CLONE` column in the `ExampleDb` data.frame from which the trees were generated. * `v_gene`: IGHV gene name. * `j_gene`: IGHJ gene name. * `junc_len`: Length of the junction region (nucleotides). And the following node annotations (vertex attributes): * `SAMPLE`: Time point in relation to influenza vaccination. * `ISOTYPE`: The isotype(s) assigned to the sequence. Multiple isotypes are delimited by comma, and reflect identical V(D)J sequences observed with more than one isotype. * `DUPCOUNT`: The copy number (duplicate count), which indicates the total number of reads with the same V(D)J sequence. ```{r, eval=TRUE, warning=FALSE, message=FALSE} # Load required packages library(alakazam) library(igraph) library(dplyr) # Load example trees data(ExampleTrees) # Select one tree for example purposes graph <- ExampleTrees[[24]] # And add some annotation complexity to the tree V(graph)$SAMPLE[c(2, 7)] <- "-1h" V(graph)$ISOTYPE[c(2, 7)] <- "IgM" # Make a list of example trees excluding multi-isotype trees graph_list <- ExampleTrees[sapply(ExampleTrees, function(x) !any(grepl(",", V(x)$ISOTYPE)))] ``` ## Plotting annotations on a tree There are many options for configuring how an igrpah object is plotted which are helpful for visualing annotation topologies. Below is an extensive example of how to plot a tree by configuring the colors, labels, shapes and sizes of different visual elements according to annotations embedded in the graph. ```{r, eval=TRUE} # Set node colors V(graph)$color[V(graph)$SAMPLE == "-1h"] <- "seagreen" V(graph)$color[V(graph)$SAMPLE == "+7d"] <- "steelblue" V(graph)$color[V(graph)$name == "Germline"] <- "black" V(graph)$color[grepl("Inferred", V(graph)$name)] <- "white" # Set node labels V(graph)$label <- paste(V(graph)$SAMPLE, V(graph)$ISOTYPE, sep=", ") V(graph)$label[V(graph)$name == "Germline"] <- "" V(graph)$label[grepl("Inferred", V(graph)$name)] <- "" # Set node shapes V(graph)$shape <- "crectangle" V(graph)$shape[V(graph)$name == "Germline"] <- "circle" V(graph)$shape[grepl("Inferred", V(graph)$name)] <- "circle" # Set node sizes V(graph)$size <- 60 V(graph)$size[V(graph)$name == "Germline"] <- 30 V(graph)$size[grepl("Inferred", V(graph)$name)] <- 15 # Remove large default margins par(mar=c(0, 0, 0, 0) + 0.05) # Plot the example tree plot(graph, layout=layout_as_tree, vertex.frame.color="grey", vertex.label.color="black", edge.label.color="black", edge.arrow.mode=0) # Add legend legend("topleft", c("Germline", "Inferred", "-1h", "+7d"), fill=c("black", "white", "seagreen", "steelblue"), cex=0.75) ``` ## Summarizing node properties Various annotation dependent node statistics can be calculated using the `summarizeSubstrees` and `getPathLengths` functions. `getPathLengths` calculates distances from the root (germline) *to child nodes*, whereas `summarizeSubtrees` calculates paths and subtree statistics *from child nodes*. ### Calculating distance from the germline To determine the shortest path from the germline sequence to any node, we use `getPathLengths`, which returns the distance both as the number of "hops" (`STEPS`) and the number of mutational events (`DISTANCE`). ```{r, eval=TRUE} # Consider all nodes getPathLengths(graph, root="Germline") ``` Note, the `STEPS` counted in the above example include traversal of inferred intermediates. If you want to exclude such nodes, and consider only nodes associated with observed sequences, you can specify an annotation field and value that will be excluded from the number of steps. In the example below we are excluding `NA` values in the `ISOTYPE` annotation (`field="ISOTYPE", exclude=NA`). ```{r, eval=TRUE} # Exclude nodes without an isotype annotation from step count getPathLengths(graph, root="Germline", field="ISOTYPE", exclude=NA) ``` Note, `STEPS` has changed with respect to the previous example, but `DISTANCE` remains the same. ### Calculating subtree properties The `summarizeSubtrees` function returns a table of each node with the following properties for each node: * `NAME`: The node identifier. * `PARENT`: The identifier of the node's parent. * `OUTDEGREE`: The number of edges leading from the node. * `SIZE`: The total number of nodes within the subtree rooted at the node. * `DEPTH`: The depth of the subtree that is rooted at the node. * `PATHLENGTH`: The maximum path length beneath the node. * `OUTDEGREE_NORM`: The `OUTDEGREE` normalized by the total number of edges. * `SIZE_NORM`: The `SIZE` normalized by the total tree size. * `DEPTH_NORM`: The `DEPTH` normalized by the total tree depth. * `PATHLENGTH_NORM`: The `PATHLENGTH` normalized by the longest path. The `fields=c("SAMPLE", "ISOTYPE")` argument in the example below simply defines which annotations we wish to retain in the output. This argument has no effect on the results, in constast to the behavior of `getPathLengths`. ```{r, eval=TRUE} # Summarize tree df <- summarizeSubtrees(graph, fields=c("SAMPLE", "ISOTYPE"), root="Germline") print(df[1:4]) print(df[c(1, 5:8)]) print(df[c(1, 9:12)]) ``` Distributions of normalized subtree statistics for a population of trees can be plotted using the `plotSubtrees` function. In the example below, we have specified `silent=TRUE` which causes `plotSubtrees` to return the ggplot object without rendering the plot. The ggplot object are then plotting using the `gridPlot` function which places each individual plot in a separate panel of the same figure. ```{r, eval=TRUE} # Set sample colors sample_colors <- c("-1h"="seagreen", "+7d"="steelblue") # Box plots of node outdegree by sample p1 <- plotSubtrees(graph_list, "SAMPLE", "outdegree", colors=sample_colors, main_title="Node outdegree", legend_title="Time", style="box", silent=TRUE) # Box plots of subtree size by sample p2 <- plotSubtrees(graph_list, "SAMPLE", "size", colors=sample_colors, main_title="Subtree size", legend_title="Time", style="box", silent=TRUE) # Violin plots of subtree path length by isotype p3 <- plotSubtrees(graph_list, "ISOTYPE", "pathlength", colors=IG_COLORS, main_title="Subtree path length", legend_title="Isotype", style="violin", silent=TRUE) # Violin plots of subtree depth by isotype p4 <- plotSubtrees(graph_list, "ISOTYPE", "depth", colors=IG_COLORS, main_title="Subtree depth", legend_title="Isotype", style="violin", silent=TRUE) # Plot in a 2x2 grid gridPlot(p1, p2, p3, p4, ncol=2) ``` ## Counting and testing node annotation relationships Given a set of annotated trees, you can determine the abundance of specific parent-child relationships within individual trees using the `tableEdges` function and the signficance of these relationships in population of trees using the `testEdges` function. Annotation relationships over edges can be calculated as direct or indirect relationships, where a direct relationship is a parent-child pair and an indirect relationship is a decent relationship that travels through another node (or nodes) first. ### Tabulating edges for a single tree Tabulating all directparent-child annotation relationships in the tree by isotype annotation can be performed like so: ```{r, eval=TRUE} # Count direct edges between isotypes tableEdges(graph, "ISOTYPE") ``` The above output is cluttered with the `NA` annotations from the germline and inferred nodes. We can perform the same direct tabulation, but exclude any nodes annotated with either `Germline` or `NA` for isotype using the `exclude` argument: ```{r, eval=TRUE} # Direct edges excluding germline and inferred nodes tableEdges(graph, "ISOTYPE", exclude=c("Germline", NA)) ``` As there are inferred nodes in the tree, we might want to consider indirect parent-child relationships that traverse through inferred nodes. This is accomplished using the same arguments as above, but with the addition of the `indirect=TRUE` argument which will skip over the excluded nodes when tabulating annotation pairs: ```{r, eval=TRUE} # Count indirect edges walking through germline and inferred nodes tableEdges(graph, "ISOTYPE", indirect=TRUE, exclude=c("Germline", NA)) ``` ### Significance testing of edges in a population of trees Given a population of trees, as a list of annotated igraph objects, you can determine if there is enrichment for specific annotation pairs using the `testEdges` function. This has the same options as `tableEdges`, except that the values `c("Germline", NA)` are excluded by default. `testEdges` performs a permutation test to generated a null distribution, excluding permutation of of any annotations specified to the `exclude` argument (these annotation remain fix in the tree). P-values output by `testEdges` are one-sided tests that the annotation pair is observed more often than expected. ```{r, eval=TRUE} # Test isotype relationships edge_test <- testEdges(graph_list, "ISOTYPE", nperm=20) # Print p-value table print(edge_test) # Plot null distributions for each annotation pair plotEdgeTest(edge_test, color="steelblue", main_title="Isotype Edges", style="hist") ``` ## Counting and testing MRCA annotations The most recent common ancestor (MRCA) of an Ig lineage we define herein as the most ancestral observed, or inferred, sequences in the lineage tree. Meaning, the node that is most proximal, by some measure, to the germline (root) node. The `getMRCA` and `testMRCA` functions provide extraction and significance testing of MRCA sequences by annotation value, respectively. ### Extracting MRCAs from a tree Extracting the MRCA from a tree is accomplished using the `getMRCA` function. The germline distance criteria are as described above for `getPathLengths` and can be either node hops or mutational events, with or without exclusion of nodes with specific annotations. To simply extract the annotations for the node(s) immediately below the germline, you can use the `path=steps` argument without any node exclusion: ```{r, eval=TRUE} # Use unweighted path length and do not exclude any nodes mrca_df <- getMRCA(graph, path="steps", root="Germline") # Print subset of the annotation data.frame print(mrca_df[c("NAME", "SAMPLE", "ISOTYPE", "STEPS", "DISTANCE")]) ``` To use mutational distance and consider only observed (ie, non-germline and non-inferred) nodes, we specify the exclusion field (`field="ISOTYPE"`) and exclusion value within that field (`exclude=NA`): ```{r, eval=TRUE} # Exclude nodes without an isotype annotation and use weighted path length mrca_df <- getMRCA(graph, path="distance", root="Germline", field="ISOTYPE", exclude=NA) # Print excluding sequence, label, color, shape and size annotations print(mrca_df[c("NAME", "SAMPLE", "ISOTYPE", "STEPS", "DISTANCE")]) ``` ### Significance testing of MRCA annotations Similar to `testEdges`, the function `testMRCA` will perform a permutation test to determine the significance of an annotation appearing at the MRCA over a population of trees. P-values output by `testMRCA` are one-sided tests that the annotation is observed more often than expected in the MRCA position. ```{r, eval=TRUE} # Test isotype MRCA annotations mrca_test <- testMRCA(graph_list, "ISOTYPE", nperm=20) # Print p-value table print(mrca_test) # Plot null distributions for each annotation plotMRCATest(mrca_test, color="steelblue", main_title="Isotype MRCA", style="hist") ``` alakazam/inst/doc/Diversity-Vignette.pdf0000644000176200001440000077746113513671720020050 0ustar liggesusers%PDF-1.5 % 25 0 obj << /Length 1912 /Filter /FlateDecode >> stream xXY6~ϯ:mlIS4nעBlɑ:3=z=yX| YXg/,,22*x*HKɣy_l.fbY|٘Y"%u 7׻2aSaU};Yl64Pi@ ҩyV·oDr?p6{ika;m6uʴo%h+x<ṗ^TIOUZ."Te9YmZ"D3?sA۶JOkfrˬaM "#M2s^}"(RE(3 v,0~p*ʼn[rO6& y\G83Q7FgPsI7>>8gidOOs!1Vp8BT^TxH!$\!pY9S'D  2g.2 :UQ8%,&J QvA Wd+~RL/KH2%4mjPh Ѧuk' q3+Lc,€8ۃ#;?W±? xFz:}Afs, | zjRC ]X?^RUScӗr}ES]nݡ|`#5'%>>>dRC1!;ΏLY$LgB1C< FF(c,tjS)^WOi(Y2I{V¶Yw+&@[L8DR wWO7WIkkbX8y܅\B|0nI$\:nœ䠏|wWO_jt!֮+isi :0sTi/= o P K̐|qrfu}ݙnl{ "|AÅ󈿊DlmAp`}`'ٖB}b!? i$ n wJ!\͟z\ endstream endobj 43 0 obj << /Length 2029 /Filter /FlateDecode >> stream xXkoآZ<5Hή` Jlaw2r9üyWx{[lHxKX{Ȫfsi?ն,-u-b+j~6y/,HXQ8bP]-pzS)NM͊U.yvt9ÓdPyI(\,li6Bi~;NԶibwb4?Umwa \Z%ֆ 9y&4ux6y?l0֍p;Q: DA"ݡL5~b]fyFf4&SF=`8zS#u4}mzɊ2쌶fz2 B` 3wM2g~ڙ8UjXRS3_/0_KcF6:'c\hŷᆪyOju[} mm!hۯ}%Z E<+MNH)!\" 2'J 2D=E$E:)! N'GJquW XekQH.mwEioEMF]:Fo?MSPPU l[v;5,`ܩcJA ##{ჴ|Xm5A0{d!cvd//4ʭpfYUm ejue6At\AH nf[!ؕUlzmro[} bM 0[d)dOL*$E0n*tq)&%H+-8 NjMnai;jR|&sSSnYeimGri7MMTl ظw 때E]8 Phu1 eK!BK8nx FM?.v(J->^c}wXi?5V4|8N?}9=g' kgzN x(0?9P^F I^H)8Ύ> OSa%wy89C?C?ޜR""㎑X:!Lȇ$:LE%EDI%$oSΌȌUXw$:;g:(I,ӓ*둃7Lc,{=,|'x`6N$r$ƫNttrP"=^ND+, ++d+Z^jdÐycvR4;W%|َAĸ`nn)*ц <1BCkMd =p>-An38|>bZ[ݍ/ WG?A%w.0^Si4CU|$!Ti/x3:UG/s8wwz„Ε dBR^.^u endstream endobj 48 0 obj << /Length 1294 /Filter /FlateDecode >> stream xXn6}W) hI@6"Eh@hnśwȡ,dc{w3Ù32fBt|rr%vHBj̗> m(14(+S~iQSs<{k  ¿SfT r+'hR>Z(|6O(L4s!͜7lrrQ㢘 LzH3|s^E ZDE#;8-=%KzAڧ7١L 7m7Qp;s(lnI.k# c rjYTYh\*]+Kl˶n[\ˉGiܦZb\AXGDŽ(xw 2qqϢNb~|+r"ni{/7:>CnP QJ4jX̱W5d6*N endstream endobj 45 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Diversity-Vignette_files/figure-latex/unnamed-chunk-5-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 51 0 R /BBox [0 0 416 276] /Resources << /XObject << /Im1 52 0 R >>/ProcSet [ /PDF ] >> /Length 35 /Filter /FlateDecode >> stream x+2T0BC]S]s\.}\C|@.T endstream endobj 52 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Diversity-Vignette_files/figure-latex/unnamed-chunk-5-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 53 0 R /BBox [ 0 0 432 288] /Resources << /ProcSet [/PDF/Text] /Font << /F2 54 0 R >> /ExtGState << /GS1 55 0 R /GS257 56 0 R /GS258 57 0 R >> /ColorSpace << /sRGB 58 0 R >> >> /Length 51733 /Filter /FlateDecode >> stream xKn=ΞׯQlK"C7%ndF ɿu3+ʼ?S5PC)9HyoQ>z,edJͷ"J<ԫݝfo|~+v٘o;ʫ^Wm/h.g^m_I56pM?~Zӝg+{BiO^h~  kX}Ny"<OD #g 67s: Ƨ4P?>Q=X()(1QG+;^v=no?Y.$nAݭNhv?x{?~g}ޮ-]@O^J~[j85|A3P^O18^5nnsgHgq+:$}J%-"WRSZ\/({]a͍c774e=5>Wy*"j>Խ \ap"j9E-77} {^N^o> =d)EΝxPOzPBNV|e歸]'c=8V?+YÙKN(dPuo̹w]{4zI{a7(YI;OMJ?fLx#sXcŰJ潊Vƹc*-M7e*kٝ2O(̢ƌ^8 v<% x,H^O*) ]^э9 vJ:7ސ~WæO;&iErLO^D|XKo'Өeoe({粫oyF&pM0{0~?8oړ{%ovsn@zաaw~p.{Jw;S]xոKt>p 3${f#S=ݺcoč~Zg#^8e=9-x+ 3m*s4\ɌHޟuW3{!EZp5@W2֐p5H0lNu 5Nm* T,)ܑ {Tkq㸨=UI5-MQKQ,{J~ {dVCA+f;{J;KZt ?(ރ],KT4KUe?1zx+K;\͒zW4C-NA%W|+wX%%^`uX Kd.(u%$"z'g)-7s h9C X&0eO_{ ^kX" ɳb8w[ {|[twk ]8> EqCrl{ WI?)a$g|uvɑ:uވt'9As'WaU~t<^pK\q>XڞI,n{5{ROIMX~<9A e`|`mQ,6!ބM8Q/<'Weh\QU fW0[(c%wtE;X7x$r5A)9 #*3΍9?xvYYoMa/xK"5آ-JɷE)Fݏ6p)7ʞjgM x16Lρl+ń-G^T+;_׆|QVt*F4=jw)Xj%U6ZZ;vMݰ**_oQl XK?|svNw]*E\Rui D-Ҽ:#a*)!wO;ҀĦԱ@Ytu}DEzd#;6$eL;'M^;d9s7n8L*Ȏ-Tr,OI{EõjGJ5ld#ɬս4졆OQ ɷS]g%l;<Q'%T(7{{HTc {Z{XY@}<:q(C{hZD8tZGD+B|ʒe=xb%wOlVqe5:J􃢐 jF5?ktFݭ QJ$rgDd#ςO0QRXRwX6EiOfYU;sP\d ̧606x'!G8^:`5q HL"$Cr8'\/cu 5=q#^yq4Tm%yn,Lhpl\ o}pseBQPu5Ʋ46"P|VYѝ[-t/d59^dwd;΃§X~ `sv8jݱ.kHI,Fx5 7P2 |uR9Q/⢢%vu nJd>Qw95 .^aK,HIyLi2kw<0&|{V:$<8[CY`›]pB&)q2W޹>Q\x@$c0=ӀzlAfԫ%-^-V~ %=H*LceB>5 CoNԻޡ ̷CwcsuѡI݀Z{z^}}L@o N; 3Nlׁ5A5>e~)l;K&g لCw_$xagλ,6%>-]x*ugG0{&\ҠGVkoYѝCYo/Dt!MX{^[Sjƒj5n$e=) 5졭.N j/TR@n['*q(7DiGEzWi~BxF xPfPI ժ=xY 0ξE x:Vg. z7a*E=N5- F{̀XCrx{X@CY٠ϲ^({c{W4 MSJSY~HcncqB6[tnʞӼ`53^gH +3p܊$ +ٝ!^Ix ٝ!D@AR'[4oymV@a[Ѵvau72d1<=owI߸w 쭈[R*9Geqw z@A+p_q徑T*ՁB5*iTҨ Sԍv.EK.!7oNW͡Ǎ S\>8 WV.O!,\e|py::B w]%-;.@# m x8B8 wO1Iz'bިQfq5 9μ=p;<' 9Sn9|=$$t0 ^9dY]MNR;Gf-Ų1'ᆨͲe7)HAS3O]tewI.f?HIA= 8 7u$"eoAUzQYXv~<"itsl8)e$`sYR_IR'ioh@~uFsܯ>xˎ $|ދ@ro74BI=YjD{LGRnB#B,;Xv`β*d6m,X NB!dͲe7n],Xvbɲe'N}{, YVYVYVYPgaYaYae,YlgƲe¯6jӯ6NnFȲe.],XI*d'eeeeH7)P YVXVXVXV)e;e`Nv4lgƲi,۪a&B݋P YvB],t&NB!dYcee TUG@eYa lࠒeةdgv*XJsB%NB!쀈91g2LƜɘsJ*F%JT*TRRI²B%TrPA%;쬨SN%lr*B1='cT1FcT1FcT19ƨb*8}8#cbc oo}F0f2F07|5Vh .G9(2n(g匣ʸɊ&+h"cEƊ)+3(et3(A JgP:bGoΊ+j"L"ID8#02#02WadFadFa*5p&C {_/}a {WH:jԪQ+ 08/ fcp?8'`p"$a0I'W"K%V_}Z 2w2w2w6 M@wwvwgwwvwgwwvwg9;Gwݝstw;c{gl}Dߙvogvogv3wogvog6oT87NKmƜ1o8~om ׍1\ssӯ8<?b0@>82>CzE 4*iרRIezJ wPz;8SӸ D(S]^cz1RL9RcO+d0(z;/a/a⮋?د.Z5)jRzA HTh%%5(jPԠNQE5X =w?RԢEQ&EM222R- HFHQ:E5j3.nB#lNo>"B22RYPgaE ԹSNu{7ڹ UaF;7ڙ} RXRgeEŠ!s *Ί+*hUFK܈eXF|hɊ&+*Ƨ !lA5۩FƦaw v5 \TèQ J5jRToB*٨d*袋.袋Ģ5>WX܄h’X'+dM*9؄Ajg:Hm:k,ppBR'ݓ{ְ,P'aRT8NntFMg4E||B8 IURT!UH"Z]J'p+$Ч }X'+$u:I5RT%UIRAj? HEpNiBjb.p Ẅ́LͰ \W8e:HbJo|лJ o|*@8Ҡ# A78ݠq3~ g8elpuzNtFΈ91v@ a:C FpFWitq88hFk4Z]CNo4Duڸ?lQa!w3o߸?QSEk8Պ¹U4I6.Ǐ8)jRQRRPPԠNQE{q:~ԦBeeUBq3*QTrdwOv7ZѢ ; wzǒ T֫e';B?UXaDTdFT*$s6*쀃gC4'7 d^d^dd62Bf! s's'3(l n*OȼȌ*A=ȼ:m&r[8$.:袃!  9L` v٠Obub6r 4VuE-6v\*6Qc5s$eeeekNcc`9 ;`sn ϘVekdXr\c^-6a1uY6|-MƠl k#)F;'ûv s6@AQꔺ&>iIPtrFu\Z  :u2̉޺(hΊJP9 ;`]y-T37pN lϋӀ=(A?^`],ΰ3 TrPIB/mВY:rgwwvwǞ _su$.-? gcj1p8$4B% &k܄paja'IܰnEX4B%3yB4Bv'aS&WG3\4e֥Zrkdx9GGF5⛸3z:q끰x7&'eS)ܫ K FW`p=.@) H{~>  wrfx@Yoqur0q5l` ?;3N`]AqJf!s's mCcmf籬UuT<| "\>|`]Y+W/ \&z sVz`g։@55|m5Zp^M t19+#>D)5Z*LW?X[_ I*5nmnW`5X]t;T ` W1Oד/ 'g2^ޡj\>o*hWO =~lh?xjERuOdt^;>byZKE;_i;>{~)rZy$$J_Vsy-q˪`FRk_oG4~Oy/{ }·?!ބnZ4_30şn{^|}7?2U< fٸ/|_M=g1漿Sd.[ώx/7Q޿=պgLî?BߧwM8IǿV8h(؟g3߼zs_]˷~)yyڧ0FV6ohy콷ƻ40kxS7w߱NkҤ Jr&; m8us]؆Kn-%Ek)q(9_L[ȽN¥h)ƯF~4"N޲~|hŊ M Ytktث/olE*/ogɋM{:w',-#1`wlJl@YݠEMjUOݱ6xau.#`V3W\uPpC),[~Q$V;+ .sJE){) 읰'"@T J$VEG*jQ>q  XVm'O$uָQnmRPuhe%EC?ԉ6@ƅ#" xl6Q'5MnP6aZՅH/Zym5Rجz% {Ɂ8+ōZFJPoq%%HF1ϓk܀u[6j0oRBWẕEs)*s€QJjF j5(HeḋZo\"`ma:-pq "Jԛdٛm~)Eف`-Z,6oDzF#G\uS8iMAt eD<`uh̸.6+4PO垀 ^b@vGB.fBuH_-l,H+޺sr ~W-D 5N( L%Z)މ9ᄛ%3zcwFve1inJ'Kkp;$oiDlzكsg}=Sj00HT5r1*( 6'l(;k@>݇xO 22h˖l ~s k9~̡fQV$BlP=utZ\(TOg1cSI>(ybr?:sJK|pAtBCY9PCZ;4nhT-ZlnyPzj'ۮUDQwMsJپ΃eOme5ܠ4ܫ?uwo`gٲ}?͏U @ B&L;7k@ َzwCz< vq,zge9ny}4 BB`zezVXh)n~PddJSQ鐌N<')ͬwRuNvJ,xHI2M1Œx5}vNAfƃ @]P!jmP7wπ3S;]d^#sڢBP5@:FK]G)Y j距?k]r p9UjH=s85%o?\*q%o ~x9%# *F!rQ;f-㧤 ˢeƍuޢ+Q.k!Y)ٻ,ʢ6,é5g1л,D/2o2,M#PSkVxTk(;J u=T J'ZFO ,/H^&,J^eAY95zH=⢽LN S[o#Fy@rHhd-hסQQt-ʮH"Ol0${^-j|ae)sUr$UoB\%az-ehl `=ާdٛg7a wC-ސ r{>ڄԮc"**=8{lY#p %{@`VCtCI5l,@cûl V~jz7JHD{1Y-\Pb$et Je=\7P}/eդVZ͒m؃S}t',kW· ̩"JcQcQ(7:ߊZ+:Qۓz 4"cfGYC'+Z*;]cGEꣁx룄pp3XD@_.i@AEcz ٝ!pæDW$dEu+(z|U h 5^زNy?$NH#2X$\0oJj؃V'8%%웷-F!PxQD rg Ary0B* ߈R9Pd'-?D-uӒeD>jv7&ՒXn),_tCQuh,E! !JTmjلpn",Fe iUB| ^6C|='%>fdewIRonm Qn>pz JXVpݼloJP읏R2#Cɲ\e{8He:s'07;NOلC;nWtptM:kĕWN@3ĦSHlu.∲c*,+z0ˍ=,zMIlMwsBԤ^.b{7b.(7t>C{Σ/,ay4G<+,#ܯB].eٺX̬WʒvwRT]; )YD.H6Az=^(;e=GJzT1ZTPėJIfemN·eˈ'[_X6F Բ67GJju|p40jq*ee* Q2!JZcGǦdht&**o8͟5":{c?uekzSRM6ueە#NLVF%v5%EjriI]`=,[L4aPT:>;n)dYd(((5R˱X8 v#bǽ QIQSդIQdvQb.6pw4SMQA=]q$u8Ǘy> }g@=ԨOG|c0%GCGBc0q *%UOF̛!o8Nʊ 珇թƤ(8M\]V،MLQf87%ƙxN86C}L9F|ݵ*o`|=8G4^O<%uP< Xȫ@a{E!Y&DH ,[ϼFgAY넂֣qpgĉXnvQOF|hcf{FH{Ӟôe#˂ytżp8/mT㰽{5 !4JX+qQhɣ7 (`$>p'P 4LΊj/q0Ti垌4\A%4,x@k$ w8LK>{21Jsy 5*9iɚ2=w$ҰdA'ȯhA:R!~E :o4\ %-Y#<.LX; ݟnsuձt$Tұ:~`5n}}~a푎c8–<[ Q}Q$tGQLBJJ%_hY'DՃH03pF%} Q(J55IK7b$A3{w]^Nh*Gӛ'IB#\UnJfԹ~@ED.-k-.'Cb;UqHA!e1$Ő̲e%cH /0$'OŘ|O㴘BIdUPV̓Z)nl;~A#jfuh1|{G /Op 8pn0=FF$d>uQ/9~f |&M}x9bqP4[b2Z QJ+4**I^Br}+lMOv(jLV4ƙldw|roV̾ؿYL<ΒW#>*i&z7%iLnΘp,{G]MZkR)f_1(lpjF;=%Nx^,fYaȼ(vp Ivd/c;)Xmm'5WoLդ3 p1GjݽXѢ6m [?"!q3͊ f{oH>ʽ7Rak$9ϵWQut 6ACrgE ?@ѡwdQv.;6t6>R~j`' 롼,}sޜ7{|?+`w$|0%7%["jV)M~Їl⛧q% =]'n`Jn_mzlf 3{ñ#9 H. É>h!Pr8X؄PX HF(8\.=G97?qQ' 5-z(yp?o((+p@d&M7'eiա{#Ŋ[޻y6[ ZmnvC#a Uf:ÙhUHz_GEKD_EȊ^HtK㧓.RB(W7|-8G_EQ#C%EPVآbm$@'6ڰg VS 56kVJHK[T`h~44&i:;w|.!lɊ"<0]`׸锢+/}:x -Yoh܃J߃J(Pr+;k\Dm=lQ=ӆch[RÊSEqiʙ㻵 w*HeER-3|T-c/$#n•ܟyJc e ֽv<В2 J@12OBZЃ(+R(e]nk e U{e'58QZT?@=!y DMvd'8]lw˖.O5neEysm H^zm8.%9ؔȲ R3 F7>h,;I-'D̂2p(נ zMzG73QЄ] -Ё:p\ݏU` 2_@ҁ_9Qdd07CBz@6&!hldMA٩0,: \{ wEẺKqD=gq n6pw0oda77Ez\2_cʐKd <׼_gc *JQs Hc F7RapXr~#NJf{?qX_-U=V37X%8BR2^eˏYIev}|hz=Wm ^EҀ5^Y.%:Yvv۫{[l ]!o$u"e8Vc2CYE 4Ž 7p2M"% -Z)۫nBv7Y|ꃛivcm^SeF73fZ@}RN٤Mvd,~Tv-wѽj rm}qGGwz=l>1;awpTIX&7%PޮᤨUzp2nu8gA1I]L*ru:ؿz!}J5A+euZ\MQFۀ(b]޼MQ|cRI5=L8 p)fF6EubFwEu;o&.$~{>#%uB{,/(_x&U!P M.V 6 +֡ o'bzk#lɌez:I,M6ߗ@7KH50TiJG<&3c-.lR e/dU2*0InRItTBL MHk{ y&W>" 5~icz9$蓋j,!T.¢3,!iMgI`vXؓ شơ>y p FEZ#>Z'ܰ;c2+aUcǂw\dCc30n_~Q]:w# H5.Nl_I*1qÎp2FQ zfWVV#cL8NШW.kmF dE6w6I݄jfii~0*Ik̉&xLfƢj lnͼ:.ƚNYƦo܃9RqcsnZEOGGF}e(5;`wo/P4`'u*jYQuwwRwDqq"&UP6Sg<ɼzxPMQ:h!PrPA5(MATY:eƹQ4.Bk`DPM^0['rф5 Fk% H;VOIL΍)y;iI5&՘ILgr,zMMSEXƲEkͲƦl禦dmEEhO288t{az9 n}TEKY{ZL5eXL5E-2oɝjtѩF/Z,,!B5<>GEe,XS]2ߏ j(L9*4礲|!Zd2cy|NH]fk? n(i uj&m囷a9)nґ꩖uZp-VZt)Xt\M̛ei.Tcoe8gJG:HZFs G1p*{"uWy}`N'VZ: F="zG{qR1 و:E'iq@?`&$ AE Jh+T JN@Eu`)B0lgẼ~框VlʨVFZMj6iRjLj'YejJ.%s]k!6"gɻySSII*Df>[JP%Xv.ͲHNnlP\ 78~bd(D5I]nƒj5:!BRՠ(dVR jt%a2KUؿB%_YeBgoOTRR+VJSjJ١J/!W5z B*a+cdYzQ+&gH't¹H7hEZw ZE%&A/ԏ?JnBM!V^wCg|%% =q0g 5N"G]h퍐JYci:-%dŲe7h`I$ UHI$8:^}'J$2|2oX<$4/X\!5JFQJ*fsJaBfdZ蓶XvS24ݤ&GʤONI%'-9'r`a>$)HY]TN1لŁ+L\TrqܕHM%1SRM%}*!{(ZPCK/!};cI8ZTϻC;eM%7]' !Ie_%g=u#H>Gu"u ~%X퀝pzt%U)H,;ɼ7 |Af* ܕT:w*SQ`0i&u* vВcQ2uTVOO DlQ'"܄PۿllRIA5aR7Rg!V~eeVUd_Q 0鱓jrX)W=N^3࢒wj\Q>QFH%W|2n;^%l5 3냋̛w'Z|>y%4JO|O^9~%ocd2+ɲh~ V>}ֵU<}¹Ų˲>8EI@p.ex Ms p>xsYsYV>H߸S˾:uS[2 Y|fSߩ탋pKx'}NmvR *!utI_]z^isbAF;h gm1$qֻtl E>b=^`۩kU䉿VE7.wއ|I[']9{tnoIC5O=cj>tV{6e_oS6e0uv^.[Zk%lU1CNl=ض:_zOxj7W\=?9Puj>|9k5Ts9s"jN5w5ww{7~ncspF7a<|W|0n:nl 16Z |J:N4xj76[O͇[Sv?l=h 5j>+BB97<{C5g=|>4t!ۻJwwCs7v6[aCͣ}x\:! wpO5OϜiS vzg!փԼwlv6n_zZoTHmǟ|MW5oM|wa_߰?4e~a!hUu< Kk5no B3vax!D{ECPs [ zVw_DJ5_.zsz8%mV5k |[!W( Phf⦅!5Q07'4U^iŠW4e|E2~x-pp1g%+][bϣnuں ϧBmhnhQh0FC+B3^!!DUBB?)w!dG! |:dQQB/h…!t/翣!tC:nb{Sv׳{zPolfN5iVyECXe,CX!,CXpNjDو#:蘯hD3ɿ*61Ww_Bq[qں G=(7 ;W4Q~{>wш!F y]Oݺ C8( !( ! !<(A C򊆐WiDiד44\hD,s:B.óZCW5lN;/[7F4 a1_.0F4 aW'a8.*7\ aW4eV!,CX !LC a4hfya|EC0 a+0QްB7>^!xEC!!!xECHCxECHCH5 ! ! ! h[ECh+B3^!T5|ECj BQshJ!C(j,>WbM񊆰 ayW4U_zEC0< aT,o8 ayyW4^ W4n]ͽ!S9_RͩW4Ts9W4Ps9+B9 W4hMMxECjj W42^QEEͥfSbClb.CXj^j^j^ռԼԼ+yyyW4^QSCcG! 555+7L5S9^QͩTs9+9j5xE5C^Q͡6_QMMMͭzE5W5W5W5xE5W5W55j.j.j.j.j.j)|J.SbSWlbռԼ+yyyy+yyyyWTTTTWTTTPX^Q]]]]SͩȜTs9՜՜j5C1^Q͡Ps(2+)WTsSsSsSdSd=^QUUU5_QUUUEe""K{E5>OnWb!6 ""W""zE5O5O5OENEjjj<<<99v5w5w5wEvEvExE5w5wE"S9_QͩTs*2Ps(2|E5C͡ȦȦ6_QMMMMMaUsUsUdUdUdUdWTsUsUdQdQdQdȢȢH^Ç׿8.b{*y)r)r)r)r)r+y)r)r)r*r*rWTTTTTTT8^QCCCCCC""""""{""STd*2+9LE"CȘPd(2 E""zEE6E6E6E6E6E6E6EYYYYYYYYEEEEEEEEOQy}uGQy}u@UTRRRRRRRjȥȩȩȩȩȩȩȩ^QSCCCCCCC"""""""""z}EE"STd*2LEa(2 E"CPd(2TՎWTdSdSdSdSdSdSdSdSdUUUUȪȪȪȪȪȪȢȢȢȢȢH1#&}Ĥ>bGLI)3_QKKKKKKKKKUKUSUSUs"""""""""F{EEEvEvEvEvEvEvEvEvUuUuURU9_QTd*2LE"CPU*T UBUxEE6E6E6E6E6E6E6E6EVUUUUUUUUUUUUUUU,,,,,,,,,annnnnininin-n-n-?"""""""""F"""""""""RUTU*UJURUPU*T U"^QPdSdSdSdSdSdSdSUSUSUSUUUUUUUUUUUUUUUUUUUUUQUQUQUQUQUQUQUQUQ+t+tKtKtKtktktttttttˏ9999U5U5U5U5U5U5U5T5T5T5T5T5T5T5T5T5TUUUUUUUUUUJURUTU*UJUBUPU*T UBUMUMUMUMUMUMUMUMUMUMUUUUUUUUUUUUUUUUUUUUUEUEUEUEUEUEUEUEUEUtѭtѭt-m-m-mѭeѭeѭe-^-^-^ѭVѭV-OѭGѭGѭG-@-@-@ѭ8ѭ8ѭ8ѭ8-1-1-1ѭ)ѭ)ѭ)-"-"-"-"ѭѭѭ----ѭ ѭ ѭ ---ѭЭЭЭ---ЭЭЭЭ------ЭЭЭ----ЭЭЭ----ЭЭЭЭ---ЭЭЭЭ------ЭЭЭЭ-}-}-}ЭuЭuЭuЭu-n-n-n-nЭfЭfЭfЭf-_-_-P-P-P-PЭHЭHЭHЭH-A-A-A-AЭ9Э9Э9Э9-2-2-2Э*Э*-#ЭЭЭЭ----Э Э Э Э ----w]uw]wߵw];׿w]~װ5w ]K~גߵw-]~׃w=]}t5wM]}euw]]}Gѧ>8S|jOS>uʧNZS/|O=5ힺS{vO=S{j`Oc=uԢZSzjQOM =5&uSy:O]<6fS#yj$OsxoSmM6֦ZZkSljMͳy65Ϧ-cS{ljM=6æ~`SlxM5uzZSOkiM=5uԵVSjZM}/5ԗRS_jԧ4SfL3ubNԉZ/SejL2Z\+SseLݔ}2O>'SdjL A25HZ S djL-1<SWcjL]1u5ԷSb[L}Q15*Fԙ:S+bjEL1"fl Saj6L݅0uNS`L05 !:S`j L-%0R_jKM/u.嗺R_K}|/5ƽԸR^jKy5/ּԋzR/^Kv.uۥnmR{]jKu.5Х@R\Ksc.ȥzRO\jKMp .5R[kK}m-ȖR#[jdKks-VԛzRoZMKh-5fԌRYj7Kf,_RCYj(K e,2zRXK=b),5RXK]`+y>RcWjJ]+urNɕZRVJZ9+5gԍR7VJW*_oRUJU*uTBZR UJ=Sg*L&$RTJ]Q+*A6RSjtJN)u6ΦٔZR+SjeJLw).ޥԬRRjVJI;)u'vRlۜ`syV[ :ouD-X8o1#JPJ}@'5Ɵ:}ROI<'ԼwRNI:='ԞqR?NI 8'5ऎq:nRMjI-6&ԤShRMjI]3k&uͤ6&dR_LI}1&5¤F:_RKjuI.%ޖےYR3KjfI+{%uvԮURJOI)!%5ԁ:PRJj9I-'$􋨩$TJRSI"I]$$6DRHI!1$uN Z?RGjH#zܑ;R7GH}#o~k}#k~ԯ4RFjH##`Ԃz.REHM"5YU(REF(REH}Q"5JF:#RgDjH!>އ쐚o5f쐺RwCnH !/ԿRBjXH C!u(ԡZRKBAH=!5e RAIe R[Aj+H} 5Ɓ8:R@j H:Rk@j H ifGl4?L|0?LÌ0c?]f)a~9a~~T.Lì0>Lü0>̫ü0>L30s>LSoan|Ƈa2|fa{a~{&/ Ä0=`3Ô0e=X樇9aRz&Y,0 =L;<0p& Ì07L )aNo9ao~% v40M7L tü0/7`J&↙7P06L SmT06̭ iOɴa2m=~m$̞ et"aldž bÄ06Gf);”05q ?渆Iak}05b Vô0m5S T<0O5LL ?l&a&j04L= sMïQari\&ɥa6i͈04L G@ah0_4L 3Bo7aFh)ag03L <$03 :ì03Amyaf&j_+33{aff~b L s/d#ael~& ̮ +a:eN'0a2&LaA0C2L K)adXT?́ :acV,ǰ}5<01,P&.a 0S1T ̇ajbX7>E s\00L> l006 00' |00&a0c0L 먇)a0'0 Ia`X< ¬0/L ¼0/ D0/+f{a9r5GniBžͼf%f"P3,if4m6S}6=ܞffnO3Ӭif4u:Rtf)f~NXe3!A jٌo3jաCUU8T1bx4,̓i416c1Lf&Lb3YDL}iIl4s]-ff6K3;Twttץ.uKw]8T8T8T8T8TsP͡C5U:TuPšC*oH^3oYU(Likf|СCM5j:tPáC ;TwPݡҡҡҡҡҡ¡¡¡¡¡C5j9TuPաCUO)Z\l~_Y6 Fd0BsY\k.5k|-64>趜u5WEvͪ22uf\saio~o.5ޚkm͵CZuqV]M꫶Yu^V]/Z^Yu"V]U/UK`5'jB.rU6WժZU#yuUY^][UPV]_LUWRTu) T]WMկnUWKUtSYrR\]? FjaUMOGUKBUqu TuWT]~jTWy:UoHuj.TnJMuLui괭:mk1U/m?ŗW{jK[5VWr)Uk7JujDTWLVIuj&ToTAw[OT9ϩTRmV5@.dT2Euj.UT*KUdumꈬ:"UcuP]} 冪QPFFuA=.(T?lQ]A |P<\2:_T=E@uQj뫮T{auDՉ'* ~&ꘫ~ͭr]\~~Ϫ۫۫۫U/ثeFZܾ Z j33V$Z^[jvN4h:tDÉ԰4zvU=U_eW+WMwU_TTTTUUUUUUUTUTsUPvsTU0W0W>WWU/OռS}vUuUuURUPU*TjjjvvvP U3KnqծRZ\5T_V_V-'UImmmmER}=[i4440sعٹo3j9*oMoMQZj~}YZu(T_uV_uVVmVmV]՗UAi8P/Z+_W'=,++~66bw1XEX ],W,WW|W|W̝.+s+fGK__oՊ)hhŲr,bZr4\EY[1ӸffK\Vr1[X*[oV|U|U-*rŊ- +*?[|CU̞-~ĶJbBlTŔKbRk;łWŴbIbѪbb&j3H\briQ⛢bhSP1Yf]P1򧘷Y|S,8*b_-ss-_ k?VX|ESr,))1_ +ߺYulkU _scoNY49TsPաC*ŵʊwŷ!,{R|Q̠+.)(/4*oULl+(~bZEkPlK7_e*((~;/l7IXVPB@7 TG|):(V~(+(s(_?yS|9PٔۀbbTbZ_~bS1ө~b.S?bUbR_beb)Ō.Vqb/8h8`wDE' e5e4ʨ(NT2; X9)*+++#eMMu,,,OStzNO/6p,1n+{KVCCE6ChVCPl-V|_ pٺh박{xu9 a+'$u]u?8meuwfv[ikVb+lz?bN[nk5mM[ְZ1b+71>&n}i+n»}0mmm6[ybkyr"5OE׼]kihi潽sWY*k^e3zTH;R̩`6EA.eUUoAȪHNRV>#-?./r?N,D͉Ū'b| /6p8pPPPPP͡CU*џ'58;_bGC=n֮><T0^*{|bw==~O_oF|Μϔznx.;O;O;;w;w;afjjg $S\ sؙ;R⍱xc>&/V;g5laqq}>Ct6!bp.C$kkdEMrN>|MM_M`LRA>A5}6A}9Tu#uwpw;>O۾XtpՑ;K~vsw?d8A>Xs#=7J}fzI/p&[y8X>N4|̧ܿ2/,çȦȦȦH?|ͭ'{r7ސzvzNAW-Ijp|+>ڦgtan?_)OU\6 \?ly?9| W7v33e_pifӝ?ç K,|>ϜR }: {7{e#=(̇j=p}v=SDC5E|胜p|y_|2GDoz2okGuY ,>o"0d?{ ۽1v_Wv0vv~ސ >*>|>%;?v |9deIWN:lwڽ#uaky$y~pwlrֹ0]z.04@_?}ћGf7sH?VVЫ#ӽ)ًSqJD|G0>A%>>S<1Yz?l#H64"_2M~H:ҋ.).>JdO*~|k>3U?S5>?,}E.˦+ϧdb ;ɇ|gGTk,U`V|I|>?Mj3| SŸ~۽M旣VnA~;Զ^/-'?AtLy"yvy>Y|!O|y4?КgV6I,& ?'uƚeڧ,UOjnާs"j|P[QUIghե)?<ܕbZr^_xK'|,>*ޯ>Bm𦩤,mOSv=ȣ>5RM^z59Q<5WSQEjH]頋eY~L뫋'uQˢ./Y]7TubSp~<*^X ٣>RmT3s%kU'8je1E¸_uk9@^޾orj}?~_q_KG__OSa?og?7n5g=| Đ'L=C=EX{7/׷0\M܇g~?$݇,اx4ָO/ 7qj=O~:qT~7u]3-k@뚹nu[_WM];z$< 7W=yyc/!]=~ȍp+q>fc'P﷌Яy<<"O<FqslG|'{xy< yO '<("lх?N#*|Kv(̍Y)ۍ}珘 [zh/ˍ/6v^ϑ_x#~g/>6׶l~||*Ela8"N]?E;W;W;_msO;)N۹۹|:y@gZųqM)NBi B0ix!,CX|yy@..:Sy8DCHC8_x]Sun qx..'x!T}sL 'x!QUPU*Uuݮ 8]\uuoTTR8Vbxko[C&vq͉5'jNNNNULщ҉{{ <0)tDӉkܘzozmaC<.~'x.:u':?pDÉ"{3qx~w8D;8x7.:768΍NtxCtTdWdWdWdWPyq? <?t_y"y=D~..m qn۪۶ Eoullb!=1N8vr嶇n{sgwC*C\ulLm3ppיmmm۞?N~xn^ϣMN9ܸvr嶇n{=6>۳Xݶmum6mnnnnnnnn{H7v^ݶpTo;Fn;vu^gF=xl}^m m7.<=xsycx*۞?bܸIbu=?b㯣{9kvE`:k5`{ %`{`gloWmγlgīl/ԉ߅a ~U]~7k ߧЯn]@*}j_e>,x+gR]xݵU _%o:S{UQDWT]yy:J]5wW~W5٫.Ƴjqչ7K^5At*ۯ´W ثD]*zJ%`xk 5Oz`J^%`jw ~%^%`atxF<+^WIԳUKw ؍翰ut+^%`7Zt=KWvY]*zzx5=.?.³Ƴw _ %`Q~%`/ͻYWkW6Ow l)+Ƿu}N-;+{%`Yqpxrg p8ev ؍axTJ%`7>g]v㳮.{]vc$x*up]vx%`O%`7vYYj,Kn<e2c+{#7]<(+{c;ngݚ_ eZY'NJm}u1]ăN7>+ZŢ~%`+{ӯѯ]+{\ೂׯn\OUL+}~YZWAqSsׯ S+We{~%`o|# Y%-+{.{c=0ϯs]g5̯Z,i_ ~%`o\Ϳ7F5~~%`o\λ썌QWgq_ g]vcNYbx+%4v ؍S\ |3%`7gxO] .m%YKnDd(2i}]v#{ "FN»ƩyT%`7>]v.;xgV㘖%`ǰKn|V%`7>kfLd#OG^|82ChX.;pP<6v ؍j,UKn5j8t(vr/wAA]v.f{ma!H%`7>C%`x`wm.]n-+{㳘Яm¯Ϛ77*.p:rCKWZQ3fD͈ٯFUMU-U-U=kuJnLw ؍vn 9#)+{㳊ϯ>J):0-+ZJk _ á¡ҡҡC 5j:rá8ܻ >+xJr> 0÷ԲԯF5/5/' WYn+qѯDDD݉(KntyK2'ï RZέ7v սQսAG ؍.[u%`O%`7vZ({c4 q~e[gJ({cښ85lM[9ΉgG ؍N[m=l=F[(ikm[iuzz<[WY*^emM[nku:lrGޑv [g^8D[ִ֨lx Oi6u]7$p wpgG Va+W uӳnzMfӻn6 %`o\\p`7m=>JI< {ry.Ony.]/\Bq(PyszxN wTFN++c8P0DSˉ{*=J^;vXXXXKntD݉ 'N42%F'ZNtE7>5Wkd7"ExPP]]CCCӡC-Zj^j>~%`7vEHb_as9vvvvvvvvv^Ma#+vvv~^n+iLqb<<ee=ys8Z=.C;W;7;?W.C;+t؍B0ix!,CX|amm߻'?sؙ۸!tUuU U U U UMUMUMU-U-U-U:Tup;<wx.CUBUTU*UUUUU5T5Tu]ޘA%`E':pWv 8M5'jNԜ((((u'Nԝh8p~N4h:tDˉ-':p9Qx ݓ{2tKЉe((;Qwo 'N4h(r7M'\\D<.'...sc] E"StTdWdWdWdWPpۡȩȩȩȩȥKK"E>D] n˩2l.So%?q0xnVVvpwNQ9hz|Z)n=>Kt-wNpr'6]^tNNN../r–k˵rvv}tOE5T#`\\\\]]]] ׆kõõõõHk{xm'͝:/...זk˵rvvv}'8E6666׾sOLѵpm6\;\:_WIwWtm~Xg~a^kkk}k˵e߮6kf۬qmxzC6׾/]ۻ8k7 ׾N8{c4iMצkO[?mavrrmBllavW<]'^ 6׶!Nѵghκ [[5- [j צ-ڴi Si ˵KR\maض:C'a:Cp0$ 'axO0=ޓs] cxOdxOqj,5KFQjFjl5H]73%>E} o-+ohGFjaGRCP#((H5RƴiRchѲTQjeGeGRR[ MX_ᄚ}awlz:Ote=cӃޟ<> K K 5 ;vvJKӎM;v,,,,v_7xhmm?'8?~)x{*x >}'DK K K K K KRiL/L/:/K-K-K-K-KReTYj[j[j[j[jz]-,BLqMTTTTX*, KRiTZ*-5-5-5-5-5-,,,,,U*KRemmm-^^^^rü0/y9axGRaTX*,5,5,5,5,5> 7y7y7y7y7y7y7y79Q_rԗ/G}y7ۛ{?>lM 1EK5KuKuKuKuKu K K K K K %RRRSɩe~Rd)Y[[--Jn5ֈ [#.lp.ąF\qakąJv%]ɰ߰TX* %CɡaP2L%SɴT~(Tr*9;-\J.%KɲT)YJd)Jn%)͝qCLqlV~}N*yWyb).]J%Cad*JiT2JN%SɥRr),+헒dYJn%kx>! 6+7+!N>m? +CɰT2VNO%erYl[y[y[y~|CKrrrK"Z[[[[9ip,e. wYxx,e. p,<+eקoٲ[\V.+e2nGp 7hnmãmGhnOhnnnrX9V+ك=8܃=8܃=8܃=x9p7܃Ãox Or -+o+oC˞nLd%s0ݒLd%-ntK[2ݒLtK[2=-鱘nXLtb%ӥKwh,zq8i崅L+O[VV^^; 6e}V޶p;4hm {]bK,Y51D+)~l -t+w[V[+--- +[0 VN[H+--L-L+O[*²e ˠe ˠrBYl>Tm ۠m ۠m 5hlOLq*o{'ѠD-t-t+w[*BX9l!l! [- - - -Ai iPBM[M[M[-[X-[X-[X-[(e ePBma m[`w}O qS\A.wwyX<]a]n.7{yX<~G [ [ AàaPAJkM4h4h4h Z-AˠePyʠZA*ʠm6h mx2ɾ۽۽۽۽۽={{oAۃ~; vl(Q=跣`;  AiPAiPMAӠi4h4 Z-Aˠe2hTAePTAemA۠md&ø0ƅ0.< hP3t C7x lAݠnP76(AaPt4(  n ACW2 JҠ4(iP4 M4h4mpˠeвe2hT AeP`T^m6h6hmpzm'v1DE4h΍xݠnnPnPdaP6 aаa0h0h4l0 JLsӠ47?4w4mp4 68 Z-\-\. .sˠ2 *,sˠmmжm6h S;US;US;US;USIO4lyALIwtJ;U'!ӝ*݇NIwtJ;d'!2݇IwtLwtLwtLwtLwtLw 68]-\.s .s2 *,sˠ2wmp6e<lbCLqK`3e3'| gN8sp3'| GP8sp3'| GP8p#(| GP8p#(A GP8p#(#h6K4w{A4w̽-s2-,s2w{am6wݯ7>!qK,]Dsܖfn7vsnn憹an憹a0w;san榹in榹i4w;͝Ns!}].sh].s2-s2-s}n/6w˼>Sb6s_z6s_wuޱvs07 s07>0w;?siin榹iin;͝?՘Nse2wRc]rm(s2l(sm6wݶpNtMtMal:ܦm:ܦc6n6n6n6n6}6pp{]anFj 5aP#MsST#HsiS4w;͝?ո= o] q)NDsojF[Fnso5[x8%FShhj45nnFWFjan~1j 5CP#HsST#H5RiTc1՘jXj,5KeR(5J2l(5JRcضjl5[ d9'Xr0  r0>h@5MFFWjt5]FjFjw!j 5CPc1jFjFjSTc1՘jL5SRcXj,5KFQjFQjN)5[V6ESB`S?hlhj45MFSѽ8]FWjt5F^*5BP#j 5CZ 5CT#H5RT#H/NjZVSTc1՘jL5SYZ-KRc(5JR8UiUZVVcjl5[Ƈ_ #7/ܼ0cŒ 36/ؼ0cŒǛFSu慑Fn^ya慑Fn^y0'jt5]FxqB* B* 5CPc1j 5ghZVUjZVUjL5STc1՘^jiZZ-VKjiUjFQjFQ48[jkuq ?{MbCKThj45-EVMUתkյZuV]UתkZVUhZVFj 5CPc18C*JR*JR*JVSjj5ZMVSjiZZ-VKҪ*JҪ*5JRjl5[lV[+uw\wuw\wuw\?~]S\bZ5VMUӪiմjZ5V]UתkյZuV]UhZVUhZVUhZ VCjh5Z VUjZVUjZVUj5ZMVSjj5Z݆ycSK`iUZVUiUZ!t^:uDΥs#\:ΕGҹt.:o{Qy_ZߣbCbK,QskGԹtnyDM綿c|bGbS\G,Q9m!t#h sCGy#9uvD[HS#B:>ᴅGi S9h rD[X:/8-,Ϋh s#BB\yD[([(ߏԨ#Mbq)#.W'!|S:btn툶l#Bs#BsGs#Bs' [[~D[[cbp°#<K6qD[H[yD[H[H[#´Gi S繎h 制lama²h rD[([8---:--maŽ#¶=¼ctUlbCLqq%6[hmB6h >an -<-t[uD[[vD[[qD[[[:- [툶0la#°h rD[H[8--<-->;61!:-vD[XmaZGe u9--Tjjp¶ݏh {ю-uD;گ-?.¸<K'lb?bC#B[Gf rD;vm#BOvvv0.Ga #h #hGFюn'{ܱ!#8 M[v4h\Gi rD;Zvlahª#Q]hGe GG۹߿lGb-`K,qc}xcCGv~Tͧ_7?o/__O/o>_3qo>_~fԿL/N_~\|i?vW?H$>W?kȟ^[_2[ToGuG$/!~}mq{~kWo7}Ow//}zI[u}jL/__7o>ϯ~ĥoz$]g.n7Tڸ.y _ _qR7|~'4׮~}7]y׳vwm\?l~~>Vğ7?'4. >Csr{KfOyK_>Yaψxz_Ͽg۟o(Ԯ}}Q7T__rOsaBviwwh~-uʵ߿l·ݼ)˼U{Ҹc?j9t/n})L?RzD|_/E\?\_~ĥR\wݒr}|{#o\9M<9!_ԌI9bnu}v endstream endobj 60 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 65 0 obj << /Length 511 /Filter /FlateDecode >> stream xVN0}WX hĽv츑 @&ATe"MH=73R*2*Pľ=(@>xs1" h#Q((Q/י,/c_ry?=a@ t#W+u"wx.yIh(`xLNZRG_ qgJ'֫'0'=`>kTZg~a>cT{^i8]mږw MކFClj<4?sڴ72NW*2plݏ-TR]*ϋu1 a-"A"̖_!1nV;chpK`d8#2ԜRkdmE-s |0~nfyuf2OtQսnt7=Sj;=NvYרe7ʿ1 :^@~E?wվ*rP_L?_~>it{]ʻG0a;29 endstream endobj 61 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Diversity-Vignette_files/figure-latex/unnamed-chunk-7-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 67 0 R /BBox [0 0 416 277] /Resources << /XObject << /Im1 68 0 R >>/ProcSet [ /PDF ] >> /Length 35 /Filter /FlateDecode >> stream x+2T0BC]S]3\.}\C|@.T endstream endobj 68 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Diversity-Vignette_files/figure-latex/unnamed-chunk-7-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 69 0 R /BBox [ 0 0 432 288] /Resources << /ProcSet [/PDF/Text] /Font << /F2 70 0 R >> /ExtGState << /GS1 71 0 R /GS257 72 0 R /GS258 73 0 R >> /ColorSpace << /sRGB 74 0 R >> >> /Length 2051 /Filter /FlateDecode >> stream xXn%߯҃`8"$vb$@"Y^34m 9`k*4ŪS@O )dY~wC{K\8V7B}^|uŵn/)rpҡ+őÃKq ƢG ѐeo.,f%9b-JG s8L116UFzI%r#ɈP 85\-G8lX`XլYxA'P{&y`b#ZbQ/ a2`&̩ɚ`$ǡYD)W51LM7PIn1ìWn)!fѕ[CMRzk)3^L[Ȓ}l&"ٶ)c[*A$Ε#gb6X6tϰgГRh+e@NnFTJ ̎Huv6#VVd0'YF©ZMgYU *:-$QtV9`5^숧ۘ@آ4.QrIzDkIG@rRQE8/#0D7َALvY>C-O<QaWL`mܣϹ~$;zn-mh=&U7=>H=Q'X4(9ì iF4xY6UE"gǪ6ql+FlժSLQV," d>o(k'3erJWםOӕ˕IvN!Ƕ_#g=<˳]:1 Og+g؅ [&?HGUBv?|x8-*+!;GY߀62p>HPRѮM PP"mCP/PHP}@b,IZ/?܋l_dSJսiwr +\g~yM~Ws endstream endobj 76 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 79 0 obj << /Length 1284 /Filter /FlateDecode >> stream xڥWmo6_!tfQ/CR CaH@[-9ɣ$+$-`=<,\(>R9w<(ٺwc?nV[YM8qr0}vɅn+⯓:HJL4$ vLu4y"y0eZ)LWIYƌ+|*do77~^̓bp3 FID#+lTAD|ϙ!qR{gd0IegE^^V-mpgD5bTkRyoG3W ﬋Y҃+~^Uop t<,oR Q$FMV'Z%b!$S/Yf d#R>xYA>CABZPȀūzHFyz("֣#MDQ" ܈9d.$T3XZ=q~ålng1~PIm 7Vy࠴Q"-,1xgY,GC^08LE;zSQZmI$oi]vT$ci6OKX PϿ0Yڮ׳te@x rcMNUO=.0M3 biQ<-yVu5Xd&ghb;3W-(+ }wfLma? 1Q?כU2b( ̨#\t9 .&2ڛa9~oΘ7bwcUy#8{77/ds_A851x97/ŨH>rm\<]% ^ǝd/ۍ}7Y:j{2Ht;a. g>̼C8q>xBv<4q_u~eFjq-hA>-O| q LQ녈Àp L\}5ACOww.& ƃ2';uP?.,ķ& -IhљjDFEc(gч`V9Aܣ/E|ZNŦ.8ԯqE}؀'y4I]pn?D͉+( i < <`z`/.Id-t =SqaS#qΖRxۻ㨒yMl9( endstream endobj 62 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Diversity-Vignette_files/figure-latex/unnamed-chunk-7-2.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 83 0 R /BBox [0 0 416 277] /Resources << /XObject << /Im1 84 0 R >>/ProcSet [ /PDF ] >> /Length 35 /Filter /FlateDecode >> stream x+2T0BC]S]3\.}\C|@.T endstream endobj 84 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Diversity-Vignette_files/figure-latex/unnamed-chunk-7-2.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 85 0 R /BBox [ 0 0 432 288] /Resources << /ProcSet [/PDF/Text] /Font << /F2 86 0 R >> /ExtGState << /GS1 87 0 R /GS257 88 0 R /GS258 89 0 R >> /ColorSpace << /sRGB 90 0 R >> >> /Length 3366 /Filter /FlateDecode >> stream xZM% %,(~X )X V|#%>C+y-Ou}||zixKOw{؏>j'!~jtZi{[[eO{/}}.c}G/ٷo^{N 笷i2V۫sLZO^L{>a< q9}G 1,5念R'1SF;j֏}T1)ގ)Y]͖dsRdS S6MNf LǨ$iE;Op(SR*"Kd:2ԜTЕk,jbfۇ~{8xQ3e5lNjuDE:mr$] jN]Cͤ>t)'*mScK숩/8ZVSwUR[ХYJ? Ka|L}?XDu MvD kYs {=CP9"T$i/h."d0^\{[^8'NVZ\v% H+>VW:#% `k3]41e,`f39L* MG! = R.ѳ]\'fm2bYӵ,hh!̋2 :ؚvt O+йb|ǾozFNl#)ظ X/bAԈml4=1'sA2ض7-xy0;,ryeT#-KϽ\H>V*c,-S38J䌲5h '9DNÊI$Fz(Hb*r*ⷜ2I/'g8~BX%w_K Lp< (>xބx$y_ ɞ?eNx6%x^[`L<$eRxJCs[i1(i9 u4)ܐcň8 pW!9' Sx*_2f/_ardy:LM}/^`(EfOˬcPbl[e eLœe`.XBYD2}ؖ$medfbLrz4Df9D(d.}ḅL)PF~B;|zLxRL 2d¸mcLQz2 21M8c vYY-6wdIuY/TQe=Y픵\m0چiv'3DiknۖJ|y[C=E^#o&mܞW=YJKzJ泴3;:RGW[ɂ]'Մ cmVgw0d$i_<0O|_ۿ>|;/㻴}tMuiI,jS֠%²u`H'Hˢ B )2G&݇6Pgg>kgi!L 6yE@jH]>^hՆOl6|4ř*[o*)C/|$Vq`V,?|V8 䰭Z}Wl&:>ˤ60\Cf|ȬzqA) .ѫ#9y0vS)0tr ;"GLr:AN72t:>cW͘әӹ5#b2hGSbyK)OUbylj'4xQL'}aiPhBHa.x&4})N0(YV9U|So|*#0J§:2 shf㽀*tdIvW3(rW3*)q\) :p:ͨwrPHwE¥)݉lbi0'>tBxv5;xvg&y"{a TeYcaQAy]nhix`۝G;qȶo>(=NBpe<9d'='" C/O%o _d(oJ!Nv)|,.&K %#_KRp"/+l*K}D"Jx$P7JY^Bha6!P<á󸼇[*3zZE*Q I/oPA}졮K}v55ka_oJw/6YXES 9oi{6臚Yz D?'4$4 ^?|hR^?C7=_˹cbԮJnt]gÞ_)g9 Erkݼ;!:үӼ{Bge_k {@~gz읢Udwؠ̮;c,R[σfu3ߎ;ɓI~ZxRfQ=kgJ0mb[[ IwWLUĮRqYofA3KƠy_~W UOEY:࡟hD/Z!}~_gI!ju@fJ]QuxW< wP XW<<x+Y0w )x赬꫶'Nq(*ח+]6 :ǹ"^041UɃ&/_Tmٟz3P?yL{6e@u* |i.x{竟_˯~ۺ endstream endobj 92 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 97 0 obj << /Length 594 /Filter /FlateDecode >> stream xn0E "X@p/qM_ISb5`[w(RE !9璼[1/[3 lYdV8.vr~f 4Ө'4͔ct\Pq Tc,.1?aeTe VH@1x,ب49$18&V-GaNS8cn8Z7{'t9HplOfn }` zS5!ڗMSFЊݲ`)6kn!ؖn }l-YWg)EA  G{u _DDRW;3庮)E<:1 Wo]mvmAXTr\g6]zuzhͦ|T[򄺚[C{lU[=1#{eZYr6HG.Лy S m.}Lš3NVU򑾧4Qۗz4Bs|||`$iz|30Xrk0}H!9Z 4_pg endstream endobj 93 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Diversity-Vignette_files/figure-latex/unnamed-chunk-8-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 99 0 R /BBox [0 0 416 195] /Resources << /XObject << /Im1 100 0 R >>/ProcSet [ /PDF ] >> /Length 36 /Filter /FlateDecode >> stream x+2T0BC]S]C3\.}\C|@.Zk endstream endobj 100 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Diversity-Vignette_files/figure-latex/unnamed-chunk-8-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 101 0 R /BBox [ 0 0 432 216] /Resources << /ProcSet [/PDF/Text] /Font << /F2 102 0 R /F6 103 0 R >> /ExtGState << /GS1 104 0 R /GS2 105 0 R /GS257 106 0 R >> /ColorSpace << /sRGB 107 0 R >> >> /Length 1353 /Filter /FlateDecode >> stream xX͎7 S=D%~ݤ]t-@Af$mc I{9x8GR(ZP {?e1ҏ@? sQl*y mVP nVnh3ZV!Q;|z=u;hFVͅDۈuc@t&F;cgbnTGL8g\fs ym Mx;F/k>7)\B5f3ɞFmX4KwD >T{ė$t]3p_:$d Vc8&+Mtϣ'}N"m]aEͶH2Z|W}`دy-T<9PH,-5 RZo+lUʇQ;h8kVYgJ4cݝROBS٤0}v(e=bֱ|L % 9Lz԰Ub2|a=t%]}%Y5esO:8wxi'ABߨN~Rz\58 ͖2L(`20֞f䷦2՟n')=ݜ'pM!TêhmZ&-x޺k K"F kr)yVu-U_Ŧ//pGr@V^z싥XN{Ӹyػݚ>w+0C}6~:6SOjl I63 PCҰVZmZ3S}cqS3H9ZJ.7'80V2mqԓ_B`Ķ{ĥRA6|cq tgB|Aój$n'Z=^vbώP=heZWڑi)BǸ|0nkO ovOzc!Hw|ؽ>{xFx%8xKi9/k[^JaTO>n}|Jo5p endstream endobj 109 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 94 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Diversity-Vignette_files/figure-latex/unnamed-chunk-8-2.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 110 0 R /BBox [0 0 416 195] /Resources << /XObject << /Im1 111 0 R >>/ProcSet [ /PDF ] >> /Length 36 /Filter /FlateDecode >> stream x+2T0BC]S]C3\.}\C|@.Zk endstream endobj 111 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Diversity-Vignette_files/figure-latex/unnamed-chunk-8-2.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 112 0 R /BBox [ 0 0 432 216] /Resources << /ProcSet [/PDF/Text] /Font << /F2 113 0 R /F6 114 0 R >> /ExtGState << /GS1 115 0 R /GS2 116 0 R /GS257 117 0 R >> /ColorSpace << /sRGB 118 0 R >> >> /Length 1390 /Filter /FlateDecode >> stream xXn7Wp/eF @+]Y$6 Z!#(05eP ?e1RxgBOwК}Vbb׆϶\CgWnów۱h䁼|X&k/wR^+ F8!G<1 FmhV-p3H13 x"x닶FM@x53st(s o.䊷!I3CK^`7yS*{rY6]t4*m4y;jJBJ7aĸq.8 +a}JHZ82VĎ1Ļ:_pv'hqZjBU,[ZbW؞|&sq 2Uar&m rlUz. bj7PqJS:s:&5-(9Pc^a#w|Rf vPx&C{LY$"[D96jqz4u47[ܺ%:焟:8wti'AͿd~eoUn'l Dz+0G:k8a18 s&(a;2֞S0fNq$5;d잨S`zKEHj~c5ykm{4;/f/LI{i# hk}uWݰ>Ql/' $ @g&ϰ//aܗRaobA{qe|4߹Q1/ wbG wl^wDJ"Jy:JD<1:_?43#bFE^B](ΰQ5z~O!qKW)IZ:6}ɡUtz:o ʟ'وm-[XZioUcsM9o~}&-"MH_W'x-,wzq7SJs7[/ Yw/? kf_j/y%!|z-RЉo"=HOc$78zV4mů~W{ĩ2bd7[Rx1v[{*g H|0%R.{K+88> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 131 0 obj << /Length1 1964 /Length2 22509 /Length3 0 /Length 23668 /Filter /FlateDecode >> stream xڴzct]vmUlc۶mv:vǶٱ13<3k~Vڼ^EJ(H+`dk`,jkDHVַad2010@ 9;;s؝N&NhRç`6vWr3fPlh ?66Ɣ.BvfNb0[ ohihiз1HIdl]? [ dPVQP)*)R}Vtu?.BJb4a% @LYQϫ'SҧOO?"JJr"`;8I_>M 3'';.zzWWW:SgG':[S:;);\m,V賜Nf%)sCcG?NPZS/bpGcHcZFIilD!g?9rWR\wLoe8;:9#1{?=3K&- #!*D+9x6ҶձsrsO<a).9"6FB֟ONN5Ֆ66-5112Su#g;zes{gc A[fj` kR?Kigk0ѷr4671|tw1898{{]`dn96&?SkR~P#[+w 40PcKJFژ? VVi_&RgsGQs7c#9s'CTr 'ϡ12_"?s`??gthhic`cKeYY?lBr5.ۘX 3 de#c@Ogcsv:@i$;^@//`Ы q~q > 120?2}M ;l7imoo3 o@7osyNs7Iok7I/sO;ŠNƪFn3wr0wdd??iGueag2qpY?8lOB,rY6LrҝUIƃOw` eJsi$Yo&UMQSȐ^+"g*ru.qL?N0<Hs9T17uEHoߍĔcMV.֏VNe!ACU ] w TO}k!ty_kgFwXÃΒ#߮>TƁ[󻽚kQShB{ l:?YOq*}~[^p[ڍF+67pV0ռ}Fp iħ#u_gZna!L{Umq3z 9tCr" ¸LR )~]So6 yN)ste$-MRiX$Lk@OT733*}6z]qHxC "N h<]{XJG]ayབྷiϦˈȨ~PR ny1hWY%:uF[BW5Ҭ':>&rCʿl$4e ZPYpK4O<&bڷJQSDvyN}gE44ڂoh\Yr\D#4LOx-rmƨd礆.Ey93"1 ݾoXE@B=$BW ԘfÅ iT}D`?򣅄+*̸q*iYH&cJ˷Ä;| 5RFr,I Omv+ӤE"a,ʨkzN#\MFЏ펼n=DuPڪ8{璇~hB6;Owm xc:㖢1Dy6R>h2 fʺZ9]!xnI-quՋ G_ؓP[(8x$.%iG馋Fokؒ"(I!EAyP@[T+DO&t#_"YIӡsE2rB\-J I/ۢ* &D} CC bC9}od͡ՋR9QeƏ USN1 ,OtVP4Pθ-"#u8J2+ .۰Օ-^>'{UA8RqU!mL#8?I1dbMO O.u,^:TCO[Hu*_w8P9D~C&JxDdD4ΌNlkv_*S|PC}p/o[_]{2G< Hں#ۉ2Ÿd~1ţP#ay1ub/MSiƈѯӕp`I0:@C;`<<|_{4Ds8ZTUYf| '֬"رb|7B)z {fɈ-ʼ SDQ7Y֥-9A8w?;پ7IrkI-sbJgc~[-v;qd0}kQsȒx#M+޺beA6y V5 9Jw;'G{8HTq}"XP j>`.X>C:t#k J]ОE~I{<_L7uLYs9G#IX &=G 緲^B?\Qn[G%ܢ(YTE-M>r0.\(hrG,``;_Z{j0oA:ۅK=mVŦL. ^FWb:t%2a>וO|܏ړD()J.+5SV ^pU{Cqɒ [UXicWh1C%Q0 ǴN3`Gtk/Z|%8A悇?o;HZT ǀ >k=`_tU]iE/V}Yrޥ(dnjSѲQ-v:|4z2 r+U['aݖGA:vK,͊ZĽQIFZrL!ҼZQKZwY4yU7t[_wdmPjpj [?1۬@)aa. y[L0{$0Sr^AO^EnӕCV8zҗSD|1 q~W}wVݜjEwf%[ol+-E5dknȜn){9|s+w? -ev_Qu{^Tg 3-J K6y > U *NORs Tz|u(KI=LvƜԃoD4sI@GlS*TJF??W3 ̡',W*'-SK5<?^$mwhPﶉ#߀/rKCêqJ+dnb,_Y'`XRO|RgF@fr/?LB}S"@,ouKj5D!XLʠ]\0jcbfTLt(e,x2۝}R 8]l=D_Tl# [b"U-vN25^W w]=iCHg\5Q`W{'SXZU)|J,HꆻNfz-6ғ#ᦅhg^Ŏnx#_<ԇǟ  ҃PbVͼ`Jة2'\ I,:ieIK޶b @ ~4>h !/b5<&iC`E@`Er(˩k!䪤@KdmzН*uIMl9?#d:FU筈+mDĄ,+ls7s-:,J~Nf)l%Y Bkwt[ﭼ33UqHA,G4aœoCc@pS̓  r);s9޶M}ͷ4EexH)`Pߍ7lMik9|ZTa!A)v/W?j.3IBl_$R/hU לTQCwM%rj8pH`_SӒA i,G)%TWų`"^"8CC@O+2cuXlV؏lk#Ym߶<ႢDpVr;jַTjawUP GISV)r2ʷ'LV T};5˜bgg#0Ih%[,FF[̦ e2w;hKgv%![|!N CxxC_r#o^E>nfO#WnSgO=*lx =^7+y*AJ%ztyh(C|])zY:mjKrf`*rStA'd+F&>x+k*GȂ~M4C*j+]~XZRK!c2έ3VP-: _1 ӑ_ ſLk}Oʛ_ z"  :Rࢱ=e@0zR {oxc՟Z׶ɕXp SۭBl}ޡ&b!7 iXg: 0$:<"f-q ]{ hS9ȻZ [*q?.yQt9:QvOHfB<QrvݕSNl9Z@Kkx+bF3^RXx_>JݥYHh^:˹ZVrll`;+ȯR%`j2hƪ0RҶvCg*%?g@m-+TÆ1xMj($Z@AVׇe`61áe:(PSoOǤF)GrhRlu RտPh~\着{XːR,B Cq8(AofiƷ[&L[7b=35` dJ1]j櫿"Bg_.f>9P 0#"8s͒1B̽ptOIRlGnX_H#0~4=*+tuBȻ"ʻŠ(_6FqE*]^\Y`[妏q&&GΖ]l:j$h. :;bqަ(/q4IFZBiV5v;Sa}Z^ڶLqcCiEg>f=ϑʦ+^]/Y_l`&Pz}o0bKnw / W j]&Pvf[~DԽ*U>?x8%a9uԖ1cA)- KcW#p'%&/1D'kU>Wu x _K1 q#]vb i =x|0 ΁{ًߙ7[\'\]RgvT? v]gv?1.ćt{fq-hKll>#_ H%`aؿewG\M!JJ_cyATSjM9N\T%-'4<ƴ"8Do췣eGzraA#h("$ PR&@fW+;T= ߳6Di;’`v~>_JVҎ3MC]3)]O=̽`wknGJ8>̍fAdTfV6@1_PUd(:S(Tzh|o\;H^Mm1P\f6msr`Z@pG0/A^23xD5AcBUB&&vDMJ(b 1hA<ę.|o넱eeeZ?T,j,IbhLU qf Wlx t~LX!ڈN7+'9Rw+>Z|c#ZFmIae~_>h353bM3"=?g~w UچrΔ4«2} Bԑ1!s_lJȕ.p͝p%r*H;f-uo]yA#* :LQnfM9?Cg~?T0f%|"p%RIX!!zE?ul1LV]kZZŇ.Ĺ*"g,Exte4u5<&Q[ .}K{L(=sBc~^i'-q Хsύ+#_d}C-OPD1N5 I=YM&h3 gL#xjx5=BpFvRJT-dnJ=i9P&_= ;y+C/S\I!9($ Qew/V]A,1+^Jrۣ4BDfU?ϤmDĎ )-|FUHeY%}1܀0a[Pм؁ǜYHb4^6^L"IED/u^d D@)>`4/)2RmYbT:A[IA^u-%o3;/**aҙ.Ld#Wu2<" 6JYO JR{" KתkmuKE>@Q R)MDe4RCZZ\JpOM%(і_~|)j_<0S@?4a[›n|ɉZ4^{tiH^2᧤]7m~Z(;s3u a1vMzB(އGiGc5CCz0x9Yi8 YP- 7t Fm΂xuKh62;Y\Q%TOc> ׇ<҆Rי*Y\4ޤdӡ)ƒumCk۾{u!Wh)ƃ"'FZu ؚ lO{> / \,3MGnPʵ@ؙ OHQ~|tLL(!,"]| ![̆Nq8c[kIRx?:'pQdOWMڅ ֣FtH T2OT˳XgDiUv[^[$>Ёucyh79lE^FUAּOE> o"Ȫ6un ֔3O ϲ܌+́Rxgenv#퉶Y)s; *7홶^]K=ec|}.(:&F1"oNEP;&|;b)>:z5>ji0.b7O\>6O}emg;FØ\/OfiX U)m('ɿ1ƒ n.uL3& ҁ7ί;b)bJ5rObqIpJ ]GdSbHb2o^gQn|&3nK%ѡf &#Q>s6gݣ#-+B^ulwP:u"ǐ*1KJ֥Dw9àC- 篂q%1Iqa#aA^[ |=0H=j!UE`ט-&{uξ[.Fr N%[KxvO7+zM߅,(naH! o6ڝAqӯ r<@%Ez6"T濦8`oeUA<嶒CdVe}!*E_sw𞭻uBx1SVi\PwN_|Fh(E`F΀fW:N-+}~`>41Ym%\+ F䓀Ļ~t+cD Q9eSڗwn>;A}@Q6?āhn`s:' UA`2v޳ c PX|L9P):sS/p})H'(^Q bJc=d.065ou1o:ozXȣr-SBy6VRar4ݡA;FANkR_퉺;Epī!/Vj"iiY>LᄰQf3x@%;+D3MHf'[&&֤g7*x$)"O8AkE}ɗZi DӔ%Ez k}9 `C@Ubf[^ mw99!ġkk| [*q,*Osȱ(a;‰!+~;vֵ W&#[eG2Q@կSQh=$BY'=[2 >ni01LTF"ti2X$UeeYe ~qWxwY\8-r<H"_|Cs"iH; /|(({|MRg̎JEYM*P|-A2_Rz4Jڭ*2O Kݰ|GaV,u=P \J R5 ڼ#*uht>wϼc̃+U(;R4M`Hcn $8+mNKNrz59loeddl@2㎘05E~TDN *^UՒd CLLP $,KfR1-/ =e-Oo\ d`f͑n΍@AyS"|k1+54TaDL Nr ObZ}H$6#L]zP݃B;r=AZXYfGL[w}uw?pୣ((mџT~ _o~%ɸ4Z%׫E#} G_B3V @͎C%MuE`UNZ.&L%v]'< XaӭE?лD~xx=BQ^N#Ґxvιhc3z3Pۧr{5Jl&q%HQGJFyΜ|8EU{-{R85 $4Q3D,cx_M0s~"^jG)AGstk=8WJi,{.\W18B e({|L/llȪ_(z\ VB_[J: '\(Nۉty oo@3] \[2$-u+T킻U/˥H/UԄNqW ׬M46'-,^e!'ZPw^aEPNi?)o|jhFSWZ(GjPQA bϸNʌykvٯtobmj3;@Q3hS7u8YU#%>Sg1W%`cPFx.!\ RIp,$izsI%.wfIjƢ.*J%P~%pbQvBjRȭm>1Җ)$ĨxeЯ)75wG1>AϪGxu0os1ˉ]aLtu ]ed@*L(QUh"&=oKk"~XF>[`S0{; Je!ދjcc&Zpf2Tf1`aV7)PV]ʡZ- ^y!h. Չ )6Η]A1aU0P6,hyo M3qtbHǸ?PU@8=¥Mo -9HP ..8Cπj'@jQ6OIJ[#-g]`Ǹ(/KP PYyH9(9$ESghWl98a2-dKIk; 38Er`%t=n*C$vϽ髴2 }^/4>Z9oMTH,?`[kK ٠3' s>BAJczN_i?XY ~v̕vdc|j,U.- =|nhLMktD;Ӄ֬r??(:t*'r} ޷2aQe F9Ϡ_l9ʦ^%H-p:K<5TӾ_EBJ=v/@TP%Tu~ōr#;ek "e)|!`KkY9]aI:rVyr7~L߀֚)-R7w K)WNx֋R V˃kG#3Deo*Ŷt&jFK+ܻ`&YQ_H{j03]<Ƭ@$v pak;c_eIctu 䪘8rk(gHK+: |i̛I{gDn;[ԲLc:G?R!؇5&g[oռN ,( ,)Q+c/䓯\ߚ7 qKXfbUBGv\KfH^+ȹBHș\rsyjD틈%D:ڭ9x gTlɸ5ҵ_4 (۞|#D9?a݃R-W&b>hlۈ9}`R$ۧWڎB*P4}6AZva q~`UJ,f %y6c et!D\U<ge00gg7pU"[Qac ` ,kȽcCU}9 3ބJ]veEN̈́J>cP|]JlN%Pqmw, a:<ͷ< 6}:>nǕ`-d֒vv r$XZy//__IMƲzY!yN:9:V=>w Y -MgA/2?vOR8c{F!՞̔'-e.lyh 5W=*=wռ~8.CE'A "<Ljl} <8n7bJzX`TAv\b[v{I E1O;;B *;;cd;&h2,+WFQhjBvhAިӄSF뫻6$MxߞePW)ߥ#g6Zy#;M/RY->*=s0RHt_1NY8P?4mZ6:ܶs(vL>GLvaoPOݒc)ȷΏ qIxj3?(zI٥F@Sxw'1 "nZ$z3/noI6EǓw|d lڷ>-q?ք#RZu0Orl$;.xL3$){QJh(|(EUDp'knpO>"ɹ|KDu`I$8yhuir%>H^+ d .Oq nnN!E~Nrb?>K}HLQ Tu#GZ.o5#ڑ%Of~ͼѴz`<D`&::&'Xg `ߴ(_kd!By$"d[vRW6M̅ʹ=;hA0Z;9=[![ܣ?kGW?-m[$VjDaOl8:ɪEX?iE:_NAW$DhPe!,Rnbd (`Bu'2ʯʏG j Tɂ'6Sn>a|1pM3/* ;%P\$8-{72W}b ߵ&7|59b4`, *2QbxA6x!5ry24cL4$2Fw;(>`b:=쌌.p!CY %'iN<nBI#?R}Հl)sBgpV2dyZϯ*-ٴnywD/ dJrucXL9j f**bv@W{{JV}~T<꽖PQpN*h+ )9ًx>=\.$MUVf큉@|ҫjHhoVm[e6iǟTD,L1'ؑ͡S~?`.jߤӎië’S/Eq_yLz 3ߔt `ّ+|F'hǹfÙ?2ʾF%6r./ѦmWKjCK;x~-r6cb:".x=UY۰V:yр'2HҺ n0E٤SvCrMѿyEZN_d,疥[?e!Ieaè&4tmn5IϞ|>}!ز' v AmFX @qw%pUlSRxrF!Pke GݖgI;U;ffdoM>wUB ":CGR#YE, '##Uefp^%Rr=jQи/Æ)9"bgO %ۃphu`PJqF6ty>K43Q {㹞A]W.x2B4)=Mm'_fAKfЭӱ|amڂk)чE u_shsx~ 2mQh/^ ]e@[? ,C`yoXuF0&| zϵ,B}= Ƀxqp*qC"wb#VϞtğZM[ Br5*lfn sLkcnřfϨ_Zoz=ln7ú?naWç$߹\WaÍ'0B_J_3UYd0D)&GIhZ"R1]BMӬ~k"Z6CΕ}9S9r+ eDes{6˟UZ^%hT]т2F ADŽ1XO v qkΏJ{4ŕTdO.>ɖȉ#P5_k]I*1 ,61`pV2;(.BV`(MB_U-3"@*0#e]G#XѴvt3kQM/(p x2Qy^\) N^3H8gˊ7,RD@-&22iLm'xh+ ?Rw 9E,m=F?Xv%4g,0:eG]OSfSJKucE1IXz]г\;#*_jIKjTv[,VR R[ P+=! 2 b*ш0W\6> icXnqsSH]%Gr4ګ][ R,dk(\8d"bG!{7ɦ{I0# ʇM J}~x&6({ *?iB^kR|N%ҌE>L;qœX7B^jŖ=A:BVbfUktfjey+r D W.Ps]ÑѢp~mcS2,k^K{P)=pf iG1@Sˮژ ?F *_A`hϒ>5KT[%*2bAHoV^Ѯ*#UIF[+rQN9o&X"2&sY- 7+.pTkxX*32H$yy6hwڒ-LIExL!<Q!L(]k]r: kPl`@0˻_,cg"6|2wh!9>xqZhz#M,";¾! --WЬA2!4= NsTc@X5!sqRĀJ{Enp<'|t9Jpv9^gϛqŽ R2Y^lÚ9 9cPzVꍆnH@Īz5R6eh6 w n<Nj5P=uiJy[][:B|WCbHyXBV +ҡ7-]M%U>)WGg -qpa#Ց c9сW՘z!z5ܲp ̓ >S?77pN{Km&IBW\NZHnL[w_ѣun45Q]!6rl,B \~0(\vP7_XUC˵7u_LOy&О% a|,!A_Rj,kI4ac%؎'8k s5\DGg~b4&VK19lBZ/;а]eW9~FfUHM"4g`n"*%))Gt 8~L%mbG T\ߗ+ 88!s\o;:8v"Gĸ0yZ9bηs6ZK Ƴ:tQ3¨nVGk^I9)F; gj%|CU?$N>Vl;6ƓQI_ F;raA^` ,<*$8ӨljMѪ4G%jmuc; @f}5\*TAqm 'nxJ@37S>xlJgKt幕aÜ'Z'I+ )hb xZK*n摪\ip6iO Tp"UD}`FTXȺm'X+cqAsa6oK:GMgp\NwO(3e`!/MŇdic@-*}=2mR({^ٙ;Ǥ" w l Gwj#rh%cݲӦusCSAaALG=.o53`#Soy!]?kٽVq4)("8/%9)1;bsc?ufOn獬m.K7lA!oƼoQV=4Z5w1o k7`Cv26Q8)+/Y ߼K{{rQ4dX[UD(6`EZ4w*%P+Qt m8lvpJ ^ݢ*7 ,Q9-/x, h{pTŐ,yGYуe<ZyGխrh[3,9ZIBިd|jK-ty٢G6p%Y𽶜OoTg7c`,~E!|`lCj6{db4kv%;@*Uf2m9`+OO-A}Iy\UZs ʪWmT;|*s)jY kNr41it;pDK<04K=RSDZ2oD} L 6ja &єyD&t2'6G 8u5MW'cn )k4> fmb(eHS/aYsW@I 3E9z5Ճ? @i6jW%2sler+(mvs)$6.[s/)jd$_F]L) endstream endobj 133 0 obj << /Length1 2430 /Length2 29142 /Length3 0 /Length 30567 /Filter /FlateDecode >> stream xڴuX>Lw#0ЍttJtKR‡{Zwpp^y^qs %( r31AfNlL@kw3W;3++'+ l r4<`Ղ t*-% L5LfnjEjkmwy3 {- Ϭ Py m '9 huZRu-U : "%S֔2Zj^[35_vWSbc] tuQ2j r' vgadvw3\ic^?]dN _~OhktrvKWW9^_7 ?ؘ㫨p4u̜,^ f`w7?_%Ϳs(i82C_3_ϲ-@Nnn`Elٻ?2%1e9i) M&sbRvljw<1IE~/+7RN GWnH'i'0՛.u{Kwg-'[wȬ`+zYذNϾ6 2spZ_?|<;o"$6u_ ?圬@_JzN-ANK2%l?=oC3G[4/o WG3ٺIz-Um6jr`sv#𺻯 _׵w8|m1~o9))=}y6I9Y,m\3WW3o$]`.%e0;.gw? {\ߢ! `,RF<? "Xd (*F:?qXWf:k#Wz7zY^NG?lY_k__[Izmrw+_:v:e* Vk|-/d{Pl${9U+Y?W_g h#eůrڂk.JkYntKOx׬`W_}ek__">Er|Vx8\\AGnW;]ե7z#ܐNhĺs=߆IV/xF+s3`j):8lVaq g$.1Kqϊt?oVı"hȣ9{U_@p4ȓn~b|$!rF}RLs~S*CxbREc2% Φ— EpQYuR>5B3ajEQQ}D)ºz`Mx~Zƽ7ȈVG!cJF]NęR;3wY`vbx TnK"|Kҵj$ɳ$ONoUrq4 WDyN2HW0пIbaLG!9N$,+atX!$)ku $1kgGGp591ڴ|B;*JUO;SB GR/ r_P;8$rǸ~;yF%rwM܅2I y]ʔDƆ+i~muzR S@:#eBIx~^#jpyF$ /CP~vWi`zqڕԷi kgM5\'GKmg&Ubgց^*oc{ P,Bh9ʦ%xRvۮ6`J慴p2|NxD #a}Aᐃ(uB<[چG蘎ym(Hm8?ϊ~ +}3% O 3N) eDZN~L[uK%ǞKTs{7-,ud WzCA7_؎;0mdЙ0 *,$:*(7՞#}O Gw9~;59Aͻ.[be'n"%B5,σ/0eO"'̷ktS(o/hMzgnX% "«4 2#]!\-2FD,}r'#J5+;}嬀KN݁eHD>]O2l$ [ɰ6Yz5ol ar6~17ez9QvYfw 5Ymw֦Fw@2q>'e$%s"W :vWJB|"" hW3s܄Bs1PٵE>b|wM:ʼn ,$T/ŕykQ\>x3ک(CKоKX&@0&E>ܣA^ K5(es#^09oӷ6 \g1WsZ"Ȧ%};L?UW"/(|_б6 X+IJn; 3rVY/| bۢOήCRzBϚ*gzPR[]dQyw~+ ; | U >k:~)0/D{"Fo< @#}֙p ?LsbG+ϚVfTLd2>+~{q pywIy,$YS, 9Ht#.ISާf3l3\ȱuNX)^v&dw>PJ 4%;JٓjtrC1lR1/KЩIQ.`6?3|.sK.jp&5rQVLt =b=@Fpa>EM7VgȪxѬ ΡQ= 'xFRz&S$.}t1ɕ=۷,%Ċf"gJNެ@@ŷo!9d|k|8eV/+V{ԏ.9+?)9 Rx׹[C94a>=^&mzjR: f F^gۦUҼaøVUV; !vКYW,/gU""dSBW뫔> ee\#]lF A"0^rZ3ȸzV fK|G*roZ"5PSڠ"&a8G\aaË5dy7.VOI. ?uKW1tQWH!EK&avBث/HP'[űҵ_R,3Z M<{宽{ZT?,h1]C)s7ۏ5qU<䈼qDr܎n'ǩPW sVrK:֠a Czɡj ?pˁA)ʵ]W ڇD ȇ*U+4ְu□K-FQ9 Ci\{N/`fXfcZZ$Zqv)"xBx!3!k^ hѕҦ1PlM=Ew]R5 !ftH>} 24%#/0أ<#O/!"IcKϱ62};0'{WpMzKȸi)K޾6Wd*S<zM|^xRb~[vdb7-Z%Ľe6\՞wxႾg>5Swq'IrTFϦ6Zm :^ڏIn_}u1U4FTl ;G ji?bm=Uĥ>фbqS $-?%~_Mм15|L{u]$J8:/P=LL2lm:^$fvFF/@#㏸3}oT dY>y-YtOXNNɄ[O=4wvj9ug9ʽGۆSh!5^[c Ka(S1RcVx*Xyw^^_u8,x e{/"m.rLB|C.%USָ>Hgͯ$Pys;L7.'ϋK2\(P_|ㄿqy'o^x`>5ώ"*='vC.0#렳4hu .-v%6g/33Y+QH:/zm[ů۳BzC?!>]Rn6>cKTVбB `P{{q.Xxz u$}^0^bԓ L>*=YJ:i)5BIo HB%`[3Q(E;jĵx~sʦ1Wh{O)G,>Ƙk(!W^ a6+z΋%Бgoo>/vg3 (Xn[Q֭!,M!Ƹ%2"L=Ǩ7I$Nu̱H!%WVQc,0/wyu|ά;R>pXS3U(('Zwq~@8qB*#]D%Dk~'&`WRM>my, Ry[L \.g*ɒ.V5Bs̹_f,f.e䱼L=."08<3gޗ{4'5F+Ч`ÞR'b^P ۪@GNp&^OQȯB9hQ&w{7H^*(ʙSZ*qiߧE\JmEi'M;G% U cH$dU|[XZ [X5s;R)n"PvqMf6@&AҚSoYŎT*"'Xt-X[ qb8n:Ri\eͬY2-B( QNKo\乢 6ՔKC/xn<k[ />Z8>StQvKl٤ҕB!mT akjVx0n}P۝9~sgqCR^ό8+,ǯB6uvx`" j,*+m\xƆo;OmD{_bq:k"fsP0ݶ̠lw+ÉƶulԌKDZ)jOyJ?t(%mTd8wnԱ`|dT?C[')|Og^Gf & NMھ!mSoa2EPS"g໛ݽ uEJ iAZ:G ➕o`c8ĥddY! ;溔rh2 +UqX5Fn*^,qTX}x8gݸ0K)3,-_kVo?6C:c\U% @H~8H_abUZn 6$~rXO%('=W+j2^hL}/ wX8+wX)2Cd~`+z{I1\|OeӶ]':ا{IMmai. +T?-<[ -X8}@[T0n{uINezxZpLlBДKfKNMo!-[)Uƛ*"tNRI7WqB rWǺ' ~~a͈Rwo# W 53aeֶa.HM=~]l zG}_1k:w}7A‡%|{\"ѮUگ!Pe΀IJ<e\w:>RJO gkgL1֓AsI:Y^8*g_C2@zoG5upw+lt1ИG(u Q77#h:5KNtLӨY2 2PBoF򢋶>‚-g$4:}o)%*Jl QB X L_B1/TLJw|1GGxA^8}>Sθ/5\|nOYL\:NAKDOgh}BmPEk[z&Dh &/|М9bOɞEBFץR0=dDͭ'FB\D:V\E%J$/CysHȠ@8):"CYRK{z@[{U0`FEgًәo(#5bl=_ϖ9ugPb%A f)GDP+MRC;v;LW<ya8a63 qjZSrF]i֚W5T(2f-?공fԀE*#Pwl3tޔyQȕnoT@>;I`k cy0 8kbf1*wɂQkXQn}L흈߮fY(ON/R8|u3{{ i{Eн-wQ޿3\LlR?E҈0H;QAr :"8=x2Hu&Xˣl h$~B'.Dd I߳OqZyV ~YguikUڣAV\#=ʪZY[vzǩF&*=S{~ll? iWXDKSY8bw-#+gzgr-(!+35k'SOVrE &5C&K!vyqcL>2/Q~(<(-#e&ڤ~QEwס _ے-k#B\MPXN0&39|>%(1^TQ" F{[fLl| - wNukB G̒<[/oڶȔ8D"AK~nM]m'EFvՕ[!@a)~}2t(Q‡Z> RtOّ]yS]I7-{ϫmC}çz0p_^lSߪ z)L8[xne:9&qmɲ lYBb ڇ>IR8ihjQ?[Z _1?Si+z'jzJ\xT+3i`)^h-~R }+QҪ"yοN 2s /Љ{\ٴ}1Å2VEfiUXuȾJNř;1VxSt6L` sZZXg6{:_2zkVX *)fB$?%HيܞD^I~ 0%S4"*Eׄ="Mbrp|0ԯQ >DriqB'5=spA+G;#}(-nh՜Y .9'!~΍0?h:֗|v'P-~;&L6 IΣ"`MqϖjF)#W^?bqO[pQ|^NfL{ݥh%FPA. isq mʨ5TPG ׷*oMTr֊ɦ;_EG9z0k?* 3)Bw>ϛ' Gj%U?Qs3<i)0/{I6D*-,هC`s(3r77M2s| \L?Ķ yN}3箄j){ ңqtMKt&¯5H4@t뗍 >~Oy=XH,GY#mhNU>7(+פj #.9)$:38d0Ia"3SkF HӁA꾡b vS6M]}ճy4#aԨּQ~ISB 㥁F$obu,lbdNw}7ZK.#x8{\ jQ'I/@VBpEPG*!=`tNavPћ>/"R 5aA0+T/ Evd堳 }\{fFTB.UԎ/%W\0쫏Χv/ kSA;яK49`pu0FF1T26y*OQDu.ڭ` 짚~Q"ZE%z`} p3e1kaXrTFo%螓(=?19;KT~[NY/h\r]N*Ã{p۾֫Hh8i2u5 %A=Vn -@b$ }赆U3Fe^W %_=7r߻ ' SؑLՑnmց' ?]fPk_b0u&;L&Zu. eXQM%odfĨZc+9zDӖalۻO䪵KJMvxl{Z\EwP6ّ8c)Ǯ8͛Kpɱ<@>cmT!BM_CDK u0b*Y0{&/"+OZ628,&1a3(9GQ]f0`h_Tba8WObJ6Mb % |7ԬT=;%Pb#fk*asw<:;C9Z|`O=8?xq~Q'4#9u18wDq_^%A4bt3c` @A'?FdDsT`9e:`Ou\iZmGJ E Pȁrh1gMᨚF&}b6tD|.*)mt<2,>d1*XcWJ ,t8zRaG%V}D@᩟sNX4k?-]hE8P/C9\)+!6/ID Nv$7Gt55{۴",\8)^ Q ТkwVɩz\nur߬c&J9\S_EA#.vof 4-n 8f\Ӿma3OT1gB"%"N'9ިs4*A92'P=2e0$%7R$-kp_k~9vVd&~87Abn7$ GT38dwEPʙE8 \."T_cL$PԨz;L^Ѥ;{ٖԥ2fBHGr+ojg wȃ7|IQhEd\Kԡ^zE N,a)&wnجveAаHy_ՈEtDJu yD~00v/c^[_γKpXY}+o3(`E\_1 LEj}A(A E󫽇r"ÖyD~ Ot>[8)?ӥhrMpY: r滖_[(j bLir{JE=o'$纅i&GɪyzBqPg{@60)s#LvUƓ$5ъw5"r9043liكf;wϩT;] 1s² [c@bdTby4}d!bX I[jHaqi{xt7`Xr0Lѝad€1XO1.+ 8GF2>#~'a"~2u!fI'1p? G 4qE?[si,8!KR]G [o"~ո#͑͜Phn9[٥z# dVױy0EkIf;\|aey]`tAK͉ %-p 5)ҧ쭀+PtPD؉'QaύzՇ^YLS^]f>J2L{RYE!uzO7 φ M%n3rN(܄!ۛ|Hx%?OL0C? `AE5R1ԞbHҴkN6 WvtCySY/j )? }9 5MÑϹ,eDʼuo쌅S=}29vB;ҢULԈam*aLv} S+&>Eyru~hу{tX1Z]Cg}_X669Y;ڢ*Z=@Oł-kԅC)Uu)Nb> )5a*>}9PR%!6#a*ܟfJ&cG w:Q7wi9'U6sz@D$dMUTqLῖW_,m3Lg[xrI`d[*l I{7Dp{7<ԟwlWw7ߏU~)/v@xvPf +xPuXg$E?^TL!~x5Q5QUE !C wgj'¤gK08Np ڄE$AEN:6q[rs)bJ G;C}{dd0aH B>b'x-޻*fgFq:VJxTsY}|e6)xf:݄Q/4^?/ЧPUCq-u\{co Jaefr]>RI(Imׇ=anΰs傲K]8C>]->}󇔨&ܖlx%N:ѽ&ŋO5 (&SmeO5Ң ~IrrvUhŦNo)'Jŀu=J>/ aZǎ$ 9Gߣ>eF-uaބ!8UPٿZX6C'2 g?[C?#,:/;-3 P[h0^l9#aA˖lXݺo+'{CK[373]$W˔JF?ϻ%mNٖ46HJm۶m۶m۶۶m1.%6_ ֟~8|0>v(OqSgusunibmAG"*Aw 9]\4Wگ[^H&TA.P|,ZG٭iLUoÅyrc/OP}Kh!^R%B̧ nD{pD]qsWo50uNUIEslu}!o_\4뢻L7h>ɣ7y <~Z"Fp+&ǪRXMiRnY)LaVcyrQif\J"h{V>W\,J_+7Яs@c+ܞ/$-2Fm)N^9^DUP5d­V!J1n@k.X(DEᖋɞ%!jJ%-΂b0) E؏5~-$:Oe@4oMXOsK~imԜrflhy͕zD/%}Yg\tMu\)=^2=}:4QCQ%I?G2Ǿ SlPիsΔ]z˯ͱ@ǺP^ω؂+$1hTv-=~V:<9ʑl'उm1%r5 %w *m''o#2WŮE޻a>QBaB7Tvoڐw}+Ѻpg0CƃkV0Wu߃{QļTSF.䘈77&OXv Otd?z΅D K;;d5V88]n¥*RN purR܆P~饷 tV捃AҔ8p̆ T)c8OW)+1+绘SvSlAU. 96 ؞/FYl*گ1`X~G~$t17.Y֔6!ag"b ˃/~5 [D%uJ6^835LL_D:Gjuo]@=Ԫ#&|_qEAA`<Ӷڰ=IpOAěK 5i =&02o sD u_/ NH]TFƠ܁O u3 H컧Y&A4i4]tKZX%F2pŷMvGAuG1rĻ<Ƚ/eNVHAEl;<0E})Clb./jn8}&]y~q:ɕ:" Sd/?,$zF79ऍ߯~终z!{-qIA=Bo P|ⷴV@m)߰f҃$ -K*8ۗ JXp`kPLRPjS)/֧^<i{X@&,,g:kX7A\YI7\'`>);Y719ӯC6b`TgX@~4%io#:ۼ+*)F8 [a]g) 7Z7Ka򪻲8ͷV^6d3rkI|N`sAE0=ND>n4maB&ȢS> QQ+@ j1K}pL~]"h>U%aafۉiȡ_)Diց٧bށmhƝ!&ѭ6+;z$ŦwѺ ki<79?RMi-DK)`HR /sn^WP_UբXE)ŷ,VaR ePmY ڄYXiURdMZgkh;EV6nO%Z,J+~^ECXiSl HQH`bd::e[>U23 ƇK" 2;=G_v|F(=gpb70bY_/b| >>\lx91#kAvIB-74=MgŵQ.@?X_PR\$ew抰ߩG0FjΆ~|L%'ӊL.AcKgj:Cヱ#R0h q[ :ǥE *wB B\UA>5L,<`lj8@%F!|[fؙ0]z 77_F`jufJg8*o&~pi8(ꊜ<E9I:|C+Lk& aF+bRYK8Z|w!(L> b@"X-#8A-@C?ZhrXyC@$Qyyĥ\ bGLA-NT03wϋ<0UO,kԗ)l}Bz&5pgsߪKcb+d?j6s*W# Ѝ*/b2qr/=_ӠorѐDИ?_)֖ze`A7-jz8wpۡs%=d;4 $BHT fa3B]S'°f>Zvijf_H3 E 9iP %Mo<dx(^KF;կfZyj!>: 37W~|z`.}ݘt,*9jOj9-K]X|o'i Nb95Zos.dk翚'-$;F `kpK\U&OBvQʑvط,ѯp@5 I$sV+{4[d{L^ոR9v. '~m-:`$' ?`?u ̸,EABK-ABI4DE/oK#ӿ!Ķ r&\M}`HUQPzoYQ]#PtBAG1 o%Hnj?4^VRof)|𨗽vY + rJ2f\@tRhh$j g# 6^6^sXANwW6'{ݺaj7QG} D8ހY+(lΘv$`E?/ }aWo'NS1a߹/h"6kՓ]NZ M\YžM}p'_@fNحǨ(kW k>HZ(J> #f;ϼk,h&w]Aj.Usa!uE(cDDuS68t\FQvӭ:Бs9'T$)R{-S'%aJʁ6i.ii+D-Q:Ek1i?\`z(oUҲ(j1ʒCW$5C :J]HSyi"Ķ6u@tMTy+hc$dęӮY JpJ,f Y 0obl< ɨ>LCd^ Edͷ>dp*E*_錀Ó*0A%EٯC@G:u9S[9VXl!N';CL}SlWR/GQ dd¶ODO՝%aL~e΅6׏-<پ竼N[IaCQO0?PO2JJe|gUVJUg=|,cv(n!B}<,%)IaR.`LF˩LgsTHJaJy+0#]4_C@sci)aM-wR<>p3\.&刘$!s z8n(/Z\r?W)dHZxO5ܬuȱ3)d4,(Ea_u-ZpDX#SSkj]mDF fvt^=8E쌇Î.h ȶgu7cty'rv(kieJ= =v9 jbCb'`61z[0 0k훉8%6 G~]!3kV7sliXea*a2U)ˆXGb /)ЃE<6xI}Q>G<(Uylm~a GjMK+4u uF.쫳sI#ɀ`}ţ߰MvFiYItRkU6qa/"k54'8pb%Dޖy|̨ϔ<zq[ *k,FY+`Ѷ彏zmC=6iB%O_\ HiJE]:z2SQdINWΪewu=2Bx*fb>Z /\z`^[jKه3.|8.dD-+Zۋ^#29wz>K&Bc_ z4PV^nTpȴmǚn(fA_>2lT@-Co~Ը'zS<\R󺍓y/Y!ʃ5J;k@?^)W [[/s8 :=S =6NՃ;\ -pud3SXDtAC33(6ly? lÌk B|zʈfh/ vmZb؎\125"F>km9 .<ROơV?aCTJc{iQ+љ`mFmnN :j )cO6l3O.pMNboPbր/1^nbCJvέRɳUFiU}}P¼g"Kve1x ,Xp{ ľ`!/L0EN?Vv͇}VkO]^Vh$8eDK]ES?ɉ[h#0w_) Y@;lﶪ:'9V ä#yv- O{:ЍG_[l2J X~`* w20rlM-K'( u|:?"#vԥݫƖ/I/K= Sn+Yk.@O~L;u:뜑A ڱwK )}C9241&#Ky@[uzpM\˭@3j/h=-?͇仇o Qŭd;C?QrFc.ʷX<ϵ|v=Q.*%ߔ(/%:YP2`ނ߬2{'WQec~"7Y,OSaC+!fojfd?mi᎔?|ddL#{^Aٌ U ?dՃ$b@Ul57ݑ@HTu7uՏfMڴ>ߦH+F+`me]}۱,^JR47 ;zze}O V!--WZ4gb(ǵ֝C*Po VTKs`|Ir 5p{j1n|Oטwƈg"d]n@ױA`P. z5#t- tT1sq1NEE'+C.2JhyAďJ'm;D,Q7q 3(Ym&:6;)ĥ?=GяHputEΆ rE`N÷#;| `:dRbtUPY,o[tE@9Czu+Nިׅ:Q1జ9Z@k_ВuAc8֙D/,%Zr=YZ]uȳ Fij88F^k]$Tv:<8e\^W)#ѴcR^WD,rl"#s (W6ϯܐ q@;Ϗpa~|J8&tPc<(565[]nw bQ> & -j1ҺWy$wЬm-&2mc#,{[A(,v7޸ۿ? j?Vlj+|IPP3 k5skZ<~>yR54}+ Fz?|p(k- 9Y)C!2L|S˲V1]`I3*x+GD@w r_o4qE T$;]8Oo38ivv61O揢9h:}7KM@_E5_FHvN)6/~R4#ˌY7Bs0c ܄M]?R0'K̸> zbNIMi<^Ҙo՟}d#ES-uZ着 kt+ gWBHE AB}="  WܓOa=!O05B_}*,4έP'L2? }a.q5W3HJ(5F2``OLqE#{,,QuxEAmꞑA8.%BDy Hтu TVޝj!%Qe oktIj(~M&y-%L02)ِ"£yCy_XC|5f?-,[[GlJpͩ7/XU::2γ}|apeXQ.@g%Y nӥ[WWJt 0rsR&Ep#JpcZ q Wvh3p/t<^%&A}Ұ3CswM9ܞ}:a,oR)Nߤrc&2uӱTT D^n2N u5y6j-HqT};G۴gwY;6Yri"AyꣻQz"1ra m 3-rv9ڔXsm i &3HpHo׭9|/1 = /GNp^‡;kFW?@BHi{Q<'/ǭEf@hY{evu h9RB3B119x1Dzf-c0(##UYG.?~u`"wg#AgaV)-/e4w2c,NHkBcrZPZ]q$Ba1: "Ԁ-,0cJu0ֿC5 >=s~/)=h'[gƾD`D*O< #P7tݪi9_t ZRbMR*sara'څEt,vDx~^ "p'ŬJA&G+ ʺ|9IXyw4(>Vo8Xa"8E[[:֟zCU4:;pӜg:se'0b7f*цlj[5KHbdȜpȾ\ ʃAP*v{T(vFzxK޿g7>k=gֺ ztʗ7 C߽30@71E(u;Fy!s򧀳dIӤ<ljpl2Y 'EUg<Ԑy}SPlbIJV 0|R:{H~ᚷnG S6@*ۦy;Ş|mb*=։ʟ >" h9(C/w631-KAVm8=v 9LC'aO Lj}G?@rN&ݡ( )^-iF] p.;wP{bFHatxBk_X{5ə놗zZxmO_a:E~&u2lؐ?z J)Q+8Ƙ[/My+&e%w1pEV)*yw>cS$q"iƤV^`-[b.Uj~DG@#;rʸ8W[$68[ w3!5G .6@w^@O[x=OMۖg" #gJA&KSDcU"H1vC)"8NQyS~qf@F[C3(]gvs'_Uz '.RG *<3ԣsJd4rF!I #HG =sE9'+,YРƸ6?)\9h5Ly3GU0sɍpw\z GdtH *ƱZQVa `4c"TZ:2`vl7)0߰QiSoȭ3@|W"@;  ~Dʃl'Ìr į(דblUY6gYL3C/#ObXB7Pq+P7|\9,)Lf6Q5Ҥb˯W͵אO!v"X"ixŮ(ԮC-쯊r&ÀbkC/Oga(qN$09M-Q9KAdvut[}6D'V MmYDZ4dh[?R8`+9s\ ьܛǽ+sGQ)7\lPa1JS]V^,_\Y*q/yl7IF{Y)A\Xl Ljvn1?+{A;c|uۉl1' &[wR8"ٱvcbHcΕKQJVBjdEYQ_- ֜i/byʻEJ69=/t QiIyGcڎ:tW]UeTw N,0T%|f{Hu"ˌ-VJ/H騙Pjh#yj}R5ZzIjWLx ri9|/XGH^%H YRN SRP&#(A1m{ZYmCBæ}$B-DUMf!ab|օ:|*ޢ(2vLN,͏ilWTy[veSudie2{83QspQԟ  G^*tӤ> Iyfl2/PE)D7yz\(Π0@gԞC,_}3p#\fC Q(_|E3m/_" Z7´#~'|8܂((nP0%ttGE)ٗw<֋o (OYgԋ+Kncth җ#[9ZH$-G$ͨ.==PMS哑{\ 9ٓGڷGvdstW4FsM>j@GU0Ynk]oibXOΨTc cn X~0$eSN-4=h R)& 2,S2r]$É/Al rHx Rq+%6Wpɦ'К%$DldkD)J ;ڤb}jqJ,Y!@Mb*2K=C)e&y.4mN'B{!?izFPDiw(H42L0.DN;[]5)Ԩz0ѱKCW& EMx9q{uݬmJE+'*H?C1zju" e~LJc2QAeQ/N$CK f)qv\*LfG;GfS}1l & h奤_#G 0+ |U3* XM|D+I^tB7t3,oSbo3Rxgk75$2:jAjޯJI |KfTW b`$Qti7wXTg! endstream endobj 135 0 obj << /Length1 1941 /Length2 23013 /Length3 0 /Length 24231 /Filter /FlateDecode >> stream xڴeT6 ݂;ŵ ] ww-ESܭ[яukFFv{ʝJR%UFS1PdWٱr3]llL,,b@#gK3lP4q~}`aᅧH퀎JS@lad@NΌFNjE dhin';#HE2F& 7'kK)@I r{Zh@vcdPjU%TTR*JLU]A@\DAM`HTڽoPP{y7./&$ V+Fߩ9l"X8;131893͙mO r?6 bg^Ng t gisq}/ӻ{/60rWNII`kdi 33y7t6rvq%{MNsqt!/+uQl|cFv.NddwD '{?=K&/ -)(>xv19;e' `yR ;S1{N'n^'glk;Cafigj.v.@i1[ft¿变>^ { r2r]>^T'gZ8] [ɿT34*l<@3xfHi%bc`d ?5oC#[K4/Mli@F6tt*Y:X]ڿF/bgn|o_"?+e> _4:9v2~|JRrJwl3Zڙ8FF, b}lS_`f9]}f G? 0xFF<f#^"w xMY@6?;?;?{twjCw9̎DN\fw^w^CG g\W!˿{?_Xd Դ4} ._xܽ9ޫ`egy?}C/>@yǯV)M&ˠ(yN*d ' psȀB-_2 @r}튴(bټ}O1U6%@`RȐ_RIF{(]1J P9m6vLWֺV8ڌhA83&ҨGdn0?{Dھ U_#Ux}jVQtG`LG荾bT~7Kh*yZ$Mtv,6I1i[2 ֢6 riGC5z{LmψwV(/#JZUb6ZaO >bkdsH"A7W@Ж|*@"SFJm 2jz GeYv~C$"b |gB76%*Uȷn5qWvX[)>mC/3Z ĵzԸk_ É( '#T= C]+xq#(~[=9F=9<%\ƓAch ]̏&3"LMy7~|6Tk(4ͭu +м#˜7{L$G`R e:`JYr*MIo7?3V~: 曦%4V}@WK=}gX.jA _!pR G.\$M+d)bM,&̂"/i+)LA= Rba'3lٱɑo_6bC *͹3 G3A;F^bg2v^k^*> {&"Z$;l~zqʜﵽu@X=DO!tmz~ґ%L4l!.1%E ƱLTYcғ\ms-L@TL|a6A}$/ZB^o=S3F^6Ou߫ŪB;9EWﮑl8ε͙ӗ;p1T E!,=a=q۴Ba(B`w5STcwrC`FF, ̝ \cHK1pIu{ Kb86L4_KSkg"*zn2fB q<|]םΏL)=k' ԉ$a6J sWSUz'^Fԕ4I]z;)e]i"Q>EI^ðjpZQ*{9m#J-vn>)TV/Zs0 ҟG#g7I5MOAFn\\">ҰYeB`U&Ep'HM&ǍeyG)Mdu&7b鹤/aNm?et 9 >KLe>Q#*]p+H{GII_jNO&ZCr.8D?h>P9bn|rUƄߠv&a"QFuA[f3߶cE>xKR)ՔBϊk t}X0= 7ELM3&qaW7U/'; lo>R(o8TiS+6N@v adX߂] S/E|)|&}UU !4GGrc\ɪWfyUn*< u&WbTiz]7WCylcĖz[US-zV= Seu<|65 X e>zUYD:a !hO"FUx^)2%}Z>E\gEwo\: p3t ;ʛB1}1y ǣ߄뫰UKL8,@z)GmQFA8@2%К)VeܡqE}_vabkŔϬ͌!J Bf8ccvjM5Rz{$sFdn!XG- Y%R0`A4O&>uqn#0]Gtg~gUʷ`AX#+,\@mˆ^%NR9w˺>E"ᄺTqQjk8U& %z|֛w{zw!12_AgI)sh>G/a@*Bcu=1i+Y:&j#~aNz8I3>y2(%@IS[<̛rY˛ԶQ=d==c_Qqࠁ`Ȗ;B_Z<kT~ZƷ</ RpY@/Pq'IiV \bV 4⺟xh(ŝm:46 5V%Mmz k΃b[ 'Wfr>% i^ kx0HoP ЌZp E~*SU LURCr$96>cbBj1ҟg%Dž^I%`gޘǐ vqBkw,IPvd8>A崏$6 wK { %s1r_Nmug^]1Zk)4dg3)HU/Fc`*ct2*Lɦbc5nu+)Kn6bd70MOf%їLI,TҖؾͭa|ȸT,-Г淂"O{ANUߞOq]Um<!56FsO']t-u"؛a{Vs OY!G>v0>Cz /q]̕+XPiuxRVU/bgO!zKh)Bs}qnosMp9)TR}r19[RӜoiR xRΩ5HZpxDIX͖+÷qCGb S,s h|Z֯B`@~ .8 EO/*Kki/];sw{q\!!ybPv"h5/hDB8{/{jNb] ({K!F<1Pc$0wOJ-LPdmnW~gGOdJ`J԰ gpP2Q PB*u;? >Fͫq% qNs/ 쎭.y, ZJF0m uP㐦@sc `D=(iNOtJ ۔+0][O,%RpPsp?Ĥm^")X~\:B,0G39=}w@ddzDID:If#`$C4J :O:]eF:OsE1RK1G<%>--ITaF?%_%WB~[|ݙ-ҭY5Hli`NS8Vwm*'K2Ɉ:iXŌm3;ILwiqYHWK:ܑ!D5 4Fz#M=<"'`4I4Vb.lį wV]_`H5:5=OTCߒnJKc >\L<O%Ϳ+#2euY%/4`\:? :JӨ~G^ϟ"a@y!SU6׏(O#,]鑬h_-Ծ^=S7z>(¢W$-V4ķv۟kzSgGFƭ9hջ&s]eK9Y]b櫗ߒǮڮ!FX&- _0;g23߭بٷ;@7K<0&5?PZQN) gtBJ##KHien B!!MIg%9Mgv-f GFeY^K+\Bdr儻ng)#j<-YOo8’m+6~vjR:n~|&Es |8${l?އͤ#GF‚')XG}2&EܒHF!q >b %d3% NHϖc\F Fv7ܸU&9 '@g'5-f{q>EWJX0!̭n=?4#[ .Fй"̈yoTNdJ#Hue3Cdɗ{/N}Hm uyo/v߃/S |<F 4UYPMJ^hiZ1B:Wo^.NS#^bC[-VkB*B\jB^?YHhN?bybnu1r||)%:J4[]`δ;NBgfbFjSq4M/9qF妩AN-q6ݼ<="sڗk]t2ЏdC)SW^~? =jF [lGBe'n>&{t@E#'CDwQUDE#ux]tAt*;` )Z~ @ʰb8e\UCX[wjR,%>h5)*o6ׇUzZQZf@Ϊm9+ %oK`>LQ^dK26mwO9keaG֎!ov k?,N z~MɾX\4f)Z0۾~{E*zTPnQ޹RN꡹-ʼnb)6&0Z֛"J{`V 2µ@D @f|{I(k8S^͵y9$A2?R>8nk^F8YJRLsOM5'6O*(xau :Ba=p뒂>!=Dh{P_\uv-oKmf 9h;Qfz: /n"7` M8WPvS'"`d2\q>RWo_*Ov,3=<ڳj =#)Ju4Mv77c?5A\&C arCgkڏ pq>ܳvA6HjebGG]n _R 潉Կ qKƲCgǾ\I7jJKZ)kN!db6Qm-n o/ M2=1i v/=Holk4 YT()>Ɂ# Y 䱾{~c k9UvFy^ (iE?xM!cNڲ_ I%rH(`%DQؘ\]d@Vv0vvkbEGCs/3}S)rZ9VLAᇼ`ʄd5H 3]JBBZ JлJ=U_0Qc9 f&cРIAN?iNzJӑ KLHU1xR/9xHw'6c!A!Q9 Ta!ol&'!4LpF}S80%Pd(mwT`&,?B} A_rX-" 脐{'Bsp uY[Eޜ%gX{{䯓Z{1ɣeݍ 2z,w,\Tj>m_,Y&`?Ue]l Hew(rĿ*ܗO\7" S\UH~i*i5=) ##̧vpSv߳x[,au:dLG7S@WN )^M_ l3 [@O@ލ5*!ݰDLS׫r'=|8*w䣾}ge&_ g>`xʛR 2 P<6Ro5`6麬}͑ vdoj7`8H뼬Zu2GuyxK6V*ђkg:M;+(heϿtU>"dLP D>Oq +=J,WHI"I(;iD;[1C9&>nK]˃2RLf_R3!LKy!4Jaf~ANePMMa$P+LOvf-.+\²:[fVXGF~FTX(ɸ,fEZ,W70gJ ok'%y,RVW O+ U8oy;Fr%-~mTM̹qF486Pޔю;=KZ3v}0͈Zx]$:ҳ|l+x+:O,gȿn!q#] 5m^?5y!P9!E؂1rRޮ]aY ɯݭ ZUՒfV=|?8Kb0~BPY,&p ;|'[ [@d|ΑAO:0q.P#+jPIvOjUVcNBIb>,j㫲m硯Nd-D;J=82Xl ݘXCΞXX@F:dɫgJ0mzeH綯M/0e9 /k(^mBU-YN~9 _9b/]}TnKjtKKG!Vr4/>ݮΞ% I#>L %R*͉XwFA)O.f=J0yzvve$+HmvW + T 100PJL |kҎ/GNie[lbb@JJ: N^n|C=[o _HTΞwUՋ6s"v qB49$K>\3StE#Q'`vj[|6@+AE!=󱪰WO\|'VG̊PDσ68m=WR@;:LͥZσa\ ѾU},3P4#)ʀpp>Ld/(p{hXwB]KƯhǐwp[C0%3:aLMOH;PRc"eY<lmukdFRAkܸM*_>Μa3R73\5P^n+E<\PFd+SoVyvk#+<_IL$i%T%iN:6I%ƍ"PgY8IGp/@=I^~c!<0L']ًd"Q6)"N@!1ta< Eѕ }t+4f6?8Gu/rDZS#^Wtz#nYPE`iCx[$c|ozT+ RȲ+#ҕ}2 =@{÷'B06טS:>S·I*dkGg0##IJә$e VRԦ дng`L*M. JUT߈D;J b^aJD 1(\.d´&<8sR,򍰻7~{L~*B0.tCC1G,TUMnuYhotyi`F>uQS(>V L5nߧfw"~Jjwo@nDZzr(I:pksa=!b}-[j=K۝\tq5ҏ͂_LLeb38SC.q2oō17/ MAPl|R/n7zOL՛:Pz`K\݀"5\YYJR#w.e@u Z.dԦhvS/.NP=C=VQ6zrfƕ_GwlY#+ >AjfkAd;Q]K"K:Y3}N/Fo9m@'52zX $f_599h͈aP3*֠R|] M[ DC089F6la#q;X]JsBB!3u-p˚ӘGK:YVOW6,ɏDb\]1-^ǕKh|v:@YicsSRoJ<|z+}3V FߨE f)tC#-}BVi&ks7fC=iLqTFE`~ bʩDY:L}hĺqm۳'wāP!ѓmަ,2l} }ǸKA o(Wg#7r( =X*Atmͽ-jKcI^.jֳ/^= pg*?}^NHp>߄~H9C{C~t~[djSRܹk01eMw84/vY3aBR{׬k2Iz:*9fvwʡXdcXS+_?ŠM͞(d-9&ۍ92]sy˯Oqml5t fEv1.C]mx@a -ԦnPCVfޏ;Vk+o;'Vą9K},yxgFZye'˭Bw7 rFq]G`0gjJ{pʦ:m۲5,$*kU`װa1dOsH047 B);R$h{J"AG1FCy.MѴJ}(?ݸH?D9ZJȇ"\!$y!g#NZOrSS$7n!.tiGz?F͈~Pʐ !Ʃt؇K"[[ U!oƵmtQ Ԃ "E;hC8Q뒂'v`gKK[̨'1t YsFdzM|j/eM~4Mq7ЈבYp!rH8lM,6CD28M~$s67/R{Tm[P$&i'7DCK%6WXk3k*suŐ5*e_3B"7&9UK:Pgê:!3(1PeX'bԒ=44پeOykjY+$ [}Ŏyb ˔x|[:|."iZ]pL ^v?b%]_I}˴Fcƙ3 ( 3/|v`x2!~홭 RϤq?h(H iU٥.?e]`0DLOE^jJtk'coWFCa JLJvF/yB?Hȉ+ˡ0,i"rѴ{tj("8MeX O;Ts[؈Dg:6Կ.'+@p9?[GN!$twOu]}5{g?:+f(VjHb]DJІ(Mlk&3Il-XUG2 ̢̋w-|.n>6s8(N8XOby!/Rg2Z onboHmW46R%h#Ҿ@G<ˈX=DzI)9e҆_6s׵j&K Zc]g'Md֘Uu0_?iTr g꛰[_1[{Lq!vL :NS%0Ъ(\vmt Kѵ}.•K⠙;{uUgYic^V<6Ȇ9W >Y_GG[Mq!lXfA)cmX$a Dޒat EP2|)s#骽WP'L%یbY-+?ۧzj8~eXR0TҊͽfFC8/9 AyAX4՞ps,CxmoCEt?ٓ`?ec<ْ& xMY+$K;HD`u=r[DƛSz­[+"Ckn`$#mmɚkyFW p;Z  MQ_-Phe V }ϕMQX6bqRS K&SU%ڎR\ %Qm]N*٭>xzW!yVXJLS@e'6-e H-HTv<u~UaQ+nӾ%\6t`u`6R}q*n2#I%<(E YV4w.m݆!gw"Dev%–;zA/ e̻: L v%0`="қK;QW6@Wz6о{_`J]ψ+e%J- 3ٍP, jlZ>ֺ1Qgsdf'©-At(K6rɢ^1X\AA1o'3&cHan#fֵjg7;iO:3Ro\@ggQ%Mp'hn+,'3G6 ,X2_e~\kE*2(P_?f YU^4cKR>\Qd19s!d/W] R=(5 76 ]%W_ -W}󂬧fwZG°A֔f=g76#h8) ZC0H%r-k$q7$H#QSAĆv4,z.<8L\Y}g[ ljm:4<w21be38 ٧qX=W(X?!ƙYd<>Sw,ˁB)$xd;HVH^Џk Wm:js -B%_¯60^6¢Ɛ%m -Tu=뒒K扽uɑQow~V<6i9pb1WoeZJw.E ,t< 8x&~`Mfe3D"bmPv.)m+A @f}D4"Pj}'RN fjÁp9dtTQ_  !*lkGysPp'2p^ǻ5'襒s_qtc rO50S ֶ4^\76; =AZ;OlmnUC30q@W# —o@yYIpz7nN]Lbs7<8C\ F#[<͚{h,CAB:f9҃ruwh W[Oͻ(AT7>Sh|kjE$+n h6dU41 91U=ř/%=cfg9|>Kݐ:|n{?5x;0H̱E)Y=qi C3e9бdZ<XL{iQI겑Qs P8b0.(FZT/7Pf-DeCQΏiZ eGe-btjؼM#yNh5IO20jvY=kPupS6^!̪P'LذażxY'3sq.>Jzx1c:qU3`0O[Pq =G]dٗf쌼EėٲC9؅>? hjt E{Wt_ВÃID z?76𑟶MEdl|n(_@/v\(sFz4L Ejλl67NXO7+@a|[gfbk^OM#ƌY3L"Y@1vdLyXTo9Aib&%I:^+л=)CBJ OҬECL3)ЬSՈ]ǀ*9g!TY!8 U九'0s`opmQ41DS/_%ˉ{YqX,- Gth01RzB%z'm9_Opqף9n~Ko[ރ$(ml($h7SF7MU=SuXCk&D[Htuդ684G}7q+VAv=rl8sDX$"5̖nUh߀;3{Dx oz53+ 3f7#E19@*DpDiُ#.yŅP)OS:=vya_k@@;uqI"uZ@5Ku5&1!|-I;Y@tb3|pl.52GGɾQ#l|=\bM5Tk:R z؝CS[5*G;fl-[(9)|Ķ5CrոCW^e;{e]~M 0q)@ӝ]$NpIUa2h9˘h #T_x> u`NH]Sju:𔻣(`:.AO*%zUOL HO7n{_ SdYIplIjGJ h`K:Ո ڕ$Gl lF'_y䨀4 '4X+Lhƚ~xUݮ1ӀH2L@Bk0&g;3qi'߬c?dbXcL%`W<.s)նIKɹǶny&E1] @L(5Vg6I%,Bl <;0IB|"7[m\ 8>D^8E|ahS~=|ǹ5VV+D?O,,#$6E g?< ]B^\#kX;K!k-_#]IjZVMamh@4ޅ7k@]~0g&:/fL&%gW*|СOJX4JC9YpQDYm?&g^;`&a]au ҩ 4^U*%OAj1ಂ맞i`=µ L@nWt0C2'Y:^fE|ȹ4D9<-7ӯ*_ԫE}CRyfQiJ[^٫x \]v I:n`2=ېĹ CjZxHpwlvC-s/N #grED"p^T ,S`0[ȃٓLM i+A֮%;Ci+wsDy [>v&L 58wWjb5(Н[Ee+XYZ߻m-|"~"gr&,#?"?>ބw}^#{dNsw@ؓ7+1Ir3)ށ%xWjՑ|)JI^*g I[,qzⷑMWc <(yH[Ȧ&mQe_ؘYѢ(`Bw}$߀n)wh"M2"+L1VKj>}B\J#1`C`HfY!ݭ3/KScYϚqME*Q2{ TM\sjl8-k65"a%,~׺e_'1 qs̮j6{>#V" H\+m[j .)ޔ#@ ˼ͬ`'#1p/>{V &C>!ʯ~0HS39{ Oi7\*5w9L"})8aAo*Drs%Dgo*NlʗC E˷p@){xӋ|ytd-LkQҠp>.̗s9< D57*#J2\H /Ptln& +e` fCŋ-q(kߴ \#OkD|+ͮQ$FZV SxrdpVÏP.Źbt(U~L}I16êqV3붢y@׈&Rufas ziT fuwER*}u;LGhQ60UoVtz!)lc2 yG=M_w`Z~T8?0!!7lp wP7NpM>i&08/jO2bQ.eϡi; IaɈr(6 uGAWUD7<=ΙW_7o2)֢K//%xFF;O-K} # ghtg dțI@54B,w\)`j<,sC ޡ.Srxk7}ZnFG -yjf=(=ݒC+?Qda;]G5`р0&&yCQ6|X@{4W6*✡>Ү1F&/&y)*DR.C aTX,gy/H*Dϟ<eB)ィv2SP7oDxg3&5\>NЊSɉ1jha+Cu?BL@&8 tS{a΃ip 8 1W#_vТXf5LTLY"5k)$%< ZN6{Ґ(ał`.lN7E?}+ ʦzinXbxHU(`g q!jGܔtg%{7cEՠOwP1A`MR#25fFGu<ƫ3?tR~S /'<8OAz_s2W[({0ƀl00c+"s%)V8GQ43uԥɄo@HEͱ|¦G ;S@on|4ɡz'f@بXbtӈ]pk+m HEoA`0ī.Œn^RE;_/7EiAQ{!q;覦@)mx[eŌ+=XMduhwJBcz-y;Y:&l՚%"{q}>*SN2RA>4QUj<70߰8`;̽-Ahgdkסbl汜dF7<n*ח]rRȴHAُfDF 5WhKM-H#95! (igkk]zlOWK⊅%%ɷsO޼QeAa-F& k "$.nPC>N'7;w>݂:/4+\2ZfIhI׎gXn7iהs1o!5]Nml쌡&ԢG[i~B. ؍[J7 Zh2AhWuf|h4x;XCs9T\0 \ŧ!6ARI "A9]{?\㒶QnT&R/ܚ@]~-Z,!KpBB)!> stream xڵueX\۲-!6ݥqqww  %.}}u5jԬYs.*2uFQ P redeb((LAl66&D**qg $a pZ]Bl,,Ti FZ̼@WS /G +/vqe43uy +-Dlce';#LŘrv`;) ǤP{m` hmjo [4:MuI5u:[bu7GG")UҐҚ~5Jo7?ኒ*`]lWmo)-ՑÃŕ lhW}6. 7[;]')s 'H 7ʷ7 {k럜\6u+VAEE`jrLAon.lo_n4r.~[)z6\l\\]XTgl@Ed$5Ĩ~/?D%<,\V^ېJ,oU i[\^g@`[ڀ,,t͑Yd7?6++t=ͭ5-̬omq;,M]~6;w?"+7m _eA`JҽR 0 `DdV s_ZRnJ@n:{hKvv0/Ehbjnwg% Y9Xعf4+}l\ao<7qoin88oOf1eyM3;I6 +' m 89>omkbL [` vF\f?7Y`0k rMXYXYo9$xYriޚo[~? yozߒ:\qxw'=+ۛ?j<fonʟSϝVwum,ghlvXogT-&ax#/mIl~kq~6 4G\6hV/Y4S KtR##5I'QM.j ̦.+Ju>bۿ|oOP1W'Db V\JNw$Ic.K8og},+EABXV,g{Let..H{>ѕ&p{TYc >b#} mҫK# /Xǹkĉq<ڼ78-`2q=٫Iі}~a7j, R&FxC69_NrXj/MDc|ffFX ǓѪwSXKZ/4E`mzi'.RoW^4msa@ Â~F֏.Lǥ6`AC5q* !%ﱽ-EE8Z_|ԅRU Aq1ى?koJ }Q`7*h\P}Ob 4SEԴxM8 }G9{0ZM95A9n:ey \; 38{ b×Zbo톄mX j5U5ڭآU(FPn Q+W/}\5ᘺ[z~,ȭgw_S۶A~8C+;*V'÷:ݞ频:;k[G_;y_3Aӄb#yk= J.c]tt!{q\gꔺ.zV&PQ/B7!Kۄ(6aQ1(%B1o5,!,9 OpC;'Mn}PN>-wOȅ!J(x:_|VO˞ H ;i} jN="e|)z%k-:.FkD/sS$inpRdABrk"v%`TlSƤph }.8OjKl xc;t}B 90_}z(E} ҵӳy%sԝD.אC)Ӎm,V9$gMWun00 nWX *>' P; Fn|1)/ (/cjm-CL e#I5S.f̣+(Uf2"UHnV76zfj==tZf1O/A^j?d}ظOs\KY$$R9ůgIc` ﺙ",y˻O:CiԘ-ʭ 8 {xtTNBeR1|{T(Ul"r,)}BBaF3k 5VjG9FUD9*>C>tާdB$b,ֹ#Pn9w\tB5HۦAh%]\{+,8'D(pcCy}D@/T\.yR)U;:=:hn;LhfGHX Fm1M!ഗ)xb,v-B <8e :{z~tXK''VP!&[=̻ȷa%>; jZu>Tvj;A+ 腥SI\>ymєNL<2hGtW#FyKd_ȩ%ӔNӔ+pgNs^ h㭣m׃/3Ld44|aFHl=f?Dvcg>6[^>.E}ĮEC,.GG! @xnq|.k2B6Ur%ͽIiV#߾1-S vSLsiW=F*.5`zl !KUB^8֑F JG$]Ȍh F^$Gn6dB;[^'"#f0WW+9Gx-;,!/h7Q)k{-[Hwx~Im͑\ȇF07UgbYYJj 6~fOD^|~ 0(m{ti]ͱKl&θbE0'ƯȕFc6ÝP,4} y.7w[XT1OB:u&g=Kһ U6ڥbC \ligmT𿖲/r(%o B5)Jɐ tƉ:^y6 ;cH^YF7菰WRMUIĕvF M8}Qw>jlq#UqeeV>{,sI$;x>3Z*8Z6a?Μ5Q,~{7_ewỘZba'ᰑJ'=êыAN$=* s^:g 6 ]ftlQťO14*ʯg_(OcV ^nPܠXΩӷ%`ߧ bGw꾅đP+z4lpӼ^n,*;-v沄2)rn8t}eM(O*õ^ޫ @(w U:~dWB_hkh˻._ fc3ND(^.N&Gք֭np'1<8pOi8C2݌dyy_ Ki;. i('R^fXUiSԽ2N(͎Fjv?LZÒ"ܲgrR*tG <ǂ- %^05՟նɳ~/1\;AMiȉ$,z%~7XKנd *KGNT<AΰWbfUۺU$mܹ:X3GAiWZ`Or2/${6,:zf ]L{9+}7F-Hy'{3F)Q?(wMw˳XqNd #}kUsAF~c* ʥYx˂cf2U Su{TWӞ˗m3*̈́v Aq j ߥP  /NK8hO%ekCJN3k6"1|G͌ͥ'%:> Z_**3 Ne]C7-q/xMV1I޳u\mXl$ jI&C|=GͥPJPF}qdho9p iYwnw>k3=-+ݵ>T vl"Y2F9vͤM-bv[lWyPUs`THq`y1d `b—;qF_+6^˦nάNܱeTz} KRSAg-+ptb(ZI&V^, Pb_G}+uЭCy _םƲ1`̟Wp;r$DS'I|LC[,[iX=9ΟGԨl\ؗfεSx)`cDu~ .%N3y͵cC2Q D\Gm}=𘳴*ӟ:([,ݡnZ/oimH9'?16| q]0WY) S.p58;l#Ho%g(63ÂX$aFܫ˓^UhXf#2 /PeP)?+;UqD 0wFqoVG 9TD6Ǐg?b ;aB0-^t 0(/ zV`5% W|Zj6Nc\tzcջuݭ##?,;I{OOp6?D|/GwʤƉ*<Zݫb5԰J].!+eHyFhO$37^;|p5L0P{[;^Dh\_YxAdX6ZI?c0:Z0*CJ+a{钴fw-;HnMtvK<`jGQnYjW"ASM+փg\wL$~.-f!Reoi3o# Iyj8ůi\PX̬aP"?6K4ՎI,=Yy(XP3oJIBPo=Nwۦ *TY(+2{u>dO27rC+5;[Wo6lKj|ُZGd8Tw=4۸Pl^W"8H`1É 3 Ze[QaK$d/*G2}G-5)n.efTI f><5d.yGɓU ?:CrbQWQ]8Y73+;B !KslFH"k&s|rJTB\II}VksϴAüFv;f GijcyE;.o޹Md`7[E~,\`ٶ0Aڎs#+Ny;2nx ަ3-2F-c5gyס=vZzǴ#\xe+JnIT9['۝HxA_v0A@RY9!6~JR4<+< ,phUf#w+Do|D͖>8j?_?J_/) ֹz,-jEQmmh1xU&g[y]W iorTmk#PKn$r78Vq:DJIѬGUFG}fWe}7=yǒ֭-CqX/\Au*16zS3AeF(q-HyTD^m]$gި,-GAjke.ˉ!iK(dAQiPvlY5u9?~dy1+HށS*3r?.ZuOfTgKܝOJiZ^%& 7,&_ :K},+궉 JΣHvrte(9+͈پ ܮӜ|TӀ_|IDOw)LY/%ulFGfaT+NrOcN@(kLr,Li$qXh6;<߆Nr,/ڼf1_,)_ *{7MRw/Actډ1U' r0և9gÐk]uQOOBnS`exLOL jMuf=vLNt4j*Mޛ@C%ix 3S% x Lհ(W-U승y{,=y1IM'g.N-Q4S)"p.| Z b)s ~rT56YVI#l^nB5\@uR HWq]RUV yO%6$k.@V@@%%rP#gw l_t2{eMׅN.>|/Vٯ8Sր6YnB\4璼 'ya=7J%ˬ&ڠ4E{ oD]qIpOc:5x%=%PIL>nk7'lz3B!sXaCC;pOZ %F+y?fFI=]2h@)g4'4b,8@ϝi6c![|9q_2 [REGXPc ȴhW-8NX(~C$Ec$ѱ,ɯC8]; ?vJI,A5utl9H&I1De_.rm&z;5Ic3] mNÚ0^ֈlٞCÈ,JhZƯ!fľID@j2낎lmNմ/UtleQa]^/>}Jθ6{L3Tyw'<}P c-'݊+^DA߸Yjɑ<ͳ&WbM:0MaWR+||Db[|W|ϵB<i;!n?\JHm:`y]&D~b]ٖٓbu3MZ8B&o:fNyjTU4S3K}ok1(u;ȩYaQt)V"M$(٦D J6Q`QcL1mtEB~~6jƊbv4 B$'AKx-aBv /c[͖IdJ^ M}X"G0AjȢixI tXmPlARc gaR7Y:LާkѰ;_~_v.ѱFzʍ-Z-+:L]T # 6%>,b?nÛ",\ }9f xZ3 vx9b:Wc*ӊιsa~Ft7F~ T-҆AhǺ)O/m"ReUx&0,YB4v"?MTNhNsA} xDiXjل'BT=?QWl%d>Gq^֪;^@tONU%m';XX72sПrcl?ex(\~Poj5{r|RWtr-6Ad#_t8Q]݄s'&cn#Ȕ<TMn˝ZGiZbX"d%FpRwS;IW:R?'D-7 .iCO'p1Ф\ m~k5fbKE0~*"2=lUwjQ950x.r,i!v@q4'S S1!ԇJ;e&iОN*U[Qoߟ WprŐ=ڝbT4ڟ_Јl\CJܠ B9& 7Xʧig$Pqg[7 e\Yfvda2\S_5eפ+MĂwY=a]Qވ%EOHWşѸҾPGz$ 5ȹ% ԻPTnӱ?BGtxF]wx/ԅrLAP&V&XT4`c#XtqXb nunva&PW 2<9iF{:4E.(J X Sgی{%J (aHZ1a>X[t !ցҳ<D.kڣ{t.̙ݾnsB u%dvyVn |{z]4ҍ%VSW,gKj!Rf[ϙ?/Cgm~٩*Q|-YЕ9i3qZ5 EjE2p$J-&H2+qH+0C*Vh(/._'& 3;Xm m+x!%3q;]` k up&{oL9R%(:@|6|p3aE.dԻX< wu;Кy?~d 4%REpʖZSSS|+E|g5\cGtkw)ކ.ŵ2Ae#5 ^U>sEjy}<&ujfUvr'X)5Wȹ8lm5ː9^VZ+lƥYK[291úʋr}=Si ʂ(Ry7+bjh}]nGǀoۛCd`#t;͸E߁jʔh]2YjusO0e2ګm(0s[kH6U Dh vXkyܻq;^uQ)`|r$[}mhh /_J`hpn<综ŘbʒrA9\9*mQ"V/^w] zq%8\jC$k5U:X{}hC.bH΍ƉBY;.2R|Z]a݈&m}䳙[o;HJ3$V_?\x1-wqeZ.i묙 7F =S{T^=sLθ!'Quƴd`;q 4ITBya4!!(4{UoM΅Z9+TytWD0ɼ pn{px[.8Z-sa,P*jp6xm1pW=P2rb!nЉ_büjSubʃӫLN FQ~Q93J#gI)p`V fG~nCa`q0vqBY-!|) gEb:f-ί;zK`9C4r2"&ױM!vy1N}CwBV yi2x`Ds4wd-OsFtWF*{ &Zi >geaW_Z`'x Qav6ϹP?3BIJd֨0c "~tqA%L7qz>[?G j$Cr =x1Bw9t`O_M#AD;؈;^=-0 y=7{$.I}yjRl/2y{5n:)J8d _z̤3~$tIsF q>v$AE F&0l5!{:ߵuKmj0˴/Fh/gDsQf )Ҿ19afESo  ,MMUku3B>GJ9Eu0\5&bDô6cY͖J6c/2Z0O/_MvEaD/0@fֽ&!2#.&l|[bhayxak` ߉2Jv?tM Jb7]ؕωsbdxAِ;-A8PcouTe :z%Wcw!x:|Lc2Oxa~WиVٲ%vWeK$}]'ӏu)O\˶4sC))V, 5VfL=~V $vp`ȼ;A&QY5ܟZn)jQm _T/k$XX {ŅAv @e ]׆Mi}LXuel~QY]ʏh##S9 }HjN`h<TN eaD-gO՞4]/`zrqE4{ Y@YE8H4TPq'^d[{m[i) mƀ)=8V\I{z%14`r05'݌5Rn1D{Hܽԥhr &'_ juo4;)D1 TV.fG1{K{M$}Qh'I !K\=p #{]T{xD̨rHlJ׻r*բY%wp%"Sn[se?ڭJfBLNcwD?dk"Ì]0fiUjH!7; R$O|g= \S4/PÈtVKkF5y/-fM1Ρ]-eGhfo8,]5l H e-\]OAfWbI?<܂1ykSgo>fDх]!JUKY#tA1/0v(UT혆 ?CF|f'M1+V+O endstream endobj 139 0 obj << /Length1 1934 /Length2 23770 /Length3 0 /Length 24928 /Filter /FlateDecode >> stream xڴeT\[5 .;$w ZS;Kp!8/t7jTksF QPf15JڀXy262 fQ[+c+#33;dnk#nYYy(R@û` T,j#] 15Ҽڹ91D-60uq4er.Bs hf`e55J)%yUeNvvW=@\DNETH*TLr*?y Jh*H0Y tp4j| ]MlJ6x\\\MAvVէbfpu_Vq1:@fs##?T;A*ПV08/_ hc`cn299T(srpC*g颶+ӱ2p3qrt7l#[GsG?"&V?;3sd"r%%Ud[ΆAF+/?Dex\VN{{JZ[W>qw@nLЖ6.6ލTm흀]o)`@W#3??b?wv~G[7H{̀EvzJK`H(n~&%do\N%3 h ܳrl]A^ Dh "4ڐ6}&bqM) G$D>x_n_gcFeEy*g 6Ug>/Z5M$Sr(6R1 j;Lw)'-Јdxh[+C~.HgN ;-bvwXmvxmɘW:HUTI nuQ¡7R;D~,ɫyVYˑ-7m!5,.H1lFBkE?SAizZ/f0nJU`̯m1KVLr]zfOo]bzBo& w_6KB)6= Ҩ#:?T]n$m0=IqyW[9&yf𥉉Rm`X&#P$Z ˧T"ERV]hî}ū~~'&O!Ϙ|_a/q_8$>]663PݳdborbkkSWD"ϦjC |_uO + s53lth5%5㴬a]Bv ^m+#$sďWfd 1#X c3|Ő9]P.ZHW LUd P~kXuMWUq14QkKQYΖYQ;e;'z\b=d.S(ڈ!9 !/2 p" k/)*q٩a{&v˯ZۉwlObxa߇i-'aWt9Qr{yXtk]ۢ$op ni2{.(]d}4N: SXKp%v63[0[dhMpi' YOyf=O<7z Q'-`6Ə[ }F1نZ:E솞"~0OƝ%]Dn"1T٦۬& Hnlڃ( HDZ /O(;r~b|G!k]/þ܍TΣ!\aџB;bEʞoYuRg5P'8KFD ժma3E-B0z(x bkF&1TZ0OΤqYuy3?< a O'XD-7 DsD5to`: `j=5"6Lm@[Kمeg!Z,j6ę r k #*T*imwjCwFSڬdSDM "0BXO^V}y~7H >xsLbp{u`>e1tS|}[KU89`chO2Fm%qp[9bHALމAzN i4% QvcGRAo5?cY͇/O.fZsR1 @){q(TP q*4(dcH Aִ ~t%"7Ċ&cL9Y,=IKABDЭw?mr%.O=@Cf_Wt:,/5Ԅe>3)'U!,A2n֗rp^NY)^5(6Xh.p_ƪ\;`B5uΌN9*Y/|&da_3S ͰJ䱳G :{~ZtՇ,XfP%J,Q"VcZ#lȠ6('-U:edC{d!S܅_^!7Q屳SMxM@4$ŠvQjD LS}AU.WHz}2/~a2Rˇ^; qrMƍF:0GTؔsdZ (N#è'lW߮lWSŒ1!hQ[!aw&1 Bff$pϬM]$v!ߚ@Zu_@a?vi - ʃ0s ߄!*{'O 1ޖ,}'@U[. I.%?ӿk`6] /5QwN*$umlnF`y(fZޤ >s O0d3#mj ,={yK$Hu 4]#G|iy(a~x4&9eVT^Zy"9-E(zM">hS, LU6M+ ffwPa'rnQJ>{ā1> ,paX/}*jW2_ jUQtJˆ WË&4@}=A</&Q`TY>H˜uQC/I*SqrIX4m:NH\a:vȸibv*n+-7a1]de`|(JV0O]V#pK=183g1)O>a5-'X ׵2S ˰^CZГ'~jPn QAo #H:U42CLh U20ǹ6S-<+"yZ6U~Iua]#|gڠ-}I4_ Bσm^_FP bfP.( SgTlĭc6N1\AvgN"KAnmiMz\Z"|brOx:Gz~b]%"YX(|ԿnK(@Z͟܉8͔uٲ}AYGo|%`*@+Li. ]Vwf ŀ Ags>nlv>'':eС8WG`ǖM8^]S .>HZv.DƛuBw3fM>ph\׫hK7P<;X CeiaZ,쭩  =qbh@>,`$pN|rʚ o؅FWG_# Opj)Gs%{Rnvz1k6 !,t&|@ʸq\rxtK$}jp>k>*5FRQmmf]~XcVwC@r/& Q㶗Kl>ʏʅqk\YO;> 9l.e=v~"vw$oϡTY›*~fERؗ\aT T̗S)7TTzn>Ahxx㎪_|I$z]B*a.s/ȋ%ky /di!R>֟F)]H臨H|Б՞m$- |P`VG\wI/pdZjR S^|c>hjy {smҵޭ'кү9Ȑ8!;C?c䅥հC"YDuEyf:&O HcDUBz3.ո/?`h)::*:LIs$ى7!v rl֥>Qdvvbp80O6/ws3對5LaH@9ր5#d*@<@È,k8 #;o_BUtF;V9jH#ԆVԸ]\*ad1 frwǏ|de0ö4_ڞL_]~&GaR jG_X\ uWo*}lسwĖLybRbA!XW0)(G]rqP1kߔ=VwTX/eChGHm-MnZ@3pkQ#MTvp$ 66mp[O9ue^ ?xN'ٯG:q@%U DZ!3CjM&XdvZş׆Whn]qT"er 1mv[%x.CaIk9*_5x&jokgeS{dd_>F⡑ 8@fۖQ>b g+N ǹ1F{n3tK@?:Kd4B>~|7?T]&!)|ނ{%)mz餈\֧V䣡d iwCڂE*?We潲g8Rdܜ+ipIRW=(eD5!b>c֊a.MS]?QO\xͺEudG?.HjY~*lbݬ iL!~^agC6; n}092:3 $Vb]6$ 1h'Sa=R1}W۸Nʒ,d:v|7 톥7 Wowk*Oc )17H@Ӂ)/=j` ?rh9,rͮ! !]t LC> [.[™#_lΦGٓt_~iA51D,vҔ@A5j?gAXͪNpY8ꥶ>̞^`5mF4t!@e,\rS;xGB}.grxÕ\7+5![Fk=*kF]GNoTibUuinz6:B^_&V"AVqux{$g%2{\鏀pMtCz&i*~,qd>rH5-D>fAA6?n)''**}<|9Z"2Pesw>bVUWUv+HIM|ŭ\p6 z.9~ީ6po6fnXiN+q +TbQXB|k .:j ߚ9I1>˓ť6o`'OG!'nkn#x}Mcgqj< muoVy q2pn3:jKy-g·+VsTվP0z Ʒ 'Z "fRTɾ3yet0ho\jg/\Qҡ k'&1=sQbbbh>Mug|J' gC$QDtj 1%%rk54f[mmSIII#'{rNW Rg1(hV6{7CV!yax 9Ѩd>clIP u8Vqq5v45;}=ͮYqQ]!q4ʛ'4FR@l©0^çPWjse\22NcVSm6P-;ז丁_?fߚΞ/4 F} J?χVцSዦR͹hΓCV:]6hFѸMw0K)g?ݒ>h;;8$;@|J}V'YDȌE,?I5y[S$ZXշhb@Jz՟M'+nG6CaBQuVK.:veUv, *Ύ~W\;q`Tasm[1W*^sѷ7{4%EN\ѶI>$ G?Ο{PL bhë6e?dĄVBtXݞ_)xV|qHEa`d 0k{-)`w|ַĒՌiĦ$|RN tT!kČ l*l6-Mzc#Z]~;[Nuh&ez9>)^ꂤ5x64 ϛmqrcL鑛A#},$Lo᥺K#|XSz4컬y[SWf{jߋ _]hGKPؿeju9+qa0Wj)?MamPڝpT)A4/_ 惹|<6B_V-l:2L>8c BXK89)Dj7vUR g72vp*8g[`5o;7#-|AD|"v)? N  D?C6n ~i{WIP?:Y@-+tiG\&φΈ4w*nm7cB!W>4FYe9묃;Phzި1C2,n1;l!e-bN`DJ8( "qjkreXmȝ׵R~eg*[=ڐn:;27ƁXygl8Irqsû|tOҪ AgpmQ`b~;NGwtfGYcY[' J5ʧTTE17R'hꄾJa#?Fxt;JMY(%?Gzj.Q843C.*t64 3I- -Li^-8b~+V԰풓|Ta5=o+tK0#2L9[bpPÖ~tCë `D)9o_*kdJn*H7ְh)IQV2w>5=E5^PO[rVQ{3曵Q0 O g8;Tұ=EF^X[8L+ 7" Zt&qtb'$Wߣbroa 7-jI 1Hhz#N,CE駉Y46<mF"0-ݏ 'Jtv| zoZQ4$Yg< e-!SqڧEe৘9e_}ie˘"bm8w_Ϥ!A;9pH#{Ղ1|n(!t?\zVF(EaI {!KN_\d[{W֫mേC?fjL}vwUmvtmBI VEJOwCRWc#b0:hA3q qvn|1ctoՇF3C:hvP?88`f!f,W5=o'oW7,:e44wwoEiU%l(j0;\kq]\`wPa GMrM4,F\2j[!xSRB*~?HRȆS_[]!"_@ k8R>Xh'D-ԮMlL3I.a9yc[ B.RxHj-%8AClR%$ aЛa]1x(@ci㹹WjgǝYiސqNXM7nQ* C 3|G7!G2%]ln٣lv9EP$JÉI9/M能^{Dƚ<'s"4*^8k!OFg[ܗLfEuW 9pxDnJ#j7 Wg]A{iqz-َ4rJf`9;OfyÝc4匥_&1'Xy`ltNbk`1nQ>pt(Xґ%GdDL/hR2~bhi](7P,d?(TM%1ٚ*  wL jy蓃dlѕ6ѬIapOC;(+#Yzrɂ3!Dw;Ut|ETPJ"iY52-K)3:ק_WMLCPw9lƒ$_#U&F~ZB~/6ŃLUg9n 'vBu!=(ʖȀ?ʥ`KYUroqʄ FDN@L]]ڐUv|Ga ~_G3 :p(~Fz`6_A=laL-g}ܟrAPwZ+OWJRrEӋ[#! w/.Ȼy1 BE4i˳m{J:ֺ@HB|&VlꀆO8pZ^h]e 5.U31i ePl1/J A"M#xe[8n;2>׻%$0f0ᝉre#xcx;GP\pO2>Ɍ4"vDf'dsX>UjjԽv&mUNj +[4WuVD5v-3}Z6R,"wӁ.ki(97v'ELcd2[j(X.S('&]6l+mcTru'=G^Xܚpd 29( -փ2n.v*,d-XS>Chhk烂iDfBF{טJ~% Cb}t9x~~%J1-"E#q?kD2Jo3hy,W}𻠷8c!\[/hdE|iUI,7t <u,>9%(bcWpA!6bS?.-zkӯ uPY@z#mɺuK՗:96Bޔ-WU my9ƪpt-4 ~YbKMbSMBۜͳ"tyQ|*EAǐC5h,ɴHml0X@"st2 NfTgG'Cj(tCuo4Ѱ\{?P9c0uq73(S~>#31 ]3~Y%!)$F^oOc/!G7t)djpdFJ d]Fwf4![pĤIΚ?/MQ$'ø+mmY|c+U%0 =mQ.[1LsWYuգ$J᥺?:: 3l:3T`f+m+}AWJzq,AK Hs뫍tx3^q 4?Z +HLnYKjQnhY5:r?dĝpe.Q0xL&dȄVG֤){]RH :kFmb_\%} ^gh*&k 9leš~5]2i]0 OԩƵxtkm)xQXeshO6S:6$Gj>Љ<2ZmݤTv4_ֿJOպ~5!_&bԀRWQ{k30[3)I֥S~lP0‡XP٧I1fi<*?&ʀY׌&yE:w)Ht7?;=g {Lͪ@{BECPyizar-xq.z\&僰RY$Iq Ǫ 2?2g.zu^yM@l/i<0@_e4Eg% 05?|n!sR ! \)OUBvcD\&6Nӛxk%[_x8Q\lub:Qda_e+%!g xL!NƱD2twȒae\C(\M] zvs_ː~vn;ֶ(d}p$3п]Z.ņrdGY%{8 \SvO z̠NS6n\tI!';Mg1m6,N;8`co f7}UBK$·F$'-sDv [%/ f鳗X1[š5-&b@d18i~M}kTWy;6OHd{CQb[.jo7;aҼSVZ!㳁4Ǝ7YRP&ջo[jk!%[`7 /Ud ,ړf K(쯓h. Ţk>NbǞN'>5wWa xC>)*ޮ 3q}/Fw inF3 Y !EA1/k?f׽b??Y!\&띉G뿧\QwM)ŠWEwflIT:strZMCG:7 &Jyc~Q גJzUOpýI__`蠣U/ݔ}籗xxXPLN"U̘;liW&/~`=gBCv\'7qC(-?ɵDߡgoUt,gi *y2uX]W-% ڇEQa e0(m,qPkK:QbOhPS,"Iś7xR͒=*-(Co}J< 7@%|Ċ 5c1 ] 1Ѿd"~%6}* G$G~sPK s)&2 & ;@JaEp@jdW|E,狜]c!©:M<33'c{Zarw] ,Chc#ZCvQuk}AesɜMwiVaXFtܬ& o@N ?%>Y$*ݹ6)wrBfHyy$aJ-va$b.θpZ:fڪjjrrF P.ͤcc)} YkƬ5gL:Zhqj<ԣkߩq Ϋ{WHQu6s, D bf32RUNsT=̕ ;^ X)mѧTj=qp& Ih(L>?8ϭBr?[DIa5\7C:ty@< R}khC1Fxy'2 .v mYVX5n!GAtaϧt$!gjPJ><Ǘ\f>ޣ ;|:CpMf Kc֙+?[AU_ ]iTh]۔Ivm*zl {SFy9Z.PO~H,>"7䈆Miz1!6->z-,Tuzx ND>bi8饰#qx<"tVw7΂^PI`&ѣl>+-4w3Rց]*ftͺTRʗaNcnCDSja;L\4#3ݳH*C& ̪y> wEgՀ9)LHl+]?Ns #?9K <'_FC `r.6,-,;L|W?K+1}(Sv0@8L s/XS?1$q;Q4IRc3.Tg462X)l)~u!!!.K<5w!`D9_lNf.ɻ=>Ւ|^*)+ >XVs_SH/9,dž`f[k_ ʖ*{ #@m+jylrLql+&<<TR45O$w̎k0 \׎n!r E(%$PT Cdt'G]7Љ?EWھ!*0ddFq%m!$a$Ɇ:a`}$!c iGbu8LÄC "\]@ @%#\#2ՒB@j8dY/Xa wp Us|]mp'c{pw~([]kY ]DuImbok|nsp3//q(v:xi766m|Vj-jg\?da\ % x(ɁGؗS8Xu|O;5^ǍJ=ToJo;f.:e7/ѦmяrȔlhw"u}<9%Xlw>(̆bX_'zk 廩)AVTD׾'ZXCLY@k~OV%׽]6kf nqAXJdi:j4aٟtIG]l 0Jd0ɋrP3X/@jH2"WVX8IDRj?Mq ɫZ[;XbGwnf…wxb8!q]l}ڢ)L kf/9J,=e,;ð3fYH0FȬ J(@OeF_sYzkXj9rй`K}DH.m>W!!M=$%Lɓ*گwA[SXc>Lg%ٿv .ANe 6q;%feH§Miy5 C.Zց`J\6*Nbb>;8vV> N׵^C$Xe_cCO3i?Ȃ,nƐGp})}@ WIkcMh  {!1'ڹuoV+6<&-%b F66eٍh_h@C{W[߇&t"iF|Bejc}*JSl8yNzexvmhGN2EJ{B_mW(}bѣGs2'_t*G=PW OHiu|(8938溘TXui%~BkWs9gvI_)- ֽ{eeXضSb}lPEVDAOf7=Z!d4llL䵟H!e^L~~,ȬRRhsH i bqwW"4-4_yb]kyFPDbRf勛?̦yۢNe<AF5 n}N_Mq=E5nu(2sE7+D<b #aTI>6=fvAgPvV=?ȋCGZoab`)lnnԻ%MlSv\]'O{i__ y Ʀ;'}w~N#'+wlQأ`uv,ّp},կ1(t*ƣBnԑFEZftXj?:s'{wYtӳq6bHrt+]Щe;`S~cOAd 8j[_,(g0B L̮=;l>([7~d`Cw#C}7 E;)U݋5B=D^y!3sJ8FG7Hܵk88 {}`!s?>R8#d*1C7,y ޘ$bN`*d4ZC>hGOIGQv-тRmJ=!Ʃ]ZwRܽЈ}3?A_D:jü!u`IkJ~`PZ,k%wS3(g " pIE0p"Lr Z VVE/f=Ei$nW!CRceATYt6DD[Lft5:`6O{цmTaHQ<-v+^22gٸe[r7>uaIT,X-=haD9G$Bʽ3K_΄An/>囤K*%yAN9f.2O}i_$y5u:dc32'b  8*3pTu7A+0QC_Vd,jJtT|0MI p:h ͼ㇎,8i ʍ;H =-l[4r?D:2$=M @EBbFK9Da3%"N-'qER+M;nD%ъx6gqbEQf=g76#߄7JopQ o'dZE94u"(3 +-F61n_qFT/osGS%5A Ѩ% vo2 R$lUg|oW]#BE%Ktg, 8˞t6)ARF(:P,I(!3s<dKZ֕j)P^TE޲M#b.ACOYWqq'R^5L7TZݩ?iG Cd3ń8>b`f2*4{RpVlAgrƜ`6Ek'4%j`QXvԆ}zyS~Bř-DV5dق̪R%1Ђ] Uwd/pew`Vۨwʛz$[g?[4/K"U+3KyaQc}JiczWu)q 뭷!l)f˲$[tt$łC sXՏuA+4^u&yV)R*dGܗ)b5) (<0^9'yW&Pl>G0V7A%~u:+u)fdy/h\Y)3/aE2I=1,v"!ݦ][y[̺v T9*oA(q^f}S Z,uY t嶏Ʒ*^lä2JOLQ<~񫀍bбdn aO@fE^Ȟ7`>Wm~2U6}Ę?7 `py BccjF^ q.jG8jE%g mkB^_cnj:^>&ˁ#.Y siTw9Rv:…BgvSٟ3%+CSi[Fbt*2!S_%!Sq|:@y @n4cJCH\p]+~X'†uPݏZW&#Зu ȩrFaT9'#W JY"Âq.nPU"3O0˽)01h_Mی.UBqmٗ 4Z2^6ɂ^0ɑp4QuE7tab }qFj1&yݠ 0WsIr`!Ɲ(̴f"F ZP<)jkVCOAPQ>bvylĚ4ֽcm$GmCNT'[Gi丽־fI z`BR6$WXAI;3%L6 as>!<͖2+3u^MLnrȒR֣ED~'Is8Bź o0  Go?Kw} @bz{UMҡ()iV\jUy$&zC8w[-qLG7PE8$OfdOp6VAd" dUpb6pA$"6[:\Wfyڢ[BTv/r.pѷcw,78V{ĖE^81RNߍ\a\zgӡIZa/ 1jϞ.nef羕ҹAK7 S)*].n+:6ڌމud"NBEiDCA4M5|eXSiCFpPV!mXT! wzn{\.[Q5ht?P ۍ՗RO7?; 4#v΢rcį&f<]ڿ;Y5n1j++ #Hs J]MaV肄fc ۥ(ƣd^1'W[/ӡ(VGDz5W"J-'ڪ4"eH{rN D ,rR$IY Ks7ӈ6HBR֨7*ѿ9Ź9F5Sr_> StO|f)ge Gv:| @ϟgEdz u}J]b!ƚZ (@:(ʳ|B2%!|r^}JAHξEV[Ycy0ɭ5'6W/a/ H)':vINyh7^(}[0T}an-im SX>^#瀚ĭjkq#lT'#]!Kl8LX~9˜[/6np0LWun ywogЈ&iwτ~ fVF9V%e'@!„,櫊b8SkQ EHG2bw%N;{%cčjUj7˯a%`lҤgņ9ܙYU]Te)H @u+J g4*]?%0D R>#܄N_WʦJȢ%{BڶuTZOdahX ƔOAJp I&lX|/Cمo^Q*vQ܃&܁ ]}*'Ř_fy%lN> EzD(&qUۛrfKLQ p3mEk%΄}]hyu3rWXbh)w,8 h3+{[& I{G]ov="HC͵|N'H$[sN yj \Ͳ̽,ћXo\r$8{lգv"c^#[BZdstT88 ύջ}棘k+(Wb$^-ppnmP9 h#,(n3<z$ۤb۪^"濄~`z(pκo;w'4¤o),̘[|> stream xڴeT\ͺ5&@pݝ;6{ٻڙ~YŁ,KpM_Y,,9q{8/JvFw:Yl ;X5[׿8! _L/]Y+S7%+80?8l],.xU.Hpn}gSҀ/d+_,YNb6?W'U]@6@M+3_!c oXv (\e<R1bc}8}#_\u'>"-/LBӚ>NR0ВIYΜ ! dQxRK(Bm_7$WM])  i0e/%9+.ejKh#tt=İN¼L%+o[^<҂dc `iV\q2QAΘ CO]ZQwzE|;R6qP)AI&QnTn!6sG+[i#jChr&&"{Ub4Q`A=kR;=G6lzc5*])#y]9a>좿jq ]fYtE'jӨr$%Z?:876!qSgW@33>\վ`'T.BthjmNޟaC֜`mQ Rx;I:2bv;2@sG^9 ~YjW͎zmw }ЯqgTT[Zb+F 8^#Xscj&*~9c~Fn0z6LSӪHzDR} ɷ#џڮ5P)UxXxEDxg#˝)ĸ&3}vۥVئX_͜΃?YgԆp|y7Aipd&fo ~Bam13*$az "r2NPXj_i=}N >!FÜGfBĕd/j^S Jf"IfTıB\ ]`׽m{)VVMJ4x 3[ , mc:e q1 ,< ㉍a߳33A_ *H\},<91uiBjE G8oe(Hm$ g tzSم3qz-E@Necs쎞a-yɞ9)<<\F$χ67&', % δ$TNIQSOD.ǯd(zVa.vY)"5U>نGy `N_[~!`9kx<9C[ғ 7I±bH:9/Q3H*n%%ʹկ k!@oIBwFmh\LH7[F<0m y|t'BPG1lԛ[,del.РY]QJRe?6g>>_=veePmS}Z ̑Bxz8U 9|]]/ /pѣ>sa9r$(f ~~oYY|}V'Fذ$%r=–DŽ6>9IN#NaZWұmaF8^g*"HZCQ5#jy{pvy+f.CWP^7ջ Ǣ>Ɛ5r+"_QkY`YU2Ȼf-˭2?WԒaT:EXJT| h$vMĕBxq}+Ȅj!8Rq@fw[[ (ÒlOڴZ5Zg]B+n[W.evjBC,hH}e(Ѝr!n5Wl~)ea?vТ :LuQ.]3jK=?vrR1r+kU/#E˳^uC%Px?((PLŽpkV[Yo6 4 [,aRьoRO x /aDSڤl\)(P*"poFJRU\NJ.F7 R2#nt-ptkYT{8c}q ?c]z g *{ jȑ{%y=КWҸZT2/|tMc [?Ot|e0nTRB4ExX,=!A 8Ox9_є.RlIq'd+XYIor}!HdAEAzp_`Eh|:1*,\yk1 ]x_{(! >{XɑP47e dEcmnU}/N4=>~m(>n9n\e “`ecE_\d+hˤ)dr*pp_pL2$% 7YȊގeN'͏ zA9[rS N&B_2Z0yP(>"n.E_cE4&:(2k+ͮId Z(PKǴrV J.W3 O \vDߕr?4;ioVy!8DUPF__<4DH!aBJ /WXCJ!Ô\PqE PPdQ2*;p DuyYS?%>\uҥ]'bZ:j"`HW sM'1MW/BDό'Wn&J[yVG.H[l`--Tv rfI{E>b!ׁ/Ȓ*f1Tjƅ,HM D9I>}W=d4or|#Cc <ك%:Xm[>􆳡ReL7:'6PcVL4GV{؞ a5Jwſ5v @i+oqTWCggΣ«@DǒU\4/0M˦s:>=|&ȏw-+{'o}u䳘|"l:bAsTsR B b|ٳBȏqeލx(ҝꚔD'( ~;~B,)Ȭ6(mÿ0O 7xb߆ht'T^o׈*( >=p,ZI`+.6t"[+X.=ؖwQ[1&RϮ u Igاs5ov1DHGXb 譿C5n34N (8 ((+jTKtW{Zշ3?aO.(?ݝ_#)%]t܊,8"뉸9#5Qq g-EL 3%_粔^WK߆KwKiS>ϵuhi⾺/;/0ie7;Z '$8E# 6S_ZtjKrӻHvA#!?IWjwywFu I BBݤmpʭa>d1̺UMh6KLwxǟ<Ï\aW嬻q1|dq!>{;w-bhM@T0㣶t]9mYbC+]ej "'lǩ)=a?˛`0D`Z=d%QRy!xvS;3D'f>`x%(q?ӹra__;0Zm(*q@˭/M;] `L/r qrlaO.9\א=֜s~N1asZI+܎ >~/0pnj5J#,W\}j/pTpt_iW؉&%$ZТA%e5,utU{Gy](Bb4v6W膣*E/=c򧸶waxlD _Ғ/A3(},C's{#̞2Z2&Ex ~ņ:L&tQ@".G7O6u3z(HtZ_.Gmj7ďsFc6;- .WGc섛4c)LF^MX-G~17S} |nԱe_y\Xu=HF8:q {NFm9ŢZKsM R|؎ݍ ]z]yϙp]+UBD|cao?)b!/H>OxDT, <2g,Mxq^r!'ȷ֯Ƚ?4{m p*R!X+=LRG:^JfbA6#\[|$2nGʉ y'e"zLdcyQSO88m/<$x$ٿ4zԌ5cuZfI_MM'-|Lx_aTGu>tb%<[f!O~_UѴȁ$$:ʓvǩ (Աv+h'!`uGEg R%O@v{+*8Ad9~jVX6- I5s19C+!= w}h%[ԌⰌ̵tNO̸L* gÖ.eΘ!cV@nQzl/k_`i-W֗Jul'MaN-VzB=M[;O`p΃;\0# / HHI U#w;g d`dCrGv .Fs/f2گm_/,)k6c+wtu^ bڀ/Z.hqՓĮ 2(#Xͭ^z=Ѷg#1F/":pqLwz-{~H$EM#Fs7x͈J}ee] {G8#]p`M.= Ua5D*rqWY1-)gĖҎ:i>e*$ 9SGJQ!C694*$IG' CWĤ2ķ\PZMpy <#0&-_V!6!kaiZh*ӵ \:"uGӓCM9$ptJ) 6Hvת&p8v~*ޱ9k-#ZY`#}a(DD;_Npt-а gG9,Eǃ[Տ Sp#U6ʴY)-ƻ.v\̲RhLjRe: cyc*][Mt3t+%_ƽ^aCqmس;K^/|K4uwKH¯gHp1/0v,tJ\@Q9F>t宼vR3-F1rLS`<[|, }e~Bҝd+gW}ퟥa?&ln %#sDk&>Z}lpm>.2jDצYscD4%fӗޕҟd4% -QWCݳSAX)ZQ c8GVij :_^YHl)}Wz0Y֤TB6q;Ce!ݎWoc7?#Ԙ݄@KܐX6 r0i7Oͤ=dC嘮AK$UsĿ} !_8g\դ 7SFdp"jF0z%7NM#wwgSije |:ΈJXS|Y̗!T(tTFy^bAY9f1kkWì,j+uIn9 2*,(leכ^F~Hݲ~|хNjvL>[ IQ-5.,6f<cl>43D_ԕ;q6-ׇkQ 3vM'(HI>Wdףj7u.7$ٵ͂@$|e}[țT[6sz8oBY;?QI I=! 7 հ9Ho(E3>RJ߿̫.UV:XƎ "4ه]j4]N]@1 2\xO*S6`KMEGzڙ ˡadb-B$M.[sF+zo0> qUlzX|S‘cqNY[Zi=z+V)eh:%x?^l&cyIBq@}4(Hᴚk,;rV܆o` Y[ä3'ɱpU}HgP}3fndjo|7$kvYQy =}=\Z/d]deLǐ/xz[쩣jH9> r7uNb,ʟ"ftĿ h9{}!Y*;vu~PX7KjC߾#66Xywu ~;}X|&~KG^92?~.jPխe"HƨM~CUYÇw' 'J h ]M|ZEFK.0QEA#,YrivOMDmܼ bhGm& 0x?Stbz))a>wGBL"ȋ۪`b{+g O&[8 E_t~y֤vXOe@D]\W)|H LZCk!IR-;O:2Pt 'v(^Mq%Zf? aU2p*Ƹ햌8I CZX{;T[NM]S_ECdQA?{HrC%)©%^6bn ezI?[okn>(zU=8 -iIyLY 4ΐ74j.P$i%`LJ2|!o8tC`QT5gx}3j4CfC90B /+ 0>$*ͽU0ieux]tEKzCVIN8R﹛,q>mny2Jx#ǟX˔2Ҳ:_535t5$]jRy৙zeg]<A G.~eZXR1+*bj8d#H iSF*g3B"0aﳺ%RZv^Ew3c?KR`ٱ6z~ԕG3BK]@Q>~/^wNJΝtv/$jq0 Sn9ڏ{{L=NHL39جth-o"6Bhae2*%/{ͯlG *W"Sd> Ƈޥo"Oj'˚99;ܾ*&/_D*y~׽ T0-s9)fȳ4'/U\;BCtfѻMX7b^B]sƶ&$\M>nzrd%dDUd 0ϱT,"My _i2P E,Ù9Α$uY趄#E1$,>yvGºM;Rٹ¨ݵIuc$8ȼL<ga.i8b)Qaa:q4O/CuX0\9.:a>k׷9>u^;=i;ryքL|'rO '_@ֲß +D 8!4o7~JQ{eǨ*VϟwL>EX#|EB֍X]mHQ*S_y;s\[aA&W :B "'KdyKO1Sz]d9?M}A)޶y[;Oɳ{.jfnեuT6ß7ܰfW6 t+}Rb=s^pVrv3'xo̟a-g3r?'6 ]G'NToXCVuKǝCݒ6h'1f0g_>eJr,)檇)2Jk4`Z0D”#mc*: c"sjKZo"6v(X[̗N5>WU+̡ L;fjJcزQ\^kT[g/Mޣ@+3@IJG ;(bX*O.-z|U\a^@#uTfM 9b!ѽ6gbI,B`B˲3pnH5?N-7'3HY5ߺAIW].|EXDTDZRVulħ8U"#> toZ[}iLC ,* 0v<{dLφ, P-D[u1a8R0* QrA1l8atep(坄F7tC>T8| t2-҇cd%iyVq)$,_q\h),2tyϖ5|Q/(BJ8N MZRJ{5}>PV#+g5?gPqJ+*2>fr#۝]/H„0S&*w[ã\Z8mׁqz (wEtհ t~HýM S*" {F^jbiNUKw:$8Ŭ҇?bj,iZ4È2+?#Q~ ?KN8~be$~yIrYq囝) WF'2ᒇ譒[/0fX߰B|O: د4evoZWBb[תD W:Z$&^6182L]̤< `7_==aS9D SԶ['4S= ]0Dt}`MB꿛8`]/b粕1t˖U6nA a-7L}%92`C<-OM>V-u{7a2_<@K <1 CC]H]xb3D!hrQj`LLP+oq.j?NҌLUL$dr[g|(XH qثpF:ɭc씦()O [UJ@@fdk):/]g4AT,W ϬfulbcQ(ZۂDᓄHT@cgjHsrOd]HMnrsYج #) [V1j)՘\_ ZH|J%[?>/NI~NQޫsPzx ځ28z`Mu,!'|25O/I Uo&岝y; ~X;(ruhYxD[;;JD2\YO*[B[^47,,YW1 NjC 7~DCt}JIoeTr"YN&ﲂxZSj6@5CP.CyA7^_0v  R< '3)DL{X鯵b K}FōP+5^]DG?ZB1w+ˎSw䏦<| OL!߷E`0Rgnt63Y%Ci#M"7s\46Ni'Ъb:.b &xTEߙ,M>] AM,{ժ^ۆ!"񮎏_޲wt~8ֈZ%VLDt ], '`1S8/ݽ<-l# ~ "!p]#p [S5<(ʹm7&,޶w;%W)qB8n)m>|,@Mb\Lj.vC]u3cU|`K+3/BC8ZWN%>LMjZ;_dҙvfst%c&:̠FN4ªIo`\E`B'9RuoxrR%Zi$]!$7d~p s*8PyXE9<Ù;z%5I۽MrIV4|FS&QEe5D/x{ࢶ&tCX1Zbtɻ}jgVAM7,].*']i˨՝'F%=Kw#f-\ӫ|t@)eQpddfer^$9IVrC4xNuf64ˇ3 |ne;cO\1m)H&j\]iYz`k2j3:Q ?7gRsi^>gAz?|g4nRJqh߳<{/+ȄиPP[aׅVYj/ mon1>DܔblOUx+r5Xƒz'zS[f"t;V=XUhPSN6/?J{W.ЍwkETF(cܼ'Q&@MMx"%~@۹~܄PsTC}zxwߙm8{X[\6ހkxNi2azSJZ\IG:%o@%#"抪,Y H6Cu{jGEޱecqUF0\Vδ{ ہəSY\Mnm$'eG0,GAC[q)!RCB7ŹQ!iErQOx:;4=@p8,=}>i2~wE?*;ՆNrξY{dy@ @{YY bl-EP=qZkO# Pt:? M$գ+rZ=Ъ@gzl #b{Y:WE>-X13Ҏ 9Rɹ#lXa E8%'3=-XOb37pv#zv)yFx.o`_EZxOoa;ҷ K%Ǯ:W EEsq!HtԈ9]ZKVܞi6R[6 v՗v+9Mv0N%Ú`:H!>ǂ qḔJ 63ŦgI']5k. YY:?WRm 1)?P>Bx%g%&/VgQec6'jOw^|J=W6o!M[},p@!ICJq$lG7s6U~ (y[a.NI~6P2A&p@$uq/V]򩩐-8{!N™1%!Zѱ \7c- ՞?*^y+T2 <_5ɲ fbֲGt@97G2 ?dVIRei -\cZYn4W*5͓pf-}uf jOc&&+BINنl-' F]r[(:/H-Y7!^Kc.js6+{iD=-HrzerðJ=t, L>>)WblP:CNp"C]Nu6 uB&"UEɠוx`h>l̉ V7͢'!}[Š>m>J4,(n;PٛHiN1`vWs tn#kk2&]޿h?| bzԭw3e['BV!9L9}kf.!4NsAHoe5iñ Cdi<9U޺mSPց>9͠lq_VQW`|@K<<Zq|ko`]5c21lEd(V:oK&ܪ%A<8G.gjt_!@&Ԁ8X%Qxm0ED]!2D:$-ʮM+|L瓦.}yp'|A4 {#RQl2V a⤸CQ!fXb Ӂgp C` {h5L=ow VKa6}?u#YB&Tl [(lP.7<5!vșɩTˣ%^3A82)(C;\81TFX,.q6c;3C3e?RdтѐM>h+ckZ$܎iH(á\Ja,[fIu?? {.?)Se3,q2Pa[!_EC %c}]|J4x[[r*0yX$sАfߥ$T-f Cqi|lc0&W#@,*EqV#ElT[LjгWX7_tF!{~yMe~㒔IAf6}rJ.-QYF@ ~}||ƍUxS4/)1en(tO"M2BR}9ǀd<tzɄg(n bY mȜ.57^AeE zi֖sT_h-dLlli?u0掳-QOSvQ IͦBw?rfݰG(8F@4\|IIj3G bcUBQZ^:GyINh=ճeIfMT7o 2[l+ypэ°A,Uhf;:9L(Au}5F]˪p0βH"~6ӎ*{ 7%+Ro3;Œ{Z60ŬW ZuurBGZ5VPnl'WWeСhL)о@"̓9 -du9ߞ UB,1T,)c[z?II@ 1ubDl@+Q#](+9hjn9΀A$䓗8ksܖkTtɪ7֗%nY :WGxFݽʅA/-H01~ޙXNʃBL z*h>]&ͺN(-t=;&&csd_/1|kS$dQ+w`h)!nw¶PviJc+4I &鵉(r)y۫Ƕuݑin]q"3~zb ! Ezlk>;YRHpC@ LefRacTmlJyDꯪIqMf.ctmAjx\T-G6H mF/=0>W)tafdҢtsj WZqu2y ]/݃[sBQ H>zEng5v@; WS&HAv><;5vz#2/2Ḥ(64+ vZ=X7.'3ni4IWV\E ì(_JHmJq['M% ol'0Jr<ڵ}`-+ ST%mK܄!{6X;B%w<~ :BIh7) 0IMDZ.4w,|Aa M+8./2;y@utqP`%yE[u(̄[f]yys(5ZڿnѯDDr)JZ<0h:Q5VSYƒ Iՠo4#5b`&{(Sx<{mϩ8 -5Up>?)g)at;Fyr>&;wD"HRz1q^LaDwc(XAh qDwA/!n>Qq?S2Tvo(3JZ =%7YQЦYr3u;']I|Ѹ t9! CѸYG@ BK*vy hw۫<оwTűQ%BdPDvw/ y:B gK}FKt@RqZA%ll;[xya 2L<]!#X9}Im=|槾J#ʉ }+dzyO5S 2d6rl4U<.BJћIRZOE~!o0ktUqRCabãKw,P)oˆmTsJrm 8HcDH:2j:J:*C59yU߷dodD dΛZ'nB)/:Wo:ƨ9pE{0mVw/vЧǟVzῒ8(@K~`O3Gއ冿'C"֕,e8y@]֌O ytD ٖW=dMs:L絋z rO~ٟO[~=rk&_X;KΖ+:Qd תX7z'^v$˹>B^ wUGP)za Ƣ[qI]4>stВffY9/]^}]h/`[&vAlvx0YfiO*xWe6"IGa芓NluzG3٢"jT*|T7wN bZ*-?!˔Q%x ˊ  NIމ|Fꚮ˜k&Isx3>Lڴ8gxO u,LjƊ_>[i 7ɪltHa5#Q7PZr )$Zn4ERgyS,QQ'{V{Bn]'5%رgҠMLh$. R}m *P<ʲXqO=qͥ#r.t~1&x\V۹,z8J,T=},a$n5t3Ew^ 9 ϑ/Nf$ep}G׉Pj ڡ3Yp~Iɣ-рļ*#:1ګ3G<YRQ*X<>{ 29Uo}Yl$QzQOYUEEݨ^]$Gt[B,, ]W csT5Vph>a`˕~R`_8D= ~,(9QJpDVu^{KnOhg[ZS%(1.OpyZJ碉~i@i%PrSUh`ʭ30@9qJF(C933[+=FFlph)'Cn"őADrk@EOțȜ*¥Wخl6 "YUS }?Qϻt]߷llZAylH8,@ԃB ;\p҇\ %sX;ԏwO&.؋YfZ3.E} oOÝBi:l1  bx4K*anʻ_:''Dn]l0盎ZAJ hPguq*Q=YOvBQbW2UFR7oJLz{`cH+(!Eͭe |ThM"kdҊ7ߔqcpbvB͝;6+ 4Wzji-5v?*!4hJ996joHd[!_9\ =sbv%@j?'h@?bDb}~WU!1JݚM_@w ; 4Pf¥1HVve}#22|?N)p&̜ # !._( z)N|KxŧTJT@y_.]+lk1X88HhVLIk , =̒"޲8) G8w1'v+ ." 3rWO_HF8k*5%*ѽD:Hm wA*3}*gjKg+K$Ia%A!p:8IZYQrJ3 T)؉ *#Ҷ{]>l?-8Hbt'ݓ憨ş󞁱H&x뱨>1 }42o,O߬Hm(C#1Ӈ28;EhOݨ1*ſ`nr>3 J/[$ l k!8yi__*ZAkߗ8B\xC1S%I=_e{siOdU?, Κ l< w\GT.LkH9B5ƅSd=ys ? ?qJT#yB*%6j %!|O]kɨè7 YnhP]ݠ=A7 U\rHwQXIDHJb8 C$/yIkHʥjցzÂd ܛ12qREjRb})b|Yzw.eI"@UWdpzx7UQ$te.u$KeΘɫtiJw?B3~3QqNZa'Bxf0\6dU?a2-ϭ$sN\} >cF-PfcfikR %J0t>B; K[s]Yageyn "YϱrAD#d &/9+ZYzfC~-\u0LpS*/:5f7 UtJNBNe:W9[F,Xz:?*KXb.Ȟ2t^&da"Т +W>Q1PE7*6zQ+_?h][䝟9TmHl5~}j;-I!pga+JHVR"N2kOw2<2;~a\fwˮc O|M#b0(&VvMR]W9أA>pҨӖ~]j*5H鑽]I1rûYc7UM?E?з?e0?Wx>\A8<.w"=3zw,uENgK{ϞΪp4d ruVSi3 XΛq**l,LYp6jzί4dž?b\{T4\m[a?Z}oJqFܭ <ZaVF)&cov]%=-♧ݍ˰DQ[mηHOIG2chЪp5>@8O+.D[wF-0>0aℹ<+`cut^/&4jTTayO@1"ۂܪ~+A gKaw+I63ka%G @:&&E։3u#;EjDqC,CKōEh@][JG^:y|_YJ5~~hKCZ&RI6î9۝(-?؂:AKd'è5ݭ3iI+Ÿ R?L0=45hD˻uPX1ɸRp'K/ 1@HkyD eq6CjTf_d.K1oY|%vmLې\ E^ݩm)~uM/ 0lK'V*C cqЋ0r&t.06|0U/Tf]P)TY'P&//p87M[\w熦Ed = VpUEolgFB_dlZK9}VkjD"5Zɖ2@61(B(Ϲ&:sLmP>s쯟ףM2]DonSw-pX9-^ꋈޛ?؉z gP+ё,#-8@x>oX~^;xC a.;T P?6X9kO,X[V&hTJb򖂈F`x 9F!Ȓx $la6`ioh!##3nBdҰ x^K<,bD@bx͉2l ܶBV7X*Smj%P.iviee}@t͂ep\[{[z?9D5YzzO*B@O:?*%ZTت k>xjF`8i^c²1f-5i n/[3fadssc_a[x/&U;pXjYnM˜ !uI#( ?C Z}Y0`~fd$YRhP`=uk ~VW@%Bnm??9@AH3S!OXNA:E|Ԅ^v]3PL:{*/Z'<[Vov89iQ+>! `J  7ip endstream endobj 143 0 obj << /Length1 2541 /Length2 19632 /Length3 0 /Length 21124 /Filter /FlateDecode >> stream xڴeT[SHwwww-NݭK)EKq+š87=߽ ̹Z QVc1%Av ,̼yA̎HA!4rى9y\%g# :cH6(j"p4pwޢY#k% ˨PjhadcԁZ 5 U5 #8=kHE%@Mzwu9=@Ql]AB]D][Yw +wF fC j'͍ٞəhho?u K'ti)^ IJXbF8i9 ?i,WVY9LF.N@S b.s(?i(\_e,YwfvDe$%gǠwǎD `ee0TT dk f}>9={@nv^/ロ3iY:e,B#3:@Ăwf巘/{= ci z9Ύ.@!pL-Mc*D3xmJޣ ;) I vtQ4RWGoԊ G[#Y:IZM-M,i3ؙ ,lj4~(肏ߧX_:TX<^m& `RUJdjig`9:y 2jS?`b9].>3#0Lb7I0Iqd N(A(JA&?\Π 0k?ΠA`.?X0YL?\l2`.o5/_L!p@,2˿ : Y vlv.ƿ_)Yu.|͜HYG` @r#wpxXp1NAp?98t- /05?=drvp]޸ApV oG:ʿoy?<"՜AǣL-ug4 X~'ş/oQQ; =np\M7%t .-L>JNUR0Ta j&,eLumgRy}SJ(l^['MU*Hj2jf*,Wthd%4Ǝx:cX'^/SI*Va݊XZ0m޹/u/NuB:cE,~,FӡK+P:DvM$lG`-)jt*lZ͙J=}R^)sLI7 ; gиsOv}$: vveYhױFnT=>ޫyGYqkhiHct4ͥa#e |Z(b=VN[{,,(&AG^Mו#*knͻbZ\jBNGXw.Tw'/3ܐU~If춧d̮ȧ(t,FM[H"kfs&t$TuxLgjJ]I WO篔7BF<7](tB#=P~~"ulU=BbF%zT*j߼^q_ޔۘEB4=r΄9_,wd (|Dd9Es~#6HFtfx31G*jJ4:hHTgb_5\Y?ElmlJyܳtI ɻI[?r s{zpA^"9|c|6 5؀Y EԬ2x'1YٓmS,DJ^VDJ["oSd%{)LoD,,Ҵ#Tc%If&v[\4ح`o0k3)*K R(S-'.n|~V҂7du&bW4 VOL\L\) OǤmv u]vOtLI)UG}c`-|8~*1;My5X$'h*h$~~Hue/ȫpH[r[2 < &؀c!Vڢ-A_sw_)uʹ"׊w~%C  i";?ŕX\\>!#ejWhep^vi$kxWs>i\_s4jS/,>,@J^=Q6Gt_;/>n}2d[sĮʋ_Z{I( )ӹRqcv%H0ES.@A]Dʹ`QXGXƛ!mM ʸ!!,&wk1L`\9Q4, OЀLF V2sW T={MiAw#JD7uf_%R&aט.vrlJ_%,Ow[Oj FCI3ROhLWZIQh3QGvj}eӇR_c!| (hCr-ᘮBFAzMAԶsmFEf 'v{먅zJ8tHC.?I~X+w]7aM' z^ 8qD~YN[|[SK1}5ӆObLH̆A}狉1i.7{ELj-A\ T)CH$] U'Z0<-bWH)ƃ1YKhU^F*t)r%~k ~ut/_R3߿0%a?__xؒqɭEՒ̴YU#|1N ieמՔBOnf,Ba!2O>L`(CG^S܈Ln)g# Ƕyz7b,0R]WǞthe 0mA&C韌G1sg֭/j<|:<"۩&EO!29Nxr+|'U%Jͯ+0+{ȟ uvTYX3ɂ֙0N\b/1_sα Ʀ lFc-8誷U蠝=6V&O՜pRpKXWds` uԹR: YR5 K9?/i\?zm|kK21=6(7sht異OiX84x,^›j?tYMm "a}&+dӉ#Ӻn-SR`;_ 8洵@Rs|\B%vk.}|?9t9oLOPuB1)52_]:B/q=R9j"n ZNLo}9E'ܴZԴiw8b@Ma8 Oď|n PfMtLUrgr1jĹᦹdhg/zxR XWv~#urfaN/K^u:YA'pm,)nnD&y{r'ׅO\4O/j a }Ĥ5%PmE4v4X/1.I_c7j D%g/?Gɩ4P s_n`\L qd N '̥U*ar9IY^Us;k7J?2բ0`wxēS 〈S>dx!ֳUJfLvB i3",p4&ZJ.$L ]XF$B,ϤiƮjK50mW4N+b̐Zqn=U.)fv(+"8qϚ/4nðqp#~c-c⑛D6+)] 1XZSq\)'lGG.4s쎘~S Q9½{0[Rl Jd } aYR8d?F>}>XheHwkĩ,1#kѠ}'dRdGWWdb%bb1Y%+ UKbf>5%6V~b!yK&ksṛLg e>Ȼ5JGh,\FG MBB*cDW -o<[^2BOܣ+T fFR\/kh?PٳTYhG tә-k u ?{ UNGԁBou]]H2%QI*Ww P.7I\Yn+WEͿ%ڿc 6U+__ED{j41l rX&nP*J"\i1T8ÒX7BӦ |D2Jo!GH (sT&Ήv.O1(@A[!K+=cOQɄV<֤>R}b#%hv ?E>R}WAlƦRLgȯ<>tn$CeS\k\=*\p࿋whK*oͬ]=o q\Yvd_U~:7< *PZXvD1wC^Si&*Z8sٶp ש&};I^ﯥ}I )eMs|c~ ˷JGHx4s `ũ{d8̜lrVO!#?[ALFneQ.6n{fy%b/Q!im͊GBf{y۷CԢbMoߥ}}^,B$V&n) >^8[ qKX0+zc9B1^~5f]?=z| 1] [9quCSa)WӦlR>{3\&# %nmܙן d@Wa+I3ѳDR}Coqq.IDh V)X4 5mi{u,EÿBMYQ3/[K|]*٠\ %:IdrCk73^C-($bTt@O-z T:e7>֞jZ$/]K0VDh7Γ&w^r{|@H7n:ӣ^DNT?ՄsZ:?/j!u$^-ubLFStR-: #+G Y v^F:1Ѿ0R#f A%>dJ"AUT bdDE3SGj:$ZO> r; }yL%{>$ Gʟ #MDjH|!-Ujާ:fvqR8^Y߹WFXA,|IT&̲)h]s3B_t{ȁ,Lc~P)=I:H7[_6Zz|gV0@m!BM")b[xA mFzmety0))yc23`d2!=9'S[O?iQ.gS+-_K b~>6prWz'D*-CG#S*=mo8rO5:;E{uCqsw3jg x{߆γl[d,L*^}P#!j#K.niFW0 T61B3> uH$/܎w{Iiq>mBuR=7㆑7D2K4ǧ'sP9 4cwr?qy$p1iXhHE_/&e,xL+cRx4w|E{|]egwx':`uEE-xQ}ЧP*fdһ>h.WJ3ɕ_U"Ǿ ?|ǁt!ob(WH=?sbt;A-U-gAҫ qѰ @h+w\& z6~x#3 X5:ζݩWiLra<]˦KΨNh%)n垾Za*~6*\HưE>mGȡlb_DgF2bHX (YнRvx؞J;w~q+(mB01}A=0Lycȱ"OGTj}:UgWZRSiˮ~ pp_Syokre[/e;v˗P$Ϻ׻|,x 0'ZsE&ȩ S1>0Xc}znXMOm {"I-yiyļJ:w<1os{͜Z,_2}o&jv9[eak&TjK;'u2QiwCʌ_[E/'!l/̉Rz:OnFoz_&ySH\jAcU~ oztnOk- O"ɐfͯEϘ3r(lGj0,iܥBBjKh3K;\iHdXY`W(TD^oM0ڵ؁9k[m1K GL}"@wiE1붇|r=?萹B8ѵg =|[x_$vvnL飼k@Im$el(?qE, !I J &D/XSN(>c"naFnMс_"Z݇VA.ǧO,Uz:w^H/Eq񓠈BK[*K eR+A/Vl8I)SxCV&pVf}j~0dw  iUڌvѽbzACo}":%/ߌ;|gP5]q 2^[*YdíaD8Ou #'{nv@&Nq&AdUNGQR#mxN!mRgRTNU /rkTpQIFyA)DytBf3ݻ2rhf;t #:E n./=,Au&o3 {y3>O\[]CO}}wj'A{vvu3Ԋ SA;ɼǯwoj(L u9ʻ X#L M[*KC}aQ.Js.^1ip(hiΦ9_^" סM8=NQg~kҧ,ivԕ@t` T9@7ɛDnW eL׿,7gSd jsƒc@>л|c,˖861?LŜrud"!ARgYbzx ЌSQDEHT}6FpTl>rR54zŨ-o/mD:a򣏪e̖uSE,Ql!Qx7TJYef@F&A=Koze"P܆RB聙q0Bߍ|2 '8Zp,\WUtc(O"'A_k -zHCĻzk_i>o%`"unDA0#Rj+im6~D b?pWvNQ8@WS8i/*z=,O;# Qׄur@&'n6LU\!O}#E1e(+wߎ]&J<[֯ -f0XnHmt25s/^mLRٌ,*2Du7ɓPHޅɱ^lp9ݎft|)$xx=}9NJk/GPw۴L)eb( i&ƒ%I*Ugo\ld@ncy ?9zfL:_DySa,D#!]E2:3`dNC%}e(†%XU_X ~6>F`46+l&H{0ő90t"a/}WA7,Ĕ1nv_,qG)˾hw~VRc|g p割O'z1Skn/ EO8dt2B+SްGP__Z͓fNJʁRi-=fNbjEN1kP E">PϥN:)=LFHՑm&9hN]qG$7B4e9)U~+b4{n bٳݫN$&ʣ M2wl[%HZx Ba, X]JK \+Ƈ\{O<ڏ:U"HSH8dj,SF&\uO9@DC%$C( vwT'Ch:˄r!tֱ۠Q/ c7f](LuBݵݒ~zCՙ*#ݿM-1lF эMqe|y_R{/vl"cZQ t6Ov؅`A{}ʁC7u^CvGpoWeX IF~jzoA˜#ŧ3Sg irV:dG.grkp?[W X|C}|{hϝ-MyQ,R}Wgj%rrZGU?Wp|H#cQ|X-ʘ{@_Y.BHRsqu5b.$WFдn[a'*NPRas}pӌ 90?m'I$'GXj6AFLC732 Y,Ӑ@fop˦B#Ս>ټ!@ڿbu],3vvo&x0h)1Baܑ 8ʭ팊ضۑ)Ua0GhϔDtoM&$q^p|ܝR:H!O!K"E 5~ i!H>[D*#8 CH5!:,N,0"m qƕS0q pMdx0͔.t0grV=8˄ NtIQ|:Qů}PP 5oe҃{dEp!f5beWUHێRݟf_d~%\А}ŝeEP(#㐚1|ԋIK0ף7,<%&imWM.ݸPN&b_N(dnf"o)ϔ*~X)閭<كViUuߟ14Xja~-[8V\JӀ $:;u**>YjPم82iw fvH9NomdTRJ; ϛy{@Bo~Cdɰ`lQ!)w~KMR:_Dz<CkC خTYW}&u+NfiWˎtƷ􂷺c'>IТ(dԌ&NFaV :>ZEjaFie`@(E#FѴwo`y 'YYp6Y`姀Ӑf8`C/сpKLꄁ+`Űzx~')sAKСUD_Vn.-]:}Fbö0JO!GEUR^g%}2o.uآEO;wJQw2>.1xd@bWj'LV4U0=2k(ζX<ћ CRIk 9/ MFElYv"45؈4FdSp; 9Rӻ<COY!j:oC&SA(sʚȵZj$h^jD.Wy],ia' _>=O]خw'ҏ4.Df:.a:eش-Lα*Lzw4ZkQs~墖Ug;6v{3X ?NkYf_R! K)2 bǽrL|ڝLԿAm1OdíA26KX>ScطhoFI12a-ЍWVOi`_]ajҗ ^X0TGD%]^֚)_ܗ\C6"q[EKibJ5T<N iu:[Wd^Wslcegp13q6hHIik}o)M|D0oVSﱜ'IیXE`\zm:|뛟02fP쳠okF ,SĐR-}8g^eT/w |N=܀.dn+|Ȑը~:Vy K~GQ6& ~h,h"Rj [M8&||&TqjY1>mĸyo9,T =Fjĥ1]?ue)U3Ň߿ɡB&彿B-B+/-,:o?.bˢv}=F^JQ1 T 'rPv8mM:"7İf[p oePXQC4Y`qG-/ hMɷJZ_bTͲ =[lr}7,ܒ]/>%!)ekvNbfWg v+_peZY^Le3@y>ͽ,| LHeY>KUGS!7T6' 7I uSס^88@S+ &F'G.3_BFlc)o sZYK]50w8(_c⶜L=@x;nMH]O -@$l s$<feH§Miy5 C+xAIi0m=R]WCXHO& YPk;@bэoMuU] q}}̪YKzi3(^B-TCOyfy!e4:2*$"p,wU~~ Z CUg@j7COP|s_Mi ̅"b)bۡȥ').c~gZ14kcjWF]Z sy@F{0?K6S&wo>!DkET3֕3s,{ )M'NDUtsyguf;  8 BÝ*tgjY/?.qS#,r9H<#8;e!f$v-*ZQΒ'KӚZ,0MjۧmPw^rIDΌڹtf0G7[!]pe .'T*|(^絀1A6%mF4o!b pF*@;puy :iAjܣMg$B "4*(PBc}Y19B,K3 ecxc Xxb.;]UJ ncI;B"V]0vHUA;Xx_ў|AvHBNGQ 2ebA ~w5viḧ́gQ4&@Gv_CJ] k4?H_?Qbco*?@O%f/\*, .8% g6hnxO :"+͞I$:cQk;cH@4=/w:( uw7jgƑ=;zRE~b'S2۬ljG8.Hv+c|>Zu \ь( ċXksm0i\ cуwj]Izϩd\T.rm1YK,|^v+{ufRJAmnP83ivjhog>z7t.h4HrSg! d4Vn:v^t]R-rD 0#`Cbi6.w"Ӿ>)OceK |@-~(X$vdwb:&ζ\]ԥ* F`ng6)V< '- k'"$do( 4.C` [[s̠-VxΘpے5ju^oy(1~C ?;:9 ;!33X_Co(c@NٵϮ!>\"g9 !&m9c=d^,nP-*c+?u:28 KvtzM&^>)_Ã@HfxwQ Qq%rmE1%w,n9XYiSЫ N2I`g;DwKc7ENEӥ/5cxYSkΌ"f;TJoBWgIk>횑k9Q0g-j_*@? !z-2Vx/W!;k.#<!@WD! {o)gU?A&mPY+p>s#j4+ ejCuȴ,nPCJu1h[TӨV"%zHo'ބК~,CVYg .6pCv~uN5)jk |C @\ 6/װJs%6V" '= c&֒ L5#ZTۨa֔"+[v\6~GHh Pnr̈́vXyJDbs;EM^|_js[kmZpY3S#S`oXO!(@hزn6C-M)f4-5Q^Z}l)qPlbc+"s%UjpؓJҠġ)9nP2Ŵ'>5֣?}k8i, aNQ;-{dUm b@o?_ q L׭BR[٨h}B oշ V3p<}Z,Cԍ~ސ%^ p_.[L7嬬$B!yv1QgNm'GLg%΃Sgwn\l??mK!i ]vO<0st8|:5eS&_DžAKqS^&[$T5ʼG fu*;{b)ͯJ9hH ߪ}%iϑoc,XC r!l`'b6_~FS~YUzJ54nQsPqcd l /Q{ÖdTc{*WDaM0yW5V>dT1U74GDp䫔K"8J+D,Pj"b2(%;B~Ɉ;uEZBmiz-^*E ΢;F-n|~ōh|J2ʘ0/Ӎ㓙ti!I'1_/fFLljD$ܙ@.Q|MZ)Y:m=[uGĚ,\O}⮪xe[;oI[yt>k_&fLEH+0qaI~ي2H>Ǟۡ:VGo8jtǴ" ı0!era4> stream xZkSH_&.k+5Uy@B&d!|or&_綄,!Pؤ Zݷj!LKE&5՘VUe0.陥LF)LI&L)&&=)[a4;(PcE0> 7׌|R2Q{fI`P Jf+Ž#= qὅ?eA>jpG3D8—0Z8ADkQ!@M=zȇW@*tDԞ"B1j$i\1j .rAot\!< zhܫ,ְK3"B+*YJ$f G-9TI *3ĝ{R3gr);:.l#y\=Hp=,TDRy hP-D$@B*ty)%X,=i #UQPOP kM1; LpԓJCVerd){0-հ#Sk{kT|"┊3*FTTFuJUv!}гV߸M5.X˻7֣Րm CRsǭY$$4sϡ%siۑ4|oZwi紽^ VV^`>RX؂29{|Y'*M=[L٤_LiH-;`?.?}GA &Ɍ%cH&3/:]z >1=zvXC?.'bo'2ݐ{A! Y\rBd&FH=b+^>3`+l(d˰Y,wC߿Nf{6pzNw„Laʵ0b\ٷ~[x6\'DޭqdʯԤ& 1yz6L&|\)f ǯ13&pBw`<:_hԲßjzM z`&tSuq%_`/ayF((TC?p x`/&hx. k05)DoU<ax=ȸ.wB|rJdol1w22>)&Sf:Fڨ]W;'cBkY^L}lFLgb<ꥱ%APްg=C'Ugj.|kJEj=c~J} O`y1XT~~9әZƧ ~#& ڲ4vo=yB^ |Hge8~4OGG2RtO۬QqT9u:IyV?gGAOI }$5 ab: ͠8}(oOf|2;峊`I, ߌ$I3*1Mz ,pFs̜WK޾<mjn{qhF4Kӌ˂Ќ$xь3if51t,p *B>^$<20|#$(H2+#ṉ gIt+ŔȢv~q,+2Sw/RNՔc.c%YuU|zX1Eƒ"~MuOʭ^TۢE%hQCt_|( CaujY47حd~+ߐf2h馴B`F9ok>5!d)Ib/IuOutK*S-Vз)JN"rVD0OrL2+IDoFv4"'Ӝּ# Vt!HmƘEVnUs8ҵh2s>!:^2Ҁ`HPh) RLw:[]K7t$}=w) )NS׬/ݛH4B-H2,̓҂#'m#@N [3.T:@A$92,%vZ.k;Gss>i1W3f[jmP[#uK=+i\+[S\*T"#4-[,X\2R-)W= bӞ]Tޥ\v'&B8V;B*r疛vcy]yt I4^$ِ.F7T74-.R&8kDjzSQ(IHxh2FFkԑr0Yhl2Zbn=q^]KHu 5,V[Xi0y7x;L2Ru[Sכ\83=- Ǵ>1x-OTxL-8Z7x]Hw-S:[_>Ϟ Rߺ۪Ѱh|s*NЋ<7qOa73hȇ|OOW|?'yvvsR˫W-b}858h"}) 8Epp]@<>?z_= @/G8Ӽ:wT&g'}hKH:^ֵ yϊɰ!:~/x."og^i+xpd9zq.Bqx.r󼻄 _nҫŧentҜ`Ւ{_Gt2hCN@)ARrbR.bod>kAOaDX@n[D3rg2s5Tt6lxVRnOtsl\Ht;@36?^nb[V:Er-^6GuLoE7` !<fS0[z68u22hbyj}hk>K|lf7Bzw[\o0)8]1WW1{JɪlSAnu endstream endobj 153 0 obj << /Author(\376\377\000J\000a\000s\000o\000n\000\040\000A\000n\000t\000h\000o\000n\000y\000\040\000V\000a\000n\000d\000e\000r\000\040\000H\000e\000i\000d\000e\000n)/Title(\376\377\000A\000l\000a\000k\000a\000z\000a\000m\000:\000\040\000A\000n\000a\000l\000y\000s\000i\000s\000\040\000o\000f\000\040\000c\000l\000o\000n\000a\000l\000\040\000a\000b\000u\000n\000d\000a\000n\000c\000e\000\040\000a\000n\000d\000\040\000d\000i\000v\000e\000r\000s\000i\000t\000y)/Subject()/Creator(LaTeX with hyperref package)/Producer(pdfTeX-1.40.19)/Keywords() /CreationDate (D:20190717121527-07'00') /ModDate (D:20190717121527-07'00') /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.14159265-2.6-1.40.19 (TeX Live 2018) kpathsea version 6.3.0) >> endobj 145 0 obj << /Type /ObjStm /N 22 /First 175 /Length 1060 /Filter /FlateDecode >> stream xŖYo8+م;D]@Q gNDBeѡ('谫YI3~ 9d 602/ !p]p" Eds=Bg0O *yXq MxуWه8488pm1T1=>Bf}`BJ|jQ:H-X$}L|,uNsBƅԱ p291͗N3һc5 =-f2R U.<(43-%NTi̥"}B.AV0O0V1ENFj=?CMU-\V;];\z&( ;ngX5Ajǰw&UywޕAs»l3Fbd/FoSKM-'z1kĘZ׋Kdm&baV6ݤ<5t_ :j endstream endobj 154 0 obj << /Type /XRef /Index [0 155] /Size 155 /W [1 3 1] /Root 152 0 R /Info 153 0 R /ID [ ] /Length 409 /Filter /FlateDecode >> stream x%;OTQy * /PA[mmlOAG0$6|cbaboec11D翦e}}gfGD"Pm3HUR3I~jM pZ#%j;IE;O}MΌLtNBbxbdr]P}3aŝ)J/^8OC ]pGe(~,T_SPV|$+~ q80Ê?sH>^|#tRk?8 g,0R{j}ϫ"\z?WG+0 Wa af4_: p n+U|-yH + kpiQGʺkcej'ʶ*,:+xLpɋ$6'ys%忚{M>? endstream endobj startxref 261272 %%EOF alakazam/inst/doc/Lineage-Vignette.R0000644000176200001440000001013613513671727017044 0ustar liggesusers## ---- eval=TRUE, warning=FALSE, message=FALSE---------------------------- # Load required packages library(alakazam) library(igraph) library(dplyr) # Select clone from example database data(ExampleDb) sub_db <- subset(ExampleDb, CLONE == 3138) ## ---- eval=TRUE---------------------------------------------------------- # This example data set does not have ragged ends # Preprocess clone without ragged end masking (default) clone <- makeChangeoClone(sub_db, text_fields=c("SAMPLE", "ISOTYPE"), num_fields="DUPCOUNT") # Show combined annotations clone@data[, c("SAMPLE", "ISOTYPE", "DUPCOUNT")] ## ---- eval=FALSE--------------------------------------------------------- # # Run PHYLIP and parse output # dnapars_exec <- "~/apps/phylip-3.69/dnapars" # graph <- buildPhylipLineage(clone, dnapars_exec, rm_temp=TRUE) ## ---- echo=FALSE, warning=FALSE, message=FALSE--------------------------- # Load data insted of running phylip # Clone 3138 is at index 23 graph <- ExampleTrees[[23]] ## ---- eval=TRUE, warning=FALSE, message=FALSE---------------------------- # The graph has shared annotations for the clone data.frame(CLONE=graph$clone, JUNCTION_LENGTH=graph$junc_len, V_GENE=graph$v_gene, J_GENE=graph$j_gene) # The vertices have sequence specific annotations data.frame(SEQUENCE_ID=V(graph)$name, ISOTYPE=V(graph)$ISOTYPE, DUPCOUNT=V(graph)$DUPCOUNT) ## ---- eval=TRUE---------------------------------------------------------- # Plot graph with defaults plot(graph) ## ---- eval=TRUE---------------------------------------------------------- # Modify graph and plot attributes V(graph)$color <- "steelblue" V(graph)$color[V(graph)$name == "Germline"] <- "black" V(graph)$color[grepl("Inferred", V(graph)$name)] <- "white" V(graph)$label <- V(graph)$ISOTYPE E(graph)$label <- "" # Remove large default margins par(mar=c(0, 0, 0, 0) + 0.1) # Plot graph plot(graph, layout=layout_as_tree, edge.arrow.mode=0, vertex.frame.color="black", vertex.label.color="black", vertex.size=40) # Add legend legend("topleft", c("Germline", "Inferred", "Sample"), fill=c("black", "white", "steelblue"), cex=0.75) ## ---- eval=TRUE, warning=FALSE, results="hide"--------------------------- # Preprocess clones clones <- ExampleDb %>% group_by(CLONE) %>% do(CHANGEO=makeChangeoClone(., text_fields=c("SAMPLE", "ISOTYPE"), num_fields="DUPCOUNT")) ## ---- eval=FALSE--------------------------------------------------------- # # Build lineages # dnapars_exec <- "~/apps/phylip-3.69/dnapars" # graphs <- lapply(clones$CHANGEO, buildPhylipLineage, # dnapars_exec=dnapars_exec, rm_temp=TRUE) ## ---- echo=FALSE, warning=FALSE, message=FALSE--------------------------- # Load data insted of running phylip graphs <- ExampleTrees ## ---- eval=TRUE---------------------------------------------------------- # Note, clones with only a single sequence will not be processed. # A warning will be generated and NULL will be returned by buildPhylipLineage # These entries may be removed for clarity graphs[sapply(graphs, is.null)] <- NULL # The set of tree may then be subset by node count for further # analysis, if desired. graphs <- graphs[sapply(graphs, vcount) >= 5] ## ---- eval=TRUE, show=FALSE---------------------------------------------- # Modify graph and plot attributes V(graph)$color <- categorical_pal(8)[1] V(graph)$label <- V(graph)$name E(graph)$label <- E(graph)$weight ## ---- eval=TRUE, warning=FALSE, message=FALSE---------------------------- ##plot lineage tree using igraph plot(graph, layout=layout_as_tree) # convert to phylo phylo <- graphToPhylo(graph) #plot using ape plot(phylo, show.node.label=TRUE) #write tree file in Newick format ape::write.tree(phylo, file="example.tree") ## ---- eval=TRUE---------------------------------------------------------- #read in tree as phylo object phylo_r <- ape::read.tree("example.tree") #convert to graph object graph_r <- phyloToGraph(phylo_r, germline="Germline") #plot converted form using igraph - it's the same as before plot(graph_r,layout=layout_as_tree) alakazam/inst/doc/GeneUsage-Vignette.pdf0000644000176200001440000062154513513671724017724 0ustar liggesusers%PDF-1.5 % 20 0 obj << /Length 1808 /Filter /FlateDecode >> stream xXIs6WpCK\;u',u\N Q E}Dt|m[@\48yDѓ_cĔ$I,yRII`:>I$hM98u.T5~\*H.e/I8Os-6bI×8-A1eyDӈE0AH 8 LhD&R9j g ҀQӜezZ,k\@LI$)AwA ;T+o0|4'Rh$㡚kVJz ?n.A.¶Ýs+;X߳IvNɃquKeRUs['p,Jg95WHE\tz ,y(D$<#BH endstream endobj 38 0 obj << /Length 1939 /Filter /FlateDecode >> stream xYoG_a/GEJRBl+;8;ױϱo^6;so_?xv"p`tGv!a6|=^JTd& zW# mrZY D{O>/o==~|?>97VQXdД(zO_J= Oex}GQ|8Ï"FnG&(n6 =A}>^J1lp)hD ,1s>S^g j"x,ig]+# Mb%A'+nW1TR]vEˑes }8 OӬ4$ABz d0=Yl(b,JJIb@ ٦b[Lm0 6@eYr2qr٥'V1C]}>(dˈ}ɚ+0YQ eœf2*{T{3, P(`phIh;"0GP!BmJ |JhxSixyek']!<ƐfWϘEkIK9m.9$R6oDUK&|ݒXociJ'Rn:#.~O-XfDP EUăl2 :Nϋ*ä 7K*[-C X \SƲ:1lAO ̣y6P*`zLk*7d0,/2 -p00ZGeWpvx}nc%gΖ>B̵V܌\hRjbðpo Tw_Q*6MUI$B:tlaRP\$|\ijI2SCYȡR R MZg|(l*I>kןY1U}kt^ŕl5"O8+P]_uCHRD% ,jN7Uy]7zl= FV]lg\&sD5rw.'6_q|Fߡ- ENy涓|.K楾G+2I_ؖF{D};t}^tpem" >=8@Q見$JJF:-\S%shez%C ySyѿjkvl\%Վ ;"vk6|P%VWqҊ h$UKTEwyAe2ճBIoWdTnl};KG+ٻ8MA;}ξ/4 7ku<-,oe106E}BdQIq/̦;ĩYd| ٖvN&V_Ùi.<͋~!v< *yس} ]wQ?H,Ov,DSA&yЗ)ea׊*t6:%XU|E~Mᝤ=˽ /uX (.b endstream endobj 43 0 obj << /Length 982 /Filter /FlateDecode >> stream xXo0_Tv| 0X7GeCUyYPҔąd-njRsw;G ltpxb.5"QAخ:mQR'8J;WY ƪ{ 'FրW&1ĸ2c)q ]"w=|յi`7CX|~dtm&n45zw5 X%5a:"r 2IojZ֟fmD`b}">m "=낱^wPrqe؊b."k/<\E/ }yvX )De?6,b#n@W]4`0RW4( )mP٬C `NDEbSq۽hDR!PH@b\);CvAޗӽ/7GIdz68rڡ*ZeOJ޶au[ERPa,,ND匐|( êIa*vA-R `M.U^#7sv0VNzz|Ae|p|;/B~L^>^ˍ[aj 7ϕgyī-A7,\ ddI=:j6*TSsN, fQI4{6e?1BJ O5xyOSTEќoMsJ9Zӽ+2Ŷui9XזVLQHÍgv(`>0t'UND/|MtHBƖ7BMpi6fȞӇP&e˩RHH$rn/qwy؟wP8+!kjYWEOV1VDSuWp{j@(ȦL3 ^:n endstream endobj 35 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./GeneUsage-Vignette_files/figure-latex/unnamed-chunk-3-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 45 0 R /BBox [0 0 528 262] /Resources << /XObject << /Im1 46 0 R >>/ProcSet [ /PDF ] >> /Length 35 /Filter /FlateDecode >> stream x+2T0BC] 22TH5Tp Y endstream endobj 46 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./GeneUsage-Vignette_files/figure-latex/unnamed-chunk-3-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 47 0 R /BBox [ 0 0 540 288] /Resources << /ProcSet [/PDF/Text] /Font << /F2 48 0 R >> /ExtGState << /GS1 49 0 R /GS2 50 0 R /GS257 51 0 R /GS258 52 0 R >> /ColorSpace << /sRGB 53 0 R >> >> /Length 1774 /Filter /FlateDecode >> stream xXKo]5_ R"y%Jp,.P*BR<}\y=8.OJ\__܇͓N&sr{s=;7^ɽobsЧ_>N>.م>v(;.|/N`%-v&T|jaޔcUaQ`zQ\Qa>GxLR6M aiT/AVJX 1) VD, L BZ|F!MهVfYBZ^|X@ i2cCAHl@P!`r!lXm~)֧¹Xp ,{[Wn՘Q]됗SJoNeLrŶ+SЏӌ +t:ڄ| ǃ58VyCtj+fmda R"m[䊔mWy.[Z`GcN"!gO8 "b;!+*X.EL# cTౝ,GʤrքQγP8X`X Azjɧv_#|qo(Eu|5,(:[k.i_[8̣762t$]Zc)/32ݴGtV=mEmrے\䫎v* mEmrێ[ݷW͸݊:p9Y-n3V oϾ9/:Ѐr! CnAp=oAH;) BpsbC9|SxePj;#L\yxf`..og)nzh$5wt[aN' M:zy./.?|rB؝d~kw{P#*lw2tzD}06k4j WW/^~l^>q z#w5mpu$}~6ÍtkՋt\'@U]Rt#ՇvjT$ǩ-)ҖEvoQ##wڶ G2VND\V)#*[ط|6'|SL"en#h?r~sW|aʑrIy)'垈D_JwB9 endstream endobj 55 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 58 0 obj << /Length 1837 /Filter /FlateDecode >> stream xX{oF ?BP@bEch tmeH^+ ٖm6~dI#'6`0`sZG2w-fܒ𝭏 ;jXL[/k fܑcN& b(k2>ړQ(hZQdX^YL d(f]nDyR%y OOϙo1 ݐqy0s<׷$d5Y#UL\qP:s-ńpP9bYl} >,WuV]A*px~er`GوAilҘ^R,OuVlN_4Yp/9"6@o ntVq4C(+lq'uLYN,BpFcϓVF`-Z"%1i_IP2*љL 5E^J R0 _H]jXDHʼҬZLDIQ!72pѐ>!g/\Ɗ+ɟoΎaD[-%N(v##^JaaXE|bt*bk;ѱ]  Hu ~ W↎b}ƾe .aF>_GwBow o7DyfXR~G`3~j6e?u8 I̴>xNy4("^F%zTi&,jk8ԣIO[7E\T:Zasj=11|[.*ò>?vuu#+uM0֖&NmbĝU7mEH?eؕ7ܙ؃ }?|@tŀ<8JXZa>5)#uvocd{-%n-%&ة?!T „Xc}d:M_!>rv\ LAH$ơQ| ku80^m퉟ՄƨAُg⩑Н~!d ̧$⺌>?{1׵/`L!>(}=M3 w6G|/Ű<@agw{,`%巏c9N]mjvj><"gQDA8^G Jr{ZT}0Ʉj;+7? Y*|Ga#xV4JC/Xc5c`{l!zmL_l=Db1a,NE5+tQI 5u}4(SJ&7.qϠ,i m!(HLy!L,&Asnwp{Uݲ/`PζBⷫISӖMeV!t 2P<.c+2ŕbr'IHlҼ/`PBSxb_FһI ԫ?Ӧ'ѽS׹_)D؛v҇x=z+/m nM?\0ciI4o$= endstream endobj 40 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./GeneUsage-Vignette_files/figure-latex/unnamed-chunk-4-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 61 0 R /BBox [0 0 528 262] /Resources << /XObject << /Im1 62 0 R >>/ProcSet [ /PDF ] >> /Length 35 /Filter /FlateDecode >> stream x+2T0BC] 22TH5Tp Y endstream endobj 62 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./GeneUsage-Vignette_files/figure-latex/unnamed-chunk-4-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 63 0 R /BBox [ 0 0 540 288] /Resources << /ProcSet [/PDF/Text] /Font << /F2 64 0 R >> /ExtGState << /GS1 65 0 R /GS2 66 0 R /GS257 67 0 R /GS258 68 0 R >> /ColorSpace << /sRGB 69 0 R >> >> /Length 1682 /Filter /FlateDecode >> stream xX[o\5~_D(y$U6CՇ*MK3xMÞ=ϞǞ3{Y|<\l< :7~>VK7~q6,}:K $l&l[:P[oV]@B?v m1WT]6[fP'>JYU ? 0fx6*i"r.M|@J`iJ'@[l+B  uT!s`R ,Ʋ b^J ARL*Ggېy{N.7RJU? Xنktmx H]tiб3!m s\`/%sEs;}9||/groLenxW`JyBd`¹'| Oxb`JyBa''@[*lbk"[dd f&2)\o1P87IH}P& ym^&[Z.D75}-Xz (,d9тCM3IǜFz\`$ DebEBl"8&pVU.'pIi]wKH8M+,#<~b8ʽqY?2xemu}ZL~h @c-YE2"}''\㰫J8G] + Sf%EiM6Ӻ>De}\veGBO\pl+ΪO@2 m|KEWpZW]o`yt6?HC@k! a=ȴE0.0t@!r5RAׄuUguLkqDЬ$J& ˬD()\RpZׇU.{0aDIM)D\*Œ#fU%0ˣJpI=i])WWs ;8ˆ:v;eŤbNKN*nl}~KmvS&h(tYROf7fM$> mLݍW8_'mnݔNMhM.wG4Z,VƷTFS@!w3u۩].S7+m2uۃZPvg=enV,V̟Z[{m78Y_kh8[&wg^셞cx<^+r< =< O-a^v]!)þ,3'G#]8z~l?|zcsO/_g(GrWdKG"~{(/7.B?Ia)4~Nw)em*Uܤ\Z6HJZ\R\?2WEm巾M<?D4|є&sD؝"r_'{.F$ HK={%WZ_"ī'3V1BF",Q6&D0b줷ڢ:J . u}}[|#}!5~)' )WW>m~yr? endstream endobj 71 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 75 0 obj << /Length 1744 /Filter /FlateDecode >> stream xYYoF~ׯ xIQ\NJ ZS,(RX}oAAYr]a9.Q7yak u12=됮<1hMdLǦ 4{ޯ#j빍 OIm1fR}L:)G0t[߁'\-tcaXDE in'gq:r?'tti)#.`T.͂ڑ=f30<ѓb$vM8G cbN )]Tգ(n$;e^~*+b)sY|Q=ڳ\,+V%Ue<+({~FkgY=bI%eZɢ`Sxo$AseOoai6gSs+b?EݪBWeȖԐo(DDl2\j:)eB4[x.}BPȾ)u!a0z&WϮ>PlmgJ섅2 ]H)ŴM:Jl뺉ӄZ 7vI+㙔7!tm{+QWZ&i*3'2n7+a>5~Dw>qzD 2ZRS#ú11g2# 4*|P\xGp̹`&@RųʟGU\U#kI9K_!cݙp5TDyZ,OCOѳw3> w\dO"(NT*R'N,-װ߮/jȬyD.DF[oP(Nu4yNZu2%A#AgSmE64[qUUo"#,^VY]TE1E5*T쭡5&5K_"O{l_5>ӯufe n5-k]7w#i :Z\]ŰU64U~b%)sT`8^ΑHB5)¶auT0@ѓEڀ&-@ BdD6 UK7ۀ(-|k^Pn3êU`aM0س0ږ`*si#P[!RֲEkNM&/|6g|6iQҠ .'>/ProcSet [ /PDF ] >> /Length 35 /Filter /FlateDecode >> stream x+2T0BC] 22TH5Tp Y endstream endobj 78 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./GeneUsage-Vignette_files/figure-latex/unnamed-chunk-6-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 79 0 R /BBox [ 0 0 540 288] /Resources << /ProcSet [/PDF/Text] /Font << /F2 80 0 R >> /ExtGState << /GS1 81 0 R /GS2 82 0 R /GS257 83 0 R /GS258 84 0 R >> /ColorSpace << /sRGB 85 0 R >> >> /Length 2527 /Filter /FlateDecode >> stream xZo b_ ڙ}TQiAEvkXvk_?r{N^!9Gax5ߎq)Yn v_b1˫諗:wO4 +nd׻#S_t2Iq0.,cZ9m)!R6.Ŭa) @Du F91` Fכ1̴,ˮd9lAeawLskSXx +Jm\a3l| UHu}2ǐM*H9 麿0i,/J#]$ky7 e7X㘒5p"O.u̳ЪI7a.ʼn 2H h%ut"ݰ೰.yU=i)G:0o9ؚd6cNgyy|>!o5{Ѱlf| (chGb&bNB=y]yDRmcn.('e̔kF4!oZ8 !HWt{ndjV!2+kv^ SbD&,]6 縎W[‰UnE ":<(iǪB2'̥9Ϋd 1KQF2ـ s^5U^Y6!$ @q,Ejsr*,axxlg >byil@*,;Nh{Ջ8:Ul>PWkYNbv+k^b++jlXklERnVe+ZeیVlƵ6 bM'+MЎ͙@WŦ3=\JZAO2JZAGYZI+ ~R;ȮԶ9g)0g=ޞmؒƹ"2@EԜ>VsVQ>+xf; y@#1 MM @& 6NcƧHR POU(r0 UT,Q>9J3NC |Ҹ;UwO]%R!K; u=ǹL3+ň 4V6֦rnvRSDżaHO R DvQ7`H S CiXDa |%%N]D!+&eW Ab  W#ºI:LGV-)]B3B2Ygxc*Bm#጗/]&dcnś}k1LJi=E*"ՙ(}R+VuESYZFkؚ,XIS@,JU2;͋uq,sڀzD(3%n; w~D4L((ǾBbiΈ9Yk7ʚL6 ֹ zwYXp=%MzJ,Sx*-U@QWZ e$ŪB"5Ҭms(RK?^X;:^Rhw2 7C?A#šUͯ w|<-XOQM<}"{3bj]6 WMף -/d'Qzu^Qu.vNW9e~3, H>#(7nx7gޝqS}p\wB+ on 2ߓOMJX_ySoUm?M)~R_ o[ߍ1X,?4}}pL|sG+½ʦ?$ ,wkv|WO\W|_99O_ ͓@yn}M{)BZp.6B9n9ӵ@gTfiAfYfy6> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 91 0 obj << /Length 1169 /Filter /FlateDecode >> stream xY[o6~:!)[ME;L+tq%^H|MS`Q|9Ѐer =d 4 `Cp S.^D^/ԕS>O&A6 .2^_(+LҢ Ax9||kC1 j?lh@X= A6_8iрnE$3naጃ ۳RґP: Jt?C EEL5o? F,"lv6A@XWR4!b|u>Jq$F_%{V ت^_9VR'ml`v%q_EkxWBWw7ÏVM[b@ ?|k^Գ̺=,&J/]9.(ScUN DzR ^,P9~9Rh ,)S?Z[_#@Ә}** X=AZ1B'u,`Ǭ F1|Ii5Bi?DZ?ҟ $ /7 㵀z;o ř򪡾ʝ5Hp-<q016V6(Y?U5kuRqN|YXO~2RDE3O>悤6: E  اF-leA3o9%j*W,ZGwRGH%,& 6ҰDn&Z"ofݻ-uiZ)Ilܶ}hQ}d`)_!XBczFBlwM-4零݉SՌZIustoYglK%'ו2i-,ƪdSu,rzF#Ҁa>/ProcSet [ /PDF ] >> /Length 35 /Filter /FlateDecode >> stream x+2T0BC] 22TH5Tp Y endstream endobj 94 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./GeneUsage-Vignette_files/figure-latex/unnamed-chunk-8-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 95 0 R /BBox [ 0 0 540 288] /Resources << /ProcSet [/PDF/Text] /Font << /F2 96 0 R >> /ExtGState << /GS1 97 0 R /GS2 98 0 R /GS257 99 0 R /GS258 100 0 R >> /ColorSpace << /sRGB 101 0 R >> >> /Length 2584 /Filter /FlateDecode >> stream xZIodŀ`/Gk(d 'eAg^ji>kaU, y/G/߻w~ p77/w^]~^t}5uio-<*f_pO_JZ;%/Uw7B.0` 1%A02l'K_Qtҍ6&&0$3b`,j]zw<-x_Rt!}e`hj[ڃ@AXhR^څ@M,}£ <M(oa*T 5 &:*=\H Uh&tܩ->}Sfni)=*(T7#澅fnb0Ls`.sOŹ &ڙ--q5VINYAOS̄.؍35, H~,9X%\"4+%D'*eL:  b--uI~nyfDҷRؽէGwEOۉĶ@2AMe`fAUڌ  {d͌>/Oj]j9YSɪ 56rtXO&hõ8wtP2!.20!>N/ ,c;G>5S Kje,c"B 2QD_+4e}gi 0su&FT!ZM*A$Z56cuEHm4@p^Y~ J44cZU ̒ʕeheZOy,gm^?]=-dofa~`#qUoUCK'ZDgHԣ"Z賊SE+ʱ1h:ZJZ9VVcj-굘eTJ5{2 -脐 CyIk-2׾v!7gCt)*\5r&trpF'+8NP:Q R𬣲1->O݌[VXʲ9'd9+(5E5( ?vJene/,T57F@"1G4jPKa̀R*G<刜i7 rʀXO5"gm=GQ1=[LHʃ3"5"ɲ{ sHcHBXʲ%"} Hvx|# Ҥ>pUYf_nF} ]bٍ=2hĂV mB5H9/2@K3 8\SVb.rPKǬZVSb Y[7&߭[:SA.j: J>R9xk] BR20*[#rֳHNQi 8d~yR &BZIU堩{S5"gmdSqb8c=&* A*U+Mֈ9RG*3dFgLHR00/T l@9I36xS>V}*a9kϋ ؅"%J,|9,2L)rR20 _lY[ϒx>@{%黌yF}g*1Ur Xn5X c9kSO\?7{OR*mgr: r)?v=>\n=3yO2ϰ+7ng r|w/gC#c}pܞwB53 5m1οg ѶyOHB޼'#$|td_yLGJoIHש["'W,>_Qitz?w<5?< /@)A&D'Qf;Adn斖f,,PnF-} ]-eٍx}Gb{'y&U{$9+:kG3.k l.9MX0nF#BDvcG-C{CRh 5S~|aȉrŋ)SKOe N/t/-dGꄨ endstream endobj 103 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 114 0 obj << /Length1 2039 /Length2 22918 /Length3 0 /Length 24154 /Filter /FlateDecode >> stream xڴyct۶vܱ:fŶm8c۶mccwl'>7j53Wo PƉ +lkmhL'lke`gdd%#q:Yڈ:NcG3##,@htPr@'CUw; /hDgdژY>\Dl,̝`鏷0=@`hcۺ~-6#) )$U?8:O-"*jQ!yU1P UhQ-@^C'χw91U!U-E1&?k0\Wm.Js'';nWWWz3gG'z[3z;S5p:X>VlcN's1I_JV~8}ȝ]G#Ĵ94憎** -l66NNΎdO ſ D_ÿo¶+ӱ6t3qvGosƶ6NZXTg,l K~φN;6NnNY'$* dd0q?H*fc"bkmQ#Z|XmicjRS ?]7qcPwJo n RŔ?b?x{L 7XOGC O"X&?R6?*_l?_CJ1&6V),(w7RgC?DTQ hhdlK.dAz!3+ǎ%R3GV8t,Y:&}p`gK?Te%h.ۚXؘ`fcx2}PI 6N.;g'o쟍d0 qDF\#VR>b>b>b~D1 &L? 3``lo#?G"38NKG/~*?zOf9 ?2~p '5<\/%P&rNn_?CO¶nt:fN.X8__g94@ve֘'kjsHXt$Y%tmn^E'%tDgEoے!٨Ejx-#ΰt;4T4|caʖЃb%`b>>FWvݝQlI]Ly5ocR ̈i:kdɚS¥G *^S68"k?YYbZ%"/aj(/dghj 9Bs N䱖k_a"7+qgǡs7% ~ChRާ\W,A:TC'o5:[Xl Z;tpB\Edcf*DeZDeTydRt.kΎߏ9SY0/oțH.~DYɣ2lBriȈvbm侈'Gm(X{A]8K?h~ ivƈ3TЗp‶39ٓ\:`>> |4Dw8ZҬU]az 'REcņnr]& \Iḡ?Wu)jeNswOWzt>zpu;abl֚Z XܕFocu[-q7uj4}5+`Z$Nqm 0je7xik5s!vN>=k{qVߥ9#-8sWN)G!ܴtÙ%>GqKԱ6]Dx)T|[t,9Q#BB4VAj\w=7'[oN&`85*{o|NV]"`gU M%[>Gd&NqU|Kݜg>rp>T(Oh=u"l?Gwn R[r|CdG[ ~H@S4yUO4(+ W2 2ﲀn,S EQ8Bv2]Ȳ>ڽ:{YGh;ZE'ݖvr(J'-͋ $HZ' ͠Ҽ>x,m+peNw%r.B|<Znnpj[@<1ߨ\BC?].6:}TB, ~4$ + NajDF~CYȒI:h" UL}&3ZtOO9OE}F:Ŝv-,J⨜PN\5z 'L =dD ⍻}%*门l#^9)xpBQ`8>Ŕ 5u.q}<x٤oшtbW&ޘa0LzP ,F3R8wg"]vM$c&&VbL=/mfqhJ@ԏbttm'79HeTLCO(t=ZWj.}F׬y`DTۺZLlo*`uZ{P10re0}}*w b+f~MdG.rh $&gGt7G=Cr\(1Nv^h9ٺEBU#u'gi.cf^߶- `7oߴaI&^i6e}>JN5O:whb }l,܊R5G9<)\-q_^>`>l8( Q/$-zJhƱm](@ MoF%,u䧪ؿrČpk^$;vA>۽gG= KFڷ/, +"^Lhd'Z |M湚l-#캰)|y/w5vyx Wr/ҞFEcI^nmt(0L& ('iʡgг6Y051Npm./W* (EXӄKNxӟ78`u <,}^OM|sBe%-9 $=rnT i`B 81h10mT!?5BSJBgӤ|o ;zz)P}|2i1ʚ_Q5w*a s,?QSi@)og6Z0HO@v7Gc)E4 'N 7?EO#0W-'/[ h#* *Ua bſDm==;r/~'V,&Q\Sq6Aa8l@8/CS 8>.E~;Dy%|7#> :KjƼdK&Z!ׇAϼA9ZWN1: < oH*LՎ^y>&Iߒ%68lۆN|'rz;4>=$fbPB,a1O& f%fh[W +JH(](֎:]By) f>RԉGu%{u%nvGr4]\D@J~@[&֦fHi47Ri,5bQt;$p0|t4>YMMӠ )*J<߹OO;?q\#Χ}CLR=JZ)E \_ ltի^uUN u$9>~{AD.ر$HI>H%՞!/j:D,/_d}BcSHS籮Eyw68h75ӳٟO6``xjB&un$iwiOh27|晥dy׽_Ǖ?k{42PNJ]Ub};8h n{elȪH?D^6$͋0Ӻ#K5ބ K̽H$}F?_d_]5D88"g/o}WK2j~~`~w|O.SA#1kN迥:p`M7!ZJlc^GG6T?AudZtw},3%Ft'( PlR~ɼNMfd=3չ͈+ ̧ _ø՘kE-I*E\@\\=YOFTAicr 8 k#f r<1p!F|K7E~P?"OгP.Rªaqe vkh1Co=!?iJG>Ƨ(o߿>i@־X ät1 o4̇-C 6NNՌsGm刅B ylv]G* WTƳ@ѻ{un@ˤ\Za0Wo 0ESAb@\FzxR^Qo+‘oPY?'!, NZM= zqp¢Z`\I)Sllg;ywBT9!AQ_n!]Ι|g9n 3.IB}s$ǯ3)pQ&ٹAG C)u*Pvɦ,!Ij|>;񟘲)~gߜnK@Ip(::4rF@I樂 Lo斥>IPT?fm1˗:͞i.DZzB,Jo1t[r4wlMfx.p"ԟϳ0 ۗJ_2"L>=q29ef xKDBy}Y<1"@-=m'\OMYvkۯNIyqtDT_6qn7.3H&v^xC-C|Y*x?O N;^=bΉoIŢ# O~5-3F#T˜o԰K!i>ѵwJ :??ߧuޣ؝;m)b,: "ZmE L^~['6H/QW=S}n$;@dIT^:d&W^ -l%8+4R!o`~_Db[e_oK)'(Z$@[K >HQ};2l((ttЃ7\}E5=຃Gaq6Z4g<7nٮ¨YMI#T{;-Hu?>[I#X^B!+. A"}13<_GE[~KTD#Oۺ:,h"\>I?_(HuQ* /OZV.t3sNR| }c QFSWQ /d{1FbWg舝0=~$Us?uuzkS}?q %$d]Q/2M~ww5q'w_#q J^~|3t)]3-? L {)fGn/Ȍ /9 HLx6ߚ \J~ڊ$_7df`Y:؋hYP5=gglp^Kʘ pe@-]/i#FJɠMOPh:_?W! p>YبFQ`ҲgWpLFƶ̻\U,wyM"IWRTrz?DUX7Ge!,^d,*ƥOzpCWIjm=/kؾߍU³*~+&~Yz29gSk,$+bAp\9lj~Ꙭ-Ң79a/5sp2 6w>hh$1G۵mYN/W]>iZ d/tr5j:tPHrfL'RҘ*g6I3 'thQzCeof`'-cL}㶃$ C;lRMqR-i)0#DQ5zlr;o~E߀`{."thT@뒞[6f:~V=D$sZ_ $nf=8:XSnX/#RUS,%TUsMDu2J"Sn?Nx2\^9ܱ.(YQ7c"J Yj5Pr=&59/ Q:セ :6eMgy&<}xiI>3#dLuثKP~*H ANyGbKn䜇OjH&%z'h|>:h©Hvڦ ع[tGȇaX@l5J8 @>;ҹʯI֋0RS> %E>lHs'){^8Б>@>A: êC R>uBJFӪPhr؃RdD/Y_=wRv'>Wxn)JiCɜB7xGt*585cqcªw-"o;}ѢIb*\EwUb=ḏCc{wԃF$tg*p,]y6+zEz+SZ( Vc::l` rj3rEgF-\V_h^SQk``TοUI.caߢ~}'9uXuޏYHΪӍOBXbʇ3߆ݔ`~ur0ڪq v좸2ϚlZ >X9S*)K[Gt`0J_`x _-cRE%,wtY?(@¶Eln!e|&t؜hTU}+m9H. JΐwX2q"J퐸F&?TTk(5T AClpcFdA2#%V1Ɯ9X&B81YD17Dѝlu7oJ&6GM ?uoaښS(}~yQ|H(ǭQW^ ԑpyjhFISK ϤAW `b⾑ߍ `E%8oHrP@\MxM8cgoǙ̋Jai&.\irU;'OneX~'TGX麊uyMΤ[uBſ?˕:/FR\[xR懬_1F=v:m 7HK[uxwCm@2ͿTJX1 \hG4uX ?'zo,tVrE#!zV5_$dTQ׹Ă9Qk%y_9)2D㴔t=89U}#ֳ"c I XRnmSQʣs :r߈];W>nvCP,&kV8&42脂%Ԃ)`NoiSwݜl9;:zeQCАXI<7K.j{VŒj.8&^0 ⑶/Cwg7?=!,yWώuB10Zdaq§s@ޡ\f,[@ޢעOI"T0)c`XcRAu}%-n5:+@W<\dc`j y*McM+λ@h mi&;K=}dRfN{c[Ϧ yNdeS3t}^+m9iJ%lolZN Y[ 4Vzl2K;PYcnrJ63R'un?ÈV4Ԗ̯c? OV.nw˙=JB9̖5A%9T[L6&?o&:]99}Q}-J˫w䟑n9 ct" s ] C_`"'ld:N\$/1麴zfgXf& nIXص>z`s@ۘkS%6K]sK+3V:s]Y-636\)% ,i7mgf+Zj̄(Wʪz'G ~w9DZO)ÒU ɺ,ȨAo wˉ)ˀX}C0HmY'e,c:G]=cP'+[/JtJ _e76c\T^t_w in8zu9VXN\m%9F7b1h'a(Բ)ש7IBeLQZMB֍i7EcD]8wS+36Ru-sW26nMN߷,'8j&^4T8@!<ο!\!3J"z Zn@pCbc7\wEe>I)T_l^uP3v< qi=Nӫ ^=4ED䵡w/6qhZOebM 51/8 cy= Q|/ f%Yt݊g"&W*l7+@2 ,DR6i]!`shC]Ld1u<p .MX7gnFݽka>r 3ǐn^١m&waf(Gٶa)y3Ob=} 蠧'̗s fiCDrg$nm%cX4Crn{eyTpY ƁTjjr F;?+^(9T}Wɞ]ifYtT|T x rL}VpHYl?Ssh}xV!LS"tdfstRwߛ9`%FBT8kL[-9+Mɪv/ ;y!pZtX T;<\WS`yY"Xy{:q% ̠z}|wzgar73k ц.gLYtLʤ}D&'1}M00sҷxRsw~їr |!6$Oup'F 'hwL10`J ?_LByޑZۆ 'Qm~a+ !̤͸Sd4)Cһ3Bw}@vIeR¸GB2ԡV?Kq ނW^o\Ih9f>t޴L& etN)Acۖal7$m Yd,åx# _?wH-sꙁ*o5W#߁V_4R+ի!T>75&M,Oڀfh*hrH߽%uM>>S_w؎cܕBg5|]Oy(BZ!%UTpBXvFIH,z5r (M(tEl Õ3uK h_.mz.fƜg;_,$w0૰9e~>sL3]9X{:)`rI)m+'/\(eUW<]8ںx4܄wGH .YEZG8#XHZe VM4ot ]ux(aL^(٨\zC _GBff6 ܑջmEL󓲢H5[Rn޶k3wzQqbCWp]A-`K)Fk9WO:vXQ# S]ŖQ3ۋDk̈j;_r庥s%KmQvĦǍP!K~prucﳡYkY^rYn\KA!G߾t 0-/t׬FR; WXM6uH` ropvFj 2mgmǤ-k" )6eTxEQZ# 6 .{$G^(pK axCiK)3P%]/L,9WHφ,.^5k // S_WY{(!K K7M} Nf22fX %I*W_M;5ݽ@)Jq A-o.7x Ykߐ#J-11%E=eKPGrQ8t apE8*̼(f.~I 5O¿q蒑:iQ yJGp944"FZg2< iT=K2.a͎E~QFNWb{ Y/#6c脞ld+WF!0 fNNM~^ԅܧf=_ ŞHDE [ m-y ]l*%#~(o ,,1+ur 1'6/X3r>1z_C{A5wCw3±-5,Mdj+ wfnjXU|-!ueicK_nςP8P+@/>mD'G_er x9 C7ggX_dh0{qQv2 緕A36(8u BiI` Bc' *)$2UʄC]3m5Ò4Bwe t+>|ʯxxI#"@u)+"oi} GED2>5+BJ'͊zڪ?".i02 :'f&tm[-yӔ,eJfq"o: sl~J MYL>Bd}.]yI\TSt^ J43yil GT";6TA!N+A5KK-V*iZ}K~ qrOGao(f6J(YT iAڞ_M;/9Og=09~ ɫNڵ5丏߽l?(8'Ѥt9g3b(%z n0)SH$i0:Y8~0kXd 7Ѽ)*/֛1DT;|%GSfFxi!=lq,A6N:wцle9\N*kgi=M;aS{œWU+&fbWen M*bqy Qzkד4gKŦn鮛 }wWԐfv5&+{C\_1&td BD{JDqp$GX[՗e͙vmn[YCZuD-vnGܧL1bȎKYIZwX3CX%dҥ>d~|v~$0/X ?\OjYS3,np1ˣ v ]>&R{D)tr逎 sTcJV%,qq2jYFn}~"~'*DiC TĮo-~&cTϓ'&e\OՐ$v'_(k#YgLG9]G7/XrE/Wz>﬽ +KǬ#]l?zo}9עtSL 9] d-TǻCxZ:!.kLf.y/J҉0jfUKۃyDWO,m3lk%?cy@[3bp!DMp*> 'uz/R{f驄˾yd,'o(-''+*+M6'ĽȚTvxy&#Eb SI*(H^U:m3kTEGT9\ם|$qR$fw1QHp<z=*9Z> DnZj [UrʇS)lRvD%H3L59=. v`wKN4H(]rO#Q~_\v5P5R禱=@Po:JXg4q@i\o$/JUU?9`֬"5IV\#lZ #}Nc|k]ZOTyNyo1η{&W:КƪpMg})fzؕJ<2,Ul>f>hhJ?Bѩ`/c-)\ cb*\+tT9,֚ky/$CsUH^n89덭N;'bny#'OSńN?{W%Ep .yBGQs=rЋhm }jYY X^$NT4-P/uJF{|f[uunt#-p/~WaH| q6Cr֞aK&YWN~mr61|Kmb+$OAnp5$:[% NW^.~:9H$Ģ~Ī:y\ԃc0.5:d+-vȨn6&a&¯FuثO}r="ߖ&0>1 8ve'u*;pljPӲʖ*܄66 4ûwPw *6JyfΗQh1cmu 297x27hsC+R/fAa4QM(NլP<>p N\D7̆ VWNj?rNC1j]F{.- r8n\GIp&HS4ۖ3ט.dEP:\f[J%{闥\<;zA2JF|f2$Og \cM\=$@;4) 44aIubyM;d2&1.D1p!ml.x;%xx[1Er7YPLx5WF[tk~]vYNX}Ιi{FH7/7X . G!frR/c[BAHwM"b:fw9t]c,rߺTnW?·JT RfƚAmE+Qt0t?iaz,I͜Ӄ7 >_ɞ؞e0vYwN/,|g≺Uϡ.|,`x%mQEuyRUZ $*ЊS(zQǙ)Fɝ^No: ,nyU"Q,[3ᓒ;:098eɨe߆SEYAZqM|5N+M%}nDz5!˂^6,21gBhQ, l5 p`΂+j!άa}s{6Q^Å3DHó @W)dG>(m(:4f<+dn n{̀.z9 d}?Y\ I5 ?_|!i^vzV1?$X&uHݜd0Ss̊B|B|4l0@5N1hh%6 Ρ4[ |C8,dt1HsRP]AS#~7ClAP^XD"ŒcS?LPf9԰~I%~m鋣vg3rLs̾ ^ł}dpJ -L#㦺`mRąG}t/Pk;(]d| Mѹ)z`UĀӭE|*ex(3]C:Cz {_ٌ:#*9`׍fYtlrQ $\t1k~B8#3tp0s# ycH Oqs?zRf/+!)*!rmvK}٬,RtsB|Z"Ia|ӠkA2؛0[ݩ;.'ppB Z *ñX1R?㞡$K]f3AXIkU:޼ u1u_ВVъddEF͸مp>!hԔ,Q{+%P1Зn9cEֳ$(*c2.+Br`a\Wik;Pjuk N'u,'4Xo~ZcPC=}k1 T0(n2lyi8XCn/w 8̽ !"ss%`$grx #XM"116ݕ!KwSz5r7șUջ ~]{7;`M !]b5N邒L9x65AtÁ9\9jv/kR|1*nOhP?lNy6(% _(-鞩*e As~@( ^iݕ\%i1mSrkc-NsÿB8b/zRg~ߕ?NLD(EK] C5۠LA5DMI9-MH}B̧Lg9 {O^2V!"حYw9˧1 + n=O#}4WMl#ifg(Ї/>nefxyLжJTg.tac5-zG+#[3^ 9aƣmw$(C,FiӇգnZlcbi[8xjcŜUSU/KFOl^HBCAfH/qFX. endstream endobj 116 0 obj << /Length1 2609 /Length2 30945 /Length3 0 /Length 32457 /Filter /FlateDecode >> stream xڴsx=vwl۶;m4V'ƶ64v=\ΘkḇZ)IUEMRnL,|E5G{VF5 Rhf apY@ ^J4Z4zn&N@V?@Ս tv҂B]-~`gdw@``cRd(9zG)h4%jʚ*LNN.E\]CS !! j155~:[24@+JjjH2 Z._ܨ@B-\)rsscfdtwucrtdr+t$_ ~ @ $E{ @Bi/w+eL\UPQQ؛X;L@n&nl_9..k(˿/u1GPgv&c&>im9:Z+#`amY;cSUT`T #H&7/PpXy9,!t0wvE-5H'7Go;ض 7wwbtvvJ;Ȅf to3o3H_'G'+@u5\܁/'B`[Ft\.`gh9sj` 0Z 0+9F_L4Gv4OrfKbob_k֮R^@sk73I/ hE,퀠mǤHفftX\K3[+_a@ofQ51)=];6I:9[;X8&..&,Y`ϰ@!'w7 m0Af?,%YR+Yb0Af?,)AzJ(ʩrjA P#^2@LX9@MA:Y8Afv _ o, a eAP (쿡_lv~;bCVNV@<@6 Hۿ E  bW*VPo| "gd`.A{tvKIVPgwG7}eτ aGVuWn.'()Tv&VUSԌ < p xx5h (_$??ߏ,y8AW(X{鳀.xVME9z2r救tq:MĚqt/^@3G30© hJ^8B:rIP˙Sxy;d@,"GJt(ð^7Z?VNޘ(H}b R\ "=\[1ՖF;~cxCJ%3h[ˇ,cmrZB#$\w{{J5]5.q[,C#SycEV?ʵ8R@bٯ $ xRk{p8un~#/^k?]Ր4ɓվ4[ {ivf/ADOOtĬc_<߳n^u^w?8dw3AF1!H"+o3[B+&Bq]~=:+cEɋOUvܸkVwd աHgc 绰 )57q)D7I# ^CA4wC Ǘ_O8k 6 e?V(,aU38!{z@RO#+Bb;• ~Gc|4{bؾE >uA1:=1C3ZnrW1K%8 (^s_ Tx?dPՍ oR˷o,7fy#u6NVM _D#o̭m]뽔>c? fQL1f+KZ]>@NS+Nj@`ZL-[>Lw^ !i?zPaVn.S1M'Tt{cSܭ6HZ+^9*Dy|9"XH-IiXJ`ٟ LYo*:G5$ƸPlH!VI gyiT1~&Rh[Î ~-zB[&SQE}J @"}x}?wC֩ZTW1A󋠥i t4i&0[]Ϋ)ӝ/M:4>KjoAK%Qӽs6,T`L8.MC$d \[-ctIIdA n9INtePlqIE p];㐑zw`M6ߓ2Ѳ~u˻#rh>lRN;+&oqYwmɩ]*%vJ{&pNjvPeَwv}QޮsOOudb>p%KE*H7vNv>#wGJ\t)6+t.m r`d :p2ݧI [ Aq62I%*jU,3kw 36+H`;C3JW/h>T6XF]Ձ[4a7;v{)1v%-ӻ8ȳbpY(dY'YըxGF%Qi,b-wx!C =]uj~T+NSԊT߫~ ٝ9t'}5 iu l :kOleY'cn)q'b6˓ e,82mNcVO:ǁ:i4<'N ,UjX/V ͉]ž CҖP[& rهznvƅl6!{849v&Ɖ#ZTԞGUzA^!fV9N{h'l>>r(‘=. ڏwlmd[6KF.}Fm\{^Ip&XA<]ZҚt$!R:}-IQ_$rM@aB"<{2K1՞]-' o#_10F~by"SQdѦcǥk -&jXpY*THimv7qNO}5DɎ}3m%zjs1?So_ ~>gB3N0r'J_jz٫;߫5$v_*wnn<:%ϑ$ՅvIܶxю AP9 zؒKnLd~= %L7ޏWd4)lpCG~aL 7є%;gx}ЛLI#Wᠧ0J Op Qyf6B ysѫO7DgK4S٢of2 QpL¼=S3P|,>!y_K$bEYW;z6*|w@sWkٮGgS<Oq7txb@Ae>wYr3!cy>)[H9ցJC+F7Ԅ_7;+FpL޽ R_:ҏSځ"qg2P"9)*.\s^>y/be4}B[ihZp&q{O'ӏS a},)1Zn-KN['@39MPyU9Y*+p ];*ʛϛA7Q2xorL[0+ kXgfs$DucMnU)VC*߰O79BR>M\)ܯCwf ULhh6f%~wѺa_S @'P,+d"l=loX~>-63R=j״#\+=NŰYGmjY?@bx{q<œ .?7tK 1q&ZTߣ9H\ӭbEi !, AJ$g!E)!;nGJP5V։FlrX!qC++?)Ċ旂ð4dm#j[DqB<ݱ=2G@WGs2𭌽f\qn/6CRP"9RGOLYgK&% BMm<7jr~go~?7FTnzew4n9BgR%3NP I+m1HkYú)!t1)$4lvQ4_\CF…6ɾE>Xj}gF24^$Thf TĎ]> )hЄXށڌ˺xz-_J][MCW׬IL*/8l\a.yIi顩fH1*;>BMNj8O74rm c@{_D5vNKE cxY^Ój‘ϭ|PB*l!jr}Y/<ۧ=-|3_DJjEMJ~7˺@Pcئ"]+IpSNPPSO_;Z-i,Ӎ6xRK-1'y鳼cB깺/S: ]@yƖLje ҔxauDp{Rl&c_xq&ǍuBhz蝼S)r_7NA)* g'$wR7f! 6BK a#ݺ >O݄xzם9cV,ۗ/s?3Z' qH;qSRdlncipP}ODmԩ!U5;Y b[ۖl)b0~5Mڏ'Hc_hB5ޛ7CXQ7E1~х3кk#=Aup)qwԫw .mJp6 ]8y o|cزi{DCw,`;P0qA;|u pO6&e}V7f\)/NJUnXq]3OAB6M: Yq:9|O tgЏW ^NBx2 O^6IawyKCA *qoQҟdέsK?ԩ3"!Q]m><I4g&/Vf7PfBpi&eM2VT.ѕ>H4%Q+[E{S)f]:q[D2j=z8s\rhMo#W73e`M57C'Ix+F3 *Fe Lq!ը,sY"woFÙeɼ/3ŗ\R#Ie9:3!uڲ)TnmGVh>AoHYa5r%NḜdf|7O"x}KAv@]=x11^Y#xM%F9]X !iFzz̫o]4gni6'^a^+vSK+kb}tAjVwxNd1|(vM:0 rF3,Vu|x}wLU ~ŷm~{>{0!mhw8VQ ;Y8Kfq13KԫSpwOddO\ʾ;4ikR ӻzcV#9q*(h k -$YNއcȼ8#4g(iQuHQv?Tp.{cskχZ%ODюƥ~d'E14@A}hu+QcV>o.E^)އeb<n>ztl^ ^ !( I ɜ/53g&b݌Ɓp+e/bCZA|)z"^%(Go]p㖧*oPQ|v*ݎomuXoDU?=9 SƶUz3~כ<9P6@|j_N٦'9`Q&k#0ص)j hI+>oZo-# }?B<}φjX̘֝`a]Գmqs q)~ 'ׂ=;~B =< O2!9 #ހ]Bi4<āƂRD!y57묶zXbB[o7OSR=7Ѯ4xV6}nx1"|EmsBUtYgB.204h9S08_ĺY.5I4lz8⿬,fȠe # a:?y^xD[1(B>;"붩 åXiz뾇J ȭ7.Vv#i^ :8QY fDBFg:..B5KLje>{+[Nk G ގ< gPo5k9Ut*u3%p0[ ' DpZB :'=`g{'dLN2jUžZ%wA m=l*H]!@lw5™huP&#U(r@iMpMh0r`vcNPCS[\e7@(>yaW@0-Tч%9pJ\o= 'z;nԩ%F{6/`E{^M:rn"dt~#FKr ,P} ` E8"7~!GlR\^kJqRCq85;s|b`a[kq E';p֎(=qSrO뜄CuOF!GVDmrw Jvؔ[ p" 2.`P]! FG F > ,>*,vۧvL=H:O4rܭ " ϪMgO/7AV!ZEЯ+셒y,PY 3+QؤU# 0z8eSSgCbgP&Jy&~hh&nM5Z <:eEo:Lh 6G~Zþz类r|Th$EJי4ra.$% G. WAՊMƸyh +M?MBk_)*2P5Ǫh䰀%u wezrU^ŷ6\"yfuwq-L=/1LXɥu:pΐןTmŝzѿ~ ؼڙcUpԫpch "Gav!'Q *,ڝV+NxAq4yK.$Dev.|(_zysS+6G@e?c,~Ѿz~gg‘Nҩ1^L*5Tu^ Z꺽R7[m+Fr(%FZ(zJeaf!y?inHu2-66}ݶ÷L/]X^G%՜=OVTI#uiZq3 NGV,5}n~ե0bNi*q̮~ b} ֥*gtS3ChzǾ/ +î{<57.)\L}2K86?WG+hME!bGDGjeU# D*m hvA!3nFKv5% =Lc$T{FcǑ&ZSfCCAx"pcNM=lԂ`LaeGt\nWX o$Ppy?!re"Xgy] Z~dK%P N^߳ MEKiZL s=da_yk! H)HbEM2"e)Dx,խ3073W4FPsw]-{w̽)Oh67u\ʎ֢A [Hv N 7ay䍯13fDVxUq,,w6nj#+0Jd$Ylb]F6Ga\\Wd뻏tAnaHKWo<0JX) S1j :tw ߭~;C;m8pN]` ]\Mѿp$.ݫn8fK`B8v~ZZi[Bi[<|&Ţl8S3`+ǻ5hȯ }&5.O[Rm9iFÉ4`l-a&p4wd6O<1 LO2${ y)()X`PZ,0L9P}jtcotʧ=PP/ ک2mz6>5(?}T9a)j`Cd≼!׉gUX|I"v")6;Ti0{f M `A`D9'.B!dRj gj>թgbH/Gka`d7Tԡm ƨM}爘?2K:~LVMmyIb+lq2(?+2q0uӞ7X֒Z~ẗS?=Whiܑ !m‰®`OݾFbkflS1fl|RaaT_=A I%O{."TΝYi9 $Ypc( Aܛx.{: 3\/y$~aXZJY:kja=(T_DklUdmNq7nl]m*:f d+i#Ĝ0 2h_^FS37%4e/نwmi;l߇bcȿ߳uL*U9H"#d墹iMs{VзcH3;2zlLP^cPZfD;֋)}si곝}vMcyRFay$׽,O2=Lpf|xvk,ݵ>h=LG9=%R$=a,1P~s<'* s0pVΕ nB?4cw}&QcZ sKoL7}։a{x"bKsYÃH7T!j&Po cn&;Z'3<XTGv\,v5Amsb3S}l;Fzvk>XQzQװÌe{aٔ:ڵPq? l2Wo,3G0a5YW%=ƅaҰ &E<\{UTE4I/q^/4v0MC'ґoǍ2l!zʹ$\mBw]G4`vJf SRPPNe@2nzq;]6ӢlcKi%PRjlxrf=b a5+:Xˢ~KXՂ}AmD|e:cg3r_X$ MT>JoBNn.pE?X,& No(M7BL /(P~!|Ҡh,nyVJ YorK?.sNؗ5gĢ{=.DHym0qfC).v%Ͽ+n&ldB.gSp:eo'bއ)8.2z\Jc U&}2r?T0qYcޘ0|TQ 4WWVzsxb`ϯp^B׆ij>h'* Fpa?}EoY|̻a?ok_8$"66+oH>%[c ,  jm/MW.-c݃c@7da7n' yk*հAn)_&$ 14  ܻђ> ZS|>SqPA<9ţL";+B4;K cA)]CtY5#Wesؼ_<_3c,:"Ǽ*\3J݇8!bX[$Àx%(p^ɷ R+yolܾ~1Ned"N }_:ސR$dei[fۉI.iq~fT|ͧ,KHNckz{ CZ;-] BϝTXCU -ƩNXB63H4fOt2}/4 χt=Mg $CՐBg1埩ODALy>#q4ar 9/aUe](R V I βSP8 ]pQ!lԲDppX"'bO_]m׈ (ؘ&#&.drL0Cm1#81L lF3RRJu+jBɮ~*`e;kLvi߫%;Ee֗/QLh#~oZ*[ȷ.&ό{Q4YjX yݠwY?u%DV>IUM!UE E‘-{[3n-͙$sPJw/l,cdINx,vJ$M{ V"\::LKޫ2ˈަc\pw?WSme胡L5-r?|4G05f%-᫲)B \UKP}xz6/afnU8-uQ&X8^BơfP~ZG.{jyNQZ/3'@s8N?)G#qA)[}{GEMnƄJPe $4Գ ;lcc! \N Bd_FΆvREI E)? ~vÀ]Y7okY}t4,krak5SQtZxbZ* ?#|?\ϽxO+h*%={N Щt ]1B/oLy[ٔߓAsSOcyG@z ˆng.1dO{u2q􎾹eTNf&=RDNho=b^G<u6ZԆb*q[&/ uxE!p=4s*M_#z:duhAI?L"eq4DC`Ba{1ySIP֨4fD4iVoH'8yV-Pq4xzRq\@!}Q4:KE.ʷ(g-*h. Gqd5ntmL*$UL+eK9]rFҙ r$܀ޟZ9e2/'ߌe'eyFs3ȼ!N$\}?*>qkN+ )Q:*R! "._~Ga>smaf: iژȃz dVK q2[%O,zK,(_c< Hб6IgiąlyxJW򫆖C݃H^M |=b4ײLC6}6fVG@j'gRl}SM=U;-ϷWۏ\= ܄ԊQb$@/0rRi F^U$4,۩(s"~}|Ŀepg"#yv;YfV?3*LGzg/ uPMNF12W[=w"C*mOsgohSh {" Zh]ӷq~52!TSib /<|_X' F6SpuSK UF DI5েDa*Lk樵bDaQo WAf]|_a~y?C|1rd̕gbfX5͵跶]ܒ7Yc[[R .5BTJ+O=D5IfMM{bڃǕb)$ɳcq-8b-8jlawE:>,jn0v#N!Z/~q537(-/N7,]A "661u5jŎIkZs!`xfzaKpGE&|B<pJ6@]9cP|+uD~$5q"e0NiP'=bMf[DWZl|&},ЃOIc4 o围{;OUke{FX!ǧfC5 woY8pihѨ]삘$,!lӌt.j.*2;ԷKA NdV"}"b՛nTZ+Lc;aQHz_s{_c-[*@Syձߣ:2MGV|7D_܂P*ߙ~/C"Df:C8pq/}u"t& V`ᙕU0Q1y;[r_IHTIUÆXBDFs> 5sJиTU  Eh{]@y6'g$t1~*yTv3c4N28x*tgxHƠQ%(_yvt\ɡ/( |%Jy9F&Ƹ9!Ϯ~(&k2jqvAoB@VH`IMp،5k_Vub+ڪS.X,BC4sN`\b.kjo>y=7*6,@jI;-B&϶Vn,[@YFf7&_&,j@>4X$fNIhl&H9FA9sUgFshm =8V/!=} Hev)K\ #QӾ{.;_/,VX睋kl!w_*&i AÏ8A#0x8 57-ݴPˡ1}!skzg^D|lDǑ;}5SJAXz|BdߗC9ZgVL$d{"1.i@*q`ۭkqN˕m۶mNnl۶ &m۶ݗ}۟:} 7"BRAk@ڰ)SN68(4X"kAFYpˉd`& ,skV+b1)l$!tZy0(' )<AL%Ť OyTS]+GƲP J!mC|MpI7r)2ĿQYvhT?S2f\{Ĺ>z,aY=]ܢ~V``|4j 6na h|Tzʻsb{ x?u%rM /bgx"6BV-^#uhY5(pf8~`"J;ҷ ﭠ<70I;Zh3Ju}*%5MLEvo}FOr4UH `(.FRms.m, ߽m$sTd1E>(*R&o_ժ#Wґ~G ϚBRJO% \%x5M@Z zs^ WE"2`Aa\Q.62\m0ƚ+ǫ?ɟʹJ -tT>!tV>z K4+,^Ap^3ݞ?4TJ;.Bf{,ے܀Љ︎:}"̙x*'=BCOULUb1B_ 6N퉭bg8/ +ag΂/Tb3K 6Ӱ0 7 #3wX.+Yp'Hž A|#P"꘍DӸ;#Sb7π="i3Zޘs -V=UxԸ]V#mg:g+hhtN16FS:G.͂-Ė;:}9K`b$l[\yTic⬴HVX" T` %Wh) fr|#G2U^ӂ yf-4o}#>$γf٩W+;@hK)֜>S!DiuP^=uS>;Ls[5b rTd:tP|܊;+,\;%-ge#֩g/ctY00g' ?ȎҿDN!+ȠDդwV>5snx6y.F;X2S DlyVsx0abVb>m;_c{o04w?؊aB֑A!O*$ş̽IYឬSqL ţc/s-Vu]0LzYW2Iڄ +RwdŢf9&>iǸn43""mzزY²ĄBO+ gWr`D/6ٲg$4 j-l7 BMBԇgb@We#\|Q#k&C nY6k]/ hUsxm\9]6{X๶1GсDY]C7 jX7ߤW㵡W@%5eI`Eku:>X_kWzcI[gr]6Տ ɮ4ol>y(׬tWzۖkҙ 9mkeM cW;?8n,-mY$38˥'gz#`xi9Ǵ+RVap&q d~#w`c`ˌ*[,%ӎ]>͑ ]%-p e0 Y0J_,a䮩\xI9"nXĵ{̉7ЉǙI,;J,'[QeO2\k&k'XyUhKpPN3F;aنK`j4!Uߜq˫qiJ,x VRK+ %ΫvB=u mdCfoF^ˮɌ',Mx2kzZ- Qqvuzrc # =QW×;Cj?Umy~vieI*റZ{-%ǰٴʚWvRɼSBFu:D ~-՞;}t5d=OHow.]Y%Q8{/>r "بǭyFK4ݻ~p|;'+id*x. iM{N(XIa"\H Op@ [#<u@I:YYo]we tb捌üne  (YŁ s ua1OZ6PfݷALke v( QySN8-U21YU &-8Lҙ S˚&N`X'*2b$ o&dTK n+۰F~8SjaP늌ƨ~VyT! &a5t?2z`~oR(bQ9N9LyVn`.虹qoHNq !"`*bҾğ0;@ !LZ{*ː JZVMuT{4` "^6'#Vryڌv_X 4-zr/VOJ@Sj× m\ω/ ((HZC+mRhpk3;h -t S6  <(l~eK+WFxN8g#LZI,[,MCvޭV )߲[`.I4h a48Yj}8 hJSrF'Ĥk#VJ+J15"~J{n[XB=0ݪ5szSCj>C2Isif|*qeB] RU F Ypmj)< *My[I1Zq/&~[&SzH권%NS.[k-U^@UNAs h#R. ^? _'EPP9^prwT#9v k7oNp~]T83Ϩkr|j%%׃FYA 7Ȇ:ǖqE ؠSH^){-t_]Uk?+䲇/Xpnbpb,hxz2aLM^^31W6Z28 'hV!7pYO.AL`xCăK,/:x) ) 8׋cM|VV`IqaQ3rqC!]px՘p8!tE@738&Xu`ɏ.bBJgm%J+dYz։ ّJ8S?d"'iXt~5gWEJJ;*M9wsk~ UB}vt6ʾNJ+#2$%m.k7B+-`]b[$yÎ׫ Y(rR6_ǚ]i"Ю Rz|^*9\NGXlQJdb _B3ѯ8k؎IW핍@8xjV Xoճe2F(]]e"zs]6?ni KLgb ojKZ>:̺q4$)snDA[RGi #ic䵗(JWdE~HI#At+f/L,>moߣje~Ε zP+ɏΑs 5[X] _+Lﳌ>t&5nCqn0hNf nb=[3>fR+6Dl \8&f"*\HH2@ޠ"h`S6;3W1&tA{byĨ [-K e3mY4GN+ JyL! 1G$B r>)@h{bjJ$unҋ39z&7sY3#S:<\Qw}=pB$b"6ڋX"!B ^k[q㳑}<du(:>Ę< ӜNDz2 0AP~Ħ-m}ۓZa`H:mebgLoye_,']4 zf>^KW~4s&;n!aA`M CK~9eX?9?/|`{qw6 5,xW _'%h ^LT,16-t$ME,s3XSiɾwUښ:'RЋК *-iy[_T|JI'>Lyke%N)ys ^I)yh4c؆oEȋMMw\ Z]1 جWAю - o?6B-^ToLܯ1_"H[ɲGoqys Xw}uzr:B,G'|6+ \&埙*Ù`-W_ȴ婎'qmLw 4/=t}Sxn[$r |ڪ q_vu 1*}Hg/nqDIdZ"з' 0 xp+4׾-q) v̋;kX Mx.ުcQp3rЦ*d[*PEu1EUm`{zԸFzYBxdU헸[8,k0!% }A)x;a )$NyQC΅xy$y䚀n2CC֎ӱ)eV.V}Ak`#Z^!X z`͚ף. 2?dOp_Å>鋓$ Z]gC.՝CB6iB>Eqo?4V"#!iLN~BI, <>餯ODaCܵ3 s%_lieӼ` /5߻`]um2-("h`GH0xX'XJ*1Ekt79q;R'y&Z#@li e%ZJn7Ÿ_(׷;tGO#{X7U,_/j˚AD3WrTF\LTR$}6! Y8*fר:H(`fW˭AbP^>&%Oq@&6%{wtԒ^  d~iPdthEirQ0rAԈ]:F<7XqäQ}wxER&@ vcm[RJII2W;^R%{;8=ߐU޼}&&9 '~;:9iu:5FMUtV|"^C0 Q*KɌEe7?0K8@ ႗un#[muQCOs1jtd&1[F 6~M#7:?>PZO/#Nd+6ߧwub#1N!#o>K1KA+Ϝr|& rp7HB#5g\>Ӟ;ΕlP`ԧtԱxq*l6_;'eӭن$jk[gn}$̼nӞ_ XWP݀vi ΉLY7Sϵ~O!XmC|z&r$}=e.Rd qf>DCihd#"P?juYfKU#ɾCTcyhaIT\/| AQ D렖RˈG^ >\*HmEXBta&*m̃ɿ x_/(.\e\XKg?d8vMg:AT`wtMOBɱvҵ)V]8Y\+>`S^gmM\R7$< p9t$ٲV5|`\0HsMVes&K^5َhۣNsT"P2OBx맭q(Ev"xMa xhM͕V('Sc߷$ VBDD{%7:ƢFh"2i%. gcv}Aً2]:(}9eD+ J}*vYýg* y0EȠlt2~;;nuKHFLsvQZRB8NXUu~Z>D :PYN ۻP3Ho sK z*hBݭ1x "R@GX{)F&LCZd URc@T@{}_g9J]Q(e$S%q(D&©8b$%+ь# l dŭsq}q,OuѲPe#?mF`Åͳ"C`9;ǂ{ʋixi§|S~K0vP {q itpށz(=.erAV_: 6Mn_YwxXZ5LBB7KL/w`C-?sͻ)hXAȭ3i+0vt3OJPZ[G$闯-`lUt'@+U1Arp{TޞSW"mfԛ|@֝c8bG杦]ī6iaпj٪abF5AFd4M2Էa[(!hyk\sigb 6dp+sokfӀ"7#3)`\gՀ^"I 0of"TH"t9iXő\`k8Yb$!{Qy!"ՕSq'WF:t Q׋B-}L: S@*#u0l *%wDut0A,^+xe*kPm@}^u9ZEK(Bw.I~oDde&*.+1 >̓Q]bCXd ^Oz@tU 8DST 9(Z56<DQ𓝰ɴŗlPa2Z;Acׄ@ [{7OԨ Olnaw8 ]sM d9mql-Cׅkr&H܆ aN$u"DY@[+@ I;Ҳ1/wxG;8=T 5 6dxW ͘Ih|6&B,yrr"#}AaË;u]ߔsۡM꣺HehSʋ n3w4 аmgnl 6BJB@6E# ij%&/ (i8MQyj5%I  Ǥ=H5l;P.3.\U:sc`:/Lktp2g'py݅* W}m @}p8pRA&Xq-cW槮G.o[ QI%#a<꧞B -_ߵ9 EWXXŗpbw:麤WJ11$#z5"*m#x"OpqhUֽp5v3+Çb1(G,8☀7EpZ-*fYn`XIA?ʎ P '@%Y̊HXI.eSyu :IG?ڋ__kB-Jh8*I(2k" +s^ IPf 52y8 Ɋ-^>_bŐSz6;BvHIKqKvWj;|YtXXRPf1ÓV v0Ƒg έ7.DSu8[l"]MtS9PZv5H97.l"N#RgvEjmujЃQ  o{`l5}O#N02K;*痩z?MM([sє, ԕ5ͱ>d"1.LJeI "S\)JZz`(ΊNM~Șe"@!#!ʗN*ˬ#s+H.ddmŕyWpd'qerF_K5<9!,mu!Pd\l Ty)+<Ꭰ/{6ƾI-ݸIjqY1A'5͒)zf/ɔK:~2G%{qb&UMTAN橲;%Vs  M gcZ8w0[kdQ{7b1eeN"m#Q')!ˠNfOc(isrv۳ Lr֘niJ~FM+*(^6lŴo?kyW)11Tq9T9jhN@lBy~RKL*D\Xq c-,QnV}D7S: OQ j2}qӲ(di^9Q#*(w>j05(gZVg$b3&-i$ƐG,6>I?^Q33B`D9tcԸ Jt:z{~2#~;I(r=b7S.RdA o Chpi !BD0d&[{i+bYWXS< Й4 =*&d-vR?#D@h(9FAm.{|5cH}2u54wћZóvzxj Ӗ7~-E"vvTy}#N;e;J! {r}]& eaKa|oVgĻI{!4( Ln^!bJ>sefa!/0_| S@2s%0žԄJ)g\TkXw K _ofz!2Q3NB;(>鑳 -ЄR)AjspɿBI"K8ĝq6Qw?ͤʖ\ڤ'۠4D^/A<ʭzar۪mMݚ̽U0#gPҢ>%献*,יtɾ ͇l4d!ヨZO.ƢDL3}g_ꞎקˇ*ETR'l$SxEx,?UKmR p{݄[^.&LU:Ml՟YpT pWjA=BM&/|G Wn53`xU~=9g23?-K`7af:7"蓡Rds?Ϟ]kybJN{~µ*Y$sYZ.Mӿ^Dc(k=^B8;nrJ0j!tLd gT삪AZ=(#<D\esXtSw;cPR+ aSeCVن/zd`gv78bހ|hbwWweS\@qR<4HZկU}5AICR_qà|͠}i̾ֈ KtRlRY,ߵOΘca$vܧQ &Ĥ/eX#3a'Z#Da' fP#[m_ʽ]ke{1ʺ2͕+M{d|K"yRc5&NFd2S>[3DJN juZ䭊O6d%K|P[3Mn+qQGcԾ/:e3h*sNN2q/$  df.oKUc&d -`=3N%WkhS z8i:S_-9c 1 z%,󆴕/_5=}CdB&vN[e-:<ݾy >L Ơ% G7J(1Lް(<DŽkH@3G 8Aei^䴲!)B"0"E+QCȧvxGYH&s{lT\1-Uvh5ar@}/ ־SJq! ˞߀F8Ѻ\gSrk PHU~RɖAmEdC ݦzC1˘>wxV> ZG\[v }8dWuKJ&IBȰ*.J\jS FW{E2koUiZZN8$ ZkG]oo0J"J<D׽Gerr{|AB|N3VXChx"Agg0DFw&On+Xi,Sd["FT=W L=f-KYTӔ ύ٢ zN\E!D]S\f}?. [<š !^;bZhB(\.I ;Br8y,<>WPS^b\*eXFT:4 z\̎ Pr>X>Ӣ~Kq֡.D~;5pL¦Pt9=99}Zވ٦f9.KOwy=nAUg!ko33xh~\v]w:K endstream endobj 118 0 obj << /Length1 1852 /Length2 21900 /Length3 0 /Length 23120 /Filter /FlateDecode >> stream xڴeT5 šݡhV$8Kqw+VkqwBqח^}<|5"SRe53JځLl̬9y;[# ʉHEh@ʇHNS;@6RshJvN`&c#w7dn ҽ|ww4l1f%d ag(ع-v 1 `gPjU%TTR*JtUkϪjRqQ5 P S zߜ=o5.@G'˿mc6;{? `=? +ќ,,vր#1 w:+9K 7I_Nw*ߓߚ6 8?rJJr[#K2N@S |vvtC]G{_߸69Y:U0Yɋ*HKJ1ɽ $o'o=Qq9~/+ .R g;['nѝ5af 25˽=:(-_&Vt3`55iog03qz[NF.@x&wK|2O߮?Gځl@3D;$hs-?l-mohNK`hkd>K'IK7%_. 6z׿(-)w?/;eib :9|'?&~gEEiMEEW6ILL-Av.n;"عl6# 3w{n(7E``1 `1y_[XÁ9,K[|foͿA>B6V˿5b{/oB1 XI"- lʉkSe#yBT  f ENr#|bָV|?>^&땵β5a9`-t.Nv@b"zDgwDLU/UEhuo(1UI;<^Bal6QƤ-95[D|UiTuK^sx3?2˨ҝEVgc#0 p4 B8.G%iS\_մSI3RjcP)T52*e9 %kӳ}6=A't EmۉK$WGk0oh}H/R_f,Hj<zxk^F fO=Օ'_!;+O~$E([Ec߱S2(MiKߠ4b4!|j2e|`M3 #Ӗƻ–awS|S!r$0BμcY>5kCA)UMXuʆߏ[:qntxbZd&y K9dq9~-K#D E`,/kˊ-YJX)>E(P%m:`0kdd@kF'|;ͻ]Xe6ßaņDX^?Pv^U?@lr*Y$6j%!h_3SI!bE'E톅1vlF0jIĩQ(/ .t>~6ĨiBzM߅(>`m w Z ]V\L'|ػl G%,p_^ZwZ\G%dz $ge3ת3TV\Lu-eŹ(S=W& ȸh|:6bg܆_ddwҞxuzإEo:6R RegBff$ IP@ `25#QSBmE+SǍ4.cH?.q9_ߦӱ>fnHv@c޽o@rNhkC~2?` &{J]TǍ&~Y@'oǢp_nns[:&Q"J>؇K]"T XNy"f1b-XzVT4v I:krej dgA~ \ejET^N% ,Lm]u0&ㆿ=%YMm$OT&;'έWL }YˀutIm:كXA^a"(q(D䀒izLkqJ I>C+Q6ӦI,Ӽ]i|ּFvgO·3/瓙6"%q/97D*!A])JI}E?>`n c&7J%43U^KY[`wc:-Ũ$tvx#F$;r? #zjvu^{bBuvoÜG%.V:K |(XL.f6]8<&>AxikZy e[&Ct)})½6Mxg-U#QY+-#dcj1ԥOlEDBAO1m*R ٩[u&;Ua!  j)G>>m!$ȓnس-) Z+1B Q:jնK+ح9 cu7Ue ˰~kIlδQ/u4 i!fXe //]:)XQQ!Z nxh}S['d{jiIyP{3].YBkK-;W%aKfQ7+{w2-_HDnv7t9 \pZz#?s(aLd47N x+΅G RBsh$MfT"]xl;F:6)JMH.JP1@:ڄd { }x7c]hU?$>$w'JZ?F$sw1AP`dq xBCoC  \ea_raM fw ( FA}Ԁ*Y!i#jۆK5Yi_| AQ3/xHO(ooQc1P9F%n&HySwUu_q(ݨn8ʫn kj."tJ"␲ hǙ\BX,sMد[:^J;-\D}WʀxX; N* x|Wcs8YXόL0l^;~)#pT=z)$?NH gC󵗝!˰/ ~zZ!Wi\# ZG@5pP›;T>o> ]'#\݃)QIC&DdhJM˦?ϏÇ7{zoR Af=j8Xw-ŏr2|J(`atXw2.ymӠ~|=툴d@af`gl "}!\r.NEl2){N1ȁ؞-*HS YP#u Ճu0ψez;RGE *^ƆА|d$cܯl--j$yzbyAEY5H&ö "m3ޠ2cElؒƬKFTm;mŅF 8S9;)h"T ^m*?ɩ4d941)mf HoaDZo 0vU#.ǃT$BM'%򩫋wT\rO]FH0v09?υiWu6Z'˩7|,8Bd5\Y/#z\5t,R3j>N^$g, Z]C?TĘ.E/7aZf#FMz^ZP 9 ܺq -{^E+~'hE)쬰Җr$ w=$7p(sZՎ~h9!+_E<<|giR`x{rf$D1Օj%eɣ'*u~p#t~='l3N"qIB%"{鞫Im_%EIʼncqBW~3ICMRT S1+cǃ T[mMɺoF ?)߼ݜ6?D:o4_öt ~6C䲘Sp=h2!.CWz[wzBl=AE9>M'.Y1#I~|H.4ى )7 |*AFGn;4b&41{(9[3[O+(JNoZ{`u+F&#Qʩ«J{C 0A)+H@ńD*7Lϳϥ9mx^8 .n܎4^:<xljarc'aԇP<U^j!wH m_HYbŘ38QH}L[)(fE}Nؠ0c,xǗ}gSOKyFGSѕ>&NT+N*pF6♸weT S4ݵ+I ju( /Sۿ5?O@v~џnOf kX=v!Q4sZ 8dLU.xee.v^!Z,G8ow]䬷r CT!S ;#}Si 5eC$B[FeX95/ 6㊜N\h695WaPEE<Juc5ihqȹizQTƖO8ݕU+u)EmwRlqF` @"~H4Oв):˱z;;` YQ̫o ' +ZZ̮CA23Op9rjשCEP7S&ό8 ]m3&r}2l^\m܆fx9ksԥmɳ{`A~ܞq1&TI=Eb*T%b?# n` knO!M{t vH:CY5 .*$wrF CIeYL^=[h*V|L k$)v}Z[1-3Z7נAWF$`>7RS|_7oޒ1obsgJ>mA#jou]\wXhf<ل0VGRKMqd[gZRPצ?vGk(Z1Fe)tn]"_aEE،_;XddB G \4'c@d Yњ)3H0糄߬7ҡiPs̎L]:o}ֱLT(4|cJdnLC ʧV6~Qg*.==1Ϝ^OB"7Ԝ^ÍQݯ4y3.O b1sZb撻J32y3 ]z#J?UZcx8sü ,]SN7#7JlU4@?Abr,P4nI(ӚVI qO jRVHhȻ|+A$aei"ױgL˖(e!*8j+E1ci٤GV'F䔿k[NG%,^c%6jBA,9C$_cAO[K.!Wj!:[yCMbp͙G$HUe9Bxo2-pˌXt&OP|0[n3zTYd@SCƃk?wRS ~y_ W%;sF[4g4!Y2[᷋ qs*ir(,K кйM6 +ybۇ å׬Ğlh8x+!vErHG?O).UcBwԿLZ.߆]]5C "aF.)fb. dvXY6'{~3ZEJƂ&=H/u)"qMR:8Kȱ#5CwP4R]U$=Auh88}M)s:x$0/vjʵRy+Q!(mp̈..Z+~AUȏ]9G^?j@bbw:%aٚ4٦pp07Hmon;fka4uF_/~He#Yz.xhTx$ e"jqs-E-Ra'VoU>r!65<6pO\+yTq浅~%;uoqtB^2\8]& xL݀@2c4o{O_mTW0LSV:D~q2N b.RhקpۡhB!1ґ am TK|PdXN9(0V2 Я b"Cz { -TpBI/.R: dӍ}ARB՝N(u ;ߘxȆK$$E] 4i^uY3Ǖќ6͠xiߝnBTlLe1mZ 83]/ǻ/ia"m&N}Vۯܟ9= d;,JɜDa d $q5؁r;n'YK-iLYחXN聾2(,6޸nnx,MRil{q*a_~1:/s:-R𼕖z(Ӫga)9sUԇ3(a;4OAi$yw?m}z u4Գ配R9KqƢA^ '|ڪv~ DWç;O2J[^oR쇽"nO? Ѫ`>p]*yk>2±J0`zy|R&=Ƚ@]GY Y%Fm-Py{߶ў`u1m|md?Y*wK ‘W6aIyN|AþE/L{uK\?bW磨,<_8k8>9/Qت@b(,]+°_u5Rp*2X;cwrb9pV[q%kɘz[+?#.lREUV nSBGV\~ɣۢ;p,\q\G!w!ԝ$RBXE{-O',P{0T#Nhʺz7@-(X`EB{FK=.1uGcȅA&P)Lg>C߼ gPh7v|Q=|,weGjײ^ gOXy޻\8:.e4Kܽ?2Pe}2.I=l%~mcY&dž]m蝪)8d ΣE tr4uv]&8H?w~ BE҈; ވEC.V4e*ߒqv"ʒt%Z Z{Βc:8 5ژGCƔEj Iš$!5.|u8lĭ"",nPcl@CI+1[6]vĮOGly5.&DJ1CY~ngT^VZ B}n5% Wr[iSC̵\@O\zԻ BaƯc{QSHs)W; WjiuGƜ\H+^wD ';@nQ"[nb.ߧ#u. | TÎ?>+o{5BяF/A"cΦ.>"t)!9͂ƜH#\N]Qz E_J&g ;^5G0(6K\Y?Jk6[1( Z.l"`dd@T1w}ADE9$\ A7+fDza Xv'w=ۇ.ȯ45=&3"U|U9}S ^SeII1BoӍVDP^a/]a)}EYࢀǹӜ<-X -;e;8r7+ 9PlWfiԭcw*o Con :a9\`j꺓(K(_y#po2K?<%,jv: GIEK~\CgL[2T*:z X2:h%@t)L ߒO&D.Fq IߵYq-Mb W/Uphku.?dCSӛ"8n[hD52@RKȲl2]\d]$9dtр-iUX-,*+ n)o%jx*ӸKU_ GM[{]lt:EK.L MaE.J܇fh#Rh_MvH,mhrw@p(o )D}HƝ߼Iu+WY%Fuƻvm|vR1ԃ> *8_miн }ku5d?5ԅ?t巟rxq9Yz^ɔ|ҙu _+14)Yt8Q>K[KDr KaƩqy>ׂI #Jŷg["+TJgi#>X'ħ B+Ⱦa3*+k 4}cwq>90pb{l Ql\ӁDY4t6ӝCv5YzB Y#RYܲKf)>3hO}C"o }'W:uH#ꞑgF0m-] s2RLɽ_Z#] )XuשiP[/ʫBdlr;4ݞRc+Bn"SzUy-Vaq28&ad±čRyk=;R r%(+sެdjځ"z ޅug^F5XBK7r9`a\s}{~FT+鯉;}33l<oIgl{{Sic_Nŕz"0}- .w˱ޭrֆ iG;Q2PG \ZU%0@\k 6+DHs/Hv|"K,ƊjR'@ g !Qa =;fAMSLm+.D=5S04}8˒XƦ {-,^lw~ڿRI7$OgFK"<5֋)HجkbP9ea,WSȨ!w^Vd_y8ZلSZ7VVlCmO毟9 kp͜XwIIli_ .`0~.М#*eIʣJڑ832ɨ]a!PN TlLFF@3Y-&6-k-] bKW~5[~}>2˧M-Śfj QvrN{ԏ)*ɿ`X;}<ImБImZ.ftԆ8%YzU-,_Ovi477^?aʐ*_VwMZ)N `h&&ݬliw cҋ5hHDH%FNT-D"*uGcRk&c#s%8'gx zCDD壔XA]L>%AfC_̴Q[y>=㱤k^ÛBǠK{D&ɊhxܡpLOԍlǾ;U}Zmز _`*L%0h BVUԎB^]օPi{k%%vfn*##Iej` GBaZD^0A4Ye orPtI?EՎa#D<ƫO|8$I2CV"^ Oɕ`š%c(-H$Wr8r Ml!-$G1w7 w;qG`S 1[}-̴`קԙ,xVUL2@\όAJIcIѤ`cƟՙyU Bۏaݞ7\ ;PܫC'Л/,E0] D4loo$ydy[F` ͆[?7GWne!Sbi\%tިR}úrwjn| 96eVJ傲Aڢ"QGLp7/ *Y,hv./Kiix#9uN \>Vm&ͲN7l.ae:\ȨO }* "s'ohL+mxɴɣrL=i4f 1} _7euC/-%as ˚^kIyE#1S+]#5#)m6ru[kRPE .vsϻΑ1-i|r1]C@rmɮ3~3Gd4h4`-.ciҦ(V˼!gǸh),x*S :YqR.S928?4m͆LMJZ%6[kP>H;6ٸ:կlt^m)@ bMQ.؛ >xcZ8)KiWs2>)j!&˫yP"Du.\#wn&Po/o1ذ>N.Wf\Y"㊼UMM҃ҤESNI4F߻[բs ǤPm@0ۙ)쨴%qER);&sq. ܰH+IrȭS}t>kY]ISCy'5v Ό6E)_BR S ,[So FɐbN-x5 @e 8aϙ{NlɄuT{Gu:czE6Hsyl-Ņz_ i5ɥ^%!Mp[N77L=m,IЅi,JRڈ7h{j"8 jيrQ|KjQ9q6'<zEN7u0W /Hl"u%} 9ۮ a#\TNsc[j=v$mW{/_=_ns ~F92!+`)ꙃ%=7 lߒψѱDgRг\e1oS[VqMUGs4x=ɛǣ.3-Z ܺ`- +ǰlVyMUp{$(TO_"bxUTP1w/hGO|G8iM3ݽSX劬Z;_]ۭ8_@DTu|/ݶ 4?d MPDAQRv~, njO *fٕ#uיTDXLUv @~=GNvy5vԵ$K흩 #˰|JlO;{ϒ1)>9hkd'ozmz!e$x=Ç8e6^]g/p0AǔX!J]Q%5u7w ED읜gI/容ΰ[WHaJ[_*u`s l ы 좾؁Otq0ųsS%7n#Wi/E-XGVWd)׮(0Y"ȮTQ1*rzFc?~pe "J{˥:![|Ntӣ:KtcFatQiiν]R?Fpo `{FЎ{2f{77hꏕu&h1(z; c 8'Th`2S 5i{)>GOb4%s$ko-#.~}.]=5M'D?)FZ&{6Vb2F[el4LC~fKpY|UL쀵Xb-v^{pghR Ձ)ا-e|k8? 15<ۜX둜'(-+Z6lw2Pȫ%6@2LjOߏZ!Еzp8z'1y''^Jl0}R96U&+ o[l|CS \!imy9(OP{0ڪ^RR<ؒgibXTߝ=J+3YՎrv(q꯵*RDŽx%Aa{_*Ҝ((okH5N-k[%_H`Owuʿ9}.l'CS_*eŜGˡc4L!= UIP'8aKv1̟5޾LaP[:K[@ǚ؅0PԠ(\̈́Z}ߞJި]wߴ~ԦqT&E J0M識?l]Wʎ$$X[4,W E"hu;&\"%ElXAlֿLpxၹI8 [GgQ$X*%^^UF)=>=dYq;(a $,<^E'*Mt~N v˄QZGDF)Svթm/+ΫK[CIZW&_JRcšqUmy"&J+aş,/[./ĠB 3v:#G3`y*ӛTf2wg 3D,LHZF(cLU}7PPȬkBai ݰ@< _+#ߓpK97O%Tư]^Ocư (TڧO$w7~'˖@Q;GVP&=RA+%m3}Љb쟃b ./[5N^ 3-3@zb݌rA݅A ۳KN˱W/k('.m1Pm<@n +6,[y JFeFDQڨ`ö+)&4/GOH`="RYgq-l7W9)' #cQ};|%cHCtǡ96!u3r6 }ھ\J8!j?oP7ڶRY6F1Q xjVjCe.z:=aWW\ylr5xg5pq!Ct FQu:Dkd3P𒮲 x\5/W`c=I24-p1;R߬n6H$S4HHč-y$$Jߙ浾jﶕe7H_]X&ӗCI8F03Rq䲇.1ڍ5h% @|2&$Ff(.WN&V`r<{%}ӄ~s%RbYYn!c9kM>Y#Y [Xm5؛~} E3DC?^ 22B#XݝpJQ,oI؍N'&r*ۇ2vJ%BYVW%j$!A=yK27.d~q*`jl6D۵Trò\uzZvූG.(۫cFX Dkv%#1l-dwe&˚7UUKJ+$\J zD"0hHp~väkVTmI/w$""԰HDt B0b0`L`KN} eˌB &h*vi_fR2=v|, EдPC! ACv\^P-}Z«0ZR>~6ȩt a隩sg o1>k!ai; 82qdoTO U KgV}@ٳ[?71Й懸wwoeX'΢Wn% 8aԲ>!`q~НV*,Ϟ3ѳKV[M1 w霭qqEЮݴl\ǯJ6Xn0Hy%7])6`~uS,Y!mkaؔrTt|`b@ͳobpޙo;.',IxfhY%c0V#+ǘfT 7atD/4j!59sw"ԙÄ(-&cR9S(5EN(۽\? *Ui/L^_m."y%®KR/Mj&օyzXXGIGwsvM45Ǻ&-du%Ii3`= ce; (WI2CHbTRPGR%"*Xc]qL'ִccキsU-aG8* *]H5``< w{} DozH~][~*(\FLr_~?:|4' 3 v$`\O%e$Sم-&&5&6 *@_hy?G~<3xF[n#֜?>qNn*n\g>v-W{A `~K@jwрCYh*~Fpt"\Gy Gוf ƦCm J9_3dsl^73Y'GcW N1<1.gG0H̊qV#ElT[LjгW0^sڡ7Lpw(lpg7Lx&پƧwNiI!1lVQzr{q۔ˉ{YqX,- GhKF`h (0;&;bUċ#s8"S7%&FIPK[Ŝkಿ?wSBZ匾"S#I̱SU"͛Ju:$ 3_^r9rN$RI6~5XwНڹW:daUh^3o2wxUy 7n]-N-,{)8iu$ CYJb2S͞+cEPn"pa [c\!$cL)g&U+͇L vhuѽfAdI^{ Ni4む^82XQ#XMZ5W#Y`vӆb& 0 =7 AU0Wr6{vJqJV }G?НxdEu^>rN4je}ЕHHJajĊёc ý$/f& -r;Pb /OWr]5WzVKY[4O37eg<~?9lDjSj!FCsY^W{ 1մ:I`db= w/w&tO6WS!1 ;b.vk Űu;.QJCRuuJpkA`Yg#Pi`l gGl( hx5[oM}T endstream endobj 120 0 obj << /Length1 1879 /Length2 12534 /Length3 0 /Length 13736 /Filter /FlateDecode >> stream xڵuX[۶>\(NbE Hw)PŊ(P){s9~~Ode;;ǘ++*ꌢ3 edeb((AMlPS;9Z h AP j P6:XXxQ@0h0(@V_ hfb@`q';#LŘr7g[lcRd(A^ - 0ZY @S]RM %jWДfH*iHZ iMu?@KV %?ኒ*`A`6j @k :131Y8C NVLvէa rAl/W'/b\/tB')9 $hBKЋow30֦*(MA`(l 6qB]&^@89PaUeev^>nc`g?m;g,Av?;3/K!/쀙пPpXy9,/M* ۿT> OPk[0  -\5 GxPYt7fWQQqX9}@ +urx?%Vn/ÂWvY%h/Sjy,(JKC3g%bgdjoJd S,l g);B5ٿcFV&v.-_ П#_4/tW/{l$靿$  0ur2@ayi6NNKo[3} 8@}'? `VKa0b3_ _l` `G| ^3dV89N& 8t784^]̞H@i?'_s%C @mm\MN w}I`}ѿ?{1r `eyYĚ}*5/=/ϑ݁(3s`oy?yKtHS3h! 2|:vO+Iec"D蒢ZLsm䲿qLd474y[>>c'S7-»L8aal>FvM| CplSjd-u?Ι \"qI`r[jJWb[W vuop0kugT m%Ni^߱c5f{C7 1aj\/~4sXjeێEb'5Gs33#uђ{chUR)%gRG Ua0pH5b0ZUq eRp a. \"~ fwg*znOsQc_/9 7Zuw~Fp~+c1GNb/2"'"ݬ+E`=O247*;' }!eW`"1_ÔX`Ȗ;*>qqÚk D%7j`em㌝)’ZAyze\B酧Մ.̅tH;GSf_K[GzO/~sF{D^I`7SŸдx[ -D'ޜk;h. V+YF1ˣO!VQ2ʅR1]495T=+gk2_n|X)R,bs"mz'/Lю!aND0)`l-= fDeӌ҅'vf** IŕEsGޠ[pkj Y$qW oȄIޱU#P2@gU+J5_1e'v¸%G_uxw6,.`{ ;LcXQ@m6f|e9L /l9l^!0}]"@Ѧ g5?r.dHE=@jM!V0}ePGgcl[Agl+<Ɩq3pB">b1a/Yv7HnUaZ*-P e0B_:{?_Gl Ǧ, }O w`Gf6y$T\8.&8i?AX|qk7-=b˸Pyݸ^G*)7I4'9<65~b/7|I"U v1gX9gWyz8<?-1':ʉLJ'Cܧe {} mn|Ыܟ0謩EWd8[܇ W/N4yG.75[nRG$@hP%:< nfl CFlxh?jD͡ 螎>]k'3uCio#X qHo=r|%p;(hk \8lm]Bi.h[=3I=4ιS\`}$YKh@j#1QMXn= V M+g`HfL:yvZη6kr/Q!It\GI[teifdαϖٛ'VһoJj/.kf +TWMՋpIݟ/NwI5} '5lzv]BqK(cNLD=V.k4k(V^r2Dn$2؟zZڼo[+kuq:oLѢt8[@<>ؼ kA_UK4:0ky[>JA95vt%$ʒ:{||WK<'GSDȊ wmK1iylj&1ߖ[ㆋ^ç1 s*l6Jb ȌB8ޱOOo7޽e_;apG\-SfE/滛 C:3NSf!! ÞdMc.A: ϳYuF m~i=/_s`W͜ËVn&? eY5{q4-l:Wg`j}ǐE=On٨V礅>3bߪ:חpWYV2?=nu/ iD{/$x~_ҟˬzQ 5bJ@LȤ+1lUPh}] Ix*S1^xA)%[6j(c_P7E'pGrhN^R]/8o>b񗲿sЃi9m/EK {. TvȮQ_ՠ\Ȝ֓d!]8V%o,mE5jﱘcYԛP50R^i,uh(\; o@> $<Ǘ:g+m0~oҳ°,57vٗN{FZ¸R,}۔emmIdB-{ѴKӔ۸'"VO!k{OB!jvR VNo:Ry>艳P;ѵ\Q# ?UPF"ї `qЯW`E - Mj)]sTI](:ؐ|qR٥̞$€6d׽tZ Ea^Bp1Jvݻ>нJjnf@=ذ+a53IZYKٶ@xF.4X`+R"S5E%S۬MH b67M=^7C7Hg9jk> (IdVgHૄd'VFw+;PTTodA G11ZY=m(o^WW8u, rpT:j)s@ꕘwq!ͫZ<>/Q8c~}li'׌Hwl=h>0Q'P֨IozNJӕxYz!Dbk9W.I 0/:`h`1Ol$ K*œ2ϢiՌP;x76y^2:?LnA̽b3pmWD0a>(᪑Po$!>V'XPo6sĀL}pфMBԏ[R/^sf4[,Z^a=7͎?bAa"!b>oVrJ<0!4lFX"X7.e%_.SB<8s)Ϭَ3$vU"{t\S8\l{jzMaq擄:-2@475O9C" :rq/+\1+>U3ġژ>A-i^QFD тVybt*x:/PZҘ/}y:_ ʔub}r aIo"QμQn:q`\hp$YU]}TTE_)U\@<>DMK+Ta 4co.6{]H7kNo, - !\ᚥjěԮQG7&{[>M./(/Dl0?^@_ X&$ʆb=qfIO,l )*nNnCUc'S9]S*s4Ԅ~=ķ_|R9"JOjH|!xi֞^}Ad0m`a͇8zSy> ZB~}0ah?Zd;ul }M?5V_vr[d0k.n}\՛Ѡh0%*tZ¿/)WK_ A |U<_nkAFht|m'ӦONg0rLɳ,wOxnD>e (gu~N\ُSQ%xeDYoe{!I&W螻qE:x['>Tl@'"tXiYtY zP{1u-Fyk(1׼ 1 ] g*5Xק+) U ;)p |e I Mf@ {ܙ+V~ ,M4ޔ(UG"QÀ29 EA'$>x/;yAnM`D pz:i_8n8e;OBY:v vB=jv 78:}QlsU3:V_woS̕qm񵱛c B{N SF=Ƿ-9iͼ GS 9x!MoZSk`#O\NQ߰$26=yْ  Z1ynekeyvw`w Z/bm&8D{]׍)";9J p̷p'Z IK|W5LC3^0XͶ+qDN CR {e%%ZC6%%/9$S̬O`^j0L3Liş{\d}T{Xݗ!E].eeTLZ%ʞUR^7GgMvPFX3M.I\>iߓ| &Z%X4Kko)ϔf& QHn2_&gEl7IL0_C1Kp\'eަkkM Ur뤼|)Dm%:~@iDžU}&IkWxp?_JJ ۴ahVJ ;W<|,t22-Gd['-ewܯ||>}=G U7P!D ^ߜ!pH޹%%Y&=<7ϵijk+/ |VQi1NTGC@kX=5\h 0sCyJ2x'CT~\gdfA*[L=<1CXD"Xh5?oZY?׉d7Ŕ=A欩Y=[< g`mbSק̄aCEb,Sț3QuC0\7@ƣ[5ڦ@iO wQUqHukzh4%Vq_U9dL봣\L3y֖zڨq_EN}T0E9v 5RKܫ)C1VMXhK\,NT+>?LEB#4J&y|%"AgBf5 4Y_?H^ ) #[旅3 qyAb]7%_m~͢o.OQ8Q MBo{/LiZyc1 |f~}5-)08:e٘:\4M«K]~h~C3bz=`iZawx0N"R`mTin-Bب~8'm1mm%V~5YZ9%;l':%C3*W6_c+S,Ԅ8 v.X-)JogR})$%U[t*0y,Frve'bאEK8=խ%_ؗ{"+aQ#r5-+{^QÇɵ y]TBg0j*9H`,.#P⻙Q~( kQJ?z25>= ;Q03ݜ8jR.-׸XlZ/Bm2nKEb[6^Zڼw7Z&S=ĕ>cs&lc~n܏=XHIe٩Sd=}:yk7>NVqȈ~{Oh%#[ഐ?>75DY0֖4qlX H;xr/Fpj</Ƹ&#$ fk%6LA"՝}2wBMߙ+pfRcEM19Eg~Tp0( ȈnmrVO xT3fJOn>@Ud9Bb8:q_HUl^h& .Pi -DBʋA4Y [;]C"+m(gW_[7~ɇӶʡRK|PU_&':ڪ#وA[{-.{ס #pֵ{ډWo@Qdԥ9?,M>9VѺ٥kP/BO CP<nU֮Ah}{|nPx;\k*&1 zdM]ţ-jG12'~z3WJĮβΩ𩖥 R(ڥ PA|y`QigԻJxXP}04|FƯ?k!b4--mpa;5j^hpFd^ O@Dhyn !y:}U8Z2ƑFusi{|=Zmܣ1S|ƚ•Ax^G1?d7phvd%B^_ -b3;WcPKWP ,j@*K9JР&tK-Yŕ4AN]ou}_J)ְ.T3XWo(Q;qCѴY$ aK ?_F}<rUQ|5EM[ԞTWN]*q8nZYSD-l\ 7jfƝGQ|2-rSn=SAhı5ˆD>WNa2)M~Ga;wTO+70wj;ܯX)FfގBeFzBq~C,AC\Z( Mˬ ޴: Y/W i#iJѯJm,{5n ZUmӖ2pz=&c-JZ/q VA>lЈO#oͷ;h|MV;VϢݸ\/?nZ75SQxS@Ҿz>:QιO}OUw|_/.s07dhLIq&y* ߗureCG!6br\W 4:gb<tߎ@3ߠ3M= ^WtV0ڌĞp~72fìuk.D^el5 ftgfYO iIEnѲR@7crلmC,"XfSA{H (N/ܧ Q!)i&הTU`͙ ZHCޙU.3`WpGK?E!٫W8:apXh(T\\S@=++Yrr^@,J#N\,S+9se'gu,`3 G)8n1|J#GNFD?oaԉjY>66e+/`j}u&9bhƏM(z0f,+ Q37ȁeZ]錋aк9E؈u09dYym)D3MrmAӻ ݫsaԒgdzi |E޳H⻇+^IeǨ#b66t1eBlr|HRbr>G/Ĝ+ e$FǽTKv8 -omGFêAI}6Z(Uu{ 4W-* m&w[%xD(#ds6mos0n <Hs;5 Jn ! CS 4a01O~P,/7yӈQ"ǺݠHpHOn0FR2M\<(w}0D6ml`!xtBcB=^US w׺GCx~fҠ>s;Lxq < Z٩`_DWP}\9nP)TWEauX%+"UEaYΝ.m6)oS1`XT*wk#."klFa?ݠ 0#m5B@'nMj:"Ч'$2㣒F?Za3:R=p IfBlh#rnosrrO XA5|;o8'R9HAGd@D -/Ƈ!ՈHFy ,Vc+qfXqf"'{YZ oD|pӪpnIpKQ;ᦍl+͙GԮKf??5=#W9=.)]pԱsS>3Iw> stream xڴst$ڶ=v*m۪X۶qul';;m{~Fa.͹^{U$J f&@ {Ff^ 3B hb`/f0s30323Q$@ t1VtJ. &n=#EQO?"cSwg+@QaP;LƶsP * TQTWRa(o-j1a5qP U hot(}|IWVVga l(?##/#/; _,N6w'-Ƹڛ.9+S3OÿvHFip3_4))쌭]..lOտNN84#]cez޾1c{Wg濗m`l@-z?{feM^XAZB\UAc>cWzbr.nv+ 'cT;iG\<96:2[}vJ; ~=L-5+,Mvtp:}́opn@+Fp,\3+S18*pU7w\(4s\>ƁS. W[[c; ?:0c;+[#FG,m,a4Sr12K̽-cK29J3qX ,l}= ф&5i_QfVVN'rpY> ט\>R.s'?[ `cb0I/0qLxLX?ʘ ~ L&˿A ^^ANG/\ؿnLgS-C :uh?_'?;/`Դ2s{.c<P[7;;\lvRMuu?&KzML?X7MCR0Tb h$B,gMwo[)xRK(B0mZSn̔ą4ՃʻHie f%ǎDy:cY'QH~@dipEXB_uyĈ1^3* rFѡK/TZJԾ/.ՁVٱKM?ܸ~XQ52q':YrxgAAjT2-;Pvo)k`QEOl NUxiE r 'etvhF V̒2fQsFɨ3;p&BYcXbX>#>K #_?[+Is;C|U<$ HW<2~bE0p^ QO#㾼P9 s]3m+hWc_΢+3Vēr=ڹr}Vc,I쇙zw㏼jȱ3pqtWYg~ۊa7}YTT=g=z,C%_K}D'B Nﯞ6Lj^H 9'!ēU)MeX80&$Ӕ_4nQq|_L@*3HWS5#;BThȐj:Q&Owͪy&xN1 QfLܨt]a˃xƬOe#f_iYV.'`̠EXx0R|'4u_BEDbOR iQU(eESRu-4pㅞ <-%dRqaB]Mx-lxϢy)?G!s?&Si_QG,Gc^Yʹ"݈{/-][G5sТ`:CС8%`Pl50NF j]P #(:a5H?8dIZe N7\ȏư̘qx2d/;C}I27n+x+IVq pV77t}tT6pM538=v-Tѩ"@"hDPL;kUR\'bEXō4K p?H "1(rM A+d^W2 XU&[@ t*_JĤBYY{GLDU!2?TQy=,0FPDuB%yJw46ʙ_@T#ꅊff*Bxw#Ɓ CIMZ4=!OK&G8k*"`D1 47/:^c b?;YV {QyD֓rDk2W~ezI#;keZ׬/Z㘸߳i[ɯ[56T?҂8]A*N^Cy.D76.~hNtF=[64KB aǵV50b)\,<;O| #-C h.!{rV},==S!G"{ p>SSYG ==~usUBQ{w"k|%{tsVW9E2wZ-y BFLފP&}b\T;Dd/ݗSbe7.BҝEM6kY`.\%{-|JQ@~flрt" .Ў0"B )!6y`F$_y'y_(wطcҗgQW 9}n}4 ka!@btoЏvi2&L(!qQbн]ag3<ND.˛בr*K:MRU)* Q]~;(7Hu8n=~jO룍=[Lkc !kU&ץ,{B, TdYڍ+F" Dw-r D'x!t#kEW.!lדy<Ždw_ ~DsZ#`#(aSD \Fz|Tv`!ۢ$__궪 q(h[a͖ـF=Sw7yZo6v=@gτB S刟X!qU%V%%y(XWs!bddM/ond(  ݝʬӆQH߱+[+u#RDPMLUABIMfOʊ_^d1\%hLm2gyGf-.zRM| vݎgR~2ʾ9 EBA &ޫ,z߷.xA;w!m8Nc[=m흝Nq_GzkƌU0a)zv={>) `|g; 7 }\\,7x_ӚYzn&&]>qȶadrUU o u;½Ci^ у*S}gN:BZR|fVvΓ۪CՒh<Do=(;o;GIqNo QlaxYhOwgce sB:6jT-qHdR"|{A3CzB%`n(PA=S6gg8☨//NwgN-'<dYi䐜G,!"ф}beN.5Aahzf!VpD6t%mZ_O}+Lh%N;nuڥcwӏIׅYG 6͟_ʓgg_ LK8#? ䷡%_ꭈ7>diUuo$'8da]-ʭ%RnN1$kgw$ɋ-QrZ4A+Qn?p٤5<\e.ω9wdPlnyU$k(UH_`\/.՜= i%!Bv53)NL)О oyKI#IVyg{«sUՎ1{Q_n~)\zZGWQxWӲH*UTv̨GPKˡAjG&}i[")ll ӆ 9ᴒ]=ߐ]jzQjUHWkEkc)= q`{yBVw=XLbgHǪ:s5ʏbîOŢ?݆X)!{2B[ϱ Z2D˺Z^}iʁ}S< 9b4kuWI{/,#;Dʪ((az߽vM-]zOUʔmJik4HS(;r5ep&HR.-*NZ@~_+Iewt)LMGO07,-g龫\@:VBam,*Ee:(-P9n FίAgԡZy Qu8J:hP_O2.ĝbcЫ||yS& 0rMyG@i$>HpŌJ[4s['[pkݗݪm>v ߝ`t|/$tV%>4 y"1ier{)#,)h6=<N%n+BC8ve `A\0dgs̐,n.3G?Mňbvl:]!x~߬L-Z/ϓ":-lRbwn&FteiXdǕj{~1b9$V,ZӥpK洡[ bŇfm9MTCGVĶ1ԎЯKRCQ'vH;I.9{_x$1G'b_D<$>W4&j9?E_{f1aPC^"2ρ &TlO*e2UЈLFedfo(RXA+W!dHZ/rf|_ زٲ~6wCl?KtQՎɑ{FcOfՏ (5}uxdwm[FSqʙBAn |P&#'w=w:5l΄g Lhwy(~*zWlJq_ 5aF &yQr*r\PBb9 UrVKaUpՌ8 h]_L+"r/$4E NT#/ŽPPl#R;}O(JaoLksS"F1'`PdvHU +%9x`<{n3e}LuA}~v*Ʀ%ٻf\3YP M+ƾ|p7`R-%ɟ|̓ұc[\\8Ժ"~UK0o{ #ϽODz*lڬ) j@ =%!rBzڛJ WZƬ!\a%.gƛ(cqr%f'0Y_%^,;mi||P5XS\N)vPy R@ Q DRږ =,=9L҉˯y0&AIWם@$iQy[8 M,lbr ١!wɵ0z|œY4|(F,g lmIITo t |,Ezeφ?WϭfstgL/] dDXqG0Ʋy/}ɆpD\nM $g̡ݏQAx-ttX$oDe:r# =|;>x>659CtaJ 5@[O) b V74*ga#B{q<>>!=C_x.hx'5AhJ4%w͚%h4԰JOO e us͈u]XxԿr qxbX+V#Hl`L/  wXJy9ف]}gP|Y1`D}\`wO+&m]ۈ]QPk"wvڼ] :b09Re}/buT9Jn܏ma7V/65J-iiY$;PT]ЗKtq~”\3CA=?ߔM"LlBX?f}&.ug5t{.a[%0#! ifA5&,vsbW}2)-.lH0)yl)WmXVfh.؟kkRԪ{"'l Q.Z/ oW?ÝEhꃐ'kXOdQ|*OL?i Ii=b]f^`/DAVEjo؞ bX!ƿrv4vO'h/rv{s8}< :7|ɦa*(G#ѝ8IжvX_)AD6R |M]8-%#6񒦳D OǝPOCX-gZ Pq|-I-3ŗ7.!WXe c&{h" C1_淰FPZhcd~QB2@¨YlNVz*{봶[YoRt8t;CM:"Y ܎MbS]J$n=qZfyt~>ECP.I`| '?E 10!"KX6s+-HۚwbP0l'φjѥX 8q1dg)9ڣǣj¡Roa:`L5jCJ- eWOi}A*ӵykPۭoFzn7> cwRl~$zO Ofhw%)^=(bMiu@UAUimWf`mJ(3Y Z_%boQ>a|tEE6/Qi'*>H# M&<+8-_B0[ :G">U;WK]zIL=cQO%=z.: U%Y&HHb,j|f„sΡG瞡46Ь)5immBu&H2ɧeǶ6VЅ+ւ=j泯+2iaFÁu n3x따Uvut]oa!?:c􃭂)NB<ؗؤy|n-$F0Zwq%U1dL\aɳ{%RZvh !tAC5Ik 8RP.-nG}{|"~~ .ӊFiO=L_d [k D)*:- &!8'%k25E0ҴqDC A>GlpD*8ar[;Ё^Z[~pgɿ|[zofoo$z939+l ? n)23<$TȢ`dJ{1×3 #Qҫ<|3`Yo#dz7YfɻX?_]h ;<):ڲɽC\֙AJs>z=_Q`coiQiL/]WT-SLkR:i"+#0mon2Bp%àm 5v_K.$+:| [!F dH(u0<]*{洧"io77 +2 Y4ԮA >\cB5HbM{d 3Rw,v+mMI!łZtE&&/G$8إ؊!%N}58pˏI/L|^dMD\pm-sq ?v\̺&!ƌ'#:S_XّGWH_ƒc+!$6KʤT#Uɨw4~9(-raFZ Eɋ/jl*lΎ~1ӣ>a Р/:2.pYP̃/݄/s~0`DoWJq/ƹ%;((8^~^0 z'VYJtY%K,ii¥&ZZg#/De$ ?]r\Tٓ3@8D驏GNZeg$n/;,EcOF4p`hTSbӴ4=]]a)Fa9q4~`(.ڥ^324f)k'[ŭIcu7}qi[L״{QrpgaYO*,]>uhYS/8L@%2d[`_UZ߯ H' jނge$TPhP|\źE+ʸb8ebM]OoUZ7fBx%=;M7LO`wH`zju'}jV4D䌐\!%U5#rSG5L* Ҧ!Za~ Ngܺ1BMӏiI}5=ߗ|wH9.LU좙L]e)*TN=b\%TV,|~(Jl!=*ޙ-`՝5 8x^kvX=c#HIV< DqOq%|yayd>;ۈj׵zPgw]w8Tp*p:$L⇨@pm}bcqN}w97}Poz`tֻ '>FD@QRuw%Z ԫr Jñ⺓li1kogHLe@Ai-)2z(]AŲşY[/s .Yvh|O $5Uc9݅tK()Vi8LI.Iʵb#?3wNIuIR<+:5>4:jSqIJF>RsVFs<1u)X? :m,7/,52/i=@Pg$L dךiz f )ۍR[xhvujҪeDđj+"cg W@5Wտ^+&XhE]Y8#r% +}|mK "uMhR+A ? Y;XeM'm^r_R.d^ Ab$'abEtz2a賊!`տav̿&{ro \HT8,ז&T`e<:e<>MP>AsNIFH`9hL '(W' 0) >AP՝Fve2*`;wWoQyQ3,_aE-C>E·ʏA> "x?6% ?R\[ eZeS|(/ |~dM. uu)):_Պ1=˕m xBbBĉhϾwRpw*2A~S!˲ 'IƮ 'Sv{/*"kP;K>C55MRR eKz2eS6p ooHPU:a;6m)nZM-7HZ%p{52"ZU[$HޮLB_Q|m-gt>@̒¡횾#.KḂp^GH(Eb;whF/&5R&{R7Qyw QJߜTel߯P_G\S{sKtOxē|E K%!S:`"‹H:Ot%?v(=B"ՇE"d2x;gai"ْӇ&"܎&4O9o\M{D!KU-'T^_ ݬp̻Թμ"x*h!0 xEja{iټm':puB4 'Цg1FBftq}R+O2#K ^H QR:ZCȦy´8A:JǴnu䖴Zu}AZ-2Ioȴ UwQ}ֲۼo6j:KQ&F\p?X诳Ai͠JfzR&[LQexmb|mxPtd <{_Y{eS O(3ګvJdF k)q31iaL+E* aT-6: ?^Ov qpM! FyXEy.p2)XRfS€f5.Q1 %8Tyyu#S79p8ne5k)Za.;`3yL r6% ίm"*3w uX̀+?#ur*j_ Zݦ /ݪ j\|5M%hȇnJPy0=D t>%V[ܩ6tSid9z鏖F?0.!3ʣ$F_elMK| A'ϤZ--2_eIfӃ[ M6J1]5J;P{ec) Y>WVv ]5W%PmSSNfw ~Ɨ!'9|A r V?CfYl+. s'\"\D7›&F 1@zhnlPL7Xr $|BJ=5ke,6Ωd&sd&ۻv;ۘlMl|{ukK/fLS= .Z=_DS7ԇc6P8(Q~s""~bX MBr 2/R%˷ a.24f'gcNDq.r-A-/48cN0m/x%ߔI qR/mkr(rGf ֢ 0TN}/=22Av7L"n*.ML L3s1Jg#|etr65n3vͅ^\S MiQaSɑٰ@ӱVd`^0[fj"zDS|!MpN*Uw:5%Nx^rlali3잆`{.(\ ]s(bY\ɭ-+G4@ ᶁv1sbKjkl9>|'ocdj{'TF8<ɛ|eG?%ab:څ̤a(el8A"luG ¥@!ыGW暭hMr"*jxt6eG4q>̰@H W F>)mHj8i/>f6hxpRKa2]V2~@X ȨY~ Cg.)=?ˍ Jd2IL7n&G\[:ytRP4p$ ᠢ}Mf("BPO歏ޭ ='SӀ)meV-P=[+Rԑo_E+6D5/ZFz -{](Q*G}ޞk7GDo 'Hα$#8HL(iHIa jjkHJ`r]-x_o9CQLf9NpY4 c]D.é(\_&A&X;>&DYH@!O*rh']<]h{3Fxqx+օr:bQ$zEN1ZW)27Os>a+6o>l˷_Q'|!+zƊ`yS Yg=ۻ|ɣ'&VsK^Ah#qVI~Xz7FH x?-fM,Í_R#h\{䘕ڒM:'(B` er9XYR|ptWÃ<ŖSfw;/ i}`u .TXc`J;S Bwϫ|7Ҙ+'suI9a9Z)C 􏻷)Õ'61Ƶ^9d"5jn@J 90g% J~.'S[Ql3UL0$S|'5>n*lB7[5,'?e9n9}#>dDe F,tӰq&u<#ņƥY\Ʈ~N5X!/f"m"} L,m\m6>!&辉xm9 DzJr8;#%0xLGZo؟3)-aHQuNXm#I}qAw;Qzu/ dd8i D))Vlˊ36©8+Y/Ib.v;&†겟s&Y_@,6ZM/& -Bf Q'Y7*!QsmRV?ކaYYu63;sULkao?;etP/ f߻[vPqUh;x <T wF|ɧ42vEk+n %3/ڎ, P:vUJK SϏtn 4M8FM?>aD)M1wJ5Pq .'0%?ykװk.Z^䐦ghOk灘bTt:iZbPpțT$or)KvPv!\@nWL|By^|S~zNԂVCw7ʬZ*Sz'7bO)ʐxwxǯ\c[>ݦ!u)5Y ågdv1Q==< j>(;lM̋80Bi| 3bHaj+™Lߴ4]MNԌό `(}HeA]NTݭ3s ۣvz+Z^ۉ>Ԍ =n-7Y< kQ$gK IN͇>bWkg O9rMHM3UGkMF2|ߵ6ZTreA3"im-\C$\Vy9 rmN,K /Gm}^-؉RkiZlHKE@t"Q( zuls~Yd4\%@oGy˒]2_IJ`uGmpGňDK"o7HiiG؍a3yO8ζ5*s_I  0҉/_nHLN8boBpEZ+jzhaEY Skkp'vqǭFERU$lv4lU#з?M6Fs{gLߕ<ВMڥQRy<=.g|Ho"t\0eъU a%3ז;倦cDI¸ +ZsqL=aԡcch-Tm(H^xSR(}P:ې:QGɼ~@/5gvUx8$jZ7w0I 3f:&3s -A To5?14҃+>Q*h.pKuG寲k kȏ҄{S%Xx(ba KGX&?hM\ЇoshiL1t}jV kިƐw洱D7 =ᇝ@J)&mUfU!e/I{|$w\"&l\seZYF:5f_|P[(dM]-_v%%I_b H(f~LTK[X J>= S*,G2> kW;%}1wuP90Y''7s[3IvOkiU um: ]YU=/n.+p %kY=#R}uzd}н K{u`SekA  A_0Y2N#K0j_A9o)U|@P&B&~bTqYAe;?lqGG^]V:7(M/j;Ӫű]g6`Ǿ8?2~{ 1@: M7}nqﺹuyq$UK*bF5ZA[S_2!mꐤ8N8xqzvլPN/ Ȏtr^,E$HkǏԙvVBwx[Ǿ[<-Rd|{46R U[H u;hXVmk]\3KRcq,Cb%.1heοتp>)Dgv;7 !Pn [v;uZ`M۠;!0R؆|gȞd?6B]z\}_>aY,-˓fv}V";&yvEL*St4;ˠ>b~M|; ܉?n_4c mgJdF @h)H)70WHgw?cG߼3CBjDοːݠNP(muDdo2-2-]+gT^fmx)e]Ue@l/M݁'wr[Si?h%OPHZ3WK>27p 悻Wj~3JH{RE_jq[Ͽp86tB ‘Ih}?LCee6yQxʙeQ)deVi|/0%ec/(i #Y_r(?adyN Nxbhni.G}Mv%_[T5K_E?TC&7.poҡc-)J@ǷFtf|îۉbDj2;/v*"(s:7V%?m?77'tq񑜅@"L܁/=wES)#9wJ7`LE۩G!]^/RC"\\ T9ז ̡Mk Z4G" iS 7ڒF;͇CQ.Q_dJViNNd$/9E.~Wŝwr&`ÅH+;Pt} 9/| D4z“^0Č's}8M9VQ<$Ii+m4 )\mAgG#UMrP7@mfep$ndhMu ,ώ$9X]DQOa8hYTB&\&]56}?.ϱ _A!6ht^Ina 3{EkiłU4=^b>j @mnwԹƋ5fL{Ś,=CWOgiL wAA10/{B^a'& `;`$- g= Mi⽣ y(5>KgaU!R-~$=&8~MX֬^ĵoڃ?fw0ͳ(DF=V.6xq1   w\p1ϋMT|=`Pd] ݒH P 2:ۺK"Na0( L23PS{q*k)R;{iQFCjẲeF4bR׏ IDzZHm Ԡo 3C#+:R78C]f#]l1TpZ= :{:j^܌^9 so.Rdm$df451#WC ߨwuQ4PM53( 3F^Q?;oRX.2=8.?zvZ޺0JehF40y5 4L1`ob$#C~g }=Jճ7UU~=Kҷ"={Q% TYy8߉:d@.'3%67aW-+kr !M ʂw#h Pn>߷GƼyE.@Om&-/, ϭu]çi\N4KzɈ֔Gp e0cVez\8‡xcm AJGM E .Ёz@' r-Z߽i@OJwŌ] ~yft .Y\!)K%Z_pdaKK'84Ca0v ;)Љ05n{ަocDKVڿT("ђapDF \T3T#ه`6pq. -4ͯظ/0_vH&c׮w9%"7"Vϓ4`P9oD"A\r4o_{@L(EH*Rh>ݡS#!Wp1jm0stIp3`07z WT{wWK{m⭳oqBa8vM4 ! TDԮPf^:t ȢV"pw~!Leu%dYu(qi6He4ԃ0+K ,f2%nXҚh  ñ=lP-}XI ߾%w[f[aN,,B QۊnI G) f -ڹ 1hCt\U[|<'`, >QZ꺖vU::s2]x>ZϺh*e8r)u h3l2.xq m$U;0_x*8`bQ}l6 ; lXF d )̬ƛ6zf OI%BvG):xeC\(5 mdr DO>4~up˃~kd)1PKR( .5 Yv.s~qU>IV=Fs7_J4!M{2B%~GoaRMmA' endstream endobj 124 0 obj << /Length1 2791 /Length2 28974 /Length3 0 /Length 30580 /Filter /FlateDecode >> stream xڴuT=)须Csnn)FAn~{`s^sϽv LUI (rcbcf(*)9XԁV.vfVVN$** #H qS|HT vZ̼J@7SMo' df vAV6 8ELLG- 75st,JeGO@M-M.@KCJ] A XHhhj0$Ŕ5@mFﯚ@#@Y];]IJSL9@We55p?nnN,,Vn̎.VNӴqx:]qYtkߋP1\tK NC ,1p?Sd 2L?4"Ho#xf~b wWi;\m\\5"`icـ))IKih2)ĤVO$ `ggT d!f[>INn.,O_ہ=Ada[y w'-;PN&?6+ṱY~[~~2:9:,M]~6@7$_WS  ͂r KG߿`&v_ Qd Z"(;?jI+:iW3uJ`j?>Wi/?*,f n}1=&~&{pۂ'|4]]|`/Xl,zb: O&2wYع..H>`[OXAnbrsX~x,/EHX 6`8,r'E(AJ AhAzL6嵷36\ tZsx0sG{pVAp?t ܿղfiݎ.%C[Z V+l jJa d) p1pK~^VQbk4xLǿup2RlguSpso' dgb`7_ 5x:R~#_Rs]mJWà L׊W&Wj>EkG(;_,ϟS}.*g'?CF` 7G;]W)xoy鳂&6 ՟[lqqG/_&N6L`x8~o-nJ5+[|x~"@/9ʢ@mzsxTL,I|"JLd69PSPk`6'GEY~C P.U(/)7j;JDRbyZJˁ]tyJ9HZG|S0 * `=Z]1 ;g:!~=`ǘϛ9v1jf^V.Dmq"p׊~T?#*6")ӏXZ.cDqeԷFJZ:ɽ)Das©-cyo`8!mzwqghZ^wnJnN_Bjx%b("?v>/( yln-kJ>u7ɴ9 sS4p㻻K2Ho]Ax+uJ,U4-̍!A㡎YK ݯ US/I|rz"q :a++>w&pxZW5vf "sQT<SYI_=vhU  6yg΁/xF}L,VVV_q'0Zv"Iy5 3J| w2ĆVeDCPK@Qz-4NR4WoRֿL5^3@KZ.9e9dl~ʆtGl͂\F4{ xvBduX/%jqIY&/ zZ4aY"`,l+Eʧ_bqAzKFoXnMhlv >c ,\#Cޙ('`uNY47 5vn6PndWd/75oФ4 |ͩI"ġ#Y"s]iӧb7rڤOů&zW2`.)ꢊ])tlՅ8(*&"5}Zpnĉَv&)]Gg1=G ZL됤 Bˍ#[y!KQBR-Q*Qx@[ dlU!}wfR<ކ2d{; #LLco15CΩ(=47ӣ3alIenqЎs' "$EׅK|n0"W;,='ɱ /F^HcN);@ N\gO=|/nYWV+!V DZ:rDJH{J-Wq z_Uy@abH;0Gfi/R׵uw9(yۏ^_ԟc(pYq|@s Pm >:5[S~iIvqj$l D?, Q=v8&{/:q)$,>r34isNz,5Ey <>6ݠHH3Z:w}76SZqkZʇ(m(g~gcR5gJ](aw35gStYW"d~&?`Y%Xf:H" )O*EVGf4!Tg q:;|m}`ZV?L OIobl]tcp#©):f*\t"m}_5jFA쇎 Tz4ëD~7uq[4cw.[ꦢEZeĎJJWw=P)tO@Y`j(AxLtqw5JVۻoF:߇|[Q&`PMvQOi-]ٱj lA6cMyv97qt*gG d uT5'n%)d Xy`R]式rfJ*/ ~<ƾew:gjęw5y#Ȗ_ ҴV\&?b|ĮpXr%U|:&R ]f1LH<]E+03Gz}OK)SDi&­LPH&ÑL{BE1sʫ*D)* HmiȒ%[gg a;`0\i)KS1|pn6h{D;NV|J)ŒH{˄o.V(DJPߌ#Qy~[)aRy;ۅ32e,I~bn#'r)Qq;na]^Y^!qhrhj.f]Nәy->"(eT5P/GU|FtkL)h52 +id$Q$\E%ka_-GPT#w@W o6 ~+Xt$ k\MoF}3^_Y?Q}A*edRe0w%klჅo;5@AܒG˫kl)=fO7Ȑc~_ aY=n"b sO! =M^К(FDϊr{ӫ%֣2Cn"Ba(~:V,rfI{e!b1ρ/Ȓj\fI4ZlHaw1믩ҐI2X+ C].rn:,\ЀBov{}(TR3MI fTMXzȪ[ ԡb׻YJVGߺkҞh0cMP;s׸OJmRE4=Vz1zseW^ȷM9^^I ;}2.9q<9l2ij`4eUW6QO!ͽiOeS%K`Hն&JYND+}IV*xZb0emQHwco6;GLQdQAhȷr0; ~FA3,osC%r+ciw[WޚJ'L_7?yx>_2)1!(UQ!;tD ;.۫o`'?ffDƮ2{DG ݌e񫛇{ UV0Lm5YZk85V 7 /mfF|eC܅'j8<-W41] -Ύ_&Z(Ӂm_)y"L ԡ 87c!B7NVp;ԚɾY:?9{ٴ6[o8!~ {7wW"" K6mZDs(Br)e憷kؙ1!͕VscSB@:bus~"DOk*h.uJ=4ʯ>NNxx(ZsodHPW=EvќR3INIUИ)SWUKY7"m_[R \9(j|`IK_@ 3;А` dqP1~6džwQo&WKx(rOu\ b<ǻ2%c̼13)5T%`B͎Yٗ&J|>4Won^s63faAH aN&EJ Z ʏ[L#6(]<ɧ[]^ .@r$wW.Uvv>x4<.$ %֥v+r|Ԛy0ƨ;;F4:AX=vdū:qI-1(]o׷Uuq~NתSB2ѮzH'm є~x=ߠtkXzլꎕكd*;?V :c إ5u 93|?kz5/'zH),_X%I᪞Rp2V,W~!kP`7/<=7`<[>KOc( P;1btG$w'lvIYkRᶺ d#P9p G` $Cc˾j櫝WMSocAWsUX+e~AKjrS6'-8ij8q?ѹ^`uFۈFPUdi$Tk*͓·iGN&߇ss Kxq6 fLkfV.R0~?| dgЬN"e1!NFOB #)ƓOЭL/ܽjMexـ) pUޒP/8Ll3KXK7aw9i.eH6ޠ؄Ic2פ(*yD/';_jy jrx438ֱK4x/4!X[fכ]XϯNJkzS`kx"\fsG9;3%BI@(hx9d/ XRKqkC'ߞ]KU3>c bQv|/ _w я70k"xkE* ]Z&SI:XE-cnݴ.ٛ$t3tl [RkK</j3a~ -|}!\ndރ\*}z' g|@GisWz4Wv¡iuyV0otEpWN5od p-%Os#:1g R䷹n]J^gf]of?5RxJ@k(W)@/>!'~>XA PJ/NF\Uhe&3e7jkfh7oHd9QNcޫ!sPehÞ]?#h q0mg84"e")l㦐 ݰefş;V!w+ʔfL{#!ij1AMm30djjz#Kb @kH-0N#^|BN]&rZvGlmljScCLjHv8!]j!MB;P^s.&.:\SU/Sς8-18=/ l.V6.5]#Lgf N 0ǣˢh;,D/o+~U-Fgq2M,|Ej(֍J{S95]iɭ .t9$rvi{%UG{e8/.`|&;y] S6N\~s|U;5o{6=bshĮ{nJdTiW 7i"ѐG#!;rT p_h)@֯?>> NHloѽ3BM7ovd2 Ơ l'D{!b" 70-刔 9l x{}]hLiɢ50K.4z;;Z1)/\Jz>? K?I ԾF OKMА-St{2 ;N\<כɁCU,Gt T\ gڋp vqJpȎzo5]ìE *;ȯTa5w}[JwYk^1Z8iuBL[+.t)H q&X?I;Q8'Gn;#-A+D[s1Qtآ z7#nT[Z+",f*{`{-3dX!80rF _5IpL䝪)V:"`}NI:QzƭR2ɵGP3|쾥8L"G,;.f7=:aHy%c9K9=қsog>Nu%)_(v\%BڄB8 š*xAK!:_'N+kt2kWBu]UFWC5]=7 U/9A#Fi~,Xd48 'Lc!<dX3ܾWhqβ;j}bTPbI]?=Gj΀h|O7@O>^e؜^}xOoN8"RMH]0B@0_yV] *C1Q~э\ gQ')#܎Cud.&М ;.$o%&HhRm]<ؾ1uR̬u`A-ʸ*i5~P] t]{ y&H=QF<«i6MNYPU^&g9\ k6Q?jrī9b"[N$do/MX_RϢ`x *-S[E Ucc~ydq3siA=V I_ 5VNB'B?~Jγ{E#9ȭF?Egbbay/ G".e_@ǸNG8d XeSB~u\Kľ+a{":SQlB)#^`@ A}4r5eEG{Ԯu $iV 1J<j0NmHCɝ-\H;^83C]H8iчE-ΡuoFPoU;|,RsEӰMg!~#>x1'#wXre9o9`6o)KqXd>jӒFWWJ)mU҅ *EȄѲD\ f[wQ90 "jIma6d>ؒ.*, hڡONۿ̷6&%Nl׵3sŽ3qǢ)L:/l45IƠ5 8$Ri:{*0I ȲB [%(&+mS cj>|3װ^[etZ^*LAxwY+b hSwdqd}st $pLW@ӈzG6 BtT؆D{0!sVbU^q5S BW! pVQV/ W2m&2R|E7% s-^,6эo}ٹQڊg͝$=Y+͹ `E uG,%_hAjc/'?;O]7p\\Ncv7JI#?o2 a P.Ďal0S${d\I4vE|TyT^;lZFY99HWw C_X1p qؗب.BZm(qND|6Y%oj\Z! HOVU.̱ *8N=\7/NHy~X܍t-\BD>%Y~bG:z&ߋ&xg'.9Dɝ R/|MlO9+4M?k݄m`^*;CSTg17 #I! o:) p3)ۂG0.p/I'qŷp<#tj P1 ?8~%mofsTwW{T1nbbVoE9w3:Ů}ưxs0P5SM3HnAP(H4xIGMSŁ7:H&Pd31e3塲*+M4ig2vI%ljD'/&_RM# <@&MCrF؏6uH_ F " n O$]˿t0QJf?WK4"9){]6V^&^<@jt`Цl#F%Qјz#=Po0$D+Fa)~hQDM bm2}p׀-;Xm>+%O5@]kܱ*<|Dnuיt̀ LǗ}SDa.aZOtμ*Ws$|8P8oB"/SJpnyF!>1a*ؙ+W%p ׁHgN$ga~D~m5z܅]xf4f8b*:Zז 6dҴM)[P9,64#+ml_nC%rFzIe˹҅W>}U[آ>7ҍ`v >yZzIZ9 \^>EpގM΃ľKBY,4]^|`+¶n/+W%NF^H,AOXW>J&iB*NCWN o BQm87dKߣWxC+dXZ{)Y@^&;#TMqÂwb1]!OJ65_JZlQ*`frBTlEE=_;= 7E+ ˹;)tB8g+NWe.HI&z gKt UҀ. m;wj=P9Qzraȵj E ywۡP DՎ4q옟=k ]xйЦ­ 5@!ppElS?(4Hrn{*!hÞ6\@DX1,wYte)> Wxf}[ަM_ XйO /EI*nOl" tx⍉j12YE8\ԚXuf?%IYCZzgِ<ka]TQKW|8{l.zdߓl$,]*SMN5k2(/.kSM "32ëSKZ ۇîû(h㱇p<%&5c§ԊвMҘ.5\7M܍Tȱb ZS<DnstTJn_ɥr_LLĎ]\, Z.kY MMȃRK0AQ=c5$KPjZUGtS!^M6RD~"ƜU5g+,֚,Ӫ"\v^›s3BϷM +'#悈xeOW:iFRK7'0KV(+NeGq%Op}#vRy tj::7rWE.f>*kNdF@}[8*,SE BezId66(=1G~ʡā5}ND_PbEod2^͂mFMaUF1uxGhAi2\gCYYW(F0s?|&pQ> 83U6fsS`ᭇ{* _6So 4c+y3mrKO2ŏy P%zwD'Tg?S׳sIy|1$LXdڴIŕ"xkOLaM?Ql`jCZ† A z({a)k(%Gj|;TR;fK4 Ց=M8oۄZfCu]aB-@A<-t@m!juPl/50N2UUYIfCM9%taY~$➴[ JM8/JhӨ&V%u@/>!p{ŭ4:F ]'l3 3RҜX\jhrzZ J뻆 18,:)#E0T%ܟWPyd$ųK̝'CsQ2ió0$鑬r; 3W)F6}e Sx]Ny_P(!5=J_\׈=4?iM"τj8p]#1ct( jro?J!N۷+V} Q7>x)YXSi.95W#uefqX( ’,7Bju|@,ŁȚ]7PRK{Un*}m%Ez5X Emg a9?1C<(RMGbߩOs]9_J{w\]3o ҈>Z"O|ା[LlSϟa,sXX`_1+p1ug6:I-Pb:S$k“G!~| (|-#)\ W j>0F@![sx54ȕ½O(^~$\e?T9t36Ӈ.#z>(mG(ʾp5%޻q/DA0K`v"^Pb _ z;~$(JA4ݽ%7vҚXTmnD=d)D.j85nx\p=U&-׎ODzJ;txlQ̞sC$hzR9D%AF i~=Bc\# 5R-)TtʐŨ*di2if/{Tgo>W@*өX\٩ ܿesMl Ebs>a9[+M˸/W&Seḇ4Deu}y Gų@g.wgCj"陮HkFZlm!15v'+Mz0$voTzLу#K G @: 9/t/ &fL0yVH%N-=lAm*U/j9z\]t +m[LkHA؞icj/6ʶoȰh iV @FD{`<9 `^p Q#jjoTwwLFTx;F&dAfՌP{O]җ-0e]>*p" [doR ׻iSY/>OG=gN;(%AS=OO8CFfyFԚsPΐ#с:v[ԏ3 eӐE(N&Y22up Z\1Wj pf]=c, FԾL&d%XZH>s]k@gj皰uT6$ [V`/SN˪Yx08`8ː7+a8,Ni.S}N]ogFuVHv20x"v>-ukC,C6tV⯲bYHý }H귐oXN`'xqA OMdn(1ƎK[&0!dEc xT A9}гTUƙzp!Fי5U/LK@ݗG Q^HɠSw[/.2 gdpߋ_JL]5t;8. pFD.fr*<@ 1U#xXIoHdϤKW'K mW@.^^QIqGrm?#eR<_{I8jhn:f t%soaB<Ps" v9t7d9(] BFc|ִGr=wZv@*(c)YH514|Ϋʺ[Qlʼɭӕ;]hޢ)> j/|.D5gUEw+K4n| Qhz$םv3rZ@Kx/\z%c2_).x,:Ӗ{?mДފs >6EnpL9ˍ;:RxE/nJg|H6ם+=^"]?LWlXge.؁@U= c>B0JZ.YϠw} -20GR瘩11d03s[~b?[fZ^YN+ Z{-2 b쾛JGڑ#|[Q匙ˁ hiX*:֛F`Z2 D06gKY5ي]WN1&jEpVY]#f Ro7-kGPZ+39雒XŬ$H&9C2+rAt#B<$|~^ۤ:AD Y'r:Dvs8IsV)^"~|gvB1pwHŹ93'JmYnG(D I}.)><*SgG)Tk˸:{قʧ|KI+3ύG%NY >͜Xݝܙt% E}KPן5A|86=G4jCP;h=P!L qǑL fGns)@&IQWn@ x'ǩYe6\PJ^#a(Q)rYuwnMo½1iVh5sRobjB74zt/+Bɑ5`d l1>`9Pl׹ kFCz$O#-~=|n?'-wb7ecy j;:,0vP+rdT)x=7WQ$qẙE*c4 k,ӢgIyc"O+S.;SX!~UpGǝkѷHLZ3ո#jFec'£EDh4=ÆV^M/rHDa]^Lr.EnlV*iYK4oٖ/Wؠ|T i!o#x\ {یƊn I7!6D)Ch !s^6?cw[[LTB3޲-z[L8PNիc-+K=- ](qTqź;?-/WQ1=Ҩ8@# W0x6/ȟ/(h湈hCg):O`b鬒(}^qʯZYrsL{._O- 6_jt>r4@Bc QUTp)eF%hXt|5Aou|oZ~j.l"V垂ظ굟"+-{16{uɒHб [>D+ɓښŸH}Uda/h.ea)4q8,h\mӟk 借\.G(ii{"*B.=AFU.|keнݬiV{~ |կ^1ȥJzl ;SDDŽQ߅jbuL9ĎdbR(;OFez'.@#Aێ gFu+`ǔ ?X5PFb5*QlGXGBU%[z:3?J-u?6Z%ai]5j}wEB ĖKz6CΦ ,h~^Yg84)KyH1]n  tP`MPa?򈦨̋"~n0 c 2 `ϲ xr~E㧍}-ʙ,6;ɖ* >Ж.\gK8f@vέZk.WMśCܦ&xu^o7NIE%udzr[aJS V@po { xL6rſ+oMÅER}hհurd-0m%_Oõ{ʷCUD4&Ns>zFr;5@O$yõ)aXz?`1!R>w+#u7h'~0yG`Qe p,#B,ztCQ] 2 0xcD1`|ʏ!6d r71W^wge>SV Y1S6(~oS-FSA8 B!/+|>=Tu*`e2"u'FAx+ma' 3 v$g_b(FZT/7PdBXᤜk[uyxqYQvym06g Bp $g p"|t]W56uDZD  7xD)~19m vm9/90S=: %UMmC0Y,; bI&f#6~7 ' xoa8T~[=N [N Xp xf{/#` oQI ~rCi~/Dry`{"2RƁqmOkcb{iUϡߐx,^??Ep9l:/ #gq؁ ޵3ڮ{ e"Ͳv24Nx'8:$XZW5"N9MN/&f&cv]L(Ty裬T5nSIhu4.źMtW=TȪcZ:8i@/?No;\XG32LMI(i sM45Ǻ&-\ӥB"[X)9mh<'P] XBͦHKʁA!,7",t)} |-OʰڄS Hk2xZTu-lLbu6BzMn)7a},37EJT]st.7k+L?؇DB [eKR?fQȫɖȉ#P5_k]I*0O3O>z"mmɦFi{nu ^mY\ZCpD fs7/w`uMΣ4&rVr l䴨@0p1"!roQu5"TL3c9nw<`f3 &=R$hi.FFe^_QxRrPT䧈o5a/IqW r*~)?D,)7YCg*qN8%ԆQ=񘱒\'z321_cՁ㜑?8ouxu!Y(F)m}M;y=2d *UBg'W1VGkݣ=S!HPͲ7`Argٱ,Gg-ҋYps19x֙b hɑo1y<_8m%7;|ǜZM3 ȥ~)Hq"NBXyqn"dma2ThĬxO&tx[BWМD,5xG@v;a˭=POK]:ÌΫ݄37[Ul [5+o(RӓC`Ψ2e'%_P2:Nk`\Q >e#䬥 1s G *6je/C+<ﺬD# ěO,DƸ5;!X?[U%,M,oTN2`=SqviK)Nz[C2')f$!G!O)TQLK_%<FDxղlNa]j6yx"9*c[]vnSS D- a]U4\<k aEwX [ l:KAz!)>*lH|V`e0eJAJTy3PI=J1\{ 6eru< '\'z~`H\<Yɿ'+Bi$!^9(Ұ׿ONSg% %DUG!ih}[ YbL!*{nZ\ FE!RNt2$ѯOQ:]rS30CkaBݴ:&Zg*jRfM JpN,$r?c QINˠ㎙;;p~Y&n"@B&)w{KI]Nq߅Dݸ:%;jOUDkౙ~m,P},İq (M@€$N3מw@O.rpg rس(=W1vG $ *vDk!ڥOpYU)ؠ,E?ҭ b]lZe3HJgݭѝ ;DKէ/!%?Ҭ.` -T!X& AMs3A1FxbOuS1$L's\8hR VTuq!OO!M iyr|B_ MhaYˠ5_ 3Wf$uE~pu#bobHA59[sR1<&H+Zdۑǖz(-_mahc{yr)m;+F#k=F?Xv%oy8ƀR֑d'0百OPK`0t乡HRNNDOĵ'5R8A:`I-`&n ) nTZD=Lb*H.hM@17Kp|Kތ@4X\Ye2`- S`9Eq9,9~E=/9]v!=#7yW fB{m䅳F fHs[!Tt>/Q_`S.;s b< : *X9L:E}j8}tK/E6 "ܩ97f''Ehŕhuݜ1%Cp7nC %'Vrne);,W~c4gOPțKeI$G]Gɏ3u`"b{^*Zl3>{2ש͑/+pZ'W࣌v,2&cۭ#Vu2ɤy&!yϼpdFƈD6jVWQ5{^)(=JvNjތ[$ikAKSQ.D!ѣ&5."D_ izuݬDoeHpa(󊙜ݔo||@'tz$H\ʆ8sF- Kà6:%;tU`@POPK3REnlkOk/T1K p󛰳2TD:R\|XIYhzlPl G!0N3pzCN$ &*kh$;Գ2h2 Ed8eY<25{/ߠYMq "ݘߤ={7tՉseFkiJ_I"5%TT}ٱ`Nә9 0[ڌ :9Y3g6ݠvEN?էho\&d *3E>{\&QϽz9r[ĒX'6hTQĩ' %tHkХe_hD-ķBa!-ĕ歿}JW*Mm"ug슐i7r-VkneI2C`|xV-\D5 cZ}20ԯuѵ^JD*]R`a: ɘlVM= Κ(a@vz'yk;XݮuS¦զ+-$Ƨxs(Qlp.WjjK?+K7ժpK ylk})g*Udvöpdw6! Y#m5oWujT5pR(}DF2ld}3%j8Z׵bǶǯ/rL]@927Cλ}UHpBLG| lByfZ6ȣ5 3:RK4{変T>:I9lkخ,H>! E/n}X dRe>q{'ٜ6OQޒ k``ѷ7;G˖d=+DuZ:oE? SfOB,cS w_YrԣϱUnIcS*l`0rRcT>Л=Śqe c8@Z<Ϗ8(?M7M[C*jԬ3 ?Lzk=^ 's$=Ki!6PM,\^zgaxٚwV591Đ[|_IϺcHhm'rmNfLaso5Xe{>i~w_q#OT.X IH;ڡf"r:xKYŗ q:Q[V"A峛BA5x_qY1̈́XΜߪI 28]eh+-}+Nv]߷ eln-τ{H؆Oq[e~{)=zz's.L! (>by·4b?ڥ3ǙS>:JA[Y튟Ou(_1fɐϒ{ ݦҐ1f1r|?H{Dw^n}6~*2! Px\ZA9 DDJSH7jNa|SmH?zndBdݎIx"rԏ,i#]$q >jBxЙrC;x˪דChSfcj[[7&] !0=e4}*T ˜'n5?ǭ$8l{j[?{G묐v.Ö&RXgE SIN$/WA% 0.  -H8k,\و;0l$ȺE/N"R~?r//j.fI?1hAP\A,7Sjײb9 )C@:/hLdLj%{J\ *E*N1A#opHOZق7%W Zi {X;D Ъ80 ]x}TVi A"}x: 3 0ml1k+:i}F*>eRˎ_ʈ_&ש4l ,r '9HotVZ2|D`z>ef'S+~%˄^7587US} Z蘵u׊{70dN $Ђx8k$WK;%GIn 2}l;6&PHp(TɇI'AVgbybVXNA|saDvyy9$آ>o% aL=A%AxI()vZLm?E!B3e&X_Y΀裛< LMG (љ*bxCF<ǭ8MGF6EHB^3orgx Gǝkc~<кQrgpJt!4,&IyRB O#]1Q %K{!68}g>[8;ԓjf^ӷ(t7N8cxլU p4$>8O63|V94hJq*7Rn/cM^.&BdL<gjŠsT.շ*0E8mֵus)Y,',A] #DA]Cɻ*$z9MuexҎ c]4QP?z[66@Wpkf|%x[Rb_ ^0<I,[xu]r@œY،U Gng}(sc 8/h.DS|/!ꃱC|wcpU~_k,0|# 7+uN.ɓnM,mfKO#Rb)߷$a%[񷅥 Ћu h"gۥrB(Nz󒺒GV9YI@W377m/:FAg%sHT;s /I@YI꤇)^mnx߾'$ÛtIgcMT1WZJo=W8-9X[kZB5EEߣu.\%mg5`I!YdSuaWHcw_z`{={uYa\.4+Rg-H:Io#e_]{! i霝LuiN1>j%K[ qTcŁFguRXt Gzg7㧙JB #K3.SuP֠ Yw o^+绢T>gQ=uQ-Vak.r*/NP.S!Nbj.q,@A !ƹK磁c3 h ߸,s$BJQbM~Rb,G4:l!֚ei#/=YKsY~8*K}B"~ŝ^+B'>i͒IxW9DH$bQU=H  eaLLFY OIGlƚg{ٕs ¢LsZޢ=s|E q_Zc& "VML\iQZȕ'x~TCkO헮!4 ro1U>&mwюD>4y\{SSxVV訹]4xƏ޺m t:.xٹ)%Rެ>JyA}4h ǫ%[ݞLJּ 5Yοa/O8t')H4*k7.uDm!=\W endstream endobj 126 0 obj << /Length1 2156 /Length2 16183 /Length3 0 /Length 17484 /Filter /FlateDecode >> stream xڴeX[Cp'xw@pww N!Aww :}oy)Y[gQ~PRe6JANL,|9yy0(dlci`cba@u;YAbN@>@‹H oJSgwm"Le9ֵhmp~;&ҸGxn(?wXή]>%_MX?'l>/G xQQd| ^Mac }[l'PD7hXЙ3<42.q}IpʙA1UsY֞[FEOT= JCT* aY*ؕ*k90v"fGX az:\TBNƣpiCnofhVwEjœ.ˉaKj_`CX!W܆H~-xnJգգk>83wԖwu/ &!G]osҝvZҧh;%zC«&YǠt'6TuxM's"|/X;TTXBzI)^ ySz2{!Fk(n ;ڌA1]jx[ *߰U>.y@{/7_XV`W p6sLRl4 `=GvBM RB *}~}x@z=]sYҞ w:4ϗ2::),YYېb cuc<Ovⱷ+nBRR"/SRb~N9^k6DfcD2NUPCI򔞐"M})Hm F,(eUb$HdwZf㮡2i3*(pH)#R*Qo=@V>+j28ydr(*/Wa378vbM-:)QQ f֐u^~g)x"8z0rz9xDIn:jG@UiEi#8PБ^GO}a+pHS|)[t>sROallO3F?تA[K)&R;USbs/NzUX(59 15(,М";'!x2Z!S>@p_=+#E蕎^f/LxtqtNs?mPa2`b&Wn1Рx[,Jj|)o.uʢB-*vaU{HSU.1q 4?R &K_Mtr>QVmE C:8Q(:!4; A=oh$~ gǥps)[ : Ue{)ΒmzEF-n1ul# u):ue̟ 4"̓MYyMg@/M#]" .rP6SPh֍+@ }SSuxݑ^/${m>4L>b3S[p{!-RWVHIa He>&jTqRE~PJؘy͆T&9 O®W}[kwq\՝'a993Aa9Pbꗎ 0$%B_fwPLM:<">X%1IŵxZGw[Ӆ}W l0 v>D- T2afpPJD}5o_jqLA8A2M : deg(8?PL)׺H1.%ޙȨ+EtɺNWg-UJ\ǴwVqUoiO*U=g5k:U~G2ߞ&DW/W,=e \aqm2S9YtgL%4\ Dq9`'yk^k`+BzmA]3̐lFSu.a ~ms} Pa ){<=weqiė l j`9Vx+R2Y{'"McauYc&}֦MZR/w|TMS9$[Pr| 2 ډwA嗘LT%& MpދV/es!_@dBF$$4)Y#?|cUg[Cb ^F "8@䀐k ! /'ɮQp޽UnVgv/U+*n{@+xK`;֋=_yLy@¢$LU/dQh8_Ns ߚq)~KiߑL 47"Y5[.m7@!i<5]d- $LpHU>(zvӓ08Ì$x{ vg;R.ڡ7Rl.8é+P!IMd%@l0 FqIQFQ/O1#A4g9Fll[Y؄B-]ҳ,jgBCIij7 \>"| /?% x0 F>@b}fOe>+hdNԹGiՆ*F\}X;i5%[t?3Єy^;$Su/n!'Bsb^ܵOvhNT!t>/FC՞xPX< ZMXXK 6D Gə9S}B/tߵufU$i9o{tͺ*=޳\zr ͳؤ% vx ; E'B:fp(sD'Q_"r!#fX1qYE2ٳDO/=q7z D}|Qo^MVGrvƪ=hj U71S7ENZ4* ze!nSv > Tم6SLf5uތm j!eR| Twg5^sFjڏrBG6[7f5)U~p/ϋ6 OEgp'm)BQL@9 .w۟?RZ(w>kA~{𹐔xd!Pkp7B*sljNi'H{}X<6#:,%^yMA=FהG* !t*>=[L(tl2`te/V bp=lerp*QAuϺ/2%SݰdTϲl#:rQ/TC{K ER.![JWXc"qrAPZ,a֛]*zBk{a/=;\Wy!&Ii G,W$әW{BJgc捈эg06 T32KvTiѱ0q7.j|vS?фcJ*g2`o1W`[<QƵaR }Ym{C_13Rd)+~']&喘U^ebռ):GVn<܇'$.')k: gϷ֔nZ\<,rTL緛c"$mC?$3s048{ *v5q\7]!1zoB`eB!;}ZO`MzvIM] ҿz0)D,_v7|6 |잧u[4%~"ƘzCQガy(u'~\*kN+ddMY;mIN5)AgSQ@ r-نU#x*^- %3ƛyH"GKΝ,-ΦhDJoΠzl}B –9ދ˂FIqe8SB\@$3 fҹ^+|JFYNBr"^0evUm_3r,f;{!Yv(/tKQN*c⎰Z \aNe#Ug)b7tx_ CِVIa" X̕2sΎ6kVQmޫnם-u[!KTfX;}E5â :VO:*J-_" 2k$% ƫqq]Pl`PKWx#nP6ѱ8޹J-ݕ fʨQ;!܅wNňfOqO-lAurr_l\~<˻kN5 |m>d'r *Zۜđdm;rtz({ 蕥gRY(xvI1sAACڟ6Q8VԎDW5zLpB?odQd irD<&~D2Aj t,Y~xSڍT0헵Н _i~on>MhY1nPl7eQa&^1TQKaw.7?Qꆃ(A0d7f(x Ԇ*;# TgSݕH<_LOZfW=gnꐩ]z1&Еws.>5ۙvt/P)uZQ>1fBJ|zmz&a+߮AFywT"ݽN4M+l4r$[#U98%̍}%" }\VR{Q2?-8/)4Q_]swChK! 6IH!߾@Ot+HJ]'D;Tz/mHͺG$iV ÉΦo!F5Ν;2/uEZtipWќ.?~=P |5,{oJsa T4̖gETr,PAZ~c 0[ojG@UHL=9𥖥\7a(I'aT sk{D7T? 9ߤ->!A{!uȜU$IIc`FJ2swk<>>&Uwю9O.iK/Nh7xP' Xx >%2 Ts%S0 E^_µ9>nbbٷi3|oRk8>oWX.nԒ1LM<0b[~:chn?ݍYHµ%%mҰd)PnHO:' ش΢ d./ :$O~ Jh"fH#G=*$7Zg*\QٟR@V ȱ򓟖sikK"Hé/r G$b_3@ڑ` 6]녗YGLC E$)TQI -uݛϘrPJ$م+{! jJ>$pAk\k:'Ts/ǎ%䧭D#jn%)xOXn?FyzBFLþ$З+ HwU z-;)Q"}ۻ-ȟmFݫ;Qd%%_n`ʑyI$Nuj82ʚ (4|gFZv hy\!*b2MJlT_,EJ7qQއH2TZ Ͷ5͝tk8b d9"v'\1-! n=Lɘc'$* ~^6P->pPQNvdj"[{Dt$ӿfJ3 Z .V-N">H7~kLs%$B1!DAֳ-8YQ ը zSk.0͓䐬>ȁ."3u4kb•3s<H!֔&S=|P;FzFv>,!^)?ګczޤ"Y3qT&[RrXM?Dپ%wZ$gppyB=0fJs"d{|+ NrRZ2 @"XmyQ>Ijutr`0?&<&B1QN[;#'#2ȅ4תn;k ĞvD wHQ!XIV:+1Aזvch)uL.(awUthto.VN&ݙ푍FԗAbi")06) "PVcY,>] .5&<942zb=+ϙ*-": `eJ:&_aFW  V?:tb'qxބekp8D<`!-]`1_&NN?&+Qamdi^ydlfR|4 o]~>~ /.YPkX.ĩ .J<Ϻ٘0N[η`5{\S̈u3L"X;[FRA "Q܊bL 䳿[%( GA>C+&ȸu\z аyM-p41v%˧30#\Ε`#6Fˆ]W4pe hL.PI98Yw nGTv-"{?Yޘy+{o=ZgIao Os+p2?lW8w}n: CT$rDH#Whi=rAsigJv=T@<_Q;= ]&)Ihƭ*u m\:pʂ>P#"~%m@L.4*hVH~vngb@3-"ƄfڡKD,NH*\QD|~N.")S g~("C[_{#t]82+z W~<gjDWvi[0:nDk9$ic??Q6l!Mo:2˦IZr&Ēnj6 ݷP(ؼ-x, x;6'k'or MP^maeyv捛0*'O ŬK-o-v4\X*}L#z#q[s cO ]h2P4VM :w azkNfב?Dq~! "qI: cerzȤIW5>gǪ!ra @"rm:m˘g$#$h^Hcǟ+PpYz-pnu^'`D6(T'>CX8w۔ 0gl#.tV5,4]Mڇi pq9U]8G7d #mz0O:UC잼FF G e7)ˮ(eZ ]'E^N:_ZΚ-^TgBa{箙|s$=fjC;/QOlL8f828˦J8}OMd&`́K۬Ŕ\/)']yh=몋f4Tm${C K~ŚfJnuCxW~j6X;<\8^>U 4hf['\ޏzf}%.S)'(aq[$3ڠ%K[smaz3@IӾ4MPݙ y*2}m)4INڅ *G@!zCJbT²*螺Z!-Dm?J\5ܚJ=.'E2PnҝTt]"mEcC0gVTZ <9ʔ0f`D6b7$o?fH I-1o4mC+E BJxv @j^W?fйqK䛏N7.7=Am|ml.sx}=HFM$-XP NuW(|iZ^(e: yYQ%wV0[o;Mn}xhK[nw43=zT7:,IKs7rr'8?On5S6J) %eַo9nUB%ٔS{QS|WAց(IS5ea,rQ4]VL߮|9ODpc$1kX]GN{v ֋Onpsp'FH4׈_kĬ]O/@! 1b'vr;kJ~H4RmO9-{a.l ˸.w=F)ajiJFSA~@"ࢥ>m-(pf Ue=|N_ԓ9ٱpVDeݥ޳  Qᢌ//fn.ĭYsGU)BL? Ԓ\.AROnf5'k7Lt06'Lv%a +}H9Ce>_ćsbm"];jSWv# lBtg(V[$^~a޷'c s<-A{~z=ωGFߵȉ翮icGp_j/VYs!ziMkɞѧV_xk5y)՗ԪB1&,FcϮaW8ľeyh~ qx^lr 'Wz,jaY>pnXwJ^ʃOIB!Y҃YU04ckq4asӘ9a7s~⒵ttlOyTf=,aam2fS[("9szxI8.Rxݑ!DlzX+iO){#b>;[GW;yM:x>J#V2..Emgr+Gg 'x'\^vة6hEݕ " ^?BE!Z5Ĉth@Z_kE)0905L1zyh!Ujd2Q{{Vr΂xb3 cnliǃ=QܨkNs W)%/(r=[< ASmx=})̓$4RUik1ߌZݜpF/ FS1N$\tߤ(~s%) |4/Of 2};E 9HG4Llˉ5`!q ]g8KXu88=fҭNMC@&[mCI5L*uO_Rh<쨎6'ckOhx&Ϥ D؂-ֶ]j~bp„ nR)z ֜== q)8͑-HjXzY/b9}? 5O?dC_vC/0*3C?ӤF|"=?!j+W*Khi BT ]DTYn1Wؔɻ OR BZPN\+K:x6 (u+Y\7S12}]`ˬCm2y9|ag*݂4ݥ<n5S 9\PmdFK) G>8dzjRK'_BS5pS }*Ԁ"g0\ـ[QaB?U;=z[E Lwo;<)!!M/;E((r5僎ʔ ցSC,HБEkS)4ȫbP~#[Fx:vyG_-5) :ڪdГrveΙ*ҡ@rU"VFx_;1ݠz嘉AuNjq'ĭZM#)npިI6 K4pYj έY7o Mz#8%p$]5z95Bl{(;7 gFГ4_JvgRvdfaʚƘ K5-LúWhtùQ$հ WtBUԗkL1N #d`Xo[74k.0&"(kw+za Z;D0ːe )"o f & *J \z8\rؿkw %za`C<è"6(nR髢o@EWUsi)Հ}!ho_C?eEi72p= Է?7Rؒ~@!A@.M{< M#z8.ا"Җe_.v%F5 _JN_0FpA *X{_-9mt=yI厇܇2qJO4#hP5õ)()W31Y ƌ^~Z4_XCkT|[/f}SY`R˿-I960BjF iU,Cs"OOKjS{Hor$J\nc 祻N?ZPTva.-cI60fBTЧd}38!2 92UkRLamkVwh_rA5}a8`ia5y;r,Pyv\ 7xZJæO0GK2j  P|Nԭ~4E$ؿTn+|rNއh'sB $fz|P(nDB_ F q8 :۩;P*d_@%[Ddw&lvej7 D_jƻxg!qO4v8 >N1Jۼΰ"|>]g;95=d! W_ ꙺ쭘;yRn1cxl1Ii;kЍIpl*H< J nc]{H&UKH婾ivg]0<2 6/0 -SGã^ hUOasFm>k׳NEWF4aIKx"61 &ﳒō3^6X,IӾP <ݺ'Ck(I&4ńӠ)8 Sebkqd$"(akrsс  52 \G=\5 FvWŸ@QQY[3:IJVCT51A 2_H":N󵫯6ze1}~nAJX}(ϴN!+1FAA6brY0c"'yx]SKbc-]:%|AC!Z#F!- U|d2f:- endstream endobj 2 0 obj << /Type /ObjStm /N 100 /First 819 /Length 3373 /Filter /FlateDecode >> stream x[[w9~ېI~=9'aB{:v'Զ6Nu)*n!`i²IM9fB4[4Xsɤc9~ )hu)gB4˙ӊ$4lpL#iF' ` @.JF+Pif%e0AfI  ]CV 4$ 0m|`X'H6=zPx4rA0/s4A9 ,\O( X{WG= 0AOlg4cWKq[b{MO$GW~~%c7UFx!dV'r<fU)<&,b(bs椻Z p2^a 0:3W aBt>MãMdp5$NLkGBxϰ^Cer,אao)בi9,Kd{=1,hJymƕKZڼZ(vdRŽ{y2IuX}$]_UnI鯩ѫʁ`/'|-3#2oդ,1ZP=+b>MnK Mv~JZI@poDyttZLbxT4^}Qnt4Sȷ1  3BSlXXo+6VtIXUJ|7^?B E\/7U~G93t3ͬmӠ&V P}6f!dyR[Nyj؟RUf5>IZ3(,(|NfYItm{[kG=">D9{K[zhKB1sS^h9E `U 8ZSeDs Utn233H5)) F{#)rOw4(%i;bLC2}1.!Ѣ79JyXP$z8oxW Ԅ]b>d}L#Rb-MٔR@v֥1\O%ħ$[i3"@- 64oNڍͣ*%R>&gF?<&K~sqJSI89 Dk 4YƉ',H3w];wR8~lq:ϸ4IR~nƹ76fy-噮&^APc,}#(I!?MiIҘ7FI5.'opP pH B!Ԋh@Hގ{yPIA~9(Ob#-]2t-OFX#6hfjw㵁!{1;l"tCd'C~2N?{qV98pmT8uy^%uâ>QIY1s ?>Hύ1 #Ǥtg} GˎnrеX]"aPFA[C5ç}oɃGw:7 AmWue43ŭTn] *xy5.QOg9/!ħ qޣ@x4~`^pt wpK48(7d {fl)tǩhPNxR4^>~YƵ1J Hw6_rX\Dո\om VJ/&EMSYn1/N!R|;~~ӑaEDMϏ/jpZ78v\"r2'-S={W5xākLM&3?/91 @1I.gƇ|=eoST ؞Ϭbw1@d{Oސ:2kT \ bʸ$FI.]-fṱb6&3$ 绳]p/+~.d=(H Ǽ_ߴ],LC^5rO{A ϪAsVftJ+Uٔ_Mud_C+L嫲ٰQ65dۼYM5ڍ!}ƪdzU2لm^WE[,:_CӪdk@ۍo=C.laM8.}> endobj 129 0 obj << /Type /ObjStm /N 8 /First 57 /Length 396 /Filter /FlateDecode >> stream xڥSN0+HL꼚JUހxPnDFCSIJrxwf09p )rfEߧC&!b1q_Vsx+ڏ'Qa, a7x4'6Y.$aO'o#2j]ًvpG Y" 4nRx)sr߁ =N{I=쫶c[EȁyƽE~m#̸Adl6co9-v!dB)J1GVTCdRXS۝Xmߒ u^m y"=REH#,K) cxL|;tsm$X#oTEjv=/h%swNH}/8P&$ endstream endobj 137 0 obj << /Type /XRef /Index [0 138] /Size 138 /W [1 3 1] /Root 135 0 R /Info 136 0 R /ID [ ] /Length 349 /Filter /FlateDecode >> stream x%GNA1` &s9 &G X !!X!'>w {=]ȯ#z|}BEqd8Ι}@ 4)Bx! 2TgI ) ; pipygOeAʪ_R)dVK G yPEP 3 e*_VUZvVPPP*=?2jТ2hZUbA;t@'tA7@J!ٷMLÀ/A%C0 #0 c00rhC0s0 Krbc+*VU,U߯-~>[ZW'diCM8QO k.a.{WW=芖.0 endstream endobj startxref 205064 %%EOF alakazam/inst/doc/Diversity-Vignette.Rmd0000644000176200001440000001514513513664120017775 0ustar liggesusers--- title: 'Alakazam: Analysis of clonal abundance and diversity' author: "Jason Anthony Vander Heiden" date: '`r Sys.Date()`' output: pdf_document: dev: pdf fig_height: 4 fig_width: 7.5 highlight: pygments toc: yes html_document: fig_height: 4 fig_width: 7.5 highlight: pygments theme: readable toc: yes md_document: fig_height: 4 fig_width: 7.5 preserve_yaml: no toc: yes geometry: margin=1in fontsize: 11pt vignette: > %\VignetteEngine{knitr::rmarkdown} %\VignetteIndexEntry{Diversity analysis} %\usepackage[utf8]{inputenc} --- The clonal diversity of the repertoire can be analyzed using the general form of the diversity index, as proposed by Hill in: Hill, M. Diversity and evenness: a unifying notation and its consequences. Ecology 54, 427-432 (1973). Coupled with resampling strategies to correct for variations in sequencing depth, as well as inferrence of complete clonal abundance distributions as described in: Chao A, et al. Rarefaction and extrapolation with Hill numbers: A framework for sampling and estimation in species diversity studies. Ecol Monogr. 2014 84:45-67. Chao A, et al. Unveiling the species-rank abundance distribution by generalizing the Good-Turing sample coverage theory. Ecology. 2015 96, 11891201. This package provides methods for the inferrence of a complete clonal abundance distribution, using the `estimateAbundance` function, along with two approaches to assess diversity of these distributions: 1. Generation of a smooth diversity (D) curve over a range of diversity orders (q) using `alphaDiversity`. 2. A significance test of the diversity (D) at a fixed diversity order (q). ## Example data A small example Change-O database, `ExampleDb`, is included in the `alakazam` package. Diversity calculation requires the `CLONE` field (column) to be present in the Change-O file, as well as an additional grouping column. In this example we will use the grouping columns `SAMPLE` and `ISOTYPE`. ```{r, eval=TRUE, warning=FALSE, message=FALSE} # Load required packages library(alakazam) # Load example data data(ExampleDb) ``` ## Generate a clonal abundance curve A simple table of the observed clonal abundance counts and frequencies may be generated using the `countClones` function either without copy numbers, where the size of each clone is determined by the number of sequence members: ```{r, eval=TRUE, warning=FALSE} # Partitions the data based on the SAMPLE column clones <- countClones(ExampleDb, group="SAMPLE") head(clones, 5) ``` You may also specify a column containing the abundance count of each sequence (usually copy numbers), that will including weighting of each clone size by the corresponding abundance count. Furthermore, multiple grouping columns may be specified such that `SEQ_FREQ` (unwieghted clone size as a fraction of total sequences in the group) and `COPY_FREQ` (weighted faction) are normalized to within multiple group data partitions. ```{r, eval=TRUE, warning=FALSE} # Partitions the data based on both the SAMPLE and ISOTYPE columns # Weights the clone sizes by the DUPCOUNT column clones <- countClones(ExampleDb, group=c("SAMPLE", "ISOTYPE"), copy="DUPCOUNT") head(clones, 5) ``` While `countClones` will report observed abundances, it will not provide confidence intervals. A complete clonal abundance distribution may be inferred using the `estimateAbundance` function with confidence intervals derived via bootstrapping. This output may be visualized using the `plotAbundanceCurve` function. ```{r, eval=TRUE, results='hide', warning=FALSE, fig.width=6, fig.height=4} # Partitions the data on the SAMPLE column # Calculates a 95% confidence interval via 200 bootstrap realizations curve <- estimateAbundance(ExampleDb, group="SAMPLE", ci=0.95, nboot=200) ``` ```{r, eval=TRUE, warning=FALSE, fig.width=6, fig.height=4} # Plots a rank abundance curve of the relative clonal abundances sample_colors <- c("-1h"="seagreen", "+7d"="steelblue") plot(curve, colors = sample_colors, legend_title="Sample") ``` ## Generate a diversity curve The function `alphaDiversity` performs uniform resampling of the input sequences and recalculates the clone size distribution, and diversity, with each resampling realization. Diversity (D) is calculated over a range of diversity orders (q) to generate a smooth curve. ```{r, eval=TRUE, results='hide'} # Compare diversity curve across values in the "SAMPLE" column # q ranges from 0 (min_q=0) to 4 (max_q=4) in 0.05 incriments (step_q=0.05) # A 95% confidence interval will be calculated (ci=0.95) # 200 resampling realizations are performed (nboot=200) sample_curve <- alphaDiversity(ExampleDb, group="SAMPLE", min_q=0, max_q=4, step_q=0.1, ci=0.95, nboot=200) # Compare diversity curve across values in the "ISOTYPE" column # Analyse is restricted to ISOTYPE values with at least 30 sequences by min_n=30 # Excluded groups are indicated by a warning message isotype_curve <- alphaDiversity(ExampleDb, group="ISOTYPE", min_q=0, max_q=4, step_q=0.1, ci=0.95, nboot=200) ``` ```{r, eval=TRUE, fig.width=6, fig.height=4} # Plot a log-log (log_q=TRUE, log_d=TRUE) plot of sample diversity # Indicate number of sequences resampled from each group in the title sample_main <- paste0("Sample diversity") sample_colors <- c("-1h"="seagreen", "+7d"="steelblue") plot(sample_curve, colors=sample_colors, main_title=sample_main, legend_title="Sample") # Plot isotype diversity using default set of Ig isotype colors isotype_main <- paste0("Isotype diversity") plot(isotype_curve, colors=IG_COLORS, main_title=isotype_main, legend_title="Isotype") ``` ## View diversity tests at a fixed diversity order Significance testing across groups is performed using the delta of the bootstrap distributions between groups when running `alphaDiversity` for all values of `q` specified. ```{r, eval=TRUE, fig.width=6, fig.height=3} # Test diversity at q=0, q=1 and q=2 (equivalent to species richness, Shannon entropy, # Simpson's index) across values in the "SAMPLE" column # 200 bootstrap realizations are performed (nboot=200) isotype_test <- alphaDiversity(ExampleDb, group="ISOTYPE", min_q=0, max_q=2, step_q=1, nboot=200) # Print P-value table print(isotype_test) # Plot results at q=0 and q=2 # Plot the mean and standard deviations at q=0 and q=2 plot(isotype_test, 0, colors=IG_COLORS, main_title=isotype_main, legend_title="Isotype") plot(isotype_test, 2, colors=IG_COLORS, main_title=isotype_main, legend_title="Isotype") ``` alakazam/inst/doc/AminoAcids-Vignette.R0000644000176200001440000000642013513671703017502 0ustar liggesusers## ---- eval=TRUE, warning=FALSE, message=FALSE---------------------------- # Load required packages library(alakazam) library(dplyr) # Subset example data data(ExampleDb) db <- ExampleDb[ExampleDb$SAMPLE == "+7d", ] ## ---- eval=TRUE, warning=FALSE, fig.width=7.5, fig.height=6-------------- db_props <- aminoAcidProperties(db, seq="JUNCTION", nt=TRUE, trim=TRUE, label="CDR3") # The full set of properties are calculated by default dplyr::select(db_props[1:3, ], starts_with("CDR3")) # Define a ggplot theme for all plots tmp_theme <- theme_bw() + theme(legend.position="bottom") # Generate plots for a four of the properties g1 <- ggplot(db_props, aes(x=ISOTYPE, y=CDR3_AA_LENGTH)) + tmp_theme + ggtitle("CDR3 length") + xlab("Isotype") + ylab("Amino acids") + scale_fill_manual(name="Isotype", values=IG_COLORS) + geom_boxplot(aes(fill=ISOTYPE)) g2 <- ggplot(db_props, aes(x=ISOTYPE, y=CDR3_AA_GRAVY)) + tmp_theme + ggtitle("CDR3 hydrophobicity") + xlab("Isotype") + ylab("GRAVY") + scale_fill_manual(name="Isotype", values=IG_COLORS) + geom_boxplot(aes(fill=ISOTYPE)) g3 <- ggplot(db_props, aes(x=ISOTYPE, y=CDR3_AA_BASIC)) + tmp_theme + ggtitle("CDR3 basic residues") + xlab("Isotype") + ylab("Basic residues") + scale_y_continuous(labels=scales::percent) + scale_fill_manual(name="Isotype", values=IG_COLORS) + geom_boxplot(aes(fill=ISOTYPE)) g4 <- ggplot(db_props, aes(x=ISOTYPE, y=CDR3_AA_ACIDIC)) + tmp_theme + ggtitle("CDR3 acidic residues") + xlab("Isotype") + ylab("Acidic residues") + scale_y_continuous(labels=scales::percent) + scale_fill_manual(name="Isotype", values=IG_COLORS) + geom_boxplot(aes(fill=ISOTYPE)) # Plot in a 2x2 grid gridPlot(g1, g2, g3, g4, ncol=2) ## ---- eval=TRUE, warning=FALSE------------------------------------------- db_props <- aminoAcidProperties(db, seq="JUNCTION", property=c("gravy", "charge"), nt=TRUE, trim=TRUE, label="CDR3") dplyr::select(db_props[1:3, ], starts_with("CDR3")) ## ---- eval=TRUE, warning=FALSE, message=FALSE---------------------------- # Load the relevant data objects from the seqinr package library(seqinr) data(aaindex) data(pK) h <- aaindex[["KIDA850101"]]$I p <- setNames(pK[["Murray"]], rownames(pK)) # Rename the hydrophobicity vector to use single-letter codes names(h) <- translateStrings(names(h), ABBREV_AA) db_props <- aminoAcidProperties(db, seq="JUNCTION", property=c("gravy", "charge"), nt=TRUE, trim=TRUE, label="CDR3", hydropathy=h, pK=p) dplyr::select(db_props[1:3, ], starts_with("CDR3")) ## ---- eval=TRUE, warning=FALSE, message=FALSE---------------------------- # Translate junction DNA sequences to amino acids and trim first and last codons cdr3 <- translateDNA(db$JUNCTION[1:3], trim=TRUE) # Grand average of hydrophobicity gravy(cdr3) # Average bulkiness bulk(cdr3) # Average polarity polar(cdr3) # Normalized aliphatic index aliphatic(cdr3) # Unnormalized aliphatic index aliphatic(cdr3, normalize=FALSE) # Normalized net charge charge(cdr3) # Unnormalized net charge charge(cdr3, normalize=FALSE) # Count of acidic amino acids # Takes a named list of regular expressions countPatterns(cdr3, c(ACIDIC="[DE]"), label="CDR3") alakazam/inst/doc/Lineage-Vignette.pdf0000644000176200001440000064066713513671731017431 0ustar liggesusers%PDF-1.5 % 35 0 obj << /Length 1623 /Filter /FlateDecode >> stream xXY6~ϯXt0h6wnER,h"K$7u},َӜ 9#o!&#(cy[c{1OCN7ͼWi!ވ(`(*^ۼ*GEįnM{0mR,@hֆ0 Ph#)ۻܘ$Eڌ<10;QĈ"%N,,a) x!fs)[ik7Nؐ#qHc EV/\cJL(q|W..WpyaĸY-Wu5 HeiEUQ|>{6xH ů9OwQm^.L@ طw6l, T<2h* &$:X>z'S5ھGmLg٪, ZN!ܩO:ẎRi1nz)M}! g0:Gz\b3ZUQT84XmMarmR2N \Ybdȗy+:hg&kkD#Eݩ6}ޒ6$$YZ.mo ubvTN9׫"o$d97]W4Ћ2]Q;;guR-G-<Wª-#B&&q<%8xQNCL𖪂,( M|I^`HHjQҁ2D<)>L  ycytt]yiZu"G)Q2,l X)h% . $Ș?@=NmB"B1)A<\K-RۺZ^AgG !ۇ{4Y4ܬg7XS`!$.f?ɷG@}s9ʀӃΝ{Ճ|bE Bpkm?tl=nVkLȖVe E`cDZw8Kg,Haolup )\'0m(W!}g,V:)6h( YX 앥1;iQnϪYwsq!Թmy/ښvU:Y0bLÿZ{I^3 endstream endobj 55 0 obj << /Length 2495 /Filter /FlateDecode >> stream xko7{~kY,.|M G.PA(i}/;J˵,K >Kys83&ˉ7x~`фyn%l2[L`DM$K\χbYYꓩӪbV4YYewRp" ' sr%K5G |l4ɚB~`ͪ!:9jWD5fo' &'2ˉrZ'Fڨ;U= YӕM~ܳ!楐JKUUm,Hl$-s_˵X =gѳ k4t⁢b&@iU}wY4h]7FlPGEVmW=t2]3s)o>E~~k0Y˦1n[Ro+\A?0K~6P]"Zmm.6Vp7z$c>$νv?C>rd `m lY$m=_<]ι2ōi@3B.ę<+2<{[uĜЯNS`ԔL[Upڟ{ b`@d|ɼ9Ž!>));yfs8_v˄f!F;=PtiPss_@BK&5<6ҝ2.\?rq_yzJxN沕8jTKJN8X/˥AT\a 7Z*U NM1Cmܪkw& Г_bpl/]G!Db +Z420q]QI"jv~wJ!R5Lf,6G# μxDVWx4`EG 1|엫ǘ)mچr_7Wgovr'B<:H3z}?{Uq orS 2c,R{KK.y<4U|w 0BK8Iau0 [sy"p*jc/9($xjΊa޾n'`[H{H2(%87@!J8'~S5Q͏ urckK*T -q=;]d4+]l9 6y)ײnKI8bNB~LȈƖILh4`HMaaT"kW!1g}TbJ-GLWUAr. 0Y,_l}-4CPB\/h#tqڄ ZKŸ^Wv^,qY\sX(l&\ )Jh lyNzׁfzG>!m06qyL,2/t![aLl} GJ5tBz/;)qȠAb0b uP/ 'PA^L:5)X&ԠpEh)# }YP͗plAcěvăтk&pG /<#ug{':kD "aU:6-,$TbR=ʙj :!;+~9pjmr̩_QE8*G(za3'5< V;@G7zO<9bF'i"|K6JRKYzW+tAۣHu JwrE- aqІ9fwZN:@u0'޴{lwθUy#|{qMvRߊO206n9?j)n9H ( endstream endobj 61 0 obj << /Length 1507 /Filter /FlateDecode >> stream xX[oH~ϯ>8Rc+ش@]rIű=n7~\)deUxI曱3w3wȋP C FSYy7ǣ~ wNGM4 gz?`g qRLn/ <hEv |~" ښwf<(FM ކ m3|ow8|ejg DH H`6{ [Gn Ʒ0 ocW}@XxKB 7kr@b/X܋ I6|f:g@BH4{{._f#/!6!rc3E%2 *pi|صWI*{IfԳ*S&]cjx҅_$9 *!2bWsJ]1PԨT4p\̃41Y1uM2T(׈72O"Se Q&r*Dg"DRjl$G%^'J6?~XeQ2!J>'ǝFU ' "g<.:5WvVQJ<}G6mjyMQ e\TR0Yn^)cQhY) fȡ=ư$ΌuL0SE:5$N-z.sRf4Yn4kl-pZoP*9s,AZ)4I3Mڙz* 0\{ u)Py4^Zqy=kp5DhWhPe̳ݥF9CA1i+4EB fTTfזAI5m!kUKkzz@qΥ&1UWթQ}B0N̚K<\F!dUd_EVJ\&ӓU,s[G?jo14nqJX::Ӽ0Y$k}IKN)H/J<8=Oq $Oz]ʗ/W?5wl}uƓ/S@7>[_XIW3f(VAw]?΄ϮP J8Jc0Ou";!GG}3|w/E"ԟZ:yq6 fnT"aq1wG3X>v`H(֟abע-Sx@ endstream endobj 58 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Lineage-Vignette_files/figure-latex/unnamed-chunk-6-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 64 0 R /BBox [0 0 236 146] /Resources << /XObject << /Im1 65 0 R >>/ProcSet [ /PDF ] >> /Length 38 /Filter /FlateDecode >> stream x+2T0BC]C3S]s \.}\C|@.f endstream endobj 65 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Lineage-Vignette_files/figure-latex/unnamed-chunk-6-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 66 0 R /BBox [ 0 0 540 288] /Resources << /ProcSet [/PDF/Text] /Font << /F7 67 0 R >> /ExtGState << >> /ColorSpace << /sRGB 68 0 R >> >> /Length 1542 /Filter /FlateDecode >> stream xWK5ϯ.ߏ$HD$$H$>UdFBᰣ-_n\>׳/ŕ|O.kr޻Óo_ܸw[k: Ct}{H\ CҬw 69D?+|'$ri>C6_M" W64=PDcuFhs)f_I 9h#%_4ڶ&o(, ! >AOT8 ?| !" wBUq#q #S]j~ nm?n[=hTDܙ Hq2%2DUG!ԛLdmC^t/^uAwl%kS\Hÿ|}[w!mkח.hmېﵿ#5݋W]0Yup$L^|#"u{ )w[/R[t7mo `|mۆ$|}k^ͳW@2y܇v{|sKsKyﮰz6l||ۣH*/`Y_z\0!>-ś_t3|V}\\Xzm[zs|@J endstream endobj 70 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 74 0 obj << /Length 1234 /Filter /FlateDecode >> stream xXYo6~.`1Ӓ@ǻE6IEmѶԱ}o6k;Eȹ盡McjFaVOd\~,`@)Šѹ,2Qh1mfL"fY_vݠILy])FH5 H fgm^VPV*7!Whk{HABFښk p`)&pL4+&du_޻ڠTdQd= yg-LoZB=͸\Mg'KKӶe=3;TОE6g~!.3WM Œe("r*{WZA'/hpB8;9 AɈԑ(XFU7UE~rVh2O+( J$]x+."k oFg9%6f ]ꀆ}dcWyɇtB#X=\z*w(rүh8w,Ljr #:?8:ߘKޠa gFUIp Zy[vМڎ6|:ͤ_F-&iYM C"k2BA _`>n9`{͜e-ESI,O|)w!*x5 }|SCAIE_ف'f!5aSm% sɍgKsO7NTfӘsibt9锴$9^^S:aL`ڮlGmvh†]O@wFƗz:!N޺^sY:h(GWShm xysw>_VkFG2 ?{^/ߟ{w7/u Rj$u]VւЪ3XʇШ8]?cNzr;xQ'tv6^=_=Vvo%:^cZds mQs̊!y!! _E'-h.\9{t<7]}q_h[AlPht*Mλ<2]?ʨ}X2$wG>/ProcSet [ /PDF ] >> /Length 34 /Filter /FlateDecode >> stream x+2T0BC]2TH5Tp Y endstream endobj 78 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Lineage-Vignette_files/figure-latex/unnamed-chunk-7-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 79 0 R /BBox [ 0 0 540 288] /Resources << /ProcSet [/PDF/Text] /Font << /F2 80 0 R /F7 81 0 R >> /ExtGState << >> /ColorSpace << /sRGB 82 0 R >> >> /Length 818 /Filter /FlateDecode >> stream xMOA +|L2DZA-h"8T!"п_ػ )Y{^cwv \]%e,î;}veUsy)4v./M ЏmQ#,; .pIY9>*2rkIHb&**_Ns w-'uΠ0UjgֻNYH[YԅXؐT.Uf+ ^ זeWT@/%ps-PYWq8~{;?W`ajU*)'gh}v=;pm6X]=^vG$fܾ5«/J endstream endobj 84 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 89 0 obj << /Length 1542 /Filter /FlateDecode >> stream xXIoFWH`g4=IJ{p`$%6]Bj)Ћ4fy!^pX`1P}ѷ() ALs-x"+U+;TESe|[ԺS ;-+;ʚ鏝WԞTOlX򃀽3>xu"q#1"yy>97+{Rv\4x W$(FPL`J*]Y 􏪚X', PM3* [bLsaǛ^K7 uG;eS[H7>AmAL@18F)HA_WY9c&JS3BβLcD0\~ QBm9ηrM$6=" ѻ33Vַ'$BPmKʙ75o4y$1E {y4]k ԪWuƬ>KU.-ڞ KFj&au؟ȼ,U(55zw/͌ٳ2,)[o@$,d`UwX1 >ZH!@EB0FJ3ܤ ;]"*r4I,$gs=t*(b_P/DxoDj1<]y6]9+A΢" c#G=sPnG&t^3BE,NztÚߗ?&eԴ[z /;"E`p> =oF ]厒S)ʸCyήXOPW=_8ɅCI߾ R YDgB"3ʱ. endstream endobj 85 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Lineage-Vignette_files/figure-latex/unnamed-chunk-13-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 92 0 R /BBox [0 0 235 146] /Resources << /XObject << /Im1 93 0 R >>/ProcSet [ /PDF ] >> /Length 38 /Filter /FlateDecode >> stream x+2T0BC]C3 ]s \.}\C|@.g5 endstream endobj 93 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Lineage-Vignette_files/figure-latex/unnamed-chunk-13-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 94 0 R /BBox [ 0 0 540 288] /Resources << /ProcSet [/PDF/Text] /Font << /F7 95 0 R >> /ExtGState << >> /ColorSpace << /sRGB 96 0 R >> >> /Length 1386 /Filter /FlateDecode >> stream xWnd5߯66C4!(ɂT}֌4ttlWթ}5<;3YM!Oɦ`>=y{93{d~8-6s-h3>9lsoldCLq9Z V F=9lEV{[²T <~!/PXՒ3Gl̳"pt\3pdbS5⋏pu f(1=@Yqy>ԗb/W>Ŧ֗ ߷@dZ9qq[n!4۪i: 8d ,m %D!C8y WC Cs!b˪V)DIhpDadu (9ۊ8b>G 1vS1u^L1}눐(!ÑYpS$`ÅCAae]'-e996Ȍf[{0rf,Ɯ3-Z|yi )N"PRNH~w!dGAf=< njeXxyEpy2NԞ#`dQDeC-(^r!wG`BGb9R't@aoDOŘW[o@a5ۓpjJ&y6d3NV_`'O| x^| qv}KG/peŗCNwŗ? 'u/dLGn/LD 2n\rV= rUw9aU96ǮQkJ/( | <xtjv~_P* օ컝ʭ\>_eX蓓kx'L8On B)u6Ǯr NiZ?yD[/g 0rj];٨ʕ"O!nGL WdEߧ77t?D~UL7Д(}I!?zyz}IW&ʼn[>g \Q}G?sU|s_|9/&S ./C/R2 endstream endobj 98 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 102 0 obj << /Length 1140 /Filter /FlateDecode >> stream xڽWo6_!$%ZMZ$ӕwѶ6v:x>dzDÝ&,)xrEfɴ}1B`).?2`GQ&]tҁ 3@o啂J4daIEH&CWf)Ҿ3a5Wx<ӻk_&쵾P M2&Tk HLDew)mK0\/@^WxNV1}Ut"x{?R<QP7[ծ&:1GbEdl]1"QBdd\Ԏ3!tZqv=zeq ҫ J 4 B:s ږ11>Hwŕ1>B6fsOۍE4RXlg>&N`/y]MڮP}=3`;g>TK¥#`@XBJa<[W`2Oq&%sA1(h:5`~̋``P@W .$y*yv81pIr$P qC9s3tôE&9}pb:NuYJ9P;tp ӵ.icnj>~TWڥan7jq8XN*c,{?z~bۛҷ(޶ae\',dV֫<.Ϲ{k;wX!+\%]etoT.Y}z`S]ipfV6M݅s-6vQO;TNͲ^cA ARUJ/dZHx^LjY878*OcK{cBC_|>/ProcSet [ /PDF ] >> /Length 36 /Filter /FlateDecode >> stream x+2T0BC]sS 6QH5Tp `W endstream endobj 106 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Lineage-Vignette_files/figure-latex/unnamed-chunk-13-2.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 107 0 R /BBox [ 0 0 540 288] /Resources << /ProcSet [/PDF/Text] /Font << /F4 108 0 R >> /ExtGState << >> /ColorSpace << /sRGB 109 0 R >> >> /Length 325 /Filter /FlateDecode >> stream xSn0+qrlhD**ĠV@TDZC";X#o2`?bQ{9U, <hEQΠm] lGHEЬT WAe~ -#:~leI:1x[iameqj%jG3i;/NLl<6 MlHbݥ1l)%Y2 :(إR0JlA*Kp$^WYJe>> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 99 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Lineage-Vignette_files/figure-latex/unnamed-chunk-14-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 112 0 R /BBox [0 0 235 146] /Resources << /XObject << /Im1 113 0 R >>/ProcSet [ /PDF ] >> /Length 38 /Filter /FlateDecode >> stream x+2T0BC]C3 ]s \.}\C|@.g5 endstream endobj 113 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./Lineage-Vignette_files/figure-latex/unnamed-chunk-14-1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 114 0 R /BBox [ 0 0 540 288] /Resources << /ProcSet [/PDF/Text] /Font << /F7 115 0 R >> /ExtGState << >> /ColorSpace << /sRGB 116 0 R >> >> /Length 1381 /Filter /FlateDecode >> stream xWK5 _%l8s;i%* a(L%c;Vܑ>>~${}HOɥ|r9Oɧ7W)RO_af\pȽ[)H+G7d? eϙ69;cUtSXǂ0ЬnhLo*{Q?c)Ik])LJ>A燪'Mu*\݅rsï8H-)߼zKoL3H/ o.f@ .U#?3DW?咻g~,ӿ2 endstream endobj 118 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 130 0 obj << /Length1 2096 /Length2 23972 /Length3 0 /Length 25266 /Filter /FlateDecode >> stream xڴuP[Mpw!{иww'\'CpK<3W4\kB/l 2Jxr [#;fz) Bhl 3r8-&&&nx $h 0T=j@ Lol 3~z{8Z[8JO'ӟh5`dg ag(ލjhadcT5qe'*. "&IVPj*Tyw./*$W埲]oif ۿ -y]@ 6St﯎@_q3}o_ l @h$ע{+߃?9mp_rJJr[#K;gɻ//Д_QG?52.z2]Oo#1#;/? _3KN/*˃޻c|br<.&37}HLEA瞧OO Gjk;Z,LtŞQ(-&m@gX0)פ131d03qz[_=\gG?9&C~P.mgpKO'dg03*߇3?$\lll2oqJl$a4Ut6WWev6zza;seRslұsg9g}MNN=()"K?򗓸 0rt4gzvv'(#=` 09"L"N `q&VE?`TZ!zFoz4ۛ齌?55-ﲬllFwvw {]{]{2\2\2Fwwϔҟ!wXd ԰4}Ag~?*@h'=гO3;'rzWɿ..os@w <Ȅ7*1仏xT)7q9L8=`F /`@tj]œ,U{7{uNSTb05`U*kOl&f/-k>4hgY+pVswDyj퀑nFC((.-i-W֠/nR<7 z_P`n)΃\Dlc!Ⲣ_ ŵllӕ̊+=I? ґ?9DV'FQrv~R=8c=l|oP}cFLV(SaK^M 9OHK!ƌhqZ.8ⅾ1#ıf.lj؂s]vV֐ "R$+rA7RѢɿ>)Io/}b>0\O犋IΧq7N亃 gaVq-:s *;l3g|,vl>zyk;8 4&#EV ŠPhQ\9 ]Y7Ýq:h ɚ:-s~3 PA>vU[%dPach=J[t EO ےOw?ʷڇ~5oJ9AP𴒿_YkQpbͭOk.hFIR"-ⓞ&] ́ݏ4H!ua<<&ԿΗhF8)8E$3Ŀ;x @AB0SLESa'jYX>XҔ<>/;&Eh?+a?IUe%4q,=3Ж|'}E轓ˌʬuTe}5hS_\P R(c #6-J 7V#aل~TV4:fPt"[ G%~7ɔY|LT5)/kwz( ^`Ndz*dY\ ch@ݾM_I}s{/x^W־G5ۦ9j[-swjʭo7ա:coJ qaL‚,l"֢f8n9Yv?GSp=-+=5y./}-~qiBP6 ;#P sŃjJޢGhp kltR ӓ(N+Զnzcb@/ZEeX=5?̕7l~[$6pm*횺9V:Q jD2Kq;<:UR*|$(aeœ:艫/H5s,R}L$uڢ 2?Fo*(PT n?hyQfX)kEY'tc{3YLzLҗ\v&do |žG7fޢɜ5]t/5E^S#jjf{&(XX}=C >DCCDx I>-Cn0T^yXwZY?Ժ3Dx~Xh>~Pb)u:1`F0bX̳plY|ɗ|9 v+@ UЄ2`2b,mOf B M#=neV}LUc/O3y"ۋ0Q"zAsҁ}<-0^7F|q{ V9fgKxxG"{!r ,jc1ϊj\{oO[2 $-vWS)rzGf`=gr*Z7ſQ fn~o^*Fm%۸7!9Ut0ؙtE{kVJ䌄Cߨπ{ڶ*gˌ1Fڲdcnvm?xfk Cjujt^ۡSqdN[5Ge\;َ/Ћ(`{Aj/GuwςBcvA;F[<yA˿E_#dz[dr5~4lfpQ^r >cT৕#sqP+qђEõHtiifJr쌈3$)P}DxXJݺ;&.emb#^[wߨLj- [n ;g1G s̡ӼZ0.[\tZ?z j5w_ hZ$xx\[W@c1us1L} y|:("}8\G7Uv݂H֮gM$Mf`2c|l~L}ÝHO= O{B9™r9HUaQ9)':} @ ,[x=v I\ǀ4aOT &XF>mr|J׈K SHoSR#oA3thr>TZ?DLdg{hɿMzoL>\rqoB¸CԲdd.3<s36NIH1Xܯ}{1 :Aiy[H>$ $Дi: k rE:/gw#̋_M{B;d=p0_%|DKVp\ -R{ЀN/Em&v1Aٻo+g-yan}Ơ,df=U멦`@_FGKmy\{Zdl!g猏CU1D_ ,'?n<RrS6/tEġccd+c§핶/?jCB)x0KӃ㪹1(QϐNU6N?tE;W pDmEDqM$Nw5N`ջ#F?[7-(rHA(iaʕwр9hq]TF(>##ȣd,]u7:%S # [-nQf^,qgSR<}SYI.*#>=S-sEmj?T%<͚+AkLՃ!.G@ L@>ҡul1} U%t aH3+d7^'HҼJlNx:Cxٻ{WDŽt}pם8=275RϣOي8p=A1% dQqШX۱o&ڂCH=ܜxͤ3Ru7e>8iFZXUjFY)49ä#ǿ!'0ss?8<;GwZ03Wr"B^ٸqQ,:u i벜4̪toc v"+dLK@Vc.YqOX1M2Ƌ*K]uob $|&`#|rCqbZIK:)J[)\VMIp tlyg?{I+N!w1pPEWMX ӡxaƦ-+l (%Pyōub4@KNOrA}@rDh UĤ,0MI_kS^s4Imj7!"(ܨpwyJVs wBlY}/x1P|傯Wqg+TtY1NK*>ZiYfcP(? ؕ]PᑺعAq ˖5%WOUUk^[}#0>Fgƣ?Ƽ.FY1oëː _>\暮XC2"R^ ٧\e .J*U>}f궶YwDΏN0^Aqȕ^_AF?>_Tĵ휪ڀ 1-&^3TP=hXn͓?bcnF6 ja[OMFg-'aM^mBܘ3XK #'UO>rIܢ)W/ 4Pvj{ũ5^U=TOvxh zc9/|ns<2^SgG+|cLඏ͞%u)u)Ɯ3oGb"1r0#0Q0 |KB ]M;'YyWjp;B.>㫀^O-i~W5JZ>o/%4I)rZRۖ西jvPV=tD}mǗÞ-%/;_eDerzu<~HhVrxil.,]d#u@p43%Y!%ϩMfADzr2dˈ+2*lO%gH?k$? *b䣿gMƤ[ÌJʝJSz^8;Y4]fh+ TxK~NmW`ΟI?B2bʰ3$a+edut"lN >A\he|6n+82>kf٥^d-tsqufа?bz_O,㓎0XjsԬwQBP^&h𸿉S@cV׎k8}>S+8JK̾O+e$j5vt^BֶK-TDjvn#w~ƱÅ;<4N-& 5|T]jbq6!)I@9l^N}3TRX"Dy$\/Qn'3`zx9 5+``2E0uDr h6Pui*,WGo!1SyDB JdFJ!Qh+whtZ$-WU^%Ҩ䱩L@Ո*ߓz*1zG{6M\dĔ؂2"dNda<ʥ&!5 sS@k*G.5BϼzԷ8MҞwV mu+˒TY=^3J7DUke3sHn)}+([ 4|VyA}Z~I̊]>t"i9u[~*Z^5,PՔzvY,L:oiDZ P)m6?@.25|w6[c鯣ҩRG j+6'mC4vMg$Ӻ ܿŝ+ T2ZD O흯!3A>YʫQO`[kjuxK=u~Xûڵps JƤ|Ɠ_{c"0p, ~RVEaP:P ǢnYhy}\jhZgmK7B`{㍎8;R᥺8LK4Q = ޹B)\c>?8[(TCꑇ^#B/&1iX2Xl2pb.e.:ůnzĞiз ҹSH1}gĝՕ0 =50 #8dEemdw2 pMH8<1^]VjI_sqx1P>ܥy|(Pv?t 교TŖ6Po:3%00hOCN4@s␵"=V0i3x^}g$ p$u"+vDzh33:smdΊvՉm/"zi*}@0 6J3)Ӓ 1Td0{27qWn@p4Kv *"3.{/ l꛲ ϞYn_Y3_o٪W31ePw59sإ/u75+|+ߦ*bdzPUsouVSxFy<_XU,!F ٯZdRm+9aM3']7HG)b֗Dߡ ,7ƗG3@~P3:2G-/'vn}=ھDYp5MX_u‚7ÕEVvT^Ì(W֋K[X[o}Zb $od`QK/䇴AS.)͌G$GIV}7ZcMCV6aҹۅT[qs֝^e:x$Z=( +zLQNd&$Y)򷤿EaHD1V͞/}ß)i@+b:-ł>|& ӆw'0 mzYDPh"sNe{Lg*E^7]qrڐ[0fg mm@ɍu5XM95b:N5+kf z [~xBDSt32*eD]>/`ky᭺NRwt^C8_H8Tl?"߯b)zIQ+ jAa N\8y&kDPE`!"Yt e]Q9[&eFF ֨zoI]3NiB4y[t:nwA=FDGZiL6}O lh-O,&98v"}J9:M-ϼoi=y8Ck+065giﷂ{; i͜+K̊ᑖ#^hIJ$"('٨!CF cK~vlQ}/;nC5!ȇ@Q23o!i3|ġ[z!/pGCINoȷWEA8D2L+5Q**{BjvJѐ_?w Ww%}q* buPx4AV2`Cǝos4u-wH(܁~P¼ddM@KB:%EeW@/1׶*mE,eG[$D(f0WAq1Vj\>uE"饩Zcm^ Cl =+?$wƜgt/xv@YIDKn>lRp0n5BfF {]yy 0CMwɖv1 YꠗOL IR,\Pjᚱ6:JYKpL{=,׎~poZ+V9A]^mx%1_tnrZD X[E!niY4}Di܄c% JnH鷫539V_ix2Y5qi~^pf0ϑs0 NihEA7! '3 &[|-2ȴ>t4h;0xoo-¬/W&hwvbT4Ĭ$fWMQhm^'yfG3bjѪ >BXb.H\ĚXkɑhͭw~-;(AD_(/aUZx,̶cA:*mqͺ'-ZkEZP/`DoNqTFwjgExCm% {UtTcFJۿj6l纡y7(#HGLa>2ìf5Gq1;W>X1z~g@yX9^/BVLpT zXL5OsL[bB;4( :Q4SH}%X ۳=J[kgVJPP6]\1txn7B!jJBe]>Z,o.W#aO!nDj CCd%h IŢ= Ȍ$$PV_!c3XlN<%h5Te<ݞkخ䅩(缳} Fw?'z)ȜJ(/= ]c)O Dß<''A_N"J#wmOhY&Y,鹜 i7i{y5)F0P'{BCDD%$v@=\L/rRwoG΀Dzp;I,pM<%9XфپXf;s&w eiQ#5~$؇Wa[[7ku:97+?ܣRbz8qR=%\P>H$EMja3e]jj0^o $#x ~3e8.Y)4XQkT^8)2FݜQo#-$?m\@Zn :.AD΁ gD kn\QXӣ8nёB2*њzKͥZNzx=];×.h-Ā  77 7!j'pl[mgeaLƌۯzKgl|y%,PGnyrqR;u8ذx uСf^V ²"Tc|ÍBH\4IЈ,8 Wۮܬ`()Y Lr7ؕ^Tf Tn oC]k$XLM;q?P$=o z%=Ctdɡܚ>4hka}Ъn傑"t3ܜH?[](oCˆp3818Njzi=. 얲n]Bzŏ!Erߨ1:}_>g)H6k>y+7U*驩cvz ,VS?ȌG2q `>U6t' s]"^_X0Nd[-8Є3s#_,h)Pibiͻ< b܆(~,NDHw*-'nҮGL4?uN {̌.cGLϖn2AdG(9c2v"Qo.n{ͬ['vC;)eoQo~m):3 st%y{1N3Jc ,Ş_n3Q%0D''Rk&a:XI=_2ob)m`Z,(4h0/V̟(iC'm7SoWZV^V?q+Lf#5T7Ҁ@>r9HJ!R.SQxjD{f弬8vAA>\T57QMԣwV.]*IMz aWi%I!n۰w_ٚԿ#0gx}YOx,d$PU hx {P 1vfVzL){ \/`|x-ׯbx]? /./v'ꄮW`h8[w=~Tn1-t0&9G>uXUy P؃ƕR`H^/<8&-#ڍhq!,b%q /@#)qcB}˙GҐ#yp.1~}׉@Oz-`sYשn1BvP7,y8fBv+g> ^jDbz2 E6%Y 1s1{zcMHp;*p+h:Io8mb"aQa7|rP]Tk4ߥ*4Q&.uB| |feD_vԺԊ |A8qt0i]Fbؗ`%3V6~I&/D`L^Ŧ)ns L;L5΂i%O/O{}P(cXn I H0&dwv sWMuRNS}3+G<)dh\e au;H5]&o߹ﷺfptJƨYJdJ!{3Te!%,_ iM[:HeAx͹mo=&ʧ9n~>_EHSbshɮRDp,S^T:sp !hL$fff!O Y0jCL ek$ZvnLՏJ‚,%o&*C|!~Δ7s"uq&2i+V_~ʛ`ԉu"mQ=g*WoDt۪をIxv>М k|jX} PӖzQu:2_Nl\^ϟ҂o1vOοCzMrv=fR *|paQJ!\aOv"U$d8]xˈ#H%nqueJ[>|ZƁ/Uz 宂FLC1RIz";i]Ak{b|" ͟o*<jS "KkĐӘGh 5\-Yo4+*ՒՀi=ps,1EDnw}8\t\2"I:~6=xѭ_"N(>M/a#^Fl2v3lGְs-\ɒng?¸,#k֏3sJ|DYݟ[ ˼2ӅϞe#^[AhRV^I_8;BPjB/hց6XEf;sn%OfW"fM[i8m'J#;xŔP%3(end&E؋!Q'| 1Īs$)C,RP(jM46V"MVƑu6BU,]doXWZ^M~8 WSRC+<2dW=\(]q "LٱXs /!S+ I ;>1<xҷ Iw}„:Bo1}B;ĸ hxݿuV,.E B{ٷh\B5%TV^*pL$:ڵ_Тsn (qUZ'W< E٫;}9H/a${503kP~iv콎tȌNI!Y Gے& 9Kj{4\] @;;Ȓ JQ(Q& OGߦI8ƇMl*ha VAdӼ G=oviY V/=v^ R,dk(\8d"bG#gϔGF,GX8&)wN.*^0Y_3VZ6:D{YbG$uuHym\6tSUY _9(%ƏsaUe& ]A9llx9ׄF邆[Ũ1׿(oH$6(%m JI(U_~X" e|+pFOŘtmEFml_ᄎ:z^0)UZڹ{LX?coܺNM.EB D鳵cmZGXcؚJ.$z5ǂ_^2X+ }KMUkpx9ܸ2xg(-ٿNх72n˛x B15GnߑGPFDCuv?;J_l`crDro"$Hذǹ5e=ZW&vh`,jV9yﳈ,W/x|t1z晽_I<^>#['n a JƃFhASZ:\)GbX ]l~.%Rj|͌ncp%W3q׼sZE$:s5"!oJITP(bs7fpD(5 H(k9C>T@JЃ7#PڜkaoMc Gt{,MS =<H_#?ߤpGU@pQq ͡%RuvwH(xtY8fR/pDWzsℑK>YHH |JSQ'<1C}ȼn`,:7*RC D!3X99Jd[Y^0hӢm5$! Or'#`Tz W>ݫ ?h0mYMOT7T6ݵ blrl,?a:wB=XƗ9\({l%00q wl}]C ytҦ囖WR^o·j7h5İS)Y_:[^+:(J+ǁD[ O> H%c]Ck4~[< 9J7 IRommĈ3#iKx?[#A-ћ6 O:j7yf<&q?ɂVy0qNw?O޽;etMMw?+o̽%Ym;;6fJ>CqSUUVF5Dޏbe{ m 2EtMs(CX|kjYRj7ei! w.⧧Mgl1VVLh' s#Zt00s->\qO:ā$PE:įDq#!7+:K["`Gdl9g-F(&:7 6P#XωX,VF~hhyi=b!>,omq;Fow DeXv'}yuj3nJ vkK>+EߠH>[^{N垃SyAZR,MԽhJ#LlߢS} OңgH9^_ з#. -grm鏗15!p//;./nQ Q$xw[tcJIʿ9 Wf-d`jXL gf[".ߩ^%E}&;rxEq04/9KGDtX1%rk/G@ QW|!4WIIR%!JԠ2^Yw @z}* 7% I@ sH/NP WR/(N ,pXtaŠ妦Xk)u #t3$dSZa)kн2aD#, .a hUA/ru!> 4fVܜrfah1Y2ב='[L䙿G2fjwOʼտ>G?l1m ?|<^`sa8DѪu``ƹlZUQ,2l5% tcmGxVl_5+ZBUcӍqAZ$~Mu2Z(Q#jjop olAV]CƎ=Kr~΢5*Gv9?G50UoVtz!)lc2 w(J63Y}aa˲xPoop#@\,b@H4^M DS_q2g|(EFPfeW 0ARsaZl'{훻qދgf"0_:v`zƯUU-zo_F囹I]NcR~}rI,ۋkrl,?a:ǒt;w&S2;9E g -H4m-Hw{~޴90S4DoiMQ(#Ъ"Gs;۰K>o_|UL쀵#}JGqus’]dM+.']ɭ?8A,7Ch?EDTÐ(D YOqMئ}$ށjCVD3 7h4B6fQHD 0ȿj߇Xz0"h6ZlUݧLMCQF;GtliXtr݉)K1qGB`~z&Io|k)+(_-' ]3 1ɽQU>zq: *mߥB3#?qߪ?:ES/EP.oaYۺFhoX^bwdl[= &6~7S\6hfﴧap)wv ag ˳,ؿQ㌴Wì YcXy9 }l1T$_eQ\YhyrAp|goʾtX_]O Rk`M|!2h :,Mcm J5j7R_-nw鋂`kWkV5w۰9b]Vy'y1V)wxO?5,qlq7KWLI=Ȭ-J:C6F\\kM_PTnG# 5=S~+<͓5O[ȣtU UJ1h%t:KHp@Вv 2]o@h#+SFB WA[6krڤ(euK"0jAC=nXX`-4DK٘>]DKRʘ҆{MZz~30}CDDwa"+2i@?&G "X,ڄިp'}U\|Ȝ܊`vro߻% k 髙AMy))rcH|_ǃA 1S'Y~cZ k Q@dڑ#p)t%]0,Y&ٶRF>6!}Jtq\vvL(F -+i~u$zY(=ϊYX#p}7 E54^Yg<,fVF^J ]3gF`2y m &7;kּ~˃ 0Q+{3\Cej"HNPEә =X."!,0X3j-rTdm0A0|o+w-HPX1ƆuP Pkħ3W$Ӭ452I'" 8U$|P*rJo+>x虎l11MZFiSrXJaOI#}F'mL)$ ⲋoGX:_=fZFUlsM< Ϊħt /{mCWI2&e=TD<̧r0_M٥/Տ #W?cb M<30 > ?f/x9A HUtY P3X/@jHN*rMNĦKChIÛ)Oi2 B&""oaGd79#N;frwwqW, &ai K{bh_slQRaS?r@rk0 3a#oizĠm*͎O,HT)4WŒ ̍DF VHw)W~<@*_[~>zŁ˧Rj(s-d AACڿVť+Ù xXyvygT5$:Rtx n_cqh NE'R:S^^gzJ}{| 63$}>:LJTȭ7ELf6~B+?. CݾЮMZ čJ_{$3wb>g@ rIjhm# owT67FS|{rEV ݣm'FW1 tU>ER /-yXΕ7 i;@R !f`de3yˏ^*Wtg0 8%׎*Z\x`+ut}J8BL_euZaydKU^V U=V ԥK<~V=V3/؊2JRI"҃dEEn=hRQTl7GdQRJUR?1j} t.ſӨCoTKcjE.O\}JvfruȤ{u,gG%1"%9U,(̚kCQyn_^ާ4|Ґ5 Y} #~p:÷:6% ڲ w&83)2D" ؙA,k7B_ I|7tf3iJ5+]n5[]Q[?!OX 8J^R]}D-HigIJcTSD'8N+ދ[8iqMDhsbWN Z Y,`["2Rs8 =fYb1q@-K&| d[TEuQyoĕ4]N'pAnYIP\'E6J7wkg:;NAG0*PF"^LWgOg1\3`a_VayU]'Yh:9n3Ye/cS]9Dܖn 㟍!8مf}; V#q#h@4J X00ڑb;T%D=f+XK^~!Wh;4fVqcM_dƏ{#\Oޞ㭩:Ro|IG =16Xf7zERjK+>_rPb'G]X 4 7"1rW*9~5czk?{J:R7qޜW}B>O6  HI|'P!V!jk5]2U3QBԘ,rX/A'aI8? ;őUꉣVDPޡIIo۲DTlj~0>w:ט= $f1dusxΫkc#o{,dąbl@CO;͚)tpN/Ŧ"p՘N&lK(@h!pSco!qz`^(xfַm`=Ntx@-:ZD~ (Lys!@Yf +cJ8J  endstream endobj 132 0 obj << /Length1 2587 /Length2 30712 /Length3 0 /Length 32208 /Filter /FlateDecode >> stream xڴeT\]5 ݽ [PKN஁`-xN]wwb.{u>c%( rrgbcf(*͜XԁfvfVVND** W-IqXs|Tf>@6?@dnvmt LL+gțY؃mfNyf%f2 lЂ@3+ hiHkdUT556@"6ۿ X+ X xA0=? * rkl`\g3=/'Yu & t%$x.m|̛;WI6N?.V/-Ҹt f' L怗+/& փj.Cm+ck ~+Dۀ|g_ Be89XL|4Wſ.QoV@ ĥy{@T|UºI0K;%("-ﲨAFNTq^[S',DPF󴙵BUvQqNg%F%:'^1.( +V `Jfٚ]0 ;wBc'Ě-Ϙʿqځ-yÒwY_:3rD" $|0DSKDL*v..AzHЈ1q'.uһnOɟ(㫞n.-%J/H*8PbxwE|قk\2N!u:f- >aGOCy7 )ޠAtbn ObǗ}^u*  &g. VfFUj'YUo79zkS+)*\J-wҠUw^ i$W|kKUa{ Og6 +8FX[W臘<$~q~ʌ?kVı"O4bxq\_5_p4ȋGYp\ ]O!r⏺觙e,07I%KjWedJ< |EjpQYuR>5B"8&2 V-#R5]uŕMDx~Z]l$٣QhU#.' \r@nwܛvb8 ×n^E:;kUO$Tq4 }.rR~ "]@?7t Ɨ@^N85 gA)0ŌW]}~p5RBdWB;#&Q6o_hu@>OΔݑTwARns݀D(>떸ށ[T)k#Zv˛W8Rvʛ6`JV i .KXy }3F!Q6z,7% hm_l8̊ebm"$aW)e`+_l?H+yo6Ŗ}ZɱU*9bAElyeـ2Nov1Hv6aC8 BʦWyQS=v׬Է̡p*MaCs+_*%7[F铒(A|qIRNOnGrkV:+.OI}1d-93 $x sF#//*v^v'n BTK,;~E®݊B=c?Cz`=+]$0/fV>Y:BQ&7мs {+a٥SuuF,;Fwҙ ؠ)Oߞ_khˈ4qtNPFmg&m#ӟ9ƲUAjaj[њZc"W۬uR9.exaZy Ox6?Y.I|x W%8DDf'dcByo>̛1czmm\)%'}R.kxe$]Ґ\LJPϏZrXq:aؼA;灺8,"ǩֈM"N j 5³d:2KA<]1{0F|֯(vB~Jc@#M8|MJZ/13"D,,q8C['RНTBAz;dmruvs&܎.F\t{ x HkC0jFstuEFT+hWE݊D' ֌j_wƺF0[_n0BO$q$(i T9)h\Q*#Q6=4QҺQTG@%rG}۵UǾ_յ 2 L{IeuٹXQOs2)4/]: h DC _%7ڿN?bYgLX 6Mtd.KA3I J~x;ap**O.$Z⪱Eqw[ ˪Tӡ>;/(q FsB`@"XtgQ_>.߸XdJE$D9͖xۿr&XPAS3c8-u ~&];D"d{nN:-W<]6i!Đn&l)P7|Hڽ’;ƇED#;GfRjw2Q:b!VBj<-v3is 4VԨO}y/3]M.G ^j$ABvIKdY8Jz!^۾ls S-Պf6i 1o8L੘(JTv>< ;MFࢬT~<>؛땔c7m)r4S]*9j]EIU^u 29Ι,q̵aɅ&>kwOlB'Tq~ yLj=$,v8洤-&~yY8P# )%j6j(ۖ*Q=o0Kahciǃhv -Z39䂋XGb*]O5e)jb.TTR7XZbʵƄǮnIQ>at慶Ku=9~q]bP_Rˉ:.wD&a5LaAb#R='X ^puh;p@s Lwbt:k`4_$iaWP12 Jw% ##}V#FQJEn)Wl᎝B1Od BfI/(m6G6j5iQ雃ˏ d09L$nT5:SOO(Dj;ŪC5sO(${ u)X,!7<Yy""WdiǗ*8nǙBwG6|Tq;ZO_< r(u%I(p} ZênO&:ld1:[LFF񵼪X3#D/,238|`VmkbIp^l@YŸϬMty7Rہ,۞K_ K9bVO6i[v g+m33dW1kE" | >tG8ڵ֍fG 0Bdd+f3q`3uXx%yppF_s+F-ŋ#C26J9dR΅opcD=sqfHkEM .^/dXw>gY!uS[[13K#CbNcH?8 PG/\qVߙSA<}5l%}* f[svmzvC0 Y ZKHHa/ϼhEGPLK4yYYR/ڬOvyHz)(3&Xn)όq1}Rͬu=cm(>?aaMJ?|>pP~ϴw%pa{?3=luapvZ o#iഊo6|] pZqK0 T)8v  t;hB/8ƿ"szt@z5Ok=xI+5e~@)x8~BvȄ|9wv,b7oQ>Ȑzqo{ߧq5R $v iKJIo9ـUJ7Cʣ\qf7OLħ>Jj>tNlueЌaߝhew~ A.C); l}/[1݅x;YHXy GT=Э^(Nv-S z/4_BKXG&ZZ4e (ۀ -ea1ɟrw- ?"Dо8’bM0c]'kv %(fӶEIwS pCgsw7G :"57 BVeo+TJh{|JZRk Q>BxU w~P OZ&l3Ұ=]udE{|@x,w}Z~s J,-햟5Z\cIZa$WfLGvD"J`zcʭ/6  5[ib_WE@q*WCK˂Lq8%lnk`!cX|<{΀P;"mg_;Ť;J\@'92BϹHlĀ+? okyzcS;Qm}ElC,E)*K y|󊢏)vbg #;OG<wܦ+7*X_KygIv]8&*J Lc fZFZ_}騖̇˿bȥ!f,rf:Xu,|`Gt F\Y `iԂW1G_hTK<*ȬU KXQNEAT+*o3ˀfd7m8Q3۸F܌[s:*YH/0]M_}}VANHa> Խ)ōZn|<N`]R/:Gu aX{&D-B_ўKv<RJHC=W&FxA|]ԘRa;h?î?Mҳkˊ (J r8)10NK2] >JM~vf\kxyAvI~o:Hr5x˔o$8~ծobz{Xjb8ѱpS[bei3'AYOkɱwd[3I}a#_Vt|2K[hk ΚlX$p}u&!(Qps*iIЯSql7|pgW+C~P @H~)ɳTBڕ]b(G n $frМ%.ΠVL׳7jEކvW_I f3)7UCG%-\TnUSjh+e{8cc^^g~A+Ck{g!!ӌ;71_Q8Su0-;בìbblkS96/.drrd:᪩{&rcFL4|yǯ*fj$V56&Ky&lIJ-LpG,u-V6!k ߬>m$FE'n=PBV"=b;[Xa* ~X1d.], ᖠjo⎛=m)'{k]xF)GlS= nO\GD oyoPս"/&yY~s\~_n*`\ FrLnd_> Q$(G!uA"A(c2Pl2"\=1]8gPd='|ocZtȝhC|{EO3W[gv<00x_:3Y(Z3;8ZjxJf#g&"th˼P^jM=LZ#ApD76 Ж%аfgr?CP\%HbrFK'(-b+u? :6uC~ROMX7KJ-]cIȂhL;e(v~쩻kI6+Rm(ڲ7"Q[V_fb@BWb;*h)#Z/Z(Wĺ+bVzŝ\:8\݄Dr3F,LM`Bdkeކ~F2_ ULR~_Cڜ@ *hiWj33Hh˦c+m7!_sʜGu6mwtF,`Yu4A>w~yrO̹9r~7RE1'HZK_o-MϡcΏU|G^;'@_L^# PEN0+!a, b]egC+|ӥ|&yDfqGVy"g7h~ 4yˇy@̹_Ok8[6·d9&ʼ Uel%_ KMޣN6jߋ3G1v֭V&' TsbڡI]>:6d04\|{>|BYIӜ~",w.x# t<J|V2[MmΎWS 2%49F Oٽhn4dI*<~ƈ > lS_McMIԇi-:O!א4~zuFb>u kvStVCWNYh&Ҽ[dGzLyd,. wk熐vP)ŕyؤfy,x};L1[$j/5Jo,J1W}'|XdYNPu;UBkh&!uJCE׌vD'\5vgcmoKLv`lexX%1.r3CDW70]9DIP(ṛ>S''fߡ Q,!hR*Xe*==A%&fB &HJJJ?8N=ґ$dLH=le'ǁ414=Žcqt"Dgh4Qg+sץSE0)Eb\5޸ -v H:<ܑ2_gY6l \ n?SUIRMKҢ D[d$a@b28 Jm/2gG'TݣlǕmA $30T4)fǞZ}Ff:Wm"lY WcIT 5Xd×tV纣RzD46؛Fv,2YE#|y;+kޟ#k|} K$ Z ٟǩzb֓s#kg}k%A=N;|[5ѥ%+X#1=3\F f\eCǽ9,܅5( @@(>>q+ Q驷$Ο5[F=$h~E[&Vbivߕ9IPB)CECkUVNsl + bi(a!ܐP.BO*(.([0,=Zz9 vʍTLd7)%hRq@̱T#YõC~=jŷws/Mk&zSK(U9B)}R{á3 `?q[= ++fήY~?>h gcé 7 ؽf.'.X婨bg*^mU;g G7s9ZE<8QP@+=B毉t. %^ мA>V?(`*MAF=!ϒ e,!EB6H7gTpU}ݓ(BdS`TQ|v6~b&0KX}eX&'3EĽ3 E )Cb}$̄Rc/ư?YH1mU,|mKkV?* xl GR`iYJIOugk/W%PבBtd hI`:P:hV|3/C(B;c >Jܿ/v)Y.LN WI+ Q7ϟ;<@4[3%OV9jIR8JG[$r'3m23^~g%yQ?KyYuʦǾWu.DcP:!d^|k6|.(9?*T IdvE_#udڗ2槰*OVLBRX^D;ƍGqlUꁙth‹ Mn7w#OcexV3ƇWz]oQ!RuѲq?o,}< $-r]X 486?hNH+nR9t̀4dxf@}>FutIq G0My9˞hH{·kZ?mIߐoJQ֐sVbJ$=0 D;R=Gv02B{%X?(tç($f #;A909RZ?>vnȊ/A;yZ& .L~)ǀIVٌ5lku{} jÉ?j&LR}v"h4mKqYA+V Lf|߶l_qN !6γkHHOZ+dDw45鮰(>hr1̪Ny*ŐۻJz%x3X## c)dCF.jEяڎΑ.0.2s!RDyJb_j]#^Ws9{V[nρHa}BjPiTi/뛲!cmb^ \Ɠ欈9s\rAJi:\Pٍ5')K }2a8|ld`GN$6ϖ+1~&;}*zA3C'uIl>1 H^,c GG9=8ꁙR^C&vќ{IounqP"c /M8,4|~zZ-<IN`oݴ21B[L`v t?htAøRP|ESS<h0SUxKҴ-0W }bԟUvmyاZ -`OBlTZlCʌ%"Dž^ ,ha h? w}Oh)$ Ff)V`+ڦwiї~0{Hb|~jg |lbSqlv G&"{' SsDCCΐ+3˦s 5"nDGgp8L*L";ZYbG!£;ET!N (< .!bu;)ǟmcÍC$c{Vj }+,;,־=;tXDKN,PjƌqX?|X~+*Q"zcloNTjzB׎yά񁲡 'sfq׈'@_ug9-⭊" ='ԕ ޢGM埕)+8*'Hڿ6Ķr9^]ں]4ma.l.|fYt?a,xދ,^~ƬR ݖ>YۆNiRGH!o',Ԕ%Km+rm˧ѦܾvJ1ϪrU_yV,1*]גN9Bf %}PƆH7qih컛Mx%a IQ!b8Q_櫦ߑg}5fNZ]3s2'c|k?Lhþ~Зr^ { %v,sEi͊.STCdB`hk,; %C&sA;8QNv*eԛKy6^ܼ]hdrP1\m.RǵntBhۣp?\ޒ͘PZh ";lkc;!SA;;e3~ntZ\@{£=f/QAoC^?ir6 5aݠ?@S8rĴ!ghE:Hrvՠtn.0U?VY_kw+-ɣ,xi8=tq9M0LPP5KK.bLI5}m4GJ zmey>FBr~e\R@GYο>VpSSF0*/KH`^}&;) {O2ɴ@GT=U )"l .;f\[.18A/G"d>I}# [G#$p‘ tgAKaVnj]HM*@Ek[ [7L~C}8pWZT 4 KV.wѿ tYUdyoX=0*90 ~%!dӞP6tiҎ,(kk(ej ^O|.yZ,laՍ'S79հ$/#|$."E6n6* U_)f MU}g|3jjӜf7 JhoћY( E{Շ*qpbh=Edu/'*h #S7=!7U6/HX&*bUUO:,=4X_`Ra -mnv{ͤѴK%| }_EQEB!N oE55+ !o N]2>کcgQeQ~NRHREŁ)XGc0'4[h_WĂ49j~ ժi0?},@JBC{gF9ܐPI6aHNJ])Jئk\ϲ0Auޅ0=+e|9*\>bO}ܻ"91 vM%{׈7#x&EuO!~u@#{Kq+` Ԝ'K+$JS̛;ÊsE{ ^;)sR֫7iC3VW z6Yd\rx%il/qm)^OZ*Ms, #ejmsb-z[XT [^=:qFH9` ,=5H X=>JK51g?MI%"]ʲk6mw:S/:?ڄIJō֚#] HPnC"*;}gAmpE9 $.AJuN旓&28ޢ R );5O!.-+\HhJʓt,GIX;?`lm3gi<84_QJ Ce&A+r5(*d V% m0p pP1$>U$eד^a@5a@=6BЈ>"#oiBSިQ-0)yjX Q]8'Pt*m$94P̛+Q&+$3*28| ^@}usc`>ydm<"tljbI@ 6]CR .Eg^3ؚvQг봊s$\6N W` 24Uв6,aeA8{R`xň:TnS߉oFMX'֟8 Sq̋v0"Ȫ L}*A{K_? :žK_DMo/mވ&h2}VHtgU֊a{])>K?xtDX66Yb Y@sa~`<:S\8vflEs-ϝR{T o-Y 0 +ϤНsp%>*Ȗ, P:l1lh= :0,LJ:7;kMܡ0qz#SJǧR"LՒ+2MJ=Y؍_@58; ߉wKM/0]\Re EfﻠUUg?ZM{Ai2NT8~bIqگ 4 )yeK TJXGII~.gi*P;.A!8ʓPuyVc c`9KVTъ=ll{]LSRB[i6cI.mSذ\©. -?˝p8,}φN$^?A.'iJ+32|w*G|u"'d3j*AU*-Zkb` Rʛ5aď5B':-8(F>hwFTT+DWw'Ael&o:x67ǵfzxE!$oWr5x.$zv)3z9^U]v8?t}u8(n1É}^c_l,oNTc|-t$dPk'|JCW#.5"&Gi/]6 M:x\2^Сm,xp$?ѩC#K]gStv_H'0껆xy l_SٸP:1Uc.u'{zJՆ^ް%XutP7;FT>X{1ZUH rH#uNJw+6|Hcà(tß`t!3mEU6a>89*5Rh1rԆrdɡ1{q B/TgSa4E &@VK2/iף7#efC7 c*T5(o4rڴTzPVqOJkp_PV{d* ksMUӵw%џliNs6>&"F)1{bh3s=4_p\+|Y[3Cmc*uHWg+vh 8i=.R u4-R F]&&i b•#lRH9`::b)^,~/Td9XI'G4skR0fI~uYRƓ=hz~3D:]|B%^s`vʓ2C0'}8jWsNs(`,ڎ΂Jq IIBŜT{\h̒TCU=,L4\K'iP>rF*6ߘlX9=Xɴu_-]苦b IyAw0Ǥ1hb.gMCu7a*>>hQDփ$a&jNGƥLhcM6,.N"-:c4rtL"~[lqZ79[00:4 frpK>dcEŤ8%_d˼Na/=ǨZNL3 y9W| GV_S5$QI\ +Qx`ᬗ>Pu(0EfQ9}}%:K#քlUdsd@v7q2-lǡ\<{.*{j>$(Rڀ+85O觅onI_^h&*%ڭ;v&yRWh D)č1gK3+]_xם@v!mMyh' &4;vzO,c{@A-0P­܁r{Wz'oJf 1׾J\9X.̓?'rWya[yl4 Q-n:ZarRN<9V]҉p?n?rf QFB'o\0yj⛁a+ 2Y'D,!op_ aD!lAd}Y@ )2aal\'=]\45)Յ- l>, ȵE ~ \,^cHV@z]mEi)Ǖ])Jb> w33iOHRuD⏀pֺyݽMђQno+$_4-pt?obp<4C@.)ftEzp_ (DЋ?dkJL7]{XNiN~ywR! 0N8u%$|\[; AdS2l*ƣih33"'-^4 szΒ xi%P]\{mC?8SNu |*KZ=2%`~s*c>G1Z~;GUlۘIkB$[g:ߦ~|Ѝ̧'+L4&^m򱷝09G~7 nm`}Ht8ӂ M8U-!TtS=ۿ9nqZ1\mQ.$52wu՞ 0Ez{7}Q|K2C|4zM\؇87ׅ+F=ߏQ<>j('{Ě*mF2 yrKtoomUms`lpVg,lR!p?^kq MHkWԷփJܴ]NfŲQ b|_-ň|kCŲgWOݏކ;$8 s|4 jXXh Yǔʆ%B~1DS_q2x\9@Y1bZd#d41LL\sv|cD'496ʿ3>S@m>,r0wK\r^'}~Gɼ:;}gOi$Y%uW湈KbXe~3۾][ґU[CŞ ЌES s9B^D i5Jk*Xھ!*0Rz\/@4X]ɉM];O Q~'E3g/=k..7`ޢsOVKjh,̄Q`n'}T;Xq*8Q47TLT ·_NOoi>8 'gအApc05*Y>qZ2pVeQ(Ѷ\h9&*=^E"u"sC 0<9^oKH˫|Tr:d&7I{D Ed/E>=Ie'0钧 ;3yeg'TR w-Ŏ̩E)+\*p`Z@G=z8QaN@g;<p]xk+aT8k%LPHx.l8,TC4ˎNƧN`$0N܇lAr!2g=Sȶs|54^V9o6E(OÊ@& J椪4gR]( 5J nPN%58g,M bC\\TmIF# cy×dpo_i1.Q9<ϓOHD#GTxӲxޒ1Zumkˌ lߓԇjOɠeE]ZB`2;=0AӜ FĂoDGSuĘw_%" 'D%ˬQc`4jbc 5Х*6B~1S"|;هKGΒy6q x4VďXO?TXn{ˢqh`dwѝ=g$Aŕ}Q&A/z1*sgE47"!FHo]* *^8-.rA)Q;DGF822;V6@WRH&w~CYR|QrWa><ܼoI6ljMz E$9Գ {ֲ\P꾀><F}W./nq1";<0}Qt'4"3\d6ۜj 8 q! :dd9_*6*R=,A|e;"[|uƓq{|l>S뺬:# |X:mq4!aڵ-·G8Yʤd[]|p#"ӿ ʥtXX1mVK#B)pZ<>{pyI B9na h)nRp֯yP?t|@h"/X߹vȱ]Wo"Q$uk?.l5ż]0 _^6:B>5Hw"%o14fչO E ~ \,_ZlpK^FbR{k +<|ᆰD-;^h6eq,U\\ztTJЙ8z1vz+ 4sY Rں\m:aw 񿕺}ܼ;:G-b^j-4eؚ#ݒbjd+% hfq5/܎n'zA#!> *<V@ҹNk~EGof[yaZM|jTvlAJvH#W$8-70# e<$ݚb4F2zbLئ!QO[lirߟz ^y8[of?0c""ezVPmws-ٴGLM"[wfvB~جYU18&; #qQ}cG kaKJ(N+>CxfC>GN%NP`22KѦź5 Ճe(➙ʦXk0pZ d&r{"rO/dq`?/-Yp ;7ɋ!"nXF!yx̑z;k,5r~lFɕr_IlSS }x~\+]C&Y9@GPbFB\-ae]0ZNfT{0keku.wZ0Ȱ=D834aZJd:I0NlhtoЬX-g Zm*ZU8`A/!=*lC [X@FN67#J-"^o\#}.m+à⦡Hi^HcLŚ͈yKX C)o(lW]dCfYk=8 P|@qT%;GH>eY VJ7?"EvbU ڦ#K+Dgpt1ykgA!`jKsR"4a*1 r+su[8qk]]Ʌ4g' ʁذPߴon2pX1Эӱ|P@NY4 օoZ6%BiuIXlohFPF]:<r@oG^ŵӖ'm-Dq}HVb{I!8TqjakdYIX\{P~rSsFFev{ mm!4@u#Tt}!@_o%KL>-H{FGEv& cPB.y<+p[e3|>_*_AVJIxR`/sevэE~n-ħ ރ_O'o|!!sռ8Z{5lwY1@DSł=9c˓v_C {n.5{ҴsW [3=(~Bn ڨ^g%wiwW+xU5]+zH#]O -@$l s/ӥj>TƟˈh[!)(eW"5άw3ܪ<6o٫5|kC`Όc&Mi Ƈ<(*$r.!KY,*$2dD`ΏgF&}ܻx@PC0|$Bdj1 OF5Ƿт!!BJvJ aC MNtg$4P|<˓up54Y|h%FmąS M#?n2CO@d6RnmzFqtٮZgDZ -Uc;Zވqs8W$*$&C8lT`N٫2L;f.بo~$z--nM].T:LWk߈]=U\ݛ٭0zv2}>(( QH7`;h\JV5\֫'iڈi&NAyQO Lcsrg r EgKǛ&-Ab@.80LBGW)=V[8 3.1 @hyЛkF}8%aTT+Umntv(9}q;tayعd +֐#N[mE B9ֈS U.[A7x})>Lhf a_`AclDejVj.Wh?'ͮ}b% 9Z:Q|ĝI/.ͽS*/qmN='L 4Ƶz>2gz냢t#Jj,S=%@EO|m@V!_swI'[^bϮN~d F u\[QY@JF]'L.\#@U_l!AU]qCzDXdIKW759覥(1cZeBC->M:dW6W|y4/ G zl5!6A_xcEGO ߮sc7ӣv͐GNTa@;~]N9&\a/mlA~FP+"?8<8\unA5 خc_dwۄ6PY:[3&1 {v~<9H/"){*3Tag‡( N-5j LJ[P%#)' |:M!Od"cspZmfPX15jp #W?cb M3ۘ2s"4.īa '] "Kz{Ctzz]jya~WK%vIO`bLȁ9QEpQ߷SV5%35E3jHD^d0 ^5b[8}-7i59AZ |G)_7gx{#5 nNc~A!7 qǔҿ) ثN 'J)/%;Mi/ͼmGB}n@v|^Ljgp6^*kS(5{RɮTnՒamǭZ! {oX/`HBV3N`ZqX VK&3\7!oucvC݋1DC1R{VDf28IZ2={9]HJxHYotMΌL<#ڼ~t6QJzH$K)$s:l i5^N0K' 94B9l 6>.o ūT9$Pj 6NOCa-e[-+Tn4ɇC,.,׽_d V9`葳?{O=B("v k{ES k$'5!E7p$UC7Gee& VUJwYB, wLǯf/Jh̶ӽ__".}=<#SИNtQbKt[j=m3-3G˞0n9#dOs] =^*;*RЭQp~N| /:lc!rz6eT Zr7OQkas)Tf4QJ; ѹe!6] !mjh=#yn"P\t*hlUDRw1q6ʖ$Jm m$NUlJ=?X2 ^Nyk kq1yqϷՠPSy'+! B۰㊟ .ϔr S.d05}°\,+ ep%z1yo9:w;m2O@v}Sz5;0+*( Z^xyM*4ot)BۤΆY`mLo=c&LGם &vR@0 HwRaZC*[h\<C%'!Yv%yP=0oEMXgf {?|l}h1N -k*܃ .! &iTu/F?5d-5Lz 4lˁ“+6wsYʔѕ<G`߇^vܱD{[wvVzWb}<&UBɻ͟[؜ {>)=ɹdGy%Ny|J  5rW.$* WUT lṭΥZxQG:'5 ɫ:_.[Շewhtx2&*JԀ]0w>o~Fo*UGͥ*®pY7z VbKimfI,M}Mr\=gJ,QxUbכ' q q>b͸sc@lyP'W:|HuP'5'm]> H1~cp6cS~g˖ܧx(5}ՂP ":;6_3I dO΂CP]6f=}n:tcD "jo)^uXbheQMޠX'hPt64[4_~zf6 6lFT9ߍiB.ZӓTL:nJ% r'*bSR=̵#J/KzlizrHM ż=г<`elZepy4iC3N{/̂sNqcE DVy"|nCB?(#@"lg"Tgm?<' h9I:́o_pC#jL=閃0;b&9p@)|T%ϔC#ա@,;YYUK83VGgODlf٣y=MD1O $n:q%!Tzx%oLzdolzɊ٥$COH5]z7hj$>ɶhGHan3 X(bbu%K3 wz{kv <)fJ % (%[u.zʮfaHz{\#s\F㬮=5?a0/W{郀X ކ)ڮ s-7dH*.iQR]N ԳhMBw$@zBV9  itHu׹2ۊiG}BR>yٰEe62=p6 Y:μ2߹H-]Y yuj qFAm@Tm M 9&\C-|d;&1WB#^϶ICU_ rs_0r詛b0x*M+n & LH4UQTC:=0N2Uیh@IpF܁EqЕuF9}Bf61z,o=.,2aVI/v.p[c_(/8gDZ{ o%r5U3${ aX z$INA+m@ NC$^PZ_g1 V#Mǡ=R> stream xڴeX[5{` ww  P8Np N|dӧwŘ6;ל (IELF I#+ @^AlefT9[lL,,Hb Vp;r"XXx(R [Û`P9@_@ht|sl,lAo)b`;w 3s?5T-[],@[,@fЀmF s)l Pi4$TRJjLo՜ELM]C ..i24Tپ7c(IWPQQ`e V izSTS_s'';>ffWWW&3gG'&_-`+۫WcmMdS[lA$;mZfw_aopSp#4@ǿr啕6@ ['-- 0 2[  C_.tQۓY{z]ĀΎ>1 5z?gfaMADQFRBMQmloݱerrs+O=qy> '6&b`7ՎH'n'';l+[OM5l-A2fB ` 7cs?3[#=vS#tAޞt'BbX;ۺ U] _VmOM)"m$hٴtVڀhOO;hcaF`/DmqͿ5X2iY)},\_F6N򽍥-wU5uD'ak 65qr@w$Y`x a03قRvNSҟ012xrFfEj,Ml ҩ |>EڔA/k- &*@T lM&tEdy:3魱#1·HW$2֕\XY֦֘n:: ^GG{D~uwkbhOP*!7uPPJЯ'RU,Ldg&lY!c&`-Lo3!)=KR2Mt<[,#=*ߩWhWQQη݆h \94V2ZtS'YZ'}0Ss!$ԵR| LɵѨj_lkdU9*˲u#PJ@U&g{?=iيBWa^*_gڑ9blt жY }")WnbNI (@=iSOoߏwW*ў\9JP6|xǿЏb>OCl gIEY 9M4[5T]y74|r71jTG*[d֑Fa =J-8B m&`T7جy69W_oSEV~oM׍&K#X =}'.i?C(9)oZ%I)k1f2C1 yN]LfB7L7V8 a ;-x߼c#Ϣ#lԚX 6թ3 G{v` N*TFf85O0Pw E 8:p-$A1"{" a!Lm4z~ѥeYFC\bz J%F1'LrT6H2S\n6hU M]76b4GI?cG;뼢UhAwVMjؽ8|զi; ǒ9‘J5=L Osmsf\#4zB ?sBv6&Wh7668]G_gyw3D57켒z-6;8EVoe3ZJ~X\~ Wǽw}I{䱙zzL@Zt:sbwvbO ݪ܏("CPMXb?Z2>X*FOBo΍,Y^%ni]-jT9myy5g)ƹ1WoBOAjA5ڷ(1eҞƙ4 ^I G+vԸ 7\//as>}ebvq˵ 1uGcvkQUz|\DkifYw09a՜gB)~uocAiZ)c`&t\ñߨ(זpG.9ZR (;uH$?E ?WLcg:%.mVR۵}՚X"X;Č4|^&QI1+8ow5sAq[Sf,p)cXFҕ9rՅ8c4KfCT|MCŶ|q ]#S8T 8zw D Z}L|Ӯh@2kU]3;~Zt8cCsS?];IU!m Wm(&h_#g&gO'U.^{'3ϒTlaFM oP_^]t5W-Bm,Jmd+q8Q ,SC~C& JkYܯ+;͑>řv<&2BnZVs.Y ƯԉZ uC/SE }U#MU3mטʕkQs%d%C69 Y:2Vg{R$/BTʒ hnqDVQ!` ʨC')u աaXα(1:#uډm n kI 7&g{fm~_ +ɢU{j' x;& j\CBWYr9w槓(\>)ym0dyhq`*Sw)&_Fj#jK_*y@>\]Ҹ)?;+5*"x5 nG ?u] H﫭-Qwͦ F[396oI :[;ڍwlل!gJfԏcȽ\m`dipfQMiڻV5ڢ]kbb]2DGDW-:Q 9"Q%_B?gڍ\!-Cnj4z!i|d642BO)5Ƨ4!K{Ƭ oS4=NxiThmV ?h3]n7\',k]S0 l&$q;*d m@vT3ݞ#uj7rg$"qs{ dqԠS+T׻^\٣<'rNX盔_,G*iLK# U@ nxZ =+:T=H e-kFZhf8!_(ul]"RRʹP FlzF&ޟ}{iۀIFwư6Ӗ޳T)ht[3jݔ>LZE]5QDOlHc}ɛ %zL!dÔ%^VìL& x" ޞ2\-6[W9CEdXKi{Wçо qS;HxY]û)' i)NOᓻ!3)d,Ӽ%uz 51^"ez1w& OX}ukqD_Bk Q}j8{3L7>1 _Y<9VUM{$^zkz?hIE3B|&Cl v&MlB/eF&o'n>,Vhʲ"y8DcUR5A6KO|up k% txmK:vِW  ?u N**^ h֙+ϖ@v% T㫄!1V6bS(Q5OKRA,9lpl6[+Pe0˯XX"5/+_  R5%L8Btǽghm:?w_rga+!s6c/g<'= Jh^i~p;$mTM|ջI8-Q= 9FIX}͏T]<[lIZBn_a '!YdE]>M5n|*춽!FvoP PQ3j̢Y\[EdC:׬mEp!$lemI9pmJ}z]gWʴ$=p&sibPf^w] )Z{E*Ǖc̒I0nIKnJHk?lX?䬝_-qJ*k$RnF#e3p 5r*JELfP9B2ILc?s$瑵 rVg6:'9;emFY?^l? 0>P=6&(i&B<yg)}/LPJ7OMR.,+Tw}Da@֑ë=[ a,)(C[!6"JAcN-O302՚'w&F*,l"3 .ZfAUKeN2W4DShevXz*?o/+Vorҁ%csS;C% '%Z*dHz#|l1|jg:5McxO!/)tWC<OixI6P8un6uP6#+ϔݰ܍}ye*&(铫Bhjo$Oǜ89 ?Z]*AժӫI{ 0YL'KZƝic*߷[ CSys Lk-h'5yp"^ǫY:1d5k=F^KOCpD(@T\`fn,.Xj ! 4&T_^nZT $O)AO-;FR h;&|w jV?8ߩ# X>`=ILS.aq K' ]c vߚ)UmKAxtB)nT,NF[ص q"@M|j*`(6 GZ0G޶L+;S4\ܝEyvr톔RWkq"S<;I`.I^l-YCr,pumȴǤb˩gۡLdۅ~W&ثa9}kn եue;#~xJLٺpۅUd3\HEbj ӔzNC]_Es\8<#dD'mL)kN:>q380%~ @Lr-YYS,iѦx:Bwlܚp*3PȤ#ӢIigNx rvJu2krOSⲤata?%j Z2{cd!Zl!_9Kg}Q<4hYN땢16fHĕ(\ED$y-|~ TL "YQ? :cÎMxz7EN* tg;F-5ߣ78Q@a M bl[3d3_yGmLaf84H1d&Kࢃ{$%]DN'Bi5(3|[$A_gu$fyUR0?_$R^$jȱq0>/`VgB`gS@0h Kԛ^21a 30$B!7^4$&ԙ*>yX%´ⲋ1]SAdT@NW + 7N3|\t'.<=BPá)2- ǍR!a7ӘKXz[ pNMaȤ%Ee(~ ܱOK^$gy"6ev*uAb.`5\mOGmj6яNV)=1'9_5^I^OQdhSIC2pMScKi&yTh0";E$s/ ցs#8ߍWbS6WtKόqwᡅJB wW*);UyU;;2 $TMtӑC5AZ97%L5W+:r'Mi@вT"/Ӫ8[aAl}uqi(tsgwiVE 5P%U_G n!}NYG(9(s Y o9WED͋dw>OGjR=8}_%nqV\`,f!M$a+XYfmeLBTLL5ZJ@_`';g쏌U̵LeғxĴ?A$\"T4P|*Rʅe~GQIE:1AwDwHDߊ~wE'rL=]S=jс;vM}D~H߼`P=1|tgK.{QT$/f ^Lʈ]6z'ȀPGXAf5ve p mVj'ǒEF$319G3kOhC&]%IrHIJ:`yEUϱ}V(da x?FLKb Yy;r q'b 6'8E|IB! XIo ^xq9Ba.~p<B--o(J:„&Ŵ$؎ftZMpNP1A5νNG%srsf{'=Nn8_᥿Y'E^sGW77гptxqaAJ]!rr|NSHB> k}"v]ΗrhWf#lqiSv'D]iTq o4 ;JLOﶯt XO3dlV-+CbA Z@_k#ThW'l9rr&_юfoz~'ek³* GV\SVh7o #Tx֏f$5tS,w9C|usEe X\Vm_JERc6ԙ5$S\E,ܕS4/ +g}ҪXKS$5Ċ"Ucr hՐTDU#x;X @%D|Km!&ue3/%Shz7\%!%v6b,tc:$A/&v \!A)/*NaKTe7d>;Q{貌Dggu`K`U3:~Mo9@uuk #W*2Pl5L"j n;n9cZٷi`} BN̷5̿T.mPg.ޱjztܨ ǤHb HXsuUUHqK3IL"儽E8ƚU. WT?f6e+̅FӢ^`)Qst&[; A^^?xZBi/(i.XYӜmeǶ-R-$// O\)DU $rDrQEiC$#8]yn`Mk`:jEhz,1C@[Our &X"vx83Ŕϒ;1 mVҒN/iEu-sHfl2).C-%%"eYW%\>2M`hgU:d|N h}ǧrҠع\+#ĐW[R|#ڟ$I6`IA_wyj 5켁R$uBd |:\|Q'XP{lʚ?2H6 EIS^-9&qri4ikIpMKqLovJdն궁JI>Nk_UA/]ؗ>wXbWp}+^ꊇR@ubhMtl4x)P4A+&$7>u(ȶUED$-fZQXdvm? ٤G 7"U+~ Q˵R^+t6AQPN,w 86 ]nɢ +l!UV~¨EBc(ҒrYlmSV#VVNd]ㆲԸ-T>=iLż2z^X a:HYI[thoWZnĿ]^QJk ^;QI2 "Q1%($l`mN9-y-_^߯W)O|{<oQƶLe(7l] sr*V3S^Řþqj`2Um Ay#.'z3UÍ#)+PȒ񒋰98츧cc3(*P͗2ҦuKlE _a)g,(O`Xn"Delu AyWŌ\κ<ㅩQawɽD)&g//;(5E11Hc~A;w v!i]sRB\0Q8!R],>7}x;d,걞 )_fT<O*)R1 Uc\VFŜn* !N:X39e}c)o 68 |=i*HrRu1}P3MLkc-;cQX)0  =tTnC$&GͰOK>ƎUL ⚟z:4N63YhvMq^|t~*}Pf \@I's@8^fS؇ '੖(<{2E5A cYo=×"EtJ=TYi 2Y4MuƇS fP1@.Qۡ)gw ꬧y3,kM *2#k Zi͢Pk۫t[5s`KFdlfMhf(PGΒ0C9sK:}l$y p@*L5 }!u)-R'!L\(.G 醜+q8ʬAmAksH1G/2c\SC(Y?6^ EC ŧ%+rL}0hU<>^.SG0sKsg5cj<)` Fv-m sOQ\V&$D+ $O.(xt:{?򰿄Q !vwK솸߃!w)]Vc&R&"rH^ AjDdڐ;K/V+X.v\Ag_O`X@;]9m#(]Sp1}ōaz{;,N(vA @њ$Ά 1CP(+/{M|˃ @5[\nuE_kTUxB,c )jl&ch́#s`cbjI&4z',2tиKNu|+FRF8 G8mHZKJќ`0Za(dRt {ė-7[9v 7 Ej-a ,Zy Ƣ3%,ю>GSXhe7qL =wYw(ҭv— A. 6<'] zg#.NշоtH<SZ?ۭ)sud-DN=d39X 2Nr ò'Yf{gwwx4U󋗿пjJY!r.c_]1Qb0~$ݪ)ְ-y\Ǖ]VMgE% %);-C`n=(T`Ù<u/iVPf" % -9VW*&d b97m8o2`RJBs[2~aDSdn>3ᶸ}!U&o1}9HiMݸrڙ^WiD<}(Xo I !|(ԧ-Kg.#\pX#yYG֕'UbXX6mBG'X;X ?S~W8cXV/ ˚tYD /S6j`,Ja_x0mc[% jζٓlOkmۮ&۶m=ߟ߰2X섛qn`ju ?7sA5I֓yAPb~ Z avmi~lBv4(8IqCcqs ?B!m@;ޮy;NfBk'"WL<~?DSql w3cp 1ԙ;oip)JeD廋ybF/[ Z)/%Qv- : ] GGlR*Xs:kA0EF\ɺjÐZN*\z=kCB~ 8K s/aG"W kYChJSA"L8}V2lvjtkw/6aVt N),-f$!<,_,zwS(y綞gy&Wqo9wIx4%/.qm1YF@V !8y~ٯ]PO8jO֛e(P厗vNmXsl6JC[+,PlG65$ݤ0q (" &%T! /J.4T46W[NP]X4ӷlp#vp{AN(0}<;} s9Z-%O\wL"{f= {}?B:ƧIƙ#7\׽'B ձm`37Z*ةOgB7jc? _"{G..•e"B:0g|)1Od@1+0Jdr#D\vljFyT.lw6%fsxlzrFryu-;& !ɉM:984V:,Gk%ژ (IC1&E7E"PPG}{SvxxA*Ji+tEDf("噿BhM4Reb a,S1+ :[HFd\X^&]DgD3"=%#Ldd4O^S7R>RS$|l#vK1c+aUB+eI*o @~ײ^I\xb?ZlI ?#^fX$T bo!SC $UAŭ`QuHy4nqٙ)u#|xo)cP5\LJ^Q8bxHPVrk@&hߧlzTsCE#ꖦ'VZ?!gk _&)\HwՅo7j.$%-8ϟmP\9(_uv:ҒawaaWC3αCI&AF` c3I-#gb(gB4]z'B;|gem׿ Lݞ,*fkit*4Mt7ifd7^!PE@S 2~[/KA!4>\ZU ewV_@߬1ҷbA|I̻We yE%8ٹi;-_;UpY[*P|%2x,.||5$Au$8Ga2g5a;|F s7&Mk: vu}o拏DȓzC"s5WTcF;< B]RܯHBf jLwp{j4˧6fGoֱHoʹ9[:>aKIф65fۓ)KA>qocmtckZ1:єd ӏ)q'T;hY  9?\F[OB8c)UuvQ"rai&|`>< 4p`;YpI  l^I0*];F%g?Y|#zl'S*t2+3o[A5\ewL)3yuVϏMrTEmcfyvQ幒z,y|,NKm:J@W&a}*Nۣa?5iBHR8 O M"^ K}6FKc*X~G*BW}~8y9 Jí8 ػ2Cqb'V;Ҟvss(.Q /K:']Rkbxu0TmmS?l 0%nﵙyd=/KJmBtLO^]\ /Sv%Wӝc~ZO=|5~:x+&c:4eF.ch(kK9(Tr^$D`$sbp|'[44hRC : k/z۰V[F;:R| \؁ nV5[lmYN){Xkڼ%y:}Of ^ګ!0CԊ?Y4"a7 HLC|B{Gktwv]Q3f]2TσZ -һ{PDؾ>@QrR (gn +^I_ҙA+C ݥdOi{ 7;31Dtnbf*玮չ „vjM JJP&VQQW;__+"y׆),0 + ~-t֘u W| S}na\-T#~#eD>8~n**õGZTDm͂=̧LC Z^JvCUpu1BR@Q(\X?rDb3M̐/XFrH.t(q@|lH=$_;lJTX]1hN XhwS1b ^MˮrdW][#v_h{o*,Z3Z"ڔCdymouxSRm%L[OmL9"OS>7b8aShCz-nqͧsR煰=Q"Cc@ާ x!}a\WTO?Sn`/K-9[M>2􀯷9.c5nnuwnhр]aY$lU3v>*9#<+i`CP'ۻڈZs_vjY_| :cھRgkN ek R9Nm?lcc!m72ቌ#e"qR M)~P+=GMEXc}q\y q 9[/=8S3󞖗U*? ׼`*ouG} ;ͺw~\륿ND>J,*[1F9:ZBavq#22(4ŵ?zȖ#Mk:DJ?Y;Wgg yYjCiWsb`;r@|۲!..ᪧZHvB\Eafv9t"$ X^:Ć"$$]8h;AnªjP 0Uf5';\\^lQ>lsV\*mx2g¹1}R6'p/E5\\qUz{]]z%,dͭ~D7@)>vCzZ#n~q(/r Мy˔^v%4RwQtRȠzܼ֫_ʖa3@`U7ޤZKĤfIQ1@W6+H 4t^2(?{A8zovsQ7[YܟICbT4 p96r3@д:&.S%OkJ_yJ ,Qטtm#g$ujZ7+ x^U*:+j_G`hqJb5'D>}#hYNW}bqnyluέPsvcٸ_uX$C~hk&;7䏓+\05=^#oq3BV{)g^;VOkJ*ak0?WOZuB~|/yS0=fR偐fo`WEZ OcFƺU){mVT'fiZ~#D>ZB7|JZ8ﳳۛǶIUm>~0 o!O!rr~M : h*(\ѻe"`z(ދ_ꍙXfvCl8,1!_g9YΦdQ݂`^Qظnfȶە}+D ~>T6LX0ЧUCS[5lbm#Lpҝ߹S2C_\@ƢdP (}BV -3P(h`t0')Thm%|AdK4E%?G}.%,ؕ< (`pdv^%T^p` F;y>oD<זFW1xwļ)]:91 _~4a-ҝڙ@IiG=P+; ܡ%EvӮƌrx_\v5d)O;0ONs?[ӕMڞ!x8C};'4COg|]ĵy +\fӰE,f1u*E\~( )L7Aw?:[ ,L[:o}BQfÊ<\p)6Q*z>/\TvӇh1+W,/5+gab ,63 98@ NRG9*B 0"(kGN{/ td˱Af7*4:4Vq&hϐ3At6U\Pi  k3D,c>c\(V;1hrrc5i֣on[{~HZf ۠-wPG0[mP d>Tqqx*or~ endstream endobj 136 0 obj << /Length1 1952 /Length2 13976 /Length3 0 /Length 15233 /Filter /FlateDecode >> stream xڵueX\۲-!6ݥqqww  %.}}u5jԬYs.*2uFQ P redeb((LAl66&D**qg $a pZ]Bl,,Ti FZ̼@WS /G +/vqe43uy +-Dlce';#LŘrv`;) ǤP{m` hmjo [4:MuI5u:[bu7GG")UҐҚ~5Jo7?ኒ*`]lWmo)-ՑÃŕ lhW}6. 7[;]')s 'H 7ʷ7 {k럜\6u+VAEE`jrLAon.lo_n4r.~[)z6\l\\]XTgl@Ed$5Ĩ~/?D%<,\V^ېJ,oU i[\^g@`[ڀ,,t͑Yd7?6++t=ͭ5-̬omq;,M]~6;w?"+7m _eA`JҽR 0 `DdV s_ZRnJ@n:{hKvv0/Ehbjnwg% Y9Xعf4+}l\ao<7qoin88oOf1eyM3;I6 +' m 89>omkbL [` vF\f?7Y`0k rMXYXYo9$xYriޚo[~? yozߒ:\qxw'=+ۛ?j<fonʟSϝVwum,ghlvXogT-&ax#/mIl~kq~6 4G\6hV/Y4S KtR##5I'QM.j ̦.+Ju>bۿ|oOP1W'Db V\JNw$Ic.K8og},+EABXV,g{Let..H{>ѕ&p{TYc >b#} mҫK# /Xǹkĉq<ڼ78-`2q=٫Iі}~a7j, R&FxC69_NrXj/MDc|ffFX ǓѪwSXKZ/4E`mzi'.RoW^4msa@ Â~F֏.Lǥ6`AC5q* !%ﱽ-EE8Z_|ԅRU Aq1ى?koJ }Q`7*h\P}Ob 4SEԴxM8 }G9{0ZM95A9n:ey \; 38{ b×Zbo톄mX j5U5ڭآU(FPn Q+W/}\5ᘺ[z~,ȭgw_S۶A~8C+;*V'÷:ݞ频:;k[G_;y_3Aӄb#yk= J.c]tt!{q\gꔺ.zV&PQ/B7!Kۄ(6aQ1(%B1o5,!,9 OpC;'Mn}PN>-wOȅ!J(x:_|VO˞ H ;i} jN="e|)z%k-:.FkD/sS$inpRdABrk"v%`TlSƤph }.8OjKl xc;t}B 90_}z(E} ҵӳy%sԝD.אC)Ӎm,V9$gMWun00 nWX *>' P; Fn|1)/ (/cjm-CL e#I5S.f̣+(Uf2"UHnV76zfj==tZf1O/A^j?d}ظOs\KY$$R9ůgIc` ﺙ",y˻O:CiԘ-ʭ 8 {xtTNBeR1|{T(Ul"r,)}BBaF3k 5VjG9FUD9*>C>tާdB$b,ֹ#Pn9w\tB5HۦAh%]\{+,8'D(pcCy}D@/T\.yR)U;:=:hn;LhfGHX Fm1M!ഗ)xb,v-B <8e :{z~tXK''VP!&[=̻ȷa%>; jZu>Tvj;A+ 腥SI\>ymєNL<2hGtW#FyKd_ȩ%ӔNӔ+pgNs^ h㭣m׃/3Ld44|aFHl=f?Dvcg>6[^>.E}ĮEC,.GG! @xnq|.k2B6Ur%ͽIiV#߾1-S vSLsiW=F*.5`zl !KUB^8֑F JG$]Ȍh F^$Gn6dB;[^'"#f0WW+9Gx-;,!/h7Q)k{-[Hwx~Im͑\ȇF07UgbYYJj 6~fOD^|~ 0(m{ti]ͱKl&θbE0'ƯȕFc6ÝP,4} y.7w[XT1OB:u&g=Kһ U6ڥbC \ligmT𿖲/r(%o B5)Jɐ tƉ:^y6 ;cH^YF7菰WRMUIĕvF M8}Qw>jlq#UqeeV>{,sI$;x>3Z*8Z6a?Μ5Q,~{7_ewỘZba'ᰑJ'=êыAN$=* s^:g 6 ]ftlQťO14*ʯg_(OcV ^nPܠXΩӷ%`ߧ bGw꾅đP+z4lpӼ^n,*;-v沄2)rn8t}eM(O*õ^ޫ @(w U:~dWB_hkh˻._ fc3ND(^.N&Gք֭np'1<8pOi8C2݌dyy_ Ki;. i('R^fXUiSԽ2N(͎Fjv?LZÒ"ܲgrR*tG <ǂ- %^05՟նɳ~/1\;AMiȉ$,z%~7XKנd *KGNT<AΰWbfUۺU$mܹ:X3GAiWZ`Or2/${6,:zf ]L{9+}7F-Hy'{3F)Q?(wMw˳XqNd #}kUsAF~c* ʥYx˂cf2U Su{TWӞ˗m3*̈́v Aq j ߥP  /NK8hO%ekCJN3k6"1|G͌ͥ'%:> Z_**3 Ne]C7-q/xMV1I޳u\mXl$ jI&C|=GͥPJPF}qdho9p iYwnw>k3=-+ݵ>T vl"Y2F9vͤM-bv[lWyPUs`THq`y1d `b—;qF_+6^˦nάNܱeTz} KRSAg-+ptb(ZI&V^, Pb_G}+uЭCy _םƲ1`̟Wp;r$DS'I|LC[,[iX=9ΟGԨl\ؗfεSx)`cDu~ .%N3y͵cC2Q D\Gm}=𘳴*ӟ:([,ݡnZ/oimH9'?16| q]0WY) S.p58;l#Ho%g(63ÂX$aFܫ˓^UhXf#2 /PeP)?+;UqD 0wFqoVG 9TD6Ǐg?b ;aB0-^t 0(/ zV`5% W|Zj6Nc\tzcջuݭ##?,;I{OOp6?D|/GwʤƉ*<Zݫb5԰J].!+eHyFhO$37^;|p5L0P{[;^Dh\_YxAdX6ZI?c0:Z0*CJ+a{钴fw-;HnMtvK<`jGQnYjW"ASM+փg\wL$~.-f!Reoi3o# Iyj8ůi\PX̬aP"?6K4ՎI,=Yy(XP3oJIBPo=Nwۦ *TY(+2{u>dO27rC+5;[Wo6lKj|ُZGd8Tw=4۸Pl^W"8H`1É 3 Ze[QaK$d/*G2}G-5)n.efTI f><5d.yGɓU ?:CrbQWQ]8Y73+;B !KslFH"k&s|rJTB\II}VksϴAüFv;f GijcyE;.o޹Md`7[E~,\`ٶ0Aڎs#+Ny;2nx ަ3-2F-c5gyס=vZzǴ#\xe+JnIT9['۝HxA_v0A@RY9!6~JR4<+< ,phUf#w+Do|D͖>8j?_?J_/) ֹz,-jEQmmh1xU&g[y]W iorTmk#PKn$r78Vq:DJIѬGUFG}fWe}7=yǒ֭-CqX/\Au*16zS3AeF(q-HyTD^m]$gި,-GAjke.ˉ!iK(dAQiPvlY5u9?~dy1+HށS*3r?.ZuOfTgKܝOJiZ^%& 7,&_ :K},+궉 JΣHvrte(9+͈پ ܮӜ|TӀ_|IDOw)LY/%ulFGfaT+NrOcN@(kLr,Li$qXh6;<߆Nr,/ڼf1_,)_ *{7MRw/Actډ1U' r0և9gÐk]uQOOBnS`exLOL jMuf=vLNt4j*Mޛ@C%ix 3S% x Lհ(W-U승y{,=y1IM'g.N-Q4S)"p.| Z b)s ~rT56YVI#l^nB5\@uR HWq]RUV yO%6$k.@V@@%%rP#gw l_t2{eMׅN.>|/Vٯ8Sր6YnB\4璼 'ya=7J%ˬ&ڠ4E{ oD]qIpOc:5x%=%PIL>nk7'lz3B!sXaCC;pOZ %F+y?fFI=]2h@)g4'4b,8@ϝi6c![|9q_2 [REGXPc ȴhW-8NX(~C$Ec$ѱ,ɯC8]; ?vJI,A5utl9H&I1De_.rm&z;5Ic3] mNÚ0^ֈlٞCÈ,JhZƯ!fľID@j2낎lmNմ/UtleQa]^/>}Jθ6{L3Tyw'<}P c-'݊+^DA߸Yjɑ<ͳ&WbM:0MaWR+||Db[|W|ϵB<i;!n?\JHm:`y]&D~b]ٖٓbu3MZ8B&o:fNyjTU4S3K}ok1(u;ȩYaQt)V"M$(٦D J6Q`QcL1mtEB~~6jƊbv4 B$'AKx-aBv /c[͖IdJ^ M}X"G0AjȢixI tXmPlARc gaR7Y:LާkѰ;_~_v.ѱFzʍ-Z-+:L]T # 6%>,b?nÛ",\ }9f xZ3 vx9b:Wc*ӊιsa~Ft7F~ T-҆AhǺ)O/m"ReUx&0,YB4v"?MTNhNsA} xDiXjل'BT=?QWl%d>Gq^֪;^@tONU%m';XX72sПrcl?ex(\~Poj5{r|RWtr-6Ad#_t8Q]݄s'&cn#Ȕ<TMn˝ZGiZbX"d%FpRwS;IW:R?'D-7 .iCO'p1Ф\ m~k5fbKE0~*"2=lUwjQ950x.r,i!v@q4'S S1!ԇJ;e&iОN*U[Qoߟ WprŐ=ڝbT4ڟ_Јl\CJܠ B9& 7Xʧig$Pqg[7 e\Yfvda2\S_5eפ+MĂwY=a]Qވ%EOHWşѸҾPGz$ 5ȹ% ԻPTnӱ?BGtxF]wx/ԅrLAP&V&XT4`c#XtqXb nunva&PW 2<9iF{:4E.(J X Sgی{%J (aHZ1a>X[t !ցҳ<D.kڣ{t.̙ݾnsB u%dvyVn |{z]4ҍ%VSW,gKj!Rf[ϙ?/Cgm~٩*Q|-YЕ9i3qZ5 EjE2p$J-&H2+qH+0C*Vh(/._'& 3;Xm m+x!%3q;]` k up&{oL9R%(:@|6|p3aE.dԻX< wu;Кy?~d 4%REpʖZSSS|+E|g5\cGtkw)ކ.ŵ2Ae#5 ^U>sEjy}<&ujfUvr'X)5Wȹ8lm5ː9^VZ+lƥYK[291úʋr}=Si ʂ(Ry7+bjh}]nGǀoۛCd`#t;͸E߁jʔh]2YjusO0e2ګm(0s[kH6U Dh vXkyܻq;^uQ)`|r$[}mhh /_J`hpn<综ŘbʒrA9\9*mQ"V/^w] zq%8\jC$k5U:X{}hC.bH΍ƉBY;.2R|Z]a݈&m}䳙[o;HJ3$V_?\x1-wqeZ.i묙 7F =S{T^=sLθ!'Quƴd`;q 4ITBya4!!(4{UoM΅Z9+TytWD0ɼ pn{px[.8Z-sa,P*jp6xm1pW=P2rb!nЉ_büjSubʃӫLN FQ~Q93J#gI)p`V fG~nCa`q0vqBY-!|) gEb:f-ί;zK`9C4r2"&ױM!vy1N}CwBV yi2x`Ds4wd-OsFtWF*{ &Zi >geaW_Z`'x Qav6ϹP?3BIJd֨0c "~tqA%L7qz>[?G j$Cr =x1Bw9t`O_M#AD;؈;^=-0 y=7{$.I}yjRl/2y{5n:)J8d _z̤3~$tIsF q>v$AE F&0l5!{:ߵuKmj0˴/Fh/gDsQf )Ҿ19afESo  ,MMUku3B>GJ9Eu0\5&bDô6cY͖J6c/2Z0O/_MvEaD/0@fֽ&!2#.&l|[bhayxak` ߉2Jv?tM Jb7]ؕωsbdxAِ;-A8PcouTe :z%Wcw!x:|Lc2Oxa~WиVٲ%vWeK$}]'ӏu)O\˶4sC))V, 5VfL=~V $vp`ȼ;A&QY5ܟZn)jQm _T/k$XX {ŅAv @e ]׆Mi}LXuel~QY]ʏh##S9 }HjN`h<TN eaD-gO՞4]/`zrqE4{ Y@YE8H4TPq'^d[{m[i) mƀ)=8V\I{z%14`r05'݌5Rn1D{Hܽԥhr &'_ juo4;)D1 TV.fG1{K{M$}Qh'I !K\=p #{]T{xD̨rHlJ׻r*բY%wp%"Sn[se?ڭJfBLNcwD?dk"Ì]0fiUjH!7; R$O|g= \S4/PÈtVKkF5y/-fM1Ρ]-eGhfo8,]5l H e-\]OAfWbI?<܂1ykSgo>fDх]!JUKY#tA1/0v(UT혆 ?CF|f'M1+V+O endstream endobj 138 0 obj << /Length1 2060 /Length2 25054 /Length3 0 /Length 26322 /Filter /FlateDecode >> stream xڴuTڶ=CCpwww/nݡ[qwww)R܊s޿Ȉ̵̽+##TdjL"f`$WPNlL`[3;3++' 7vXyXYYR@l0q(lZ㿀2щmBVNLL2eڀ]m 3,3@fЂA9lPj4$TRJjto՜ELM]C ..j24A&@ F:o$Eu%Xp:8Z)_ܨߘjɞՕщ`lo?uK+G+gd W?2$Z{k[Л'@4v+V^YY`glrAoNNΎloOͿbj(ÿ/uQm=]ČAΎn rrtrWF 3eSQPSgI_xx9l7yJvvoOON`w  ͭ@fnlϢ 76  Z)Vߚi:́ooH.@3 xfVNo2*He|21ߥ_vA39"Mܲ%lkhl9Y#Q hldjWeq2~ӽv$4\%7;? _kor4-ߚ_|:-EI[VYUlfsqݑXTd{/XA`7(y,bLB|#6߈"o `QqXFoF|oF[=#6ַfo@?@.? 7o4lo4@o4o4 9jt77*oNo̜nț_1tQr d˿feedOc'+7=ַf{'(@ G(͓Y?͐7/3N@iel*h\#Q0]Km8vB<]rBf B4O?H*fKbԵ𞱏!X&F@²_Y'9ݱlNN1lFk\+ @cD!}2\u=<7[,e HH^9cp=] ):q:w=H*5qb)ۗ]JPF&dW'OPoMU`QėHc5=F=eēٯ I;OEћa-#ZNtRqj▂ԑ+Z5Z8hF=]5E6Òz>Otw\%dumn׿1-f RCBtv#SQB-9C#~=; F~=ٺj]źe M]%vkM6ʯ5Y( }$s vĜxPm)̬ۊs iEg7ϭjvCTNXrB> >d8Wk.m)5Ox@N()Rl jB(_Sb_elLvMWu$ UG:bSu;|T0dZ "I_&= U-,nqr1ȌV]4w)z"?{-clJGŮBV/&^1Tf\PѤqlϷHn3Mw•mL}]l4+ dk0Oi|\B!Z%jB?@ '(6~= 4oF^c$0/ŴzsZH: 3 lXVFlZ 2: /I.K]ucפ;%+CY[ß1?Uu+)0lZK`k[}R+jθTɋaz K(jk_uEE}ITN{\cX^ZQ?P̡0,O% &&,JN*fzsg"IFX:n<)˻CANy8E8uijs1 wT-nHnL@[ VFOG #`'̓.#"H{D}#ѩ:K肋48wb f0mby6 'ߕ;[n7c E v> WZeDTq+ S]TD)]^7 vnl Jo57ط "(3SpS!#眄>\wNf_N@jQ1ָms$QvƆ(ω:MxyS$}^*J30r~ۯccG#, F~SA'8h{q[*HsI2lUL]+,K3QL^PW%)&U,*% [>S"s p{=YWM?=yxgC\AgJ@_pDP;cbt U-E$E.`H[FZ6O|kDƁe1.:@DPo&,)bJ!FjvJa(xGer5I\q^](''(_Hw|n'rO^#QpQR#^GfӀe@G#:Zq#Yw;hSjɑր"@[s{;aZp 1qO :0<3/Ξ0R=U"Reo1!<< >]3S”=e'|[/9s&CYVt&&'#]F#>?\\i:e7!'jgz҉=4֤u'Z0fT sB$UF%pMRa)$,D{6+B^"&/ܜ1+g:?auh ڹ: a!!;wəZUb{7Y3*U[^H=힐 a#=h⚻j,TJw8,.\4ltxZٱ՟~*{;\{bI@7-kEQ4*.mzjnwfNp; fTYsoN}'=$93G l@NE}9Q=[;a!zmZ쭔?brѧc  m1NTa2R!p˷XQ0{ߺww"=qCM׻a6 &=6ӵ2 9,bzoD"\`+ BjxkAH?9.-P#!+{˂ bxgLnh NMJ$<5%LC`BJHE|~.o#W{zv%ӯX';[|`}Jv0wj3bORG?İL/ϝI=I+ a3ŀ6dxڠ|TyM>R0iLj+{gp1n޶֓=bK'5;(=_L7.a D8lFcY ԁ M\sT]ƶ䅆Cq%}X%ɥe t ˴ YsB]ff>霛}E#@cҏ~2%ki#2rc`Āb3jy}3hI{d)Cyߩ^fr3ʌOZ [O-&TVrX¼Uw~%η.-ɷ.j<;Q Մj % 3l\˵r{N{.wX Q8pԻ~c[C×5V!Xo/5Nk?nV" ::>e2tNhcO]V!' olWƎPA-Tc>".6AP^zq d ^~iϢm.i[^ ]qߤ̒~UVP,#_;^5!tc:{z K>R'U^T.IqIW^"_ RUXz@.R ;K;WFV/"lt(ܨ;;! Tf(q9vA Cf~mS>5$T[`͡lض9VB Hw>cн6g$(PAmTY WPlJ??XP@R 2\P0&=8zۋyk@J4:_Uj~+0h,C)9biU[˰Z3`v@  (yh1NJ.$ZqϿO>5)i* )ܡX R}g쒏ASrZf+gK5b,L(Y哳q59KKhc,>?ܠg,|ES1{ e0,u40~%l2S5ܿgEdҪNJZA rLyeKr[g 8v "HSyO7W|lNTp1󥴙Kdh5vXĠM` C~( WK"=O Q83$m;59Ips,H4鎒}F'Z%z:ȵ';Z,6<~KFXj iMqMhC\1 _uoΦY=vdcPfeDqYMօ ,A D.`hakLMO5P'ཐ9,NRcK:'Q< &r8,5fbb++,:>qr8Szk]\Xc$TѱQ'bE#KuA陚[z>(!'|շ=؅.Xp(\~5D[Q -7-Z<|79;z 0sp&51Pl$ެJ8EhkI<-R#Dˢ\ˬZDNCxLtgo&xW\RӢߪbВ듓/g$ ada}ڬ9Z '0UP8F0\6O>Z; JxH=Jqm T q7y{"I4+څ:.I_t)4@ް,߳R;/C{PWxdߢq`->&*rѦ:f̆?.xOFMDu5bUհ3jvnI UP3 bn wR8&c d!/ .m_ I&,5YqzRiðp)ƨqtO\w}BizgQ"CD*6+#t;c]SQc>U*6SmOGp7qf(0a $[AɿbYӫu[<'F: UAKs]3DYtUjfBMvnm4de~Rr;3-ywpx P浓3V-sqisʔc]] ҷʋ#UF᳔1p(AJe0]VWxaG5KGy- uqGlqkjmQ!;@LڇJ ^m Hcd{v3̂D zЯbT>M=):P ]VZ6Xʚ.=&H,'eX_"<~rҲ"XhڬuCWM2.eqL0}  LNb!٫m?7HVpQ.MW؛uGHd?Z˩.R޻yWx.5\_ۛzkwtӗ|t)2nPJlCK /X$[~1F6]0ӳ]ihb4Uێ KfȼD/ ='Ⱑ.ˉ%`U߇Fvye@9S=ޏbM<5E jf]n9i&;Tþ*"E-vȆpKj ɡGD.l'UK7"{y!QEA"b'[i3[!ODƊ-J+ p TxB(M`-i1%)Osu8H? AS7eu{TVs+m%򐺫9_UmpHH#qʖs$κ ףTU: y{ 4t>@Da魒Hǽv#b$7(}T,EivP4b3ivkE fЅ2q2^3Ej/7u 2Dy.O~qjOXdSg Ⱦesb)ABӓ 3 `&d0>^ͩO9/퐒(a4l8%jsp5Hg%[V¦l  n( `yť5=Bu1ٖ._-=lM/^ *b +xX*v/̀A;&e\F̌o˩ܶcqa",-kԶ5Vx{GUOEB:?s,XW÷_ۄRqZkаߎ+B/mn?6>0^k' p";Ȃ2j8RQժ Q(p4(sN1 2N>o#x)/\}dg!B#VNs= )8\SLp~ϯʻnHF'44 `~*:a óA7j<_rݟ8xS3~+׾ҳLM3n$1pD5WT2|Xp~1tR U^վ( ğFNC"p oXt|M>ɂ5pՠ\_|UCLdzC bf8g'7|$Et-\{ >_:}Šy2,WBeА1us{4OpIXżdIm J_gr<ɷ*{D:cʉ('\S$D'tw=xnPXWĮ%VNsܫ1\th?D>M>*aZX-9:A*%"X~خ%% 5Tʱ _{imC U::u7 ԐRhс!%7 /Nš).mv'w0|g°fS\.0x}.#!4,ׂr=ש8;w!-wa>Ͷ317Kdeg/52 I+L-)Ά/ ƆO)ޖE0o*՝R{頄m} Pg4T…h$Qo5_ըՔ`T8w-uږ۪CV&'}i]7B1y@dW# թRגb@Ƽf# ^er `$ N:nЬDŻ` B A_zOlf' ڊ6׉N-+Tgez'S !<@gHVnt ;KX~1 b~ДiKګg0n2'eS1KB!F' lBk2Ι3 )!9. w| x.pvM[h"y%_w6dcH612hwFe&Ƃ:$_+q\1fqac+j ,= &k,2ٸ(j#-7BeN?Rj7Tcs*T& ҎrysaPwݎyɊ׊iGInMtgu_-d 9J_duYǦ'Nij=)V!4\())۩C?fmǻB1n<:N\c=tD@$gTF@^{b-;4J *|6ȄsxU/K{߼Bj,M1nRM4&&U179G q|Ѝ nh <1/Wз}w AySJsZOfYIl/UD6Pq߁[PlYPi{{z3gvl6y4uPYNׄƯ[IĔ^̀/[ ԁ;X3+Z8]c )ؼ[R T#?Y 3/-l@I2m+H6A)9ήbZ\0iHUqqfʄDIlBb̽''C]>x:m|tB n}޻Ԉ̷ɏ uPSk˛a{v&+}ew)8d#"^JK6t|H=6!nj ⬜6wު,~%AQ"@5HU8B-9SdT rž.GOι9^JƙQm'n?^6b ÌAT9+0}Sk+dٿub{ϰfSJL!XЁl&/(|ȕ1qB'aYPw^VFCD s,Vy?kJ9~Ra>*$|o'5L>MJjYo&\Nfb|g( h6R4V8ߏp^@5SUͽy1, /܃ P3$*)`uo^1lK~8GPk;P>-Eǩ3X aU.4RUu#NQwNI4A; 7= q2?,Iʅ3[ԃR?r\lz/5dB˨<]Vk.&rz/Y\V%ʭqڅd"aVd  CZ& E qo}ZG\'Qg-?;6WZ]>Deb%3BP%gYsG)#Zxɱhf+_9IF}+Ur͙i™i0כ,A';rPr6;!c rvYU5O ھALUB/֛mgWUzIVŞ%`x5_떞1i:>5u٧hC@bL+.lob%w"F9E%TuxAƹw}(g$ &K9- g!7[g6>*e)h} UwA':cjuoB&;|DxX~#seK$r~o(g)=Y*= Pow$ {ַ<-#bexG[HKE(wPd'hV[P)N =Vx?@'P (08rkz@/V6FSIvAUl]Q !azaG0aLZyhNRM<7L.6{gT2$$ƞ @ I? όܒ>wF(? aOCl/lO X [VD>ݡ8u1e6a|30\|ʫjs`2c`jBkOܷ"h-t05I1J~c ]6=Va EʝRm*y.[3:2=~cALʦ?ԩ/_keVi7?/R'6g^iC@F Wϵaf,5f $icq4,C&0˙b{iH;(7f \h$B ^U:,x_ԷH*-k>i*P(6!3U=Q )8# JE~)O%˽N/{ t6۝.>PBE/43zVVl@]3}U:[ƃ'pOA\b{ f!DwO^*-%Wc(1kն? * e1cMࣁzp@ 5IwWee9fOűtB ^jbI?+Dvq)^5uN֍RA%l$-3<2 8 a?S'm{;eT(;&;?g8< Z2n% vPaS'K wG->Ȑ)g~gkNw (Ns6YvN!#p;cv٧b!H^QIͪV8{G^Q) 3^_f>%~4Ѩth$|M["gjY\Pjj-,"'Em8:<`M[w7Yΐ5"mUW1 ,Qv1ws'*ޠm.)>,GijAjCT(O{[JE} x R]qgRYej3xa"Sez\q-UwۺWA5vW2'PfKCs=feZ& [71F7*B*Qk^Hٜ%xWK8A &LQBIwXYrXG.x/B8!16w r'Sr:?8#ra_>2W ʡakvÊ|]9s ZjcugyV*ZB]QDz'hS1I+X[ʼnjV*ƂsvUrNwOAɪ__%"NYNO+iLk,xJLEg:91<ֲ+=[q">gtŷEpni{m ^~7j=A[bFelmfdP;q?Aß=8ջpګ'>5QH<l7wcGPr R>'[ٯv륾mRqX]-FG C8,w!cȔ:+ ۣN'gb6وenU :EXQC{gCnv^2/š`͉PV-ry{ qf_=6CDYL@t{-]$%_;:]hVop] < B0R`קmF;[;XtYRfU!YSEF$&[ڪd9, K}c>r~}͑@#(+­e#)8#;A܃_ r/i7}^~T3XPpwlx[= 71e%vGSRxQVqDBZsGku{YB/m%Hfs -XqQ1]YzI3\ 8f&*q1= :- OSxrP}Ahw~L7,nQ:IҞGm':yFi^gͻ58O;-\c#nrh:G8`\ ޢm*m/pL)$圽xF5n59gĺ؜~{BXw{Oo`6dŤ7 0Cq0Vzer.<,hERW6bp7md s.{ܷENeϸ?{="S5a#8Wy8&bo@\hsvaQkz2D=~3d:=2Oy Cnx$ޒ3TFE~n4KBxqjHb`2Hd3K@86 uhavaERe]0("Tt:pQl!O}{V f$"u/h< Ws/LZx68^er<ڎݱeTКÍ|rnes'@Ҙ|F+t%mDQ]8! ij> .&L0@k0h7~a+:FJ`Ľ!…no/GPEt:1zEh2͖hfdAh{NވICM04 %lD!\H`mgvKvG#B^:PFWAQ0:3|Rr˜<4sۥ;[^DC?gvpR۠d ŧ׃;.aEI,P- Jk IMt?\)ۺ9 L4vug c4zm ·ϛ rj5J4v(jɥos|\s$GEt Cn0fet.ЎFP$qpGw0~EOu~T+k[7'kI=NC,L>{41P7c}lDѿ,4?t%*$#ĺC x W Iu'2ʯʏG j Tɂ'6Sn>a|1pM ecj`#;Gc #Jj Ŗ ,jQP:Qnz4woZ$Ec$CUSb)< en5(lB ~oă(- /\g9F^l ؗ wxsbHe%(2 GQJ[t;nf.l_`gZӸK1LoC68/Sc@HߎbwyAs' ݨᆵU\d<6!&Wˑ)CF'߼@XRD,Dgy)kj!`gjȪZސjvE.߄D̃|gD{M/ec@H8[0qKf <ԋc^-QM+G>,4ꖒƏҊ~nCvTY(‰K'3q |p'mx-0JS= SV^'\"LTG ~I.^ƅ_SYQLO@n(k: jQvkx/T(XNPd ϵ1 zm ᨅ $P.|?J:²̶>SAlJ#IcO~ P *];S$ EG/8e4 bk*Eu$&K7QGteckl%9MM !^j ^M>njX2,[T^[3盛&\PvBg8?&颴~9Q3Fe֌f(=+r5Feu3 krcޓ‹BPD羏Q2l/Cr:4|½4êZGaIEYDNv` IAq?K Hub,KW^?O.a| t_2sz»~6Y*lԘ-x5v #Nx9:JbY1csk 2;GJ6(9A|Ӑ cc#4T-ͬcr1#J3>GYׁm'wQԾϲ Ƥ͙%? .B{>PVͻۉeB;z>cN; )$POE?EIy^(bnlho&OwWj(fu9tzb33rF\D7ZCݼ]iE=WbMg:-= [E3c}T|L|ݕ4D|V >rڸwi27 %qxJ;i\JC/cU]K#Ԏr8o`6.L>f粵?TNqZآnABF5J H?%c0*^; PVCVjm(gZ 2c}oKEif꩞*W'S_zZ]FJ>apA }X#nݾ?rzKm~m_1D8~,=~$=WtA 5ufBګy .ȧ6 KV$u[~hV^d A$l'rnC|܉mլ\#%s58<=K.;qbp6T E;@Qv61ncX8uc9^+Wt>5D(򋗚{̞t>!P=u =zhv$VM[R*1~\P꾀,@8lͥX%ZIb_ꍶP;`@x:;nA$ZEQ7Y>[c컗qGuXU߭$" i5qb `p>- Kh&R@mĎb<4}Q-ftBK zj7gܮHv0A|0^ƨYp-7kW N>cdKgIl ngŝ$]=i7wwi Epb ZO${vt'VXFߙnv'fLUӧf2I}◬1J\WSeYXq2XTؓmNrV3Cv//tN!'1z<*սn\_`$mGqNp!z 9vМWZ'(PUnw?KvĬ8|ĀKaЂgwTlL= h-K\CJBSceLN{FA)`ΐW`4b摀 ޠn_ͫe#>m4+8z:߾MD/O/йx*4 zP ,SDަxCydTDABȫ*_Sш8H TyWDEmc#(l뇛;ےAFjp_Lvw$.ET/kˀ>+>;7=-!anEO\H36&S|TKHwu:D'O6Xt +Bk|SetWE>x!~QjAHFs\/ntw #Ϸ1 yA1\^N[+=YJyrs_An#'yq6do5ju^,'Ǫ+@L3Io#sAxo&!"Z#!8EpF@4?Z0$b#O<ʟǔԽxR'c'#J_!̖\umz\}̉[r=QkLj㋲S&ٗ7 >8 @k V<V%"6-~M됃8E=iJ;ZVn-@%BlַEshrSWzwiM}`K?.u.Mj~>gh K;ѐylMȀ}7{0#%,dʬt,Y@e[z?# ~˟wf|HoC{z1 o4]=\yGA gР45,i_"Df㽉P,?UV.Lϐv3=_!C" jW^,޴be\H7,rJY'zgkc+B$YK6)8Bcў1aj@Uc,lF[kVvhK)ct)ey9rsh_ҿΧK*2_3pʼnnzJ2p }6uWu?J[_+?̯|u1+̀prxh\LOT>mn7:km۰45^z4jKhهkYg)8.Wh?'ѻ}gLM 2F!E8xƥJ8l{|G@Q!XaM=n*t%D P;l7hk6~';hFPC:z\ȿ*wL , R+X 8Rt(/ 1a谰 #Gl͟4$>џrN"kks\A0V5ht?Pn#[۩D m.Sb TؘD6Lf d=#@p78Bڋ[8H%E~~ܟ()FVM n.5*`OlUww֤"D1fWz5t&Acl8'1N*ǵ@2>͎{ogcYZ!R]`>n Dc>݋+]w ?s[ݨD/e[8P!Y=~`RY<_O%W͖M+[[Cց݊O5Z0CVnIݐ$2SI\0Fru FFhF۲ɪeOA#&`LYa."BNb_%Taxpa]z,pw.1y68$ *&w\l@T仞<(ƽN@=5AOM'%f[0Xcʼn6.ש?:cԠGLUIR'%W)]G #Ǟ?Uf]ƹ1 88&?~oe`Z `FͫNE9]tު$ x!b,܌ki1~,z0ުY~d^3{4)OmxuRe'o]C\doPFS]ЀX!@ɃXeVG[Y]x< Z#&/<;h?s='+,aE3Ϙye~M,URNwbH︍+Dv3(MoB{?_ Co"ZjiiF_XH0Ŗ\ Örk{ʘ+!bY" 3M=W#SǛ}#﫵g[[!^XbTBE! Y((bqGd'l?)EstFї%@ 8F{]!̹ݖ)6zk!K'%lM464M&ae}nq"pO(TQ<_+4Nvܵ*J#9scS}ɥg1M?1܇g@%_16yOg6GjSH}"*_NՑQ +q4} ۳rxF֓3L4@ᨰ Tv*ً֔6ӑƟ.tYx`K-7̈])o͆'#H"ɗCHrӟSeܚ},S"w; qqT1 hc % -I'nA+D`aqpZמ߄}{}Za8'GBn#v}7Ȏ D爖-|Zs͍daJego!“C:0R3 "gr1x@$o87W6*ShgTf+XkyDF7|o[MnFޚCBÌ$@ ]UCB=ЄSjdą.\ϡd H\FZ|@JSז`Ӊa23+w^YNV Rgp&>iյ#ܨ b{:Xߙ!53#~voVsPI핾0m"\nz4Ԩ/zL_˴v̮<^:{ k&SewUuHrnБr{C >^4q|:ꁸW} p S3Vnlm kxY"&'{:EבTɂ'm~=݇8o,eV]R .CkÅo?B.fYr C,ӽP"m]\2R(rh]]Qa> stream xڴeTM=AKwwq 4-hpww[pwy;ۻXнOٵԧWCAB/lbg330dl혙蕁fNֆ&&6 Q!Vp p(؃ :MFn9 P 6(9 @[3 [p9wVzߙ~G0d \,&9 h MvU&@ME\Y XIĄU@u:↑@[03:*xwp9qUaU-Eqfs07J03jPS; A {FF3'G?T-.vV0N&`9A%(Y c#wݿmRvi/w#_e UTZ؂`G!` 4A @w 9̿؁gce+fh6=mc;[G G2?69ayi qUzYpفձeOXL܊\ImMDll~'f dk751=g'yMlf@ 3.O636e򰷳Z;,LGCg {3'ntfA'_f0_ PQ?wh(o7Ԓp7Rghca_͕Z,%,\& cTYdn}a[3k xM1M?z,~?3Hc+[#! X 7[ 2ۙXؚX9nL>`agx0[Ol@ `j{19¿MBF?(q n'Qb0JA,F?(e 0"A`. A\`.A`.kAZA`A,@CGc p#XeNh)9d 4ˋ?m Y6x1E2d4S<,#rdhWX]?!`=lw ٟqߧ=o0w?39//fj_,`o?`)m@fßR\G7pi['OB(1C(ffD kOZl6R)9ςv31V_ 53x:B#_R-\Tq6t4+fIx 9t2?Gc;/__ /38;_ Q  aa"gޏ 3;*@+ZDՃ ,=+X=NV{Bu%ƿ# h8ogh[< K@S&z1m G,g(կ7򫝬wm&E{뗵%mCo9ow£ jr?|K;H?diMĶFD:#Y_ѮHuJ[Vra\ f1]lcFG/}yk݉Mytmh6t] !R(K (SxV{HǼ0 kIo=JU) ~у8l;ձ$+Lepk4 XW›ͧ9.ӣ "F̨eD-/3[qbq^^^HG\7ۆs4q><~*ה *ʒs&偬Qdq)S}kl"*1:,X=W%=t}ò7Ր ɥ}ނ5górZ%-7Ȕ, p<}""1;<9ӡbiqs% #^i3\oJ&yܪ`|Z΁2cz=׌fbf>fsX5tche4;!DO*)ڮj tvR9i$n^C!ռ n#@ͱ@t`<]'ue| 4Q\AIϷ)Lm@")*Ia}"WT( լtJ8q)i^4 `dµ'*Ɂi5Fs!Dθ xr+##^zj}>p0KiϮ6춆ѤhX=UNT@x|\ʑޣ`,, \#+7d+gY+idp]ADc%f@еpXbP2Pdl?4@?_m'\c?)=( -~r G!4b'x#tOV\$`Ն9Hd$_xdmy5ư2I K?X$IS뉬v1ٻp3fDA|p%ro ;:Ql$Gu eJ+U ٲ|SDn4#Ҥ//.M(Q5򔢮 "/Y_1ر-!>#Fi31L4_;\Z*H^/@ݥd_N mL ʚ˕&zfN2,ZỲ  e(g^c΍j橿p>UxRPZ# Yp B2Hu"WGMRDf'w o2BR+#\.&Z[ ,nk}ys/Douϲ&LO܂jnʍU|: q({ 9V!Q%l]4 3;c,%`;< +!O szjoTE*@cGQl~}+mgx곯5ǐv# f$#EvJKCx]UַyG$jKkzAf~9,n3 Zrዾg)I;;WQkf@_clFEt:g*v%ص#g9G'|V4'+?DnFaK4ixHpRLBZd0YijaTfav?>ֶ9K?yM~d$:$YF_%.PvΧXCa>>LISO5$DoiZN3ğUlYaj:q $aK+ co7攀0r,pM5_l҄f&r=ސi؍?l Tȥdt {G~g]gI7 玖Vq6/tVWF@6ؔKaԫ`z^6#R}QR!Ky8=VRhKi-,U[(;op-d`/kf'~"I%)ݝWHoBnrQ YU#Hy#&?Ȥ$7?n'!~vHd|k3Ѥ>FsA( 87p6\8),Y$c{s[nuIspxqUq(٤S ~ sxhޚUhjTH_FmA62ǿׂ0AFL:z5Y'8sGHDž&TPmT$ 8~L:X%-Sݹ':dxMY8>?b{O>~_wVmX G)QۮՓwt/u{_P[$IkTI[ǡ z\e]/96Z'$s 2g+bNjyW=reJ RF}Hw7 Z%k"E̦!PnݸeY{.[Ӓz>92ӳumΞ 4>C &}Qh{`ve 9z80H'cZ>Šw=]c?Ҥ1ngDn ɾ|bK\ˏxҚ(:IQCYwӠon~ѡ1Vޣݑ}P)FJW1Wk\Z:)̩,)'l[FVj9 KAp~4k_1Ӣ)|W/Fq"'Pb=꾥2},Jsaln|Sf_]Eh% J$[s[.Tn$ p,aX !%.fSRK`/AGm<)XH lj}gtM R})I{6uQ6Hڴ٢}>gj ^Kn5t#Cb5/ި AI_f5nh/b C050EZ>zt'g77[/LѤ'漟%\ـU|E;Lr.D1F~pֳe_>&F)&+#WњĞgDž=hV:G*xŀDFHO`@qU2p T1~*ŝa#$-DH?gLDZk_2dcaۭBiMOqʹ/76͋P"#qryTPU[\Ɯr8% ۈWVVǓjxzB)#>K0_~uI}9xmWJb S ,V!Ek_v46'A ~![O@o߲ l,)Y~AvCW"հ,4T?: (gɫPםXDqn]bLnӫn$_f@Nxu Ti*-8n{?_gfp>*DQJ1٤Z| z Ҽw>m>8@e+kNP'T4˱8y nMӣ$*{]]gAy\ b4vQEmBu6&kR"þ+TzXzUg)`C׈!Q(kT_-3R9Qj{離@1D_?B 3cfKSn8Qy:{gUޱ (ݷ+Hԯ (Ck͙J~ ܠʹ@vc 4<3L)֠Eq|ʼn)R:ǖ"Cg/"S ZBu7l{64)l]ǐPz$EnM]qzCR^%"?z~l$B&l-Tdtex +c3Q0Yf'U6t̎"&UbФp1գEx(*_З '*!AOVƸ-zJhJoK R䧫I۫ NpьJ%r."l+SBQ``Պ o@n h a#gtUOQy3~Mu17O_|\z~ٿLhЦdzd}?߭i[Q-y"o$Z*wjE3GmDz.<7Kkb;;YF(te64U3$@硂|z5E-8_Z/T=*B7Z4]APG~X4Ȏ;x}@<3ŷA;7&obdQ)&WU %hv=Bn5}TBkh0XURԧ(!=,Gr:0}b@Ý(ͳͥr鷓u}(X2pk$M}xQCW h,]qmH"dc %ݢD(pE?LY7/B\6#qS'Dk@f5u&$34Yo1L<J~s(L`G'KDu ݨU$*~$vY[tvj]tXܵ_Cj?np.[UE!oݧOoYk4d\.\}1jޭr!빥z>1o|sP, 7$X,_hSRxo`B W!y d{DŽ,R⾍- [%n2dÃ2^<:*o\Ŝ+d{'ƫJG[ybRV_wPqJ? rs9ڐA}x2`)Ƙq .Nj]ZbJ<M_i}  `~Hjiߢt ը8qUl}ɣ/GہПę˛#m@|cx "&61 {{ 6ASF= Z/K75V{^a~4pZ_l0ld@[|ALu;l{הTOwbtr%~@A{_$]tPnX`8 y˩I^k |@x/FZ"#v\&N8)!L%5a&4^ bT,tr+Ͱ})HS(7Hޭ~A+g+ [쨋̲ V?I%n*2XS$x`![LU=XkT&&ʖ&w|˽(bں yQZҼ#hz4sg^]R8?5* ۡ6g|"XO?ql]FwNot`>hF7F[ 0Pbn3"_aU |ʆ޴"-j8E݅u cM^/9>\CKPHVݗ7#' >ٗ=+ kU+@"pRUPpޙ ix%jqR1U{IxU_LYWSΙ*TI rԜ{ͭ &Itl<./Uޱ5ʚr",3l&u27(?!|$FvS2/~i90"UWt^eΣn,ʫgԻ}*O~R\&n[D`Cm0UEG‰BP$bK_yr7,Eץ~薞C $Shp\Ч;V#7b܄i{wʪTo/'aʬ 7[=eǣ]drgLo {.b SxOǶ6дԡM,4iAK%L<$Xԯ)j+ۼxDQyr =F>1r5޽#>N5!kPF&O-ED}V"": mdh)8-d@;.YWDݵKa~ zG0(GfsS: %Nvx;TgʽDJ7_z-9(ĝY 3H 4"S '3U-y-:tpL| -ŠƯr;U"qj62,A*dwՌGwhOY1pm % ϺKDzlN wQmF/ z%B-;UW:!C$X/23ْ }Gl (xCljO"d܋% D$|%7 ?NgmNRDMa%<-tvW5si A5ʭ]:e'AnG:\<-w=ICLMYTp_iQ'9HPRY8cpc]3~RԑTe1HAAh-D8ѸKFb3X9NMccˢuy6e|킔C{. ;o8DB?d$_xTa:g6AbG#zFXmǭ!3ncT^[9ҬOObQr:ߨRI ݚݕ/o!4ZwU7xu+.u2s$GPY ګ"Kn [mГ kQm >O𐠒jD'TKN9yBp,?\}ʍ R-yhWL}12%&@Km&Ғ*seT -j|j1ȩ@͐\ɵH[Rh'oc'kK+}O2闫jb/U1h[^ xISy5x(Vw/oǐ\KMJ4NÃBUps)# (lǵvL`W=2H(1`(JV|oCF{8"y)MqazDV8(2( ?^_XznKH!M6+!^`*τWVof1/.݁<ώ;Uq,7s#DaDӅZu9_X! h9 /Dog*GB iBG(~KeUـ-|/@w%X=x"PͥUU{ăT9Lqwp!Ɩc{~Ȭ~3ȱ \8Y YIwDܙL0KKh7 :|ـ P6/2ncFd76(e=HkduXL' )籦gHTN P T2Dl+|1EOvS,̈ܙB l,3rqL8Γ6~ˎ%tη_hM a%ƕAs2h$nK~půWa~n?Oßp|i_y'3q"^h˷CDʾŠw,ZqVNxЅqm" K: Z|(MJY?6=:(,sW|snњ#h{z׻*zVB-&b:BuLyatqVIWWشP&6^'wdx ^#Jf'f~uFy,cl}50Bqi#6T,n&P7 qv.ݎUho.SSht YǃqV2>PxZZ)w $[vOku|Pոzq]Y 0j}<"ݝrR?ďmcrl2mZS_߰Sz%͗Ҕd3.%z&Rt 4Pl7"e[d?sLOTLC~^gǐD,65 >΋2 p?BVQ8|6?%:. LRvtvvK {'7#OJ]4Mw>~CقC m7Z\uy2Y3~[zTU0M-ZoZ: 7U390 ðNvߣ,@p_fYich/&&^`Cz!$;yB)j/OK}Cݰ?6i?H(r﹓tWS7WӫlXIIMlhFmI2VY CǸR¾r}r1hʞ%n./`sPGQ#=o߯ɘb~Mʆ7B}#tH2pezxAbZx0!1 83wԻ&ɽhp'<]Hm 66 nb+u͔N!m2FC߶'9χK s6욯eI ƣGK5 rҐEBYHgKݽ6;NfCX -p6mlQ')T6[/Ӵ~-etN$a}?m5"Z{<$'&+ȋu!PӬm4dޘ`?CrxOi׈:v<]F32}笃c 6<adb?=,\ *,>ahΨE")/#RFŒdQo#C6Ȇn"Ȅoݨm<08+;"%?vʖ7u'}D8C3'5ʟ%$Cㅘyo?()#@5S#T)wwM0aep3=3ٰRT0$3.)6?v.'L\IxB5i(AkIf%Pg+Te- ;{3k5ڡbaIҰvbSxL=sStdBx^X2'/0g0"Xi֫4o?뭘YȎDG A e\FA;rőUsT%Wk#ǔ`NI OQ ;0_ sTlO%bS6C]M$v^, ԯYen 0,\yΈ#$L!sZo78TƆ (ʎꄦ] ;trWt0Re)feXZE%nC3¶Iꗆ]0G ӴmI<$v"HuVz-N7ن. 4q'r ~)<ԙ&qBF.!ۏ_}W5"-A4dZ39uQch)B7s(ǃY>3loܿB{tl 褥H-CZqQsEYL5.^.0//8 0˗LsezdŌkz/2ٹ/YQ.ɲwTUuLiXYJy[ *í NhFB0~XLs'yVjVa`[Q4³ڸ.p==˒4]_|P4 4s]‡G\HG1&pĀ2ttgD D _'B T,iB))IWq> ?4lpUm&S3E'7wXFƾj"Jڹzﲋy$'-_$uqhues{'/SM.|%kIyB$mhUI K,5x7Sw6uw#ut\!68>>NxnZ ~g$b߾La>#-hz@S1"Ñ h4dW)`c,dExo-WxQ˩X+L1^}P$/]M\J(1xMb}joSSbZNѲgfš!P.MSŴM^X`N.'Գ@ř5-V~2ƣ浇;3۬+A\aC+Nznj ֜êfbpAwBBs ]^TЭS;oS${ج8`*փ4xq$&:\9_CXK+1䝘oW'Ge(SHxBovOYB06tL^U`Oք 1/2@^@C'u2Bhn|}FFG-:ѭ0<}]N׾0csӹ muCH}I1ך|߸Ÿm͎CafvtdSlNə \, s.m$r#!"KŪQB/)E/ͪ *vVղ 0W |o#'uJ*$ -yȱ|@cN9}[u{]ݞYM1Ia[ki_mLyT>+RjQ-dϸXǓ E[*j;1|MT GJ^iO ɧ{':q  =+PUDF}u3sCNz-OAo%|2љ/LmY_0u"itAzID'ЏZ~_j*\CM?|?I﫩Af+|a 0t0s<pFڏŻ{aos')W?n*H"-/#=Rף}O!(\v Eq?iD Ӛkh.u=- U(oU,6eqvv^߉(QU7VA삭U_ps3_EnXV8OKfa ]XꬫJxe=bV[6 naxq i~&qD+&no\?X^%vDS3Ia#}8J]Gx|as&XWpr;a04وfݺYV@~~3ܭ,%l蓕;i͟#lCHz-b9d$ȭwN؛;#2)oB4'Sp5'*Vۓ_k*d.7/-}/۹tdEkrm@$#R44Huqs⏤D7O[/&%ko<|ICd#zw|:J2Yx$z}Ep3Ep_̶0 )m+JByn@XЮygܒ=~ʍRVF8l-d :mF4Bk9N0T=jp:'Φ~ZmlWL)7~Rׯ?a1G2is݅rwgD`HI,{~G!p mIvr\ʷn qs[nҰk۱. `ru^0. 6%3*evc̄Cڝޯ/Y]KX:M4DÖ wn*7Ȍ 3%qfmGm(DFl5Ia\8LV,FU|â?A֩>k~lU4ٜzU`zθ0kRGD֖cr*'&u u:2>M񾄭aiX^Ksy4H:6Ȍ1XeC(ڷ5BMv}rSB|;J]s!g"%&?ꏈ y%LW͌j;^Iת/Ӊ}wC۰~Wz77Di<2הzFP[mjӆ_J9+5)Kngd!} 5?n{G)gT/r$NS1+~ΘMLkxc*% D6Y!X8ZVldLH.dZobqW7{dZjQ.غ4 ң6_XZ.] An/L`|e\O:COɰ9rH٤m/ :)2`k!| m !?83 {]2D;m/us|OH%*#i`Oas U[ ץ /4}mi ldYu$%刬-0?ɮix;9>a1liD~ᅊЪ8ӃZ5;REb},8 aaQfgmV& ,65DNU=>Tnxɴfu% u`9[4\IMLՂ[(=:>W>]>hWDmc$s{iT kA/J2fϮބ)ٙLbb]GTnج"A*uWY__ WB>7!c(9B|$|r\'Lw-ѲPbtNju "m)8o/VM ;0"TpnMa~6RF+C =H7)Bp|BUÅdZS`G<R!طa#TXsE%v?.v`m5,(mm۶m۶m۶m۶mkfv#RI*I%`s=zr3roiM7H/ qΣ$('dwPU޷^ LM4R*SV=ґ^A%Ǟ2>g%r)9|D>ސU5x 7z CH:"I戣Qcj7_ ςqwKK65-w?OlLBDh9{=W$HG1#Cr}BkR,&U Qpc p$6 eU9ߵ1~6۩<{P4͙LkNKMv^ȉ/ȩH#XzE^6bTSSLë^QE-moĤk nݰ2PzBimz=%p@X /F[P`C6ZaJ+[;*tu/U`um%r2a^{SxMo/+qr 0B_lz{@/#V=]B΂P)Iϋs 6i}5o le&vL!w8:y~mK\pG Њj xwaAUJ[E׎lJc؇+BފA&NV= p =~>ϱ*G57V8Ds4ެ3px^\n_+ev?!'GKj6bTD]PGP8a3VwB{W9I4$k<~:5Vg/1!J g*0j%2dyP t>E=l9݃}&M'6Xt} .2&ǣ[hkZ=V$m`[ș'2_/I̍g˟c vvlbnَ-r뚀ս.Zߕ4 }inէt<S2Z󼲏=T8Z^gGa4Hށ_qu1^kY'0Ty}Pku;yy49eg~ I ۟{հd:(ZZmsJ#Zxd0^K2$R9oeޑeY'zdJKlIΦ-|L[ƴpE9ܣg;[/NSy(^wԍV 3AwɵZΗPd A3i(U)Һ{xڅ#9<I4 0mͣT4k a(tQ=։,YI UӅ\7+D[m~L$~z*/g 7Ԁ_"QHPT3K]UM<0y1j˞R+l$}O>D^ WN[eOǩe 0M+Q""/+kr5nt|{[GpAL~|X;WIL yP(ʓ7{̎ *Ie%ߟ}_Vg P>ŝF+Է?Wlzהh^}]x\UVTJlC|+H:g0{EdxG]Їdk _%&J ~}饛e׋\֢ĴۼuT=9kvw=:h\?%. |EGZp=38gʽ?+2mJ[ k1[`6oޓ>s=ъ, NN1Hy81R!юw5ґ?J]6ՒHk9Y-ޝ;ۯKzfy$߉t]hkږuq̍?Oe|<+@=#% y{hgzk*TM%#NT6}}7Rmh:Q;EyS73ҭvLWEx-L%q+l%~4P¡1b*ֿ-N4HNI>`8w!51[K9ɹo*BjPP.m'ʁڐj0P8nOO>Z5r;^!J:Ot[9ͅ\nPh\QpcnV&FΜU6<("{<}gzqo^֗q[Px#!ܝjr MmnxD{2_$Ҁ r2ї+h4ecQBMO{NÏxx#jg{=iS5$-y<&+:/1߃ sk9sk$^9DeI~GQ#?i٦k-W@g\ىX7'ݨw!*[?!j2Pfs9pe6pbGXiw!a^^qشNC|m?۶*pO(4*AgblwH5TX\_uXx!9kQKAr},n[^Yr|:G\>r_`J~?Q#QUX/#x6{RP׸v.oi 0 &e/a]'h#UN~GVrXz1J |;D|=k{QS1Ahi϶S^ǬC9+wc`1ͣ%z4)KWXOɄU E1Mlp18:'I+[֗>h5q0Q?UNJ1 t75Nw82pQJkL;_(:7fTG}>eH6H_rKo6&ј3 :U5kNOSԊa%'Y] ԨPes4".{wwf y-P9%). ۢRpZG[|۱v_t$Zn\~_?DM)ZwS8L\+οкrjE"M~pU#z(?4 z٪B>(XA4؂yZ4l %M,N UB 3R[$5=Pp_DF CgNC>~Q!垚 f@%I$k/( 2g+6x0lj,|cH<ԌhPGZ`y:qHW3X|r(CgwknGeZ |/Qxf|Z.ۥv2%u `Vh`TZBER&tR_OMnƴTj=BF{ҍۂ nK\w'h让* "@&ښ TuQ0j#}ۍLH/8[`̏Mw*ri"m 7ʧqr17HJq HG_Wavz>9_6zm**(elwn R9ؗEÜ}|o͐Bt"t̬^`9,SZiM鹨J͵ȌRNSr'GR{n0=,ptXێ_mш4 疴goGݺk@!)587{@ d9[CzPcF~C4z#WS_f0>@iҤQ,g|ŭu#.#6- |/QdN,#v)hI׺ }v5$&,9Nx[kw' u/s*.1 ˵J 8ֈbгIiVy+\Zy\o8.S [j IB M k{BKiecX?'u?YQuFD:%n@ϫR+={+'ʕ|~ lpSEDZBbaᱳ6-i?81V7t!Zx1C3`Xi4Rx,+bD|/GEAs)]F$R\d$ hC}'+uy%/SjسiWIы[(x)lXti=t޴e4ӾCZ{]ލqwDIrq_T?9?چBIT[wͩpKS aڎoLTlsjз.##B f4#7l^t\,%y0yPFϼHkm @SAS~CJkDkJʀ3% m(2Vvry,rpw'*[{PhOzf3 M R둹rc1C{ѐjIAL^ENBUdv'k(P=T&!1Rj27 A9GN* &%lpzPZTx#P&C5LuT߃#P ZO@/u i/f6<^Aa &)nw#J:yvU(.Mz}N۔*kAYl ƛyV)lAP[UϻHs®[#tY!)Eݥ+?"lF {%∹]]ܵƗ?M_'hӷД.yp*ƅm_ -r|5Ub>;oF\҇%bmVa VB"=&;rcko'7Ko9ƪgn]=*_1‘3݃QKs䗌R8+}|8I>B W j]òo`yyZsMxn eq \7 UM#jFA;ݻ=6ݔܖqUa!ԏ|6Hvj{0wNج3BZkwБ~1YR*YsS;8ԗ:ag$?T-ND]|~&d_,+;%% yylhD)tϝoܙx=W3WyM-.Qaɟ+]_AI6v~Kp2֒B9Uܫƨ/g1:oAFe%ftvKB}>Ћ:-O@=WKKV9TIQXYQkCHNë$WT@nBHͩCM_O(VR.*y>1z6R9fA èf,!@3~&B. [{S6>i+&H-TEッM}gX5Mf:l~<&/|n :RmxsIऩef_!x_͝ );cs޲V rη0*354J4\>cbn?Z1(V7bo M$.f$7ep~#L=R';Iwjo?E»Ry8kf]жY*2IKeoY`Mgp콾5Dzs+7pu5fc=T+PgAzoZ@ՠzRB_+EC].>p~Gp,/|{TMK9lQ8]|]n M6 Rh#qz p#UЅ?W D.Lۏ]8چ,R.A߱,]Z6(+)g-ۑ9< lQ=2j_ɡ3" r, 9JX0,c`@߽a\uaЁ /q`dFO;KSojTɍRbEBWjZ EM:$D^$|T^&{ͺ:lyP#x^UIY ^gP?zEEn-66C/!9ّzqjj*6NpU0OCΛtX{j`D 3[i{=ěteH~ZsRܙ5gG3?4=!MP?iC\ #a%=I,^EZg ԓi:Cý܉-ao;3-J@ͽIÊ/@-D bA|PDwO6.><jd6x}9-Pj2qĪEK\Қ4>Wrir3qOPy;$6m)-Axn3!.RHŤ #,®~ QZ/ͼjGމŭPᠵǜ5j%ڌ75]bV:KdGN?<7RfvtqwؐTDy?-c%2CmyۗsqȝQ{T_Mؕ 5幯0*†qKW/-l;p):[tFaQ(a#_33L 38W0ŲHQ2i.WSvfaeXVӺx-h opqҪFYTp@< /Ry {8*LʥQ$G0m[|c+3t pm,Aa|Pޘ:{8'¾H]ߣ3V$ղ;@bJ|a'EPpbv8_ ŷ9uesJ[6/"u .Ql 05AR2G1P Cz'Iqn%wnT .5I&ʐmDٱ3^+qo{zQ8Jx,Y]V CĢlZ2#)?K!=s#fn;TC]٣KSs %( P B Zl ;=/K8,NI !XǶl@_UkЬ9KHViqR6̀_=ƨs2C;CpMi)|Ҙri28GC-qߛ%fNsfo7op Ly1j9UʛyzQ {VG[k~(ghfLC49^m<V?h*Ѵ@mſ_k7߱h,&j>1l^m*[T &qgyXw v + `"̷ 0 G?,[ ( h* ;q|vc14CD޿XF1{Qoc"~XdHL[C#p)ҊD)hYOMx3L䗽}g'vq>{0mgL~;* +\WsoDg9۪kǗpb9Zҧ۵sXTӣ[nR!aK vb}Y 9 G6Ff"xѼS;_s>{A@ށ7ʏ!)GHk KaZ!%`]beL"r'\5xYݠbЗ˓cmzؖvt4X2fZx;ro7"_ܤed ΘO&yU59L%ݟ8ɼZ 禶tbg;qAv4l}W“ &ߠf/iRuUCF?gv៫`a[pAJy'EjJJBskPRpX LCoy)і`t`P}BhmV75?tՏ25%;5uG!M(3ΝW"' /0Mu@z0W~ظiF<+%2MzjqBSʟ&ގʉSY[`l$,[{2/׾M=uX`Aݖ Ybmv޿zh7WQ 2oV2YJLTv=+ۮ$;#:E{ɟ4Gf%a0a$+!@p_[ <u6AOz|*/߉~q'^HB=p;$'V.Gg cS&҆ir dz v#o#[Ppi6G8_7n9xY]$1d4M%Tbu ZYp{^+Wb"2Cھ0~$!!R,*$ 3㶉/ l..[[6o?4?+iB uQm5Դ}nA2F/d{57ᆖûѪShpMŜ&84`1"uwT>M~I9}c+ph5-O_F#1 ˀg@t\lzlս&O?Iغ@ 0S2XaқvA)RkE8dLy?N()AXZy1Xs˴eG-^X01!xei:1.W!owL cECvy }R$F֣:`F`J&dp1oKxWZ`81Db.v' 2Ń3R%Π\CEQM\k!X,gՍsЎ1]mb撿v8Gt'QS4pu'|fPOv27>̙ iF<033̢o LWta]u||}BvPC`<ȞY.ςJ>I{D:Jԟ4b-<|W8(I7>k2+{[$q]cjp6g'Ka}!r,ش`CFlYc4uh(~Ub"!U#>P9̗A$*oD=Kn-+"& tu}_bc)r+l'6!Za%D(HGDcT{Wa҅֏*byкrM5s1 ߏB=dc<If.VpP·0UP2qxeH  `^DoeQTM|HbR)/X^G/>ag#^tEۢ9~S3zxy-Sܮz*E+}EOB Q ؁B˾u045diBm?Vӓ<Τ=1Rl~̟[YHH hppo:f2'ˇ Ԕ mwSs R,bm"r1NQ&wu[} 1Q9%?qpD)Zᘂay~|x:?5X mjcaoU9ѷ<lwP1QX],p船y'vnqq x冟^gwNsV9b0Cm}CMyYQui4?H!J @d\G7&QYTGdQ c)jM((DVqn@yV0w#y(ٷ^RXJJ5k\0R\ɂوBr]u{lKv@fy,{lC}ڋː ɒޏYb0ޚaYٜ-p?*h, ;e˦ g@zhW?"g-:/ Q^1D2=nsŇ_-X"N~̲=L˳i!IEi]%ӌ endstream endobj 142 0 obj << /Length1 2299 /Length2 17355 /Length3 0 /Length 18735 /Filter /FlateDecode >> stream xڴeXKӸ{pw'@݃Nw;\r9g޿em]k~i(4Y-f@0ȕ] 9Y]MmH44@SW0H(sy:8h@Mi0(]MzӿŕM Yـ o.`G/g+k?1XXD- P05{LAVeV Mhf@kS{KhkJkhd5T4Xk9:,3@J\EKajkj[1TqWW`b'p}cڛ3zkWWGA66V+7WV_m\`g;۷3Wa@ot+=(٘A.?N2)J&wBi/s _iM]URSS8ڀ\ S /hA/@V9'ͿKVfhg;f rsGm{`˿"6?] /[Xoze'[+899oM* ;8vAS>):@`KliSw 7G6mP^DHˬv 4f^##~+#`ij}!n@?*!q,l]mT.%~co5_c6`hĦv}krɸ۫:kf`c_c C^`j?:O_E_AV@ 7+;/4&uߎ?כto]inxRj?6i_V s 0uv6BbkN[W[=+ptsX(/M_& `qFoJ#>߈`SqشFo̴F6 ||f7K o5!@?Cphh MfV'7voߨ; 9ވ-0Y#!?ǿp4};Q큖K9O #pmo\-mor1|Ps/u=%wa5]v@]? 0Q6uu|vbq^e_ h>l-!ap-O˷i7so@O9"\(65_d FOTO! f%{@;%P4=0$'h*ף ŵH4skn_ٟMZ|@U;8Gy9XX#לΤN2ĉ@W8W锆UEem8XD˳ݐpbMWM(9b0ek `G8$vNMOcpCcKۺݙ{cJz6/D. Ȧ_>*(6ueɗWyOI?K_'l\y~z;̉Ka"CMrN=V*>KBX=b6lS'lb Fegg#/ť$d{4܎ڏ(%kE 7*۷ 905qmw.,#޸hsîÀP HtdoPev[6?jpwW64RÿPσ]s`K<\!nnycim&:'(xQa!r0_ӽm'Ɵ)D~;[ewE։[`>2F0&.>*Y<ek!\*>mv'$Sç='yvuzI;g4o)`֪fqH=gI*(mu["s A@g6`Og)d~A*,?F&Z_76XJUTԑhI\*(Ԙk%A ںH{P5}εkoMsnȷ@C8BLdjGG16_ }R ͠<ްq !ZO>L׮K]#fc"#mѷAEۤ~QJCx#F"ۣ „;MҰ Z'vw$,e\H$,k+ 'ӈfXQ :ش g/QTOsZ͞ʿ'p vWd ~!CM[NTW!B_-ux5KV6*0֓Л[ZTe3#q=<͟+oh9sgNiM:ڕ=.ǵ)WD/lhxhc;u~əF1iSD~ەuv0|pKշ3c@PbӅdv.\"c9d[0,v0#m1^"*l?o샅S&%;iA<ca*ሄ"+({|k4mcԃ*t:'t$JXCꆍ5XyR^B OwBr4ͦA z'PL;‰OyZIZPBpW T|xg3`xuؤd^|5 Hua֕|oy6 ljea%8#(ض`]Ta45IR~uQFF~ؿU6NtNO#Ihr-0l$!c''0"gs9J9z'hWx8+{фXuAV:LYJUaPFԴv@2;ӋLv%_/lB)x=nD{9Po=$ѵem4b\/xH2Q}N cCņ#P!gX wEw3b8>8 ^Fk:.=J;w.I4x=#L4u碄D`~o{sͬ]dqTXBhmYf>St43ˌ ?J+?~sUG(E'rAk ٓwJs3%B2D3IT#څ~(Qi5ֻa`[̀Q>iktեlP:2C1B!rI]>EL6fcBo~a;'BQcOq[MU\|nV%7|;=}2 &sNMߧ]2;r1^k٤$I7 K$n7a&^aRG#"cr)1hhؾOu}Xn&n+ Qrs*/rDՇhTSQ]"춙:1BqQtTꖛ7e9t""0+[|iaH0!M%mҥr+dF'\NOs֣'LOF1{ NӾ\4{7jf*;([{(O a~ʊ7\ B3IUKs|}{ J{;d5w/ 8hfY?쑓N<Փ/I9f ш1vt:09I%asN}|YN,U6ק2u"<-a\(Ry t9p O&&Uh-4xQC1D_~9&E~s Eg" 9(,a6hNљ)#v"y͏-S?LqWX1"iη_JZ(֐Şg#U !Yq]Y&9/n7N ;}d9z,h :4}#Wluqz'bR=2~uo)x]gڑhl6J= )!y-C;ٷ"<_AVm1TuyǬ<7SMzU_ݫfj6N @V]y+<3 |3PO*%V46WK%5Ax5(GZzlAjϟ?׻MbK9>j w_s3r𑖣*&!~ѷ+ EXE`3$@F(JJ *͚EB#f1j͕|KRhT1]yXyR"_`}_u\eLcJTny(@ik*NBMn\Z"k癘>*_rCM^-C(?p)i}m\EO6/e`ٟmD5+{\#NGёX5W{v<)m )]D9E#u;2u -Pn1>m'=|=lfoQ&M%GhkTbԼ9vNiGT#w\%b8bKjSǓb ϶9Sg ME55̉Ύ#jQs}e;6ʣ\(uEz9O ְO3t#R}a~H*/s*Nsܠ2ubG0Ԇ0 6l3<>kͣW3ɬJ#VHwot&]#dA_n0: h|Vmu!v+bcu~>J&dr qw\P6y_fl=[)12`Kc6ܳřd*W*d%%n s1SՐZiƹl$,W N ԁ|~|/ʪ)9GCl0<|ʌd>L,W %&CFl{[N0I#[g-%UxWm&g p縒RVy{Œ7F"?FsAzaԵvܐ_z)YRaAeW' 1z>5zG/ˠI֨~[ǸK=W|=O٥f#L !(yPL)k2N 4Vn\ĢWbcZV*itRykEH49i|t6SAդKב8b2y/6K읕jUjN^G,B5-x f>r[H.G264Ld ̐uz11hEq%/C#ĻhJFr| I.œj":196o:IL#O |<. UA3A0$%&%kbc+]qe' l׋QA"%k d+3L'&dňKߟ$B/u7Qht" IN1H5CT3>ZtOj; ]%&iE~ġHQ:( KR[w ;|7sZ:lmF+cKâee^>h%暫k ad6jR3vL[kԱ_ G~gR&^oRРM]7`d Fi򨢚Y :ev! %- .l`YS#x[Җ% mq2IȱػmmbI)Qg /0f 5Jܶ1R{ " W?؄Ő.|tSisZJ{H?K&R7-^)KEڞ\JоYY<} Ih ؈?3Ċf*Z\Cn`{0gt$jMveڷgm#u&|< 8N܂|*}ڪ;y'2e$wI0}4mbk Vh j+{o1K9R]Uʬ~[G(EX>zy1-v>uD)WKUKj5؏(Twjn_=#^ۢ_nz?_rkAE|F~:.~YnKq]ҡ~oJIaV!,XPvO>xrpS~jbO&Qp1GFX,  VDƂn^D`p<bv@ MԙhgwѠIX6t|5b 1|LcE4[ѐQ&*xTh5m#!O2={Nrݐm{U{gDO["{OMT ||J!{øE}_>,~_mJO J#Mz'`rhDgR?y:ghK3ÎgCdxZm !y+j˲Ǘ&C-}W~Ff7R0[>W+̮x:ăDsUsGt"&$Hw8 +R \bz}_L#viT2`BbǜCuޢ7r`d81д;GW = h]gpu[!Ss}F#/i])KegHxwlHBV4kFpE3"ib&s; 9(6s{CMB?BVU8&oLд3vB!bAk-(_>&QUCO`gx{/De6TaR4HVm ։wC34OVw ^u4b%jnj;iބքGRicDeE#)*-&~~IZOZ7=ad[dEo9F ;;!1 s.:k5EG^֫qa qq@]v[I@rI#"nL/2B6{J j05ܢKqDcwXWd0a}X1$dO3-~. z\ymN` B{uG^%+"U+Ж8m-oK,5V9%2WJ'(ʋK~ }Vs_m&ֵ],uof] '"OgH9p5n9 >wSi]/$"**Cia{Ŀr3 +뽕t`F?9B\߰Y4pqP`ä_z0GKiQu*+Kw)>kY=pddA7!*j6w~uBjtN2YhB5{sԇoB#0A)0d /GȸtPi)%CQl6_<ד{6enW詍:e}LmnwjmB ~1X13ǔ&ֽLԚ" B%_V w{5?4t IPIÍ1 (״2xdצ'b+7$`֓tc Vmve}ԭ O\ۣYUe<݉2QP%-ecnnI&xaPCl6t2<r}+mƁZ=s8,d+(hD/f ҌpCA EQTϕ=l]EqPV1+T wtַ#(pyAЭ!Sכy`)xꈖFdžhW< znq=#kӵS>W7źxꯞyA͒>b"}/>} sF*zN:3(?znefu|=Iڟ%8$e,2&/pC7w鵜P"_z8DD e7Ub9Ί{`,ϣ|=Tb)`ȷS0RP,]"<^I3U2fEV[I$O;'"#fWK8O-ꇭ%$ljyBQ ,gl2TAhgergOM1N,TdmeqwLXN:Ɛ kىHu,0dY{]j%1J `$`vwA#b;mY<)j[iwh}fרƇ3>r^dXS1z !whlNKc|cpA+bj  ކdO嘕>Պƀ{͗6C\,fYKu׃3(Ҫ %A}߿D}#[{ 2M{N57،J2h=Q$w`Q֪[nytP=b4j{Ebs;Biu=Չn,wXx3(D ϳD_?^p!m&-^ϫ7(]1RȆQtDN/m:Ԫ EasJno.QeMw>YL 2GP$ _oWnhtHKKlK0KNq>)Z~DWKz6$;;wj=d˜`!$lgbx>:qupх=ezZGٞjnkH B߬] ]9 >ĠJ"];֡BfhAQۂEP:!ә<v<`(bUHVUr_GX"o$bSY/xؙW]PWRC+.p{&5Gp[@1dQJi3[s~/Vcx.\ڢȠĜ"  G!p#j4oٜSXN MO?\ 5:DK#ّθ/]Ko9/RFspjr?{%7g-4ƸnQy4 Bz}¢!1sFy*ցO)vvc9"wK8؂结*nPHK+}qxG߬_6 _V<۴n'=5\6":J egǛ$WӊW҂@hk#E|{;O Hn`xO7çaQy5w9G©,̄(X(@!#ITALCz^x¤`~R@={dsCS`LP ]fTi=*NWAS^Bj [po-m J^!<m@DNF9!sA jvGX= Zͱ~Rퟣ%DžMkG v aKc5fD$ئԉjUp338 [腐U 3 /JGSI.Rp'y}bu.uUz۟-fhnOb(n{#Vɶ/mOQ!$ǾטW:Ub?E.#XڬD'oa$oG2zNV_kN<"мBB7{RhChWvG4 2 _J]8:]xׂUUow:@Y.(_aTtp(eo頙mR`qmS}bPj1P%-[ UBO)\c E t?߄~^Q)_,Fbr^19 |Ҵd&tA݅KF@ zJjIja2i]̿ ^;C7OuϚD+bHyA<"bfn'$ja  h5G #H\:]@ !< )*F]{IP= R_Ǧ{v3OEXފlwA :ɶ1Q-"rYj9#1S"Ⱥ횶KQE%yEm&=5I >TOjA:Xΰ0n7 0x)BƓ&[.an"݉g ڙ;l${M.˱')U]`Ѡz8F:l/r_Zo/О 89w󚽑#!cec '7_-Nt;<9w)֠)?kT V0=7+Ez-]K?)W5E:&=Lb~ަLA,.XƙE+xD8k7y9G*2XGC4:Q~dԉ"Y)V^"fwIϬ 8RJ4,sa#h:k$K-e#?*T",5ZnM`q O:Q"M62CMybnFYfwXt3b&h2-hfk͟`S]i4V,/5AאkI^9˾fYW'Ty|Sij\VX jQpBuY]nز 3x+@"1&CQ!2{_W5сKhl,ը!TdNO@NiohAm&Q{Up-q5j_h721:42ɐfS(v1E^x%_u`idj0qWra#)s =c2@ɱw82yEi¿ (?α7>1IF"NF4SM=:Ö"3-dXb&%=>鈰9&׳4ryw!4̦s I|%O -U)ӕp9j?(23&Bf1 _z/Q˵< @HI&RUmqRAg$) /;m_ 'a,*[ Hէ [ 0.^ovYRѥGH5vU-ڐ[ )9Ǭ6# 4 J1:$vqK͐U"KElP[)p@s)^N9MX[#Q4LvE6UZdY G4VuD2G~U?*Vڼ>R;Xo;`dܻgk'9nuvswp)/YBhaQextp+naذUMX+R6EʁZvfI~ƬLèhk8LW[f 'bO|~Ns5g+0He`w$QZ4CiV省)y9_vs,Z/FQVhͨL8&8`#lsrc>a6;`祜塑C؏ {\`I9@{ X݊슢xCɭɶEJdxa|JhYݪ^:Zpe%jҍAZd0},yokYy:齿H9ټ9^+ Ѭ5+nB89Tkj!d.N[O٨iDL+깵hgB]ͨ+n\ L>\~Z=v1c,G)3ىvn1R4*D$ᅲq>hzM{:b%/b]>l*gHYe< uoRĢL"+U\ƻ/{Ub~[SIYp鮗I|+lM(Y؀+FGw_!^&蝔ymy4Q3?kव!3d?WSxb+rJmS<]ql 7?H2<#QcNU Gy1Z2!4я$@g&<8굮4{ў BH `'6-\, N< ARe.BUSjN0N> tX!aVyuyI m2#caY pcq/H24q}3t.|Җ]ϻlP8},Cj'4+%R9Gr&9] nk :MEºHQKTl# rI_i6O|A6Ю#weY.8L($蝔UbD sEb)ܫ?c>##p]f ;㘽P_e'm9.}W) j4S?ФRmv:=Α|Ք4fX@Cj '-r|иC`O8X?VjG,jfc*W@q40L,I'j@wdQkl]xē#F.εkUQT++H4zj_GK,]npo/htvn"ddyUh>[i yjERn;b:r+~2{p) wVwG@;OepZtN!knNIWA ΋Tn.8,rJ}HuzzEhynD*IPqj#3Μ~TJTn#rKy9%qtRt2;)+ 5sS(WK5H]3 /<ϓq+*ePF{a2BTEveʊՆDD '$:^KM:Ո i)i=5iA /O=B%̚iE_'~6nDz2Z^[| D0M.U~=Cڅ!1o*4rt/[(K/02EGdETXcKa%č9uq/(hxtWno9Zpg[Sq$gK^*"@ MH~KZL)K׊XsAj(t3uO=TEeZSbVS8 +zA}"iS9cx9 _[ jx͌=bq*oDy2DcSǍ2xqϠ8ۇ9c wrad[:gp="J 8zrŶx>$Eo1 ZGY(9B0d0ePi0ğz\Ҭ7 dʝ' kg ePPnO;l'i^_̹d,E_)0goQ;/8fU8N:u2=}LO/ T"وuVBM] o^~V9Y Huʓ$Gx'J]W h{q~>;̆J8P? װ%Ưd./yuE`B!Fjx "OW7J (122:х3,7.l7;ClM $Pt‹7g(iĖ@ "33x 7?h-~EQ .zӹwBD*U'%jBOP޷7ŋV y %cȀ-ue p~ 3jR6vҒ=ohG}J-T8mh<0&(TdԙDo0M3.\[<@ҵۈwbjvW3Q{FۻgYR] _ZsΏhzc[!m%8W-"ڐu2[*4j x\j38آ= 7 /V|ѭ51A ) zG_ݣAݸ!2zʾ l>@tTlh0y)$s D U v5CqY5{F7,Zm?:`}19N ]u 2n#bsT endstream endobj 2 0 obj << /Type /ObjStm /N 100 /First 822 /Length 3479 /Filter /FlateDecode >> stream x[ms6_od:'[&縉hȒ#Qi_DZd7k bbA҂0%e"7,0ƤV24)pLY{fdR0cUOJ sV3IC(\=`Dlsr0 q:a >Y`|S7$`!r 2)7L& M`z&U.j0Z@E`Wc䅀A:CjZ, l#E ZLФ= (.r$pՠS~ X&KLǟO%ʏy) nM g2:. `Jy k]HYZa_NحAy%g"TA~Q\&RN`(NHjd,'SLL LeeoIDW}(qmϦe>4#<\덺 JPAUѳB?efŬFB= AyZETSC.et0x^NwŨǃjtJƐo{|\t4sp1FwGj}:9)"Koy5Mq.g'51N+~:)>Iv~2,?J~^'?߇A)Քgؖ `nއŢl6:-&a1t<*~AEl/S_kw -d:`kz;HТ?|v+m9=exxx%ڤ+v7,kLo4Gd~}C?sX5Pخc23/S<*1If;vzWԒJP;VkE)BSE/R:]'[ 3\Lo('KEZh6Mk>,(:ƒK8S.uHfVAgznVoR c QB܎>[6c$?Ռ @Ȅy}hgF ::d󼠏0:\-<@U'VΕKHG =>USi[HmhE[r/WAPZeAZRk2%m&D_%UKz,r7XRSa!仱-I@AXbIxG%)GX.hd{gf}7qgKehIRKTv>sӮM*_u{gB9cJ {ţ:=kniBwbXNqq+rf9xo]~?7> ~?>?/3^w|) _jd=z2~y:5 _K`56(JAa` 8OOY_W T8uDl\ 8g٧r,mptM /I5:8FM!SL+Ky}6)K^6^gyQɯsQG/'.&Fx4ޫ^7D2َ)K|h!wVk] "[9k(0ư ŰuѫYVsdOJ,KKzҀ5t?CaxDG/О[A_XN/v[1WUzU&E]YS!tQ^ ՀHޢ ft{^ gEl a1=*[o&}uj/_bow #Ghevkni[WlV\kϚV$aVOƜA_5yt+ݐIOùf-lەC F@#Ƀ/E׎N,z\ZїAK.E մnD_"eAW%nt8\MXjkYH˶]I`v`]Yy?KdZ3rFH0}U iϫH| u?Y !o,,kee7L,| endstream endobj 153 0 obj << /Author(\376\377\000J\000a\000s\000o\000n\000\040\000A\000n\000t\000h\000o\000n\000y\000\040\000V\000a\000n\000d\000e\000r\000\040\000H\000e\000i\000d\000e\000n)/Title(\376\377\000A\000l\000a\000k\000a\000z\000a\000m\000:\000\040\000R\000e\000c\000o\000n\000s\000t\000r\000u\000c\000t\000i\000o\000n\000\040\000o\000f\000\040\000I\000g\000\040\000l\000i\000n\000e\000a\000g\000e\000\040\000t\000r\000e\000e\000s)/Subject()/Creator(LaTeX with hyperref package)/Producer(pdfTeX-1.40.19)/Keywords() /CreationDate (D:20190717121536-07'00') /ModDate (D:20190717121536-07'00') /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.14159265-2.6-1.40.19 (TeX Live 2018) kpathsea version 6.3.0) >> endobj 144 0 obj << /Type /ObjStm /N 22 /First 174 /Length 875 /Filter /FlateDecode >> stream xڽn8sYwJ<māM`dVwH*ɎJrr ,0@H}1DsH0F@HȀRAWB# >A7q9$QHl1i`܀Rb},AM Jy:ϟ;ޟ?K Ўw{4梖fJEA"w%\Ty)J*X|Vb'*b[9އlw5UMVlqؙ/|x~ݳQy@h<Zhۛ]B-4ݹ7'Ȓ#A2dw7޶d`=91>B h}]=TNΎ.'{rzߴ3YcGl*ʆiS8iKdv#v u@ <ֻlSgjlZ%llgke,<<+%69Lu%t%tOFTLsmJ~P㭤J3[[ZYF:$u9:9CXщ2-H&T3"|(BE"vc <8975422C5473F5480459F443FECAD030>] /Length 412 /Filter /FlateDecode >> stream x%NQsPQZdZQPQ@dZ L \soߺU}."ѾW-k*! }ncW@?ߴR*V2(-Lm*MkxSn;ZXw a>G9OnJWݏb%=W/3YM )0HA O(w7GZ>2 endstream endobj startxref 212763 %%EOF alakazam/inst/doc/GeneUsage-Vignette.Rmd0000644000176200001440000001614413512442156017660 0ustar liggesusers--- title: 'Alakazam: Gene usage analysis' author: "Susanna Marquez" date: '`r Sys.Date()`' output: pdf_document: dev: pdf fig_height: 4 fig_width: 7.5 highlight: pygments toc: yes md_document: fig_height: 4 fig_width: 7.5 preserve_yaml: no toc: yes html_document: fig_height: 4 fig_width: 7.5 highlight: pygments theme: readable toc: yes geometry: margin=1in fontsize: 11pt vignette: > %\VignetteEngine{knitr::rmarkdown} %\VignetteIndexEntry{Gene usage analysis} %\usepackage[utf8]{inputenc} --- The 'alakazam' package provides basic gene usage quantification by either sequence count or clonal grouping; with or without consideration of duplicate reads/mRNA. Additionally, a set of accessory functions for sorting and parsing V(D)J gene names are also provided. ## Example data A small example Change-O database, `ExampleDb`, is included in the `alakazam` package. Gene usages analysis requires only the following columns: * `V_CALL` * `D_CALL` * `J_CALL` However, the optional clonal clustering (`CLONE`) and duplicate count (`DUPCOUNT`) columns may be used to quanitify usage by different abundance criteria. ```{r, eval=TRUE, warning=FALSE, message=FALSE} # Load required packages library(alakazam) library(dplyr) library(scales) # Subset example data data(ExampleDb) ``` ## Tabulate V(D)J allele, gene or family usage by sample The relative abundance of V(D)J alleles, genes or families within groups can be obtained with the function `countGenes`. To analyze differences in the V gene usage across different samples we will set `gene="V_CALL"` (the column containing gene data) and `groups="SAMPLE"` (the columns containing grouping variables). To quanitify abundance at the gene level we set `mode="gene"`: ```{r, eval=TRUE, warning=FALSE} # Quantify usage at the gene level gene <- countGenes(ExampleDb, gene="V_CALL", groups="SAMPLE", mode="gene") head(gene, n=4) ``` In the resultant `data.frame` the `SEQ_COUNT` columns is the number of raw sequences within each `SAMPLE` group for the given `GENE`. `SEQ_FREQ` is the frequency of each `GENE` within the given `SAMPLE`. Below we plot only the IGHV1 abundance by filtering on the `GENE` column to only rows containing IGHV1 family genes. We extract the family portion of the gene name using the `getFamily` function. Also, we take advantage of the `sortGenes` function to convert the `GENE` column to a factor with gene name lexicographically ordered in the factor levels (`method="name"`) for axis ordering using the `ggplot2` package. Alternatively, we could have ordered the genes by genomic position by passing `method="position"` to `sortGenes`. ```{r, eval=TRUE, warning=FALSE} # Assign sorted levels and subset to IGHV1 ighv1 <- gene %>% mutate(GENE=factor(GENE, levels=sortGenes(unique(GENE), method="name"))) %>% filter(getFamily(GENE) == "IGHV1") # Plot V gene usage in the IGHV1 family by sample g1 <- ggplot(ighv1, aes(x=GENE, y=SEQ_FREQ)) + theme_bw() + ggtitle("IGHV1 Usage") + theme(axis.text.x=element_text(angle=45, hjust=1, vjust=1)) + ylab("Percent of repertoire") + xlab("") + scale_y_continuous(labels=percent) + scale_color_brewer(palette="Set1") + geom_point(aes(color=SAMPLE), size=5, alpha=0.8) plot(g1) ``` Alternatively, usage can be quantified at the allele (`mode="allele"`) or family level (`mode="family"`): ```{r, eval=TRUE, warning=FALSE} # Quantify V family usage by sample family <- countGenes(ExampleDb, gene="V_CALL", groups="SAMPLE", mode="family") # Plot V family usage by sample g2 <- ggplot(family, aes(x=GENE, y=SEQ_FREQ)) + theme_bw() + ggtitle("Family Usage") + theme(axis.text.x=element_text(angle=45, hjust=1, vjust=1)) + ylab("Percent of repertoire") + xlab("") + scale_y_continuous(labels=percent) + scale_color_brewer(palette="Set1") + geom_point(aes(color=SAMPLE), size=5, alpha=0.8) plot(g2) ``` ## Tabulating gene abundance using additional groupings The `groups` argument to `countGenes` can accept multiple grouping columns and will calculated abundance within each unique combination. In the examples below groupings will be perform by unique sample and isotype pairs (`groups=c("SAMPLE", "ISOTYPE")`). Furthermore, instead of quantifying abundance by sequence count we will quantify it by clone count. Meaning, each clone will be counted only once regardless of how many sequences the clone represents. Clonal citeria are added by passing a value to the `clone` argument of `countGenes` (`clone="CLONE"`). For each clonal group, only the most common family/gene/allele will be considered for counting. ```{r, eval=TRUE, warning=FALSE} # Quantify V family clonal usage by sample and isotype family <- countGenes(ExampleDb, gene="V_CALL", groups=c("SAMPLE", "ISOTYPE"), clone="CLONE", mode="family") head(family, n=4) ``` The output `data.frame` contains the additional grouping column (`ISOTYPE`) along with the `CLONE_COUNT` and `CLONE_FREQ` columns that represent the count of clones for each V family and the frequencies within the given `SAMPLE` and `ISOTYPE` pair, respectively. ```{r, eval=TRUE, warning=FALSE} # Subset to IgM and IgG for plotting family <- filter(family, ISOTYPE %in% c("IgM", "IgG")) # Plot V family clonal usage by sample and isotype g3 <- ggplot(family, aes(x=GENE, y=CLONE_FREQ)) + theme_bw() + ggtitle("Clonal Usage") + theme(axis.text.x=element_text(angle=45, hjust=1, vjust=1)) + ylab("Percent of repertoire") + xlab("") + scale_y_continuous(labels=percent) + scale_color_brewer(palette="Set1") + geom_point(aes(color=SAMPLE), size=5, alpha=0.8) + facet_grid(. ~ ISOTYPE) plot(g3) ``` Instead of calculating abundance by sequence or clone count, abundance can be calculated using copy numbers for the individual sequences. This is accomplished by passing a copy number column to the `copy` argument (`copy="DUPCOUNT"`). Specifying both `clone` and `copy` arguments is not meaningful and will result in the `clone` argument being ignored. ```{r, eval=TRUE, warning=FALSE} # Calculate V family copy numbers by sample and isotype family <- countGenes(ExampleDb, gene="V_CALL", groups=c("SAMPLE", "ISOTYPE"), mode="family", copy="DUPCOUNT") head(family, n=4) ``` The output `data.frame` includes the `SEQ_COUNT` and `SEQ_FREQ` columns as previously defined, as well as the additional copy number columns `COPY_COUNT` and `COPY_FREQ` reflected the summed copy number (`DUPCOUNT`) for each sequence within the given `GENE`, `SAMPLE` and `ISOTYPE`. ```{r, eval=TRUE, warning=FALSE} # Subset to IgM and IgG for plotting family <- filter(family, ISOTYPE %in% c("IgM", "IgG")) # Plot V family copy abundance by sample and isotype g4 <- ggplot(family, aes(x=GENE, y=COPY_FREQ)) + theme_bw() + ggtitle("Copy Number") + theme(axis.text.x=element_text(angle=45, hjust=1, vjust=1)) + ylab("Percent of repertoire") + xlab("") + scale_y_continuous(labels=percent) + scale_color_brewer(palette="Set1") + geom_point(aes(color=SAMPLE), size=5, alpha=0.8) + facet_grid(. ~ ISOTYPE) plot(g4) ``` alakazam/inst/doc/AminoAcids-Vignette.Rmd0000644000176200001440000001712713402556374020034 0ustar liggesusers--- title: 'Alakazam: Amino acid physicochemical property analysis' author: "Susanna Marquez" date: '`r Sys.Date()`' output: pdf_document: dev: pdf fig_height: 4 fig_width: 7.5 highlight: pygments toc: yes md_document: fig_height: 4 fig_width: 7.5 preserve_yaml: no toc: yes html_document: fig_height: 4 fig_width: 7.5 highlight: pygments theme: readable toc: yes geometry: margin=1in fontsize: 11pt vignette: > %\VignetteEngine{knitr::rmarkdown} %\VignetteIndexEntry{Amino acid property analysis} %\usepackage[utf8]{inputenc} --- The `alakazam` package includes a set of function to analyze the physicochemical properties of Ig and TCR amino acid sequences. Of particular interest is the analysis of CDR3 properties, which this vignette will demonstate. However, the same process can be applied to other regions simply by altering the sequence data column used. Wu YC, et al. High-throughput immunoglobulin repertoire analysis distinguishes between human IgM memory and switched memory B-cell populations. Blood 116, 1070-8 (2010). Wu YC, et al. The relationship between CD27 negative and positive B cell populations in human peripheral blood. Front Immunol 2, 1-12 (2011). ## Example data A small example Change-O database, `ExampleDb`, is included in the `alakazam` package. ```{r, eval=TRUE, warning=FALSE, message=FALSE} # Load required packages library(alakazam) library(dplyr) # Subset example data data(ExampleDb) db <- ExampleDb[ExampleDb$SAMPLE == "+7d", ] ``` ## Calculate the properties of amino acid sequences Multiple amino acid physicochemical properties can be obtained with the function `aminoAcidProperties`. The available properties are: * `length`: total amino acid count * `gravy`: grand average of hydrophobicity * `bulkiness`: average bulkiness * `polarity`: average polarity * `aliphatic`: normalized aliphatic index * `charge`: normalized net charge * `acidic`: acidic side chain content * `basic`: basic side chain residue content * `aromatic`: aromatic side chain content This example demonstrates how to calculate all of the available amino acid properties from DNA sequences found in `JUNCTION` column of the Change-O file previously loaded. Translation of the DNA sequences to amino acid sequences is accomplished by specifying the `nt=TRUE` argument. To reduce the junction sequence to the CDR3 sequence we specify the argument `trim=TRUE` which will strip the first and last codon (the conserved residues) prior to analysis. The prefix `CDR3` is added to the output column names using the `label="CDR3"` argument. ```{r, eval=TRUE, warning=FALSE, fig.width=7.5, fig.height=6} db_props <- aminoAcidProperties(db, seq="JUNCTION", nt=TRUE, trim=TRUE, label="CDR3") # The full set of properties are calculated by default dplyr::select(db_props[1:3, ], starts_with("CDR3")) # Define a ggplot theme for all plots tmp_theme <- theme_bw() + theme(legend.position="bottom") # Generate plots for a four of the properties g1 <- ggplot(db_props, aes(x=ISOTYPE, y=CDR3_AA_LENGTH)) + tmp_theme + ggtitle("CDR3 length") + xlab("Isotype") + ylab("Amino acids") + scale_fill_manual(name="Isotype", values=IG_COLORS) + geom_boxplot(aes(fill=ISOTYPE)) g2 <- ggplot(db_props, aes(x=ISOTYPE, y=CDR3_AA_GRAVY)) + tmp_theme + ggtitle("CDR3 hydrophobicity") + xlab("Isotype") + ylab("GRAVY") + scale_fill_manual(name="Isotype", values=IG_COLORS) + geom_boxplot(aes(fill=ISOTYPE)) g3 <- ggplot(db_props, aes(x=ISOTYPE, y=CDR3_AA_BASIC)) + tmp_theme + ggtitle("CDR3 basic residues") + xlab("Isotype") + ylab("Basic residues") + scale_y_continuous(labels=scales::percent) + scale_fill_manual(name="Isotype", values=IG_COLORS) + geom_boxplot(aes(fill=ISOTYPE)) g4 <- ggplot(db_props, aes(x=ISOTYPE, y=CDR3_AA_ACIDIC)) + tmp_theme + ggtitle("CDR3 acidic residues") + xlab("Isotype") + ylab("Acidic residues") + scale_y_continuous(labels=scales::percent) + scale_fill_manual(name="Isotype", values=IG_COLORS) + geom_boxplot(aes(fill=ISOTYPE)) # Plot in a 2x2 grid gridPlot(g1, g2, g3, g4, ncol=2) ``` ### Obtaining properties individually A subset of the properties may be calculated using the `property` argument of `aminoAcidProperties`. For example, calculations may be restricted to only the grand average of hydrophobicity (`gravy`) index and normalized net charge (`charge`) by specifying `property=c("gravy", "charge")`. ```{r, eval=TRUE, warning=FALSE} db_props <- aminoAcidProperties(db, seq="JUNCTION", property=c("gravy", "charge"), nt=TRUE, trim=TRUE, label="CDR3") dplyr::select(db_props[1:3, ], starts_with("CDR3")) ``` ### Using user defined scales Each property has a default scale setting, but users may specify alternate scales if they wish. The following example shows how to import and use the Kidera et al, 1985 hydrophobicity scale and the Murrary et al, 2006 pK values from the `seqinr` package instead of the defaults for calculating the GRAVY index and net charge. ```{r, eval=TRUE, warning=FALSE, message=FALSE} # Load the relevant data objects from the seqinr package library(seqinr) data(aaindex) data(pK) h <- aaindex[["KIDA850101"]]$I p <- setNames(pK[["Murray"]], rownames(pK)) # Rename the hydrophobicity vector to use single-letter codes names(h) <- translateStrings(names(h), ABBREV_AA) db_props <- aminoAcidProperties(db, seq="JUNCTION", property=c("gravy", "charge"), nt=TRUE, trim=TRUE, label="CDR3", hydropathy=h, pK=p) dplyr::select(db_props[1:3, ], starts_with("CDR3")) ``` ### Getting vectors of individual properties The `aminoAcidProperties` function provides a convenient wrapper for calculating multiple properties at once from a data.frame. If a vector of a specific property is required this may be accomplished using one of the worker functions: * `gravy`: grand average of hydrophobicity * `bulk`: average bulkiness * `polar`: average polarity * `aliphatic`: aliphatic index * `charge`: net charge * `countPatterns`: counts the occurrence of patterns in amino acid sequences The input to each function must be vector of amino acid sequences. ```{r, eval=TRUE, warning=FALSE, message=FALSE} # Translate junction DNA sequences to amino acids and trim first and last codons cdr3 <- translateDNA(db$JUNCTION[1:3], trim=TRUE) # Grand average of hydrophobicity gravy(cdr3) # Average bulkiness bulk(cdr3) # Average polarity polar(cdr3) # Normalized aliphatic index aliphatic(cdr3) # Unnormalized aliphatic index aliphatic(cdr3, normalize=FALSE) # Normalized net charge charge(cdr3) # Unnormalized net charge charge(cdr3, normalize=FALSE) # Count of acidic amino acids # Takes a named list of regular expressions countPatterns(cdr3, c(ACIDIC="[DE]"), label="CDR3") ``` ## Default scales The following references were used for the default physicochemical scales: * Aliphatic index: Ikai AJ. Thermostability and aliphatic index of globular proteins. J Biochem 88, 1895-1898 (1980). * Bulkiness scale: Zimmerman JM, Eliezer N, Simha R. The characterization of amino acid sequences in proteins by statistical methods. J Theor Biol 21, 170-201 (1968). * Hydrophobicity scale: Kyte J, Doolittle RF. A simple method for displaying the hydropathic character of a protein. J Mol Biol 157, 105-32 (1982). * pK values: \url{http://emboss.sourceforge.net/apps/cvs/emboss/apps/iep.html} * Polarity scale: Grantham R. Amino acid difference formula to help explain protein evolution. Science 185, 862-864 (1974). alakazam/inst/doc/Topology-Vignette.R0000644000176200001440000001243613513671741017315 0ustar liggesusers## ---- eval=TRUE, warning=FALSE, message=FALSE---------------------------- # Load required packages library(alakazam) library(igraph) library(dplyr) # Load example trees data(ExampleTrees) # Select one tree for example purposes graph <- ExampleTrees[[24]] # And add some annotation complexity to the tree V(graph)$SAMPLE[c(2, 7)] <- "-1h" V(graph)$ISOTYPE[c(2, 7)] <- "IgM" # Make a list of example trees excluding multi-isotype trees graph_list <- ExampleTrees[sapply(ExampleTrees, function(x) !any(grepl(",", V(x)$ISOTYPE)))] ## ---- eval=TRUE---------------------------------------------------------- # Set node colors V(graph)$color[V(graph)$SAMPLE == "-1h"] <- "seagreen" V(graph)$color[V(graph)$SAMPLE == "+7d"] <- "steelblue" V(graph)$color[V(graph)$name == "Germline"] <- "black" V(graph)$color[grepl("Inferred", V(graph)$name)] <- "white" # Set node labels V(graph)$label <- paste(V(graph)$SAMPLE, V(graph)$ISOTYPE, sep=", ") V(graph)$label[V(graph)$name == "Germline"] <- "" V(graph)$label[grepl("Inferred", V(graph)$name)] <- "" # Set node shapes V(graph)$shape <- "crectangle" V(graph)$shape[V(graph)$name == "Germline"] <- "circle" V(graph)$shape[grepl("Inferred", V(graph)$name)] <- "circle" # Set node sizes V(graph)$size <- 60 V(graph)$size[V(graph)$name == "Germline"] <- 30 V(graph)$size[grepl("Inferred", V(graph)$name)] <- 15 # Remove large default margins par(mar=c(0, 0, 0, 0) + 0.05) # Plot the example tree plot(graph, layout=layout_as_tree, vertex.frame.color="grey", vertex.label.color="black", edge.label.color="black", edge.arrow.mode=0) # Add legend legend("topleft", c("Germline", "Inferred", "-1h", "+7d"), fill=c("black", "white", "seagreen", "steelblue"), cex=0.75) ## ---- eval=TRUE---------------------------------------------------------- # Consider all nodes getPathLengths(graph, root="Germline") ## ---- eval=TRUE---------------------------------------------------------- # Exclude nodes without an isotype annotation from step count getPathLengths(graph, root="Germline", field="ISOTYPE", exclude=NA) ## ---- eval=TRUE---------------------------------------------------------- # Summarize tree df <- summarizeSubtrees(graph, fields=c("SAMPLE", "ISOTYPE"), root="Germline") print(df[1:4]) print(df[c(1, 5:8)]) print(df[c(1, 9:12)]) ## ---- eval=TRUE---------------------------------------------------------- # Set sample colors sample_colors <- c("-1h"="seagreen", "+7d"="steelblue") # Box plots of node outdegree by sample p1 <- plotSubtrees(graph_list, "SAMPLE", "outdegree", colors=sample_colors, main_title="Node outdegree", legend_title="Time", style="box", silent=TRUE) # Box plots of subtree size by sample p2 <- plotSubtrees(graph_list, "SAMPLE", "size", colors=sample_colors, main_title="Subtree size", legend_title="Time", style="box", silent=TRUE) # Violin plots of subtree path length by isotype p3 <- plotSubtrees(graph_list, "ISOTYPE", "pathlength", colors=IG_COLORS, main_title="Subtree path length", legend_title="Isotype", style="violin", silent=TRUE) # Violin plots of subtree depth by isotype p4 <- plotSubtrees(graph_list, "ISOTYPE", "depth", colors=IG_COLORS, main_title="Subtree depth", legend_title="Isotype", style="violin", silent=TRUE) # Plot in a 2x2 grid gridPlot(p1, p2, p3, p4, ncol=2) ## ---- eval=TRUE---------------------------------------------------------- # Count direct edges between isotypes tableEdges(graph, "ISOTYPE") ## ---- eval=TRUE---------------------------------------------------------- # Direct edges excluding germline and inferred nodes tableEdges(graph, "ISOTYPE", exclude=c("Germline", NA)) ## ---- eval=TRUE---------------------------------------------------------- # Count indirect edges walking through germline and inferred nodes tableEdges(graph, "ISOTYPE", indirect=TRUE, exclude=c("Germline", NA)) ## ---- eval=TRUE---------------------------------------------------------- # Test isotype relationships edge_test <- testEdges(graph_list, "ISOTYPE", nperm=20) # Print p-value table print(edge_test) # Plot null distributions for each annotation pair plotEdgeTest(edge_test, color="steelblue", main_title="Isotype Edges", style="hist") ## ---- eval=TRUE---------------------------------------------------------- # Use unweighted path length and do not exclude any nodes mrca_df <- getMRCA(graph, path="steps", root="Germline") # Print subset of the annotation data.frame print(mrca_df[c("NAME", "SAMPLE", "ISOTYPE", "STEPS", "DISTANCE")]) ## ---- eval=TRUE---------------------------------------------------------- # Exclude nodes without an isotype annotation and use weighted path length mrca_df <- getMRCA(graph, path="distance", root="Germline", field="ISOTYPE", exclude=NA) # Print excluding sequence, label, color, shape and size annotations print(mrca_df[c("NAME", "SAMPLE", "ISOTYPE", "STEPS", "DISTANCE")]) ## ---- eval=TRUE---------------------------------------------------------- # Test isotype MRCA annotations mrca_test <- testMRCA(graph_list, "ISOTYPE", nperm=20) # Print p-value table print(mrca_test) # Plot null distributions for each annotation plotMRCATest(mrca_test, color="steelblue", main_title="Isotype MRCA", style="hist") alakazam/inst/doc/Diversity-Vignette.R0000644000176200001440000000640713513671716017466 0ustar liggesusers## ---- eval=TRUE, warning=FALSE, message=FALSE---------------------------- # Load required packages library(alakazam) # Load example data data(ExampleDb) ## ---- eval=TRUE, warning=FALSE------------------------------------------- # Partitions the data based on the SAMPLE column clones <- countClones(ExampleDb, group="SAMPLE") head(clones, 5) ## ---- eval=TRUE, warning=FALSE------------------------------------------- # Partitions the data based on both the SAMPLE and ISOTYPE columns # Weights the clone sizes by the DUPCOUNT column clones <- countClones(ExampleDb, group=c("SAMPLE", "ISOTYPE"), copy="DUPCOUNT") head(clones, 5) ## ---- eval=TRUE, results='hide', warning=FALSE, fig.width=6, fig.height=4---- # Partitions the data on the SAMPLE column # Calculates a 95% confidence interval via 200 bootstrap realizations curve <- estimateAbundance(ExampleDb, group="SAMPLE", ci=0.95, nboot=200) ## ---- eval=TRUE, warning=FALSE, fig.width=6, fig.height=4---------------- # Plots a rank abundance curve of the relative clonal abundances sample_colors <- c("-1h"="seagreen", "+7d"="steelblue") plot(curve, colors = sample_colors, legend_title="Sample") ## ---- eval=TRUE, results='hide'------------------------------------------ # Compare diversity curve across values in the "SAMPLE" column # q ranges from 0 (min_q=0) to 4 (max_q=4) in 0.05 incriments (step_q=0.05) # A 95% confidence interval will be calculated (ci=0.95) # 200 resampling realizations are performed (nboot=200) sample_curve <- alphaDiversity(ExampleDb, group="SAMPLE", min_q=0, max_q=4, step_q=0.1, ci=0.95, nboot=200) # Compare diversity curve across values in the "ISOTYPE" column # Analyse is restricted to ISOTYPE values with at least 30 sequences by min_n=30 # Excluded groups are indicated by a warning message isotype_curve <- alphaDiversity(ExampleDb, group="ISOTYPE", min_q=0, max_q=4, step_q=0.1, ci=0.95, nboot=200) ## ---- eval=TRUE, fig.width=6, fig.height=4------------------------------- # Plot a log-log (log_q=TRUE, log_d=TRUE) plot of sample diversity # Indicate number of sequences resampled from each group in the title sample_main <- paste0("Sample diversity") sample_colors <- c("-1h"="seagreen", "+7d"="steelblue") plot(sample_curve, colors=sample_colors, main_title=sample_main, legend_title="Sample") # Plot isotype diversity using default set of Ig isotype colors isotype_main <- paste0("Isotype diversity") plot(isotype_curve, colors=IG_COLORS, main_title=isotype_main, legend_title="Isotype") ## ---- eval=TRUE, fig.width=6, fig.height=3------------------------------- # Test diversity at q=0, q=1 and q=2 (equivalent to species richness, Shannon entropy, # Simpson's index) across values in the "SAMPLE" column # 200 bootstrap realizations are performed (nboot=200) isotype_test <- alphaDiversity(ExampleDb, group="ISOTYPE", min_q=0, max_q=2, step_q=1, nboot=200) # Print P-value table print(isotype_test) # Plot results at q=0 and q=2 # Plot the mean and standard deviations at q=0 and q=2 plot(isotype_test, 0, colors=IG_COLORS, main_title=isotype_main, legend_title="Isotype") plot(isotype_test, 2, colors=IG_COLORS, main_title=isotype_main, legend_title="Isotype") alakazam/inst/doc/Lineage-Vignette.Rmd0000644000176200001440000002030713512442156017355 0ustar liggesusers--- title: 'Alakazam: Reconstruction of Ig lineage trees' author: "Jason Anthony Vander Heiden" date: '`r Sys.Date()`' output: pdf_document: dev: pdf fig_height: 4 fig_width: 7.5 highlight: pygments toc: yes html_document: fig_height: 4 fig_width: 7.5 highlight: pygments theme: readable toc: yes md_document: fig_height: 4 fig_width: 7.5 preserve_yaml: no toc: yes geometry: margin=1in fontsize: 11pt vignette: > %\VignetteEngine{knitr::rmarkdown} %\VignetteIndexEntry{Lineage reconstruction} %\usepackage[utf8]{inputenc} --- Reconstruction of an Ig lineage requires the following steps: 1. Load a Change-O tab-delimited database file and select a clone 2. Preprocess the clone to remove gap characters and duplicate sequences 3. Run PHYLIP, parse the output, and modify the tree topology ## Example data A small example Change-O database, `ExampleDb`, is included in the `alakazam` package. Lineage reconstruction requires the following fields (columns) to be present in the Change-O file: * `SEQUENCE_ID` * `SEQUENCE_IMGT` * `CLONE` * `GERMLINE_IMGT_D_MASK` * `V_CALL` * `J_CALL` * `JUNCTION_LENGTH` ```{r, eval=TRUE, warning=FALSE, message=FALSE} # Load required packages library(alakazam) library(igraph) library(dplyr) # Select clone from example database data(ExampleDb) sub_db <- subset(ExampleDb, CLONE == 3138) ``` ## Preprocess a clone Before a lineage can be constructed the sequences must first be cleaned of gap (-, .) characters added by IMGT, duplicate sequences must be removed, and annotations must be combined for each cluster of duplicate sequences. Optionally, "ragged" ends of sequences, such as may occur from primer template switching, may also be cleaned by masking mismatched positions and the leading and trailing ends of each sequence. The function `makeChangeoClone` is a wrapper function which combines these steps and returns a `ChangeoClone` object which may then be passed into the lineage reconstruction function. Two arguments to `makeChangeoClone` control which annotations are retained following duplicate removal. Unique values appearing within columns given by the `text_fields` arguments will be concatenated into a single string delimited by a "," character. Values appearing within columns given by the `num_fields` arguments will be summed. ```{r, eval=TRUE} # This example data set does not have ragged ends # Preprocess clone without ragged end masking (default) clone <- makeChangeoClone(sub_db, text_fields=c("SAMPLE", "ISOTYPE"), num_fields="DUPCOUNT") # Show combined annotations clone@data[, c("SAMPLE", "ISOTYPE", "DUPCOUNT")] ``` ## Run PHYLIP Lineage construction uses the `dnapars` (maximum parsimony) application of the PHYLIP package. The function `buildPhylipLineage` performs a number of steps to execute `dnapars`, parse its output, and modify the tree topology to meet the criteria of an Ig lineage. This function takes as input a `ChangeoClone` object output by `makeChangeoClone` and returns an igraph `graph` object. The igraph `graph` object will contain clone annotations as graph attributes, sequence annotations as vertex attributes, and mutations along edges as edge attributes. The system call to `dnapars` requires a temporary folder to store input and output. This is created in the system temporary location (according to `base::tempfile`), and is not deleted by default (only because automatically deleting files is somewhat rude). In most cases, you will want to set `rm_temp=TRUE` to delete this folder. ```{r, eval=FALSE} # Run PHYLIP and parse output dnapars_exec <- "~/apps/phylip-3.69/dnapars" graph <- buildPhylipLineage(clone, dnapars_exec, rm_temp=TRUE) ``` ```{r, echo=FALSE, warning=FALSE, message=FALSE} # Load data insted of running phylip # Clone 3138 is at index 23 graph <- ExampleTrees[[23]] ``` ```{r, eval=TRUE, warning=FALSE, message=FALSE} # The graph has shared annotations for the clone data.frame(CLONE=graph$clone, JUNCTION_LENGTH=graph$junc_len, V_GENE=graph$v_gene, J_GENE=graph$j_gene) # The vertices have sequence specific annotations data.frame(SEQUENCE_ID=V(graph)$name, ISOTYPE=V(graph)$ISOTYPE, DUPCOUNT=V(graph)$DUPCOUNT) ``` ## Plotting of the lineage tree Plotting of a lineage tree may be done using the built-in functions of the igraph package. The default edge and vertex labels are edge weights and sequence identifiers, respectively. ```{r, eval=TRUE} # Plot graph with defaults plot(graph) ``` The default layout and attributes are not very pretty. We can modify the graphical parameter in the usual igraph ways. A tree layout can be built using the `layout_as_tree` layout with assignment of the root position to the germline sequence, which is named "Germline" in the object returned by `buildPhylipLineage`. ```{r, eval=TRUE} # Modify graph and plot attributes V(graph)$color <- "steelblue" V(graph)$color[V(graph)$name == "Germline"] <- "black" V(graph)$color[grepl("Inferred", V(graph)$name)] <- "white" V(graph)$label <- V(graph)$ISOTYPE E(graph)$label <- "" # Remove large default margins par(mar=c(0, 0, 0, 0) + 0.1) # Plot graph plot(graph, layout=layout_as_tree, edge.arrow.mode=0, vertex.frame.color="black", vertex.label.color="black", vertex.size=40) # Add legend legend("topleft", c("Germline", "Inferred", "Sample"), fill=c("black", "white", "steelblue"), cex=0.75) ``` Which is much better. ## Batch processing lineage trees Multiple lineage trees may be generated at once, by splitting the Change-O data.frame on the clone column. ```{r, eval=TRUE, warning=FALSE, results="hide"} # Preprocess clones clones <- ExampleDb %>% group_by(CLONE) %>% do(CHANGEO=makeChangeoClone(., text_fields=c("SAMPLE", "ISOTYPE"), num_fields="DUPCOUNT")) ``` ```{r, eval=FALSE} # Build lineages dnapars_exec <- "~/apps/phylip-3.69/dnapars" graphs <- lapply(clones$CHANGEO, buildPhylipLineage, dnapars_exec=dnapars_exec, rm_temp=TRUE) ``` ```{r, echo=FALSE, warning=FALSE, message=FALSE} # Load data insted of running phylip graphs <- ExampleTrees ``` ```{r, eval=TRUE} # Note, clones with only a single sequence will not be processed. # A warning will be generated and NULL will be returned by buildPhylipLineage # These entries may be removed for clarity graphs[sapply(graphs, is.null)] <- NULL # The set of tree may then be subset by node count for further # analysis, if desired. graphs <- graphs[sapply(graphs, vcount) >= 5] ``` ## Converting between graph, phylo, and newick formats While much of analysis in `alakazam` focuses on using `igraph` `graph` objects, R `phylo` objects are capable of being used by a rich set of phylogenetic analysis tools in R. Further, stand-alone phylogenetics programs typically import and export trees in Newick format. To convert to trees in `graph` format to `phylo` format, use `graphToPhylo`. These objects can now be used by functions detailed in other R phylogenetics packages such as `ape`. To export lineage trees as a Newick file, use the `write.tree` function provided in `ape`. ```{r, eval=TRUE, show=FALSE} # Modify graph and plot attributes V(graph)$color <- categorical_pal(8)[1] V(graph)$label <- V(graph)$name E(graph)$label <- E(graph)$weight ``` ```{r, eval=TRUE, warning=FALSE, message=FALSE} ##plot lineage tree using igraph plot(graph, layout=layout_as_tree) # convert to phylo phylo <- graphToPhylo(graph) #plot using ape plot(phylo, show.node.label=TRUE) #write tree file in Newick format ape::write.tree(phylo, file="example.tree") ``` To import lineage trees as `phylo` objects from Newick files, use the `read.tree` function provided in the `ape` package. To convert this `phylo` object to a `graph` object, use the `phyloToGraph` function with the germline sequence ID specified using the `germline` option. Note that while some of the nodes in more complex trees may rotate during this process, their topological relationships will remain the same. ```{r, eval=TRUE} #read in tree as phylo object phylo_r <- ape::read.tree("example.tree") #convert to graph object graph_r <- phyloToGraph(phylo_r, germline="Germline") #plot converted form using igraph - it's the same as before plot(graph_r,layout=layout_as_tree) ``` alakazam/inst/doc/GeneUsage-Vignette.R0000644000176200001440000000660113513671722017340 0ustar liggesusers## ---- eval=TRUE, warning=FALSE, message=FALSE---------------------------- # Load required packages library(alakazam) library(dplyr) library(scales) # Subset example data data(ExampleDb) ## ---- eval=TRUE, warning=FALSE------------------------------------------- # Quantify usage at the gene level gene <- countGenes(ExampleDb, gene="V_CALL", groups="SAMPLE", mode="gene") head(gene, n=4) ## ---- eval=TRUE, warning=FALSE------------------------------------------- # Assign sorted levels and subset to IGHV1 ighv1 <- gene %>% mutate(GENE=factor(GENE, levels=sortGenes(unique(GENE), method="name"))) %>% filter(getFamily(GENE) == "IGHV1") # Plot V gene usage in the IGHV1 family by sample g1 <- ggplot(ighv1, aes(x=GENE, y=SEQ_FREQ)) + theme_bw() + ggtitle("IGHV1 Usage") + theme(axis.text.x=element_text(angle=45, hjust=1, vjust=1)) + ylab("Percent of repertoire") + xlab("") + scale_y_continuous(labels=percent) + scale_color_brewer(palette="Set1") + geom_point(aes(color=SAMPLE), size=5, alpha=0.8) plot(g1) ## ---- eval=TRUE, warning=FALSE------------------------------------------- # Quantify V family usage by sample family <- countGenes(ExampleDb, gene="V_CALL", groups="SAMPLE", mode="family") # Plot V family usage by sample g2 <- ggplot(family, aes(x=GENE, y=SEQ_FREQ)) + theme_bw() + ggtitle("Family Usage") + theme(axis.text.x=element_text(angle=45, hjust=1, vjust=1)) + ylab("Percent of repertoire") + xlab("") + scale_y_continuous(labels=percent) + scale_color_brewer(palette="Set1") + geom_point(aes(color=SAMPLE), size=5, alpha=0.8) plot(g2) ## ---- eval=TRUE, warning=FALSE------------------------------------------- # Quantify V family clonal usage by sample and isotype family <- countGenes(ExampleDb, gene="V_CALL", groups=c("SAMPLE", "ISOTYPE"), clone="CLONE", mode="family") head(family, n=4) ## ---- eval=TRUE, warning=FALSE------------------------------------------- # Subset to IgM and IgG for plotting family <- filter(family, ISOTYPE %in% c("IgM", "IgG")) # Plot V family clonal usage by sample and isotype g3 <- ggplot(family, aes(x=GENE, y=CLONE_FREQ)) + theme_bw() + ggtitle("Clonal Usage") + theme(axis.text.x=element_text(angle=45, hjust=1, vjust=1)) + ylab("Percent of repertoire") + xlab("") + scale_y_continuous(labels=percent) + scale_color_brewer(palette="Set1") + geom_point(aes(color=SAMPLE), size=5, alpha=0.8) + facet_grid(. ~ ISOTYPE) plot(g3) ## ---- eval=TRUE, warning=FALSE------------------------------------------- # Calculate V family copy numbers by sample and isotype family <- countGenes(ExampleDb, gene="V_CALL", groups=c("SAMPLE", "ISOTYPE"), mode="family", copy="DUPCOUNT") head(family, n=4) ## ---- eval=TRUE, warning=FALSE------------------------------------------- # Subset to IgM and IgG for plotting family <- filter(family, ISOTYPE %in% c("IgM", "IgG")) # Plot V family copy abundance by sample and isotype g4 <- ggplot(family, aes(x=GENE, y=COPY_FREQ)) + theme_bw() + ggtitle("Copy Number") + theme(axis.text.x=element_text(angle=45, hjust=1, vjust=1)) + ylab("Percent of repertoire") + xlab("") + scale_y_continuous(labels=percent) + scale_color_brewer(palette="Set1") + geom_point(aes(color=SAMPLE), size=5, alpha=0.8) + facet_grid(. ~ ISOTYPE) plot(g4) alakazam/inst/CITATION0000644000176200001440000000411013402556374014152 0ustar liggesusersbibentry(bibtype = "Article", style = "citation", header = "To cite the alakazam package in publications, please use:", title = "Change-O: a toolkit for analyzing large-scale B cell immunoglobulin repertoire sequencing data.", author = c(person("Namita T.", "Gupta"), person("Jason A.", "Vander Heiden"), person("Mohamed", "Uduman"), person("Daniel", "Gadala-Maria"), person("Gur", "Yaari"), person("Steven H.", "Kleinstein")), year = 2015, journal = "Bioinformatics", pages = "1-3", doi = "10.1093/bioinformatics/btv359") bibentry(bibtype = "Article", style = "citation", header = "To cite the Ig-specific lineage reconstruction and diversity methods, please use:", title = "B cells populating the multiple sclerosis brain mature in the draining cervical lymph nodes.", author = c(person("Joel N. H.", "Stern"), person("Gur", "Yaari"), person("Jason A.", "Vander Heiden"), person("George", "Church"), person("William F.", "Donahue"), person("Rogier Q.", "Hintzen"), person("Anita J.", "Huttner"), person("Jon D.", "Laman"), person("Rashed M.", "Nagra"), person("Alyssa", "Nylander"), person("David", "Pitt"), person("Sriram", "Ramanan"), person("Bilal A.", "Siddiqui"), person("Francois", "Vigneault"), person("Steven H.", "Kleinstein"), person("David A.", "Hafler"), person("Kevin C.", "O'Connor")), year = 2014, journal = "Science Translational Medicine", number = 248, volume = 6, pages = "248ra107", doi = "10.1126/scitranslmed.3008879")