# IceCream distributed compiling support # # Stages directories with symlinks from gcc/g++ to icecc, for both # native and cross compilers. Depending on each configure or compile, # the directories are added at the head of the PATH list and ICECC_CXX # and ICEC_CC are set. # # For the cross compiler, creates a tar.gz of our toolchain and sets # ICECC_VERSION accordingly. # #The class now handles all 3 different compile 'stages' (i.e native ,cross-kernel and target) creating the #necessary enviroment tar.gz file to be used by the remote machines. #It also supports meta-toolchain generation # #If ICECC_PATH is not set in local.conf then the class will try to locate it using 'which' #but nothing is sure ;) # #If ICECC_ENV_EXEC is set in local.conf should point to the icecc-create-env script provided by the user #or the default one provided by icecc-create-env.bb will be used #(NOTE that this is a modified version of the script need it and *not the one that comes with icecc* # #User can specify if specific packages or packages belonging to class should not use icecc to distribute #compile jobs to remote machines, but handled localy, by defining ICECC_USER_CLASS_BL and ICECC_PACKAGE_BL #with the appropriate values in local.conf ######################################################################################### #Error checking is kept to minimum so double check any parameters you pass to the class ########################################################################################### def icc_determine_gcc_version(gcc): """ Hack to determine the version of GCC 'i686-apple-darwin8-gcc-4.0.1 (GCC) 4.0.1 (Apple Computer, Inc. build 5363)' """ return os.popen("%s --version" % gcc ).readline().split()[2] def create_cross_env(bb,d): """ Create a tar.bz2 of the current toolchain """ # Constin native-native compilation no environment needed if # host prefix is empty (let us duplicate the query for ease) prefix = bb.data.expand('${HOST_PREFIX}', d) if len(prefix) == 0: return "" import tarfile, socket, time prefix = bb.data.expand('${HOST_PREFIX}' , d) ice_dir = bb.data.expand("${STAGING_DIR_NATIVE}${prefix_native}") distro = bb.data.expand('${DISTRO}', d) target_sys = bb.data.expand('${TARGET_SYS}', d) target_prefix = bb.data.expand('${TARGET_PREFIX}', d) float = bb.data.getVar('TARGET_FPU', d) or "hard" name = socket.gethostname() # Stupid check to determine if we have built a libc and a cross # compiler. try: os.stat(os.path.join(ice_dir, target_sys, 'lib', 'libc.so')) os.stat(os.path.join(ice_dir, target_sys, 'bin', 'g++')) except: # no cross compiler built yet return "" VERSION = icc_determine_gcc_version( os.path.join(ice_dir,target_sys,"bin","g++") ) cross_name = prefix + distro + "-" + target_sys + "-" + float + "-" + VERSION + "-" + name tar_file = os.path.join(ice_dir, 'ice', cross_name + '.tar.gz') try: os.stat(tar_file) # tar file already exists return tar_file except: try: os.makedirs(os.path.join(ice_dir,'ice')) except: # directory already exists, continue pass #check if user has specified a specific icecc-create-env script #if not use the OE provided one cr_env_script = bb.data.getVar('ICECC_ENV_EXEC', d) or bb.data.expand('${STAGING_DIR}', d)+"/ice/icecc-create-env" #call the modified create-env script result=os.popen("%s %s %s %s %s %s" %(cr_env_script, "--silent", os.path.join(ice_dir,target_sys,'bin','gcc'), os.path.join(ice_dir,target_sys,'bin','g++'), os.path.join(ice_dir,target_sys,'bin','as'), os.path.join(ice_dir,"ice",cross_name) ) ) return tar_file def create_native_env(bb,d): import tarfile, socket, time ice_dir = bb.data.expand("${STAGING_DIR_NATIVE}${prefix_native}") prefix = bb.data.expand('${HOST_PREFIX}' , d) distro = bb.data.expand('${DISTRO}', d) target_sys = bb.data.expand('${TARGET_SYS}', d) target_prefix = bb.data.expand('${TARGET_PREFIX}', d) float = bb.data.getVar('TARGET_FPU', d) or "hard" name = socket.gethostname() archive_name = "local-host-env" + "-" + name tar_file = os.path.join(ice_dir, 'ice', archive_name + '.tar.gz') try: os.stat(tar_file) # tar file already exists return tar_file except: try: #os.makedirs(os.path.join(ice_dir)) os.makedirs(os.path.join(ice_dir,'ice')) except: # directory already exists, continue pass #check if user has specified a specific icecc-create-env script #if not use the OE provided one cr_env_script = bb.data.getVar('ICECC_ENV_EXEC', d) or bb.data.expand('${STAGING_DIR}', d)+"/ice/icecc-create-env" result=os.popen("%s %s %s %s %s %s" %(cr_env_script, "--silent", os.popen("%s gcc" % "which").read()[:-1], os.popen("%s g++" % "which").read()[:-1], os.popen("%s as" % "which").read()[:-1], os.path.join(ice_dir,"ice",archive_name) ) ) return tar_file def create_cross_kernel_env(bb,d): import tarfile, socket, time ice_dir = bb.data.expand("${STAGING_DIR_NATIVE}${prefix_native}") prefix = bb.data.expand('${HOST_PREFIX}' , d) distro = bb.data.expand('${DISTRO}', d) target_sys = bb.data.expand('${TARGET_SYS}', d) target_prefix = bb.data.expand('${TARGET_PREFIX}', d) float = bb.data.getVar('TARGET_FPU', d) or "hard" name = socket.gethostname() kernel_cc = bb.data.expand('${KERNEL_CC}', d) kernel_cc = kernel_cc[:-1] # Stupid check to determine if we have built a libc and a cross # compiler. try: os.stat(os.path.join(ice_dir, 'bin', kernel_cc)) except: # no cross compiler built yet return "" VERSION = icc_determine_gcc_version( os.path.join(ice_dir,"bin",kernel_cc) ) cross_name = prefix + distro + "-" + target_sys + "-" + float + "-" + VERSION + "-" + name tar_file = os.path.join(ice_dir, 'ice', cross_name + '.tar.gz') try: os.stat(tar_file) # tar file already exists return tar_file except: try: os.makedirs(os.path.join(ice_dir,'ice')) except: # directory already exists, continue pass #check if user has specified a specific icecc-create-env script #if not use the OE provided one cr_env_script = bb.data.getVar('ICECC_ENV_EXEC', d) or bb.data.expand('${STAGING_DIR}', d)+"/ice/icecc-create-env" result=os.popen("%s %s %s %s %s %s" %(cr_env_script, "--silent", os.path.join(ice_dir,'bin',kernel_cc), os.path.join(ice_dir,target_sys,'bin','g++'), os.path.join(ice_dir,target_sys,'bin','as'), os.path.join(ice_dir,"ice",cross_name) ) ) return tar_file def create_env(bb,d): #return create_cross_kernel_env(bb,d) if bb.data.inherits_class("native", d): return create_native_env(bb,d) elif bb.data.inherits_class("kernel", d): return create_cross_kernel_env(bb,d) elif bb.data.inherits_class("cross", d): return create_native_env(bb,d) elif bb.data.inherits_class("sdk", d): return create_native_env(bb,d) else: return create_cross_env(bb,d) def create_path(compilers, type, bb, d): """ Create Symlinks for the icecc in the staging directory """ staging = os.path.join(bb.data.expand('${STAGING_DIR}', d), "ice", type) #check if the icecc path is set by the user icecc = bb.data.getVar('ICECC_PATH', d) or os.popen("%s icecc" % "which").read()[:-1] # Create the dir if necessary try: os.stat(staging) except: os.makedirs(staging) for compiler in compilers: gcc_path = os.path.join(staging, compiler) try: os.stat(gcc_path) except: os.symlink(icecc, gcc_path) return staging + ":" def use_icc_version(bb,d): icecc_ver = "yes" system_class_blacklist = [ "none" ] for black in system_class_blacklist: if bb.data.inherits_class(black, d): icecc_ver = "no" user_class_blacklist = bb.data.getVar('ICECC_USER_CLASS_BL', d) or "none" user_class_blacklist = user_class_blacklist.split() for black in user_class_blacklist: if bb.data.inherits_class(black, d): icecc_ver = "no" return icecc_ver def icc_path(bb,d,compile): package_tmp = bb.data.expand('${PN}', d) #"system" package blacklist contains a list of packages that can not distribute compile tasks #for one reason or the other system_package_blacklist = [ "uclibc", "glibc-intermediate", "gcc", "qemu", "bind", "u-boot", "dhcp-forwarder", "enchant" ] for black in system_package_blacklist: if black in package_tmp: bb.data.setVar("PARALLEL_MAKE" , "", d) return "" #user defined exclusion list user_package_blacklist = bb.data.getVar('ICECC_USER_PACKAGE_BL', d) or "none" user_package_blacklist = user_package_blacklist.split() for black in user_package_blacklist: if black in package_tmp: bb.data.setVar("PARALLEL_MAKE" , "", d) return "" prefix = bb.data.expand('${HOST_PREFIX}', d) if compile and bb.data.inherits_class("cross", d): return create_path( ["gcc", "g++"], "native", bb, d) elif compile and bb.data.inherits_class("native", d): return create_path( ["gcc", "g++"], "native", bb, d) elif compile and bb.data.inherits_class("kernel", d): return create_path( [get_cross_kernel_ver(bb,d), "foo"], "cross-kernel", bb, d) elif not compile or len(prefix) == 0: return create_path( ["gcc", "g++"], "native", bb, d) else: return create_path( [prefix+"gcc", prefix+"g++"], "cross", bb, d) def icc_version(bb,d): return create_env(bb,d) def check_for_kernel(bb,d): if bb.data.inherits_class("kernel", d): return "yes" return "no" def get_cross_kernel_ver(bb,d): return bb.data.expand('${KERNEL_CC}', d).strip() or "gcc" # set the icecream environment variables do_configure_prepend() { export PATH=${@icc_path(bb,d,False)}$PATH export ICECC_CC="gcc" export ICECC_CXX="g++" } do_compile_prepend() { export PATH=${@icc_path(bb,d,True)}$PATH #check if we are building a kernel and select gcc-cross-kernel if [ "${@check_for_kernel(bb,d)}" = "yes" ]; then export ICECC_CC="${@get_cross_kernel_ver(bb,d)}" export ICECC_CXX="${HOST_PREFIX}g++" else export ICECC_CC="${HOST_PREFIX}gcc" export ICECC_CXX="${HOST_PREFIX}g++" fi if [ "${@use_icc_version(bb,d)}" = "yes" ]; then export ICECC_VERSION="${@icc_version(bb,d)}" else export ICECC_VERSION="NONE" fi } |P8>uZ4?ƍr( $'fXì4M^٪8FbwT/be܇KAF5qA;?@e$1/r5ݎŅ_EʹP_}/G} A2&#I__7:q##  UI1D.ejiM,rAƵmyxM#\W)'dͰ> O=;IҲݞ1>h.1dd!2m#{()% D~ GqI@T ;ZWJX1c"EX6z.SلYX̩O+-pyˀےjD@w/o:$f-uQrŽNqHoZ0wfxq{kY/4zH d?o(n-YE|j(>[WIyb.8`ǿUMPY{$kk[DXF1 ^.8!"+6L{I Sʆp&cc j ~XAceDbЋjѳ3 %g|A+Ըg>%_/g1}~nvr}RU:U/OWzu`h;FGʪ@([ǡ 4ǥ6h"e {cHQ9%zJ wn?z 1AF6˯uϏfSvZaSftjs!>8=>#8#8mTlf"ma!в=r48#cю76|.-@w(7B};( ǁ/(ǧt{?#bLMx9q}d3?xiep-qn`؟;'>;|VRQWT ѧn?KCϪfsO۷1}n@~0<(yo {%sLq8YvEqmi νr,þ ~O\ U}7w$#mJ29_%cۄwGt;><9oi.g^ 4tm$a-ʑB"GSDR}rBBE+Ofȑ6E߯6U_9G9MIFdNQɦ:GArժ ɠ\tLgO]~;$bks5c3Ȱ$ zF=F1n%I+ p?cJU|qg/ُCF^u9"~|z{)C^K * z@JZ+@p,ĒgzH}NMǻ~wyO@~xDs7v~4;ϴ?-ʕVeC\ڝi_"I+OQ^_IuO!fu5bOs7fc83wi5A7\A8+?{aMO~[$@~1 z4FAx~}z" Rn\%(%ǣ%v8X6Ӈ GD|JQ{8deuECTAIEEd^~|86GވB;bbk^6jĬ\J)diwr֥cc QPȊbduVY]s=U!.AUSvjN,!Q^IڦJUT@n_ Z|4zYѥ7z5cQ>4AH[]JQ/h ]#ñbRWCP2iS*/D{iҁ2P@z%JorqU"P;C$O(u*yJ@JQuDyQ捑R1%y޲=l߷D>rhsXI1QD_ayXd.4A5$~`zw:)gB60d$40K! _) OʖET{2YbqEdo@Z@zmlTS酿m^(d~i!(?/Ml,nNzIwW*5 {~oN +> ̛n0GP1o2r0><#iz93a?Ӭ@}v_]{C#D6 ͪ0~r&$JN7ƆÞDUE=x~RR4j8QWًQg0b7tv4y=&;P),A8NCzC8} "vLrz-G\CF966C@|!j)!+ڕ8;"ّOy*WɮזH}QlĢ>BjDR*r0Ok)Q(C)]̻m4Jᆁkq @ʆٍ7κh &e@|~/Qkd7”VjpÒ f"J̷Bvƍz ٣4T&fkJXo#:QR _I-L`9ڎm2@sDED%{pgčj`[&EC.`(SM)\è؟O4ۿCD;Vv_V0P( 䁄% TE4PS""R'q0 y (,ݰg_fT2}h,5a\2ҍHRB2=* Q@b 5WZPH¤ۢP{3{#p6fj湕1!M^l1z ؚ&ٶܾ.t4pe(xSd@8S\8g:L:M{M%0P!QRxr>|x}|3Sǫ`+⠂|ip?ap~6jd2J0TH jAb(a֞J&s+(2"gfʮگ8tvgIy^aCjMSLFE#4) CWFG#B*!$FH@Z\WvNrdWr_N0cO=BK&j*""ͥ:?*8/0ܫ߫{m9橣~V~ T@; Į=z汈_``oKf|ſ9A %WR>([rBP%_ݗF@qEOl.E>\"^4\!TXgHop ,?z *@aCܨ@d4X22vB1)C $a2BI9䣁PBQ$ iun;O~OQ>~u t@;.h@2 xpH~|kTRAgo 1k(QJjͰ<7XZ`2((F3!>:B@f PB$ B(w*ۀ_GCa ՉSd1.~lM^0%/8(a! a[ @iJF)_<$&g2nbB?,}?o?UUUUXxDD  XagC6k,ڣ0?U>MUvN)NDc/RzMTbv%kjƃ)ϕ/"j 6_#l \ﲓ|Ok]l\A(n<!S'/\Y[ G(U(ER{ldO WkrXœb˅A&q0X-2Ѵ ;Db6l_q2[9䠲i%XOh:ܜu\ &1s*#Aug~ X~{8οy?^'3O1u<7:z߻!=>j|8W m͎g"IY?7B=%O?NPH1H2;ԍ,SN}8!n#Ҋj Q=P8hP- fV@gLw5"6ץtv>f&̕5e(TfY43?I|n$D0 GϻgqZ[ab3ao1ɸ,ށ yH.!4ac(vN#PUmM~"C ]c8 mf@0D`@s Kv Yb-_%5S.$˭SSd DeD Xh^T!3X~=CZ2:Ll`ϞoLPϣA }Pֿu63ї_ V9)Lupa$!MFO g#Emr2(Ω7Ua㹟vB iĠ6*_1&B6nB%u&rB6)PE}22'tQ nvJ(m6bwcO25? &i0G8oG,rF3b 1#X4څ#bm4U 6PL[ D7q44iSp!!W!B.H$b5FZp@zOd@Yz/s;,@C`U|O Ѱi"rM}63Si B˅èFlk@ c(bC/t(#)( UC: Yw1 셕\UV+fsb^Sg=OĊ1dhLMΟ^y0 BA &=ո_2Hp5MB7ƺ04e#\!OXjkBneBk@q*A];LXz)8lCl*`ätIIJ22xEރ6T#r;vy`AzB1nxTl@MB{2GoKl"N+!٠4$+$M~/X} ~&s`Dj0Z-EeI* )|yBE8a$lĒI$ )28 Ȉ'b @Ex'cL5d&_!>|#PAhDOb#Zz93y4hu*^G6Ebn6>#mj ؘ0''` TD+6~)V"b0i7:yΟ;7@kWq!+m FR-MLI%^3Da?B?8fmXUM 8+f)-czFduB XN8C8HHhAij5ްj]ֻUsü|=385vX*I*IR (B!("%2)݉ϊXa@2)jք )@ " ))"he(&:Pq-VSK`uexV F2V)ćGkǽޙA=è/L_FLTXq}!v4#<| P3DIJgV߱^efǏٙFݶoyb呝WN9~d6HP ~E< XmŐv<-]D rpGёn\F0%]d ; !u.ğHfjV3U59<׼u57<b wUєN_!ײM&}IOT p\HP=>?g9CɩӦypK@oxkXvs_aq܇xgq7B9'bjj>J1 Q z 4]vo~"źpx:}3yHZ¿jY$ʟGN6 quEwqm!:5( k2fQߙﳰݝlsysa;ُ{=<5p[t[6\ p5?8(Lcsn [*IyPL5c]pp^YJ?)?C Y_y2\v\u<$fʏͣ,^Ī$gp{f@3osYaX:TYH&z0OCpHp?D {1P ~CB<[o ~LMo{K)1e \㚈``# |C&B|}6?>ʷ*i{ú-hp!T!"AJlh5ry,A`_۹?x %EDypO kĀ`@H$ <(nT|6vtP]U` $vdr-wm@mKAtp9 ӿi.3]tA `cϥI5Lpq`A9!zM1Tg04B= }V`v%;5P7¿!Y?Js{~8gBLlY}N3p@B >ÌL"J>j ޽!ݷs} >>t68ql綀ӄðaQ2o5^[ѧcfr i}*3¥BTӼw~w~.T 'OL:ϟwtBPf"OftF0} a?Fj}4Ubq)Jzu|YթtPWPn :W4z* @eu6 Οd{\3nEd[XzJц1Y>a\>G`h=D"j8f|f`NzU( Ӭ;p)V&8 [⻐s׊'?9h` @@x='2&!r o4sCQa_t_ +씗45=(]IYXiQuxC@sf6[=grlUVU`GJwv@l7'%>înh`*-KpقGe?Ux\/_OnkzsCgr|%5'#Ёx1n7"QFDSz^7<=, E`<8LW 1?BD1+p\AtX>zﯡ@<v+tQ؜OiUQ |cŌ2`DH@4w~@,}1O \8~1-woNG_=Lj zr=\_ HyK}:rzCcYu3%Y&ugsA;yx(znWïm 6 "HpJ17_Ƀpѕg6lC |zuc݊gȟ 'B#j ,cE4!@8~SIl1>Lwҳ`{."*`{c$Sd?98ZϺ×ʯpzшI7hwMwiTH:|W 㾳I E)0BP ,URL]w.Q  B?@G:B kN-˘ ϪU8|&GҖIST^1ո75`E-*?y '/zfAJJFD|HV9ћ湃!(`+_'yQۘ)umu{6 4w_$lymdnP)DYws_X{S9ksz oM_ȅ<+:Fݩ׮=f;Fm!^.HPN7e)AQB7OU'hw1<pza}~6YĀ< _A1PM$1xrx׈Os*UFr ?!jFyYVGoc/Uu3WFe'<@.!Y`6jTD aGy3bm>,hhM(hd_BnR7b#{Ü?uDS˓/e}IO7t#2 kCkѫV_^mzsTE|Qˍqi*2ʭ{Kݧ OqY0n"Ya6Y|(W V~N{즆8n;zpti,A2{Z*DDMjߢ=􅖊6c'J"j ›&-p|;b^E3dѫݿ2W[`[fm:+gFD'7sE}wN {4ӺWÖH ]5IQeOIgv TIYߴy<ݽ:uW!!K=[:dβ7{mXeuY+]:VVӖ 8>nQeT1er*8Ft4W"fofjq1مxۣZӳ;Q# 8lt4WXXY7-#^v6Uư.#grt׭p}r?ߣC &ZnA;3mXfw^e7+ tPZm/x Ma 4jkjfmz(UzӶC^Rz.m^hp|N1{BÅ|t{0(s>Z]#W+ylF:l.{; (}۔|<8Ofr!}5~it—|b 3-3NlFpF]ts}VlT5VRI! sSrIł ݥy*9 5t]e"N$t`|:5!f- @6 kˉd p^[\rV:!TRN sV>߳/f0?5AӗcP\.6^^u9$,ftn {"i6su|.u-Zz\1.L!߲apU ARxN*%X+G8hmڬ1r/r+cKn0m՛G1CM*Ubw*I8gz/p킷BѶQaj2].([ao|O<.2ʺ | }F6}h8v$r_o,/H=֓Kj3Xvs0[=Xez(Iw^q'⧁LyEp6[(Q͘w׎O0b$ y}7#2^jIC`#h_eTk9Lq=ERO_>GwG|F@b@ oC'ͧ J_R-~>eLM_+%_G!)) 2zO Lܤ5F#O+NUsx>$(c־:*0[(]DUPkiw9dFO7EZ7~o_ \-4H±r!CV3u6N_֑bCr^ K^TVr6eӓ2T0T_<@}az8$Qgq,CtY*&?]q87Gt!BRL@ }1TnM})%KK}`\B6$\6wÞ"p0HN~D׹@534!oWլb]6`c=U{%p-V]JaQ7m1-y D KM;v3m4ot31"+dWRܞf %4e}/Ͱ䭽Q &u8\܊j ġ K$J!kuCf_0饖 49. dTӒʸl%TL=x`ۻ5M.Y-kJ%h9@9w|߃<(E]!}נRSN?Kz>suo"a]Gy~[zj9#v$!Ekdp2ĄGUkyA.E,pb DUJ WW@-}u87Ize1S7:Bا1&*!u="iŠ(i)(l>,//_w_;$ KXnVE%QpbSoAGOʶ 0ZD؈M&gB ^ɸWo;9*`>f6b6沂ҕbC/|Qo+=C 7< ܐjIk O;P`9 /)VQ/ mDDjYji UJ7DW릌y?w;?P EQ_Y# twӾu]T}b 8h#pY D Tܜ9("h:F,_Wo?ݴSOU/ KRך(!^GD۵q꯯nT,?%Ǫ"$E]\K@:/M/^O|(}sLƫNS^tŅ3&z8a9dk#DRBrYRȢaNCكALI+֦ 7^?E6)RKC(inӮ=fH{a?iCԕPr ?9=?J %zU~UlT aNUh"ZT5h^?b8tD np{1+ "P !S.WeMǫCDHK~92w)lݫ5K @/ =7p{aoHkQTcGHmAoo:I"Nv۬N0WAi  pijFtp=Ǥ֚HRu/F.t_^P+[V3nVZdD΀~}ק=bcx*m]Hu}phM@:ӓ5y&A9Bn^NnQB %:jwZh;-F!D@@yiE>DN+y븠>t|@}ƫ{=5{m { W!d爵̉:K4i=BnNY *!D *"P`S Q!Ո۳Nڨ'?`GIEwz fù৛{>GaP/pjVP$2zBMd"2 E٪U w _O>U--~ޏ+G|pЭOGeY<7Lj]y8&m9S7)ԳwI xMI̡̾V2gI|;`u ӿ|"I$.5"F撔g>w3\V 8(R /g50;~-~u|$ ;qts iEᯎw nOu1W+B@1T9=0sբ)=VXr9&ԔɃ /4>0J%JoUurQl!ٽﺧYa==#UoZe͑s&|AEĪ peފ]*`"}"?>|;lQ^2#H^/8ÆpF'o1).FšF4&[m_`ߟIFMF]%%cnST@NBqm2Rn3׭NSI)ن`ז+EUtR p qх&sps98LD7o OX)K]!ܪwOpc`$c$@t UB8^-8ł z§B2:r<8[W(5iŅjZS2Ac` у&wf˶X]3$)lXO=R~=)abyײ4"[WI-!H )%ȅNx(݆ uet-J}$v2rl!Pkz3-`记,$*,sy}߁9=!-<jPAL/Qr¼cHnH ïgv:@sh/kyt-Nf DJt%qA("3FQӻI?T̬;lQd*&YBm> 4~{B;iKxK=hCn.SR!U%̑RTʎ55ͅx GRbTSzr&Q|d08B5!4B2' 7+1E9Czk*@AUs ,~x-e.ٲ2bM1,&|` V;-\Z:b U/>"9JW܂U ܸTjZl(Oh4AZ4{xUdc3>ⱷӣUHL9ZL>dxPFiU/ipQ.t|1ש㷷}UUDTI$$}=?-uXX >ˠz1ՄKL9. 6O|}f,HrnM[$.Ji:zpX.nNa' ,y1_uMzi%jOzІ*#noqjrdj-E*3-9-8|I"9bJgXXnh"AtF’z|i,tV]$K~y5QGnrp f]?xd؄h"eÈsJsAg)p2<> 'G]KCh[H#uDZGw{Ul Y_{?ZM$p9! $cQ瑧"'cȿEqUѨUH-դyS=R@%J\ G?Blq`kwr{Tlt lPEX't(Jz<(3 `i1Is*k@[Yb U&,QRjZm{ :k=78ݰI.BeVd0Mb~Zci`u&, 0~UQw;( eɖ: gV&AA# n[%;vvvHS ݛՁmV#mLQGNeCmyCmk'ͦU6ccgY a9o5K[I9NLq`DM,z/aO{1X_:<Es8+|}7_=| 2-UN+b/5ϯb=-z̀Ԏç (Įca}voTsےcHC%!uEFE@{&YHHNI 0 /Ur <XBK̻pH;ОTJJvҡծ\ $NuGz> \׻ΛO7Nok0ݜmPϙFi=v>=ܮt8kZIw!JJ5CC"~=#~TpsDUvUE_X}Tm+qZyurt%(% V&:LR SuaG8ޫ"*N uHA$gRM/ѡ]bMvCFo}M04чw!x-ŵ!"(-R0B~9m}[dͽB^qet%3!Ok&.Nߦ8U &fvMpWX}B3R'w[.(b>UtDCN 1~P: 4DyG@=~$Px>D6Hdʘ >A*^֭j,eo^-ߌmO5WVt(i]E##+u;= ózNgAǟKZt5-l|Doqt+e2z٢W{=&yqC+$#(P5}p%㒊uo(iF|w"N<Ga~7NoUa^[+ym~S5|y7ak DΣ'R) Koxl妠4J5x 7?Ļx@LBJmXb:܉پ!g΍w*Μs<vTh{B&\D3QפOw8&908@HBgMHo)!nCP !G}^4$n?" ͏K~JAPAVǻTY]YkTeS]]j Ђ@A=`ۻn6c:M! jS|6Q.@jnM>;?ͥP{lsxIlbJR.ńT+ Us٩rjoPUKlQ)+z.(%3^-B[謩 AaL@:s!#B$y;p^N ⬕9ߨl~h 2[4tQ9h0Ae "Q ]aݱ09I-G7 fjO;u/MP`³\Eue)^#\WfkR"pH2'2B%ۈݧp/'ѝ cEhLpy /lJLX4ڡ mQICoI"B«Bҹ*L_܄&vh ܣO+Z lzE0ImPh'`bs6|6yYAzʷ뇛B߱A @>+qF[~gwnX:F HB/\a(G<cS'[x_{$ P`T9*[XmA=1&T  CPӐQ>HsoZ#e:6 XOZon.rdpX5Ѹ69ˮv6mASjly^ Dzd +"6A1;oŅch-Ʊg P ^!HA]"55Djَ{ߏ@3(1ezT؏ᛢ\EWn*K7DvҎxV9ܹE1׉TD;K\ ɊWa~aX;k pܜ숩bm;t!B@r-2~] rdyᡪrmHZaD]kLq/b#jRwuw\a=8G_Y8W yaP~B'[#e8s?8F *ٽu5ȝF+ڳKټ@.VݒH{CedRiMњP??޺nW_eg{d7ujz:z"r0GZD!suonxL"I>^X k, J}nÃ>BWtCp=ZfrsK-6ٳV Pj ភƩrz?+tTujTݯ7sT_-;s OB;}Q y;>NMHQΉ,xywMVkL tkAQ:Y B/ /% #тXdNH[UsF{ZUS S"4,Wr7t4شnq"^& rp-q`PC..D(@/\`!ڜ-M()P.d~pe6ž.ڴKQCo59H<57D&Ģ jzCr" UVlꞓ:S"<9kU-3%J NP}Txat]^Z(U@ʢDKLu*>ٳ+PX1pe[vdV93ja-\PT݌/Z3NUܳ{ջ/Uk]hh'u܀=oϏfՁ'X4ݻ3"OA*Fn>np HW{ 6CmVje9y *ф9\N$_ O ?k!Kf"?8r5b?˻ "\:GJpӑvy}5b\*="}Ii7W]}ބ4KGz#ŠϛP:A.]$/:u^z!fFdIuhlӺ6ǛK3ϗQD $ķ E(li^C_Ƕℝ~'?D^ܘZXߺ!p/q<]ߤmp3)Ԫ&Š2"C°O#FW-Ȋ.EQ|mJ<Ԁ;g v!oQ_Ucv!7Aq$AU@$9is줙ija>$xdnMKêZ+GIQjhH #m{x @AakFh}4-8e3AP7Zi"WDhwJq׽~;2W`!K7I&>ؘFD:,3e~̷~Ox8ezpئ<Nw#UruG ܓQrO/KzG viasfci Ӝe rd8j>t44SRQ_ھ3jS:^s2\D\y#0jRZ +9BoY:ab2A}o~14i]Ǐ~=r; Dkz/diN&YiQZ8(Hr@Tx/qD>Hۛ}u̓>$UUUUUUUUUUUVz.UVYUu/VYj⬷nRJ~ ;:}xpaN#cRWtҝ :άP^1W9w7)5ms6A 8inC8YㅖpguIgJ11]Z" x1sLG9T1S5Al nVh'E;q@}M(H%BXlY:$esa rAd8 iJ- wP~w+eݓv \*Q* ʄ *"P[?;Ꙁɡs*2 ^Byi[0lrF#ޚ岀Q*nnDKAk^Pi-jm,~ϐ*Fۣʎӕ%&qAts0֢]G*vAr 4_UǙߓ {A4v7$ d#}()Ɍ$afcCU b```8`|'nB5 YRX35_bE> ضY.8=&=Df(`¨*ƌQ?^Uy3zٖm5i_!RV =#rs^E]=Sf_7x)H?>!Tm_ʱVSd(!kZXFW'w;Oy+wt9x҂F!aE>qH"Y-(QCjyL4\MQ aB.s~jvA2&6ÿaæ_D3j?D[r9ٜ:XeA^H2Fq'ӀA4(hm)34͉%Xua$_|z7' z1gϪ2wg = ܵ@A/PL}sÞϮR>0ǘ39^oT,ӎ!G5R:BHUJ/md ݡL m;Rrl](+xGac#xp7ksc=԰~gYA#/Q;)uz 3|w Mer'{?ٟPu2 8r-+`t?"Lu z->O:Z] f rƬ3hf=O X19rM_L7?'Ê[z璄JN1T`gz;OPV*AE*2R `;2|Ncmf̹9i!DZEVPgc9e-z^ÿy~O{E=}*WM"j>:$_<G9h%cI2+^~TPq0AnB2͇\D$<ϗ,/|'e FHy3ɞ۞_E@> hCDx:.Mۜ`߭P2`4np6zTl2дS+Mܴ8>p%$~\qCaNq=19gAO8A(Ш9Q$1)NuZ&^ZX1hfM[sB (Z ZbNRm\63Qi:@3 bRH>RٗpmprIK>b3&̞cRMmL2mM(uaDW!CcQ T!꠫Cson_]b\7]{p*SUr@drТF'﷗ I)mHHT`]T*,*!軍kNk)Cǐ쮀"jAd)^7} 7Kz B\jxHJQl`L<\c9$o$0.9 0 QlUc .zyR0jO9u gu "ZD}H^MfM /fQᾅzMSZǠP<طo|R@RQ+ cx ~)>6WVgX|jtn6{"Pw<zK ~Rߌs^ .vy]u@ (2tx@Ĩ I ^4 䯙RPua mch.-.QD+5%p.P䐦T\;n.O87mֽX=?t̋c"B(!D_v(D@ss% ꓁tPrX5pTHuJeyGg rzǥ`%7++sQԼjoK-y5߿o'Iü;r폕DԒWrwg8<ǝ[ 9w{le|HÆ;ƺGnms*czgYuyü 3#8>/`>MĒ8'G et[v眿U g0B0;V^ y#Sl3T1Q.8Ԩj~՞&b6"y^+fuΟ:uIkUS)g4E^_\ߚB8.F4ohoD[g7ȋ㦫{{tu;{C⳿?!eOQ߿wn/#Yl_pŴ]X:BmZ<^?$ra_I~ƂөW? [K LZ+ 6(b0K2WZ;U % mmtQ1.ՓF{H )ߚ۾1>*D(-$BI%SI*ڒz'1[D[%ys6 41V>} H%* hXLGͦ !LA E2F^(HЄ74ޕ8(h[(9z~h=dӁm]Tta enb#:0\-μ0<+z?X[ "\% -2wVV^ޮ~#XZaJO>uJgp~ڥENlZqb!R{{f#VicA-|aG.{w8RcTuMz>d]$aĒb R~x՟ػLSvu4*`IVWj/LfU毵(4Ԛ+1Q`~KlYdw%0#ύq2AtwQS2<;tvWhFRc >VwIIK$pFYmFd`,$S*DҺRTe4#xnNtw4RJ=f!iḪU:tXҾ#4Ke=NpZPc< w?*-}N(hdǴrvYٯr.`dr,_of zl7_ˉ{_PbF6]n4*옘?Ra~`UϚ!9lt9?eBT%$Sک0 ޤLAQ$5+d' G㽢Tpw9\AJDȒ1Pal\>DkM'*|15q 1#_dT@0iˣ ̥֍D8v+z8s'F}MRFXTbyŲnq)2UP% BRZEDe%];bܻky}7e}7'L*='; dt8U(ĩ/V 4̺2wqDox1\&XX CF.g1˒DOx Tlcb{W 0Ȁr-PMP N*f󚟨̓pj'Cx\爚6ʿ_7tJh9'>Hk{$M{ܛ(>[PScFIBN!-1$ċrDgq 2wk|^^I=_.Ez#*5ӳVh#ȁWMd#b:T*gFxCg]m:z3#D7Rue}p7W?VnVUZt0l{)F籒wTQNV#**Cuw '8a;e:]2M\zCy7>/;OcD[P\Ss꾮WV@tK-Hx7ueH-da Y{^M\gpj5 9uR)e|c+n ڏ Y ͤZnij0Y owѪ3krݸU%s|TmM%R3OX>6,:ֵ;仩 wKN_@{_"bYs(;hQJtùr[4Tp Pت+ wJqңE3" 3%)nk.($F;f6M]HxHAPQ Gjܜ߅[1C;@0nׯۣpE5q J51 >!9a MP)⣒qd5XeSgõQZudcYf]pTnpt!-^rBg}M(@r> ׬zw$SiZQ߄tDddI#)61]t{=P_f=~Xt@#eQE.(9zh 8 Q U.\̈&F%s;a JyL<X|Ev$I 5qpyF@YNpضoDS\^qׯhuAz&w?D(`2hØ}83fч>>b݂ #'e$>#|8vOMPu4EV/X9szwm^uaAy+\,1l5XuytqdB Vgs3 7c$ӭj5#1[DQI}zΞ8i.D\F{DNJ|ngkR;O1vSZ^jxUb!pTAwRsF_AIpHVx[h}MYczL]%p'R;/K>9op|   x옙:4_, >OB(xYEnRrr?TvFֽ^CUMl;V=>Pv)sяݿ@!"+3뽖TLӤ,.%Ϋ8,sm5[r9WB!HH_w"}z>d>Հ$ I(iXaj,-1_Pϣ? 4ța>*])|3|6kRr'7B1ʨ# Yμt{9nk{;$m=]u:#Q5x9yݮ|`*s9Bf NLz?=qD~cO-Asʆ(U~ů'aCU]x%&ôeitwÉoIԃ߯Gk:s7ϘnNxOU q.&#Ǚĺ4ig1|iM5EŒ$5={õ3Qe; 6yIQ[al+$Sdd6ଢ଼[F-grgVK@pm7 7e$%a5 e#QZ6Fm=%&phow\y8]L4|L/pw.8./N2"=@*#\Mu6N``[%h܆lG9aV[߆sL*iM="#-w>*g0Y8$wN7W3z+r*eNV֣m bUZ3y:)'44R<ζ+dj =Yc,Sp3CRj[ӆotե<pQV[m˦!+?dڈd eەZݾ}-cRDYm0."5fmՍKϗ\ۨtي 0r?4^s !L*oCۣK\!`a>EW2uq(LTUIFYA! FmCձvXM"ld" :RZg CDpPac?5{`PunrYM%wV  `2StB, lo᐀C-}}N!̢'w=mWL׼0H(qICKݤDhCԁ~5ی8}a7~ ߅A|ˆ?|) WQNy)| o6npȰAZx{BחѮ3!ԬC''碏Q~޷휰Ica/w<&Q'IMV*Q=_d}}P>S=`KЮԠN| s]]H $4F~ #8 s*l„P|z=T99\[S'5 jhgV#7w"0نy~? ?1Ҵ`o"vtd$C8ͅa.҇澋qj'?K{BFOE:6"E;}'wi^<ڳ_ܐ6=]8:jߕY]'rRXyU aP-K9/u+y: эH)G xe{O>e{\n */DjƸ ܚG ˫jZL(4lg BKB['oWڡb%VU ΚpR kNF?ǀ+qҜ xl.u"kV-ϓ='ؕcw27Ґ6Țʼnw]ݽ)Osm. f})wѠ90~hq̜H2 0($T %b <"Z&9l?=̀T"k :v^nfV?|bu5ן׳jD*b(FQD@jG"@Z 4F Ŗލ]b$KDO s!Qw8AD$ J.@AHL&dZȓ S$ bT" %J2] A u) 1p`IrQȬ3 %&BV !X( R &e"f2Y' V' AXQ7#>r& q!a9#LȸXy|*J=/eJ$r{,o7]wozl]@Xj3Fv} K/b.X*;@V\>>~v`['Өh9sr>5aP{J.?PlYJL#7: \'\Gb%l ?OJwPxղ{HO|E24ad)R HԾNb }I1jW2 E8^9{λ> eGy(p+@wvbWcؑJ3"ZB ʝb_wB?GVe]&Ƽ;+Yڅ9LH@slz" c3+t*P_L= 1ȋ\{2Rb 2v>|(V~_fFO7ɷqsC_~oC|ٿ}m^jvW].iiӫa\<=ßPO/uASkiߤ; 5'(TB%Υ#>pw/96΢Vp/ ̴Vdtzbi۶/X92'dRu0]i7.Az$8GT)bt}-^۩OîqEIJv?[n v';>^GYJ-CPz߇DK&HэOϼ)$_/w~IPRQӎp"_?t:Ɗ` $c0"qʛw g,J>G܉ nvˣ?M4 }$DHvd 0UEsAQMUO ͮu_|:f""K~F04шK@TE4 VH(*B$baF )HPZ $(hb*f(JA$)($$p~b~{`.!{*!8}7O9V Q Q_((Z}"Z!ؠo}jS`4tcz⦚) gk>{4%URa*0 Lޱ1 \NŇ&A$ ف"b"(,,*02Œ2.sDʑ06a1Fi5ɜHZ`a4PEsv)KrK s Ql!3$!-806H3SLEJCH\ "GLLC 25dİ2& za&Sz{ `2uZ"˨2oPU50c% 8K,p歺%u8Γ6Q"SNnu# Iڜ0GHq:yoMi:kR7k22 $08/I=L(5\w!Z)GL˔Dg/=mp;J8e}r@ΗMHcI1 0 G40&kQo]p`L24P3kPhu7V&,L pWm X;a!z?7<$zl;d%!?U/ эӸiJB$rp}vf$$^6 77 a'VdQVAs3w7и?WvjMf˅4'`L;c6ӑG4{g1+2ݑ'.dz*lKhQZRFvnZ_lXl%t4G@c]7plXΫ d/X[hP⪪!:N+mBlM$KЄuuKԌLOPM-k;Z8\?@C81)E(_Jty0wHH۱\pHa MBxmv$;G !"` @8 ؑKb@?Q\NaX SuW\ѭB\H!'(Όb&НB&V9p"Ny2NWIE,1ʔx*:BhƘh>hrS?Ѧ6eSTI#X=NiJNOdL BvD]E݈MQNc5MUu(17%KKj"6b'aļ]b u8 B!أ4 JEw.8j@n_23ΰ<2xʙ eM /DGNM.rG}%Z3aW8DoE4pI׆#GqɷPij+kYpl'KAma~ ='HWRա:9FX $VN)57o[ wVs./97bo@B6)(4*q&1 ])IhSa u7C~:Y]&`ȘѮ%7$F:=P)-'d4f$ {l1Lק z)V-0'}qVyq:g!( ٳ V Rʼn2#Vuφ*ppi>׿q+DI+~A>pvtI|m5DLw9q&&GTQ=ɏE44 Ƣ"<T^CƉ30eb&pZ3 >.'kIK]}yy~ob]R=4ђdqI~L֙%{K19^2QRsːBkxq(91y3Io2O_4fsi~t.*Eg(M"uM ŎH6ǷF(ЉQ j&Ϧ6mpX\xhP8w2[S&2XH3 3 `T^L; M^X38f73^Ѥ/ "&o4E@E_b܂} _نF%##w!VC_~NglZ"T7[mG?Fmӳ8PGQV mWh`m"[qAPT1!1s僌'\8]% 0ˇu|Z~s"dz܂iqںj/UP~[ڇ4:9,c17ps( =X9P|y߅S!Պ A)H @kX[퇸XAȖ5?6~P6>\. e8A(XX̓Ia E 7pG0/3W/E!DA!ˣǛ8=<ߏ6*D87~_H|v q{_HpRIuHoO !^p8I)␓O]n.Ri6_ "eI5BQvI jHh-8Z9I -mUok>?Mc+?巗8UgeEN@ہImw˱J=o9U=t倂@WP~ Պ {j{=;+w1Ҹwyk%k]<ѳmPS|3Π83im~_8w9raC־K5Pa近  ;}"!= x6A߯'S9!9 G®I7*~AVɑӇhm#džmƎ#o[z;}ORAš,2x`%rv >Iv˽F@uP`DǸYnJK[MO?/8T"9BV!ڃ_c~H% Q(X=Ê^DF>ν攬wRK_?\7>Y1Ur-?wN8TP˃qgx%.V^%O|`˺Yd`~EpL0Z_-ϳEa,:ai]|9ۮl:[[f34CCs3*E9 ^1X%2^؋Hq>o$ԜQ>MLE3_1$:{s,^V)ȌCԋI"s2p"IoR2dSzCQ(GI C R6vP<{$3L.ռLT<#ٯv;Hcw6;r\ԱB}8zEƂ܎@p~^O{7ID;GCS *YA n3Wܟ/N+~PAh?>j#047W_O%IH$ TR!P$˜2 )J%,.Dq 3 aM!I bDLs !\,!  (V(AÌSRRR$J$Zԩ>_^$VTLYV=C1}}ڽg*BF:/dLo|Z,Ut3$(Q3%0cVl>է[`^Pd æ?J+X uV?5C0X:aMP5Ch.$:z)̞$ CעJ UFkcl: HT~0*9H?Yp:,b?WZٿK@~_.aTxiV"4ߦ4_؃}<> T 6?vN;B|h *5Lb%bX%SLDHC*P+,xaY' 1xN;[xrT>  ְ@aTlaD-8-1xx \ QN)UlilX0<M&li.[Tch Q%3U1u$ARJ6ꙜqL8ȃ*}85_&TjSh h4B0ȝ|R0;>mqꞰ%w-55q_ -V9fӞX\tVXTwʶt)"Ț!# ژ>Qc4~ԩ "o+*8´o FP^BxJq>$)a())B!̫WC BRD>!T:3fDv:(2wbώ,E\ꍻ5m۬$I|;(aE^$jIȴ5[L8) jG|r $>̣$j;528y1$V'Hڰcprudj5xVfu2yUzT+B{1eɈL)SPD\wgd0C@m&k̪=J>nܹ~#w6.Ũ@mcjw+41ZĦÿ7A#va2 G*Sp yzo+rh뻤j--jd"IQT`CSBz:Spf0SDTjG/{á FQ̫wG\vl=#9GF'4P#i| zv?B!%ksߞb|rb6L\t9H?oo T_We_vg'M@H@:|sa=mQ>]l -'/6W` Jǟ PaVdx `E]w 2Buĭ$}g5iOſ)ArW38^­'?KF%CRs[ȉ ?ك Hɒ\qʜ[5c@MZNi# hÌ9S:Aa1WMdȦb}o@ZR9y+|4Qmq3[u:zʞZ\t|UxʴGYf"LϊN1?tG"eCW 鑚}حYnIfO&i}̌i:`jӡr.[k|.o ϼlȗI$=d͌#Tsp(4=} 9ſ䜷wεG_Yo)pĝ](88yvR,| 8s3dv2czFhHe kv،>Yӯ091 ?yqH?2*A $I;*SF Ǥ#Hv;gs2LGC81lI@+y]lD:8AM ߌNNyJ3҃Cel:Z "ꂓ<׏Vs0ͽn~с7 M|Zsn~ԂE]%" C[1%h)ZѶHt>Sհ>z8ul<ω#&>-OݕJk~MzJ!xwA *N5KunN]fW_e)!YAͶkJPHpcM]1'M98җfgvth@Nk"5b"\b)9o+sBɢ>zƲu\NH̚eO0בҧj1 AX4YGn4,| 4a+vye;3-#}E_^y$,^TALl1^,|R$\hݷ]( Ʌ9}ߌrbE* X~T©&o,>:?Vޅ̸r[26>ŧΛy~w )HTHp>_AGgOYk' ~ >%>uq_ T_t|}8!S8f84D|{sQ-%S;7H#}/~\uRo~UP6΂5F/^ZvI5/$0ﴣF/,|$ڥV[7ҦW<'f~-`KEκQ)8TJT3>)g̖"HS)GK*üpX҅+Z֜G^+eĞg?GYZ+Ï@3?9ߙF uoNǓPg jZ8h,}~lW(g.9/2fvPxfBC'bߋbN~e[Ut͂Nki/ 2.!^10T8 W_? c-ҍTNlH<Ԛ!.uMMӂ6ŷyv|KP)